HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CE_VDBCreate.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: CE_VDBCreate.h ( CE Library, C++)
7  *
8  * COMMENTS: GPU NanoVDB Creation.
9  */
10 
11 #ifndef __CE_VDBCreate__
12 #define __CE_VDBCreate__
13 
14 #include "CE_API.h"
15 
16 #include <bitset>
17 
18 #include <UT/UT_Error.h>
19 #include <UT/UT_StringHolder.h>
20 #include <UT/UT_Debug.h>
21 
22 #include <CE/CE_Context.h>
23 
24 #include <nanovdb/NanoVDB.h>
27 
28 namespace nanovdb
29 {
30 
31 //
32 // Pointer check utils
33 //
34 
35 static inline void ptrAssert(const void* ptr, const char* msg, const char* file, int line)
36 {
37  if (ptr == nullptr)
38  {
39  UTdebugFormatCd(red, "NULL pointer error: {} {} {}\n", msg, file, line);
40  UT_ASSERT(false);
41  }
42  else if (uint64_t(ptr) % NANOVDB_DATA_ALIGNMENT)
43  {
44  UTdebugFormatCd(red, "Pointer misalignment error: {} {} {}\n", msg, file, line);
45  UT_ASSERT(false);
46  }
47 }
48 
49 static inline void bufferAssert(const void* buf, const char* msg, const char* file, int line)
50 {
51  if (buf == nullptr)
52  {
53  UTdebugFormatCd(red, "NULL buffer error: {} {} {}\n", msg, file, line);
54  UT_ASSERT(false);
55  }
56 }
57 
58 #define checkPtr(ptr, msg) \
59  { \
60  ptrAssert((ptr), (msg), __FILE__, __LINE__); \
61  }
62 
63 #define checkBuffer(buf, msg) \
64  { \
65  bufferAssert((buf), (msg), __FILE__, __LINE__); \
66  }
67 
68 //
69 // OclDeviceBuffer
70 // TODO: should be moved to it's own header
71 //
72 
74 {
75  uint64_t mSize; // total number of bytes managed by this buffer (assumed to be identical for host and device)
76  uint8_t *mCpuData; // raw pointers to the host buffer
77  cl::Buffer mGpuData; // device buffer
78 
79 public:
80  /// @brief Static factory method that return an instance of this buffer
81  /// @param size byte size of buffer to be initialized
82  /// @param host If true buffer is initialized only on the host/CPU, else on the device/GPU
83  /// @return An instance of this class using move semantics
84  static OclDeviceBuffer create(uint64_t size, bool host = true);
85 
86  /// @brief Constructor
87  /// @param size byte size of buffer to be initialized
88  /// @param host If true buffer is initialized only on the host/CPU, else on the device/GPU
89  OclDeviceBuffer(uint64_t size = 0, bool host = true)
90  : mSize(0)
91  , mCpuData(nullptr)
92  , mGpuData(cl::Buffer())
93  {
94  if (size > 0) this->init(size, host);
95  }
96 
97  /// @brief Disallow copy-construction
98  OclDeviceBuffer(const OclDeviceBuffer&) = delete;
99 
100  /// @brief Move copy-constructor
102  : mSize(other.mSize)
103  , mCpuData(other.mCpuData)
104  , mGpuData(other.mGpuData)
105  {
106  other.mSize = 0;
107  other.mCpuData = nullptr;
108  other.mGpuData = cl::Buffer();
109  }
110 
111  /// @brief Disallow copy assignment operation
112  OclDeviceBuffer& operator=(const OclDeviceBuffer&) = delete;
113 
114  /// @brief Move copy assignment operation
116  {
117  this->clear();
118  mSize = other.mSize;
119  mCpuData = other.mCpuData;
120  mGpuData = other.mGpuData;
121  other.mSize = 0;
122  other.mCpuData = nullptr;
123  other.mGpuData = cl::Buffer();
124  return *this;
125  }
126 
127  /// @brief Destructor frees memory on both the host and device
128  ~OclDeviceBuffer() { this->clear(); };
129 
130  /// @brief Initialize buffer
131  /// @param size byte size of buffer to be initialized
132  /// @param host If true buffer is initialized only on the host/CPU, else on the device/GPU
133  /// @note All existing buffers are first cleared
134  /// @warning size is expected to be non-zero. Use clear() clear buffer!
135  void init(uint64_t size, bool host = true);
136 
137  /// @brief Retuns a raw pointer to the host/CPU buffer managed by this allocator.
138  /// @warning Note that the pointer can be NULL!
139  uint8_t* data() const { return mCpuData; }
140 
141  /// @brief Retuns a cl::Buffer ref to the device/GPU buffer managed by this allocator.
142  /// @warning Note that the pointer can be NULL!
143  const cl::Buffer& deviceData() const { return mGpuData; }
144 
145  /// @brief Upload this buffer from the host to the device, i.e. CPU -> GPU.
146  /// @param stream optional stream (defaults to stream 0) (never used)
147  /// @param sync if false the memory copy is asynchronous (never used)
148  /// @note If the device/GPU buffer does not exist it is first allocated
149  /// @warning Assumes that the host/CPU buffer already exists
150  void deviceUpload(void* stream = nullptr, bool sync = true);
151 
152  /// @brief Upload this buffer from the device to the host, i.e. GPU -> CPU.
153  /// @param stream optional stream (defaults to stream 0) (never used)
154  /// @param sync if false the memory copy is asynchronous (never used)
155  /// @note If the host/CPU buffer does not exist it is first allocated
156  /// @warning Assumes that the device/GPU buffer already exists
157  void deviceDownload(void* stream = nullptr, bool sync = true);
158 
159  /// @brief Returns the size in bytes of the raw memory buffer managed by this allocator.
160  uint64_t size() const { return mSize; }
161 
162  //@{
163  /// @brief Returns true if this allocator is empty, i.e. has no allocated memory
164  bool empty() const { return mSize == 0; }
165  bool isEmpty() const { return mSize == 0; }
166  //@}
167 
168  /// @brief De-allocate all memory managed by this allocator and set all pointers to NULL
169  void clear();
170 
171 };
172 
173 template<>
175 {
176  static constexpr bool hasDeviceDual = true;
177 };
178 
179 // --------------------------> Implementations below <--------------------------
180 
181 inline OclDeviceBuffer OclDeviceBuffer::create(uint64_t size, bool host)
182 {
183  return OclDeviceBuffer(size, host);
184 }
185 
186 inline void OclDeviceBuffer::init(uint64_t size, bool host)
187 {
188  if (mSize > 0)
189  this->clear();
190  UT_ASSERT(size > 0);
191  if (host)
192  {
193  mCpuData = new uint8_t[size];
194  checkPtr(mCpuData, "OclDeviceBuffer::init: failed to allocate host buffer");
195  }
196  else
197  {
198  CE_Context* context = CE_Context::getContext();
199  mGpuData = context->allocBuffer(size); // un-managed memory on the device, always 32B aligned!
200  checkBuffer(mGpuData(), "OclDeviceBuffer::init: failed to allocate device buffer");
201  }
202  mSize = size;
203 }
204 
205 inline void OclDeviceBuffer::deviceUpload(void* stream, bool sync)
206 {
207  CE_Context *context = CE_Context::getContext();
208 
209  checkPtr(mCpuData, "uninitialized cpu data");
210  if (mGpuData() == nullptr) {
211  mGpuData = context->allocBuffer(mSize); // un-managed memory on the device, always 32B aligned!
212  }
213  checkBuffer(mGpuData(), "uninitialized gpu data");
214 
215  context->writeBuffer(mGpuData, mSize, mCpuData);
216 }
217 
218 inline void OclDeviceBuffer::deviceDownload(void* stream, bool sync)
219 {
220  CE_Context *context = CE_Context::getContext();
221 
222  checkBuffer(mGpuData(), "uninitialized gpu data");
223  if (mCpuData == nullptr) {
224  mCpuData = new uint8_t[mSize];
225  }
226  checkPtr(mCpuData, "uninitialized cpu data");
227 
228  context->readBuffer(mGpuData, mSize, mCpuData);
229 }
230 
232 {
233  CE_Context *context = CE_Context::getContext();
234  if (mGpuData() != nullptr) context->releaseBuffer(std::move(mGpuData));
235  if (mCpuData != nullptr) delete[] mCpuData;
236  mCpuData = nullptr;
237  mGpuData = cl::Buffer();
238  mSize = 0;
239 }
240 
241 } // nanovdb namespace
242 
244 {
245 public:
247 
248  static uint32_t
249  runLengthEncoding(
250  uint32_t in_count,
251  const cl::Buffer& input,
253  cl::Buffer& counts,
254  uint32_t bit_shift_right = 0);
255 
256  static void
257  radixSortPairs(
258  uint32_t in_count,
259  cl::Buffer& in_key,
260  cl::Buffer& in_val,
261  uint32_t lsb = -1,
262  uint32_t msb = -1,
263  uint32_t offset = 0, // offset in elems of the in_* arrays
264  uint32_t buffer_nelem = -1);
265 
266  template <
267  typename BuildT,
268  typename PtrT,
269  typename BufferT = nanovdb::OclDeviceBuffer>
270  static nanovdb::GridHandle<BufferT> oclPointsToGrid(
271  const PtrT d_ijk,
272  uint32_t voxelcount,
273  double voxelsize,
274  const bool activateleaves,
275  const uint32_t leafdilation,
276  const UT_StringHolder& gridname,
277  const nanovdb::GridClass gridclass,
278  const BuildT& bgvalue,
279  cl::Buffer& tilestart,
280  exint& leafcount,
281  exint& lowercount,
282  exint& uppercount,
283  void** datacacheptr);
284 
285  template <typename BuildT>
286  static void deleteDataCache(void* datacacheptr);
287 };
288 
289 #endif
GLuint GLuint stream
Definition: glcorearb.h:1832
#define CE_API
Definition: CE_API.h:13
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
const cl::Buffer & deviceData() const
Retuns a cl::Buffer ref to the device/GPU buffer managed by this allocator.
Definition: CE_VDBCreate.h:143
GridClass
Classes (superset of OpenVDB) that are currently supported by NanoVDB.
Definition: NanoVDB.h:339
#define checkPtr(ptr, msg)
Definition: CE_VDBCreate.h:58
int64 exint
Definition: SYS_Types.h:125
#define UTdebugFormatCd(...)
Definition: UT_Debug.h:145
void releaseBuffer(cl::Buffer &&buf, bool use_pool=true)
Release the specified buffer, possibly to the CE_MemoryPool.
OclDeviceBuffer(uint64_t size=0, bool host=true)
Constructor.
Definition: CE_VDBCreate.h:89
uint8_t * data() const
Retuns a raw pointer to the host/CPU buffer managed by this allocator.
Definition: CE_VDBCreate.h:139
OclDeviceBuffer & operator=(OclDeviceBuffer &&other) noexcept
Move copy assignment operation.
Definition: CE_VDBCreate.h:115
void init(uint64_t size, bool host=true)
Initialize buffer.
Definition: CE_VDBCreate.h:186
void writeBuffer(const cl::Buffer &buf, size_t size, const void *p, bool blocking=true, size_t offset=0)
Write the specified number of bytes to the buffer.
Defines GridHandle, which manages a host, and possibly a device, memory buffer containing one or more...
uint64_t size() const
Returns the size in bytes of the raw memory buffer managed by this allocator.
Definition: CE_VDBCreate.h:160
This class serves to manage a buffer containing one or more NanoVDB Grids.
Definition: GridHandle.h:37
#define NANOVDB_DATA_ALIGNMENT
Definition: NanoVDB.h:154
GLintptr offset
Definition: glcorearb.h:665
static CE_Context * getContext(bool gl_shared=true, bool shared_fallback=true)
~OclDeviceBuffer()
Destructor frees memory on both the host and device.
Definition: CE_VDBCreate.h:128
Implements a light-weight self-contained VDB data-structure in a single file! In other words...
void readBuffer(const cl::Buffer &buf, size_t size, void *p, bool blocking=true, size_t offset=0)
Read the specified number of bytes from the buffer.
static OclDeviceBuffer create(uint64_t size, bool host=true)
Static factory method that return an instance of this buffer.
Definition: CE_VDBCreate.h:181
HostBuffer - a buffer that contains a shared or private bump pool to either externally or internally ...
#define checkBuffer(buf, msg)
Definition: CE_VDBCreate.h:63
OclDeviceBuffer & operator=(const OclDeviceBuffer &)=delete
Disallow copy assignment operation.
static constexpr bool hasDeviceDual
Definition: HostBuffer.h:101
cl::Buffer allocBuffer(int64 size, bool use_pool=true, bool read=true, bool write=true, uint32 ogl_bind=SYS_UINT32_MAX)
bool isEmpty() const
Returns true if this allocator is empty, i.e. has no allocated memory.
Definition: CE_VDBCreate.h:165
void clear()
De-allocate all memory managed by this allocator and set all pointers to NULL.
Definition: CE_VDBCreate.h:231
GLsizeiptr size
Definition: glcorearb.h:664
void deviceUpload(void *stream=nullptr, bool sync=true)
Upload this buffer from the host to the device, i.e. CPU -> GPU.
Definition: CE_VDBCreate.h:205
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
void deviceDownload(void *stream=nullptr, bool sync=true)
Upload this buffer from the device to the host, i.e. GPU -> CPU.
Definition: CE_VDBCreate.h:218
auto ptr(T p) -> const void *
Definition: format.h:4331
Memory buffer interface.
Definition: cl.hpp:1867
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
OclDeviceBuffer(OclDeviceBuffer &&other) noexcept
Move copy-constructor.
Definition: CE_VDBCreate.h:101
bool empty() const
Returns true if this allocator is empty, i.e. has no allocated memory.
Definition: CE_VDBCreate.h:164
png_structrp int png_fixed_point red
Definition: png.h:1083