tqchen commented on code in PR #19647:
URL: https://github.com/apache/tvm/pull/19647#discussion_r3330176953


##########
ci/scripts/package/before_all_linux.sh:
##########
@@ -0,0 +1,77 @@
+#!/usr/bin/env bash
+# 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.
+#
+# cibuildwheel CIBW_BEFORE_ALL_LINUX hook. It runs once per architecture inside
+# the manylinux build container, before any wheel is built. When a CUDA runtime
+# is requested it installs the pinned CUDA toolkit and builds
+# libtvm_runtime_cuda.so into build-wheel-cuda/, so the subsequent (CPU-only)
+# wheel build can bundle it via -DTVM_PACKAGE_EXTRA_LIBS. It is a no-op for
+# CPU-only wheels. This is the only piece cibuildwheel cannot do itself, since
+# its manylinux container ships no CUDA toolkit.
+#
+# Usage: before_all_linux.sh <include_cuda_runtime: 0|1> <cuda_architectures>
+set -euxo pipefail
+
+include_cuda_runtime="${1:-0}"
+cuda_architectures="${2:-75}"
+
+if [[ "${include_cuda_runtime}" != "1" ]]; then
+  echo "before_all_linux: CUDA runtime not requested; nothing to do."
+  exit 0
+fi
+
+repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
+build_dir="${repo_root}/build-wheel-cuda"
+python_bin="/opt/python/cp310-cp310/bin/python"
+parallel="$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 4)"
+
+# Install the pinned CUDA toolkit into the manylinux_2_28 container. The RHEL8
+# local-repo RPM is compatible with manylinux_2_28 for both x86_64 and aarch64.
+arch="$(uname -m)"
+cuda_rpm="cuda-repo-rhel8-13-0-local-13.0.2_580.95.05-1.${arch}.rpm"
+curl -fsSLo "/tmp/${cuda_rpm}" \
+  
"https://developer.download.nvidia.com/compute/cuda/13.0.2/local_installers/${cuda_rpm}";
+rpm -i "/tmp/${cuda_rpm}"
+dnf clean all
+dnf -y --disablerepo=epel install cuda-toolkit-13-0
+rm -f "/tmp/${cuda_rpm}"
+dnf clean all
+
+# Build the CUDA runtime sidecar with CUDA on and LLVM off, so it does not need
+# the LLVM prefix; the main CPU wheel links LLVM statically. before-all runs
+# before CIBW_BEFORE_BUILD, so install the build tools here.
+export PATH="/opt/python/cp310-cp310/bin:/usr/local/cuda/bin:${PATH}"
+"${python_bin}" -m pip install -U pip cmake ninja
+nvcc --version
+
+rm -rf "${build_dir}"
+cmake -S "${repo_root}" -B "${build_dir}" \
+  -DCMAKE_BUILD_TYPE=Release \
+  -DBUILD_TESTING=OFF \
+  -DTVM_BUILD_PYTHON_MODULE=ON \
+  -DUSE_CUDA=/usr/local/cuda \
+  -DUSE_LLVM=OFF \
+  -DUSE_CUBLAS=OFF -DUSE_CUDNN=OFF -DUSE_CUTLASS=OFF -DUSE_NCCL=OFF 
-DUSE_NVTX=OFF \
+  -DCMAKE_CUDA_ARCHITECTURES="${cuda_architectures}" \

Review Comment:
   Do we need CMAKE_CUDA_ARCHITECTURES, i am not too sure, likely for minimum 
cuda runtime CMAKE_CUDA_ARCHITECTURES is not needed. 
   
   But perhaps Cmake for now need this. so we should add comment that 
CMAKE_CUDA_ARCHITECTURES and CMAKE_CUDA_COMPILER will not impact the resulting 
binary



##########
ci/scripts/package/before_all_linux.sh:
##########
@@ -0,0 +1,77 @@
+#!/usr/bin/env bash
+# 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.
+#
+# cibuildwheel CIBW_BEFORE_ALL_LINUX hook. It runs once per architecture inside
+# the manylinux build container, before any wheel is built. When a CUDA runtime

Review Comment:
   we will also need an action for windows



##########
ci/scripts/package/before_all_linux.sh:
##########
@@ -0,0 +1,77 @@
+#!/usr/bin/env bash
+# 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.
+#
+# cibuildwheel CIBW_BEFORE_ALL_LINUX hook. It runs once per architecture inside
+# the manylinux build container, before any wheel is built. When a CUDA runtime
+# is requested it installs the pinned CUDA toolkit and builds
+# libtvm_runtime_cuda.so into build-wheel-cuda/, so the subsequent (CPU-only)
+# wheel build can bundle it via -DTVM_PACKAGE_EXTRA_LIBS. It is a no-op for
+# CPU-only wheels. This is the only piece cibuildwheel cannot do itself, since
+# its manylinux container ships no CUDA toolkit.
+#
+# Usage: before_all_linux.sh <include_cuda_runtime: 0|1> <cuda_architectures>

Review Comment:
   rename to manylinux_build_libtvm_runtime_cuda.sh



##########
ci/scripts/package/README.md:
##########
@@ -0,0 +1,106 @@
+<!--- 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. -->
+
+# TVM wheel packaging
+
+The TVM wheels are built with `cibuildwheel`. Configuration intrinsic to the
+package lives in `pyproject.toml`; the GitHub Actions workflow only adds the
+per-run environment on top. This directory holds the few helpers `cibuildwheel`
+cannot provide itself.
+
+## Build flow
+
+1. **(Linux CUDA wheels only)** the `CIBW_BEFORE_ALL_LINUX` hook runs
+   `before_all_linux.sh`, which installs the CUDA toolkit inside the manylinux
+   container and builds `libtvm_runtime_cuda.so`.
+2. `cibuildwheel` builds the main wheel with LLVM linked **statically** and 
CUDA
+   off. The prebuilt CUDA runtime is installed into `tvm/lib/` by CMake via
+   `TVM_PACKAGE_EXTRA_LIBS` — no post-build wheel rewriting.
+3. The wheel is repaired with the standard per-platform tool — `auditwheel`
+   (Linux) / `delocate` (macOS) / `delvewheel` (Windows) — excluding 
`libtvm_ffi`
+   (provided by the `apache-tvm-ffi` package) and, on Linux, the bundled
+   `libtvm_runtime_cuda.so` and its CUDA driver dependencies.
+4. The `tests/python/wheel` suite runs against the installed wheel via the
+   `[tool.cibuildwheel]` `test-command`.
+
+The publish workflow builds four wheels — Linux x86_64 and aarch64 (with the
+CUDA runtime, in cibuildwheel's default `manylinux_2_28` image), macOS arm64, 
and
+Windows AMD64 — then optionally uploads them with `pypa/gh-action-pypi-publish`
+and verifies the uploaded package.
+
+## Where configuration lives
+
+Settings intrinsic to the package go in `pyproject.toml`, so they apply to
+*every* build — `pip install .`, a local `cibuildwheel` run, a fork, or an

Review Comment:
   for standard impl notes, should not be part of the README, they may be able 
to go into .claude/skills in future



##########
cmake/utils/Library.cmake:
##########
@@ -0,0 +1,71 @@
+# 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.
+
+# Helpers for configuring library targets.
+
+#######################################################
+# tvm_set_relative_rpath(target_name)
+#
+# Give a target a relative rpath ($ORIGIN / @loader_path) so that sibling
+# shared libraries in the same directory resolve each other regardless of the
+# install location (e.g. inside a Python wheel). No-op if the target does not
+# exist.
+function(tvm_set_relative_rpath target_name)
+  if(NOT TARGET ${target_name})
+    return()
+  endif()
+
+  if(APPLE)
+    set_target_properties(${target_name} PROPERTIES

Review Comment:
   fold tvm_set_relative_rpath and tvm_configure_runtime_module into one
   
   tvm_configure_target_library



##########
pyproject.toml:
##########
@@ -34,55 +39,63 @@ classifiers = [
   "Intended Audience :: Developers",
   "Intended Audience :: Education",
   "Intended Audience :: Science/Research",
-  "License :: OSI Approved :: Apache Software License",
   "Programming Language :: Python :: 3",
-  "Programming Language :: Python :: 3.9",
   "Programming Language :: Python :: 3.10",
   "Programming Language :: Python :: 3.11",
   "Programming Language :: Python :: 3.12",
+  "Programming Language :: Python :: 3.13",
   "Topic :: Scientific/Engineering :: Artificial Intelligence",
   "Topic :: Software Development :: Libraries :: Python Modules",
 ]
-# Core dependencies - these are the minimum required for basic TVM 
functionality
+# Core runtime dependencies: the minimum needed to ``import tvm`` and build/run
+# modules. Model-importer frameworks are kept out of here (see
+# [project.optional-dependencies]). pytest is required at import time because

Review Comment:
   remove implementation notes



##########
pyproject.toml:
##########
@@ -257,32 +247,37 @@ line-ending = "auto"
 docstring-code-format = false
 docstring-code-line-length = "dynamic"
 
-[tool.mypy]
-python_version = "3.9"
-show_error_codes = true
-mypy_path = ["python"]
-files = ["python/tvm"]
-namespace_packages = true
-explicit_package_bases = true
-allow_redefinition = true
-ignore_missing_imports = true
-follow_imports = "skip"
-strict_optional = false
-exclude = '''(?x)(
-    ^\.venv/|
-    ^build/|
-    ^dist/|
-    ^\.mypy_cache/|
-    ^3rdparty/
-)'''
+[tool.cibuildwheel]
+# TVM cannot build 32-bit or musl targets; skip them so a bare `cibuildwheel`
+# invocation (outside the publish matrix) fails fast instead of attempting 
them.

Review Comment:
   just comment skip win32 i386 and musllinux wheels



##########
tests/python/wheel/pytest.ini:
##########
@@ -0,0 +1,23 @@
+# 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.
+
+# Standalone pytest config for the installed-wheel checks. Used with
+# `pytest -c .../pytest.ini` so these tests do not inherit the repository's
+# root pytest config or conftest (which loads tvm.testing.plugin and the full
+# test harness — unnecessary and heavy for a wheel smoke check).
+[pytest]
+addopts = -v

Review Comment:
   this is not needed, instead pyproject.toml should do pytest -v



##########
pyproject.toml:
##########
@@ -92,42 +105,28 @@ dev = [
   "pytest-rerunfailures",
   "pytest-repeat",
 ]
-
-# All optional dependencies (excluding dev)
-all = [
-  "coremltools",
-  "tensorflow",
-  "tensorflow-estimator",
-  "future",
-  "onnx",
-  "onnxoptimizer",
-  "onnxruntime",
-  "torch",
-  "torchvision",
-  "tflite",
-  "paddlepaddle",
-  "xgboost",
-]
-
-[project.urls]
-Homepage = "https://tvm.apache.org/";
-Documentation = "https://tvm.apache.org/docs/";
-Repository = "https://github.com/apache/tvm";
-"Bug Tracker" = "https://github.com/apache/tvm/issues";
+lint = ["ruff", "pre-commit"]
+dev = [{ include-group = "test" }, { include-group = "lint" }]
 
 [tool.scikit-build]
-# Point to the root CMakeLists.txt
-cmake.source-dir = "."
 cmake.build-type = "Release"
 
 # Configure the wheel to be Python version-agnostic
 wheel.py-api = "py3"
 
-# Build configuration
-build-dir = "build"
+# Build configuration. Use a tagged subdirectory so wheel builds do not clobber
+# a developer's top-level ``build/`` (and its compile_commands.json used by
+# clangd), and so builds can be cached per wheel tag.
+build-dir = "build/{wheel_tag}"
 
-# CMake configuration - ensure proper installation paths
-cmake.args = ["-DTVM_BUILD_PYTHON_MODULE=ON"]
+# Static CMake configuration shared by every wheel build. The dynamic bits
+# (the USE_LLVM config path, CMAKE_PREFIX_PATH, and the CUDA 
TVM_PACKAGE_EXTRA_LIBS
+# path) are layered on via CMAKE_ARGS by the publishing workflow. cmake>=3.24 
is
+# required for ZLIB_USE_STATIC_LIBS (see [build-system]).
+cmake.define.TVM_BUILD_PYTHON_MODULE = "ON"

Review Comment:
   use a standard section near the end of [tool.scikit-build] section
   
   [tool.scikit-build.cmake.define]
   TVM_BUILD_PYTHON_MODULE = "ON"
   ...



##########
pyproject.toml:
##########
@@ -257,32 +247,37 @@ line-ending = "auto"
 docstring-code-format = false
 docstring-code-line-length = "dynamic"
 
-[tool.mypy]
-python_version = "3.9"
-show_error_codes = true
-mypy_path = ["python"]
-files = ["python/tvm"]
-namespace_packages = true
-explicit_package_bases = true
-allow_redefinition = true
-ignore_missing_imports = true
-follow_imports = "skip"
-strict_optional = false
-exclude = '''(?x)(
-    ^\.venv/|
-    ^build/|
-    ^dist/|
-    ^\.mypy_cache/|
-    ^3rdparty/
-)'''
+[tool.cibuildwheel]
+# TVM cannot build 32-bit or musl targets; skip them so a bare `cibuildwheel`
+# invocation (outside the publish matrix) fails fast instead of attempting 
them.
+# The workflow matrix selects the real per-platform targets via CIBW_BUILD.
+skip = "*-win32 *-manylinux_i686 *-musllinux*"
+build-verbosity = 1
+# Verify the installed wheel with a small pytest suite (post-install checks
+# such as the LLVM compile smoke test and the static-LLVM / CUDA-runtime
+# library checks). The wheel-specific expectations are passed through the
+# environment by the publishing workflow.
+test-requires = ["pytest", "numpy"]
+# Use the suite's own pytest.ini (-c) so it does not inherit the repository's
+# root pytest config/conftest, which loads tvm.testing.plugin and the full test
+# harness — too heavy for a wheel smoke check.
+test-command = "pytest -c {project}/tests/python/wheel/pytest.ini 
{project}/tests/python/wheel"
 
-[[tool.mypy.overrides]]
-module = ["python.tvm.auto_scheduler.*"]
-ignore_errors = true
+# Per-platform build and repair steps live here (the standard cibuildwheel
+# location, mirroring tvm-ffi). The publishing workflow only layers the dynamic
+# environment (LLVM config path, CUDA runtime, dist name/version) on top.
+# set_wheel_dist.py applies the optional TestPyPI name/version override; the
+# vendored tvm-ffi is the build-time FFI dependency. auditwheel (manylinux
+# image) and delocate (cibuildwheel) are already present; only delvewheel must
+# be installed for the Windows repair.
+[tool.cibuildwheel.linux]
+before-build = 'if command -v dnf >/dev/null 2>&1; then dnf -y install 
libxml2-devel; fi && python {project}/ci/scripts/package/set_wheel_dist.py 
{project}/pyproject.toml && python -m pip install -v {project}/3rdparty/tvm-ffi'
+repair-wheel-command = "auditwheel repair --exclude libtvm_ffi.so --exclude 
libtvm_runtime_cuda.so --exclude 'libcuda.so.*' --exclude 'libcudart.so.*' 
--exclude 'libnvrtc.so.*' --exclude 'libnvrtc-builtins.so.*' -w {dest_dir} 
{wheel}"
 
-[[tool.mypy.overrides]]
-module = ["python.tvm.runtime.*"]
-ignore_errors = true
+[tool.cibuildwheel.macos]
+before-build = 'python {project}/ci/scripts/package/set_wheel_dist.py 
{project}/pyproject.toml && python -m pip install -v {project}/3rdparty/tvm-ffi'
+repair-wheel-command = 
'DYLD_LIBRARY_PATH="/opt/llvm/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}" 
delocate-wheel --ignore-missing-dependencies --exclude libtvm_ffi.dylib 
--require-archs {delocate_archs} -w {dest_dir} -v {wheel}'
 
-[dependency-groups]
-lint = ["pre-commit"]
+[tool.cibuildwheel.windows]
+before-build = 'python -m pip install delvewheel && python 
{project}/ci/scripts/package/set_wheel_dist.py {project}/pyproject.toml && 
python -m pip install -v {project}/3rdparty/tvm-ffi'
+repair-wheel-command = "delvewheel repair --analyze-existing --ignore-existing 
--add-path C:/opt/llvm/Library/bin --exclude tvm_ffi.dll --exclude 
libtvm_ffi.dll -w {dest_dir} {wheel}"

Review Comment:
    C:/opt/llvm/Library/bin should not be needed for static linking



##########
tests/python/wheel/pytest.ini:
##########
@@ -0,0 +1,23 @@
+# 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.
+
+# Standalone pytest config for the installed-wheel checks. Used with
+# `pytest -c .../pytest.ini` so these tests do not inherit the repository's
+# root pytest config or conftest (which loads tvm.testing.plugin and the full
+# test harness — unnecessary and heavy for a wheel smoke check).

Review Comment:
   remove this and instead use pytest -p no:tvm.testing.plugin -vvs



##########
tests/python/wheel/test_wheel.py:
##########
@@ -0,0 +1,91 @@
+# 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.
+"""Post-install checks for a built TVM wheel.
+
+Run by cibuildwheel against the installed wheel (``test-command`` in
+``[tool.cibuildwheel]``). Each check is opt-in via an environment variable so
+the same tests apply across the wheel matrix: when the variable is unset the
+check is skipped.
+"""
+
+import glob
+import os
+from pathlib import Path
+
+import pytest
+
+import tvm
+
+
+def _expect(name):
+    """Return True/False for an expectation env var, or None when unset."""
+    value = os.environ.get(name, "")
+    if value == "":
+        return None
+    return value.strip().lower() in ("1", "true", "yes", "on")
+
+
+def _libdir():
+    return Path(tvm.__file__).resolve().parent / "lib"
+
+
+def test_llvm_compile():

Review Comment:
   just test llvm presence, the tests below is covered by other all platform 
minimum tests



##########
ci/scripts/package/README.md:
##########
@@ -0,0 +1,106 @@
+<!--- 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. -->
+
+# TVM wheel packaging

Review Comment:
   Simplify this file, since we are now mostly standard flow, most info should 
be present in the github action and pyproject.toml
   
   Simply note helper scripts for wheel packaging



##########
.github/workflows/publish_wheel.yml:
##########
@@ -0,0 +1,269 @@
+# 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: Publish TVM wheels
+
+on:
+  workflow_dispatch:
+    inputs:
+      tag:
+        description: "Tag, branch, or SHA to build; PyPI publishes require 
refs/tags/<tag>"
+        required: true
+        type: string
+      publish_repository:
+        description: "Where to publish after the wheel build succeeds"
+        required: true
+        default: "none"
+        type: choice
+        options:
+          - none
+          - testpypi
+          - pypi
+      distribution_name:
+        description: "Optional package name override, e.g. tvm-yourname-test 
for TestPyPI"
+        required: false
+        default: ""
+        type: string
+      distribution_version:
+        description: "Optional package version override for TestPyPI 
validation builds"
+        required: false
+        default: ""
+        type: string
+      cuda_architectures:
+        description: "CMake CUDA architectures for libtvm_runtime_cuda.so"
+        required: false
+        default: "75"
+        type: string
+      verify_from_repository:
+        description: "Install the uploaded package from the selected 
repository and import-test it"
+        required: true
+        default: true
+        type: boolean
+
+permissions:
+  contents: read
+
+jobs:
+  build_wheels:
+    name: ${{ matrix.name }}
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        include:
+          - name: "Linux x86_64 wheel with CUDA runtime (manylinux_2_28)"
+            os: ubuntu-latest
+            arch: x86_64
+            build: cp310-manylinux_x86_64
+            include_cuda_runtime: "1"
+            artifact_suffix: linux-x86_64-manylinux_2_28
+          - name: "Linux aarch64 wheel with CUDA runtime (manylinux_2_28)"
+            os: ubuntu-24.04-arm
+            arch: aarch64
+            build: cp310-manylinux_aarch64
+            include_cuda_runtime: "1"
+            artifact_suffix: linux-aarch64-manylinux_2_28
+          - name: "macOS arm64 CPU wheel"
+            os: macos-14
+            arch: arm64
+            build: cp310-macosx_arm64
+            include_cuda_runtime: "0"
+            artifact_suffix: macos-arm64
+          - name: "Windows AMD64 CPU wheel"
+            os: windows-latest
+            arch: AMD64
+            build: cp310-win_amd64

Review Comment:
   windows needs to include cuda runtime



##########
pyproject.toml:
##########
@@ -257,32 +247,37 @@ line-ending = "auto"
 docstring-code-format = false
 docstring-code-line-length = "dynamic"
 
-[tool.mypy]
-python_version = "3.9"
-show_error_codes = true
-mypy_path = ["python"]
-files = ["python/tvm"]
-namespace_packages = true
-explicit_package_bases = true
-allow_redefinition = true
-ignore_missing_imports = true
-follow_imports = "skip"
-strict_optional = false
-exclude = '''(?x)(
-    ^\.venv/|
-    ^build/|
-    ^dist/|
-    ^\.mypy_cache/|
-    ^3rdparty/
-)'''
+[tool.cibuildwheel]
+# TVM cannot build 32-bit or musl targets; skip them so a bare `cibuildwheel`
+# invocation (outside the publish matrix) fails fast instead of attempting 
them.
+# The workflow matrix selects the real per-platform targets via CIBW_BUILD.
+skip = "*-win32 *-manylinux_i686 *-musllinux*"
+build-verbosity = 1
+# Verify the installed wheel with a small pytest suite (post-install checks
+# such as the LLVM compile smoke test and the static-LLVM / CUDA-runtime
+# library checks). The wheel-specific expectations are passed through the
+# environment by the publishing workflow.
+test-requires = ["pytest", "numpy"]
+# Use the suite's own pytest.ini (-c) so it does not inherit the repository's
+# root pytest config/conftest, which loads tvm.testing.plugin and the full test
+# harness — too heavy for a wheel smoke check.
+test-command = "pytest -c {project}/tests/python/wheel/pytest.ini 
{project}/tests/python/wheel"

Review Comment:
   also try add allplatform-minimum-test



##########
ci/scripts/package/set_wheel_dist.py:
##########
@@ -0,0 +1,60 @@
+# 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.
+"""Apply optional distribution name/version overrides to ``[project]``.
+
+Used by the publishing flow (e.g. TestPyPI validation builds) so the wheel is
+produced with the desired name/version directly by the build backend, instead
+of rewriting the finished wheel. Reads ``TVM_WHEEL_DIST_NAME`` and
+``TVM_WHEEL_DIST_VERSION`` from the environment; missing/empty values are left
+unchanged. A no-op when neither is set.
+"""
+
+import os
+import re
+import sys
+
+
+def _replace(text, key, value):
+    # Replace the first ``key = "..."`` entry in the [project] table.
+    pattern = re.compile(rf'(?m)^(\s*{key}\s*=\s*)"[^"]*"')
+    new, n = pattern.subn(rf'\g<1>"{value}"', text, count=1)
+    if n != 1:
+        raise SystemExit(f"set_wheel_dist: could not find a single '{key}' 
entry to override")
+    return new
+
+
+def main():
+    pyproject = sys.argv[1]
+    name = os.environ.get("TVM_WHEEL_DIST_NAME", "").strip()
+    version = os.environ.get("TVM_WHEEL_DIST_VERSION", "").strip()

Review Comment:
   should be removed, for downstream testing, they should modify pyproject.toml



##########
pyproject.toml:
##########
@@ -257,32 +247,37 @@ line-ending = "auto"
 docstring-code-format = false
 docstring-code-line-length = "dynamic"
 
-[tool.mypy]
-python_version = "3.9"
-show_error_codes = true
-mypy_path = ["python"]
-files = ["python/tvm"]
-namespace_packages = true
-explicit_package_bases = true
-allow_redefinition = true
-ignore_missing_imports = true
-follow_imports = "skip"
-strict_optional = false
-exclude = '''(?x)(
-    ^\.venv/|
-    ^build/|
-    ^dist/|
-    ^\.mypy_cache/|
-    ^3rdparty/
-)'''
+[tool.cibuildwheel]
+# TVM cannot build 32-bit or musl targets; skip them so a bare `cibuildwheel`
+# invocation (outside the publish matrix) fails fast instead of attempting 
them.
+# The workflow matrix selects the real per-platform targets via CIBW_BUILD.
+skip = "*-win32 *-manylinux_i686 *-musllinux*"
+build-verbosity = 1
+# Verify the installed wheel with a small pytest suite (post-install checks
+# such as the LLVM compile smoke test and the static-LLVM / CUDA-runtime
+# library checks). The wheel-specific expectations are passed through the
+# environment by the publishing workflow.
+test-requires = ["pytest", "numpy"]
+# Use the suite's own pytest.ini (-c) so it does not inherit the repository's
+# root pytest config/conftest, which loads tvm.testing.plugin and the full test
+# harness — too heavy for a wheel smoke check.
+test-command = "pytest -c {project}/tests/python/wheel/pytest.ini 
{project}/tests/python/wheel"
 
-[[tool.mypy.overrides]]
-module = ["python.tvm.auto_scheduler.*"]
-ignore_errors = true
+# Per-platform build and repair steps live here (the standard cibuildwheel
+# location, mirroring tvm-ffi). The publishing workflow only layers the dynamic
+# environment (LLVM config path, CUDA runtime, dist name/version) on top.
+# set_wheel_dist.py applies the optional TestPyPI name/version override; the
+# vendored tvm-ffi is the build-time FFI dependency. auditwheel (manylinux
+# image) and delocate (cibuildwheel) are already present; only delvewheel must
+# be installed for the Windows repair.
+[tool.cibuildwheel.linux]
+before-build = 'if command -v dnf >/dev/null 2>&1; then dnf -y install 
libxml2-devel; fi && python {project}/ci/scripts/package/set_wheel_dist.py 
{project}/pyproject.toml && python -m pip install -v {project}/3rdparty/tvm-ffi'

Review Comment:
   then dnf -y install libxml2-devel; i assume libxml comes from conda env? if 
static lib can come from there would be great to not rely on libxml2-devel and 
do static bundle so it is more portable.
   
   set_wheel_dist.py should be removed
   
   is  python -m pip install -v {project}/3rdparty/tvm-ffi needed?
   
   since build do not need tvm-ffi, and wheel test should have apache-tvm-ffi 
installed as a dep



##########
tests/conda/build-environment.yaml:
##########
@@ -33,6 +33,8 @@ dependencies:
   - pip
   - git
   - bzip2
+  - zlib

Review Comment:
   move this to ci/scripts/package/build-environment.yaml



##########
pyproject.toml:
##########
@@ -257,32 +247,37 @@ line-ending = "auto"
 docstring-code-format = false
 docstring-code-line-length = "dynamic"
 
-[tool.mypy]
-python_version = "3.9"
-show_error_codes = true
-mypy_path = ["python"]
-files = ["python/tvm"]
-namespace_packages = true
-explicit_package_bases = true
-allow_redefinition = true
-ignore_missing_imports = true
-follow_imports = "skip"
-strict_optional = false
-exclude = '''(?x)(
-    ^\.venv/|
-    ^build/|
-    ^dist/|
-    ^\.mypy_cache/|
-    ^3rdparty/
-)'''
+[tool.cibuildwheel]
+# TVM cannot build 32-bit or musl targets; skip them so a bare `cibuildwheel`
+# invocation (outside the publish matrix) fails fast instead of attempting 
them.
+# The workflow matrix selects the real per-platform targets via CIBW_BUILD.
+skip = "*-win32 *-manylinux_i686 *-musllinux*"
+build-verbosity = 1
+# Verify the installed wheel with a small pytest suite (post-install checks
+# such as the LLVM compile smoke test and the static-LLVM / CUDA-runtime
+# library checks). The wheel-specific expectations are passed through the
+# environment by the publishing workflow.
+test-requires = ["pytest", "numpy"]
+# Use the suite's own pytest.ini (-c) so it does not inherit the repository's
+# root pytest config/conftest, which loads tvm.testing.plugin and the full test
+# harness — too heavy for a wheel smoke check.
+test-command = "pytest -c {project}/tests/python/wheel/pytest.ini 
{project}/tests/python/wheel"
 
-[[tool.mypy.overrides]]
-module = ["python.tvm.auto_scheduler.*"]
-ignore_errors = true
+# Per-platform build and repair steps live here (the standard cibuildwheel
+# location, mirroring tvm-ffi). The publishing workflow only layers the dynamic
+# environment (LLVM config path, CUDA runtime, dist name/version) on top.
+# set_wheel_dist.py applies the optional TestPyPI name/version override; the
+# vendored tvm-ffi is the build-time FFI dependency. auditwheel (manylinux
+# image) and delocate (cibuildwheel) are already present; only delvewheel must
+# be installed for the Windows repair.
+[tool.cibuildwheel.linux]
+before-build = 'if command -v dnf >/dev/null 2>&1; then dnf -y install 
libxml2-devel; fi && python {project}/ci/scripts/package/set_wheel_dist.py 
{project}/pyproject.toml && python -m pip install -v {project}/3rdparty/tvm-ffi'
+repair-wheel-command = "auditwheel repair --exclude libtvm_ffi.so --exclude 
libtvm_runtime_cuda.so --exclude 'libcuda.so.*' --exclude 'libcudart.so.*' 
--exclude 'libnvrtc.so.*' --exclude 'libnvrtc-builtins.so.*' -w {dest_dir} 
{wheel}"
 
-[[tool.mypy.overrides]]
-module = ["python.tvm.runtime.*"]
-ignore_errors = true
+[tool.cibuildwheel.macos]
+before-build = 'python {project}/ci/scripts/package/set_wheel_dist.py 
{project}/pyproject.toml && python -m pip install -v {project}/3rdparty/tvm-ffi'
+repair-wheel-command = 
'DYLD_LIBRARY_PATH="/opt/llvm/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}" 
delocate-wheel --ignore-missing-dependencies --exclude libtvm_ffi.dylib 
--require-archs {delocate_archs} -w {dest_dir} -v {wheel}'

Review Comment:
   DYLD_LIBRARY_PATH should not be needed, if it is needed, likely we are 
linking in some dynamic libs, all links should be static linking



##########
pyproject.toml:
##########
@@ -257,32 +247,37 @@ line-ending = "auto"
 docstring-code-format = false
 docstring-code-line-length = "dynamic"
 
-[tool.mypy]
-python_version = "3.9"
-show_error_codes = true
-mypy_path = ["python"]
-files = ["python/tvm"]
-namespace_packages = true
-explicit_package_bases = true
-allow_redefinition = true
-ignore_missing_imports = true
-follow_imports = "skip"
-strict_optional = false
-exclude = '''(?x)(
-    ^\.venv/|
-    ^build/|
-    ^dist/|
-    ^\.mypy_cache/|
-    ^3rdparty/
-)'''
+[tool.cibuildwheel]
+# TVM cannot build 32-bit or musl targets; skip them so a bare `cibuildwheel`
+# invocation (outside the publish matrix) fails fast instead of attempting 
them.
+# The workflow matrix selects the real per-platform targets via CIBW_BUILD.
+skip = "*-win32 *-manylinux_i686 *-musllinux*"
+build-verbosity = 1
+# Verify the installed wheel with a small pytest suite (post-install checks
+# such as the LLVM compile smoke test and the static-LLVM / CUDA-runtime
+# library checks). The wheel-specific expectations are passed through the
+# environment by the publishing workflow.
+test-requires = ["pytest", "numpy"]
+# Use the suite's own pytest.ini (-c) so it does not inherit the repository's
+# root pytest config/conftest, which loads tvm.testing.plugin and the full test
+# harness — too heavy for a wheel smoke check.
+test-command = "pytest -c {project}/tests/python/wheel/pytest.ini 
{project}/tests/python/wheel"

Review Comment:
   try instead
   
   ```
   pytest -p no:tvm.testing.plugin -vvs {project}/tests/python/wheel
   ```



##########
tests/python/wheel/test_wheel.py:
##########
@@ -0,0 +1,91 @@
+# 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.
+"""Post-install checks for a built TVM wheel.
+
+Run by cibuildwheel against the installed wheel (``test-command`` in
+``[tool.cibuildwheel]``). Each check is opt-in via an environment variable so
+the same tests apply across the wheel matrix: when the variable is unset the
+check is skipped.
+"""
+
+import glob
+import os
+from pathlib import Path
+
+import pytest
+
+import tvm
+
+
+def _expect(name):
+    """Return True/False for an expectation env var, or None when unset."""
+    value = os.environ.get(name, "")
+    if value == "":
+        return None
+    return value.strip().lower() in ("1", "true", "yes", "on")
+
+
+def _libdir():
+    return Path(tvm.__file__).resolve().parent / "lib"
+
+
+def test_llvm_compile():
+    """import tvm and run a minimal LLVM compile+execute."""
+    if _expect("TVM_EXPECT_LLVM_ENABLED") is False:
+        pytest.skip("LLVM not expected in this wheel")
+    if not tvm.runtime.enabled("llvm"):
+        if _expect("TVM_EXPECT_LLVM_ENABLED"):
+            pytest.fail("llvm runtime expected but not enabled")
+        pytest.skip("llvm runtime not enabled")
+
+    import numpy as np
+
+    from tvm import te
+
+    n = 8
+    a = te.placeholder((n,), name="a", dtype="float32")
+    b = te.placeholder((n,), name="b", dtype="float32")
+    c = te.compute((n,), lambda i: a[i] + b[i], name="c")
+    exe = tvm.compile(te.create_prim_func([a, b, c]), target="llvm")
+
+    dev = tvm.cpu()
+    a_nd = tvm.runtime.tensor(np.arange(n, dtype="float32"), dev)
+    b_nd = tvm.runtime.tensor(np.arange(n, dtype="float32") * 2, dev)
+    c_nd = tvm.runtime.tensor(np.zeros(n, dtype="float32"), dev)
+    exe(a_nd, b_nd, c_nd)
+    np.testing.assert_allclose(c_nd.numpy(), a_nd.numpy() + b_nd.numpy(), 
rtol=1e-6)
+
+
+def test_no_dynamic_llvm():
+    """When static LLVM is expected, the wheel must not ship a dynamic 
libLLVM."""

Review Comment:
   this is not needed and should be covered by all platform minimum test as 
long as we remove llvm from search path



##########
tests/python/wheel/test_wheel.py:
##########
@@ -0,0 +1,91 @@
+# 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.
+"""Post-install checks for a built TVM wheel.
+
+Run by cibuildwheel against the installed wheel (``test-command`` in
+``[tool.cibuildwheel]``). Each check is opt-in via an environment variable so
+the same tests apply across the wheel matrix: when the variable is unset the
+check is skipped.
+"""
+
+import glob
+import os
+from pathlib import Path
+
+import pytest
+
+import tvm
+
+
+def _expect(name):
+    """Return True/False for an expectation env var, or None when unset."""

Review Comment:
   keep logic simple just TVM_WHEEL_EXPECT_CUDA_RUNTIME=1, no other cases



##########
tests/python/wheel/test_wheel.py:
##########
@@ -0,0 +1,91 @@
+# 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.
+"""Post-install checks for a built TVM wheel.
+
+Run by cibuildwheel against the installed wheel (``test-command`` in
+``[tool.cibuildwheel]``). Each check is opt-in via an environment variable so
+the same tests apply across the wheel matrix: when the variable is unset the
+check is skipped.
+"""
+
+import glob
+import os
+from pathlib import Path
+
+import pytest
+
+import tvm
+
+
+def _expect(name):
+    """Return True/False for an expectation env var, or None when unset."""
+    value = os.environ.get(name, "")
+    if value == "":
+        return None
+    return value.strip().lower() in ("1", "true", "yes", "on")
+
+
+def _libdir():
+    return Path(tvm.__file__).resolve().parent / "lib"
+
+
+def test_llvm_compile():
+    """import tvm and run a minimal LLVM compile+execute."""
+    if _expect("TVM_EXPECT_LLVM_ENABLED") is False:
+        pytest.skip("LLVM not expected in this wheel")
+    if not tvm.runtime.enabled("llvm"):
+        if _expect("TVM_EXPECT_LLVM_ENABLED"):
+            pytest.fail("llvm runtime expected but not enabled")
+        pytest.skip("llvm runtime not enabled")
+
+    import numpy as np
+
+    from tvm import te
+
+    n = 8
+    a = te.placeholder((n,), name="a", dtype="float32")
+    b = te.placeholder((n,), name="b", dtype="float32")
+    c = te.compute((n,), lambda i: a[i] + b[i], name="c")
+    exe = tvm.compile(te.create_prim_func([a, b, c]), target="llvm")

Review Comment:
   remove this test, try to have test run all platform minimum test



##########
tests/python/wheel/test_wheel.py:
##########
@@ -0,0 +1,91 @@
+# 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.

Review Comment:
   test_validate_runtime_library.py 
   
   This file validatdes installation settings, only needed for cuda, consider 
merging into all-platform-minimum test
   
   



##########
tests/python/wheel/conftest.py:
##########
@@ -0,0 +1,26 @@
+# 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.
+"""Ensure the wheel checks load libraries from the installed wheel.
+
+Development library-path overrides are dropped before tvm is imported so the
+bundled libraries are used rather than any from a local build tree.
+"""
+
+import os
+
+for _name in ("TVM_LIBRARY_PATH", "LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH"):

Review Comment:
   remove this, since common cibw test don't have extra things in lib



##########
.github/workflows/publish_wheel.yml:
##########
@@ -0,0 +1,269 @@
+# 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: Publish TVM wheels
+
+on:
+  workflow_dispatch:
+    inputs:
+      tag:
+        description: "Tag, branch, or SHA to build; PyPI publishes require 
refs/tags/<tag>"
+        required: true
+        type: string
+      publish_repository:

Review Comment:
   remove extra configs most can be hard coded, and use default, downstream can 
modify the files inplace to update settings



##########
.github/actions/build-wheel-for-publish/action.yml:
##########
@@ -0,0 +1,157 @@
+# 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: Build TVM Wheel
+description: >
+  Build and test the LLVM-enabled TVM wheel for a given OS/architecture
+  combination using cibuildwheel.
+
+inputs:
+  arch:
+    description: "Target architecture for cibuildwheel (e.g., x86_64, aarch64, 
arm64, AMD64)"
+    required: true
+  build:
+    description: "cibuildwheel build selector (e.g., cp310-manylinux_x86_64)"
+    required: true
+  distribution_name:
+    description: "Optional wheel distribution name override, useful for 
TestPyPI"
+    required: false
+    default: ""
+  distribution_version:
+    description: "Optional wheel distribution version override, useful for 
TestPyPI"
+    required: false
+    default: ""
+  cuda_architectures:
+    description: "CMake CUDA architectures for libtvm_runtime_cuda.so"
+    required: false
+    default: "75"
+  include_cuda_runtime:
+    description: "Set to 1 to build and inject the CUDA runtime library (Linux 
only)"
+    required: false
+    default: "0"
+
+runs:
+  using: "composite"
+  steps:
+    - uses: ./.github/actions/detect-env-vars
+      id: env_vars
+
+    # 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/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+      id: llvm-cache
+      with:
+        path: ${{ runner.os == 'Windows' && 'C:/opt/llvm' || '/opt/llvm' }}
+        key: tvm-wheel-llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ 
inputs.arch }}-v4
+
+    # ---- Install LLVM via conda (cache miss only) ----
+    - name: Setup conda
+      if: steps.llvm-cache.outputs.cache-hit != 'true'
+      uses: 
conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # 
v4.0.1
+      continue-on-error: true
+      id: conda1
+      with:
+        miniforge-version: latest
+        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/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # 
v4.0.1
+      with:
+        miniforge-version: latest
+        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: |
+        conda create -q -p C:\opt\llvm -c conda-forge llvmdev=%LLVM_VERSION% 
zlib zstd-static libxml2-devel -y
+
+    # ---- Build and test wheels ----
+    - name: Build and test wheels
+      uses: pypa/cibuildwheel@298ed2fb2c105540f5ed055e8a6ad78d82dd3a7e # v3.3.1
+      with:
+        package-dir: .
+        output-dir: wheelhouse
+      env:
+        CIBW_BUILD: ${{ inputs.build }}
+        CIBW_ARCHS_LINUX: ${{ inputs.arch }}
+        CIBW_ARCHS_MACOS: ${{ inputs.arch }}
+        CIBW_ARCHS_WINDOWS: ${{ inputs.arch }}
+        CMAKE_BUILD_PARALLEL_LEVEL: ${{ steps.env_vars.outputs.cpu_count }}
+        # 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"
+        # Build the CUDA runtime sidecar once per architecture inside the
+        # manylinux build container (no-op for CPU-only wheels). The CPU wheel
+        # build then bundles the resulting libtvm_runtime_cuda.so via
+        # -DTVM_PACKAGE_EXTRA_LIBS. Replaces the separate build-cuda docker 
job.
+        CIBW_BEFORE_ALL_LINUX: >-
+          bash {project}/ci/scripts/package/before_all_linux.sh
+          "${{ inputs.include_cuda_runtime }}"

Review Comment:
   consider move cuda runtime installation into a separate stage,and have linux 
wheel build depend on that stage. 
   
   If we are linux only this one actually works well. Main issue is we also 
need to support windows build, and likely windows libtvm_runtime_cuda build 
would needs to be its own stage. So to sumup splitting cuda runtime into its 
own stage likely works better



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to