diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index bd24116faa2..14af17fe1d2 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -4,7 +4,6 @@ # - PyTorch Ops in debug mode - DLL initialization error while loading open3d_torch_ops.dll # - CUDA - Draw.exe does not run due to CUDA DLL path issues - name: Windows permissions: {} @@ -15,6 +14,10 @@ on: description: "Set to OFF for Release wheels" required: false default: "ON" + oneapi_cmake_debug: + description: "Verbose oneAPI path diagnostics and CMAKE_FIND_DEBUG_MODE on xpu legs" + required: false + default: "OFF" push: branches: @@ -34,6 +37,8 @@ env: INSTALL_DIR: "C:\\Program Files\\Open3D" NPROC: 6 DEVELOPER_BUILD: ${{ github.event.inputs.developer_build || 'ON' }} + # workflow_dispatch oneapi_cmake_debug=ON enables -Verbose install logs and cmake --debug-find + OPEN3D_ONEAPI_DEBUG: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.oneapi_cmake_debug == 'ON' && '1' || '0' }} jobs: windows: @@ -45,26 +50,69 @@ jobs: runs-on: windows-2022 strategy: fail-fast: false + # Eight matrix legs (S=BUILD_SHARED_LIBS, R=STATIC_RUNTIME) plus build-wheel/test-wheel. + # Covers cpu/cuda/xpu once where needed; devel zips, viewer, SYCL, and /MD static smoke. matrix: - BUILD_SHARED_LIBS: [ON, OFF] - STATIC_RUNTIME: [ON, OFF] - BUILD_CUDA_MODULE: [ON, OFF] - CONFIG: [Release, Debug] - exclude: - - BUILD_SHARED_LIBS: ON + include: + # OFF/ON: static lib + /MT (WebRTC on Release); wheel-like linkage + - BUILD_SHARED_LIBS: OFF + STATIC_RUNTIME: ON + device: cpu + CONFIG: Release + + # Debug /MT, tests, import + - BUILD_SHARED_LIBS: OFF + STATIC_RUNTIME: ON + device: cpu + CONFIG: Debug + + # SYCL, oneAPI install, tests, import + - BUILD_SHARED_LIBS: OFF STATIC_RUNTIME: ON - - BUILD_CUDA_MODULE: ON # FIXME + device: xpu + CONFIG: Release + + # Single Windows CUDA compile leg + - BUILD_SHARED_LIBS: OFF + STATIC_RUNTIME: ON + device: cuda + CONFIG: Release + + # ON/OFF: shared + /MD devel packages (cpu Debug -> *-dbg.zip) + - BUILD_SHARED_LIBS: ON + STATIC_RUNTIME: OFF + device: cpu + CONFIG: Release + + # Shared SYCL devel zip + - BUILD_SHARED_LIBS: ON + STATIC_RUNTIME: OFF + device: xpu + CONFIG: Release + + # open3d-devel-*-dbg.zip + - BUILD_SHARED_LIBS: ON + STATIC_RUNTIME: OFF + device: cpu CONFIG: Debug + + # OFF/OFF: static lib + /MD linkage smoke + - BUILD_SHARED_LIBS: OFF + STATIC_RUNTIME: OFF + device: cpu + CONFIG: Release env: + BUILD_CUDA_MODULE: ${{ matrix.device == 'cuda' && 'ON' || 'OFF' }} + BUILD_SYCL_MODULE: ${{ matrix.device == 'xpu' && 'ON' || 'OFF' }} BUILD_WEBRTC: ${{ ( matrix.BUILD_SHARED_LIBS == 'OFF' && matrix.STATIC_RUNTIME == 'ON' ) && 'ON' || 'OFF' }} - BUILD_PYTORCH_OPS: ${{ ( matrix.BUILD_CUDA_MODULE == 'ON' || matrix.CONFIG == 'Debug' ) && 'OFF' || 'ON' }} # FIXME + BUILD_PYTORCH_OPS: ${{ ( matrix.device == 'cuda' || matrix.device == 'xpu' || matrix.CONFIG == 'Debug' ) && 'OFF' || 'ON' }} # FIXME steps: - name: Disk space used run: Get-PSDrive - name: Install CUDA - if: ${{ matrix.BUILD_CUDA_MODULE == 'ON' }} + if: ${{ matrix.device == 'cuda' }} run: | # Define variables $CUDA_VER_FULL = "${{ env.CUDA_VERSION }}" @@ -96,6 +144,25 @@ jobs: echo "CUDA_PATH_V$CUDA_VER_ID=$CUDA_PATH" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append echo "$CUDA_PATH\bin" | Out-File -FilePath $Env:GITHUB_PATH -Encoding utf8 -Append + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Install Intel oneAPI + if: ${{ matrix.device == 'xpu' }} + shell: pwsh + working-directory: ${{ env.SRC_DIR }} + env: + OPEN3D_ONEAPI_DEBUG: ${{ env.OPEN3D_ONEAPI_DEBUG }} + run: ./util/install_oneapi_windows.ps1 + + - name: Debug oneAPI layout before CMake + if: ${{ matrix.device == 'xpu' }} + shell: pwsh + working-directory: ${{ env.SRC_DIR }} + env: + OPEN3D_ONEAPI_DEBUG: ${{ env.OPEN3D_ONEAPI_DEBUG }} + run: ./util/print_oneapi_windows_paths.ps1 + - name: Install glslang via vcpkg run: | vcpkg install glslang[tools]:x64-windows @@ -103,9 +170,6 @@ jobs: $glslangBinPath = Join-Path $env:VCPKG_INSTALLATION_ROOT "installed\x64-windows\tools\glslang" $glslangBinPath | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - name: Checkout source code - uses: actions/checkout@v4 - - name: Set up Python version uses: actions/setup-python@v5 with: @@ -120,9 +184,11 @@ jobs: - name: Install PyTorch requirements run: | - if ( '${{ matrix.BUILD_CUDA_MODULE }}' -eq 'ON' ) { + if ( '${{ matrix.device }}' -eq 'cuda' ) { # python -m pip install -r open3d_ml/requirements-torch-cuda.txt python -m pip install torch torchvision --index-url https://download.pytorch.org/whl/cu126 + } elseif ( '${{ matrix.device }}' -eq 'xpu' ) { + # No PyTorch requirement for SYCL (xpu) since PyTorch ops are disabled } else { python -m pip install -r open3d_ml/requirements-torch.txt } @@ -137,7 +203,37 @@ jobs: $Env:DEVELOPER_BUILD = "ON" } cmake --version - cmake -G "Visual Studio 17 2022" -A x64 ` + $CMAKE_ARGS = @() + if ('${{ matrix.device }}' -eq 'xpu') { + # Runs setvars.bat via cmd and imports + # all resulting env vars into the current PowerShell process. + Write-Host "Initializing oneAPI environment via setvars.bat..." + $setOutput = cmd /c '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && set 2>&1' + if ($LASTEXITCODE -ne 0) { throw "setvars.bat failed (exit $LASTEXITCODE)" } + $setOutput | ForEach-Object { + if ($_ -match '^([^=]+)=(.*)$') { + [System.Environment]::SetEnvironmentVariable($Matches[1], $Matches[2]) + } + } + $CMAKE_GENERATOR = "Ninja" + # On Windows, icx.exe (MSVC-compatible) handles C++ and SYCL (-fsycl). + # icpx.exe identifies as GNU-like in oneAPI 2025.3+ which conflicts with + # CMake generating MSVC-style flags when C compiler (icx) is MSVC-like. + $CMAKE_ARGS += "-DCMAKE_C_COMPILER=icx", "-DCMAKE_CXX_COMPILER=icx", ` + "-DCMAKE_BUILD_TYPE=${{ matrix.CONFIG }}" + if ($env:OPEN3D_ONEAPI_DEBUG -eq '1') { + Write-Host "OPEN3D_ONEAPI_DEBUG=1: enabling CMAKE_FIND_DEBUG_MODE and cmake --debug-find" + $CMAKE_ARGS += '-DCMAKE_FIND_DEBUG_MODE=ON' + } + } else { + $CMAKE_GENERATOR = "Visual Studio 17 2022" + $CMAKE_ARGS += "-A", "x64" + } + $cmakeExtraArgs = @() + if ($env:OPEN3D_ONEAPI_DEBUG -eq '1' -and '${{ matrix.device }}' -eq 'xpu') { + $cmakeExtraArgs += '--debug-find' + } + cmake -G $CMAKE_GENERATOR @CMAKE_ARGS @cmakeExtraArgs ` -DDEVELOPER_BUILD=$Env:DEVELOPER_BUILD ` -DBUILD_EXAMPLES=OFF ` -DCMAKE_INSTALL_PREFIX="$env:INSTALL_DIR" ` @@ -147,7 +243,8 @@ jobs: -DBUILD_LIBREALSENSE=ON ` -DBUILD_WEBRTC=${{ env.BUILD_WEBRTC }} ` -DBUILD_UNIT_TESTS=ON ` - -DBUILD_CUDA_MODULE=${{ matrix.BUILD_CUDA_MODULE }} ` + -DBUILD_CUDA_MODULE=${{ env.BUILD_CUDA_MODULE }} ` + -DBUILD_SYCL_MODULE=${{ env.BUILD_SYCL_MODULE }} ` -DBUILD_PYTORCH_OPS=${{ env.BUILD_PYTORCH_OPS }} ` ${{ env.SRC_DIR }} @@ -155,18 +252,23 @@ jobs: working-directory: ${{ env.BUILD_DIR }} run: | $ErrorActionPreference = 'Stop' - cmake --build . --parallel ${{ env.NPROC }} --config ${{ matrix.CONFIG }} ` - --target build-examples-iteratively - cmake --build . --parallel ${{ env.NPROC }} --config ${{ matrix.CONFIG }} ` - --target INSTALL + $buildArgs = @("--build", ".", "--parallel", "${{ env.NPROC }}") + if ('${{ matrix.device }}' -ne 'xpu') { + $buildArgs += "--config", "${{ matrix.CONFIG }}" + } + cmake @buildArgs --target build-examples-iteratively + cmake @buildArgs --target INSTALL - name: Package working-directory: ${{ env.BUILD_DIR }} - if: ${{ matrix.BUILD_SHARED_LIBS == 'ON' && matrix.BUILD_CUDA_MODULE == 'OFF' }} + if: ${{ matrix.BUILD_SHARED_LIBS == 'ON' && matrix.device != 'cuda' }} run: | $ErrorActionPreference = 'Stop' - cmake --build . --parallel ${{ env.NPROC }} --config ${{ matrix.CONFIG }} ` - --target package + $buildArgs = @("--build", ".", "--parallel", "${{ env.NPROC }}") + if ('${{ matrix.device }}' -ne 'xpu') { + $buildArgs += "--config", "${{ matrix.CONFIG }}" + } + cmake @buildArgs --target package if ("${{ matrix.CONFIG }}" -eq "Debug") { Get-ChildItem package/open3d-devel-*.zip | Rename-Item -NewName ` {$_.name -Replace '.zip','-dbg.zip'} @@ -182,7 +284,7 @@ jobs: subject-path: ${{ env.BUILD_DIR }}/package/${{ env.DEVEL_PKG_NAME }} - name: Upload Package - if: ${{ matrix.BUILD_SHARED_LIBS == 'ON' && matrix.BUILD_CUDA_MODULE == 'OFF' }} + if: ${{ matrix.BUILD_SHARED_LIBS == 'ON' && matrix.device != 'cuda' }} uses: actions/upload-artifact@v4 with: name: ${{ env.DEVEL_PKG_NAME }} @@ -190,7 +292,7 @@ jobs: if-no-files-found: error - name: Update devel release with package - if: ${{ github.ref == 'refs/heads/main' && matrix.BUILD_SHARED_LIBS == 'ON' && matrix.BUILD_CUDA_MODULE == 'OFF' }} + if: ${{ github.ref == 'refs/heads/main' && matrix.BUILD_SHARED_LIBS == 'ON' && matrix.device != 'cuda' }} env: GH_TOKEN: ${{ github.token }} shell: bash @@ -200,7 +302,7 @@ jobs: - name: Viewer App working-directory: ${{ env.BUILD_DIR }} - if: ${{ matrix.BUILD_SHARED_LIBS == 'OFF' && matrix.STATIC_RUNTIME == 'ON' && matrix.BUILD_CUDA_MODULE == 'OFF' && matrix.CONFIG == 'Release' }} + if: ${{ matrix.BUILD_SHARED_LIBS == 'OFF' && matrix.STATIC_RUNTIME == 'ON' && matrix.device == 'cpu' && matrix.CONFIG == 'Release' }} run: | $ErrorActionPreference = 'Stop' cmake --build . --parallel ${{ env.NPROC }} --config ${{ matrix.CONFIG }} ` @@ -222,7 +324,7 @@ jobs: subject-path: ${{ github.workspace }}/${{ env.VIEWER_ZIP_NAME }} - name: Upload Viewer - if: ${{ matrix.BUILD_SHARED_LIBS == 'OFF' && matrix.STATIC_RUNTIME == 'ON' && matrix.BUILD_CUDA_MODULE == 'OFF' && matrix.CONFIG == 'Release' }} + if: ${{ matrix.BUILD_SHARED_LIBS == 'OFF' && matrix.STATIC_RUNTIME == 'ON' && matrix.device == 'cpu' && matrix.CONFIG == 'Release' }} uses: actions/upload-artifact@v4 with: name: open3d-app-windows-amd64 @@ -230,31 +332,59 @@ jobs: if-no-files-found: error - name: Update devel release with viewer - if: ${{ github.ref == 'refs/heads/main' && matrix.BUILD_SHARED_LIBS == 'OFF' && matrix.STATIC_RUNTIME == 'ON' && matrix.BUILD_CUDA_MODULE == 'OFF' && matrix.CONFIG == 'Release' }} + if: ${{ github.ref == 'refs/heads/main' && matrix.BUILD_SHARED_LIBS == 'OFF' && matrix.STATIC_RUNTIME == 'ON' && matrix.device == 'cpu' && matrix.CONFIG == 'Release' }} env: GH_TOKEN: ${{ github.token }} run: | bash .github/workflows/update_release.sh "${{ env.VIEWER_ZIP_NAME }}" - name: Run C++ unit tests - if: ${{ matrix.BUILD_CUDA_MODULE == 'OFF' }} + if: ${{ matrix.device != 'cuda' }} working-directory: ${{ env.BUILD_DIR }} run: | echo "Add --gtest_random_seed=SEED to the test command to repeat this test sequence." - .\bin\${{ matrix.CONFIG }}\tests.exe --gtest_shuffle --gtest_filter=-*ReduceSum64bit2DCase0*:*ReduceSum64bit2DCase3* + $testExe = if ('${{ matrix.device }}' -eq 'xpu') { ".\bin\tests.exe" } else { ".\bin\${{ matrix.CONFIG }}\tests.exe" } + & $testExe --gtest_shuffle --gtest_filter=-*ReduceSum64bit2DCase0*:*ReduceSum64bit2DCase3* - name: Linking to Open3D working-directory: ${{ env.SRC_DIR }}/examples/cmake/open3d-cmake-find-package run: | $ErrorActionPreference = 'Stop' mkdir build cd build - cmake -G "Visual Studio 17 2022" -A x64 ` + $CMAKE_ARGS = @() + if ('${{ matrix.device }}' -eq 'xpu') { + # Initialize oneAPI environment in the same step as cmake (env vars + # don't persist across steps). Runs setvars.bat via cmd and imports + # all resulting env vars into the current PowerShell process. + Write-Host "Initializing oneAPI environment via setvars.bat..." + $setOutput = cmd /c '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && set 2>&1' + if ($LASTEXITCODE -ne 0) { throw "setvars.bat failed (exit $LASTEXITCODE)" } + $setOutput | ForEach-Object { + if ($_ -match '^([^=]+)=(.*)$') { + [System.Environment]::SetEnvironmentVariable($Matches[1], $Matches[2]) + } + } + $CMAKE_GENERATOR = "Ninja" + # On Windows, icx.exe (MSVC-compatible) handles C++ and SYCL (-fsycl). + # See Config step for the reason icpx is not used. + $CMAKE_ARGS += "-DCMAKE_C_COMPILER=icx", "-DCMAKE_CXX_COMPILER=icx", ` + "-DCMAKE_BUILD_TYPE=${{ matrix.CONFIG }}" + } else { + $CMAKE_GENERATOR = "Visual Studio 17 2022" + $CMAKE_ARGS += "-A", "x64" + } + cmake -G $CMAKE_GENERATOR @CMAKE_ARGS ` -DCMAKE_INSTALL_PREFIX="$env:INSTALL_DIR" ` -DSTATIC_WINDOWS_RUNTIME=${{ matrix.STATIC_RUNTIME }} ` .. - cmake --build . --config ${{ matrix.CONFIG }} - if ( '${{ matrix.BUILD_CUDA_MODULE }}' -eq 'OFF' ) { # FIXME - .\${{ matrix.CONFIG }}\Draw.exe --skip-for-unit-test + $buildArgs = @("--build", ".") + if ('${{ matrix.device }}' -ne 'xpu') { + $buildArgs += "--config", "${{ matrix.CONFIG }}" + } + cmake @buildArgs + if ( '${{ matrix.device }}' -ne 'cuda' ) { # FIXME + $drawExe = if ('${{ matrix.device }}' -eq 'xpu') { ".\Draw.exe" } else { ".\${{ matrix.CONFIG }}\Draw.exe" } + & $drawExe --skip-for-unit-test } Remove-Item -LiteralPath $env:INSTALL_DIR -Recurse -Force -ErrorAction SilentlyContinue - name: Install Open3D python build requirements @@ -267,13 +397,18 @@ jobs: working-directory: ${{ env.BUILD_DIR }} run: | $ErrorActionPreference = 'Stop' - cmake --build . --config ${{ matrix.CONFIG }} --target install-pip-package + $buildArgs = @("--build", ".", "--target", "install-pip-package") + if ('${{ matrix.device }}' -ne 'xpu') { + $buildArgs += "--config", "${{ matrix.CONFIG }}" + } + cmake @buildArgs - name: Import python package # If BUILD_SHARED_LIBS == ON, Open3D.dll needs to be copied, which is not recommended for python. - if: ${{ matrix.BUILD_SHARED_LIBS == 'OFF' && matrix.BUILD_CUDA_MODULE == 'OFF' }} # FIXME + if: ${{ matrix.BUILD_SHARED_LIBS == 'OFF' && matrix.device != 'cuda' }} # FIXME run: | python -c "import open3d; print('Imported:', open3d)" python -c "import open3d; print('CUDA enabled: ', open3d.core.cuda.is_available())" + python -c "import open3d; print('SYCL enabled: ', open3d.core.sycl.is_available() if hasattr(open3d.core, 'sycl') else False)" - name: Disk space used run: Get-PSDrive @@ -290,6 +425,7 @@ jobs: # 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', '3.12', '3.13', '3.14'] + device: [cpu, xpu] is_main: - ${{ github.ref == 'refs/heads/main' }} exclude: @@ -303,10 +439,31 @@ jobs: python_version: '3.13' env: - BUILD_PYTORCH_OPS: 'ON' + BUILD_CUDA_MODULE: 'OFF' + BUILD_SYCL_MODULE: ${{ matrix.device == 'xpu' && 'ON' || 'OFF' }} + BUILD_PYTORCH_OPS: ${{ matrix.device == 'xpu' && 'OFF' || 'ON' }} steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Install Intel oneAPI + if: ${{ matrix.device == 'xpu' }} + shell: pwsh + working-directory: ${{ env.SRC_DIR }} + env: + OPEN3D_ONEAPI_DEBUG: ${{ env.OPEN3D_ONEAPI_DEBUG }} + run: ./util/install_oneapi_windows.ps1 + + - name: Debug oneAPI layout before CMake + if: ${{ matrix.device == 'xpu' }} + shell: pwsh + working-directory: ${{ env.SRC_DIR }} + env: + OPEN3D_ONEAPI_DEBUG: ${{ env.OPEN3D_ONEAPI_DEBUG }} + run: ./util/print_oneapi_windows_paths.ps1 + - name: Install glslang via vcpkg run: | vcpkg install glslang[tools]:x64-windows @@ -314,9 +471,6 @@ jobs: $glslangBinPath = Join-Path $env:VCPKG_INSTALLATION_ROOT "installed\x64-windows\tools\glslang" $glslangBinPath | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - name: Checkout source code - uses: actions/checkout@v4 - - name: Checkout Open3D-ML uses: actions/checkout@v4 with: @@ -344,16 +498,46 @@ jobs: python -m pip install -U -r open3d_ml/requirements-torch.txt } - - name: Config + # Move build directory to C: https://github.com/actions/virtual-environments/issues/1341 run: | $ErrorActionPreference = 'Stop' - New-Item -Path ${{ env.BUILD_DIR }} -ItemType Directory - cd ${{ env.BUILD_DIR }} + New-Item -Path '${{ env.BUILD_DIR }}' -ItemType Directory + cd '${{ env.BUILD_DIR }}' if ($Env:DEVELOPER_BUILD -ne "OFF") { $Env:DEVELOPER_BUILD = "ON" } - cmake -G "Visual Studio 17 2022" -A x64 ` + cmake --version + $CMAKE_ARGS = @() + if ('${{ matrix.device }}' -eq 'xpu') { + # Runs setvars.bat via cmd and imports + # all resulting env vars into the current PowerShell process. + Write-Host "Initializing oneAPI environment via setvars.bat..." + $setOutput = cmd /c '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && set 2>&1' + if ($LASTEXITCODE -ne 0) { throw "setvars.bat failed (exit $LASTEXITCODE)" } + $setOutput | ForEach-Object { + if ($_ -match '^([^=]+)=(.*)$') { + [System.Environment]::SetEnvironmentVariable($Matches[1], $Matches[2]) + } + } + $CMAKE_GENERATOR = "Ninja" + # On Windows, icx.exe (MSVC-compatible) handles C++ and SYCL (-fsycl). + # See Config step for the reason icpx is not used. + $CMAKE_ARGS += "-DCMAKE_C_COMPILER=icx", "-DCMAKE_CXX_COMPILER=icx", ` + "-DCMAKE_BUILD_TYPE=Release" + if ($env:OPEN3D_ONEAPI_DEBUG -eq '1') { + Write-Host "OPEN3D_ONEAPI_DEBUG=1: enabling CMAKE_FIND_DEBUG_MODE and cmake --debug-find" + $CMAKE_ARGS += '-DCMAKE_FIND_DEBUG_MODE=ON' + } + } else { + $CMAKE_GENERATOR = "Visual Studio 17 2022" + $CMAKE_ARGS += "-A", "x64" + } + $cmakeExtraArgs = @() + if ($env:OPEN3D_ONEAPI_DEBUG -eq '1' -and '${{ matrix.device }}' -eq 'xpu') { + $cmakeExtraArgs += '--debug-find' + } + cmake -G $CMAKE_GENERATOR @CMAKE_ARGS @cmakeExtraArgs ` -DCMAKE_INSTALL_PREFIX="$env:INSTALL_DIR" ` -DDEVELOPER_BUILD="$Env:DEVELOPER_BUILD" ` -DBUILD_SHARED_LIBS=OFF ` @@ -363,6 +547,8 @@ jobs: -DBUILD_LIBREALSENSE=ON ` -DBUILD_WEBRTC=ON ` -DBUILD_JUPYTER_EXTENSION=ON ` + -DBUILD_CUDA_MODULE=${{ env.BUILD_CUDA_MODULE }} ` + -DBUILD_SYCL_MODULE=${{ env.BUILD_SYCL_MODULE }} ` -DBUILD_PYTORCH_OPS=${{ env.BUILD_PYTORCH_OPS }} ` ${{ env.SRC_DIR }} @@ -370,7 +556,11 @@ jobs: working-directory: ${{ env.BUILD_DIR }} run: | $ErrorActionPreference = 'Stop' - cmake --build . --parallel ${{ env.NPROC }} --config Release --target pip-package + $buildArgs = @("--build", ".", "--parallel", "${{ env.NPROC }}", "--target", "pip-package") + if ('${{ matrix.device }}' -ne 'xpu') { + $buildArgs += "--config", "Release" + } + cmake @buildArgs $PIP_PKG_NAME=(Get-ChildItem lib/python_package/pip_package/open3d*.whl).Name echo "PIP_PKG_NAME=$PIP_PKG_NAME" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append @@ -405,6 +595,7 @@ jobs: fail-fast: false matrix: python_version: ['3.10', '3.11', '3.12', '3.13', '3.14'] + device: [cpu, xpu, cuda] is_main: - ${{ github.ref == 'refs/heads/main' }} exclude: @@ -417,7 +608,7 @@ jobs: - is_main: false python_version: '3.13' env: - BUILD_PYTORCH_OPS: 'ON' + BUILD_PYTORCH_OPS: ${{ matrix.device == 'cpu' && 'ON' || 'OFF' }} steps: - name: Checkout source code uses: actions/checkout@v4 @@ -453,15 +644,21 @@ jobs: python -m pip install -U -r open3d_ml/requirements-torch.txt } $py_tag=(python -c "import sys; print(f'cp{sys.version_info.major}{sys.version_info.minor}')") - if (Test-Path -Path "pip_package") { - $PIP_PKG_NAME=(Get-ChildItem pip_package\open3d*-$py_tag-*.whl).Name + $search_dir = if (Test-Path -Path "pip_package") { "pip_package" } else { "." } + if ('${{ matrix.device }}' -eq 'xpu') { + $PIP_PKG_NAME=(Get-ChildItem (Join-Path $search_dir "open3d_xpu*-$py_tag-*.whl") -ErrorAction SilentlyContinue).Name } else { - $PIP_PKG_NAME=(Get-ChildItem open3d*-$py_tag-*.whl).Name + $PIP_PKG_NAME=(Get-ChildItem (Join-Path $search_dir "open3d-*-$py_tag-*.whl") -ErrorAction SilentlyContinue | Where-Object { $_.Name -notlike "open3d_xpu*" }).Name + } + if (-not $PIP_PKG_NAME) { + Write-Error "Could not find a valid Open3D wheel in $search_dir matching the python version $py_tag and device!" + exit 1 } echo "Installing Open3D wheel $PIP_PKG_NAME in virtual environment..." - python -m pip install "$PIP_PKG_NAME" + python -m pip install (Join-Path $search_dir $PIP_PKG_NAME) python -c "import open3d; print('Imported:', open3d)" python -c "import open3d; print('CUDA enabled: ', open3d.core.cuda.is_available())" + python -c "import open3d; print('SYCL enabled: ', open3d.core.sycl.is_available() if hasattr(open3d.core, 'sycl') else False)" deactivate - name: Run Python unit tests diff --git a/3rdparty/README_SYCL.md b/3rdparty/README_SYCL.md index 26549446616..bb04db44011 100644 --- a/3rdparty/README_SYCL.md +++ b/3rdparty/README_SYCL.md @@ -98,9 +98,15 @@ Open3D is designed to make use of the SYCL GPU devices. ## List of oneAPI Python packages -To make `pip install open3d` works out-of-the box on SYCL-enabled platforms, -we can utilize runtime libraries released via PyPI. This feature needs to be -implemented. +Open3D SYCL wheels declare a dependency on `dpcpp-cpp-rt` (see +`python/requirements_sycl.txt`). Pip installs the transitive Intel runtime +packages into the same Python environment. On Linux, ``pybind`` RPATH finds +``/lib``; on Windows, ``open3d/__init__.py`` registers +``site-packages/*.data/data/Library/bin`` with ``add_dll_directory``. + +Windows CI (xpu) installs build-time oneAPI from Intel Base + HPC webimages with +selective components only (``util/ci_install_oneapi_windows_sycl.ps1``, aligned +with `oneapi-ci `_). User: - https://pypi.org/user/IntelAutomationEngineering/ diff --git a/3rdparty/embree/embree.cmake b/3rdparty/embree/embree.cmake index 36df1b1db6b..9a86cf94526 100644 --- a/3rdparty/embree/embree.cmake +++ b/3rdparty/embree/embree.cmake @@ -65,7 +65,14 @@ endif() if(BUILD_SYCL_MODULE) - set(ISA_ARGS ${ISA_ARGS} -DCMAKE_CXX_COMPILER=icpx) + # On Windows, icx.exe (MSVC-compatible) handles C++ and SYCL (-fsycl). + # icpx.exe (GNU-like in oneAPI 2025.3+) conflicts with MSVC-style flags + # generated by CMake when using Ninja on Windows. + if(WIN32) + set(ISA_ARGS ${ISA_ARGS} -DCMAKE_CXX_COMPILER=icx) + else() + set(ISA_ARGS ${ISA_ARGS} -DCMAKE_CXX_COMPILER=icpx) + endif() set(ISA_ARGS ${ISA_ARGS} -DCMAKE_C_COMPILER=icx) set(ISA_ARGS ${ISA_ARGS} -DEMBREE_SYCL_SUPPORT=ON) list(APPEND ISA_LIBS embree4_sycl ze_wrapper) @@ -102,7 +109,6 @@ ExternalProject_Add( /${Open3D_INSTALL_LIB_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}sys${CMAKE_STATIC_LIBRARY_SUFFIX} /${Open3D_INSTALL_LIB_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}math${CMAKE_STATIC_LIBRARY_SUFFIX} /${Open3D_INSTALL_LIB_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}tasking${CMAKE_STATIC_LIBRARY_SUFFIX} - /${Open3D_INSTALL_LIB_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}ze_wrapper${CMAKE_STATIC_LIBRARY_SUFFIX} ${ISA_BUILD_BYPRODUCTS} ) diff --git a/3rdparty/find_dependencies.cmake b/3rdparty/find_dependencies.cmake index fb926d36ebb..385bd45e0c5 100644 --- a/3rdparty/find_dependencies.cmake +++ b/3rdparty/find_dependencies.cmake @@ -1617,7 +1617,12 @@ if(OPEN3D_USE_ONEAPI_PACKAGES) ) if (BUILD_SYCL_MODULE) # target_link_options(3rdparty_mkl INTERFACE "-Wl,-export-dynamic") - target_link_libraries(3rdparty_mkl INTERFACE OpenCL) + if (WIN32) + find_package(OpenCL REQUIRED) + target_link_libraries(3rdparty_mkl INTERFACE OpenCL::OpenCL) + else() + target_link_libraries(3rdparty_mkl INTERFACE OpenCL) + endif() endif() # MKL definitions target_compile_options(3rdparty_mkl INTERFACE "$<$:$<$:-m64>>") diff --git a/CMakeLists.txt b/CMakeLists.txt index 3283c8e8b21..d07954b59cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -301,8 +301,8 @@ if (BUILD_SYCL_MODULE AND NOT CMAKE_CXX_COMPILER_ID MATCHES "IntelLLVM") "but got CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID} " "and CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}.") endif() -if (BUILD_SYCL_MODULE AND (NOT UNIX OR APPLE)) - message(FATAL_ERROR "Open3D SYCL support is only available on Linux") +if (BUILD_SYCL_MODULE AND APPLE) + message(FATAL_ERROR "Open3D SYCL support is not available on Apple") endif() if(BUILD_SYCL_MODULE AND NOT GLIBCXX_USE_CXX11_ABI) message(FATAL_ERROR "BUILD_SYCL_MODULE=ON requires GLIBCXX_USE_CXX11_ABI=ON") diff --git a/cmake/Open3DPackaging.cmake b/cmake/Open3DPackaging.cmake index e6ce4a3c15c..b3531a5fcd5 100644 --- a/cmake/Open3DPackaging.cmake +++ b/cmake/Open3DPackaging.cmake @@ -26,6 +26,9 @@ endif() if (BUILD_CUDA_MODULE) set(_sys ${_sys}-cuda) endif() +if (BUILD_SYCL_MODULE) + set(_sys ${_sys}-sycl) +endif() if (NOT MSVC) set(CPACK_STRIP_FILES ON) # Don't strip MSVC Debug build endif() diff --git a/cpp/pybind/CMakeLists.txt b/cpp/pybind/CMakeLists.txt index 5a3d8b8893e..d46b68206ae 100644 --- a/cpp/pybind/CMakeLists.txt +++ b/cpp/pybind/CMakeLists.txt @@ -75,9 +75,9 @@ endif() # At `make`: open3d.so (or the equivalents) will be created at # PYTHON_COMPILED_MODULE_DIR. The default location is -# `build/lib/${CMAKE_BUILD_TYPE}/Python/{cpu|cuda}` +# `build/lib/${CMAKE_BUILD_TYPE}/Python/{cpu|cuda|xpu}` set(PYTHON_COMPILED_MODULE_DIR - "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/Python/$,cuda,cpu>") + "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/Python/$,cuda,$,xpu,cpu>>") if (UNIX AND NOT APPLE) # Use RPATH instead of RUNPATH in pybind so that needed libc++.so can find child dependant libc++abi.so in RPATH diff --git a/cpp/pybind/make_python_package.cmake b/cpp/pybind/make_python_package.cmake index aa4171414b0..384e05f7f04 100644 --- a/cpp/pybind/make_python_package.cmake +++ b/cpp/pybind/make_python_package.cmake @@ -23,7 +23,7 @@ foreach(COMPILED_MODULE_PATH ${COMPILED_MODULE_PATH_LIST}) get_filename_component(COMPILED_MODULE_NAME ${COMPILED_MODULE_PATH} NAME) get_filename_component(COMPILED_MODULE_ARCH_DIR ${COMPILED_MODULE_PATH} DIRECTORY) get_filename_component(COMPILED_MODULE_BASE_DIR ${COMPILED_MODULE_ARCH_DIR} DIRECTORY) - foreach(ARCH cpu cuda) + foreach(ARCH cpu cuda xpu) if(IS_DIRECTORY "${COMPILED_MODULE_BASE_DIR}/${ARCH}") file(INSTALL "${COMPILED_MODULE_BASE_DIR}/${ARCH}/" DESTINATION "${PYTHON_PACKAGE_DST_DIR}/open3d/${ARCH}" diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index cb8c4f31d30..761a586879e 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -52,11 +52,14 @@ endif() open3d_show_and_abort_on_warning(tests) open3d_set_global_properties(tests) # On Windows, running tests from the build folder needs tbb.dll to be in the same folder. +# Use the TBB::tbb namespaced target, since it exists both when TBB is built from +# source (bare "tbb" target, aliased to TBB::tbb) and when it's found via the oneAPI +# TBB package for SYCL builds (only TBB::tbb is defined, no bare "tbb" target). if (WIN32) add_custom_command( TARGET tests POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different $ "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$/" + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$/" ) endif() diff --git a/docs/sycl.rst b/docs/sycl.rst index d7737a9b106..540772c521c 100644 --- a/docs/sycl.rst +++ b/docs/sycl.rst @@ -6,7 +6,8 @@ Cross-platform GPU support (SYCL) From v0.19, Open3D provides an experimental SYCL backend for cross-platform GPU support. This backend allows Open3D operations to run on many different GPUs, including integrated GPUs and discrete GPUs from Intel, Nvidia and AMD. We -provide pre-built C++ binaries and Python wheels for Linux (Ubuntu 22.04+). +provide pre-built C++ binaries and Python wheels for Linux (Ubuntu 22.04+) and +Windows 10+. Enabled features ----------------- @@ -15,7 +16,7 @@ Many Tensor API operations and Tensor Geometry operations without custom kernels can now be offloaded to SYCL devices. In addition, HW accelerated raycasting queries in :py:class:`open3d.t.geometry.RayCastingScene` are also supported. You will get an error if an operation is not supported. The implementation is tested -on Linux on Intel integrated and discrete GPUs. Currently, a single GPU +on Linux and Windows on Intel integrated and discrete GPUs. Currently, a single GPU (`SYCL:0`, if available) and the CPU (`SYCL:1` if a GPU is available, else `SYCL:0`) are supported. @@ -30,7 +31,9 @@ and (optionally) SYCL runtime for your `Nvidia `_ GPU. For Python, the wheels will automatically install the DPC++ runtime package -(`dpcpp-cpp-rt`). Make sure to have the `correct drivers installed +(`dpcpp-cpp-rt`) into the same environment. On Windows, Open3D registers those +pip-installed DLL directories at import time (system-wide oneAPI runtimes are +not used). Make sure to have the `correct drivers installed `_ for your GPU. For raycasting on Intel GPUs, you will also need the `intel-level-zero-gpu-raytracing` package. @@ -48,6 +51,13 @@ raycasting on Intel GPUs, you will also need the - `Python 3.14 `__ - `C++ x86_64 `__ + * - Windows SYCL + - `Python 3.10 `__ + - `Python 3.11 `__ + - `Python 3.12 `__ + - `Python 3.13 `__ + - `Python 3.14 `__ + Usage ------ diff --git a/python/open3d/__init__.py b/python/open3d/__init__.py index 87608701d5c..d5e94f27119 100644 --- a/python/open3d/__init__.py +++ b/python/open3d/__init__.py @@ -16,6 +16,7 @@ import os import sys import re +import site os.environ["KMP_DUPLICATE_LIB_OK"] = "True" # Enable thread composability manager to coordinate Intel OpenMP and TBB threads. Only works with Intel OpenMP. @@ -27,8 +28,32 @@ import warnings from open3d._build_config import _build_config +_added_dll_dirs = [] if sys.platform == "win32": # Unix: Use rpath to find libraries _win32_dll_dir = os.add_dll_directory(str(Path(__file__).parent)) + # SYCL wheels depend on Intel DPC++ runtime packages (dpcpp-cpp-rt) installed + # in the same environment. Their DLLs live under site-packages/*.data/... + if _build_config["BUILD_SYCL_MODULE"]: + _intel_pip_dll_dirs = set() + _site_package_roots = [Path(_p) for _p in site.getsitepackages()] + _user_site = site.getusersitepackages() + if _user_site: + _site_package_roots.append(Path(_user_site)) + for _site_root in _site_package_roots: + if not _site_root.is_dir(): + continue + for _lib_bin in _site_root.glob("*.data/data/Library/bin"): + if not _lib_bin.is_dir(): + continue + _intel_pip_dll_dirs.add(_lib_bin) + for _child in _lib_bin.iterdir(): + if _child.is_dir(): + _intel_pip_dll_dirs.add(_child) + for _p in sorted(_intel_pip_dll_dirs): + try: + _added_dll_dirs.append(os.add_dll_directory(str(_p))) + except Exception: + pass __DEVICE_API__ = "cpu" if _build_config["BUILD_CUDA_MODULE"]: @@ -85,7 +110,7 @@ ) except OSError as os_error: warnings.warn( - f"Open3D was built with CUDA support, but an error ocurred while loading the Open3D CUDA Python bindings. This is usually because the CUDA libraries could not be found. Check your CUDA installation. Falling back to the CPU pybind library. Reported error: {os_error}.", + f"Open3D was built with CUDA support, but an error occurred while loading the Open3D CUDA Python bindings. This is usually because the CUDA libraries could not be found. Check your CUDA installation. Falling back to the CPU pybind library. Reported error: {os_error}.", ImportWarning, ) except StopIteration: @@ -96,6 +121,34 @@ ImportWarning, ) +if _build_config["BUILD_SYCL_MODULE"]: + try: + from open3d.xpu.pybind import ( + core, + camera, + data, + geometry, + io, + pipelines, + utility, + t, + ) + from open3d.xpu import pybind + + __DEVICE_API__ = "xpu" + except OSError as os_error: + warnings.warn( + f"Open3D was built with SYCL support, but an error occurred while loading the Open3D SYCL Python bindings. Ensure the DPC++ runtime (dpcpp-cpp-rt) is installed in this Python environment. Falling back to the CPU pybind library. Reported error: {os_error}.", + ImportWarning, + ) + except StopIteration: + warnings.warn( + "Open3D was built with SYCL support, but Open3D SYCL Python " + "binding library not found! Falling back to the CPU Python " + "binding library.", + ImportWarning, + ) + if __DEVICE_API__ == "cpu": from open3d.cpu.pybind import ( core, @@ -211,4 +264,6 @@ def _jupyter_nbextension_paths(): if sys.platform == "win32": _win32_dll_dir.close() + for _d in _added_dll_dirs: + _d.close() del os, sys, CDLL, find_library, Path, warnings, _insert_pybind_names diff --git a/python/open3d/ml/__init__.py b/python/open3d/ml/__init__.py index cf7342e0a27..66c0e11d713 100644 --- a/python/open3d/ml/__init__.py +++ b/python/open3d/ml/__init__.py @@ -9,6 +9,8 @@ import open3d as _open3d if _open3d.__DEVICE_API__ == 'cuda': from open3d.cuda.pybind.ml import * +elif _open3d.__DEVICE_API__ == 'xpu': + from open3d.xpu.pybind.ml import * else: from open3d.cpu.pybind.ml import * diff --git a/python/open3d/ml/contrib/__init__.py b/python/open3d/ml/contrib/__init__.py index b883e8024fd..3593e7d9a2a 100644 --- a/python/open3d/ml/contrib/__init__.py +++ b/python/open3d/ml/contrib/__init__.py @@ -8,5 +8,7 @@ import open3d as _open3d if _open3d.__DEVICE_API__ == 'cuda': from open3d.cuda.pybind.ml.contrib import * +elif _open3d.__DEVICE_API__ == 'xpu': + from open3d.xpu.pybind.ml.contrib import * else: from open3d.cpu.pybind.ml.contrib import * diff --git a/python/open3d/visualization/__init__.py b/python/open3d/visualization/__init__.py index cab0cad14ad..4edd59b1766 100644 --- a/python/open3d/visualization/__init__.py +++ b/python/open3d/visualization/__init__.py @@ -10,6 +10,10 @@ if open3d._build_config["BUILD_GUI"]: from open3d.cuda.pybind.visualization import gui from open3d.cuda.pybind.visualization import * +elif open3d.__DEVICE_API__ == "xpu": + if open3d._build_config["BUILD_GUI"]: + from open3d.xpu.pybind.visualization import gui + from open3d.xpu.pybind.visualization import * else: if open3d._build_config["BUILD_GUI"]: from open3d.cpu.pybind.visualization import gui diff --git a/util/install_oneapi_windows.ps1 b/util/install_oneapi_windows.ps1 new file mode 100644 index 00000000000..34da6fd7794 --- /dev/null +++ b/util/install_oneapi_windows.ps1 @@ -0,0 +1,94 @@ +#Requires -RunAsAdministrator +# Install Intel oneAPI C++ essentials for Windows SYCL (xpu) CI builds. +# Pattern from oneapi-src/oneapi-ci (2025.3.0 URLs @ 0804a4c): +# https://github.com/oneapi-src/oneapi-ci/tree/0804a4c9281440d8a91ac0680388b101e5f673ad +# +# Open3D uses the setvars.bat script to set up the oneAPI environment for icx (C +# and C++ compiler). VS 2022 integration is enabled for cmake -T Intel DPC++ toolset support. +param( + [switch]$Verbose +) + +$ErrorActionPreference = 'Stop' +if ($env:OPEN3D_ONEAPI_DEBUG -eq '1') { + $Verbose = $true +} + +# oneAPI 2025.3 offline webimages (oneapi-src/oneapi-ci @ 0804a4c9281440d8a91ac0680388b101e5f673ad) +$ONEAPI_BASEKIT_URL = "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/1f18901e-877d-469d-a41a-a10f11b39336/intel-oneapi-base-toolkit-2025.3.0.372.exe" + +# Default components: +$ONEAPI_WIN_BASE_COMPONENTS = @( + "intel.oneapi.win.cpp-dpcpp-common", + "intel.oneapi.win.tbb.devel", + "intel.oneapi.win.dpl", + "intel.oneapi.win.ipp.devel", + "intel.oneapi.win.mkl.devel" +) -join ":" + +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$PrintPathsScript = Join-Path $ScriptDir 'print_oneapi_windows_paths.ps1' + +$TempRoot = if ($env:RUNNER_TEMP) { $env:RUNNER_TEMP } else { $env:TEMP } +$WorkDir = Join-Path $TempRoot "open3d_oneapi_$([guid]::NewGuid().ToString('N'))" +$InstallLogArchive = Join-Path $TempRoot 'open3d_oneapi_install_logs' +New-Item -ItemType Directory -Force -Path $WorkDir | Out-Null +$InstallExitCode = 0 +Push-Location $WorkDir +try { + Write-Host "Downloading OneAPI webimage..." + curl.exe --output webimage.exe --url $ONEAPI_BASEKIT_URL --retry 5 --retry-delay 5 --fail + Write-Host "Extracting OneAPI webimage..." + $ExtractProc = Start-Process -FilePath ".\webimage.exe" -ArgumentList @( + "-s", "-x", "-f", "webimage_extracted", "--log", "extract.log" + ) -Wait -PassThru -NoNewWindow + if ($ExtractProc.ExitCode -ne 0) { + throw "OneAPI webimage extract failed with exit code $($ExtractProc.ExitCode)" + } + Remove-Item webimage.exe -Force + $Bootstrapper = Join-Path $WorkDir "webimage_extracted\bootstrapper.exe" + if (-not (Test-Path $Bootstrapper)) { + throw "bootstrapper.exe not found after extracting OneAPI webimage" + } + Write-Host "Installing OneAPI components: $ONEAPI_WIN_BASE_COMPONENTS" + if ($Verbose) { + Write-Host "Install work dir: $WorkDir" + Write-Host "NEED_VS2022_INTEGRATION=1 (required for cmake -T Intel DPC++ toolset)" + } + $InstallArgs = @( + "-s", "--action", "install", + "--components=$ONEAPI_WIN_BASE_COMPONENTS", + "--eula=accept", + "-p=NEED_VS2017_INTEGRATION=0", + "-p=NEED_VS2019_INTEGRATION=0", + "-p=NEED_VS2022_INTEGRATION=1", + "--log-dir=$WorkDir" + ) + $InstallProc = Start-Process -FilePath $Bootstrapper -ArgumentList $InstallArgs -Wait -PassThru -NoNewWindow + $InstallExitCode = $InstallProc.ExitCode + if ($InstallExitCode -ne 0) { + throw "OneAPI bootstrapper install failed with exit code $InstallExitCode" + } +} finally { + if ($Verbose -or $InstallExitCode -ne 0) { + if (Test-Path -LiteralPath $WorkDir) { + Write-Host "Archiving installer logs to $InstallLogArchive" + New-Item -ItemType Directory -Force -Path $InstallLogArchive | Out-Null + Copy-Item -Path (Join-Path $WorkDir '*') -Destination $InstallLogArchive -Recurse -Force -ErrorAction SilentlyContinue + Write-Host "See extract.log and installer logs under: $InstallLogArchive" + } + } + Pop-Location + Remove-Item -Recurse -Force $WorkDir -ErrorAction SilentlyContinue +} + +Write-Host "OneAPI bootstrapper reported success (exit code 0)." +if (Test-Path -LiteralPath $PrintPathsScript) { + if ($Verbose) { + & $PrintPathsScript -Verbose + } else { + & $PrintPathsScript + } +} else { + Write-Warning "Missing $PrintPathsScript" +} diff --git a/util/print_oneapi_windows_paths.ps1 b/util/print_oneapi_windows_paths.ps1 new file mode 100644 index 00000000000..af269a57967 --- /dev/null +++ b/util/print_oneapi_windows_paths.ps1 @@ -0,0 +1,139 @@ +# Print Intel oneAPI layout and CMake-related paths on Windows (CI debugging). +# Usage: ./util/print_oneapi_windows_paths.ps1 [-Verbose] +# Env: OPEN3D_ONEAPI_DEBUG=1 enables extra detail (same as -Verbose). +param( + [switch]$Verbose +) + +$ErrorActionPreference = 'Continue' +if ($env:OPEN3D_ONEAPI_DEBUG -eq '1') { + $Verbose = $true +} + +function Write-Section($Title) { + Write-Host "" + Write-Host "========== $Title ==========" +} + +function Test-PathReport($Label, $Path) { + $exists = Test-Path -LiteralPath $Path + $mark = if ($exists) { '[OK]' } else { '[MISSING]' } + Write-Host "$mark $Label" + Write-Host " $Path" + return $exists +} + +function Find-FirstFile($Roots, $Pattern) { + foreach ($root in $Roots) { + if (-not (Test-Path -LiteralPath $root)) { continue } + $hit = Get-ChildItem -LiteralPath $root -Recurse -Filter $Pattern -ErrorAction SilentlyContinue | + Select-Object -First 1 + if ($hit) { return $hit } + } + return $null +} + +$OneApiRoot = 'C:\Program Files (x86)\Intel\oneAPI' +$MklCmakeDir = Join-Path $OneApiRoot 'mkl\latest\lib\cmake\mkl' +$TbbRoot = Join-Path $OneApiRoot 'tbb\latest' +$CompilerLatest = Join-Path $OneApiRoot 'compiler\latest' + +Write-Section 'oneAPI environment variables' +foreach ($name in @( + 'ONEAPI_ROOT', 'MKLROOT', 'TBBROOT', 'CMPLR_ROOT', 'DPL_ROOT', 'IPP_ROOT', + 'CMAKE_PREFIX_PATH', 'PATH' + )) { + $val = [Environment]::GetEnvironmentVariable($name, 'Process') + if (-not $val) { $val = [Environment]::GetEnvironmentVariable($name, 'Machine') } + if (-not $val) { $val = [Environment]::GetEnvironmentVariable($name, 'User') } + if ($name -eq 'PATH' -and $val) { + Write-Host "${name}: (length $($val.Length); use -Verbose for Intel entries)" + if ($Verbose) { + $val -split ';' | Where-Object { $_ -match 'Intel|oneAPI|icx' } | ForEach-Object { Write-Host " $_" } + } + } elseif ($val) { + Write-Host "${name}=$val" + } else { + Write-Host "${name}=" + } +} + +Write-Section 'oneAPI install tree (Open3D SYCL expectations)' +Test-PathReport 'oneAPI root' $OneApiRoot | Out-Null +Test-PathReport 'MKLConfig.cmake dir' $MklCmakeDir | Out-Null +Test-PathReport 'TBB package root (CMAKE_PREFIX_PATH)' $TbbRoot | Out-Null +Test-PathReport 'DPC++ compiler latest symlink' $CompilerLatest | Out-Null + +$mklConfig = Join-Path $MklCmakeDir 'MKLConfig.cmake' +Test-PathReport 'MKLConfig.cmake' $mklConfig | Out-Null +$tbbConfig = Join-Path $TbbRoot 'lib\cmake\tbb\TBBConfig.cmake' +Test-PathReport 'TBBConfig.cmake' $tbbConfig | Out-Null + +$icx = Join-Path $CompilerLatest 'bin\icx.exe' +Test-PathReport 'icx.exe' $icx | Out-Null + +Write-Section 'OpenCL (Windows SYCL / mkl_sycl link)' +$openClLib = Find-FirstFile @($CompilerLatest) 'OpenCL.lib' +if ($openClLib) { + Write-Host '[OK] OpenCL.lib' + Write-Host " $($openClLib.FullName)" + $incCandidate = Join-Path $openClLib.Directory.Parent.FullName 'include' + Test-PathReport 'OpenCL include (parent/include)' $incCandidate | Out-Null +} else { + Write-Host '[MISSING] OpenCL.lib under compiler\latest' + Write-Host " Search root: $CompilerLatest" +} + +Write-Section 'Visual Studio Intel DPC++ platform toolset (cmake -T)' +$vsRoots = @( + Join-Path $env:ProgramFiles 'Microsoft Visual Studio' + Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio' +) +$toolsetProps = $null +foreach ($vsRoot in $vsRoots) { + if (-not (Test-Path -LiteralPath $vsRoot)) { continue } + $toolsetProps = Get-ChildItem -LiteralPath $vsRoot -Recurse -ErrorAction SilentlyContinue | + Where-Object { + $_.Name -eq 'Toolset.props' -and + $_.FullName -match '\\PlatformToolsets\\Intel\(R\) oneAPI DPC\+\+ Compiler\\' + } | + Select-Object -First 1 + if ($toolsetProps) { break } +} +if ($toolsetProps) { + Write-Host '[OK] Intel(R) oneAPI DPC++ Compiler Toolset.props' + Write-Host " $($toolsetProps.FullName)" +} else { + Write-Host '[MISSING] Platform toolset Toolset.props (CMake -T may fail at build with MSB8020)' + foreach ($vsRoot in $vsRoots) { + Write-Host " Searched under: $vsRoot" + } +} + +Write-Section 'Suggested CMake configure hints (windows.yml xpu legs)' +Write-Host '-T "Intel(R) oneAPI DPC++ Compiler"' +Write-Host "-DCMAKE_PREFIX_PATH=$MklCmakeDir;$TbbRoot" +if ($openClLib) { + $oclLib = $openClLib.FullName.Replace('\', '/') + $oclInc = (Join-Path $openClLib.Directory.Parent.FullName 'include').Replace('\', '/') + Write-Host "-DOpenCL_LIBRARY=$oclLib" + Write-Host "-DOpenCL_INCLUDE_DIR=$oclInc" +} else { + Write-Host '-DOpenCL_LIBRARY=' +} + +if ($Verbose) { + Write-Section 'Directory listing (verbose)' + foreach ($sub in @('compiler', 'mkl', 'tbb', 'dpl', 'ipp')) { + $p = Join-Path $OneApiRoot $sub + if (Test-Path -LiteralPath $p) { + Write-Host "--- $p ---" + Get-ChildItem -LiteralPath $p -ErrorAction SilentlyContinue | ForEach-Object { Write-Host " $($_.Name)" } + } + } +} + +Write-Section 'setvars (optional alternative to CMAKE_PREFIX_PATH)' +$setvars = Join-Path $OneApiRoot 'setvars-vcvarsall.bat' +Test-PathReport 'setvars-vcvarsall.bat' $setvars | Out-Null +Write-Host 'Local builds often run: cmd /c "setvars-vcvarsall.bat" vs2022 before cmake.'