12 #ifndef CUDA_API_WRAPPERS_ARRAY_HPP_ 13 #define CUDA_API_WRAPPERS_ARRAY_HPP_ 19 #include <cuda_fp16.h> 28 template <
typename T, dimensionality_t NumDimensions>
37 template <dimensionality_t NumDimensions>
38 using descriptor_t = typename ::std::conditional<NumDimensions == 2, CUDA_ARRAY_DESCRIPTOR, CUDA_ARRAY3D_DESCRIPTOR>::type;
41 template <
typename T, dimensionality_t NumDimensions>
50 template <
typename T>
struct format_specifier {};
52 template <>
struct format_specifier<uint8_t > {
static constexpr
const CUarray_format value = CU_AD_FORMAT_UNSIGNED_INT8; };
53 template <>
struct format_specifier<uint16_t> {
static constexpr
const CUarray_format value = CU_AD_FORMAT_UNSIGNED_INT16; };
54 template <>
struct format_specifier<uint32_t> {
static constexpr
const CUarray_format value = CU_AD_FORMAT_UNSIGNED_INT32; };
55 template <>
struct format_specifier<int8_t > {
static constexpr
const CUarray_format value = CU_AD_FORMAT_SIGNED_INT8; };
56 template <>
struct format_specifier<int16_t > {
static constexpr
const CUarray_format value = CU_AD_FORMAT_SIGNED_INT16; };
57 template <>
struct format_specifier<int32_t > {
static constexpr
const CUarray_format value = CU_AD_FORMAT_SIGNED_INT32; };
59 template <>
struct format_specifier<half > {
static constexpr
const CUarray_format value = CU_AD_FORMAT_HALF; };
61 template <>
struct format_specifier<float > {
static constexpr
const CUarray_format value = CU_AD_FORMAT_FLOAT; };
67 CUDA_ARRAY3D_DESCRIPTOR descriptor;
68 descriptor.Width = dimensions.
width;
69 descriptor.Height = dimensions.height;
70 descriptor.Depth = dimensions.depth;
71 descriptor.Format = format_specifier<T>::value;
72 descriptor.NumChannels = 1;
77 auto status = cuArray3DCreate(&handle, &descriptor);
85 CUDA_ARRAY_DESCRIPTOR descriptor;
86 descriptor.Width = dimensions.
width;
87 descriptor.Height = dimensions.height;
88 descriptor.Format = format_specifier<T>::value;
89 descriptor.NumChannels = 1;
91 auto status = cuArrayCreate(&handle, &descriptor);
96 template <
typename T, dimensionality_t NumDimensions>
99 CAW_SET_SCOPE_CONTEXT(context_handle);
100 return create_in_current_context<T>(dimensions);
105 CAW_SET_SCOPE_CONTEXT(context_handle);
106 auto status = cuArrayDestroy(handle);
107 throw_if_error_lazy(status,
"Failed destroying the array at " + cuda::detail_::ptr_as_hex(handle));
110 template <dimensionality_t NumDimensions>
117 auto status = cuArrayGetDescriptor(&result, handle);
119 ::std::string(
"Failed obtaining the descriptor of the CUDA 2D array at ")
120 + cuda::detail_::ptr_as_hex(handle));
128 auto status = cuArray3DGetDescriptor(&result, handle);
130 ::std::string(
"Failed obtaining the descriptor of the CUDA 3D array at ")
131 + cuda::detail_::ptr_as_hex(handle));
135 template <dimensionality_t NumDimensions>
138 CAW_SET_SCOPE_CONTEXT(context_handle);
139 return get_descriptor_in_current_context<NumDimensions>(handle);
142 template <dimensionality_t NumDimensions>
148 return { descriptor.Width, descriptor.Height, descriptor.Depth };
154 return { descriptor.Width, descriptor.Height };
157 template <dimensionality_t NumDimensions>
160 auto descriptor = get_descriptor_in_current_context<NumDimensions>(handle_in_current_context);
161 return dimensions_of<NumDimensions>(descriptor);
164 template <dimensionality_t NumDimensions>
167 CAW_SET_SCOPE_CONTEXT(context_handle);
168 return dimensions_of_in_current_context<NumDimensions>(handle);
200 template <
typename T, dimensionality_t NumDimensions>
202 static_assert(NumDimensions == 2 or NumDimensions == 3,
"CUDA only supports 2D and 3D arrays");
217 dimensions_(dimensions), device_id_(device_id), context_handle_(context_handle), handle_(handle)
219 assert(handle !=
nullptr);
223 array_t(
array_t&& other) noexcept :
array_t(other.device_id_, other.context_handle_, other.handle_, other.dimensions_)
225 other.handle_ =
nullptr;
228 ~
array_t() DESTRUCTOR_EXCEPTION_SPEC
230 if (not handle_) {
return; }
231 #ifndef THROW_IN_DESTRUCTORS 235 array::detail_::destroy(handle_, context_handle_);
237 #ifndef THROW_IN_DESTRUCTORS 244 handle_type
get()
const noexcept {
return handle_; }
245 device::id_t device_id()
const noexcept {
return device_id_; }
246 context::handle_t context_handle()
const noexcept {
return context_handle_; }
263 device::id_t device_id_;
264 context::handle_t context_handle_;
270 template <
typename T, dimensionality_t NumDimensions>
277 return { device_id, context_handle, handle, dimensions };
283 template <
typename T, dimensionality_t NumDimensions>
289 template <
typename T, dimensionality_t NumDimensions>
299 #endif // CUDA_API_WRAPPERS_ARRAY_HPP_ typename ::std::conditional< NumDimensions==2, CUDA_ARRAY_DESCRIPTOR, CUDA_ARRAY3D_DESCRIPTOR >::type descriptor_t
Raw CUDA driver descriptor structure for an array of dimension.
Definition: array.hpp:38
Wrapper class for a CUDA context.
Definition: context.hpp:249
Definitions and functionality wrapping CUDA APIs.
Definition: array.hpp:22
CUcontext handle_t
Raw CUDA driver handle for a context; see {context_t}.
Definition: types.hpp:880
dimension_t width
The three constituent individual dimensions, named.
Definition: types.hpp:109
Owning wrapper for CUDA 2D and 3D arrays.
Definition: array.hpp:29
CUdevice id_t
Numeric ID of a CUDA device used by the CUDA Runtime API.
Definition: types.hpp:852
::std::size_t size_bytes() const noexcept
Overall size in bytes of the elements of the array, over all dimensions.
Definition: array.hpp:255
Dimensions for 2D CUDA arrays.
Definition: types.hpp:156
array::descriptor_t< NumDimensions > descriptor_type
See array::descriptor_t.
Definition: array.hpp:208
array::handle_t handle_type
See array::handle_t.
Definition: array.hpp:206
array_t(device::id_t device_id, context::handle_t context_handle, handle_type handle, dimensions_type dimensions)
Constructs a CUDA array wrapper from the raw type used by the CUDA Runtime API - and takes ownership ...
Definition: array.hpp:216
Contains a proxy class for CUDA execution contexts.
Dimensions for 3D CUDA arrays.
Definition: types.hpp:106
dimension_t width
The two constituent individual dimensions, named; no "depth" for the 2D case.
Definition: types.hpp:159
::std::size_t size_t
A size type for use throughout the wrappers library (except when specific API functions limit the siz...
Definition: types.hpp:78
::std::size_t size() const noexcept
Overall number of elements in the array, over all dimensions.
Definition: array.hpp:252
array_t< T, NumDimensions > create(const context_t &context, dimensions_t< NumDimensions > dimensions)
Create a new (typed) CUDA array of the specified dimensions.
Definition: array.hpp:27
#define throw_if_error_lazy(status__,...)
A macro for only throwing an error if we've failed - which also ensures no string is constructed unle...
Definition: error.hpp:327
CUarray handle_t
Raw CUDA driver handle for arrays (of any dimension)
Definition: array.hpp:34
array_t< T, NumDimensions > wrap(device::id_t device_id, context::handle_t context_handle, handle_t handle, dimensions_t< NumDimensions > dimensions) noexcept
Wrap an existing CUDA array in an array_t instance.
Definition: array.hpp:271
Facilities for exception-based handling of Runtime and Driver API errors, including a basic exception...
descriptor_type descriptor() const
Get the full set of features of this array in a single structure, recognizable by the CUDA driver (e...
Definition: array.hpp:259
Wrapper class for a CUDA device.
Definition: device.hpp:135
CUDA's array memory-objects are multi-dimensional; but their dimensions, or extents, are not the same as cuda::grid::dimensions_t ; they may be much larger in each axis.
Definition: types.hpp:102