From: Alexey Shvetsov Date: Tue, 8 May 2012 18:17:50 +0000 (+0400) Subject: [tools] g_sans - add OpenMP based parallelism X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=commitdiff_plain;h=9ffa148a0e0b3814ee2c887af0373c0c773139ed;p=alexxy%2Fgromacs.git [tools] g_sans - add OpenMP based parallelism This commit adds OpenMP based parallelism for calc_radial_distribution_histogram function Also it adds check for mcover parameter which should be -1 or (0,1] Change-Id: Ic14267782c69c25364b69a91719cb451fd8e3a89 Signed-off-by: Alexey Shvetsov --- diff --git a/src/tools/gmx_sans.c b/src/tools/gmx_sans.c index 311fa9c3a4..ab3730a36b 100644 --- a/src/tools/gmx_sans.c +++ b/src/tools/gmx_sans.c @@ -55,6 +55,10 @@ #include "gmx_ana.h" #include "nsfactor.h" +#ifdef GMX_OPENMP +#include +#endif + int gmx_sans(int argc,char *argv[]) { @@ -80,6 +84,7 @@ int gmx_sans(int argc,char *argv[]) static real start_q=0.0, end_q=2.0, q_step=0.01; static real mcover=-1; static unsigned int seed=0; + static int nthreads=-1; static const char *emode[]= { NULL, "direct", "mc", NULL }; static const char *emethod[]={ NULL, "debye", "fft", NULL }; @@ -95,7 +100,7 @@ int gmx_sans(int argc,char *argv[]) { "-mode", FALSE, etENUM, {emode}, "Mode for sans spectra calculation" }, { "-mcover", FALSE, etREAL, {&mcover}, - "Monte-Carlo coverage"}, + "Monte-Carlo coverage should be -1(default) or (0,1]"}, { "-method", FALSE, etENUM, {emethod}, "[HIDDEN]Method for sans spectra calculation" }, { "-pbc", FALSE, etBOOL, {&bPBC}, @@ -110,6 +115,10 @@ int gmx_sans(int argc,char *argv[]) "Stepping in q (1/nm)"}, { "-seed", FALSE, etINT, {&seed}, "Random seed for Monte-Carlo"}, +#ifdef GMX_OPENMP + { "-nt", FALSE, etINT, {&nthreads}, + "Number of threads to start"}, +#endif }; FILE *fp; const char *fnTPX,*fnNDX,*fnDAT=NULL; @@ -144,13 +153,22 @@ int gmx_sans(int argc,char *argv[]) { efXVG, "-pr", "pr", ffWRITE } }; +#ifdef GMX_OPENMP + nthreads = omp_get_max_threads(); +#endif + CopyRight(stderr,argv[0]); parse_common_args(&argc,argv,PCA_BE_NICE, NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv); /* check that binwidth not smaller than smallers distance */ check_binwidth(binwidth); + check_mcover(mcover); + /* setting number of omp threads globaly */ +#ifdef GMX_OPENMP + omp_set_num_threads(nthreads); +#endif /* Now try to parse opts for modes */ switch(emethod[0][0]) { case 'd': diff --git a/src/tools/nsfactor.c b/src/tools/nsfactor.c index 79ebdbcebc..e7879e7ca0 100644 --- a/src/tools/nsfactor.c +++ b/src/tools/nsfactor.c @@ -46,12 +46,26 @@ #include "vec.h" #include "nsfactor.h" +#ifdef GMX_OPENMP +#include +#endif + void check_binwidth(real binwidth) { real smallest_bin=0.1; if (binwidth1.0) { + gmx_fatal(FARGS,"mcover should be -1 or (0,1]"); + } else if ((mcover<0)&(mcover != -1)) { + gmx_fatal(FARGS,"mcover should be -1 or (0,1]"); + } else { + return; + } +} + void normalize_probability(int n,double *a){ int i; double norm=0.0; @@ -148,11 +162,17 @@ gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram ( real mcover, unsigned int seed) { gmx_radial_distribution_histogram_t *pr=NULL; - rvec dist; - double rmax; - int i,j; - gmx_large_int_t mc=0,max; - gmx_rng_t rng=NULL; + rvec dist; + double rmax; + int i,j; +#ifdef GMX_OPENMP + double **tgr; + int tid; + int nthreads; + gmx_rng_t *trng=NULL; +#endif + gmx_large_int_t mc=0,max; + gmx_rng_t rng=NULL; /* allocate memory for pr */ snew(pr,1); @@ -181,18 +201,86 @@ gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram ( max=(gmx_large_int_t)floor(0.5*mcover*isize*(isize-1)); } rng=gmx_rng_init(seed); - while(mcgrn); + trng[i]=gmx_rng_init(gmx_rng_uniform_uint32(rng)); + } + #pragma omp parallel shared(tgr,trng,mc) private(tid,i,j) + { + tid = omp_get_thread_num(); + /* now starting parallel threads */ + #pragma omp for + for(mc=0;mcslength[index[i]]*gsans->slength[index[j]]; + } + } + } + /* collecting data from threads */ + for(i=0;igrn;i++) { + for(j=0;jgr[i] += tgr[j][i]; + } + } + /* freeing memory for tgr and destroying trng */ + for(i=0;igr[(int)floor(sqrt(distance2(x[index[i]],x[index[j]]))/binwidth)]+=gsans->slength[index[i]]*gsans->slength[index[j]]; - mc++; } +#endif gmx_rng_destroy(rng); } else { - for(i=0;igrn); + } + #pragma omp parallel shared(tgr) private(tid,i,j) + { + tid = omp_get_thread_num(); + /* starting parallel threads */ + #pragma omp for + for(i=0;islength[index[i]]*gsans->slength[index[j]]; + } + } + } + /* collecating data for pr->gr */ + for(i=0;igrn;i++) { + for(j=0;jgr[i] += tgr[j][i]; + } + } + /* freeing memory for tgr */ + for(i=0;igr[(int)floor(sqrt(distance2(x[index[i]],x[index[j]]))/binwidth)]+=gsans->slength[index[i]]*gsans->slength[index[j]]; + } + } +#endif } /* normalize */ diff --git a/src/tools/nsfactor.h b/src/tools/nsfactor.h index 7f2d9cc59e..3e6e5fa562 100644 --- a/src/tools/nsfactor.h +++ b/src/tools/nsfactor.h @@ -74,13 +74,15 @@ typedef struct gmx_static_structurefator_t { void check_binwidth(real binwidth); +void check_mcover(real mcover); + void normalize_probability(int n, double *a); gmx_nentron_atomic_structurefactors_t *gmx_neutronstructurefactors_init(const char *datfn); gmx_sans_t *gmx_sans_init(t_topology *top, gmx_nentron_atomic_structurefactors_t *gnsf); -gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram ( gmx_sans_t *gsans, +gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram (gmx_sans_t *gsans, rvec *x, matrix box, atom_id *index,