Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/nanovdb.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,6 @@ jobs:
- name: install
shell: powershell
run: .\ci\install_windows.ps1
- name: install_numpy
shell: powershell
run: .\ci\install_windows_numpy.ps1
- name: build
# nvcc doesn't set _WIN32 when run in bash so we need to set it manually
shell: bash
Expand Down
57 changes: 14 additions & 43 deletions nanovdb/nanovdb/GridHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -623,64 +623,35 @@ splitGrids(const GridHandle<BufferT> &handle, const BufferT* other = nullptr)

/// @brief Combines (or merges) multiple GridHandles into a single GridHandle containing all grids
/// @tparam BufferT Type of the input and output grid buffers
/// @param handles array of non-owning pointers to the GridHandles to be combined
/// @param count number of pointers in @a handles
/// @param handles Vector of GridHandles to be combined
/// @param pool optional pool used for allocation of output GridHandle
/// @return single GridHandle containing all input grids
/// @note This overload borrows the input handles, so it can be used when the
/// handles are owned elsewhere (e.g. by a language binding) and can be
/// neither moved from nor cheaply copied.
template<typename BufferT>
template<typename BufferT, template <class, class...> class VectorT>
inline GridHandle<BufferT>
mergeGrids(const GridHandle<BufferT>* const* handles, size_t count, const BufferT* pool = nullptr)
mergeGrids(const VectorT<GridHandle<BufferT>> &handles, const BufferT* pool = nullptr)
{
static_assert(!BufferHasDeviceSingle<BufferT>::value,
"mergeGrids requires a buffer type providing create(): cuda::copyTo HostBuffer handles first");
static_assert(!BufferHasHostSingle<BufferT>::value,
"mergeGrids requires a buffer type providing create(): copy the handles to HostBuffer first");
uint64_t size = 0u;
uint32_t counter = 0u, gridCount = 0u;
for (size_t i = 0; i < count; ++i) {
gridCount += handles[i]->gridCount();
for (uint32_t n=0; n<handles[i]->gridCount(); ++n) size += handles[i]->gridSize(n);
for (auto &h : handles) {
gridCount += h.gridCount();
for (uint32_t n=0; n<h.gridCount(); ++n) size += h.gridSize(n);
}
// Return an empty handle when there is nothing to merge: BufferT::create(0)
// can produce a non-null zero-byte region, from which the GridHandle
// constructor would attempt to read a GridData header.
if (gridCount == 0u) return GridHandle<BufferT>();
auto buffer = BufferT::create(size, pool);
void *dst = buffer.data();
for (size_t i = 0; i < count; ++i) {
const GridHandle<BufferT> &h = *handles[i];
for (auto &h : handles) {
const void *src = h.data();
for (uint32_t n=0; n<h.gridCount(); ++n) {
// gridData(n) applies the per-grid offset, so padded (non-contiguous)
// source buffers are copied correctly.
const GridData *src = h.gridData(n);
NANOVDB_ASSERT(src && src->isValid());
const uint64_t gridSize = h.gridSize(n);
std::memcpy(dst, src, gridSize);
tools::updateGridCount(reinterpret_cast<GridData*>(dst), counter++, gridCount);
dst = util::PtrAdd(dst, gridSize);
std::memcpy(dst, src, h.gridSize(n));
GridData *data = reinterpret_cast<GridData*>(dst);
NANOVDB_ASSERT(data->isValid());
tools::updateGridCount(data, counter++, gridCount);
dst = util::PtrAdd(dst, data->mGridSize);
src = util::PtrAdd(src, data->mGridSize);
}
}
return GridHandle<BufferT>(std::move(buffer));
}// mergeGrids

/// @brief Combines (or merges) multiple GridHandles into a single GridHandle containing all grids
/// @tparam BufferT Type of the input and output grid buffers
/// @param handles Vector of GridHandles to be combined
/// @param pool optional pool used for allocation of output GridHandle
/// @return single GridHandle containing all input grids
template<typename BufferT, template <class, class...> class VectorT>
inline GridHandle<BufferT>
mergeGrids(const VectorT<GridHandle<BufferT>> &handles, const BufferT* pool = nullptr)
{
std::vector<const GridHandle<BufferT>*> ptrs;
ptrs.reserve(handles.size());
for (auto &h : handles) ptrs.push_back(&h);
return mergeGrids<BufferT>(ptrs.data(), ptrs.size(), pool);
}// mergeGrids

} // namespace nanovdb

#if defined(__CUDACC__)
Expand Down
1 change: 0 additions & 1 deletion nanovdb/nanovdb/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ A lightweight GPU friendly version of VDB initially targeting rendering applicat
* [Source tree](../../doc/nanovdb/SourceTree.md)
* [Examples](../../doc/nanovdb/HelloWorld.md)
* [TEACHME — learn NanoVDB by prompting an LLM coding agent](../../doc/nanovdb/TEACHME/README.md)
* [Python examples](python/examples/)

### Copyright Contributors to the OpenVDB Project
### SPDX-License-Identifier: Apache-2.0
Expand Down
141 changes: 0 additions & 141 deletions nanovdb/nanovdb/python/BuildTypes.def

This file was deleted.

61 changes: 2 additions & 59 deletions nanovdb/nanovdb/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,8 @@ option(NANOVDB_BUILD_PYTHON_UNITTESTS [=[
"Include the NanoVDB Python unit test. Requires a python interpreter]=]
${NANOVDB_BUILD_UNITTESTS})

# Stubs are only consumed from an installed wheel (they ship next to the .so
# in nanovdb/), so default ON only when SKBUILD is driving the build. In an
# in-source dev / OpenVDB-CI build the .pyi is not used and stub generation
# can be skipped — which also dodges the macOS CI's sanitizer-runtime
# DYLD_INSERT_LIBRARIES wrapper, under which Python dlopen'ing the .so
# triggers TSan "Interceptors are not working" and aborts stubgen.
option(NANOVDB_BUILD_PYTHON_STUBS
"Generate .pyi type stubs for the nanovdb Python module (requires nanobind 2.x or newer)."
${SKBUILD})

nanobind_add_module(nanovdb_python NB_STATIC
NanoVDBModule.cc
PyBuildGrid.cc
PyCreateNanoGrid.cc
PyGridChecksum.cc
PyGridHandle.cc
Expand All @@ -29,8 +18,6 @@ nanobind_add_module(nanovdb_python NB_STATIC
PyPrimitives.cc
PySampleFromVoxels.cc
PyTools.cc
PyTree.cc
PyVoxelBlockManager.cc
cuda/PyDeviceBuffer.cc
cuda/PyDeviceGridHandle.cu
cuda/PyPointsToGrid.cu
Expand All @@ -46,47 +33,10 @@ if(SKBUILD)
set_target_properties(nanovdb_python PROPERTIES INSTALL_RPATH "$ORIGIN/../../openvdb/lib")
install(TARGETS nanovdb_python DESTINATION ${NANOVDB_INSTALL_LIBDIR})
install(FILES __init__.py DESTINATION nanovdb)
# Ship the nanovdb C/C++ headers inside the Python wheel so downstream
# extension authors can compile against the same NanoVDB the wheel was
# built with. nanovdb.get_include() resolves to this directory at runtime.
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../
DESTINATION nanovdb/include/nanovdb
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.cuh"
PATTERN "python" EXCLUDE
PATTERN "examples" EXCLUDE
PATTERN "unittest" EXCLUDE
PATTERN "cmd" EXCLUDE
PATTERN "docs" EXCLUDE)
else()
install(TARGETS nanovdb_python DESTINATION ${VDB_PYTHON_INSTALL_DIRECTORY})
endif()

# .pyi type stubs for IDE / type-checker support. Driven by the CMake helper
# that ships with nanobind 2.x; silently skipped on older nanobind where the
# helper does not exist.
if(NANOVDB_BUILD_PYTHON_STUBS AND COMMAND nanobind_add_stub)
set(NANOVDB_STUB_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
nanobind_add_stub(nanovdb_python_stub
MODULE nanovdb
OUTPUT "${NANOVDB_STUB_OUTPUT_DIR}/nanovdb.pyi"
PYTHON_PATH $<TARGET_FILE_DIR:nanovdb_python>
DEPENDS nanovdb_python
MARKER_FILE "${NANOVDB_STUB_OUTPUT_DIR}/py.typed"
INCLUDE_PRIVATE)
if(SKBUILD)
install(FILES
"${NANOVDB_STUB_OUTPUT_DIR}/nanovdb.pyi"
"${NANOVDB_STUB_OUTPUT_DIR}/py.typed"
DESTINATION nanovdb)
endif()
elseif(NANOVDB_BUILD_PYTHON_STUBS)
message(STATUS
"NANOVDB_BUILD_PYTHON_STUBS is ON but nanobind_add_stub is unavailable "
"(nanobind >= 2.0 required). Skipping stub generation.")
endif()

# pytest
if(NANOVDB_BUILD_PYTHON_UNITTESTS)

Expand All @@ -99,19 +49,12 @@ if(NANOVDB_BUILD_PYTHON_UNITTESTS)
COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/TestNanoVDB.py -v
WORKING_DIRECTORY "${NANOVDB_PYTHON_WORKING_DIR}")

# Smoke-run every example script (they self-skip when optional
# dependencies such as NumPy or OpenVDB are unavailable).
add_test(NAME pytest_nanovdb_examples
COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/TestExamples.py -v
WORKING_DIRECTORY "${NANOVDB_PYTHON_WORKING_DIR}")
set_tests_properties(pytest_nanovdb_examples PROPERTIES TIMEOUT 300)

if(WIN32)
set(PYTHONPATH "$ENV{PYTHONPATH};${NANOVDB_PYTHON_WORKING_DIR}")
string(REPLACE "\\;" ";" PYTHONPATH "${PYTHONPATH}")
string(REPLACE ";" "\\;" PYTHONPATH "${PYTHONPATH}")
set_tests_properties(pytest_nanovdb pytest_nanovdb_examples PROPERTIES ENVIRONMENT "PYTHONPATH=${PYTHONPATH}")
set_tests_properties(pytest_nanovdb PROPERTIES ENVIRONMENT "PYTHONPATH=${PYTHONPATH}")
else()
set_tests_properties(pytest_nanovdb pytest_nanovdb_examples PROPERTIES ENVIRONMENT "PYTHONPATH=$ENV{PYTHONPATH}:${NANOVDB_PYTHON_WORKING_DIR}")
set_tests_properties(pytest_nanovdb PROPERTIES ENVIRONMENT "PYTHONPATH=$ENV{PYTHONPATH}:${NANOVDB_PYTHON_WORKING_DIR}")
endif()
endif()
Loading
Loading