From 83dc12e8d9941182c3515d27cec6f01f243e8636 Mon Sep 17 00:00:00 2001 From: Aleksander Wennersteen Date: Sun, 20 Sep 2026 20:51:02 +0200 Subject: [PATCH 01/11] Update Numba dependency and test matrix to 0.66 Numba 0.66 selects llvmlite 0.48 and LLVM 22. This dependency change must land with the following LLVM 22 compiler and runtime update; it is not validated as a standalone release. Assisted-by: Codex --- .github/workflows/build-upload-wheels.yml | 7 +------ buildscripts/conda-recipes/pyomp/meta.yaml | 4 ++-- buildscripts/modal/test_gpu.py | 2 +- pyproject.toml | 2 +- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-upload-wheels.yml b/.github/workflows/build-upload-wheels.yml index 6a91fcd25b2e..99a4d9cdfb47 100644 --- a/.github/workflows/build-upload-wheels.yml +++ b/.github/workflows/build-upload-wheels.yml @@ -85,12 +85,7 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, ubuntu-24.04-arm] python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] - numba-version: ['0.62.0', '0.62.1', '0.63.0', '0.63.1'] - exclude: - - python-version: '3.14' - numba-version: '0.62.0' - - python-version: '3.14' - numba-version: '0.62.1' + numba-version: ['0.66.0'] steps: - name: Download built wheels diff --git a/buildscripts/conda-recipes/pyomp/meta.yaml b/buildscripts/conda-recipes/pyomp/meta.yaml index 0c689c90fea6..85d31c4f619a 100644 --- a/buildscripts/conda-recipes/pyomp/meta.yaml +++ b/buildscripts/conda-recipes/pyomp/meta.yaml @@ -45,7 +45,7 @@ requirements: - sysroot_linux-aarch64 # [aarch64] - setuptools - setuptools_scm - - numba >=0.62, <0.64 + - numba >=0.66, <0.67 - clang {{ LLVM_VERSION }} - clangxx {{ LLVM_VERSION }} - clang-tools {{ LLVM_VERSION }} @@ -59,7 +59,7 @@ requirements: run: - python - setuptools - - numba >=0.62, <0.64 + - numba >=0.66, <0.67 # require llvm-openmp for the openmp cpu runtime. - llvm-openmp 21.1.8.* # [osx] - llvm-openmp {{ LLVM_VERSION }} # [not osx] diff --git a/buildscripts/modal/test_gpu.py b/buildscripts/modal/test_gpu.py index b01a55e94d6a..5b7d6d1c2a09 100644 --- a/buildscripts/modal/test_gpu.py +++ b/buildscripts/modal/test_gpu.py @@ -8,7 +8,7 @@ PYTHON_VERSIONS = ("3.10", "3.11", "3.12", "3.13", "3.14") -NUMBA_VERSION = "0.63.1" +NUMBA_VERSION = "0.66.0" MINIFORGE_VERSION = "26.3.2-3" MINIFORGE_SHA256 = "848194851a98903134187fbb4ab50efe87b003e0c0f808f97644b7524a62bf2c" WHEEL_DIRECTORY = ( diff --git a/pyproject.toml b/pyproject.toml index 5069c16cff2a..1d1366f3e3f3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ classifiers = [ "Intended Audience :: Developers", "Topic :: Software Development :: Compilers", ] -dependencies = ["numba>=0.62, <0.64", "lark", "cffi", "setuptools"] +dependencies = ["numba>=0.66, <0.67", "lark", "cffi", "setuptools"] maintainers = [ { name = "Giorgis Georgakoudis", email = "georgakoudis1@llnl.gov" }, ] From 76509d9eed1274570e637c19bfd8413cd762974f Mon Sep 17 00:00:00 2001 From: Aleksander Wennersteen Date: Sun, 20 Sep 2026 20:51:14 +0200 Subject: [PATCH 02/11] Build the OpenMP pass and runtimes with LLVM 22.1.8 Adapt OpenMPIRBuilder configuration, reduction and target arguments, plugin headers, and the GPU parallel runtime ABI. Port the runtime patches and build the relocated GPU device bitcode separately. Update LLVM build pins and document the tested platform limits. Validated together with Numba 0.66: 120 host tests, 68 mandatory host-offload tests, and four mandatory RTX 3080 offload tests passed. The full GPU suite and other platforms remain unverified. Assisted-by: Codex --- .github/workflows/build-upload-wheels.yml | 4 +- README.md | 10 + buildscripts/conda-recipes/pyomp/meta.yaml | 10 +- docs/source/installation.rst | 59 ++++++ docs/source/openmp.rst | 8 +- pyproject.toml | 2 +- setup.py | 23 ++- .../22.1.8/0002-Link-statically-LLVM.patch | 20 ++ .../22.1.8/0003-Do-not-build-liboffload.patch | 10 + .../0004-Add-getter-for-device-info.patch | 171 ++++++++++++++++++ .../openmp/libs/pass/CGIntrinsicsOpenMP.cpp | 26 ++- .../openmp/libs/pass/CGIntrinsicsOpenMP.h | 6 +- .../openmp/libs/pass/IntrinsicsOpenMP.cpp | 4 + 13 files changed, 337 insertions(+), 16 deletions(-) create mode 100644 src/numba/openmp/libs/openmp/patches/22.1.8/0002-Link-statically-LLVM.patch create mode 100644 src/numba/openmp/libs/openmp/patches/22.1.8/0003-Do-not-build-liboffload.patch create mode 100644 src/numba/openmp/libs/openmp/patches/22.1.8/0004-Add-getter-for-device-info.patch diff --git a/.github/workflows/build-upload-wheels.yml b/.github/workflows/build-upload-wheels.yml index 99a4d9cdfb47..679d56233117 100644 --- a/.github/workflows/build-upload-wheels.yml +++ b/.github/workflows/build-upload-wheels.yml @@ -52,7 +52,7 @@ jobs: # Set LLVM_VERSION for the host to forward to the cibuildwheel # environment. env: - LLVM_VERSION: "20.1.8" + LLVM_VERSION: "22.1.8" run: python -m cibuildwheel --output-dir wheelhouse - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 @@ -69,7 +69,7 @@ jobs: - name: Build sdist env: - LLVM_VERSION: "20.1.8" + LLVM_VERSION: "22.1.8" run: pipx run build --sdist - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 diff --git a/README.md b/README.md index cc12e95f8157..15b68ef678fd 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,16 @@ PyOMP is also distributed through Conda, installable using the following command conda install -c python-for-hpc -c conda-forge pyomp ``` +### LLVM 22 development branch + +This branch targets Numba 0.66.x and llvmlite 0.48.x with LLVM 22.1.8. +It is a source port, not a published PyOMP release. Linux x86_64 CPU execution +and host-device offload are tested with Python 3.12. Four basic NVIDIA GPU +offload tests also pass on an RTX 3080 with CUDA 12.8 tools. The full GPU suite, +other GPUs, macOS, Linux ARM64, and the wider Python CI matrix remain unverified. +See [source build and validation instructions](docs/source/installation.rst). +The released-version compatibility table below remains historical. + ### Compatibility matrix | PyOMP | Numba | diff --git a/buildscripts/conda-recipes/pyomp/meta.yaml b/buildscripts/conda-recipes/pyomp/meta.yaml index 85d31c4f619a..fdd5deebffed 100644 --- a/buildscripts/conda-recipes/pyomp/meta.yaml +++ b/buildscripts/conda-recipes/pyomp/meta.yaml @@ -1,5 +1,5 @@ {% set version = environ.get('GIT_DESCRIBE_TAG', '0.0.0').lstrip('v') %} -{% set LLVM_VERSION = environ.get('LLVM_VERSION', '20.1.8') %} +{% set LLVM_VERSION = environ.get('LLVM_VERSION', '22.1.8') %} {% set LLVM_VERSION_MAJOR = LLVM_VERSION.split('.')[0] %} {% set LLVM_VERSION_MINOR = LLVM_VERSION.split('.')[1] %} @@ -34,6 +34,7 @@ requirements: - sysroot_linux-aarch64 # [aarch64] - cmake - ninja + - patch # [linux] - setuptools_scm - elfutils # [linux] - libffi # [linux] @@ -50,10 +51,10 @@ requirements: - clangxx {{ LLVM_VERSION }} - clang-tools {{ LLVM_VERSION }} - llvmdev {{ LLVM_VERSION }} + - lld {{ LLVM_VERSION }} # [linux] - zlib # require llvm-openmp for the openmp cpu runtime. - - llvm-openmp 21.1.8.* # [osx] - - llvm-openmp {{ LLVM_VERSION }} # [not osx] + - llvm-openmp {{ LLVM_VERSION }} - elfutils # [linux] - libffi # [linux] run: @@ -61,8 +62,7 @@ requirements: - setuptools - numba >=0.66, <0.67 # require llvm-openmp for the openmp cpu runtime. - - llvm-openmp 21.1.8.* # [osx] - - llvm-openmp {{ LLVM_VERSION }} # [not osx] + - llvm-openmp {{ LLVM_VERSION }} - lark - cffi diff --git a/docs/source/installation.rst b/docs/source/installation.rst index c7fdfae5b35c..650aac217b52 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -31,6 +31,65 @@ supported. | 0.3.x | 0.57.x - 0.60.x | +--------+---------------------+ +LLVM 22 source build +-------------------- + +The LLVM 22 development branch requires Numba 0.66.x (llvmlite 0.48.x). +Build with Clang and LLVM development libraries version 22.1.8, including +LLVM's NVPTX and AMDGPU targets and the LLVM linker tools. On Linux, install +the libffi and libelf development headers and the ``patch`` utility as well. +Use an isolated environment: + +.. code-block:: console + + $ python3 -m venv .venv22 + $ . .venv22/bin/activate + $ pip install setuptools setuptools-scm wheel cmake ninja 'numba==0.66.0' lark cffi + $ export LLVM_VERSION=22.1.8 LLVM_DIR=$(llvm-config --cmakedir) + $ export CC=clang CXX=clang++ CMAKE_BUILD_PARALLEL_LEVEL=4 + $ export ENABLE_BUNDLED_LIBOMP=1 ENABLE_BUNDLED_LIBOMPTARGET=1 + $ pip wheel --no-build-isolation --no-deps . -w dist + $ pip install --no-deps dist/pyomp-*.whl + $ RUN_TARGET=0 python -m numba.runtests -v -- numba.openmp.tests.test_openmp + $ OMP_TARGET_OFFLOAD=mandatory TEST_DEVICE=host RUN_TARGET=1 python -m numba.runtests -v -- numba.openmp.tests.test_openmp.TestOpenmpTarget + +The build downloads LLVM sources and applies the versioned runtime patches. +LLVM 22 builds GPU device bitcode separately from libomptarget; both NVPTX +and AMDGPU bitcode are included in the Linux wheel. Set +``ENABLE_BUNDLED_LIBOMP=0`` when using an existing LLVM OpenMP runtime, as in +the Conda recipe. ``CMAKE_BUILD_PARALLEL_LEVEL`` controls build concurrency. + +Validation is limited to Linux x86_64 with Python 3.12, Numba 0.66.0, +llvmlite 0.48.0 (LLVM 22.1.0), and Clang/runtime 22.1.8. The host suite +ran 235 tests with 120 passing and 115 existing skips, including disabled +target tests and unsupported clauses. The separate mandatory host-device run +ran 72 tests with 68 passing and 4 existing skips. +Four basic GPU tests also pass on an NVIDIA RTX 3080 (sm_86), driver 595.84, +using CUDA 12.8.93 compiler tools: teams/distribute/parallel-for, tofrom +mapping, explicit updates, and a parallel reduction. These use mandatory +offload and select the NVIDIA device; CPU fallback is not counted as success. +The full GPU suite, other GPUs (including Blackwell), CUDA 13 compiler tools, +macOS, Linux ARM64, Conda packages, and the wider Python CI matrix remain +unverified. +This update does not add target ``nowait``/``depend`` support. + +To repeat the basic NVIDIA checks with an installed wheel, expose the NVIDIA +driver to the process and provide CUDA compiler tools. The isolated test +used NVIDIA's pip package with the following paths: + +.. code-block:: console + + $ pip install nvidia-cuda-nvcc-cu12==12.8.93 + $ export CUDA_HOME="$VIRTUAL_ENV/lib/python3.12/site-packages/nvidia/cuda_nvcc" + $ export PATH="$CUDA_HOME/bin:$PATH" + $ export LD_LIBRARY_PATH="$CUDA_HOME/nvvm/lib64${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" + $ export OMP_TARGET_OFFLOAD=mandatory TEST_DEVICE=gpu RUN_TARGET=1 + $ python -m numba.runtests -v -- \ + numba.openmp.tests.test_openmp.TestOpenmpTarget.test_target_teams_distribute_parallel_for \ + numba.openmp.tests.test_openmp.TestOpenmpTarget.test_target_data_tofrom \ + numba.openmp.tests.test_openmp.TestOpenmpTarget.test_target_update_to_from \ + numba.openmp.tests.test_openmp.TestOpenmpTarget.test_target_teams_distribute_parallel_for_reduction + Additional options ------------------ diff --git a/docs/source/openmp.rst b/docs/source/openmp.rst index 4dd05db54d07..ebb1dcb6201b 100644 --- a/docs/source/openmp.rst +++ b/docs/source/openmp.rst @@ -348,7 +348,13 @@ Once you have identified a device ID, you can use it in OpenMP target directives Version and platform support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The following table shows tested combinations of PyOMP, Numba, Python, LLVM, and supported platforms: +The LLVM 22 development branch targets Numba 0.66.x and llvmlite 0.48.x. +Local validation covers Linux x86_64, Python 3.12, CPU parallelism, and +mandatory host-device offload. Four basic GPU tests pass on an NVIDIA RTX 3080 +with CUDA 12.8 tools; the full GPU suite and other platforms remain unverified +for this branch. See :doc:`installation` for build and GPU test details. + +The following table describes released versions of PyOMP: .. table:: :widths: auto diff --git a/pyproject.toml b/pyproject.toml index 1d1366f3e3f3..e95f5abf5ed7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,7 +57,7 @@ PIP_NO_INPUT = "1" [tool.cibuildwheel.linux] before-all = [ - "yum install -y elfutils-libelf-devel libffi-devel clang-devel-20.1.8 llvm-devel-20.1.8", + "yum install -y elfutils-libelf-devel libffi-devel clang-devel-22.1.8 llvm-devel-22.1.8 lld-22.1.8 patch", ] [tool.cibuildwheel.linux.environment] diff --git a/setup.py b/setup.py index 9bb623935421..351c3d92753b 100644 --- a/setup.py +++ b/setup.py @@ -84,6 +84,10 @@ def _build_cmake(self, ext: CMakeExtension): lib_dir = Path(self.build_lib) / "numba/openmp/libs" extra_cmake_args = self._env_toolchain_args(ext) + if ext.name.startswith("libompdevice-"): + extra_cmake_args.append( + f"-DLLVM_LIBRARY_OUTPUT_INTDIR={build_dir.absolute() / 'lib'}" + ) # Set RPATH. if sys.platform.startswith("linux"): extra_cmake_args.append(r"-DCMAKE_INSTALL_RPATH=$ORIGIN") @@ -116,7 +120,7 @@ def _build_cmake(self, ext: CMakeExtension): print("Build at dir ", build_dir) subprocess.run( - ["cmake", "--build", build_dir, "-j"], check=True, stdin=subprocess.DEVNULL + ["cmake", "--build", build_dir], check=True, stdin=subprocess.DEVNULL ) print("Install at dir ", install_dir) subprocess.run( @@ -359,6 +363,7 @@ def _check_true(env_var): cmake_args=[ "-DOPENMP_STANDALONE_BUILD=ON", "-DLLVM_ENABLE_RUNTIMES=offload", + "-DLLVM_INCLUDE_TESTS=OFF", # Avoid conflicts in manylinux builds with packaged clang/llvm # under /usr/include and its gcc-toolset provided header files. "-DCMAKE_NO_SYSTEM_FROM_IMPORTED=ON", @@ -366,6 +371,22 @@ def _check_true(env_var): ) ) + # LLVM 22 builds GPU device bitcode separately from libomptarget. + if int(PrepareOpenMP.LLVM_VERSION.split(".")[0]) >= 22: + for target in ("nvptx64-nvidia-cuda", "amdgcn-amd-amdhsa"): + ext_modules.append( + CMakeExtension( + f"libompdevice-{target}", + setup=PrepareOpenMP, + source_dir=PrepareOpenMP.get_source_dir().parent / "openmp", + install_dir="openmp", + cmake_args=[ + f"-DLLVM_DEFAULT_TARGET_TRIPLE={target}", + "-DLLVM_INCLUDE_TESTS=OFF", + ], + ) + ) + setup( ext_modules=ext_modules, diff --git a/src/numba/openmp/libs/openmp/patches/22.1.8/0002-Link-statically-LLVM.patch b/src/numba/openmp/libs/openmp/patches/22.1.8/0002-Link-statically-LLVM.patch new file mode 100644 index 000000000000..1af1a5e1d311 --- /dev/null +++ b/src/numba/openmp/libs/openmp/patches/22.1.8/0002-Link-statically-LLVM.patch @@ -0,0 +1,20 @@ +--- a/offload/plugins-nextgen/CMakeLists.txt ++++ b/offload/plugins-nextgen/CMakeLists.txt +@@ -4,6 +4,7 @@ + add_subdirectory(common) + function(add_target_library target_name lib_name) + add_llvm_library(${target_name} STATIC ++ DISABLE_LLVM_LINK_LLVM_DYLIB + LINK_COMPONENTS + AggressiveInstCombine + Analysis +--- a/offload/libomptarget/CMakeLists.txt ++++ b/offload/libomptarget/CMakeLists.txt +@@ -8,6 +8,7 @@ + + add_llvm_library(omptarget + SHARED ++ DISABLE_LLVM_LINK_LLVM_DYLIB + + device.cpp + interface.cpp diff --git a/src/numba/openmp/libs/openmp/patches/22.1.8/0003-Do-not-build-liboffload.patch b/src/numba/openmp/libs/openmp/patches/22.1.8/0003-Do-not-build-liboffload.patch new file mode 100644 index 000000000000..918bb129efdc --- /dev/null +++ b/src/numba/openmp/libs/openmp/patches/22.1.8/0003-Do-not-build-liboffload.patch @@ -0,0 +1,10 @@ +--- a/offload/CMakeLists.txt ++++ b/offload/CMakeLists.txt +@@ -391,7 +391,6 @@ + # Build target agnostic offloading library. + add_subdirectory(libomptarget) + +-add_subdirectory(liboffload) + + # Add tests. + if(OFFLOAD_INCLUDE_TESTS) diff --git a/src/numba/openmp/libs/openmp/patches/22.1.8/0004-Add-getter-for-device-info.patch b/src/numba/openmp/libs/openmp/patches/22.1.8/0004-Add-getter-for-device-info.patch new file mode 100644 index 000000000000..52ff16ad8f14 --- /dev/null +++ b/src/numba/openmp/libs/openmp/patches/22.1.8/0004-Add-getter-for-device-info.patch @@ -0,0 +1,171 @@ +--- a/offload/include/device.h ++++ b/offload/include/device.h +@@ -15,6 +15,8 @@ + + #include + #include ++#include "llvm/Support/raw_ostream.h" ++ + #include + #include + #include +@@ -128,7 +130,7 @@ + int32_t queryAsync(AsyncInfoTy &AsyncInfo); + + /// Calls the corresponding print device info function in the plugin. +- bool printDeviceInfo(); ++ bool printDeviceInfo(llvm::raw_ostream &OS = llvm::outs()); + + /// Event related interfaces. + /// { +--- a/offload/plugins-nextgen/common/include/PluginInterface.h ++++ b/offload/plugins-nextgen/common/include/PluginInterface.h +@@ -247,43 +247,43 @@ + } + + /// Print all info entries in the tree +- void print() const { ++ void print(llvm::raw_ostream &OS = llvm::outs()) const { + // Fake an additional indent so that values are offset from the keys +- doPrint(0, maxKeySize(1)); ++ doPrint(OS, 0, maxKeySize(1)); + } + + private: +- void doPrint(int Level, uint64_t MaxKeySize) const { ++ void doPrint(llvm::raw_ostream &OS, int Level, uint64_t MaxKeySize) const { + if (Key.size()) { + // Compute the indentations for the current entry. + uint64_t KeyIndentSize = Level * IndentSize; + uint64_t ValIndentSize = + MaxKeySize - (Key.size() + KeyIndentSize) + IndentSize; + +- llvm::outs() << std::string(KeyIndentSize, ' ') << Key ++ OS << std::string(KeyIndentSize, ' ') << Key + << std::string(ValIndentSize, ' '); + std::visit( +- [](auto &&V) { ++ [&OS](auto &&V) { + using T = std::decay_t; + if constexpr (std::is_same_v) +- llvm::outs() << V; ++ OS << V; + else if constexpr (std::is_same_v) +- llvm::outs() << (V ? "Yes" : "No"); ++ OS << (V ? "Yes" : "No"); + else if constexpr (std::is_same_v) +- llvm::outs() << V; ++ OS << V; + else if constexpr (std::is_same_v) { + // Do nothing + } else + static_assert(false, "doPrint visit not exhaustive"); + }, + Value); +- llvm::outs() << (Units.empty() ? "" : " ") << Units << "\n"; ++ OS << (Units.empty() ? "" : " ") << Units << "\n"; + } + + // Print children + if (Children) + for (const auto &Entry : *Children) +- Entry.doPrint(Level + 1, MaxKeySize); ++ Entry.doPrint(OS, Level + 1, MaxKeySize); + } + + // Recursively calculates the maximum width of each key, including indentation +@@ -999,7 +999,7 @@ + virtual Expected obtainInfoImpl() = 0; + + /// Print information about the device. +- Error printInfo(); ++ Error printInfo(llvm::raw_ostream &OS = llvm::outs()); + + /// Return true if the device has work that is either queued or currently + /// running +@@ -1499,7 +1499,7 @@ + int32_t query_async(int32_t DeviceId, __tgt_async_info *AsyncInfoPtr); + + /// Prints information about the given devices supported by the plugin. +- void print_device_info(int32_t DeviceId); ++ void print_device_info(int32_t DeviceId, llvm::raw_ostream &OS = llvm::outs()); + + /// Creates an event in the given plugin if supported. + int32_t create_event(int32_t DeviceId, void **EventPtr); +--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp ++++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp +@@ -1451,7 +1451,7 @@ + return InfoOrErr; + } + +-Error GenericDeviceTy::printInfo() { ++Error GenericDeviceTy::printInfo(llvm::raw_ostream &OS) { + auto InfoOrErr = obtainInfo(); + + // Get the vendor-specific info entries describing the device properties. +@@ -1459,7 +1459,7 @@ + return Err; + + // Print all info entries. +- InfoOrErr->print(); ++ InfoOrErr->print(OS); + + return Plugin::success(); + } +@@ -1974,8 +1974,8 @@ + return OFFLOAD_SUCCESS; + } + +-void GenericPluginTy::print_device_info(int32_t DeviceId) { +- if (auto Err = getDevice(DeviceId).printInfo()) ++void GenericPluginTy::print_device_info(int32_t DeviceId, llvm::raw_ostream &OS) { ++ if (auto Err = getDevice(DeviceId).printInfo(OS)) + REPORT() << "Failure to print device " << DeviceId + << " info: " << toString(std::move(Err)); + } +--- a/offload/libomptarget/device.cpp ++++ b/offload/libomptarget/device.cpp +@@ -345,8 +345,8 @@ + } + + // Run region on device +-bool DeviceTy::printDeviceInfo() { +- RTL->print_device_info(RTLDeviceID); ++bool DeviceTy::printDeviceInfo(llvm::raw_ostream &OS) { ++ RTL->print_device_info(RTLDeviceID, OS); + return true; + } + +--- a/offload/libomptarget/exports ++++ b/offload/libomptarget/exports +@@ -66,6 +66,7 @@ + llvm_omp_target_unlock_mem; + __tgt_set_info_flag; + __tgt_print_device_info; ++ __tgt_get_device_info; + omp_get_interop_ptr; + omp_get_interop_str; + omp_get_interop_int; +--- a/offload/libomptarget/interface.cpp ++++ b/offload/libomptarget/interface.cpp +@@ -530,6 +530,20 @@ + return DeviceOrErr->printDeviceInfo(); + } + ++EXTERN int __tgt_get_device_info(int64_t DeviceId, ++ void (*CopyCallback)(const char *, size_t)) { ++ assert(PM && "Runtime not initialized"); ++ auto DeviceOrErr = PM->getDevice(DeviceId); ++ if (!DeviceOrErr) ++ FATAL_MESSAGE(DeviceId, "%s", toString(DeviceOrErr.takeError()).c_str()); ++ ++ std::string DeviceInfoStr; ++ llvm::raw_string_ostream OS(DeviceInfoStr); ++ bool Ret = DeviceOrErr->printDeviceInfo(OS); ++ CopyCallback(DeviceInfoStr.c_str(), DeviceInfoStr.size()); ++ return Ret; ++} ++ + EXTERN void __tgt_target_nowait_query(void **AsyncHandle) { + assert(PM && "Runtime not initialized"); + OMPT_IF_BUILT(ReturnAddressSetterRAII RA(__builtin_return_address(0))); diff --git a/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp b/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp index 489ccb0145c3..e80fa5e0bdaf 100644 --- a/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp +++ b/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp @@ -538,6 +538,11 @@ OutlinedInfoStruct CGIntrinsicsOpenMP::createOutlinedFunction( } CGIntrinsicsOpenMP::CGIntrinsicsOpenMP(Module &M) : OMPBuilder(M), M(M) { +#if LLVM_VERSION_MAJOR >= 22 + bool IsGPU = isOpenMPDeviceRuntime(); + OMPBuilder.Config = OpenMPIRBuilderConfig( + IsGPU, IsGPU, false, false, false, false, false); +#endif OMPBuilder.initialize(); TgtOffloadEntryTy = StructType::create({OMPBuilder.Int8Ptr, @@ -851,8 +856,12 @@ void CGIntrinsicsOpenMP::emitOMPParallelDeviceRuntime( assert(NumThreads && "Expected non-null NumThreads"); - FunctionCallee KmpcParallel51 = + FunctionCallee KmpcParallel = +#if LLVM_VERSION_MAJOR >= 22 + OMPBuilder.getOrCreateRuntimeFunction(M, OMPRTL___kmpc_parallel_60); +#else OMPBuilder.getOrCreateRuntimeFunction(M, OMPRTL___kmpc_parallel_51); +#endif // Set proc_bind to -1 by default as it is unused. assert(Ident && "Expected non-null Ident"); @@ -880,10 +889,13 @@ void CGIntrinsicsOpenMP::emitOMPParallelDeviceRuntime( OutlinedWrapperFnBitcast, CapturedVarAddrsBitcast, NumCapturedArgs}; +#if LLVM_VERSION_MAJOR >= 22 + Args.push_back(OMPBuilder.Builder.getInt32(0)); // Non-strict num_threads. +#endif - auto *CallKmpcParallel51 = - checkCreateCall(OMPBuilder.Builder, KmpcParallel51, Args); - assert(CallKmpcParallel51 && + auto *CallKmpcParallel = + checkCreateCall(OMPBuilder.Builder, KmpcParallel, Args); + assert(CallKmpcParallel && "Expected non-null call instr from code generation"); FunctionCallee KmpcFreeShared = @@ -2315,7 +2327,11 @@ void CGIntrinsicsOpenMP::emitOMPTargetHost( KernelNumTeams, KernelNumThreads, Constant::getNullValue(OMPBuilder.VoidPtr), - /*TargetInfo.NoWait*/ false}; + /*TargetInfo.NoWait*/ false, +#if LLVM_VERSION_MAJOR >= 22 + omp::OMPDynGroupprivateFallbackType::Abort, +#endif + }; OpenMPIRBuilder::getKernelArgsVector(Args, OMPBuilder.Builder, ArgsVector); assert(TargetInfo.DeviceID && "Expected non-null device id"); diff --git a/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.h b/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.h index 7d36d4b8848c..96f6f2e3fac1 100644 --- a/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.h +++ b/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.h @@ -422,7 +422,11 @@ struct CGReduction { {ReductionTy, Orig, Priv, OpenMPIRBuilder::EvalKind::Scalar, CGReduction::reductionNonAtomic, /* ReductionGenClang */ nullptr, - CGReduction::reductionAtomic}); + CGReduction::reductionAtomic, +#if LLVM_VERSION_MAJOR >= 22 + /* DataPtrPtrGen */ nullptr, +#endif + }); #endif return Priv; diff --git a/src/numba/openmp/libs/pass/IntrinsicsOpenMP.cpp b/src/numba/openmp/libs/pass/IntrinsicsOpenMP.cpp index 351e415cf408..4f3ba86b4fc0 100644 --- a/src/numba/openmp/libs/pass/IntrinsicsOpenMP.cpp +++ b/src/numba/openmp/libs/pass/IntrinsicsOpenMP.cpp @@ -33,7 +33,11 @@ #include #include #include +#if LLVM_VERSION_MAJOR >= 22 +#include +#else #include +#endif #include #include #include From 447bfc687455070c285215085107330c7f622642 Mon Sep 17 00:00:00 2001 From: Aleksander Wennersteen Date: Sun, 20 Sep 2026 21:15:14 +0200 Subject: [PATCH 03/11] Build LLVM 22 wheels with conda-forge tools and retain platform CI results --- .github/workflows/build-upload-conda.yml | 10 ++++++++-- .github/workflows/build-upload-wheels.yml | 2 ++ buildscripts/cibuildwheel/setup-miniforge3.sh | 2 +- pyproject.toml | 9 +++++---- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-upload-conda.yml b/.github/workflows/build-upload-conda.yml index 75a35cc9cadd..d803614c80e7 100644 --- a/.github/workflows/build-upload-conda.yml +++ b/.github/workflows/build-upload-conda.yml @@ -20,7 +20,9 @@ jobs: runs-on: ${{ matrix.os }} env: CONDA_LABEL: dev + ANACONDA_TOKEN: ${{ secrets.ANACONDA_TOKEN }} strategy: + fail-fast: false matrix: # TODO: Add windows. os: [ubuntu-latest, macos-latest, ubuntu-24.04-arm] @@ -53,7 +55,7 @@ jobs: auto-update-conda: false show-channel-urls: true - - name: Build and upload pyomp + - name: Build and test pyomp # This ensures conda env is active. shell: bash -l {0} run: | @@ -68,13 +70,17 @@ jobs: --python ${{ matrix.python-version }} \ buildscripts/conda-recipes/pyomp + - name: Upload pyomp + if: env.ANACONDA_TOKEN != '' + shell: bash -l {0} + run: | # Get the output file path. OUTPUT=$(conda build -c conda-forge --output \ --python ${{ matrix.python-version }} \ buildscripts/conda-recipes/pyomp) # Upload the package. - conda run -n base anaconda -t ${{ secrets.ANACONDA_TOKEN }} upload \ + conda run -n base anaconda -t "$ANACONDA_TOKEN" upload \ --user python-for-hpc --label ${{ env.CONDA_LABEL}} \ --force "$OUTPUT" diff --git a/.github/workflows/build-upload-wheels.yml b/.github/workflows/build-upload-wheels.yml index 679d56233117..5ab75187badb 100644 --- a/.github/workflows/build-upload-wheels.yml +++ b/.github/workflows/build-upload-wheels.yml @@ -32,6 +32,7 @@ jobs: build-wheels: runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: # TODO: Add windows. os: [ubuntu-latest, macos-latest, ubuntu-24.04-arm] @@ -82,6 +83,7 @@ jobs: needs: build-wheels runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: os: [ubuntu-latest, macos-latest, ubuntu-24.04-arm] python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] diff --git a/buildscripts/cibuildwheel/setup-miniforge3.sh b/buildscripts/cibuildwheel/setup-miniforge3.sh index 2142c212429f..6c97047de5cc 100644 --- a/buildscripts/cibuildwheel/setup-miniforge3.sh +++ b/buildscripts/cibuildwheel/setup-miniforge3.sh @@ -60,4 +60,4 @@ source "_stage/miniforge3/bin/activate" base # Create conda environment with tools and libraries for the LLVM_VERSION. echo "Installing llvmdev ${LLVM_VERSION}..." -conda create -n llvmdev-${LLVM_VERSION} --override-channels -c conda-forge -q -y clang=${LLVM_VERSION} clangxx=${LLVM_VERSION} clang-tools=${LLVM_VERSION} llvmdev=${LLVM_VERSION} zstd +conda create -n llvmdev-${LLVM_VERSION} --override-channels -c conda-forge -q -y clang=${LLVM_VERSION} clangxx=${LLVM_VERSION} clang-tools=${LLVM_VERSION} llvmdev=${LLVM_VERSION} lld=${LLVM_VERSION} zstd diff --git a/pyproject.toml b/pyproject.toml index e95f5abf5ed7..0e19c7d585a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,15 +57,16 @@ PIP_NO_INPUT = "1" [tool.cibuildwheel.linux] before-all = [ - "yum install -y elfutils-libelf-devel libffi-devel clang-devel-22.1.8 llvm-devel-22.1.8 lld-22.1.8 patch", + "yum install -y elfutils-libelf-devel libffi-devel patch", + "bash buildscripts/cibuildwheel/setup-miniforge3.sh", ] [tool.cibuildwheel.linux.environment] ENABLE_BUNDLED_LIBOMP = "1" ENABLE_BUNDLED_LIBOMPTARGET = "1" -LLVM_DIR = "/usr/lib64/cmake/llvm" -CC = "/usr/bin/clang" -CXX = "/usr/bin/clang++" +LLVM_DIR = "${PWD}/_stage/miniforge3/envs/llvmdev-${LLVM_VERSION}/lib/cmake/llvm" +CC = "${PWD}/_stage/miniforge3/envs/llvmdev-${LLVM_VERSION}/bin/clang" +CXX = "${PWD}/_stage/miniforge3/envs/llvmdev-${LLVM_VERSION}/bin/clang++" [tool.cibuildwheel.macos] before-all = ["bash buildscripts/cibuildwheel/setup-miniforge3.sh"] From afcfb06e3d688b253c1d4961b4ac8a7e47179275 Mon Sep 17 00:00:00 2001 From: Aleksander Wennersteen Date: Sun, 20 Sep 2026 21:19:33 +0200 Subject: [PATCH 04/11] Link wheel compiler runtimes statically for manylinux compatibility --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 0e19c7d585a3..09c5ffe0a2d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,12 +56,15 @@ USE_CXX11_ABI = "1" PIP_NO_INPUT = "1" [tool.cibuildwheel.linux] +repair-wheel-command = "auditwheel show {wheel} && auditwheel repair -w {dest_dir} {wheel}" before-all = [ "yum install -y elfutils-libelf-devel libffi-devel patch", "bash buildscripts/cibuildwheel/setup-miniforge3.sh", ] [tool.cibuildwheel.linux.environment] +# Conda's C++ runtime is newer than the manylinux system runtime. +LDFLAGS = "-static-libstdc++ -static-libgcc" ENABLE_BUNDLED_LIBOMP = "1" ENABLE_BUNDLED_LIBOMPTARGET = "1" LLVM_DIR = "${PWD}/_stage/miniforge3/envs/llvmdev-${LLVM_VERSION}/lib/cmake/llvm" From 9598ac0c3a3f2d197c89f5429a3cf55af9e92098 Mon Sep 17 00:00:00 2001 From: Aleksander Wennersteen Date: Sun, 20 Sep 2026 21:20:37 +0200 Subject: [PATCH 05/11] Separate GPU build flags and update Numba SIMD detection --- buildscripts/conda-recipes/pyomp/run_test.sh | 2 +- setup.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/buildscripts/conda-recipes/pyomp/run_test.sh b/buildscripts/conda-recipes/pyomp/run_test.sh index 64ac06240a74..d2f9d0932799 100644 --- a/buildscripts/conda-recipes/pyomp/run_test.sh +++ b/buildscripts/conda-recipes/pyomp/run_test.sh @@ -12,7 +12,7 @@ export PYTHONFAULTHANDLER=1 # of low accuracy SVML libm replacements in ufunc loops. _NPY_CMD='from numba.misc import numba_sysinfo;\ sysinfo=numba_sysinfo.get_sysinfo();\ - print(sysinfo["NumPy AVX512_SKX detected"] and + print("AVX512_SKX" in sysinfo["NumPy Supported SIMD features"] and sysinfo["NumPy Version"]>="1.22")' NUMPY_DETECTS_AVX512_SKX_NP_GT_122=$(python -c "$_NPY_CMD") echo "NumPy >= 1.22 with AVX512_SKX detected: $NUMPY_DETECTS_AVX512_SKX_NP_GT_122" diff --git a/setup.py b/setup.py index 351c3d92753b..74a26580b943 100644 --- a/setup.py +++ b/setup.py @@ -383,6 +383,9 @@ def _check_true(env_var): cmake_args=[ f"-DLLVM_DEFAULT_TARGET_TRIPLE={target}", "-DLLVM_INCLUDE_TESTS=OFF", + # Host CPU flags from Conda do not apply to GPU bitcode. + "-DCMAKE_C_FLAGS=", + "-DCMAKE_CXX_FLAGS=", ], ) ) From 3352f6c5725d76e99a8a36c38ceefee815dddc74 Mon Sep 17 00:00:00 2001 From: Aleksander Wennersteen Date: Sun, 20 Sep 2026 21:40:14 +0200 Subject: [PATCH 06/11] Record LLVM 22 platform validation and remaining GPU coverage --- README.md | 9 +++++---- docs/source/installation.rst | 16 +++++++++------- docs/source/openmp.rst | 9 +++++---- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 15b68ef678fd..a8253e35da01 100644 --- a/README.md +++ b/README.md @@ -44,10 +44,11 @@ conda install -c python-for-hpc -c conda-forge pyomp ### LLVM 22 development branch This branch targets Numba 0.66.x and llvmlite 0.48.x with LLVM 22.1.8. -It is a source port, not a published PyOMP release. Linux x86_64 CPU execution -and host-device offload are tested with Python 3.12. Four basic NVIDIA GPU -offload tests also pass on an RTX 3080 with CUDA 12.8 tools. The full GPU suite, -other GPUs, macOS, Linux ARM64, and the wider Python CI matrix remain unverified. +It is a source port, not a published PyOMP release. Wheel and Conda CI cover Python +3.10–3.14 on Linux x86_64, Linux ARM64, and macOS ARM64. CPU execution is tested +on all three platforms, with mandatory host-device offload on Linux. Four basic +NVIDIA GPU offload tests also pass on an RTX 3080 with CUDA 12.8 tools. +The full GPU suite, other GPUs, and CUDA 13 compiler tools remain unverified. See [source build and validation instructions](docs/source/installation.rst). The released-version compatibility table below remains historical. diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 650aac217b52..fd71cb262e38 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -59,18 +59,20 @@ and AMDGPU bitcode are included in the Linux wheel. Set ``ENABLE_BUNDLED_LIBOMP=0`` when using an existing LLVM OpenMP runtime, as in the Conda recipe. ``CMAKE_BUILD_PARALLEL_LEVEL`` controls build concurrency. -Validation is limited to Linux x86_64 with Python 3.12, Numba 0.66.0, -llvmlite 0.48.0 (LLVM 22.1.0), and Clang/runtime 22.1.8. The host suite -ran 235 tests with 120 passing and 115 existing skips, including disabled -target tests and unsupported clauses. The separate mandatory host-device run -ran 72 tests with 68 passing and 4 existing skips. +Wheel and Conda CPU tests pass on Linux x86_64, Linux ARM64, and macOS ARM64 with Python +3.10–3.14 and Numba 0.66.0. On Linux, the host suite runs 235 tests with +120 passing and 115 existing skips, including disabled target tests and +unsupported clauses. The separate mandatory host-device run passes 68 tests +with 4 existing skips. On macOS, the host suite passes 119 tests with 116 skips; +all 72 target tests are skipped because offloading is unsupported there. +Local validation also passes with Python 3.12, llvmlite 0.48.0 (LLVM 22.1.0), +and Clang/runtime 22.1.8. Four basic GPU tests also pass on an NVIDIA RTX 3080 (sm_86), driver 595.84, using CUDA 12.8.93 compiler tools: teams/distribute/parallel-for, tofrom mapping, explicit updates, and a parallel reduction. These use mandatory offload and select the NVIDIA device; CPU fallback is not counted as success. The full GPU suite, other GPUs (including Blackwell), CUDA 13 compiler tools, -macOS, Linux ARM64, Conda packages, and the wider Python CI matrix remain -unverified. +and other operating systems and architectures remain unverified. This update does not add target ``nowait``/``depend`` support. To repeat the basic NVIDIA checks with an installed wheel, expose the NVIDIA diff --git a/docs/source/openmp.rst b/docs/source/openmp.rst index ebb1dcb6201b..e1b511c908aa 100644 --- a/docs/source/openmp.rst +++ b/docs/source/openmp.rst @@ -349,10 +349,11 @@ Version and platform support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The LLVM 22 development branch targets Numba 0.66.x and llvmlite 0.48.x. -Local validation covers Linux x86_64, Python 3.12, CPU parallelism, and -mandatory host-device offload. Four basic GPU tests pass on an NVIDIA RTX 3080 -with CUDA 12.8 tools; the full GPU suite and other platforms remain unverified -for this branch. See :doc:`installation` for build and GPU test details. +Wheel and Conda CI cover Python 3.10–3.14 and CPU parallelism on Linux x86_64, Linux +ARM64, and macOS ARM64, with mandatory host-device offload on Linux. +Four basic GPU tests pass on an NVIDIA RTX 3080 with CUDA 12.8 tools; +the full GPU suite and other GPUs remain unverified for this branch. +See :doc:`installation` for build and GPU test details. The following table describes released versions of PyOMP: From a09f2cccd91936585cf613326ee44831a3345b1a Mon Sep 17 00:00:00 2001 From: Aleksander Wennersteen Date: Tue, 22 Sep 2026 17:45:25 +0200 Subject: [PATCH 07/11] Revert extreanous changes to prepare for upstream offering --- .github/workflows/build-upload-conda.yml | 10 +-- .github/workflows/build-upload-wheels.yml | 2 - README.md | 12 +-- docs/source/installation.rst | 63 +-------------- docs/source/openmp.rst | 10 +-- .../0004-Add-getter-for-device-info.patch | 81 ++++++++++++------- 6 files changed, 57 insertions(+), 121 deletions(-) diff --git a/.github/workflows/build-upload-conda.yml b/.github/workflows/build-upload-conda.yml index d803614c80e7..75a35cc9cadd 100644 --- a/.github/workflows/build-upload-conda.yml +++ b/.github/workflows/build-upload-conda.yml @@ -20,9 +20,7 @@ jobs: runs-on: ${{ matrix.os }} env: CONDA_LABEL: dev - ANACONDA_TOKEN: ${{ secrets.ANACONDA_TOKEN }} strategy: - fail-fast: false matrix: # TODO: Add windows. os: [ubuntu-latest, macos-latest, ubuntu-24.04-arm] @@ -55,7 +53,7 @@ jobs: auto-update-conda: false show-channel-urls: true - - name: Build and test pyomp + - name: Build and upload pyomp # This ensures conda env is active. shell: bash -l {0} run: | @@ -70,17 +68,13 @@ jobs: --python ${{ matrix.python-version }} \ buildscripts/conda-recipes/pyomp - - name: Upload pyomp - if: env.ANACONDA_TOKEN != '' - shell: bash -l {0} - run: | # Get the output file path. OUTPUT=$(conda build -c conda-forge --output \ --python ${{ matrix.python-version }} \ buildscripts/conda-recipes/pyomp) # Upload the package. - conda run -n base anaconda -t "$ANACONDA_TOKEN" upload \ + conda run -n base anaconda -t ${{ secrets.ANACONDA_TOKEN }} upload \ --user python-for-hpc --label ${{ env.CONDA_LABEL}} \ --force "$OUTPUT" diff --git a/.github/workflows/build-upload-wheels.yml b/.github/workflows/build-upload-wheels.yml index 5ab75187badb..679d56233117 100644 --- a/.github/workflows/build-upload-wheels.yml +++ b/.github/workflows/build-upload-wheels.yml @@ -32,7 +32,6 @@ jobs: build-wheels: runs-on: ${{ matrix.os }} strategy: - fail-fast: false matrix: # TODO: Add windows. os: [ubuntu-latest, macos-latest, ubuntu-24.04-arm] @@ -83,7 +82,6 @@ jobs: needs: build-wheels runs-on: ${{ matrix.os }} strategy: - fail-fast: false matrix: os: [ubuntu-latest, macos-latest, ubuntu-24.04-arm] python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] diff --git a/README.md b/README.md index a8253e35da01..282c4a79f74a 100644 --- a/README.md +++ b/README.md @@ -41,21 +41,11 @@ PyOMP is also distributed through Conda, installable using the following command conda install -c python-for-hpc -c conda-forge pyomp ``` -### LLVM 22 development branch - -This branch targets Numba 0.66.x and llvmlite 0.48.x with LLVM 22.1.8. -It is a source port, not a published PyOMP release. Wheel and Conda CI cover Python -3.10–3.14 on Linux x86_64, Linux ARM64, and macOS ARM64. CPU execution is tested -on all three platforms, with mandatory host-device offload on Linux. Four basic -NVIDIA GPU offload tests also pass on an RTX 3080 with CUDA 12.8 tools. -The full GPU suite, other GPUs, and CUDA 13 compiler tools remain unverified. -See [source build and validation instructions](docs/source/installation.rst). -The released-version compatibility table below remains historical. - ### Compatibility matrix | PyOMP | Numba | | ----- | --------------- | +| 0.6.x | 0.66.x | | 0.5.x | 0.62.x - 0.63.x | | 0.4.x | 0.61.x | | 0.3.x | 0.57.x - 0.60.x | diff --git a/docs/source/installation.rst b/docs/source/installation.rst index fd71cb262e38..9a0879f604d2 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -24,6 +24,8 @@ supported. +--------+---------------------+ | PyOMP | Numba | +========+=====================+ +| 0.6.x | 0.66.x | ++--------+---------------------+ | 0.5.x | 0.62.x - 0.63.x | +--------+---------------------+ | 0.4.x | 0.61.x | @@ -31,67 +33,6 @@ supported. | 0.3.x | 0.57.x - 0.60.x | +--------+---------------------+ -LLVM 22 source build --------------------- - -The LLVM 22 development branch requires Numba 0.66.x (llvmlite 0.48.x). -Build with Clang and LLVM development libraries version 22.1.8, including -LLVM's NVPTX and AMDGPU targets and the LLVM linker tools. On Linux, install -the libffi and libelf development headers and the ``patch`` utility as well. -Use an isolated environment: - -.. code-block:: console - - $ python3 -m venv .venv22 - $ . .venv22/bin/activate - $ pip install setuptools setuptools-scm wheel cmake ninja 'numba==0.66.0' lark cffi - $ export LLVM_VERSION=22.1.8 LLVM_DIR=$(llvm-config --cmakedir) - $ export CC=clang CXX=clang++ CMAKE_BUILD_PARALLEL_LEVEL=4 - $ export ENABLE_BUNDLED_LIBOMP=1 ENABLE_BUNDLED_LIBOMPTARGET=1 - $ pip wheel --no-build-isolation --no-deps . -w dist - $ pip install --no-deps dist/pyomp-*.whl - $ RUN_TARGET=0 python -m numba.runtests -v -- numba.openmp.tests.test_openmp - $ OMP_TARGET_OFFLOAD=mandatory TEST_DEVICE=host RUN_TARGET=1 python -m numba.runtests -v -- numba.openmp.tests.test_openmp.TestOpenmpTarget - -The build downloads LLVM sources and applies the versioned runtime patches. -LLVM 22 builds GPU device bitcode separately from libomptarget; both NVPTX -and AMDGPU bitcode are included in the Linux wheel. Set -``ENABLE_BUNDLED_LIBOMP=0`` when using an existing LLVM OpenMP runtime, as in -the Conda recipe. ``CMAKE_BUILD_PARALLEL_LEVEL`` controls build concurrency. - -Wheel and Conda CPU tests pass on Linux x86_64, Linux ARM64, and macOS ARM64 with Python -3.10–3.14 and Numba 0.66.0. On Linux, the host suite runs 235 tests with -120 passing and 115 existing skips, including disabled target tests and -unsupported clauses. The separate mandatory host-device run passes 68 tests -with 4 existing skips. On macOS, the host suite passes 119 tests with 116 skips; -all 72 target tests are skipped because offloading is unsupported there. -Local validation also passes with Python 3.12, llvmlite 0.48.0 (LLVM 22.1.0), -and Clang/runtime 22.1.8. -Four basic GPU tests also pass on an NVIDIA RTX 3080 (sm_86), driver 595.84, -using CUDA 12.8.93 compiler tools: teams/distribute/parallel-for, tofrom -mapping, explicit updates, and a parallel reduction. These use mandatory -offload and select the NVIDIA device; CPU fallback is not counted as success. -The full GPU suite, other GPUs (including Blackwell), CUDA 13 compiler tools, -and other operating systems and architectures remain unverified. -This update does not add target ``nowait``/``depend`` support. - -To repeat the basic NVIDIA checks with an installed wheel, expose the NVIDIA -driver to the process and provide CUDA compiler tools. The isolated test -used NVIDIA's pip package with the following paths: - -.. code-block:: console - - $ pip install nvidia-cuda-nvcc-cu12==12.8.93 - $ export CUDA_HOME="$VIRTUAL_ENV/lib/python3.12/site-packages/nvidia/cuda_nvcc" - $ export PATH="$CUDA_HOME/bin:$PATH" - $ export LD_LIBRARY_PATH="$CUDA_HOME/nvvm/lib64${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" - $ export OMP_TARGET_OFFLOAD=mandatory TEST_DEVICE=gpu RUN_TARGET=1 - $ python -m numba.runtests -v -- \ - numba.openmp.tests.test_openmp.TestOpenmpTarget.test_target_teams_distribute_parallel_for \ - numba.openmp.tests.test_openmp.TestOpenmpTarget.test_target_data_tofrom \ - numba.openmp.tests.test_openmp.TestOpenmpTarget.test_target_update_to_from \ - numba.openmp.tests.test_openmp.TestOpenmpTarget.test_target_teams_distribute_parallel_for_reduction - Additional options ------------------ diff --git a/docs/source/openmp.rst b/docs/source/openmp.rst index e1b511c908aa..0e160e8434df 100644 --- a/docs/source/openmp.rst +++ b/docs/source/openmp.rst @@ -348,14 +348,7 @@ Once you have identified a device ID, you can use it in OpenMP target directives Version and platform support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The LLVM 22 development branch targets Numba 0.66.x and llvmlite 0.48.x. -Wheel and Conda CI cover Python 3.10–3.14 and CPU parallelism on Linux x86_64, Linux -ARM64, and macOS ARM64, with mandatory host-device offload on Linux. -Four basic GPU tests pass on an NVIDIA RTX 3080 with CUDA 12.8 tools; -the full GPU suite and other GPUs remain unverified for this branch. -See :doc:`installation` for build and GPU test details. - -The following table describes released versions of PyOMP: +The following table shows tested combinations of PyOMP, Numba, Python, LLVM, and supported platforms: .. table:: :widths: auto @@ -363,6 +356,7 @@ The following table describes released versions of PyOMP: ===================== ==================== ==================== ============ ================================ PyOMP Numba Python LLVM Supported Platforms ===================== ==================== ==================== ============ ================================ + 0.6.x 0.66.x 3.10 - 3.14 22.x linux-64, osx-arm64, linux-arm64 0.5.x 0.62.x - 0.63.x 3.10 - 3.14 20.x linux-64, osx-arm64, linux-arm64 0.4.x 0.61.x 3.10 - 3.13 15.x linux-64, osx-arm64, linux-arm64 0.3.x 0.57.x - 0.60.x 3.9 - 3.12 14.x linux-64, osx-arm64, linux-arm64 diff --git a/src/numba/openmp/libs/openmp/patches/22.1.8/0004-Add-getter-for-device-info.patch b/src/numba/openmp/libs/openmp/patches/22.1.8/0004-Add-getter-for-device-info.patch index 52ff16ad8f14..fa8fe63bec67 100644 --- a/src/numba/openmp/libs/openmp/patches/22.1.8/0004-Add-getter-for-device-info.patch +++ b/src/numba/openmp/libs/openmp/patches/22.1.8/0004-Add-getter-for-device-info.patch @@ -1,39 +1,41 @@ --- a/offload/include/device.h +++ b/offload/include/device.h -@@ -15,6 +15,8 @@ - - #include - #include -+#include "llvm/Support/raw_ostream.h" -+ +@@ -18,6 +18,7 @@ #include #include #include -@@ -128,7 +130,7 @@ ++#include + #include + #include + #include +@@ -128,7 +129,7 @@ int32_t queryAsync(AsyncInfoTy &AsyncInfo); /// Calls the corresponding print device info function in the plugin. - bool printDeviceInfo(); -+ bool printDeviceInfo(llvm::raw_ostream &OS = llvm::outs()); ++ bool printDeviceInfo(llvm::raw_ostream *OS = nullptr); /// Event related interfaces. /// { --- a/offload/plugins-nextgen/common/include/PluginInterface.h +++ b/offload/plugins-nextgen/common/include/PluginInterface.h -@@ -247,43 +247,43 @@ +@@ -247,43 +247,46 @@ } /// Print all info entries in the tree - void print() const { -+ void print(llvm::raw_ostream &OS = llvm::outs()) const { ++ void print(llvm::raw_ostream *OS = nullptr) const { ++ // Choose output stream: provided one or llvm::outs(). ++ llvm::raw_ostream &Out = OS ? *OS : llvm::outs(); ++ // Fake an additional indent so that values are offset from the keys - doPrint(0, maxKeySize(1)); -+ doPrint(OS, 0, maxKeySize(1)); ++ doPrint(0, maxKeySize(1), Out); } private: - void doPrint(int Level, uint64_t MaxKeySize) const { -+ void doPrint(llvm::raw_ostream &OS, int Level, uint64_t MaxKeySize) const { ++ void doPrint(int Level, uint64_t MaxKeySize, llvm::raw_ostream &Out) const { if (Key.size()) { // Compute the indentations for the current entry. uint64_t KeyIndentSize = Level * IndentSize; @@ -41,21 +43,21 @@ MaxKeySize - (Key.size() + KeyIndentSize) + IndentSize; - llvm::outs() << std::string(KeyIndentSize, ' ') << Key -+ OS << std::string(KeyIndentSize, ' ') << Key ++ Out << std::string(KeyIndentSize, ' ') << Key << std::string(ValIndentSize, ' '); std::visit( - [](auto &&V) { -+ [&OS](auto &&V) { ++ [&Out](auto &&V) { using T = std::decay_t; if constexpr (std::is_same_v) - llvm::outs() << V; -+ OS << V; ++ Out << V; else if constexpr (std::is_same_v) - llvm::outs() << (V ? "Yes" : "No"); -+ OS << (V ? "Yes" : "No"); ++ Out << (V ? "Yes" : "No"); else if constexpr (std::is_same_v) - llvm::outs() << V; -+ OS << V; ++ Out << V; else if constexpr (std::is_same_v) { // Do nothing } else @@ -63,32 +65,32 @@ }, Value); - llvm::outs() << (Units.empty() ? "" : " ") << Units << "\n"; -+ OS << (Units.empty() ? "" : " ") << Units << "\n"; ++ Out << (Units.empty() ? "" : " ") << Units << "\n"; } // Print children if (Children) for (const auto &Entry : *Children) - Entry.doPrint(Level + 1, MaxKeySize); -+ Entry.doPrint(OS, Level + 1, MaxKeySize); ++ Entry.doPrint(Level + 1, MaxKeySize, Out); } // Recursively calculates the maximum width of each key, including indentation -@@ -999,7 +999,7 @@ +@@ -999,7 +1002,7 @@ virtual Expected obtainInfoImpl() = 0; /// Print information about the device. - Error printInfo(); -+ Error printInfo(llvm::raw_ostream &OS = llvm::outs()); ++ Error printInfo(llvm::raw_ostream *OS = nullptr); /// Return true if the device has work that is either queued or currently /// running -@@ -1499,7 +1499,7 @@ +@@ -1499,7 +1502,7 @@ int32_t query_async(int32_t DeviceId, __tgt_async_info *AsyncInfoPtr); /// Prints information about the given devices supported by the plugin. - void print_device_info(int32_t DeviceId); -+ void print_device_info(int32_t DeviceId, llvm::raw_ostream &OS = llvm::outs()); ++ void print_device_info(int32_t DeviceId, llvm::raw_ostream *OS = nullptr); /// Creates an event in the given plugin if supported. int32_t create_event(int32_t DeviceId, void **EventPtr); @@ -99,7 +101,7 @@ } -Error GenericDeviceTy::printInfo() { -+Error GenericDeviceTy::printInfo(llvm::raw_ostream &OS) { ++Error GenericDeviceTy::printInfo(llvm::raw_ostream *OS) { auto InfoOrErr = obtainInfo(); // Get the vendor-specific info entries describing the device properties. @@ -118,20 +120,28 @@ -void GenericPluginTy::print_device_info(int32_t DeviceId) { - if (auto Err = getDevice(DeviceId).printInfo()) -+void GenericPluginTy::print_device_info(int32_t DeviceId, llvm::raw_ostream &OS) { ++void GenericPluginTy::print_device_info(int32_t DeviceId, raw_ostream *OS) { + if (auto Err = getDevice(DeviceId).printInfo(OS)) REPORT() << "Failure to print device " << DeviceId << " info: " << toString(std::move(Err)); } --- a/offload/libomptarget/device.cpp +++ b/offload/libomptarget/device.cpp -@@ -345,8 +345,8 @@ +@@ -24,6 +24,7 @@ + + #include "Shared/EnvironmentVar.h" + #include "llvm/Support/Error.h" ++#include "llvm/Support/raw_ostream.h" + + #include + #include +@@ -345,8 +346,8 @@ } // Run region on device -bool DeviceTy::printDeviceInfo() { - RTL->print_device_info(RTLDeviceID); -+bool DeviceTy::printDeviceInfo(llvm::raw_ostream &OS) { ++bool DeviceTy::printDeviceInfo(llvm::raw_ostream *OS) { + RTL->print_device_info(RTLDeviceID, OS); return true; } @@ -148,21 +158,30 @@ omp_get_interop_int; --- a/offload/libomptarget/interface.cpp +++ b/offload/libomptarget/interface.cpp -@@ -530,6 +530,20 @@ +@@ -25,6 +25,7 @@ + #include "Utils/ExponentialBackoff.h" + + #include "llvm/Frontend/OpenMP/OMPConstants.h" ++#include "llvm/Support/raw_ostream.h" + + #include + #include +@@ -530,6 +531,21 @@ return DeviceOrErr->printDeviceInfo(); } +EXTERN int __tgt_get_device_info(int64_t DeviceId, -+ void (*CopyCallback)(const char *, size_t)) { ++ void (*CopyCallback)(const char *, size_t)) { + assert(PM && "Runtime not initialized"); + auto DeviceOrErr = PM->getDevice(DeviceId); + if (!DeviceOrErr) + FATAL_MESSAGE(DeviceId, "%s", toString(DeviceOrErr.takeError()).c_str()); + + std::string DeviceInfoStr; -+ llvm::raw_string_ostream OS(DeviceInfoStr); -+ bool Ret = DeviceOrErr->printDeviceInfo(OS); ++ llvm::raw_string_ostream OS{DeviceInfoStr}; ++ bool Ret = DeviceOrErr->printDeviceInfo(&OS); + CopyCallback(DeviceInfoStr.c_str(), DeviceInfoStr.size()); ++ + return Ret; +} + From 56be21e6a67821bc3865ed65e499885b2e9ba284 Mon Sep 17 00:00:00 2001 From: Aleksander Wennersteen Date: Tue, 22 Sep 2026 20:30:45 +0200 Subject: [PATCH 08/11] Remove unrelated changes from LLVM 22 port --- pyproject.toml | 1 - setup.py | 2 +- src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp | 8 ++++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 09c5ffe0a2d4..440279a6ffaf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,6 @@ USE_CXX11_ABI = "1" PIP_NO_INPUT = "1" [tool.cibuildwheel.linux] -repair-wheel-command = "auditwheel show {wheel} && auditwheel repair -w {dest_dir} {wheel}" before-all = [ "yum install -y elfutils-libelf-devel libffi-devel patch", "bash buildscripts/cibuildwheel/setup-miniforge3.sh", diff --git a/setup.py b/setup.py index 74a26580b943..3eaa4708dbd7 100644 --- a/setup.py +++ b/setup.py @@ -120,7 +120,7 @@ def _build_cmake(self, ext: CMakeExtension): print("Build at dir ", build_dir) subprocess.run( - ["cmake", "--build", build_dir], check=True, stdin=subprocess.DEVNULL + ["cmake", "--build", build_dir, "-j"], check=True, stdin=subprocess.DEVNULL ) print("Install at dir ", install_dir) subprocess.run( diff --git a/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp b/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp index e80fa5e0bdaf..7441e684fa47 100644 --- a/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp +++ b/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp @@ -856,7 +856,7 @@ void CGIntrinsicsOpenMP::emitOMPParallelDeviceRuntime( assert(NumThreads && "Expected non-null NumThreads"); - FunctionCallee KmpcParallel = + FunctionCallee KmpcParallel51 = #if LLVM_VERSION_MAJOR >= 22 OMPBuilder.getOrCreateRuntimeFunction(M, OMPRTL___kmpc_parallel_60); #else @@ -893,9 +893,9 @@ void CGIntrinsicsOpenMP::emitOMPParallelDeviceRuntime( Args.push_back(OMPBuilder.Builder.getInt32(0)); // Non-strict num_threads. #endif - auto *CallKmpcParallel = - checkCreateCall(OMPBuilder.Builder, KmpcParallel, Args); - assert(CallKmpcParallel && + auto *CallKmpcParallel51 = + checkCreateCall(OMPBuilder.Builder, KmpcParallel51, Args); + assert(CallKmpcParallel51 && "Expected non-null call instr from code generation"); FunctionCallee KmpcFreeShared = From 1c2a3b059d34667ca5b9d6293edffff4fcbe5ea9 Mon Sep 17 00:00:00 2001 From: Aleksander Wennersteen Date: Tue, 22 Sep 2026 20:48:27 +0200 Subject: [PATCH 09/11] Remove unneeded llvm version guards --- setup.py | 31 +++++++++---------- .../openmp/libs/pass/CGIntrinsicsOpenMP.cpp | 10 ------ .../openmp/libs/pass/CGIntrinsicsOpenMP.h | 2 -- .../openmp/libs/pass/IntrinsicsOpenMP.cpp | 4 --- 4 files changed, 14 insertions(+), 33 deletions(-) diff --git a/setup.py b/setup.py index 3eaa4708dbd7..124068318f17 100644 --- a/setup.py +++ b/setup.py @@ -363,7 +363,6 @@ def _check_true(env_var): cmake_args=[ "-DOPENMP_STANDALONE_BUILD=ON", "-DLLVM_ENABLE_RUNTIMES=offload", - "-DLLVM_INCLUDE_TESTS=OFF", # Avoid conflicts in manylinux builds with packaged clang/llvm # under /usr/include and its gcc-toolset provided header files. "-DCMAKE_NO_SYSTEM_FROM_IMPORTED=ON", @@ -372,23 +371,21 @@ def _check_true(env_var): ) # LLVM 22 builds GPU device bitcode separately from libomptarget. - if int(PrepareOpenMP.LLVM_VERSION.split(".")[0]) >= 22: - for target in ("nvptx64-nvidia-cuda", "amdgcn-amd-amdhsa"): - ext_modules.append( - CMakeExtension( - f"libompdevice-{target}", - setup=PrepareOpenMP, - source_dir=PrepareOpenMP.get_source_dir().parent / "openmp", - install_dir="openmp", - cmake_args=[ - f"-DLLVM_DEFAULT_TARGET_TRIPLE={target}", - "-DLLVM_INCLUDE_TESTS=OFF", - # Host CPU flags from Conda do not apply to GPU bitcode. - "-DCMAKE_C_FLAGS=", - "-DCMAKE_CXX_FLAGS=", - ], - ) + for target in ("nvptx64-nvidia-cuda", "amdgcn-amd-amdhsa"): + ext_modules.append( + CMakeExtension( + f"libompdevice-{target}", + setup=PrepareOpenMP, + source_dir=PrepareOpenMP.get_source_dir().parent / "openmp", + install_dir="openmp", + cmake_args=[ + f"-DLLVM_DEFAULT_TARGET_TRIPLE={target}", + # Host CPU flags from Conda do not apply to GPU bitcode. + "-DCMAKE_C_FLAGS=", + "-DCMAKE_CXX_FLAGS=", + ], ) + ) setup( diff --git a/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp b/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp index 7441e684fa47..2252259356a1 100644 --- a/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp +++ b/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp @@ -538,11 +538,9 @@ OutlinedInfoStruct CGIntrinsicsOpenMP::createOutlinedFunction( } CGIntrinsicsOpenMP::CGIntrinsicsOpenMP(Module &M) : OMPBuilder(M), M(M) { -#if LLVM_VERSION_MAJOR >= 22 bool IsGPU = isOpenMPDeviceRuntime(); OMPBuilder.Config = OpenMPIRBuilderConfig( IsGPU, IsGPU, false, false, false, false, false); -#endif OMPBuilder.initialize(); TgtOffloadEntryTy = StructType::create({OMPBuilder.Int8Ptr, @@ -857,11 +855,7 @@ void CGIntrinsicsOpenMP::emitOMPParallelDeviceRuntime( assert(NumThreads && "Expected non-null NumThreads"); FunctionCallee KmpcParallel51 = -#if LLVM_VERSION_MAJOR >= 22 OMPBuilder.getOrCreateRuntimeFunction(M, OMPRTL___kmpc_parallel_60); -#else - OMPBuilder.getOrCreateRuntimeFunction(M, OMPRTL___kmpc_parallel_51); -#endif // Set proc_bind to -1 by default as it is unused. assert(Ident && "Expected non-null Ident"); @@ -889,9 +883,7 @@ void CGIntrinsicsOpenMP::emitOMPParallelDeviceRuntime( OutlinedWrapperFnBitcast, CapturedVarAddrsBitcast, NumCapturedArgs}; -#if LLVM_VERSION_MAJOR >= 22 Args.push_back(OMPBuilder.Builder.getInt32(0)); // Non-strict num_threads. -#endif auto *CallKmpcParallel51 = checkCreateCall(OMPBuilder.Builder, KmpcParallel51, Args); @@ -2328,9 +2320,7 @@ void CGIntrinsicsOpenMP::emitOMPTargetHost( KernelNumThreads, Constant::getNullValue(OMPBuilder.VoidPtr), /*TargetInfo.NoWait*/ false, -#if LLVM_VERSION_MAJOR >= 22 omp::OMPDynGroupprivateFallbackType::Abort, -#endif }; OpenMPIRBuilder::getKernelArgsVector(Args, OMPBuilder.Builder, ArgsVector); diff --git a/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.h b/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.h index 96f6f2e3fac1..22f5b2c85e49 100644 --- a/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.h +++ b/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.h @@ -423,9 +423,7 @@ struct CGReduction { CGReduction::reductionNonAtomic, /* ReductionGenClang */ nullptr, CGReduction::reductionAtomic, -#if LLVM_VERSION_MAJOR >= 22 /* DataPtrPtrGen */ nullptr, -#endif }); #endif diff --git a/src/numba/openmp/libs/pass/IntrinsicsOpenMP.cpp b/src/numba/openmp/libs/pass/IntrinsicsOpenMP.cpp index 4f3ba86b4fc0..9f798593e672 100644 --- a/src/numba/openmp/libs/pass/IntrinsicsOpenMP.cpp +++ b/src/numba/openmp/libs/pass/IntrinsicsOpenMP.cpp @@ -33,11 +33,7 @@ #include #include #include -#if LLVM_VERSION_MAJOR >= 22 #include -#else -#include -#endif #include #include #include From 6984ea84accd14ae1657d4e1e306a5e9dc9199a5 Mon Sep 17 00:00:00 2001 From: Aleksander Wennersteen Date: Tue, 22 Sep 2026 21:55:42 +0200 Subject: [PATCH 10/11] Fix LLVM 22 runtime builds and wheel toolchain --- buildscripts/cibuildwheel/setup-miniforge3.sh | 2 +- pyproject.toml | 15 +++++++-------- setup.py | 2 ++ src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp | 8 ++++---- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/buildscripts/cibuildwheel/setup-miniforge3.sh b/buildscripts/cibuildwheel/setup-miniforge3.sh index 6c97047de5cc..2142c212429f 100644 --- a/buildscripts/cibuildwheel/setup-miniforge3.sh +++ b/buildscripts/cibuildwheel/setup-miniforge3.sh @@ -60,4 +60,4 @@ source "_stage/miniforge3/bin/activate" base # Create conda environment with tools and libraries for the LLVM_VERSION. echo "Installing llvmdev ${LLVM_VERSION}..." -conda create -n llvmdev-${LLVM_VERSION} --override-channels -c conda-forge -q -y clang=${LLVM_VERSION} clangxx=${LLVM_VERSION} clang-tools=${LLVM_VERSION} llvmdev=${LLVM_VERSION} lld=${LLVM_VERSION} zstd +conda create -n llvmdev-${LLVM_VERSION} --override-channels -c conda-forge -q -y clang=${LLVM_VERSION} clangxx=${LLVM_VERSION} clang-tools=${LLVM_VERSION} llvmdev=${LLVM_VERSION} zstd diff --git a/pyproject.toml b/pyproject.toml index 440279a6ffaf..c6200d0b99d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,7 +40,7 @@ local_scheme = "no-local-version" archs = ["native"] # Pass LLVM_VERSION from the host environment to cibuildwheel. environment-pass = ["LLVM_VERSION"] -# We use miniconda3 to get the clang/llvm toolchain on Linux. +# Use system LLVM packages on Linux and Miniforge on macOS. before-build = ["rm -rf build dist src/*.egg-info"] # Skip building 3.14t wheels as they are not supported by the current numba/llvmlite version. skip = ["*-musllinux_*", "cp38-*", "cp314t-*"] @@ -57,18 +57,17 @@ PIP_NO_INPUT = "1" [tool.cibuildwheel.linux] before-all = [ - "yum install -y elfutils-libelf-devel libffi-devel patch", - "bash buildscripts/cibuildwheel/setup-miniforge3.sh", + "curl -fsSL https://copr.fedorainfracloud.org/coprs/g/fedora-llvm-team/llvm-compat-packages/repo/rhel-8/group_fedora-llvm-team-llvm-compat-packages-rhel-8.repo -o /etc/yum.repos.d/llvm-compat.repo", + "yum install -y elfutils-libelf-devel libffi-devel patch clang22-devel-22.1.0 llvm22-devel-22.1.0 lld22-22.1.0", + "pipx install --force patchelf==0.19.1", ] [tool.cibuildwheel.linux.environment] -# Conda's C++ runtime is newer than the manylinux system runtime. -LDFLAGS = "-static-libstdc++ -static-libgcc" ENABLE_BUNDLED_LIBOMP = "1" ENABLE_BUNDLED_LIBOMPTARGET = "1" -LLVM_DIR = "${PWD}/_stage/miniforge3/envs/llvmdev-${LLVM_VERSION}/lib/cmake/llvm" -CC = "${PWD}/_stage/miniforge3/envs/llvmdev-${LLVM_VERSION}/bin/clang" -CXX = "${PWD}/_stage/miniforge3/envs/llvmdev-${LLVM_VERSION}/bin/clang++" +LLVM_DIR = "/usr/lib64/llvm22/lib64/cmake/llvm" +CC = "/usr/bin/clang-22" +CXX = "/usr/bin/clang++-22" [tool.cibuildwheel.macos] before-all = ["bash buildscripts/cibuildwheel/setup-miniforge3.sh"] diff --git a/setup.py b/setup.py index 124068318f17..a8362d2317e4 100644 --- a/setup.py +++ b/setup.py @@ -363,6 +363,7 @@ def _check_true(env_var): cmake_args=[ "-DOPENMP_STANDALONE_BUILD=ON", "-DLLVM_ENABLE_RUNTIMES=offload", + "-DLLVM_INCLUDE_TESTS=OFF", # Avoid conflicts in manylinux builds with packaged clang/llvm # under /usr/include and its gcc-toolset provided header files. "-DCMAKE_NO_SYSTEM_FROM_IMPORTED=ON", @@ -380,6 +381,7 @@ def _check_true(env_var): install_dir="openmp", cmake_args=[ f"-DLLVM_DEFAULT_TARGET_TRIPLE={target}", + "-DLLVM_INCLUDE_TESTS=OFF", # Host CPU flags from Conda do not apply to GPU bitcode. "-DCMAKE_C_FLAGS=", "-DCMAKE_CXX_FLAGS=", diff --git a/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp b/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp index 2252259356a1..7fb4deaed438 100644 --- a/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp +++ b/src/numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp @@ -854,7 +854,7 @@ void CGIntrinsicsOpenMP::emitOMPParallelDeviceRuntime( assert(NumThreads && "Expected non-null NumThreads"); - FunctionCallee KmpcParallel51 = + FunctionCallee KmpcParallel60 = OMPBuilder.getOrCreateRuntimeFunction(M, OMPRTL___kmpc_parallel_60); // Set proc_bind to -1 by default as it is unused. @@ -885,9 +885,9 @@ void CGIntrinsicsOpenMP::emitOMPParallelDeviceRuntime( NumCapturedArgs}; Args.push_back(OMPBuilder.Builder.getInt32(0)); // Non-strict num_threads. - auto *CallKmpcParallel51 = - checkCreateCall(OMPBuilder.Builder, KmpcParallel51, Args); - assert(CallKmpcParallel51 && + auto *CallKmpcParallel60 = + checkCreateCall(OMPBuilder.Builder, KmpcParallel60, Args); + assert(CallKmpcParallel60 && "Expected non-null call instr from code generation"); FunctionCallee KmpcFreeShared = From 66690fff5d747e09db1fc367b2f2a10d931d5f75 Mon Sep 17 00:00:00 2001 From: Aleksander Wennersteen Date: Tue, 22 Sep 2026 22:03:39 +0200 Subject: [PATCH 11/11] Restore conda-forge LLVM 22.1.8 for wheel builds --- buildscripts/cibuildwheel/setup-miniforge3.sh | 2 +- pyproject.toml | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/buildscripts/cibuildwheel/setup-miniforge3.sh b/buildscripts/cibuildwheel/setup-miniforge3.sh index 2142c212429f..6c97047de5cc 100644 --- a/buildscripts/cibuildwheel/setup-miniforge3.sh +++ b/buildscripts/cibuildwheel/setup-miniforge3.sh @@ -60,4 +60,4 @@ source "_stage/miniforge3/bin/activate" base # Create conda environment with tools and libraries for the LLVM_VERSION. echo "Installing llvmdev ${LLVM_VERSION}..." -conda create -n llvmdev-${LLVM_VERSION} --override-channels -c conda-forge -q -y clang=${LLVM_VERSION} clangxx=${LLVM_VERSION} clang-tools=${LLVM_VERSION} llvmdev=${LLVM_VERSION} zstd +conda create -n llvmdev-${LLVM_VERSION} --override-channels -c conda-forge -q -y clang=${LLVM_VERSION} clangxx=${LLVM_VERSION} clang-tools=${LLVM_VERSION} llvmdev=${LLVM_VERSION} lld=${LLVM_VERSION} zstd diff --git a/pyproject.toml b/pyproject.toml index c6200d0b99d8..440279a6ffaf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,7 +40,7 @@ local_scheme = "no-local-version" archs = ["native"] # Pass LLVM_VERSION from the host environment to cibuildwheel. environment-pass = ["LLVM_VERSION"] -# Use system LLVM packages on Linux and Miniforge on macOS. +# We use miniconda3 to get the clang/llvm toolchain on Linux. before-build = ["rm -rf build dist src/*.egg-info"] # Skip building 3.14t wheels as they are not supported by the current numba/llvmlite version. skip = ["*-musllinux_*", "cp38-*", "cp314t-*"] @@ -57,17 +57,18 @@ PIP_NO_INPUT = "1" [tool.cibuildwheel.linux] before-all = [ - "curl -fsSL https://copr.fedorainfracloud.org/coprs/g/fedora-llvm-team/llvm-compat-packages/repo/rhel-8/group_fedora-llvm-team-llvm-compat-packages-rhel-8.repo -o /etc/yum.repos.d/llvm-compat.repo", - "yum install -y elfutils-libelf-devel libffi-devel patch clang22-devel-22.1.0 llvm22-devel-22.1.0 lld22-22.1.0", - "pipx install --force patchelf==0.19.1", + "yum install -y elfutils-libelf-devel libffi-devel patch", + "bash buildscripts/cibuildwheel/setup-miniforge3.sh", ] [tool.cibuildwheel.linux.environment] +# Conda's C++ runtime is newer than the manylinux system runtime. +LDFLAGS = "-static-libstdc++ -static-libgcc" ENABLE_BUNDLED_LIBOMP = "1" ENABLE_BUNDLED_LIBOMPTARGET = "1" -LLVM_DIR = "/usr/lib64/llvm22/lib64/cmake/llvm" -CC = "/usr/bin/clang-22" -CXX = "/usr/bin/clang++-22" +LLVM_DIR = "${PWD}/_stage/miniforge3/envs/llvmdev-${LLVM_VERSION}/lib/cmake/llvm" +CC = "${PWD}/_stage/miniforge3/envs/llvmdev-${LLVM_VERSION}/bin/clang" +CXX = "${PWD}/_stage/miniforge3/envs/llvmdev-${LLVM_VERSION}/bin/clang++" [tool.cibuildwheel.macos] before-all = ["bash buildscripts/cibuildwheel/setup-miniforge3.sh"]