From 2d3db2e71344c8fb7a30ce61e1e476ec2aa2594b Mon Sep 17 00:00:00 2001 From: cliffburdick Date: Mon, 2 May 2022 12:18:47 -0700 Subject: [PATCH] Throw an exception if using SetVals on non-managed pointer --- CMakeLists.txt | 3 +- include/matx_make.h | 4 +-- include/matx_tensor.h | 44 +++++++++++++++++++++++++----- test/00_tensor/BasicTensorTests.cu | 1 + 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fc1067f1..57d9d15f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,7 +207,8 @@ target_link_libraries(matx INTERFACE CUDA::cudart CUDA::cublas CUDA::cublasLt CUDA::cufft - CUDA::cusolver) + CUDA::cusolver + CUDA::cuda_driver) # Build config files if the user isn't adding this as a subdirectory. At this point our transitive target # should have all build properties needed based on the options passed in diff --git a/include/matx_make.h b/include/matx_make.h index 4fab4a13..995dc314 100644 --- a/include/matx_make.h +++ b/include/matx_make.h @@ -195,10 +195,10 @@ auto make_tensor() { * @returns New tensor * **/ -template +template auto make_tensor(T *ptr) { std::array shape; - return make_tensor(ptr, std::move(shape)); + return make_tensor(ptr, std::move(shape)); } diff --git a/include/matx_tensor.h b/include/matx_tensor.h index cfd1044e..0ffe2638 100644 --- a/include/matx_tensor.h +++ b/include/matx_tensor.h @@ -1154,34 +1154,48 @@ class tensor_t : public detail::tensor_impl_t { return tensor_t{storage_, std::move(new_desc), this->ldata_}; } + __MATX_INLINE__ __MATX_HOST__ bool IsManagedPointer() { + bool managed; + MATX_ASSERT(cuPointerGetAttribute(&managed, CU_POINTER_ATTRIBUTE_IS_MANAGED, (CUdeviceptr)Data()) == CUDA_SUCCESS, matxNotSupported); + return managed; + } + /** * Rank-0 initializer list setting * + * Note that for performance reasons only CUDA managed pointers are supported with SetVals + * at the moment. + * * @param val * 0 initializer list value * * @returns reference to view * */ - __MATX_INLINE__ __MATX_HOST__ void SetVals(T const &val) noexcept + __MATX_INLINE__ __MATX_HOST__ void SetVals(T const &val) { static_assert(RANK == 0, "Single value in SetVals must be applied only to rank-0 tensor"); + MATX_ASSERT_STR(IsManagedPointer(), matxNotSupported, "SetVals only supports CUDA managed pointers"); this->operator()() = val; } /** * Rank-1 non-complex or rank-0 initializer list setting * + * Note that for performance reasons only CUDA managed pointers are supported with SetVals + * at the moment. + * * @param vals * 1D initializer list of values * * @returns reference to view * */ - __MATX_INLINE__ __MATX_HOST__ void SetVals(const std::initializer_list &vals) noexcept + __MATX_INLINE__ __MATX_HOST__ void SetVals(const std::initializer_list &vals) { static_assert(((!is_cuda_complex_v && RANK == 1) || (is_cuda_complex_v && RANK == 0)), "Single initializer list on SetVals only for non-complex rank 1 tensor or complex rank 0 tensors"); + MATX_ASSERT_STR(IsManagedPointer(), matxNotSupported, "SetVals only supports CUDA managed pointers"); for (size_t i = 0; i < vals.size(); i++) { if constexpr (is_cuda_complex_v) { typename T::value_type real = (vals.begin() + i)->real(); @@ -1197,6 +1211,9 @@ class tensor_t : public detail::tensor_impl_t { /** * Rank-2 non-complex or rank-1 initializer list setting * + * Note that for performance reasons only CUDA managed pointers are supported with SetVals + * at the moment. + * * @param vals * 1D/2D initializer list of values * @@ -1205,10 +1222,11 @@ class tensor_t : public detail::tensor_impl_t { */ __MATX_INLINE__ __MATX_HOST__ void SetVals(const std::initializer_list> - &vals) noexcept + &vals) { static_assert(((!is_cuda_complex_v && RANK == 2) || (is_cuda_complex_v && RANK == 1)), "Double initializer list on SetVals only for non-complex rank 2 tensor or complex rank 1 tensors"); + MATX_ASSERT_STR(IsManagedPointer(), matxNotSupported, "SetVals only supports CUDA managed pointers"); for (size_t i = 0; i < vals.size(); i++) { for (size_t j = 0; j < (vals.begin() + i)->size(); j++) { if constexpr (is_cuda_complex_v) { @@ -1229,6 +1247,9 @@ class tensor_t : public detail::tensor_impl_t { /** * Rank-3 non-complex or rank-2 complex initializer list setting * + * Note that for performance reasons only CUDA managed pointers are supported with SetVals + * at the moment. + * * @param vals * 3D/2D initializer list of values * @@ -1238,10 +1259,11 @@ class tensor_t : public detail::tensor_impl_t { __MATX_INLINE__ __MATX_HOST__ void SetVals(const std::initializer_list< const std::initializer_list>> - vals) noexcept + vals) { static_assert(((!is_cuda_complex_v && RANK == 3) || (is_cuda_complex_v && RANK == 2)), - "Triple initializer list on SetVals only for non-complex rank 3 tensor or complex rank 2 tensors"); + "Triple initializer list on SetVals only for non-complex rank 3 tensor or complex rank 2 tensors"); + MATX_ASSERT_STR(IsManagedPointer(), matxNotSupported, "SetVals only supports CUDA managed pointers"); for (size_t i = 0; i < vals.size(); i++) { for (size_t j = 0; j < (vals.begin() + i)->size(); j++) { for (size_t k = 0; k < ((vals.begin() + i)->begin() + j)->size(); k++) { @@ -1265,6 +1287,9 @@ class tensor_t : public detail::tensor_impl_t { /** * Rank-4 non-complex or rank-3 complex initializer list setting * + * Note that for performance reasons only CUDA managed pointers are supported with SetVals + * at the moment. + * * @param vals * 3D/4D initializer list of values * @@ -1274,10 +1299,11 @@ class tensor_t : public detail::tensor_impl_t { __MATX_INLINE__ __MATX_HOST__ void SetVals(const std::initializer_list>>> - &vals) noexcept + &vals) { static_assert(((!is_cuda_complex_v && RANK == 4) || (is_cuda_complex_v && RANK == 3)), "Quad initializer list on SetVals only for non-complex rank 4 tensor or complex rank 3 tensors"); + MATX_ASSERT_STR(IsManagedPointer(), matxNotSupported, "SetVals only supports CUDA managed pointers"); for (size_t i = 0; i < vals.size(); i++) { for (size_t j = 0; j < (vals.begin() + i)->size(); j++) { for (size_t k = 0; k < ((vals.begin() + i)->begin() + j)->size(); k++) { @@ -1310,6 +1336,9 @@ class tensor_t : public detail::tensor_impl_t { /** * Rank-4 complex initializer list setting * + * Note that for performance reasons only CUDA managed pointers are supported with SetVals + * at the moment. + * * @param vals * 4D initializer list of values * @@ -1320,10 +1349,11 @@ class tensor_t : public detail::tensor_impl_t { SetVals(const std::initializer_list< const std::initializer_list>>>> - &vals) noexcept + &vals) { static_assert((is_cuda_complex_v && RANK == 4), "Quintuple initializer list on SetVals only for complex rank 3 tensors"); + MATX_ASSERT_STR(IsManagedPointer(), matxNotSupported, "SetVals only supports CUDA managed pointers"); for (size_t i = 0; i < vals.size(); i++) { for (size_t j = 0; j < (vals.begin() + i)->size(); j++) { for (size_t k = 0; k < ((vals.begin() + i)->begin() + j)->size(); k++) { diff --git a/test/00_tensor/BasicTensorTests.cu b/test/00_tensor/BasicTensorTests.cu index fb10bc0b..75ecae70 100644 --- a/test/00_tensor/BasicTensorTests.cu +++ b/test/00_tensor/BasicTensorTests.cu @@ -402,6 +402,7 @@ TYPED_TEST(BasicTensorTestsIntegral, InitAssign) ASSERT_EQ(t2v_small(i, j), i * 4 + j + 1); } } + MATX_EXIT_HANDLER(); }