Remove PImpl scaffolding from CUDA version of SETTLE
authorArtem Zhmurov <zhmurov@gmail.com>
Mon, 27 May 2019 16:56:39 +0000 (18:56 +0200)
committerArtem Zhmurov <zhmurov@gmail.com>
Fri, 26 Jul 2019 08:20:31 +0000 (10:20 +0200)
GPU version of SETTLE was implemented as a class with private
implementation so it will be possible to initialize on
non-CUDA hosts. Now, the implementation can be hidden
inside the Update and Constraints PImpl so that the CUDA
specific types and calls can be exposed in SETTLE and
private implementation is no longer needed there.

Refs #2816, #2888

Change-Id: I4c78f2629be34b42bb5f4f7d34970c3e41515691

src/gromacs/mdlib/CMakeLists.txt
src/gromacs/mdlib/settle_cuda.cu [moved from src/gromacs/mdlib/settle_cuda_impl.cu with 89% similarity]
src/gromacs/mdlib/settle_cuda.cuh [moved from src/gromacs/mdlib/settle_cuda_impl.h with 80% similarity]
src/gromacs/mdlib/settle_cuda.h [deleted file]
src/gromacs/mdlib/settle_cuda_impl.cpp [deleted file]
src/gromacs/mdlib/tests/CMakeLists.txt
src/gromacs/mdlib/tests/settle.cpp
src/gromacs/mdlib/tests/settle_runners.cu [new file with mode: 0644]
src/gromacs/mdlib/tests/settle_runners.h [new file with mode: 0644]
src/gromacs/mdlib/update_constrain_cuda_impl.cu
src/gromacs/mdlib/update_constrain_cuda_impl.h

index 9b37d64041b76624811388e04c703449214f3b74..506c0160e84c6ee20e963f240386648787eb3fee 100644 (file)
@@ -42,7 +42,7 @@ if(GMX_USE_CUDA)
     gmx_add_libgromacs_sources(
        leapfrog_cuda_impl.cu
        lincs_cuda.cu
-       settle_cuda_impl.cu
+       settle_cuda.cu
        update_constrain_cuda_impl.cu
        )
 endif()
similarity index 89%
rename from src/gromacs/mdlib/settle_cuda_impl.cu
rename to src/gromacs/mdlib/settle_cuda.cu
index 8371e75876bfb85458046dec872f3fca1299b282..633ec901771629611cdbde68448e887371dc0f12 100644 (file)
@@ -51,7 +51,7 @@
  */
 #include "gmxpre.h"
 
-#include "settle_cuda_impl.h"
+#include "settle_cuda.cuh"
 
 #include <assert.h>
 #include <stdio.h>
@@ -66,7 +66,6 @@
 #include "gromacs/gpu_utils/gputraits.cuh"
 #include "gromacs/gpu_utils/vectype_ops.cuh"
 #include "gromacs/math/vec.h"
-#include "gromacs/mdlib/settle_cuda.h"
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/pbcutil/pbc_aiuc_cuda.cuh"
 
@@ -100,7 +99,7 @@ template <bool updateVelocities, bool computeVirial>
 __launch_bounds__(c_maxThreadsPerBlock)
 __global__ void settle_kernel(const int                            numSettles,
                               const int3*  __restrict__            gm_settles,
-                              const SettleCuda::SettleParameters   pars,
+                              const SettleParameters               pars,
                               const float3*  __restrict__          gm_x,
                               float3*  __restrict__                gm_xprime,
                               const PbcAiuc                        pbcAiuc,
@@ -412,13 +411,13 @@ inline auto getSettleKernelPtr(const bool  updateVelocities,
     return kernelPtr;
 }
 
-void SettleCuda::Impl::apply(const float3 *d_x,
-                             float3       *d_xp,
-                             const bool    updateVelocities,
-                             float3       *d_v,
-                             const real    invdt,
-                             const bool    computeVirial,
-                             tensor        virialScaled)
+void SettleCuda::apply(const float3 *d_x,
+                       float3       *d_xp,
+                       const bool    updateVelocities,
+                       float3       *d_v,
+                       const real    invdt,
+                       const bool    computeVirial,
+                       tensor        virialScaled)
 {
 
     ensureNoPendingCudaError("In CUDA version SETTLE");
@@ -499,43 +498,7 @@ void SettleCuda::Impl::apply(const float3 *d_x,
     return;
 }
 
-void SettleCuda::Impl::copyApplyCopy(const int   numAtoms,
-                                     const rvec *h_x,
-                                     rvec       *h_xp,
-                                     const bool  updateVelocities,
-                                     rvec       *h_v,
-                                     const real  invdt,
-                                     const bool  computeVirial,
-                                     tensor      virialScaled)
-{
-    float3 *d_x, *d_xp, *d_v;
-
-    allocateDeviceBuffer(&d_x,  numAtoms, nullptr);
-    allocateDeviceBuffer(&d_xp, numAtoms, nullptr);
-    allocateDeviceBuffer(&d_v,  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);
-    if (updateVelocities)
-    {
-        copyToDeviceBuffer(&d_v, (float3*)h_v, 0, numAtoms, stream_, GpuApiCallBehavior::Sync, nullptr);
-    }
-    apply(d_x, d_xp,
-          updateVelocities, d_v, invdt,
-          computeVirial, virialScaled);
-
-    copyFromDeviceBuffer((float3*)h_xp, &d_xp, 0, numAtoms, stream_, GpuApiCallBehavior::Sync, nullptr);
-    if (updateVelocities)
-    {
-        copyFromDeviceBuffer((float3*)h_v, &d_v, 0, numAtoms, stream_, GpuApiCallBehavior::Sync, nullptr);
-    }
-
-    freeDeviceBuffer(&d_x);
-    freeDeviceBuffer(&d_xp);
-    freeDeviceBuffer(&d_v);
-}
-
-SettleCuda::Impl::Impl(const gmx_mtop_t &mtop)
+SettleCuda::SettleCuda(const gmx_mtop_t &mtop)
 {
     static_assert(sizeof(real) == sizeof(float),
                   "Real numbers should be in single precision in GPU code.");
@@ -636,7 +599,7 @@ SettleCuda::Impl::Impl(const gmx_mtop_t &mtop)
 
 }
 
-SettleCuda::Impl::Impl(const real mO,  const real mH,
+SettleCuda::SettleCuda(const real mO,  const real mH,
                        const real dOH, const real dHH)
 {
     static_assert(sizeof(real) == sizeof(float), "Real numbers should be in single precision in GPU code.");
@@ -653,7 +616,7 @@ SettleCuda::Impl::Impl(const real mO,  const real mH,
 
 }
 
-SettleCuda::Impl::~Impl()
+SettleCuda::~SettleCuda()
 {
     // Early exit if there is no settles
     if (numSettles_ == 0)
@@ -667,9 +630,8 @@ SettleCuda::Impl::~Impl()
     }
 }
 
-
-void SettleCuda::Impl::set(const t_idef               &idef,
-                           const t_mdatoms gmx_unused &md)
+void SettleCuda::set(const t_idef               &idef,
+                     const t_mdatoms gmx_unused &md)
 {
     const int  nral1     = 1 + NRAL(F_SETTLE);
     t_ilist    il_settle = idef.il[F_SETTLE];
@@ -692,47 +654,9 @@ void SettleCuda::Impl::set(const t_idef               &idef,
 
 }
 
-void SettleCuda::Impl::setPbc(const t_pbc *pbc)
-{
-    setPbcAiuc(pbc->ndim_ePBC, pbc->box, &pbcAiuc_);
-}
-
-SettleCuda::SettleCuda(const gmx_mtop_t &mtop)
-    : impl_(new Impl(mtop))
-{
-}
-
-SettleCuda::SettleCuda(const real mO,  const real mH,
-                       const real dOH, const real dHH)
-    : impl_(new Impl(mO, mH, dOH, dHH))
-{
-}
-
-SettleCuda::~SettleCuda() = default;
-
-void SettleCuda::copyApplyCopy(const int   numAtoms,
-                               const rvec *h_x,
-                               rvec       *h_xp,
-                               const bool  updateVelocities,
-                               rvec       *h_v,
-                               const real  invdt,
-                               const bool  computeVirial,
-                               tensor      virialScaled)
-{
-    impl_->copyApplyCopy(numAtoms, h_x, h_xp,
-                         updateVelocities, h_v, invdt,
-                         computeVirial, virialScaled);
-}
-
 void SettleCuda::setPbc(const t_pbc *pbc)
 {
-    impl_->setPbc(pbc);
-}
-
-void SettleCuda::set(const t_idef    &idef,
-                     const t_mdatoms &md)
-{
-    impl_->set(idef, md);
+    setPbcAiuc(pbc->ndim_ePBC, pbc->box, &pbcAiuc_);
 }
 
 } // namespace gmx
similarity index 80%
rename from src/gromacs/mdlib/settle_cuda_impl.h
rename to src/gromacs/mdlib/settle_cuda.cuh
index 2cba615d3b742c769f7fa4f2a322161b7ea02137..412bbc8bb71b4936bfc701ff9a0921555c1a679e 100644 (file)
  */
 /*! \internal \file
  *
- * \brief Declares CUDA implementation class for SETTLE
- *
- * This header file is needed to include from both the device-side
- * kernels file, and the host-side management code.
+ * \brief Declares class for CUDA implementation of SETTLE
  *
  * \author Artem Zhmurov <zhmurov@gmail.com>
  *
  * \ingroup module_mdlib
  */
-#ifndef GMX_MDLIB_SETTLE_CUDA_IMPL_H
-#define GMX_MDLIB_SETTLE_CUDA_IMPL_H
+#ifndef GMX_MDLIB_SETTLE_CUDA_CUH
+#define GMX_MDLIB_SETTLE_CUDA_CUH
+
+#include "gmxpre.h"
 
-#include "gromacs/mdlib/settle_cuda.h"
+#include "gromacs/math/functions.h"
+#include "gromacs/math/invertmatrix.h"
+#include "gromacs/math/vec.h"
 #include "gromacs/mdtypes/mdatom.h"
-#include "gromacs/pbcutil/pbc_aiuc_cuda.cuh"
+#include "gromacs/pbcutil/pbc.h"
+#include "gromacs/pbcutil/pbc_aiuc.h"
 #include "gromacs/topology/idef.h"
+#include "gromacs/topology/topology.h"
 
 namespace gmx
 {
@@ -61,7 +64,7 @@ namespace gmx
  * \todo Remove duplicates, check if recomputing makes more sense in some cases.
  * \todo Move the projection parameters into separate structure.
  */
-struct SettleCuda::SettleParameters
+struct SettleParameters
 {
     //! Mass of oxygen atom
     float   mO;
@@ -144,7 +147,7 @@ static void initializeProjectionMatrix(const real invmO, const real invmH,
  * \param[in]  dHH  Target H-H bond length
  */
 gmx_unused // Temporary solution to keep clang happy
-static void initSettleParameters(SettleCuda::SettleParameters *p,
+static void initSettleParameters(SettleParameters *p,
                                  const real mO,  const real mH,
                                  const real dOH, const real dHH)
 {
@@ -181,7 +184,7 @@ static void initSettleParameters(SettleCuda::SettleParameters *p,
 }
 
 /*! \internal \brief Class with interfaces and data for CUDA version of SETTLE. */
-class SettleCuda::Impl
+class SettleCuda
 {
 
     public:
@@ -195,7 +198,7 @@ class SettleCuda::Impl
          *                      target O-H and H-H distances. These values are also checked for
          *                      consistency.
          */
-        Impl(const gmx_mtop_t  &mtop);
+        SettleCuda(const gmx_mtop_t  &mtop);
 
         /*! \brief Create SETTLE object
          *
@@ -204,10 +207,10 @@ class SettleCuda::Impl
          * \param[in] dOH       Target distance for O-H bonds.
          * \param[in] dHH       Target for the distance between two hydrogen atoms.
          */
-        Impl(const real mO,  const real mH,
-             const real dOH, const real dHH);
+        SettleCuda(const real mO,  const real mH,
+                   const real dOH, const real dHH);
 
-        ~Impl();
+        ~SettleCuda();
 
         /*! \brief Apply SETTLE.
          *
@@ -236,38 +239,6 @@ class SettleCuda::Impl
                    const bool    computeVirial,
                    tensor        virialScaled);
 
-        /*! \brief Apply SETTLE to the coordinates/velocities stored in CPU memory.
-         *
-         * This method should not be used in any code-path, where performance is of any value.
-         * Only suitable for test and will be removed in future patch sets.
-         * Allocates GPU memory, copies data from CPU, applies SETTLE to coordinates and,
-         * if requested, to velocities, copies the results back, frees GPU memory.
-         * Method uses this class data structures which should be filled with set() and setPbc()
-         * methods.
-         *
-         * \todo Remove this method
-         *
-         * \param[in]     numAtoms          Number of atoms
-         * \param[in]     h_x               Coordinates before timestep (in CPU memory)
-         * \param[in,out] h_xp              Coordinates after timestep (in CPU memory). The
-         *                                  resulting constrained coordinates will be saved here.
-         * \param[in]     updateVelocities  If the velocities should be updated.
-         * \param[in,out] h_v               Velocities to update (in CPU memory, can be nullptr
-         *                                  if not updated)
-         * \param[in]     invdt             Reciprocal timestep (to scale Lagrange
-         *                                  multipliers when velocities are updated)
-         * \param[in]     computeVirial     If virial should be updated.
-         * \param[in,out] virialScaled      Scaled virial tensor to be updated.
-         */
-        void copyApplyCopy(const int   numAtoms,
-                           const rvec *h_x,
-                           rvec       *h_xp,
-                           const bool  updateVelocities,
-                           rvec       *h_v,
-                           const real  invdt,
-                           const bool  computeVirial,
-                           tensor      virialScaled);
-
         /*! \brief
          * Update data-structures (e.g. after NB search step).
          *
diff --git a/src/gromacs/mdlib/settle_cuda.h b/src/gromacs/mdlib/settle_cuda.h
deleted file mode 100644 (file)
index b553cde..0000000
+++ /dev/null
@@ -1,162 +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.
- */
-/*! \libinternal \file
- *
- * \brief Declaration of high-level functions of CUDA implementation of SETTLE.
- *
- * \todo This should only list interfaces needed for libgromacs clients.
- *
- * \author Artem Zhmurov <zhmurov@gmail.com>
- *
- * \ingroup module_mdlib
- * \inlibraryapi
- */
-#ifndef GMX_MDLIB_SETTLE_CUDA_H
-#define GMX_MDLIB_SETTLE_CUDA_H
-
-#include "gromacs/math/invertmatrix.h"
-#include "gromacs/mdtypes/mdatom.h"
-#include "gromacs/topology/idef.h"
-#include "gromacs/topology/topology.h"
-#include "gromacs/utility/classhelpers.h"
-
-namespace gmx
-{
-
-// TODO: Rename to SettleGpu
-class SettleCuda
-{
-
-    public:
-
-        /*! \brief Structure containing parameters for settles.
-         *
-         * Contains masses of atoms, distances between them and their pre-computed
-         * derivatives (to avoid recomputing them for each water molecule).
-         */
-        struct SettleParameters;
-
-        /*! \brief Create SETTLE object
-         *
-         *  Extracts masses for oxygen and hydrogen as well as the O-H and H-H target distances
-         *  from the topology data (mtop), check their values for consistency and calls the
-         *  following constructor.
-         *
-         * \param[in] mtop      Topology of the system to get the masses for O and H atoms and
-         *                      target O-H and H-H distances. These values are also checked for
-         *                      consistency.
-         */
-        SettleCuda(const gmx_mtop_t &mtop);
-
-        /*! \brief Create SETTLE object
-         *
-         * \param[in] mO        Mass of the oxygen atom.
-         * \param[in] mH        Mass of the hydrogen atom.
-         * \param[in] dOH       Target distance for O-H bonds.
-         * \param[in] dHH       Target for the distance between two hydrogen atoms.
-         */
-        SettleCuda(real mO,  real mH,
-                   real dOH, real dHH);
-
-        ~SettleCuda();
-
-        /*! \brief Apply SETTLE to the coordinates/velocities stored in CPU memory.
-         *
-         * This method should not be used in any code-path, where performance is of any value.
-         * Only suitable for test and will be removed in future patch sets.
-         * Allocates GPU memory, copies data from CPU, applies SETTLE to coordinates and,
-         * if requested, to velocities, copies the results back, frees GPU memory.
-         * Method uses this class data structures which should be filled with set() and setPbc()
-         * methods.
-         *
-         * \todo Remove this method
-         *
-         * \param[in]     numAtoms          Number of atoms
-         * \param[in]     h_x               Coordinates before timestep (in CPU memory)
-         * \param[in,out] h_xp              Coordinates after timestep (in CPU memory). The
-         *                                  resulting constrained coordinates will be saved here.
-         * \param[in]     updateVelocities  If the velocities should be updated.
-         * \param[in,out] h_v               Velocities to update (in CPU memory, can be nullptr
-         *                                  if not updated)
-         * \param[in]     invdt             Reciprocal timestep (to scale Lagrange
-         *                                  multipliers when velocities are updated)
-         * \param[in]     computeVirial     If virial should be updated.
-         * \param[in,out] virialScaled      Scaled virial tensor to be updated.
-         */
-        void copyApplyCopy(int         numAtoms,
-                           const rvec *h_x,
-                           rvec       *h_xp,
-                           bool        updateVelocities,
-                           rvec       *h_v,
-                           real        invdt,
-                           bool        computeVirial,
-                           tensor      virialScaled);
-
-        /*! \brief
-         * Update data-structures (e.g. after NB search step).
-         *
-         * Updates the constraints data and copies it to the GPU. Should be
-         * called if the particles were sorted, redistributed between domains, etc.
-         * Does not recycle the data preparation routines from the CPU version.
-         * All three atoms from single water molecule should be handled by the same GPU.
-         *
-         * SETTLEs atom ID's are taken from idef.il[F_SETTLE].iatoms.
-         *
-         * \param[in] idef    System topology
-         * \param[in] md      Atoms data. Can be used to update masses if needed (not used now).
-         */
-        void set(const t_idef     &idef,
-                 const t_mdatoms  &md);
-
-        /*! \brief
-         * Update PBC data.
-         *
-         * \param[in] pbc  The PBC data in t_pbc format.
-         */
-        void setPbc(const t_pbc *pbc);
-
-        /*! \brief Class with hardware-specific interfaces and implementations.*/
-        class Impl;
-
-    private:
-        gmx::PrivateImplPointer<Impl> impl_;
-
-
-
-};
-
-} // namespace gmx
-
-#endif
diff --git a/src/gromacs/mdlib/settle_cuda_impl.cpp b/src/gromacs/mdlib/settle_cuda_impl.cpp
deleted file mode 100644 (file)
index 0a4b588..0000000
+++ /dev/null
@@ -1,101 +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 Stub file to compile on systems without CUDA compiler.
- *
- * May be used to implement SETTLE CUDA interfaces for non-GPU builds.
- * Currently used to satisfy compiler on systems, where CUDA is not available.
- *
- * \author Artem Zhmurov <zhmurov@gmail.com>
- *
- * \ingroup module_mdlib
- */
-#include "gmxpre.h"
-
-#include "config.h"
-
-#include "gromacs/mdlib/settle_cuda.h"
-
-#if GMX_GPU != GMX_GPU_CUDA
-
-namespace gmx
-{
-
-class SettleCuda::Impl
-{
-};
-
-SettleCuda::SettleCuda(gmx_unused const gmx_mtop_t &mtop)
-    : impl_(nullptr)
-{
-    GMX_ASSERT(false, "A CPU stub for SETTLE was called insted of the correct implementation.");
-}
-
-SettleCuda::SettleCuda(gmx_unused const real mO,  gmx_unused const real mH,
-                       gmx_unused const real dOH, gmx_unused const real dHH)
-    : impl_(nullptr)
-{
-    GMX_ASSERT(false, "A CPU stub for SETTLE was called insted of the correct implementation.");
-}
-
-SettleCuda::~SettleCuda() = default;
-
-void SettleCuda::copyApplyCopy(gmx_unused int         numAtoms,
-                               gmx_unused const rvec *h_x,
-                               gmx_unused rvec       *h_xp,
-                               gmx_unused bool        updateVelocities,
-                               gmx_unused rvec       *h_v,
-                               gmx_unused real        invdt,
-                               gmx_unused bool        computeVirial,
-                               gmx_unused tensor      virialScaled)
-{
-    GMX_ASSERT(false, "A CPU stub for SETTLE was called insted of the correct implementation.");
-}
-
-void SettleCuda::set(gmx_unused const t_idef     &idef,
-                     gmx_unused const t_mdatoms  &md)
-{
-    GMX_ASSERT(false, "A CPU stub for SETTLE was called insted of the correct implementation.");
-}
-
-void SettleCuda::setPbc(gmx_unused const t_pbc *pbc)
-{
-    GMX_ASSERT(false, "A CPU stub for SETTLE was called insted of the correct implementation.");
-}
-
-}      // namespace gmx
-
-#endif /* GMX_GPU != GMX_GPU_CUDA */
index e3ac4b1cfe281b44470c88ecd334d35bab44374d..15ad0b1a1aeca64c5f74a75268c0b55a7413357d 100644 (file)
@@ -39,6 +39,7 @@ file(GLOB MDLIB_TEST_SOURCES
 if (GMX_USE_CUDA)
     file(GLOB MDLIB_TEST_CUDA_SOURCES
          constr_impl.cu
+         settle_runners.cu
          )
 endif()
 
index f0f1865ea516e1f0da2affd5065f701a19f0823b..642ceb4117b68f4ca4e050270ae820603a2665ac 100644 (file)
@@ -47,7 +47,6 @@
 #include "gromacs/math/paddedvector.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/math/vectypes.h"
-#include "gromacs/mdlib/settle_cuda.h"
 #include "gromacs/mdtypes/mdatom.h"
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/topology/idef.h"
@@ -60,6 +59,8 @@
 #include "gromacs/mdlib/tests/watersystem.h"
 #include "testutils/testasserts.h"
 
+#include "settle_runners.h"
+
 namespace gmx
 {
 
@@ -86,9 +87,9 @@ class SettleTest : public ::testing::TestWithParam<SettleTestParameters>
 {
     public:
         //! Updated water atom positions to constrain (DIM reals per atom)
-        PaddedVector<gmx::RVec> updatedPositions_;
+        PaddedVector<RVec>      updatedPositions_;
         //! Water atom velocities to constrain (DIM reals per atom)
-        PaddedVector<gmx::RVec> velocities_;
+        PaddedVector<RVec>      velocities_;
         //! No periodic boundary conditions
         t_pbc                   pbcNone_;
         //! Rectangular periodic box
@@ -199,7 +200,7 @@ TEST_P(SettleTest, SatisfiesConstraints)
     const t_ilist  ilist   = { mtop.moltype[0].ilist[F_SETTLE].size(), 0, mtop.moltype[0].ilist[F_SETTLE].iatoms.data(), 0 };
 
     // Copy the original positions from the array of doubles to a vector of reals
-    PaddedVector<gmx::RVec> startingPositions;
+    PaddedVector<RVec> startingPositions;
     startingPositions.resizeWithPadding(c_waterPositions.size());
     std::copy(c_waterPositions.begin(), c_waterPositions.end(), startingPositions.begin());
 
@@ -208,10 +209,10 @@ TEST_P(SettleTest, SatisfiesConstraints)
 
 #if GMX_GPU == GMX_GPU_CUDA
     // Make a copy of all data-structures for GPU code testing
-    PaddedVector<gmx::RVec> updatedPositionsGpu   = updatedPositions_;
-    PaddedVector<gmx::RVec> velocitiesGpu         = velocities_;
-    tensor                  virialGpu             = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
-#endif
+    PaddedVector<RVec> updatedPositionsGpu   = updatedPositions_;
+    PaddedVector<RVec> velocitiesGpu         = velocities_;
+    tensor             virialGpu             = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
+#endif      // GMX_GPU == GMX_GPU_CUDA
 
     // Finally make the settle data structures
     settledata    *settled = settle_init(mtop);
@@ -239,9 +240,9 @@ TEST_P(SettleTest, SatisfiesConstraints)
     // Verify the updated coordinates match the requirements
     for (int i = 0; i < numSettles; ++i)
     {
-        const gmx::RVec &positionO  = updatedPositions_[i*3 + 0];
-        const gmx::RVec &positionH1 = updatedPositions_[i*3 + 1];
-        const gmx::RVec &positionH2 = updatedPositions_[i*3 + 2];
+        const RVec &positionO  = updatedPositions_[i*3 + 0];
+        const RVec &positionH1 = updatedPositions_[i*3 + 1];
+        const RVec &positionH2 = updatedPositions_[i*3 + 2];
 
         EXPECT_REAL_EQ_TOL(dOH*dOH, distance2(positionO, positionH1), tolerance) << formatString("for water %d ", i) << testDescription;
         EXPECT_REAL_EQ_TOL(dOH*dOH, distance2(positionO, positionH2), tolerance) << formatString("for water %d ", i) << testDescription;
@@ -291,21 +292,21 @@ TEST_P(SettleTest, SatisfiesConstraints)
     if (canPerformGpuDetection())
     {
         // Run the CUDA code and check if it gives identical results to CPU code
-        t_idef                        idef;
+        t_idef idef;
         idef.il[F_SETTLE] = ilist;
 
-        std::unique_ptr<SettleCuda>   settleCuda = std::make_unique<SettleCuda>(mtop);
-        settleCuda->setPbc(usePbc ? &pbcXyz_ : &pbcNone_);
-        settleCuda->set(idef, mdatoms);
-
-        settleCuda->copyApplyCopy(mdatoms.homenr,
-                                  as_rvec_array(startingPositions.data()),
-                                  as_rvec_array(updatedPositionsGpu.data()),
-                                  useVelocities,
-                                  as_rvec_array(velocitiesGpu.data()),
-                                  reciprocalTimeStep,
-                                  calcVirial,
-                                  virialGpu);
+        applySettleCuda(mdatoms.homenr,
+                        as_rvec_array(startingPositions.data()),
+                        as_rvec_array(updatedPositionsGpu.data()),
+                        useVelocities,
+                        as_rvec_array(velocitiesGpu.data()),
+                        reciprocalTimeStep,
+                        calcVirial,
+                        virialGpu,
+                        usePbc ? &pbcXyz_ : &pbcNone_,
+                        mtop,
+                        idef,
+                        mdatoms);
 
         FloatingPointTolerance toleranceGpuCpu = absoluteTolerance(0.0001);
 
@@ -337,7 +338,7 @@ TEST_P(SettleTest, SatisfiesConstraints)
             }
         }
     }
-#endif
+#endif      // GMX_GPU == GMX_GPU_CUDA
 }
 
 // Scan the full Cartesian product of numbers of SETTLE interactions
diff --git a/src/gromacs/mdlib/tests/settle_runners.cu b/src/gromacs/mdlib/tests/settle_runners.cu
new file mode 100644 (file)
index 0000000..fe6dffc
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2018,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 Implements the test runner for GPU version of SETTLE.
+ *
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ * \ingroup module_mdlib
+ */
+#include "gmxpre.h"
+
+#include "settle_runners.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/math/vectypes.h"
+#include "gromacs/mdlib/settle_cuda.cuh"
+#include "gromacs/utility/unique_cptr.h"
+
+namespace gmx
+{
+namespace test
+{
+
+void applySettleCuda(const int          numAtoms,
+                     const rvec        *h_x,
+                     rvec              *h_xp,
+                     const bool         updateVelocities,
+                     rvec              *h_v,
+                     const real         invdt,
+                     const bool         computeVirial,
+                     tensor             virialScaled,
+                     const t_pbc       *pbc,
+                     const gmx_mtop_t  &mtop,
+                     const t_idef      &idef,
+                     const t_mdatoms   &mdatoms)
+{
+    auto settleCuda = std::make_unique<SettleCuda>(mtop);
+    settleCuda->setPbc(pbc);
+    settleCuda->set(idef, mdatoms);
+
+    float3 *d_x, *d_xp, *d_v;
+
+    allocateDeviceBuffer(&d_x,  numAtoms, nullptr);
+    allocateDeviceBuffer(&d_xp, numAtoms, nullptr);
+    allocateDeviceBuffer(&d_v,  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);
+    if (updateVelocities)
+    {
+        copyToDeviceBuffer(&d_v, (float3*)h_v, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr);
+    }
+    settleCuda->apply(d_x, d_xp,
+                      updateVelocities, d_v, invdt,
+                      computeVirial, virialScaled);
+
+    copyFromDeviceBuffer((float3*)h_xp, &d_xp, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr);
+    if (updateVelocities)
+    {
+        copyFromDeviceBuffer((float3*)h_v, &d_v, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr);
+    }
+
+    freeDeviceBuffer(&d_x);
+    freeDeviceBuffer(&d_xp);
+    freeDeviceBuffer(&d_v);
+}
+
+} // namespace test
+} // namespace gmx
diff --git a/src/gromacs/mdlib/tests/settle_runners.h b/src/gromacs/mdlib/tests/settle_runners.h
new file mode 100644 (file)
index 0000000..05d3bd5
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2018,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 SETTLE tests header.
+ *
+ * Declares the functions that do the buffer management and apply
+ * SETTLE constraints ("test runners").
+ *
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ * \ingroup module_mdlib
+ */
+
+#ifndef GMX_MDLIB_TESTS_SETTLE_RUNNERS_H
+#define GMX_MDLIB_TESTS_SETTLE_RUNNERS_H
+
+#include "config.h"
+
+#include "gromacs/math/vectypes.h"
+
+struct t_pbc;
+struct gmx_mtop_t;
+struct t_idef;
+struct t_mdatoms;
+
+namespace gmx
+{
+namespace test
+{
+
+#if GMX_GPU == GMX_GPU_CUDA
+
+/*! \brief
+ * Initialize and apply SETTLE constraints on CUDA-enabled GPU.
+ *
+ * \param[in]     numAtoms          Number of atoms.
+ * \param[in]     h_x               Coordinates before timestep (in CPU memory).
+ * \param[in,out] h_xp              Coordinates after timestep (in CPU memory). The
+ *                                  resulting constrained coordinates will be saved here.
+ * \param[in]     updateVelocities  If the velocities should be updated.
+ * \param[in,out] h_v               Velocities to update (in CPU memory, can be nullptr
+ *                                  if not updated).
+ * \param[in]     invdt             Reciprocal timestep (to scale Lagrange
+ *                                  multipliers when velocities are updated)
+ * \param[in]     computeVirial     If virial should be updated.
+ * \param[in,out] virialScaled      Scaled virial tensor to be updated.
+ * \param[in]     pbc               Periodic boundary data.
+ * \param[in]     mtop              Topology of the system to get the masses for O and
+ *                                  H atoms target O-H and H-H distances.
+ * \param[in]     idef              System topology.
+ * \param[in]     mdatoms           Atoms data.
+ */
+void applySettleCuda(int                numAtoms,
+                     const rvec        *h_x,
+                     rvec              *h_xp,
+                     bool               updateVelocities,
+                     rvec              *h_v,
+                     real               invdt,
+                     bool               computeVirial,
+                     tensor             virialScaled,
+                     const t_pbc       *pbc,
+                     const gmx_mtop_t  &mtop,
+                     const t_idef      &idef,
+                     const t_mdatoms   &mdatoms);
+
+#endif // GMX_GPU == GMX_GPU_CUDA
+
+}      // namespace test
+}      // namespace gmx
+
+#endif // GMX_MDLIB_TESTS_SETTLE_RUNNERS_H
index 4f66f1260e1c123a34e5797ba21fcf0a760e67ae..3f0f3067158f8655c25759f7ca2fccc3cc20ddd8 100644 (file)
 #include "gromacs/gpu_utils/vectype_ops.cuh"
 #include "gromacs/math/vec.h"
 #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"
-#include "settle_cuda_impl.h"
 
 namespace gmx
 {
@@ -122,7 +122,7 @@ UpdateConstrainCuda::Impl::Impl(int                numAtoms,
     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::Impl>(mtop);
+    settleCuda_ = std::make_unique<SettleCuda>(mtop);
 
 }
 
index 1e6869c21b58410f24814bfc4294245f40c4b39a..e3d893b6cd296d4706da465f2f3af07dd92e55aa 100644 (file)
 #ifndef GMX_MDLIB_UPDATE_CONSTRAIN_CUDA_IMPL_H
 #define GMX_MDLIB_UPDATE_CONSTRAIN_CUDA_IMPL_H
 
+#include "gmxpre.h"
+
 #include "gromacs/mdlib/lincs_cuda.cuh"
+#include "gromacs/mdlib/settle_cuda.cuh"
 #include "gromacs/mdlib/update_constrain_cuda.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/pbcutil/pbc.h"
@@ -54,7 +57,6 @@
 #include "gromacs/topology/idef.h"
 
 #include "leapfrog_cuda_impl.h"
-#include "settle_cuda_impl.h"
 
 namespace gmx
 {
@@ -207,7 +209,7 @@ class UpdateConstrainCuda::Impl
         //! LINCS CUDA object to use for non-water constraints
         std::unique_ptr<LincsCuda>           lincsCuda_;
         //! SETTLE CUDA object for water constrains
-        std::unique_ptr<SettleCuda::Impl>    settleCuda_;
+        std::unique_ptr<SettleCuda>          settleCuda_;
 
 };