Set temperature scaling groups upon construction of integrator
authorArtem Zhmurov <zhmurov@gmail.com>
Sat, 20 Feb 2021 22:48:03 +0000 (22:48 +0000)
committerPascal Merz <pascal.merz@me.com>
Sat, 20 Feb 2021 22:48:03 +0000 (22:48 +0000)
The temperature scaling parameters do not change, so can be
set upon construction of the integrator object.

Closes #3794

src/gromacs/mdlib/leapfrog_gpu.cu
src/gromacs/mdlib/leapfrog_gpu.h
src/gromacs/mdlib/leapfrog_gpu_sycl.cpp
src/gromacs/mdlib/tests/leapfrogtestrunners_gpu.cpp
src/gromacs/mdlib/update_constrain_gpu.h
src/gromacs/mdlib/update_constrain_gpu_impl.cpp
src/gromacs/mdlib/update_constrain_gpu_impl.cu
src/gromacs/mdlib/update_constrain_gpu_impl.h
src/gromacs/mdrun/md.cpp

index d47619109e7e453ef54944b44641cfb7fe394767..2f5b589870120960eb1b2c53e2c9f3393f1d06ff 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -307,9 +307,12 @@ void LeapFrogGpu::integrate(const DeviceBuffer<float3>        d_x,
     return;
 }
 
-LeapFrogGpu::LeapFrogGpu(const DeviceContext& deviceContext, const DeviceStream& deviceStream) :
+LeapFrogGpu::LeapFrogGpu(const DeviceContext& deviceContext,
+                         const DeviceStream&  deviceStream,
+                         const int            numTempScaleValues) :
     deviceContext_(deviceContext),
-    deviceStream_(deviceStream)
+    deviceStream_(deviceStream),
+    numTempScaleValues_(numTempScaleValues)
 {
     numAtoms_ = 0;
 
@@ -319,6 +322,14 @@ LeapFrogGpu::LeapFrogGpu(const DeviceContext& deviceContext, const DeviceStream&
     kernelLaunchConfig_.blockSize[1]     = 1;
     kernelLaunchConfig_.blockSize[2]     = 1;
     kernelLaunchConfig_.sharedMemorySize = 0;
+
+    // If the temperature coupling is enabled, we need to make space for scaling factors
+    if (numTempScaleValues_ > 0)
+    {
+        h_lambdas_.resize(numTempScaleValues_);
+        reallocateDeviceBuffer(
+                &d_lambdas_, numTempScaleValues_, &numLambdas_, &numLambdasAlloc_, deviceContext_);
+    }
 }
 
 LeapFrogGpu::~LeapFrogGpu()
@@ -326,37 +337,24 @@ LeapFrogGpu::~LeapFrogGpu()
     freeDeviceBuffer(&d_inverseMasses_);
 }
 
-void LeapFrogGpu::set(const int             numAtoms,
-                      const real*           inverseMasses,
-                      const int             numTempScaleValues,
-                      const unsigned short* tempScaleGroups)
+void LeapFrogGpu::set(const int numAtoms, const real* inverseMasses, const unsigned short* tempScaleGroups)
 {
     numAtoms_                       = numAtoms;
     kernelLaunchConfig_.gridSize[0] = (numAtoms_ + c_threadsPerBlock - 1) / c_threadsPerBlock;
 
-    numTempScaleValues_ = numTempScaleValues;
-
     reallocateDeviceBuffer(
             &d_inverseMasses_, numAtoms_, &numInverseMasses_, &numInverseMassesAlloc_, deviceContext_);
     copyToDeviceBuffer(
             &d_inverseMasses_, (float*)inverseMasses, 0, numAtoms_, deviceStream_, GpuApiCallBehavior::Sync, nullptr);
 
     // Temperature scale group map only used if there are more then one group
-    if (numTempScaleValues > 1)
+    if (numTempScaleValues_ > 1)
     {
         reallocateDeviceBuffer(
                 &d_tempScaleGroups_, numAtoms_, &numTempScaleGroups_, &numTempScaleGroupsAlloc_, deviceContext_);
         copyToDeviceBuffer(
                 &d_tempScaleGroups_, tempScaleGroups, 0, numAtoms_, deviceStream_, GpuApiCallBehavior::Sync, nullptr);
     }
-
-    // If the temperature coupling is enabled, we need to make space for scaling factors
-    if (numTempScaleValues_ > 0)
-    {
-        h_lambdas_.resize(numTempScaleValues);
-        reallocateDeviceBuffer(
-                &d_lambdas_, numTempScaleValues_, &numLambdas_, &numLambdasAlloc_, deviceContext_);
-    }
 }
 
 } // namespace gmx
index e802d4c8e313df0cacb29b5ce5bc821b50614825..108259f1c677e1804c7eddd6db4f19a4f6c1826b 100644 (file)
@@ -101,10 +101,11 @@ class LeapFrogGpu
 public:
     /*! \brief Constructor.
      *
-     * \param[in] deviceContext  Device context (dummy in CUDA).
-     * \param[in] deviceStream   Device stream to use.
+     * \param[in] deviceContext       Device context (dummy in CUDA).
+     * \param[in] deviceStream        Device stream to use.
+     * \param[in] numTempScaleValues  Number of temperature scale groups.
      */
-    LeapFrogGpu(const DeviceContext& deviceContext, const DeviceStream& deviceStream);
+    LeapFrogGpu(const DeviceContext& deviceContext, const DeviceStream& deviceStream, int numTempScaleValues);
     ~LeapFrogGpu();
 
     /*! \brief Integrate
@@ -140,15 +141,11 @@ public:
      * and temperature coupling groups. Copies inverse masses and temperature coupling groups
      * to the GPU.
      *
-     * \param[in] numAtoms            Number of atoms in the system.
-     * \param[in] inverseMasses       Inverse masses of atoms.
-     * \param[in] numTempScaleValues  Number of temperature scale groups.
-     * \param[in] tempScaleGroups     Maps the atom index to temperature scale value.
+     * \param[in] numAtoms        Number of atoms in the system.
+     * \param[in] inverseMasses   Inverse masses of atoms.
+     * \param[in] tempScaleGroups Maps the atom index to temperature scale value.
      */
-    void set(const int             numAtoms,
-             const real*           inverseMasses,
-             int                   numTempScaleValues,
-             const unsigned short* tempScaleGroups);
+    void set(const int numAtoms, const real* inverseMasses, const unsigned short* tempScaleGroups);
 
     /*! \brief Class with hardware-specific interfaces and implementations.*/
     class Impl;
index d82c9c12eb4a860713aca003b6b28f989f348789..9afb0320fb23d3c72f8e0e4878a3a53169e0011e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -273,11 +273,20 @@ void LeapFrogGpu::integrate(DeviceBuffer<float3>              d_x,
                          prVelocityScalingMatrixDiagonal_);
 }
 
-LeapFrogGpu::LeapFrogGpu(const DeviceContext& deviceContext, const DeviceStream& deviceStream) :
+LeapFrogGpu::LeapFrogGpu(const DeviceContext& deviceContext,
+                         const DeviceStream&  deviceStream,
+                         const int            numTempScaleValues) :
     deviceContext_(deviceContext),
     deviceStream_(deviceStream),
-    numAtoms_(0)
+    numAtoms_(0),
+    numTempScaleValues_(numTempScaleValues)
 {
+    // If the temperature coupling is enabled, we need to make space for scaling factors
+    if (numTempScaleValues_ > 0)
+    {
+        reallocateDeviceBuffer(
+                &d_lambdas_, numTempScaleValues_, &numLambdas_, &numLambdasAlloc_, deviceContext_);
+    }
 }
 
 LeapFrogGpu::~LeapFrogGpu()
@@ -285,13 +294,9 @@ LeapFrogGpu::~LeapFrogGpu()
     freeDeviceBuffer(&d_inverseMasses_);
 }
 
-void LeapFrogGpu::set(const int             numAtoms,
-                      const real*           inverseMasses,
-                      const int             numTempScaleValues,
-                      const unsigned short* tempScaleGroups)
+void LeapFrogGpu::set(const int numAtoms, const real* inverseMasses, const unsigned short* tempScaleGroups)
 {
-    numAtoms_           = numAtoms;
-    numTempScaleValues_ = numTempScaleValues;
+    numAtoms_ = numAtoms;
 
     reallocateDeviceBuffer(
             &d_inverseMasses_, numAtoms_, &numInverseMasses_, &numInverseMassesAlloc_, deviceContext_);
@@ -306,13 +311,6 @@ void LeapFrogGpu::set(const int             numAtoms,
         copyToDeviceBuffer(
                 &d_tempScaleGroups_, tempScaleGroups, 0, numAtoms_, deviceStream_, GpuApiCallBehavior::Sync, nullptr);
     }
-
-    // If the temperature coupling is enabled, we need to make space for scaling factors
-    if (numTempScaleValues_ > 0)
-    {
-        reallocateDeviceBuffer(
-                &d_lambdas_, numTempScaleValues_, &numLambdas_, &numLambdasAlloc_, deviceContext_);
-    }
 }
 
 } // namespace gmx
index f88ae219ce5b2ee4a7a0098c033835b54c9fba16..b85ed94b52ec3b49193984edf3073fc4b45d1297 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -95,12 +95,10 @@ void LeapFrogDeviceTestRunner::integrate(LeapFrogTestData* testData, int numStep
     copyToDeviceBuffer(&d_v, h_v, 0, numAtoms, deviceStream, GpuApiCallBehavior::Sync, nullptr);
     copyToDeviceBuffer(&d_f, h_f, 0, numAtoms, deviceStream, GpuApiCallBehavior::Sync, nullptr);
 
-    auto integrator = std::make_unique<LeapFrogGpu>(deviceContext, deviceStream);
+    auto integrator =
+            std::make_unique<LeapFrogGpu>(deviceContext, deviceStream, testData->numTCoupleGroups_);
 
-    integrator->set(testData->numAtoms_,
-                    testData->inverseMasses_.data(),
-                    testData->numTCoupleGroups_,
-                    testData->mdAtoms_.cTC);
+    integrator->set(testData->numAtoms_, testData->inverseMasses_.data(), testData->mdAtoms_.cTC);
 
     bool doTempCouple = testData->numTCoupleGroups_ > 0;
     for (int step = 0; step < numSteps; step++)
index 3e77d8d3cee6c55cbc90551b29b9f3a6d7049936..ce23e1dfa04123e2298c60c18e34dc8be8ced217 100644 (file)
@@ -76,18 +76,20 @@ public:
      * any) consumers of the updated coordinates. The \p xUpdatedOnDevice also can not be a nullptr
      * because the markEvent(...) method is called unconditionally.
      *
-     * \param[in] ir                Input record data: LINCS takes number of iterations and order of
-     *                              projection from it.
-     * \param[in] mtop              Topology of the system: SETTLE gets the masses for O and H atoms
-     *                              and target O-H and H-H distances from this object.
-     * \param[in] deviceContext     GPU device context.
-     * \param[in] deviceStream      GPU stream to use.
-     * \param[in] xUpdatedOnDevice  The event synchronizer to use to mark that update is done
-     *                              on the GPU.
-     * \param[in] wcycle            The wallclock counter
+     * \param[in] ir                  Input record data: LINCS takes number of iterations and order of
+     *                                projection from it.
+     * \param[in] mtop                Topology of the system: SETTLE gets the masses for O and H atoms
+     *                                and target O-H and H-H distances from this object.
+     * \param[in] numTempScaleValues  Number of temperature scaling groups. Zero for no temperature scaling.
+     * \param[in] deviceContext       GPU device context.
+     * \param[in] deviceStream        GPU stream to use.
+     * \param[in] xUpdatedOnDevice    The event synchronizer to use to mark that update is done
+     *                                on the GPU.
+     * \param[in] wcycle              The wallclock counter
      */
     UpdateConstrainGpu(const t_inputrec&     ir,
                        const gmx_mtop_t&     mtop,
+                       int                   numTempScaleValues,
                        const DeviceContext&  deviceContext,
                        const DeviceStream&   deviceStream,
                        GpuEventSynchronizer* xUpdatedOnDevice,
@@ -147,14 +149,12 @@ public:
      * \param[in]      d_f                 Device buffer with forces.
      * \param[in]      idef                System topology
      * \param[in]      md                  Atoms data.
-     * \param[in]      numTempScaleValues  Number of temperature scaling groups. Zero for no temperature scaling.
      */
     void set(DeviceBuffer<RVec>            d_x,
              DeviceBuffer<RVec>            d_v,
              DeviceBuffer<RVec>            d_f,
              const InteractionDefinitions& idef,
-             const t_mdatoms&              md,
-             int                           numTempScaleValues);
+             const t_mdatoms&              md);
 
     /*! \brief
      * Update PBC data.
index dc2b0421c3d8ce1ce1e1e0e959bdb6a7dc3abd67..b0f3872860900129780a8fe75ee9ec9f42e7e206 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -58,6 +58,7 @@ class UpdateConstrainGpu::Impl
 
 UpdateConstrainGpu::UpdateConstrainGpu(const t_inputrec& /* ir   */,
                                        const gmx_mtop_t& /* mtop */,
+                                       const int /* numTempScaleValues */,
                                        const DeviceContext& /* deviceContext */,
                                        const DeviceStream& /* deviceStream */,
                                        GpuEventSynchronizer* /* xUpdatedOnDevice */,
@@ -101,8 +102,7 @@ void UpdateConstrainGpu::set(DeviceBuffer<RVec> /* d_x */,
                              DeviceBuffer<RVec> /* d_v */,
                              const DeviceBuffer<RVec> /* d_f */,
                              const InteractionDefinitions& /* idef */,
-                             const t_mdatoms& /* md */,
-                             const int /* numTempScaleValues */)
+                             const t_mdatoms& /* md */)
 {
     GMX_ASSERT(!impl_,
                "A CPU stub for UpdateConstrain was called instead of the correct implementation.");
index ba27a8a58c38537a304464b29dfd4e5996d327f3..f03ab778c3951b84a1f83ee7243bc07c96ed5952 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -215,6 +215,7 @@ void UpdateConstrainGpu::Impl::scaleVelocities(const matrix scalingMatrix)
 
 UpdateConstrainGpu::Impl::Impl(const t_inputrec&     ir,
                                const gmx_mtop_t&     mtop,
+                               const int             numTempScaleValues,
                                const DeviceContext&  deviceContext,
                                const DeviceStream&   deviceStream,
                                GpuEventSynchronizer* xUpdatedOnDevice,
@@ -227,7 +228,7 @@ UpdateConstrainGpu::Impl::Impl(const t_inputrec&     ir,
     GMX_ASSERT(xUpdatedOnDevice != nullptr, "The event synchronizer can not be nullptr.");
 
 
-    integrator_ = std::make_unique<LeapFrogGpu>(deviceContext_, deviceStream_);
+    integrator_ = std::make_unique<LeapFrogGpu>(deviceContext_, deviceStream_, numTempScaleValues);
     lincsGpu_ = std::make_unique<LincsGpu>(ir.nLincsIter, ir.nProjOrder, deviceContext_, deviceStream_);
     settleGpu_ = std::make_unique<SettleGpu>(mtop, deviceContext_, deviceStream_);
 
@@ -243,8 +244,7 @@ void UpdateConstrainGpu::Impl::set(DeviceBuffer<RVec>            d_x,
                                    DeviceBuffer<RVec>            d_v,
                                    const DeviceBuffer<RVec>      d_f,
                                    const InteractionDefinitions& idef,
-                                   const t_mdatoms&              md,
-                                   const int                     numTempScaleValues)
+                                   const t_mdatoms&              md)
 {
     // TODO wallcycle
     wallcycle_start_nocount(wcycle_, ewcLAUNCH_GPU);
@@ -266,7 +266,7 @@ void UpdateConstrainGpu::Impl::set(DeviceBuffer<RVec>            d_x,
             &d_inverseMasses_, numAtoms_, &numInverseMasses_, &numInverseMassesAlloc_, deviceContext_);
 
     // Integrator should also update something, but it does not even have a method yet
-    integrator_->set(numAtoms_, md.invmass, numTempScaleValues, md.cTC);
+    integrator_->set(numAtoms_, md.invmass, md.cTC);
     lincsGpu_->set(idef, numAtoms_, md.invmass);
     settleGpu_->set(idef);
 
@@ -290,11 +290,12 @@ GpuEventSynchronizer* UpdateConstrainGpu::Impl::getCoordinatesReadySync()
 
 UpdateConstrainGpu::UpdateConstrainGpu(const t_inputrec&     ir,
                                        const gmx_mtop_t&     mtop,
+                                       const int             numTempScaleValues,
                                        const DeviceContext&  deviceContext,
                                        const DeviceStream&   deviceStream,
                                        GpuEventSynchronizer* xUpdatedOnDevice,
                                        gmx_wallcycle*        wcycle) :
-    impl_(new Impl(ir, mtop, deviceContext, deviceStream, xUpdatedOnDevice, wcycle))
+    impl_(new Impl(ir, mtop, numTempScaleValues, deviceContext, deviceStream, xUpdatedOnDevice, wcycle))
 {
 }
 
@@ -337,10 +338,9 @@ void UpdateConstrainGpu::set(DeviceBuffer<RVec>            d_x,
                              DeviceBuffer<RVec>            d_v,
                              const DeviceBuffer<RVec>      d_f,
                              const InteractionDefinitions& idef,
-                             const t_mdatoms&              md,
-                             const int                     numTempScaleValues)
+                             const t_mdatoms&              md)
 {
-    impl_->set(d_x, d_v, d_f, idef, md, numTempScaleValues);
+    impl_->set(d_x, d_v, d_f, idef, md);
 }
 
 void UpdateConstrainGpu::setPbc(const PbcType pbcType, const matrix box)
index 7453a98105712aca5264b16aa737789d8f53e213..8e101b8cd0ed51ffb1c73b474c3b000ea09bd138 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -71,18 +71,20 @@ public:
      * any) consumers of the updated coordinates. The \p xUpdatedOnDevice also can not be a nullptr
      * because the markEvent(...) method is called unconditionally.
      *
-     * \param[in] ir                Input record data: LINCS takes number of iterations and order of
-     *                              projection from it.
-     * \param[in] mtop              Topology of the system: SETTLE gets the masses for O and H atoms
-     *                              and target O-H and H-H distances from this object.
-     * \param[in] deviceContext     GPU device context.
-     * \param[in] deviceStream      GPU stream to use.
-     * \param[in] xUpdatedOnDevice  The event synchronizer to use to mark that
-     *                              update is done on the GPU.
-     * \param[in] wcycle            The wallclock counter
+     * \param[in] ir                  Input record data: LINCS takes number of iterations and order of
+     *                                projection from it.
+     * \param[in] mtop                Topology of the system: SETTLE gets the masses for O and H atoms
+     *                                and target O-H and H-H distances from this object.
+     * \param[in] numTempScaleValues  Number of temperature scaling groups. Set zero for no temperature coupling.
+     * \param[in] deviceContext       GPU device context.
+     * \param[in] deviceStream        GPU stream to use.
+     * \param[in] xUpdatedOnDevice    The event synchronizer to use to mark that
+     *                                update is done on the GPU.
+     * \param[in] wcycle              The wallclock counter
      */
     Impl(const t_inputrec&     ir,
          const gmx_mtop_t&     mtop,
+         int                   numTempScaleValues,
          const DeviceContext&  deviceContext,
          const DeviceStream&   deviceStream,
          GpuEventSynchronizer* xUpdatedOnDevice,
@@ -147,14 +149,12 @@ public:
      * \param[in]      d_f            Device buffer with forces.
      * \param[in] idef                System topology
      * \param[in] md                  Atoms data.
-     * \param[in] numTempScaleValues  Number of temperature scaling groups. Set zero for no temperature coupling.
      */
     void set(DeviceBuffer<RVec>            d_x,
              DeviceBuffer<RVec>            d_v,
              const DeviceBuffer<RVec>      d_f,
              const InteractionDefinitions& idef,
-             const t_mdatoms&              md,
-             const int                     numTempScaleValues);
+             const t_mdatoms&              md);
 
     /*! \brief
      * Update PBC data.
index cf64bf19c6771a63dd4a72434827e3c203b02f97..f161798d84833df7651824d0cc4492218b4c141e 100644 (file)
@@ -473,6 +473,7 @@ void gmx::LegacySimulator::do_md()
         integrator = std::make_unique<UpdateConstrainGpu>(
                 *ir,
                 *top_global,
+                ekind->ngtc,
                 fr->deviceStreamManager->context(),
                 fr->deviceStreamManager->stream(gmx::DeviceStreamType::UpdateAndConstraints),
                 stateGpu->xUpdatedOnDevice(),
@@ -1481,8 +1482,7 @@ void gmx::LegacySimulator::do_md()
                                     stateGpu->getVelocities(),
                                     stateGpu->getForces(),
                                     top.idef,
-                                    *mdatoms,
-                                    ekind->ngtc);
+                                    *mdatoms);
 
                     // Copy data to the GPU after buffers might have being reinitialized
                     stateGpu->copyVelocitiesToGpu(state->v, AtomLocality::Local);