Skip to content

NanoVDB: assign each upper-node tile to a single GPU in DistributedPointsToGrid - #2283

Open
swahtz wants to merge 2 commits into
AcademySoftwareFoundation:masterfrom
swahtz:nanovdb/distributed-tile-ownership
Open

NanoVDB: assign each upper-node tile to a single GPU in DistributedPointsToGrid#2283
swahtz wants to merge 2 commits into
AcademySoftwareFoundation:masterfrom
swahtz:nanovdb/distributed-tile-ownership

Conversation

@swahtz

@swahtz swahtz commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

The device segment boundaries produced by the initial even split were rebalanced by adjusting only adjacent pairs of boundaries. That cannot consolidate an upper-node tile spanning three or more GPUs, since a fully-interior device lies entirely within the tile. Downstream construction assumes each tile - and therefore each lower node, leaf node and voxel - is owned by exactly one device, so multiple devices built the same leaf concurrently and raced on its value mask, silently dropping active voxels.

Replace the pairwise GPU rebalance with a global, monotonic snap performed on the host over the (small) set of device boundaries. The keys are globally sorted at that point, so a tile boundary is simply a position where the key changes; fully-interior devices are left empty, which the rest of the pipeline already handles.

Add two multi-GPU regression tests: SingleUpperNode, which places all input in one upper-node tile and asserts the exact unique active-voxel count, and MatchesSingleGpu, which cross-checks topology and occupancy against the single-GPU builder on the same input.

…intsToGrid

The device segment boundaries produced by the initial even split were
rebalanced by adjusting only adjacent pairs of boundaries. That cannot
consolidate an upper-node tile spanning three or more GPUs, since a
fully-interior device lies entirely within the tile. Downstream
construction assumes each tile - and therefore each lower node, leaf node
and voxel - is owned by exactly one device, so multiple devices built the
same leaf concurrently and raced on its value mask, silently dropping
active voxels.

Replace the pairwise GPU rebalance with a global, monotonic snap performed
on the host over the (small) set of device boundaries. The keys are
globally sorted at that point, so a tile boundary is simply a position
where the key changes; fully-interior devices are left empty, which the
rest of the pipeline already handles.

Add two multi-GPU regression tests: SingleUpperNode, which places all
input in one upper-node tile and asserts the exact unique active-voxel
count, and MatchesSingleGpu, which cross-checks topology and occupancy
against the single-GPU builder on the same input.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
leftIntervals[deviceId] = 0;
}
cudaCheck(cudaEventRecord(transformReduceEvents[deviceId], stream));
cudaCheck(cudaStreamSynchronize(stream));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to do this on the device instead of the host in order to avoid the stream sync? Alternatively, would it be possible to run a benchmark on an analytic example (e.g. a sampled torus) to show that performance isn't affected?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I added a snapBoundariesToRunsKernel so we run the snapping computation on-device.

@swahtz swahtz added the bug label Aug 20, 2026
…tream sync

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants