|
49 | 49 | #include <nanovdb/NanoVDB.h> |
50 | 50 | #include <nanovdb/tools/cuda/VoxelBlockManager.cuh> |
51 | 51 | #include <nanovdb/util/cuda/DeviceGridTraits.cuh> |
| 52 | +#include <nanovdb/util/cuda/Util.h> |
52 | 53 |
|
53 | 54 | #include <c10/cuda/CUDAException.h> |
54 | 55 | #include <c10/cuda/CUDAGuard.h> |
@@ -271,17 +272,17 @@ esdfSweepVBMKernel(nanovdb::NanoGrid<nanovdb::ValueOnIndex> *__restrict__ esdfGr |
271 | 272 |
|
272 | 273 | const uint64_t blockFirstOffset = static_cast<uint64_t>(blockIdx.x) * BW + 1; |
273 | 274 |
|
274 | | - nanovdb::tools::cuda::VoxelBlockManager<BW>::template decodeInverseMaps<nanovdb::ValueOnIndex>( |
275 | | - esdfGrid, |
276 | | - firstLeafID[blockIdx.x], |
277 | | - jumpMap + static_cast<uint64_t>(blockIdx.x) * JML, |
278 | | - blockFirstOffset, |
279 | | - smem_leafIndex, |
280 | | - smem_voxelOffset); |
| 275 | + nanovdb::tools::cuda::VoxelBlockManager<ESDF_BLOCK_WIDTH_LOG2>::template decodeInverseMaps< |
| 276 | + nanovdb::ValueOnIndex>(esdfGrid, |
| 277 | + firstLeafID[blockIdx.x], |
| 278 | + jumpMap + static_cast<uint64_t>(blockIdx.x) * JML, |
| 279 | + blockFirstOffset, |
| 280 | + smem_leafIndex, |
| 281 | + smem_voxelOffset); |
281 | 282 | // __syncthreads() is issued inside decodeInverseMaps. |
282 | 283 |
|
283 | 284 | const uint32_t leafID = smem_leafIndex[threadIdx.x]; |
284 | | - if (leafID == nanovdb::tools::cuda::VoxelBlockManager<BW>::UnusedLeafIndex) { |
| 285 | + if (leafID == nanovdb::tools::cuda::VoxelBlockManager<ESDF_BLOCK_WIDTH_LOG2>::UnusedLeafIndex) { |
285 | 286 | return; |
286 | 287 | } |
287 | 288 | const uint16_t voxOff = smem_voxelOffset[threadIdx.x]; |
@@ -395,8 +396,6 @@ runEsdfSweepsAndFinalize(const c10::intrusive_ptr<GridBatchData> &esdfGrid, |
395 | 396 | bool use_vbm, |
396 | 397 | at::cuda::CUDAStream stream) { |
397 | 398 | const int64_t esdfVoxels = esdfGrid->totalVoxels(); |
398 | | - auto u32Opts = torch::TensorOptions().dtype(torch::kInt32).device(esdfInit.device()); |
399 | | - auto u64Opts = torch::TensorOptions().dtype(torch::kInt64).device(esdfInit.device()); |
400 | 399 | auto i32Opts = torch::TensorOptions().dtype(torch::kInt32).device(esdfInit.device()); |
401 | 400 |
|
402 | 401 | auto *esdfDeviceGrid = esdfGrid->mGridHdl->deviceGrid<nanovdb::ValueOnIndex>(0); |
@@ -433,36 +432,48 @@ runEsdfSweepsAndFinalize(const c10::intrusive_ptr<GridBatchData> &esdfGrid, |
433 | 432 | const int nBlocks = |
434 | 433 | static_cast<int>((esdfVoxels + ESDF_BLOCK_WIDTH - 1) / ESDF_BLOCK_WIDTH); |
435 | 434 |
|
| 435 | + // firstLeafID / jumpMap live in torch tensors so they come from the |
| 436 | + // same caching-allocator pool as every other fvdb allocation. |
| 437 | + // nanovdb's VoxelBlockManagerHandle can't own them (its accessors |
| 438 | + // static_cast from deviceData(), which TorchDeviceBuffer types as |
| 439 | + // uint8_t*), so launch the public build functor directly — the same |
| 440 | + // launch buildVoxelBlockManager performs on a handle it owns. The |
| 441 | + // functor expects a zeroed jumpMap, which torch::zeros provides. |
| 442 | + auto u32Opts = torch::TensorOptions().dtype(torch::kInt32).device(esdfInit.device()); |
| 443 | + auto u64Opts = torch::TensorOptions().dtype(torch::kInt64).device(esdfInit.device()); |
436 | 444 | torch::Tensor firstLeafID = torch::zeros({nBlocks}, u32Opts); |
437 | 445 | torch::Tensor jumpMap = torch::zeros({nBlocks * ESDF_JUMP_MAP_LENGTH}, u64Opts); |
438 | | - |
439 | | - nanovdb::tools::cuda::buildVoxelBlockManager<ESDF_BLOCK_WIDTH_LOG2, 128>( |
440 | | - /*firstOffset=*/1, |
441 | | - /*lastOffset=*/static_cast<uint64_t>(esdfVoxels), |
442 | | - /*nBlocks=*/nBlocks, |
443 | | - /*lowerCount=*/lowerCount, |
444 | | - /*grid=*/esdfDeviceGrid, |
445 | | - /*firstLeafID=*/ |
446 | | - reinterpret_cast<uint32_t *>(firstLeafID.data_ptr<int32_t>()), |
447 | | - /*jumpMap=*/ |
448 | | - reinterpret_cast<uint64_t *>(jumpMap.data_ptr<int64_t>()), |
449 | | - /*stream=*/stream.stream()); |
| 446 | + uint32_t *vbmFirstLeafID = reinterpret_cast<uint32_t *>(firstLeafID.data_ptr<int32_t>()); |
| 447 | + uint64_t *vbmJumpMap = reinterpret_cast<uint64_t *>(jumpMap.data_ptr<int64_t>()); |
| 448 | + |
| 449 | + using VbmBuildOp = |
| 450 | + nanovdb::tools::cuda::BuildVoxelBlockManagerFunctor<ESDF_BLOCK_WIDTH_LOG2>; |
| 451 | + nanovdb::util::cuda::operatorKernel<VbmBuildOp> |
| 452 | + <<<dim3(lowerCount, VbmBuildOp::SlicesPerLowerNode, 1), |
| 453 | + VbmBuildOp::MaxThreadsPerBlock, |
| 454 | + 0, |
| 455 | + stream.stream()>>>( |
| 456 | + /*firstOffset=*/static_cast<uint64_t>(1), |
| 457 | + /*lastOffset=*/static_cast<uint64_t>(esdfVoxels), |
| 458 | + /*nBlocks=*/nBlocks, |
| 459 | + esdfDeviceGrid, |
| 460 | + vbmFirstLeafID, |
| 461 | + vbmJumpMap); |
450 | 462 | C10_CUDA_KERNEL_LAUNCH_CHECK(); |
451 | 463 |
|
452 | 464 | for (int sweep = 0; sweep < numSweepsMax; ++sweep) { |
453 | 465 | changedFlag.zero_(); |
454 | 466 | esdfSweepVBMKernel<<<static_cast<unsigned int>(nBlocks), |
455 | 467 | static_cast<unsigned int>(ESDF_BLOCK_WIDTH), |
456 | 468 | 0, |
457 | | - stream.stream()>>>( |
458 | | - esdfDeviceGrid, |
459 | | - reinterpret_cast<uint32_t *>(firstLeafID.data_ptr<int32_t>()), |
460 | | - reinterpret_cast<uint64_t *>(jumpMap.data_ptr<int64_t>()), |
461 | | - esdfIn->data_ptr<float>(), |
462 | | - esdfOut->data_ptr<float>(), |
463 | | - voxelSizeF, |
464 | | - maxDistF, |
465 | | - changedFlag.data_ptr<int32_t>()); |
| 469 | + stream.stream()>>>(esdfDeviceGrid, |
| 470 | + vbmFirstLeafID, |
| 471 | + vbmJumpMap, |
| 472 | + esdfIn->data_ptr<float>(), |
| 473 | + esdfOut->data_ptr<float>(), |
| 474 | + voxelSizeF, |
| 475 | + maxDistF, |
| 476 | + changedFlag.data_ptr<int32_t>()); |
466 | 477 | C10_CUDA_KERNEL_LAUNCH_CHECK(); |
467 | 478 | std::swap(esdfIn, esdfOut); |
468 | 479 | // .item() is a sync + host-device copy (~30 us). Each |
|
0 commit comments