From 4d90a922ad47dfdbf62117bb04decde615172e1e Mon Sep 17 00:00:00 2001 From: Berk Hess Date: Wed, 4 Dec 2019 13:50:42 +0100 Subject: [PATCH] Move nr_nonperturbed out of t_ilist The member nr_nonperturbed of t_ilist is only used in a few places and fits better in t_idef. This is also needed for refactoring of idef and t_ilist that will follow. Change-Id: I921e06497d341a98530d7950f2393c19d0a350cb --- src/gromacs/listed_forces/gpubonded_impl.cu | 2 +- src/gromacs/listed_forces/listed_forces.cpp | 53 +++++++++++-------- .../listed_forces/manage_threading.cpp | 2 +- src/gromacs/mdlib/tests/settletestdata.cpp | 3 +- src/gromacs/topology/idef.cpp | 17 +++--- src/gromacs/topology/idef.h | 5 +- src/gromacs/topology/topsort.cpp | 5 +- 7 files changed, 47 insertions(+), 40 deletions(-) diff --git a/src/gromacs/listed_forces/gpubonded_impl.cu b/src/gromacs/listed_forces/gpubonded_impl.cu index 041ee514b7..ba983faeb1 100644 --- a/src/gromacs/listed_forces/gpubonded_impl.cu +++ b/src/gromacs/listed_forces/gpubonded_impl.cu @@ -120,7 +120,7 @@ static bool fTypeHasPerturbedEntries(const t_idef& idef, int fType) const t_ilist& ilist = idef.il[fType]; - return (idef.ilsort != ilsortNO_FE && ilist.nr_nonperturbed != ilist.nr); + return (idef.ilsort != ilsortNO_FE && idef.numNonperturbedInteractions[fType] != ilist.nr); } //! Converts \p src with atom indices in state order to \p dest in nbnxn order diff --git a/src/gromacs/listed_forces/listed_forces.cpp b/src/gromacs/listed_forces/listed_forces.cpp index 4b46781c2e..4e1533ae1e 100644 --- a/src/gromacs/listed_forces/listed_forces.cpp +++ b/src/gromacs/listed_forces/listed_forces.cpp @@ -80,6 +80,8 @@ namespace { +using gmx::ArrayRef; + /*! \brief Return true if ftype is an explicit pair-listed LJ or * COULOMB interaction type: bonded LJ (usually 1-4), or special * listed non-bonded for FEP. */ @@ -298,6 +300,8 @@ BondedKernelFlavor selectBondedKernelFlavor(const gmx::StepWorkload& stepWork, real calc_one_bond(int thread, int ftype, const t_idef* idef, + ArrayRef iatoms, + const int numNonperturbedInteractions, const WorkDivision& workDivision, const rvec x[], rvec4 f[], @@ -318,7 +322,7 @@ real calc_one_bond(int thread, "The topology should be marked either as no FE or sorted on FE"); const bool havePerturbedInteractions = - (idef->ilsort == ilsortFE_SORTED && idef->il[ftype].nr_nonperturbed < idef->il[ftype].nr); + (idef->ilsort == ilsortFE_SORTED && numNonperturbedInteractions < iatoms.ssize()); BondedKernelFlavor flavor = selectBondedKernelFlavor(stepWork, fr->use_simd_kernels, havePerturbedInteractions); int efptFTYPE; @@ -331,11 +335,10 @@ real calc_one_bond(int thread, efptFTYPE = efptBONDED; } - const int nat1 = interaction_function[ftype].nratoms + 1; - const int nbonds = idef->il[ftype].nr / nat1; - const t_iatom* iatoms = idef->il[ftype].iatoms; + const int nat1 = interaction_function[ftype].nratoms + 1; + const int nbonds = iatoms.ssize() / nat1; - GMX_ASSERT(fr->gpuBonded != nullptr || workDivision.end(ftype) == idef->il[ftype].nr, + GMX_ASSERT(fr->gpuBonded != nullptr || workDivision.end(ftype) == iatoms.ssize(), "The thread division should match the topology"); const int nb0 = workDivision.bound(ftype, thread); @@ -350,13 +353,13 @@ real calc_one_bond(int thread, nice to account to its own subtimer, but first wallcycle needs to be extended to support calling from multiple threads. */ - v = cmap_dihs(nbn, iatoms + nb0, idef->iparams, idef->cmap_grid, x, f, fshift, pbc, g, - lambda[efptFTYPE], &(dvdl[efptFTYPE]), md, fcd, global_atom_index); + v = cmap_dihs(nbn, iatoms.data() + nb0, idef->iparams, idef->cmap_grid, x, f, fshift, + pbc, g, lambda[efptFTYPE], &(dvdl[efptFTYPE]), md, fcd, global_atom_index); } else { - v = calculateSimpleBond(ftype, nbn, iatoms + nb0, idef->iparams, x, f, fshift, pbc, g, - lambda[efptFTYPE], &(dvdl[efptFTYPE]), md, fcd, + v = calculateSimpleBond(ftype, nbn, iatoms.data() + nb0, idef->iparams, x, f, fshift, + pbc, g, lambda[efptFTYPE], &(dvdl[efptFTYPE]), md, fcd, global_atom_index, flavor); } } @@ -365,8 +368,8 @@ real calc_one_bond(int thread, /* TODO The execution time for pairs might be nice to account to its own subtimer, but first wallcycle needs to be extended to support calling from multiple threads. */ - do_pairs(ftype, nbn, iatoms + nb0, idef->iparams, x, f, fshift, pbc, g, lambda, dvdl, md, - fr, havePerturbedInteractions, stepWork, grpp, global_atom_index); + do_pairs(ftype, nbn, iatoms.data() + nb0, idef->iparams, x, f, fshift, pbc, g, lambda, dvdl, + md, fr, havePerturbedInteractions, stepWork, grpp, global_atom_index); } if (thread == 0) @@ -435,11 +438,14 @@ static void calcBondedForces(const t_idef* idef, /* Loop over all bonded force types to calculate the bonded forces */ for (ftype = 0; (ftype < F_NRE); ftype++) { - if (idef->il[ftype].nr > 0 && ftype_is_bonded_potential(ftype)) + const t_ilist& ilist = idef->il[ftype]; + if (ilist.nr > 0 && ftype_is_bonded_potential(ftype)) { - v = calc_one_bond(thread, ftype, idef, fr->bondedThreading->workDivision, x, ft, - fshift, fr, pbc_null, g, grpp, nrnb, lambda, dvdlt, md, fcd, - stepWork, global_atom_index); + ArrayRef iatoms = gmx::constArrayRefFromArray(ilist.iatoms, ilist.nr); + v = calc_one_bond( + thread, ftype, idef, iatoms, idef->numNonperturbedInteractions[ftype], + fr->bondedThreading->workDivision, x, ft, fshift, fr, pbc_null, g, grpp, + nrnb, lambda, dvdlt, md, fcd, stepWork, global_atom_index); epot[ftype] += v; } } @@ -615,21 +621,22 @@ void calc_listed_lambda(const t_idef* idef, if (ftype_is_bonded_potential(ftype)) { const t_ilist& ilist = idef->il[ftype]; - /* Create a temporary t_ilist with only perturbed interactions */ - t_ilist& ilist_fe = idef_fe.il[ftype]; - ilist_fe.iatoms = ilist.iatoms + ilist.nr_nonperturbed; - ilist_fe.nr_nonperturbed = 0; - ilist_fe.nr = ilist.nr - ilist.nr_nonperturbed; + /* Create a temporary iatom list with only perturbed interactions */ + const int numNonperturbed = idef->numNonperturbedInteractions[ftype]; + ArrayRef iatoms = gmx::constArrayRefFromArray(ilist.iatoms + numNonperturbed, + ilist.nr - numNonperturbed); + t_ilist& ilist_fe = idef_fe.il[ftype]; /* Set the work range of thread 0 to the perturbed bondeds */ workDivision.setBound(ftype, 0, 0); - workDivision.setBound(ftype, 1, ilist_fe.nr); + workDivision.setBound(ftype, 1, iatoms.ssize()); if (ilist_fe.nr > 0) { gmx::StepWorkload tempFlags; tempFlags.computeEnergy = true; - v = calc_one_bond(0, ftype, &idef_fe, workDivision, x, f, fshift, fr, pbc_null, g, - grpp, nrnb, lambda, dvdl_dum, md, fcd, tempFlags, global_atom_index); + v = calc_one_bond(0, ftype, idef, iatoms, iatoms.ssize(), workDivision, x, f, + fshift, fr, pbc_null, g, grpp, nrnb, lambda, dvdl_dum, md, fcd, + tempFlags, global_atom_index); epot[ftype] += v; } } diff --git a/src/gromacs/listed_forces/manage_threading.cpp b/src/gromacs/listed_forces/manage_threading.cpp index f8d4ff0584..b696861250 100644 --- a/src/gromacs/listed_forces/manage_threading.cpp +++ b/src/gromacs/listed_forces/manage_threading.cpp @@ -196,7 +196,7 @@ static bool ftypeHasPerturbedEntries(const t_idef& idef, int ftype) const t_ilist& ilist = idef.il[ftype]; - return (idef.ilsort != ilsortNO_FE && ilist.nr_nonperturbed != ilist.nr); + return (idef.ilsort != ilsortNO_FE && idef.numNonperturbedInteractions[ftype] != ilist.nr); } //! Divides bonded interactions over threads and GPU diff --git a/src/gromacs/mdlib/tests/settletestdata.cpp b/src/gromacs/mdlib/tests/settletestdata.cpp index 8feab2e0a0..4cea8e864a 100644 --- a/src/gromacs/mdlib/tests/settletestdata.cpp +++ b/src/gromacs/mdlib/tests/settletestdata.cpp @@ -139,8 +139,7 @@ SettleTestData::SettleTestData(int numSettles) : } // Reshape some data so it can be directly used by the SETTLE constraints - ilist_ = { mtop_.moltype[0].ilist[F_SETTLE].size(), 0, - mtop_.moltype[0].ilist[F_SETTLE].iatoms.data(), 0 }; + ilist_ = { mtop_.moltype[0].ilist[F_SETTLE].size(), mtop_.moltype[0].ilist[F_SETTLE].iatoms.data(), 0 }; idef_.il[F_SETTLE] = ilist_; } diff --git a/src/gromacs/topology/idef.cpp b/src/gromacs/topology/idef.cpp index ef3f17e837..b438c3583d 100644 --- a/src/gromacs/topology/idef.cpp +++ b/src/gromacs/topology/idef.cpp @@ -411,15 +411,15 @@ void init_idef(t_idef* idef) idef->iparams_fbposres = nullptr; for (int f = 0; f < F_NRE; ++f) { - idef->il[f].iatoms = nullptr; - idef->il[f].nalloc = 0; - idef->il[f].nr = 0; - idef->il[f].nr_nonperturbed = 0; + idef->il[f].iatoms = nullptr; + idef->il[f].nalloc = 0; + idef->il[f].nr = 0; + idef->numNonperturbedInteractions[f] = 0; } idef->cmap_grid = nullptr; idef->iparams_posres_nalloc = 0; idef->iparams_fbposres_nalloc = 0; - idef->ilsort = 0; + idef->ilsort = ilsortUNKNOWN; } void done_idef(t_idef* idef) @@ -439,11 +439,10 @@ void done_idef(t_idef* idef) void copy_ilist(const t_ilist* src, t_ilist* dst) { - dst->nr = src->nr; - dst->nr_nonperturbed = src->nr_nonperturbed; - dst->nalloc = src->nalloc; + dst->nr = src->nr; + dst->nalloc = src->nr; - snew(dst->iatoms, dst->nr); + snew(dst->iatoms, dst->nalloc); for (int i = 0; i < dst->nr; ++i) { dst->iatoms[i] = src->iatoms[i]; diff --git a/src/gromacs/topology/idef.h b/src/gromacs/topology/idef.h index 15c010e286..269d531fc0 100644 --- a/src/gromacs/topology/idef.h +++ b/src/gromacs/topology/idef.h @@ -244,7 +244,6 @@ struct t_ilist int size() const { return nr; } int nr; - int nr_nonperturbed; t_iatom* iatoms; int nalloc; }; @@ -345,7 +344,9 @@ typedef struct t_idef int iparams_posres_nalloc, iparams_fbposres_nalloc; t_ilist il[F_NRE]; - int ilsort; + /* The number of non-perturbed interactions at the start of each entry in il */ + int numNonperturbedInteractions[F_NRE]; + int ilsort; } t_idef; /* diff --git a/src/gromacs/topology/topsort.cpp b/src/gromacs/topology/topsort.cpp index cf7ed9d356..960e39ca42 100644 --- a/src/gromacs/topology/topsort.cpp +++ b/src/gromacs/topology/topsort.cpp @@ -229,7 +229,7 @@ void gmx_sort_ilist_fe(t_idef* idef, const real* qA, const real* qB) } } /* Now we now the number of non-perturbed interactions */ - ilist->nr_nonperturbed = ic; + idef->numNonperturbedInteractions[ftype] = ic; /* Copy the buffer with perturbed interactions to the ilist */ for (a = 0; a < ib; a++) @@ -239,8 +239,9 @@ void gmx_sort_ilist_fe(t_idef* idef, const real* qA, const real* qB) if (debug) { + const int numNonperturbed = idef->numNonperturbedInteractions[ftype]; fprintf(debug, "%s non-pert %d pert %d\n", interaction_function[ftype].longname, - ilist->nr_nonperturbed, ilist->nr - ilist->nr_nonperturbed); + numNonperturbed, ilist->nr - numNonperturbed); } } } -- 2.22.0