AcademySoftwareFoundation / AcademySoftwareFoundation/openvdb
NanoVDB: VoxelBlockManagerHandle accessors don't compile for buffer types whose data()/deviceData() return typed pointers
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 3.4k
- Forks
- 777
- Avg merge
- 3d 9h
- Merged PRs (30d)
- 34
Description
Problem
nanovdb::tools::VoxelBlockManagerHandle<BufferT>'s eight pointer accessors static_cast directly from the buffer's data() / deviceData():
// nanovdb/tools/VoxelBlockManager.h:152 (and 159, 166, 173, 185, 188, 191, 194)
deviceFirstLeafID() { return static_cast<uint32_t*>(mFirstLeafID.deviceData()); }
This compiles when deviceData() returns void* (as NanoVDB's own HostBuffer / DeviceBuffer / UnifiedBuffer do), but a static_cast from any typed pointer to uint32_t* is ill-formed. A custom BufferT whose data() / deviceData() return e.g. uint8_t* fails to compile as soon as one of these accessors is instantiated:
nanovdb/tools/VoxelBlockManager.h(152): error: invalid type conversion
deviceFirstLeafID() { return static_cast<uint32_t*>(mFirstLeafID.deviceData()); }
detected during instantiation of ... VoxelBlockManagerHandle<BufferT>::deviceFirstLeafID()
[with BufferT=fvdb::TorchDeviceBuffer, U=fvdb::TorchDeviceBuffer]
Nothing in the BufferTraits contract requires void* returns — and the rest of the generic surface (GridHandle, cuda::mergeGridHandles, buildVoxelBlockManager's BufferT::create path, etc.) works fine with typed-pointer buffers because a typed pointer converts implicitly to void*. VoxelBlockManagerHandle is the outlier: it's the only place that needs the conversion in the other direction and spells it as a single static_cast.
Where this bites
fvdb-core's TorchDeviceBuffer (its BufferT backed by PyTorch's caching allocator, uint8_t* data()/deviceData()) is used as the buffer type for grid handles throughout fvdb. Building a VoxelBlockManagerHandle<TorchDeviceBuffer> — the natural way to keep the VBM's firstLeafID / jumpMap arrays in the same memory pool as everything else, per the #2232 direction — fails to compile. fvdb currently works around it by allocating the arrays itself and launching BuildVoxelBlockManagerFunctor directly, bypassing the handle (openvdb/fvdb-core#733).
Proposed fix
Route the casts through void*, which is valid for both void* and typed-pointer buffers and is a no-op for the existing types:
deviceFirstLeafID() { return static_cast<uint32_t*>(static_cast<void*>(mFirstLeafID.deviceData())); }
(equivalently on the const overloads via const void*), applied to all eight accessors: hostFirstLeafID ×2, hostJumpMap ×2, deviceFirstLeafID ×2, deviceJumpMap ×2.
A TestNanoVDB-side guard could instantiate the handle over a minimal buffer whose data()/deviceData() return uint8_t* to keep this from regressing.
Happy to put up the one-file PR. Related context: the injectable-memory-resource roadmap #2232, where downstream buffer/resource types are expected to plug into these generic seams.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in nanovdb/tools/VoxelBlockManager.h at the eight VoxelBlockManagerHandle accessors listed in the issue. Review the existing BufferTraits usage and add a TestNanoVDB guard using a minimal buffer whose data() and deviceData() return uint8_t*. Done means the handle compiles for typed-pointer buffers while preserving support for NanoVDB's existing buffer types.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100