Early exit for CUDA versions of SETTLE and LINCS
authorArtem Zhmurov <zhmurov@gmail.com>
Fri, 28 Jun 2019 14:52:17 +0000 (16:52 +0200)
committerArtem Zhmurov <zhmurov@gmail.com>
Wed, 3 Jul 2019 11:56:33 +0000 (13:56 +0200)
Change-Id: Ia3c56a1be6b8ceaa8e1b7be956c1f1f3628c9139

src/gromacs/mdlib/lincs_cuda_impl.cu
src/gromacs/mdlib/settle_cuda_impl.cu

index 8676f210a217447fd3112a9e581e9fd4341c47fe..eb03a4821409e860a75a0874a536e6cbf9097661 100644 (file)
@@ -441,6 +441,12 @@ void LincsCuda::Impl::apply(const float3 *d_x,
 {
     ensureNoPendingCudaError("In CUDA version of LINCS");
 
+    // Early exit if no constraints
+    if (kernelParams_.numConstraintsThreads == 0)
+    {
+        return;
+    }
+
     if (computeVirial)
     {
         // Fill with zeros so the values can be reduced to it
@@ -648,6 +654,14 @@ void LincsCuda::Impl::set(const t_idef    &idef,
     t_iatom  *iatoms         = idef.il[F_CONSTR].iatoms;
     const int stride         = NRAL(F_CONSTR) + 1;
     const int numConstraints = idef.il[F_CONSTR].nr/stride;
+
+    // Early exit if no constraints
+    if (numConstraints == 0)
+    {
+        kernelParams_.numConstraintsThreads = 0;
+        return;
+    }
+
     // Constructing adjacency list --- usefull intermediate structure
     std::vector<std::vector<std::tuple<int, int, int> > > atomsAdjacencyList(numAtoms);
     for (int c = 0; c < numConstraints; c++)
index f58c545ddbd3426c4c1a713aaa8c59a489518cfb..7239f6d36aaf1d671db6d64fce1a14fb7489be27 100644 (file)
@@ -423,6 +423,12 @@ void SettleCuda::Impl::apply(const float3 *d_x,
 
     ensureNoPendingCudaError("In CUDA version SETTLE");
 
+    // Early exit if no settles
+    if (numSettles_ == 0)
+    {
+        return;
+    }
+
     if (computeVirial)
     {
         // Fill with zeros so the values can be reduced to it
@@ -536,6 +542,20 @@ SettleCuda::Impl::Impl(const gmx_mtop_t &mtop)
     static_assert(c_threadsPerBlock > 0 && ((c_threadsPerBlock & (c_threadsPerBlock - 1)) == 0),
                   "Number of threads per block should be a power of two in order for reduction to work.");
 
+    // This is to prevent the assertion failure for the systems without water
+    int totalSettles = 0;
+    for (unsigned mt = 0; mt < mtop.moltype.size(); mt++)
+    {
+        const int        nral1           = 1 + NRAL(F_SETTLE);
+        InteractionList  interactionList = mtop.moltype.at(mt).ilist[F_SETTLE];
+        std::vector<int> iatoms          = interactionList.iatoms;
+        totalSettles += iatoms.size()/nral1;
+    }
+    if (totalSettles == 0)
+    {
+        return;
+    }
+
     // TODO This should be lifted to a separate subroutine that gets the values of Oxygen and Hydrogen
     // masses, checks if they are consistent across the topology and if there is no more than two values
     // for each mass if the free energy perturbation is enabled. In later case, masses may need to be
@@ -635,6 +655,11 @@ SettleCuda::Impl::Impl(const real mO,  const real mH,
 
 SettleCuda::Impl::~Impl()
 {
+    // Early exit if there is no settles
+    if (numSettles_ == 0)
+    {
+        return;
+    }
     freeDeviceBuffer(&d_virialScaled_);
     if (h_atomIds_.size() > 0)
     {