diff --git a/.github/scripts/build-xpu-windows.bat b/.github/scripts/build-xpu-windows.bat index 02d281d6e..044d94662 100644 --- a/.github/scripts/build-xpu-windows.bat +++ b/.github/scripts/build-xpu-windows.bat @@ -1,4 +1,9 @@ -set INTEL_DLE_URL=https://registrationcenter-download.intel.com/akdlm/IRC_NAS/75d4eb97-914a-4a95-852c-7b9733d80f74/intel-deep-learning-essentials-2025.1.3.8_offline.exe +if "%ONEAPI_VERSION%"=="2025" set INTEL_DLE_URL=https://registrationcenter-download.intel.com/akdlm/IRC_NAS/75d4eb97-914a-4a95-852c-7b9733d80f74/intel-deep-learning-essentials-2025.1.3.8_offline.exe +if "%ONEAPI_VERSION%"=="2026" set INTEL_DLE_URL=https://registrationcenter-download.intel.com/akdlm/IRC_NAS/d2148e15-b3c4-4313-afa9-a2373318b0b5/intel-deep-learning-essentials-2026.0.0.613_offline.exe +if "%INTEL_DLE_URL%"=="" ( + echo Unsupported ONEAPI_VERSION: "%ONEAPI_VERSION%" + exit /b 1 +) set INTEL_DLE_TMP=%RUNNER_TEMP%\intel_dle set INTEL_DLE_LOG=%RUNNER_TEMP%\intel_dle_log.txt diff --git a/.github/scripts/build-xpu.sh b/.github/scripts/build-xpu.sh index 5683ff3fb..7b72c349c 100755 --- a/.github/scripts/build-xpu.sh +++ b/.github/scripts/build-xpu.sh @@ -2,11 +2,17 @@ set -xeuo pipefail : "${RUNNER_OS:?RUNNER_OS must be set (Linux/Windows)}" +: "${ONEAPI_VERSION:?ONEAPI_VERSION must be set (2025/2026)}" + +case "${ONEAPI_VERSION}" in + 2025) image=intel/deep-learning-essentials:2025.1.3-0-devel-ubuntu22.04 ;; + 2026) image=intel/deep-learning-essentials:2026.0.0-devel-ubuntu22.04 ;; + *) echo "Unsupported ONEAPI_VERSION: ${ONEAPI_VERSION}"; exit 1 ;; +esac # We currently only build XPU on Linux x64 and Windows x64. if [ "${RUNNER_OS}" == "Linux" ]; then # TODO: We might want to pre-build this as our own customized image in the future. - image=intel/deep-learning-essentials:2025.1.3-0-devel-ubuntu22.04 echo "Using image $image" docker run --rm -i \ -w /src -v "$PWD:/src" "$image" sh -c \ diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 4d28f821f..e4464b825 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -94,28 +94,35 @@ jobs: build-xpu: strategy: + fail-fast: false matrix: os: [ubuntu-22.04, windows-2022] + oneapi_version: ["2025", "2026"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Build C++ (Linux) if: runner.os == 'Linux' run: bash .github/scripts/build-xpu.sh + env: + ONEAPI_VERSION: ${{ matrix.oneapi_version }} - name: Build C++ (Windows) if: runner.os == 'Windows' run: .github/scripts/build-xpu-windows.bat shell: cmd + env: + ONEAPI_VERSION: ${{ matrix.oneapi_version }} - name: Upload build artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: shared_library_xpu_${{ runner.os }}_${{ runner.arch }} + name: shared_library_xpu_${{ runner.os }}_${{ runner.arch }}_${{ matrix.oneapi_version }} path: output/* retention-days: 7 if-no-files-found: error build-rocm: strategy: + fail-fast: false matrix: os: [ubuntu-22.04] rocm_version: ["6.2.4", "6.3.4", "6.4.4", "7.0.2", "7.1.1", "7.2.4"] diff --git a/CMakeLists.txt b/CMakeLists.txt index 65f8347a4..2834b4312 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -333,13 +333,29 @@ elseif(BUILD_MPS) add_custom_target(metallib DEPENDS "bitsandbytes/bitsandbytes.metallib") elseif(BUILD_XPU) list(APPEND SRC_FILES ${XPU_FILES}) - string(APPEND BNB_OUTPUT_NAME "_xpu") add_compile_definitions(BUILD_XPU) set(CMAKE_C_COMPILER icx) set(CMAKE_CXX_COMPILER icpx) if(WIN32) set(CMAKE_CXX_COMPILER icx) endif() + + # Get the oneAPI year (2025, 2026, ...) so we can name the library with it. + execute_process( + COMMAND ${CMAKE_CXX_COMPILER} --version + OUTPUT_VARIABLE _XPU_COMPILER_VERSION_OUTPUT + ERROR_VARIABLE _XPU_COMPILER_VERSION_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + string(REGEX MATCH "20[0-9][0-9]" XPU_VERSION "${_XPU_COMPILER_VERSION_OUTPUT}") + + if(XPU_VERSION) + message(STATUS "XPU oneAPI Version: ${XPU_VERSION}") + string(APPEND BNB_OUTPUT_NAME "_xpu${XPU_VERSION}") + else() + message(WARNING "Could not detect oneAPI version from icpx; building unversioned libbitsandbytes_xpu.") + string(APPEND BNB_OUTPUT_NAME "_xpu") + endif() else() string(APPEND BNB_OUTPUT_NAME "_cpu") set(GPU_SOURCES) diff --git a/bitsandbytes/cextension.py b/bitsandbytes/cextension.py index 6f0a0916b..e234f20d3 100644 --- a/bitsandbytes/cextension.py +++ b/bitsandbytes/cextension.py @@ -331,6 +331,20 @@ def __getitem__(self, name): return self.__getattr__(name) +def get_xpu_bnb_library_path() -> Path: + """Get the path to the XPU native library matching the oneAPI toolchain. + + Prefers the versioned library (e.g. libbitsandbytes_xpu2026) matching the first + 4 digits of torch.version.xpu, falling back to an unversioned libbitsandbytes_xpu. + """ + xpu_version = getattr(torch.version, "xpu", None) + if xpu_version: + versioned = PACKAGE_DIR / f"libbitsandbytes_xpu{xpu_version[:4]}{DYNAMIC_LIBRARY_SUFFIX}" + if versioned.exists(): + return versioned + return PACKAGE_DIR / f"libbitsandbytes_xpu{DYNAMIC_LIBRARY_SUFFIX}" + + def get_native_library() -> BNBNativeLibrary: """ Load CUDA library XOR CPU, as the latter contains a subset of symbols of the former. @@ -347,7 +361,7 @@ def get_native_library() -> BNBNativeLibrary: binary_path = cuda_binary_path if torch._C._has_xpu: - binary_path = PACKAGE_DIR / f"libbitsandbytes_xpu{DYNAMIC_LIBRARY_SUFFIX}" + binary_path = get_xpu_bnb_library_path() logger.debug(f"Loading bitsandbytes native library from: {binary_path}")