This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-tirx.git
The following commit(s) were added to refs/heads/main by this push:
new 694488d97 Switch to uv and pinned LLVM/Z3 build SDKs (#54)
694488d97 is described below
commit 694488d9719edaa4d31fd3c9d075dece80955b67
Author: Tianqi Chen <[email protected]>
AuthorDate: Sat Oct 24 22:19:25 2026 -0400
Switch to uv and pinned LLVM/Z3 build SDKs (#54)
Switch build, test, and documentation workflows to uv-managed project
environments and shared dependency groups. Replace Conda-provided LLVM
with pinned `mlc-llvm-static[all]` and `mlc-z3-static` build SDKs,
discovered automatically and linked statically.
Use `setup-uv` in GitHub Actions, simplify source-build and
customized-LLVM wheel instructions, and remove unused pytest plugins.
The SDK packages remain build-only dependencies, with explicit external
LLVM selection supported.
---
.github/actions/build-wheel-for-publish/action.yml | 84 ++-------------------
.github/actions/setup/action.yml | 63 ----------------
.github/workflows/main.yml | 76 +++++++++----------
AGENTS.md | 35 +++++----
ci/jenkins/gpu_jenkinsfile.groovy | 2 +-
ci/wheel/build-environment.yaml | 42 -----------
ci/wheel/windows_build_libtvm_runtime_cuda.bat | 4 +-
cmake/modules/contrib/Z3.cmake | 4 +-
cmake/utils/FindLLVM.cmake | 34 ++++++++-
docs/README.md | 9 +--
docs/conf.py | 2 -
docs/dev/ci_cd.rst | 38 +++++-----
docs/dev/doc_build.rst | 13 ++--
docs/dev/source_build.rst | 86 +++++++++++-----------
pyproject.toml | 39 +++++++---
src/codegen/llvm/llvm_instance.h | 2 +-
tests/python/codegen/llvm/test_aarch64.py | 17 +++++
tests/python/tirx/test_cuda_backend_config.py | 7 ++
tests/scripts/task_build_arm.sh | 3 +-
tests/scripts/task_build_cpu.sh | 3 +-
tests/scripts/task_build_gpu.sh | 3 +-
tests/scripts/task_build_gpu_other.sh | 13 ++--
tests/scripts/task_install_build_dependencies.sh | 13 ++--
tests/scripts/task_python_docs.sh | 6 +-
tests/scripts/task_python_unittest.sh | 2 +-
tests/scripts/test_task_install_dist_wheels.sh | 10 ++-
26 files changed, 255 insertions(+), 355 deletions(-)
diff --git a/.github/actions/build-wheel-for-publish/action.yml
b/.github/actions/build-wheel-for-publish/action.yml
index 8ff8cc979..c44969d10 100644
--- a/.github/actions/build-wheel-for-publish/action.yml
+++ b/.github/actions/build-wheel-for-publish/action.yml
@@ -39,66 +39,6 @@ inputs:
runs:
using: "composite"
steps:
- # Single source of truth for the LLVM toolchain version, shared by the
cache
- # key and the conda install steps below.
- - name: Set LLVM version
- shell: bash
- run: echo "LLVM_VERSION=22.1.0" >> "$GITHUB_ENV"
-
- - name: Prepare LLVM cache path (Unix)
- if: runner.os != 'Windows'
- shell: bash
- run: |
- set -eux
- sudo mkdir -p /opt/llvm
- sudo chown -R "$(whoami)" /opt/llvm
-
- # ---- Cache LLVM prefix ----
- - name: Cache LLVM
- uses: actions/[email protected]
- id: llvm-cache
- with:
- path: ${{ runner.os == 'Windows' && 'C:/opt/llvm' || '/opt/llvm' }}
- key: tirx-wheel-llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{
inputs.arch }}-v6
-
- # ---- Install LLVM via conda (cache miss only) ----
- - name: Setup conda
- if: steps.llvm-cache.outputs.cache-hit != 'true'
- uses: conda-incubator/[email protected]
- continue-on-error: true
- id: conda1
- with:
- # Miniforge 26.9.4-0 fails `conda init --all` on Windows; see
IntelPython/dpnp#3119.
- miniforge-version: "26.7.2-1"
- conda-remove-defaults: true
-
- - name: Setup conda (retry with tar.bz2)
- if: steps.llvm-cache.outputs.cache-hit != 'true' && steps.conda1.outcome
== 'failure'
- uses: conda-incubator/[email protected]
- with:
- miniforge-version: "26.7.2-1"
- use-only-tar-bz2: true
- conda-remove-defaults: true
-
- - name: Install LLVM (Unix)
- if: steps.llvm-cache.outputs.cache-hit != 'true' && runner.os !=
'Windows'
- shell: bash -l {0}
- run: |
- set -eux
- if [[ "${RUNNER_OS}" == "Linux" ]]; then
- sudo mkdir -p /opt/llvm
- sudo chown -R "$(whoami)" /opt/llvm
- fi
- conda create -q -p /opt/llvm -c conda-forge \
- "llvmdev=${LLVM_VERSION}" "clangdev=${LLVM_VERSION}"
"compiler-rt=${LLVM_VERSION}" zlib zstd-static libxml2-devel \
- -y
-
- - name: Install LLVM (Windows)
- if: steps.llvm-cache.outputs.cache-hit != 'true' && runner.os ==
'Windows'
- shell: cmd /C call {0}
- run: |
- call conda create -q -p C:\opt\llvm -c conda-forge
llvmdev=%LLVM_VERSION% zlib zstd-static libxml2-devel -y
-
# The {project} placeholder is not expanded inside CIBW_ENVIRONMENT
values, so
# compute the forward-slash host path here (the Windows analog of the Linux
# /project hardcode).
@@ -118,27 +58,15 @@ runs:
CIBW_ARCHS_LINUX: ${{ inputs.arch }}
CIBW_ARCHS_MACOS: ${{ inputs.arch }}
CIBW_ARCHS_WINDOWS: ${{ inputs.arch }}
- # Linux builds run in cibuildwheel's default manylinux_2_28 container;
- # bind-mount the cached LLVM prefix into it. Ignored on macOS/Windows,
- # which build without a container.
- CIBW_CONTAINER_ENGINE: "docker; create_args: --volume
/opt/llvm:/opt/llvm:ro"
- # Each per-OS block carries the toolchain location (conda LLVM prefix +
- # llvm-config path), the universal static-link policy
(TVM_TIRX_USE_LLVM --link-static
- # and ZLIB_USE_STATIC_LIBS), and the CUDA sidecar. Feature defines
that vary by
- # wheel (e.g. TVM_TIRX_USE_METAL on macOS) come from the matrix via
inputs.cmake_defines.
- # One explicit block per build platform (macOS / Linux / Windows);
cibuildwheel
- # env overrides replace rather than merge, so there is no shared base
block.
+ # Isolated builds install the pinned LLVM/Z3 SDKs from pyproject.toml.
+ # Keep per-platform feature settings and the CUDA runtime sidecar.
CIBW_ENVIRONMENT_MACOS: >-
- CMAKE_PREFIX_PATH="/opt/llvm"
- CMAKE_ARGS="-DTVM_TIRX_USE_LLVM='/opt/llvm/bin/llvm-config
--link-static' -DZLIB_USE_STATIC_LIBS=ON -DCMAKE_PREFIX_PATH=/opt/llvm ${{
inputs.cmake_defines }}"
+ MACOSX_DEPLOYMENT_TARGET="14.0"
+ CMAKE_ARGS="${{ inputs.cmake_defines }}"
CIBW_ENVIRONMENT_LINUX: >-
- CMAKE_PREFIX_PATH="/opt/llvm"
- LIBRARY_PATH="/opt/llvm/lib"
- CMAKE_ARGS="-DTVM_TIRX_USE_LLVM='/opt/llvm/bin/llvm-config
--link-static' -DZLIB_USE_STATIC_LIBS=ON -DCMAKE_PREFIX_PATH=/opt/llvm ${{
inputs.cmake_defines }}
-DTVM_TIRX_PACKAGE_EXTRA_LIBS=/project/build-wheel-cuda/lib/libtvm_runtime_cuda.so"
+ CMAKE_ARGS="${{ inputs.cmake_defines }}
-DTVM_TIRX_PACKAGE_EXTRA_LIBS=/project/build-wheel-cuda/lib/libtvm_runtime_cuda.so"
CIBW_ENVIRONMENT_WINDOWS: >-
- CMAKE_PREFIX_PATH="C:/opt/llvm/Library"
- PATH="C:/opt/llvm/Library/bin;$PATH"
-
CMAKE_ARGS="-DTVM_TIRX_USE_LLVM='C:/opt/llvm/Library/bin/llvm-config.exe
--link-static' -DZLIB_USE_STATIC_LIBS=ON
-DCMAKE_PREFIX_PATH=C:/opt/llvm/Library ${{ inputs.cmake_defines }}
-DTVM_TIRX_PACKAGE_EXTRA_LIBS=${{ env.TVM_CUDA_EXTRA_LIB }}"
+ CMAKE_ARGS="${{ inputs.cmake_defines }}
-DTVM_TIRX_PACKAGE_EXTRA_LIBS=${{ env.TVM_CUDA_EXTRA_LIB }}"
# Turns the wheel-specific assertions in
# tests/python/runtime/test_validate_wheel_library.py
# ON (they skip unless these are set). Every published wheel is
LLVM-enabled,
diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml
deleted file mode 100644
index 7005e82b1..000000000
--- a/.github/actions/setup/action.yml
+++ /dev/null
@@ -1,63 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-name: Setup TVM CI environment
-description: Set up the cached conda build environment and install tvm-ffi.
-
-runs:
- using: "composite"
- steps:
- - uses: actions/[email protected]
- env:
- CACHE_NUMBER: 2
- with:
- path: ~/conda_pkgs_dir
- key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{
hashFiles('ci/wheel/build-environment.yaml') }}
- - uses: conda-incubator/[email protected]
- continue-on-error: true
- id: conda1
- with:
- activate-environment: tvm-build
- channel-priority: strict
- environment-file: ci/wheel/build-environment.yaml
- auto-activate-base: false
- # Miniforge 26.9.4-0 fails `conda init --all` on Windows; see
IntelPython/dpnp#3119.
- miniforge-version: "26.7.2-1"
- python-version: "3.10"
- conda-remove-defaults: true
- - uses: conda-incubator/[email protected]
- if: steps.conda1.outcome == 'failure'
- with:
- activate-environment: tvm-build
- channel-priority: strict
- environment-file: ci/wheel/build-environment.yaml
- auto-activate-base: false
- miniforge-version: "26.7.2-1"
- use-only-tar-bz2: true
- python-version: "3.10"
- conda-remove-defaults: true
- - name: Conda info
- shell: pwsh
- run: |
- mamba info
- mamba list
- mamba info --envs
- mamba list --name base
- - name: Install tvm-ffi pip package
- shell: bash -l {0}
- run: |
- pip install -v ./3rdparty/tvm-ffi
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 603cfcbe0..60f1bc964 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -48,50 +48,46 @@ jobs:
- uses: actions/[email protected]
with:
submodules: 'recursive'
- - uses: ./.github/actions/setup
+ - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 #
v10.2.0
+ with:
+ python-version: "3.12"
+ activate-environment: true
+ - name: Prepare build and test environment
+ shell: bash
+ run: |
+ uv sync --no-default-groups --group build --group test
--no-install-project --no-install-package apache-tvm-ffi
+ uv pip install --no-deps ./3rdparty/tvm-ffi
- name: Detect environment variables
id: env_vars
uses: ./.github/actions/detect-env-vars
- name: Build TIRx wheels
- shell: bash -l {0}
+ shell: bash
env:
+ MACOSX_DEPLOYMENT_TARGET: "14.0"
CMAKE_BUILD_PARALLEL_LEVEL: ${{ steps.env_vars.outputs.cpu_count }}
run: |
set -euxo pipefail
- pip install "scikit-build-core>=0.11" "setuptools-scm>=8"
- export CMAKE_ARGS="-DTVM_TIRX_USE_LLVM=ON -DTVM_TIRX_USE_METAL=ON
-DTVM_TIRX_BUILD_TESTS=OFF"
- pip wheel --no-deps -w dist . -v
- pip install --no-deps --force-reinstall dist/apache_tvm_tirx-*.whl
- - name: Install TIRx from wheels
- shell: bash -l {0}
- run: |
- set -euxo pipefail
- pip install psutil cloudpickle ml_dtypes numpy packaging scipy
typing_extensions
- # --no-deps: this package requires apache-tvm-ffi>=0.1.14.post1, and
the source-built core
- # versions as 0.1.dev1+g<sha> from the shallow checkout, which is <
0.1.0 under PEP 440.
- # Without it pip replaces the source-matched core with a PyPI build.
- pip install --no-deps "apache-tvm-ffi-orcjit>=0.1.2"
- # Keep the source-matched tvm-ffi installed by the setup steps.
- pip install --no-deps dist/*.whl
-
+ export CMAKE_ARGS="-DTVM_TIRX_USE_METAL=ON
-DTVM_TIRX_BUILD_TESTS=OFF"
+ uv build --wheel --out-dir dist . -v
+ uv pip install --no-deps --force-reinstall dist/apache_tvm_tirx-*.whl
- name: Test
- shell: bash -l {0}
+ shell: bash
run: >-
- python -m pytest -v tests/python/codegen/llvm/test_minimal.py
+ uv run --no-sync python -m pytest -v
tests/python/codegen/llvm/test_minimal.py
tests/python/runtime/test_validate_wheel_library.py
tests/python/script
- name: Minimal Metal Compile-Only
- shell: bash -l {0}
+ shell: bash
run: |
set -euxo pipefail
- python -m pytest -v -s
'tests/python/codegen/gpu_common/test_allreduce.py::test_allreduce_sum_compile'
- python -m pytest -v -s
'tests/python/backend/metal/codegen/test_basic.py::test_func_with_trailing_pod_params'
+ uv run --no-sync python -m pytest -v -s
'tests/python/codegen/gpu_common/test_allreduce.py::test_allreduce_sum_compile'
+ uv run --no-sync python -m pytest -v -s
'tests/python/backend/metal/codegen/test_basic.py::test_func_with_trailing_pod_params'
- name: Minimal Metal Compile-and-Run
- shell: bash -l {0}
+ shell: bash
run: |
set -euxo pipefail
- python -m pytest -v -s tests/python/backend/metal
- python -m pytest -v -s
'tests/python/codegen/gpu_common/test_intrinsics.py'
- python -m pytest -v -s
'tests/python/codegen/gpu_common/test_allreduce.py::test_allreduce_sum[dims0-metal]'
+ uv run --no-sync python -m pytest -v -s tests/python/backend/metal
+ uv run --no-sync python -m pytest -v -s
'tests/python/codegen/gpu_common/test_intrinsics.py'
+ uv run --no-sync python -m pytest -v -s
'tests/python/codegen/gpu_common/test_allreduce.py::test_allreduce_sum[dims0-metal]'
Windows:
if: >-
@@ -102,7 +98,15 @@ jobs:
- uses: actions/[email protected]
with:
submodules: 'recursive'
- - uses: ./.github/actions/setup
+ - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 #
v10.2.0
+ with:
+ python-version: "3.12"
+ activate-environment: true
+ - name: Prepare build and test environment
+ shell: bash
+ run: |
+ uv sync --no-default-groups --group build --group test
--no-install-project --no-install-package apache-tvm-ffi
+ uv pip install --no-deps ./3rdparty/tvm-ffi
- name: Detect environment variables
id: env_vars
uses: ./.github/actions/detect-env-vars
@@ -111,21 +115,13 @@ jobs:
env:
CMAKE_BUILD_PARALLEL_LEVEL: ${{ steps.env_vars.outputs.cpu_count }}
run: |
- pip install "scikit-build-core>=0.11" "setuptools-scm>=8" || exit /b
1
- set CMAKE_ARGS=-DTVM_TIRX_USE_LLVM=ON -DTVM_TIRX_BUILD_TESTS=OFF
- pip wheel --no-deps -w dist . -v || exit /b 1
+ set CMAKE_ARGS=-DTVM_TIRX_BUILD_TESTS=OFF
+ uv build --wheel --out-dir dist . -v || exit /b 1
for %%w in (dist\apache_tvm_tirx-*.whl) do (
- pip install --no-deps --force-reinstall "%%w" || exit /b 1
+ uv pip install --no-deps --force-reinstall "%%w" || exit /b 1
)
- - name: Install test dependencies
- shell: cmd /C call {0}
- run: |
- pip install psutil cloudpickle ml_dtypes numpy packaging scipy
typing_extensions || exit /b 1
- rem --no-deps keeps the source-built apache-tvm-ffi (versioned below
0.1.14.post1 from the
- rem shallow checkout) from being replaced by a PyPI build.
- pip install --no-deps "apache-tvm-ffi-orcjit>=0.1.2" || exit /b 1
- name: Test
shell: cmd /C call {0}
run: >-
- python -m pytest -v tests/python/codegen/llvm/test_minimal.py
+ uv run --no-sync python -m pytest -v
tests/python/codegen/llvm/test_minimal.py
tests/python/runtime/test_validate_wheel_library.py
tests/python/script
diff --git a/AGENTS.md b/AGENTS.md
index 291a9ae3b..2b28a8075 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -49,21 +49,19 @@ ci/wheel/ Wheel-build support
## Building
-Use `uv` for Python environments and package installation. Run commands from
-the repository root; the default virtual environment is `.venv`.
+Run commands from the repository root. `uv sync` creates and manages the
project
+`.venv`; use `uv run --no-sync` to run commands in that environment.
### Prerequisites
-- Python 3.10+, a C++20 compiler, CMake 3.26+, and Ninja.
-- LLVM development libraries and `llvm-config` for the default LLVM backend.
+- Python 3.10+, a C++20 compiler, Git, and uv.
- Initialize dependencies: `git submodule update --init --recursive`.
- Install the relevant device SDK when enabling a device runtime.
### Python editable install (primary workflow)
```bash
-uv venv
-uv pip install --verbose --group dev -e .
+uv sync --no-default-groups
```
Re-run the editable install after changing C++ code or build configuration.
@@ -73,7 +71,7 @@ Pass native build settings through `CMAKE_ARGS`, for example:
```bash
CMAKE_ARGS="-DTVM_TIRX_USE_LLVM=ON -DTVM_TIRX_USE_CUDA=OFF" \
- uv pip install --force-reinstall --verbose -e .
+ uv sync --no-default-groups --reinstall-package apache-tvm-tirx
```
The main switches are `TVM_TIRX_USE_LLVM`, `TVM_TIRX_USE_CUDA`,
@@ -84,8 +82,9 @@ runtimes such as Metal, ROCm, Vulkan, and OpenCL have their
own
### C++-only build
```bash
-cmake -S . -B build_cpp -DCMAKE_BUILD_TYPE=RelWithDebInfo
-cmake --build build_cpp --parallel --config RelWithDebInfo --target
tvm_tirx_compiler
+uv sync --only-group build
+uv run --no-sync cmake -S . -B build_cpp -G Ninja
-DCMAKE_BUILD_TYPE=RelWithDebInfo
+uv run --no-sync cmake --build build_cpp --parallel --config RelWithDebInfo
--target tvm_tirx_compiler
```
The `runtime` target builds the core runtime and enabled device runtimes.
@@ -95,23 +94,26 @@ The `runtime` target builds the core runtime and enabled
device runtimes.
### C++ tests
```bash
-cmake -S . -B build_test -DTVM_TIRX_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Debug
-cmake --build build_test --parallel --config Debug --target tirx_cpptest
-ctest --test-dir build_test -C Debug --output-on-failure
+uv sync --only-group build
+uv run --no-sync cmake -S . -B build_test -G Ninja -DTVM_TIRX_BUILD_TESTS=ON
-DCMAKE_BUILD_TYPE=Debug
+uv run --no-sync cmake --build build_test --parallel --config Debug --target
tirx_cpptest
+uv run --no-sync ctest --test-dir build_test -C Debug --output-on-failure
```
CMake uses an installed GoogleTest package when available and fetches it
otherwise.
### Python tests
-After the editable install with the `dev` or `test` dependency group:
+Install the test dependencies and editable package:
```bash
+uv sync --no-default-groups --group test
uv run --no-sync pytest -v tests/python -m "not gpu"
uv run --no-sync pytest -v tests/python/ir/test_type.py
```
-Run the relevant GPU tests on a machine with the matching runtime and hardware:
+Run the relevant GPU tests on a machine with the matching runtime and hardware.
+For CUDA tests, add `--group cuda` to the sync command above:
```bash
uv run --no-sync pytest -v tests/python -m gpu
@@ -145,6 +147,7 @@ cargo is preferred). `import tvm_tirx` loads it and
registers the operators of i
### Pre-commit (primary lint workflow)
```bash
+uv sync --only-group lint
uv run --no-sync pre-commit run --all-files
uv run --no-sync pre-commit run --files path/to/changed_file
```
@@ -195,10 +198,10 @@ Use the existing tag-based style, for example `[FIX]`,
`[REFACTOR]`, `[FEAT]`,
## Documentation
-After building TIRx, install the documentation dependency group and build:
+Install the documentation dependencies and editable package, then build:
```bash
-uv pip install --group docs
+uv sync --no-default-groups --group docs
uv run --no-sync python -m sphinx -b html -W docs docs/_build/html
```
diff --git a/ci/jenkins/gpu_jenkinsfile.groovy
b/ci/jenkins/gpu_jenkinsfile.groovy
index 59bbdb323..081f346a0 100644
--- a/ci/jenkins/gpu_jenkinsfile.groovy
+++ b/ci/jenkins/gpu_jenkinsfile.groovy
@@ -63,7 +63,7 @@ parallel(
ci.download_artifacts('gpu')
sh(
script: """${docker_run} ${images.ci_gpu} bash -euo pipefail -c '
- source ./tests/scripts/test_task_install_dist_wheels.sh
+ source ./tests/scripts/test_task_install_dist_wheels.sh --group
cuda
./tests/scripts/task_python_unittest_gpuonly.sh
'""",
label: 'Run Python GPU unit tests',
diff --git a/ci/wheel/build-environment.yaml b/ci/wheel/build-environment.yaml
deleted file mode 100644
index 3b2c4dd16..000000000
--- a/ci/wheel/build-environment.yaml
+++ /dev/null
@@ -1,42 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the specific
-# language governing permissions and limitations under the License.
-
-# Build environment for TVM wheel building.
-# This environment provides the necessary dependencies for building TVM wheels.
-name: tvm-wheel-build
-
-# The conda channels to lookup the dependencies
-channels:
- - conda-forge
-
-# The packages to install to the environment
-dependencies:
- # Core build tools
- - cmake >=3.24
- - ninja
- - make
- - llvmdev >=11
- - python >=3.10
- - pip
- - git
- - bzip2
- - zlib
- - zstd-static
- - pytest
- - numpy
- - scipy
- - cython
- - libxml2-devel
diff --git a/ci/wheel/windows_build_libtvm_runtime_cuda.bat
b/ci/wheel/windows_build_libtvm_runtime_cuda.bat
index 8b3b2204c..061a5518a 100644
--- a/ci/wheel/windows_build_libtvm_runtime_cuda.bat
+++ b/ci/wheel/windows_build_libtvm_runtime_cuda.bat
@@ -35,8 +35,8 @@ rem on PATH in this shell.
set "conda_exe=conda"
where conda >nul 2>nul || set "conda_exe=%CONDA%\Scripts\conda.exe"
-rem Install the pinned CUDA toolkit via conda from the nvidia channel,
mirroring the
-rem LLVM-via-conda install used elsewhere. The win-64 channel caps at 13.0.x,
so this
+rem Install the pinned CUDA toolkit via conda from the nvidia channel.
+rem The win-64 channel caps at 13.0.x, so this
rem pins 13.0.2 -- slightly behind the Linux image's CUDA 13.1, which is
harmless: the
rem sidecar has no device code and links the CUDA runtime by soname only. The
nvidia
rem CDN occasionally returns a transient HTTP 5xx, so retry once; a
half-finished first
diff --git a/cmake/modules/contrib/Z3.cmake b/cmake/modules/contrib/Z3.cmake
index 37c37f74c..d83110049 100644
--- a/cmake/modules/contrib/Z3.cmake
+++ b/cmake/modules/contrib/Z3.cmake
@@ -84,8 +84,8 @@ elseif(Z3_FOUND OR (Z3_INCLUDE_DIR AND Z3_LIBRARY))
else()
if(TVM_Z3_REQUIRED)
message(FATAL_ERROR
- "TVM_TIRX_USE_Z3 is ON, but Z3 was not found. Install the static Z3
development "
- "package with `pip install 'mlc-z3-static>=4.16.0'`, or point "
+ "TVM_TIRX_USE_Z3 is ON, but Z3 was not found. From the source root, run "
+ "`uv sync --only-group build` and configure with `uv run --no-sync
cmake`, or point "
"Z3_DIR/CMAKE_PREFIX_PATH at a Z3 installation.")
endif()
message(STATUS "Build without Z3 SMT solver support")
diff --git a/cmake/utils/FindLLVM.cmake b/cmake/utils/FindLLVM.cmake
index de5fb324c..a1e3d964d 100644
--- a/cmake/utils/FindLLVM.cmake
+++ b/cmake/utils/FindLLVM.cmake
@@ -44,7 +44,7 @@ endfunction()
# Usage:
# find_llvm(${USE_LLVM} [${LLVM_VERSION}])
#
-# - When USE_LLVM=ON, use auto search
+# - When USE_LLVM=ON, prefer the Python mlc-llvm-static SDK, then auto search
# - When USE_LLVM=/path/to/llvm-config, use corresponding config
# - The optional LLVM_VERSION=<required version> which will find a matching
version
# If LLVM_VERSION=10 then it will find 10.X.X, any version of 10
@@ -66,6 +66,32 @@ macro(find_llvm use_llvm)
endif()
if(${LLVM_CONFIG} MATCHES ${IS_TRUE_PATTERN})
+ # Like Z3 discovery, preserve an explicit LLVM_DIR override.
+ if(NOT LLVM_DIR)
+ find_package(Python3 COMPONENTS Interpreter QUIET)
+ if(Python3_EXECUTABLE)
+ execute_process(
+ COMMAND "${Python3_EXECUTABLE}" -m mlc_llvm_static.config --cmake-dir
+ OUTPUT_VARIABLE LLVM_STATIC_CMAKE_DIR
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET
+ RESULT_VARIABLE LLVM_STATIC_RESULT
+ )
+ if(LLVM_STATIC_RESULT EQUAL 0 AND EXISTS "${LLVM_STATIC_CMAKE_DIR}")
+ set(LLVM_DIR "${LLVM_STATIC_CMAKE_DIR}")
+ get_filename_component(LLVM_STATIC_PREFIX "${LLVM_DIR}/../../.."
ABSOLUTE)
+ list(PREPEND CMAKE_PREFIX_PATH "${LLVM_STATIC_PREFIX}")
+ set(ZLIB_USE_STATIC_LIBS ON)
+ # This provider supplies imported static targets, including its
+ # transitive dependencies; never select an ambient LLVM dylib.
+ set(LLVM_LINK_LLVM_DYLIB OFF)
+ if(TVM_TIRX_BUILD_PYTHON_MODULE)
+ install(DIRECTORY "${LLVM_STATIC_PREFIX}/../licenses/"
+ DESTINATION licenses COMPONENT tvm_tirx FILES_MATCHING PATTERN
"*.txt")
+ endif()
+ endif()
+ endif()
+ endif()
# This is a workaround for an upstream LLVM issue [0], in which
# the `CMAKE_INSTALL_LIBDIR` variable is used before definition.
# While there is an LLVM PR to resolve this fix [1], as of
@@ -78,13 +104,17 @@ macro(find_llvm use_llvm)
find_package(LLVM ${llvm_version_required} QUIET CONFIG)
if(NOT LLVM_FOUND)
message(FATAL_ERROR
- "LLVM development files were not found. Install LLVM 15 or newer,
including "
+ "LLVM development files were not found. From the source root, run "
+ "`uv sync --only-group build` and configure with `uv run --no-sync
cmake`, "
+ "or install LLVM 15 or newer, including "
"its development headers and libraries (for example, llvm-dev on
Debian/Ubuntu "
"or llvm-devel on Fedora). Set LLVM_DIR to the directory containing "
"LLVMConfig.cmake, add the LLVM installation to CMAKE_PREFIX_PATH, or
set "
"TVM_TIRX_USE_LLVM to the full path to llvm-config. To build without
LLVM, "
"explicitly set TVM_TIRX_USE_LLVM=OFF.")
endif()
+ # LLVMConfig.cmake exports command-line flags as one space-separated
string.
+ separate_arguments(LLVM_DEFINITIONS NATIVE_COMMAND "${LLVM_DEFINITIONS}")
llvm_map_components_to_libnames(LLVM_LIBS "all")
if (NOT LLVM_LIBS)
message(STATUS "Not found - LLVM_LIBS")
diff --git a/docs/README.md b/docs/README.md
index f963e32ff..228c0a0b2 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -17,13 +17,12 @@
# TIRx Documentation
-See [Build from Source](dev/source_build.rst) for the Miniforge/mamba and uv
-environment. After building TIRx, install the documentation dependencies and
build from the
-repository root:
+From the repository root, sync the documentation dependencies and editable
+package into the project `.venv`:
```bash
-uv pip install --group docs
-uv run python -m sphinx -b html -W docs docs/_build/html
+uv sync --no-default-groups --group docs
+uv run --no-sync python -m sphinx -b html -W docs docs/_build/html
```
Set `BUILD_CPP_DOCS=1` to also generate the C++ API reference; this requires
Doxygen.
diff --git a/docs/conf.py b/docs/conf.py
index 864ae5637..00b86830d 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -28,8 +28,6 @@ build_exhale = os.environ.get("BUILD_CPP_DOCS", "0") == "1"
_DOCS_DIR = Path(__file__).resolve().parent
-sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "python"))
-
project = "tvm-tirx"
html_title = project
author = "Apache TVM Community"
diff --git a/docs/dev/ci_cd.rst b/docs/dev/ci_cd.rst
index f18a90e97..fb04b2550 100644
--- a/docs/dev/ci_cd.rst
+++ b/docs/dev/ci_cd.rst
@@ -37,22 +37,22 @@ Install and register the hooks so they run automatically
before each commit:
.. code-block:: bash
- uv tool install pre-commit
- pre-commit install
+ uv sync --only-group lint
+ uv run --no-sync pre-commit install
You can also run hooks manually:
.. code-block:: bash
# Run all hooks on every file
- pre-commit run --all-files
+ uv run --no-sync pre-commit run --all-files
# Run only on staged files
- pre-commit run
+ uv run --no-sync pre-commit run
# Run a single hook in isolation
- pre-commit run ruff-check --all-files
- pre-commit run clang-format --all-files
+ uv run --no-sync pre-commit run ruff-check --all-files
+ uv run --no-sync pre-commit run clang-format --all-files
The main tools are:
@@ -69,13 +69,14 @@ Use ``pre-commit clean`` if a stale hook environment causes
problems.
C++ Tests
---------
-Configure, build, and run locally:
+Configure, build, and run locally in the project ``.venv``:
.. code-block:: bash
- cmake . -B build_test -G Ninja -DTVM_TIRX_BUILD_TESTS=ON
-DCMAKE_BUILD_TYPE=Debug
- cmake --build build_test --config Debug --target tirx_cpptest
- ctest -V -C Debug --test-dir build_test --output-on-failure
+ uv sync --only-group build
+ uv run --no-sync cmake . -B build_test -G Ninja -DTVM_TIRX_BUILD_TESTS=ON
-DCMAKE_BUILD_TYPE=Debug
+ uv run --no-sync cmake --build build_test --config Debug --target
tirx_cpptest
+ uv run --no-sync ctest -V -C Debug --test-dir build_test --output-on-failure
CMake uses an installed GoogleTest package or fetches it when needed.
On Windows, run from a Visual Studio Developer Command Prompt.
@@ -83,17 +84,18 @@ On Windows, run from a Visual Studio Developer Command
Prompt.
Python Tests
------------
-Reproduce locally with:
+Reproduce locally in the project ``.venv``:
.. code-block:: bash
# Install the editable package and test dependencies
- uv pip install --reinstall --verbose --group test -e .
+ uv sync --no-default-groups --group test
# Run the CPU tests
- uv run pytest -vvs tests/python -m "not gpu"
+ uv run --no-sync pytest -vvs tests/python -m "not gpu"
Use ``-m gpu`` for device tests with the matching backend, SDK, and hardware.
+For CUDA tests, add ``--group cuda`` to the sync command above.
Pass a test file or directory to focus on the component you changed.
Build Python Wheels
@@ -101,10 +103,12 @@ Build Python Wheels
CI builds wheels using `cibuildwheel <https://cibuildwheel.pypa.io/>`__ on
Linux (x86_64, aarch64), Windows (AMD64), and macOS (arm64). Wheel
configuration
-lives in ``[tool.cibuildwheel]`` in ``pyproject.toml``. Configure the
platform's
-LLVM toolchain as in the `wheel build action
-<https://github.com/apache/tvm-tirx/blob/main/.github/actions/build-wheel-for-publish/action.yml>`__;
-Linux builds also require Docker and the LLVM prefix mounted into the build
image.
+lives in ``[tool.cibuildwheel]`` in ``pyproject.toml``. Isolated builds install
+the exact LLVM/Z3 SDK pins from ``[build-system].requires``; no separate LLVM
+prefix or Conda environment is needed. Linux builds require Docker. macOS arm64
+wheels require ``MACOSX_DEPLOYMENT_TARGET=14.0``, matching the pinned SDK.
+The separate Windows CUDA runtime sidecar still uses its existing Conda CUDA
+toolkit installer; that is independent of LLVM/Z3 discovery.
To build wheels locally:
diff --git a/docs/dev/doc_build.rst b/docs/dev/doc_build.rst
index 874bfbc0a..400a226f4 100644
--- a/docs/dev/doc_build.rst
+++ b/docs/dev/doc_build.rst
@@ -25,9 +25,10 @@ Building the docs requires the Python package to be
installed first; see
.. admonition:: Prerequisite
:class: hint
- - Use the activated mamba environment from :doc:`source_build`.
+ - Use the project ``.venv``, as in :doc:`source_build`.
- Run commands from the repository root.
- - Install the documentation tools with ``uv pip install --group docs``.
+ - Install the documentation tools and editable package with
+ ``uv sync --no-default-groups --group docs``.
- Optional: install ``Doxygen`` if you plan to generate the C++ API
reference (see :ref:`build-cpp-docs`).
@@ -38,7 +39,7 @@ Rebuild and serve the documentation locally with live reload:
.. code-block:: bash
- uv run sphinx-autobuild docs docs/_build/html \
+ uv run --no-sync sphinx-autobuild docs docs/_build/html \
--ignore docs/reference/python/generated --ignore
docs/reference/cpp/generated
Open ``http://127.0.0.1:8000`` after the initial build completes.
@@ -50,7 +51,7 @@ Generate the HTML documentation once, with warnings treated
as errors:
.. code-block:: bash
- uv run python -m sphinx -b html -W docs docs/_build/html
+ uv run --no-sync python -m sphinx -b html -W docs docs/_build/html
Open ``docs/_build/html/index.html`` to browse the result.
@@ -71,12 +72,12 @@ Set ``BUILD_CPP_DOCS=1`` on the desired build command to
enable the extra step:
.. code-block:: bash
# Interactive build with auto-rebuild on C++ header changes
- BUILD_CPP_DOCS=1 uv run sphinx-autobuild docs docs/_build/html \
+ BUILD_CPP_DOCS=1 uv run --no-sync sphinx-autobuild docs docs/_build/html \
--ignore docs/reference/python/generated --ignore
docs/reference/cpp/generated \
--watch include
# One-off build
- BUILD_CPP_DOCS=1 uv run python -m sphinx -b html -W docs docs/_build/html
+ BUILD_CPP_DOCS=1 uv run --no-sync python -m sphinx -b html -W docs
docs/_build/html
Cleanup
-------
diff --git a/docs/dev/source_build.rst b/docs/dev/source_build.rst
index 23ed8301a..0c8994b59 100644
--- a/docs/dev/source_build.rst
+++ b/docs/dev/source_build.rst
@@ -19,31 +19,14 @@ Build from Source
=================
This guide provides instructions on how to build the TIRx package from source.
+``uv sync`` creates the project ``.venv`` and installs the package in editable
mode.
.. admonition:: Prerequisite
:class: tip
- Python: 3.10 or newer.
- Compiler: a C++20-capable GCC, Clang, or MSVC toolchain.
- - Build tools: Git, CMake 3.26+, and uv.
- - LLVM: development libraries and ``llvm-config`` from LLVM 15 or newer.
-
- On most platforms, you can get LLVM and the build dependencies through
- `Miniforge <https://github.com/conda-forge/miniforge>`__:
-
- .. code-block:: bash
-
- mamba create -n tirx-dev -c conda-forge python=3.12 llvmdev cmake git uv
- mamba activate tirx-dev
- llvm-config --version
-
- Use this mamba environment for all commands. Keep ``uv run`` in the same
- environment without resynchronizing the packages installed by ``uv pip``:
-
- .. code-block:: bash
-
- export UV_PROJECT_ENVIRONMENT="$CONDA_PREFIX"
- export UV_NO_SYNC=1
+ - Build tools: Git and uv.
Build the Python Package
------------------------
@@ -65,14 +48,13 @@ Download the source via:
git submodule update --init --recursive
Build the Python package with scikit-build-core, which drives CMake to compile
-the C++ libraries and supplies Ninja when needed in the default isolated build:
+the C++ libraries and supplies CMake/Ninja when needed in the isolated build:
.. code-block:: bash
- uv pip install --force-reinstall --verbose -e .
+ uv sync --no-default-groups
-The ``--force-reinstall`` flag forces a rebuild, and ``-e`` (editable) means
-Python-only changes are reflected immediately without rebuilding.
+The editable install reflects Python-only changes immediately without
rebuilding.
**CMake flags** can be exported through ``CMAKE_ARGS`` before running the
install command. For example, to switch off the CUDA runtime (which is
@@ -85,7 +67,8 @@ automatically switched on when available):
Available CMake options (see `CMakeLists.txt
<https://github.com/apache/tvm-tirx/blob/main/CMakeLists.txt>`__) include:
-- ``TVM_TIRX_USE_LLVM`` -- Enable LLVM, or select an ``llvm-config`` command
(default: ``ON``).
+- ``TVM_TIRX_USE_LLVM`` -- Prefer the build Python's static LLVM SDK, or
select an
+ explicit ``LLVM_DIR`` / ``llvm-config`` command (default: ``ON``). ``OFF``
disables LLVM.
- ``TVM_TIRX_USE_CUDA`` -- Enable the CUDA runtime (default: ``AUTO``).
- ``TVM_TIRX_USE_METAL`` -- Enable the Metal runtime on macOS (default:
``OFF``).
- ``TVM_TIRX_USE_Z3`` -- Enable the Z3 solver (default: ``AUTO``).
@@ -98,8 +81,8 @@ Verify the installation:
.. code-block:: bash
- uv run python -c "import tvm_tirx; print(tvm_tirx.__version__)"
- uv run tvm-tirx-config -h
+ uv run --no-sync python -c "import tvm_tirx; print(tvm_tirx.__version__)"
+ uv run --no-sync tvm-tirx-config -h
.. tip::
@@ -107,36 +90,57 @@ Verify the installation:
.. code-block:: bash
- tvm-tirx-config --includedir
- tvm-tirx-config --libfiles
+ uv run --no-sync tvm-tirx-config --includedir
+ uv run --no-sync tvm-tirx-config --libfiles
On Linux/macOS, query linker flags for the compiler or runtime libraries:
.. code-block:: bash
- tvm-tirx-config --libs compiler # Compiler and its dependencies
- tvm-tirx-config --libs runtime # Core runtime
- tvm-tirx-config --libs runtime cuda # Core and CUDA runtimes (CUDA
build)
- tvm-tirx-config --ldflags # Library search paths
+ uv run --no-sync tvm-tirx-config --libs compiler # Compiler and its
dependencies
+ uv run --no-sync tvm-tirx-config --libs runtime # Core runtime
+ uv run --no-sync tvm-tirx-config --libs runtime cuda # Core and CUDA
runtimes (CUDA build)
+ uv run --no-sync tvm-tirx-config --ldflags # Library search
paths
+
+Build with CMake
+----------------
-Build Wheels with Static LLVM
------------------------------
+Install only the build tools and SDKs, without installing the Python package,
+then configure and build:
+
+.. code-block:: bash
+
+ uv sync --only-group build
+ uv run --no-sync cmake -S . -B build_cpp -G Ninja -DCMAKE_BUILD_TYPE=Release
+ uv run --no-sync cmake --build build_cpp --parallel
+
+Build Wheels with Customized LLVM
+---------------------------------
+
+By default, builds use the pinned prebuilt LLVM/Z3 static SDK packages from
+PyPI specified in ``pyproject.toml``; no manual SDK setup is needed.
+
+An explicit ``LLVM_DIR`` or ``TVM_TIRX_USE_LLVM=/path/to/llvm-config`` selects
+an external LLVM installation. Supply its development libraries and transitive
+dependencies before building.
+
+.. note::
-When shipping wheels, link LLVM statically so users do not need the same shared
-LLVM library installed. Install its development dependencies and export the
-static-link setting before building the wheel:
+ When building wheels for release, we recommend linking LLVM statically into
+ the wheel to avoid conflicts with LLVM libraries used by other packages.
+ Pass ``--link-static`` to ``llvm-config`` to enable this.
.. code-block:: bash
- mamba install -c conda-forge zlib zstd-static libxml2-devel
- export CMAKE_ARGS="-DTVM_TIRX_USE_LLVM='llvm-config --link-static'
-DZLIB_USE_STATIC_LIBS=ON"
+ CMAKE_ARGS="-DTVM_TIRX_USE_LLVM='/path/to/llvm-config --link-static'" uv
build --wheel
-See :doc:`ci_cd` for wheel builds and the publication toolchain configuration.
+For macOS wheels using the default SDK, set ``MACOSX_DEPLOYMENT_TARGET=14.0``.
+See :doc:`ci_cd` for the publication toolchain configuration.
Troubleshooting
---------------
-- **Rebuilding after C++ changes**: re-run ``uv pip install --force-reinstall
-e .``.
+- **Rebuilding after C++ changes**: re-run ``uv sync --no-default-groups
--reinstall-package apache-tvm-tirx``.
Editable installs automatically reflect only Python changes.
- **Submodules missing**: run ``git submodule update --init --recursive`` from
the repository root.
diff --git a/pyproject.toml b/pyproject.toml
index 8441b4349..76bcf3c33 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -58,20 +58,31 @@ popen-pool = ["psutil", "cloudpickle"]
all = ["psutil", "cloudpickle"]
[dependency-groups]
-torch = ["torch"]
+build = [
+ "cmake>=3.26",
+ "ninja",
+ "scikit-build-core>=0.11,!=1.1.0",
+ "setuptools-scm>=8",
+ "cython>=3.2.8",
+ "mlc-llvm-static[all]==23.1.1",
+ "mlc-z3-static==5.3.1.post0",
+]
+torch = [
+ "torch",
+ "setuptools", # setuptools is needed by torch jit for best perf
+ "ninja",
+ "numpy",
+ "ml_dtypes",
+]
+cuda = ["cuda-bindings"]
popen-pool = ["psutil", "cloudpickle"]
test = [
- "z3-solver",
- "pytest",
- "pytest-xdist",
- "pytest-cov",
- "pytest-mock",
- "pytest-benchmark",
- "pytest-timeout",
- "pytest-rerunfailures",
- "pytest-repeat",
{ include-group = "torch" },
{ include-group = "popen-pool" },
+ "pytest",
+ "pytest-xdist",
+ "z3-solver",
+ "packaging",
]
lint = ["ruff", "pre-commit"]
dev = [{ include-group = "test" }, { include-group = "lint" }]
@@ -88,8 +99,12 @@ docs = [
tvm-tirx-config = "tvm_tirx.config:__main__"
[build-system]
-# mlc-z3-static ships the PIC static libz3 + headers consumed by
TVM_TIRX_USE_Z3=ON.
-requires = ["scikit-build-core>=0.11", "mlc-z3-static>=4.16.0"]
+# Static development SDKs are build requirements, not runtime dependencies.
+requires = [
+ "scikit-build-core>=0.11",
+ "mlc-llvm-static[all]==23.1.1",
+ "mlc-z3-static==5.3.1.post0",
+]
build-backend = "scikit_build_core.build"
[tool.scikit-build]
diff --git a/src/codegen/llvm/llvm_instance.h b/src/codegen/llvm/llvm_instance.h
index 425490a2a..7424d175a 100644
--- a/src/codegen/llvm/llvm_instance.h
+++ b/src/codegen/llvm/llvm_instance.h
@@ -42,7 +42,7 @@
// LLVM compatibility macro
#if TVM_LLVM_VERSION >= 200
-#define llvmGetPointerTo(arg, offset) (llvm::PointerType::get((arg), (offset)))
+#define llvmGetPointerTo(arg, offset)
(llvm::PointerType::get((arg)->getContext(), (offset)))
#else
#define llvmGetPointerTo(arg, offset) (arg->getPointerTo(offset))
#endif
diff --git a/tests/python/codegen/llvm/test_aarch64.py
b/tests/python/codegen/llvm/test_aarch64.py
index 1db9d6540..6e0649236 100644
--- a/tests/python/codegen/llvm/test_aarch64.py
+++ b/tests/python/codegen/llvm/test_aarch64.py
@@ -385,6 +385,11 @@ def test_eq(dtype):
r"cm(p)?eq\tp[0-9].[shdb],( p[0-9]/[zm],)? z[0-9].[shdb],
z[0-9].[shdb]", assembly
)
+ if llvm.version_major() >= 23 and dtype in ("float", "float16"):
+ # LLVM 23 can use NEON for both the main loop and the epilogue.
+ loads += re.findall(r"ld[rp]\tq[0-9]+", assembly)
+ matches += re.findall(r"fcmeq\tv[0-9]+\.[0-9]+[hs]", assembly)
+
assert len(loads) > 1
# The number of SVE compares depends on the LLVM cost model: LLVM <= 17
# interleaves the scalable loop by two, while LLVM 20 emits a fixed-width
@@ -426,6 +431,12 @@ def test_neq(dtype):
r"cm(p)?(gt|ne)\tp[0-9].[shdb],( p[0-9]/[zm],)? z[0-9].[shdb],
z[0-9].[shdb]", assembly
)
+ if llvm.version_major() >= 23 and dtype in ("float", "float16"):
+ # LLVM 23 can use NEON for both the main loop and the epilogue.
+ loads += re.findall(r"ld[rp]\tq[0-9]+", assembly)
+ matches += re.findall(r"fcmgt\tv[0-9]+\.[0-9]+[hs]", assembly)
+ assert re.search(r"orr\tv[0-9]+\.16b", assembly)
+
assert len(loads) > 1
# The number of SVE compares depends on the LLVM cost model: LLVM <= 17
# interleaves the scalable loop by two, while LLVM 20 emits a fixed-width
@@ -536,6 +547,12 @@ def test_not(dtype):
r"eor\tz[0-9].[shdb],( p[0-9]/[zm],)? z[0-9].[shdb], z[0-9].[shdb]",
assembly
)
+ if llvm.version_major() >= 23:
+ # Full-vector loads need no predicate. LLVM also represents bytewise
+ # complement as 255 - x, which is identical to xor with all ones.
+ loads += re.findall(r"ldr\tz[0-9]+,", assembly)
+ matches += re.findall(r"subr\tz[0-9]+\.b, z[0-9]+\.b, #255", assembly)
+
assert len(loads) > 1
assert len(matches) > 1
diff --git a/tests/python/tirx/test_cuda_backend_config.py
b/tests/python/tirx/test_cuda_backend_config.py
index 68934898d..1d84824ba 100644
--- a/tests/python/tirx/test_cuda_backend_config.py
+++ b/tests/python/tirx/test_cuda_backend_config.py
@@ -53,6 +53,13 @@ def _require_compiler(compiler):
status, major, minor = nvrtc.nvrtcVersion()
assert status == nvrtc.nvrtcResult.NVRTC_SUCCESS
version = (major, minor)
+ # Python bindings alone do not provide the toolkit headers used by the
driver.
+ from tvm_tirx.support.nvcc import find_cuda_path
+
+ try:
+ find_cuda_path()
+ except RuntimeError:
+ pytest.skip("CUDA toolkit is not installed")
if version < (12, 8):
pytest.skip("sm_100a compile tests require CUDA 12.8 or newer")
diff --git a/tests/scripts/task_build_arm.sh b/tests/scripts/task_build_arm.sh
index 576687813..15a8c00a6 100755
--- a/tests/scripts/task_build_arm.sh
+++ b/tests/scripts/task_build_arm.sh
@@ -20,9 +20,8 @@ set -euxo pipefail
export CMAKE_ARGS="
-DTVM_TIRX_BUILD_TESTS=ON
- -DTVM_TIRX_USE_LLVM=llvm-config-17
-DCMAKE_CXX_FLAGS=-Werror
"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir
dist .
+uv build --wheel --no-build-isolation --offline --out-dir dist .
./build/tirx_cpptest
diff --git a/tests/scripts/task_build_cpu.sh b/tests/scripts/task_build_cpu.sh
index 2e5e54009..7d6b7a805 100755
--- a/tests/scripts/task_build_cpu.sh
+++ b/tests/scripts/task_build_cpu.sh
@@ -20,9 +20,8 @@ set -euxo pipefail
export CMAKE_ARGS="
-DTVM_TIRX_BUILD_TESTS=ON
- -DTVM_TIRX_USE_LLVM='/usr/bin/llvm-config-17 --link-static'
-DCMAKE_CXX_FLAGS='-Wno-error=range-loop-construct -Wno-error=comment'
"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir
dist .
+uv build --wheel --no-build-isolation --offline --out-dir dist .
./build/tirx_cpptest
diff --git a/tests/scripts/task_build_gpu.sh b/tests/scripts/task_build_gpu.sh
index d58c23324..45f20bd58 100755
--- a/tests/scripts/task_build_gpu.sh
+++ b/tests/scripts/task_build_gpu.sh
@@ -23,10 +23,9 @@ export CMAKE_ARGS="
-DTVM_TIRX_USE_CUDA=ON
-DTVM_TIRX_USE_VULKAN=OFF
-DTVM_TIRX_USE_OPENCL=OFF
- -DTVM_TIRX_USE_LLVM='/usr/bin/llvm-config-15 --link-static'
-DCMAKE_CXX_FLAGS=-Werror
-DCMAKE_CUDA_ARCHITECTURES=75
"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir
dist .
+uv build --wheel --no-build-isolation --offline --out-dir dist .
./build/tirx_cpptest
diff --git a/tests/scripts/task_build_gpu_other.sh
b/tests/scripts/task_build_gpu_other.sh
index 98bb57df1..caa9dcd58 100755
--- a/tests/scripts/task_build_gpu_other.sh
+++ b/tests/scripts/task_build_gpu_other.sh
@@ -20,9 +20,12 @@
set -euxo pipefail
# Keep these libraries separate from the published GPU wheel artifacts.
-uv pip install --python python3 --no-deps --target build/python
./3rdparty/tvm-ffi
-export PYTHONPATH="$PWD/build/python"
-cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+unset PYTHONPATH TVM_LIBRARY_PATH TVM_FFI_LIBRARY_PATH TVM_TIRX_LIBRARY_PATH
+export PYTHONNOUSERSITE=1
+source .venv/bin/activate
+uv sync --only-group build
+uv pip install --no-deps --offline --reinstall dist/apache_tvm_ffi-*.whl
+uv run --no-sync cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo
\
-DTVM_TIRX_USE_OPENCL=ON -DTVM_TIRX_USE_VULKAN=ON -DTVM_TIRX_USE_ROCM=ON \
- -DTVM_TIRX_USE_LLVM='/usr/bin/llvm-config-15 --link-static'
-DCMAKE_CXX_FLAGS=-Werror
-cmake --build build --target tvm_tirx_compiler tvm_runtime_opencl
tvm_runtime_vulkan tvm_runtime_rocm
+ -DCMAKE_CXX_FLAGS=-Werror
+uv run --no-sync cmake --build build --target tvm_tirx_compiler
tvm_runtime_opencl tvm_runtime_vulkan tvm_runtime_rocm
diff --git a/tests/scripts/task_install_build_dependencies.sh
b/tests/scripts/task_install_build_dependencies.sh
index 2b84c57c7..0beed707f 100755
--- a/tests/scripts/task_install_build_dependencies.sh
+++ b/tests/scripts/task_install_build_dependencies.sh
@@ -19,9 +19,10 @@
set -euxo pipefail
rm -rf dist
-uv pip install --python python3 --target .local/python \
- "scikit-build-core>=0.11,!=1.1.0" "setuptools-scm>=8" "cython>=3.2.8"
"mlc-z3-static>=4.16.0"
-export PYTHONPATH="$PWD/.local/python"
-
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir
dist ./3rdparty/tvm-ffi
-uv pip install --python python3 --target .local/python --no-deps --offline
--reinstall dist/apache_tvm_ffi-*.whl
+unset PYTHONPATH TVM_LIBRARY_PATH TVM_FFI_LIBRARY_PATH TVM_TIRX_LIBRARY_PATH
+export PYTHONNOUSERSITE=1
+uv venv --clear --python "$(command -v python3)"
+source .venv/bin/activate
+uv sync --only-group build
+uv build --wheel --no-build-isolation --offline --out-dir dist
./3rdparty/tvm-ffi
+uv pip install --no-deps --offline --reinstall dist/apache_tvm_ffi-*.whl
diff --git a/tests/scripts/task_python_docs.sh
b/tests/scripts/task_python_docs.sh
index 24ac6c611..643293e15 100755
--- a/tests/scripts/task_python_docs.sh
+++ b/tests/scripts/task_python_docs.sh
@@ -18,10 +18,8 @@
set -euxo pipefail
-source ./tests/scripts/test_task_install_dist_wheels.sh
-uv pip install --python python3 --target .local/python --group docs
-export TVM_TIRX_LIBRARY_PATH="$PWD/.local/python/tvm_tirx/lib"
+source ./tests/scripts/test_task_install_dist_wheels.sh --group docs
rm -rf docs/_build docs/reference/python/generated
-BUILD_CPP_DOCS=1 python3 -m sphinx -E -a -b html -d docs/_build/doctrees -W
--keep-going docs docs/_build/html
+BUILD_CPP_DOCS=1 uv run --no-sync python -m sphinx -E -a -b html -d
docs/_build/doctrees -W --keep-going docs docs/_build/html
git rev-parse HEAD > docs/_build/html/commit_hash
tar -czf docs.tgz -C docs/_build/html .
diff --git a/tests/scripts/task_python_unittest.sh
b/tests/scripts/task_python_unittest.sh
index e71f60338..43d26bd58 100755
--- a/tests/scripts/task_python_unittest.sh
+++ b/tests/scripts/task_python_unittest.sh
@@ -22,4 +22,4 @@ export PYTEST_ADDOPTS="${CI_PYTEST_ADD_OPTIONS:-}
${PYTEST_ADDOPTS:-}"
if [ "$#" -eq 0 ]; then
set -- tests/python
fi
-python3 -m pytest -vvs -n auto -o faulthandler_timeout=120 -m
"${TVM_TEST_MARKER:-not gpu}" "$@"
+uv run --no-sync python -m pytest -vvs -n auto -o faulthandler_timeout=120 -m
"${TVM_TEST_MARKER:-not gpu}" "$@"
diff --git a/tests/scripts/test_task_install_dist_wheels.sh
b/tests/scripts/test_task_install_dist_wheels.sh
index c4ddf2992..0ccbe1c92 100755
--- a/tests/scripts/test_task_install_dist_wheels.sh
+++ b/tests/scripts/test_task_install_dist_wheels.sh
@@ -20,7 +20,11 @@ set -euxo pipefail
unset PYTHONPATH TVM_LIBRARY_PATH TVM_FFI_LIBRARY_PATH TVM_TIRX_LIBRARY_PATH
export PYTHONNOUSERSITE=1
-uv pip install --python python3 --target .local/python --no-deps
"apache-tvm-ffi-orcjit>=0.1.2"
-uv pip install --python python3 --target .local/python --no-deps --offline
--reinstall \
+uv venv --clear --python "$(command -v python3)"
+source .venv/bin/activate
+
+# Prepare groups before installing the exact artifacts under test.
+uv sync --no-default-groups --group test \
+ --no-install-project --no-install-package apache-tvm-ffi "$@"
+uv pip install --no-deps --offline --reinstall \
dist/apache_tvm_ffi-*.whl dist/apache_tvm_tirx-*.whl
-export PYTHONPATH="$PWD/.local/python"