Refactor and enable RVec to float conversion test
authorArtem Zhmurov <zhmurov@gmail.com>
Thu, 6 Feb 2020 11:39:39 +0000 (12:39 +0100)
committerPaul Bauer <paul.bauer.q@gmail.com>
Fri, 21 Feb 2020 09:07:40 +0000 (10:07 +0100)
Since using CUDA directly in Google tests is not always possible,
this patch moves the cuda-specific code into separate runner file.
Also the RVec->float3 casting function is moved into new header,
thus eliminating inclusion of the cuda runtime in the tests. The
test file is renamed to reflect what is actually tested.

Fixes the post submit failure introduced in
c5c220a03663d975e31e8573c1849247ce3f8ad0, which was first avoided
by disabling the test in e91b744e8cbf2038a4dddce0609a33f396902bb5.

Fixes #3372.

Change-Id: Ie6423876e7725766109f74fdd3e76a24188b0b18

src/gromacs/domdec/gpuhaloexchange_impl.cu
src/gromacs/ewald/pme_gather.cu
src/gromacs/ewald/pme_spread.cu
src/gromacs/gpu_utils/cudautils.cuh
src/gromacs/gpu_utils/tests/CMakeLists.txt
src/gromacs/gpu_utils/tests/typecasts.cpp [moved from src/gromacs/gpu_utils/tests/gpu_utils.cpp with 65% similarity]
src/gromacs/gpu_utils/tests/typecasts_runner.cpp [new file with mode: 0644]
src/gromacs/gpu_utils/tests/typecasts_runner.cu [new file with mode: 0644]
src/gromacs/gpu_utils/tests/typecasts_runner.h [new file with mode: 0644]
src/gromacs/gpu_utils/typecasts.cuh [new file with mode: 0644]
src/gromacs/nbnxm/cuda/nbnxm_cuda.cu

index 9c5aa5b8fe392cca6adc036d3e4620ef64c5ad37..2ac4228d6f2a6f4c3b3f625d671f6b71ae94ebe8 100644 (file)
@@ -56,6 +56,7 @@
 #include "gromacs/gpu_utils/cudautils.cuh"
 #include "gromacs/gpu_utils/devicebuffer.h"
 #include "gromacs/gpu_utils/gpueventsynchronizer.cuh"
+#include "gromacs/gpu_utils/typecasts.cuh"
 #include "gromacs/gpu_utils/vectype_ops.cuh"
 #include "gromacs/math/vectypes.h"
 #include "gromacs/pbcutil/ishift.h"
index 616516df2335214cb16b118cb84d796d1e7a5b33..63635aac36b10b5031a769a09f9fc907140baf7c 100644 (file)
@@ -44,7 +44,7 @@
 #include <cassert>
 
 #include "gromacs/gpu_utils/cuda_kernel_utils.cuh"
-#include "gromacs/gpu_utils/cudautils.cuh"
+#include "gromacs/gpu_utils/typecasts.cuh"
 
 #include "pme.cuh"
 #include "pme_calculate_splines.cuh"
index 99f7828c86707276d6e976601086d4cd93abf1ae..3fb0ad802fcd0085ecaf0a88b1a6acb136049ae9 100644 (file)
@@ -47,7 +47,7 @@
 #include <cassert>
 
 #include "gromacs/gpu_utils/cuda_kernel_utils.cuh"
-#include "gromacs/gpu_utils/cudautils.cuh"
+#include "gromacs/gpu_utils/typecasts.cuh"
 
 #include "pme.cuh"
 #include "pme_calculate_splines.cuh"
  * Optional second stage of the spline_and_spread_kernel.
  *
  * \tparam[in] order                PME interpolation order.
- * \tparam[in] wrapX                A boolean which tells if the grid overlap in dimension X should
- * be wrapped. \tparam[in] wrapY                A boolean which tells if the grid overlap in
- * dimension Y should be wrapped. \tparam[in] useOrderThreads      A boolean which Tells if we
- * should use order threads per atom (order*order used if false) \param[in]  kernelParams Input PME
- * CUDA data in constant memory. \param[in]  atomIndexOffset      Starting atom index for the
- * execution block w.r.t. global memory. \param[in]  atomCharge           Atom charge/coefficient of
- * atom processed by thread. \param[in]  sm_gridlineIndices   Atom gridline indices in the shared
- * memory. \param[in]  sm_theta             Atom spline values in the shared memory.
+ * \tparam[in] wrapX                Whether the grid overlap in dimension X should be wrapped.
+ * \tparam[in] wrapY                Whether the grid overlap in dimension Y should be wrapped.
+ * \tparam[in] useOrderThreads      Whether we should use order threads per atom (order*order used if false).
+ *
+ * \param[in]  kernelParams         Input PME CUDA data in constant memory.
+ * \param[in]  atomIndexOffset      Starting atom index for the execution block w.r.t. global memory.
+ * \param[in]  atomCharge           Atom charge/coefficient of atom processed by thread.
+ * \param[in]  sm_gridlineIndices   Atom gridline indices in the shared memory.
+ * \param[in]  sm_theta             Atom spline values in the shared memory.
  */
 template<const int order, const bool wrapX, const bool wrapY, const bool useOrderThreads>
 __device__ __forceinline__ void spread_charges(const PmeGpuCudaKernelParams kernelParams,
index 6f41e8589cef48b528bc3e1b48d2967764ae4c0d..71d9b7dac45dac38ac76b96357cdec6b91e0acde 100644 (file)
@@ -215,19 +215,6 @@ static inline void rvec_inc(rvec a, const float3 b)
     rvec tmp = { b.x, b.y, b.z };
     rvec_inc(a, tmp);
 }
-/*! \brief Cast RVec buffer to float3 buffer.
- *
- * \param[in] in The RVec buffer to cast.
- *
- * \returns Buffer, casted to float3*.
- */
-static inline __host__ __device__ float3* asFloat3(gmx::RVec* in)
-{
-    static_assert(sizeof(in[0]) == sizeof(float3),
-                  "Size of the host-side data-type is different from the size of the device-side "
-                  "counterpart.");
-    return reinterpret_cast<float3*>(in);
-}
 
 /*! \brief Wait for all taks in stream \p s to complete.
  *
index d99967c82b07d5c5b9d704c05169b1270e85781b..8d688e9a2d7488d519820740dd998c8bdc0e9225 100644 (file)
@@ -48,7 +48,10 @@ if(GMX_USE_CUDA)
     # CUDA-only test
     list(APPEND SOURCES_FROM_CXX
         pinnedmemorychecker.cpp
+        typecasts.cpp
+        typecasts_runner.cpp
         )
+    gmx_add_libgromacs_sources(typecasts_runner.cu)
     # TODO Making a separate library is heavy handed, but nothing else
     # seems to work. Also don't use a hyphen in its name, because nvcc
     # can't cope with that.
similarity index 65%
rename from src/gromacs/gpu_utils/tests/gpu_utils.cpp
rename to src/gromacs/gpu_utils/tests/typecasts.cpp
index 5adf0a72a7ec481602c3a48c3bcef68317071732..1c415ac908880bf016e20878bf33092a350c8baa 100644 (file)
  */
 #include "gmxpre.h"
 
-#include "config.h"
-
 #include <vector>
 
-#ifndef __CUDA_ARCH__
-/*! \brief Dummy definition to avoid compiler error
- *
- * \todo Find a better solution. Probably, move asFloat3(...) function to different header.
- */
-#    define __CUDA_ARCH__ -1
-#    include <cuda_runtime.h>
-#    undef __CUDA_ARCH__
-#else
-#    include <cuda_runtime.h>
-#endif
 #include <gtest/gtest.h>
 
-#include "gromacs/gpu_utils/cudautils.cuh"
-#include "gromacs/math/vectypes.h"
-#include "gromacs/utility/real.h"
+#include "gromacs/utility/exceptions.h"
 
-#if GMX_GPU == GMX_GPU_CUDA
+#include "testutils/testasserts.h"
+#include "testutils/testmatchers.h"
+
+#include "typecasts_runner.h"
 
 namespace gmx
 {
@@ -69,21 +57,22 @@ namespace gmx
 namespace test
 {
 
-TEST(GpuDataTypesCompatibilityTest, RVecAndFloat3)
+//! Test data in RVec format
+static const std::vector<RVec> rVecInput = { { 1.0, 2.0, 3.0 }, { 4.0, 5.0, 6.0 } };
+
+TEST(GpuDataTypesCompatibilityTest, RVecAndFloat3OnHost)
 {
-    std::vector<RVec> dataRVec;
-    dataRVec.emplace_back(1.0, 2.0, 3.0);
-    dataRVec.emplace_back(4.0, 5.0, 6.0);
-    float3* dataFloat3 = asFloat3(dataRVec.data());
-    EXPECT_EQ(dataFloat3[0].x, dataRVec[0][XX]);
-    EXPECT_EQ(dataFloat3[0].y, dataRVec[0][YY]);
-    EXPECT_EQ(dataFloat3[0].z, dataRVec[0][ZZ]);
-    EXPECT_EQ(dataFloat3[1].x, dataRVec[1][XX]);
-    EXPECT_EQ(dataFloat3[1].y, dataRVec[1][YY]);
-    EXPECT_EQ(dataFloat3[1].z, dataRVec[1][ZZ]);
+    std::vector<RVec> rVecOutput(rVecInput.size());
+    convertRVecToFloat3OnHost(rVecOutput, rVecInput);
+    EXPECT_THAT(rVecInput, testing::Pointwise(RVecEq(ulpTolerance(0)), rVecOutput));
 }
 
-} // namespace test
-} // namespace gmx
+TEST(GpuDataTypesCompatibilityTest, RVecAndFloat3OnDevice)
+{
+    std::vector<RVec> rVecOutput(rVecInput.size());
+    convertRVecToFloat3OnDevice(rVecOutput, rVecInput);
+    EXPECT_THAT(rVecInput, testing::Pointwise(RVecEq(ulpTolerance(0)), rVecOutput));
+}
 
-#endif // GMX_GPU == GMX_GPU_CUDA
\ No newline at end of file
+} // namespace test
+} // namespace gmx
\ No newline at end of file
diff --git a/src/gromacs/gpu_utils/tests/typecasts_runner.cpp b/src/gromacs/gpu_utils/tests/typecasts_runner.cpp
new file mode 100644 (file)
index 0000000..e63dea1
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, 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 for runners for tests types compatibility.
+ *
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ */
+#include "gmxpre.h"
+
+#include "typecasts_runner.h"
+
+#include "config.h"
+
+#include <vector>
+
+#include "testutils/testasserts.h"
+
+#if GMX_GPU != GMX_GPU_CUDA
+
+namespace gmx
+{
+
+namespace test
+{
+
+void convertRVecToFloat3OnHost(std::vector<gmx::RVec>& /* rVecOutput */,
+                               const std::vector<gmx::RVec>& /* rVecInput */)
+{
+    FAIL() << "Can't test float3 and RVec compatibility without CUDA.");
+}
+
+void convertRVecToFloat3OnDevice(std::vector<gmx::RVec>& /* rVecOutput */,
+                                 const std::vector<gmx::RVec>& /* rVecInput*/)
+{
+    FAIL() << "Can't test float3 and RVec compatibility without CUDA.");
+}
+
+} // namespace test
+} // namespace gmx
+
+#endif // GMX_GPU != GMX_GPU_CUDA
\ No newline at end of file
diff --git a/src/gromacs/gpu_utils/tests/typecasts_runner.cu b/src/gromacs/gpu_utils/tests/typecasts_runner.cu
new file mode 100644 (file)
index 0000000..c6615c4
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, 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
+ * Runners for tests of CUDA types compatibility.
+ *
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ */
+#include "gmxpre.h"
+
+#include "typecasts_runner.h"
+
+#include "config.h"
+
+#include <vector>
+
+#include "gromacs/gpu_utils/cudautils.cuh"
+#include "gromacs/gpu_utils/devicebuffer.h"
+#include "gromacs/gpu_utils/gpu_testutils.h"
+#include "gromacs/gpu_utils/typecasts.cuh"
+#include "gromacs/utility/exceptions.h"
+#include "gromacs/utility/stringutil.h"
+
+#if GMX_GPU == GMX_GPU_CUDA
+
+namespace gmx
+{
+
+namespace test
+{
+
+/* \brief Perform a component-wise conversion of the float3 vector back to RVec format.
+ *
+ * This is needed to pass the data back to the CPU testing code for comparison with the initial input.
+ *
+ * \param[out] rVecOutput    Output data in RVec format for the output.
+ * \param[in]  float3Output  Output data in float3 format.
+ * \param[in]  numElements   Size of the data buffers.
+ */
+void inline saveFloat3InRVecFormat(std::vector<gmx::RVec>& rVecOutput, const float3* float3Output, int numElements)
+{
+    for (int i = 0; i < numElements; i++)
+    {
+        rVecOutput[i][XX] = float3Output[i].x;
+        rVecOutput[i][YY] = float3Output[i].y;
+        rVecOutput[i][ZZ] = float3Output[i].z;
+    }
+}
+
+void convertRVecToFloat3OnHost(std::vector<gmx::RVec>& rVecOutput, const std::vector<gmx::RVec>& rVecInput)
+{
+    const int numElements = rVecInput.size();
+
+    float3* dataFloat3 = asFloat3(const_cast<RVec*>(rVecInput.data()));
+
+    saveFloat3InRVecFormat(rVecOutput, dataFloat3, numElements);
+}
+
+//! Number of CUDA threads in a block.
+constexpr static int c_threadsPerBlock = 256;
+
+/*! \brief GPU kernel to perform type conversion on the device.
+ *
+ * \param[out] gm_float3Output Buffer to write the output into.
+ * \param[in]  gm_rVecInput    Input data in RVec format.
+ * \param[in]  size            Size of the data buffers.
+ *
+ */
+static __global__ void convertRVecToFloat3OnDevice_kernel(DeviceBuffer<float3> gm_float3Output,
+                                                          DeviceBuffer<RVec>   gm_rVecInput,
+                                                          const int            size)
+{
+    int threadIndex = blockIdx.x * blockDim.x + threadIdx.x;
+    if (threadIndex < size)
+    {
+        gm_float3Output[threadIndex] = asFloat3(gm_rVecInput)[threadIndex];
+    }
+}
+
+void convertRVecToFloat3OnDevice(std::vector<gmx::RVec>& h_rVecOutput, const std::vector<gmx::RVec>& h_rVecInput)
+{
+    if (canComputeOnGpu())
+    {
+        const int numElements = h_rVecInput.size();
+
+        DeviceBuffer<RVec> d_rVecInput;
+        allocateDeviceBuffer(&d_rVecInput, numElements, nullptr);
+        copyToDeviceBuffer(&d_rVecInput, h_rVecInput.data(), 0, numElements, nullptr,
+                           GpuApiCallBehavior::Sync, nullptr);
+
+        DeviceBuffer<float3> d_float3Output;
+        allocateDeviceBuffer(&d_float3Output, numElements * DIM, nullptr);
+
+        std::vector<float3> h_float3Output(numElements);
+
+        KernelLaunchConfig kernelLaunchConfig;
+        kernelLaunchConfig.gridSize[0]  = (numElements + c_threadsPerBlock - 1) / c_threadsPerBlock;
+        kernelLaunchConfig.blockSize[0] = c_threadsPerBlock;
+        kernelLaunchConfig.blockSize[1] = 1;
+        kernelLaunchConfig.blockSize[2] = 1;
+        kernelLaunchConfig.sharedMemorySize = 0;
+        kernelLaunchConfig.stream           = nullptr;
+
+        auto       kernelPtr  = convertRVecToFloat3OnDevice_kernel;
+        const auto kernelArgs = prepareGpuKernelArguments(
+                kernelPtr, kernelLaunchConfig, &d_float3Output, &d_rVecInput, &numElements);
+        launchGpuKernel(kernelPtr, kernelLaunchConfig, nullptr,
+                        "convertRVecToFloat3OnDevice_kernel", kernelArgs);
+
+        copyFromDeviceBuffer(h_float3Output.data(), &d_float3Output, 0, numElements, nullptr,
+                             GpuApiCallBehavior::Sync, nullptr);
+
+        saveFloat3InRVecFormat(h_rVecOutput, h_float3Output.data(), numElements);
+
+        freeDeviceBuffer(&d_rVecInput);
+        freeDeviceBuffer(&d_float3Output);
+    }
+}
+
+} // namespace test
+} // namespace gmx
+
+#endif // GMX_GPU == GMX_GPU_CUDA
\ No newline at end of file
diff --git a/src/gromacs/gpu_utils/tests/typecasts_runner.h b/src/gromacs/gpu_utils/tests/typecasts_runner.h
new file mode 100644 (file)
index 0000000..60ea524
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, 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
+ * Header for runner for CUDA float3 type layout tests.
+ *
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ */
+#ifndef GMX_GPU_UTILS_TESTS_TYPECASTS_RUNNER_H
+#define GMX_GPU_UTILS_TESTS_TYPECASTS_RUNNER_H
+
+#include "gmxpre.h"
+
+#include <vector>
+
+#include "gromacs/math/vectypes.h"
+
+namespace gmx
+{
+
+namespace test
+{
+
+/*! \brief Tests the compatibility of RVec and float3 using the conversion on host.
+ *
+ * \param[out] rVecOutput  Data in RVec format for the output.
+ * \param[in]  rVecInput   Data in RVec format with the input.
+ */
+void convertRVecToFloat3OnHost(std::vector<gmx::RVec>& rVecOutput, const std::vector<gmx::RVec>& rVecInput);
+
+/*! \brief Tests the compatibility of RVec and float3 using the conversion on device.
+ *
+ * \param[out] rVecOutput  Data in RVec format for the output.
+ * \param[in]  rVecInput   Data in RVec format with the input.
+ */
+void convertRVecToFloat3OnDevice(std::vector<gmx::RVec>& rVecOutput, const std::vector<gmx::RVec>& rVecInput);
+
+} // namespace test
+} // namespace gmx
+
+#endif // GMX_GPU_UTILS_TESTS_TYPECASTS_RUNNER_H
\ No newline at end of file
diff --git a/src/gromacs/gpu_utils/typecasts.cuh b/src/gromacs/gpu_utils/typecasts.cuh
new file mode 100644 (file)
index 0000000..1dd63b7
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, 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 Declare functions to be used to cast CPU types to compatible GPU types.
+ *
+ *  \author Artem Zhmurov <zhmurov@gmail.com>
+ *
+ *  \inlibraryapi
+ */
+#ifndef GMX_GPU_UTILS_TYPECASTS_CUH
+#define GMX_GPU_UTILS_TYPECASTS_CUH
+
+#include "gmxpre.h"
+
+#include "gromacs/math/vectypes.h"
+
+/*! \brief Cast RVec buffer to float3 buffer.
+ *
+ * \param[in] in The RVec buffer to cast.
+ *
+ * \returns Buffer, casted to float3*.
+ */
+static inline __host__ __device__ float3* asFloat3(gmx::RVec* in)
+{
+    static_assert(sizeof(in[0]) == sizeof(float3),
+                  "Size of the host-side data-type is different from the size of the device-side "
+                  "counterpart.");
+    return reinterpret_cast<float3*>(in);
+}
+
+#endif // GMX_GPU_UTILS_TYPECASTS_CUH
index 2defa174d647f2a34f4fad32acba32523df1615e..e47834cb9ae8890a76536be3b569faaa0e213846 100644 (file)
@@ -56,6 +56,7 @@
 
 #include "gromacs/gpu_utils/cudautils.cuh"
 #include "gromacs/gpu_utils/gpueventsynchronizer.cuh"
+#include "gromacs/gpu_utils/typecasts.cuh"
 #include "gromacs/gpu_utils/vectype_ops.cuh"
 #include "gromacs/mdtypes/simulation_workload.h"
 #include "gromacs/nbnxm/atomdata.h"