From a4a173e566e5935b89b97de610ae54622a416b55 Mon Sep 17 00:00:00 2001 From: Jan Lebert Date: Tue, 16 Apr 2024 17:40:58 -0700 Subject: [PATCH] Add macOS arm64 CI runner, fix macOS arm64 builds, fused multi-platform viewer app and python wheels (#6695) * Test macOS arm64 runner * Use matrix to run jobs for both Intel and Apple SIlicon * cleanup workflow, try to fix libomp related issue * Fuse x64 and arm64 wheels, fix wheel naming & unit tests * embree 4.3.1: fix macOS arm64 compile * Add prebuilt arm64 filament binaries * Fuse viewer app * Documentation CI fix by adding lxml[html_clean] to requirements. * Fix for uploading linux CUDA artifacts to github name clash --------- Co-authored-by: Sameer Sheorey --- .github/workflows/macos.yml | 207 +++++++++++++++++--- .github/workflows/ubuntu-cuda.yml | 2 +- 3rdparty/embree/embree.cmake | 10 +- 3rdparty/filament/filament_build.cmake | 1 + 3rdparty/filament/filament_download.cmake | 14 +- 3rdparty/librealsense/fix-macos-arm64.patch | 22 +++ 3rdparty/librealsense/librealsense.cmake | 3 + CHANGELOG.md | 1 + CMakeLists.txt | 17 +- cpp/tests/geometry/TriangleMesh.cpp | 145 +++++++++++--- docs/getting_started.in.rst | 6 +- docs/requirements.txt | 4 +- python/setup.py | 5 + python/test/ml_ops/test_radius_search.py | 4 +- util/ci_utils.sh | 10 +- 15 files changed, 373 insertions(+), 78 deletions(-) create mode 100644 3rdparty/librealsense/fix-macos-arm64.patch diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 16b242d081b..4ac23fd67a8 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -26,10 +26,13 @@ env: jobs: MacOS: - runs-on: macos-12 + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: + # macos-12 is Intel runner, macos-14 is Apple Silicon + # https://github.com/actions/runner-images + os: [macos-12, macos-14] CONFIG: [ON, OFF] env: BUILD_SHARED_LIBS: ${{ matrix.CONFIG }} @@ -47,26 +50,49 @@ jobs: path: ~/.ccache # We include the commit sha in the cache key, as new cache entries are # only created if there is no existing entry for the key yet. - key: ${{ runner.os }}-ccache-${{ github.sha }} + key: ${{ runner.os }}-${{ runner.arch }}-ccache-${{ github.sha }} # Restore any ccache cache entry, if none for - # ${{ runner.os }}-ccache-${{ github.sha }} exists. + # ${{ runner.os }}-${{ runner.arch }}-ccache-${{ github.sha }} exists. # Common prefix will be used so that ccache can be used across commits. restore-keys: | - ${{ runner.os }}-ccache + ${{ runner.os }}-${{ runner.arch }}-ccache + - name: Set up Python version uses: actions/setup-python@v5 with: - python-version: 3.8 + python-version: '3.11' + - name: Install dependencies run: | brew install ccache pkg-config - # Install libomp 11.1.0 from old brew bottle for catalina (10.15). - # Directly installing the Ruby formula will install for the current OS + + if [[ ${{ runner.arch}} == "ARM64" ]]; then + # Fix gfortran not found issue + ln -s $(which gfortran-13) /usr/local/bin/gfortran + + # Default macos-14 image Xcode (version 15.0.1) linker causes build issues. + # Newer Xcode versions work, but embree recommends Apple clang <= 14 on + # arm64 to avoid possible "EXEC_BAD_INSTRUCTION" runtime exceptions: + # https://github.com/embree/embree/releases/tag/v4.3.1 + sudo xcode-select -switch /Applications/Xcode_14.3.1.app + fi + + # Install libomp 11.1.0 from old brew bottle for x64 catalina (10.15) + # / arm64 big sur (11.0). Directly installing the Ruby formula will + # install for the current OS. # https://github.com/microsoft/LightGBM/issues/4229 - brew unlink libomp - curl -L -H "Authorization: Bearer QQ==" -o libomp-11.1.0.catalina.bottle.tar.gz \ - https://ghcr.io/v2/homebrew/core/libomp/blobs/sha256:45a5aa653bd45bd5ff5858580b1a4670c4b5a51ea29d68d45a53f72f56010e05 - brew install -f libomp-11.1.0.catalina.bottle.tar.gz + if [[ ${{ runner.arch}} == "X64" ]]; then + brew unlink libomp + # x64 catalina (10.15) bottle + export LIBOMP_BOTTLE_HASH=45a5aa653bd45bd5ff5858580b1a4670c4b5a51ea29d68d45a53f72f56010e05 + else # ARM64 + # arm64 big_sur (11.0) bottle + export LIBOMP_BOTTLE_HASH=f87f7841eb8b72650fa771af39642361aec371ea1a1f94f081ecc0e8168a0e75 + fi + curl -L -H "Authorization: Bearer QQ==" -o libomp-11.1.0.bottle.tar.gz \ + https://ghcr.io/v2/homebrew/core/libomp/blobs/sha256:$LIBOMP_BOTTLE_HASH + brew install -f libomp-11.1.0.bottle.tar.gz + ccache -M 2G # See .github/workflows/readme.md for ccache strategy. - name: Config and build run: | @@ -82,7 +108,7 @@ jobs: pushd build make -j${NPROC} Open3DViewer pushd bin - zip -rv open3d-app-macosx-10_15.zip Open3D.app + zip -rv open3d-app-macosx-10_15-${{ runner.arch}}.zip Open3D.app ccache -s - name: Upload package @@ -116,21 +142,58 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ env.BUILD_SHARED_LIBS == 'OFF' }} with: - name: open3d-app-macosx-10_15 - path: build/bin/open3d-app-macosx-10_15.zip + name: open3d-app-macosx-10_15-${{ runner.arch}} + path: build/bin/open3d-app-macosx-10_15-${{ runner.arch}}.zip + if-no-files-found: error + + fuse-viewer: + name: Fuse x64 and ARM64 viewer app + runs-on: [macos-12] + needs: [MacOS] + steps: + - name: Download viewer apps + uses: actions/download-artifact@v4 + with: + pattern: open3d-app-macosx-10_15-* + merge-multiple: true + + - name: Fuse x64 and arm64 viewer apps + run: | + unzip open3d-app-macosx-10_15-X64.zip -d x64 + unzip open3d-app-macosx-10_15-ARM64.zip -d arm64 + for i in arm64/Open3D.app/Contents/MacOS/*; do + filepath=Open3D.app/Contents/MacOS/$(basename $i) + lipo -create arm64/${filepath} x64/${filepath} -output arm64/${filepath} + done + mv arm64/Open3D.app Open3D.app + zip -rv open3d-app-macosx-10_15-universal2.zip Open3D.app + + - name: Upload Open3D viewer app + uses: actions/upload-artifact@v4 + with: + name: open3d-app-macosx-10_15-universal2 + path: open3d-app-macosx-10_15-universal2.zip if-no-files-found: error build-wheel: name: Build wheel - runs-on: macos-12 + runs-on: ${{ matrix.os }} strategy: fail-fast: false # https://github.community/t/how-to-conditionally-include-exclude-items-in-matrix-eg-based-on-branch/16853/6 matrix: + # 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'] is_main: - ${{ github.ref == 'refs/heads/main' }} exclude: + # TODO: remove macos-14 excludes when https://github.com/actions/setup-python/issues/808 is fixed + - os: macos-14 + python_version: '3.8' + - os: macos-14 + python_version: '3.9' - is_main: false python_version: '3.8' - is_main: false @@ -158,12 +221,12 @@ jobs: path: ~/.ccache # We include the commit sha in the cache key, as new cache entries are # only created if there is no existing entry for the key yet. - key: ${{ runner.os }}-ccache-${{ github.sha }} + key: ${{ runner.os }}-${{ runner.arch }}-ccache-${{ github.sha }} # Restore any ccache cache entry, if none for - # ${{ runner.os }}-ccache-${{ github.sha }} exists. + # ${{ runner.os }}-${{ runner.arch }}-ccache-${{ github.sha }} exists. # Common prefix will be used so that ccache can be used across commits. restore-keys: | - ${{ runner.os }}-ccache + ${{ runner.os }}-${{ runner.arch }}-ccache - name: Set up Python uses: actions/setup-python@v5 @@ -180,12 +243,26 @@ jobs: cmake --version source util/ci_utils.sh install_python_dependencies + + # Fix macos-14 arm64 runner image issues, see comments in MacOS job. + if [[ ${{ runner.arch}} == "ARM64" ]]; then + ln -s $(which gfortran-13) /usr/local/bin/gfortran + sudo xcode-select -switch /Applications/Xcode_14.3.1.app + fi + # Install libomp 11.1.0. See comment above. + if [[ ${{ runner.arch}} == "X64" ]]; then + brew unlink libomp + # x64 catalina (10.15) bottle + export LIBOMP_BOTTLE_HASH=45a5aa653bd45bd5ff5858580b1a4670c4b5a51ea29d68d45a53f72f56010e05 + else # ARM64 + # arm64 big_sur (11.0) bottle + export LIBOMP_BOTTLE_HASH=f87f7841eb8b72650fa771af39642361aec371ea1a1f94f081ecc0e8168a0e75 + fi + curl -L -H "Authorization: Bearer QQ==" -o libomp-11.1.0.bottle.tar.gz \ + https://ghcr.io/v2/homebrew/core/libomp/blobs/sha256:$LIBOMP_BOTTLE_HASH + brew install -f libomp-11.1.0.bottle.tar.gz brew install ccache - brew unlink libomp - curl -L -H "Authorization: Bearer QQ==" -o libomp-11.1.0.catalina.bottle.tar.gz \ - https://ghcr.io/v2/homebrew/core/libomp/blobs/sha256:45a5aa653bd45bd5ff5858580b1a4670c4b5a51ea29d68d45a53f72f56010e05 - brew install -f libomp-11.1.0.catalina.bottle.tar.gz ccache -M 2G # See .github/workflows/readme.md for ccache strategy. - name: Config and build wheel @@ -227,17 +304,97 @@ jobs: gsutil cp build/lib/python_package/pip_package/${{ env.PIP_PKG_NAME }} gs://open3d-releases/python-wheels/ echo "Download pip package at: https://storage.googleapis.com/open3d-releases/python-wheels/${{ env.PIP_PKG_NAME }}" + fuse-wheel: + name: Fuse universal2 wheel + runs-on: [macos-12] + needs: [build-wheel] + strategy: + 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'] + is_main: + - ${{ github.ref == 'refs/heads/main' }} + exclude: + - is_main: false + python_version: '3.10' + steps: + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python_version }} + - name: Download X64 wheels + uses: actions/download-artifact@v4 + with: + pattern: open3d-*macosx*_x86_64.whl + path: x64_wheels + merge-multiple: true + - name: Download ARM64 wheels + uses: actions/download-artifact@v4 + with: + pattern: open3d-*macosx*_arm64.whl + path: arm64_wheels + merge-multiple: true + - name: Fuse x64 and ARM64 wheels + env: + python_version: ${{ matrix.python_version }} + run: | + PYTAG="-cp$(echo ${{ env.python_version }} | tr -d '.')" + mkdir universal_wheels + + pip install delocate + delocate-fuse -v x64_wheels/open3d-*${PYTAG}*.whl arm64_wheels/open3d-*${PYTAG}*.whl + + # Normalize file name as delocate-fuse doesn't update it + OLD_WHL_NAME=$(basename x64_wheels/open3d-*${PYTAG}*.whl) + NEW_WHL_NAME=${OLD_WHL_NAME/x86_64/universal2} + mv x64_wheels/${OLD_WHL_NAME} universal_wheels/${NEW_WHL_NAME} + + echo "PIP_PKG_NAME=$NEW_WHL_NAME" >> $GITHUB_ENV + - name: Upload merged wheels + uses: actions/upload-artifact@v4 + with: + name: ${{ env.PIP_PKG_NAME }} + path: universal_wheels/${{ env.PIP_PKG_NAME }} + if-no-files-found: error + + - name: GCloud CLI auth + if: ${{ github.ref == 'refs/heads/main' }} + uses: 'google-github-actions/auth@v2' + with: + project_id: ${{ secrets.GCE_PROJECT }} + credentials_json: '${{ secrets.GCE_SA_KEY_GPU_CI }}' + - name: GCloud CLI setup + if: ${{ github.ref == 'refs/heads/main' }} + uses: google-github-actions/setup-gcloud@v2 + with: + version: ${{ env.GCE_CLI_GHA_VERSION }} + project_id: ${{ secrets.GCE_PROJECT }} + + - name: Upload wheel to GCS bucket + if: ${{ github.ref == 'refs/heads/main' }} + env: + python_version: ${{ matrix.python_version }} + run: | + gsutil cp universal_wheels/${{ env.PIP_PKG_NAME }} gs://open3d-releases/python-wheels/ + echo "Download pip package at: https://storage.googleapis.com/open3d-releases/python-wheels/${{ env.PIP_PKG_NAME }}" + test-wheel: name: Test wheel - runs-on: macos-12 + runs-on: ${{ matrix.os }} needs: [build-wheel] strategy: fail-fast: false matrix: + os: [macos-12, macos-14] python_version: ['3.8', '3.9', '3.10', '3.11'] is_main: - ${{ github.ref == 'refs/heads/main' }} exclude: + - os: macos-14 + python_version: '3.8' + - os: macos-14 + python_version: '3.9' - is_main: false python_version: '3.8' - is_main: false @@ -273,7 +430,7 @@ jobs: python -V source util/ci_utils.sh pi_tag=$(python -c "import sys; print(f'cp{sys.version_info.major}{sys.version_info.minor}')") - test_wheel open3d*-"$pi_tag"-*.whl + test_wheel open3d*-"$pi_tag"-*_$(uname -m).whl - name: Run Python unit tests (benchmarks) run: | @@ -286,7 +443,7 @@ jobs: # no need to run on macOS runs-on: ubuntu-latest if: ${{ github.ref == 'refs/heads/main' }} - needs: [build-wheel, MacOS] + needs: [fuse-wheel, MacOS] steps: - name: GCloud CLI auth uses: 'google-github-actions/auth@v2' diff --git a/.github/workflows/ubuntu-cuda.yml b/.github/workflows/ubuntu-cuda.yml index bc7dcf9f67a..250be1597fb 100644 --- a/.github/workflows/ubuntu-cuda.yml +++ b/.github/workflows/ubuntu-cuda.yml @@ -152,7 +152,7 @@ jobs: if: ${{ env.BUILD_PACKAGE == 'true' }} uses: actions/upload-artifact@v4 with: - name: open3d-devel-linux-x86_64-cuda-${CI_CONFIG} + name: open3d-devel-linux-x86_64-cuda-${{ matrix.CI_CONFIG }} path: open3d-devel-linux*.tar.xz if-no-files-found: error diff --git a/3rdparty/embree/embree.cmake b/3rdparty/embree/embree.cmake index e0794b55da0..35d27f11048 100644 --- a/3rdparty/embree/embree.cmake +++ b/3rdparty/embree/embree.cmake @@ -8,13 +8,11 @@ include(ExternalProject) # select ISAs if(APPLE) if(APPLE_AARCH64) - # Turn off ISA optimizations for Apple ARM64 for now. - set(ISA_ARGS -DEMBREE_ISA_AVX=OFF - -DEMBREE_ISA_AVX2=OFF - -DEMBREE_ISA_AVX512=OFF - -DEMBREE_ISA_SSE2=OFF - -DEMBREE_ISA_SSE42=OFF + set(ISA_ARGS -DEMBREE_ISA_NEON=OFF + -DEMBREE_ISA_NEON2X=ON ) + set(ISA_LIBS embree_avx2) + set(ISA_BUILD_BYPRODUCTS "/${Open3D_INSTALL_LIB_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}embree_avx2${CMAKE_STATIC_LIBRARY_SUFFIX}") else() # With AppleClang we can select only 1 ISA. set(ISA_ARGS -DEMBREE_ISA_AVX=OFF diff --git a/3rdparty/filament/filament_build.cmake b/3rdparty/filament/filament_build.cmake index cf2d650530e..432f55a28c0 100644 --- a/3rdparty/filament/filament_build.cmake +++ b/3rdparty/filament/filament_build.cmake @@ -72,5 +72,6 @@ ExternalProject_Add( -DFILAMENT_SUPPORTS_VULKAN=OFF -DFILAMENT_SKIP_SAMPLES=ON -DFILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB=20 # to support many small entities + -DSPIRV_WERROR=OFF BUILD_BYPRODUCTS ${lib_byproducts} ) diff --git a/3rdparty/filament/filament_download.cmake b/3rdparty/filament/filament_download.cmake index ef41dd17faf..f21cc91c31b 100644 --- a/3rdparty/filament/filament_download.cmake +++ b/3rdparty/filament/filament_download.cmake @@ -26,9 +26,17 @@ else() string(APPEND lib_dir /x86_64/md) endif() elseif(APPLE) - set(FILAMENT_URL https://github.com/google/filament/releases/download/v1.9.19/filament-v1.9.19-mac.tgz) - set(FILAMENT_SHA256 2765d0ce60647fc17d1880c4618cf7d6b5343d8be4dad87978c3917d9c723b4e) - string(APPEND lib_dir /x86_64) + if (APPLE_AARCH64) + set(FILAMENT_URL https://github.com/isl-org/open3d_downloads/releases/download/filament/filament-v1.9.19-macos_arm64.tgz) + set(FILAMENT_SHA256 3422bdff451d90144fbb69e625d8dcaeaf3222dc2c28879536067937955bc362) + string(APPEND lib_dir /arm64) + # Our arm64 builds use FILAMENT_SUPPORTS_VULKAN=OFF + list(REMOVE_ITEM filament_LIBRARIES bluevk) + else() + set(FILAMENT_URL https://github.com/google/filament/releases/download/v1.9.19/filament-v1.9.19-mac.tgz) + set(FILAMENT_SHA256 2765d0ce60647fc17d1880c4618cf7d6b5343d8be4dad87978c3917d9c723b4e) + string(APPEND lib_dir /x86_64) + endif() else() # Linux: Check glibc version and use open3d filament binary if new (Ubuntu 20.04 and similar) execute_process(COMMAND ldd --version OUTPUT_VARIABLE ldd_version) string(REGEX MATCH "([0-9]+\.)+[0-9]+" glibc_version ${ldd_version}) diff --git a/3rdparty/librealsense/fix-macos-arm64.patch b/3rdparty/librealsense/fix-macos-arm64.patch new file mode 100644 index 00000000000..0de73a574a1 --- /dev/null +++ b/3rdparty/librealsense/fix-macos-arm64.patch @@ -0,0 +1,22 @@ +From beb4c44debc8336de991c983274cad841eb5c323 Mon Sep 17 00:00:00 2001 +From: Pavol Rusnak +Date: Sun, 20 Jun 2021 12:26:58 +0200 +Subject: [PATCH] Fix build on macOS arm64 + +--- + src/proc/color-formats-converter.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/proc/color-formats-converter.cpp b/src/proc/color-formats-converter.cpp +index 564a23d9c4..6c6c8c97d8 100644 +--- a/src/proc/color-formats-converter.cpp ++++ b/src/proc/color-formats-converter.cpp +@@ -18,7 +18,7 @@ + #include // For SSSE3 intrinsics + #endif + +-#if defined (ANDROID) || (defined (__linux__) && !defined (__x86_64__)) ++#if defined (ANDROID) || (defined (__linux__) && !defined (__x86_64__)) || (defined (__APPLE__) && !defined (__x86_64__)) + + bool has_avx() { return false; } + diff --git a/3rdparty/librealsense/librealsense.cmake b/3rdparty/librealsense/librealsense.cmake index c6b4e358e32..e5caa700df7 100644 --- a/3rdparty/librealsense/librealsense.cmake +++ b/3rdparty/librealsense/librealsense.cmake @@ -17,6 +17,9 @@ ExternalProject_Add( COMMAND ${GIT_EXECUTABLE} init COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_LIST_DIR}/fix-cudacrt.patch + # Patch for macOS ARM64 support for versions < 2.50.0 + COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace + ${CMAKE_CURRENT_LIST_DIR}/fix-macos-arm64.patch CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= -DBUILD_SHARED_LIBS=OFF diff --git a/CHANGELOG.md b/CHANGELOG.md index 3509dda95e6..af429044ee2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ - Fix regression in printing cuda tensor from PR #6444 🐛 - Add Python pathlib support for file IO (PR #6619) - Fix log error message for `probability` argument validation in `PointCloud::SegmentPlane` (PR #6622) +- Fix macOS arm64 builds, add CI runner for macOS arm64 (PR #6695) ## 0.13 diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d03dad7dc6..7abd4307b91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,11 +12,6 @@ cmake_minimum_required(VERSION 3.20) # CMake 3.20+ is required to: # - detect IntelLLVM compiler for SYCL -if (APPLE) -set (CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING - "Minimum OS X deployment version" FORCE) -endif() - # CMAKE_HOST_SYSTEM_PROCESSOR is only available after calling project(), # which depends on ${OPEN3D_VERSION}, which depends on ${DEVELOPER_BUILD}. if(UNIX AND NOT APPLE) @@ -35,6 +30,11 @@ if(APPLE) ) if(PROCESSOR_ARCH STREQUAL "arm64") set(APPLE_AARCH64 TRUE) + set (CMAKE_OSX_DEPLOYMENT_TARGET "11.0" CACHE STRING + "Minimum OS X deployment version" FORCE) + else() + set (CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING + "Minimum OS X deployment version" FORCE) endif() endif() @@ -117,9 +117,12 @@ option(USE_SYSTEM_VTK "Use system pre-installed VTK" OFF option(USE_SYSTEM_ZEROMQ "Use system pre-installed ZeroMQ" OFF) if(LINUX_AARCH64 OR APPLE_AARCH64) option(BUILD_VTK_FROM_SOURCE "Build VTK from source" ON ) - option(BUILD_FILAMENT_FROM_SOURCE "Build filament from source" ON ) else() option(BUILD_VTK_FROM_SOURCE "Build VTK from source" OFF) +endif() +if(LINUX_AARCH64) + option(BUILD_FILAMENT_FROM_SOURCE "Build filament from source" ON ) +else() option(BUILD_FILAMENT_FROM_SOURCE "Build filament from source" OFF) endif() @@ -198,7 +201,7 @@ cmake_policy(GET CMP0072 CMP0072_VALUE) if ((LINUX_AARCH64 OR APPLE_AARCH64) AND BUILD_ISPC_MODULE) message(FATAL_ERROR "ISPC module is not yet supported on ARM Linux") endif() -if ((LINUX_AARCH64 OR APPLE_AARCH64) AND NOT BUILD_FILAMENT_FROM_SOURCE) +if (LINUX_AARCH64 AND NOT BUILD_FILAMENT_FROM_SOURCE) message(FATAL_ERROR "ARM CPU detected, you must set BUILD_FILAMENT_FROM_SOURCE=ON.") endif() if ((LINUX_AARCH64 OR APPLE_AARCH64) AND NOT USE_BLAS) diff --git a/cpp/tests/geometry/TriangleMesh.cpp b/cpp/tests/geometry/TriangleMesh.cpp index 559330bb2a0..ff6d75f6c8c 100644 --- a/cpp/tests/geometry/TriangleMesh.cpp +++ b/cpp/tests/geometry/TriangleMesh.cpp @@ -1843,33 +1843,121 @@ TEST(TriangleMesh, CreateFromPointCloudPoisson) { {0.742035, 0.885688, 0.458892}, {0.742035, 0.885688, 0.458892}, {0.383097, 0.761093, 0.173810}, {0.284898, 0.359292, 0.669062}}; mesh_gt.triangles_ = { - {1, 13, 0}, {0, 14, 2}, {13, 14, 0}, {1, 15, 13}, - {15, 16, 13}, {1, 3, 15}, {14, 13, 16}, {16, 17, 14}, - {2, 18, 4}, {14, 18, 2}, {4, 18, 5}, {18, 14, 17}, - {17, 19, 18}, {18, 19, 6}, {6, 5, 18}, {7, 16, 15}, - {7, 8, 16}, {8, 20, 16}, {21, 16, 20}, {17, 16, 21}, - {9, 20, 8}, {10, 20, 9}, {21, 20, 10}, {22, 17, 21}, - {19, 17, 22}, {19, 22, 11}, {11, 6, 19}, {22, 21, 10}, - {10, 12, 22}, {11, 22, 12}, {24, 0, 23}, {1, 0, 24}, - {0, 2, 25}, {25, 23, 0}, {3, 1, 24}, {24, 26, 3}, - {2, 4, 27}, {27, 25, 2}, {27, 5, 28}, {4, 5, 27}, - {28, 6, 29}, {5, 6, 28}, {8, 7, 30}, {30, 31, 8}, - {32, 8, 31}, {9, 8, 32}, {33, 9, 32}, {10, 9, 33}, - {6, 11, 34}, {34, 29, 6}, {12, 10, 33}, {33, 35, 12}, - {34, 12, 35}, {11, 12, 34}, {24, 23, 48}, {36, 23, 25}, - {36, 37, 23}, {37, 48, 23}, {38, 24, 48}, {38, 39, 24}, - {39, 26, 24}, {39, 49, 26}, {38, 48, 37}, {25, 27, 40}, - {40, 36, 25}, {27, 28, 41}, {41, 40, 27}, {28, 29, 42}, - {42, 41, 28}, {39, 30, 49}, {39, 31, 30}, {39, 50, 31}, - {39, 43, 50}, {44, 50, 43}, {32, 31, 50}, {44, 32, 50}, - {44, 45, 32}, {45, 33, 32}, {42, 34, 46}, {29, 34, 42}, - {47, 33, 45}, {35, 33, 47}, {34, 35, 47}, {47, 46, 34}, - {37, 36, 51}, {39, 38, 52}, {53, 52, 51}, {52, 37, 51}, - {52, 38, 37}, {36, 40, 54}, {54, 51, 36}, {54, 40, 41}, - {51, 54, 55}, {55, 53, 51}, {55, 41, 42}, {54, 41, 55}, - {43, 39, 52}, {56, 52, 53}, {56, 44, 52}, {44, 43, 52}, - {45, 44, 56}, {56, 55, 57}, {53, 55, 56}, {55, 42, 46}, - {46, 57, 55}, {45, 56, 57}, {57, 47, 45}, {57, 46, 47}}; + {1, 13, 0}, + {0, 14, 2}, + {13, 14, 0}, + {1, 15, 13}, + {15, 16, 13}, + {1, 3, 15}, + {14, 13, 16}, + {16, 17, 14}, + {2, 18, 4}, + {14, 18, 2}, + {4, 18, 5}, + {18, 14, 17}, + {17, 19, 18}, + {18, 19, 6}, + {6, 5, 18}, + {7, 16, 15}, + {7, 8, 16}, + {8, 20, 16}, + {21, 16, 20}, + {17, 16, 21}, + {9, 20, 8}, + {10, 20, 9}, + {21, 20, 10}, + {22, 17, 21}, + {19, 17, 22}, + {19, 22, 11}, + {11, 6, 19}, + {22, 21, 10}, + {10, 12, 22}, + {11, 22, 12}, + {24, 0, 23}, + {1, 0, 24}, + {0, 2, 25}, + {25, 23, 0}, + {3, 1, 24}, + {24, 26, 3}, + {2, 4, 27}, + {27, 25, 2}, + {27, 5, 28}, + {4, 5, 27}, + {28, 6, 29}, + {5, 6, 28}, + {8, 7, 30}, + {30, 31, 8}, + {32, 8, 31}, + {9, 8, 32}, + {33, 9, 32}, + {10, 9, 33}, + {6, 11, 34}, + {34, 29, 6}, + {12, 10, 33}, + {33, 35, 12}, + {34, 12, 35}, + {11, 12, 34}, + {24, 23, 48}, + {36, 23, 25}, + {36, 37, 23}, + {37, 48, 23}, + {38, 24, 48}, + {38, 39, 24}, + {39, 26, 24}, + {39, 49, 26}, + {38, 48, 37}, + {25, 27, 40}, + {40, 36, 25}, + {27, 28, 41}, + {41, 40, 27}, + {28, 29, 42}, + {42, 41, 28}, + {39, 30, 49}, + {39, 31, 30}, + {39, 50, 31}, + {39, 43, 50}, + {44, 50, 43}, + {32, 31, 50}, +#if defined(__APPLE__) && defined(__arm64__) + // Apple Silicon consistently triangulates the vertices differently + {44, 45, 50}, + {45, 32, 50}, +#else + {44, 32, 50}, + {44, 45, 32}, +#endif + {45, 33, 32}, + {42, 34, 46}, + {29, 34, 42}, + {47, 33, 45}, + {35, 33, 47}, + {34, 35, 47}, + {47, 46, 34}, + {37, 36, 51}, + {39, 38, 52}, + {53, 52, 51}, + {52, 37, 51}, + {52, 38, 37}, + {36, 40, 54}, + {54, 51, 36}, + {54, 40, 41}, + {51, 54, 55}, + {55, 53, 51}, + {55, 41, 42}, + {54, 41, 55}, + {43, 39, 52}, + {56, 52, 53}, + {56, 44, 52}, + {44, 43, 52}, + {45, 44, 56}, + {56, 55, 57}, + {53, 55, 56}, + {55, 42, 46}, + {46, 57, 55}, + {45, 56, 57}, + {57, 47, 45}, + {57, 46, 47} + }; std::vector densities_gt = { 0.39865168929100037, 0.32580316066741943, 0.39778709411621094, 0.2200755625963211, 0.428702175617218, 0.4288075268268585, @@ -2208,7 +2296,8 @@ TEST(TriangleMesh, CreateMeshCoordinateFrame) { indices.push_back(output_tm->triangles_[i](1, 0)); indices.push_back(output_tm->triangles_[i](2, 0)); } - unique(indices.begin(), indices.end()); + auto last = unique(indices.begin(), indices.end()); + indices.erase(last, indices.end()); sort(indices.begin(), indices.end()); auto output = output_tm->SelectByIndex(indices); diff --git a/docs/getting_started.in.rst b/docs/getting_started.in.rst index b9f390ea835..4d3ccc84214 100644 --- a/docs/getting_started.in.rst +++ b/docs/getting_started.in.rst @@ -82,9 +82,9 @@ version (``HEAD`` of ``main`` branch): - `Python 3.11 `__ * - MacOS - - `Python 3.8 `__ - - `Python 3.9 `__ - - `Python 3.10 `__ + - `Python 3.8 `__ + - `Python 3.9 `__ + - `Python 3.10 `__ - `Python 3.11 `__ * - Windows diff --git a/docs/requirements.txt b/docs/requirements.txt index 299c15f5a84..a974fc66a1d 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -4,4 +4,6 @@ jinja2==3.1.3 m2r2==0.3.3.post2 matplotlib==3.7.3 nbsphinx==0.9.3 -sphinx==7.1.2 \ No newline at end of file +sphinx==7.1.2 +nbconvert==6.5.4 +lxml[html_clean]==5.2.1 diff --git a/python/setup.py b/python/setup.py index 029c5717180..e32f69ab615 100644 --- a/python/setup.py +++ b/python/setup.py @@ -70,6 +70,11 @@ def get_tag(self): libc.gnu_get_libc_version.restype = ctypes.c_char_p GLIBC_VER = libc.gnu_get_libc_version().decode("utf8").split(".") plat = f"manylinux_{GLIBC_VER[0]}_{GLIBC_VER[1]}{plat[5:]}" + elif plat[:6] == "macosx": + # If the Python interpreter is an universal2 app the resulting wheel is tagged as + # universal2 instead of the current architecture. This is a workaround to fix it. + plat = plat.replace("universal2", platform.machine()) + return python, abi, plat diff --git a/python/test/ml_ops/test_radius_search.py b/python/test/ml_ops/test_radius_search.py index 85b2af0ad0d..b799b2c7602 100644 --- a/python/test/ml_ops/test_radius_search.py +++ b/python/test/ml_ops/test_radius_search.py @@ -103,7 +103,7 @@ def test_radius_search(dtype, ml, num_points_queries, metric, if normalize_distances: gt_dist /= radii[i] - np.testing.assert_allclose(dist, gt_dist, rtol=1e-7, atol=1e-8) + np.testing.assert_allclose(dist, gt_dist, rtol=1e-7, atol=1e-7) @mltest.parametrize.ml_cpu_only @@ -236,4 +236,4 @@ def test_radius_search_batches(ml, batch_size): if normalize_distances: gt_dist /= radii[i] - np.testing.assert_allclose(dist, gt_dist, rtol=1e-7, atol=1e-8) + np.testing.assert_allclose(dist, gt_dist, rtol=1e-7, atol=1e-7) diff --git a/util/ci_utils.sh b/util/ci_utils.sh index 38ff654880e..aa30d2c12ad 100644 --- a/util/ci_utils.sh +++ b/util/ci_utils.sh @@ -55,8 +55,14 @@ install_python_dependencies() { TF_ARCH_DISABLE_NAME=tensorflow-cpu TORCH_GLNX="torch==$TORCH_CUDA_GLNX_VER" else - TF_ARCH_NAME=tensorflow-cpu - TF_ARCH_DISABLE_NAME=tensorflow + # tensorflow-cpu wheels for macOS arm64 are not available + if [[ "$OSTYPE" == "darwin"* ]]; then + TF_ARCH_NAME=tensorflow + TF_ARCH_DISABLE_NAME=tensorflow + else + TF_ARCH_NAME=tensorflow-cpu + TF_ARCH_DISABLE_NAME=tensorflow + fi TORCH_GLNX="torch==$TORCH_CPU_GLNX_VER" fi