From e88c7b13270d961393ab1e64c03d1f7ccd047cce Mon Sep 17 00:00:00 2001 From: Sameer Sheorey <41028320+ssheorey@users.noreply.github.com> Date: Sun, 29 Sep 2024 23:07:07 -0700 Subject: [PATCH 1/7] Replace conda with pyenv to fix incorrect libstdc++ use in jammy CI. (#6966) * Replace conda with pyenv to fix incorrect libstdc++ use in jammy CI. * Use RPATH instead of RUNPATH to load libc++abi.so directly in Python. No need to find and load explicitly. * Use libc++11 to build in Ubuntu 22.04. Warn if newer version is used. * TODO: Solution for Ubuntu 24.04 --- 3rdparty/find_dependencies.cmake | 9 ++++++ cpp/open3d/core/nns/NanoFlannImpl.h | 25 ++++------------ cpp/pybind/CMakeLists.txt | 3 ++ cpp/tests/t/geometry/TensorMap.cpp | 7 +++++ docker/Dockerfile.ci | 44 +++++++++++++++++++---------- docker/docker_test.sh | 2 +- python/open3d/__init__.py | 8 ------ util/install_deps_ubuntu.sh | 11 ++++++-- 8 files changed, 63 insertions(+), 46 deletions(-) diff --git a/3rdparty/find_dependencies.cmake b/3rdparty/find_dependencies.cmake index 77b7085df69..d91377a3138 100644 --- a/3rdparty/find_dependencies.cmake +++ b/3rdparty/find_dependencies.cmake @@ -1338,6 +1338,7 @@ if(BUILD_GUI) if (CPP_LIBRARY AND CPPABI_LIBRARY) set(CLANG_LIBDIR ${llvm_lib_dir}) message(STATUS "CLANG_LIBDIR found in ubuntu-default: ${CLANG_LIBDIR}") + set(LIBCPP_VERSION ${llvm_ver}) break() endif() endforeach() @@ -1362,7 +1363,10 @@ if(BUILD_GUI) llvm-8/lib llvm-7/lib ) + file(REAL_PATH ${CPPABI_LIBRARY} CPPABI_LIBRARY) get_filename_component(CLANG_LIBDIR ${CPPABI_LIBRARY} DIRECTORY) + string(REGEX MATCH "llvm-([0-9]+)/lib" _ ${CLANG_LIBDIR}) + set(LIBCPP_VERSION ${CMAKE_MATCH_1}) endif() # Find clang libraries at the exact path ${CLANG_LIBDIR}. @@ -1378,6 +1382,11 @@ if(BUILD_GUI) target_link_libraries(3rdparty_filament INTERFACE -lstdc++ ${CPP_LIBRARY} ${CPPABI_LIBRARY}) message(STATUS "Filament C++ libraries: ${CPP_LIBRARY} ${CPPABI_LIBRARY}") + if (LIBCPP_VERSION GREATER 11) + message(WARNING "libc++ (LLVM) version ${LIBCPP_VERSION} > 11 includes libunwind that " + "interferes with the system libunwind.so.8 and may crash Python code when exceptions " + "are used. Please consider using libc++ (LLVM) v11.") + endif() endif() if (APPLE) find_library(CORE_VIDEO CoreVideo) diff --git a/cpp/open3d/core/nns/NanoFlannImpl.h b/cpp/open3d/core/nns/NanoFlannImpl.h index 027d6d0c4ee..9a9ceb100c4 100644 --- a/cpp/open3d/core/nns/NanoFlannImpl.h +++ b/cpp/open3d/core/nns/NanoFlannImpl.h @@ -118,13 +118,6 @@ void _KnnSearchCPU(NanoFlannIndexHolderBase *holder, return; } - auto points_equal = [](const T *const p1, const T *const p2, - size_t dimension) { - std::vector p1_vec(p1, p1 + dimension); - std::vector p2_vec(p2, p2 + dimension); - return p1_vec == p2_vec; - }; - std::vector> neighbors_indices(num_queries); std::vector> neighbors_distances(num_queries); std::vector neighbors_count(num_queries, 0); @@ -147,8 +140,9 @@ void _KnnSearchCPU(NanoFlannIndexHolderBase *holder, for (size_t valid_i = 0; valid_i < num_valid; ++valid_i) { TIndex idx = result_indices[valid_i]; if (ignore_query_point && - points_equal(&queries[i * dimension], - &points[idx * dimension], dimension)) { + std::equal(&queries[i * dimension], + &queries[i * dimension] + dimension, + &points[idx * dimension])) { continue; } neighbors_indices[i].push_back(idx); @@ -222,13 +216,6 @@ void _RadiusSearchCPU(NanoFlannIndexHolderBase *holder, return; } - auto points_equal = [](const T *const p1, const T *const p2, - size_t dimension) { - std::vector p1_vec(p1, p1 + dimension); - std::vector p2_vec(p2, p2 + dimension); - return p1_vec == p2_vec; - }; - std::vector> neighbors_indices(num_queries); std::vector> neighbors_distances(num_queries); std::vector neighbors_count(num_queries, 0); @@ -255,9 +242,9 @@ void _RadiusSearchCPU(NanoFlannIndexHolderBase *holder, int num_neighbors = 0; for (const auto &idx_dist : search_result) { if (ignore_query_point && - points_equal(&queries[i * dimension], - &points[idx_dist.first * dimension], - dimension)) { + std::equal(&queries[i * dimension], + &queries[i * dimension] + dimension, + &points[idx_dist.first * dimension])) { continue; } neighbors_indices[i].push_back(idx_dist.first); diff --git a/cpp/pybind/CMakeLists.txt b/cpp/pybind/CMakeLists.txt index e7a534a3eb3..c79bbd96719 100644 --- a/cpp/pybind/CMakeLists.txt +++ b/cpp/pybind/CMakeLists.txt @@ -80,6 +80,9 @@ set(PYTHON_COMPILED_MODULE_DIR if (APPLE) set_target_properties(pybind PROPERTIES BUILD_RPATH "@loader_path;@loader_path/..") elseif (UNIX) + # Use RPATH instead of RUNPATH in pybind so that needed libc++.so can find child dependant libc++abi.so in RPATH + # https://stackoverflow.com/questions/69662319/managing-secondary-dependencies-of-shared-libraries + target_link_options(pybind PRIVATE "LINKER:--disable-new-dtags") set_target_properties(pybind PROPERTIES BUILD_RPATH "$ORIGIN;$ORIGIN/..") endif() set_target_properties(pybind PROPERTIES diff --git a/cpp/tests/t/geometry/TensorMap.cpp b/cpp/tests/t/geometry/TensorMap.cpp index 372c6b82270..8512ce68ccb 100644 --- a/cpp/tests/t/geometry/TensorMap.cpp +++ b/cpp/tests/t/geometry/TensorMap.cpp @@ -32,6 +32,13 @@ TEST_P(TensorMapPermuteDevices, Constructor) { // Primary key is required. EXPECT_ANY_THROW(t::geometry::TensorMap()); + // Delete primary key. + EXPECT_ANY_THROW(tm0.Erase("positions")); + + // Reserved keys. + EXPECT_ANY_THROW(tm0.insert( + {"primary_key", core::Tensor::Zeros({2, 3}, dtype, device)})); + // Iterators. std::map tensor_map( {{"positions", core::Tensor::Zeros({10, 3}, dtype, device)}, diff --git a/docker/Dockerfile.ci b/docker/Dockerfile.ci index cd52a838882..73feb7bffd6 100644 --- a/docker/Dockerfile.ci +++ b/docker/Dockerfile.ci @@ -67,34 +67,48 @@ RUN if [ "${BUILD_SYCL_MODULE}" = "ON" ]; then \ rm -rf /etc/apt/sources.list.d/oneAPI.list; \ fi -# Dependencies: basic +# Dependencies: basic and python-build RUN apt-get update && apt-get install -y \ git \ wget \ curl \ build-essential \ pkg-config \ + zlib1g \ + zlib1g-dev \ + libssl-dev \ + libbz2-dev \ + libreadline-dev \ + libsqlite3-dev \ + libncursesw5-dev \ + xz-utils \ + tk-dev \ + libxml2-dev \ + libxmlsec1-dev \ + libffi-dev \ + liblzma-dev \ && rm -rf /var/lib/apt/lists/* -# Miniconda or Intel conda -# The **/open3d/bin paths are used during docker run, in this way docker run +# pyenv or Intel Python +# The pyenv python paths are used during docker run, in this way docker run # does not need to activate the environment again. -ENV PATH="/root/miniconda3/bin:${PATH}" -ENV PATH="/root/miniconda3/envs/open3d/bin:${PATH}" +# The soft link from the python patch level version to the python mino version +# ensures python wheel commands (i.e. open3d) are in PATH, since we don't know +# which patch level pyenv will install (latest). +ENV PYENV_ROOT=/root/.pyenv +ENV PATH="$PYENV_ROOT/shims:$PYENV_ROOT/bin:$PYENV_ROOT/versions/$PYTHON_VERSION/bin:$PATH" ENV PATH="/opt/intel/oneapi/intelpython/latest/bin:${PATH}" -ENV PATH="/opt/intel/oneapi/intelpython/latest/envs/open3d/bin:${PATH}" RUN if [ "${BUILD_SYCL_MODULE}" = "OFF" ]; then \ - wget -q https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh; \ - bash Miniconda3-latest-Linux-x86_64.sh -b; \ - rm Miniconda3-latest-Linux-x86_64.sh; \ + curl https://pyenv.run | bash \ + && pyenv update \ + && pyenv install $PYTHON_VERSION \ + && pyenv global $PYTHON_VERSION \ + && pyenv rehash \ + && ln -s $PYENV_ROOT/versions/${PYTHON_VERSION}* $PYENV_ROOT/versions/${PYTHON_VERSION}; \ fi -RUN conda --version \ - && conda create -y -n open3d python=${PYTHON_VERSION} +RUN python --version && pip --version -# Activate open3d virtualenv -# This works during docker build. It becomes the prefix of all RUN commands. -# Ref: https://stackoverflow.com/a/60148365/1255535 -SHELL ["conda", "run", "-n", "open3d", "/bin/bash", "-o", "pipefail", "-c"] +SHELL ["/bin/bash", "-o", "pipefail", "-c"] # Dependencies: cmake ENV PATH=${HOME}/${CMAKE_VERSION}/bin:${PATH} diff --git a/docker/docker_test.sh b/docker/docker_test.sh index 441b17ed4e3..d328d14535d 100755 --- a/docker/docker_test.sh +++ b/docker/docker_test.sh @@ -141,7 +141,7 @@ cpp_python_linking_uninstall_test() { # Python test echo "pytest is randomized, add --randomly-seed=SEED to repeat the test sequence." ${docker_run} -i --rm "${DOCKER_TAG}" /bin/bash -c " \ - python -m pytest python/test ${pytest_args} -s" + python -W default -m pytest python/test ${pytest_args} -s" restart_docker_daemon_if_on_gcloud # Command-line tools test diff --git a/python/open3d/__init__.py b/python/open3d/__init__.py index 141bf426c50..f7354b2a90c 100644 --- a/python/open3d/__init__.py +++ b/python/open3d/__init__.py @@ -45,14 +45,6 @@ def load_cdll(path): if sys.platform == "win32": # Unix: Use rpath to find libraries _win32_dll_dir = os.add_dll_directory(str(Path(__file__).parent)) -if _build_config["BUILD_GUI"] and not (find_library("c++abi") or - find_library("c++")): - try: # Preload libc++.so and libc++abi.so (required by filament) - load_cdll(str(next((Path(__file__).parent).glob("*c++abi.*")))) - load_cdll(str(next((Path(__file__).parent).glob("*c++.*")))) - except StopIteration: # Not found: check system paths while loading - pass - __DEVICE_API__ = "cpu" if _build_config["BUILD_CUDA_MODULE"]: # Load CPU pybind dll gracefully without introducing new python variable. diff --git a/util/install_deps_ubuntu.sh b/util/install_deps_ubuntu.sh index 3e359a1a6e7..2786b19c23b 100755 --- a/util/install_deps_ubuntu.sh +++ b/util/install_deps_ubuntu.sh @@ -39,17 +39,22 @@ eval $( echo DISTRIB_ID="$DISTRIB_ID"; echo DISTRIB_RELEASE="$DISTRIB_RELEASE" ) +# To avoid dependence on libunwind, we don't want to use clang / libc++ versions later than 11. +# Ubuntu 20.04's has versions 8, 10 or 12 while Ubuntu 22.04 has versions 11 and later. if [ "$DISTRIB_ID" == "Ubuntu" -a "$DISTRIB_RELEASE" == "20.04" ]; then - # Ubuntu 20.04's clang/libc++-dev/libc++abi-dev are version 8, 10 or 12. - # To avoid dependence on libunwind, we don't want to use versions later than 10. deps=("${deps[@]/clang/clang-10}") deps=("${deps[@]/libc++-dev/libc++-10-dev}") deps=("${deps[@]/libc++abi-dev/libc++abi-10-dev}") fi +if [ "$DISTRIB_ID" == "Ubuntu" -a "$DISTRIB_RELEASE" == "22.04" ]; then + deps=("${deps[@]/clang/clang-11}") + deps=("${deps[@]/libc++-dev/libc++-11-dev}") + deps=("${deps[@]/libc++abi-dev/libc++abi-11-dev}") +fi # Special case for ARM64 if [ "$(uname -m)" == "aarch64" ]; then - # For compling LAPACK in OpenBLAS + # For compiling LAPACK in OpenBLAS deps+=("gfortran") fi From dd0d35956e1f9744563c5e0631474a243c9d861d Mon Sep 17 00:00:00 2001 From: Sameer Sheorey <41028320+ssheorey@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:31:47 -0700 Subject: [PATCH 2/7] jinja2 CVE fix (#6992) https://github.com/isl-org/Open3D/security/dependabot/6 --- cpp/pybind/t/geometry/boundingvolume.cpp | 48 ++++-------------------- docs/make_docs.py | 6 +-- docs/requirements.txt | 5 ++- 3 files changed, 14 insertions(+), 45 deletions(-) diff --git a/cpp/pybind/t/geometry/boundingvolume.cpp b/cpp/pybind/t/geometry/boundingvolume.cpp index 981b8f3dd46..8e4494d1b79 100644 --- a/cpp/pybind/t/geometry/boundingvolume.cpp +++ b/cpp/pybind/t/geometry/boundingvolume.cpp @@ -22,51 +22,19 @@ void pybind_boundingvolume_declarations(py::module& m) { std::shared_ptr, Geometry, DrawableGeometry> aabb(m, "AxisAlignedBoundingBox", - R"(A bounding box that is aligned along the coordinate axes -and defined by the min_bound and max_bound." -- (min_bound, max_bound): Lower and upper bounds of the bounding box for all -axes. - - Usage - - AxisAlignedBoundingBox::GetMinBound() - - AxisAlignedBoundingBox::SetMinBound(const core::Tensor &min_bound) - - AxisAlignedBoundingBox::GetMaxBound() - - AxisAlignedBoundingBox::SetMaxBound(const core::Tensor &max_bound) - - Value tensor must have shape {3,}. - - Value tensor must have the same data type and device. - - Value tensor can only be float32 (default) or float64. - - The device of the tensor determines the device of the box. + R"(A bounding box that is aligned along the coordinate axes and +has the properties: -- color: Color of the bounding box. - - Usage - - AxisAlignedBoundingBox::GetColor() - - AxisAlignedBoundingBox::SetColor(const core::Tensor &color) - - Value tensor must have shape {3,}. - - Value tensor can only be float32 (default) or float64. - - Value tensor can only be range [0.0, 1.0].)"); +- (``min_bound``, ``max_bound``): Lower and upper bounds of the bounding box for all axes. These are tensors with shape (3,) and a common data type and device. The data type can only be ``open3d.core.float32`` (default) or ``open3d.core.float64``. The device of the tensor determines the device of the box. +- ``color``: Color of the bounding box is a tensor with shape (3,) and a data type ``open3d.core.float32`` (default) or ``open3d.core.float64``. Values can only be in the range [0.0, 1.0].)"); py::class_, std::shared_ptr, Geometry, DrawableGeometry> obb(m, "OrientedBoundingBox", - R"(A bounding box oriented along an arbitrary frame of reference. -- (center, rotation, extent): The oriented bounding box is defined by its -center position, rotation maxtrix and extent. - - Usage - - OrientedBoundingBox::GetCenter() - - OrientedBoundingBox::SetCenter(const core::Tensor ¢er) - - OrientedBoundingBox::GetRotation() - - OrientedBoundingBox::SetRotation(const core::Tensor &rotation) - - Value tensor of center and extent must have shape {3,}. - - Value tensor of rotation must have shape {3, 3}. - - Value tensor must have the same data type and device. - - Value tensor can only be float32 (default) or float64. - - The device of the tensor determines the device of the box. + R"(A bounding box oriented along an arbitrary frame of reference +with the properties: -- color: Color of the bounding box. - - Usage - - OrientedBoundingBox::GetColor() - - OrientedBoundingBox::SetColor(const core::Tensor &color) - - Value tensor must have shape {3,}. - - Value tensor can only be float32 (default) or float64. - - Value tensor can only be range [0.0, 1.0].)"); +- (``center``, ``rotation``, ``extent``): The oriented bounding box is defined by its center position (shape (3,)), rotation maxtrix (shape (3,3)) and extent (shape (3,)). Each of these tensors must have the same data type and device. The data type can only be ``open3d.core.float32`` (default) or ``open3d.core.float64``. The device of the tensor determines the device of the box. +- ``color``: Color of the bounding box is a tensor with shape (3,) and a data type ``open3d.core.float32`` (default) or ``open3d.core.float64``. Values can only be in the range [0.0, 1.0].)"); } void pybind_boundingvolume_definitions(py::module& m) { auto aabb = static_cast Date: Thu, 3 Oct 2024 21:02:19 +0200 Subject: [PATCH 3/7] Faster CPU (Arg-)Reductions (#6989) * Avoid multithread access to shared array in a loop (CPU Reductions) * Add two pass CPU ArgReduction Engine to speed up argreductions with single outputs --- cpp/open3d/core/kernel/ReductionCPU.cpp | 66 +++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/cpp/open3d/core/kernel/ReductionCPU.cpp b/cpp/open3d/core/kernel/ReductionCPU.cpp index 7caa60b34f7..710f1aaea24 100644 --- a/cpp/open3d/core/kernel/ReductionCPU.cpp +++ b/cpp/open3d/core/kernel/ReductionCPU.cpp @@ -122,13 +122,14 @@ class CPUReductionEngine { for (int64_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) { int64_t start = thread_idx * workload_per_thread; int64_t end = std::min(start + workload_per_thread, num_workloads); + scalar_t local_result = identity; for (int64_t workload_idx = start; workload_idx < end; ++workload_idx) { scalar_t* src = reinterpret_cast( indexer.GetInputPtr(0, workload_idx)); - thread_results[thread_idx] = - element_kernel(*src, thread_results[thread_idx]); + local_result = element_kernel(*src, local_result); } + thread_results[thread_idx] = local_result; } scalar_t* dst = reinterpret_cast(indexer.GetOutputPtr(0)); for (int64_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) { @@ -190,14 +191,25 @@ class CPUArgReductionEngine { // elements. We need to keep track of the indices within each // sub-iteration. int64_t num_output_elements = indexer_.NumOutputElements(); + if (num_output_elements <= 1) { + LaunchArgReductionKernelTwoPass(indexer_, reduce_func, identity); + } else { + LaunchArgReductionParallelDim(indexer_, reduce_func, identity); + } + } + template + static void LaunchArgReductionParallelDim(const Indexer& indexer, + func_t reduce_func, + scalar_t identity) { + int64_t num_output_elements = indexer.NumOutputElements(); #pragma omp parallel for schedule(static) \ num_threads(utility::EstimateMaxThreads()) for (int64_t output_idx = 0; output_idx < num_output_elements; output_idx++) { // sub_indexer.NumWorkloads() == ipo. - // sub_indexer's workload_idx is indexer_'s ipo_idx. - Indexer sub_indexer = indexer_.GetPerOutputIndexer(output_idx); + // sub_indexer's workload_idx is indexer's ipo_idx. + Indexer sub_indexer = indexer.GetPerOutputIndexer(output_idx); scalar_t dst_val = identity; for (int64_t workload_idx = 0; workload_idx < sub_indexer.NumWorkloads(); workload_idx++) { @@ -212,6 +224,52 @@ class CPUArgReductionEngine { } } + /// Create num_threads workers to compute partial arg reductions + /// and then reduce to the final results. + /// This only applies to arg reduction op with one output. + template + static void LaunchArgReductionKernelTwoPass(const Indexer& indexer, + func_t reduce_func, + scalar_t identity) { + if (indexer.NumOutputElements() > 1) { + utility::LogError( + "Internal error: two-pass arg reduction only works for " + "single-output arg reduction ops."); + } + int64_t num_workloads = indexer.NumWorkloads(); + int64_t num_threads = utility::EstimateMaxThreads(); + int64_t workload_per_thread = + (num_workloads + num_threads - 1) / num_threads; + std::vector thread_results_idx(num_threads, 0); + std::vector thread_results_val(num_threads, identity); + +#pragma omp parallel for schedule(static) \ + num_threads(utility::EstimateMaxThreads()) + for (int64_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) { + int64_t start = thread_idx * workload_per_thread; + int64_t end = std::min(start + workload_per_thread, num_workloads); + scalar_t local_result_val = identity; + int64_t local_result_idx = 0; + for (int64_t workload_idx = start; workload_idx < end; + ++workload_idx) { + int64_t src_idx = workload_idx; + scalar_t* src_val = reinterpret_cast( + indexer.GetInputPtr(0, workload_idx)); + std::tie(local_result_idx, local_result_val) = reduce_func( + src_idx, *src_val, local_result_idx, local_result_val); + } + thread_results_val[thread_idx] = local_result_val; + thread_results_idx[thread_idx] = local_result_idx; + } + scalar_t dst_val = identity; + int64_t* dst_idx = reinterpret_cast(indexer.GetOutputPtr(0)); + for (int64_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) { + std::tie(*dst_idx, dst_val) = reduce_func( + thread_results_idx[thread_idx], + thread_results_val[thread_idx], *dst_idx, dst_val); + } + } + private: Indexer indexer_; }; From 5f148f2fd3c309c6585019f7c2c9402853a16e37 Mon Sep 17 00:00:00 2001 From: Stuart Date: Fri, 4 Oct 2024 17:21:41 -0400 Subject: [PATCH 4/7] Support python 312 (#6717) * TensorFlow updated to v2.16.2 * PyTorch updated to v2.2.0 * CUDA updated to 12.1 * Update windows CUDA version to match Linux, TF version, torch as latest supporting Intel Mac, update werkzeug, flask to matching versions. * Update stdgpu * Clearer ASSIMP error messages * Always obey CMAKE_CUDA_ARCHITECTURES if used. * use shared_ptr to capture array in lambda * set TORCH_CUDA_ARCH_LIST as workaround for CUDA 12 and Pytorch <2.4 * Update and sort library list in 3rdparty/README.md --------- Co-authored-by: Sameer Sheorey Co-authored-by: Benjamin Ummenhofer Co-authored-by: Sameer Sheorey <41028320+ssheorey@users.noreply.github.com> --- .github/workflows/macos.yml | 15 +- .github/workflows/ubuntu-wheel.yml | 13 +- .github/workflows/windows.yml | 17 +- 3rdparty/README.md | 185 +++++++++--------- 3rdparty/cmake/FindPytorch.cmake | 25 +++ 3rdparty/find_dependencies.cmake | 1 + 3rdparty/stdgpu/stdgpu.cmake | 6 +- CHANGELOG.md | 1 + CMakeLists.txt | 30 +-- cpp/open3d/t/geometry/RaycastingScene.cpp | 3 +- cpp/open3d/t/io/file_format/FileASSIMP.cpp | 2 +- cpp/pybind/core/tensor_converter.cpp | 6 +- docker/Dockerfile.wheel | 6 +- docker/README.md | 2 +- docker/docker_build.sh | 45 ++++- docker/docker_test.sh | 24 +++ docs/arm.rst | 1 + docs/getting_started.in.rst | 7 +- python/README.rst | 1 + .../ml/tf/python/layers/neighbor_search.py | 9 +- python/requirements.txt | 3 +- python/requirements_test.txt | 6 +- python/setup.py | 1 + python/test/ml_ops/test_sparseconv.py | 48 +++-- python/test/t/io/test_realsense.py | 4 +- util/ci_utils.sh | 7 +- 26 files changed, 310 insertions(+), 158 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 2aea46eb596..1c3ff74deba 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -62,7 +62,7 @@ jobs: - name: Set up Python version uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.12' - name: Install dependencies run: | @@ -194,7 +194,7 @@ jobs: # macos-12 is Intel runner, macos-14 is Apple Silicon # https://github.com/actions/runner-images os: [macos-12, macos-14] - python_version: ['3.8', '3.9', '3.10', '3.11'] + python_version: ['3.8', '3.9', '3.10', '3.11', '3.12'] is_main: - ${{ github.ref == 'refs/heads/main' }} exclude: @@ -209,6 +209,8 @@ jobs: python_version: '3.9' - is_main: false python_version: '3.10' + - is_main: false + python_version: '3.11' env: BUILD_CUDA_MODULE: OFF @@ -310,12 +312,14 @@ jobs: fail-fast: false # https://github.community/t/how-to-conditionally-include-exclude-items-in-matrix-eg-based-on-branch/16853/6 matrix: - python_version: ['3.10', '3.11'] + python_version: ['3.10', '3.11', '3.12'] is_main: - ${{ github.ref == 'refs/heads/main' }} exclude: - is_main: false python_version: '3.10' + - is_main: false + python_version: '3.11' steps: - name: Checkout source code # for gh release upload uses: actions/checkout@v4 @@ -374,7 +378,7 @@ jobs: fail-fast: false matrix: os: [macos-12, macos-14] - python_version: ['3.8', '3.9', '3.10', '3.11'] + python_version: ['3.8', '3.9', '3.10', '3.11', '3.12'] is_main: - ${{ github.ref == 'refs/heads/main' }} exclude: @@ -388,6 +392,8 @@ jobs: python_version: '3.9' - is_main: false python_version: '3.10' + - is_main: false + python_version: '3.11' env: OPEN3D_ML_ROOT: ${{ github.workspace }}/Open3D-ML @@ -399,6 +405,7 @@ jobs: uses: actions/checkout@v4 with: repository: isl-org/Open3D-ML + ref: main path: ${{ env.OPEN3D_ML_ROOT }} - name: Download wheels diff --git a/.github/workflows/ubuntu-wheel.yml b/.github/workflows/ubuntu-wheel.yml index 591d0852238..c55bc1d65c6 100644 --- a/.github/workflows/ubuntu-wheel.yml +++ b/.github/workflows/ubuntu-wheel.yml @@ -33,7 +33,7 @@ jobs: strategy: fail-fast: false matrix: - python_version: ['3.8', '3.9', '3.10', '3.11'] + python_version: ['3.8', '3.9', '3.10', '3.11', '3.12'] is_main: - ${{ github.ref == 'refs/heads/main' }} exclude: @@ -43,6 +43,8 @@ jobs: python_version: '3.9' - is_main: false python_version: '3.10' + - is_main: false + python_version: '3.11' env: DEVELOPER_BUILD: ${{ github.event.inputs.developer_build || 'ON' }} PYTHON_VERSION: ${{ matrix.python_version }} @@ -67,6 +69,8 @@ jobs: docker/docker_build.sh cuda_wheel_py310_dev elif [ "${{ env.PYTHON_VERSION }}" = "3.11" ] && [ "${{ env.DEVELOPER_BUILD }}" = "ON" ]; then docker/docker_build.sh cuda_wheel_py311_dev + elif [ "${{ env.PYTHON_VERSION }}" = "3.12" ] && [ "${{ env.DEVELOPER_BUILD }}" = "ON" ]; then + docker/docker_build.sh cuda_wheel_py312_dev elif [ "${{ env.PYTHON_VERSION }}" = "3.8" ] && [ "${{ env.DEVELOPER_BUILD }}" = "OFF" ]; then docker/docker_build.sh cuda_wheel_py38 elif [ "${{ env.PYTHON_VERSION }}" = "3.9" ] && [ "${{ env.DEVELOPER_BUILD }}" = "OFF" ]; then @@ -75,6 +79,8 @@ jobs: docker/docker_build.sh cuda_wheel_py310 elif [ "${{ env.PYTHON_VERSION }}" = "3.11" ] && [ "${{ env.DEVELOPER_BUILD }}" = "OFF" ]; then docker/docker_build.sh cuda_wheel_py311 + elif [ "${{ env.PYTHON_VERSION }}" = "3.12" ] && [ "${{ env.DEVELOPER_BUILD }}" = "OFF" ]; then + docker/docker_build.sh cuda_wheel_py312 fi PIP_PKG_NAME="$(basename ${GITHUB_WORKSPACE}/open3d-[0-9]*.whl)" PIP_CPU_PKG_NAME="$(basename ${GITHUB_WORKSPACE}/open3d_cpu*.whl)" @@ -122,7 +128,7 @@ jobs: strategy: fail-fast: false matrix: - python_version: ['3.8', '3.9', '3.10', '3.11'] + python_version: ['3.8', '3.9', '3.10', '3.11', '3.12'] is_main: - ${{ github.ref == 'refs/heads/main' }} exclude: @@ -132,6 +138,8 @@ jobs: python_version: '3.9' - is_main: false python_version: '3.10' + - is_main: false + python_version: '3.11' env: OPEN3D_ML_ROOT: ${{ github.workspace }}/Open3D-ML steps: @@ -145,6 +153,7 @@ jobs: uses: actions/checkout@v4 with: repository: isl-org/Open3D-ML + ref: ss/python-3.12 # remove before merge path: ${{ env.OPEN3D_ML_ROOT }} - name: Download wheels uses: actions/download-artifact@v4 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 82c90c2c17a..04a408802d0 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -25,6 +25,7 @@ env: STOOLS_VER: "67.3.2" JEDI_VER: "0.17.2" # https://github.com/ipython/ipython/issues/12740 IDNA_VER: "2.8" # https://github.com/psf/requests/issues/5710 + CUDA_VERSION: "12.1.0" SRC_DIR: "D:\\a\\open3d\\open3d" BUILD_DIR: "C:\\Open3D\\build" NPROC: 2 @@ -47,7 +48,6 @@ jobs: STATIC_RUNTIME: ON include: - BUILD_CUDA_MODULE: ON - CUDA_VERSION: 11.0.3 env: BUILD_WEBRTC: ${{ ( matrix.BUILD_SHARED_LIBS == 'OFF' && matrix.STATIC_RUNTIME == 'ON' ) && 'ON' || 'OFF' }} @@ -64,20 +64,20 @@ jobs: if: ${{ matrix.BUILD_CUDA_MODULE == 'ON' }} run: | # Define variables - $CUDA_VER_FULL = "${{ matrix.CUDA_VERSION }}" + $CUDA_VER_FULL = "${{ env.CUDA_VERSION }}" $CUDA_VER_ARR = $CUDA_VER_FULL.Split(".") $CUDA_VER = "$($CUDA_VER_ARR[0]).$($CUDA_VER_ARR[1])" $CUDA_VER_ID = "$($CUDA_VER_ARR[0])_$($CUDA_VER_ARR[1])" # Installer url if ( $CUDA_VER_ARR[0] -ge 11 ) { - $CUDA_URL = "http://developer.download.nvidia.com/compute/cuda/$CUDA_VER_FULL/network_installers/cuda_$($CUDA_VER_FULL)_win10_network.exe" + $CUDA_URL = "http://developer.download.nvidia.com/compute/cuda/$CUDA_VER_FULL/network_installers/cuda_$($CUDA_VER_FULL)_windows_network.exe" } else { $CUDA_URL = "http://developer.download.nvidia.com/compute/cuda/$CUDA_VER/Prod/network_installers/cuda_$($CUDA_VER_FULL)_win10_network.exe" } # Installer arguments $CUDA_INSTALL_ARGS = "-s" # Required packages - $CUDA_PACKAGES = "nvcc", "visual_studio_integration", "cublas", "cublas_dev", "cudart", "cusolver", "cusolver_dev", "npp", "npp_dev" + $CUDA_PACKAGES = "nvcc", "visual_studio_integration", "cublas", "cublas_dev", "cudart", "cusolver", "cusolver_dev", "npp", "npp_dev", "thrust" $CUDA_PACKAGES.ForEach({ $CUDA_INSTALL_ARGS += " $($_)_$($CUDA_VER)" }) # Download and install CUDA echo "Downloading CUDA installer from $CUDA_URL" @@ -110,6 +110,7 @@ jobs: if (${env:DEVELOPER_BUILD} -ne "OFF") { ${env:DEVELOPER_BUILD}="ON" } + cmake --version cmake -G "Visual Studio 16 2019" -A x64 ` -DDEVELOPER_BUILD="${env:DEVELOPER_BUILD}" ` -DCMAKE_SYSTEM_VERSION="10.0.19041.0" ` @@ -240,7 +241,7 @@ jobs: fail-fast: false # https://github.community/t/how-to-conditionally-include-exclude-items-in-matrix-eg-based-on-branch/16853/6 matrix: - python_version: ['3.8', '3.9', '3.10', '3.11'] + python_version: ['3.8', '3.9', '3.10', '3.11', '3.12'] is_main: - ${{ github.ref == 'refs/heads/main' }} exclude: @@ -250,6 +251,8 @@ jobs: python_version: '3.9' - is_main: false python_version: '3.10' + - is_main: false + python_version: '3.11' steps: - name: Checkout source code @@ -328,7 +331,7 @@ jobs: strategy: fail-fast: false matrix: - python_version: ['3.8', '3.9', '3.10', '3.11'] + python_version: ['3.8', '3.9', '3.10', '3.11', '3.12'] is_main: - ${{ github.ref == 'refs/heads/main' }} exclude: @@ -338,6 +341,8 @@ jobs: python_version: '3.9' - is_main: false python_version: '3.10' + - is_main: false + python_version: '3.11' steps: - name: Checkout source code diff --git a/3rdparty/README.md b/3rdparty/README.md index c7c9f94a74e..b494ac77fc7 100644 --- a/3rdparty/README.md +++ b/3rdparty/README.md @@ -8,139 +8,138 @@ system dependencies. ```txt -------------------------------------------------------------------------------- +benchmark 1.5.5 Apache-2 license +A microbenchmark support library +https://github.com/google/benchmark +-------------------------------------------------------------------------------- +boringssl: edfe413 Dual OpenSSL, SSLeay, ISC license +BoringSSL is a fork of OpenSSL that is designed to meet Google's needs. +https://github.com/google/boringssl +-------------------------------------------------------------------------------- +CUB 1.8.0 BSD license +A flexible library of cooperative threadblock primitives and other utilities for +CUDA kernel programming +https://github.com/NVlabs/cub +-------------------------------------------------------------------------------- +cppzmq 4.6.0 MIT license +Header-only C++ binding for libzmq +https://github.com/zeromq/cppzmq +As an alternative, you can modify 3rdparty/zeromq/zeromq_build.cmake to fetch +zeromq from our fork +https://github.com/isl-org/libzmq +-------------------------------------------------------------------------------- +curl 7.88.0 Curl license +Curl is a command-line tool for transferring data specified with URL syntax. +https://github.com/curl/curl +-------------------------------------------------------------------------------- +CUTLASS 1.3.3 BSD license +CUDA Templates for Linear Algebra Subroutines +https://github.com/NVIDIA/cutlass +-------------------------------------------------------------------------------- +dirent 1.21 MIT license +https://github.com/tronkko/dirent +A C/C++ programming interface for cross-platform filesystem +-------------------------------------------------------------------------------- +DirectX-Headers v1.606.3 MIT license +Official DirectX headers available under an open source license +https://github.com/microsoft/DirectX-Headers +-------------------------------------------------------------------------------- +DirectXMath may2022 MIT license +DirectXMath is an all inline SIMD C++ linear algebra library for use in games +and graphics apps +https://github.com/microsoft/DirectXMath +-------------------------------------------------------------------------------- Eigen 3.4 Mainly MPL2 license A high-level C++ library of template headers for linear algebra, matrix and vector operations, numerical solvers and related algorithms http://eigen.tuxfamily.org/ -------------------------------------------------------------------------------- -GLFW 3.3.0 (dev) zlib/libpng license -A cross-platform library for creating windows with OpenGL contexts and receiving -input and events -http://www.glfw.org/ +embree 4.3.1 Apache-2 license +Embree is a collection of high-performance ray tracing kernels +https://github.com/embree/embree +-------------------------------------------------------------------------------- +flann 1.8.4 BSD license +A C++ library for performing fast approximate nearest neighbor searches in high +dimensional spaces +http://www.cs.ubc.ca/research/flann/ -------------------------------------------------------------------------------- GLEW 2.1.0 MIT License A cross-platform open-source C/C++ extension loading library http://glew.sourceforge.net/ -------------------------------------------------------------------------------- -RPly 1.1.3 MIT license -A library to read and write PLY files -http://w3.impa.br/~diego/software/rply/ --------------------------------------------------------------------------------- -zlib 1.2.8 zlib license -A lossless data-compression library used by libpng -http://www.zlib.net/ --------------------------------------------------------------------------------- -libpng 1.6.18 libpng license -The free reference library for reading and writing PNGs -http://www.libpng.org/ --------------------------------------------------------------------------------- -libjpeg 9a libjpeg license -A widely used C library for reading and writing JPEG image files -http://libjpeg.sourceforge.net/ +GLFW 3.3.0 (dev) zlib/libpng license +A cross-platform library for creating windows with OpenGL contexts and receiving +input and events +http://www.glfw.org/ -------------------------------------------------------------------------------- jsoncpp 1.8.4 MIT license A C++ library that allows manipulating JSON values https://github.com/open-source-parsers/jsoncpp -------------------------------------------------------------------------------- -flann 1.8.4 BSD license -A C++ library for performing fast approximate nearest neighbor searches in high -dimensional spaces -http://www.cs.ubc.ca/research/flann/ +libjpeg-turbo 2.1.5.1 BSD-style license +A widely used C library for reading and writing JPEG image files +https://github.com/libjpeg-turbo/libjpeg-turbo -------------------------------------------------------------------------------- -dirent 1.21 MIT license -https://github.com/tronkko/dirent -A C/C++ programming interface for cross-platform filesystem +libpng 1.6.37 libpng license +The free reference library for reading and writing PNGs +http://www.libpng.org/ -------------------------------------------------------------------------------- librealsense 2.44.0 Apache-2 license A cross-platform library for capturing data from the Intel RealSense F200, SR300, R200 and L500 cameras https://github.com/IntelRealSense/librealsense -------------------------------------------------------------------------------- -tinyfiledialogs 2.7.2 zlib license -A lightweight cross-platform file dialog library -https://sourceforge.net/projects/tinyfiledialogs/ --------------------------------------------------------------------------------- -tinygltf v2.2.0 MIT license -Header only C++11 tiny glTF 2.0 library -https://github.com/syoyo/tinygltf --------------------------------------------------------------------------------- -tinyobjloader v1.0.0 MIT license -Tiny but powerful single file wavefront obj loader -https://github.com/syoyo/tinyobjloader --------------------------------------------------------------------------------- -pybind11 v2.6.2 BSD license -Python binding for C++11 -https://github.com/pybind/pybind11 --------------------------------------------------------------------------------- -PoissonReco 12.0 BSD license -Poisson Surface Reconstruction -https://github.com/mkazhdan/PoissonRecon --------------------------------------------------------------------------------- -Parallel STL 20190522 Apache-2 license -An implementation of the C++ standard library algorithms with support for -execution policies -https://github.com/oneapi-src/oneDPL +libzmq 4.3.3 LGPLv3 + static link exception license +ZeroMQ is a high-performance asynchronous messaging library +https://github.com/zeromq/libzmq -------------------------------------------------------------------------------- -CUB 1.8.0 BSD license -A flexible library of cooperative threadblock primitives and other utilities for -CUDA kernel programming -https://github.com/NVlabs/cub +msgpack-c 3.3.0 Boost Software License 1.0 +MessagePack implementation for C and C++ +https://github.com/msgpack/msgpack-c/tree/cpp_master -------------------------------------------------------------------------------- nanoflann 1.3.1 BSD license A C++11 header-only library for Nearest Neighbor (NN) search with KD-trees https://github.com/jlblancoc/nanoflann -------------------------------------------------------------------------------- -CUTLASS 1.3.3 BSD license -CUDA Templates for Linear Algebra Subroutines -https://github.com/NVIDIA/cutlass +PoissonReco 12.0 BSD license +Poisson Surface Reconstruction +https://github.com/mkazhdan/PoissonRecon -------------------------------------------------------------------------------- -benchmark 1.5.0 Apache-2 license -A microbenchmark support library -https://github.com/google/benchmark +pybind11 v2.13.1 BSD license +Python binding for C++11 +https://github.com/pybind/pybind11 -------------------------------------------------------------------------------- -msgpack-c da2fc25f8 Boost Software License 1.0 -MessagePack implementation for C and C++ -https://github.com/msgpack/msgpack-c/tree/cpp_master +RPly 1.1.3 MIT license +A library to read and write PLY files +http://w3.impa.br/~diego/software/rply/ -------------------------------------------------------------------------------- -libzmq 4.3.2 LGPLv3 + static link exception license -ZeroMQ is a high-performance asynchronous messaging library -https://github.com/zeromq/libzmq +stdgpu 1b6a3319 Apache-2.0 license +Efficient STL-like Data Structures on the GPU +https://github.com/stotko/stdgpu/ -------------------------------------------------------------------------------- -cppzmq 4.6.0 MIT license -Header-only C++ binding for libzmq -https://github.com/zeromq/cppzmq -As an alternative, you can modify 3rdparty/zeromq/zeromq_build.cmake to fetch -zeromq from our fork -https://github.com/isl-org/libzmq +tinyfiledialogs 2.7.2 zlib license +A lightweight cross-platform file dialog library +https://sourceforge.net/projects/tinyfiledialogs/ -------------------------------------------------------------------------------- -embree 3.13.0 Apache-2 license -Embree is a collection of high-performance ray tracing kernels -https://github.com/embree/embree +tinygltf 72f4a55 MIT license +Header only C++11 tiny glTF 2.0 library +https://github.com/syoyo/tinygltf -------------------------------------------------------------------------------- -curl 7.79.1 Curl license -Curl is a command-line tool for transferring data specified with URL syntax. -https://github.com/curl/curl +tinyobjloader v1.0.0 MIT license +Tiny but powerful single file wavefront obj loader +https://github.com/syoyo/tinyobjloader -------------------------------------------------------------------------------- -boringssl: edfe413 Dual OpenSSL, SSLeay, ISC license -BoringSSL is a fork of OpenSSL that is designed to meet Google's needs. -https://github.com/google/boringssl +UVAtlas may2022 MIT license +UVAtlas isochart texture atlas +https://github.com/microsoft/uvatlas -------------------------------------------------------------------------------- vtk 9.1 BSD license The Visualization Toolkit (VTK) https://gitlab.kitware.com/vtk/vtk -------------------------------------------------------------------------------- -DirectX-Headers v1.606.3 MIT license -Official DirectX headers available under an open source license -https://github.com/microsoft/DirectX-Headers --------------------------------------------------------------------------------- -DirectXMath may2022 MIT license -DirectXMath is an all inline SIMD C++ linear algebra library for use in games -and graphics apps -https://github.com/microsoft/DirectXMath --------------------------------------------------------------------------------- -UVAtlas may2022 MIT license -UVAtlas isochart texture atlas -https://github.com/microsoft/uvatlas +zlib 1.2.13 zlib license +A lossless data-compression library used by libpng +http://www.zlib.net/ -------------------------------------------------------------------------------- ``` diff --git a/3rdparty/cmake/FindPytorch.cmake b/3rdparty/cmake/FindPytorch.cmake index eb2a53e2ec5..31babdca149 100644 --- a/3rdparty/cmake/FindPytorch.cmake +++ b/3rdparty/cmake/FindPytorch.cmake @@ -14,6 +14,20 @@ # # and import the target 'torch'. +# "80-real" to "8.0" and "80" to "8.0+PTX": +macro(translate_arch_string input output) + if("${input}" MATCHES "[0-9]+-real") + string(REGEX REPLACE "([1-9])([0-9])-real" "\\1.\\2" version "${input}") + elseif("${input}" MATCHES "([0-9]+)") + string(REGEX REPLACE "([1-9])([0-9])" "\\1.\\2+PTX" version "${input}") + elseif(input STREQUAL "native") + set(version "Auto") + else() + message(FATAL_ERROR "Invalid architecture string: ${input}") + endif() + set(${output} "${version}") +endmacro() + if(NOT Pytorch_FOUND) # Searching for pytorch requires the python executable if (NOT Python3_EXECUTABLE) @@ -41,6 +55,17 @@ if(NOT Pytorch_FOUND) unset(PyTorch_FETCH_PROPERTIES) unset(PyTorch_PROPERTIES) + if(BUILD_CUDA_MODULE) + # Using CUDA 12.x and Pytorch <2.4 gives the error "Unknown CUDA Architecture Name 9.0a in CUDA_SELECT_NVCC_ARCH_FLAGS". + # As a workaround we explicitly set TORCH_CUDA_ARCH_LIST + set(TORCH_CUDA_ARCH_LIST "") + foreach(arch IN LISTS CMAKE_CUDA_ARCHITECTURES) + translate_arch_string("${arch}" ptarch) + list(APPEND TORCH_CUDA_ARCH_LIST "${ptarch}") + endforeach() + message(STATUS "Using top level CMAKE_CUDA_ARCHITECTURES for TORCH_CUDA_ARCH_LIST: ${TORCH_CUDA_ARCH_LIST}") + endif() + # Use the cmake config provided by torch find_package(Torch REQUIRED PATHS "${Pytorch_ROOT}" NO_DEFAULT_PATH) diff --git a/3rdparty/find_dependencies.cmake b/3rdparty/find_dependencies.cmake index d91377a3138..c3dc3885565 100644 --- a/3rdparty/find_dependencies.cmake +++ b/3rdparty/find_dependencies.cmake @@ -168,6 +168,7 @@ set(ExternalProject_CMAKE_ARGS -DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} -DCMAKE_CUDA_COMPILER_LAUNCHER=${CMAKE_CUDA_COMPILER_LAUNCHER} -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} + -DCMAKE_CUDA_FLAGS=${CMAKE_CUDA_FLAGS} -DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION} -DCMAKE_INSTALL_LIBDIR=${Open3D_INSTALL_LIB_DIR} # Always build 3rd party code in Release mode. Ignored by multi-config diff --git a/3rdparty/stdgpu/stdgpu.cmake b/3rdparty/stdgpu/stdgpu.cmake index f486fc3d4ce..fb9a64e09fd 100644 --- a/3rdparty/stdgpu/stdgpu.cmake +++ b/3rdparty/stdgpu/stdgpu.cmake @@ -7,8 +7,9 @@ include(ExternalProject) ExternalProject_Add( ext_stdgpu PREFIX stdgpu - URL https://github.com/stotko/stdgpu/archive/e10f6f3ccc9902d693af4380c3bcd188ec34a2e6.tar.gz - URL_HASH SHA256=7bb2733b099f7cedc86d2aee7830d128ac1222cfafa34cbaa4e818483c0a93f6 + # Jun 20 2024. Later versions need CUDA 11.5 and an API update (stdgpu::pair) + URL https://github.com/stotko/stdgpu/archive/1b6a3319f1fbf180166e1bbc1d75f69ab622a0a0.tar.gz + URL_HASH SHA256=faa3bf9cbe49ef9cc09e2e07e60d10bbf3b896edb6089c920bebe0f850fd95e4 DOWNLOAD_DIR "${OPEN3D_THIRD_PARTY_DOWNLOAD_DIR}/stdgpu" UPDATE_COMMAND "" CMAKE_ARGS @@ -17,6 +18,7 @@ ExternalProject_Add( -DSTDGPU_BUILD_SHARED_LIBS=OFF -DSTDGPU_BUILD_EXAMPLES=OFF -DSTDGPU_BUILD_TESTS=OFF + -DSTDGPU_BUILD_BENCHMARKS=OFF -DSTDGPU_ENABLE_CONTRACT_CHECKS=OFF -DTHRUST_INCLUDE_DIR=${CUDAToolkit_INCLUDE_DIRS} ${ExternalProject_CMAKE_ARGS_hidden} diff --git a/CHANGELOG.md b/CHANGELOG.md index e5803ea862f..03818e01b47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ - `TriangleMesh`'s `+=` operator appends UVs regardless of the presence of existing features (PR #6728) - Fix build with fmt v10.2.0 (#6783) - Fix segmentation fault (lambda reference capture) of VisualizerWithCustomAnimation::Play (PR #6804) +- Python 3.12 support - Add O3DVisualizer API to enable collapse control of verts in the side panel (PR #6865) - Split pybind declarations/definitions to avoid C++ types in Python docs (PR #6869) - Fix minimal oriented bounding box of MeshBase derived classes and add new unit tests (PR #6898) diff --git a/CMakeLists.txt b/CMakeLists.txt index dc2bdc62e15..7b047cd0b82 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -387,10 +387,18 @@ cmake_language(EVAL CODE "cmake_language(DEFER CALL open3d_patch_findthreads_mod # Build CUDA module by default if CUDA is available if(BUILD_CUDA_MODULE) - if(BUILD_COMMON_CUDA_ARCHS) - if (CMAKE_CUDA_ARCHITECTURES) - message(STATUS "Building with user-provided architectures: ${CMAKE_CUDA_ARCHITECTURES}") - else() + # Suppress nvcc unsupported compiler error for MSVC 2022 with CUDA 11.7 to 12.4 + # https://forums.developer.nvidia.com/t/problems-with-latest-vs2022-update/294150/12 + if (MSVC AND MSVC_VERSION VERSION_LESS_EQUAL "1949") + # Set this before any CUDA checks + set(CMAKE_CUDA_FLAGS "--allow-unsupported-compiler" CACHE STRING "Additional flags for nvcc" FORCE) + message(WARNING "Using --allow-unsupported-compiler flag for nvcc with MSVC 2022. " + "Set $Env:NVCC_PREPEND_FLAGS='--allow-unsupported-compiler' if nvcc still fails.") + endif() + if (CMAKE_CUDA_ARCHITECTURES) + message(STATUS "Building with user-provided CUDA architectures: ${CMAKE_CUDA_ARCHITECTURES}") + else() + if(BUILD_COMMON_CUDA_ARCHS) # Build with all supported architectures for previous 2 generations and # M0 (minor=0) architectures for previous generations (including # deprecated). Note that cubin for M0 runs on GPUs with architecture Mx. @@ -410,14 +418,14 @@ if(BUILD_CUDA_MODULE) set(CMAKE_CUDA_ARCHITECTURES 30-real 50-real 60-real 70-real 75) # Kepler, Maxwell, Pascal, Turing endif() message(STATUS "Using CUDA architectures: ${CMAKE_CUDA_ARCHITECTURES}") - endif() - else() - execute_process(COMMAND nvidia-smi RESULT_VARIABLE NVIDIA_CHECK OUTPUT_QUIET) - if (NVIDIA_CHECK EQUAL 0) - message(STATUS "Building with native CUDA architecture.") - set(CMAKE_CUDA_ARCHITECTURES native) else() - message(WARNING "No CUDA GPU detected. Building with CMake default CUDA architecture.") + execute_process(COMMAND nvidia-smi RESULT_VARIABLE NVIDIA_CHECK OUTPUT_QUIET) + if (NVIDIA_CHECK EQUAL 0) + message(STATUS "Building with native CUDA architecture.") + set(CMAKE_CUDA_ARCHITECTURES native) + else() + message(WARNING "No CUDA GPU detected. Building with CMake default CUDA architecture.") + endif() endif() endif() enable_language(CUDA) diff --git a/cpp/open3d/t/geometry/RaycastingScene.cpp b/cpp/open3d/t/geometry/RaycastingScene.cpp index bc003f8cbed..12f082d0ee1 100644 --- a/cpp/open3d/t/geometry/RaycastingScene.cpp +++ b/cpp/open3d/t/geometry/RaycastingScene.cpp @@ -33,7 +33,8 @@ typedef Eigen::Vector3f Vec3f; // Error function called by embree. void ErrorFunction(void* userPtr, enum RTCError error, const char* str) { - open3d::utility::LogError("embree error: {} {}", error, str); + open3d::utility::LogError("Embree error: {} {}", rtcGetErrorString(error), + str); } // Checks the last dim, ensures that the number of dims is >= min_ndim, checks diff --git a/cpp/open3d/t/io/file_format/FileASSIMP.cpp b/cpp/open3d/t/io/file_format/FileASSIMP.cpp index da23953fe79..7f7ce6a3cfb 100644 --- a/cpp/open3d/t/io/file_format/FileASSIMP.cpp +++ b/cpp/open3d/t/io/file_format/FileASSIMP.cpp @@ -245,7 +245,7 @@ bool WriteTriangleMeshUsingASSIMP(const std::string& filename, if (mesh.HasTriangleColors()) { utility::LogWarning( "Exporting triangle colors is not supported. Please convert to " - "vertex colors or export to a format that supporst it."); + "vertex colors or export to a format that supports it."); } Assimp::Exporter exporter; diff --git a/cpp/pybind/core/tensor_converter.cpp b/cpp/pybind/core/tensor_converter.cpp index 018d857e5ed..1e07ad91d0c 100644 --- a/cpp/pybind/core/tensor_converter.cpp +++ b/cpp/pybind/core/tensor_converter.cpp @@ -106,10 +106,10 @@ Tensor PyArrayToTensor(py::array array, bool inplace) { Dtype dtype = pybind_utils::ArrayFormatToDtype(info.format, info.itemsize); Device device("CPU:0"); - array.inc_ref(); - std::function deleter = [array](void*) -> void { + auto shared_array = std::make_shared(array); + std::function deleter = [shared_array](void*) mutable -> void { py::gil_scoped_acquire acquire; - array.dec_ref(); + shared_array.reset(); }; auto blob = std::make_shared(device, info.ptr, deleter); Tensor t_inplace(shape, strides, info.ptr, dtype, blob); diff --git a/docker/Dockerfile.wheel b/docker/Dockerfile.wheel index 8faa243bf26..25372da258d 100644 --- a/docker/Dockerfile.wheel +++ b/docker/Dockerfile.wheel @@ -1,5 +1,5 @@ # FROM must be called before other ARGS except for ARG BASE_IMAGE -ARG BASE_IMAGE=nvidia/cuda:11.7.1-cudnn8-devel-ubuntu20.04 +ARG BASE_IMAGE=nvidia/cuda:12.1.0-cudnn8-devel-ubuntu20.04 FROM ${BASE_IMAGE} # Customizable build arguments from cuda.yml @@ -98,7 +98,7 @@ RUN which python \ # Checkout Open3D-ML main branch # TODO: We may add support for local Open3D-ML repo or pinned ML repo tag ENV OPEN3D_ML_ROOT=/root/Open3D-ML -RUN git clone https://github.com/isl-org/Open3D-ML.git ${OPEN3D_ML_ROOT} +RUN git clone --depth 1 https://github.com/isl-org/Open3D-ML.git ${OPEN3D_ML_ROOT} # Open3D C++ dependencies # Done before copying the full Open3D directory for better Docker caching @@ -112,7 +112,7 @@ COPY ./python/requirements.txt /root/Open3D/python/ COPY ./python/requirements_jupyter_build.txt /root/Open3D/python/ COPY ./python/requirements_jupyter_install.txt /root/Open3D/python/ RUN source /root/Open3D/util/ci_utils.sh \ - && install_python_dependencies with-cuda with-jupyter + && install_python_dependencies with-jupyter # Open3D Jupyter dependencies RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash - \ diff --git a/docker/README.md b/docker/README.md index 6922834cbf7..cd3a8198579 100644 --- a/docker/README.md +++ b/docker/README.md @@ -26,7 +26,7 @@ to install Nvidia Docker to run the CUDA container. To verify that the Nvidia Docker is working, run: ```bash -docker run --rm --gpus all nvidia/cuda:11.7-base nvidia-smi +docker run --rm --gpus all nvidia/cuda:12.1-base nvidia-smi ``` ### ARM64 Docker diff --git a/docker/docker_build.sh b/docker/docker_build.sh index bc150b06e11..c92aed26829 100755 --- a/docker/docker_build.sh +++ b/docker/docker_build.sh @@ -27,20 +27,24 @@ OPTION: openblas-amd64-py39-dev : OpenBLAS AMD64 3.9 wheel, developer mode openblas-amd64-py310-dev : OpenBLAS AMD64 3.10 wheel, developer mode openblas-amd64-py311-dev : OpenBLAS AMD64 3.11 wheel, developer mode + openblas-amd64-py312-dev : OpenBLAS AMD64 3.12 wheel, developer mode openblas-amd64-py38 : OpenBLAS AMD64 3.8 wheel, release mode openblas-amd64-py39 : OpenBLAS AMD64 3.9 wheel, release mode openblas-amd64-py310 : OpenBLAS AMD64 3.10 wheel, release mode openblas-amd64-py311 : OpenBLAS AMD64 3.11 wheel, release mode + openblas-amd64-py312 : OpenBLAS AMD64 3.12 wheel, release mode # OpenBLAS ARM64 (Dockerfile.openblas) openblas-arm64-py38-dev : OpenBLAS ARM64 3.8 wheel, developer mode openblas-arm64-py39-dev : OpenBLAS ARM64 3.9 wheel, developer mode openblas-arm64-py310-dev : OpenBLAS ARM64 3.10 wheel, developer mode openblas-arm64-py311-dev : OpenBLAS ARM64 3.11 wheel, developer mode + openblas-arm64-py312-dev : OpenBLAS ARM64 3.12 wheel, developer mode openblas-arm64-py38 : OpenBLAS ARM64 3.8 wheel, release mode openblas-arm64-py39 : OpenBLAS ARM64 3.9 wheel, release mode openblas-arm64-py310 : OpenBLAS ARM64 3.10 wheel, release mode openblas-arm64-py311 : OpenBLAS ARM64 3.11 wheel, release mode + openblas-arm64-py312 : OpenBLAS ARM64 3.12 wheel, release mode # Ubuntu CPU CI (Dockerfile.ci) cpu-static : Ubuntu CPU static @@ -66,10 +70,12 @@ OPTION: cuda_wheel_py39_dev : CUDA Python 3.9 wheel, developer mode cuda_wheel_py310_dev : CUDA Python 3.10 wheel, developer mode cuda_wheel_py311_dev : CUDA Python 3.11 wheel, developer mode + cuda_wheel_py312_dev : CUDA Python 3.12 wheel, developer mode cuda_wheel_py38 : CUDA Python 3.8 wheel, release mode cuda_wheel_py39 : CUDA Python 3.9 wheel, release mode cuda_wheel_py310 : CUDA Python 3.10 wheel, release mode cuda_wheel_py311 : CUDA Python 3.11 wheel, release mode + cuda_wheel_py312 : CUDA Python 3.12 wheel, release mode " HOST_OPEN3D_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. >/dev/null 2>&1 && pwd)" @@ -78,8 +84,8 @@ HOST_OPEN3D_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. >/dev/null 2>&1 && pw CCACHE_VERSION=4.3 CMAKE_VERSION=cmake-3.24.4-linux-x86_64 CMAKE_VERSION_AARCH64=cmake-3.24.4-linux-aarch64 -CUDA_VERSION=11.7.1-cudnn8 -CUDA_VERSION_LATEST=11.8.0-cudnn8 +CUDA_VERSION=12.1.0-cudnn8 +CUDA_VERSION_LATEST=12.1.0-cudnn8 print_usage_and_exit_docker_build() { echo "$__usage_docker_build" @@ -128,6 +134,9 @@ openblas_export_env() { elif [[ "py311" =~ ^($options)$ ]]; then export PYTHON_VERSION=3.11 export DOCKER_TAG=${DOCKER_TAG}-py311 + elif [[ "py312" =~ ^($options)$ ]]; then + export PYTHON_VERSION=3.12 + export DOCKER_TAG=${DOCKER_TAG}-py312 else echo "Invalid python version." print_usage_and_exit_docker_build @@ -182,6 +191,8 @@ cuda_wheel_build() { PYTHON_VERSION=3.10 elif [[ "py311" =~ ^($options)$ ]]; then PYTHON_VERSION=3.11 + elif [[ "py312" =~ ^($options)$ ]]; then + PYTHON_VERSION=3.12 else echo "Invalid python version." print_usage_and_exit_docker_build @@ -311,7 +322,7 @@ ci_build() { export BASE_IMAGE=nvidia/cuda:${CUDA_VERSION}-devel-ubuntu20.04 export DEVELOPER_BUILD=ON export CCACHE_TAR_NAME=open3d-ci-4-shared-focal - export PYTHON_VERSION=3.8 + export PYTHON_VERSION=3.12 export BUILD_SHARED_LIBS=ON export BUILD_CUDA_MODULE=ON # TODO: tensorflow tests moved here till PyTorch supports cxx11_abi @@ -327,7 +338,7 @@ ci_build() { export BASE_IMAGE=nvidia/cuda:${CUDA_VERSION}-devel-ubuntu20.04 export DEVELOPER_BUILD=OFF export CCACHE_TAR_NAME=open3d-ci-4-shared-focal - export PYTHON_VERSION=3.8 + export PYTHON_VERSION=3.12 export BUILD_SHARED_LIBS=ON export BUILD_CUDA_MODULE=ON # TODO: tensorflow tests moved here till PyTorch supports cxx11_abi @@ -374,7 +385,7 @@ cpu-shared_export_env() { export BASE_IMAGE=ubuntu:20.04 export DEVELOPER_BUILD=ON export CCACHE_TAR_NAME=open3d-ci-cpu - export PYTHON_VERSION=3.8 + export PYTHON_VERSION=3.12 export BUILD_SHARED_LIBS=ON export BUILD_CUDA_MODULE=OFF # TODO: tensorflow tests moved here till PyTorch supports cxx11_abi @@ -406,7 +417,7 @@ cpu-shared-release_export_env() { export BASE_IMAGE=ubuntu:20.04 export DEVELOPER_BUILD=OFF export CCACHE_TAR_NAME=open3d-ci-cpu - export PYTHON_VERSION=3.8 + export PYTHON_VERSION=3.12 # no TF versions after 2.13.2 for Python 3.8 export BUILD_SHARED_LIBS=ON export BUILD_CUDA_MODULE=OFF # TODO: tensorflow tests moved here till PyTorch supports cxx11_abi @@ -490,6 +501,10 @@ function main() { openblas_export_env amd64 py311 dev openblas_build ;; + openblas-amd64-py312-dev) + openblas_export_env amd64 py312 dev + openblas_build + ;; openblas-amd64-py38) openblas_export_env amd64 py38 openblas_build @@ -506,6 +521,10 @@ function main() { openblas_export_env amd64 py311 openblas_build ;; + openblas-amd64-py312) + openblas_export_env amd64 py312 + openblas_build + ;; # OpenBLAS ARM64 openblas-arm64-py38-dev) @@ -524,6 +543,10 @@ function main() { openblas_export_env arm64 py311 dev openblas_build ;; + openblas-arm64-py312-dev) + openblas_export_env arm64 py312 dev + openblas_build + ;; openblas-arm64-py38) openblas_export_env arm64 py38 openblas_build @@ -540,6 +563,10 @@ function main() { openblas_export_env arm64 py311 openblas_build ;; + openblas-arm64-py312) + openblas_export_env arm64 py312 + openblas_build + ;; # CPU CI cpu-static) @@ -586,6 +613,9 @@ function main() { cuda_wheel_py311_dev) cuda_wheel_build py311 dev ;; + cuda_wheel_py312_dev) + cuda_wheel_build py312 dev + ;; cuda_wheel_py38) cuda_wheel_build py38 ;; @@ -598,6 +628,9 @@ function main() { cuda_wheel_py311) cuda_wheel_build py311 ;; + cuda_wheel_py312) + cuda_wheel_build py312 + ;; # ML CIs 2-focal) diff --git a/docker/docker_test.sh b/docker/docker_test.sh index d328d14535d..a7ab13fbc3c 100755 --- a/docker/docker_test.sh +++ b/docker/docker_test.sh @@ -20,20 +20,24 @@ OPTION: openblas-amd64-py39-dev : OpenBLAS AMD64 3.9 wheel, developer mode openblas-amd64-py310-dev : OpenBLAS AMD64 3.10 wheel, developer mode openblas-amd64-py311-dev : OpenBLAS AMD64 3.11 wheel, developer mode + openblas-amd64-py312-dev : OpenBLAS AMD64 3.12 wheel, developer mode openblas-amd64-py38 : OpenBLAS AMD64 3.8 wheel, release mode openblas-amd64-py39 : OpenBLAS AMD64 3.9 wheel, release mode openblas-amd64-py310 : OpenBLAS AMD64 3.10 wheel, release mode openblas-amd64-py311 : OpenBLAS AMD64 3.11 wheel, release mode + openblas-amd64-py312 : OpenBLAS AMD64 3.12 wheel, release mode # OpenBLAS ARM64 (Dockerfile.openblas) openblas-arm64-py38-dev : OpenBLAS ARM64 3.8 wheel, developer mode openblas-arm64-py39-dev : OpenBLAS ARM64 3.9 wheel, developer mode openblas-arm64-py310-dev : OpenBLAS ARM64 3.10 wheel, developer mode openblas-arm64-py311-dev : OpenBLAS ARM64 3.11 wheel, developer mode + openblas-arm64-py312-dev : OpenBLAS ARM64 3.12 wheel, developer mode openblas-arm64-py38 : OpenBLAS ARM64 3.8 wheel, release mode openblas-arm64-py39 : OpenBLAS ARM64 3.9 wheel, release mode openblas-arm64-py310 : OpenBLAS ARM64 3.10 wheel, release mode openblas-arm64-py311 : OpenBLAS ARM64 3.11 wheel, release mode + openblas-arm64-py312 : OpenBLAS ARM64 3.12 wheel, release mode # Ubuntu CPU CI (Dockerfile.ci) cpu-static : Ubuntu CPU static @@ -228,6 +232,11 @@ openblas-amd64-py311-dev) openblas_print_env cpp_python_linking_uninstall_test ;; +openblas-amd64-py312-dev) + openblas_export_env amd64 py312 dev + openblas_print_env + cpp_python_linking_uninstall_test + ;; openblas-amd64-py38) openblas_export_env amd64 py38 openblas_print_env @@ -248,6 +257,11 @@ openblas-amd64-py311) openblas_print_env cpp_python_linking_uninstall_test ;; +openblas-amd64-py312) + openblas_export_env amd64 py312 + openblas_print_env + cpp_python_linking_uninstall_test + ;; # OpenBLAS ARM64 openblas-arm64-py38-dev) @@ -270,6 +284,11 @@ openblas-arm64-py311-dev) openblas_print_env cpp_python_linking_uninstall_test ;; +openblas-arm64-py312-dev) + openblas_export_env arm64 py312 dev + openblas_print_env + cpp_python_linking_uninstall_test + ;; openblas-arm64-py38) openblas_export_env arm64 py38 openblas_print_env @@ -290,6 +309,11 @@ openblas-arm64-py311) openblas_print_env cpp_python_linking_uninstall_test ;; +openblas-arm64-py312) + openblas_export_env arm64 py312 + openblas_print_env + cpp_python_linking_uninstall_test + ;; # CPU CI cpu-static) diff --git a/docs/arm.rst b/docs/arm.rst index e9f9c942413..35ddf813bed 100644 --- a/docs/arm.rst +++ b/docs/arm.rst @@ -71,6 +71,7 @@ commands: ./docker_build.sh openblas-arm64-py39 # Python 3.9 ./docker_build.sh openblas-arm64-py310 # Python 3.10 ./docker_build.sh openblas-arm64-py311 # Python 3.11 + ./docker_build.sh openblas-arm64-py312 # Python 3.12 After running ``docker_build.sh``, you shall see a ``.whl`` file generated the current directly on the host. Then simply install the ``.whl`` file by: diff --git a/docs/getting_started.in.rst b/docs/getting_started.in.rst index 734cb694e1c..efa04016fce 100644 --- a/docs/getting_started.in.rst +++ b/docs/getting_started.in.rst @@ -32,6 +32,7 @@ Supported Python versions: * 3.9 * 3.10 * 3.11 +* 3.12 Supported operating systems: @@ -53,7 +54,7 @@ Pip (PyPI) .. warning:: Versions of ``numpy>=2.0.0`` require ``Open3D>0.18.0`` or the latest development - version of Open3D. If you are using an older version of Open3D, downgrade ``numpy`` + version of Open3D. If you are using an older version of Open3D, downgrade ``numpy`` with .. code-block:: bash @@ -99,24 +100,28 @@ version (``HEAD`` of ``main`` branch): - `Python 3.9 `__ - `Python 3.10 `__ - `Python 3.11 `__ + - `Python 3.12 `__ * - Linux (CPU) - `Python 3.8 `__ - `Python 3.9 `__ - `Python 3.10 `__ - `Python 3.11 `__ + - `Python 3.12 `__ * - MacOS - `Python 3.8 (x86_64) `__ - `Python 3.9 (x86_64) `__ - `Python 3.10 (x86_64+arm64) `__ - `Python 3.11 (x86_64+arm64) `__ + - `Python 3.12 (x86_64+arm64) `__ * - Windows - `Python 3.8 `__ - `Python 3.9 `__ - `Python 3.10 `__ - `Python 3.11 `__ + - `Python 3.12 `__ Please use these links from the `latest version of this page `__ only. You can also diff --git a/python/README.rst b/python/README.rst index 0c225d07581..e266c2904ab 100644 --- a/python/README.rst +++ b/python/README.rst @@ -48,6 +48,7 @@ With Python versions: * 3.9 * 3.10 * 3.11 +* 3.12 Resources ====================== diff --git a/python/open3d/ml/tf/python/layers/neighbor_search.py b/python/open3d/ml/tf/python/layers/neighbor_search.py index 8a9059ef485..d13dd799d11 100644 --- a/python/open3d/ml/tf/python/layers/neighbor_search.py +++ b/python/open3d/ml/tf/python/layers/neighbor_search.py @@ -121,6 +121,11 @@ def call(self, queries_row_splits = queries.row_splits queries = queries.values + if isinstance(radius, tf.Tensor): + radius_ = tf.cast(radius, points.dtype) + else: + radius_ = radius + if points_row_splits is None: points_row_splits = tf.cast(tf.stack([0, tf.shape(points)[0]]), dtype=tf.int64) @@ -131,7 +136,7 @@ def call(self, table = ops.build_spatial_hash_table( max_hash_table_size=self.max_hash_table_size, points=points, - radius=radius, + radius=radius_, points_row_splits=points_row_splits, hash_table_size_factor=hash_table_size_factor) else: @@ -142,7 +147,7 @@ def call(self, metric=self.metric, points=points, queries=queries, - radius=radius, + radius=radius_, points_row_splits=points_row_splits, queries_row_splits=queries_row_splits, hash_table_splits=table.hash_table_splits, diff --git a/python/requirements.txt b/python/requirements.txt index 148650326df..a7da4963446 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -1,5 +1,6 @@ numpy>=1.18.0,<2.0.0 dash>=2.6.0 -werkzeug>=2.2.3 +werkzeug>=3.0.0 +flask>=3.0.0 nbformat>=5.7.0 configargparse diff --git a/python/requirements_test.txt b/python/requirements_test.txt index 7bb3fd72143..38caaf57575 100644 --- a/python/requirements_test.txt +++ b/python/requirements_test.txt @@ -1,6 +1,8 @@ pytest==7.1.2 pytest-randomly==3.8.0 -scipy==1.10.1 -tensorboard==2.13.0 +scipy==1.10.1; python_version < "3.12" +scipy==1.11.4; python_version >= "3.12" +tensorboard==2.13.0; python_version < "3.12" +tensorboard==2.16.2; python_version >= "3.12" oauthlib==3.2.2 certifi==2024.7.4 diff --git a/python/setup.py b/python/setup.py index e32f69ab615..70b840cb801 100644 --- a/python/setup.py +++ b/python/setup.py @@ -136,6 +136,7 @@ def finalize_options(self): "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Education", "Topic :: Multimedia :: Graphics :: 3D Modeling", "Topic :: Multimedia :: Graphics :: 3D Rendering", diff --git a/python/test/ml_ops/test_sparseconv.py b/python/test/ml_ops/test_sparseconv.py index 1fd6ed5058b..71a019ccc50 100644 --- a/python/test/ml_ops/test_sparseconv.py +++ b/python/test/ml_ops/test_sparseconv.py @@ -89,9 +89,15 @@ def bias_initializer(a): if ml.module.__name__ == 'torch': sparse_conv.to(ml.device) - y = mltest.run_op(ml, ml.device, True, sparse_conv, inp_features, - inp_positions * voxel_size, out_positions * voxel_size, - voxel_size, inp_importance) + y = mltest.run_op(ml, + ml.device, + True, + sparse_conv, + inp_features, + inp_positions * voxel_size, + out_positions * voxel_size, + voxel_size=voxel_size, + inp_importance=inp_importance) # Compare the output to a standard 3d conv # store features in a volume to use standard 3d convs @@ -210,9 +216,15 @@ def test_compare_to_conv3d_batches(ml, dtype, kernel_size, out_channels, inp_features = tf.RaggedTensor.from_row_splits( values=inp_features, row_splits=inp_positions_row_splits) - y = mltest.run_op(ml, ml.device, True, sparse_conv, inp_features, - inp_positions * voxel_size, out_positions * voxel_size, - voxel_size, inp_importance) + y = mltest.run_op(ml, + ml.device, + True, + sparse_conv, + inp_features, + inp_positions * voxel_size, + out_positions * voxel_size, + voxel_size=voxel_size, + inp_importance=inp_importance) for idx in range(batch_size): inp_pos = inp_positions[idx].numpy() inp_feat = inp_features[idx].numpy() @@ -336,9 +348,15 @@ def bias_initializer(a): if ml.module.__name__ == 'torch': sparse_conv_transpose.to(ml.device) - y = mltest.run_op(ml, ml.device, True, sparse_conv_transpose, inp_features, - inp_positions * voxel_size, out_positions * voxel_size, - voxel_size, out_importance) + y = mltest.run_op(ml, + ml.device, + True, + sparse_conv_transpose, + inp_features, + inp_positions * voxel_size, + out_positions * voxel_size, + voxel_size=voxel_size, + out_importance=out_importance) # Compare the output to a standard 3d conv # store features in a volume to use standard 3d convs @@ -463,9 +481,15 @@ def test_compare_to_conv3dtranspose_batches(ml, dtype, kernel_size, inp_features = tf.RaggedTensor.from_row_splits( values=inp_features, row_splits=inp_positions_row_splits) - y = mltest.run_op(ml, ml.device, True, sparse_conv_transpose, inp_features, - inp_positions * voxel_size, out_positions * voxel_size, - voxel_size, out_importance) + y = mltest.run_op(ml, + ml.device, + True, + sparse_conv_transpose, + inp_features, + inp_positions * voxel_size, + out_positions * voxel_size, + voxel_size=voxel_size, + out_importance=out_importance) for idx in range(batch_size): inp_pos = inp_positions[idx].numpy() inp_feat = inp_features[idx].numpy() diff --git a/python/test/t/io/test_realsense.py b/python/test/t/io/test_realsense.py index 2d05e1c28d7..c6df67ae181 100755 --- a/python/test/t/io/test_realsense.py +++ b/python/test/t/io/test_realsense.py @@ -64,7 +64,7 @@ def test_RSBagReader(): assert n_frames == 6 # save_frames - bag_reader = o3d.t.io.RGBDVideoReader.create("L515_test_s.bag") + bag_reader = o3d.t.io.RGBDVideoReader.create(sample_l515_bag.path) bag_reader.save_frames("L515_test_s") # Use issubset() since there may be other OS files present assert {'depth', 'color', @@ -79,8 +79,6 @@ def test_RSBagReader(): }.issubset(os.listdir('L515_test_s/color')) shutil.rmtree("L515_test_s") - if os.name != 'nt': # Permission error in Windows - os.remove("L515_test_s.bag") # Test recording from a RealSense camera, if one is connected diff --git a/util/ci_utils.sh b/util/ci_utils.sh index 93e48c2e463..5ba30b071dc 100644 --- a/util/ci_utils.sh +++ b/util/ci_utils.sh @@ -25,8 +25,8 @@ LOW_MEM_USAGE=${LOW_MEM_USAGE:-OFF} # Dependency versions: # CUDA: see docker/docker_build.sh # ML -TENSORFLOW_VER="2.13.0" -TORCH_VER="2.0.1" +TENSORFLOW_VER="2.16.2" +TORCH_VER="2.2.2" TORCH_REPO_URL="https://download.pytorch.org/whl/torch/" # Python PIP_VER="23.2.1" @@ -362,8 +362,7 @@ install_docs_dependencies() { echo Installing Open3D-ML dependencies from "${OPEN3D_ML_ROOT}" python -m pip install -r "${OPEN3D_ML_ROOT}/requirements.txt" python -m pip install -r "${OPEN3D_ML_ROOT}/requirements-torch.txt" - python -m pip install -r "${OPEN3D_ML_ROOT}/requirements-tensorflow.txt" || - python -m pip install tensorflow # FIXME: Remove after Open3D-ML update + python -m pip install -r "${OPEN3D_ML_ROOT}/requirements-tensorflow.txt" else echo OPEN3D_ML_ROOT="$OPEN3D_ML_ROOT" not specified or invalid. Skipping ML dependencies. fi From 397504427d3c58abb5fb84a15a10ed31876460f9 Mon Sep 17 00:00:00 2001 From: manuelvogel12 <120781514+manuelvogel12@users.noreply.github.com> Date: Wed, 9 Oct 2024 17:28:16 +0200 Subject: [PATCH 5/7] Add Tensor-based implementation of FarthestPointDownSample (#6948) * Add Tensor-based implementation of FarthestPointDownSample * Use tensor-based version also for CPU Pointclouds --- cpp/open3d/t/geometry/PointCloud.cpp | 36 ++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/cpp/open3d/t/geometry/PointCloud.cpp b/cpp/open3d/t/geometry/PointCloud.cpp index b345e0ea985..9986557a6f1 100644 --- a/cpp/open3d/t/geometry/PointCloud.cpp +++ b/cpp/open3d/t/geometry/PointCloud.cpp @@ -384,11 +384,37 @@ PointCloud PointCloud::RandomDownSample(double sampling_ratio) const { } PointCloud PointCloud::FarthestPointDownSample(size_t num_samples) const { - // We want the sampled points has the attributes of the original point - // cloud, so full copy is needed. - const open3d::geometry::PointCloud lpcd = ToLegacy(); - return FromLegacy(*lpcd.FarthestPointDownSample(num_samples), - GetPointPositions().GetDtype(), GetDevice()); + const core::Dtype dtype = GetPointPositions().GetDtype(); + const int64_t num_points = GetPointPositions().GetLength(); + if (num_samples == 0) { + return PointCloud(GetDevice()); + } else if (num_samples == size_t(num_points)) { + return Clone(); + } else if (num_samples > size_t(num_points)) { + utility::LogError( + "Illegal number of samples: {}, must <= point size: {}", + num_samples, num_points); + } + core::Tensor selection_mask = + core::Tensor::Zeros({num_points}, core::Bool, GetDevice()); + core::Tensor smallest_distances = core::Tensor::Full( + {num_points}, std::numeric_limits::infinity(), dtype, + GetDevice()); + + int64_t farthest_index = 0; + + for (size_t i = 0; i < num_samples; i++) { + selection_mask[farthest_index] = true; + core::Tensor selected = GetPointPositions()[farthest_index]; + + core::Tensor diff = GetPointPositions() - selected; + core::Tensor distances_to_selected = (diff * diff).Sum({1}); + smallest_distances = open3d::core::Minimum(distances_to_selected, + smallest_distances); + + farthest_index = smallest_distances.ArgMax({0}).Item(); + } + return SelectByMask(selection_mask); } std::tuple PointCloud::RemoveRadiusOutliers( From 1263be4fca0b2dab0af1268c75663cabcb153dc7 Mon Sep 17 00:00:00 2001 From: Daniel Simon Date: Sun, 13 Oct 2024 11:56:43 -0700 Subject: [PATCH 6/7] Missing build byproducts for VTK when downloaded (#7007) --- 3rdparty/vtk/vtk_build.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/vtk/vtk_build.cmake b/3rdparty/vtk/vtk_build.cmake index f9217f2301e..eb8430e8e46 100644 --- a/3rdparty/vtk/vtk_build.cmake +++ b/3rdparty/vtk/vtk_build.cmake @@ -295,7 +295,7 @@ if(BUILD_VTK_FROM_SOURCE) else() #### download prebuilt vtk foreach(item IN LISTS VTK_LIBRARIES) - list(APPEND VTK_BUILD_BYPRODUCTS /lib/${item}${CMAKE_STATIC_LIBRARY_SUFFIX}) + list(APPEND VTK_BUILD_BYPRODUCTS /lib/${CMAKE_STATIC_LIBRARY_PREFIX}${item}${CMAKE_STATIC_LIBRARY_SUFFIX}) endforeach() if(LINUX_AARCH64) From 1a98853634b3aa316f26edba5816f5d1c6247936 Mon Sep 17 00:00:00 2001 From: Robin <102535177+rxba@users.noreply.github.com> Date: Sun, 13 Oct 2024 21:02:15 +0200 Subject: [PATCH 7/7] Warn if alpha shape reconstruction has alpha too small for point scale and results in empty mesh (#6998) --- CHANGELOG.md | 1 + .../SurfaceReconstructionAlphaShape.cpp | 53 +++++++++++-------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03818e01b47..1dac344abb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ - Fix projection of point cloud to Depth/RGBD image if no position attribute is provided (PR #6880) - Support lowercase types when reading PCD files (PR #6930) - Fix visualization/draw ICP example and add warnings (PR #6933) +- Fix alpha shape reconstruction if alpha too small for point scale (PR #6998) ## 0.13 diff --git a/cpp/open3d/geometry/SurfaceReconstructionAlphaShape.cpp b/cpp/open3d/geometry/SurfaceReconstructionAlphaShape.cpp index 2fc58c9c8d3..eeff478a65f 100644 --- a/cpp/open3d/geometry/SurfaceReconstructionAlphaShape.cpp +++ b/cpp/open3d/geometry/SurfaceReconstructionAlphaShape.cpp @@ -158,28 +158,37 @@ std::shared_ptr TriangleMesh::CreateFromPointCloudAlphaShape( "[CreateFromPointCloudAlphaShape] done remove duplicate triangles " "and unreferenced vertices"); - auto tmesh = t::geometry::TriangleMesh::FromLegacy(*mesh); - - // use new object tmesh2 here even if some arrays share memory with tmesh. - // We don't want to replace the blobs in tmesh. - auto tmesh2 = t::geometry::vtkutils::ComputeNormals( - tmesh, /*vertex_normals=*/true, /*face_normals=*/false, - /*consistency=*/true, /*auto_orient_normals=*/true, - /*splitting=*/false); - - mesh->vertices_ = core::eigen_converter::TensorToEigenVector3dVector( - tmesh2.GetVertexPositions()); - mesh->triangles_ = core::eigen_converter::TensorToEigenVector3iVector( - tmesh2.GetTriangleIndices()); - if (mesh->HasVertexColors()) { - mesh->vertex_colors_ = - core::eigen_converter::TensorToEigenVector3dVector( - tmesh2.GetVertexColors()); - } - if (mesh->HasVertexNormals()) { - mesh->vertex_normals_ = - core::eigen_converter::TensorToEigenVector3dVector( - tmesh2.GetVertexNormals()); + if (mesh->vertices_.size() > 0) { + auto tmesh = t::geometry::TriangleMesh::FromLegacy(*mesh); + + // use new object tmesh2 here even if some arrays share memory with + // tmesh. We don't want to replace the blobs in tmesh. + auto tmesh2 = t::geometry::vtkutils::ComputeNormals( + tmesh, /*vertex_normals=*/true, /*face_normals=*/false, + /*consistency=*/true, /*auto_orient_normals=*/true, + /*splitting=*/false); + + mesh->vertices_ = core::eigen_converter::TensorToEigenVector3dVector( + tmesh2.GetVertexPositions()); + mesh->triangles_ = core::eigen_converter::TensorToEigenVector3iVector( + tmesh2.GetTriangleIndices()); + if (mesh->HasVertexColors()) { + mesh->vertex_colors_ = + core::eigen_converter::TensorToEigenVector3dVector( + tmesh2.GetVertexColors()); + } + if (mesh->HasVertexNormals()) { + mesh->vertex_normals_ = + core::eigen_converter::TensorToEigenVector3dVector( + tmesh2.GetVertexNormals()); + } + } else { + utility::LogWarning( + fmt::format("[CreateFromPointCloudAlphaShape] alpha shape " + "reconstruction resulted in empty mesh. Alpha " + "value ({}) could be too small.", + alpha) + .c_str()); } return mesh;