void count_bonded_distances(gmx_mtop_t *mtop, const t_inputrec *ir, double *ndistance_c, double *ndistance_simd) { gmx_bool bExcl; int nst_ener_or_vir; double nonsimd_step_frac; int mb, nmol, ftype; gmx_moltype_t *molt; double ndtot_c, ndtot_simd; #ifdef GMX_SIMD_HAVE_REAL gmx_bool bSimdBondeds = TRUE; #else gmx_bool bSimdBondeds = FALSE; #endif bExcl = (ir->cutoff_scheme == ecutsGROUP && IR_EXCL_FORCES(*ir) && !EEL_FULL(ir->coulombtype)); if (bSimdBondeds) { /* We only have SIMD versions of these bondeds without energy and * without shift-forces, we take that into account here. */ if (ir->nstcalcenergy > 0) { nonsimd_step_frac = 1.0/ir->nstcalcenergy; } else { nonsimd_step_frac = 0; } if (ir->epc != epcNO && 1.0/ir->nstpcouple > nonsimd_step_frac) { nonsimd_step_frac = 1.0/ir->nstpcouple; } } else { nonsimd_step_frac = 1; } /* Count the number of pbc_rvec_sub calls required for bonded interactions. * This number is also roughly proportional to the computational cost. */ ndtot_c = 0; ndtot_simd = 0; #if defined _ICC && __ICC == 1400 || defined __ICL && __ICL == 1400 #pragma novector /* Work-around for incorrect vectorization */ #endif for (mb = 0; mb < mtop->nmolblock; mb++) { molt = &mtop->moltype[mtop->molblock[mb].type]; nmol = mtop->molblock[mb].nmol; for (ftype = 0; ftype < F_NRE; ftype++) { int nbonds; if (interaction_function[ftype].flags & IF_BOND) { double nd_c, nd_simd; nd_c = 0; nd_simd = 0; /* For all interactions, except for the three exceptions * in the switch below, #distances = #atoms - 1. */ switch (ftype) { case F_POSRES: case F_FBPOSRES: nd_c = 1; break; case F_CONNBONDS: break; /* These bonded potentially use SIMD */ case F_ANGLES: case F_PDIHS: case F_RBDIHS: nd_c = nonsimd_step_frac *(NRAL(ftype) - 1); nd_simd = (1 - nonsimd_step_frac)*(NRAL(ftype) - 1); break; default: nd_c = NRAL(ftype) - 1; break; } nbonds = nmol*molt->ilist[ftype].nr/(1 + NRAL(ftype)); ndtot_c += nbonds*nd_c; ndtot_simd += nbonds*nd_simd; } } if (bExcl) { ndtot_c += nmol*(molt->excls.nra - molt->atoms.nr)/2; } } if (debug) { fprintf(debug, "nr. of distance calculations in bondeds: C %.1f SIMD %.1f\n", ndtot_c, ndtot_simd); } if (ndistance_c != NULL) { *ndistance_c = ndtot_c; } if (ndistance_simd != NULL) { *ndistance_simd = ndtot_simd; } }
static real optimize_ncells(FILE *fplog, int nnodes_tot,int npme_only, gmx_bool bDynLoadBal,real dlb_scale, gmx_mtop_t *mtop,matrix box,gmx_ddbox_t *ddbox, t_inputrec *ir, gmx_domdec_t *dd, real cellsize_limit,real cutoff, gmx_bool bInterCGBondeds,gmx_bool bInterCGMultiBody, ivec nc) { int npp,npme,ndiv,*div,*mdiv,d,nmax; gmx_bool bExcl_pbcdx; float pbcdxr; real limit; ivec itry; limit = cellsize_limit; dd->nc[XX] = 1; dd->nc[YY] = 1; dd->nc[ZZ] = 1; npp = nnodes_tot - npme_only; if (EEL_PME(ir->coulombtype)) { npme = (npme_only > 0 ? npme_only : npp); } else { npme = 0; } if (bInterCGBondeds) { /* For Ewald exclusions pbc_dx is not called */ bExcl_pbcdx = (IR_EXCL_FORCES(*ir) && !EEL_FULL(ir->coulombtype)); pbcdxr = (double)n_bonded_dx(mtop,bExcl_pbcdx)/(double)mtop->natoms; } else { /* Every molecule is a single charge group: no pbc required */ pbcdxr = 0; } /* Add a margin for DLB and/or pressure scaling */ if (bDynLoadBal) { if (dlb_scale >= 1.0) { gmx_fatal(FARGS,"The value for option -dds should be smaller than 1"); } if (fplog) { fprintf(fplog,"Scaling the initial minimum size with 1/%g (option -dds) = %g\n",dlb_scale,1/dlb_scale); } limit /= dlb_scale; } else if (ir->epc != epcNO) { if (fplog) { fprintf(fplog,"To account for pressure scaling, scaling the initial minimum size with %g\n",DD_GRID_MARGIN_PRES_SCALE); limit *= DD_GRID_MARGIN_PRES_SCALE; } } if (fplog) { fprintf(fplog,"Optimizing the DD grid for %d cells with a minimum initial size of %.3f nm\n",npp,limit); if (inhomogeneous_z(ir)) { fprintf(fplog,"Ewald_geometry=%s: assuming inhomogeneous particle distribution in z, will not decompose in z.\n",eewg_names[ir->ewald_geometry]); } if (limit > 0) { fprintf(fplog,"The maximum allowed number of cells is:"); for(d=0; d<DIM; d++) { nmax = (int)(ddbox->box_size[d]*ddbox->skew_fac[d]/limit); if (d >= ddbox->npbcdim && nmax < 2) { nmax = 2; } if (d == ZZ && inhomogeneous_z(ir)) { nmax = 1; } fprintf(fplog," %c %d",'X' + d,nmax); } fprintf(fplog,"\n"); } } if (debug) { fprintf(debug,"Average nr of pbc_dx calls per atom %.2f\n",pbcdxr); } /* Decompose npp in factors */ ndiv = factorize(npp,&div,&mdiv); itry[XX] = 1; itry[YY] = 1; itry[ZZ] = 1; clear_ivec(nc); assign_factors(dd,limit,cutoff,box,ddbox,mtop->natoms,ir,pbcdxr, npme,ndiv,div,mdiv,itry,nc); sfree(div); sfree(mdiv); return limit; }