OpenVDB 12.0.0
 
Loading...
Searching...
No Matches
HostBuffer.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3
4/*!
5 @file nanovdb/HostBuffer.h
6
7 @date April 20, 2021
8
9 @brief HostBuffer - a buffer that contains a shared or private bump
10 pool to either externally or internally managed host memory.
11
12 @details This HostBuffer can be used in multiple ways, most of which are
13 demonstrated in the examples below. Memory in the pool can
14 be managed or unmanged (e.g. internal or external) and can
15 be shared between multiple buffers or belong to a single buffer.
16
17 Example that uses HostBuffer::create inside io::readGrids to create a
18 full self-managed buffer, i.e. not shared and without padding, per grid in the file.
19 @code
20 auto handles = nanovdb::io::readGrids("file.nvdb");
21 @endcode
22
23 Example that uses HostBuffer::createFull. Assuming you have a raw pointer
24 to a NanoVDB grid of unknown type, this examples shows how to create its
25 GridHandle which can be used to enquire about the grid type and meta data.
26 @code
27 void *data;// pointer to a NanoVDB grid of unknown type
28 uint64_t size;// byte size of NanoVDB grid of unknown type
29 auto buffer = nanovdb::HostBuffer::createFull(size, data);
30 nanovdb::GridHandle<> gridHandle(std::move(buffer));
31 @endcode
32
33 Example that uses HostBuffer::createPool for internally managed host memory.
34 Suppose you want to read multiple grids in multiple files, but reuse the same
35 fixed sized memory buffer to both avoid memory fragmentation as well as
36 exceeding the fixed memory ceiling!
37 @code
38 auto pool = nanovdb::HostBuffer::createPool(1 << 30);// 1 GB memory pool
39 std::vector<std::string>> frames;// vector of grid names
40 for (int i=0; i<frames.size(); ++i) {
41 auto handles = nanovdb::io::readGrids(frames[i], 0, pool);// throws if grids in file exceed 1 GB
42 ...
43 pool.reset();// clears all handles and resets the memory pool for reuse
44 }
45 @endcode
46
47 Example that uses HostBuffer::createPool for externally managed host memory.
48 Note that in this example @c handles are allowed to outlive @c pool since
49 they internally store a shared pointer to the memory pool. However @c data
50 MUST outlive @c handles since the pool does not own its memory in this example.
51 @code
52 const size_t poolSize = 1 << 30;// 1 GB
53 void *data = std::malloc(size + NANOVDB_DATA_ALIGNMENT);// 1 GB pool with padding
54 void *buffer = nanovdb::alignPtr(data);// 32B aligned buffer
55 //void *buffer = std::aligned_alloc(NANOVDB_DATA_ALIGNMENT, poolSize);// in C++17
56 auto pool = nanovdb::HostBuffer::createPool(poolSize, buffer);
57 auto handles1 = nanovdb::io::readGrids("file1.nvdb", 0, pool);
58 auto handles2 = nanovdb::io::readGrids("file2.nvdb", 0, pool);
59 ....
60 std::free(data);
61 //std::free(buffer);
62 @endcode
63
64 Example that uses HostBuffer::createPool for externally managed host memory.
65 Note that in this example @c handles are allowed to outlive @c pool since
66 they internally store a shared pointer to the memory pool. However @c array
67 MUST outlive @c handles since the pool does not own its memory in this example.
68 @code
69 const size_t poolSize = 1 << 30;// 1 GB
70 std::unique_ptr<char[]> array(new char[size + NANOVDB_DATA_ALIGNMENT]);// scoped pool of 1 GB with padding
71 void *buffer = nanovdb::alignPtr(array.get());// 32B aligned buffer
72 auto pool = nanovdb::HostBuffer::createPool(poolSize, buffer);
73 auto handles = nanovdb::io::readGrids("file.nvdb", 0, pool);
74 @endcode
75*/
76
77#ifndef NANOVDB_HOSTBUFFER_H_HAS_BEEN_INCLUDED
78#define NANOVDB_HOSTBUFFER_H_HAS_BEEN_INCLUDED
79
80#include <nanovdb/NanoVDB.h>// for NANOVDB_DATA_ALIGNMENT;
81#include <stdint.h> // for types like int32_t etc
82#include <cstdio> // for fprintf
83#include <cstdlib> // for std::malloc/std::realloc/std::free
84#include <memory>// for std::make_shared
85#include <mutex>// for std::mutex
86#include <unordered_set>// for std::unordered_set
87#include <cassert>// for assert
88#include <sstream>// for std::stringstream
89#include <cstring>// for memcpy
90
91#define checkPtr(ptr, msg) \
92 { \
93 ptrAssert((ptr), (msg), __FILE__, __LINE__); \
94 }
95
96namespace nanovdb {
97
98template<typename BufferT>
100{
101 static constexpr bool hasDeviceDual = false;
102};
103
104// ----------------------------> HostBuffer <--------------------------------------
105
106/// @brief This is a buffer that contains a shared or private pool
107/// to either externally or internally managed host memory.
108///
109/// @note Terminology:
110/// Pool: 0 = buffer.size() < buffer.poolSize()
111/// Buffer: 0 < buffer.size() < buffer.poolSize()
112/// Full: 0 < buffer.size() = buffer.poolSize()
113/// Empty: 0 = buffer.size() = buffer.poolSize()
115{
116 struct Pool;// forward declaration of private pool struct
117 std::shared_ptr<Pool> mPool;
118 uint64_t mSize; // total number of bytes for the NanoVDB grid.
119 void* mData; // raw buffer for the NanoVDB grid.
120
121#if defined(DEBUG) || defined(_DEBUG)
122 static inline void ptrAssert(void* ptr, const char* msg, const char* file, int line, bool abort = true)
123 {
124 if (ptr == nullptr) {
125 fprintf(stderr, "NULL pointer error: %s %s %d\n", msg, file, line);
126 if (abort)
127 exit(1);
128 }
129 if (uint64_t(ptr) % NANOVDB_DATA_ALIGNMENT) {
130 fprintf(stderr, "Alignment pointer error: %s %s %d\n", msg, file, line);
131 if (abort)
132 exit(1);
133 }
134 }
135#else
136 static inline void ptrAssert(void*, const char*, const char*, int, bool = true)
137 {
138 }
139#endif
140
141public:
142 /// @brief Return a full buffer or an empty buffer
143 HostBuffer(uint64_t bufferSize = 0);
144
145 /// @brief Move copy-constructor
146 HostBuffer(HostBuffer&& other);
147
148 /// @brief Custom descructor
149 ~HostBuffer() { this->clear(); }
150
151 /// @brief Move copy assignment operation
153
154 /// @brief Disallow copy-construction
155 HostBuffer(const HostBuffer&) = delete;
156
157 /// @brief Disallow copy assignment operation
158 HostBuffer& operator=(const HostBuffer&) = delete;
159
160 /// @brief Return a pool buffer which satisfies: buffer.size == 0,
161 /// buffer.poolSize() == poolSize, and buffer.data() == nullptr.
162 /// If data==nullptr, memory for the pool will be allocated.
163 ///
164 /// @throw If poolSize is zero.
165 static HostBuffer createPool(uint64_t poolSize, void *data = nullptr);
166
167 /// @brief Return a full buffer which satisfies: buffer.size == bufferSize,
168 /// buffer.poolSize() == bufferSize, and buffer.data() == data.
169 /// If data==nullptr, memory for the pool will be allocated.
170 ///
171 /// @throw If bufferSize is zero.
172 static HostBuffer createFull(uint64_t bufferSize, void *data = nullptr);
173
174 /// @brief Return a buffer with @c bufferSize bytes managed by
175 /// the specified memory @c pool. If none is provided, i.e.
176 /// @c pool == nullptr or @c pool->poolSize() == 0, one is
177 /// created with size @c bufferSize, i.e. a full buffer is returned.
178 ///
179 /// @throw If the specified @c pool has insufficient memory for
180 /// the requested buffer size.
181 static HostBuffer create(uint64_t bufferSize, const HostBuffer* pool = nullptr);
182
183 /// @brief Initialize as a full buffer with the specified size. If data is NULL
184 /// the memory is internally allocated.
185 void init(uint64_t bufferSize, void *data = nullptr);
186
187 //@{
188 /// @brief Retuns a pointer to the raw memory buffer managed by this allocator.
189 ///
190 /// @warning Note that the pointer can be NULL if the allocator was not initialized!
191 const void* data() const { return mData; }
192 void* data() { return mData; }
193 //@}
194
195 //@{
196 /// @brief Returns the size in bytes associated with this buffer.
197 uint64_t bufferSize() const { return mSize; }
198 uint64_t size() const { return this->bufferSize(); }
199 //@}
200
201 /// @brief Returns the size in bytes of the memory pool shared with this instance.
202 uint64_t poolSize() const;
203
204 /// @brief Return true if memory is managed (using std::malloc and std:free) by the
205 /// shared pool in this buffer. Else memory is assumed to be managed externally.
206 bool isManaged() const;
207
208 //@{
209 /// @brief Returns true if this buffer has no memory associated with it
210 bool isEmpty() const { return !mPool || mSize == 0 || mData == nullptr; }
211 bool empty() const { return this->isEmpty(); }
212 //@}
213
214 /// @brief Return true if this is a pool, i.e. an empty buffer with a nonempty
215 /// internal pool, i.e. this->size() == 0 and this->poolSize() != 0
216 bool isPool() const { return mSize == 0 && this->poolSize() > 0; }
217
218 /// @brief Return true if the pool exists, is nonempty but has no more available memory
219 bool isFull() const;
220
221 /// @brief Clear this buffer so it is empty.
222 void clear();
223
224 /// @brief Clears all existing buffers that are registered against the memory pool
225 /// and resets the pool so it can be reused to create new buffers.
226 ///
227 /// @throw If this instance is not empty or contains no pool.
228 ///
229 /// @warning This method is not thread-safe!
230 void reset();
231
232 /// @brief Total number of bytes from the pool currently in use by buffers
233 uint64_t poolUsage() const;
234
235 /// @brief resize the pool size. It will attempt to resize the existing
236 /// memory block, but if that fails a deep copy is performed.
237 /// If @c data is not NULL it will be used as new externally
238 /// managed memory for the pool. All registered buffers are
239 /// updated so GridHandle::grid might return a new address (if
240 /// deep copy was performed).
241 ///
242 /// @note This method can be use to resize the memory pool and even
243 /// change it from internally to externally managed memory or vice versa.
244 ///
245 /// @throw if @c poolSize is less than this->poolUsage() the used memory
246 /// or allocations fail.
247 void resizePool(uint64_t poolSize, void *data = nullptr);
248
249}; // HostBuffer class
250
251// --------------------------> Implementation of HostBuffer::Pool <------------------------------------
252
253// This is private struct of HostBuffer so you can safely ignore the API
255{
256 using HashTableT = std::unordered_set<HostBuffer*>;
257 std::mutex mMutex; // mutex for updating mRegister and mFree
259 void *mData, *mFree;
260 uint64_t mSize, mPadding;
262
263 /// @brief External memory ctor
264 Pool(uint64_t size = 0, void* data = nullptr)
265 : mData(data)
266 , mFree(mData)
267 , mSize(size)
268 , mPadding(0)
269 , mManaged(data == nullptr)
270 {
271 if (mManaged) {
272 mData = Pool::alloc(mSize);
273 if (mData == nullptr) throw std::runtime_error("Pool::Pool malloc failed");
274 }
276 if (!mManaged && mPadding != 0) {
277 throw std::runtime_error("Pool::Pool: external memory buffer is not aligned to " +
278 std::to_string(NANOVDB_DATA_ALIGNMENT) +
279 " bytes.\nHint: use nanovdb::alignPtr or std::aligned_alloc (C++17 only)");
280 }
282 }
283
284 /// @brief Custom destructor
286 {
287 assert(mRegister.empty());
288 if (mManaged) std::free(mData);
289 }
290
291 /// @brief Disallow copy-construction
292 Pool(const Pool&) = delete;
293
294 /// @brief Disallow move-construction
295 Pool(const Pool&&) = delete;
296
297 /// @brief Disallow copy assignment operation
298 Pool& operator=(const Pool&) = delete;
299
300 /// @brief Disallow move assignment operation
301 Pool& operator=(const Pool&&) = delete;
302
303 /// @brief Return the total number of bytes used from this Pool by buffers
304 uint64_t usage() const { return util::PtrDiff(mFree, mData) - mPadding; }
305
306 /// @brief Allocate a buffer of the specified size and add it to the register
307 void add(HostBuffer* buffer, uint64_t size)
308 {
309 void *alignedFree = util::PtrAdd(mFree, alignmentPadding(mFree));
310
311 if (util::PtrAdd(alignedFree, size) > util::PtrAdd(mData, mPadding + mSize)) {
312 std::stringstream ss;
313 ss << "HostBuffer::Pool: insufficient memory\n"
314 << "\tA buffer requested " << size << " bytes with " << NANOVDB_DATA_ALIGNMENT
315 << "-bytes alignment from a pool with "
316 << mSize << " bytes of which\n\t" << (util::PtrDiff(alignedFree, mData) - mPadding)
317 << " bytes are used by " << mRegister.size() << " other buffer(s). "
318 << "Pool is " << (mManaged ? "internally" : "externally") << " managed.\n";
319 //std::cerr << ss.str();
320 throw std::runtime_error(ss.str());
321 }
322 buffer->mSize = size;
323 const std::lock_guard<std::mutex> lock(mMutex);
324 mRegister.insert(buffer);
325 buffer->mData = alignedFree;
326 mFree = util::PtrAdd(alignedFree, size);
327 }
328
329 /// @brief Remove the specified buffer from the register
330 void remove(HostBuffer *buffer)
331 {
332 const std::lock_guard<std::mutex> lock(mMutex);
333 mRegister.erase(buffer);
334 }
335
336 /// @brief Replaces buffer1 with buffer2 in the register
337 void replace(HostBuffer *buffer1, HostBuffer *buffer2)
338 {
339 const std::lock_guard<std::mutex> lock(mMutex);
340 mRegister.erase( buffer1);
341 mRegister.insert(buffer2);
342 }
343
344 /// @brief Reset the register and all its buffers
345 void reset()
346 {
347 for (HostBuffer *buffer : mRegister) {
348 buffer->mPool.reset();
349 buffer->mSize = 0;
350 buffer->mData = nullptr;
351 }
352 mRegister.clear();
354 }
355
356 /// @brief Resize this Pool and update registered buffers as needed. If data is no NULL
357 /// it is used as externally managed memory.
358 void resize(uint64_t size, void *data = nullptr)
359 {
360 const uint64_t memUsage = this->usage();
361
362 const bool managed = (data == nullptr);
363
364 if (!managed && alignmentPadding(data) != 0) {
365 throw std::runtime_error("Pool::resize: external memory buffer is not aligned to " +
366 std::to_string(NANOVDB_DATA_ALIGNMENT) + " bytes");
367 }
368
369 if (memUsage > size) {
370 throw std::runtime_error("Pool::resize: insufficient memory");
371 }
372
373 uint64_t padding = 0;
374 if (mManaged && managed && size != mSize) { // managed -> managed
375 padding = mPadding;
376 data = Pool::realloc(mData, memUsage, size, padding); // performs both copy and free of mData
377 } else if (!mManaged && managed) { // un-managed -> managed
378 data = Pool::alloc(size);
379 padding = alignmentPadding(data);
380 }
381
382 if (data == nullptr) {
383 throw std::runtime_error("Pool::resize: allocation failed");
384 } else if (data != mData) {
385 void* paddedData = util::PtrAdd(data, padding);
386
387 if (!(mManaged && managed)) { // no need to copy if managed -> managed
388 memcpy(paddedData, util::PtrAdd(mData, mPadding), memUsage);
389 }
390
391 for (HostBuffer* buffer : mRegister) { // update registered buffers
392 //buffer->mData = paddedData + ptrdiff_t(buffer->mData - (mData + mPadding));
393 buffer->mData = util::PtrAdd(paddedData, util::PtrDiff(buffer->mData, util::PtrAdd(mData, mPadding)));
394 }
395 mFree = util::PtrAdd(paddedData, memUsage); // update the free pointer
396 if (mManaged && !managed) {// only free if managed -> un-managed
397 std::free(mData);
398 }
399
400 mData = data;
401 mPadding = padding;
402 }
403 mSize = size;
404 mManaged = managed;
405 }
406 /// @brief Return true is all the memory in this pool is in use.
407 bool isFull() const
408 {
409 assert(mFree <= util::PtrAdd(mData, mPadding + mSize));
410 return mSize > 0 ? mFree == util::PtrAdd(mData, mPadding + mSize) : false;
411 }
412
413private:
414
415 static void* alloc(uint64_t size)
416 {
417//#if (__cplusplus >= 201703L)
418// return std::aligned_alloc(NANOVDB_DATA_ALIGNMENT, size);//C++17 or newer
419//#else
420 // make sure we alloc enough space to align the result
421 return std::malloc(size + NANOVDB_DATA_ALIGNMENT);
422//#endif
423 }
424
425 static void* realloc(void* const origData,
426 uint64_t origSize,
427 uint64_t desiredSize,
428 uint64_t& padding)
429 {
430 // make sure we alloc enough space to align the result
431 void* data = std::realloc(origData, desiredSize + NANOVDB_DATA_ALIGNMENT);
432
433 if (data != nullptr && data != origData) {
434 uint64_t newPadding = alignmentPadding(data);
435 // Number of padding bytes may have changed -- move data if that's the case
436 if (newPadding != padding) {
437 // Realloc should not happen when shrinking down buffer, but let's be safe
438 std::memmove(util::PtrAdd(data, newPadding),
439 util::PtrAdd(data, padding),
440 math::Min(origSize, desiredSize));
441 padding = newPadding;
442 }
443 }
444
445 return data;
446 }
447
448};// struct HostBuffer::Pool
449
450// --------------------------> Implementation of HostBuffer <------------------------------------
451
452inline HostBuffer::HostBuffer(uint64_t size) : mPool(nullptr), mSize(size), mData(nullptr)
453{
454 if (size>0) {
455 mPool = std::make_shared<Pool>(size);
456 mData = mPool->mFree;
457 mPool->mRegister.insert(this);
458 mPool->mFree = util::PtrAdd(mPool->mFree, size);
459 }
460}
461
462inline HostBuffer::HostBuffer(HostBuffer&& other) : mPool(other.mPool), mSize(other.mSize), mData(other.mData)
463{
464 if (mPool && mSize != 0) {
465 mPool->replace(&other, this);
466 }
467 other.mPool.reset();
468 other.mSize = 0;
469 other.mData = nullptr;
470}
471
472inline void HostBuffer::init(uint64_t bufferSize, void *data)
473{
474 if (bufferSize == 0) {
475 throw std::runtime_error("HostBuffer: invalid buffer size");
476 }
477 if (mPool) {
478 mPool.reset();
479 }
480 if (!mPool || mPool->mSize != bufferSize) {
481 mPool = std::make_shared<Pool>(bufferSize, data);
482 }
483 mPool->add(this, bufferSize);
484}
485
487{
488 if (mPool) {
489 mPool->remove(this);
490 }
491 mPool = other.mPool;
492 mSize = other.mSize;
493 mData = other.mData;
494 if (mPool && mSize != 0) {
495 mPool->replace(&other, this);
496 }
497 other.mPool.reset();
498 other.mSize = 0;
499 other.mData = nullptr;
500 return *this;
501}
502
503inline uint64_t HostBuffer::poolSize() const
504{
505 return mPool ? mPool->mSize : 0u;
506}
507
508inline uint64_t HostBuffer::poolUsage() const
509{
510 return mPool ? mPool->usage(): 0u;
511}
512
513inline bool HostBuffer::isManaged() const
514{
515 return mPool ? mPool->mManaged : false;
516}
517
518inline bool HostBuffer::isFull() const
519{
520 return mPool ? mPool->isFull() : false;
521}
522
524{
525 if (poolSize == 0) {
526 throw std::runtime_error("HostBuffer: invalid pool size");
527 }
528 HostBuffer buffer;
529 buffer.mPool = std::make_shared<Pool>(poolSize, data);
530 // note the buffer is NOT registered by its pool since it is not using its memory
531 buffer.mSize = 0;
532 buffer.mData = nullptr;
533 return buffer;
534}
535
537{
538 if (bufferSize == 0) {
539 throw std::runtime_error("HostBuffer: invalid buffer size");
540 }
541 HostBuffer buffer;
542 buffer.mPool = std::make_shared<Pool>(bufferSize, data);
543 buffer.mPool->add(&buffer, bufferSize);
544 return buffer;
545}
546
548{
549 HostBuffer buffer;
550 if (pool == nullptr || !pool->mPool) {
551 buffer.mPool = std::make_shared<Pool>(bufferSize);
552 } else {
553 buffer.mPool = pool->mPool;
554 }
555 buffer.mPool->add(&buffer, bufferSize);
556 return buffer;
557}
558
559inline void HostBuffer::clear()
560{
561 if (mPool) {// remove self from the buffer register in the pool
562 mPool->remove(this);
563 }
564 mPool.reset();
565 mSize = 0;
566 mData = nullptr;
567}
568
569inline void HostBuffer::reset()
570{
571 if (this->size()>0) {
572 throw std::runtime_error("HostBuffer: only empty buffers can call reset");
573 }
574 if (!mPool) {
575 throw std::runtime_error("HostBuffer: this buffer contains no pool to reset");
576 }
577 mPool->reset();
578}
579
580inline void HostBuffer::resizePool(uint64_t size, void *data)
581{
582 if (!mPool) {
583 throw std::runtime_error("HostBuffer: this buffer contains no pool to resize");
584 }
585 mPool->resize(size, data);
586}
587
588} // namespace nanovdb
589
590#endif // end of NANOVDB_HOSTBUFFER_H_HAS_BEEN_INCLUDED
Implements a light-weight self-contained VDB data-structure in a single file! In other words,...
#define NANOVDB_DATA_ALIGNMENT
Definition NanoVDB.h:126
This is a buffer that contains a shared or private pool to either externally or internally managed ho...
Definition HostBuffer.h:115
void * data()
Definition HostBuffer.h:192
~HostBuffer()
Custom descructor.
Definition HostBuffer.h:149
HostBuffer(const HostBuffer &)=delete
Disallow copy-construction.
const void * data() const
Retuns a pointer to the raw memory buffer managed by this allocator.
Definition HostBuffer.h:191
HostBuffer(uint64_t bufferSize=0)
Return a full buffer or an empty buffer.
Definition HostBuffer.h:452
HostBuffer & operator=(HostBuffer &&other)
Move copy assignment operation.
Definition HostBuffer.h:486
uint64_t bufferSize() const
Returns the size in bytes associated with this buffer.
Definition HostBuffer.h:197
bool empty() const
Definition HostBuffer.h:211
static HostBuffer createFull(uint64_t bufferSize, void *data=nullptr)
Return a full buffer which satisfies: buffer.size == bufferSize, buffer.poolSize() == bufferSize,...
Definition HostBuffer.h:536
uint64_t poolSize() const
Returns the size in bytes of the memory pool shared with this instance.
Definition HostBuffer.h:503
uint64_t size() const
Definition HostBuffer.h:198
void init(uint64_t bufferSize, void *data=nullptr)
Initialize as a full buffer with the specified size. If data is NULL the memory is internally allocat...
Definition HostBuffer.h:472
HostBuffer & operator=(const HostBuffer &)=delete
Disallow copy assignment operation.
uint64_t poolUsage() const
Total number of bytes from the pool currently in use by buffers.
Definition HostBuffer.h:508
bool isPool() const
Return true if this is a pool, i.e. an empty buffer with a nonempty internal pool,...
Definition HostBuffer.h:216
bool isManaged() const
Return true if memory is managed (using std::malloc and std:free) by the shared pool in this buffer....
Definition HostBuffer.h:513
static HostBuffer create(uint64_t bufferSize, const HostBuffer *pool=nullptr)
Return a buffer with bufferSize bytes managed by the specified memory pool. If none is provided,...
Definition HostBuffer.h:547
void clear()
Clear this buffer so it is empty.
Definition HostBuffer.h:559
bool isEmpty() const
Returns true if this buffer has no memory associated with it.
Definition HostBuffer.h:210
void reset()
Clears all existing buffers that are registered against the memory pool and resets the pool so it can...
Definition HostBuffer.h:569
bool isFull() const
Return true if the pool exists, is nonempty but has no more available memory.
Definition HostBuffer.h:518
void resizePool(uint64_t poolSize, void *data=nullptr)
resize the pool size. It will attempt to resize the existing memory block, but if that fails a deep c...
Definition HostBuffer.h:580
static HostBuffer createPool(uint64_t poolSize, void *data=nullptr)
Return a pool buffer which satisfies: buffer.size == 0, buffer.poolSize() == poolSize,...
Definition HostBuffer.h:523
static DstT * PtrAdd(void *p, int64_t offset)
Adds a byte offset to a non-const pointer to produce another non-const pointer.
Definition Util.h:478
static int64_t PtrDiff(const void *p, const void *q)
Compute the distance, in bytes, between two pointers, dist = p - q.
Definition Util.h:464
Definition GridHandle.h:27
static __hostdev__ uint64_t alignmentPadding(const void *p)
return the smallest number of bytes that when added to the specified pointer results in a 32 byte ali...
Definition NanoVDB.h:550
Definition HostBuffer.h:100
static constexpr bool hasDeviceDual
Definition HostBuffer.h:101
Definition HostBuffer.h:255
std::unordered_set< HostBuffer * > HashTableT
Definition HostBuffer.h:256
void resize(uint64_t size, void *data=nullptr)
Resize this Pool and update registered buffers as needed. If data is no NULL it is used as externally...
Definition HostBuffer.h:358
uint64_t usage() const
Return the total number of bytes used from this Pool by buffers.
Definition HostBuffer.h:304
void replace(HostBuffer *buffer1, HostBuffer *buffer2)
Replaces buffer1 with buffer2 in the register.
Definition HostBuffer.h:337
Pool(uint64_t size=0, void *data=nullptr)
External memory ctor.
Definition HostBuffer.h:264
uint64_t mSize
Definition HostBuffer.h:260
void * mData
Definition HostBuffer.h:259
Pool(const Pool &)=delete
Disallow copy-construction.
void add(HostBuffer *buffer, uint64_t size)
Allocate a buffer of the specified size and add it to the register.
Definition HostBuffer.h:307
void remove(HostBuffer *buffer)
Remove the specified buffer from the register.
Definition HostBuffer.h:330
void * mFree
Definition HostBuffer.h:259
Pool & operator=(const Pool &&)=delete
Disallow move assignment operation.
std::mutex mMutex
Definition HostBuffer.h:257
Pool(const Pool &&)=delete
Disallow move-construction.
HashTableT mRegister
Definition HostBuffer.h:258
uint64_t mPadding
Definition HostBuffer.h:260
Pool & operator=(const Pool &)=delete
Disallow copy assignment operation.
void reset()
Reset the register and all its buffers.
Definition HostBuffer.h:345
~Pool()
Custom destructor.
Definition HostBuffer.h:285
bool isFull() const
Return true is all the memory in this pool is in use.
Definition HostBuffer.h:407
bool mManaged
Definition HostBuffer.h:261