From f43487ee6f10ab0c31ca1767e8206aba3f295e21 Mon Sep 17 00:00:00 2001 From: Jeongseok Lee Date: Fri, 22 Mar 2024 20:29:28 -0700 Subject: [PATCH] [dartpy] Add nanobind dependency --- .github/workflows/ci_windows.yml | 3 +- .github/workflows/publish_dartpy.yml | 3 +- CMakeLists.txt | 56 +++++++++++++----------- cmake/DARTFindDependencies.cmake | 15 ++++++- docker/dev/v6.14/Dockerfile.ubuntu.noble | 1 + pixi.lock | 19 ++++++++ pixi.toml | 13 ++++++ python/CMakeLists.txt | 3 ++ python/dartpy2/CMakeLists.txt | 10 +++++ python/dartpy2/dartpy2.cpp | 49 +++++++++++++++++++++ 10 files changed, 142 insertions(+), 30 deletions(-) create mode 100644 python/dartpy2/CMakeLists.txt create mode 100644 python/dartpy2/dartpy2.cpp diff --git a/.github/workflows/ci_windows.yml b/.github/workflows/ci_windows.yml index 5d7240798d5c1..171ac5932bf5d 100644 --- a/.github/workflows/ci_windows.yml +++ b/.github/workflows/ci_windows.yml @@ -47,6 +47,7 @@ jobs: bullet3 freeglut glfw3 + nanobind nlopt opengl osg @@ -55,7 +56,7 @@ jobs: tracy urdfdom triplet: x64-windows - revision: "2024.02.14" + revision: "2024.03.25" github-binarycache: true token: ${{ github.token }} diff --git a/.github/workflows/publish_dartpy.yml b/.github/workflows/publish_dartpy.yml index 2dec358a14891..fc29ac276d146 100644 --- a/.github/workflows/publish_dartpy.yml +++ b/.github/workflows/publish_dartpy.yml @@ -111,6 +111,7 @@ jobs: freeglut glfw3 imgui + nanobind nlopt ode opengl @@ -119,7 +120,7 @@ jobs: tinyxml2 urdfdom triplet: x64-windows - revision: "2024.02.14" + revision: "2024.03.25" github-binarycache: true token: ${{ github.token }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e2ef2722ec21..95bf0e65a1eb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,6 +88,7 @@ dart_option(DART_ENABLE_SIMD "Build DART with all SIMD instructions on the current local machine" ON) dart_option(DART_BUILD_GUI_OSG "Build osgDart library" ON) dart_option(DART_BUILD_DARTPY "Build dartpy" ON) +dart_option(DART_BUILD_DARTPY2 "[Experimental] Build Python binding (dartpy2) with nanobind" OFF) dart_option(DART_BUILD_PROFILE "Build DART with profiling options" OFF) dart_option(DART_CODECOV "Turn on codecov support" OFF) dart_option(DART_FAST_DEBUG "Add -O1 option for DEBUG mode build" OFF) @@ -162,24 +163,25 @@ endif() #=============================================================================== # Build type settings #=============================================================================== -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: Debug | Release | RelWithDebInfo | MinSizeRel" FORCE) -endif() -string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UPPERCASE) - -set(DART_BUILD_MODE_DEBUG FALSE) -set(DART_BUILD_MODE_RELEASE FALSE) - -if("${CMAKE_BUILD_TYPE_UPPERCASE}" STREQUAL "DEBUG") - set(DART_BUILD_MODE_DEBUG TRUE) -elseif("${CMAKE_BUILD_TYPE_UPPERCASE}" STREQUAL "RELEASE") - set(DART_BUILD_MODE_RELEASE TRUE) -elseif("${CMAKE_BUILD_TYPE_UPPERCASE}" STREQUAL "RELWITHDEBINFO") - set(DART_BUILD_MODE_RELEASE TRUE) -elseif("${CMAKE_BUILD_TYPE_UPPERCASE}" STREQUAL "MINSIZEREL") - set(DART_BUILD_MODE_RELEASE TRUE) -else() - message(WARNING "CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} unknown. Valid options are: Debug | Release | RelWithDebInfo | MinSizeRel") +if(NOT CMAKE_CONFIGURATION_TYPES) + if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") + endif() + string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UPPERCASE) + + # Initialize Dart build mode variables + set(DART_BUILD_MODE_DEBUG FALSE) + set(DART_BUILD_MODE_RELEASE FALSE) + + # Set Dart build mode based on the CMAKE_BUILD_TYPE + if("${CMAKE_BUILD_TYPE_UPPERCASE}" STREQUAL "DEBUG") + set(DART_BUILD_MODE_DEBUG TRUE) + elseif("${CMAKE_BUILD_TYPE_UPPERCASE}" MATCHES "RELEASE|RELWITHDEBINFO|MINSIZEREL") + set(DART_BUILD_MODE_RELEASE TRUE) + else() + message(WARNING "CMAKE_BUILD_TYPE '${CMAKE_BUILD_TYPE}' unknown. Valid options are: Debug | Release | RelWithDebInfo | MinSizeRel") + endif() endif() # Active log level: @@ -355,14 +357,16 @@ if(DART_VERBOSE) message(STATUS "Build gui::osg : ${DART_BUILD_GUI_OSG}") message(STATUS "Install path : ${CMAKE_INSTALL_PREFIX}") message(STATUS "CXX_FLAGS : ${CMAKE_CXX_FLAGS}") - if(${CMAKE_BUILD_TYPE_UPPERCASE} STREQUAL "RELEASE") - message(STATUS "CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}") - elseif(${CMAKE_BUILD_TYPE_UPPERCASE} STREQUAL "DEBUG") - message(STATUS "CXX_FLAGS_DEBUG : ${CMAKE_CXX_FLAGS_DEBUG}") - elseif(${CMAKE_BUILD_TYPE_UPPERCASE} STREQUAL "RELWITHDEBINFO") - message(STATUS "CXX_FLAGS_RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") - elseif(${CMAKE_BUILD_TYPE_UPPERCASE} STREQUAL "PROFILE") - message(STATUS "CXX_FLAGS_PROFILE: ${CMAKE_CXX_FLAGS_PROFILE}") + if(NOT CMAKE_CONFIGURATION_TYPES) + if(${CMAKE_BUILD_TYPE_UPPERCASE} STREQUAL "RELEASE") + message(STATUS "CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}") + elseif(${CMAKE_BUILD_TYPE_UPPERCASE} STREQUAL "DEBUG") + message(STATUS "CXX_FLAGS_DEBUG : ${CMAKE_CXX_FLAGS_DEBUG}") + elseif(${CMAKE_BUILD_TYPE_UPPERCASE} STREQUAL "RELWITHDEBINFO") + message(STATUS "CXX_FLAGS_RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + elseif(${CMAKE_BUILD_TYPE_UPPERCASE} STREQUAL "PROFILE") + message(STATUS "CXX_FLAGS_PROFILE: ${CMAKE_CXX_FLAGS_PROFILE}") + endif() endif() message(STATUS "DART_SOURCE_DIR : ${DART_SOURCE_DIR}") message(STATUS "DART_BINARY_DIR : ${DART_BINARY_DIR}") diff --git a/cmake/DARTFindDependencies.cmake b/cmake/DARTFindDependencies.cmake index 51071ce08504c..10e5040fa8c9b 100644 --- a/cmake/DARTFindDependencies.cmake +++ b/cmake/DARTFindDependencies.cmake @@ -110,6 +110,19 @@ endif() # Optional dependencies #======================= +find_package(Python3 COMPONENTS Interpreter Development REQUIRED) + +if(DART_BUILD_DARTPY2) + include(FetchContent) + FetchContent_Declare(nanobind + GIT_REPOSITORY https://github.com/wjakob/nanobind.git + GIT_TAG master + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + ) + FetchContent_MakeAvailable(nanobind) +endif() + if(DART_BUILD_PROFILE) include(FetchContent) FetchContent_Declare(tracy @@ -126,8 +139,6 @@ if(DART_BUILD_PROFILE) endif() endif() -find_package(Python3 COMPONENTS Interpreter Development) - option(DART_SKIP_spdlog "If ON, do not use spdlog even if it is found." OFF) mark_as_advanced(DART_SKIP_spdlog) dart_find_package(spdlog) diff --git a/docker/dev/v6.14/Dockerfile.ubuntu.noble b/docker/dev/v6.14/Dockerfile.ubuntu.noble index 2a91654d30c68..1a89c2ad38ef6 100644 --- a/docker/dev/v6.14/Dockerfile.ubuntu.noble +++ b/docker/dev/v6.14/Dockerfile.ubuntu.noble @@ -62,6 +62,7 @@ RUN apt-get install -y --no-install-recommends \ RUN apt-get install -y --no-install-recommends \ libpython3-dev \ + nanobind-dev \ pybind11-dev \ python3 \ python3-dev \ diff --git a/pixi.lock b/pixi.lock index 261a97c73e894..65c265538dd7c 100644 --- a/pixi.lock +++ b/pixi.lock @@ -119,6 +119,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/mumps-include-5.6.2-ha770c72_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mumps-seq-5.6.2-hfef103a_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nanobind-1.9.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.4-h59595ed_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nettle-3.9.1-h7ab15ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ninja-1.11.1-h924138e_0.conda @@ -276,6 +277,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/mumps-include-5.6.2-h694c41f_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/mumps-seq-5.6.2-he3629b0_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nanobind-1.9.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.4-h93d8f39_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nettle-3.9.1-h8e11ae5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ninja-1.11.1-hb8565cd_0.conda @@ -417,6 +419,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mumps-include-5.6.2-hce30654_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mumps-seq-5.6.2-hbbab245_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nanobind-1.9.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.4-h463b476_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nettle-3.9.1-h40ed0f5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.11.1-hffc8910_0.conda @@ -535,6 +538,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.0.0-h66d3029_49657.conda - conda: https://conda.anaconda.org/conda-forge/win-64/mumps-seq-5.6.2-h1f49738_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nanobind-1.9.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.11.1-h91493d7_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/nlopt-2.7.1-py312h7fb0d8c_4.conda - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-1.26.4-py312h8753938_0.conda @@ -5805,6 +5809,21 @@ packages: license_family: MIT size: 10492 timestamp: 1675543414256 +- kind: conda + name: nanobind + version: 1.9.2 + build: pyhd8ed1ab_0 + subdir: noarch + noarch: python + url: https://conda.anaconda.org/conda-forge/noarch/nanobind-1.9.2-pyhd8ed1ab_0.conda + sha256: 79702a7055d2cbc4a5e5299248694a5ec14f07bce4715c320bc9fb19e85be08b + md5: 9ffe2a357e884ff9cb4a61a542bee596 + depends: + - python >=3.8 + license: BSD-3-Clause + license_family: BSD + size: 138768 + timestamp: 1708688744475 - kind: conda name: ncurses version: '6.4' diff --git a/pixi.toml b/pixi.toml index 4be21adb8cd8e..21b82f432d923 100644 --- a/pixi.toml +++ b/pixi.toml @@ -35,6 +35,8 @@ ipopt = ">=3.14.14,<3.15" nlopt = ">=2.7.1,<2.8" pagmo = ">=2.19.0,<2.20" numpy = ">=1.26.4,<1.27" +nanobind = ">=1.9.2,<1.10" +python = ">=3.12.2,<3.13" [tasks] clean = "rm -rf build" @@ -48,6 +50,13 @@ install-local = { cmd = "cmake --install build --prefix $CONDA_PREFIX", depends_ configure-unix = { cmd = "cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=Release -DDART_VERBOSE=ON -DDART_USE_SYSTEM_IMGUI=ON" } configure-win = { cmd = "cmake -S . -B build -G 'Visual Studio 17 2022' -DDART_VERBOSE=ON -DDART_MSVC_DEFAULT_OPTIONS=ON -DBUILD_SHARED_LIBS=OFF -DDART_USE_SYSTEM_IMGUI=OFF" } +build-dartpy2-unix = { cmd = "cmake --build build -j --target dartpy2", depends_on = [ + "configure", +] } +build-dartpy2-win = { cmd = "cmake --build build -j --target dartpy2 --config Release", depends_on = [ + "configure", +] } + example-hello-world = { cmd = "cmake --build build --target hello_world --parallel && ./build/bin/hello_world", depends_on = [ "configure", ] } @@ -101,6 +110,7 @@ build-tests = { cmd = "cmake --build build -j --target tests", depends_on = [ build-dartpy = { cmd = "cmake --build build -j --target dartpy", depends_on = [ "configure", ] } +build-dartpy2 = { depends_on = ["build-dartpy2-unix"] } test = { cmd = "ctest --test-dir build --output-on-failure", depends_on = [ "build-tests", ] } @@ -140,6 +150,7 @@ build-tests = { cmd = "cmake --build build -j --target tests", depends_on = [ build-dartpy = { cmd = "cmake --build build -j --target dartpy", depends_on = [ "configure", ] } +build-dartpy2 = { depends_on = ["build-dartpy2-unix"] } test = { cmd = "ctest --test-dir build --output-on-failure", depends_on = [ "build-tests", ] } @@ -175,6 +186,7 @@ build-tests = { cmd = "cmake --build build -j --target tests", depends_on = [ build-dartpy = { cmd = "cmake --build build -j --target dartpy", depends_on = [ "configure", ] } +build-dartpy2 = { depends_on = ["build-dartpy2-unix"] } test = { cmd = "ctest --test-dir build --output-on-failure", depends_on = [ "build-tests", ] } @@ -207,6 +219,7 @@ build-tests = { cmd = "cmake --build build --config Release -j --target tests", build-dartpy = { cmd = "cmake --build build -j --target dartpy", depends_on = [ "configure", ] } +build-dartpy2 = { depends_on = ["build-dartpy2-win"] } test = { cmd = "ctest --test-dir build --build-config Release --output-on-failure", depends_on = [ "build-tests", ] } diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index cc23a4001ca7b..db94f4cacdc29 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -22,6 +22,9 @@ endif() set(DART_DARTPY_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/dartpy") add_subdirectory(dartpy) +if(DART_BUILD_DARTPY2) + add_subdirectory(dartpy2) +endif() add_subdirectory(tests) add_subdirectory(examples) add_subdirectory(tutorials) diff --git a/python/dartpy2/CMakeLists.txt b/python/dartpy2/CMakeLists.txt new file mode 100644 index 0000000000000..8b36dbfc58cae --- /dev/null +++ b/python/dartpy2/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2011-2024, The DART development contributors +# All rights reserved. +# +# The list of contributors can be found at: +# https://github.com/dartsim/dart/blob/main/LICENSE +# +# This file is provided under the "BSD-style" License + +find_package(Python3 COMPONENTS Interpreter Development.Module REQUIRED) +nanobind_add_module(dartpy2 dartpy2.cpp) diff --git a/python/dartpy2/dartpy2.cpp b/python/dartpy2/dartpy2.cpp new file mode 100644 index 0000000000000..4413ee3ac3551 --- /dev/null +++ b/python/dartpy2/dartpy2.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011-2024, The DART development contributors + * All rights reserved. + * + * The list of contributors can be found at: + * https://github.com/dartsim/dart/blob/main/LICENSE + * + * This file is provided under the following "BSD-style" License: + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +namespace dart::python { + +NB_MODULE(dartpy2, m) +{ + // m.doc() = "dartpy2: Python API of Dynamic Animation and Robotics + // Toolkit"; + + // #ifdef DARTPY_VERSION_INFO + // m.attr("__version__") = DARTPY_VERSION_INFO; + // #else + // m.attr("__version__") = "dev"; + // #endif +} + +} // namespace dart::python