Simplify DD exclusion counting
authorBerk Hess <hess@kth.se>
Mon, 30 Sep 2019 20:13:27 +0000 (22:13 +0200)
committerBerk Hess <hess@kth.se>
Tue, 1 Oct 2019 11:15:37 +0000 (13:15 +0200)
Change-Id: I7004b6860fc0c21fc4d82378b4a86d29a94d9391

src/gromacs/domdec/domdec_struct.h
src/gromacs/domdec/domdec_topology.cpp
src/gromacs/domdec/partition.cpp

index 60bd04913d39482cbe185ec374db263f475d45f6..c80e6687df66f70eab3891cd408edb90608e7841 100644 (file)
@@ -193,8 +193,8 @@ struct gmx_domdec_t { //NOLINT(clang-analyzer-optin.performance.Padding)
     int                 nbonded_global = 0;
     int                 nbonded_local  = 0;
 
-    /* The number of inter charge-group exclusions */
-    int  n_intercg_excl = 0;
+    /* Whether we have non-self exclusion */
+    bool haveExclusions = false;
 
     /* Vsite stuff */
     gmx::HashedMap<int>       *ga2la_vsite = nullptr;
index 116392522613e0e23496f60ba92a885c77bceeb7..676303f47e44efd9658215bdbff77dcdafce456a 100644 (file)
@@ -458,38 +458,21 @@ static void global_atomnr_to_moltype_ind(const gmx_reverse_top_t *rt,
     *i_mol = (i_gl - mbi->a_start) - (*mol)*mbi->natoms_mol;
 }
 
-/*! \brief Count the exclusions for all atoms in \p cgs */
-static void count_excls(const t_block *cgs, const t_blocka *excls,
-                        int *n_excl, int *n_intercg_excl, int *n_excl_at_max)
+/*! \brief Returns the maximum number of exclusions per atom */
+static int getMaxNumExclusionsPerAtom(const t_blocka &excls)
 {
-    int cg, at0, at1, at, excl, atj;
-
-    *n_excl         = 0;
-    *n_intercg_excl = 0;
-    *n_excl_at_max  = 0;
-    for (cg = 0; cg < cgs->nr; cg++)
+    int maxNumExcls = 0;
+    for (int at = 0; at < excls.nr; at++)
     {
-        at0 = cgs->index[cg];
-        at1 = cgs->index[cg+1];
-        for (at = at0; at < at1; at++)
-        {
-            for (excl = excls->index[at]; excl < excls->index[at+1]; excl++)
-            {
-                atj = excls->a[excl];
-                if (atj > at)
-                {
-                    (*n_excl)++;
-                    if (atj < at0 || atj >= at1)
-                    {
-                        (*n_intercg_excl)++;
-                    }
-                }
-            }
+        const int numExcls = excls.index[at + 1] - excls.index[at];
 
-            *n_excl_at_max = std::max(*n_excl_at_max,
-                                      excls->index[at+1] - excls->index[at]);
-        }
+        GMX_RELEASE_ASSERT(numExcls != 1 || excls.a[excls.index[at]] == at,
+                           "With 1 exclusion we expect a self-exclusion");
+
+        maxNumExcls = std::max(maxNumExcls, numExcls);
     }
+
+    return maxNumExcls;
 }
 
 /*! \brief Run the reverse ilist generation and store it in r_il when \p bAssign = TRUE */
@@ -750,17 +733,18 @@ void dd_make_reverse_top(FILE *fplog,
 
     gmx_reverse_top_t *rt = dd->reverse_top;
 
-    dd->n_intercg_excl = 0;
+    dd->haveExclusions = false;
     rt->n_excl_at_max  = 0;
     for (const gmx_molblock_t &molb : mtop->molblock)
     {
-        int                  n_excl_mol, n_excl_icg, n_excl_at_max;
-
-        const gmx_moltype_t &molt = mtop->moltype[molb.type];
-        count_excls(&molt.cgs, &molt.excls,
-                    &n_excl_mol, &n_excl_icg, &n_excl_at_max);
-        dd->n_intercg_excl += molb.nmol*n_excl_icg;
-        rt->n_excl_at_max   = std::max(rt->n_excl_at_max, n_excl_at_max);
+        const int maxNumExclusionsPerAtom =
+            getMaxNumExclusionsPerAtom(mtop->moltype[molb.type].excls);
+        // We checked above that max 1 exclusion means only self exclusions
+        if (maxNumExclusionsPerAtom > 1)
+        {
+            dd->haveExclusions = true;
+        }
+        rt->n_excl_at_max = std::max(rt->n_excl_at_max, maxNumExclusionsPerAtom);
     }
 
     if (vsite && vsite->numInterUpdategroupVsites > 0)
@@ -1560,7 +1544,7 @@ static void finish_local_exclusions(gmx_domdec_t *dd, gmx_domdec_zones_t *zones,
     const gmx::Range<int> nonhomeIzonesAtomRange(zones->izone[0].cg1,
                                                  zones->izone[zones->nizone - 1].cg1);
 
-    if (dd->n_intercg_excl == 0)
+    if (!dd->haveExclusions)
     {
         /* There are no exclusions involving non-home charge groups,
          * but we need to set the indices for neighborsearching.
@@ -1622,14 +1606,14 @@ static int make_local_bondeds_excls(gmx_domdec_t *dd,
         nzone_bondeds = 1;
     }
 
-    if (dd->n_intercg_excl > 0)
+    if (dd->haveExclusions)
     {
         /* We only use exclusions from i-zones to i- and j-zones */
         nzone_excl = zones->nizone;
     }
     else
     {
-        /* There are no inter-cg exclusions and only zone 0 sees itself */
+        /* There are no exclusions and only zone 0 sees itself */
         nzone_excl = 1;
     }
 
index 2f938be8208e6ebad49312b96cee19034c75636f..0508912990423a317f37747a56636f3b47505cc5 100644 (file)
@@ -3178,7 +3178,7 @@ void dd_partition_system(FILE                        *fplog,
         }
         else
         {
-            if (EEL_FULL(ir->coulombtype) && dd->n_intercg_excl > 0)
+            if (EEL_FULL(ir->coulombtype) && dd->haveExclusions)
             {
                 nat_f_novirsum = comm->atomRanges.end(DDAtomRanges::Type::Zones);
             }