nco/nco_omp.h File Reference

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netcdf.h>
#include "nco_netcdf.h"
#include "nco.h"
#include "nco_ctl.h"

Include dependency graph for nco_omp.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int omp_get_dynamic (void)
int omp_get_max_threads (void)
int omp_get_nested (void)
int omp_get_num_procs (void)
int omp_get_num_threads (void)
int omp_get_thread_num (void)
int omp_in_parallel (void)
void omp_set_dynamic (int dynamic_threads)
void omp_set_nested (int nested)
void omp_set_num_threads (int num_threads)
int nco_openmp_ini (int thr_nbr)
int nco_var_prc_crr_prn (const int idx, const char *const var_nm)


Function Documentation

int nco_openmp_ini int  thr_nbr  ) 
 

Definition at line 30 of file nco_omp.c.

References dbg_lvl_get(), EXIT_FAILURE, False, FILE, int_CEWI, ncap, ncatted, ncbo, ncea, ncecat, ncflint, ncks, nco_dfl_case_prg_id_err(), nco_exit(), ncpdq, ncra, ncrcat, ncrename, ncwa, omp_get_max_threads(), omp_get_num_procs(), omp_get_num_threads(), omp_in_parallel(), omp_set_dynamic(), omp_set_num_threads(), prg_get(), prg_nm_get(), and True.

Referenced by main().

00031 {
00032   /* Purpose: Initialize OpenMP multi-threading environment
00033      Honor user-requested thread number, balance against known code efficiency,
00034      print diagnostics
00035      Returns thr_nbr=1 in three situations:
00036      1. UP codes (not threaded)
00037      2. SMP codes compiled with compilers which lack OpenMP support
00038      3. SMP codes where single thread requested/advised
00039      Otherwise returns system-dependent thr_nbr */
00040 
00041   /* Using naked stdin/stdout/stderr in parallel region generates warning
00042      Copy appropriate filehandle to variable scoped shared in parallel clause */
00043 
00044   FILE * const fp_stderr=stderr; /* [fl] stderr filehandle CEWI */
00045 
00046   bool USR_SPC_THR_RQS=False;
00047 
00048   const int dyn_thr=1; /* [flg] Allow system to dynamically set number of threads */
00049 
00050   int thr_nbr_act; /* O [nbr] Number of threads NCO uses */
00051   int thr_nbr_max_fsh=4; /* [nbr] Maximum number of threads program can use efficiently */
00052   int thr_nbr_max=int_CEWI; /* [nbr] Maximum number of threads system allows */
00053   int prc_nbr_max; /* [nbr] Maximum number of processors available */
00054   int thr_nbr_rqs=int_CEWI; /* [nbr] Number of threads to request */
00055 
00056 #ifndef _OPENMP
00057   if(dbg_lvl_get() > 0) (void)fprintf(fp_stderr,"%s: INFO Compiler lacks (or user turned off) OpenMP support. Code will execute in Uni-Processor (UP) mode with single thread.\n",prg_nm_get());
00058 #endif /* !_OPENMP */
00059 
00060   /* Strategy: 
00061      0. Determine maximum number of threads system will allocate (thr_nbr_max)
00062      1. Command-line thread request, if any, overrides automatic algorithm
00063      2. If no command-line request then system allocates OMP_NUM_THREADS if possible
00064      3. Reduce maximum number of threads available to system to thr_nbr_max_fsh
00065      Many operators cannot use more than thr_nbr_max_fsh ~ 2--4 threads efficiently
00066      Play nice: Set dynamic threading so that system can make efficiency decisions
00067      When dynamic threads are set, system never allocates more than thr_nbr_max_fsh */
00068   if(thr_nbr < 0){
00069     (void)fprintf(fp_stderr,"%s: ERROR User-requested thread number = %d is less than zero\n",prg_nm_get(),thr_nbr);
00070     nco_exit(EXIT_FAILURE);
00071   } /* endif err */
00072 
00073   if(thr_nbr == 0)
00074     if(dbg_lvl_get() > 2)
00075       (void)fprintf(fp_stderr,"%s: INFO User did not specify thread request > 0 on command line. NCO will automatically assign threads based on OMP_NUM_THREADS environment and machine capabilities.\nHINT: Not specifiying any --thr_nbr (or specifying --thr_nbr=0) causes NCO to try to pick the optimal thread number. Specifying --thr_nbr=1 tells NCO to execute in Uni-Processor (UP) (i.e., single-threaded) mode.\n",prg_nm_get());
00076 
00077   if(thr_nbr > 0) USR_SPC_THR_RQS=True;
00078 
00079   prc_nbr_max=omp_get_num_procs(); /* [nbr] Maximum number of processors available */
00080   if(omp_in_parallel()){
00081     (void)fprintf(fp_stderr,"%s: ERROR Attempted to get maximum thread number from within parallel region\n",prg_nm_get());
00082     nco_exit(EXIT_FAILURE);
00083   }else{
00084     thr_nbr_max=omp_get_max_threads(); /* [nbr] Maximum number of threads system allows */
00085   } /* end error */
00086 
00087   if(dbg_lvl_get() > 2){
00088     (void)fprintf(fp_stderr,"%s: INFO Number of processors available is %d\n",prg_nm_get(),prc_nbr_max);
00089     (void)fprintf(fp_stderr,"%s: INFO Maximum number of threads system allows is %d\n",prg_nm_get(),thr_nbr_max);
00090   } /* endif dbg */
00091 
00092   if(USR_SPC_THR_RQS){
00093     /* Always try to honor user-specified thread request... */
00094     thr_nbr_rqs=thr_nbr; /* [nbr] Number of threads to request */
00095     /* ...if possible... */
00096     if(dbg_lvl_get() > 2) (void)fprintf(fp_stderr,"%s: INFO User command-line-requested %d thread%s\n",prg_nm_get(),thr_nbr,(thr_nbr > 1) ? "s" : "");
00097     if(thr_nbr > thr_nbr_max){
00098       (void)fprintf(fp_stderr,"%s: WARNING Reducing user-requested thread number = %d to maximum thread number allowed = %d\n",prg_nm_get(),thr_nbr,thr_nbr_max);
00099       thr_nbr_rqs=thr_nbr_max; /* [nbr] Number of threads to request */
00100     } /* endif */
00101   }else{ /* !USR_SPC_THR_RQS */
00102     /* Otherwise use automatic thread allocation algorithm */
00103 
00104     /* Request maximum number of threads permitted */
00105     thr_nbr_rqs=thr_nbr_max; /* [nbr] Number of threads to request */
00106 
00107     /* Disable threading on per-program basis to play nicely with others */
00108     switch(prg_get()){
00109       /* Operators with pre-set thread limit */
00110     case ncecat: 
00111     case ncrcat: 
00112       /* ncecat and ncrcat are extremely I/O intensive 
00113          Maximum efficiency when one thread reads from input file while other writes to output file */
00114       thr_nbr_max_fsh=2;
00115       break;
00116       /* Operators without maximum pre-set thread limit (NB: not all of these are threaded!) */
00117     case ncap: 
00118     case ncbo: 
00119     case ncatted: 
00120     case ncea:
00121     case ncflint: 
00122     case ncks: 
00123     case ncpdq: 
00124     case ncra:
00125     case ncrename: 
00126     case ncwa: 
00127       break;
00128     default: nco_dfl_case_prg_id_err(); break;
00129     } /* end case */
00130     
00131     /* Automatic algorithm tries to play nice with others */
00132     (void)omp_set_dynamic(dyn_thr); /* [flg] Allow system to dynamically set number of threads */
00133     if(dbg_lvl_get() > 0) (void)fprintf(fp_stderr,"%s: INFO Allowing OS to dynamically set threads\n",prg_nm_get());
00134 
00135     /* Apply program/system limitations */
00136     if(thr_nbr_max > thr_nbr_max_fsh){
00137       if(dbg_lvl_get() > 0) (void)fprintf(fp_stderr,"%s: INFO Reducing default thread number from %d to %d, an operator-dependent \"play-nice\" number set in nco_openmp_ini()\n",prg_nm_get(),thr_nbr_max,thr_nbr_max_fsh);
00138       thr_nbr_rqs=thr_nbr_max_fsh; /* [nbr] Number of threads to request */
00139     } /* endif */      
00140   } /* !USR_SPC_THR_RQS */
00141 
00142   /* Set thread number */
00143   if(omp_in_parallel()){
00144     (void)fprintf(fp_stderr,"%s: ERROR Attempted to set thread number from within parallel region\n",prg_nm_get());
00145     nco_exit(EXIT_FAILURE);
00146   }else{
00147     (void)omp_set_num_threads(thr_nbr_rqs); 
00148     if(dbg_lvl_get() > 0) (void)fprintf(fp_stderr,"%s: INFO omp_set_num_threads() used to set execution environment to spawn teams of %d threads\n",prg_nm_get(),thr_nbr_rqs);
00149   } /* end error */
00150 
00151   thr_nbr_act=omp_get_max_threads();
00152   if(dbg_lvl_get() > 2) (void)fprintf(fp_stderr,"%s: INFO After using omp_set_num_threads() to adjust for any user requests/NCO optimizations, omp_get_max_threads() reports that a parallel construct here/now would spawn %d threads\n",prg_nm_get(),thr_nbr_act);
00153 #ifdef _OPENMP
00154   if(dbg_lvl_get() > 2){
00155 #pragma omp parallel default(none) shared(fp_stderr,thr_nbr_act)
00156     { /* begin OpenMP parallel */
00157 #pragma omp single nowait
00158       { /* begin OpenMP single */
00159         thr_nbr_act=omp_get_num_threads(); /* [nbr] Number of threads NCO uses */
00160         if(dbg_lvl_get() > 0) (void)fprintf(fp_stderr,"%s: INFO Small parallel test region spawned team of %d threads\n",prg_nm_get(),thr_nbr_act);
00161       } /* end OpenMP single */
00162     } /* end OpenMP parallel */
00163   } /* end dbg */
00164 #endif /* !_OPENMP */
00165   
00166   return thr_nbr_act; /* O [nbr] Number of threads NCO uses */
00167 } /* end nco_openmp_ini() */

int nco_var_prc_crr_prn const int  idx,
const char *const   var_nm
 

Definition at line 171 of file nco_omp.c.

References omp_get_thread_num(), and prg_nm_get().

Referenced by main().

00173 {
00174   /* Purpose: Print name of current variable */
00175   int rcd=0; /* [rcd] Return code */
00176 
00177 #ifdef _OPENMP
00178   (void)fprintf(stderr,"%s: INFO Thread #%d processing var_prc[%d] = \"%s\"\n",prg_nm_get(),omp_get_thread_num(),idx,var_nm);
00179 #else /* !_OPENMP */
00180   rcd+=idx*0; /* CEWI */
00181   (void)fprintf(stderr,"%s, ",var_nm);
00182 #endif /* !_OPENMP */
00183 
00184   return rcd;
00185 } /* end nco_var_prc_crr_prn() */

int omp_get_dynamic void   ) 
 

Definition at line 15 of file nco_omp.c.

00015 {return 0;}

int omp_get_max_threads void   ) 
 

Definition at line 16 of file nco_omp.c.

Referenced by nco_openmp_ini().

00016 {return 1;}

int omp_get_nested void   ) 
 

Definition at line 17 of file nco_omp.c.

00017 {return 0;}

int omp_get_num_procs void   ) 
 

Definition at line 18 of file nco_omp.c.

Referenced by nco_openmp_ini().

00018 {return 1;}

int omp_get_num_threads void   ) 
 

Definition at line 19 of file nco_omp.c.

Referenced by nco_openmp_ini().

00019 {return 1;}

int omp_get_thread_num void   ) 
 

Definition at line 20 of file nco_omp.c.

Referenced by main(), and nco_var_prc_crr_prn().

00020 {return 0;}

int omp_in_parallel void   ) 
 

Definition at line 21 of file nco_omp.c.

Referenced by main(), and nco_openmp_ini().

00021 {return 0;}

void omp_set_dynamic int  dynamic_threads  ) 
 

Definition at line 23 of file nco_omp.c.

Referenced by nco_openmp_ini().

00023 {int foo=0;dynamic_threads+=foo;}

void omp_set_nested int  nested  ) 
 

Definition at line 24 of file nco_omp.c.

00024 {int foo=0;nested+=foo;}

void omp_set_num_threads int  num_threads  ) 
 

Definition at line 25 of file nco_omp.c.

Referenced by nco_openmp_ini().

00025 {int foo=0;num_threads+=foo;}


Generated on Thu Mar 16 18:16:02 2006 for nco by  doxygen 1.4.4