Remove PImpl scaffolding from CUDA version of Leap-Frog
authorArtem Zhmurov <zhmurov@gmail.com>
Tue, 28 May 2019 14:09:41 +0000 (16:09 +0200)
committerChristian Blau <cblau@gwdg.de>
Tue, 6 Aug 2019 13:52:58 +0000 (15:52 +0200)
Private implementation in CUDA version of Leap-Frog was
used to introduce this integrator as a stand-alone unit.
Now it is merged with constraints, PImpl is no longer
needed.

Refs #2816, #2888

Change-Id: Iea82abef016b7e15b9be44a0e1b446e12e582d3c

src/gromacs/mdlib/CMakeLists.txt
src/gromacs/mdlib/leapfrog_cuda.cu [moved from src/gromacs/mdlib/leapfrog_cuda_impl.cu with 74% similarity]
src/gromacs/mdlib/leapfrog_cuda.cuh [moved from src/gromacs/mdlib/leapfrog_cuda.h with 67% similarity]
src/gromacs/mdlib/leapfrog_cuda_impl.h [deleted file]
src/gromacs/mdlib/tests/CMakeLists.txt
src/gromacs/mdlib/tests/leapfrog.cpp
src/gromacs/mdlib/tests/leapfrog.cu [new file with mode: 0644]
src/gromacs/mdlib/tests/leapfrogtest.h [moved from src/gromacs/mdlib/leapfrog_cuda_impl.cpp with 57% similarity]
src/gromacs/mdlib/update_constrain_cuda_impl.cu
src/gromacs/mdlib/update_constrain_cuda_impl.h

index 506c0160e84c6ee20e963f240386648787eb3fee..727adcc284fec93f526c72abf1875e92580e6736 100644 (file)
@@ -40,9 +40,9 @@ if (BUILD_TESTING)
 endif()
 if(GMX_USE_CUDA)
     gmx_add_libgromacs_sources(
-       leapfrog_cuda_impl.cu
        lincs_cuda.cu
        settle_cuda.cu
+       leapfrog_cuda.cu
        update_constrain_cuda_impl.cu
        )
 endif()
similarity index 74%
rename from src/gromacs/mdlib/leapfrog_cuda_impl.cu
rename to src/gromacs/mdlib/leapfrog_cuda.cu
index a1d142acecdba86d6d8e232e8b388a149909ae47..bfb3afcd6f76b0ddec588df557ad84d2673a8f46 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
@@ -48,7 +49,7 @@
  */
 #include "gmxpre.h"
 
-#include "leapfrog_cuda_impl.h"
+#include "leapfrog_cuda.cuh"
 
 #include <assert.h>
 #include <stdio.h>
@@ -62,7 +63,6 @@
 #include "gromacs/gpu_utils/gputraits.cuh"
 #include "gromacs/gpu_utils/vectype_ops.cuh"
 #include "gromacs/math/vec.h"
-#include "gromacs/mdlib/leapfrog_cuda.h"
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/pbcutil/pbc_aiuc_cuda.cuh"
 
@@ -124,11 +124,11 @@ __global__ void leapfrog_kernel(const int                  numAtoms,
     return;
 }
 
-void LeapFrogCuda::Impl::integrate(const float3 *d_x,
-                                   float3       *d_xp,
-                                   float3       *d_v,
-                                   const float3 *d_f,
-                                   const real    dt)
+void LeapFrogCuda::integrate(const float3 *d_x,
+                             float3       *d_xp,
+                             float3       *d_v,
+                             const float3 *d_f,
+                             const real    dt)
 {
 
     ensureNoPendingCudaError("In CUDA version of Leap-Frog integrator");
@@ -159,38 +159,7 @@ void LeapFrogCuda::Impl::integrate(const float3 *d_x,
     return;
 }
 
-void LeapFrogCuda::Impl::copyIntegrateCopy(const int   numAtoms,
-                                           const rvec *h_x,
-                                           rvec       *h_xp,
-                                           rvec       *h_v,
-                                           const rvec *h_f,
-                                           const real  dt)
-{
-    float3 *d_x, *d_xp, *d_v, *d_f;
-
-    allocateDeviceBuffer(&d_x,  numAtoms, nullptr);
-    allocateDeviceBuffer(&d_xp, numAtoms, nullptr);
-    allocateDeviceBuffer(&d_v,  numAtoms, nullptr);
-    allocateDeviceBuffer(&d_f,  numAtoms, nullptr);
-
-    copyToDeviceBuffer(&d_x,  (float3*)h_x,  0, numAtoms, stream_, GpuApiCallBehavior::Sync, nullptr);
-    copyToDeviceBuffer(&d_xp, (float3*)h_xp, 0, numAtoms, stream_, GpuApiCallBehavior::Sync, nullptr);
-    copyToDeviceBuffer(&d_v,  (float3*)h_v,  0, numAtoms, stream_, GpuApiCallBehavior::Sync, nullptr);
-    copyToDeviceBuffer(&d_f,  (float3*)h_f,  0, numAtoms, stream_, GpuApiCallBehavior::Sync, nullptr);
-
-    integrate(d_x, d_xp, d_v, d_f, dt);
-
-    copyFromDeviceBuffer((float3*)h_xp, &d_xp, 0, numAtoms, stream_, GpuApiCallBehavior::Sync, nullptr);
-    copyFromDeviceBuffer((float3*)h_v, &d_v, 0, numAtoms, stream_, GpuApiCallBehavior::Sync, nullptr);
-
-    freeDeviceBuffer(&d_x);
-    freeDeviceBuffer(&d_xp);
-    freeDeviceBuffer(&d_v);
-    freeDeviceBuffer(&d_f);
-
-}
-
-LeapFrogCuda::Impl::Impl()
+LeapFrogCuda::LeapFrogCuda()
 {
     numAtoms_ = 0;
 
@@ -198,18 +167,18 @@ LeapFrogCuda::Impl::Impl()
     stream_ = nullptr;
 }
 
-LeapFrogCuda::Impl::~Impl()
+LeapFrogCuda::~LeapFrogCuda()
 {
     freeDeviceBuffer(&d_inverseMasses_);
 
 }
 
-void LeapFrogCuda::Impl::setPbc(const t_pbc *pbc)
+void LeapFrogCuda::setPbc(const t_pbc *pbc)
 {
     setPbcAiuc(pbc->ndim_ePBC, pbc->box, &pbcAiuc_);
 }
 
-void LeapFrogCuda::Impl::set(const t_mdatoms &md)
+void LeapFrogCuda::set(const t_mdatoms &md)
 {
     if (md.nr > numAtoms_)
     {
@@ -224,32 +193,4 @@ void LeapFrogCuda::Impl::set(const t_mdatoms &md)
                        0, numAtoms_, stream_, GpuApiCallBehavior::Sync, nullptr);
 }
 
-
-LeapFrogCuda::LeapFrogCuda()
-    : impl_(new Impl())
-{
-}
-
-LeapFrogCuda::~LeapFrogCuda() = default;
-
-void LeapFrogCuda::copyIntegrateCopy(const int   numAtoms,
-                                     const rvec *h_x,
-                                     rvec       *h_xp,
-                                     rvec       *h_v,
-                                     const rvec *h_f,
-                                     const real  dt)
-{
-    impl_->copyIntegrateCopy(numAtoms, h_x, h_xp, h_v, h_f, dt);
-}
-
-void LeapFrogCuda::setPbc(const t_pbc *pbc)
-{
-    impl_->setPbc(pbc);
-}
-
-void LeapFrogCuda::set(const t_mdatoms &md)
-{
-    impl_->set(md);
-}
-
 } //namespace gmx
similarity index 67%
rename from src/gromacs/mdlib/leapfrog_cuda.h
rename to src/gromacs/mdlib/leapfrog_cuda.cuh
index 3510172e11655d9f8fa8bca8291f37600cd0f742..16a84cbfc474308d2a45429bc6571db7a3fe4235 100644 (file)
  */
 /*! \libinternal \file
  *
- * \brief Declaration of high-level functions of CUDA implementation of Leap-Frog.
+ * \brief Declarations for CUDA implementation of Leap-Frog.
  *
- * \todo This should only list interfaces needed for libgromacs clients (e.g.
- *       management of coordinates, velocities and forces should not be here).
  * \todo Reconsider naming towards using "gpu" suffix instead of "cuda".
  *
  * \author Artem Zhmurov <zhmurov@gmail.com>
  * \ingroup module_mdlib
  * \inlibraryapi
  */
-#ifndef GMX_MDLIB_LEAPFROG_CUDA_H
-#define GMX_MDLIB_LEAPFROG_CUDA_H
+#ifndef GMX_MDLIB_LEAPFROG_CUDA_CUH
+#define GMX_MDLIB_LEAPFROG_CUDA_CUH
 
 #include "gromacs/mdtypes/mdatom.h"
 #include "gromacs/pbcutil/pbc.h"
+#include "gromacs/pbcutil/pbc_aiuc.h"
 #include "gromacs/utility/classhelpers.h"
 
 namespace gmx
@@ -63,29 +62,6 @@ class LeapFrogCuda
         LeapFrogCuda();
         ~LeapFrogCuda();
 
-        /*! \brief Integrate
-         *
-         * Copies data from CPU to GPU, integrates the equation of motion
-         * using Leap-Frog algorithm, copies the result back. Should only
-         * be used for testing.
-         *
-         * \todo This is temporary solution and will be removed in the
-         *       following revisions.
-         *
-         * \param[in] numAtoms  Number of atoms.
-         * \param[in]     h_x   Initial coordinates.
-         * \param[out]    h_xp  Place to save the resulting coordinates to.
-         * \param[in,out] h_v   Velocities (will be updated).
-         * \param[in]     h_f   Forces.
-         * \param[in]     dt    Timestep.
-         */
-        void copyIntegrateCopy(int         numAtoms,
-                               const rvec *h_x,
-                               rvec       *h_xp,
-                               rvec       *h_v,
-                               const rvec *h_f,
-                               real        dt);
-
         /*! \brief
          * Update PBC data.
          *
@@ -103,11 +79,34 @@ class LeapFrogCuda
          */
         void set(const t_mdatoms &md);
 
-        /*! \brief Class with hardware-specific interfaces and implementations.*/
-        class Impl;
+        /*! \brief Integrate
+         *
+         * Integrates the equation of motion using Leap-Frog algorithm.
+         * Updates coordinates and velocities on the GPU.
+         *
+         * \param[in]     d_x   Initial coordinates.
+         * \param[out]    d_xp  Place to save the resulting coordinates to.
+         * \param[in,out] d_v   Velocities (will be updated).
+         * \param[in]     d_f   Forces.
+         * \param[in]     dt    Timestep.
+         */
+        void integrate(const float3 *d_x,
+                       float3       *d_xp,
+                       float3       *d_v,
+                       const float3 *d_f,
+                       const real    dt);
 
     private:
-        gmx::PrivateImplPointer<Impl> impl_;
+
+        //! CUDA stream
+        cudaStream_t stream_;
+        //! Periodic boundary data
+        PbcAiuc      pbcAiuc_;
+        //! Number of atoms
+        int          numAtoms_;
+
+        //! 1/mass for all atoms (GPU)
+        real        *d_inverseMasses_;
 
 };
 
diff --git a/src/gromacs/mdlib/leapfrog_cuda_impl.h b/src/gromacs/mdlib/leapfrog_cuda_impl.h
deleted file mode 100644 (file)
index 8e9a6c1..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2019, 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.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-/*! \internal \file
- *
- * \brief Declares CUDA implementation class for Leap-Frog
- *
- * This header file is needed to include from both the device-side
- * kernels file, and the host-side management code.
- *
- * \author Artem Zhmurov <zhmurov@gmail.com>
- *
- * \ingroup module_mdlib
- */
-#ifndef GMX_MDLIB_LEAPFROG_CUDA_IMPL_H
-#define GMX_MDLIB_LEAPFROG_CUDA_IMPL_H
-
-#include "gromacs/mdlib/leapfrog_cuda.h"
-#include "gromacs/pbcutil/pbc.h"
-#include "gromacs/pbcutil/pbc_aiuc_cuda.cuh"
-
-namespace gmx
-{
-
-/*! \internal \brief Class with interfaces and data for CUDA version of Leap-Frog. */
-class LeapFrogCuda::Impl
-{
-
-    public:
-
-        Impl();
-        ~Impl();
-
-        /*! \brief Make a numerical integration step on a GPU
-         *
-         * Integrates the equation of motion using Leap-Frog algorithm.
-         * Updates coordinates and velocities on the GPU.
-         *
-         * \param[in]     d_x   GPU buffer from which the initial coordinates are taken.
-         * \param[out]    d_xp  GPU buffer where the resulting coordinates are written.
-         * \param[in,out] d_v   GPU buffer with current velocities, will be updated for the paricles being integrated.
-         * \param[in]     d_f   GPU buffer with forces that act on particles being integrated.
-         * \param[in]     dt    Timestep.
-         */
-        void integrate(const float3 *d_x,
-                       float3       *d_xp,
-                       float3       *d_v,
-                       const float3 *d_f,
-                       const real    dt);
-
-        /*! \brief Copy data, make a numerical integration step on GPU, copy result back.
-         *
-         * Copies data from CPU to GPU, integrates the equation of motion
-         * using Leap-Frog algorithm, copies the result back. Should only
-         * be used for testing. The H2D and D2H copy is done synchronously.
-         *
-         * \todo This is temporary solution and will be removed in the
-         *       following revisions.
-         *
-         * \param[in] numAtoms  Number of atoms.
-         * \param[in]     h_x   CPU buffer with initial coordinates.
-         * \param[out]    h_xp  CPU buffer to which the final coordinates will be copied.
-         * \param[in,out] h_v   CPU buffer with velocities, that will be updated for the particles being integrated.
-         * \param[in]     h_f   CPU buffer with forces that act on the particles being integrted.
-         * \param[in]     dt    Timestep.
-         */
-        void copyIntegrateCopy(const int   numAtoms,
-                               const rvec *h_x,
-                               rvec       *h_xp,
-                               rvec       *h_v,
-                               const rvec *h_f,
-                               const real  dt);
-
-        /*! \brief
-         * Update PBC data.
-         *
-         * Converts PBC data from t_pbc into the PbcAiuc format and stores the latter.
-         *
-         * \param[in] pbc The PBC data in t_pbc format.
-         */
-        void setPbc(const t_pbc *pbc);
-
-        /*! \brief Set the integrator
-         *
-         * Copies inverse masses from CPU to GPU.
-         *
-         * \param[in] md    MD atoms, from which inverse masses are taken.
-         */
-        void set(const t_mdatoms &md);
-
-    private:
-
-        //! CUDA stream
-        cudaStream_t stream_;
-        //! Periodic boundary data
-        PbcAiuc      pbcAiuc_;
-        //! Number of atoms
-        int          numAtoms_;
-
-        //! 1/mass for all atoms (GPU)
-        real        *d_inverseMasses_;
-
-};
-
-} // namespace gmx
-
-#endif
index 2969d052b39577a9d95493c3eac590994128c930..a21a5d480f048591648988618f678192b9d4fc17 100644 (file)
 # To help us fund GROMACS development, we humbly ask that you cite
 # the research papers on the package. Check out http://www.gromacs.org.
 
-file(GLOB MDLIB_TEST_SOURCES
-     constrtestrunners.cpp
-     constrtestdata.cpp
-     )
-
 gmx_add_unit_test(MdlibUnitTest mdlib-test
                   calc_verletbuf.cpp
                   constr.cpp
+                  constrtestdata.cpp
+                  constrtestrunners.cpp
                   ebin.cpp
                   energyoutput.cpp
                   leapfrog.cpp
@@ -53,5 +50,6 @@ gmx_add_unit_test(MdlibUnitTest mdlib-test
 # TODO: Make CUDA source to compile inside the testing framework
 if(GMX_USE_CUDA)
     gmx_add_libgromacs_sources(constrtestrunners.cu
+                               leapfrog.cu
                                settle_runners.cu)
 endif()
index 1e3215d5b934d944f4f9898206fba93600f3a801..b4492b8ecefe1f55c843c9e6f85b38ddba6dfe0e 100644 (file)
 
 #include "gromacs/gpu_utils/gpu_testutils.h"
 #include "gromacs/math/vec.h"
-#include "gromacs/mdlib/leapfrog_cuda.h"
+#include "gromacs/mdtypes/mdatom.h"
 #include "gromacs/utility/stringutil.h"
 
 #include "testutils/refdata.h"
 #include "testutils/testasserts.h"
 
+#include "leapfrogtest.h"
+
 namespace gmx
 {
 namespace test
@@ -193,44 +195,30 @@ TEST_P(IntegratorTest, SimpleIntegration)
     real timestep;    // 2. Timestep
     rvec v0;          // 3. Velocity
     rvec f0;          // 4. Force
-    int  nStep;       // 5. Number of steps
-    std::tie(numAtoms, timestep, v0[XX], v0[YY], v0[ZZ], f0[XX], f0[YY], f0[ZZ], nStep) = GetParam();
+    int  numSteps;    // 5. Number of steps
+    std::tie(numAtoms, timestep, v0[XX], v0[YY], v0[ZZ], f0[XX], f0[YY], f0[ZZ], numSteps) = GetParam();
 
     std::string testDescription = formatString("while testing %d atoms for %d timestep (dt = %f, v0=(%f, %f, %f), f0=(%f, %f, %f))",
-                                               numAtoms, nStep, timestep,
+                                               numAtoms, numSteps, timestep,
                                                v0[XX], v0[YY], v0[ZZ],
                                                f0[XX], f0[YY], f0[ZZ]);
 
-
     init(numAtoms, timestep, v0, f0);
 
-    std::unique_ptr<LeapFrogCuda> integrator = std::make_unique<LeapFrogCuda>();
-
-    integrator->set(mdAtoms_);
-
-    for (int step = 0; step < nStep; step++)
-    {
-        integrator->copyIntegrateCopy(numAtoms,
-                                      (rvec*)(x_.data()),
-                                      (rvec*)(xPrime_.data()),
-                                      (rvec*)(v_.data()),
-                                      (rvec*)(f_.data()),
-                                      timestep_);
-
-        for (int i = 0; i < numAtoms; i++)
-        {
-            for (int d = 0; d < DIM; d++)
-            {
-                x_.at(i)[d] = xPrime_.at(i)[d];
-            }
-        }
-    }
+    integrateLeapFrogCuda(numAtoms,
+                          (rvec*)(x_.data()),
+                          (rvec*)(xPrime_.data()),
+                          (rvec*)(v_.data()),
+                          (rvec*)(f_.data()),
+                          timestep_,
+                          numSteps,
+                          mdAtoms_);
 
-    real totalTime = nStep*timestep;
+    real totalTime = numSteps*timestep;
     // TODO For the case of constant force, the numerical scheme is exact and
     //      the only source of errors is floating point arithmetic. Hence,
     //      the tolerance can be calculated.
-    FloatingPointTolerance tolerance = absoluteTolerance(nStep*0.000005);
+    FloatingPointTolerance tolerance = absoluteTolerance(numSteps*0.000005);
 
     for (unsigned i = 0; i < x_.size(); i++)
     {
diff --git a/src/gromacs/mdlib/tests/leapfrog.cu b/src/gromacs/mdlib/tests/leapfrog.cu
new file mode 100644 (file)
index 0000000..2281e49
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, 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.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief Run integration using CUDA
+ *
+ * Handles GPU data management and actual numerical integration.
+ *
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ * \ingroup module_mdlib
+ */
+#include "gmxpre.h"
+
+#include <assert.h>
+
+#include <cmath>
+
+#include <algorithm>
+#include <unordered_map>
+#include <vector>
+
+#include "gromacs/gpu_utils/devicebuffer.cuh"
+#include "gromacs/gpu_utils/gpu_utils.h"
+#include "gromacs/math/vec.h"
+#include "gromacs/mdlib/leapfrog_cuda.cuh"
+
+#include "leapfrogtest.h"
+
+namespace gmx
+{
+namespace test
+{
+
+void integrateLeapFrogCuda(const int        numAtoms,
+                           const rvec      *h_x,
+                           rvec            *h_xp,
+                           rvec            *h_v,
+                           const rvec      *h_f,
+                           const real       dt,
+                           const int        numSteps,
+                           t_mdatoms        mdAtoms)
+{
+    float3 *d_x, *d_xp, *d_v, *d_f;
+
+    allocateDeviceBuffer(&d_x,  numAtoms, nullptr);
+    allocateDeviceBuffer(&d_xp, numAtoms, nullptr);
+    allocateDeviceBuffer(&d_v,  numAtoms, nullptr);
+    allocateDeviceBuffer(&d_f,  numAtoms, nullptr);
+
+    copyToDeviceBuffer(&d_x,  (float3*)h_x,  0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr);
+    copyToDeviceBuffer(&d_xp, (float3*)h_xp, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr);
+    copyToDeviceBuffer(&d_v,  (float3*)h_v,  0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr);
+    copyToDeviceBuffer(&d_f,  (float3*)h_f,  0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr);
+
+    auto integrator = std::make_unique<LeapFrogCuda>();
+
+    integrator->set(mdAtoms);
+
+    for (int step = 0; step < numSteps; step++)
+    {
+        integrator->integrate(d_x, d_xp, d_v, d_f, dt);
+
+        copyFromDeviceBuffer((float3*)h_xp, &d_xp, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr);
+        copyToDeviceBuffer(&d_x,    (float3*)h_xp, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr);
+    }
+
+    copyFromDeviceBuffer((float3*)h_xp, &d_xp, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr);
+    copyFromDeviceBuffer((float3*)h_v,  &d_v,  0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr);
+
+    freeDeviceBuffer(&d_x);
+    freeDeviceBuffer(&d_xp);
+    freeDeviceBuffer(&d_v);
+    freeDeviceBuffer(&d_f);
+}
+
+}   // namespace test
+}   // namespace gmx
similarity index 57%
rename from src/gromacs/mdlib/leapfrog_cuda_impl.cpp
rename to src/gromacs/mdlib/tests/leapfrogtest.h
index f93dcf2b152c2b0489549ce4d3c1c6c614a670a1..ca2124137f604d2d2e74261d58b2443e03e3c9a2 100644 (file)
  * the research papers on the package. Check out http://www.gromacs.org.
  */
 /*! \internal \file
- *
- * \brief May be used to implement Leap-Frog CUDA interfaces for non-GPU builds.
- *
- * Currently, reports and exits if any of the interfaces are called.
- * Needed to satisfy compiler on systems, where CUDA is not available.
+ * \brief Declaration of interfaces to run integrator on various devices
  *
  * \author Artem Zhmurov <zhmurov@gmail.com>
- *
  * \ingroup module_mdlib
  */
-#include "gmxpre.h"
 
 #include "config.h"
 
-#include "gromacs/mdlib/leapfrog_cuda.h"
+#include "gromacs/math/vec.h"
 
-#if GMX_GPU != GMX_GPU_CUDA
+struct t_mdatoms;
 
 namespace gmx
 {
-
-class LeapFrogCuda::Impl
+namespace test
 {
-};
-
-LeapFrogCuda::LeapFrogCuda()
-    : impl_(nullptr)
-{
-    GMX_ASSERT(false, "A CPU stub for LeapFrog was called insted of the correct implementation.");
-}
-
-LeapFrogCuda::~LeapFrogCuda() = default;
 
-void LeapFrogCuda::copyIntegrateCopy(gmx_unused const int   numAtoms,
-                                     gmx_unused const rvec *h_x,
-                                     gmx_unused rvec       *h_xp,
-                                     gmx_unused rvec       *h_v,
-                                     gmx_unused const rvec *h_f,
-                                     gmx_unused const real  dt)
-{
-    GMX_ASSERT(false, "A CPU stub for LeapFrog was called insted of the correct implementation.");
-}
+#if GMX_GPU == GMX_GPU_CUDA
 
-void LeapFrogCuda::setPbc(gmx_unused const t_pbc *pbc)
-{
-    GMX_ASSERT(false, "A CPU stub for LeapFrog was called insted of the correct implementation.");
-}
+/*! \brief Integrate using CUDA version of Leap-Frog
+ *
+ * Copies data from CPU to GPU, integrates the equation of motion
+ * for requested number of steps using Leap-Frog algorithm, copies
+ * the result back.
+ *
+ * \param[in]     numAtoms  Number of atoms.
+ * \param[in]     h_x       Initial coordinates.
+ * \param[out]    h_xp      Place to save the resulting coordinates to.
+ * \param[in,out] h_v       Velocities (will be updated).
+ * \param[in]     h_f       Forces.
+ * \param[in]     dt        Timestep.
+ * \param[in]     numSteps  Total number of steps to runtegration for.
+ * \param[in]     mdAtoms   Infromation on atoms (atom masses are used here).
+ */
+void integrateLeapFrogCuda(int         numAtoms,
+                           const rvec *h_x,
+                           rvec       *h_xp,
+                           rvec       *h_v,
+                           const rvec *h_f,
+                           real        dt,
+                           int         numSteps,
+                           t_mdatoms   mdAtoms);
 
-void LeapFrogCuda::set(gmx_unused const t_mdatoms &md)
-{
-    GMX_ASSERT(false, "A CPU stub for LeapFrog was called insted of the correct implementation.");
-}
+#endif // GMX_GPU == GMX_GPU_CUDA
 
+}      // namespace test
 }      // namespace gmx
-
-#endif /* GMX_GPU != GMX_GPU_CUDA */
index 3f0f3067158f8655c25759f7ca2fccc3cc20ddd8..cdd56bc2c6cffafd70a0b584f7956eb7528e1a9c 100644 (file)
 #include "gromacs/gpu_utils/gputraits.cuh"
 #include "gromacs/gpu_utils/vectype_ops.cuh"
 #include "gromacs/math/vec.h"
+#include "gromacs/mdlib/leapfrog_cuda.cuh"
 #include "gromacs/mdlib/lincs_cuda.cuh"
 #include "gromacs/mdlib/settle_cuda.cuh"
 #include "gromacs/mdlib/update_constrain_cuda.h"
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/pbcutil/pbc_aiuc_cuda.cuh"
 
-#include "leapfrog_cuda_impl.h"
-
 namespace gmx
 {
 
@@ -120,10 +119,9 @@ UpdateConstrainCuda::Impl::Impl(int                numAtoms,
     stream_ = nullptr;
 
     GMX_RELEASE_ASSERT(numAtoms == mtop.natoms, "State and topology number of atoms should be the same.");
-    integrator_ = std::make_unique<LeapFrogCuda::Impl>();
     lincsCuda_  = std::make_unique<LincsCuda>(ir.nLincsIter, ir.nProjOrder);
     settleCuda_ = std::make_unique<SettleCuda>(mtop);
-
+    integrator_ = std::make_unique<LeapFrogCuda>();
 }
 
 UpdateConstrainCuda::Impl::~Impl()
index e3d893b6cd296d4706da465f2f3af07dd92e55aa..76b120810d69cb6ccb4b51bebb39a93f5d621ee6 100644 (file)
@@ -48,6 +48,7 @@
 
 #include "gmxpre.h"
 
+#include "gromacs/mdlib/leapfrog_cuda.cuh"
 #include "gromacs/mdlib/lincs_cuda.cuh"
 #include "gromacs/mdlib/settle_cuda.cuh"
 #include "gromacs/mdlib/update_constrain_cuda.h"
@@ -56,8 +57,6 @@
 #include "gromacs/pbcutil/pbc_aiuc_cuda.cuh"
 #include "gromacs/topology/idef.h"
 
-#include "leapfrog_cuda_impl.h"
-
 namespace gmx
 {
 
@@ -205,7 +204,7 @@ class UpdateConstrainCuda::Impl
         real               *d_inverseMasses_;
 
         //! Leap-Frog integrator
-        std::unique_ptr<LeapFrogCuda::Impl>  integrator_;
+        std::unique_ptr<LeapFrogCuda>        integrator_;
         //! LINCS CUDA object to use for non-water constraints
         std::unique_ptr<LincsCuda>           lincsCuda_;
         //! SETTLE CUDA object for water constrains