std::unique_ptr<gmx::StatePropagatorDataGpu> stateGpu;
if (useGpuForPme)
{
- // TODO: The local and non-local nonbonded streams are passed as nullptrs, since they will be not used for the GPU buffer
- // management in PME only ranks. Make the constructor safer.
- stateGpu = std::make_unique<gmx::StatePropagatorDataGpu>(commandStream, nullptr, nullptr,
- deviceContext, GpuApiCallBehavior::Async, paddingSize);
+ // TODO: Special PME-only constructor is used here. There is no mechanism to prevent from using the other constructor here.
+ // This should be made safer.
+ stateGpu = std::make_unique<gmx::StatePropagatorDataGpu>(commandStream, deviceContext, GpuApiCallBehavior::Async, paddingSize);
}
makeStatePropagatorDataGpu(const gmx_pme_t &pme)
{
// TODO: Pin the host buffer and use async memory copies
- return std::make_unique<StatePropagatorDataGpu>(pme_gpu_get_device_stream(&pme), nullptr, nullptr,
+ // TODO: Special constructor for PME-only rank / PME-tests is used here. There should be a mechanism to
+ // restrict one from using other constructor here.
+ return std::make_unique<StatePropagatorDataGpu>(pme_gpu_get_device_stream(&pme),
pme_gpu_get_device_context(&pme),
GpuApiCallBehavior::Sync,
pme_gpu_get_padding_size(&pme));
const void *deviceContext,
GpuApiCallBehavior transferKind,
int paddingSize);
+
+ /*! \brief Constructor to use in PME-only rank and in tests.
+ *
+ * This constructor should be used if only a coordinate device buffer should be managed
+ * using a single stream. Any operation on force or velocity buffer as well as copy of
+ * non-local coordinates will exit with assertion failure. Note, that the pmeStream can
+ * not be a nullptr and the constructor will exit with an assertion failure.
+ *
+ * \todo Currently, unsupported copy operations are blocked by assertion that the stream
+ * not nullptr. This should be improved.
+ *
+ * \param[in] pmeStream Device PME stream, nullptr is not allowed.
+ * \param[in] deviceContext Device context, nullptr allowed for non-OpenCL builds.
+ * \param[in] transferKind H2D/D2H transfer call behavior (synchronous or not).
+ * \param[in] paddingSize Padding size for coordinates buffer.
+ */
+ StatePropagatorDataGpu(const void *pmeStream,
+ const void *deviceContext,
+ GpuApiCallBehavior transferKind,
+ int paddingSize);
+
//! Move constructor
StatePropagatorDataGpu(StatePropagatorDataGpu &&other) noexcept;
//! Move assignment
{
}
+StatePropagatorDataGpu::StatePropagatorDataGpu(const void * /* pmeStream */,
+ const void * /* deviceContext */,
+ GpuApiCallBehavior /* transferKind */,
+ int /* paddingSize */)
+ : impl_(nullptr)
+{
+}
+
StatePropagatorDataGpu::StatePropagatorDataGpu(StatePropagatorDataGpu && /* other */) noexcept = default;
StatePropagatorDataGpu &StatePropagatorDataGpu::operator=(StatePropagatorDataGpu && /* other */) noexcept = default;
GpuApiCallBehavior transferKind,
int paddingSize);
+ /*! \brief Constructor to use in PME-only rank and in tests.
+ *
+ * This constructor should be used if only a coordinate device buffer should be managed
+ * using a single stream. Any operation on force or velocity buffer as well as copy of
+ * non-local coordinates will exit with assertion failure. Note, that the pmeStream can
+ * not be a nullptr and the constructor will exit with an assertion failure.
+ *
+ * \todo Currently, unsupported copy operations are blocked by assertion that the stream
+ * not nullptr. This should be improved.
+ *
+ * \param[in] pmeStream Device PME stream, nullptr is not allowed.
+ * \param[in] deviceContext Device context, nullptr allowed for non-OpenCL builds.
+ * \param[in] transferKind H2D/D2H transfer call behavior (synchronous or not).
+ * \param[in] paddingSize Padding size for coordinates buffer.
+ */
+ Impl(const void *pmeStream,
+ const void *deviceContext,
+ GpuApiCallBehavior transferKind,
+ int paddingSize);
+
~Impl();
fCopyStreams_[AtomLocality::All] = nullptr;
}
+StatePropagatorDataGpu::Impl::Impl(const void *pmeStream,
+ const void *deviceContext,
+ GpuApiCallBehavior transferKind,
+ int paddingSize) :
+ transferKind_(transferKind),
+ paddingSize_(paddingSize)
+{
+ static_assert(GMX_GPU != GMX_GPU_NONE, "This object should only be constructed on the GPU code-paths.");
+ GMX_RELEASE_ASSERT(getenv("GMX_USE_GPU_BUFFER_OPS") == nullptr, "GPU buffer ops are not supported in this build.");
+
+ if (GMX_GPU == GMX_GPU_OPENCL)
+ {
+ GMX_ASSERT(deviceContext != nullptr, "GPU context should be set in OpenCL builds.");
+ deviceContext_ = *static_cast<const DeviceContext*>(deviceContext);
+ }
+
+ GMX_ASSERT(pmeStream != nullptr, "GPU PME stream should be set.");
+ pmeStream_ = *static_cast<const CommandStream*>(pmeStream);
+
+ localStream_ = nullptr;
+ nonLocalStream_ = nullptr;
+ updateStream_ = nullptr;
+
+
+ // Only local/all coordinates are allowed to be copied in PME-only rank/ PME tests.
+ // This it temporary measure to make it safe to use this class in those cases.
+ xCopyStreams_[AtomLocality::Local] = pmeStream_;
+ xCopyStreams_[AtomLocality::NonLocal] = nullptr;
+ xCopyStreams_[AtomLocality::All] = pmeStream_;
+
+ vCopyStreams_[AtomLocality::Local] = nullptr;
+ vCopyStreams_[AtomLocality::NonLocal] = nullptr;
+ vCopyStreams_[AtomLocality::All] = nullptr;
+
+ fCopyStreams_[AtomLocality::Local] = nullptr;
+ fCopyStreams_[AtomLocality::NonLocal] = nullptr;
+ fCopyStreams_[AtomLocality::All] = nullptr;
+}
+
StatePropagatorDataGpu::Impl::~Impl()
{
}
{
}
+StatePropagatorDataGpu::StatePropagatorDataGpu(const void *pmeStream,
+ const void *deviceContext,
+ GpuApiCallBehavior transferKind,
+ int paddingSize)
+ : impl_(new Impl(pmeStream,
+ deviceContext,
+ transferKind,
+ paddingSize))
+{
+}
+
StatePropagatorDataGpu::StatePropagatorDataGpu(StatePropagatorDataGpu && /* other */) noexcept = default;
StatePropagatorDataGpu &StatePropagatorDataGpu::operator=(StatePropagatorDataGpu && /* other */) noexcept = default;