unsigned gomp_dynamic_max_threads (void) { unsigned n_onln, loadavg, nthreads_var = gomp_icv (false)->nthreads_var; n_onln = get_num_procs (); if (n_onln > nthreads_var) n_onln = nthreads_var; loadavg = 0; #ifdef HAVE_GETLOADAVG { double dloadavg[3]; if (getloadavg (dloadavg, 3) == 3) { /* Add 0.1 to get a kind of biased rounding. */ loadavg = dloadavg[2] + 0.1; } } #endif if (loadavg >= n_onln) return 1; else return n_onln - loadavg; }
int openblas_get_num_procs(void) { #ifndef SMP return 1; #else return get_num_procs(); #endif }
int blas_get_cpu_number(void){ char *p; #if defined(OS_LINUX) || defined(OS_WINDOWS) || defined(OS_FREEBSD) || defined(OS_DARWIN) int max_num; #endif int blas_goto_num = 0; int blas_omp_num = 0; if (blas_num_threads) return blas_num_threads; #if defined(OS_LINUX) || defined(OS_WINDOWS) || defined(OS_FREEBSD) || defined(OS_DARWIN) max_num = get_num_procs(); #endif blas_goto_num = 0; #ifndef USE_OPENMP p = getenv("OPENBLAS_NUM_THREADS"); if (p) blas_goto_num = atoi(p); if (blas_goto_num < 0) blas_goto_num = 0; if (blas_goto_num == 0) { p = getenv("GOTO_NUM_THREADS"); if (p) blas_goto_num = atoi(p); if (blas_goto_num < 0) blas_goto_num = 0; } #endif blas_omp_num = 0; p = getenv("OMP_NUM_THREADS"); if (p) blas_omp_num = atoi(p); if (blas_omp_num < 0) blas_omp_num = 0; if (blas_goto_num > 0) blas_num_threads = blas_goto_num; else if (blas_omp_num > 0) blas_num_threads = blas_omp_num; else blas_num_threads = MAX_CPU_NUMBER; #if defined(OS_LINUX) || defined(OS_WINDOWS) || defined(OS_FREEBSD) || defined(OS_DARWIN) if (blas_num_threads > max_num) blas_num_threads = max_num; #endif if (blas_num_threads > MAX_CPU_NUMBER) blas_num_threads = MAX_CPU_NUMBER; #ifdef DEBUG printf( "Adjusted number of threads : %3d\n", blas_num_threads); #endif blas_cpu_number = blas_num_threads; return blas_num_threads; }
// B C S //############################################################################## // // Apply boundary conditions. // void bcs( lattice_ptr lattice) { int i, j, k, n, n1, a, id; int ni, nj, nk; int subs; double *ftemp, *f, *f1, *feq, *feq1, *rhoo, temp[Q]; double v, rho_in, rho_out, rho1; double c0; double D; double c2; #if RHO0_TEST //------------------------------------------------------------------[ TEST ]---- double *rho0; //------------------------------------------------------------------[ TEST ]---- #endif /* RHO0_TEST */ double u_x, u_y, u_z, usq,udotx; double u_in[2][2], u_out[2][2], u, rho, hua; double c; ni = lattice->param.LX; nj = lattice->param.LY; nk = lattice->param.LZ; id = get_proc_id(lattice); // for( subs=0; subs<(NUM_FLUID_COMPONENTS)-(INAMURO_SIGMA_COMPONENT); subs++) for( subs=0; subs<NUM_FLUID_COMPONENTS; subs++) { // P R E S S U R E T O P I N F L O W B C //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // pressure top inflow // -- Pressure boundary on top side using inflow pressure condition. if( (id ==(get_num_procs(lattice)-1)) && !lattice->param.GZL && lattice->param.pressure_t_in[subs] ) { k = nk-1; switch(NUM_FLUID_COMPONENTS) { case 1: { rho_in = lattice->param.rho_in; break;} case 2: { if(subs==0) { rho_in = lattice->param.rho_in;} if(subs==1) { rho_in = lattice->param.rho_A[subs];} break; } } for( j=0; j<nj; j++) { for( i=0; i<ni; i++) { n = XYZ2N( i, j, k, ni, nj); ftemp = lattice->pdf[subs][n].ftemp; // Top, Inflow if( lattice->param.incompressible) { u_z = -rho_in + ( ftemp[ C] + ftemp[ N] + ftemp[ S] + ftemp[ E] + ftemp[ W] + 2.*( ftemp[T ] + ftemp[TW] + ftemp[TE] + ftemp[TS] + ftemp[TN])); c = u_z; } else // compressible { u_z = -1. + ( ftemp[C] + ftemp[N ] + ftemp[S ] + ftemp[ E] + ftemp[ W] + ftemp[NE] + ftemp[NW] + ftemp[SE] + ftemp[SW] + 2.*( ftemp[T ] + ftemp[TW] + ftemp[TE] + ftemp[TS] + ftemp[TN])) / rho_in; c = u_z*rho_in; } //rev_Huang ftemp[B ] = ftemp[T ] - (1./3.)*c; ftemp[BW] = ftemp[TE] - (1./6.)*c + 0.5*(-ftemp[ W] - ftemp[NW] - ftemp[SW] + ftemp[ E] + ftemp[NE] + ftemp[SE]); ftemp[BE] = ftemp[TW] - (1./6.)*c - 0.5*(-ftemp[ W] - ftemp[NW] - ftemp[SW] + ftemp[ E] + ftemp[NE] + ftemp[SE]); ftemp[BS] = ftemp[TN] - (1./6.)*c + 0.5*( ftemp[N ] + ftemp[NW] + ftemp[NE] - ftemp[S ] - ftemp[SW] - ftemp[SE]); ftemp[BN] = ftemp[TS] - (1./6.)*c - 0.5*( ftemp[N ] + ftemp[NW] + ftemp[NE] - ftemp[S ] - ftemp[SW] - ftemp[SE]); #if 1 // Confirm density rho = ftemp[ C] + ftemp[ E] + ftemp[ W] + ftemp[ N] + ftemp[ S] + ftemp[ T] + ftemp[ B] + ftemp[NE] + ftemp[NW] + ftemp[SE] + ftemp[SW] + ftemp[TN] + ftemp[TS] + ftemp[BN] + ftemp[BS] + ftemp[TE] + ftemp[TW] + ftemp[BE] + ftemp[BW]; if( rho_in - rho > 1e-6) { printf("%s %d >> ERROR: pressure_top_in FAIL! " "rho_in = %f, rho = %f\n",__FILE__,__LINE__, rho_in, rho); } #endif } /* for( i=0; i<ni; i++) */ } /* for( j=0; j<nj; j++) */ } /* if( lattice->param.pressure_t_in[subs] ) */ //******************************************************************************** // P R E S S U R E B O T T O M O U T F L O W B C (peter's attempt?) //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // pressure bottom outflow // -- Pressure boundary on bottom side using outflow pressure condition. if((id ==0) && !lattice->param.GZL && lattice->param.pressure_b_out[subs] ) { k = 0; switch(NUM_FLUID_COMPONENTS) { case 1: { rho_out = lattice->param.rho_out; break; } case 2: { if(subs==0) { rho_out = lattice->param.rho_out;} if(subs==1) { rho_out = lattice->param.rho_A[subs];} break; } } for( j=0; j<nj; j++) { for( i=0; i<ni; i++) { n = XYZ2N( i, j, k, ni, nj); ftemp = lattice->pdf[subs][n].ftemp; // Bottom, rho_out if( lattice->param.incompressible) { u_z = rho_out - ( ftemp[C] + ftemp[N] + ftemp[S] + ftemp[E] + ftemp[W] + 2.*( ftemp[B] + ftemp[BW] + ftemp[BE] + ftemp[BS] + ftemp[BN])); c = u_z; } else // compressible { u_z = 1. - ( ftemp[C] + ftemp[N ] + ftemp[S ] + ftemp[ E] + ftemp[ W] + ftemp[NW] + ftemp[NE] + ftemp[SW] + ftemp[SE] + 2.*( ftemp[B ] + ftemp[BW] + ftemp[BE] + ftemp[BS] + ftemp[BN])) / rho_out; c = u_z*rho_out; } ftemp[T ] = ftemp[B ] + (1./3.)*c; ftemp[TW] = ftemp[BE] + (1./6.)*c + 0.5*(-ftemp[ W] - ftemp[NW] - ftemp[SW] + ftemp[ E] + ftemp[NE] + ftemp[SE]); ftemp[TE] = ftemp[BW] + (1./6.)*c - 0.5*(-ftemp[ W] - ftemp[NW] - ftemp[SW] + ftemp[ E] + ftemp[NE] + ftemp[SE]); ftemp[TS] = ftemp[BN] + (1./6.)*c + 0.5*( ftemp[N ] + ftemp[NW] + ftemp[NE] - ftemp[S ] - ftemp[SW] - ftemp[SE]); ftemp[TN] = ftemp[BS] + (1./6.)*c - 0.5*( ftemp[N ] + ftemp[NW] + ftemp[NE] - ftemp[S ] - ftemp[SW] - ftemp[SE]); #if 1 // Confirm density rho = ftemp[ C] + ftemp[ E] + ftemp[ W] + ftemp[ N] + ftemp[ S] + ftemp[ T] + ftemp[ B] + ftemp[NE] + ftemp[NW] + ftemp[SE] + ftemp[SW] + ftemp[TN] + ftemp[TS] + ftemp[BN] + ftemp[BS] + ftemp[TE] + ftemp[TW] + ftemp[BE] + ftemp[BW]; if( rho_out - rho > 1e-6) { printf("%s %d >> ERROR: pressure_bottom_out FAIL! " "rho_out = %f, rho = %f\n",__FILE__,__LINE__, rho_out, rho); } #endif } /* for( i=0; i<ni; i++) */ } /* for( j=0; j<nj; j++) */ } /* if( lattice->param.pressure_b_out[subs] ) */ //******************************************************************************** // V E L O C I T Y T O P I N F L O W B C //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // velocity top inflow // -- Velocity boundary on top side using inflow velocity condition. if( id == get_num_procs( lattice) - 1 && !lattice->param.GZL && lattice->param.velocity_t_in[subs]) { //printf("%s %d >> BOOM!",__FILE__,__LINE__); if(subs==0) u = lattice->param.uz_in; //lattice->param.uz_in; Non-wetting if(subs==1) u = lattice->param.uz_in; //lattice->param.uz_in; k = nk-1; for( j=0; j<nj; j++) { for( i=0; i<ni; i++) { n = XYZ2N( i, j, k, ni, nj); ftemp = lattice->pdf[subs][n].ftemp; if( !lattice->solids[subs][n].is_solid) { rho = ( ftemp[C ] + ftemp[W ] + ftemp[E ] + ftemp[N ] + ftemp[S ] + ftemp[NW] + ftemp[NE] + ftemp[SW] + ftemp[SE] + 2.*( ftemp[T ] + ftemp[TW] + ftemp[TE] + ftemp[TS] + ftemp[TN]) ) / ( 1. + u); c = rho*u; ftemp[B ] = ftemp[T ] - (1./3.)*c; ftemp[BW] = ftemp[TE] - (1./6.)*c + 0.5* (-ftemp[W ]- ftemp[NW]- ftemp[SW] + ftemp[E] +ftemp[NE] + ftemp[SE]); ftemp[BE] = ftemp[TW] - (1./6.)*c - 0.5* (-ftemp[W ]- ftemp[NW]- ftemp[SW] + ftemp[E] +ftemp[NE] + ftemp[SE]); ftemp[BS] = ftemp[TN] - (1./6.)*c + 0.5* (ftemp[N ] + ftemp[NW] + ftemp[NE] -ftemp[S ] -ftemp[SW] - ftemp[SE]); ftemp[BN] = ftemp[TS] - (1./6.)*c - 0.5* (ftemp[N ] + ftemp[NW] + ftemp[NE] -ftemp[S ] -ftemp[SW] - ftemp[SE]); } /* if( !is_solid) */ } /* for( i=0; i<ni; i++) */ } /* for( j=0; j<nj; j++) */ } /* if( lattice->param.velocity_t_in[subs]) */ // V E L O C I T Y B O T T O M O U T F L O W B C //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // velocity bottom inflow // -- Velocity boundary on bottom side using outflow velocity condition. if( id == 0 && !lattice->param.GZL && lattice->param.velocity_b_out[subs]) { //printf("%s %d >> BOOM!",__FILE__,__LINE__); if(subs==0) u = lattice->param.uz_out; //lattice->param.uz_out; Non-wetting if(subs==1) u = lattice->param.uz_out; //lattice->param.uz_out; k = 0; for( j=0; j<nj; j++) { for( i=0; i<ni; i++) { n = XYZ2N( i, j, k, ni, nj); ftemp = lattice->pdf[subs][n].ftemp; if( !lattice->solids[subs][n].is_solid) { rho = ( ftemp[C ] + ftemp[W ] + ftemp[E ] + ftemp[N ] + ftemp[S ] + ftemp[NW] + ftemp[NE] + ftemp[SW] + ftemp[SE] + 2.*( ftemp[B ] + ftemp[BW] + ftemp[BE] + ftemp[BS] + ftemp[BN]) ) / ( 1. - u); c = rho*u; ftemp[T ] = ftemp[B ] + (1./3.)*c; ftemp[TW] = ftemp[BE] + (1./6.)*c + 0.5* (-ftemp[W ]- ftemp[NW]- ftemp[SW] + ftemp[E] +ftemp[NE] + ftemp[SE]); ftemp[TE] = ftemp[BW] + (1./6.)*c - 0.5* (-ftemp[W ]- ftemp[NW]- ftemp[SW] + ftemp[E] +ftemp[NE] + ftemp[SE]); ftemp[TS] = ftemp[BN] + (1./6.)*c + 0.5* (ftemp[N ] + ftemp[NW] + ftemp[NE] -ftemp[S ] -ftemp[SW] - ftemp[SE]); ftemp[TN] = ftemp[BS] + (1./6.)*c - 0.5* (ftemp[N ] + ftemp[NW] + ftemp[NE] -ftemp[S ] -ftemp[SW] - ftemp[SE]); } /* if( !is_solid) */ } /* for( i=0; i<ni; i++) */ } /* for( j=0; j<nj; j++) */ } /* if( lattice->param.velocity_b_in[subs]) */ //******************************************************************************** // GZL P R E S S U R E // V E L O C I T Y T O P I N F L O W B C //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // -- Velocity boundary on top side using inflow velocity condition. #if PARALLEL id = get_proc_id(lattice); #else id = get_num_procs(lattice)-1; #endif if( (id ==get_num_procs(lattice)-1) && lattice->param.GZL && lattice->param.PressureBC)//lattice->param.velocity_t_in[subs]) { printf("%s %d >> BOOM!",__FILE__,__LINE__); k = nk-1; for( j=0; j<nj; j++) { for( i=0; i<ni; i++) { n = XYZ2N( i, j, k, ni, nj); f = lattice->pdf[subs][n].f; #if STORE_UEQ // u_x = &lattice->ueq[n].u[0] = 0.02; // lattice->ueq[n].u[1] = 0.; // lattice->ueq[n].u[2] = 0.; #else /* !( STORE_UEQ) */ // lattice->macro_vars[subs][n].u[0] = 0.02 ; // lattice->macro_vars[subs][n].u[1] = 0. ; // lattice->macro_vars[subs][n].u[2] = 0. ; #endif /* STORE_UEQ */ n1 = XYZ2N( i, j, k-1, ni, nj); f1 = lattice->pdf[subs][n1].f; feq1 = lattice->pdf[subs][n1].feq; // rhoo = &( lattice->macro_vars[subs][n].rho); switch(NUM_FLUID_COMPONENTS) {case 1: { rho = /*lattice->macro_vars[subs][n1].rho;*/lattice->param.rho_in; u_x = 0.;//lattice->macro_vars[subs][n1].u[0] ; u_y = 0.;//lattice->macro_vars[subs][n1].u[1] ; u_z = lattice->macro_vars[subs][n1].u[2] ; lattice->macro_vars[subs][n].u[2] = u_z; break; } case 2: { #if STORE_UEQ if(subs==0) { rho =lattice->param.rho_in;// 8+ 0.001*(double)lattice->time;// ; subs= 0 Non-wetting if( lattice->time >1000) {rho = lattice->param.rho_in;} } if(subs==1) rho = 0.000 ; //lattice->param.uz_in; subs= 1 Wetting // rho = lattice->param.rho_A[subs]; u_x = 0.;// lattice->ueq[n1].u[0] ; u_y = 0.;// lattice->ueq[n1].u[1] ; u_z = lattice->ueq[n1].u[2] ; lattice->macro_vars[subs][n].u[2] = u_z; lattice->ueq[n].u[2] = u_z; #endif break; } } lattice->macro_vars[subs][n].rho = rho; lattice->macro_vars[subs][n].u[0] = u_x; lattice->macro_vars[subs][n].u[1] = u_y; if( !lattice->solids[subs][n].is_solid) { compute_a_feq( feq, rho, u_x, u_y, u_z ); for (a= 0; a<Q; a++) { temp[a] = f1[a] - feq1[a]; f[a]=feq[a]+ temp[a]; } } /* if( !is_solid) */ } /* for( i=0; i<ni; i++) */ } /* for( j=0; j<nj; j++) */ } /* if( lattice->param.velocity_GZL) */ //GZL P R E S S U R E // V E L O C I T Y B O T T O M O U T F L O W B C //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // velocity bottom inflow // -- Velocity boundary on bottom side using inflow velocity condition. #if PARALLEL id = get_proc_id(lattice); #else id = 0; #endif if( (id ==0) && lattice->param.GZL && lattice->param.PressureBC)//lattice->param.velocity_b_in[subs]) { printf("%s %d >> BOOM!",__FILE__,__LINE__); k = 0; for( j=0; j<nj; j++) { for( i=0; i<ni; i++) { n = XYZ2N( i, j, k, ni, nj); f = lattice->pdf[subs][n].f; n1 = XYZ2N( i, j, k+1, ni, nj); f1 = lattice->pdf[subs][n1].f; feq1 = lattice->pdf[subs][n1].feq; switch(NUM_FLUID_COMPONENTS) {case 1: { rho = /*lattice->macro_vars[subs][n1].rho;*/lattice->param.rho_out; u_x = 0.;//lattice->macro_vars[subs][n1].u[0] ; u_y = 0.;//lattice->macro_vars[subs][n1].u[1] ; u_z = lattice->macro_vars[subs][n1].u[2] ; lattice->macro_vars[subs][n].u[2] = u_z; break; } case 2: { #if STORE_UEQ if(subs==0) rho = 0.000; if(subs==1) { rho =lattice->param.rho_out; //8.0- 0.001*(double)lattice->time;// if( lattice->time >6000) {rho = lattice->param.rho_out;} } // rho = lattice->param.rho_B[subs]; u_x = 0.;//lattice->ueq[n1].u[0] ; u_y = 0.;//lattice->ueq[n1].u[1] ; u_z = lattice->ueq[n1].u[2] ; lattice->macro_vars[subs][n].u[2] = u_z; lattice->ueq[n].u[2] = u_z; #endif break; } } lattice->macro_vars[subs][n].rho = rho; lattice->macro_vars[subs][n].u[0] = u_x; lattice->macro_vars[subs][n].u[1] = u_y; if( !lattice->solids[subs][n].is_solid) { compute_a_feq( feq, rho, u_x, u_y, u_z ); for (a= 0; a<Q; a++) { temp[a] =f1[a] - feq1[a]; f[a] = feq[a]+ temp[a]; } } /* if( !is_solid) */ } /* for( i=0; i<ni; i++) */ } /* for( j=0; j<nj; j++) */ } /* if( lattice->param.velocity_GZL) */ //PAN V E L O C I T Y T O P I N F L O W B C //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // -- Velocity boundary on top side using inflow velocity condition. if( lattice->param.GZL && (!lattice->param.PressureBC))//lattice->param.velocity_t_in[subs]) { printf("%s %d >> BOOM!",__FILE__,__LINE__); k = nk-1; for( j=0; j<nj; j++) { for( i=0; i<ni; i++) { n = XYZ2N( i, j, k, ni, nj); f = lattice->pdf[subs][n].f; // feq = lattice->pdf[subs][n].feq; n1 = XYZ2N( i, j, k-1, ni, nj); f1 = lattice->pdf[subs][n1].f; feq1 = lattice->pdf[subs][n1].feq; rhoo = &( lattice->macro_vars[subs][n].rho); switch(NUM_FLUID_COMPONENTS) {case 1: { rho = /*lattice->macro_vars[subs][n1].rho;*/lattice->param.rho_in; u_x = 0.;//lattice->macro_vars[subs][n1].u[0] ; u_y = 0.;//lattice->macro_vars[subs][n1].u[1] ; u_z = -0.0;//lattice->macro_vars[subs][n1].u[2] ; break; } case 2: { #if STORE_UEQ rho = lattice->param.rho_A[subs]; u_x = 0.;// lattice->ueq[n1].u[0] ; u_y = 0.;// lattice->ueq[n1].u[1] ; u_z = 0.;// lattice->ueq[n1].u[2] ; #endif break; } } lattice->macro_vars[subs][n].rho = rho; lattice->macro_vars[subs][n].u[0] = u_x; lattice->macro_vars[subs][n].u[1] = u_y; lattice->macro_vars[subs][n].u[2] = u_z; if( !lattice->solids[subs][n].is_solid) { compute_a_feq( feq, rho, u_x, u_y, u_z ); for (a= 0; a<Q; a++) {f[a] = feq[a];}//+(f1[a] - feq1[a]); } /* if( !is_solid) */ } /* for( i=0; i<ni; i++) */ } /* for( j=0; j<nj; j++) */ } /* if( lattice->param.velocity_GZL) */ //PAN V E L O C I T Y B O T T O M I N F L O W B C //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // velocity bottom inflow // -- Velocity boundary on bottom side using inflow velocity condition. if( lattice->param.GZL && (!lattice->param.PressureBC))//lattice->param.velocity_b_in[subs]) { printf("%s %d >> BOOM!",__FILE__,__LINE__); k = 0; for( j=0; j<nj; j++) { for( i=0; i<ni; i++) { n = XYZ2N( i, j, k, ni, nj); f = lattice->pdf[subs][n].f; // feq = lattice->pdf[subs][n].feq; n1 = XYZ2N( i, j, k+1, ni, nj); f1 = lattice->pdf[subs][n1].f; feq1 = lattice->pdf[subs][n1].feq; switch(NUM_FLUID_COMPONENTS) {case 1: { rho = /*lattice->macro_vars[subs][n1].rho;*/lattice->param.rho_out; u_x = 0.;//lattice->macro_vars[subs][n1].u[0] ; u_y = 0.;//lattice->macro_vars[subs][n1].u[1] ; u_z = -0.0;//lattice->macro_vars[subs][n1].u[2] ; break; } case 2: { #if STORE_UEQ rho = lattice->param.rho_B[subs]; u_x = 0.;//lattice->ueq[n1].u[0] ; u_y = 0.;//lattice->ueq[n1].u[1] ; u_z = 0.;//lattice->ueq[n1].u[2] ; #endif break; } } lattice->macro_vars[subs][n].rho = rho; lattice->macro_vars[subs][n].u[0] = u_x; lattice->macro_vars[subs][n].u[1] = u_y; lattice->macro_vars[subs][n].u[2] = u_z; if( !lattice->solids[subs][n].is_solid) { compute_a_feq( feq, rho, u_x, u_y, u_z ); if(subs==1) compute_a_feq( feq1, 2.0- 0.0003*(double)lattice->time, u_x, u_y, u_z ); for (a= 0; a<Q; a++) { f[a] = feq[a]; }// +(f1[a] - feq1[a]); } /* if( !is_solid) */ } /* for( i=0; i<ni; i++) */ } /* for( j=0; j<nj; j++) */ } /* if( lattice->param.velocity_GZL) */ } /* for( subs=0; subs<(NUM_FLUID_COMPONENTS)-(INAMURO_SIGMA_COMPONENT); subs++) */ }
inline controller::controller() : chains(&stack_m), mirror(&stack_s), clock(1) { this->each = new node_each(this); this->which = NULL; for(int i = 0; i < get_num_procs(); i++) nodes.push_back(i); if(!verbose()) this->io_guard.enable(); }
int omp_get_num_procs (void) { return get_num_procs (); }