From 33b031b5699dd3b42e1c7893e4349ba820626d6f Mon Sep 17 00:00:00 2001 From: Matthew Abruzzo Date: Wed, 1 Nov 2023 11:54:10 -0400 Subject: [PATCH 1/2] Introduce 2 tweaks to DeviceVector to improve safety of the class 1. Delete implicitly declared constructors/assignment operations. We could definitely define these, but currently they can lead to dereferencing null pointers or double-freeing pointers 2. While I was here, I also added an explicit check that the elements of the vector are trivially copyable. This is the formal requirement for being able to copy an object with a variant of memcpy. --- src/utils/DeviceVector.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/utils/DeviceVector.h b/src/utils/DeviceVector.h index 4024edf34..7221bedf2 100644 --- a/src/utils/DeviceVector.h +++ b/src/utils/DeviceVector.h @@ -13,6 +13,7 @@ #include #include #include +#include #include // External Includes @@ -35,12 +36,16 @@ namespace cuda_utilities * `data()` method. This class works for any device side pointer, scalar or * array valued. * - * \tparam T Any serialized type where `sizeof(T)` returns correct results - * should work but non-primitive types have not been tested. + * \tparam T Any trivially copyable type where `sizeof(T)` returns correct + * results should work, but non-primitive types have not been tested. */ template class DeviceVector { + static_assert(std::is_trivially_copyable_v, + "DeviceVector can only be used with trivially_copyable types " + "due to the internal usage of memcpy"); + public: /*! * \brief Construct a new Device Vector object by calling the @@ -60,6 +65,15 @@ class DeviceVector */ ~DeviceVector() { _deAllocate(); } + /* The following are deleted because they currently lead to invalid state. + * (But they can all easily be implemented in the future). + */ + DeviceVector() = delete; + DeviceVector(const DeviceVector &) = delete; + DeviceVector(DeviceVector &&) = delete; + DeviceVector &operator=(const DeviceVector &other) = delete; + DeviceVector &operator=(DeviceVector &&other) = delete; + /*! * \brief Get the raw device pointer * From 543c08cd721bf19fbe1ee95c35ce70115cdb2c37 Mon Sep 17 00:00:00 2001 From: Matthew Abruzzo Date: Fri, 3 Nov 2023 12:58:50 -0400 Subject: [PATCH 2/2] revising the static_assert error message in DeviceVector --- src/utils/DeviceVector.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/DeviceVector.h b/src/utils/DeviceVector.h index 7221bedf2..ebe3e4db8 100644 --- a/src/utils/DeviceVector.h +++ b/src/utils/DeviceVector.h @@ -43,8 +43,8 @@ template class DeviceVector { static_assert(std::is_trivially_copyable_v, - "DeviceVector can only be used with trivially_copyable types " - "due to the internal usage of memcpy"); + "DeviceVector can only be used with trivially_copyable types due to the internal " + "usage of functions like cudaMemcpy, cudaMemcpyPeer, cudaMemset"); public: /*!