AcademySoftwareFoundation / AcademySoftwareFoundation/openvdb
NanoVDB: type the remaining byte scratch buffers as cuda::Buffer<T> (CUDA)
- Dominant language
- C++
- Stars
- 3.4k
- Forks
- 774
- Avg merge
- 3d 9h
- Merged PRs (30d)
- 34
Description
## Context
With #2312 / #2322 typing the Mask sidecars, a census of the CUDA tools found the same pattern — a `cuda::Buffer` allocated as `N * sizeof(T)` and reinterpreted as `T*` at every use — in ~25 more places. Typing them deletes the casts, replaces byte arithmetic with element counts (so `Buffer`'s count×sizeof overflow check applies), and lets accessors return typed pointers. Recording the census so it doesn't need re-finding.
Already typed (verified): PointsToGrid, DistributedPointsToGrid, AddBlindData, IndexToGrid, GridStats, NodeManager's size scratch.
## Pure retypes (homogeneous array for the buffer's whole life)
**`tools::cuda::TopologyBuilder`** (~30 casts)
- `mUpperOffsets`, `mLowerOffsets`, `mLeafOffsets`, `mLowerParents`, `mLeafParents` → `Buffer`; `mVoxelOffsets` → `Buffer` (five `reinterpret_cast` sites alone).
- The three local count buffers in the enumerate pass (`upperCounts`, `lowerCounts`, `leafCounts`) → `Buffer`.
- `mLowerOffsets`, `mLeafOffsets` and the lower/leaf count locals are also read through a `uint32_t (*)[Mask<5>::SIZE]` view: give each a row-shaped accessor beside its allocation, the pattern `deviceLowerMasks()` established in #2322, so the stride is fixed once.
- `mDeviceData` (one `TopologyBuilderData`) → `Buffer` of count 1, as DistributedPointsToGrid's `mDataBuf` already is.
- Once these are typed, the header's static_assert about "reinterpreting byte scratch as word-sized types" covers only the root staging and should be narrowed or removed.
- Stays bytes (correctly): `mHostRoot`/`mDeviceRoot` — a variable-sized root blob (`RootT::memUsage(n)` is not `n * sizeof`).
**`tools::cuda::MeshToGrid`** (~16 casts, no cross-file ripple)
- Members: `mXformedTriangles` (`Triangle`), `mBoxTrianglePairsBuffer` (`MeshToGridBoxTrianglePair`), `mUniqueRootOriginsBuffer` (`Coord`); their `deviceXxx()` accessors collapse to `.data()`.
- Locals: `rootBoxCounts`, `rootBoxOffsets`, `keysBuffer`, `sortedKeysBuffer`, `uniqueKeysBuffer`, `countsBuffer`, `offsetsBuffer` (`uint64_t`), `numSelectedBuffer` (`int32_t`, count 1), `newPairsBuffer` (`BoxTrianglePair`).
- The byte `ScratchT` alias likely becomes unused in this file.
**`tools::cuda::SignedFloodFill`**: `nodeBuffer` (an array of `RootChild`) → `Buffer`. The tree+root+tiles staging buffer beside it is heterogeneous and stays bytes.
## API-level — needs a design decision, not a sweep
**`VoxelBlockManagerHandle`**: `mFirstLeafID` (`uint32_t`) and `mJumpMap` (`uint64_t`) drive ten accessor casts, but the handle takes one `BufferT` for both arrays. Typing them without changing the public signature means deriving the element-typed buffers from `BufferT` (e.g. via `cuda::Buffer`'s `rebind` for the single-space family, with untyped fallback for `HostBuffer`/the dual family) rather than adding type parameters. Touches the host builder, the CUDA builder and TestNanoVDB; coordinate with the in-flight single-space VoxelBlockManagerHandle work. MeshToGrid's UDF `sidecarBuffer` is likewise a caller-supplied public return type (`SidecarBufferT`) and is out of scope for a sweep.
## Correctly bytes — not candidates
GridHandle's chain-parse scratch (metadata array followed by a status struct), NodeManager's header-plus-three-arrays layout, TempPool (type-erased by construction), SignedFloodFill's tree/root/tiles staging, the tools' variable-sized root blobs (`HostBuffer`), and every cast into grid internals (grids are byte blobs by design).
Contributor guide
Research direction
Start with the CUDA tools named in the census: TopologyBuilder, MeshToGrid, and SignedFloodFill, comparing their scratch-buffer allocations and accessors with the typed patterns from #2312 and #2322. Keep the explicitly heterogeneous and variable-sized buffers as bytes, and coordinate separately on VoxelBlockManagerHandle with the host builder, CUDA builder, and TestNanoVDB; done means the listed homogeneous buffers are typed without casts and the relevant API design is resolved.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- tooling
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100