Change CanBePinned to PinnedIfSupported
authorRoland Schulz <roland.schulz@intel.com>
Thu, 6 Sep 2018 00:32:15 +0000 (17:32 -0700)
committerRoland Schulz <roland.schulz@intel.com>
Thu, 6 Sep 2018 01:36:12 +0000 (18:36 -0700)
Allow setting the policy independent of support. Allows testing
without support.

Change-Id: I8aff34757868e705cea579d21f78a50b08f2c2ed

src/gromacs/ewald/pme.cpp
src/gromacs/fft/fft5d.cpp
src/gromacs/gpu_utils/hostallocator.cpp
src/gromacs/gpu_utils/hostallocator.h
src/gromacs/gpu_utils/tests/hostallocator.cpp
src/gromacs/gpu_utils/tests/pinnedmemorychecker.cpp

index a179d6fb4527c453aaf72734c02efcdbb70ed11f..befc17c9d28087f01f50d3a49704879430d57bc0 100644 (file)
@@ -232,16 +232,7 @@ PmeRunMode pme_run_mode(const gmx_pme_t *pme)
 
 gmx::PinningPolicy pme_get_pinning_policy()
 {
-    // When the OpenCL implementation of HostAllocationPolicy
-    // implements an form of host-side pinning, amend this logic.
-    if (GMX_GPU == GMX_GPU_CUDA)
-    {
-        return gmx::PinningPolicy::CanBePinned;
-    }
-    else
-    {
-        return gmx::PinningPolicy::CannotBePinned;
-    }
+    return gmx::PinningPolicy::PinnedIfSupported;
 }
 
 /*! \brief Number of bytes in a cache line.
@@ -918,7 +909,7 @@ gmx_pme_t *gmx_pme_init(const t_commrec     *cr,
                           pme->overlap[0].s2g1[pme->nodeid_major]-pme->overlap[0].s2g0[pme->nodeid_major+1],
                           pme->overlap[1].s2g1[pme->nodeid_minor]-pme->overlap[1].s2g0[pme->nodeid_minor+1]);
             /* This routine will allocate the grid data to fit the FFTs */
-            const auto allocateRealGridForGpu = (pme->runMode == PmeRunMode::Mixed) ? gmx::PinningPolicy::CanBePinned : gmx::PinningPolicy::CannotBePinned;
+            const auto allocateRealGridForGpu = (pme->runMode == PmeRunMode::Mixed) ? gmx::PinningPolicy::PinnedIfSupported : gmx::PinningPolicy::CannotBePinned;
             gmx_parallel_3dfft_init(&pme->pfft_setup[i], ndata,
                                     &pme->fftgrid[i], &pme->cfftgrid[i],
                                     pme->mpi_comm_d,
index d7755c653d057815f811b0a28c946cbe3818a980..82763e799da7bb6152701245ad4331399b468f39 100644 (file)
@@ -390,7 +390,8 @@ fft5d_plan fft5d_plan_3d(int NG, int MG, int KG, MPI_Comm comm[2], int flags, t_
     if (!(flags&FFT5D_NOMALLOC))
     {
         // only needed for PME GPU mixed mode
-        if (realGridAllocationPinningPolicy == gmx::PinningPolicy::CanBePinned)
+        if (realGridAllocationPinningPolicy == gmx::PinningPolicy::PinnedIfSupported &&
+            GMX_GPU == GMX_GPU_CUDA)
         {
             const std::size_t numBytes = lsize * sizeof(t_complex);
             lin = static_cast<t_complex *>(gmx::PageAlignedAllocationPolicy::malloc(numBytes));
@@ -1286,7 +1287,7 @@ void fft5d_destroy(fft5d_plan plan)
     if (!(plan->flags&FFT5D_NOMALLOC))
     {
         // only needed for PME GPU mixed mode
-        if (plan->pinningPolicy == gmx::PinningPolicy::CanBePinned &&
+        if (plan->pinningPolicy == gmx::PinningPolicy::PinnedIfSupported &&
             isHostMemoryPinned(plan->lin))
         {
             gmx::unpinBuffer(plan->lin);
index 1553aa930a24b0b2f41ce1162b493c7aa0a49d15..d177456a7f33416138c272dd0ebe9a57495ed930 100644 (file)
@@ -60,24 +60,18 @@ namespace gmx
 HostAllocationPolicy::HostAllocationPolicy(PinningPolicy pinningPolicy)
     : pinningPolicy_(pinningPolicy)
 {
-    if (GMX_GPU != GMX_GPU_CUDA)
-    {
-        GMX_RELEASE_ASSERT(pinningPolicy == PinningPolicy::CannotBePinned,
-                           "A suitable build of GROMACS (e.g. with CUDA) is required for a "
-                           "HostAllocationPolicy to be set to a mode that produces pinning.");
-    }
 }
 
 std::size_t HostAllocationPolicy::alignment()
 {
-    return (pinningPolicy_ == PinningPolicy::CanBePinned ?
+    return (pinningPolicy_ == PinningPolicy::PinnedIfSupported ?
             PageAlignedAllocationPolicy::alignment() :
             AlignedAllocationPolicy::alignment());
 }
 
 void *HostAllocationPolicy::malloc(std::size_t bytes) const noexcept
 {
-    if (pinningPolicy_ == PinningPolicy::CanBePinned)
+    if (pinningPolicy_ == PinningPolicy::PinnedIfSupported)
     {
         void *p = PageAlignedAllocationPolicy::malloc(bytes);
         pin(p, bytes);
@@ -97,7 +91,7 @@ void HostAllocationPolicy::free(void *buffer) const noexcept
         return;
     }
     unpin(buffer);
-    if (pinningPolicy_ == PinningPolicy::CanBePinned)
+    if (pinningPolicy_ == PinningPolicy::PinnedIfSupported)
     {
         PageAlignedAllocationPolicy::free(buffer);
     }
index eeccd27a9ee2e28c49b266ea9d6ae7b3e19242ef..7b0c0cd53bf4027fa9c3774bd7024478460c0ec3 100644 (file)
@@ -73,8 +73,8 @@ namespace gmx
 enum class PinningPolicy : int
 {
     CannotBePinned,     // Memory is not known to be suitable for pinning.
-    CanBePinned,        // Memory is suitable for efficient pinning, e.g. because it is
-                        // allocated to be page aligned, and will be pinned when non-empty.
+    PinnedIfSupported,  // Memory is suitable for efficient pinning, e.g. because it is
+                        // allocated to be page aligned, and will be pinned when supported.
 };
 
 //! Forward declaration of host allocation policy class.
@@ -118,7 +118,7 @@ using HostVector = std::vector<T, HostAllocator<T> >;
  * std::vector::get_allocator().getPolicy() to control whether the
  * allocation policy should activate its pinning mode. The policy
  * object can also be used to explicitly pin() and unpin() the buffer
- * when it is using PinningPolicy::CanBePinned. The policy object is
+ * when it is using PinningPolicy::PinnedIfSupported. The policy object is
  * returned by value (as required by the C++ standard for
  * get_allocator(), which copies a std::shared_ptr, so the policy
  * object should be retrieved sparingly, e.g. only upon resize of the
index 274e6f730c2ad838313b25295608f0c9b83c3fa4..1c73fbaedaa5d04a85331832b9e9620913c0ce1e 100644 (file)
@@ -221,98 +221,98 @@ TYPED_TEST(HostAllocatorTest, FillInputAlsoWorksAfterCallingReserve)
     this->fillInput(&input);
 }
 
-#if GMX_GPU == GMX_GPU_CUDA
-
-// Policy suitable for pinning is only supported for a CUDA build
-
-TYPED_TEST(HostAllocatorTest, TransfersWithPinningWorkWithCuda)
-{
-    if (!this->haveValidGpus())
-    {
-        return;
-    }
-
-    typename TestFixture::VectorType input;
-    changePinningPolicy(&input, PinningPolicy::CanBePinned);
-    this->fillInput(&input);
-    typename TestFixture::VectorType output;
-    changePinningPolicy(&output, PinningPolicy::CanBePinned);
-    output.resize(input.size());
-
-    this->runTest(input, output);
-}
-
-//! Helper function for wrapping a call to isHostMemoryPinned.
-template <typename VectorType>
-bool isPinned(const VectorType &v)
-{
-    void *data = const_cast<void *>(static_cast<const void *>(v.data()));
-    return isHostMemoryPinned(data);
-}
-
 TYPED_TEST(HostAllocatorTestNoMem, CreateVector)
 {
     typename TestFixture::VectorType input1;
-    EXPECT_FALSE(input1.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
-    typename TestFixture::VectorType input2({PinningPolicy::CanBePinned});
-    EXPECT_TRUE (input2.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
+    EXPECT_FALSE(input1.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
+    typename TestFixture::VectorType input2({PinningPolicy::PinnedIfSupported});
+    EXPECT_TRUE (input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
 }
 
 TYPED_TEST(HostAllocatorTestNoMem, MoveAssignment)
 {
-    typename TestFixture::VectorType input1({PinningPolicy::CanBePinned});
+    typename TestFixture::VectorType input1({PinningPolicy::PinnedIfSupported});
     input1 = typename TestFixture::VectorType();
-    EXPECT_FALSE(input1.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
+    EXPECT_FALSE(input1.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
 
     typename TestFixture::VectorType input2;
-    input2 = typename TestFixture::VectorType({PinningPolicy::CanBePinned});
-    EXPECT_TRUE (input2.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
+    input2 = typename TestFixture::VectorType({PinningPolicy::PinnedIfSupported});
+    EXPECT_TRUE (input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
 }
 
 TYPED_TEST(HostAllocatorTestNoMem, MoveConstruction)
 {
     typename TestFixture::VectorType input1;
     typename TestFixture::VectorType input2(std::move(input1));
-    EXPECT_FALSE(input2.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
+    EXPECT_FALSE(input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
 
-    typename TestFixture::VectorType input3({PinningPolicy::CanBePinned});
+    typename TestFixture::VectorType input3({PinningPolicy::PinnedIfSupported});
     typename TestFixture::VectorType input4(std::move(input3));
-    EXPECT_TRUE(input4.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
+    EXPECT_TRUE(input4.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
 }
 
 TYPED_TEST(HostAllocatorTestNoMem, CopyAssignment)
 {
     typename TestFixture::VectorType input1;
-    typename TestFixture::VectorType input2({PinningPolicy::CanBePinned});
+    typename TestFixture::VectorType input2({PinningPolicy::PinnedIfSupported});
     input1 = input2;
-    EXPECT_FALSE(input1.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
-    EXPECT_TRUE (input2.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
+    EXPECT_FALSE(input1.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
+    EXPECT_TRUE (input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
     input2 = input1;
-    EXPECT_FALSE(input1.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
-    EXPECT_TRUE (input2.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
+    EXPECT_FALSE(input1.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
+    EXPECT_TRUE (input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
 }
 
 TYPED_TEST(HostAllocatorTestNoMem, CopyConstruction)
 {
     typename TestFixture::VectorType input1;
-    typename TestFixture::VectorType input2(input1);
-    EXPECT_FALSE(input2.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
+    typename TestFixture::VectorType input2(input1); //NOLINT(performance-unnecessary-copy-initialization)
+    EXPECT_FALSE(input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
 
-    typename TestFixture::VectorType input3({PinningPolicy::CanBePinned});
-    typename TestFixture::VectorType input4(input3);
-    EXPECT_FALSE(input4.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
+    typename TestFixture::VectorType input3({PinningPolicy::PinnedIfSupported});
+    typename TestFixture::VectorType input4(input3); //NOLINT(performance-unnecessary-copy-initialization)
+    EXPECT_FALSE(input4.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
 }
 
 TYPED_TEST(HostAllocatorTestNoMem, Swap)
 {
     typename TestFixture::VectorType input1;
-    typename TestFixture::VectorType input2({PinningPolicy::CanBePinned});
+    typename TestFixture::VectorType input2({PinningPolicy::PinnedIfSupported});
     swap(input1, input2);
-    EXPECT_TRUE (input1.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
-    EXPECT_FALSE(input2.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
+    EXPECT_TRUE (input1.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
+    EXPECT_FALSE(input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
     swap(input2, input1);
-    EXPECT_FALSE(input1.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
-    EXPECT_TRUE (input2.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
+    EXPECT_FALSE(input1.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
+    EXPECT_TRUE (input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
+}
+
+#if GMX_GPU == GMX_GPU_CUDA
+
+// Policy suitable for pinning is only supported for a CUDA build
+
+TYPED_TEST(HostAllocatorTest, TransfersWithPinningWorkWithCuda)
+{
+    if (!this->haveValidGpus())
+    {
+        return;
+    }
+
+    typename TestFixture::VectorType input;
+    changePinningPolicy(&input, PinningPolicy::PinnedIfSupported);
+    this->fillInput(&input);
+    typename TestFixture::VectorType output;
+    changePinningPolicy(&output, PinningPolicy::PinnedIfSupported);
+    output.resize(input.size());
+
+    this->runTest(input, output);
+}
+
+//! Helper function for wrapping a call to isHostMemoryPinned.
+template <typename VectorType>
+bool isPinned(const VectorType &v)
+{
+    void *data = const_cast<void *>(static_cast<const void *>(v.data()));
+    return isHostMemoryPinned(data);
 }
 
 TYPED_TEST(HostAllocatorTest, ManualPinningOperationsWorkWithCuda)
@@ -323,8 +323,8 @@ TYPED_TEST(HostAllocatorTest, ManualPinningOperationsWorkWithCuda)
     }
 
     typename TestFixture::VectorType input;
-    changePinningPolicy(&input, PinningPolicy::CanBePinned);
-    EXPECT_TRUE(input.get_allocator().pinningPolicy() == PinningPolicy::CanBePinned);
+    changePinningPolicy(&input, PinningPolicy::PinnedIfSupported);
+    EXPECT_TRUE(input.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported);
     EXPECT_FALSE(isPinned(input));
 
     // Unpin before allocation is fine, but does nothing.
@@ -364,10 +364,10 @@ TYPED_TEST(HostAllocatorTest, ManualPinningOperationsWorkWithCuda)
     // time for the contents to be able to be copied.
     EXPECT_NE(oldInputData, input.data());
 
-    // Switching policy to CanBePinned must pin the buffer (via
+    // Switching policy to PinnedIfSupported must pin the buffer (via
     // realloc and copy).
     oldInputData = input.data();
-    changePinningPolicy(&input, PinningPolicy::CanBePinned);
+    changePinningPolicy(&input, PinningPolicy::PinnedIfSupported);
     EXPECT_TRUE(isPinned(input));
     // These cannot be equal as both had to be allocated at the same
     // time for the contents to be able to be copied.
@@ -376,13 +376,6 @@ TYPED_TEST(HostAllocatorTest, ManualPinningOperationsWorkWithCuda)
 
 #else
 
-TYPED_TEST(HostAllocatorTest, ChangingPinningPolicyRequiresCuda)
-{
-    typename TestFixture::VectorType input;
-    EXPECT_DEATH_IF_SUPPORTED(changePinningPolicy(&input, PinningPolicy::CanBePinned),
-                              ".*A suitable build of GROMACS.* is required.*");
-}
-
 TYPED_TEST(HostAllocatorTest, ManualPinningOperationsWorkEvenWithoutCuda)
 {
     typename TestFixture::VectorType input;
index 7366aaf344eb49f5da0db49c44d1275660536648..fb64ead7c108d39dcac412fd98839d3bcbaea6a7 100644 (file)
@@ -95,7 +95,7 @@ TEST_F(PinnedMemoryCheckerTest, PinnedContainerIsRecognized)
     }
 
     HostVector<real> dummy(3, 1.5);
-    changePinningPolicy(&dummy, PinningPolicy::CanBePinned);
+    changePinningPolicy(&dummy, PinningPolicy::PinnedIfSupported);
     EXPECT_TRUE(isHostMemoryPinned(dummy.data()));
 }