float pme_load_estimate(gmx_mtop_t *mtop,t_inputrec *ir,matrix box) { t_atom *atom; int mb,nmol,atnr,cg,a,a0,nq_tot; gmx_bool bBHAM,bLJcut,bChargePerturbed,bWater,bQ,bLJ; double cost_bond,cost_pp,cost_redist,cost_spread,cost_fft,cost_solve,cost_pme; float ratio; t_iparams *iparams; gmx_moltype_t *molt; /* Computational cost of bonded, non-bonded and PME calculations. * This will be machine dependent. * The numbers here are accurate for Intel Core2 and AMD Athlon 64 * in single precision. In double precision PME mesh is slightly cheaper, * although not so much that the numbers need to be adjusted. */ iparams = mtop->ffparams.iparams; atnr = mtop->ffparams.atnr; cost_bond = C_BOND*n_bonded_dx(mtop,TRUE); if (ir->cutoff_scheme == ecutsGROUP) { pp_group_load(mtop,ir,box,&nq_tot,&cost_pp,&bChargePerturbed); } else { pp_verlet_load(mtop,ir,box,&nq_tot,&cost_pp,&bChargePerturbed); } cost_redist = C_PME_REDIST*nq_tot; cost_spread = C_PME_SPREAD*nq_tot*pow(ir->pme_order,3); cost_fft = C_PME_FFT*ir->nkx*ir->nky*ir->nkz*log(ir->nkx*ir->nky*ir->nkz); cost_solve = C_PME_SOLVE*ir->nkx*ir->nky*ir->nkz; if (ir->efep != efepNO && bChargePerturbed) { /* All PME work, except redist & spline coefficient calculation, doubles */ cost_spread *= 2; cost_fft *= 2; cost_solve *= 2; } cost_pme = cost_redist + cost_spread + cost_fft + cost_solve; ratio = cost_pme/(cost_bond + cost_pp + cost_pme); if (debug) { fprintf(debug, "cost_bond %f\n" "cost_pp %f\n" "cost_redist %f\n" "cost_spread %f\n" "cost_fft %f\n" "cost_solve %f\n", cost_bond,cost_pp,cost_redist,cost_spread,cost_fft,cost_solve); fprintf(debug,"Estimate for relative PME load: %.3f\n",ratio); } return ratio; }
float pme_load_estimate(gmx_mtop_t *mtop, t_inputrec *ir, matrix box) { t_atom *atom; int mb, nmol, atnr, cg, a, a0, nq_tot, nlj_tot, f; gmx_bool bBHAM, bLJcut, bChargePerturbed, bTypePerturbed; gmx_bool bWater, bQ, bLJ; double ndistance_c, ndistance_simd; double cost_bond, cost_pp, cost_redist, cost_spread, cost_fft, cost_solve, cost_pme; float ratio; t_iparams *iparams; gmx_moltype_t *molt; /* Computational cost of bonded, non-bonded and PME calculations. * This will be machine dependent. * The numbers here are accurate for Intel Core2 and AMD Athlon 64 * in single precision. In double precision PME mesh is slightly cheaper, * although not so much that the numbers need to be adjusted. */ iparams = mtop->ffparams.iparams; atnr = mtop->ffparams.atnr; count_bonded_distances(mtop, ir, &ndistance_c, &ndistance_simd); /* C_BOND is the cost for bonded interactions with SIMD implementations, * so we need to scale the number of bonded interactions for which there * are only C implementations to the number of SIMD equivalents. */ cost_bond = c_bond*(ndistance_c *simd_cycle_factor(FALSE) + ndistance_simd*simd_cycle_factor(bHaveSIMD)); if (ir->cutoff_scheme == ecutsGROUP) { pp_group_load(mtop, ir, box, &nq_tot, &nlj_tot, &cost_pp, &bChargePerturbed, &bTypePerturbed); } else { pp_verlet_load(mtop, ir, box, &nq_tot, &nlj_tot, &cost_pp, &bChargePerturbed, &bTypePerturbed); } cost_redist = 0; cost_spread = 0; cost_fft = 0; cost_solve = 0; if (EEL_PME(ir->coulombtype)) { double grid = ir->nkx*ir->nky*((ir->nkz + 1)/2); f = ((ir->efep != efepNO && bChargePerturbed) ? 2 : 1); cost_redist += c_pme_redist*nq_tot; cost_spread += f*c_pme_spread*nq_tot*pow(ir->pme_order, 3); cost_fft += f*c_pme_fft*grid*log(grid)/log(2); cost_solve += f*c_pme_solve*grid*simd_cycle_factor(bHaveSIMD); } if (EVDW_PME(ir->vdwtype)) { double grid = ir->nkx*ir->nky*((ir->nkz + 1)/2); f = ((ir->efep != efepNO && bTypePerturbed) ? 2 : 1); if (ir->ljpme_combination_rule == eljpmeLB) { /* LB combination rule: we have 7 mesh terms */ f *= 7; } cost_redist += c_pme_redist*nlj_tot; cost_spread += f*c_pme_spread*nlj_tot*pow(ir->pme_order, 3); cost_fft += f*c_pme_fft*2*grid*log(grid)/log(2); cost_solve += f*c_pme_solve*grid*simd_cycle_factor(bHaveSIMD); } cost_pme = cost_redist + cost_spread + cost_fft + cost_solve; ratio = cost_pme/(cost_bond + cost_pp + cost_pme); if (debug) { fprintf(debug, "cost_bond %f\n" "cost_pp %f\n" "cost_redist %f\n" "cost_spread %f\n" "cost_fft %f\n" "cost_solve %f\n", cost_bond, cost_pp, cost_redist, cost_spread, cost_fft, cost_solve); fprintf(debug, "Estimate for relative PME load: %.3f\n", ratio); } return ratio; }
float pme_load_estimate(const gmx_mtop_t *mtop, const t_inputrec *ir, matrix box) { int nq_tot, nlj_tot, f; gmx_bool bChargePerturbed, bTypePerturbed; double cost_bond, cost_pp, cost_redist, cost_spread, cost_fft, cost_solve, cost_pme; float ratio; /* Computational cost of bonded, non-bonded and PME calculations. * This will be machine dependent. * The numbers here are accurate for Intel Core2 and AMD Athlon 64 * in single precision. In double precision PME mesh is slightly cheaper, * although not so much that the numbers need to be adjusted. */ cost_bond = C_BOND*n_bonded_dx(mtop, TRUE); if (ir->cutoff_scheme == ecutsGROUP) { pp_group_load(mtop, ir, box, &nq_tot, &nlj_tot, &cost_pp, &bChargePerturbed, &bTypePerturbed); } else { pp_verlet_load(mtop, ir, box, &nq_tot, &nlj_tot, &cost_pp, &bChargePerturbed, &bTypePerturbed); } cost_redist = 0; cost_spread = 0; cost_fft = 0; cost_solve = 0; if (EEL_PME(ir->coulombtype)) { f = ((ir->efep != efepNO && bChargePerturbed) ? 2 : 1); cost_redist += C_PME_REDIST*nq_tot; cost_spread += f*C_PME_SPREAD*nq_tot*std::pow(static_cast<real>(ir->pme_order), static_cast<real>(3.0)); cost_fft += f*C_PME_FFT*ir->nkx*ir->nky*ir->nkz*std::log(static_cast<real>(ir->nkx*ir->nky*ir->nkz)); cost_solve += f*C_PME_SOLVE*ir->nkx*ir->nky*ir->nkz; } if (EVDW_PME(ir->vdwtype)) { f = ((ir->efep != efepNO && bTypePerturbed) ? 2 : 1); if (ir->ljpme_combination_rule == eljpmeLB) { /* LB combination rule: we have 7 mesh terms */ f *= 7; } cost_redist += C_PME_REDIST*nlj_tot; cost_spread += f*C_PME_SPREAD*nlj_tot*std::pow(static_cast<real>(ir->pme_order), static_cast<real>(3.0)); cost_fft += f*C_PME_FFT*ir->nkx*ir->nky*ir->nkz*std::log(static_cast<real>(ir->nkx*ir->nky*ir->nkz)); cost_solve += f*C_PME_SOLVE*ir->nkx*ir->nky*ir->nkz; } cost_pme = cost_redist + cost_spread + cost_fft + cost_solve; ratio = cost_pme/(cost_bond + cost_pp + cost_pme); if (debug) { fprintf(debug, "cost_bond %f\n" "cost_pp %f\n" "cost_redist %f\n" "cost_spread %f\n" "cost_fft %f\n" "cost_solve %f\n", cost_bond, cost_pp, cost_redist, cost_spread, cost_fft, cost_solve); fprintf(debug, "Estimate for relative PME load: %.3f\n", ratio); } return ratio; }