Move nr_nonperturbed out of t_ilist
authorBerk Hess <hess@kth.se>
Wed, 4 Dec 2019 12:50:42 +0000 (13:50 +0100)
committerMagnus Lundborg <magnus.lundborg@scilifelab.se>
Sun, 22 Dec 2019 13:29:10 +0000 (14:29 +0100)
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
src/gromacs/listed_forces/listed_forces.cpp
src/gromacs/listed_forces/manage_threading.cpp
src/gromacs/mdlib/tests/settletestdata.cpp
src/gromacs/topology/idef.cpp
src/gromacs/topology/idef.h
src/gromacs/topology/topsort.cpp

index 041ee514b77ffa37252ad0d82769b665c9409b24..ba983faeb1fe8f207ab84a9406a4de3562aa490c 100644 (file)
@@ -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
index 4b46781c2e154bb0b43c5f8b6d6773ba4a4966c6..4e1533ae1e6f9625361ac28fd68a51e119c00289 100644 (file)
@@ -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<const int>      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<const int> 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<const int> 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;
             }
         }
index f8d4ff05848abe7217f334ee91e08bc1d00d5371..b696861250d6a45d4ac5d005236941b590d201f0 100644 (file)
@@ -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
index 8feab2e0a02b2249dce77ffefc02049c309e24c3..4cea8e864a3ca4b036a3f802d4805563bea9310d 100644 (file)
@@ -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_;
 }
 
index ef3f17e8374d4ec1197a70dd7a35adc51c02d8ca..b438c3583db518dd01590746695e241ba43de338 100644 (file)
@@ -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];
index 15c010e286c48ee702f994c67efa113c799d1bdc..269d531fc0380b7a7fa022e4f0ff0cf22ecee8c9 100644 (file)
@@ -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;
 
 /*
index cf7ed9d3564a2ddb72ba9bd19d33c185d008bb44..960e39ca426935ae72653a511b1a2712ec2dcc94 100644 (file)
@@ -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);
             }
         }
     }