Skip to content

Commit

Permalink
Add NanoVDB Python bindings
Browse files Browse the repository at this point in the history
Signed-off-by: Matthew Cong <[email protected]>
  • Loading branch information
matthewdcong committed Oct 11, 2024
1 parent 009d4f4 commit f5f3f6c
Show file tree
Hide file tree
Showing 48 changed files with 3,054 additions and 165 deletions.
68 changes: 68 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,74 @@ if(NOT OPENVDB_BUILD_NANOVDB AND
find_package(OpenVDB REQUIRED COMPONENTS nanovdb)
endif()

# Locate Python and nanobind if necessary
if(OPENVDB_BUILD_PYTHON_MODULE OR (OPENVDB_BUILD_NANOVDB AND NANOVDB_BUILD_PYTHON_MODULE))
# Small function which mimics basic output (bar components) of
# FindPackageHandleStandardArgs. This is required as we want to ensure
# the minimum python version is MINIMUM_PYTHON_VERSION - however this cannot
# be provided to find_package(Python) with differing major versions. e.g.
# calls to find_package(Python 2.7) fails if python3 is found on the system.
function(OPENVDB_CHECK_PYTHON_VERSION)
set(PY_TARGET ${ARGV0})
set(PY_TARGET_VERSION ${ARGV1})
set(PY_TARGET_INCLUDES ${ARGV2})
set(MIN_VERSION ${ARGV3})
set(FUTURE_MIN_VERSION ${ARGV4})

if(NOT TARGET ${PY_TARGET})
message(FATAL_ERROR "Could NOT find ${PY_TARGET} (Required is at least version "
"\"${MIN_VERSION}\")"
)
endif()

if(PY_TARGET_VERSION AND MIN_VERSION)
if(PY_TARGET_VERSION VERSION_LESS MIN_VERSION)
message(FATAL_ERROR "Could NOT find ${PY_TARGET}: Found unsuitable version "
"\"${PY_TARGET_VERSION}\" but required is at least \"${MIN_VERSION}\" (found ${PY_TARGET_INCLUDES})"
)
endif()
endif()

message(STATUS "Found ${PY_TARGET}: ${PY_TARGET_INCLUDES}) (found suitable "
"version \"${PY_TARGET_VERSION}\", minimum required is \"${MIN_VERSION}\")"
)

if(OPENVDB_FUTURE_DEPRECATION AND PY_TARGET_VERSION AND FUTURE_MIN_VERSION)
if(PY_TARGET_VERSION VERSION_LESS FUTURE_MIN_VERSION)
message(DEPRECATION "Support for ${PY_TARGET} versions < ${FUTURE_MIN_VERSION} "
"is deprecated and will be removed.")
endif()
endif()
endfunction()

# Configure Python and Numpy.
# To ensure consistent versions between components Interpreter, Compiler,
# Development and NumPy, specify all components at the same time when using
# FindPython.

# @note explicitly only search for Development.Module from 3.18 as searching
# Development.Embed can cause issues on linux systems where it doesn't exist
set(OPENVDB_PYTHON_REQUIRED_COMPONENTS Development Interpreter)

# Make sure find_package(Python) is only ever invoked once with all required components
find_package(Python 3.8 REQUIRED COMPONENTS ${OPENVDB_PYTHON_REQUIRED_COMPONENTS})
find_package(nanobind REQUIRED)

openvdb_check_python_version(Python::Module
"${Python_VERSION}"
"${Python_INCLUDE_DIRS}"
"${MINIMUM_PYTHON_VERSION}"
"${FUTURE_MINIMUM_PYTHON_VERSION}")

if(NOT DEFINED VDB_PYTHON_INSTALL_DIRECTORY)
get_filename_component(Python_PACKAGES_DIR ${Python_SITELIB} NAME)
set(VDB_PYTHON_INSTALL_DIRECTORY
${CMAKE_INSTALL_LIBDIR}/python${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}/${Python_PACKAGES_DIR}
CACHE STRING "The directory to install the openvdb and nanovdb Python modules."
)
endif()
endif()


# Validate the OpenVDB ABI Version. If OpenVDB_ABI is not set, we're either building
# the core library OR the ABI hasn't been deduced from a VDB installation. Use the
Expand Down
1 change: 1 addition & 0 deletions ci/install_macos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ brew install googletest
brew install jq # for trivial parsing of brew json
brew install openexr
brew install nanobind # also installs the dependent python version
brew install robin-map # required for nanobind
brew install zlib
brew install jemalloc

Expand Down
1 change: 1 addition & 0 deletions ci/install_nanobind.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ mkdir build
cd build

cmake \
-DNB_TEST=OFF \
"${CMAKE_EXTRA[@]}" \
..

Expand Down
13 changes: 8 additions & 5 deletions cmake/config/OpenVDBCXX.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -184,20 +184,23 @@ if(OPENVDB_CXX_STRICT)
add_compile_options("$<$<AND:$<CXX_COMPILER_ID:GNU>,$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,9.3.0>>:-Wimplicit-fallthrough>")
# Only check global constructors for libraries (we should really check for
# executables too but gtest relies on these types of constructors for its
# framework).
add_compile_options("$<$<AND:$<NOT:$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>>,$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>>:-Wglobal-constructors>")
# framework). nanobind also incorporates these constructors so skip it as well.
add_compile_options("$<$<AND:$<NOT:$<OR:$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanobind-static>>>,$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>>:-Wglobal-constructors>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-Wno-sign-conversion>")
# GNU
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Werror>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wall>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wextra>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-pedantic>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wcast-align>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wcast-qual>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wconversion>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wdisabled-optimization>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Woverloaded-virtual>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wnon-virtual-dtor>")
# Disable select warnings for the nanobind static library
add_compile_options("$<$<AND:$<NOT:$<OR:$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanobind-static>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,openvdb_python>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanovdb_python>>>,$<COMPILE_LANG_AND_ID:CXX,GNU>>:-pedantic>")
add_compile_options("$<$<AND:$<NOT:$<OR:$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanobind-static>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,openvdb_python>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanovdb_python>>>,$<COMPILE_LANG_AND_ID:CXX,GNU>>:-Wcast-qual>")
add_compile_options("$<$<AND:$<NOT:$<OR:$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanobind-static>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,openvdb_python>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanovdb_python>>>,$<COMPILE_LANG_AND_ID:CXX,GNU>>:-Wconversion>")
add_compile_options("$<$<AND:$<OR:$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanobind-static>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,openvdb_python>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanovdb_python>>,$<COMPILE_LANG_AND_ID:CXX,GNU>>:-Wno-unused-variable>")
add_compile_options("$<$<AND:$<OR:$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanobind-static>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,openvdb_python>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanovdb_python>>,$<COMPILE_LANG_AND_ID:CXX,GNU>>:-Wno-unused-but-set-parameter>")
else()
# NO OPENVDB_CXX_STRICT, suppress some warnings
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
Expand Down
2 changes: 1 addition & 1 deletion doc/dependencies.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ LLVM | 10.0.0 | 13.0.0* | Target-independent code generation
Bison | 3.0.0 | 3.7.0 | General-purpose parser generator | Y | Y | https://www.gnu.org/software/gcc
Flex | 2.6.0 | 2.6.4 | Fast lexical analyzer generator | Y | Y | https://github.com/westes/flex
Python | 3.9.1 | 3.10 | The python interpreter and libraries | Y | Y | https://www.python.org
nanobind | 1.9.2 | Latest | C++/python bindings | Y | Y | https://nanobind.readthedocs.io
nanobind | 2.0.0 | Latest | C++/python bindings | Y | Y | https://nanobind.readthedocs.io
NumPy | 1.20.0 | 1.23.0 | Scientific computing with Python | Y | Y | http://www.numpy.org
GoogleTest | 1.10 | Latest | A unit testing framework module for C++ | Y | Y | https://github.com/google/googletest
CppUnit | 1.10 | Latest | A unit testing framework module for C++ | N | Y | https://freedesktop.org/wiki/Software/cppunit
Expand Down
5 changes: 5 additions & 0 deletions nanovdb/nanovdb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ option(NANOVDB_BUILD_TOOLS "Build command-line tools" ON)
option(NANOVDB_BUILD_UNITTESTS "Build Unit tests" OFF)
option(NANOVDB_BUILD_EXAMPLES "Build examples" OFF)
#option(NANOVDB_BUILD_BENCHMARK "Build benchmark in examples" OFF)
option(NANOVDB_BUILD_PYTHON_MODULE "Build the nanovdb Python module" OFF)

option(NANOVDB_USE_INTRINSICS "Build with hardware intrinsics support" OFF)
option(NANOVDB_USE_CUDA "Build with CUDA support" OFF)
Expand Down Expand Up @@ -354,3 +355,7 @@ endif()
if(NANOVDB_BUILD_EXAMPLES)
add_subdirectory(examples)
endif()

if(NANOVDB_BUILD_PYTHON_MODULE)
add_subdirectory(python)
endif()
51 changes: 51 additions & 0 deletions nanovdb/nanovdb/python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
option(NANOVDB_BUILD_PYTHON_UNITTESTS [=[
"Include the NanoVDB Python unit test. Requires a python interpreter]=]
${NANOVDB_BUILD_UNITTESTS})
nanobind_add_module(nanovdb_python NB_STATIC
NanoVDBModule.cc
PyCreateNanoGrid.cc
PyGridChecksum.cc
PyGridHandle.cc
PyGridStats.cc
PyGridValidator.cc
PyHostBuffer.cc
PyIO.cc
PyMath.cc
PyNanoToOpenVDB.cc
PyPrimitives.cc
PySampleFromVoxels.cc
PyTools.cc
cuda/PyDeviceBuffer.cc
cuda/PyDeviceGridHandle.cu
cuda/PyPointsToGrid.cu
cuda/PySampleFromVoxels.cu
cuda/PySignedFloodFill.cu
)
target_include_directories(nanovdb_python PRIVATE ${CUDA_INCLUDE_DIRECTORY})
target_link_libraries(nanovdb_python PRIVATE nanovdb ${CUDA_LIBRARIES} ${NANOVDB_BLOSC} ${NANOVDB_ZLIB} ${NANOVDB_OPENVDB} ${NANOVDB_TBB})
target_compile_definitions(nanovdb_python PRIVATE ${NANOVDB_USE_CUDA_FLAG} ${NANOVDB_USE_BLOSC_FLAG} ${NANOVDB_USE_ZLIB_FLAG} ${NANOVDB_USE_OPENVDB_FLAG} ${NANOVDB_USE_TBB_FLAG})
set_target_properties(nanovdb_python PROPERTIES OUTPUT_NAME "nanovdb")
install(TARGETS nanovdb_python DESTINATION ${VDB_PYTHON_INSTALL_DIRECTORY})
# pytest
if(NANOVDB_BUILD_PYTHON_UNITTESTS)
set(NANOVDB_PYTHON_WORKING_DIR "${CMAKE_CURRENT_BINARY_DIR}")
if(WIN32)
set(NANOVDB_PYTHON_WORKING_DIR "${NANOVDB_PYTHON_WORKING_DIR}/$<CONFIG>")
endif()
add_test(NAME pytest_nanovdb
COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/TestNanoVDB.py -v
WORKING_DIRECTORY "${NANOVDB_PYTHON_WORKING_DIR}")
if(WIN32)
set(PYTHONPATH "$ENV{PYTHONPATH};${NANOVDB_PYTHON_WORKING_DIR}")
string(REPLACE "\\;" ";" PYTHONPATH "${PYTHONPATH}")
string(REPLACE ";" "\\;" PYTHONPATH "${PYTHONPATH}")
else()
set_tests_properties(pytest_nanovdb PROPERTIES ENVIRONMENT "PYTHONPATH=$ENV{PYTHONPATH}:${NANOVDB_PYTHON_WORKING_DIR}")
endif()
endif()
Loading

0 comments on commit f5f3f6c

Please sign in to comment.