Skip to content

Commit 9f73006

Browse files
author
Andreas Henne
committed
Fixed an issue in nanovdb::tools::cuda::indexToGrid that occured when building a grid with internal nodes that differed in size from the size of internal nodes of the index grid.
1 parent 4b38fba commit 9f73006

2 files changed

Lines changed: 55 additions & 35 deletions

File tree

nanovdb/nanovdb/tools/cuda/IndexToGrid.cuh

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,17 @@ __global__ void processRootTilesKernel(typename IndexToGrid<SrcBuildT>::NodeAcce
183183
auto &dstTile = *nodeAcc->template dstRoot<DstBuildT>().tile(tid);
184184
dstTile.key = srcTile.key;
185185
if (srcTile.child) {
186-
dstTile.child = sizeof(NanoRoot<DstBuildT>) + sizeof(NanoRoot<DstBuildT>::Tile)*((srcTile.child - sizeof(NanoRoot<SrcBuildT>))/sizeof(NanoRoot<SrcBuildT>::Tile));
186+
using SrcTileT = typename NanoRoot<SrcBuildT>::Tile;
187+
using DstTileT = typename NanoRoot<DstBuildT>::Tile;
188+
using SrcChildT = typename NanoRoot<SrcBuildT>::ChildNodeType;
189+
using DstChildT = typename NanoRoot<DstBuildT>::ChildNodeType;
190+
const uint64_t nodeSkip = nodeAcc->nodeCount[3];
191+
const uint64_t srcOff = sizeof(SrcTileT)*nodeSkip + sizeof(NanoRoot<SrcBuildT>);
192+
const uint64_t dstOff = sizeof(DstTileT)*nodeSkip + sizeof(NanoRoot<DstBuildT>);
193+
194+
const uint64_t childID = (srcTile.child - srcOff)/sizeof(SrcChildT);
195+
dstTile.child = dstOff + childID*sizeof(DstChildT);
196+
187197
dstTile.value = srcValues[0];// set to background
188198
dstTile.state = false;
189199
} else {

nanovdb/nanovdb/unittest/TestNanoVDB.cu

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,41 +1062,51 @@ TEST(TestNanoVDBCUDA, CudaIndexGridToGrid_ValueOnIndex)
10621062
idxHdl.deviceUpload();
10631063
auto *idxGrid = idxHdl.grid<BuildT>();
10641064
EXPECT_TRUE(idxGrid);
1065-
//timer.restart("Create value list on CPU");
1066-
float *values = new float[idxGrid->valueCount()], *d_values = nullptr;
1067-
values[0] = floatGrid->tree().root().background();
1068-
for (auto it = floatGrid->indexBBox().begin(); it; ++it) {
1069-
EXPECT_EQ(acc.isActive(*it), idxGrid->tree().isActive(*it));
1070-
if (acc.isActive(*it)) {
1071-
const uint64_t idx = idxGrid->tree().getValue(*it);
1072-
EXPECT_TRUE(idx < idxGrid->valueCount());
1073-
values[idx] = acc.getValue(*it);
1065+
1066+
auto checkConvertedValueGrid = [&](const auto& fromOriginalData, const auto& toOriginalData) {
1067+
using FloatType = decltype(fromOriginalData(0.0f));
1068+
1069+
//timer.restart("Create value list on CPU");
1070+
FloatType *values = new FloatType[idxGrid->valueCount()], *d_values = nullptr;
1071+
values[0] = fromOriginalData(floatGrid->tree().root().background());
1072+
for (auto it = floatGrid->indexBBox().begin(); it; ++it) {
1073+
EXPECT_EQ(acc.isActive(*it), idxGrid->tree().isActive(*it));
1074+
if (acc.isActive(*it)) {
1075+
const uint64_t idx = idxGrid->tree().getValue(*it);
1076+
EXPECT_TRUE(idx < idxGrid->valueCount());
1077+
values[idx] = fromOriginalData(acc.getValue(*it));
1078+
}
10741079
}
1075-
}
1076-
//timer.restart("Allocate and copy values from CPU to GPU");
1077-
cudaCheck(cudaMalloc((void**)&d_values, idxGrid->valueCount()*sizeof(float)));
1078-
cudaCheck(cudaMemcpy(d_values, values, idxGrid->valueCount()*sizeof(float), cudaMemcpyHostToDevice));
1079-
EXPECT_FALSE(idxHdl.deviceGrid<float>());
1080-
auto *d_idxGrid = idxHdl.deviceGrid<BuildT>();
1081-
EXPECT_TRUE(d_idxGrid);
1082-
//timer.restart("Call CudaIndexToGrid");
1083-
auto hdl = nanovdb::tools::cuda::indexToGrid<float>(d_idxGrid, d_values);
1084-
//timer.restart("unit-test");
1085-
EXPECT_FALSE(hdl.grid<float>());// no host grid
1086-
EXPECT_TRUE(hdl.deviceGrid<float>());
1087-
hdl.deviceDownload();
1088-
auto *floatGrid2 = hdl.grid<float>();
1089-
EXPECT_TRUE(floatGrid2);
1090-
auto acc2 = floatGrid2->getAccessor();
1091-
EXPECT_EQ(floatGrid->indexBBox(), floatGrid2->indexBBox());
1092-
EXPECT_EQ(floatGrid->worldBBox(), floatGrid2->worldBBox());
1093-
EXPECT_EQ(floatGrid->tree().root().background(), floatGrid2->tree().root().background());
1094-
for (auto it = floatGrid->indexBBox().begin(); it; ++it) {
1095-
EXPECT_EQ(acc.isActive(*it), acc2.isActive(*it));
1096-
if (acc.isActive(*it)) EXPECT_EQ(acc.getValue(*it), acc2.getValue(*it));
1097-
}
1098-
//timer.stop();
1099-
cudaFree(d_values);
1080+
//timer.restart("Allocate and copy values from CPU to GPU");
1081+
cudaCheck(cudaMalloc((void**)&d_values, idxGrid->valueCount()*sizeof(FloatType)));
1082+
cudaCheck(cudaMemcpy(d_values, values, idxGrid->valueCount()*sizeof(FloatType), cudaMemcpyHostToDevice));
1083+
EXPECT_FALSE(idxHdl.deviceGrid<FloatType>());
1084+
auto *d_idxGrid = idxHdl.deviceGrid<BuildT>();
1085+
EXPECT_TRUE(d_idxGrid);
1086+
//timer.restart("Call CudaIndexToGrid");
1087+
auto hdl = nanovdb::tools::cuda::indexToGrid<FloatType>(d_idxGrid, d_values);
1088+
//timer.restart("unit-test");
1089+
EXPECT_FALSE(hdl.template grid<FloatType>());// no host grid
1090+
EXPECT_TRUE(hdl.template deviceGrid<FloatType>());
1091+
hdl.deviceDownload();
1092+
auto *floatGrid2 = hdl.template grid<FloatType>();
1093+
EXPECT_TRUE(floatGrid2);
1094+
auto acc2 = floatGrid2->getAccessor();
1095+
EXPECT_EQ(floatGrid->indexBBox(), floatGrid2->indexBBox());
1096+
EXPECT_EQ(floatGrid->worldBBox(), floatGrid2->worldBBox());
1097+
EXPECT_EQ(floatGrid->tree().root().background(), toOriginalData(floatGrid2->tree().root().background()));
1098+
for (auto it = floatGrid->indexBBox().begin(); it; ++it) {
1099+
EXPECT_EQ(acc.isActive(*it), acc2.isActive(*it));
1100+
if (acc.isActive(*it)) EXPECT_EQ(acc.getValue(*it), toOriginalData(acc2.getValue(*it)));
1101+
}
1102+
//timer.stop();
1103+
cudaFree(d_values);
1104+
};
1105+
checkConvertedValueGrid([](float x) { return x; }, [](float x) { return x; });
1106+
1107+
// Convert index grid to grid of Vec3fs, whereat the original float data is just stored in all components of a Vec3f.
1108+
// This test covers code in indexToGrid that is only relevant if the size of grid data changes and does not align.
1109+
checkConvertedValueGrid([](float x) { return nanovdb::Vec3f(x); }, [](const nanovdb::Vec3f& x) { return x[0]; });
11001110
}// CudaPointToGrid_ValueOnIndex
11011111

11021112
TEST(TestNanoVDBCUDA, CudaSignedFloodFill)

0 commit comments

Comments
 (0)