void init_pppm(FILE *log,t_commrec *cr,t_nsborder *nsb, bool bVerbose,bool bOld,rvec box,char *ghatfn,t_inputrec *ir) { int nx,ny,nz,m,porder; ivec grids; real r1,rc; const real tol = 1e-5; rvec spacing; #ifdef WITHOUT_FFTW fatal_error(0,"PPPM used, but GROMACS was compiled without FFTW support!\n"); #endif if (cr != NULL) { if (cr->nnodes > 1) fprintf(log,"Initializing parallel PPPM.\n"); } fprintf(log,"Will use the PPPM algorithm for long-range electrostatics\n"); if (!fexist(ghatfn)) { beta[XX]=beta[YY]=beta[ZZ]= 1.85; nx = ir->nkx; ny = ir->nky; nz = ir->nkz; fprintf(log,"Generating Ghat function\n"); fprintf(log,"Grid size is %d x %d x %d\n",nx,ny,nz); if ((nx < 4) || (ny < 4) || (nz < 4)) fatal_error(0,"Grid must be at least 4 points in all directions"); ghat = mk_rgrid(nx,ny,nz); mk_ghat(NULL,nx,ny,nz,ghat,box,ir->rcoulomb_switch,ir->rcoulomb,TRUE,bOld); if (bVerbose) pr_scalar_gk("generghat.xvg",nx,ny,nz,box,ghat); } else { fprintf(stderr,"Reading Ghat function from %s\n",ghatfn); ghat = rd_ghat(log,ghatfn,grids,spacing,beta,&porder,&r1,&rc); /* Check whether cut-offs correspond */ if ((fabs(r1-ir->rcoulomb_switch)>tol) || (fabs(rc-ir->rcoulomb)>tol)) { fprintf(log,"rcoulomb_switch = %10.3e rcoulomb = %10.3e" " r1 = %10.3e rc = %10.3e\n", ir->rcoulomb_switch,ir->rcoulomb,r1,rc); fflush(log); fatal_error(0,"Cut-off lengths in tpb file and Ghat file %s " "do not match\nCheck your log file!",ghatfn); } /* Check whether boxes correspond */ for(m=0; (m<DIM); m++) if (fabs(box[m]-grids[m]*spacing[m]) > tol) { pr_rvec(log,0,"box",box,DIM); pr_rvec(log,0,"grid-spacing",spacing,DIM); pr_ivec(log,0,"grid size",grids,DIM); fflush(log); fatal_error(0,"Box sizes in tpb file and Ghat file %s do not match\n" "Check your log file!",ghatfn); } if (porder != 2) fatal_error(0,"porder = %d, should be 2 in %s",porder,ghatfn); nx = grids[XX]; ny = grids[YY]; nz = grids[ZZ]; if (bVerbose) pr_scalar_gk("optimghat.xvg",nx,ny,nz,box,ghat); } /* Now setup the FFT things */ grid = mk_fftgrid(log,PAR(cr),nx,ny,nz,ir->bOptFFT); }
int main(int argc,char *argv[]) { int mmm[] = { 8, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 100 }; int nnn[] = { 24, 32, 48, 60, 72, 84, 96 }; #define NNN asize(nnn) FILE *fp,*fplog; int *niter; int i,j,n,nit,ntot,n3,rsize; double t,nflop,start; double *rt,*ct; t_fftgrid *g; t_commrec *cr; static gmx_bool bReproducible = FALSE; static int nnode = 1; static int nitfac = 1; t_pargs pa[] = { { "-reproducible", FALSE, etBOOL, {&bReproducible}, "Request binary reproducible results" }, { "-np", FALSE, etINT, {&nnode}, "Number of NODEs" }, { "-itfac", FALSE, etINT, {&nitfac}, "Multiply number of iterations by this" } }; static t_filenm fnm[] = { { efLOG, "-g", "fft", ffWRITE }, { efXVG, "-o", "fft", ffWRITE } }; #define NFILE asize(fnm) cr = init_par(&argc,&argv); if (MASTER(cr)) CopyRight(stdout,argv[0]); parse_common_args(&argc,argv, PCA_CAN_SET_DEFFNM | (MASTER(cr) ? 0 : PCA_QUIET), NFILE,fnm,asize(pa),pa,0,NULL,0,NULL); gmx_log_open(ftp2fn(efLOG,NFILE,fnm),cr,1,0,&fplog); snew(niter,NNN); snew(ct,NNN); snew(rt,NNN); rsize = sizeof(real); for(i=0; (i<NNN); i++) { n = nnn[i]; if (n < 16) niter[i] = 50; else if (n < 26) niter[i] = 20; else if (n < 51) niter[i] = 10; else niter[i] = 5; niter[i] *= nitfac; nit = niter[i]; if (MASTER(cr)) fprintf(stderr,"\r3D FFT (%s precision) %3d^3, niter %3d ", (rsize == 8) ? "Double" : "Single",n,nit); g = mk_fftgrid(n,n,n,NULL,NULL,cr,bReproducible); if (PAR(cr)) start = time(NULL); else start_time(); for(j=0; (j<nit); j++) { gmxfft3D(g,GMX_FFT_REAL_TO_COMPLEX,cr); gmxfft3D(g,GMX_FFT_COMPLEX_TO_REAL,cr); } if (PAR(cr)) rt[i] = time(NULL)-start; else { update_time(); rt[i] = node_time(); } done_fftgrid(g); sfree(g); } if (MASTER(cr)) { fprintf(stderr,"\n"); fp=xvgropen(ftp2fn(efXVG,NFILE,fnm), "FFT timings","n^3","t (s)"); for(i=0; (i<NNN); i++) { n3 = 2*niter[i]*nnn[i]*nnn[i]*nnn[i]; fprintf(fp,"%10d %10g\n",nnn[i],rt[i]/(2*niter[i])); } gmx_fio_fclose(fp); } return 0; }
int gmx_pppm_init(FILE *log, t_commrec *cr, const output_env_t oenv, gmx_bool bVerbose, gmx_bool bOld, matrix box, char *ghatfn, t_inputrec *ir, gmx_bool bReproducible) { int nx,ny,nz,m,porder; ivec grids; real r1,rc; const real tol = 1e-5; rvec box_diag,spacing; #ifdef DISABLE_PPPM gmx_fatal(FARGS,"PPPM is not functional in the current version, we plan to implement PPPM through a small modification of the PME code."); return -1; #else #ifdef GMX_WITHOUT_FFTW gmx_fatal(FARGS,"PPPM used, but GROMACS was compiled without FFTW support!\n"); #endif if (log) { if (cr != NULL) { if (cr->nnodes > 1) fprintf(log,"Initializing parallel PPPM.\n"); } fprintf(log, "Will use the PPPM algorithm for long-range electrostatics\n"); } for(m=0; m<DIM; m++) box_diag[m] = box[m][m]; if (!gmx_fexist(ghatfn)) { beta[XX]=beta[YY]=beta[ZZ]= 1.85; nx = ir->nkx; ny = ir->nky; nz = ir->nkz; if (log) { fprintf(log,"Generating Ghat function\n"); fprintf(log,"Grid size is %d x %d x %d\n",nx,ny,nz); } if ((nx < 4) || (ny < 4) || (nz < 4)) gmx_fatal(FARGS,"Grid must be at least 4 points in all directions"); ghat = mk_rgrid(nx,ny,nz); mk_ghat(NULL,nx,ny,nz,ghat,box_diag, ir->rcoulomb_switch,ir->rcoulomb,TRUE,bOld); if (bVerbose) pr_scalar_gk("generghat.xvg",oenv,nx,ny,nz,box_diag,ghat); } else { fprintf(stderr,"Reading Ghat function from %s\n",ghatfn); ghat = rd_ghat(log,oenv,ghatfn,grids,spacing,beta,&porder,&r1,&rc); /* Check whether cut-offs correspond */ if ((fabs(r1-ir->rcoulomb_switch)>tol) || (fabs(rc-ir->rcoulomb)>tol)) { if (log) { fprintf(log,"rcoulomb_switch = %10.3e rcoulomb = %10.3e" " r1 = %10.3e rc = %10.3e\n", ir->rcoulomb_switch,ir->rcoulomb,r1,rc); fflush(log); } gmx_fatal(FARGS,"Cut-off lengths in tpb file and Ghat file %s " "do not match\nCheck your log file!",ghatfn); } /* Check whether boxes correspond */ for(m=0; (m<DIM); m++) if (fabs(box_diag[m]-grids[m]*spacing[m]) > tol) { if (log) { pr_rvec(log,0,"box",box_diag,DIM,TRUE); pr_rvec(log,0,"grid-spacing",spacing,DIM,TRUE); pr_ivec(log,0,"grid size",grids,DIM,TRUE); fflush(log); } gmx_fatal(FARGS,"Box sizes in tpb file and Ghat file %s do not match\n" "Check your log file!",ghatfn); } if (porder != 2) gmx_fatal(FARGS,"porder = %d, should be 2 in %s",porder,ghatfn); nx = grids[XX]; ny = grids[YY]; nz = grids[ZZ]; if (bVerbose) pr_scalar_gk("optimghat.xvg",oenv,nx,ny,nz,box_diag,ghat); } /* Now setup the FFT things */ #ifdef GMX_MPI cr->mpi_comm_mygroup=cr->mpi_comm_mysim; #endif grid = mk_fftgrid(nx,ny,nz,NULL,NULL,cr,bReproducible); return 0; #endif }