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");
73 "a memory resource needs operator==: add friend bool operator==(const R&, const R&), true when memory "
74 "allocated through one may be deallocated through the other (always, for a stateless resource), "
75 "and operator!= for cuda::mr under C++17");
76 static_assert(std::is_trivially_copyable<T>::value,
77 "Buffer requires a trivially copyable T: elements are copied bytewise and never constructed or destroyed");
107 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
112 this->allocate(count,
stream);
123 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
131 template<typename S = R, std::enable_if_t<!is_async_resource<S>::value &&
is_resource<S>::value,
int> = 0>
135 this->allocate(count, cudaStream_t{0});
140 template<typename S = R, std::enable_if_t<!is_async_resource<S>::value &&
is_resource<S>::value,
int> = 0>
151 , mResource(std::move(other.mResource))
155 other.mData =
nullptr;
163 if (
this != &other) {
166 mResource = std::move(other.mResource);
169 other.mData =
nullptr;
179 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
183 if (mData)
cudaCheck(cudaMemcpyAsync(out.mData, mData, this->size_bytes(), cudaMemcpyDefault,
stream));
189 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
194 template<typename S = R, std::enable_if_t<!is_async_resource<S>::value &&
is_resource<S>::value,
int> = 0>
198 if (mData)
cudaCheck(cudaMemcpy(out.mData, mData, this->size_bytes(), cudaMemcpyDefault));
208 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
209 cudaStream_t
stream()
const {
return this->mStream; }
218 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
232 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
235 if (count != mSize) {
239 T* newData = count ?
static_cast<T*
>(mResource.allocate_async(checkedBytes(count), R::DEFAULT_ALIGNMENT,
stream))
241 if (newData && mData) {
242 const size_t prefix = count < mSize ? count : mSize;
244 cudaCheck(cudaMemcpyAsync(newData, mData, prefix *
sizeof(T), cudaMemcpyDefault,
stream));
247 mResource.deallocate_async(newData, checkedBytes(count), R::DEFAULT_ALIGNMENT,
stream);
252 this->deallocate(mData, mSize);
264 template<typename S = R, std::enable_if_t<!is_async_resource<S>::value &&
is_resource<S>::value,
int> = 0>
267 if (count == mSize)
return;
270 T* newData = count ?
static_cast<T*
>(mResource.allocate(checkedBytes(count), R::DEFAULT_ALIGNMENT))
272 if (newData && mData) {
273 const size_t prefix = count < mSize ? count : mSize;
275 cudaCheck(cudaMemcpy(newData, mData, prefix *
sizeof(T), cudaMemcpyDefault));
278 mResource.deallocate(newData, checkedBytes(count), R::DEFAULT_ALIGNMENT);
282 this->deallocate(mData, mSize);
289 const T*
data()
const {
return mData; }
299 size_t size()
const {
return mSize; }
305 bool empty()
const {
return mSize == 0; }
312 this->deallocate(mData, mSize);
322 template<typename S = R, std::enable_if_t<is_async_resource<S>::value,
int> = 0>
337 std::swap(mResource, other.mResource);
338 std::swap(mData, other.mData);
339 std::swap(mSize, other.mSize);
348 static size_t checkedBytes(
size_t count)
350 if (count >
size_t(std::numeric_limits<std::ptrdiff_t>::max()) /
sizeof(T))
351 throw std::runtime_error(
"nanovdb::cuda::Buffer: element count exceeds the maximum buffer 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; }
439template<
typename BufferT>
455template<
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
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:124
T ElementType
Element and resource types, for generic code that rebinds one or constructs sibling buffers over the ...
Definition Buffer.h:84
R ResourceType
Definition Buffer.h:85
Buffer(const Buffer &)=delete
Explicitly disallow copy construction and assignment operation.
size_t size() const
Returns the number of elements.
Definition Buffer.h:299
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:332
void destroy()
Frees the buffer memory (if any) and resets to the empty state. A stream-ordered resource frees on th...
Definition Buffer.h:310
cudaStream_t stream() const
Definition Buffer.h:209
Buffer< U, R > rebind
Alias for a sibling buffer over the same resource with a different element type.
Definition Buffer.h:90
const T * data() const
Definition Buffer.h:289
bool empty() const
Returns true if this buffer manages no memory.
Definition Buffer.h:305
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:108
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:180
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:323
R resource() const
Definition Buffer.h:296
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:132
void resize(cudaStream_t stream, size_t count)
Resizes the buffer to count elements, preserving the leading min(old, new) elements....
Definition Buffer.h:233
Buffer copy() const
Returns a deep copy of this buffer ordered on the retained stream, i.e. copy(this->stream()).
Definition Buffer.h:190
void resize(size_t count)
Resizes the buffer to count elements through the synchronous resource, preserving the leading min(old...
Definition Buffer.h:265
Buffer(size_t count, NoInit)
Convenience c-tor using a default-constructed resource.
Definition Buffer.h:141
~Buffer()
D-tor. A stream-ordered resource frees on the retained stream; a synchronous resource frees immediate...
Definition Buffer.h:204
T * data()
Returns a pointer to the elements, or nullptr if empty.
Definition Buffer.h:288
void set_stream(cudaStream_t stream)
Replaces the retained stream without synchronizing; subsequent deallocation (and destruction) is orde...
Definition Buffer.h:219
Buffer(Buffer &&other) noexcept
Move c-tor; steals the allocation (and retained stream, if any) and leaves other empty.
Definition Buffer.h:149
Buffer & operator=(Buffer &&other) noexcept
Move assignment; frees the current allocation first, then steals from other and leaves it empty....
Definition Buffer.h:161
size_t size_bytes() const
Returns the size of the buffer's allocation in bytes.
Definition Buffer.h:302
Buffer & operator=(const Buffer &)=delete
Definition VoxToNanoVDB.h:15
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:34
Cuda specific utility functions.
#define cudaCheck(ans)
Definition Util.h:49
static constexpr bool hasHostSingle
Definition Buffer.h:470
static constexpr bool hasDeviceSingle
Definition Buffer.h:461
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:113
Companion detection: is_device_accessible_resource<R>::value is true iff R declares static constexpr ...
Definition DeviceResource.h:142
Detection trait: is_equality_comparable_resource<R>::value is true iff R models a resource concept an...
Definition DeviceResource.h:175
Detection trait: is_host_accessible_resource<R>::value is true iff R declares static constexpr bool H...
Definition DeviceResource.h:130
Detection trait: is_resource<R>::value is true iff R models the synchronous Resource concept,...
Definition DeviceResource.h:160