void do_nonbonded(t_commrec *cr,t_forcerec *fr, rvec x[],rvec f[],t_mdatoms *mdatoms,t_blocka *excl, real egnb[],real egcoul[],real egpol[],rvec box_size, t_nrnb *nrnb,real lambda,real *dvdlambda, int nls,int eNL,int flags) { gmx_bool bLR,bDoForces,bForeignLambda; t_nblist * nlist; real * fshift; int n,n0,n1,i,i0,i1,nrnb_ind,sz; t_nblists *nblists; gmx_bool bWater; nb_kernel_t * kernelptr; pf_nb_kernel_t *pf_kernelptr; FILE * fp; int fac=0; int nthreads = 1; int tabletype; int outeriter,inneriter; real * tabledata = NULL; gmx_gbdata_t gbdata; bLR = (flags & GMX_DONB_LR); bDoForces = (flags & GMX_DONB_FORCES); bForeignLambda = (flags & GMX_DONB_FOREIGNLAMBDA); gbdata.gb_epsilon_solvent = fr->gb_epsilon_solvent; gbdata.epsilon_r = fr->epsilon_r; gbdata.gpol = egpol; if(fr->bAllvsAll) { if(fr->bGB) { #if (defined GMX_SSE2 || defined GMX_X86_64_SSE || defined GMX_X86_64_SSE2 || defined GMX_IA32_SSE || defined GMX_IA32_SSE2) # ifdef GMX_DOUBLE if(fr->UseOptimizedKernels) { nb_kernel_allvsallgb_sse2_double(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsallgb(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } # else /* not double */ if(fr->UseOptimizedKernels) { nb_kernel_allvsallgb_sse2_single(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsallgb(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } # endif /* double/single alt. */ #else /* no SSE support compiled in */ nb_kernel_allvsallgb(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); #endif inc_nrnb(nrnb,eNR_NBKERNEL_ALLVSALLGB,inneriter); } else { #if (defined GMX_SSE2 || defined GMX_X86_64_SSE || defined GMX_X86_64_SSE2 || defined GMX_IA32_SSE || defined GMX_IA32_SSE2) # ifdef GMX_DOUBLE if(fr->UseOptimizedKernels) { nb_kernel_allvsall_sse2_double(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsall(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } # else /* not double */ if(fr->UseOptimizedKernels) { nb_kernel_allvsall_sse2_single(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsall(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } # endif /* double/single check */ #else /* No SSE2 support compiled in */ nb_kernel_allvsall(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); #endif inc_nrnb(nrnb,eNR_NBKERNEL_ALLVSALL,inneriter); } inc_nrnb(nrnb,eNR_NBKERNEL_OUTER,outeriter); return; } if (eNL >= 0) { i0 = eNL; i1 = i0+1; } else { i0 = 0; i1 = eNL_NR; } if (nls >= 0) { n0 = nls; n1 = nls+1; } else { n0 = 0; n1 = fr->nnblists; } if(nb_kernel_list == NULL) { gmx_fatal(FARGS,"gmx_setup_kernels has not been called"); } fshift = fr->fshift[0]; for(n=n0; (n<n1); n++) { nblists = &fr->nblists[n]; for(i=i0; (i<i1); i++) { outeriter = inneriter = 0; if (bLR) { nlist = &(nblists->nlist_lr[i]); } else { nlist = &(nblists->nlist_sr[i]); } if (nlist->nri > 0) { nrnb_ind = nlist->il_code; if(nrnb_ind==eNR_NBKERNEL_FREE_ENERGY) { /* generic free energy, use combined table */ tabledata = nblists->tab.tab; } else { if (bForeignLambda) { /* We don't need the non-perturbed interactions */ continue; } tabletype = nb_kernel_table[nrnb_ind]; /* normal kernels, not free energy */ if (!bDoForces) { nrnb_ind += eNR_NBKERNEL_NR/2; } if(tabletype == TABLE_COMBINED) { tabledata = nblists->tab.tab; } else if(tabletype == TABLE_COUL) { tabledata = nblists->coultab; } else if(tabletype == TABLE_VDW) { tabledata = nblists->vdwtab; } else { tabledata = NULL; } } nlist->count = 0; if(nlist->free_energy) { if(nlist->ivdw==2) { gmx_fatal(FARGS,"Cannot do free energy Buckingham interactions."); } gmx_nb_free_energy_kernel(nlist->icoul, nlist->ivdw, nlist->nri, nlist->iinr, nlist->jindex, nlist->jjnr, nlist->shift, fr->shift_vec[0], fshift, nlist->gid, x[0], f[0], mdatoms->chargeA, mdatoms->chargeB, fr->epsfac, fr->k_rf, fr->c_rf, fr->ewaldcoeff, egcoul, mdatoms->typeA, mdatoms->typeB, fr->ntype, fr->nbfp, egnb, nblists->tab.scale, tabledata, lambda, dvdlambda, fr->sc_alpha, fr->sc_power, fr->sc_sigma6_def, fr->sc_sigma6_min, bDoForces, &outeriter, &inneriter); } else if (nlist->enlist == enlistCG_CG) { /* Call the charge group based inner loop */ gmx_nb_generic_cg_kernel(nlist, fr, mdatoms, x[0], f[0], fshift, egcoul, egnb, nblists->tab.scale, tabledata, &outeriter, &inneriter); } else { /* Not free energy */ /* Pairwise forces between solute and solvent don't bring much information, as the molecules of solvent * move around. For this reason, only pairwise forces between solute atoms are calculated. * This allows the normal (non-pairwise force) kernels to be used for solute-solvent and solvent-solvent * interactions; the main reason is performance, as the normal kernels are not slowed down by the * checking whether atom is involved in an interesting interaction. */ if ((fr->pf_global) && (nlist->enlist == enlistATOM_ATOM)) { pf_kernelptr = pf_nb_kernel_list[nrnb_ind]; (*pf_kernelptr)( &(nlist->nri), nlist->iinr, nlist->jindex, nlist->jjnr, nlist->shift, fr->shift_vec[0], fshift, nlist->gid, x[0], f[0], mdatoms->chargeA, &(fr->epsfac), &(fr->k_rf), &(fr->c_rf), egcoul, mdatoms->typeA, &(fr->ntype), fr->nbfp, egnb, &(nblists->tab.scale), tabledata, fr->invsqrta, fr->dvda, &(fr->gbtabscale), fr->gbtab.tab, &nthreads, &(nlist->count), nlist->mtx, &outeriter, &inneriter, (real *)&gbdata, fr->pf_global); } else { /* non pairwise force kernel */ kernelptr = nb_kernel_list[nrnb_ind]; if (kernelptr == NULL) { /* Call a generic nonbonded kernel */ /* If you want to hack/test your own interactions, * do it in this routine and make sure it is called * by setting the environment variable GMX_NB_GENERIC. */ gmx_nb_generic_kernel(nlist, fr, mdatoms, x[0], f[0], fshift, egcoul, egnb, nblists->tab.scale, tabledata, &outeriter, &inneriter); } else { /* Call nonbonded kernel from function pointer */ (*kernelptr)( &(nlist->nri), nlist->iinr, nlist->jindex, nlist->jjnr, nlist->shift, fr->shift_vec[0], fshift, nlist->gid, x[0], f[0], mdatoms->chargeA, &(fr->epsfac), &(fr->k_rf), &(fr->c_rf), egcoul, mdatoms->typeA, &(fr->ntype), fr->nbfp, egnb, &(nblists->tab.scale), tabledata, fr->invsqrta, fr->dvda, &(fr->gbtabscale), fr->gbtab.tab, &nthreads, &(nlist->count), nlist->mtx, &outeriter, &inneriter, (real *)&gbdata); } /* end of non pairwise force kernel */ } } /* Update flop accounting */ /* Outer loop in kernel */ switch (nlist->enlist) { case enlistATOM_ATOM: fac = 1; break; case enlistSPC_ATOM: fac = 3; break; case enlistSPC_SPC: fac = 9; break; case enlistTIP4P_ATOM: fac = 4; break; case enlistTIP4P_TIP4P: fac = 16; break; case enlistCG_CG: fac = 1; break; } inc_nrnb(nrnb,eNR_NBKERNEL_OUTER,fac*outeriter); /* inner loop in kernel */ inc_nrnb(nrnb,nrnb_ind,inneriter); } } } }
void do_nonbonded(t_commrec *cr,t_forcerec *fr, rvec x[],rvec f[],t_mdatoms *mdatoms,t_blocka *excl, real egnb[],real egcoul[],real egpol[],rvec box_size, t_nrnb *nrnb,real lambda,real *dvdlambda, int nls,int eNL,int flags) { gmx_bool bLR,bDoForces,bForeignLambda; t_nblist * nlist; real * fshift; int n,n0,n1,i,i0,i1,nrnb_ind,sz; t_nblists *nblists; gmx_bool bWater; FILE * fp; int fac=0; int nthreads = 1; int tabletype; int outeriter,inneriter; real * tabledata = NULL; gmx_gbdata_t gbdata; nb_kernel_t *kernelptr=NULL; nb_adress_kernel_t *adresskernelptr=NULL; gmx_bool bCG; /* for AdresS */ int k;/* for AdresS */ bLR = (flags & GMX_DONB_LR); bDoForces = (flags & GMX_DONB_FORCES); bForeignLambda = (flags & GMX_DONB_FOREIGNLAMBDA); bCG = FALSE; /* for AdresS */ gbdata.gb_epsilon_solvent = fr->gb_epsilon_solvent; gbdata.epsilon_r = fr->epsilon_r; gbdata.gpol = egpol; if (!fr->adress_type==eAdressOff && !bDoForces){ gmx_fatal(FARGS,"No force kernels not implemeted for adress"); } if(fr->bAllvsAll) { if(fr->bGB) { #if (defined GMX_SSE2 || defined GMX_X86_64_SSE || defined GMX_X86_64_SSE2 || defined GMX_IA32_SSE || defined GMX_IA32_SSE2) # ifdef GMX_DOUBLE if(fr->UseOptimizedKernels) { nb_kernel_allvsallgb_sse2_double(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsallgb(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } # else /* not double */ if(fr->UseOptimizedKernels) { nb_kernel_allvsallgb_sse2_single(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsallgb(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } # endif /* double/single alt. */ #else /* no SSE support compiled in */ nb_kernel_allvsallgb(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); #endif inc_nrnb(nrnb,eNR_NBKERNEL_ALLVSALLGB,inneriter); } else { #if (defined GMX_SSE2 || defined GMX_X86_64_SSE || defined GMX_X86_64_SSE2 || defined GMX_IA32_SSE || defined GMX_IA32_SSE2) # ifdef GMX_DOUBLE if(fr->UseOptimizedKernels) { nb_kernel_allvsall_sse2_double(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsall(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } # else /* not double */ if(fr->UseOptimizedKernels) { nb_kernel_allvsall_sse2_single(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsall(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } # endif /* double/single check */ #else /* No SSE2 support compiled in */ nb_kernel_allvsall(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); #endif inc_nrnb(nrnb,eNR_NBKERNEL_ALLVSALL,inneriter); } inc_nrnb(nrnb,eNR_NBKERNEL_OUTER,outeriter); return; } if (eNL >= 0) { i0 = eNL; i1 = i0+1; } else { i0 = 0; i1 = eNL_NR; } if (nls >= 0) { n0 = nls; n1 = nls+1; } else { n0 = 0; n1 = fr->nnblists; } if(nb_kernel_list == NULL) { gmx_fatal(FARGS,"gmx_setup_kernels has not been called"); } fshift = fr->fshift[0]; for(n=n0; (n<n1); n++) { nblists = &fr->nblists[n]; for(i=i0; (i<i1); i++) { outeriter = inneriter = 0; if (bLR) { nlist = &(nblists->nlist_lr[i]); } else { nlist = &(nblists->nlist_sr[i]); } if (nlist->nri > 0) { nrnb_ind = nlist->il_code; if(nrnb_ind==eNR_NBKERNEL_FREE_ENERGY) { /* generic free energy, use combined table */ tabledata = nblists->tab.tab; } else { if (bForeignLambda) { /* We don't need the non-perturbed interactions */ continue; } tabletype = nb_kernel_table[nrnb_ind]; /* normal kernels, not free energy */ if (!bDoForces) { nrnb_ind += eNR_NBKERNEL_NR/2; } if(tabletype == TABLE_COMBINED) { tabledata = nblists->tab.tab; } else if(tabletype == TABLE_COUL) { tabledata = nblists->coultab; } else if(tabletype == TABLE_VDW) { tabledata = nblists->vdwtab; } else { tabledata = NULL; } } nlist->count = 0; if(nlist->free_energy) { if(nlist->ivdw==2) { gmx_fatal(FARGS,"Cannot do free energy Buckingham interactions."); } gmx_nb_free_energy_kernel(nlist->icoul, nlist->ivdw, nlist->nri, nlist->iinr, nlist->jindex, nlist->jjnr, nlist->shift, fr->shift_vec[0], fshift, nlist->gid, x[0], f[0], mdatoms->chargeA, mdatoms->chargeB, fr->epsfac, fr->k_rf, fr->c_rf, fr->ewaldcoeff, egcoul, mdatoms->typeA, mdatoms->typeB, fr->ntype, fr->nbfp, egnb, nblists->tab.scale, tabledata, lambda, dvdlambda, fr->sc_alpha, fr->sc_power, fr->sc_sigma6_def, fr->sc_sigma6_min, bDoForces, &outeriter, &inneriter); } else if (nlist->enlist == enlistCG_CG) { if (fr->adress_type==eAdressOff){ /* Call the charge group based inner loop */ gmx_nb_generic_cg_kernel(nlist, fr, mdatoms, x[0], f[0], fshift, egcoul, egnb, nblists->tab.scale, tabledata, &outeriter, &inneriter); } else { /*gmx_nb_generic_adress_kernel(nlist, fr, mdatoms, x[0], f[0], fshift, egcoul, egnb, nblists->tab.scale, tabledata, &outeriter, &inneriter);*/ gmx_fatal(FARGS,"Death & horror! Adress cgcg kernel not implemented anymore.\n"); } } else { /* AdresS*/ /* for adress we need to determine for each energy group wether it is explicit or coarse-grained */ if (!fr->adress_type == eAdressOff) { bCG = FALSE; if ( !fr->adress_group_explicit[ mdatoms->cENER[nlist->iinr[0]] ] ){ bCG=TRUE; } /* If this processor has only explicit atoms (w=1) skip the coarse grained force calculation. Same for only coarsegrained atoms and explicit interactions. Last condition is to make sure that generic kernel is not skipped*/ if (mdatoms->pureex && bCG && nb_kernel_list[nrnb_ind] != NULL) continue; if (mdatoms->purecg && !bCG && nb_kernel_list[nrnb_ind] != NULL) continue; } if (fr->adress_type == eAdressOff || mdatoms->pureex || mdatoms->purecg){ /* if we only have to calculate pure cg/ex interactions we can use the faster standard gromacs kernels*/ kernelptr = nb_kernel_list[nrnb_ind]; }else{ /* This processor has hybrid interactions which means * we have to * use our own kernels. We have two kernel types: one that * calculates the forces with the explicit prefactor w1*w2 * and one for coarse-grained with (1-w1*w2) * explicit kernels are the second part of the kernel * list */ if (!bCG) nrnb_ind += eNR_NBKERNEL_NR/2; adresskernelptr = nb_kernel_list_adress[nrnb_ind]; } if (kernelptr == NULL && adresskernelptr == NULL) { /* Call a generic nonbonded kernel */ /* If you want to hack/test your own interactions, * do it in this routine and make sure it is called * by setting the environment variable GMX_NB_GENERIC. */ if (fr->adress_type==eAdressOff){ gmx_nb_generic_kernel(nlist, fr, mdatoms, x[0], f[0], fshift, egcoul, egnb, nblists->tab.scale, tabledata, &outeriter, &inneriter); }else /* do generic AdResS kernels (slow)*/ { gmx_nb_generic_adress_kernel(nlist, fr, mdatoms, x[0], f[0], fshift, egcoul, egnb, nblists->tab.scale, tabledata, &outeriter, &inneriter, bCG); } } else { /* Call nonbonded kernel from function pointer */ if (kernelptr!=NULL){ (*kernelptr)( &(nlist->nri), nlist->iinr, nlist->jindex, nlist->jjnr, nlist->shift, fr->shift_vec[0], fshift, nlist->gid, x[0], f[0], mdatoms->chargeA, &(fr->epsfac), &(fr->k_rf), &(fr->c_rf), egcoul, mdatoms->typeA, &(fr->ntype), fr->nbfp, egnb, &(nblists->tab.scale), tabledata, fr->invsqrta, fr->dvda, &(fr->gbtabscale), fr->gbtab.tab, &nthreads, &(nlist->count), nlist->mtx, &outeriter, &inneriter, (real *)&gbdata); }else if (adresskernelptr != NULL) { /* Adress kernels */ (*adresskernelptr)( &(nlist->nri), nlist->iinr, nlist->jindex, nlist->jjnr, nlist->shift, fr->shift_vec[0], fshift, nlist->gid, x[0], f[0], mdatoms->chargeA, &(fr->epsfac), &(fr->k_rf), &(fr->c_rf), egcoul, mdatoms->typeA, &(fr->ntype), fr->nbfp, egnb, &(nblists->tab.scale), tabledata, fr->invsqrta, fr->dvda, &(fr->gbtabscale), fr->gbtab.tab, &nthreads, &(nlist->count), nlist->mtx, &outeriter, &inneriter, fr->adress_ex_forcecap, mdatoms->wf); } } } /* Update flop accounting */ /* Outer loop in kernel */ switch (nlist->enlist) { case enlistATOM_ATOM: fac = 1; break; case enlistSPC_ATOM: fac = 3; break; case enlistSPC_SPC: fac = 9; break; case enlistTIP4P_ATOM: fac = 4; break; case enlistTIP4P_TIP4P: fac = 16; break; case enlistCG_CG: fac = 1; break; } inc_nrnb(nrnb,eNR_NBKERNEL_OUTER,fac*outeriter); /* inner loop in kernel */ inc_nrnb(nrnb,nrnb_ind,inneriter); } } } }