Skip to content

NanoVDB: type the remaining byte scratch buffers as cuda::Buffer<T> (CUDA) #2327

Description

@harrism

Context

With #2312 / #2322 typing the Mask sidecars, a census of the CUDA tools found the same pattern — a cuda::Buffer<std::byte, R> 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<uint32_t>; mVoxelOffsets → Buffer<uint64_t> (five reinterpret_cast<uint64_t*> sites alone).
  • The three local count buffers in the enumerate pass (upperCounts, lowerCounts, leafCounts) → Buffer<uint32_t>.
  • 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 NanoVDB: type the CUDA scratch buffers as cuda::Buffer<T> (CUDA) #2322, so the stride is fixed once.
  • mDeviceData (one TopologyBuilderData) → Buffer<Data> 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<ValueT>) → Buffer<ChildT, ManagedResource>. The tree+root+tiles staging buffer beside it is heterogeneous and stays bytes.

API-level — needs a design decision, not a sweep

VoxelBlockManagerHandle<BufferT>: 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).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions