9#ifndef NANOVDB_CUDA_BUFFER_H_HAS_BEEN_INCLUDED
10#define NANOVDB_CUDA_BUFFER_H_HAS_BEEN_INCLUDED
12#include <cuda_runtime_api.h>
67template<
typename T,
typename R = DeviceResource>
71 "Buffer requires R to model the AsyncResource or the Resource concept");
72 static_assert(std::is_trivially_copyable<T>::value,
73 "Buffer requires a trivially copyable T: elements are copied bytewise and never constructed or destroyed");
103 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
108 this->allocate(count,
stream);
119 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
127 template<typename S = R, std::enable_if_t<!is_async_resource<S>::value &&
is_resource<S>::value,
int> = 0>
131 this->allocate(count, cudaStream_t{0});
136 template<typename S = R, std::enable_if_t<!is_async_resource<S>::value &&
is_resource<S>::value,
int> = 0>
147 , mResource(std::move(other.mResource))
151 other.mData =
nullptr;
159 if (
this != &other) {
162 mResource = std::move(other.mResource);
165 other.mData =
nullptr;
175 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
179 if (mData)
cudaCheck(cudaMemcpyAsync(out.mData, mData, this->size_bytes(), cudaMemcpyDefault,
stream));
185 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
190 template<typename S = R, std::enable_if_t<!is_async_resource<S>::value &&
is_resource<S>::value,
int> = 0>
194 if (mData)
cudaCheck(cudaMemcpy(out.mData, mData, this->size_bytes(), cudaMemcpyDefault));
204 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
205 cudaStream_t
stream()
const {
return this->mStream; }
214 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
228 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
231 if (count != mSize) {
235 T* newData = count ?
static_cast<T*
>(mResource.allocate_async(checkedBytes(count), R::DEFAULT_ALIGNMENT,
stream))
237 if (newData && mData) {
238 const size_t prefix = count < mSize ? count : mSize;
240 cudaCheck(cudaMemcpyAsync(newData, mData, prefix *
sizeof(T), cudaMemcpyDefault,
stream));
243 mResource.deallocate_async(newData, checkedBytes(count), R::DEFAULT_ALIGNMENT,
stream);
248 this->deallocate(mData, mSize);
260 template<typename S = R, std::enable_if_t<!is_async_resource<S>::value &&
is_resource<S>::value,
int> = 0>
263 if (count == mSize)
return;
266 T* newData = count ?
static_cast<T*
>(mResource.allocate(checkedBytes(count), R::DEFAULT_ALIGNMENT))
268 if (newData && mData) {
269 const size_t prefix = count < mSize ? count : mSize;
271 cudaCheck(cudaMemcpy(newData, mData, prefix *
sizeof(T), cudaMemcpyDefault));
274 mResource.deallocate(newData, checkedBytes(count), R::DEFAULT_ALIGNMENT);
278 this->deallocate(mData, mSize);
285 const T*
data()
const {
return mData; }
295 size_t size()
const {
return mSize; }
301 bool empty()
const {
return mSize == 0; }
308 this->deallocate(mData, mSize);
315 [[deprecated(
"Use cuda::Buffer::destroy instead")]]
323 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
338 std::swap(mResource, other.mResource);
339 std::swap(mData, other.mData);
340 std::swap(mSize, other.mSize);
348 static size_t checkedBytes(
size_t count)
350 if (count > std::numeric_limits<size_t>::max() /
sizeof(T))
351 throw std::runtime_error(
"nanovdb::cuda::Buffer: element count overflows the byte size");
352 return count *
sizeof(T);
360 void allocate(
size_t count, cudaStream_t
stream)
363 if constexpr (IsAsync)
364 mData =
static_cast<T*
>(mResource.allocate_async(checkedBytes(count), R::DEFAULT_ALIGNMENT,
stream));
366 mData =
static_cast<T*
>(mResource.allocate(checkedBytes(count), R::DEFAULT_ALIGNMENT));
375 void deallocate(T* p,
size_t count)
378 if constexpr (IsAsync)
379 mResource.deallocate_async(p, count *
sizeof(T), R::DEFAULT_ALIGNMENT, this->mStream);
381 mResource.deallocate(p, count *
sizeof(T), R::DEFAULT_ALIGNMENT);
407 if (
data ==
nullptr && count != 0)
408 throw std::runtime_error(
"BufferView: null data with a non-zero element count");
412 T*
data()
const {
return mData; }
415 size_t size()
const {
return mSize; }
421 bool empty()
const {
return mSize == 0; }
436 [[deprecated(
"Use cuda::BufferView::destroy instead")]]
444template<
typename BufferT>
460template<
typename T,
typename R>
BufferView()=default
Default c-tor of an empty view.
size_t size() const
Returns the number of viewed elements.
Definition Buffer.h:415
T * data() const
Returns a pointer to the viewed elements, or nullptr if empty.
Definition Buffer.h:412
BufferView(T *data, size_t count)
C-tor viewing a contiguous range; the caller guarantees the underlying storage outlives every use of ...
Definition Buffer.h:405
void destroy()
Detaches the view (nulls the pointer and zeroes the size) without touching the underlying storage – t...
Definition Buffer.h:428
bool empty() const
Returns true if this view references no elements.
Definition Buffer.h:421
void clear()
Detaches the view.
Definition Buffer.h:437
size_t size_bytes() const
Returns the size of the viewed range in bytes.
Definition Buffer.h:418
Buffer(cudaStream_t stream, size_t count, NoInit)
Convenience c-tor using a default-constructed resource.
Definition Buffer.h:120
T ElementType
Element and resource types, for generic code that rebinds one or constructs sibling buffers over the ...
Definition Buffer.h:80
R ResourceType
Definition Buffer.h:81
Buffer(const Buffer &)=delete
Explicitly disallow copy construction and assignment operation.
size_t size() const
Returns the number of elements.
Definition Buffer.h:295
Buffer()=default
Default c-tor of an empty buffer; performs no allocation.
void swap(Buffer &other) noexcept
Exchanges the contents of this buffer with other. Neither buffer allocates, frees,...
Definition Buffer.h:333
void destroy()
Frees the buffer memory (if any) and resets to the empty state. A stream-ordered resource frees on th...
Definition Buffer.h:306
cudaStream_t stream() const
Definition Buffer.h:205
Buffer< U, R > rebind
Alias for a sibling buffer over the same resource with a different element type.
Definition Buffer.h:86
const T * data() const
Definition Buffer.h:285
bool empty() const
Returns true if this buffer manages no memory.
Definition Buffer.h:301
Buffer(cudaStream_t stream, R resource, size_t count, NoInit)
C-tor allocating count uninitialized elements, stream-ordered on stream. Parameter order follows cuda...
Definition Buffer.h:104
Buffer copy(cudaStream_t stream) const
Returns a deep copy of this buffer, allocated from a copy of the resource; the allocation and element...
Definition Buffer.h:176
void destroy(cudaStream_t stream)
Frees the buffer memory (if any) on stream and resets to the empty state. stream becomes the retained...
Definition Buffer.h:324
R resource() const
Definition Buffer.h:292
Buffer(R resource, size_t count, NoInit)
C-tor allocating count uninitialized elements from a synchronous resource: the stream-less analog of ...
Definition Buffer.h:128
Buffer copy() const
Returns a deep copy of this buffer ordered on the retained stream, i.e. copy(this->stream()).
Definition Buffer.h:186
void resize(size_t count)
Resizes the buffer to count elements through the synchronous resource, preserving the leading min(old...
Definition Buffer.h:261
Buffer(size_t count, NoInit)
Convenience c-tor using a default-constructed resource.
Definition Buffer.h:137
void resize(size_t count, cudaStream_t stream)
Resizes the buffer to count elements, preserving the leading min(old, new) elements....
Definition Buffer.h:229
~Buffer()
D-tor. A stream-ordered resource frees on the retained stream; a synchronous resource frees immediate...
Definition Buffer.h:200
void clear()
Frees the buffer memory (if any) and resets to the empty state.
Definition Buffer.h:316
T * data()
Returns a pointer to the elements, or nullptr if empty.
Definition Buffer.h:284
void set_stream(cudaStream_t stream)
Replaces the retained stream without synchronizing; subsequent deallocation (and destruction) is orde...
Definition Buffer.h:215
Buffer(Buffer &&other) noexcept
Move c-tor; steals the allocation (and retained stream, if any) and leaves other empty.
Definition Buffer.h:145
Buffer & operator=(Buffer &&other) noexcept
Move assignment; frees the current allocation first, then steals from other and leaves it empty....
Definition Buffer.h:157
size_t size_bytes() const
Returns the size of the buffer's allocation in bytes.
Definition Buffer.h:298
Buffer & operator=(const Buffer &)=delete
Definition VoxToNanoVDB.h:15
Definition GridHandle.h:37
constexpr NoInit noInit
Definition Buffer.h:29
Defines a simple memory pool used to call cub functions that use dynamic temporary storage.
Definition GridHandle.h:31
Cuda specific utility functions.
#define cudaCheck(ans)
Definition Util.h:49
static constexpr bool hasHostSingle
Definition Buffer.h:476
static constexpr bool hasDeviceSingle
Definition Buffer.h:467
static constexpr bool hasDeviceDual
Definition Buffer.h:463
Definition HostBuffer.h:101
Tag type selecting the Buffer constructors that skip element initialization, leaving the contents ind...
Definition Buffer.h:28
cudaStream_t mStream
Definition Buffer.h:41
Conditional stream storage for Buffer. The async specialization retains the stream of the most recent...
Definition Buffer.h:38
Detection trait: is_async_resource<R>::value is true iff R models the stream-ordered AsyncResource co...
Definition DeviceResource.h:118
Companion detection: is_device_accessible_resource<R>::value is true iff R declares static constexpr ...
Definition DeviceResource.h:147
Detection trait: is_host_accessible_resource<R>::value is true iff R declares static constexpr bool H...
Definition DeviceResource.h:135
Detection trait: is_resource<R>::value is true iff R models the synchronous Resource concept,...
Definition DeviceResource.h:165