From 76ec195e1993de8a21f09f1fa795114614909016 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Thu, 23 Jul 2026 01:55:53 -0400 Subject: [PATCH 01/39] Split pip packaging into halide + halide-bin libHalide, the autoschedulers, and the generator tools were bundled into every per-Python-version wheel, so cibuildwheel rebuilt the entire LLVM-linked library from scratch once per CPython ABI per platform (~20 full builds today). Split the binary components into a new halide-bin wheel (py3-none-, built once per platform) that halide now depends on and links against via find_package(Halide), so halide's own per-version build is just the pybind11 extension. A plain `pip install .` is unaffected: the split only activates when HALIDE_SPLIT_BUILD=1 is set, which only CI does. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/pip.yml | 201 +++++++++++++++++- packaging/pip-bin/pyproject.toml | 69 ++++++ packaging/pip-bin/src/halide_bin/__init__.py | 5 + packaging/pip/CMakeLists.txt | 4 +- packaging/pip/TrampolineConfig.cmake.in | 2 +- packaging/pip/_dynamic_metadata.py | 71 +++++++ pyproject.toml | 29 ++- python_bindings/packaging/CMakeLists.txt | 8 + python_bindings/packaging/pip/CMakeLists.txt | 19 ++ .../packaging/pip/TrampolineConfig.cmake.in | 5 + python_bindings/src/halide/__init__.py | 21 +- 11 files changed, 412 insertions(+), 22 deletions(-) create mode 100644 packaging/pip-bin/pyproject.toml create mode 100644 packaging/pip-bin/src/halide_bin/__init__.py create mode 100644 packaging/pip/_dynamic_metadata.py create mode 100644 python_bindings/packaging/pip/CMakeLists.txt create mode 100644 python_bindings/packaging/pip/TrampolineConfig.cmake.in diff --git a/.github/workflows/pip.yml b/.github/workflows/pip.yml index ce846083e729..ec551a58f985 100644 --- a/.github/workflows/pip.yml +++ b/.github/workflows/pip.yml @@ -20,8 +20,8 @@ permissions: contents: read # to fetch code (actions/checkout) jobs: - build-wheels: - name: Build Halide wheels for ${{ matrix.platform_tag }} + build-halide-bin: + name: Build halide-bin for ${{ matrix.platform_tag }} runs-on: ${{ matrix.os }} strategy: @@ -64,7 +64,10 @@ jobs: echo "Halide_LLVM_ROOT=$(halide-llvm --prefix)" >> "$GITHUB_ENV" ######################################################################## - # Wheels + # Wheel (no CPython ABI to matrix over -- halide-bin is a plain + # py3-none- wheel, so we only ever need to invoke + # cibuildwheel against a single, arbitrary interpreter to drive the + # underlying CMake build once per platform). ######################################################################## #- uses: mxschmitt/action-tmate@v3 @@ -130,17 +133,114 @@ jobs: CIBW_ENVIRONMENT_LINUX: > Halide_LLVM_ROOT=/project/opt/llvm CMAKE_PREFIX_PATH=/project/opt - SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE='{local_scheme="no-local-version"}' + SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE_BIN='{local_scheme="no-local-version"}' CIBW_ENVIRONMENT_MACOS: > CMAKE_PREFIX_PATH='${{ github.workspace }}/opt' Python_ROOT_DIR='' - SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE='{local_scheme="no-local-version"}' + SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE_BIN='{local_scheme="no-local-version"}' CIBW_ENVIRONMENT_WINDOWS: > CMAKE_GENERATOR=Ninja CMAKE_PREFIX_PATH='${{ github.workspace }}\opt' - SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE='{local_scheme="no-local-version"}' + SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE_BIN='{local_scheme="no-local-version"}' CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: delvewheel repair --ignore-existing -w {dest_dir} {wheel} - CIBW_BEFORE_TEST_LINUX: pip install cmake ninja + + - uses: actions/upload-artifact@v7 + with: + name: wheels-bin-${{ matrix.platform_tag }} + path: ./wheelhouse/*.whl + + build-wheels: + name: Build Halide wheels for ${{ matrix.platform_tag }} + needs: build-halide-bin + + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + platform_tag: manylinux_x86_64 + - os: windows-latest + platform_tag: win_amd64 + - os: macos-15-intel + platform_tag: macosx_x86_64 + - os: macos-15 + platform_tag: macosx_arm64 + + env: + MACOSX_DEPLOYMENT_TARGET: 11 + HALIDE_SPLIT_BUILD: "1" + + steps: + - uses: actions/checkout@v7 + with: + fetch-depth: 0 + fetch-tags: true + + - uses: ilammy/msvc-dev-cmd@v1 + - uses: lukka/get-cmake@v4.4.0 + with: + cmakeVersion: "~3.28.0" + + ######################################################################## + # halide-bin + # + # Building the Python bindings no longer needs LLVM/FlatBuffers/WABT at + # all -- it links against an already-installed halide-bin via + # find_package(Halide). Fetch the wheel this platform's + # build-halide-bin job just produced, and unpack a copy of it so + # CMAKE_PREFIX_PATH can point straight at a real directory (as opposed + # to a still-zipped wheel). + ######################################################################## + + - uses: actions/download-artifact@v8 + with: + name: wheels-bin-${{ matrix.platform_tag }} + path: dist-bin + + - name: Unpack halide-bin for the build + shell: bash + run: python -m zipfile -e dist-bin/*.whl opt/halide-bin + + ######################################################################## + # Wheels + ######################################################################## + + #- uses: mxschmitt/action-tmate@v3 + + - name: Build wheels + uses: pypa/cibuildwheel@v4.1.1 + env: + CIBW_BUILD: "cp3*-${{ matrix.platform_tag }}" + CIBW_SKIP: "cp3{5,6,7,8,9}* cp314t-*" + CIBW_ENVIRONMENT_LINUX: > + CMAKE_PREFIX_PATH=/project/opt/halide-bin/halide_bin/data + SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE='{local_scheme="no-local-version"}' + CIBW_ENVIRONMENT_MACOS: > + CMAKE_PREFIX_PATH='${{ github.workspace }}/opt/halide-bin/halide_bin/data' + Python_ROOT_DIR='' + SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE='{local_scheme="no-local-version"}' + CIBW_ENVIRONMENT_WINDOWS: > + CMAKE_GENERATOR=Ninja + CMAKE_PREFIX_PATH='${{ github.workspace }}\opt\halide-bin\halide_bin\data' + SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE='{local_scheme="no-local-version"}' + # halide_.pyd/.so now depends on a Halide.dll/libHalide supplied by the + # already-installed halide-bin package, not one bundled in this wheel -- + # `--exclude` stops delvewheel from vendoring a second copy of it, while + # `--add-path` lets its dependency scan actually resolve it. + CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: > + delvewheel repair --ignore-existing --exclude Halide.dll + --add-path '${{ github.workspace }}\opt\halide-bin\halide_bin\data\bin' + -w {dest_dir} {wheel} + # halide-bin isn't published yet during this CI run, so resolve it + # from the wheel we just downloaded instead of the package index. + # Linux additionally needs cmake/ninja installed into the (otherwise + # bare) per-wheel manylinux test container -- macOS/Windows already + # have them on PATH via the get-cmake action above. + CIBW_BEFORE_TEST_LINUX: > + pip install cmake ninja && + pip install --no-index --find-links {project}/dist-bin halide-bin + CIBW_BEFORE_TEST: pip install --no-index --find-links {project}/dist-bin halide-bin CIBW_TEST_COMMAND: > cmake -G Ninja -S {project}/python_bindings/apps -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build && @@ -156,9 +256,94 @@ jobs: name: wheels-${{ matrix.platform_tag }} path: ./wheelhouse/*.whl + build-runtime-wheels: + name: Build halide-runtime wheels for ${{ matrix.platform_tag }} + needs: build-halide-bin + + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + platform_tag: manylinux_x86_64 + - os: windows-latest + platform_tag: win_amd64 + - os: macos-15-intel + platform_tag: macosx_x86_64 + - os: macos-15 + platform_tag: macosx_arm64 + + env: + MACOSX_DEPLOYMENT_TARGET: 11 + HALIDE_SPLIT_BUILD: "1" + + steps: + - uses: actions/checkout@v7 + with: + fetch-depth: 0 + fetch-tags: true + + - uses: ilammy/msvc-dev-cmd@v1 + - uses: lukka/get-cmake@v4.4.0 + with: + cmakeVersion: "~3.28.0" + + ######################################################################## + # halide-bin + # + # The runtime module is compiled against an already-installed halide-bin + # (for the runtime headers, the shared marshalling source, and GenRT to + # generate its bundled Halide runtime), exactly like build-wheels above. + # Unlike that job, the resulting extension links no libHalide and the wheel + # has no halide-bin dependency. + ######################################################################## + + - uses: actions/download-artifact@v8 + with: + name: wheels-bin-${{ matrix.platform_tag }} + path: dist-bin + + - name: Unpack halide-bin for the build + shell: bash + run: python -m zipfile -e dist-bin/*.whl opt/halide-bin + + ######################################################################## + # Wheels + ######################################################################## + + - name: Build wheels + uses: pypa/cibuildwheel@v4.1.1 + with: + package-dir: packaging/pip-runtime + env: + CIBW_BUILD: "cp3*-${{ matrix.platform_tag }}" + CIBW_SKIP: "cp3{5,6,7,8,9}* cp314t-*" + CIBW_ENVIRONMENT_LINUX: > + CMAKE_PREFIX_PATH=/project/opt/halide-bin/halide_bin/data + SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE_RUNTIME='{local_scheme="no-local-version"}' + CIBW_ENVIRONMENT_MACOS: > + CMAKE_PREFIX_PATH='${{ github.workspace }}/opt/halide-bin/halide_bin/data' + Python_ROOT_DIR='' + SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE_RUNTIME='{local_scheme="no-local-version"}' + CIBW_ENVIRONMENT_WINDOWS: > + CMAKE_GENERATOR=Ninja + CMAKE_PREFIX_PATH='${{ github.workspace }}\opt\halide-bin\halide_bin\data' + SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE_RUNTIME='{local_scheme="no-local-version"}' + # The runtime wheel links no libHalide, so its test environment needs + # nothing installed: a successful `import halide.runtime` in a bare + # environment is itself proof that the module is libHalide-free. + CIBW_TEST_COMMAND: > + python -c "import halide.runtime as r; assert r.load and r.Kernel and r.Buffer; print('halide.runtime OK')" + + - uses: actions/upload-artifact@v7 + with: + name: wheels-runtime-${{ matrix.platform_tag }} + path: ./wheelhouse/*.whl + publish: name: Publish on PyPI - needs: build-wheels + needs: [build-halide-bin, build-wheels, build-runtime-wheels] runs-on: ubuntu-latest permissions: id-token: write diff --git a/packaging/pip-bin/pyproject.toml b/packaging/pip-bin/pyproject.toml new file mode 100644 index 000000000000..4918318eaf0e --- /dev/null +++ b/packaging/pip-bin/pyproject.toml @@ -0,0 +1,69 @@ +[build-system] +requires = ["scikit-build-core~=0.11.0", "setuptools-scm>=8.3.1"] +build-backend = "scikit_build_core.build" + +[project] +name = "halide-bin" +authors = [ + { name = "The Halide team", email = "halide-dev@lists.csail.mit.edu" }, +] +maintainers = [{ name = "Alex Reinking", email = "areinking@adobe.com" }] +description = "Python-independent binary components for Halide (libHalide, autoschedulers, generator tools, headers, CMake package files)." +license = { file = "../../LICENSE.txt" } +requires-python = ">=3.10" +dynamic = ['version'] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Natural Language :: English", + "Operating System :: MacOS", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Programming Language :: C++", + "Topic :: Scientific/Engineering", + "Topic :: Software Development :: Code Generators", + "Topic :: Software Development :: Compilers", + "Topic :: Software Development :: Libraries", +] + +[project.urls] +Homepage = "https://halide-lang.org" +Documentation = "https://halide-lang.org/docs" +Issues = "https://github.com/halide/Halide/issues" +Repository = "https://github.com/halide/Halide.git" + +[tool.scikit-build] +minimum-version = "build-system.requires" +cmake.version = ">=3.28" +ninja.version = ">=1.11,!=1.13.0" +cmake.source-dir = "../.." +wheel.packages = ["src/halide_bin"] +wheel.install-dir = "halide_bin/data" +# No Python extension modules in this package -- python-version-agnostic tag. +wheel.py-api = "py3" +metadata.version.provider = "scikit_build_core.metadata.setuptools_scm" + +[tool.scikit-build.cmake.define] +CMAKE_DISABLE_FIND_PACKAGE_JPEG = true +CMAKE_DISABLE_FIND_PACKAGE_PNG = true +FETCHCONTENT_FULLY_DISCONNECTED = true +Halide_ENABLE_EXCEPTIONS = true +Halide_ENABLE_RTTI = true +Halide_WASM_BACKEND = "wabt" +WITH_PYTHON_BINDINGS = false +WITH_TESTS = false +WITH_TUTORIALS = false + +## +# Don't version libHalide.so/dylib -- wheels are zip files that do +# not understand symbolic links. Including version information here +# causes the final wheel to have three copies of our library. Not good. +CMAKE_PLATFORM_NO_VERSIONED_SONAME = true + +[[tool.scikit-build.overrides]] +if.platform-system = "^win32" +inherit.cmake.define = "append" +cmake.define.Halide_WASM_BACKEND = "OFF" + +[tool.setuptools_scm] +root = "../.." diff --git a/packaging/pip-bin/src/halide_bin/__init__.py b/packaging/pip-bin/src/halide_bin/__init__.py new file mode 100644 index 000000000000..a2d204ffd307 --- /dev/null +++ b/packaging/pip-bin/src/halide_bin/__init__.py @@ -0,0 +1,5 @@ +import os + + +def install_dir(): + return os.path.join(os.path.dirname(__file__), "data") diff --git a/packaging/pip/CMakeLists.txt b/packaging/pip/CMakeLists.txt index e4c251038817..b05fea71a552 100644 --- a/packaging/pip/CMakeLists.txt +++ b/packaging/pip/CMakeLists.txt @@ -29,7 +29,7 @@ install( # bin/, which CMake does not understand. These users can add %VIRTUAL_ENV% # to their CMAKE_PREFIX_PATH. DESTINATION "${SKBUILD_DATA_DIR}/share/cmake/Halide" - COMPONENT Halide_Python + COMPONENT Halide_Development ) # Same thing for HalideCompiler @@ -38,7 +38,7 @@ install( "${CMAKE_CURRENT_BINARY_DIR}/HalideCompilerConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/../HalideCompilerConfigVersion.cmake" DESTINATION "${SKBUILD_DATA_DIR}/share/cmake/HalideCompiler" - COMPONENT Halide_Python + COMPONENT Halide_Development ) # Same thing for HalideAutoschedulers diff --git a/packaging/pip/TrampolineConfig.cmake.in b/packaging/pip/TrampolineConfig.cmake.in index 918328354248..1d7469b25c6d 100644 --- a/packaging/pip/TrampolineConfig.cmake.in +++ b/packaging/pip/TrampolineConfig.cmake.in @@ -3,4 +3,4 @@ cmake_minimum_required(VERSION 3.28) include(CMakeFindDependencyMacro) find_dependency(Python 3 COMPONENTS Interpreter Development.Module) -include("${Python_SITEARCH}/halide/@INSTALL_DIR@/@PACKAGE@Config.cmake") +include("${Python_SITEARCH}/halide_bin/data/@INSTALL_DIR@/@PACKAGE@Config.cmake") diff --git a/packaging/pip/_dynamic_metadata.py b/packaging/pip/_dynamic_metadata.py new file mode 100644 index 000000000000..35378ce1c70c --- /dev/null +++ b/packaging/pip/_dynamic_metadata.py @@ -0,0 +1,71 @@ +""" +Dynamic metadata provider for the `halide` pip package. + +Computes the version via setuptools_scm -- identically to +scikit_build_core's builtin `scikit_build_core.metadata.setuptools_scm` +provider -- and reuses that exact value to pin the `halide-bin` runtime +dependency when building in split mode (HALIDE_SPLIT_BUILD=1 -- see +.github/workflows/pip.yml), so the `==` pin and the actual `halide-bin` +version can never silently diverge. Outside of split mode (e.g. a plain +`pip install .`), `dependencies` is identical to the static list this +project shipped before the split. +""" + +from __future__ import annotations + +import os + +__all__ = ["dynamic_metadata", "get_requires_for_dynamic_metadata"] + + +def __dir__() -> list[str]: + return __all__ + + +_STATIC_DEPENDENCIES = [ + "imageio>=2", + "pillow; platform_machine == 'armv8l' or platform_machine == 'armv7l'", + "numpy>=1.26", +] + + +def _compute_version() -> str: + from setuptools_scm import Configuration, _get_version + + config = Configuration.from_file("pyproject.toml") + try: + version = _get_version(config, force_write_version_files=True) + except TypeError: # setuptools_scm < 8 + version = _get_version(config) + + if version is None: + msg = f"setuptools-scm was unable to detect version for {config.absolute_root}." + raise ValueError(msg) + + return version + + +def dynamic_metadata( + field: str, + settings: dict[str, object] | None = None, +) -> str | list[str]: + if settings: + msg = "No inline configuration is supported" + raise ValueError(msg) + + if field == "version": + return _compute_version() + + if field == "dependencies": + if not os.environ.get("HALIDE_SPLIT_BUILD"): + return list(_STATIC_DEPENDENCIES) + return [*_STATIC_DEPENDENCIES, f"halide-bin=={_compute_version()}"] + + msg = f"Only 'version' and 'dependencies' fields are supported, not {field!r}" + raise ValueError(msg) + + +def get_requires_for_dynamic_metadata( + _settings: dict[str, object] | None = None, +) -> list[str]: + return ["setuptools-scm"] diff --git a/pyproject.toml b/pyproject.toml index 50cb58b4db49..06daee871a8a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,12 +16,7 @@ description = "Halide is a programming language designed to make it easier to wr license = { file = "LICENSE.txt" } readme = "./packaging/pip/README.md" requires-python = ">=3.10" -dependencies = [ - "imageio>=2", - "pillow; platform_machine == 'armv8l' or platform_machine == 'armv7l'", - "numpy>=1.26", -] -dynamic = ['version'] +dynamic = ['version', 'dependencies'] keywords = [ "array", "compiler", @@ -116,6 +111,8 @@ Issues = "https://github.com/halide/Halide/issues" Repository = "https://github.com/halide/Halide.git" [tool.scikit-build] +# Required for in-tree dynamic-metadata plugins (packaging/pip/_dynamic_metadata.py). +experimental = true cmake.version = ">=3.28" ninja.version = ">=1.11,!=1.13.0" wheel.install-dir = "halide" @@ -127,7 +124,14 @@ sdist.exclude = [ "tutorial/", "dependencies/update-*.sh", ] -metadata.version.provider = "scikit_build_core.metadata.setuptools_scm" + +[tool.scikit-build.metadata.version] +provider = "_dynamic_metadata" +provider-path = "packaging/pip" + +[tool.scikit-build.metadata.dependencies] +provider = "_dynamic_metadata" +provider-path = "packaging/pip" [tool.scikit-build.cmake.define] CMAKE_DISABLE_FIND_PACKAGE_JPEG = true @@ -152,6 +156,17 @@ if.platform-system = "^win32" inherit.cmake.define = "append" cmake.define.Halide_WASM_BACKEND = "OFF" +## +# Split-package build: build only the Python bindings, against an +# already-installed `halide-bin` (found via CMAKE_PREFIX_PATH, which the +# caller -- e.g. .github/workflows/pip.yml -- must set explicitly). Only +# official release CI sets HALIDE_SPLIT_BUILD; a plain `pip install .` +# from a source checkout is unaffected and keeps building everything from +# scratch, as before. +[[tool.scikit-build.overrides]] +if.env.HALIDE_SPLIT_BUILD = true +cmake.source-dir = "python_bindings" + [tool.setuptools_scm] # Needs to exist for scikit-build-core to use setuptools_scm diff --git a/python_bindings/packaging/CMakeLists.txt b/python_bindings/packaging/CMakeLists.txt index dee493fb4fd2..328084de1f14 100644 --- a/python_bindings/packaging/CMakeLists.txt +++ b/python_bindings/packaging/CMakeLists.txt @@ -88,3 +88,11 @@ if (WITH_PYTHON_BINDINGS OR WITH_PYTHON_STUBS) COMPONENT Halide_Python ) endif () + +## +# Pip overrides +## + +if (SKBUILD) + add_subdirectory(pip) +endif () diff --git a/python_bindings/packaging/pip/CMakeLists.txt b/python_bindings/packaging/pip/CMakeLists.txt new file mode 100644 index 000000000000..990039edf953 --- /dev/null +++ b/python_bindings/packaging/pip/CMakeLists.txt @@ -0,0 +1,19 @@ +## +# Create a trampoline to the real Halide_PythonConfig.cmake. +# +# Same trick as packaging/pip/CMakeLists.txt in the root project: the wheel +# directory gets grafted to one of an unpredictable set of paths determined +# by sysconfig, so this trampoline finds platlib via sysconfig before jumping +# to the real Halide_PythonConfig.cmake inside the halide package. + +configure_file(TrampolineConfig.cmake.in "Halide_PythonConfig.cmake" @ONLY) + +install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/Halide_PythonConfig.cmake" + # It's better to duplicate the version file than to trampoline to it, as + # this would require calling find_package(Python) in the version file. + "${CMAKE_CURRENT_BINARY_DIR}/../Halide_PythonConfigVersion.cmake" + DESTINATION "${SKBUILD_DATA_DIR}/share/cmake/Halide_Python" + COMPONENT Halide_Python +) diff --git a/python_bindings/packaging/pip/TrampolineConfig.cmake.in b/python_bindings/packaging/pip/TrampolineConfig.cmake.in new file mode 100644 index 000000000000..45d40bad64a5 --- /dev/null +++ b/python_bindings/packaging/pip/TrampolineConfig.cmake.in @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.28) +include(CMakeFindDependencyMacro) +find_dependency(Python 3 COMPONENTS Interpreter Development.Module) + +include("${Python_SITEARCH}/halide/@Halide_Python_INSTALL_CMAKEDIR@/Halide_PythonConfig.cmake") diff --git a/python_bindings/src/halide/__init__.py b/python_bindings/src/halide/__init__.py index b0438e6bff68..580263c20306 100644 --- a/python_bindings/src/halide/__init__.py +++ b/python_bindings/src/halide/__init__.py @@ -1,3 +1,18 @@ +def _halide_install_dir(): + # `halide-bin` is only present when this package was built in split mode + # (see pyproject.toml's HALIDE_SPLIT_BUILD override); a plain, monolithic + # build has no such dependency and bundles everything under this package's + # own directory instead, exactly as before the split. + try: + import halide_bin + except ImportError: + import os + + return os.path.dirname(__file__) + else: + return halide_bin.install_dir() + + def _preload_bundled_halide_library(): # Force-load our own copy of the Halide runtime library by absolute path before # importing halide_, so that halide_'s implicit load of the same library (by @@ -10,7 +25,7 @@ def _preload_bundled_halide_library(): from pathlib import Path - root = Path(__file__).parent + root = Path(_halide_install_dir()) bin_dir = root / "bin" if hasattr(os, "add_dll_directory") and bin_dir.is_dir(): @@ -38,9 +53,7 @@ def _preload_bundled_halide_library(): def install_dir(): - import os - - return os.path.dirname(__file__) + return _halide_install_dir() from ._generator_helpers import ( # noqa: E402, F401 From 0ec8488f31fee27955a1826121a332d767d312a5 Mon Sep 17 00:00:00 2001 From: Derek Gerstmann Date: Mon, 3 Aug 2026 15:20:22 -0700 Subject: [PATCH 02/39] Add standalone halide.runtime module for calling AOT kernels without libHalide Introduce `halide.runtime`, a small Python extension that can load and call precompiled Halide AOT kernels without depending on libHalide (the compiler) or LLVM. This lets you compile pipelines on a build machine with the full toolchain and run them on deployment machines that have neither. Shared marshalling core ----------------------- The buffer-protocol <-> halide_buffer_t marshalling (`unpack_buffer` and `PyHalideBuffer`) previously lived only as string literals inside PythonExtensionGen.cpp. Lift it into a single source of truth, src/PythonExtensionRuntime.template.cpp, embedded into libHalide via binary2cpp (added to C_TEMPLATE_FILES in both src/CMakeLists.txt and the Makefile) and also compiled directly into the runtime module. `unpack_buffer` is now `inline` so it can be emitted into every generated .py.cpp (including the multi-library OMIT_MODULE_DEFINITION case) without violating the ODR. PythonExtensionGen.cpp shrinks by ~160 lines and its three copies of the conversion logic are unified. The runtime module (python_bindings/src/halide/runtime/) ------------------------------------------------------- * PyRuntime.cpp: a pybind11 extension linking only Halide::Runtime (headers) plus a compiled runtime via add_halide_runtime -- never libHalide. - `load(path, name=None)`: dlopen/LoadLibrary an artifact, dlsym its `_argv`/`_metadata`, and return a callable `Kernel`. - `Kernel`: `__call__` marshals buffer-protocol objects (NumPy) and scalars of every type into the argv array driven by halide_filter_metadata_t; exposes `name`, `target`, `argument_names`, and `arguments` (per-argument name/kind/type/dimensions introspection). - `Buffer`: wraps a buffer-protocol object as a halide_buffer_t, exposing the duck-typed `_get_raw_halide_buffer_t` protocol (shared with halide.Buffer and generated extensions) plus a zero-copy NumPy round-trip. - Installs a non-aborting error handler both in its own runtime and, via dlsym, in each loaded kernel's runtime, so a runtime error (e.g. a missing GPU driver) raises a Python exception instead of aborting the interpreter. Lazy compiler import -------------------- Rewrite halide/__init__.py to defer loading the compiler extension (halide_) and the generator helpers until a compiler attribute is first accessed (PEP 562 module __getattr__/__dir__). `import halide.runtime` therefore never pulls in libHalide, even when the compiler is present. A runtime-only install raises a clear ImportError, guiding users to the full `halide` package, when the compiler is accessed. Packaging --------- * Install the runtime module (component Halide_PythonRuntime) and split the Python-source install so that component is self-contained. * Install PythonExtensionRuntime.template.cpp next to HalideRuntime.h so the runtime module can be built out-of-tree (the CMake now finds the template in-tree or via the installed Halide::Runtime include dirs). * Add packaging/pip-runtime: a libHalide-free `halide-runtime` wheel that builds only the runtime target and installs only its component (numpy dependency, no halide-bin). * Add a build-runtime-wheels job to .github/workflows/pip.yml (split-built against halide-bin; a bare-environment `import halide.runtime` is itself the no-libHalide check) and publish it alongside the existing wheels. Tests (python_bindings/test/runtime/) ------------------------------------- * load_aot.py: load a real generated kernel, call it, and exercise Buffer interop, asserting the compiler was never imported. * call_convention.py: drive a kernel entirely from `kernel.arguments` covering every scalar type, a 2-D buffer, and a Tuple output; a second build with the enum GeneratorParam `combine=xor` demonstrates that a compile-time GeneratorParam changes behavior without changing the runtime calling convention. * gpu.py: Metal/OpenCL/CUDA/Vulkan coverage (CUDA gated on LLVM's NVPTX backend, Metal on Apple), running the backends with a live device and skipping the rest. * A CMake check asserting the runtime module has no libHalide dependency. Docs and tutorial ----------------- * doc/Python.md: a new "Calling AOT Code Without the Compiler (halide.runtime)" section covering producing a loadable kernel, load()/Kernel/arguments, and the Buffer type. * python_bindings/tutorial/lesson_15_runtime.py: a self-contained lesson that AOT-compiles a pipeline, links it into a loadable shared library (force_load on macOS, --whole-archive on Linux, link.exe /DLL with a .def on Windows), and then loads and runs it with only halide.runtime. Co-Authored-By: Claude Opus 4.8 --- Makefile | 3 +- doc/Python.md | 122 ++++ packaging/CMakeLists.txt | 10 + packaging/pip-runtime/README.md | 24 + packaging/pip-runtime/pyproject.toml | 92 +++ python_bindings/packaging/CMakeLists.txt | 30 + python_bindings/src/halide/CMakeLists.txt | 3 + python_bindings/src/halide/__init__.py | 137 +++- .../src/halide/runtime/CMakeLists.txt | 70 ++ .../src/halide/runtime/PyRuntime.cpp | 604 ++++++++++++++++++ .../src/halide/runtime/__init__.py | 15 + python_bindings/test/CMakeLists.txt | 1 + python_bindings/test/runtime/CMakeLists.txt | 117 ++++ .../test/runtime/aot_module_stub.c | 3 + .../test/runtime/call_convention.py | 136 ++++ .../test/runtime/callconv_generator.cpp | 77 +++ .../test/runtime/check_no_libhalide.cmake | 30 + python_bindings/test/runtime/gpu.py | 63 ++ .../test/runtime/gpu_generator.cpp | 28 + python_bindings/test/runtime/load_aot.py | 67 ++ .../test/runtime/runtimeadd_generator.cpp | 23 + python_bindings/tutorial/CMakeLists.txt | 1 + python_bindings/tutorial/lesson_15_runtime.py | 195 ++++++ src/CMakeLists.txt | 2 +- src/PythonExtensionGen.cpp | 190 +----- src/PythonExtensionRuntime.template.cpp | 186 ++++++ 26 files changed, 2026 insertions(+), 203 deletions(-) create mode 100644 packaging/pip-runtime/README.md create mode 100644 packaging/pip-runtime/pyproject.toml create mode 100644 python_bindings/src/halide/runtime/CMakeLists.txt create mode 100644 python_bindings/src/halide/runtime/PyRuntime.cpp create mode 100644 python_bindings/src/halide/runtime/__init__.py create mode 100644 python_bindings/test/runtime/CMakeLists.txt create mode 100644 python_bindings/test/runtime/aot_module_stub.c create mode 100644 python_bindings/test/runtime/call_convention.py create mode 100644 python_bindings/test/runtime/callconv_generator.cpp create mode 100644 python_bindings/test/runtime/check_no_libhalide.cmake create mode 100644 python_bindings/test/runtime/gpu.py create mode 100644 python_bindings/test/runtime/gpu_generator.cpp create mode 100644 python_bindings/test/runtime/load_aot.py create mode 100644 python_bindings/test/runtime/runtimeadd_generator.cpp create mode 100755 python_bindings/tutorial/lesson_15_runtime.py create mode 100644 src/PythonExtensionRuntime.template.cpp diff --git a/Makefile b/Makefile index bc8cd47885ee..0db462d31e6b 100644 --- a/Makefile +++ b/Makefile @@ -633,7 +633,8 @@ SOURCE_FILES = \ C_TEMPLATE_FILES = \ CodeGen_C_prologue \ - CodeGen_C_vectors + CodeGen_C_vectors \ + PythonExtensionRuntime HTML_TEMPLATE_FILES = \ StmtToHTML_dependencies.html \ diff --git a/doc/Python.md b/doc/Python.md index bea2c0168174..93c421e529d1 100644 --- a/doc/Python.md +++ b/doc/Python.md @@ -588,6 +588,128 @@ pass `order='F'` to make numpy use the Halide-compatible memory layout. If you're passing in an array constructed somewhere else, the easiest thing to do is to `.transpose()` it before passing it to your Halide code. +### Calling AOT Code Without the Compiler (`halide.runtime`) + +The approach above imports a Python extension that was produced at build time by +`add_halide_python_extension_library`. Sometimes you instead want to load a +precompiled Halide kernel _dynamically_, at runtime, from an ordinary shared +library -- and to do so in an environment that does not have the Halide compiler +(or `libHalide`) installed at all. This is what the `halide.runtime` module is +for: it is a small, standalone package that can load and call AOT-compiled +Halide kernels without depending on `libHalide`. + +This is primarily useful for deployment. You can compile your pipelines on a +build machine that has the full Halide toolchain, then ship only the resulting +kernels plus this tiny runtime, and run them on machines that have neither the +compiler nor LLVM installed. + +`halide.runtime` is always included in the full `halide` package, but it is also +published as a separate, `libHalide`-free wheel for exactly this deployment +case: + +```shell +pip install halide-runtime +``` + +Importing `halide.runtime` never loads `libHalide`; in the full package, the +compiler is loaded only if and when you first access a compiler symbol such as +`hl.Func`. (In a runtime-only install there is no compiler at all, so accessing +one raises an `ImportError` explaining that only the runtime is present and +pointing you at the full `halide` package.) + +#### Producing a loadable kernel + +`halide.runtime` loads a shared library that exports a Halide filter's +`_argv` and `_metadata` symbols -- the ordinary product of AOT +compilation. Note that this is _not_ the same artifact as the Python extension +produced by `add_halide_python_extension_library`, which deliberately hides +every symbol except its `PyInit_` entry point. Instead, link the AOT library +into a plain shared module that keeps those symbols visible: + +```cmake +add_halide_library(my_kernel FROM my_generator GENERATOR my_kernel) + +# Wrap the static AOT library in a shared module, keeping the filter's +# _argv/_metadata symbols exported so they can be resolved at load time. +# (A MODULE library needs at least one source of its own; an empty stub is fine.) +add_library(my_kernel_module MODULE stub.c) +target_link_libraries(my_kernel_module PRIVATE + "$") +set_target_properties(my_kernel_module PROPERTIES + PREFIX "" OUTPUT_NAME my_kernel + C_VISIBILITY_PRESET default + CXX_VISIBILITY_PRESET default) +``` + +Because `add_halide_library` bundles a Halide runtime into the library by +default, the resulting shared module is self-contained and, like +`halide.runtime` itself, has no dependency on `libHalide`. + +#### Loading and calling a kernel + +Once you have such a library, loading and calling it looks much like using the +compiled extension above: + +```python +import numpy as np +import halide.runtime as hlr + +# dlopen the shared library and locate the Halide filter inside it. The filter +# name defaults to the library's file name; pass name=... if it differs. +kernel = hlr.load("/path/to/my_kernel.so", name="my_kernel") + +print(kernel.name) # "my_kernel" +print(kernel.target) # the Target string it was compiled for +print(kernel.argument_names) # e.g. ['input', 'offset', 'output'] + +# `kernel.arguments` gives the full calling convention: one dict per argument, +# in argv order, with its name, kind ('input_scalar', 'input_buffer', or +# 'output_buffer'), element type (e.g. 'uint8'), and dimensions (0 for scalars). +for arg in kernel.arguments: + print( + arg + ) # {'name': 'input', 'kind': 'input_buffer', 'type': 'uint8', 'dimensions': 2} + +input_buf = imageio.imread("/path/to/some/file.png") +output_buf = np.empty(input_buf.shape, dtype=input_buf.dtype) + +# Arguments -- inputs, scalars, and the output buffer(s) -- are passed +# positionally in the order given by kernel.argument_names, or by keyword, +# in the Python manner: +kernel(input_buf, np.int32(5), output_buf) +# kernel(input=input_buf, offset=5, output=output_buf) +``` + +As with the compiled extension, Halide does not allocate outputs for you: you +must pass in a correctly-sized output buffer, and error conditions raise a +Python exception rather than returning an int. + +#### The `halide.runtime.Buffer` type + +Any object that supports the Python buffer protocol (such as a numpy array) may +be passed directly to a kernel. For finer control, `halide.runtime.Buffer` wraps +such an object as a Halide runtime buffer, without copying: + +```python +buf = hlr.Buffer(np.empty((480, 640), dtype=np.uint8)) +buf.dimensions # 2 +buf.type # "uint8" +buf.shape # [480, 640] + +view = np.asarray(buf) # a zero-copy view of the same memory +``` + +A `Buffer` exposes the same `_get_raw_halide_buffer_t` protocol that +`halide.Buffer` and the extensions produced by +`add_halide_python_extension_library` use, so the very same object can be handed +either to a kernel loaded via `halide.runtime.load` or to a function in a +generated extension module. + +The same memory-order caveats described in the previous section apply here: +numpy's default row-major layout corresponds to Halide's axes in reverse order, +so construct your arrays with `order='F'` (or `.transpose()` them) when the axis +order matters. + ### Advanced Generator-Related Topics #### Generator Aliases diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt index 9cf6ab2e8cd8..eeaf901059c0 100644 --- a/packaging/CMakeLists.txt +++ b/packaging/CMakeLists.txt @@ -91,6 +91,16 @@ endif () install(TARGETS Halide_Runtime EXPORT Halide_Targets FILE_SET HEADERS COMPONENT Halide_Development) +# The shared buffer-marshalling core, #included both by generated Python +# extensions (embedded via binary2cpp) and compiled into the standalone +# halide.runtime module. Install it next to HalideRuntime.h so an out-of-tree +# build of the runtime module finds it via Halide::Runtime's include dirs. +install( + FILES "${Halide_SOURCE_DIR}/src/PythonExtensionRuntime.template.cpp" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + COMPONENT Halide_Development +) + ## # Halide tools ## diff --git a/packaging/pip-runtime/README.md b/packaging/pip-runtime/README.md new file mode 100644 index 000000000000..29ef62d30b7c --- /dev/null +++ b/packaging/pip-runtime/README.md @@ -0,0 +1,24 @@ +# halide-runtime + +A tiny, standalone runtime for calling **precompiled Halide AOT kernels** from +Python, with **no dependency on libHalide** (no compiler, no LLVM). + +```python +import numpy as np +import halide.runtime as hlr + +kernel = hlr.load("mykernel.so") # dlopen a precompiled Halide artifact +out = np.empty_like(inp) +kernel(inp, out) # call it with NumPy arrays +``` + +This package provides only `halide.runtime` — `hlr.load(...)`, the resulting +`Kernel` objects, and a lightweight `hlr.Buffer` wrapper. It is a strict subset +of the full [`halide`](https://pypi.org/project/halide/) package; install this +one for small deployment environments that run precompiled pipelines but do not +need the Halide compiler. Accessing the compiler API (e.g. `halide.Func`) from a +runtime-only install raises a clear `ImportError` directing you to the full +`halide` package. + +See the Halide Python docs: + diff --git a/packaging/pip-runtime/pyproject.toml b/packaging/pip-runtime/pyproject.toml new file mode 100644 index 000000000000..1858ae252a01 --- /dev/null +++ b/packaging/pip-runtime/pyproject.toml @@ -0,0 +1,92 @@ +[build-system] +requires = [ + "pybind11>=2.11.1", + "scikit-build-core~=0.11.0", + "setuptools-scm>=8.3.1", +] +build-backend = "scikit_build_core.build" + +[project] +name = "halide-runtime" +authors = [ + { name = "The Halide team", email = "halide-dev@lists.csail.mit.edu" }, +] +maintainers = [{ name = "Alex Reinking", email = "areinking@adobe.com" }] +description = "Standalone Halide runtime: load and call precompiled Halide AOT kernels without depending on libHalide (no compiler, no LLVM)." +license = { file = "../../LICENSE.txt" } +readme = "README.md" +requires-python = ">=3.10" +dynamic = ['version'] +dependencies = ["numpy>=1.26"] +keywords = ["array", "image processing", "runtime", "aot", "halide"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Natural Language :: English", + "Operating System :: MacOS", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Programming Language :: C++", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: Implementation :: CPython", + "Topic :: Multimedia :: Graphics", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Image Processing", +] + +[project.urls] +Homepage = "https://halide-lang.org" +Documentation = "https://github.com/halide/Halide/blob/main/doc/Python.md" +Issues = "https://github.com/halide/Halide/issues" +Repository = "https://github.com/halide/Halide.git" + +[tool.scikit-build] +minimum-version = "build-system.requires" +experimental = true +cmake.version = ">=3.28" +ninja.version = ">=1.11,!=1.13.0" +cmake.source-dir = "../.." + +# Build and package ONLY the standalone runtime extension: build just its target +# (so libHalide's compiler bindings are never compiled) and install just its +# component (the _runtime extension plus the small pure-Python surface: the lazy +# halide/__init__.py and halide/runtime/__init__.py). The resulting wheel links +# no libHalide and has no `halide-bin` dependency. +build.targets = ["Halide_PythonRuntime"] +install.components = ["Halide_PythonRuntime"] +wheel.install-dir = "halide" +sdist.include = ["dependencies/"] + +metadata.version.provider = "scikit_build_core.metadata.setuptools_scm" + +[tool.scikit-build.cmake.define] +CMAKE_DISABLE_FIND_PACKAGE_JPEG = true +CMAKE_DISABLE_FIND_PACKAGE_PNG = true +FETCHCONTENT_FULLY_DISCONNECTED = true +Halide_ENABLE_EXCEPTIONS = true +Halide_ENABLE_RTTI = true +Halide_INSTALL_PYTHONDIR = "." +Halide_WASM_BACKEND = "wabt" +WITH_PYTHON_BINDINGS = true +WITH_TESTS = false +WITH_TUTORIALS = false +CMAKE_PLATFORM_NO_VERSIONED_SONAME = true + +[[tool.scikit-build.overrides]] +if.platform-system = "^win32" +inherit.cmake.define = "append" +cmake.define.Halide_WASM_BACKEND = "OFF" + +## +# Split-package build: build only the Python bindings tree against an +# already-installed `halide-bin` (found via CMAKE_PREFIX_PATH, which the caller +# must set), so the runtime extension is compiled without building libHalide. +# The extension still links no libHalide at runtime. +[[tool.scikit-build.overrides]] +if.env.HALIDE_SPLIT_BUILD = true +cmake.source-dir = "../../python_bindings" + +[tool.setuptools_scm] +root = "../.." diff --git a/python_bindings/packaging/CMakeLists.txt b/python_bindings/packaging/CMakeLists.txt index 328084de1f14..f715b3b0fab8 100644 --- a/python_bindings/packaging/CMakeLists.txt +++ b/python_bindings/packaging/CMakeLists.txt @@ -6,6 +6,25 @@ set(Halide_INSTALL_PYTHONDIR "${CMAKE_INSTALL_LIBDIR}/python3/site-packages/hali ) if (WITH_PYTHON_BINDINGS) + # The runtime-only Python surface -- the lazy top-level __init__ (which does + # not import the compiler until a compiler attribute is used) and the + # halide.runtime subpackage. These go in the Halide_PythonRuntime component + # so a libHalide-free halide-runtime wheel can select just this component and + # still be a complete, importable package. + install( + FILES "${Halide_Python_SOURCE_DIR}/src/halide/__init__.py" + DESTINATION "${Halide_INSTALL_PYTHONDIR}" + COMPONENT Halide_PythonRuntime + ) + install( + DIRECTORY "${Halide_Python_SOURCE_DIR}/src/halide/runtime/" + DESTINATION "${Halide_INSTALL_PYTHONDIR}/runtime" + COMPONENT Halide_PythonRuntime + FILES_MATCHING + PATTERN "*.py" + ) + + # The remaining (compiler-side) Python sources. install( DIRECTORY "${Halide_Python_SOURCE_DIR}/src/halide/" DESTINATION "${Halide_INSTALL_PYTHONDIR}" @@ -13,6 +32,8 @@ if (WITH_PYTHON_BINDINGS) FILES_MATCHING PATTERN "*.py" PATTERN "halide_" EXCLUDE + PATTERN "runtime" EXCLUDE + PATTERN "__init__.py" EXCLUDE ) install( @@ -21,6 +42,15 @@ if (WITH_PYTHON_BINDINGS) LIBRARY DESTINATION "${Halide_INSTALL_PYTHONDIR}" COMPONENT Halide_Python ) + # The standalone halide.runtime module. It links no libHalide, so it needs + # no RPATH patching. It gets its own install component so a libHalide-free + # runtime-only wheel can select just this (plus the *.py below); the full + # package installs every component and so includes it too. + install( + TARGETS Halide_PythonRuntime + LIBRARY DESTINATION "${Halide_INSTALL_PYTHONDIR}/runtime" COMPONENT Halide_PythonRuntime + ) + get_property(halide_is_imported TARGET Halide::Halide PROPERTY IMPORTED) get_property(halide_type TARGET Halide::Halide PROPERTY TYPE) diff --git a/python_bindings/src/halide/CMakeLists.txt b/python_bindings/src/halide/CMakeLists.txt index 138625bbf149..e3a7c6819f30 100644 --- a/python_bindings/src/halide/CMakeLists.txt +++ b/python_bindings/src/halide/CMakeLists.txt @@ -87,3 +87,6 @@ add_custom_command( add_custom_target(Halide_Python_sources DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${stamp_file}") add_dependencies(Halide_Python Halide_Python_sources) + +# The standalone `halide.runtime` submodule (links only Halide::Runtime). +add_subdirectory(runtime) diff --git a/python_bindings/src/halide/__init__.py b/python_bindings/src/halide/__init__.py index 580263c20306..c9ae1430dc61 100644 --- a/python_bindings/src/halide/__init__.py +++ b/python_bindings/src/halide/__init__.py @@ -43,34 +43,121 @@ def _preload_bundled_halide_library(): return -_preload_bundled_halide_library() -del _preload_bundled_halide_library +def install_dir(): + return _halide_install_dir() -from .halide_ import * # noqa: E402, F403 -# noinspection PyUnresolvedReferences, PyProtectedMember -from .halide_ import _, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9 # noqa: E402, F401 +# --------------------------------------------------------------------------- +# Lazy loading of the compiler extension. +# +# `import halide.runtime` must not pull in libHalide, but importing any submodule +# runs this parent package's __init__ first. So instead of eagerly importing the +# compiler extension (halide_) here, we defer it until a compiler attribute is +# actually accessed on the `halide` module (PEP 562 module __getattr__). A +# runtime-only deployment can therefore `import halide.runtime` with no compiler +# and no libHalide present. +# --------------------------------------------------------------------------- +# The implicit-argument placeholders, which `from .halide_ import *` would skip +# because they begin with an underscore. +_PLACEHOLDER_ARG_NAMES = ( + "_", + "_0", + "_1", + "_2", + "_3", + "_4", + "_5", + "_6", + "_7", + "_8", + "_9", +) -def install_dir(): - return _halide_install_dir() +_GENERATOR_HELPER_NAMES = ( + "_create_python_generator", + "_generatorcontext_enter", + "_generatorcontext_exit", + "_get_python_generator_names", + "active_generator_context", + "alias", + "funcs", + "generator", + "main", + "Generator", + "GeneratorParam", + "InputBuffer", + "InputScalar", + "OutputBuffer", + "OutputScalar", + "vars", +) +_compiler_loaded = False +_compiler_loading = False -from ._generator_helpers import ( # noqa: E402, F401 - _create_python_generator, - _generatorcontext_enter, - _generatorcontext_exit, - _get_python_generator_names, - active_generator_context, - alias, - funcs, - generator, - main, - Generator, - GeneratorParam, - InputBuffer, - InputScalar, - OutputBuffer, - OutputScalar, - vars, -) + +def _load_compiler(): + """Import the Halide compiler extension and hoist its names into this module. + + Idempotent, and safe to call repeatedly. Raises ImportError if the compiler + extension is unavailable (e.g. a libHalide-free, runtime-only install); the + "loaded" flag is only latched on success so that later accesses re-raise that + same clear error rather than a confusing AttributeError.""" + global _compiler_loaded, _compiler_loading + if _compiler_loaded or _compiler_loading: + # `_compiler_loading` guards re-entrant access (e.g. from the generator + # helpers imported below) while names are still being populated. + return + _compiler_loading = True + try: + _preload_bundled_halide_library() + + try: + from . import halide_ + except ImportError as e: + raise ImportError( + "The Halide compiler is not available in this installation. This " + "looks like a runtime-only install, which provides `halide.runtime` " + "(for calling precompiled AOT kernels) without libHalide. Install " + "the full `halide` package to use the compiler/JIT API." + ) from e + + g = globals() + _populate_from_compiler(g, halide_) + _compiler_loaded = True + finally: + _compiler_loading = False + + +def _populate_from_compiler(g, halide_): + # `from .halide_ import *` semantics: all public (non-underscore) names ... + for name in dir(halide_): + if not name.startswith("_"): + g.setdefault(name, getattr(halide_, name)) + # ... plus the implicit-argument placeholders imported explicitly. + for name in _PLACEHOLDER_ARG_NAMES: + g[name] = getattr(halide_, name) + + from . import _generator_helpers + + for name in _GENERATOR_HELPER_NAMES: + g[name] = getattr(_generator_helpers, name) + + +def __getattr__(name): + # PEP 562: invoked only for attributes not already found in globals(), so once + # _load_compiler() has hoisted the compiler names this is no longer hit for them. + if name == "__all__": + _load_compiler() + return sorted(n for n in globals() if not n.startswith("_")) + _load_compiler() + try: + return globals()[name] + except KeyError: + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from None + + +def __dir__(): + _load_compiler() + return sorted(globals()) diff --git a/python_bindings/src/halide/runtime/CMakeLists.txt b/python_bindings/src/halide/runtime/CMakeLists.txt new file mode 100644 index 000000000000..f7eb15abc20d --- /dev/null +++ b/python_bindings/src/halide/runtime/CMakeLists.txt @@ -0,0 +1,70 @@ +## +# The `halide.runtime` extension module. +# +# This links ONLY the header-only Halide runtime (Halide::Runtime), never +# libHalide, so it can be imported standalone to call precompiled AOT kernels. +## + +pybind11_add_module(Halide_PythonRuntime) +add_library(Halide::PythonRuntime ALIAS Halide_PythonRuntime) + +set_target_properties(Halide_PythonRuntime + PROPERTIES + OUTPUT_NAME _runtime + EXPORT_NAME PythonRuntime +) + +target_sources(Halide_PythonRuntime PRIVATE PyRuntime.cpp) + +# PyRuntime.cpp #includes the shared marshalling core (it depends only on +# + HalideRuntime.h). In an in-tree build it lives in the Halide +# source tree; when building against an installed Halide it is installed next to +# HalideRuntime.h and found via Halide::Runtime's include directories (so no +# extra include path is needed in that case). +if ( + DEFINED Halide_SOURCE_DIR + AND EXISTS "${Halide_SOURCE_DIR}/src/PythonExtensionRuntime.template.cpp" +) + target_include_directories(Halide_PythonRuntime PRIVATE "${Halide_SOURCE_DIR}/src") +endif () + +# Runtime only: link a compiled Halide runtime (halide_copy_to_host, +# halide_device_free, error/print handlers, ...) plus the header-only runtime +# interface -- but NOT libHalide/the compiler. +add_halide_runtime(Halide_PythonRuntime_rt) +target_link_libraries(Halide_PythonRuntime PRIVATE Halide::Runtime Halide_PythonRuntime_rt) + +# Place the module at halide/runtime/ *inside the compiler package's tree* so it +# is importable as `halide.runtime`. The parent (Halide_Python) builds into +# `/$/halide`; this subdirectory's binary dir is one level +# deeper, so `../$/halide/runtime` co-locates the two. +set_target_properties(Halide_PythonRuntime + PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../$/halide/runtime" +) + +if (Halide_ASAN_ENABLED) + set_target_properties(Halide_PythonRuntime PROPERTIES CMAKE_SHARED_LINKER_FLAGS -shared-libasan) +endif () + +# Copy the Python source for the subpackage next to the extension. +set(python_sources __init__.py) +list(TRANSFORM python_sources + PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/" + OUTPUT_VARIABLE python_sources_source_dir +) + +set(stamp_file "$/Halide_PythonRuntime_sources.stamp") +add_custom_command( + OUTPUT "${stamp_file}" + COMMAND "${CMAKE_COMMAND}" -E make_directory $ + COMMAND + "${CMAKE_COMMAND}" -E copy -t $ + ${python_sources_source_dir} + COMMAND "${CMAKE_COMMAND}" -E touch "${stamp_file}" + DEPENDS ${python_sources_source_dir} + VERBATIM +) + +add_custom_target(Halide_PythonRuntime_sources DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${stamp_file}") +add_dependencies(Halide_PythonRuntime Halide_PythonRuntime_sources) diff --git a/python_bindings/src/halide/runtime/PyRuntime.cpp b/python_bindings/src/halide/runtime/PyRuntime.cpp new file mode 100644 index 000000000000..0a0e8c2892f0 --- /dev/null +++ b/python_bindings/src/halide/runtime/PyRuntime.cpp @@ -0,0 +1,604 @@ +// The `halide.runtime` extension module. +// +// This module deliberately depends ONLY on the header-only Halide runtime +// (HalideRuntime.h / HalideBuffer.h) and pybind11 -- it must NOT depend on +// libHalide. It provides just enough to load a precompiled AOT Halide kernel +// (a shared object exporting `_argv` and `_metadata`) and call it +// with buffer-protocol objects (e.g. NumPy arrays) and Python scalars. +// +// It shares the buffer-protocol <-> halide_buffer_t marshalling core with the +// Python extensions emitted by PythonExtensionGen, via the single source of +// truth in src/PythonExtensionRuntime.template.cpp (included below). Interop +// with `halide.Buffer` (from the compiler module) and with objects produced by +// generated extensions flows through the duck-typed `_get_raw_halide_buffer_t` +// protocol, so no libHalide types cross the boundary. + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "HalideRuntime.h" + +#ifdef _WIN32 +#include +#else +#include +#endif + +// Pull in the shared marshalling core: Halide::PythonRuntime::unpack_buffer() +// and PyHalideBuffer<>. `unpack_buffer` is `inline` and PyHalideBuffer lives in +// an anonymous namespace, so including this translation unit here (rather than +// compiling it separately) is well-formed and keeps a single implementation. +// NOLINTNEXTLINE(bugprone-suspicious-include): intentionally shared source. +#include "PythonExtensionRuntime.template.cpp" + +namespace py = pybind11; + +namespace { + +// --------------------------------------------------------------------------- +// Cross-platform dynamic library handling +// --------------------------------------------------------------------------- + +#ifdef _WIN32 +using LibHandle = HMODULE; +LibHandle open_library(const std::string &path) { + return LoadLibraryA(path.c_str()); +} +void *find_symbol(LibHandle handle, const std::string &name) { + return reinterpret_cast(GetProcAddress(handle, name.c_str())); +} +void close_library(LibHandle handle) { + FreeLibrary(handle); +} +std::string library_error() { + return "LoadLibrary/GetProcAddress failed (error " + std::to_string(GetLastError()) + ")"; +} +#else +using LibHandle = void *; +LibHandle open_library(const std::string &path) { + return dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL); +} +void *find_symbol(LibHandle handle, const std::string &name) { + return dlsym(handle, name.c_str()); +} +void close_library(LibHandle handle) { + dlclose(handle); +} +std::string library_error() { + const char *e = dlerror(); + return e ? std::string(e) : std::string("unknown dynamic-linker error"); +} +#endif + +// --------------------------------------------------------------------------- +// Error handling +// +// By default the Halide runtime prints an error to stderr and aborts the +// process. That is unacceptable in a library: a bad argument or a missing GPU +// driver would take down the interpreter. We install a handler that instead +// records the message so Kernel::call can raise it as a Python exception. Each +// AOT artifact carries its own copy of the runtime, so the handler must be +// installed both into this module's runtime and, at load time, into the +// runtime bundled in each loaded kernel. +// --------------------------------------------------------------------------- + +std::mutex &error_mutex() { + static std::mutex m; + return m; +} + +std::string &last_error() { + static std::string s; + return s; +} + +extern "C" void runtime_error_handler(void * /*user_context*/, const char *msg) { + std::scoped_lock lock(error_mutex()); + last_error() = msg ? msg : ""; +} + +std::string take_last_error() { + std::scoped_lock lock(error_mutex()); + std::string s = last_error(); + last_error().clear(); + return s; +} + +using SetErrorHandlerFn = void (*)(void (*)(void *, const char *)); + +// Best-effort default filter name from a library path: strip the directory, +// any file extension, and a leading "lib". e.g. "/x/libfoo.so" -> "foo". +std::string default_filter_name(const std::string &path) { + size_t slash = path.find_last_of("/\\"); + std::string base = (slash == std::string::npos) ? path : path.substr(slash + 1); + size_t dot = base.find('.'); + if (dot != std::string::npos) { + base = base.substr(0, dot); + } + if (base.rfind("lib", 0) == 0 && base.size() > 3) { + base = base.substr(3); + } + return base; +} + +using ArgvCallFn = int (*)(void **); +using MetadataFn = const halide_filter_metadata_t *(*)(); + +// --------------------------------------------------------------------------- +// A single loaded AOT filter. +// --------------------------------------------------------------------------- + +std::string type_to_string(halide_type_t t); // defined below + +// The three halide_argument_kind_t values, as readable strings. +std::string kind_to_string(int kind) { + switch (kind) { + case halide_argument_kind_input_scalar: + return "input_scalar"; + case halide_argument_kind_input_buffer: + return "input_buffer"; + case halide_argument_kind_output_buffer: + return "output_buffer"; + default: + return "unknown"; + } +} + +class Kernel { +public: + Kernel(LibHandle handle, ArgvCallFn argv_fn, const halide_filter_metadata_t *md) + : handle_(handle), argv_fn_(argv_fn), md_(md) { + } + + ~Kernel() { + if (handle_) { + close_library(handle_); + } + } + + Kernel(const Kernel &) = delete; + Kernel &operator=(const Kernel &) = delete; + + std::string name() const { + return md_->name ? md_->name : ""; + } + + std::string target() const { + return md_->target ? md_->target : ""; + } + + // The argument names, in argv order. + std::vector argument_names() const { + std::vector names; + names.reserve(md_->num_arguments); + for (int i = 0; i < md_->num_arguments; i++) { + names.emplace_back(md_->arguments[i].name); + } + return names; + } + + // Full per-argument metadata, in argv order: a dict per argument describing + // the calling convention -- its name, kind (input_scalar / input_buffer / + // output_buffer), element type (e.g. "uint8"), and dimensions (0 for scalars). + py::list arguments() const { + py::list result; + for (int i = 0; i < md_->num_arguments; i++) { + const halide_filter_argument_t &a = md_->arguments[i]; + py::dict d; + d["name"] = std::string(a.name); + d["kind"] = kind_to_string(a.kind); + d["type"] = type_to_string(a.type); + d["dimensions"] = a.dimensions; + result.append(std::move(d)); + } + return result; + } + + // Per-argument scratch storage that must outlive the argv_fn call. + struct ArgSlot { + halide_scalar_value_t scalar{}; + halide_buffer_t buffer{}; + std::vector dims; + Py_buffer py_buf{}; + bool py_buf_valid = false; + bool needs_device_free = false; + }; + + void call(const py::args &args, const py::kwargs &kwargs) { + const int argc = md_->num_arguments; + + std::vector slots(argc); + std::vector argv(argc, nullptr); + + // Release any Python buffers / device allocations on scope exit. + struct Cleanup { + std::vector &slots; + ~Cleanup() { + for (auto &s : slots) { + if (s.needs_device_free) { + halide_device_free(nullptr, &s.buffer); + } + if (s.py_buf_valid) { + PyBuffer_Release(&s.py_buf); + } + } + } + } cleanup{slots}; + + // Map user arguments (positional + keyword) onto metadata slots, + // auto-filling the implicit __user_context argument if present. + std::vector values(argc); + std::vector filled(argc, false); + + size_t next_positional = 0; + for (int i = 0; i < argc; i++) { + if (is_user_context(md_->arguments[i])) { + filled[i] = true; // handled specially below; consumes no user arg + } + } + + for (auto item : args) { + // Advance to the next slot the user is expected to fill. + while (next_positional < (size_t)argc && filled[next_positional]) { + next_positional++; + } + if (next_positional >= (size_t)argc) { + throw std::runtime_error("Too many positional arguments for kernel '" + name() + "'."); + } + values[next_positional] = item; + filled[next_positional] = true; + next_positional++; + } + + for (auto kw : kwargs) { + const std::string key = py::cast(kw.first); + int slot = -1; + for (int i = 0; i < argc; i++) { + if (!is_user_context(md_->arguments[i]) && key == md_->arguments[i].name) { + slot = i; + break; + } + } + if (slot < 0) { + throw std::runtime_error("Unknown argument '" + key + "' for kernel '" + name() + "'."); + } + if (values[slot]) { + throw std::runtime_error("Argument '" + key + "' specified more than once."); + } + values[slot] = kw.second; + filled[slot] = true; + } + + for (int i = 0; i < argc; i++) { + const halide_filter_argument_t &a = md_->arguments[i]; + + ArgSlot &slot = slots[i]; + + if (is_user_context(a)) { + slot.scalar.u.u64 = 0; // null user context + argv[i] = &slot.scalar; + continue; + } + + if (!values[i]) { + throw std::runtime_error("Missing argument '" + std::string(a.name) + + "' for kernel '" + name() + "'."); + } + + if (a.kind == halide_argument_kind_input_scalar) { + store_scalar(a, values[i], &slot.scalar); + argv[i] = &slot.scalar; + } else { + // Input or output buffer. + const bool writable = (a.kind == halide_argument_kind_output_buffer); + halide_buffer_t *raw = unpack_buffer_arg(a, values[i], writable, slot); + if (a.kind == halide_argument_kind_input_buffer) { + raw->set_host_dirty(); + } + argv[i] = raw; + } + } + + take_last_error(); // clear any stale message + + int result; + { + py::gil_scoped_release release; + result = argv_fn_(argv.data()); + } + if (result != 0) { + const std::string msg = take_last_error(); + throw std::runtime_error( + msg.empty() ? ("Halide kernel '" + name() + "' returned error " + std::to_string(result)) : ("Halide kernel '" + name() + "': " + msg)); + } + + // Flush any device-side outputs back to host (host-only buffer protocol). + for (int i = 0; i < argc; i++) { + const halide_filter_argument_t &a = md_->arguments[i]; + if (a.kind == halide_argument_kind_output_buffer) { + auto *buf = static_cast(argv[i]); + if (buf->device_dirty()) { + (void)halide_copy_to_host(nullptr, buf); + } + } + } + } + +private: + static bool is_user_context(const halide_filter_argument_t &a) { + return a.kind == halide_argument_kind_input_scalar && + std::strcmp(a.name, "__user_context") == 0; + } + + // Convert one buffer-protocol / Halide-buffer argument into a halide_buffer_t. + // Uses the shared `_get_raw_halide_buffer_t` fast path first, then falls back + // to the shared unpack_buffer() implementation. + halide_buffer_t *unpack_buffer_arg(const halide_filter_argument_t &a, + py::handle value, + bool writable, + ArgSlot &slot) { + PyObject *obj = value.ptr(); + + // Fast path: an object that already exposes a raw halide_buffer_t + // (halide.Buffer, halide.runtime.Buffer, or another generated result). + if (PyObject_HasAttrString(obj, "_get_raw_halide_buffer_t")) { + PyObject *raw = PyObject_CallMethod(obj, "_get_raw_halide_buffer_t", nullptr); + if (raw && PyLong_Check(raw)) { + auto ptr = (uintptr_t)PyLong_AsUnsignedLongLong(raw); + Py_DECREF(raw); + if (ptr) { + return reinterpret_cast(ptr); + } + } else { + Py_XDECREF(raw); + PyErr_Clear(); + } + } + + // General path: buffer-protocol object (e.g. NumPy array). + slot.dims.resize(a.dimensions > 0 ? a.dimensions : 1); + bool ok = Halide::PythonRuntime::unpack_buffer( + obj, writable ? PyBUF_WRITABLE : 0, a.name, a.dimensions, + slot.py_buf, slot.dims.data(), slot.buffer, slot.py_buf_valid, + slot.needs_device_free); + if (!ok) { + throw py::error_already_set(); + } + return &slot.buffer; + } + + void store_scalar(const halide_filter_argument_t &a, py::handle value, + halide_scalar_value_t *out) { + const halide_type_t t = a.type; + +#define HALIDE_RUNTIME_SCALAR_CASE(CODE, BITS, CTYPE, FIELD) \ + if (t.code == (CODE) && t.bits == (BITS)) { \ + out->u.FIELD = py::cast(value); \ + return; \ + } + + HALIDE_RUNTIME_SCALAR_CASE(halide_type_float, 32, float, f32) + HALIDE_RUNTIME_SCALAR_CASE(halide_type_float, 64, double, f64) + HALIDE_RUNTIME_SCALAR_CASE(halide_type_int, 8, int8_t, i8) + HALIDE_RUNTIME_SCALAR_CASE(halide_type_int, 16, int16_t, i16) + HALIDE_RUNTIME_SCALAR_CASE(halide_type_int, 32, int32_t, i32) + HALIDE_RUNTIME_SCALAR_CASE(halide_type_int, 64, int64_t, i64) + HALIDE_RUNTIME_SCALAR_CASE(halide_type_uint, 1, bool, b) + HALIDE_RUNTIME_SCALAR_CASE(halide_type_uint, 8, uint8_t, u8) + HALIDE_RUNTIME_SCALAR_CASE(halide_type_uint, 16, uint16_t, u16) + HALIDE_RUNTIME_SCALAR_CASE(halide_type_uint, 32, uint32_t, u32) + HALIDE_RUNTIME_SCALAR_CASE(halide_type_uint, 64, uint64_t, u64) + HALIDE_RUNTIME_SCALAR_CASE(halide_type_handle, 64, uint64_t, u64) + +#undef HALIDE_RUNTIME_SCALAR_CASE + + throw std::runtime_error("Unsupported scalar type for argument '" + + std::string(a.name) + "'."); + } + + LibHandle handle_; + ArgvCallFn argv_fn_; + const halide_filter_metadata_t *md_; +}; + +std::string type_to_string(halide_type_t t) { + if (t.code == halide_type_uint && t.bits == 1) { + return "bool"; + } + const char *base; + switch (t.code) { + case halide_type_int: + base = "int"; + break; + case halide_type_uint: + base = "uint"; + break; + case halide_type_float: + base = "float"; + break; + default: + base = "handle"; + break; + } + return std::string(base) + std::to_string(t.bits); +} + +// A thin wrapper around a buffer-protocol object (e.g. a NumPy array) that +// exposes it as a halide_buffer_t. This is the interop bridge: it speaks the +// same `_get_raw_halide_buffer_t` protocol as halide.Buffer and the generated +// AOT extensions, so one object can be passed to both a load()'ed Kernel and a +// generated-extension function. It does not own or copy the underlying memory; +// the wrapped object is kept alive for the Buffer's lifetime. +class Buffer { +public: + explicit Buffer(py::object source) + : source_(std::move(source)) { + PyObject *obj = source_.ptr(); + + // Determine ndim so we can size the Halide dimension array. + Py_buffer probe; + if (PyObject_GetBuffer(obj, &probe, PyBUF_FORMAT | PyBUF_STRIDES) < 0) { + throw py::error_already_set(); + } + const int ndim = probe.ndim; + PyBuffer_Release(&probe); + + dims_.resize(ndim > 0 ? ndim : 1); + + // Prefer a writable view (so the buffer can be used as an output), but + // fall back to read-only for immutable inputs. + bool ok = Halide::PythonRuntime::unpack_buffer( + obj, PyBUF_WRITABLE, "buffer", 0, view_, dims_.data(), buf_, + view_valid_, needs_device_free_); + if (!ok) { + PyErr_Clear(); + ok = Halide::PythonRuntime::unpack_buffer( + obj, 0, "buffer", 0, view_, dims_.data(), buf_, + view_valid_, needs_device_free_); + } + if (!ok) { + throw py::error_already_set(); + } + } + + ~Buffer() { + if (needs_device_free_) { + halide_device_free(nullptr, &buf_); + } + if (view_valid_) { + PyBuffer_Release(&view_); + } + } + + Buffer(const Buffer &) = delete; + Buffer &operator=(const Buffer &) = delete; + + uintptr_t raw_halide_buffer_t() { + return reinterpret_cast(&buf_); + } + + int dimensions() const { + return buf_.dimensions; + } + + std::string type() const { + return type_to_string(buf_.type); + } + + // Shape in NumPy (row-major) axis order. + std::vector shape() const { + std::vector s(view_.ndim); + for (int i = 0; i < view_.ndim; i++) { + s[i] = (int)view_.shape[i]; + } + return s; + } + + // Re-export the underlying memory via the buffer protocol, in NumPy axis + // order, so `numpy.asarray(buffer)` is a zero-copy view of the same data. + py::buffer_info buffer_info() { + std::vector shape(view_.shape, view_.shape + view_.ndim); + std::vector strides(view_.strides, view_.strides + view_.ndim); + return py::buffer_info( + view_.buf, view_.itemsize, + std::string(view_.format ? view_.format : "B"), + view_.ndim, shape, strides, view_.readonly != 0); + } + +private: + py::object source_; + Py_buffer view_{}; + bool view_valid_ = false; + bool needs_device_free_ = false; + std::vector dims_; + halide_buffer_t buf_{}; +}; + +std::shared_ptr load(const std::string &path, const py::object &name_obj) { + LibHandle handle = open_library(path); + if (!handle) { + throw std::runtime_error("Could not load '" + path + "': " + library_error()); + } + + // Redirect the kernel runtime's errors to our handler so a runtime failure + // (e.g. a missing GPU driver) raises a Python exception instead of aborting. + if (void *set_handler = find_symbol(handle, "halide_set_error_handler")) { + reinterpret_cast(set_handler)(&runtime_error_handler); + } + + std::vector candidates; + if (!name_obj.is_none()) { + candidates.push_back(py::cast(name_obj)); + } else { + candidates.push_back(default_filter_name(path)); + } + + for (const std::string &name : candidates) { + auto argv_fn = reinterpret_cast(find_symbol(handle, name + "_argv")); + auto meta_fn = reinterpret_cast(find_symbol(handle, name + "_metadata")); + if (argv_fn && meta_fn) { + const halide_filter_metadata_t *md = meta_fn(); + if (!md) { + continue; + } + if (md->version != halide_filter_metadata_t::VERSION) { + close_library(handle); + throw std::runtime_error("Kernel '" + name + "' has metadata version " + + std::to_string(md->version) + ", expected " + + std::to_string(halide_filter_metadata_t::VERSION)); + } + return std::make_shared(handle, argv_fn, md); + } + } + + close_library(handle); + std::string tried = candidates.empty() ? "" : candidates.front(); + throw std::runtime_error( + "Could not find Halide filter symbols '" + tried + "_argv' / '" + tried + + "_metadata' in '" + path + "'. Pass name=... if the function name differs from the file name."); +} + +} // namespace + +PYBIND11_MODULE(_runtime, m) { + m.doc() = "Standalone Halide runtime: load and call precompiled AOT kernels " + "without depending on libHalide."; + + // Make our own runtime's errors non-fatal too (e.g. a failed copy-to-host). + halide_set_error_handler(&runtime_error_handler); + + py::class_(m, "Buffer", py::buffer_protocol()) + .def(py::init(), py::arg("source"), + "Wrap a buffer-protocol object (e.g. a NumPy array) as a Halide " + "runtime buffer, without copying.") + .def_buffer(&Buffer::buffer_info) + .def("_get_raw_halide_buffer_t", &Buffer::raw_halide_buffer_t) + .def_property_readonly("dimensions", &Buffer::dimensions) + .def_property_readonly("type", &Buffer::type) + .def_property_readonly("shape", &Buffer::shape) + .def("__repr__", [](const Buffer &b) { + return ""; + }); + + py::class_>(m, "Kernel") + .def("__call__", &Kernel::call) + .def_property_readonly("name", &Kernel::name) + .def_property_readonly("target", &Kernel::target) + .def_property_readonly("argument_names", &Kernel::argument_names) + .def_property_readonly("arguments", &Kernel::arguments) + .def("__repr__", [](const Kernel &k) { + return ""; + }); + + m.def("load", &load, py::arg("path"), py::arg("name") = py::none(), + "Load a precompiled Halide AOT kernel from a shared library.\n\n" + "`path` is the shared object to dlopen; `name` is the Halide function\n" + "name (defaults to the library's file name). Returns a callable Kernel."); +} diff --git a/python_bindings/src/halide/runtime/__init__.py b/python_bindings/src/halide/runtime/__init__.py new file mode 100644 index 000000000000..af5c26e5d2ab --- /dev/null +++ b/python_bindings/src/halide/runtime/__init__.py @@ -0,0 +1,15 @@ +"""Standalone Halide runtime. + +Load and call precompiled Halide AOT kernels without depending on libHalide:: + + import halide.runtime as hlr + kernel = hlr.load("path/to/kernel.so") + kernel(input_array, output_array) + +This subpackage links only the header-only Halide runtime, so it can be used in +deployment environments that do not have the Halide compiler installed. +""" + +from ._runtime import Buffer, Kernel, load + +__all__ = ["Buffer", "Kernel", "load"] diff --git a/python_bindings/test/CMakeLists.txt b/python_bindings/test/CMakeLists.txt index 786664317f17..35e801a78715 100644 --- a/python_bindings/test/CMakeLists.txt +++ b/python_bindings/test/CMakeLists.txt @@ -10,3 +10,4 @@ endif () add_subdirectory(correctness) add_subdirectory(generators) +add_subdirectory(runtime) diff --git a/python_bindings/test/runtime/CMakeLists.txt b/python_bindings/test/runtime/CMakeLists.txt new file mode 100644 index 000000000000..ac607e9ddc08 --- /dev/null +++ b/python_bindings/test/runtime/CMakeLists.txt @@ -0,0 +1,117 @@ +## +# Tests for the standalone `halide.runtime` module. +## + +# Register a Halide generator (once). Separated from kernel building so a single +# generator can be compiled for several targets (e.g. the GPU backends below). +function(add_runtime_test_generator GEN SRC) + add_halide_generator(${GEN}_gen SOURCES "${SRC}") +endfunction() + +# Build an AOT kernel and wrap it into a loadable shared module named ".so". +# Unlike a Python extension library (which hides all but PyInit_), we keep the +# filter's `_argv` / `_metadata` symbols exported so the runtime loader +# can dlsym them; WHOLE_ARCHIVE pulls in the filter objects even though the stub +# references nothing. The loader defaults the filter name to the file stem, so we +# name the module and the Halide function identically. +function(add_runtime_test_kernel MOD) + cmake_parse_arguments(ARG "" "GENERATOR" "FEATURES;PARAMS" ${ARGN}) + if (NOT ARG_GENERATOR) + set(ARG_GENERATOR ${MOD}) + endif () + + add_halide_library( + ${MOD}_aot + FROM ${ARG_GENERATOR}_gen + GENERATOR ${ARG_GENERATOR} + FUNCTION_NAME ${MOD} + FEATURES ${ARG_FEATURES} + PARAMS ${ARG_PARAMS} + ) + + add_library(${MOD}_module MODULE aot_module_stub.c) + target_link_libraries(${MOD}_module PRIVATE "$") + set_target_properties(${MOD}_module + PROPERTIES + PREFIX "" + OUTPUT_NAME ${MOD} + C_VISIBILITY_PRESET default + CXX_VISIBILITY_PRESET default + ) +endfunction() + +# A tiny kernel: load, call, and Buffer interop. +add_runtime_test_generator(runtimeadd runtimeadd_generator.cpp) +add_runtime_test_kernel(runtimeadd) +add_python_test(FILE load_aot.py LABEL python_runtime TEST_ARGS "$") + +# The full scalar/buffer calling convention: every scalar type, a 2-D buffer, +# and multiple outputs including a Tuple output. We compile the generator twice +# with different values of its enum GeneratorParam `combine` (a compile-time +# choice, baked into each kernel) to show that it selects behavior without +# changing the runtime calling convention. +add_runtime_test_generator(callconv callconv_generator.cpp) +add_runtime_test_kernel(callconv) # combine=add (default) +add_runtime_test_kernel(callconv_xor GENERATOR callconv PARAMS combine=xor) +add_python_test( + FILE call_convention.py + LABEL python_runtime + TEST_ARGS "$" "$" +) + +## +# GPU coverage. +# +# We compile the same GPU-scheduled kernel for each backend that can be built on +# this platform, then run one test that tries each and skips a backend at run +# time if its device/driver is missing (as on a headless CI runner). +# +# * Metal -- Apple only (its runtime links Apple frameworks). +# * OpenCL -- OpenCL C is emitted and compiled by the driver at run time; +# the runtime is dlopen-based, so it builds everywhere. +# * Vulkan -- SPIR-V is emitted directly (no LLVM GPU target); vk_int8 is +# required because the kernel uses 8-bit buffers. +# * CUDA -- needs LLVM's NVPTX backend to emit PTX. +## + +add_runtime_test_generator(gpuadd gpu_generator.cpp) + +set(gpu_modules "") + +if (APPLE) + add_runtime_test_kernel(gpuadd_metal GENERATOR gpuadd FEATURES metal) + list(APPEND gpu_modules gpuadd_metal) +endif () + +add_runtime_test_kernel(gpuadd_opencl GENERATOR gpuadd FEATURES opencl) +list(APPEND gpu_modules gpuadd_opencl) + +add_runtime_test_kernel(gpuadd_vulkan GENERATOR gpuadd FEATURES vulkan vk_int8) +list(APPEND gpu_modules gpuadd_vulkan) + +if ("NVPTX" IN_LIST Halide_LLVM_COMPONENTS) + add_runtime_test_kernel(gpuadd_cuda GENERATOR gpuadd FEATURES cuda) + list(APPEND gpu_modules gpuadd_cuda) +else () + message(STATUS "halide.runtime GPU test: skipping CUDA (LLVM has no NVPTX backend)") +endif () + +set(gpu_module_files "") +foreach (mod IN LISTS gpu_modules) + list(APPEND gpu_module_files "$") +endforeach () + +add_python_test(FILE gpu.py LABEL python_runtime TEST_ARGS ${gpu_module_files}) + +# The whole point of the runtime module: it must not depend on libHalide. +# (Symbol-visibility trick from the export-single-symbol test; POSIX only.) +if (NOT MSVC AND NOT WIN32) + add_test( + NAME python_runtime_no_libhalide + COMMAND + "${CMAKE_COMMAND}" + "-DMODULE=$" + -P "${CMAKE_CURRENT_SOURCE_DIR}/check_no_libhalide.cmake" + ) + set_tests_properties(python_runtime_no_libhalide PROPERTIES LABELS "python;python_runtime") +endif () diff --git a/python_bindings/test/runtime/aot_module_stub.c b/python_bindings/test/runtime/aot_module_stub.c new file mode 100644 index 000000000000..7c29acced3e2 --- /dev/null +++ b/python_bindings/test/runtime/aot_module_stub.c @@ -0,0 +1,3 @@ +/* Empty stub: the runtimeadd_module shared library is built entirely from the + * WHOLE_ARCHIVE'd AOT static library. A CMake MODULE library still needs at + * least one source file of its own, which this provides. */ diff --git a/python_bindings/test/runtime/call_convention.py b/python_bindings/test/runtime/call_convention.py new file mode 100644 index 000000000000..635f716f6987 --- /dev/null +++ b/python_bindings/test/runtime/call_convention.py @@ -0,0 +1,136 @@ +"""Exercise the full AOT calling convention through halide.runtime. + +This drives the `callconv` kernel entirely from its introspected metadata +(`kernel.arguments`): input scalars of every type, a 2-D input buffer, and three +outputs of differing element types -- including a Tuple output that lowers to +several output buffers. Because everything is computed elementwise, the numpy +reference is independent of Halide's axis ordering. +""" + +import sys + +import numpy as np + +import halide.runtime as hlr + +# Halide type string (as reported by kernel.arguments) -> numpy dtype. +_DTYPE = { + "bool": np.uint8, + "int8": np.int8, + "int16": np.int16, + "int32": np.int32, + "int64": np.int64, + "uint8": np.uint8, + "uint16": np.uint16, + "uint32": np.uint32, + "uint64": np.uint64, + "float32": np.float32, + "float64": np.float64, +} + +# Deliberately spans signed/unsigned, narrow/wide, and float types. Values are +# small enough that the int64 accumulator never overflows. +SCALARS = { + "s_bool": True, + "s_i8": -5, + "s_i16": 300, + "s_i32": -70000, + "s_i64": 5_000_000_000, + "s_u8": 7, + "s_u16": 40000, + "s_u32": 3_000_000_000, + "s_u64": 10_000_000_000, + "s_f32": 1.5, # exactly representable in float32 + "s_f64": 2.25, +} + + +def run(kernel, shape, input_buf): + """Call `kernel` with a value for every argument, driven by its metadata.""" + args = {a["name"]: a for a in kernel.arguments} + call_args = {} + for name, a in args.items(): + if a["kind"] == "input_buffer": + call_args[name] = input_buf + elif a["kind"] == "output_buffer": + call_args[name] = np.zeros(shape, dtype=_DTYPE[a["type"]]) + else: # input_scalar + call_args[name] = SCALARS[name] + # Note: "packed.0"/"packed.1" are not valid Python identifiers, but keyword + # expansion of a dict accepts arbitrary string keys. + kernel(**call_args) + return call_args + + +def main(): + # Two kernels compiled from the same generator with different values of its + # enum GeneratorParam `combine`: the default (add) and a `combine=xor` build. + add_path, xor_path = sys.argv[1], sys.argv[2] + kernel = hlr.load(add_path, name="callconv") + + # Introspection describes the calling convention: name, kind, type, dims. + args = {a["name"]: a for a in kernel.arguments} + assert args["input"]["kind"] == "input_buffer" + assert args["input"]["type"] == "uint8" and args["input"]["dimensions"] == 2 + assert args["s_bool"]["kind"] == "input_scalar" + assert args["s_u64"]["type"] == "uint64" and args["s_u64"]["dimensions"] == 0 + assert args["total"]["kind"] == "output_buffer" and args["total"]["type"] == "int64" + assert args["scaled"]["type"] == "float64" + # The Tuple output shows up as two separate output buffers. + assert "packed.0" in args and "packed.1" in args + assert args["packed.0"]["type"] == "uint8" and args["packed.1"]["type"] == "int32" + + shape = (3, 4) + input_buf = np.arange(12, dtype=np.uint8).reshape(shape) + + call_args = run(kernel, shape, input_buf) + + in64 = input_buf.astype(np.int64) + scalar_sum = ( + 1 # s_bool + - 5 + + 300 + - 70000 + + 5_000_000_000 # signed + + 7 + + 40000 + + 3_000_000_000 + + 10_000_000_000 # unsigned + ) + expected_total = in64 + scalar_sum + np.testing.assert_array_equal(call_args["total"], expected_total) + + expected_scaled = ( + np.float32(1.5).astype(np.float64) * in64.astype(np.float64) + 2.25 + ) + np.testing.assert_array_equal(call_args["scaled"], expected_scaled) + + # Default `combine=add`: packed.0 = input + s_u8. + np.testing.assert_array_equal( + call_args["packed.0"], (input_buf + 7).astype(np.uint8) + ) + np.testing.assert_array_equal( + call_args["packed.1"], expected_total.astype(np.int32) + ) + + # The enum GeneratorParam is a compile-time choice: the `combine=xor` build is + # a different kernel with the *same* calling convention but different behavior. + xor_kernel = hlr.load(xor_path, name="callconv_xor") + assert [a["name"] for a in xor_kernel.arguments] == list(args), ( + "the enum GeneratorParam must not change the runtime calling convention" + ) + xor_args = run(xor_kernel, shape, input_buf) + np.testing.assert_array_equal( + xor_args["packed.0"], (input_buf ^ 7).astype(np.uint8) + ) + # Everything not selected by the enum is unchanged. + np.testing.assert_array_equal(xor_args["total"], expected_total) + + # No compiler was needed for any of this. + assert "halide.halide_" not in sys.modules + + print("Success!") + + +if __name__ == "__main__": + main() diff --git a/python_bindings/test/runtime/callconv_generator.cpp b/python_bindings/test/runtime/callconv_generator.cpp new file mode 100644 index 000000000000..a0bc1f5240e6 --- /dev/null +++ b/python_bindings/test/runtime/callconv_generator.cpp @@ -0,0 +1,77 @@ +#include "Halide.h" + +using namespace Halide; + +// Exercises the full AOT scalar/buffer calling convention as seen by +// halide.runtime: a 2-D input buffer, input scalars of every supported width and +// signedness, and three outputs of different element types -- including a Tuple +// output, which lowers to several output buffers (a "structured" output). +class CallConv : public Generator { +public: + // A compile-time enum GeneratorParam: it selects how `packed.0` is computed + // and is baked into the generated code (it is NOT a runtime argument). It is + // set at build time, e.g. `add_halide_library(... PARAMS combine=xor)`. + enum class Combine { Add, + Sub, + Xor }; + GeneratorParam combine{ + "combine", + Combine::Add, + {{"add", Combine::Add}, {"sub", Combine::Sub}, {"xor", Combine::Xor}}}; + + Input> input{"input"}; + + Input s_bool{"s_bool"}; + Input s_i8{"s_i8"}; + Input s_i16{"s_i16"}; + Input s_i32{"s_i32"}; + Input s_i64{"s_i64"}; + Input s_u8{"s_u8"}; + Input s_u16{"s_u16"}; + Input s_u32{"s_u32"}; + Input s_u64{"s_u64"}; + Input s_f32{"s_f32"}; + Input s_f64{"s_f64"}; + + // Distinct output element types. + Output> total{"total"}; + Output> scaled{"scaled"}; + // A Tuple output: lowers to two output buffers named "packed.0"/"packed.1". + Output packed{"packed", {UInt(8), Int(32)}, 2}; + + Var x, y; + + void generate() { + Expr in = cast(input(x, y)); + Expr sum = in + + select(s_bool, cast(1), cast(0)) + + cast(s_i8) + cast(s_i16) + + cast(s_i32) + s_i64 + + cast(s_u8) + cast(s_u16) + + cast(s_u32) + cast(s_u64); + + // The enum GeneratorParam picks the operation at compile time. + Expr combined; + const Combine op = combine; + switch (op) { + case Combine::Add: + combined = input(x, y) + s_u8; + break; + case Combine::Sub: + combined = input(x, y) - s_u8; + break; + case Combine::Xor: + combined = input(x, y) ^ s_u8; + break; + } + + total(x, y) = sum; + scaled(x, y) = cast(s_f32) * cast(input(x, y)) + s_f64; + packed(x, y) = Tuple(cast(combined), cast(sum)); + } + + void schedule() { + } +}; + +HALIDE_REGISTER_GENERATOR(CallConv, callconv) diff --git a/python_bindings/test/runtime/check_no_libhalide.cmake b/python_bindings/test/runtime/check_no_libhalide.cmake new file mode 100644 index 000000000000..da48400e2b35 --- /dev/null +++ b/python_bindings/test/runtime/check_no_libhalide.cmake @@ -0,0 +1,30 @@ +# Verify that the given shared MODULE does not depend on libHalide (the +# compiler). The standalone runtime must link only the header-only runtime +# interface plus a compiled Halide runtime, never libHalide. +# +# Invoked as: cmake -DMODULE= -P check_no_libhalide.cmake + +if (NOT MODULE) + message(FATAL_ERROR "MODULE must be set") +endif () + +if (APPLE) + execute_process(COMMAND otool -L "${MODULE}" OUTPUT_VARIABLE deps RESULT_VARIABLE rc) +else () + find_program(OBJDUMP objdump) + if (OBJDUMP) + execute_process(COMMAND "${OBJDUMP}" -p "${MODULE}" OUTPUT_VARIABLE deps RESULT_VARIABLE rc) + else () + execute_process(COMMAND ldd "${MODULE}" OUTPUT_VARIABLE deps RESULT_VARIABLE rc) + endif () +endif () + +if (NOT rc EQUAL 0) + message(FATAL_ERROR "Failed to inspect dependencies of ${MODULE}") +endif () + +if (deps MATCHES "libHalide") + message(FATAL_ERROR "Runtime module ${MODULE} unexpectedly depends on libHalide:\n${deps}") +endif () + +message(STATUS "OK: ${MODULE} has no libHalide dependency") diff --git a/python_bindings/test/runtime/gpu.py b/python_bindings/test/runtime/gpu.py new file mode 100644 index 000000000000..23ce3e3dcca1 --- /dev/null +++ b/python_bindings/test/runtime/gpu.py @@ -0,0 +1,63 @@ +"""Check that halide.runtime can load and run kernels compiled for GPU targets. + +Each backend (Metal, CUDA, OpenCL, Vulkan) is compiled into its own loadable +module; the AOT artifact bundles its own device-capable Halide runtime, so the +standalone (CPU-only) halide.runtime module can drive it: input host buffers are +copied to the device, the kernel runs, and outputs are copied back to host. + +The module paths that were actually built on this platform are passed as +arguments. A backend whose device/driver is missing at run time (common on CI) +is skipped individually; if no backend has a usable device, the whole test skips. +""" + +import os +import sys + +import numpy as np + +import halide.runtime as hlr + +_GPU_FEATURES = ("cuda", "opencl", "metal", "vulkan", "webgpu") + + +def backend_of(target): + return next((f for f in _GPU_FEATURES if f in target), None) + + +def main(): + module_paths = sys.argv[1:] + + inp = np.arange(64, dtype=np.uint8).reshape(8, 8) + expected = (inp.astype(np.int64) + 3).astype(np.uint8) + + ran = [] + for path in module_paths: + # The module file is named ".so"; the loader defaults the filter + # name to that stem, which matches the Halide function name. + kernel = hlr.load(path) + backend = backend_of(kernel.target) or os.path.basename(path) + + out = np.zeros_like(inp) + try: + kernel(inp, np.int32(3), out) + except Exception as e: + # No usable device on this machine (e.g. a headless CI runner). + print(f"[skip] {backend}: device unavailable: {e}") + continue + + np.testing.assert_array_equal(out, expected) + print(f"ran on {backend}: OK") + ran.append(backend) + + assert "halide.halide_" not in sys.modules + + if not ran: + built = ", ".join(backend_of(hlr.load(p).target) or p for p in module_paths) + print(f"[SKIP] no usable GPU device (built backends: {built or 'none'})") + return + + print("Success! GPU backends verified:", ", ".join(ran)) + + +if __name__ == "__main__": + main() diff --git a/python_bindings/test/runtime/gpu_generator.cpp b/python_bindings/test/runtime/gpu_generator.cpp new file mode 100644 index 000000000000..1a35139e1f7c --- /dev/null +++ b/python_bindings/test/runtime/gpu_generator.cpp @@ -0,0 +1,28 @@ +#include "Halide.h" + +using namespace Halide; + +// A simple elementwise kernel with a GPU schedule, used to check that +// halide.runtime can load and run a kernel compiled for a GPU target (the AOT +// artifact bundles its own device-capable Halide runtime). Falls back to a CPU +// schedule when compiled without a GPU feature. +class GpuAdd : public Generator { +public: + Input> input{"input"}; + Input offset{"offset"}; + Output> output{"output"}; + + Var x, y, xo, yo, xi, yi; + + void generate() { + output(x, y) = cast(input(x, y) + offset); + } + + void schedule() { + if (get_target().has_gpu_feature()) { + output.gpu_tile(x, y, xo, yo, xi, yi, 8, 8); + } + } +}; + +HALIDE_REGISTER_GENERATOR(GpuAdd, gpuadd) diff --git a/python_bindings/test/runtime/load_aot.py b/python_bindings/test/runtime/load_aot.py new file mode 100644 index 000000000000..0a1afa71ca89 --- /dev/null +++ b/python_bindings/test/runtime/load_aot.py @@ -0,0 +1,67 @@ +"""Test the standalone `halide.runtime` loader against a precompiled AOT kernel. + +The key property under test is that `halide.runtime` can load and call a +precompiled Halide kernel WITHOUT importing the Halide compiler package (and thus +without libHalide): `import halide.runtime` must not pull in `halide.halide_`. +""" + +import sys + +import numpy as np + +import halide.runtime as hlr + + +def main(): + aot_path = sys.argv[1] + + # Importing the runtime must not have loaded the compiler extension. + assert "halide.halide_" not in sys.modules, ( + "importing halide.runtime pulled in the halide compiler extension" + ) + + kernel = hlr.load(aot_path, name="runtimeadd") + assert kernel.name == "runtimeadd", kernel.name + assert kernel.argument_names == ["input", "offset", "output"], kernel.argument_names + + rng = np.arange(0, 256, dtype=np.uint8) + out = np.zeros_like(rng) + + # positional + kernel(rng, np.int32(5), out) + expected = ((rng.astype(np.int64) + 5) % 256).astype(np.uint8) + assert np.array_equal(out, expected), (out, expected) + + # keyword + mixed + out2 = np.zeros_like(rng) + kernel(rng, output=out2, offset=200) + expected2 = ((rng.astype(np.int64) + 200) % 256).astype(np.uint8) + assert np.array_equal(out2, expected2), (out2, expected2) + + # halide.runtime.Buffer interop: introspection + zero-copy NumPy round-trip. + grid = np.arange(6, dtype=np.uint8).reshape(2, 3) + buf = hlr.Buffer(grid) + assert buf.dimensions == 2 and buf.type == "uint8" and buf.shape == [2, 3] + assert ( + isinstance(buf._get_raw_halide_buffer_t(), int) + and buf._get_raw_halide_buffer_t() != 0 + ) + view = np.asarray(buf) + assert np.array_equal(view, grid) + view[0, 0] = 42 + assert grid[0, 0] == 42, "Buffer must be a zero-copy view of its source" + + # Pass Buffer objects to the kernel (via the _get_raw_halide_buffer_t bridge). + out3 = np.zeros_like(rng) + kernel(hlr.Buffer(rng), np.int32(7), hlr.Buffer(out3)) + expected3 = ((rng.astype(np.int64) + 7) % 256).astype(np.uint8) + assert np.array_equal(out3, expected3), (out3, expected3) + + # Still no compiler after all of this. + assert "halide.halide_" not in sys.modules + + print("Success!") + + +if __name__ == "__main__": + main() diff --git a/python_bindings/test/runtime/runtimeadd_generator.cpp b/python_bindings/test/runtime/runtimeadd_generator.cpp new file mode 100644 index 000000000000..a4c84e7cdb65 --- /dev/null +++ b/python_bindings/test/runtime/runtimeadd_generator.cpp @@ -0,0 +1,23 @@ +#include "Halide.h" + +using namespace Halide; + +// A deliberately tiny AOT kernel used to exercise the standalone `halide.runtime` +// loader: one input buffer, one scalar, one output buffer. +class RuntimeAddGenerator : public Generator { +public: + Input> input{"input"}; + Input offset{"offset"}; + Output> output{"output"}; + + Var x; + + void generate() { + output(x) = cast(input(x) + offset); + } + + void schedule() { + } +}; + +HALIDE_REGISTER_GENERATOR(RuntimeAddGenerator, runtimeadd) diff --git a/python_bindings/tutorial/CMakeLists.txt b/python_bindings/tutorial/CMakeLists.txt index 0893275dc187..a8e273b47776 100644 --- a/python_bindings/tutorial/CMakeLists.txt +++ b/python_bindings/tutorial/CMakeLists.txt @@ -34,6 +34,7 @@ set(tests lesson_12_using_the_gpu.py lesson_13_tuples.py lesson_14_types.py + lesson_15_runtime.py lesson_17_predicated_rdom.py lesson_18_parallel_associative_reductions.py lesson_19_wrapper_funcs.py diff --git a/python_bindings/tutorial/lesson_15_runtime.py b/python_bindings/tutorial/lesson_15_runtime.py new file mode 100755 index 000000000000..e034c02fa0a1 --- /dev/null +++ b/python_bindings/tutorial/lesson_15_runtime.py @@ -0,0 +1,195 @@ +#!/usr/bin/python3 + +# Halide tutorial lesson 15. + +# This lesson demonstrates how to load and call a precompiled, ahead-of-time +# (AOT) compiled Halide pipeline at runtime using the standalone "halide.runtime" +# module. + +# This lesson can be built by invoking the command: +# make test_tutorial_lesson_15_runtime +# in a shell with the current directory at python_bindings/ + +# Lesson 10 showed how to AOT-compile a pipeline and call it through a generated +# Python extension. This lesson shows another way to run AOT code: loading a +# precompiled shared library dynamically and calling it, using only +# "halide.runtime". Unlike "import halide", halide.runtime does not depend on +# libHalide (the compiler) at all -- it is a small package whose whole job is to +# run precompiled kernels. + +# This is useful for deployment: you can compile your pipelines on a build +# machine that has the full Halide toolchain, then ship just the compiled kernels +# and this tiny runtime, and run them on machines that have neither the compiler +# nor LLVM installed. + +# There are two distinct phases below: +# 1. Build time (needs the Halide compiler): compile a pipeline to a shared +# library. In a real project this happens in your build system. +# 2. Deploy time (needs only halide.runtime): load that shared library and +# call it. This is the part you would actually ship. + +import os +import platform +import shutil +import subprocess +import tempfile + +import numpy as np + +# halide.runtime is all you need to *call* precompiled kernels. Importing it does +# not load libHalide. (We import the full "halide" package only for the +# build-time compilation step below.) +import halide.runtime as hlr + + +def compile_pipeline(directory): + # Build time: AOT-compile a simple pipeline to a loadable shared library. + # Returns the path to the shared library, or None if this environment cannot + # build one (e.g. there is no C compiler on the PATH). + import halide as hl + + # A simple one-stage pipeline that brightens an image, just like lesson 10. + x, y = hl.Var("x"), hl.Var("y") + input = hl.ImageParam(hl.UInt(8), 2, "input") + offset = hl.Param(hl.Int(32), name="offset") + brighter = hl.Func("brighter") + brighter[x, y] = hl.cast(hl.UInt(8), input[x, y] + offset) + brighter.vectorize(x, 16).parallel(y) + + # Compile to a static library. Unlike compile_to(object), a static library + # bundles a copy of the Halide runtime, so the shared library we link below + # is self-contained and, like halide.runtime itself, needs no libHalide. + # + # We compile for this machine (get_host_target) so we can run it right away. + archive = os.path.join(directory, "brighter.a") + brighter.compile_to( + {hl.OutputFileType.static_library: archive}, + [input, offset], + "brighter", + hl.get_host_target(), + ) + + # halide.runtime loads a *shared* library, so link the static library into + # one, taking care to keep the filter's symbols visible. In a real project + # your build system does this for you; see doc/Python.md for a CMake recipe. + return link_shared_library(archive, os.path.join(directory, "brighter"), "brighter") + + +def link_shared_library(archive, stem, name): + # Link the static library `archive` into a shared library that exports the + # filter's `_argv` / `_metadata` entry points, so halide.runtime + # can resolve them. Returns the shared library path, or None if this + # environment has no suitable linker. + system = platform.system() + + if system == "Windows": + # Use the MSVC linker (link.exe) if the Visual Studio toolchain is on the + # PATH (e.g. from a Developer Command Prompt). We wrap the static library + # into a DLL, listing the entry points to export in a .def file. /NOENTRY + # is fine here: the DLL shares the host process's already-initialized + # dynamic CRT, so it needs no startup code of its own. + if shutil.which("link") is None: + return None + library = stem + ".dll" + def_path = stem + ".def" + with open(def_path, "w") as f: + f.write("EXPORTS\n") + f.write(f" {name}_argv\n") + f.write(f" {name}_metadata\n") + args = [ + "link", + "/nologo", + "/DLL", + "/NOENTRY", + archive, + f"/DEF:{def_path}", + f"/OUT:{library}", + ] + elif system == "Darwin": + library = stem + ".dylib" + cc = os.environ.get("CC", "cc") + args = [cc, "-shared", "-o", library, "-Wl,-force_load," + archive] + else: + library = stem + ".so" + cc = os.environ.get("CC", "cc") + args = [ + cc, + "-shared", + "-o", + library, + "-Wl,--whole-archive", + archive, + "-Wl,--no-whole-archive", + "-lpthread", + "-ldl", + ] + + try: + subprocess.run(args, check=True) + except (OSError, subprocess.CalledProcessError): + return None + return library + + +def main(): + with tempfile.TemporaryDirectory() as directory: + library = compile_pipeline(directory) + if library is None: + # We couldn't produce a shared library to load in this environment, + # and the interesting part of the lesson needs one. + print("[SKIP] could not build a shared library to load") + return 0 + + # ------------------------------------------------------------------ + # Deploy time: everything below uses only halide.runtime, not + # libHalide. This is the code you would actually ship to run + # precompiled kernels. + # ------------------------------------------------------------------ + + # Load the precompiled kernel. The filter name defaults to the library's + # file name; we pass it explicitly here for clarity. + kernel = hlr.load(library, name="brighter") + + # A loaded Kernel knows what it was compiled for and how it must be + # called. `kernel.arguments` describes the calling convention: one entry + # per argument, with its name, kind (input_scalar / input_buffer / + # output_buffer), element type, and dimensions. + print("Loaded kernel:", kernel.name) + print("Compiled for target:", kernel.target) + for arg in kernel.arguments: + print(" argument:", arg) + + # Let's make some input data to test with. Note that, as in lesson 10, + # when a numpy array is passed to Halide code its axes are reversed; + # since this pipeline is elementwise that doesn't affect the result. + input = np.empty((640, 480), dtype=np.uint8) + for y in range(480): + for x in range(640): + input[x, y] = (x ^ (y + 1)) & 0xFF + + # Halide does not allocate outputs for us, so we provide a buffer for the + # result. + output = np.empty((640, 480), dtype=np.uint8) + + offset = 5 + + # Call it. Arguments may be passed by position, in the order given by + # kernel.argument_names ... + kernel(input, offset, output) + # ... or by name, in the Python manner: + # kernel(input=input, offset=offset, output=output) + # + # (Errors raise a Python exception rather than returning an int.) + + # Now let's check the filter performed as advertised: it was supposed to + # add the offset to every input pixel, with uint8 wraparound. + expected = (input.astype(np.int32) + offset).astype(np.uint8) + assert np.array_equal(output, expected), "kernel produced the wrong result" + + # Everything worked! + print("Success!") + return 0 + + +if __name__ == "__main__": + main() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cde4acb85a74..a16c9ec0d42e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -434,7 +434,7 @@ target_sources( # debuggers now honor Natvis on Linux and macOS too. See tools/Halide.natvis. target_sources(Halide PRIVATE "${Halide_SOURCE_DIR}/tools/Halide.natvis") -set(C_TEMPLATE_FILES CodeGen_C_prologue CodeGen_C_vectors) +set(C_TEMPLATE_FILES CodeGen_C_prologue CodeGen_C_vectors PythonExtensionRuntime) set(HTML_TEMPLATE_FILES StmtToHTML_dependencies.html StmtToHTML.js StmtToHTML.css) diff --git a/src/PythonExtensionGen.cpp b/src/PythonExtensionGen.cpp index 50b5f3b0ba12..9231b34d4ea7 100644 --- a/src/PythonExtensionGen.cpp +++ b/src/PythonExtensionGen.cpp @@ -6,6 +6,13 @@ #include "PythonExtensionGen.h" #include "Util.h" +// The buffer-protocol <-> halide_buffer_t marshalling helpers +// (Halide::PythonRuntime::unpack_buffer and PyHalideBuffer) live in a single +// source of truth, src/PythonExtensionRuntime.template.cpp, which is embedded +// here via binary2cpp and also compiled directly into the standalone +// `halide.runtime` Python module. +extern "C" unsigned char halide_c_template_PythonExtensionRuntime[]; + namespace Halide { namespace Internal { @@ -162,92 +169,6 @@ void _module_halide_print(void *user_context, const char *msg) { } // namespace -namespace Halide::PythonRuntime { - -bool unpack_buffer(PyObject *py_obj, - int py_getbuffer_flags, - const char *name, - int dimensions, - Py_buffer &py_buf, - halide_dimension_t *halide_dim, - halide_buffer_t &halide_buf, - bool &py_buf_valid, - bool &needs_device_free) { - py_buf_valid = false; - needs_device_free = false; - - memset(&py_buf, 0, sizeof(py_buf)); - if (PyObject_GetBuffer(py_obj, &py_buf, PyBUF_FORMAT | PyBUF_STRIDED_RO | py_getbuffer_flags) < 0) { - PyErr_Format(PyExc_ValueError, "Invalid argument %s: Expected %d dimensions, got %d", name, dimensions, py_buf.ndim); - return false; - } - py_buf_valid = true; - - if (dimensions && py_buf.ndim != dimensions) { - PyErr_Format(PyExc_ValueError, "Invalid argument %s: Expected %d dimensions, got %d", name, dimensions, py_buf.ndim); - return false; - } - // Always reverse axes. - // TODO(jiawen): Can probably consolidate this with similar code in PyCallable.cpp and - // pybufferinfo_to_halidebuffer() in PyBuffer.h. - for (int i = 0; i < py_buf.ndim; ++i) { - const int j = py_buf.ndim - 1 - i; // numpy axis j maps to Halide dim i - halide_dim[i].min = 0; - halide_dim[i].stride = (int)(py_buf.strides[j] / py_buf.itemsize); // Python strides are in bytes - halide_dim[i].extent = (int)py_buf.shape[j]; - halide_dim[i].flags = 0; - if (py_buf.suboffsets && py_buf.suboffsets[j] >= 0) { - // Halide doesn't support arrays of pointers. But we should never see this - // anyway, since we did not specify PyBUF_INDIRECT. - PyErr_Format(PyExc_ValueError, "Invalid buffer: suboffsets not supported"); - return false; - } - } - - halide_buf = {}; - needs_device_free = true; - if (!py_buf.format) { - halide_buf.type.code = halide_type_uint; - halide_buf.type.bits = 8; - } else { - /* Convert struct type code. See - * https://docs.python.org/2/library/struct.html#module-struct */ - char *p = py_buf.format; - while (strchr("@<>!=", *p)) { - p++; // ignore little/bit endian (and alignment) - } - if (*p == 'f' || *p == 'd' || *p == 'e') { - // 'f', 'd', and 'e' are float, double, and half, respectively. - halide_buf.type.code = halide_type_float; - } else if (*p >= 'a' && *p <= 'z') { - // lowercase is signed int. - halide_buf.type.code = halide_type_int; - } else { - // uppercase is unsigned int. - halide_buf.type.code = halide_type_uint; - } - const char *type_codes = "bBhHiIlLqQfde"; // integers and floats - if (*p == '?') { - // Special-case bool, so that it is a distinct type vs uint8_t - // (even though the memory layout is identical) - halide_buf.type.bits = 1; - } else if (strchr(type_codes, *p)) { - halide_buf.type.bits = (uint8_t)py_buf.itemsize * 8; - } else { - // We don't handle 's' and 'p' (char[]) and 'P' (void*) - PyErr_Format(PyExc_ValueError, "Invalid data type for %s: %s", name, py_buf.format); - return false; - } - } - halide_buf.dimensions = py_buf.ndim; - halide_buf.dim = halide_dim; - halide_buf.host = (uint8_t *)py_buf.buf; - - return true; -} - -} // namespace Halide::PythonRuntime - extern "C" { HALIDE_EXPORT_SYMBOL PyObject *_HALIDE_EXPAND_AND_CONCAT(PyInit_, HALIDE_PYTHON_EXTENSION_MODULE_NAME)() { @@ -289,96 +210,13 @@ void PythonExtensionGen::compile(const Module &module) { extern_decl_gen.compile(module); } - dest << normalize_line_endings(R"INLINE_CODE( -namespace Halide::PythonRuntime { -extern bool unpack_buffer(PyObject *py_obj, - int py_getbuffer_flags, - const char *name, - int dimensions, - Py_buffer &py_buf, - halide_dimension_t *halide_dim, - halide_buffer_t &halide_buf, - bool &py_buf_valid, - bool &needs_device_free); -} // namespace Halide::PythonRuntime - -namespace { - -template -struct PyHalideBuffer { - // Must allocate at least 1, even if d=0 - static constexpr int dims_to_allocate = (dimensions < 1) ? 1 : dimensions; - static constexpr const char* get_raw_halide_runtime_buffer_fn = "_get_raw_halide_buffer_t"; - - Py_buffer py_buf; - halide_buffer_t* halide_buf = nullptr; - bool py_buf_needs_release = false; - bool needs_device_free = false; - - bool unpack_from_halide_buffer(PyObject *py_obj) { - if (!PyObject_HasAttrString(py_obj, get_raw_halide_runtime_buffer_fn)) { - return false; - } - - PyObject *py_raw_buffer = PyObject_CallMethod(py_obj, get_raw_halide_runtime_buffer_fn, NULL); - if (!py_raw_buffer) { - PyErr_Clear(); - return false; - } - - if (!PyLong_Check(py_raw_buffer)) { - Py_DECREF(py_raw_buffer); - return false; - } - - uintptr_t py_raw_buffer_ptr = (uintptr_t)PyLong_AsUnsignedLongLong(py_raw_buffer); - Py_DECREF(py_raw_buffer); - - if (py_raw_buffer_ptr == 0) { - return false; - } - - halide_buf = reinterpret_cast(py_raw_buffer_ptr); - return true; - } - - bool unpack(PyObject *py_obj, int py_getbuffer_flags, const char *name) { - if (unpack_from_halide_buffer(py_obj)) { - return true; - } - if (Halide::PythonRuntime::unpack_buffer( - py_obj, py_getbuffer_flags, name, dimensions, py_buf, - unpacked_dim, unpacked_buf, py_buf_needs_release, - needs_device_free)) { - halide_buf = &unpacked_buf; - return true; - } - return false; - } - - ~PyHalideBuffer() { - if (needs_device_free) { - halide_device_free(nullptr, halide_buf); - } - if (py_buf_needs_release) { - PyBuffer_Release(&py_buf); - } - } - - PyHalideBuffer() = default; - PyHalideBuffer(const PyHalideBuffer &other) = delete; - PyHalideBuffer &operator=(const PyHalideBuffer &other) = delete; - PyHalideBuffer(PyHalideBuffer &&other) = delete; - PyHalideBuffer &operator=(PyHalideBuffer &&other) = delete; - -private: - halide_dimension_t unpacked_dim[dims_to_allocate]; - halide_buffer_t unpacked_buf; -}; - -} // namespace - -)INLINE_CODE"); + // Emit the buffer marshalling helpers (Halide::PythonRuntime::unpack_buffer + // and the PyHalideBuffer wrapper) from the shared source of truth. This is + // the same implementation compiled into the standalone `halide.runtime` + // module; see src/PythonExtensionRuntime.template.cpp. + dest << "\n" + << normalize_line_endings((const char *)halide_c_template_PythonExtensionRuntime) + << "\n"; for (const auto &f : module.functions()) { if (f.linkage == LinkageType::ExternalPlusMetadata) { diff --git a/src/PythonExtensionRuntime.template.cpp b/src/PythonExtensionRuntime.template.cpp new file mode 100644 index 000000000000..ff9e6c0c1165 --- /dev/null +++ b/src/PythonExtensionRuntime.template.cpp @@ -0,0 +1,186 @@ +/* This file is the single source of truth for the buffer-protocol <-> + * halide_buffer_t marshalling used to invoke AOT-compiled Halide pipelines from + * Python. It is used two ways: + * + * 1. It is embedded (via binary2cpp, as halide_c_template_PythonExtensionRuntime) + * into libHalide and emitted verbatim into each generated ".py.cpp" Python + * extension by PythonExtensionGen, so those extensions remain self-contained + * and depend on nothing beyond and HalideRuntime.h. + * + * 2. It is compiled directly into the standalone `halide.runtime` module, which + * can load and call precompiled AOT kernels without depending on libHalide. + * + * Because it is emitted into generated code that already includes , + * , and "HalideRuntime.h", the includes below are include-guard no-ops + * in that context; they are present so this file is a valid translation unit on + * its own. `unpack_buffer` is `inline` so that emitting its definition into every + * generated ".py.cpp" (including the multi-library case) does not violate the ODR. + */ +#include + +#include +#include + +#include "HalideRuntime.h" + +namespace Halide::PythonRuntime { + +inline bool unpack_buffer(PyObject *py_obj, + int py_getbuffer_flags, + const char *name, + int dimensions, + Py_buffer &py_buf, + halide_dimension_t *halide_dim, + halide_buffer_t &halide_buf, + bool &py_buf_valid, + bool &needs_device_free) { + py_buf_valid = false; + needs_device_free = false; + + memset(&py_buf, 0, sizeof(py_buf)); + if (PyObject_GetBuffer(py_obj, &py_buf, PyBUF_FORMAT | PyBUF_STRIDED_RO | py_getbuffer_flags) < 0) { + PyErr_Format(PyExc_ValueError, "Invalid argument %s: Expected %d dimensions, got %d", name, dimensions, py_buf.ndim); + return false; + } + py_buf_valid = true; + + if (dimensions && py_buf.ndim != dimensions) { + PyErr_Format(PyExc_ValueError, "Invalid argument %s: Expected %d dimensions, got %d", name, dimensions, py_buf.ndim); + return false; + } + // Always reverse axes. + // TODO(jiawen): Can probably consolidate this with similar code in PyCallable.cpp and + // pybufferinfo_to_halidebuffer() in PyBuffer.h. + for (int i = 0; i < py_buf.ndim; ++i) { + const int j = py_buf.ndim - 1 - i; // numpy axis j maps to Halide dim i + halide_dim[i].min = 0; + halide_dim[i].stride = (int)(py_buf.strides[j] / py_buf.itemsize); // Python strides are in bytes + halide_dim[i].extent = (int)py_buf.shape[j]; + halide_dim[i].flags = 0; + if (py_buf.suboffsets && py_buf.suboffsets[j] >= 0) { + // Halide doesn't support arrays of pointers. But we should never see this + // anyway, since we did not specify PyBUF_INDIRECT. + PyErr_Format(PyExc_ValueError, "Invalid buffer: suboffsets not supported"); + return false; + } + } + + halide_buf = {}; + needs_device_free = true; + if (!py_buf.format) { + halide_buf.type.code = halide_type_uint; + halide_buf.type.bits = 8; + } else { + /* Convert struct type code. See + * https://docs.python.org/2/library/struct.html#module-struct */ + char *p = py_buf.format; + while (strchr("@<>!=", *p)) { + p++; // ignore little/bit endian (and alignment) + } + if (*p == 'f' || *p == 'd' || *p == 'e') { + // 'f', 'd', and 'e' are float, double, and half, respectively. + halide_buf.type.code = halide_type_float; + } else if (*p >= 'a' && *p <= 'z') { + // lowercase is signed int. + halide_buf.type.code = halide_type_int; + } else { + // uppercase is unsigned int. + halide_buf.type.code = halide_type_uint; + } + const char *type_codes = "bBhHiIlLqQfde"; // integers and floats + if (*p == '?') { + // Special-case bool, so that it is a distinct type vs uint8_t + // (even though the memory layout is identical) + halide_buf.type.bits = 1; + } else if (strchr(type_codes, *p)) { + halide_buf.type.bits = (uint8_t)py_buf.itemsize * 8; + } else { + // We don't handle 's' and 'p' (char[]) and 'P' (void*) + PyErr_Format(PyExc_ValueError, "Invalid data type for %s: %s", name, py_buf.format); + return false; + } + } + halide_buf.dimensions = py_buf.ndim; + halide_buf.dim = halide_dim; + halide_buf.host = (uint8_t *)py_buf.buf; + + return true; +} + +} // namespace Halide::PythonRuntime + +namespace { + +template +struct PyHalideBuffer { + // Must allocate at least 1, even if d=0 + static constexpr int dims_to_allocate = (dimensions < 1) ? 1 : dimensions; + static constexpr const char *get_raw_halide_runtime_buffer_fn = "_get_raw_halide_buffer_t"; + + Py_buffer py_buf; + halide_buffer_t *halide_buf = nullptr; + bool py_buf_needs_release = false; + bool needs_device_free = false; + + bool unpack_from_halide_buffer(PyObject *py_obj) { + if (!PyObject_HasAttrString(py_obj, get_raw_halide_runtime_buffer_fn)) { + return false; + } + + PyObject *py_raw_buffer = PyObject_CallMethod(py_obj, get_raw_halide_runtime_buffer_fn, nullptr); + if (!py_raw_buffer) { + PyErr_Clear(); + return false; + } + + if (!PyLong_Check(py_raw_buffer)) { + Py_DECREF(py_raw_buffer); + return false; + } + + uintptr_t py_raw_buffer_ptr = (uintptr_t)PyLong_AsUnsignedLongLong(py_raw_buffer); + Py_DECREF(py_raw_buffer); + + if (py_raw_buffer_ptr == 0) { + return false; + } + + halide_buf = reinterpret_cast(py_raw_buffer_ptr); + return true; + } + + bool unpack(PyObject *py_obj, int py_getbuffer_flags, const char *name) { + if (unpack_from_halide_buffer(py_obj)) { + return true; + } + if (Halide::PythonRuntime::unpack_buffer( + py_obj, py_getbuffer_flags, name, dimensions, py_buf, + unpacked_dim, unpacked_buf, py_buf_needs_release, + needs_device_free)) { + halide_buf = &unpacked_buf; + return true; + } + return false; + } + + ~PyHalideBuffer() { + if (needs_device_free) { + halide_device_free(nullptr, halide_buf); + } + if (py_buf_needs_release) { + PyBuffer_Release(&py_buf); + } + } + + PyHalideBuffer() = default; + PyHalideBuffer(const PyHalideBuffer &other) = delete; + PyHalideBuffer &operator=(const PyHalideBuffer &other) = delete; + PyHalideBuffer(PyHalideBuffer &&other) = delete; + PyHalideBuffer &operator=(PyHalideBuffer &&other) = delete; + +private: + halide_dimension_t unpacked_dim[dims_to_allocate]; + halide_buffer_t unpacked_buf; +}; + +} // namespace From 16b1d804eb8253bafc970794ec35383655660f0e Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Thu, 20 Aug 2026 17:35:58 -0400 Subject: [PATCH 03/39] Remove unused tgz and zip packaging scripts --- packaging/tgz/package.sh | 19 ------------- packaging/zip/package.bat | 60 --------------------------------------- 2 files changed, 79 deletions(-) delete mode 100755 packaging/tgz/package.sh delete mode 100644 packaging/zip/package.bat diff --git a/packaging/tgz/package.sh b/packaging/tgz/package.sh deleted file mode 100755 index 26bcbbcdf175..000000000000 --- a/packaging/tgz/package.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -set -e -o pipefail - -halide_source=$(realpath "$1") -halide_build_root=$(realpath "$2") - -[ -z "$LLVM_DIR" ] && echo "Must set specific LLVM_DIR for packaging" && exit -[ -z "$Clang_DIR" ] && echo "Must set specific Clang_DIR for packaging" && exit -[ -z "$halide_source" ] && echo "Usage: $0 " && exit -[ -z "$halide_build_root" ] && echo "Usage: $0 " && exit - -cmake --preset=package-unix -S "$halide_source" -B "$halide_build_root/shared-Release" \ - "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" - -cmake --build "$halide_build_root/shared-Release" - -cd "$halide_build_root" - -cpack -G TGZ -C Release diff --git a/packaging/zip/package.bat b/packaging/zip/package.bat deleted file mode 100644 index be516124be06..000000000000 --- a/packaging/zip/package.bat +++ /dev/null @@ -1,60 +0,0 @@ -@echo off - -set halide_source=%~1 -set halide_build_root=%~2 -set halide_arch=%~3 - -if not exist "%VCPKG_ROOT%\.vcpkg-root" ( - echo Must define VCPKG_ROOT to be the root of the VCPKG install - goto error -) - -if not exist "%LLVM_DIR%\LLVMConfig.cmake" ( - echo Must set specific LLVM_DIR for packaging - goto error -) - -if not exist "%Clang_DIR%\ClangConfig.cmake" ( - echo Must set specific Clang_DIR for packaging - goto error -) - -if not exist "%LLD_DIR%\LLDConfig.cmake" ( - echo Must set specific LLD_DIR for packaging - goto error -) - -if "%halide_source%" == "" ( - echo Usage: %~0 "" "" [Win32,x64,ARM,ARM64] - goto error -) - -if "%halide_build_root%" == "" ( - echo Usage: %~0 "" "" [Win32,x64,ARM,ARM64] - goto error -) - -if "%halide_arch%" == "" ( - echo Usage: %~0 "" "" [Win32,x64,ARM,ARM64] - goto error -) - -cmake --preset=package-windows -A "%halide_arch%" -S "%halide_source%" -B "%halide_build_root%" -if ERRORLEVEL 1 goto error - -REM We don't distribute Debug binaries because they aren't useful -cmake --build "%halide_build_root%" --config Release -if ERRORLEVEL 1 goto error - -pushd "%halide_build_root%" -cpack -G ZIP -C "Release" -if ERRORLEVEL 1 ( - popd - goto error -) -popd - -exit /b - -:error -exit /b 1 From 338c3b24956fdb5dbe82f90a7671e44794d1132e Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Thu, 20 Aug 2026 19:08:52 -0400 Subject: [PATCH 04/39] Use SPDX license form --- packaging/pip-bin/pyproject.toml | 2 +- packaging/pip-runtime/pyproject.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packaging/pip-bin/pyproject.toml b/packaging/pip-bin/pyproject.toml index 4918318eaf0e..1267bd762cef 100644 --- a/packaging/pip-bin/pyproject.toml +++ b/packaging/pip-bin/pyproject.toml @@ -9,7 +9,7 @@ authors = [ ] maintainers = [{ name = "Alex Reinking", email = "areinking@adobe.com" }] description = "Python-independent binary components for Halide (libHalide, autoschedulers, generator tools, headers, CMake package files)." -license = { file = "../../LICENSE.txt" } +license = "MIT" requires-python = ">=3.10" dynamic = ['version'] classifiers = [ diff --git a/packaging/pip-runtime/pyproject.toml b/packaging/pip-runtime/pyproject.toml index 1858ae252a01..c0385d4ddd3f 100644 --- a/packaging/pip-runtime/pyproject.toml +++ b/packaging/pip-runtime/pyproject.toml @@ -13,7 +13,7 @@ authors = [ ] maintainers = [{ name = "Alex Reinking", email = "areinking@adobe.com" }] description = "Standalone Halide runtime: load and call precompiled Halide AOT kernels without depending on libHalide (no compiler, no LLVM)." -license = { file = "../../LICENSE.txt" } +license = "MIT" readme = "README.md" requires-python = ">=3.10" dynamic = ['version'] diff --git a/pyproject.toml b/pyproject.toml index 06daee871a8a..844c97263235 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ authors = [ ] maintainers = [{ name = "Alex Reinking", email = "areinking@adobe.com" }] description = "Halide is a programming language designed to make it easier to write high-performance image and array processing code." -license = { file = "LICENSE.txt" } +license = "MIT" readme = "./packaging/pip/README.md" requires-python = ">=3.10" dynamic = ['version', 'dependencies'] From 7386d31a46190d57bb4fdfd2468e0d554e3657a9 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Fri, 21 Aug 2026 13:29:47 -0400 Subject: [PATCH 05/39] Upgrade pre-commit hooks --- .pre-commit-config.yaml | 14 +- packaging/pip-bin/pyproject.toml | 6 +- packaging/pip-runtime/pyproject.toml | 7 +- packaging/pip/_dynamic_metadata.py | 82 ++---- pyproject.toml | 47 ++-- src/autoschedulers/adams2019/CMakeLists.txt | 4 +- .../anderson2021/CMakeLists.txt | 4 +- src/runtime/CMakeLists.txt | 12 +- uv.lock | 233 +----------------- 9 files changed, 82 insertions(+), 327 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 45080e2be295..ef8b11c39ebd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: ) - repo: https://github.com/codespell-project/codespell - rev: v2.4.1 + rev: v2.4.3 hooks: - id: codespell args: [ --ignore-words-list, "CreateOr,implementors,PADD,re-use,re-used,re-using,SME,+sme,subtile,subtiles,tRe" ] @@ -63,12 +63,12 @@ repos: ) - repo: https://github.com/gitleaks/gitleaks - rev: v8.9.0 + rev: v8.30.0 hooks: - id: gitleaks - repo: https://github.com/google/keep-sorted - rev: v0.8.0 + rev: v0.10.0 hooks: - id: keep-sorted args: [ @@ -89,19 +89,19 @@ repos: - mdformat-shfmt - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.5 + rev: v0.16.4 hooks: - id: ruff-check - id: ruff-format - repo: https://github.com/shellcheck-py/shellcheck-py - rev: v0.11.0.1 + rev: v0.11.0.1-1 hooks: - id: shellcheck exclude: ^apps/HelloAndroid.*/gradlew$ - repo: https://github.com/maxwinterstein/shfmt-py - rev: v3.12.0.1 + rev: v4.0.0 hooks: - id: shfmt args: [ -i, "4", -ci, -s, -w ] @@ -113,7 +113,7 @@ repos: - id: taplo-format - repo: https://github.com/halide/cmtk-pre-commit - rev: v0.1.0 + rev: v0.2.1 hooks: - id: cmtk diff --git a/packaging/pip-bin/pyproject.toml b/packaging/pip-bin/pyproject.toml index 1267bd762cef..99e2c07faec0 100644 --- a/packaging/pip-bin/pyproject.toml +++ b/packaging/pip-bin/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["scikit-build-core~=0.11.0", "setuptools-scm>=8.3.1"] +requires = ["scikit-build-core~=1.0.3", "setuptools-scm>=8.3.1"] build-backend = "scikit_build_core.build" [project] @@ -32,6 +32,9 @@ Documentation = "https://halide-lang.org/docs" Issues = "https://github.com/halide/Halide/issues" Repository = "https://github.com/halide/Halide.git" +[[tool.dynamic-metadata]] +provider = "scikit_build_core.metadata.setuptools_scm" + [tool.scikit-build] minimum-version = "build-system.requires" cmake.version = ">=3.28" @@ -41,7 +44,6 @@ wheel.packages = ["src/halide_bin"] wheel.install-dir = "halide_bin/data" # No Python extension modules in this package -- python-version-agnostic tag. wheel.py-api = "py3" -metadata.version.provider = "scikit_build_core.metadata.setuptools_scm" [tool.scikit-build.cmake.define] CMAKE_DISABLE_FIND_PACKAGE_JPEG = true diff --git a/packaging/pip-runtime/pyproject.toml b/packaging/pip-runtime/pyproject.toml index c0385d4ddd3f..208d16926a7e 100644 --- a/packaging/pip-runtime/pyproject.toml +++ b/packaging/pip-runtime/pyproject.toml @@ -1,7 +1,7 @@ [build-system] requires = [ "pybind11>=2.11.1", - "scikit-build-core~=0.11.0", + "scikit-build-core~=1.0.3", "setuptools-scm>=8.3.1", ] build-backend = "scikit_build_core.build" @@ -42,6 +42,9 @@ Documentation = "https://github.com/halide/Halide/blob/main/doc/Python.md" Issues = "https://github.com/halide/Halide/issues" Repository = "https://github.com/halide/Halide.git" +[[tool.dynamic-metadata]] +provider = "scikit_build_core.metadata.setuptools_scm" + [tool.scikit-build] minimum-version = "build-system.requires" experimental = true @@ -59,8 +62,6 @@ install.components = ["Halide_PythonRuntime"] wheel.install-dir = "halide" sdist.include = ["dependencies/"] -metadata.version.provider = "scikit_build_core.metadata.setuptools_scm" - [tool.scikit-build.cmake.define] CMAKE_DISABLE_FIND_PACKAGE_JPEG = true CMAKE_DISABLE_FIND_PACKAGE_PNG = true diff --git a/packaging/pip/_dynamic_metadata.py b/packaging/pip/_dynamic_metadata.py index 35378ce1c70c..361f9f4afcbf 100644 --- a/packaging/pip/_dynamic_metadata.py +++ b/packaging/pip/_dynamic_metadata.py @@ -1,71 +1,31 @@ """ Dynamic metadata provider for the `halide` pip package. - -Computes the version via setuptools_scm -- identically to -scikit_build_core's builtin `scikit_build_core.metadata.setuptools_scm` -provider -- and reuses that exact value to pin the `halide-bin` runtime -dependency when building in split mode (HALIDE_SPLIT_BUILD=1 -- see -.github/workflows/pip.yml), so the `==` pin and the actual `halide-bin` -version can never silently diverge. Outside of split mode (e.g. a plain -`pip install .`), `dependencies` is identical to the static list this -project shipped before the split. """ from __future__ import annotations +from typing import Any +from collections.abc import Mapping -import os - -__all__ = ["dynamic_metadata", "get_requires_for_dynamic_metadata"] - - -def __dir__() -> list[str]: - return __all__ - - -_STATIC_DEPENDENCIES = [ - "imageio>=2", - "pillow; platform_machine == 'armv8l' or platform_machine == 'armv7l'", - "numpy>=1.26", -] - - -def _compute_version() -> str: - from setuptools_scm import Configuration, _get_version - - config = Configuration.from_file("pyproject.toml") - try: - version = _get_version(config, force_write_version_files=True) - except TypeError: # setuptools_scm < 8 - version = _get_version(config) - - if version is None: - msg = f"setuptools-scm was unable to detect version for {config.absolute_root}." - raise ValueError(msg) - - return version +__all__ = ["dynamic_metadata"] def dynamic_metadata( - field: str, - settings: dict[str, object] | None = None, -) -> str | list[str]: - if settings: - msg = "No inline configuration is supported" - raise ValueError(msg) - - if field == "version": - return _compute_version() + settings: Mapping[str, Any], + project: Mapping[str, Any], +) -> dict[str, Any]: + import os - if field == "dependencies": - if not os.environ.get("HALIDE_SPLIT_BUILD"): - return list(_STATIC_DEPENDENCIES) - return [*_STATIC_DEPENDENCIES, f"halide-bin=={_compute_version()}"] - - msg = f"Only 'version' and 'dependencies' fields are supported, not {field!r}" - raise ValueError(msg) - - -def get_requires_for_dynamic_metadata( - _settings: dict[str, object] | None = None, -) -> list[str]: - return ["setuptools-scm"] + if settings: + raise ValueError("No inline configuration is supported") + + if os.environ.get("HALIDE_SPLIT_BUILD"): + deps = [ + "imageio>=2", + "pillow; platform_machine == 'armv8l' or platform_machine == 'armv7l'", + "numpy>=1.26", + f"halide-bin=={project['version']}", + ] + else: + deps = [] + + return {"dependencies": deps} diff --git a/pyproject.toml b/pyproject.toml index 844c97263235..f5fd123d1537 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [build-system] requires = [ "pybind11>=2.11.1", - "scikit-build-core~=0.11.0", + "scikit-build-core>=1.0.3", "setuptools-scm>=8.3.1", ] build-backend = "scikit_build_core.build" @@ -62,7 +62,7 @@ classifiers = [ dev = [ # Matches build-system.requires "pybind11>=2.11.1", - "scikit-build-core~=0.11.0", + "scikit-build-core>=1.0.3", "setuptools-scm>=8.3.1", ] apps = [ @@ -110,33 +110,39 @@ Documentation = "https://github.com/halide/Halide/blob/main/doc/Python.md" Issues = "https://github.com/halide/Halide/issues" Repository = "https://github.com/halide/Halide.git" +[[tool.dynamic-metadata]] +provider = "scikit_build_core.metadata.setuptools_scm" + +[[tool.dynamic-metadata]] +provider = { path = "packaging/pip", module = "_dynamic_metadata" } + [tool.scikit-build] -# Required for in-tree dynamic-metadata plugins (packaging/pip/_dynamic_metadata.py). -experimental = true +minimum-version = "build-system.requires" cmake.version = ">=3.28" ninja.version = ">=1.11,!=1.13.0" wheel.install-dir = "halide" -sdist.include = ["dependencies/"] -sdist.exclude = [ - ".github/", - "apps/", - "test/", - "tutorial/", - "dependencies/update-*.sh", +sdist.inclusion-mode = "explicit" +sdist.include = [ + "cmake", + "dependencies", + "packaging", + "python_bindings", + "src", + "tools", + ".git_archival.txt", + "CMakeLists.txt", + "LICENSE.txt", + "pyproject.toml", + "README.md", + "uv.lock", + "vcpkg.json", + "vcpkg-configuration.json", ] - -[tool.scikit-build.metadata.version] -provider = "_dynamic_metadata" -provider-path = "packaging/pip" - -[tool.scikit-build.metadata.dependencies] -provider = "_dynamic_metadata" -provider-path = "packaging/pip" +sdist.exclude = ["dependencies/update-*.sh"] [tool.scikit-build.cmake.define] CMAKE_DISABLE_FIND_PACKAGE_JPEG = true CMAKE_DISABLE_FIND_PACKAGE_PNG = true -FETCHCONTENT_FULLY_DISCONNECTED = true Halide_ENABLE_EXCEPTIONS = true Halide_ENABLE_RTTI = true Halide_INSTALL_PYTHONDIR = "." @@ -144,6 +150,7 @@ Halide_WASM_BACKEND = "wabt" WITH_PYTHON_BINDINGS = true WITH_TESTS = false WITH_TUTORIALS = false +WITH_UTILS = false ## # Don't version libHalide.so/dylib -- wheels are zip files that do diff --git a/src/autoschedulers/adams2019/CMakeLists.txt b/src/autoschedulers/adams2019/CMakeLists.txt index 06c1ee75af04..88fcac946d92 100644 --- a/src/autoschedulers/adams2019/CMakeLists.txt +++ b/src/autoschedulers/adams2019/CMakeLists.txt @@ -10,8 +10,8 @@ set(WF_CPP baseline.cpp) add_custom_command( OUTPUT ${WF_CPP} COMMAND - binary2cpp baseline_weights < "$" > - ${WF_CPP} + binary2cpp baseline_weights < "$" + > ${WF_CPP} DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/baseline.weights" binary2cpp VERBATIM ) diff --git a/src/autoschedulers/anderson2021/CMakeLists.txt b/src/autoschedulers/anderson2021/CMakeLists.txt index 345d2cb6e3ea..c4a84cc4dcc4 100644 --- a/src/autoschedulers/anderson2021/CMakeLists.txt +++ b/src/autoschedulers/anderson2021/CMakeLists.txt @@ -9,8 +9,8 @@ set(WF_CPP baseline.cpp) add_custom_command( OUTPUT ${WF_CPP} COMMAND - binary2cpp baseline_weights < "$" > - ${WF_CPP} + binary2cpp baseline_weights < "$" + > ${WF_CPP} DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/baseline.weights" binary2cpp VERBATIM ) diff --git a/src/runtime/CMakeLists.txt b/src/runtime/CMakeLists.txt index 0440be914ace..cac63a328b52 100644 --- a/src/runtime/CMakeLists.txt +++ b/src/runtime/CMakeLists.txt @@ -342,8 +342,8 @@ set(RT_BC "${CMAKE_CURRENT_SOURCE_DIR}/nvidia_libdevice_bitcode/libdevice.10.bc" add_custom_command( OUTPUT "_initmod_ptx_libdevice.cpp" COMMAND - binary2cpp "halide_internal_initmod_ptx_libdevice_ll" < "$" > - "_initmod_ptx_libdevice.cpp" + binary2cpp "halide_internal_initmod_ptx_libdevice_ll" < "$" + > "_initmod_ptx_libdevice.cpp" DEPENDS binary2cpp "${RT_BC}" VERBATIM ) @@ -352,8 +352,8 @@ target_sources(Halide_initmod PRIVATE "_initmod_ptx_libdevice.cpp") add_custom_command( OUTPUT "_initmod_inlined_c.cpp" COMMAND - binary2cpp "halide_internal_initmod_inlined_c" < - "$" > "_initmod_inlined_c.cpp" + binary2cpp "halide_internal_initmod_inlined_c" + < "$" > "_initmod_inlined_c.cpp" DEPENDS "halide_buffer_t.cpp" binary2cpp VERBATIM ) @@ -364,8 +364,8 @@ foreach (i IN LISTS RUNTIME_HEADER_FILES) add_custom_command( OUTPUT "_initmod_${SYM_NAME}.cpp" COMMAND - binary2cpp "halide_internal_runtime_header_${SYM_NAME}" < - "$" > "_initmod_${SYM_NAME}.cpp" + binary2cpp "halide_internal_runtime_header_${SYM_NAME}" + < "$" > "_initmod_${SYM_NAME}.cpp" DEPENDS "${i}" binary2cpp VERBATIM ) diff --git a/uv.lock b/uv.lock index a6f0e1e7544b..0ced1555937f 100644 --- a/uv.lock +++ b/uv.lock @@ -386,15 +386,6 @@ wheels = [ [[package]] name = "halide" source = { editable = "." } -dependencies = [ - { name = "imageio", version = "2.37.2", source = { registry = "https://piwheels.org/simple" }, marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "imageio", version = "2.37.2", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "numpy", version = "2.4.2", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine == 'armv7l') or (python_full_version >= '3.11' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "pillow", version = "12.3.0", source = { registry = "https://piwheels.org/simple" }, marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, -] [package.dev-dependencies] apps = [ @@ -484,13 +475,6 @@ tools = [ ] [package.metadata] -requires-dist = [ - { name = "imageio", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=2" }, - { name = "imageio", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=2", index = "https://piwheels.org/simple" }, - { name = "numpy", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=1.26" }, - { name = "numpy", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=1.26", index = "https://piwheels.org/simple" }, - { name = "pillow", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", index = "https://piwheels.org/simple" }, -] [package.metadata.requires-dev] apps = [ @@ -507,7 +491,7 @@ ci-base = [ { name = "pybind11", specifier = ">=2.11.1" }, { name = "pytest", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'" }, { name = "ruff", specifier = ">=0.12" }, - { name = "scikit-build-core", specifier = "~=0.11.0" }, + { name = "scikit-build-core", specifier = ">=1.0.3" }, { name = "setuptools-scm", specifier = ">=8.3.1" }, { name = "tbump", specifier = ">=6.11" }, ] @@ -521,7 +505,7 @@ ci-llvm-21 = [ { name = "pybind11", specifier = ">=2.11.1" }, { name = "pytest", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'" }, { name = "ruff", specifier = ">=0.12" }, - { name = "scikit-build-core", specifier = "~=0.11.0" }, + { name = "scikit-build-core", specifier = ">=1.0.3" }, { name = "setuptools-scm", specifier = ">=8.3.1" }, { name = "tbump", specifier = ">=6.11" }, ] @@ -535,7 +519,7 @@ ci-llvm-22 = [ { name = "pybind11", specifier = ">=2.11.1" }, { name = "pytest", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'" }, { name = "ruff", specifier = ">=0.12" }, - { name = "scikit-build-core", specifier = "~=0.11.0" }, + { name = "scikit-build-core", specifier = ">=1.0.3" }, { name = "setuptools-scm", specifier = ">=8.3.1" }, { name = "tbump", specifier = ">=6.11" }, ] @@ -549,13 +533,13 @@ ci-llvm-main = [ { name = "pybind11", specifier = ">=2.11.1" }, { name = "pytest", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'" }, { name = "ruff", specifier = ">=0.12" }, - { name = "scikit-build-core", specifier = "~=0.11.0" }, + { name = "scikit-build-core", specifier = ">=1.0.3" }, { name = "setuptools-scm", specifier = ">=8.3.1" }, { name = "tbump", specifier = ">=6.11" }, ] dev = [ { name = "pybind11", specifier = ">=2.11.1" }, - { name = "scikit-build-core", specifier = "~=0.11.0" }, + { name = "scikit-build-core", specifier = ">=1.0.3" }, { name = "setuptools-scm", specifier = ">=8.3.1" }, ] docs = [ @@ -685,51 +669,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" }, ] -[[package]] -name = "imageio" -version = "2.37.2" -source = { registry = "https://piwheels.org/simple" } -resolution-markers = [ - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", -] -dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "numpy", version = "2.4.2", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine == 'armv7l') or (python_full_version >= '3.11' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "pillow", version = "12.3.0", source = { registry = "https://piwheels.org/simple" }, marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, -] -wheels = [ - { url = "https://piwheels.org/simple/imageio/imageio-2.37.2-py3-none-any.whl", hash = "sha256:85f2b4d9e29c87955339e7417e54574e335d06d5c180bdbdc03dcdfdb56cd75c" }, -] - -[[package]] -name = "imageio" -version = "2.37.2" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", -] -dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "pillow", version = "12.3.0", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a3/6f/606be632e37bf8d05b253e8626c2291d74c691ddc7bcdf7d6aaf33b32f6a/imageio-2.37.2.tar.gz", hash = "sha256:0212ef2727ac9caa5ca4b2c75ae89454312f440a756fcfc8ef1993e718f50f8a", size = 389600, upload-time = "2025-11-04T14:29:39.898Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/fe/301e0936b79bcab4cacc7548bf2853fc28dced0a578bab1f7ef53c9aa75b/imageio-2.37.2-py3-none-any.whl", hash = "sha256:ad9adfb20335d718c03de457358ed69f141021a333c40a53e57273d8a5bd0b9b", size = 317646, upload-time = "2025-11-04T14:29:37.948Z" }, -] - [[package]] name = "imagesize" version = "2.0.0" @@ -1041,21 +980,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, ] -[[package]] -name = "numpy" -version = "2.2.6" -source = { registry = "https://piwheels.org/simple" } -resolution-markers = [ - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", -] -wheels = [ - { url = "https://piwheels.org/simple/numpy/numpy-2.2.6-cp311-cp311-linux_armv6l.whl", hash = "sha256:9d5168644d4f18fda98839f03a5e6ede9b1b780ac4a187c188971a3dc4b0382e" }, - { url = "https://piwheels.org/simple/numpy/numpy-2.2.6-cp311-cp311-linux_armv7l.whl", hash = "sha256:9d5168644d4f18fda98839f03a5e6ede9b1b780ac4a187c188971a3dc4b0382e" }, - { url = "https://piwheels.org/simple/numpy/numpy-2.2.6-cp313-cp313-linux_armv6l.whl", hash = "sha256:495b42b52f5be434ff56e549d9deac19ac50de272f1f803755408e21c5e5e8cc" }, - { url = "https://piwheels.org/simple/numpy/numpy-2.2.6-cp313-cp313-linux_armv7l.whl", hash = "sha256:495b42b52f5be434ff56e549d9deac19ac50de272f1f803755408e21c5e5e8cc" }, -] - [[package]] name = "numpy" version = "2.2.6" @@ -1122,23 +1046,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, ] -[[package]] -name = "numpy" -version = "2.4.2" -source = { registry = "https://piwheels.org/simple" } -resolution-markers = [ - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", -] -wheels = [ - { url = "https://piwheels.org/simple/numpy/numpy-2.4.2-cp311-cp311-linux_armv6l.whl", hash = "sha256:67750511a0e237521e4c633ead976d0f77d3879f9c078de89c5aca943ee8fc56" }, - { url = "https://piwheels.org/simple/numpy/numpy-2.4.2-cp311-cp311-linux_armv7l.whl", hash = "sha256:67750511a0e237521e4c633ead976d0f77d3879f9c078de89c5aca943ee8fc56" }, - { url = "https://piwheels.org/simple/numpy/numpy-2.4.2-cp313-cp313-linux_armv6l.whl", hash = "sha256:c46cb8ff822299dca11cedfb7c631fa6169dc30764c50764f6a4d7ba6690cd55" }, - { url = "https://piwheels.org/simple/numpy/numpy-2.4.2-cp313-cp313-linux_armv7l.whl", hash = "sha256:c46cb8ff822299dca11cedfb7c631fa6169dc30764c50764f6a4d7ba6690cd55" }, -] - [[package]] name = "numpy" version = "2.4.2" @@ -1287,129 +1194,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl", hash = "sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723", size = 55206, upload-time = "2026-01-27T03:59:45.137Z" }, ] -[[package]] -name = "pillow" -version = "12.3.0" -source = { registry = "https://piwheels.org/simple" } -resolution-markers = [ - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", -] -wheels = [ - { url = "https://piwheels.org/simple/pillow/pillow-12.3.0-cp311-cp311-linux_armv6l.whl", hash = "sha256:402669e2c8551ae30ffafa9bb013d8797d7cd7132dd8ed5db14edb6f303c5d2a" }, - { url = "https://piwheels.org/simple/pillow/pillow-12.3.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:402669e2c8551ae30ffafa9bb013d8797d7cd7132dd8ed5db14edb6f303c5d2a" }, - { url = "https://piwheels.org/simple/pillow/pillow-12.3.0-cp313-cp313-linux_armv6l.whl", hash = "sha256:d8b2b201942a627bca287184e7330d3ccbf4a6cce11ccc6ca8d2fb3bd1b08dff" }, - { url = "https://piwheels.org/simple/pillow/pillow-12.3.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:d8b2b201942a627bca287184e7330d3ccbf4a6cce11ccc6ca8d2fb3bd1b08dff" }, -] - -[[package]] -name = "pillow" -version = "12.3.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", -] -sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/25/c2/669d88644cddb1485bd9534e63e8cf476c8e51cb3c3a1297677023505c0e/pillow-12.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6c0016e7b354317c4e9e525b937ac8596c38d2d232b419529b9cd7a1cd46e39a", size = 5392418, upload-time = "2026-07-01T11:53:27.808Z" }, - { url = "https://files.pythonhosted.org/packages/6b/ba/3762f376a2948e3036488d773a146e0ae6ecc2ca03ac20e2615bd0b2ba02/pillow-12.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bcc33feacfaefce60c12fd500a277533bdc02b10a19f7f6d348763d8140bbba7", size = 4785287, upload-time = "2026-07-01T11:53:29.761Z" }, - { url = "https://files.pythonhosted.org/packages/07/50/b5d688cc9c52d4482f3d5bcab6ce20bc2a74a85d2343841c907444a3be2c/pillow-12.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5594fc43d548a7ed94949d139aa1341b270f1863f11cfd37f5a6c8b778a6b67f", size = 6253754, upload-time = "2026-07-01T11:53:32.298Z" }, - { url = "https://files.pythonhosted.org/packages/4e/89/36f4cd76cf4baf05c50ababb976249153f18c959171c7f6ba09a6f217260/pillow-12.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0606c8bf2cdefea14a43530f7657cbbb7ecf1c4222512492ef4a4434a9501ec", size = 6925605, upload-time = "2026-07-01T11:53:34.487Z" }, - { url = "https://files.pythonhosted.org/packages/eb/c0/4de58cf6633b9e3a6061ef4be6fb91fc3c90b812ece886f531e3c523d777/pillow-12.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:85f998ea1848bc6757289e739cfbdda3a04adfd58b02fc018ce54d754a5ce468", size = 6327788, upload-time = "2026-07-01T11:53:36.433Z" }, - { url = "https://files.pythonhosted.org/packages/87/3c/14d53682a19550dbbaf3b598f807d5457646c510805a44c7d7891cd1cd1a/pillow-12.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:25b9b82bb22e6e2b3cd07b39c68b7b862001226cb3dff7130d1cb914121b39ed", size = 7036288, upload-time = "2026-07-01T11:53:38.712Z" }, - { url = "https://files.pythonhosted.org/packages/38/1d/36279e3c77efe034e4cc2b0393ee74ffdb5a62391dacbf9b916154f5f0b8/pillow-12.3.0-cp310-cp310-win32.whl", hash = "sha256:37dc8f7bbb66efe481bb60defacef820c950c24713fb44962ed6aa2a50966de1", size = 6472396, upload-time = "2026-07-01T11:53:40.781Z" }, - { url = "https://files.pythonhosted.org/packages/48/7c/8fa0039574c476d7c6fa57dd7c32a130436877c6ec1e5ce1cc8ec44878c1/pillow-12.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:300557495eb45ebb8aec96c2da9c4be642fbf7cd937278b4013ba894ea8eb0eb", size = 7226887, upload-time = "2026-07-01T11:53:42.764Z" }, - { url = "https://files.pythonhosted.org/packages/fa/17/e324be141d173c1c919428066c3259f21c1b8982e564e01a4a81e96dbdcf/pillow-12.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:514435a37670e3e5e08f3945b68718b6ed329bb84367777e16f9f4dfe1e61a0f", size = 2568039, upload-time = "2026-07-01T11:53:45.372Z" }, - { url = "https://files.pythonhosted.org/packages/fb/c8/0a78b0e02d7ac54bc03e5321c9220da52f0c2ea83b21f7c40e7f3169c502/pillow-12.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:00808c5e14ef63ac5161091d242999076604ff74b883423a11e5d7bbb38bf756", size = 5392415, upload-time = "2026-07-01T11:53:47.162Z" }, - { url = "https://files.pythonhosted.org/packages/b2/5b/a02d30018abd97ced9f5a6c63d28597694a00d066516b9c1c6de45859fc9/pillow-12.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37d6d0a00072fd2948eb22bce7e1475f34569d90c87c59f7a2ec59541b77f7a6", size = 4785266, upload-time = "2026-07-01T11:53:49.079Z" }, - { url = "https://files.pythonhosted.org/packages/c8/98/766667a4be768150a202836acd9fad19c06824ca86c4286d3cf6b274964e/pillow-12.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bcb46e2f9feff8d06323983bd83ed00c201fdcab3d74973e7072a889b3979fcd", size = 6263814, upload-time = "2026-07-01T11:53:51.32Z" }, - { url = "https://files.pythonhosted.org/packages/3b/2d/ede717bc1144f63886c21fd349bb95860b0d1a21149ff16f2bb362b612b6/pillow-12.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23d27a3e0307ec2244cc51e7287b919aa68d097504ebe19df4e76a98a3eea5bd", size = 6934408, upload-time = "2026-07-01T11:53:53.487Z" }, - { url = "https://files.pythonhosted.org/packages/a3/48/9c58b685e69d49c31af6c8eb9012055fab7e665785165c84796e2c73ce72/pillow-12.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4f883547d4b7f0495ebe7056b0cc2aea76094e7a4abc8e933540f3271df27d9c", size = 6337160, upload-time = "2026-07-01T11:53:55.457Z" }, - { url = "https://files.pythonhosted.org/packages/ff/fa/dc2a5c0ba6df93f67c31d34b808b7ce440b40cdbf96f0b81cde1d1e6fa93/pillow-12.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:236ff70b9312fb68943c703aa842ca6a758abfa45ac187a5e7c1452e96ef72b5", size = 7045172, upload-time = "2026-07-01T11:53:57.736Z" }, - { url = "https://files.pythonhosted.org/packages/86/a5/444817a4d4c4c2417df00513086ca196f388d8f9ef40c2e4ccd1ad1af54b/pillow-12.3.0-cp311-cp311-win32.whl", hash = "sha256:10e41f0fbf1eec8cfd234b8fe17a4caac7c9d0db4c204d3c173a8f9f6ef3232b", size = 6472232, upload-time = "2026-07-01T11:53:59.767Z" }, - { url = "https://files.pythonhosted.org/packages/63/c6/4bad1b18d132a50b27e1365e1ab163616f7a5bb56d330f66f9d1d9d4f9d4/pillow-12.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8e95e1385e4998ae9694eeaa4730ba5457ff61185b3a55e2e7bea0880aef452a", size = 7233653, upload-time = "2026-07-01T11:54:02.066Z" }, - { url = "https://files.pythonhosted.org/packages/fd/16/00f91ab7760dc842f5aad55217e80fc4a7067a0604535249bc8a2d6d9870/pillow-12.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:ebaea975e03d3141d9d3a507df75c9b3ec90fa9d2ffd07567b3a978d9d790b26", size = 2568195, upload-time = "2026-07-01T11:54:04.622Z" }, - { url = "https://files.pythonhosted.org/packages/37/bf/fb3ebff8ddcb76aac5a01389251bbbb9519922a9b520d8247c1ca864a25d/pillow-12.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ba09209fbe443b4acccebe845d8a138b89a8f4fbaeedd44953490b5315d5e965", size = 5345969, upload-time = "2026-07-01T11:54:06.397Z" }, - { url = "https://files.pythonhosted.org/packages/d8/66/9a386a92561f402389a4fc70c18838bf6d35eb5eb5c6850b4b2dc64f5048/pillow-12.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffd0c5368496f41b0944be820fcb7a838aa6e623d250b01acf2643939c3f99d7", size = 4780323, upload-time = "2026-07-01T11:54:09.351Z" }, - { url = "https://files.pythonhosted.org/packages/25/27/ac8f99618ffd3dde21db0f4d4b1d2ab00c0880595bfd17df103f7f39fd0c/pillow-12.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9c7f76c0673154f044e9d78c8655fb4213f6ca31a836df48b40fe5d187717b9", size = 6266838, upload-time = "2026-07-01T11:54:11.71Z" }, - { url = "https://files.pythonhosted.org/packages/84/21/a35af28dcc61f37ed850a2d64c65c701321dfbf25085e469d5559360cbbf/pillow-12.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91", size = 6940830, upload-time = "2026-07-01T11:54:13.732Z" }, - { url = "https://files.pythonhosted.org/packages/eb/51/8b08617af3ad95e33ce6d7dd2c99ed6c8298f7fb131636303956be022e25/pillow-12.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e491916b378fba47242221bb9ead245211b70d504f495d105d17b14a24b4907c", size = 6344383, upload-time = "2026-07-01T11:54:15.756Z" }, - { url = "https://files.pythonhosted.org/packages/1d/72/cf78ac9780bb93c28328f408973845a309d4d145041665f734572ced1b52/pillow-12.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0dd2064cbc55aaec028ef5fbb60fa47bb6c3e7918e07ff17935284b227a9d2df", size = 7052934, upload-time = "2026-07-01T11:54:17.721Z" }, - { url = "https://files.pythonhosted.org/packages/20/20/25e0f4dc178a6bc0696793720055519a0de89e7661dae886992decbd2f81/pillow-12.3.0-cp312-cp312-win32.whl", hash = "sha256:dbce0b29841537a2fa4a214c2bbf14de3587c9680caa9b4e217568472490b28f", size = 6472684, upload-time = "2026-07-01T11:54:19.839Z" }, - { url = "https://files.pythonhosted.org/packages/45/89/da2f7971a317f83d807fdd4065c0af40208e59e692cc43d315a71a0e96d1/pillow-12.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a2b55dd6b2a4c4b7d87ffa56bdb33fdc5fdb9a462173861a7bc097f17d91cb09", size = 7227137, upload-time = "2026-07-01T11:54:22.025Z" }, - { url = "https://files.pythonhosted.org/packages/de/47/4845a0a6c0dbf1db8456bd9fc791f13c5ced7ced20606d08a0aacfd25b49/pillow-12.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:331b624368d4f1d069149002f25f44bc61c8919ce8ddb3c45bdad8f6e2d89510", size = 2568267, upload-time = "2026-07-01T11:54:24.051Z" }, - { url = "https://files.pythonhosted.org/packages/9d/ac/31fb64e1e7efb5a4b50cd3d92049ba89ac6e4d8d3bb6a74e15048ca3353e/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:21900ce7ba264168cd50defae43cd75d25c833ad4ad6e73ffc5596d12e25ac89", size = 4161684, upload-time = "2026-07-01T11:54:25.934Z" }, - { url = "https://files.pythonhosted.org/packages/87/b4/9805e23d2b4d77842b468513841fda254ee42f0289d25088340e4ff46e2d/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4e8c2a84d977f50b9daed6eeaf3baef67d00d5d74d932288f02cb94518ee3ace", size = 4255487, upload-time = "2026-07-01T11:54:27.935Z" }, - { url = "https://files.pythonhosted.org/packages/df/39/ecf519435a200c693fe053a6ee4d835b41cf963a4dfc2551c4e637cb2a71/pillow-12.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:ae26d61dfa7a47befdc7572b521024e8745f3d809bd95ca9505a7bba9ef849ec", size = 3696433, upload-time = "2026-07-01T11:54:29.813Z" }, - { url = "https://files.pythonhosted.org/packages/42/92/2fc3ffad878ae8dd5469ec1bc8eb83b71f48e13efdf68f02709003982a32/pillow-12.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7a743ff716f746fc19a9557f60dab1600d4613255f8a7aeb3cdde4db7eb15a66", size = 5345889, upload-time = "2026-07-01T11:54:31.97Z" }, - { url = "https://files.pythonhosted.org/packages/10/76/8803c13605b763d33d156c4678fc77f8443389c0c51c8aef707bb02015f4/pillow-12.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d69141514cc30b774ceea5e3ed3a6635c8d8a96edf664689b890f4089111fb35", size = 4780109, upload-time = "2026-07-01T11:54:34.026Z" }, - { url = "https://files.pythonhosted.org/packages/1f/01/e18aff37cb0b4aac47ac90f016d347a49aca667ef97f190b06ac2aabc928/pillow-12.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f7401aebd7f581d7f83a439d87d474999317ee099218e5ad25d125290990ba65", size = 6263736, upload-time = "2026-07-01T11:54:36.131Z" }, - { url = "https://files.pythonhosted.org/packages/f7/62/de5bdd77d935331f4f802edc11e4d82950f642caad6cb2f949837b8560e2/pillow-12.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0847a763afefb695bc912d7c131e7e0632d4edc1d8698f58ddabec8e46b8b6d3", size = 6937129, upload-time = "2026-07-01T11:54:38.216Z" }, - { url = "https://files.pythonhosted.org/packages/70/4d/105627a13300c5e0df1d174230b32fd1273062c96f7745fd552b945d1e1d/pillow-12.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:571b9fcb07b97ef3a492028fb3d2dc0993ca23a06138b0315286566d29ef718a", size = 6339562, upload-time = "2026-07-01T11:54:40.354Z" }, - { url = "https://files.pythonhosted.org/packages/6b/1d/f13de01a553988ab895ba1c722e06cf3144d4f57656fd5b81b6d881f1179/pillow-12.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:756c768d0c9c2955feb7a56c37ea24aea2e369f8d36a88da270b6a9f19e62b5e", size = 7049439, upload-time = "2026-07-01T11:54:42.489Z" }, - { url = "https://files.pythonhosted.org/packages/c9/f9/066794cca041b969964f779ee5fa66a9498bbf34248ac39c5d7954e4198f/pillow-12.3.0-cp313-cp313-win32.whl", hash = "sha256:a876864214e136f0eb367788dbd7df045f4806801518e2cfe9e13229cfe06d8f", size = 6473287, upload-time = "2026-07-01T11:54:44.9Z" }, - { url = "https://files.pythonhosted.org/packages/a6/9b/7a58e61d62be561da3a356fe2384d4059a6345fc130e23ef1c36a5b81d24/pillow-12.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:1cca606cd25738df4ed873d5ad46bbdb3d83b5cbca291f6b4ff13a4df6b0bbe8", size = 7239691, upload-time = "2026-07-01T11:54:47.141Z" }, - { url = "https://files.pythonhosted.org/packages/aa/b0/c4ed4f0ef8f8fa5ee8351537db6650bb8189f7e118842978dd6589065692/pillow-12.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:b629de27fda84b42cde7edef0d85f13b958b47f6e9bbcbba9b673c562a89bd8b", size = 2568185, upload-time = "2026-07-01T11:54:49.137Z" }, - { url = "https://files.pythonhosted.org/packages/dc/01/001f65b68192f0228cc1dbbc8d2530ab5d58b61037ba0587f946fea607cd/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:9cf95fe4d0f84c82d282745d9bb08ad9f926efa00be4697e767b814ce40d4330", size = 4161736, upload-time = "2026-07-01T11:54:51.156Z" }, - { url = "https://files.pythonhosted.org/packages/1a/d2/0219746d0fd16fc8a84498e79452375be3797d3ce4044596ce565164b84f/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8728f216dcdb6e6d555cf971cb34076139ad74b31fc2c14da4fafc741c5f6217", size = 4255435, upload-time = "2026-07-01T11:54:53.414Z" }, - { url = "https://files.pythonhosted.org/packages/c8/02/8d0bc62ef0302318c46ff2a512822d2610e81c7aa46c9b3abe6cbaca5ad0/pillow-12.3.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:a45650e8ce7fafffd731db8550230db6b0d306d181a90b67d3e6bca2f1990930", size = 3696262, upload-time = "2026-07-01T11:54:55.739Z" }, - { url = "https://files.pythonhosted.org/packages/85/e2/73c77d218410b14f5f2d565e8a998d5317b7b9c75368d29985139f7a46f0/pillow-12.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ba54cfebe86920a559a7c4d6b9050791c20513650a1952ebe3368c7dc70306f8", size = 5350344, upload-time = "2026-07-01T11:54:57.657Z" }, - { url = "https://files.pythonhosted.org/packages/c7/da/32c752228ae345f489e3a42499d817b6c3996da7e8a3bc7a04fc806b243b/pillow-12.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e158cb00350dc278f3b91551101aa7d12415a66ebf2c91d8d5ac14e56ddd3ad0", size = 4780131, upload-time = "2026-07-01T11:54:59.713Z" }, - { url = "https://files.pythonhosted.org/packages/b1/9d/8b2c807dbef61a5197c047afe99823787eb66f63daf9fb2432f91d6f0462/pillow-12.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9aeb04d6aef139de265b29683e119b638208f88cf73cdd1658aa07221165321", size = 6263757, upload-time = "2026-07-01T11:55:01.778Z" }, - { url = "https://files.pythonhosted.org/packages/5c/44/c85361f65dbe00eea8576ee467c768d25129989efb76e94f205e9ca9bb46/pillow-12.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:251bf95b67017e27b13d82f5b326234ca62d70f9cf4c2b9032de2358a3b12c7b", size = 6936962, upload-time = "2026-07-01T11:55:03.93Z" }, - { url = "https://files.pythonhosted.org/packages/18/7e/e483414b35800b86b6f08dbbc7803fb5cd52c4d6f897f47d53ea2c7e6f65/pillow-12.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fe3cca2e4e8a592be0f269a1ca4835c25199d9f3ce815c8491048f785b0a0198", size = 6339171, upload-time = "2026-07-01T11:55:05.989Z" }, - { url = "https://files.pythonhosted.org/packages/f0/f4/68c491844841ede6bed70189546b3ee9731cf9f2cbad396faff5e1ccba45/pillow-12.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:23aceaa007d6172b02c277f0cd359c79492bbb14f7072b4ede9fbcaf20648130", size = 7048116, upload-time = "2026-07-01T11:55:08.131Z" }, - { url = "https://files.pythonhosted.org/packages/a3/34/77f3f793fed8efc7d243f21b33c5a3f0d1c97ee70346d3db855587e155ff/pillow-12.3.0-cp314-cp314-win32.whl", hash = "sha256:af8d94b0db561cf68b88a267c5c44b49e134f525d0dc2cb7ed413a66bc23559a", size = 6467209, upload-time = "2026-07-01T11:55:10.408Z" }, - { url = "https://files.pythonhosted.org/packages/f1/e0/492879f69d94f91f60fc8cd05ba03650e9520afebb2fb7aa12777d7c7f38/pillow-12.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:fdafc9cce40277e0f7a0feabce0ee50dd2fa1800f3b38015e51296b5e814048d", size = 7237707, upload-time = "2026-07-01T11:55:12.745Z" }, - { url = "https://files.pythonhosted.org/packages/c9/ac/6b11f2875f1c2ac040d84e1bbf9cf22a88038f901ca1037898b280b38365/pillow-12.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:e91206ee562682b51b98ef4b26a6ef48fd84e15fd4c4bc5ec768eb641d206838", size = 2565995, upload-time = "2026-07-01T11:55:14.736Z" }, - { url = "https://files.pythonhosted.org/packages/52/69/c2208e56af9bfc1913afb24020297a691eb1d4ef688474c8a04913f65e04/pillow-12.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:164b31cd1a0490ab6efae01aa5df49da7061be0af1b30e035b6e9a1bfe34ee6e", size = 5352503, upload-time = "2026-07-01T11:55:17.076Z" }, - { url = "https://files.pythonhosted.org/packages/07/70/e5686d753e898a45d778ff1718dba8516ead6ab6b95d85fc8c4b70650cf2/pillow-12.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5afb51d599ea772b8365ae807ae557f18bccfe46ab261fd1c2a9ed700fc6eb17", size = 4782956, upload-time = "2026-07-01T11:55:19.448Z" }, - { url = "https://files.pythonhosted.org/packages/d5/37/25c6692f06927ee973ff18c8d9ee98ad0b4d84ee67a09610c2dd1447958e/pillow-12.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3edce1d53195db527e0191f84b71d02022de0540bf43a16ed734ed7537b07385", size = 6322855, upload-time = "2026-07-01T11:55:21.613Z" }, - { url = "https://files.pythonhosted.org/packages/cc/91/420637fcb8f1bc11029e403b4538e6694744428d8246118e45719f944556/pillow-12.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf16ba1b4d0b6b7c8e534936632270cf70eb00dbe09005bc345b2677b726855c", size = 6989642, upload-time = "2026-07-01T11:55:24.006Z" }, - { url = "https://files.pythonhosted.org/packages/10/08/b94d7811281ccf0d143a1cf768d1c49e1e54af63e7b708ab2ee3eb87face/pillow-12.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:24870b09b224f7ae3c39ed07d10e819d06f8720bc551847b1d623832b5b0e28d", size = 6391281, upload-time = "2026-07-01T11:55:26.252Z" }, - { url = "https://files.pythonhosted.org/packages/d2/87/24233f785f55474dc02ce3e739c5528a77e3a862e9333d1dd7a25cc31f70/pillow-12.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:30f2aa603c41533cc25c05acd0da21636e84a315768feb631c937177db558931", size = 7096716, upload-time = "2026-07-01T11:55:28.318Z" }, - { url = "https://files.pythonhosted.org/packages/23/26/fcb2f6e37175b04f53570b59937867e2b80ee1685e744023153028fc14f9/pillow-12.3.0-cp314-cp314t-win32.whl", hash = "sha256:4b0a7fe987b14c31ebda6083f74f22b561fd3739bc0ac51e019622e3d72668c7", size = 6474125, upload-time = "2026-07-01T11:55:30.956Z" }, - { url = "https://files.pythonhosted.org/packages/90/de/3634abee5f1c9e13c56787b7d5517b0ba8d6de51700b95578cf338349c9f/pillow-12.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:962864dc93511324d51ddbb5b9f8731bf71675b93ca612a07441896f4688fb8c", size = 7242939, upload-time = "2026-07-01T11:55:34.044Z" }, - { url = "https://files.pythonhosted.org/packages/ce/2a/fd13f8eb24de5714a6eb444a3d67e2842c6c576e159a43793adf23051351/pillow-12.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0740a512dc522224c77d9aa5a8d70d8b7d73fb91f2c21125d8d025d3b8990e45", size = 2567506, upload-time = "2026-07-01T11:55:35.988Z" }, - { url = "https://files.pythonhosted.org/packages/5d/dc/8fdce34ec725a33c81c6ba122b904d6b9024e50ea9ac7bede62fab54506c/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0feb2e9d6ad6c9e3c06effe9d00f3f1e618a6643273576b016f591e9315a7139", size = 4162063, upload-time = "2026-07-01T11:55:37.941Z" }, - { url = "https://files.pythonhosted.org/packages/76/66/2044b9a63d3b84ff048228dfcb7cd9bf0df983e8470971bf7d4c57b693de/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:9e881fca225083806662a5c43d627d215f258ff43c890f831966c7d7ba9c7402", size = 4255549, upload-time = "2026-07-01T11:55:40.022Z" }, - { url = "https://files.pythonhosted.org/packages/52/7e/1f67e6f4ece6b582ee4b539decbcc9f848dc245a93ed8cd7338bafef72f1/pillow-12.3.0-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:4998562bf62a445225f22e07c896bb04b35b1b1f2eb6d760584c9c51d7a5f78c", size = 3696331, upload-time = "2026-07-01T11:55:41.98Z" }, - { url = "https://files.pythonhosted.org/packages/12/40/d306fc2c8e4d45d7f175c77edca7063be7b86fe7fe6e68f4353bf71d808c/pillow-12.3.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:dc624f6bc473dacdf7ef7eb8678d0d08edf15cd94fad6ae5c7d6cc67a4e4902f", size = 5350370, upload-time = "2026-07-01T11:55:44.028Z" }, - { url = "https://files.pythonhosted.org/packages/dd/44/668fb1437e8ce420f62d6106eb66e44a5971602a4d794615bdf79315d82d/pillow-12.3.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:71d6097b330eea8fd15097780c8e89cb1a8ce7838669f48c5bacd6f663dd4701", size = 4780147, upload-time = "2026-07-01T11:55:46.073Z" }, - { url = "https://files.pythonhosted.org/packages/0c/08/93fa2e70e30a2d81547e481b6ee2bb9522117221fb1e0ce4b5df70967677/pillow-12.3.0-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:28ce87c5ab450a9dd970b52e5aca5fe63ed432d18a2eaddd1979a00a1ba24ace", size = 6273659, upload-time = "2026-07-01T11:55:48.264Z" }, - { url = "https://files.pythonhosted.org/packages/f8/6d/043e96ff814fc31a33077e4cba86082167db520c93632afdf2042febbb0c/pillow-12.3.0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6b02afb9b97f65fbca5f31db6a2a3ba21aa93030225f150fa3f249717e938fb4", size = 6947439, upload-time = "2026-07-01T11:55:50.503Z" }, - { url = "https://files.pythonhosted.org/packages/af/92/ba71d2ee2ac0edf3fa33bd9d5ee9ee080da70b1766f3ca3934f9938ddac9/pillow-12.3.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:1182d52bc2d5e5d7d0949503aa7e36d12f42205dc287e4883f407b1988820d39", size = 6353577, upload-time = "2026-07-01T11:55:52.697Z" }, - { url = "https://files.pythonhosted.org/packages/0f/ce/e63064e2122923ff687c8ad792d0d736a7b3920a56a46982e81a7fdd25d6/pillow-12.3.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e795b7eb908249c4e43c7c99fac7c2c75dab0c43566e37db472a355f63693d71", size = 7060394, upload-time = "2026-07-01T11:55:55.149Z" }, - { url = "https://files.pythonhosted.org/packages/54/76/a09cc3ccc8d773a7283d34c38bec1708f9e3cc932093cbc4c5e71ac4060b/pillow-12.3.0-cp315-cp315-win32.whl", hash = "sha256:57b3d78c95ba9059768b10e28b813002261d3f3dfc55cc48b0c988f625175827", size = 6467375, upload-time = "2026-07-01T11:55:57.769Z" }, - { url = "https://files.pythonhosted.org/packages/3e/03/1846c49ba3b1d5550392a4bbd06d6fb4578e1cd91a803198b5c90f5f7d53/pillow-12.3.0-cp315-cp315-win_amd64.whl", hash = "sha256:fa4ecea169a355be7a3ade2c783e2ed12f0e40d2c5621cda8b3297faf7fbb9f5", size = 7237048, upload-time = "2026-07-01T11:55:59.975Z" }, - { url = "https://files.pythonhosted.org/packages/fb/bb/89f35dcc79610423f9f195504d7def7f0d1416a711541b42867e25fe3412/pillow-12.3.0-cp315-cp315-win_arm64.whl", hash = "sha256:877c3f311ff35410f690861c4409e7ccbf0cd2f878e50628a28e5a0bb689e658", size = 2566006, upload-time = "2026-07-01T11:56:02.143Z" }, - { url = "https://files.pythonhosted.org/packages/30/88/707027ba09942dfa2c28759b5c222d769290a41c6d20ea60ec250801941f/pillow-12.3.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:e9871b1ffbfa9656b60aeee92ed5136a5742696006fa322b29ea3d8da0ecc9cf", size = 5352509, upload-time = "2026-07-01T11:56:04.2Z" }, - { url = "https://files.pythonhosted.org/packages/b0/6d/00352fa25332c2569cd387851f568cc5a4b75a9adbfb37ac4fbce4c02eec/pillow-12.3.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:53aa02d20d10c3d814d536aa4e5ac9b84ca0ff5a88377963b085ad6822f93e64", size = 4783167, upload-time = "2026-07-01T11:56:06.631Z" }, - { url = "https://files.pythonhosted.org/packages/13/4f/9e049dfa21af7c22427275720e2490267ba8138120add5c4c574deb69782/pillow-12.3.0-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:446c34dcc4324b084a53b705127dc15717b22c5e140ae0a3c38349d4efec071e", size = 6329237, upload-time = "2026-07-01T11:56:08.868Z" }, - { url = "https://files.pythonhosted.org/packages/36/16/cf6eeaae8d0fce8dd390a33437cf68c5d5bd73834a2bc6e2f14efda0ab45/pillow-12.3.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf1845d02ad822a369a49f2bb9345b1614744267682e7a03527dc3bf6eea1777", size = 6997047, upload-time = "2026-07-01T11:56:11.379Z" }, - { url = "https://files.pythonhosted.org/packages/1e/69/dbf769bdd55f48bf5733cac28edc6364ffaa072ec9ba336266e4fe66be55/pillow-12.3.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:186941b6aef820ad110fb01fb06eb925374dc3a21b17e37ec9a53b250c6fe2d1", size = 6400440, upload-time = "2026-07-01T11:56:13.908Z" }, - { url = "https://files.pythonhosted.org/packages/a0/e1/ffc9cfc2eea0d178da8018e18e959301ad9d6bc9f3edb7181e748a474b97/pillow-12.3.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:f13c32a3abd6079a66d9526e18dad9b6d280384d49d7c54040cd57b6424041d9", size = 7105895, upload-time = "2026-07-01T11:56:16.575Z" }, - { url = "https://files.pythonhosted.org/packages/18/f0/a5595c1e8c3ae44b9828cb2f0fa8155e5095ef04d6327b8f61cf44a3df85/pillow-12.3.0-cp315-cp315t-win32.whl", hash = "sha256:1657923d2d45afb66526e5b933e5b3052e6bdea196c90d3abb2424e18c77dae8", size = 6474384, upload-time = "2026-07-01T11:56:18.855Z" }, - { url = "https://files.pythonhosted.org/packages/e4/04/62bcd9f844984c5938d3b05264a61d797a29d3e0812341a8204af70bbdee/pillow-12.3.0-cp315-cp315t-win_amd64.whl", hash = "sha256:8cd2f7bdda092d99c9fc2fb7391354f306d01443d22785d0cbfafa2e2c8bb418", size = 7243537, upload-time = "2026-07-01T11:56:21.214Z" }, - { url = "https://files.pythonhosted.org/packages/3d/68/1f3066acedf37673694a7141381d8f811ae97f30d34413d236abe7d489f1/pillow-12.3.0-cp315-cp315t-win_arm64.whl", hash = "sha256:06ff022112bc9cbf83b60f8e028d94ad87b60621706487e65f673de61610ab59", size = 2567491, upload-time = "2026-07-01T11:56:23.506Z" }, - { url = "https://files.pythonhosted.org/packages/75/18/2e8b40223153ccbc60df07f9e8928dc0c76202aa4e55ae9f53962b6510d6/pillow-12.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b3c777e849237620b022f7f297dd67705f9f5cf1685f09f02e46f93e92725468", size = 5302510, upload-time = "2026-07-01T11:56:25.736Z" }, - { url = "https://files.pythonhosted.org/packages/46/3e/51fabf59d5ab801ceab709453d3ab6b180083496579549de4c45ced6528a/pillow-12.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:b343699e8308bdc51978310e1c959c584e7869cc8c40780058c87da7781a1e94", size = 4736058, upload-time = "2026-07-01T11:56:28.041Z" }, - { url = "https://files.pythonhosted.org/packages/bf/20/22fe9384b7949e25fb1293bcfc84fb82590ff4ea6b37c95b24d26d793d86/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbd139c8447d25dd750ab79ee274cc5e1fe80fc56340ab10b18a195e1b6eca3e", size = 5237776, upload-time = "2026-07-01T11:56:30.263Z" }, - { url = "https://files.pythonhosted.org/packages/08/14/f6ba68107680ffa74b39985f3f30884e41318fbc4250caa423c79b4788bb/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e7e480451b9fa137494bccd3a7d69adbe8ac65a87d97be61e11f1b1050a5bac3", size = 5860358, upload-time = "2026-07-01T11:56:32.68Z" }, - { url = "https://files.pythonhosted.org/packages/36/54/0169bc772ec491108b62f644f8ecf1fe5d8ae5ebafde2ee2142210166903/pillow-12.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:04f01d28a6aaff387bf842a13be313df23ba0597a44f1a976c9feb3c6ff4711a", size = 7231786, upload-time = "2026-07-01T11:56:35.046Z" }, -] - [[package]] name = "platformdirs" version = "4.9.4" @@ -1688,17 +1472,18 @@ wheels = [ [[package]] name = "scikit-build-core" -version = "0.11.6" +version = "1.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "exceptiongroup", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, { name = "packaging" }, { name = "pathspec" }, { name = "tomli", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/48/b2/c11aaa746f3dfcdb46499affbc5f9784c991d354a80ca92f96a0f0f5aadf/scikit_build_core-0.11.6.tar.gz", hash = "sha256:5982ccd839735be99cfd3b92a8847c6c196692f476c215da84b79d2ad12f9f1b", size = 286006, upload-time = "2025-08-22T22:11:56.112Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8d/7c/0f69b0c7150ce4bcee78c199fe3b7e03a6e01578451bd5d5d1a58beb32f9/scikit_build_core-1.0.3.tar.gz", hash = "sha256:a4d7a05978ee37975c37743510c8991e2debce7ef83afb0a07c0c576fd4f16e8", size = 477539, upload-time = "2026-07-12T05:08:30.298Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/49/ec16b3db6893db788ae35f98506ff5a9c25dca7eb18cc38ada8a4c1dc944/scikit_build_core-0.11.6-py3-none-any.whl", hash = "sha256:ce6d8fe64e6b4c759ea0fb95d2f8a68f60d2df31c2989838633b8ec930736360", size = 185764, upload-time = "2025-08-22T22:11:52.438Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b0/7ad8fa9aebb0835b2e20afebf1483cbe175d1612fe01e85042ce9ced8755/scikit_build_core-1.0.3-py3-none-any.whl", hash = "sha256:ae95427b7d3c14a6cf8bbfd4d901f6138ab64c99e20cbe8ea7d75cd26093f085", size = 278294, upload-time = "2026-07-12T05:08:28.725Z" }, ] [[package]] From b5f7e90c740d4e0e486d9639623eedcb813c3108 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Fri, 21 Aug 2026 15:03:37 -0400 Subject: [PATCH 06/39] Split Python bindings into workspace packages --- .github/workflows/pip.yml | 112 ++- .gitignore | 5 +- packaging/CMakeLists.txt | 21 +- packaging/{common => }/Description.txt | 0 .../HalideAutoschedulersConfig.cmake | 0 .../{common => }/HalideCompilerConfig.cmake | 0 packaging/{common => }/HalideConfig.cmake | 0 packaging/{common => }/Welcome.txt | 0 packaging/pip-bin/src/halide_bin/__init__.py | 5 - packaging/pip/_dynamic_metadata.py | 31 - pyproject.toml | 239 +---- python_bindings/CMakeLists.txt | 29 +- python_bindings/halide-bin/CMakeLists.txt | 2 + .../halide-bin/packaging}/CMakeLists.txt | 0 .../packaging}/TrampolineConfig.cmake.in | 2 +- .../halide-bin}/pyproject.toml | 31 +- python_bindings/halide-runtime/CMakeLists.txt | 1 + .../halide-runtime}/README.md | 0 .../halide-runtime/_dynamic_metadata.py | 35 + .../halide-runtime}/pyproject.toml | 30 +- .../src/halide/runtime/CMakeLists.txt | 11 +- .../src/halide/runtime/PyRuntime.cpp | 0 .../src/halide/runtime/__init__.py | 0 python_bindings/halide/CMakeLists.txt | 18 + .../pip => python_bindings/halide}/README.md | 0 python_bindings/halide/_dynamic_metadata.py | 37 + .../{ => halide}/apps/CMakeLists.txt | 0 .../{ => halide}/apps/bilateral_grid_app.py | 0 .../apps/bilateral_grid_generator.py | 0 python_bindings/{ => halide}/apps/blur_app.py | 0 .../{ => halide}/apps/blur_generator.py | 0 .../{ => halide}/apps/identity_app.py | 0 .../{ => halide}/apps/identity_generator.py | 0 .../{ => halide}/apps/interpolate_app.py | 0 .../apps/interpolate_generator.py | 0 .../{ => halide}/apps/local_laplacian_app.py | 0 .../apps/local_laplacian_generator.py | 0 .../{ => halide}/cmake/AddPythonTest.cmake | 0 .../{ => halide}/packaging/CMakeLists.txt | 10 +- .../packaging/Halide_PythonConfig.cmake.in | 0 .../packaging/cmake}/CMakeLists.txt | 2 +- .../cmake}/TrampolineConfig.cmake.in | 0 python_bindings/halide/pyproject.toml | 190 ++++ .../{src/halide => halide/src}/CMakeLists.txt | 3 - .../{src/halide => halide/src}/__init__.py | 55 +- .../src}/_generator_helpers.py | 0 .../src}/halide_/PyArgument.cpp | 0 .../src}/halide_/PyArgument.h | 0 .../src}/halide_/PyBinaryOperators.h | 0 .../src}/halide_/PyBoundaryConditions.cpp | 0 .../src}/halide_/PyBoundaryConditions.h | 0 .../src}/halide_/PyBuffer.cpp | 0 .../halide => halide/src}/halide_/PyBuffer.h | 0 .../src}/halide_/PyCallable.cpp | 0 .../src}/halide_/PyCallable.h | 0 .../src}/halide_/PyConciseCasts.cpp | 0 .../src}/halide_/PyConciseCasts.h | 0 .../src}/halide_/PyDerivative.cpp | 0 .../src}/halide_/PyDerivative.h | 0 .../halide => halide/src}/halide_/PyEnums.cpp | 0 .../halide => halide/src}/halide_/PyEnums.h | 0 .../halide => halide/src}/halide_/PyError.cpp | 0 .../halide => halide/src}/halide_/PyError.h | 0 .../halide => halide/src}/halide_/PyExpr.cpp | 0 .../halide => halide/src}/halide_/PyExpr.h | 0 .../src}/halide_/PyExternFuncArgument.cpp | 0 .../src}/halide_/PyExternFuncArgument.h | 0 .../halide => halide/src}/halide_/PyFunc.cpp | 0 .../halide => halide/src}/halide_/PyFunc.h | 0 .../src}/halide_/PyFuncRef.cpp | 0 .../halide => halide/src}/halide_/PyFuncRef.h | 0 .../src}/halide_/PyGenerator.cpp | 0 .../src}/halide_/PyGenerator.h | 0 .../src}/halide_/PyHalide.cpp | 0 .../halide => halide/src}/halide_/PyHalide.h | 0 .../src}/halide_/PyIROperator.cpp | 0 .../src}/halide_/PyIROperator.h | 0 .../src}/halide_/PyImageParam.cpp | 0 .../src}/halide_/PyImageParam.h | 0 .../src}/halide_/PyInlineReductions.cpp | 0 .../src}/halide_/PyInlineReductions.h | 0 .../src}/halide_/PyLambda.cpp | 0 .../halide => halide/src}/halide_/PyLambda.h | 0 .../src}/halide_/PyLoopLevel.cpp | 0 .../src}/halide_/PyLoopLevel.h | 0 .../src}/halide_/PyModule.cpp | 0 .../halide => halide/src}/halide_/PyModule.h | 0 .../halide => halide/src}/halide_/PyParam.cpp | 0 .../halide => halide/src}/halide_/PyParam.h | 0 .../src}/halide_/PyParameter.cpp | 0 .../src}/halide_/PyParameter.h | 0 .../src}/halide_/PyPipeline.cpp | 0 .../src}/halide_/PyPipeline.h | 0 .../halide => halide/src}/halide_/PyRDom.cpp | 0 .../halide => halide/src}/halide_/PyRDom.h | 0 .../src}/halide_/PyScheduleMethods.h | 0 .../src}/halide_/PySerialization.cpp | 0 .../src}/halide_/PySerialization.h | 0 .../halide => halide/src}/halide_/PyStage.cpp | 0 .../halide => halide/src}/halide_/PyStage.h | 0 .../src}/halide_/PyTarget.cpp | 0 .../halide => halide/src}/halide_/PyTarget.h | 0 .../halide => halide/src}/halide_/PyTuple.cpp | 0 .../halide => halide/src}/halide_/PyTuple.h | 0 .../halide => halide/src}/halide_/PyType.cpp | 0 .../halide => halide/src}/halide_/PyType.h | 0 .../halide => halide/src}/halide_/PyVar.cpp | 0 .../halide => halide/src}/halide_/PyVar.h | 0 .../src}/halide_/PyVarOrRVar.cpp | 0 .../src}/halide_/PyVarOrRVar.h | 0 .../{src/halide => halide/src}/imageio.py | 0 .../{ => halide}/stub/CMakeLists.txt | 0 .../{ => halide}/stub/PyStubImpl.cpp | 0 .../{ => halide}/test/CMakeLists.txt | 0 .../test/correctness/CMakeLists.txt | 0 .../test/correctness/addconstant_test.py | 0 .../{ => halide}/test/correctness/atomics.py | 0 .../{ => halide}/test/correctness/autodiff.py | 0 .../{ => halide}/test/correctness/basics.py | 0 .../{ => halide}/test/correctness/bit_test.py | 0 .../test/correctness/boundary_conditions.py | 0 .../{ => halide}/test/correctness/buffer.py | 0 .../{ => halide}/test/correctness/callable.py | 0 .../test/correctness/compile_to.py | 0 .../{ => halide}/test/correctness/division.py | 0 .../{ => halide}/test/correctness/extern.py | 0 .../test/correctness/float_precision_test.py | 0 .../test/correctness/iroperator.py | 0 .../{ => halide}/test/correctness/memoize.py | 0 .../correctness/multi_method_module_test.py | 0 .../test/correctness/multipass_constraints.py | 0 .../test/correctness/negate_test.py | 0 .../{ => halide}/test/correctness/pystub.py | 0 .../{ => halide}/test/correctness/rdom.py | 0 .../test/correctness/realize_warnings.py | 0 .../test/correctness/runtime_prefixes.py | 0 .../test/correctness/serialization.py | 0 .../{ => halide}/test/correctness/target.py | 0 .../test/correctness/the_sort_function.c | 0 .../test/correctness/tuple_select.py | 0 .../{ => halide}/test/correctness/type.py | 0 .../test/correctness/user_context_test.py | 0 .../{ => halide}/test/correctness/var.py | 0 .../test/generators/CMakeLists.txt | 0 .../generators/addconstantcpp_generator.cpp | 0 .../generators/addconstantpy_generator.py | 0 .../test/generators/bitcpp_generator.cpp | 0 .../test/generators/bitpy_generator.py | 0 .../test/generators/complexcpp_generator.cpp | 0 .../test/generators/complexpy_generator.py | 0 .../test/generators/simplecpp_generator.cpp | 0 .../test/generators/simplepy_generator.py | 0 .../generators/user_context_generator.cpp | 0 .../{ => halide}/test/runtime/CMakeLists.txt | 0 .../test/runtime/aot_module_stub.c | 0 .../test/runtime/call_convention.py | 0 .../test/runtime/callconv_generator.cpp | 0 .../test/runtime/check_no_libhalide.cmake | 0 .../{ => halide}/test/runtime/gpu.py | 0 .../test/runtime/gpu_generator.cpp | 0 .../{ => halide}/test/runtime/load_aot.py | 0 .../test/runtime/runtimeadd_generator.cpp | 0 .../{ => halide}/tutorial/CMakeLists.txt | 0 .../{ => halide}/tutorial/lesson_01_basics.py | 0 .../tutorial/lesson_02_input_image.py | 0 .../tutorial/lesson_03_debugging_1.py | 0 .../tutorial/lesson_04_debugging_2.py | 0 .../tutorial/lesson_05_scheduling_1.py | 0 ...esson_06_realizing_over_shifted_domains.py | 0 .../lesson_07_multi_stage_pipelines.py | 0 .../tutorial/lesson_08_scheduling_2.py | 0 .../tutorial/lesson_09_update_definitions.py | 0 .../lesson_10_aot_compilation_generate.py | 0 .../tutorial/lesson_10_aot_compilation_run.py | 0 .../tutorial/lesson_11_cross_compilation.py | 0 .../tutorial/lesson_12_using_the_gpu.py | 0 .../{ => halide}/tutorial/lesson_13_tuples.py | 0 .../{ => halide}/tutorial/lesson_14_types.py | 0 .../tutorial/lesson_15_generators.py | 0 .../tutorial/lesson_15_runtime.py | 0 .../tutorial/lesson_16_rgb_generate.py | 0 .../tutorial/lesson_16_rgb_run.py | 0 .../tutorial/lesson_17_predicated_rdom.py | 0 ...sson_18_parallel_associative_reductions.py | 0 .../tutorial/lesson_19_wrapper_funcs.py | 0 .../tutorial/lesson_20_cloning_funcs.py | 0 .../lesson_21_auto_scheduler_generate.py | 0 .../tutorial/lesson_21_auto_scheduler_run.py | 0 .../tutorial/lesson_22_jit_performance.py | 0 .../tutorial/lesson_23_serialization.py | 0 .../{ => halide}/tutorial/lesson_24_async.py | 0 python_bindings/src/CMakeLists.txt | 1 - uv.lock | 828 +++++++++++------- 193 files changed, 980 insertions(+), 718 deletions(-) rename packaging/{common => }/Description.txt (100%) rename packaging/{common => }/HalideAutoschedulersConfig.cmake (100%) rename packaging/{common => }/HalideCompilerConfig.cmake (100%) rename packaging/{common => }/HalideConfig.cmake (100%) rename packaging/{common => }/Welcome.txt (100%) delete mode 100644 packaging/pip-bin/src/halide_bin/__init__.py delete mode 100644 packaging/pip/_dynamic_metadata.py create mode 100644 python_bindings/halide-bin/CMakeLists.txt rename {packaging/pip => python_bindings/halide-bin/packaging}/CMakeLists.txt (100%) rename {packaging/pip => python_bindings/halide-bin/packaging}/TrampolineConfig.cmake.in (63%) rename {packaging/pip-bin => python_bindings/halide-bin}/pyproject.toml (71%) create mode 100644 python_bindings/halide-runtime/CMakeLists.txt rename {packaging/pip-runtime => python_bindings/halide-runtime}/README.md (100%) create mode 100644 python_bindings/halide-runtime/_dynamic_metadata.py rename {packaging/pip-runtime => python_bindings/halide-runtime}/pyproject.toml (79%) rename python_bindings/{ => halide-runtime}/src/halide/runtime/CMakeLists.txt (86%) rename python_bindings/{ => halide-runtime}/src/halide/runtime/PyRuntime.cpp (100%) rename python_bindings/{ => halide-runtime}/src/halide/runtime/__init__.py (100%) create mode 100644 python_bindings/halide/CMakeLists.txt rename {packaging/pip => python_bindings/halide}/README.md (100%) create mode 100644 python_bindings/halide/_dynamic_metadata.py rename python_bindings/{ => halide}/apps/CMakeLists.txt (100%) rename python_bindings/{ => halide}/apps/bilateral_grid_app.py (100%) rename python_bindings/{ => halide}/apps/bilateral_grid_generator.py (100%) rename python_bindings/{ => halide}/apps/blur_app.py (100%) rename python_bindings/{ => halide}/apps/blur_generator.py (100%) rename python_bindings/{ => halide}/apps/identity_app.py (100%) rename python_bindings/{ => halide}/apps/identity_generator.py (100%) rename python_bindings/{ => halide}/apps/interpolate_app.py (100%) rename python_bindings/{ => halide}/apps/interpolate_generator.py (100%) rename python_bindings/{ => halide}/apps/local_laplacian_app.py (100%) rename python_bindings/{ => halide}/apps/local_laplacian_generator.py (100%) rename python_bindings/{ => halide}/cmake/AddPythonTest.cmake (100%) rename python_bindings/{ => halide}/packaging/CMakeLists.txt (92%) rename python_bindings/{ => halide}/packaging/Halide_PythonConfig.cmake.in (100%) rename python_bindings/{packaging/pip => halide/packaging/cmake}/CMakeLists.txt (91%) rename python_bindings/{packaging/pip => halide/packaging/cmake}/TrampolineConfig.cmake.in (100%) create mode 100644 python_bindings/halide/pyproject.toml rename python_bindings/{src/halide => halide/src}/CMakeLists.txt (97%) rename python_bindings/{src/halide => halide/src}/__init__.py (70%) rename python_bindings/{src/halide => halide/src}/_generator_helpers.py (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyArgument.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyArgument.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyBinaryOperators.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyBoundaryConditions.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyBoundaryConditions.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyBuffer.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyBuffer.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyCallable.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyCallable.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyConciseCasts.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyConciseCasts.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyDerivative.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyDerivative.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyEnums.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyEnums.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyError.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyError.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyExpr.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyExpr.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyExternFuncArgument.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyExternFuncArgument.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyFunc.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyFunc.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyFuncRef.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyFuncRef.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyGenerator.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyGenerator.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyHalide.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyHalide.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyIROperator.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyIROperator.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyImageParam.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyImageParam.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyInlineReductions.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyInlineReductions.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyLambda.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyLambda.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyLoopLevel.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyLoopLevel.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyModule.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyModule.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyParam.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyParam.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyParameter.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyParameter.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyPipeline.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyPipeline.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyRDom.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyRDom.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyScheduleMethods.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PySerialization.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PySerialization.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyStage.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyStage.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyTarget.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyTarget.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyTuple.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyTuple.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyType.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyType.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyVar.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyVar.h (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyVarOrRVar.cpp (100%) rename python_bindings/{src/halide => halide/src}/halide_/PyVarOrRVar.h (100%) rename python_bindings/{src/halide => halide/src}/imageio.py (100%) rename python_bindings/{ => halide}/stub/CMakeLists.txt (100%) rename python_bindings/{ => halide}/stub/PyStubImpl.cpp (100%) rename python_bindings/{ => halide}/test/CMakeLists.txt (100%) rename python_bindings/{ => halide}/test/correctness/CMakeLists.txt (100%) rename python_bindings/{ => halide}/test/correctness/addconstant_test.py (100%) rename python_bindings/{ => halide}/test/correctness/atomics.py (100%) rename python_bindings/{ => halide}/test/correctness/autodiff.py (100%) rename python_bindings/{ => halide}/test/correctness/basics.py (100%) rename python_bindings/{ => halide}/test/correctness/bit_test.py (100%) rename python_bindings/{ => halide}/test/correctness/boundary_conditions.py (100%) rename python_bindings/{ => halide}/test/correctness/buffer.py (100%) rename python_bindings/{ => halide}/test/correctness/callable.py (100%) rename python_bindings/{ => halide}/test/correctness/compile_to.py (100%) rename python_bindings/{ => halide}/test/correctness/division.py (100%) rename python_bindings/{ => halide}/test/correctness/extern.py (100%) rename python_bindings/{ => halide}/test/correctness/float_precision_test.py (100%) rename python_bindings/{ => halide}/test/correctness/iroperator.py (100%) rename python_bindings/{ => halide}/test/correctness/memoize.py (100%) rename python_bindings/{ => halide}/test/correctness/multi_method_module_test.py (100%) rename python_bindings/{ => halide}/test/correctness/multipass_constraints.py (100%) rename python_bindings/{ => halide}/test/correctness/negate_test.py (100%) rename python_bindings/{ => halide}/test/correctness/pystub.py (100%) rename python_bindings/{ => halide}/test/correctness/rdom.py (100%) rename python_bindings/{ => halide}/test/correctness/realize_warnings.py (100%) rename python_bindings/{ => halide}/test/correctness/runtime_prefixes.py (100%) rename python_bindings/{ => halide}/test/correctness/serialization.py (100%) rename python_bindings/{ => halide}/test/correctness/target.py (100%) rename python_bindings/{ => halide}/test/correctness/the_sort_function.c (100%) rename python_bindings/{ => halide}/test/correctness/tuple_select.py (100%) rename python_bindings/{ => halide}/test/correctness/type.py (100%) rename python_bindings/{ => halide}/test/correctness/user_context_test.py (100%) rename python_bindings/{ => halide}/test/correctness/var.py (100%) rename python_bindings/{ => halide}/test/generators/CMakeLists.txt (100%) rename python_bindings/{ => halide}/test/generators/addconstantcpp_generator.cpp (100%) rename python_bindings/{ => halide}/test/generators/addconstantpy_generator.py (100%) rename python_bindings/{ => halide}/test/generators/bitcpp_generator.cpp (100%) rename python_bindings/{ => halide}/test/generators/bitpy_generator.py (100%) rename python_bindings/{ => halide}/test/generators/complexcpp_generator.cpp (100%) rename python_bindings/{ => halide}/test/generators/complexpy_generator.py (100%) rename python_bindings/{ => halide}/test/generators/simplecpp_generator.cpp (100%) rename python_bindings/{ => halide}/test/generators/simplepy_generator.py (100%) rename python_bindings/{ => halide}/test/generators/user_context_generator.cpp (100%) rename python_bindings/{ => halide}/test/runtime/CMakeLists.txt (100%) rename python_bindings/{ => halide}/test/runtime/aot_module_stub.c (100%) rename python_bindings/{ => halide}/test/runtime/call_convention.py (100%) rename python_bindings/{ => halide}/test/runtime/callconv_generator.cpp (100%) rename python_bindings/{ => halide}/test/runtime/check_no_libhalide.cmake (100%) rename python_bindings/{ => halide}/test/runtime/gpu.py (100%) rename python_bindings/{ => halide}/test/runtime/gpu_generator.cpp (100%) rename python_bindings/{ => halide}/test/runtime/load_aot.py (100%) rename python_bindings/{ => halide}/test/runtime/runtimeadd_generator.cpp (100%) rename python_bindings/{ => halide}/tutorial/CMakeLists.txt (100%) rename python_bindings/{ => halide}/tutorial/lesson_01_basics.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_02_input_image.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_03_debugging_1.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_04_debugging_2.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_05_scheduling_1.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_06_realizing_over_shifted_domains.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_07_multi_stage_pipelines.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_08_scheduling_2.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_09_update_definitions.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_10_aot_compilation_generate.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_10_aot_compilation_run.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_11_cross_compilation.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_12_using_the_gpu.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_13_tuples.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_14_types.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_15_generators.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_15_runtime.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_16_rgb_generate.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_16_rgb_run.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_17_predicated_rdom.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_18_parallel_associative_reductions.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_19_wrapper_funcs.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_20_cloning_funcs.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_21_auto_scheduler_generate.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_21_auto_scheduler_run.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_22_jit_performance.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_23_serialization.py (100%) rename python_bindings/{ => halide}/tutorial/lesson_24_async.py (100%) delete mode 100644 python_bindings/src/CMakeLists.txt diff --git a/.github/workflows/pip.yml b/.github/workflows/pip.yml index ec551a58f985..fa80718ab20b 100644 --- a/.github/workflows/pip.yml +++ b/.github/workflows/pip.yml @@ -1,6 +1,7 @@ name: Build PyPI package on: + workflow_dispatch: push: branches: [ main ] release: @@ -74,9 +75,10 @@ jobs: - name: Build wheels uses: pypa/cibuildwheel@v4.2.0 + with: + package-dir: python_bindings/halide-bin env: - CIBW_BUILD: "cp3*-${{ matrix.platform_tag }}" - CIBW_SKIP: "cp3{5,6,7,8,9}* cp3??t-*" + CIBW_BUILD: "cp312-${{ matrix.platform_tag }}" CIBW_BEFORE_ALL_LINUX: > /opt/python/cp312-cp312/bin/pip install cmake ninja "halide-llvm==${{ env.LLVM_VERSION }}" @@ -151,7 +153,7 @@ jobs: build-wheels: name: Build Halide wheels for ${{ matrix.platform_tag }} - needs: build-halide-bin + needs: [build-halide-bin, build-runtime-wheels] runs-on: ${{ matrix.os }} strategy: @@ -169,7 +171,6 @@ jobs: env: MACOSX_DEPLOYMENT_TARGET: 11 - HALIDE_SPLIT_BUILD: "1" steps: - uses: actions/checkout@v7 @@ -186,11 +187,11 @@ jobs: # halide-bin # # Building the Python bindings no longer needs LLVM/FlatBuffers/WABT at - # all -- it links against an already-installed halide-bin via - # find_package(Halide). Fetch the wheel this platform's - # build-halide-bin job just produced, and unpack a copy of it so - # CMAKE_PREFIX_PATH can point straight at a real directory (as opposed - # to a still-zipped wheel). + # all -- its dynamic metadata hook installs the matching halide-bin into + # the isolated build environment, where find_package(Halide) discovers + # it. Fetch the wheel this platform's build-halide-bin job just produced + # and expose it to pip via PIP_FIND_LINKS. Windows also needs an unpacked + # copy later so delvewheel can resolve (but not vendor) Halide.dll. ######################################################################## - uses: actions/download-artifact@v8 @@ -198,7 +199,13 @@ jobs: name: wheels-bin-${{ matrix.platform_tag }} path: dist-bin - - name: Unpack halide-bin for the build + - uses: actions/download-artifact@v8 + with: + name: wheels-runtime-${{ matrix.platform_tag }} + path: dist-runtime + + - name: Unpack halide-bin for Windows wheel repair + if: matrix.os == 'windows-latest' shell: bash run: python -m zipfile -e dist-bin/*.whl opt/halide-bin @@ -210,19 +217,21 @@ jobs: - name: Build wheels uses: pypa/cibuildwheel@v4.1.1 + with: + package-dir: python_bindings/halide env: CIBW_BUILD: "cp3*-${{ matrix.platform_tag }}" CIBW_SKIP: "cp3{5,6,7,8,9}* cp314t-*" CIBW_ENVIRONMENT_LINUX: > - CMAKE_PREFIX_PATH=/project/opt/halide-bin/halide_bin/data + PIP_FIND_LINKS=/project/dist-bin SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE='{local_scheme="no-local-version"}' CIBW_ENVIRONMENT_MACOS: > - CMAKE_PREFIX_PATH='${{ github.workspace }}/opt/halide-bin/halide_bin/data' + PIP_FIND_LINKS='${{ github.workspace }}/dist-bin' Python_ROOT_DIR='' SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE='{local_scheme="no-local-version"}' CIBW_ENVIRONMENT_WINDOWS: > CMAKE_GENERATOR=Ninja - CMAKE_PREFIX_PATH='${{ github.workspace }}\opt\halide-bin\halide_bin\data' + PIP_FIND_LINKS='${{ github.workspace }}\dist-bin' SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE='{local_scheme="no-local-version"}' # halide_.pyd/.so now depends on a Halide.dll/libHalide supplied by the # already-installed halide-bin package, not one bundled in this wheel -- @@ -230,7 +239,7 @@ jobs: # `--add-path` lets its dependency scan actually resolve it. CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: > delvewheel repair --ignore-existing --exclude Halide.dll - --add-path '${{ github.workspace }}\opt\halide-bin\halide_bin\data\bin' + --add-path '${{ github.workspace }}\opt\halide-bin\halide\bin' -w {dest_dir} {wheel} # halide-bin isn't published yet during this CI run, so resolve it # from the wheel we just downloaded instead of the package index. @@ -239,8 +248,8 @@ jobs: # have them on PATH via the get-cmake action above. CIBW_BEFORE_TEST_LINUX: > pip install cmake ninja && - pip install --no-index --find-links {project}/dist-bin halide-bin - CIBW_BEFORE_TEST: pip install --no-index --find-links {project}/dist-bin halide-bin + pip install --no-index --find-links {project}/dist-bin --find-links {project}/dist-runtime halide-bin halide-runtime + CIBW_BEFORE_TEST: pip install --no-index --find-links {project}/dist-bin --find-links {project}/dist-runtime halide-bin halide-runtime CIBW_TEST_COMMAND: > cmake -G Ninja -S {project}/python_bindings/apps -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build && @@ -276,7 +285,6 @@ jobs: env: MACOSX_DEPLOYMENT_TARGET: 11 - HALIDE_SPLIT_BUILD: "1" steps: - uses: actions/checkout@v7 @@ -295,8 +303,9 @@ jobs: # The runtime module is compiled against an already-installed halide-bin # (for the runtime headers, the shared marshalling source, and GenRT to # generate its bundled Halide runtime), exactly like build-wheels above. - # Unlike that job, the resulting extension links no libHalide and the wheel - # has no halide-bin dependency. + # PIP_FIND_LINKS makes the just-built wheel available to the isolated + # build resolver. Unlike that job, the resulting extension links no + # libHalide and the wheel has no runtime halide-bin dependency. ######################################################################## - uses: actions/download-artifact@v8 @@ -304,10 +313,6 @@ jobs: name: wheels-bin-${{ matrix.platform_tag }} path: dist-bin - - name: Unpack halide-bin for the build - shell: bash - run: python -m zipfile -e dist-bin/*.whl opt/halide-bin - ######################################################################## # Wheels ######################################################################## @@ -315,20 +320,20 @@ jobs: - name: Build wheels uses: pypa/cibuildwheel@v4.1.1 with: - package-dir: packaging/pip-runtime + package-dir: python_bindings/halide-runtime env: CIBW_BUILD: "cp3*-${{ matrix.platform_tag }}" CIBW_SKIP: "cp3{5,6,7,8,9}* cp314t-*" CIBW_ENVIRONMENT_LINUX: > - CMAKE_PREFIX_PATH=/project/opt/halide-bin/halide_bin/data + PIP_FIND_LINKS=/project/dist-bin SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE_RUNTIME='{local_scheme="no-local-version"}' CIBW_ENVIRONMENT_MACOS: > - CMAKE_PREFIX_PATH='${{ github.workspace }}/opt/halide-bin/halide_bin/data' + PIP_FIND_LINKS='${{ github.workspace }}/dist-bin' Python_ROOT_DIR='' SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE_RUNTIME='{local_scheme="no-local-version"}' CIBW_ENVIRONMENT_WINDOWS: > CMAKE_GENERATOR=Ninja - CMAKE_PREFIX_PATH='${{ github.workspace }}\opt\halide-bin\halide_bin\data' + PIP_FIND_LINKS='${{ github.workspace }}\dist-bin' SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE_RUNTIME='{local_scheme="no-local-version"}' # The runtime wheel links no libHalide, so its test environment needs # nothing installed: a successful `import halide.runtime` in a bare @@ -343,6 +348,7 @@ jobs: publish: name: Publish on PyPI + if: github.event_name != 'workflow_dispatch' needs: [build-halide-bin, build-wheels, build-runtime-wheels] runs-on: ubuntu-latest permissions: @@ -362,28 +368,42 @@ jobs: set -euo pipefail shopt -s nullglob - files=(dist/halide-*.whl) + halide_files=(dist/halide-*.whl) + bin_files=(dist/halide_bin-*.whl) + runtime_files=(dist/halide_runtime-*.whl) shopt -u nullglob - if [ ${#files[@]} -eq 0 ]; then - echo "no wheels found in dist/, nothing to publish" + if [ ${#halide_files[@]} -eq 0 ] || [ ${#bin_files[@]} -eq 0 ] || [ ${#runtime_files[@]} -eq 0 ]; then + echo "one or more Halide distributions have no wheels in dist/" exit 1 fi - - # Wheel filenames are "{name}-{version}-{python tag}-{abi - # tag}-{platform tag}.whl"; any hyphens in name/version are - # normalized to underscores specifically so "-" is an unambiguous - # field separator, so plain splitting is safe here. - filename=$(basename "${files[0]}") - version="${filename#halide-}" - version="${version%%-*}" - tag="halide@${version}" - - if gh release view "$tag" --repo halide/pypi >/dev/null 2>&1; then - gh release upload "$tag" "${files[@]}" --repo halide/pypi --clobber - else - gh release create "$tag" "${files[@]}" \ - --repo halide/pypi --title "$tag" --notes "Automated nightly build from Halide" - fi + # halide/pypi exposes one package per GitHub release, so each + # distribution needs its own tag and only its own wheel files. + publish_release() { + local package=$1 + local wheel_prefix=$2 + shift 2 + local files=("$@") + local filename version tag + + # Wheel filenames are "{name}-{version}-{python tag}-{abi + # tag}-{platform tag}.whl"; distribution-name hyphens are + # normalized to underscores, so the first hyphen ends the prefix. + filename=$(basename "${files[0]}") + version="${filename#"${wheel_prefix}"-}" + version="${version%%-*}" + tag="${package}@${version}" + + if gh release view "$tag" --repo halide/pypi >/dev/null 2>&1; then + gh release upload "$tag" "${files[@]}" --repo halide/pypi --clobber + else + gh release create "$tag" "${files[@]}" \ + --repo halide/pypi --title "$tag" --notes "Automated nightly build from Halide" + fi + } + + publish_release halide halide "${halide_files[@]}" + publish_release halide-bin halide_bin "${bin_files[@]}" + publish_release halide-runtime halide_runtime "${runtime_files[@]}" - name: Trigger index rebuild if: github.event_name == 'push' && github.ref_name == 'main' diff --git a/.gitignore b/.gitignore index 28cf9d022cd6..95769621ee19 100644 --- a/.gitignore +++ b/.gitignore @@ -279,5 +279,6 @@ CLAUDE.local.md !src/autoschedulers/adams2019/included_schedule_file.schedule.h # TODO: these should become .cmake.in -!packaging/common/HalideConfig.cmake -!packaging/common/HalideCompilerConfig.cmake +!packaging/HalideConfig.cmake +!packaging/HalideCompilerConfig.cmake +!packaging/HalideAutoschedulersConfig.cmake diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt index eeaf901059c0..0b3fb346d28b 100644 --- a/packaging/CMakeLists.txt +++ b/packaging/CMakeLists.txt @@ -281,14 +281,14 @@ else () endif () configure_package_config_file( - common/HalideConfig.cmake HalideConfig.cmake + HalideConfig.cmake HalideConfig.cmake PATH_VARS Halide_INSTALL_COMPILERDIR INSTALL_DESTINATION "${Halide_INSTALL_CMAKEDIR}" NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO ) configure_package_config_file( - common/HalideCompilerConfig.cmake HalideCompilerConfig.cmake + HalideCompilerConfig.cmake HalideCompilerConfig.cmake PATH_VARS ${extra_paths} INSTALL_DESTINATION "${Halide_INSTALL_COMPILERDIR}" NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO @@ -296,7 +296,7 @@ configure_package_config_file( if (WITH_AUTOSCHEDULERS) configure_package_config_file( - common/HalideAutoschedulersConfig.cmake HalideAutoschedulersConfig.cmake + HalideAutoschedulersConfig.cmake HalideAutoschedulersConfig.cmake INSTALL_DESTINATION "${Halide_INSTALL_AUTOSCHEDULERSDIR}" NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO ) @@ -361,7 +361,10 @@ endif () ## if (SKBUILD) - add_subdirectory(pip) + add_subdirectory( + "${Halide_SOURCE_DIR}/python_bindings/halide-bin/packaging" + "${CMAKE_CURRENT_BINARY_DIR}/pip" + ) endif () ## @@ -376,8 +379,8 @@ set(CPACK_PACKAGE_VERSION_MAJOR ${Halide_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${Halide_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${Halide_VERSION_PATCH}) set(CPACK_VERBATIM_VARIABLES YES) -set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_LIST_DIR}/common/Description.txt") -set(CPACK_RESOURCE_FILE_WELCOME "${CMAKE_CURRENT_LIST_DIR}/common/Welcome.txt") +set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_LIST_DIR}/Description.txt") +set(CPACK_RESOURCE_FILE_WELCOME "${CMAKE_CURRENT_LIST_DIR}/Welcome.txt") set(CPACK_RESOURCE_FILE_LICENSE "${Halide_SOURCE_DIR}/LICENSE.txt") set(CPACK_RESOURCE_FILE_README "${Halide_SOURCE_DIR}/README.md") @@ -418,6 +421,12 @@ cpack_add_component( DEPENDS Halide_Runtime ) +cpack_add_component( + Halide_PythonRuntime + DISPLAY_NAME "Python runtime bindings" + DESCRIPTION "Python package providing header-only Halide runtime bindings" +) + cpack_add_component( Halide_Documentation DISPLAY_NAME "Halide documentation" diff --git a/packaging/common/Description.txt b/packaging/Description.txt similarity index 100% rename from packaging/common/Description.txt rename to packaging/Description.txt diff --git a/packaging/common/HalideAutoschedulersConfig.cmake b/packaging/HalideAutoschedulersConfig.cmake similarity index 100% rename from packaging/common/HalideAutoschedulersConfig.cmake rename to packaging/HalideAutoschedulersConfig.cmake diff --git a/packaging/common/HalideCompilerConfig.cmake b/packaging/HalideCompilerConfig.cmake similarity index 100% rename from packaging/common/HalideCompilerConfig.cmake rename to packaging/HalideCompilerConfig.cmake diff --git a/packaging/common/HalideConfig.cmake b/packaging/HalideConfig.cmake similarity index 100% rename from packaging/common/HalideConfig.cmake rename to packaging/HalideConfig.cmake diff --git a/packaging/common/Welcome.txt b/packaging/Welcome.txt similarity index 100% rename from packaging/common/Welcome.txt rename to packaging/Welcome.txt diff --git a/packaging/pip-bin/src/halide_bin/__init__.py b/packaging/pip-bin/src/halide_bin/__init__.py deleted file mode 100644 index a2d204ffd307..000000000000 --- a/packaging/pip-bin/src/halide_bin/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -import os - - -def install_dir(): - return os.path.join(os.path.dirname(__file__), "data") diff --git a/packaging/pip/_dynamic_metadata.py b/packaging/pip/_dynamic_metadata.py deleted file mode 100644 index 361f9f4afcbf..000000000000 --- a/packaging/pip/_dynamic_metadata.py +++ /dev/null @@ -1,31 +0,0 @@ -""" -Dynamic metadata provider for the `halide` pip package. -""" - -from __future__ import annotations -from typing import Any -from collections.abc import Mapping - -__all__ = ["dynamic_metadata"] - - -def dynamic_metadata( - settings: Mapping[str, Any], - project: Mapping[str, Any], -) -> dict[str, Any]: - import os - - if settings: - raise ValueError("No inline configuration is supported") - - if os.environ.get("HALIDE_SPLIT_BUILD"): - deps = [ - "imageio>=2", - "pillow; platform_machine == 'armv8l' or platform_machine == 'armv7l'", - "numpy>=1.26", - f"halide-bin=={project['version']}", - ] - else: - deps = [] - - return {"dependencies": deps} diff --git a/pyproject.toml b/pyproject.toml index f5fd123d1537..de993e2d74f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,90 +1,30 @@ -[build-system] -requires = [ - "pybind11>=2.11.1", - "scikit-build-core>=1.0.3", - "setuptools-scm>=8.3.1", -] -build-backend = "scikit_build_core.build" - [project] -name = "halide" -authors = [ - { name = "The Halide team", email = "halide-dev@lists.csail.mit.edu" }, -] -maintainers = [{ name = "Alex Reinking", email = "areinking@adobe.com" }] -description = "Halide is a programming language designed to make it easier to write high-performance image and array processing code." -license = "MIT" -readme = "./packaging/pip/README.md" +name = "halide-workspace" +version = "0" requires-python = ">=3.10" -dynamic = ['version', 'dependencies'] -keywords = [ - "array", - "compiler", - "domain-specific language", - "dsl", - "gpu", - "hexagon", - "image processing", - "machine learning", - "performance", - "programming language", -] -classifiers = [ - "Development Status :: 5 - Production/Stable", - "Environment :: GPU", - "Environment :: GPU :: NVIDIA CUDA", - "Environment :: WebAssembly", - "Intended Audience :: Developers", - "Intended Audience :: Science/Research", - "Natural Language :: English", - "Operating System :: MacOS", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Programming Language :: C++", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Programming Language :: Python :: 3.14", - "Programming Language :: Python :: Implementation :: CPython", - "Topic :: Multimedia :: Graphics", - "Topic :: Scientific/Engineering", - "Topic :: Scientific/Engineering :: Artificial Intelligence", - "Topic :: Scientific/Engineering :: Image Processing", - "Topic :: Software Development :: Code Generators", - "Topic :: Software Development :: Compilers", - "Topic :: Software Development :: Libraries", + +[tool.uv.workspace] +members = [ + "python_bindings/halide-bin", + "python_bindings/halide-runtime", + "python_bindings/halide", ] [dependency-groups] -dev = [ - # Matches build-system.requires - "pybind11>=2.11.1", - "scikit-build-core>=1.0.3", - "setuptools-scm>=8.3.1", -] +dev = ["pybind11>=2.11.1", "scikit-build-core>=1.0.3", "setuptools-scm>=8.3.1"] apps = [ - # for apps/onnx -- matches the vcpkg version "onnx==1.19.0; platform_machine != 'armv8l' and platform_machine != 'armv7l'", - # onnx 1.19.0 gencode requires protobuf 7.x runtime "protobuf>=7; platform_machine != 'armv8l' and platform_machine != 'armv7l'", - # unspecified onnx dependency "pytest; platform_machine != 'armv8l' and platform_machine != 'armv7l'", ] tools = [ "cmake>=3.28", - # 1.13.0 uses LF in .rsp files, breaking MSVC link.exe. - # See: https://github.com/ninja-build/ninja/pull/2616 "ninja>=1.11,!=1.13.0", "pre-commit>=4", "ruff>=0.12", "tbump>=6.11", ] docs = [ - # for doc/ -- renders doc/*.md prose, the Breathe/Doxygen API reference, - # and the tutorial (captured via gdb/lldb, see doc/tutorial_website/) "sphinx>=7.2", "myst-parser>=3.0", "breathe>=4.35", @@ -92,107 +32,41 @@ docs = [ "sphinxcontrib-video>=0.4", "sphinx-design>=0.6", ] - ci-base = [ { include-group = "dev" }, { include-group = "apps" }, { include-group = "tools" }, ] - ci-llvm-main = [{ include-group = "ci-base" }, "halide-llvm~=23.0.0.dev0"] ci-llvm-22 = [{ include-group = "ci-base" }, "halide-llvm~=22.1.0"] ci-llvm-21 = [{ include-group = "ci-base" }, "halide-llvm~=21.1.0"] -[project.urls] -Homepage = "https://halide-lang.org" -Documentation = "https://github.com/halide/Halide/blob/main/doc/Python.md" -"Documentation (C++)" = "https://halide-lang.org/docs" -Issues = "https://github.com/halide/Halide/issues" -Repository = "https://github.com/halide/Halide.git" - -[[tool.dynamic-metadata]] -provider = "scikit_build_core.metadata.setuptools_scm" - -[[tool.dynamic-metadata]] -provider = { path = "packaging/pip", module = "_dynamic_metadata" } - -[tool.scikit-build] -minimum-version = "build-system.requires" -cmake.version = ">=3.28" -ninja.version = ">=1.11,!=1.13.0" -wheel.install-dir = "halide" -sdist.inclusion-mode = "explicit" -sdist.include = [ - "cmake", - "dependencies", - "packaging", - "python_bindings", - "src", - "tools", - ".git_archival.txt", - "CMakeLists.txt", - "LICENSE.txt", - "pyproject.toml", - "README.md", - "uv.lock", - "vcpkg.json", - "vcpkg-configuration.json", -] -sdist.exclude = ["dependencies/update-*.sh"] - -[tool.scikit-build.cmake.define] -CMAKE_DISABLE_FIND_PACKAGE_JPEG = true -CMAKE_DISABLE_FIND_PACKAGE_PNG = true -Halide_ENABLE_EXCEPTIONS = true -Halide_ENABLE_RTTI = true -Halide_INSTALL_PYTHONDIR = "." -Halide_WASM_BACKEND = "wabt" -WITH_PYTHON_BINDINGS = true -WITH_TESTS = false -WITH_TUTORIALS = false -WITH_UTILS = false - -## -# Don't version libHalide.so/dylib -- wheels are zip files that do -# not understand symbolic links. Including version information here -# causes the final wheel to have three copies of our library. Not good. -CMAKE_PLATFORM_NO_VERSIONED_SONAME = true - -[[tool.scikit-build.overrides]] -if.platform-system = "^win32" -inherit.cmake.define = "append" -cmake.define.Halide_WASM_BACKEND = "OFF" +[tool.uv.sources] +halide-bin = { workspace = true } +halide-runtime = { workspace = true } +halide-llvm = { index = "halide" } +imageio = { index = "piwheels", marker = "platform_machine == 'armv8l' or platform_machine == 'armv7l'" } +numpy = { index = "piwheels", marker = "platform_machine == 'armv8l' or platform_machine == 'armv7l'" } +pillow = { index = "piwheels", marker = "platform_machine == 'armv8l' or platform_machine == 'armv7l'" } -## -# Split-package build: build only the Python bindings, against an -# already-installed `halide-bin` (found via CMAKE_PREFIX_PATH, which the -# caller -- e.g. .github/workflows/pip.yml -- must set explicitly). Only -# official release CI sets HALIDE_SPLIT_BUILD; a plain `pip install .` -# from a source checkout is unaffected and keeps building everything from -# scratch, as before. -[[tool.scikit-build.overrides]] -if.env.HALIDE_SPLIT_BUILD = true -cmake.source-dir = "python_bindings" +[[tool.uv.index]] +name = "halide" +url = "https://pypi.halide-lang.org/simple" +explicit = true -[tool.setuptools_scm] -# Needs to exist for scikit-build-core to use setuptools_scm +[[tool.uv.index]] +name = "piwheels" +url = "https://piwheels.org/simple" +explicit = true -[tool.ruff.lint] -# docs: https://docs.astral.sh/ruff/rules/ -select = [ - "E4", # pycodestyle / import statements - "E7", # pycodestyle / superfluous or misused syntax - "E9", # pycodestyle / internal error (odd this can be disabled) - "F", # pyflakes - "FURB", # refurb / rules for upgrading old Python usage - "PERF", # perflint / rules for performance pitfalls - "RUF", # Ruff-specific rules - "SIM", # flake8 / simplify - "UP", # pyupgrade / detect uses of old Python features -] -ignore = [ - "UP045", # Don't replace Optional[T] with T | None - "SIM108", # Don't replace an if statement with ternary +[tool.uv] +package = false +conflicts = [ + [ + { package = "halide-workspace", group = "ci-llvm-main" }, + { package = "halide-workspace", group = "ci-llvm-22" }, + { package = "halide-workspace", group = "ci-llvm-21" }, + ], ] [tool.tbump] @@ -214,49 +88,6 @@ search = "VERSION {current_version}" src = "python_bindings/CMakeLists.txt" search = "VERSION {current_version}" -[[tool.tbump.file]] -src = "vcpkg.json" - -[[tool.tbump.file]] -src = "apps/vcpkg.json" - -[[tool.tbump.file]] -src = "src/runtime/HalideRuntime.h" -version_template = "{major}" -search = "#define HALIDE_VERSION_MAJOR {current_version}" - -[[tool.tbump.file]] -src = "src/runtime/HalideRuntime.h" -version_template = "{minor}" -search = "#define HALIDE_VERSION_MINOR {current_version}" - -[[tool.tbump.file]] -src = "src/runtime/HalideRuntime.h" -version_template = "{patch}" -search = "#define HALIDE_VERSION_PATCH {current_version}" - -[tool.uv] -conflicts = [ - [ - { group = "ci-llvm-main" }, - { group = "ci-llvm-22" }, - { group = "ci-llvm-21" }, - { group = "ci-llvm-20" }, - ], -] - -[tool.uv.sources] -halide-llvm = { index = "halide" } -imageio = { index = "piwheels", marker = "platform_machine == 'armv8l' or platform_machine == 'armv7l'" } -numpy = { index = "piwheels", marker = "platform_machine == 'armv8l' or platform_machine == 'armv7l'" } -pillow = { index = "piwheels", marker = "platform_machine == 'armv8l' or platform_machine == 'armv7l'" } - -[[tool.uv.index]] -name = "halide" -url = "https://pypi.halide-lang.org/simple" -explicit = true - -[[tool.uv.index]] -name = "piwheels" -url = "https://piwheels.org/simple" -explicit = true +[tool.ruff.lint] +select = ["E4", "E7", "E9", "F", "FURB", "PERF", "RUF", "SIM", "UP"] +ignore = ["UP045", "SIM108"] diff --git a/python_bindings/CMakeLists.txt b/python_bindings/CMakeLists.txt index 3d0c609bac92..a0ed83afce12 100644 --- a/python_bindings/CMakeLists.txt +++ b/python_bindings/CMakeLists.txt @@ -45,35 +45,24 @@ if (WITH_PYTHON_BINDINGS) endif () # Note: this must happen, especially when WITH_PYTHON_BINDINGS is OFF. -find_package(Halide REQUIRED Halide) +find_package(Halide REQUIRED) if (NOT Halide_ENABLE_RTTI OR NOT Halide_ENABLE_EXCEPTIONS) message(FATAL_ERROR "Python bindings require RTTI and exceptions to be enabled.") endif () -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/halide/cmake") include(AddPythonTest) ## # Add our sources to this sub-tree. ## +# Package subtrees are deliberately ordered: the binary package owns the +# compiler installation, the runtime owns the header-only extension, and the +# compiler package consumes both while adding the familiar Python surface. +add_subdirectory(halide-bin) if (WITH_PYTHON_BINDINGS) - add_subdirectory(src) -endif () - -if (WITH_PYTHON_STUBS) - add_subdirectory(stub) -endif () - -if (WITH_TEST_PYTHON) - add_subdirectory(apps) - add_subdirectory(test) -endif () - -if (WITH_TUTORIALS) - add_subdirectory(tutorial) -endif () - -if (WITH_PACKAGING) - add_subdirectory(packaging) + set(Halide_Python_PACKAGE_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/halide/src") + add_subdirectory(halide-runtime) endif () +add_subdirectory(halide) diff --git a/python_bindings/halide-bin/CMakeLists.txt b/python_bindings/halide-bin/CMakeLists.txt new file mode 100644 index 000000000000..faba64a687ff --- /dev/null +++ b/python_bindings/halide-bin/CMakeLists.txt @@ -0,0 +1,2 @@ +# The binary wheel has no Python extension target. Its installation payload is +# supplied by the top-level Halide project when scikit-build configures it. diff --git a/packaging/pip/CMakeLists.txt b/python_bindings/halide-bin/packaging/CMakeLists.txt similarity index 100% rename from packaging/pip/CMakeLists.txt rename to python_bindings/halide-bin/packaging/CMakeLists.txt diff --git a/packaging/pip/TrampolineConfig.cmake.in b/python_bindings/halide-bin/packaging/TrampolineConfig.cmake.in similarity index 63% rename from packaging/pip/TrampolineConfig.cmake.in rename to python_bindings/halide-bin/packaging/TrampolineConfig.cmake.in index 1d7469b25c6d..918328354248 100644 --- a/packaging/pip/TrampolineConfig.cmake.in +++ b/python_bindings/halide-bin/packaging/TrampolineConfig.cmake.in @@ -3,4 +3,4 @@ cmake_minimum_required(VERSION 3.28) include(CMakeFindDependencyMacro) find_dependency(Python 3 COMPONENTS Interpreter Development.Module) -include("${Python_SITEARCH}/halide_bin/data/@INSTALL_DIR@/@PACKAGE@Config.cmake") +include("${Python_SITEARCH}/halide/@INSTALL_DIR@/@PACKAGE@Config.cmake") diff --git a/packaging/pip-bin/pyproject.toml b/python_bindings/halide-bin/pyproject.toml similarity index 71% rename from packaging/pip-bin/pyproject.toml rename to python_bindings/halide-bin/pyproject.toml index 99e2c07faec0..0a323b223675 100644 --- a/packaging/pip-bin/pyproject.toml +++ b/python_bindings/halide-bin/pyproject.toml @@ -40,10 +40,32 @@ minimum-version = "build-system.requires" cmake.version = ">=3.28" ninja.version = ">=1.11,!=1.13.0" cmake.source-dir = "../.." -wheel.packages = ["src/halide_bin"] -wheel.install-dir = "halide_bin/data" +wheel.install-dir = "halide" # No Python extension modules in this package -- python-version-agnostic tag. wheel.py-api = "py3" +sdist.inclusion-mode = "explicit" +sdist.include = [ + "pyproject.toml", + "src/halide/bin/__init__.py", + "python_bindings/halide-bin/src/halide/bin/__init__.py", +] + +[tool.scikit-build.sdist.force-include] +"../../cmake" = "cmake" +"../../dependencies" = "dependencies" +"../../packaging" = "packaging" +"../../python_bindings" = "python_bindings" +"../../src" = "src" +"../../tools" = "tools" +"../../.git_archival.txt" = ".git_archival.txt" +"../../CMakeLists.txt" = "CMakeLists.txt" +"../../LICENSE.txt" = "LICENSE.txt" +"../../README.md" = "README.md" +"../../vcpkg.json" = "vcpkg.json" +"../../vcpkg-configuration.json" = "vcpkg-configuration.json" + +[tool.scikit-build.wheel.force-include] +"python_bindings/halide-bin/src/halide/bin/__init__.py" = "halide/bin/__init__.py" [tool.scikit-build.cmake.define] CMAKE_DISABLE_FIND_PACKAGE_JPEG = true @@ -55,6 +77,7 @@ Halide_WASM_BACKEND = "wabt" WITH_PYTHON_BINDINGS = false WITH_TESTS = false WITH_TUTORIALS = false +WITH_UTILS = false ## # Don't version libHalide.so/dylib -- wheels are zip files that do @@ -67,5 +90,9 @@ if.platform-system = "^win32" inherit.cmake.define = "append" cmake.define.Halide_WASM_BACKEND = "OFF" +[[tool.scikit-build.overrides]] +if.from-sdist = true +cmake.source-dir = "." + [tool.setuptools_scm] root = "../.." diff --git a/python_bindings/halide-runtime/CMakeLists.txt b/python_bindings/halide-runtime/CMakeLists.txt new file mode 100644 index 000000000000..06c53d327e69 --- /dev/null +++ b/python_bindings/halide-runtime/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(src/halide/runtime) diff --git a/packaging/pip-runtime/README.md b/python_bindings/halide-runtime/README.md similarity index 100% rename from packaging/pip-runtime/README.md rename to python_bindings/halide-runtime/README.md diff --git a/python_bindings/halide-runtime/_dynamic_metadata.py b/python_bindings/halide-runtime/_dynamic_metadata.py new file mode 100644 index 000000000000..22a208a398f3 --- /dev/null +++ b/python_bindings/halide-runtime/_dynamic_metadata.py @@ -0,0 +1,35 @@ +"""Build requirements for the ``halide-runtime`` distribution.""" + +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any + +__all__ = ["dynamic_metadata", "get_requires_for_dynamic_metadata"] + + +def get_requires_for_dynamic_metadata(settings: Mapping[str, Any]) -> list[str]: + if settings: + raise ValueError("No inline configuration is supported") + + from scikit_build_core.metadata.setuptools_scm import ( + dynamic_metadata as scm_version, + ) + + version = scm_version("version") + public_version = version.partition("+")[0] + return [f"halide-bin=={public_version}"] + + +def dynamic_metadata( + settings: Mapping[str, Any], + _project: Mapping[str, Any], +) -> dict[str, Any]: + if settings: + raise ValueError("No inline configuration is supported") + + from scikit_build_core.metadata.setuptools_scm import ( + dynamic_metadata as scm_version, + ) + + return {"version": scm_version("version")} diff --git a/packaging/pip-runtime/pyproject.toml b/python_bindings/halide-runtime/pyproject.toml similarity index 79% rename from packaging/pip-runtime/pyproject.toml rename to python_bindings/halide-runtime/pyproject.toml index 208d16926a7e..c52b6721fe7e 100644 --- a/packaging/pip-runtime/pyproject.toml +++ b/python_bindings/halide-runtime/pyproject.toml @@ -43,14 +43,14 @@ Issues = "https://github.com/halide/Halide/issues" Repository = "https://github.com/halide/Halide.git" [[tool.dynamic-metadata]] -provider = "scikit_build_core.metadata.setuptools_scm" +provider = { path = ".", module = "_dynamic_metadata" } [tool.scikit-build] minimum-version = "build-system.requires" experimental = true cmake.version = ">=3.28" ninja.version = ">=1.11,!=1.13.0" -cmake.source-dir = "../.." +cmake.source-dir = ".." # Build and package ONLY the standalone runtime extension: build just its target # (so libHalide's compiler bindings are never compiled) and install just its @@ -60,7 +60,21 @@ cmake.source-dir = "../.." build.targets = ["Halide_PythonRuntime"] install.components = ["Halide_PythonRuntime"] wheel.install-dir = "halide" -sdist.include = ["dependencies/"] +sdist.inclusion-mode = "explicit" +sdist.include = ["pyproject.toml", "README.md", "_dynamic_metadata.py"] + +[tool.scikit-build.sdist.force-include] +"../../cmake" = "cmake" +"../../dependencies" = "dependencies" +"../../packaging" = "packaging" +"../../python_bindings" = "python_bindings" +"../../src" = "src" +"../../tools" = "tools" +"../../.git_archival.txt" = ".git_archival.txt" +"../../CMakeLists.txt" = "CMakeLists.txt" +"../../LICENSE.txt" = "LICENSE.txt" +"../../vcpkg.json" = "vcpkg.json" +"../../vcpkg-configuration.json" = "vcpkg-configuration.json" [tool.scikit-build.cmake.define] CMAKE_DISABLE_FIND_PACKAGE_JPEG = true @@ -73,6 +87,7 @@ Halide_WASM_BACKEND = "wabt" WITH_PYTHON_BINDINGS = true WITH_TESTS = false WITH_TUTORIALS = false +WITH_UTILS = false CMAKE_PLATFORM_NO_VERSIONED_SONAME = true [[tool.scikit-build.overrides]] @@ -80,14 +95,9 @@ if.platform-system = "^win32" inherit.cmake.define = "append" cmake.define.Halide_WASM_BACKEND = "OFF" -## -# Split-package build: build only the Python bindings tree against an -# already-installed `halide-bin` (found via CMAKE_PREFIX_PATH, which the caller -# must set), so the runtime extension is compiled without building libHalide. -# The extension still links no libHalide at runtime. [[tool.scikit-build.overrides]] -if.env.HALIDE_SPLIT_BUILD = true -cmake.source-dir = "../../python_bindings" +if.from-sdist = true +cmake.source-dir = "python_bindings" [tool.setuptools_scm] root = "../.." diff --git a/python_bindings/src/halide/runtime/CMakeLists.txt b/python_bindings/halide-runtime/src/halide/runtime/CMakeLists.txt similarity index 86% rename from python_bindings/src/halide/runtime/CMakeLists.txt rename to python_bindings/halide-runtime/src/halide/runtime/CMakeLists.txt index f7eb15abc20d..5d05d2f54b83 100644 --- a/python_bindings/src/halide/runtime/CMakeLists.txt +++ b/python_bindings/halide-runtime/src/halide/runtime/CMakeLists.txt @@ -34,13 +34,14 @@ endif () add_halide_runtime(Halide_PythonRuntime_rt) target_link_libraries(Halide_PythonRuntime PRIVATE Halide::Runtime Halide_PythonRuntime_rt) -# Place the module at halide/runtime/ *inside the compiler package's tree* so it -# is importable as `halide.runtime`. The parent (Halide_Python) builds into -# `/$/halide`; this subdirectory's binary dir is one level -# deeper, so `../$/halide/runtime` co-locates the two. +# Place the module next to the compiler extension in normal CMake builds. The +# package binary directory is set by python_bindings/CMakeLists.txt. +if (NOT DEFINED Halide_Python_PACKAGE_BINARY_DIR) + set(Halide_Python_PACKAGE_BINARY_DIR "${CMAKE_BINARY_DIR}") +endif () set_target_properties(Halide_PythonRuntime PROPERTIES - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../$/halide/runtime" + LIBRARY_OUTPUT_DIRECTORY "${Halide_Python_PACKAGE_BINARY_DIR}/$/halide/runtime" ) if (Halide_ASAN_ENABLED) diff --git a/python_bindings/src/halide/runtime/PyRuntime.cpp b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp similarity index 100% rename from python_bindings/src/halide/runtime/PyRuntime.cpp rename to python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp diff --git a/python_bindings/src/halide/runtime/__init__.py b/python_bindings/halide-runtime/src/halide/runtime/__init__.py similarity index 100% rename from python_bindings/src/halide/runtime/__init__.py rename to python_bindings/halide-runtime/src/halide/runtime/__init__.py diff --git a/python_bindings/halide/CMakeLists.txt b/python_bindings/halide/CMakeLists.txt new file mode 100644 index 000000000000..ab0f089148cf --- /dev/null +++ b/python_bindings/halide/CMakeLists.txt @@ -0,0 +1,18 @@ +add_subdirectory(src) + +if (WITH_PYTHON_STUBS) + add_subdirectory(stub) +endif () + +if (WITH_TEST_PYTHON) + add_subdirectory(apps) + add_subdirectory(test) +endif () + +if (WITH_TUTORIALS) + add_subdirectory(tutorial) +endif () + +if (WITH_PACKAGING) + add_subdirectory(packaging) +endif () diff --git a/packaging/pip/README.md b/python_bindings/halide/README.md similarity index 100% rename from packaging/pip/README.md rename to python_bindings/halide/README.md diff --git a/python_bindings/halide/_dynamic_metadata.py b/python_bindings/halide/_dynamic_metadata.py new file mode 100644 index 000000000000..79f94ae17ca8 --- /dev/null +++ b/python_bindings/halide/_dynamic_metadata.py @@ -0,0 +1,37 @@ +"""Dynamic dependencies for the ``halide`` distribution.""" + +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any + +__all__ = ["dynamic_metadata", "get_requires_for_dynamic_metadata"] + + +def get_requires_for_dynamic_metadata(settings: Mapping[str, Any]) -> list[str]: + if settings: + raise ValueError("No inline configuration is supported") + + from scikit_build_core.metadata.setuptools_scm import ( + dynamic_metadata as scm_version, + ) + + version = scm_version("version") + public_version = version.partition("+")[0] + return [f"halide-bin=={public_version}"] + + +def dynamic_metadata( + settings: Mapping[str, Any], + project: Mapping[str, Any], +) -> dict[str, Any]: + if settings: + raise ValueError("No inline configuration is supported") + + version = project["version"] + return { + "dependencies": [ + f"halide-bin=={version}", + f"halide-runtime=={version}", + ] + } diff --git a/python_bindings/apps/CMakeLists.txt b/python_bindings/halide/apps/CMakeLists.txt similarity index 100% rename from python_bindings/apps/CMakeLists.txt rename to python_bindings/halide/apps/CMakeLists.txt diff --git a/python_bindings/apps/bilateral_grid_app.py b/python_bindings/halide/apps/bilateral_grid_app.py similarity index 100% rename from python_bindings/apps/bilateral_grid_app.py rename to python_bindings/halide/apps/bilateral_grid_app.py diff --git a/python_bindings/apps/bilateral_grid_generator.py b/python_bindings/halide/apps/bilateral_grid_generator.py similarity index 100% rename from python_bindings/apps/bilateral_grid_generator.py rename to python_bindings/halide/apps/bilateral_grid_generator.py diff --git a/python_bindings/apps/blur_app.py b/python_bindings/halide/apps/blur_app.py similarity index 100% rename from python_bindings/apps/blur_app.py rename to python_bindings/halide/apps/blur_app.py diff --git a/python_bindings/apps/blur_generator.py b/python_bindings/halide/apps/blur_generator.py similarity index 100% rename from python_bindings/apps/blur_generator.py rename to python_bindings/halide/apps/blur_generator.py diff --git a/python_bindings/apps/identity_app.py b/python_bindings/halide/apps/identity_app.py similarity index 100% rename from python_bindings/apps/identity_app.py rename to python_bindings/halide/apps/identity_app.py diff --git a/python_bindings/apps/identity_generator.py b/python_bindings/halide/apps/identity_generator.py similarity index 100% rename from python_bindings/apps/identity_generator.py rename to python_bindings/halide/apps/identity_generator.py diff --git a/python_bindings/apps/interpolate_app.py b/python_bindings/halide/apps/interpolate_app.py similarity index 100% rename from python_bindings/apps/interpolate_app.py rename to python_bindings/halide/apps/interpolate_app.py diff --git a/python_bindings/apps/interpolate_generator.py b/python_bindings/halide/apps/interpolate_generator.py similarity index 100% rename from python_bindings/apps/interpolate_generator.py rename to python_bindings/halide/apps/interpolate_generator.py diff --git a/python_bindings/apps/local_laplacian_app.py b/python_bindings/halide/apps/local_laplacian_app.py similarity index 100% rename from python_bindings/apps/local_laplacian_app.py rename to python_bindings/halide/apps/local_laplacian_app.py diff --git a/python_bindings/apps/local_laplacian_generator.py b/python_bindings/halide/apps/local_laplacian_generator.py similarity index 100% rename from python_bindings/apps/local_laplacian_generator.py rename to python_bindings/halide/apps/local_laplacian_generator.py diff --git a/python_bindings/cmake/AddPythonTest.cmake b/python_bindings/halide/cmake/AddPythonTest.cmake similarity index 100% rename from python_bindings/cmake/AddPythonTest.cmake rename to python_bindings/halide/cmake/AddPythonTest.cmake diff --git a/python_bindings/packaging/CMakeLists.txt b/python_bindings/halide/packaging/CMakeLists.txt similarity index 92% rename from python_bindings/packaging/CMakeLists.txt rename to python_bindings/halide/packaging/CMakeLists.txt index f715b3b0fab8..b18e0a1c05ad 100644 --- a/python_bindings/packaging/CMakeLists.txt +++ b/python_bindings/halide/packaging/CMakeLists.txt @@ -12,12 +12,12 @@ if (WITH_PYTHON_BINDINGS) # so a libHalide-free halide-runtime wheel can select just this component and # still be a complete, importable package. install( - FILES "${Halide_Python_SOURCE_DIR}/src/halide/__init__.py" + FILES "${Halide_Python_SOURCE_DIR}/halide/src/__init__.py" DESTINATION "${Halide_INSTALL_PYTHONDIR}" COMPONENT Halide_PythonRuntime ) install( - DIRECTORY "${Halide_Python_SOURCE_DIR}/src/halide/runtime/" + DIRECTORY "${Halide_Python_SOURCE_DIR}/halide-runtime/src/halide/runtime/" DESTINATION "${Halide_INSTALL_PYTHONDIR}/runtime" COMPONENT Halide_PythonRuntime FILES_MATCHING @@ -26,7 +26,7 @@ if (WITH_PYTHON_BINDINGS) # The remaining (compiler-side) Python sources. install( - DIRECTORY "${Halide_Python_SOURCE_DIR}/src/halide/" + DIRECTORY "${Halide_Python_SOURCE_DIR}/halide/src/" DESTINATION "${Halide_INSTALL_PYTHONDIR}" COMPONENT Halide_Python FILES_MATCHING @@ -124,5 +124,7 @@ endif () ## if (SKBUILD) - add_subdirectory(pip) + add_subdirectory( + "${Halide_Python_SOURCE_DIR}/halide/packaging/cmake" "${CMAKE_CURRENT_BINARY_DIR}/pip" + ) endif () diff --git a/python_bindings/packaging/Halide_PythonConfig.cmake.in b/python_bindings/halide/packaging/Halide_PythonConfig.cmake.in similarity index 100% rename from python_bindings/packaging/Halide_PythonConfig.cmake.in rename to python_bindings/halide/packaging/Halide_PythonConfig.cmake.in diff --git a/python_bindings/packaging/pip/CMakeLists.txt b/python_bindings/halide/packaging/cmake/CMakeLists.txt similarity index 91% rename from python_bindings/packaging/pip/CMakeLists.txt rename to python_bindings/halide/packaging/cmake/CMakeLists.txt index 990039edf953..6f97cd5678af 100644 --- a/python_bindings/packaging/pip/CMakeLists.txt +++ b/python_bindings/halide/packaging/cmake/CMakeLists.txt @@ -1,7 +1,7 @@ ## # Create a trampoline to the real Halide_PythonConfig.cmake. # -# Same trick as packaging/pip/CMakeLists.txt in the root project: the wheel +# Same trick as the halide-bin CMake trampoline: the wheel # directory gets grafted to one of an unpredictable set of paths determined # by sysconfig, so this trampoline finds platlib via sysconfig before jumping # to the real Halide_PythonConfig.cmake inside the halide package. diff --git a/python_bindings/packaging/pip/TrampolineConfig.cmake.in b/python_bindings/halide/packaging/cmake/TrampolineConfig.cmake.in similarity index 100% rename from python_bindings/packaging/pip/TrampolineConfig.cmake.in rename to python_bindings/halide/packaging/cmake/TrampolineConfig.cmake.in diff --git a/python_bindings/halide/pyproject.toml b/python_bindings/halide/pyproject.toml new file mode 100644 index 000000000000..9cd9f396e817 --- /dev/null +++ b/python_bindings/halide/pyproject.toml @@ -0,0 +1,190 @@ +[build-system] +requires = [ + "pybind11>=2.11.1", + "scikit-build-core>=1.0.3", + "setuptools-scm>=8.3.1", +] +build-backend = "scikit_build_core.build" + +[project] +name = "halide" +authors = [ + { name = "The Halide team", email = "halide-dev@lists.csail.mit.edu" }, +] +maintainers = [{ name = "Alex Reinking", email = "areinking@adobe.com" }] +description = "Halide is a programming language designed to make it easier to write high-performance image and array processing code." +license = "MIT" +readme = "README.md" +requires-python = ">=3.10" +dynamic = ['version', 'dependencies'] +dependencies = [ + "imageio>=2", + "pillow; platform_machine == 'armv8l' or platform_machine == 'armv7l'", +] +keywords = [ + "array", + "compiler", + "domain-specific language", + "dsl", + "gpu", + "hexagon", + "image processing", + "machine learning", + "performance", + "programming language", +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: GPU", + "Environment :: GPU :: NVIDIA CUDA", + "Environment :: WebAssembly", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Natural Language :: English", + "Operating System :: MacOS", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Programming Language :: C++", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: Implementation :: CPython", + "Topic :: Multimedia :: Graphics", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Artificial Intelligence", + "Topic :: Scientific/Engineering :: Image Processing", + "Topic :: Software Development :: Code Generators", + "Topic :: Software Development :: Compilers", + "Topic :: Software Development :: Libraries", +] + +[project.urls] +Homepage = "https://halide-lang.org" +Documentation = "https://github.com/halide/Halide/blob/main/doc/Python.md" +"Documentation (C++)" = "https://halide-lang.org/docs" +Issues = "https://github.com/halide/Halide/issues" +Repository = "https://github.com/halide/Halide.git" + +[[tool.dynamic-metadata]] +provider = "scikit_build_core.metadata.setuptools_scm" + +[[tool.dynamic-metadata]] +provider = { path = ".", module = "_dynamic_metadata" } + +[tool.scikit-build] +minimum-version = "build-system.requires" +cmake.version = ">=3.28" +ninja.version = ">=1.11,!=1.13.0" +cmake.source-dir = ".." +build.targets = ["Halide_Python"] +install.components = ["Halide_Python"] +wheel.install-dir = "halide" +sdist.inclusion-mode = "explicit" +sdist.include = ["pyproject.toml", "README.md", "_dynamic_metadata.py"] +sdist.exclude = ["dependencies/update-*.sh"] + +[tool.scikit-build.sdist.force-include] +"../../cmake" = "cmake" +"../../dependencies" = "dependencies" +"../../packaging" = "packaging" +"../../python_bindings" = "python_bindings" +"../../src" = "src" +"../../tools" = "tools" +"../../.git_archival.txt" = ".git_archival.txt" +"../../CMakeLists.txt" = "CMakeLists.txt" +"../../LICENSE.txt" = "LICENSE.txt" +"../../vcpkg.json" = "vcpkg.json" +"../../vcpkg-configuration.json" = "vcpkg-configuration.json" + +[tool.scikit-build.cmake.define] +CMAKE_DISABLE_FIND_PACKAGE_JPEG = true +CMAKE_DISABLE_FIND_PACKAGE_PNG = true +Halide_ENABLE_EXCEPTIONS = true +Halide_ENABLE_RTTI = true +Halide_INSTALL_PYTHONDIR = "." +Halide_WASM_BACKEND = "wabt" +WITH_PYTHON_BINDINGS = true +WITH_PYTHON_STUBS = false +WITH_TESTS = false +WITH_TUTORIALS = false +WITH_UTILS = false + +## +# Don't version libHalide.so/dylib -- wheels are zip files that do +# not understand symbolic links. Including version information here +# causes the final wheel to have three copies of our library. Not good. +CMAKE_PLATFORM_NO_VERSIONED_SONAME = true + +[[tool.scikit-build.overrides]] +if.platform-system = "^win32" +inherit.cmake.define = "append" +cmake.define.Halide_WASM_BACKEND = "OFF" + +[[tool.scikit-build.overrides]] +if.from-sdist = true +cmake.source-dir = "python_bindings" + +[tool.setuptools_scm] +root = "../.." + +[tool.ruff.lint] +# docs: https://docs.astral.sh/ruff/rules/ +select = [ + "E4", # pycodestyle / import statements + "E7", # pycodestyle / superfluous or misused syntax + "E9", # pycodestyle / internal error (odd this can be disabled) + "F", # pyflakes + "FURB", # refurb / rules for upgrading old Python usage + "PERF", # perflint / rules for performance pitfalls + "RUF", # Ruff-specific rules + "SIM", # flake8 / simplify + "UP", # pyupgrade / detect uses of old Python features +] +ignore = [ + "UP045", # Don't replace Optional[T] with T | None + "SIM108", # Don't replace an if statement with ternary +] + +[tool.tbump] +github_url = "https://github.com/halide/Halide/" + +[tool.tbump.version] +current = "22.0.0" +regex = '(?P\d+)\.(?P\d+)\.(?P\d+)' + +[tool.tbump.git] +message_template = "Bump version to {new_version}" +tag_template = "v{new_version}.dev0" + +[[tool.tbump.file]] +src = "CMakeLists.txt" +search = "VERSION {current_version}" + +[[tool.tbump.file]] +src = "python_bindings/CMakeLists.txt" +search = "VERSION {current_version}" + +[[tool.tbump.file]] +src = "vcpkg.json" + +[[tool.tbump.file]] +src = "apps/vcpkg.json" + +[[tool.tbump.file]] +src = "src/runtime/HalideRuntime.h" +version_template = "{major}" +search = "#define HALIDE_VERSION_MAJOR {current_version}" + +[[tool.tbump.file]] +src = "src/runtime/HalideRuntime.h" +version_template = "{minor}" +search = "#define HALIDE_VERSION_MINOR {current_version}" + +[[tool.tbump.file]] +src = "src/runtime/HalideRuntime.h" +version_template = "{patch}" +search = "#define HALIDE_VERSION_PATCH {current_version}" diff --git a/python_bindings/src/halide/CMakeLists.txt b/python_bindings/halide/src/CMakeLists.txt similarity index 97% rename from python_bindings/src/halide/CMakeLists.txt rename to python_bindings/halide/src/CMakeLists.txt index e3a7c6819f30..138625bbf149 100644 --- a/python_bindings/src/halide/CMakeLists.txt +++ b/python_bindings/halide/src/CMakeLists.txt @@ -87,6 +87,3 @@ add_custom_command( add_custom_target(Halide_Python_sources DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${stamp_file}") add_dependencies(Halide_Python Halide_Python_sources) - -# The standalone `halide.runtime` submodule (links only Halide::Runtime). -add_subdirectory(runtime) diff --git a/python_bindings/src/halide/__init__.py b/python_bindings/halide/src/__init__.py similarity index 70% rename from python_bindings/src/halide/__init__.py rename to python_bindings/halide/src/__init__.py index c9ae1430dc61..ee3ea64340e2 100644 --- a/python_bindings/src/halide/__init__.py +++ b/python_bindings/halide/src/__init__.py @@ -1,50 +1,7 @@ -def _halide_install_dir(): - # `halide-bin` is only present when this package was built in split mode - # (see pyproject.toml's HALIDE_SPLIT_BUILD override); a plain, monolithic - # build has no such dependency and bundles everything under this package's - # own directory instead, exactly as before the split. - try: - import halide_bin - except ImportError: - import os - - return os.path.dirname(__file__) - else: - return halide_bin.install_dir() - - -def _preload_bundled_halide_library(): - # Force-load our own copy of the Halide runtime library by absolute path before - # importing halide_, so that halide_'s implicit load of the same library (by - # soname/module name) resolves to this already-loaded instance instead of - # searching LD_LIBRARY_PATH / PATH / the default dynamic linker paths, where a - # foreign, incompatible libHalide could shadow ours. - # See: https://github.com/halide/Halide/issues/8866 - import ctypes - import os - - from pathlib import Path - - root = Path(_halide_install_dir()) - - bin_dir = root / "bin" - if hasattr(os, "add_dll_directory") and bin_dir.is_dir(): - os.add_dll_directory(str(bin_dir)) - - for relpath in ( - "bin/Halide.dll", - "lib/libHalide.dylib", - "lib64/libHalide.so", - "lib/libHalide.so", - ): - lib_path = root / relpath - if lib_path.exists(): - ctypes.CDLL(str(lib_path)) - return - - def install_dir(): - return _halide_install_dir() + from . import bin + + return bin.install_dir() # --------------------------------------------------------------------------- @@ -111,7 +68,11 @@ def _load_compiler(): return _compiler_loading = True try: - _preload_bundled_halide_library() + # halide-bin owns library discovery and loads its bundled libHalide at + # import time, making the binary package the single authority. + from importlib import import_module + + import_module(".bin", __name__) try: from . import halide_ diff --git a/python_bindings/src/halide/_generator_helpers.py b/python_bindings/halide/src/_generator_helpers.py similarity index 100% rename from python_bindings/src/halide/_generator_helpers.py rename to python_bindings/halide/src/_generator_helpers.py diff --git a/python_bindings/src/halide/halide_/PyArgument.cpp b/python_bindings/halide/src/halide_/PyArgument.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyArgument.cpp rename to python_bindings/halide/src/halide_/PyArgument.cpp diff --git a/python_bindings/src/halide/halide_/PyArgument.h b/python_bindings/halide/src/halide_/PyArgument.h similarity index 100% rename from python_bindings/src/halide/halide_/PyArgument.h rename to python_bindings/halide/src/halide_/PyArgument.h diff --git a/python_bindings/src/halide/halide_/PyBinaryOperators.h b/python_bindings/halide/src/halide_/PyBinaryOperators.h similarity index 100% rename from python_bindings/src/halide/halide_/PyBinaryOperators.h rename to python_bindings/halide/src/halide_/PyBinaryOperators.h diff --git a/python_bindings/src/halide/halide_/PyBoundaryConditions.cpp b/python_bindings/halide/src/halide_/PyBoundaryConditions.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyBoundaryConditions.cpp rename to python_bindings/halide/src/halide_/PyBoundaryConditions.cpp diff --git a/python_bindings/src/halide/halide_/PyBoundaryConditions.h b/python_bindings/halide/src/halide_/PyBoundaryConditions.h similarity index 100% rename from python_bindings/src/halide/halide_/PyBoundaryConditions.h rename to python_bindings/halide/src/halide_/PyBoundaryConditions.h diff --git a/python_bindings/src/halide/halide_/PyBuffer.cpp b/python_bindings/halide/src/halide_/PyBuffer.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyBuffer.cpp rename to python_bindings/halide/src/halide_/PyBuffer.cpp diff --git a/python_bindings/src/halide/halide_/PyBuffer.h b/python_bindings/halide/src/halide_/PyBuffer.h similarity index 100% rename from python_bindings/src/halide/halide_/PyBuffer.h rename to python_bindings/halide/src/halide_/PyBuffer.h diff --git a/python_bindings/src/halide/halide_/PyCallable.cpp b/python_bindings/halide/src/halide_/PyCallable.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyCallable.cpp rename to python_bindings/halide/src/halide_/PyCallable.cpp diff --git a/python_bindings/src/halide/halide_/PyCallable.h b/python_bindings/halide/src/halide_/PyCallable.h similarity index 100% rename from python_bindings/src/halide/halide_/PyCallable.h rename to python_bindings/halide/src/halide_/PyCallable.h diff --git a/python_bindings/src/halide/halide_/PyConciseCasts.cpp b/python_bindings/halide/src/halide_/PyConciseCasts.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyConciseCasts.cpp rename to python_bindings/halide/src/halide_/PyConciseCasts.cpp diff --git a/python_bindings/src/halide/halide_/PyConciseCasts.h b/python_bindings/halide/src/halide_/PyConciseCasts.h similarity index 100% rename from python_bindings/src/halide/halide_/PyConciseCasts.h rename to python_bindings/halide/src/halide_/PyConciseCasts.h diff --git a/python_bindings/src/halide/halide_/PyDerivative.cpp b/python_bindings/halide/src/halide_/PyDerivative.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyDerivative.cpp rename to python_bindings/halide/src/halide_/PyDerivative.cpp diff --git a/python_bindings/src/halide/halide_/PyDerivative.h b/python_bindings/halide/src/halide_/PyDerivative.h similarity index 100% rename from python_bindings/src/halide/halide_/PyDerivative.h rename to python_bindings/halide/src/halide_/PyDerivative.h diff --git a/python_bindings/src/halide/halide_/PyEnums.cpp b/python_bindings/halide/src/halide_/PyEnums.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyEnums.cpp rename to python_bindings/halide/src/halide_/PyEnums.cpp diff --git a/python_bindings/src/halide/halide_/PyEnums.h b/python_bindings/halide/src/halide_/PyEnums.h similarity index 100% rename from python_bindings/src/halide/halide_/PyEnums.h rename to python_bindings/halide/src/halide_/PyEnums.h diff --git a/python_bindings/src/halide/halide_/PyError.cpp b/python_bindings/halide/src/halide_/PyError.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyError.cpp rename to python_bindings/halide/src/halide_/PyError.cpp diff --git a/python_bindings/src/halide/halide_/PyError.h b/python_bindings/halide/src/halide_/PyError.h similarity index 100% rename from python_bindings/src/halide/halide_/PyError.h rename to python_bindings/halide/src/halide_/PyError.h diff --git a/python_bindings/src/halide/halide_/PyExpr.cpp b/python_bindings/halide/src/halide_/PyExpr.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyExpr.cpp rename to python_bindings/halide/src/halide_/PyExpr.cpp diff --git a/python_bindings/src/halide/halide_/PyExpr.h b/python_bindings/halide/src/halide_/PyExpr.h similarity index 100% rename from python_bindings/src/halide/halide_/PyExpr.h rename to python_bindings/halide/src/halide_/PyExpr.h diff --git a/python_bindings/src/halide/halide_/PyExternFuncArgument.cpp b/python_bindings/halide/src/halide_/PyExternFuncArgument.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyExternFuncArgument.cpp rename to python_bindings/halide/src/halide_/PyExternFuncArgument.cpp diff --git a/python_bindings/src/halide/halide_/PyExternFuncArgument.h b/python_bindings/halide/src/halide_/PyExternFuncArgument.h similarity index 100% rename from python_bindings/src/halide/halide_/PyExternFuncArgument.h rename to python_bindings/halide/src/halide_/PyExternFuncArgument.h diff --git a/python_bindings/src/halide/halide_/PyFunc.cpp b/python_bindings/halide/src/halide_/PyFunc.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyFunc.cpp rename to python_bindings/halide/src/halide_/PyFunc.cpp diff --git a/python_bindings/src/halide/halide_/PyFunc.h b/python_bindings/halide/src/halide_/PyFunc.h similarity index 100% rename from python_bindings/src/halide/halide_/PyFunc.h rename to python_bindings/halide/src/halide_/PyFunc.h diff --git a/python_bindings/src/halide/halide_/PyFuncRef.cpp b/python_bindings/halide/src/halide_/PyFuncRef.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyFuncRef.cpp rename to python_bindings/halide/src/halide_/PyFuncRef.cpp diff --git a/python_bindings/src/halide/halide_/PyFuncRef.h b/python_bindings/halide/src/halide_/PyFuncRef.h similarity index 100% rename from python_bindings/src/halide/halide_/PyFuncRef.h rename to python_bindings/halide/src/halide_/PyFuncRef.h diff --git a/python_bindings/src/halide/halide_/PyGenerator.cpp b/python_bindings/halide/src/halide_/PyGenerator.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyGenerator.cpp rename to python_bindings/halide/src/halide_/PyGenerator.cpp diff --git a/python_bindings/src/halide/halide_/PyGenerator.h b/python_bindings/halide/src/halide_/PyGenerator.h similarity index 100% rename from python_bindings/src/halide/halide_/PyGenerator.h rename to python_bindings/halide/src/halide_/PyGenerator.h diff --git a/python_bindings/src/halide/halide_/PyHalide.cpp b/python_bindings/halide/src/halide_/PyHalide.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyHalide.cpp rename to python_bindings/halide/src/halide_/PyHalide.cpp diff --git a/python_bindings/src/halide/halide_/PyHalide.h b/python_bindings/halide/src/halide_/PyHalide.h similarity index 100% rename from python_bindings/src/halide/halide_/PyHalide.h rename to python_bindings/halide/src/halide_/PyHalide.h diff --git a/python_bindings/src/halide/halide_/PyIROperator.cpp b/python_bindings/halide/src/halide_/PyIROperator.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyIROperator.cpp rename to python_bindings/halide/src/halide_/PyIROperator.cpp diff --git a/python_bindings/src/halide/halide_/PyIROperator.h b/python_bindings/halide/src/halide_/PyIROperator.h similarity index 100% rename from python_bindings/src/halide/halide_/PyIROperator.h rename to python_bindings/halide/src/halide_/PyIROperator.h diff --git a/python_bindings/src/halide/halide_/PyImageParam.cpp b/python_bindings/halide/src/halide_/PyImageParam.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyImageParam.cpp rename to python_bindings/halide/src/halide_/PyImageParam.cpp diff --git a/python_bindings/src/halide/halide_/PyImageParam.h b/python_bindings/halide/src/halide_/PyImageParam.h similarity index 100% rename from python_bindings/src/halide/halide_/PyImageParam.h rename to python_bindings/halide/src/halide_/PyImageParam.h diff --git a/python_bindings/src/halide/halide_/PyInlineReductions.cpp b/python_bindings/halide/src/halide_/PyInlineReductions.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyInlineReductions.cpp rename to python_bindings/halide/src/halide_/PyInlineReductions.cpp diff --git a/python_bindings/src/halide/halide_/PyInlineReductions.h b/python_bindings/halide/src/halide_/PyInlineReductions.h similarity index 100% rename from python_bindings/src/halide/halide_/PyInlineReductions.h rename to python_bindings/halide/src/halide_/PyInlineReductions.h diff --git a/python_bindings/src/halide/halide_/PyLambda.cpp b/python_bindings/halide/src/halide_/PyLambda.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyLambda.cpp rename to python_bindings/halide/src/halide_/PyLambda.cpp diff --git a/python_bindings/src/halide/halide_/PyLambda.h b/python_bindings/halide/src/halide_/PyLambda.h similarity index 100% rename from python_bindings/src/halide/halide_/PyLambda.h rename to python_bindings/halide/src/halide_/PyLambda.h diff --git a/python_bindings/src/halide/halide_/PyLoopLevel.cpp b/python_bindings/halide/src/halide_/PyLoopLevel.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyLoopLevel.cpp rename to python_bindings/halide/src/halide_/PyLoopLevel.cpp diff --git a/python_bindings/src/halide/halide_/PyLoopLevel.h b/python_bindings/halide/src/halide_/PyLoopLevel.h similarity index 100% rename from python_bindings/src/halide/halide_/PyLoopLevel.h rename to python_bindings/halide/src/halide_/PyLoopLevel.h diff --git a/python_bindings/src/halide/halide_/PyModule.cpp b/python_bindings/halide/src/halide_/PyModule.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyModule.cpp rename to python_bindings/halide/src/halide_/PyModule.cpp diff --git a/python_bindings/src/halide/halide_/PyModule.h b/python_bindings/halide/src/halide_/PyModule.h similarity index 100% rename from python_bindings/src/halide/halide_/PyModule.h rename to python_bindings/halide/src/halide_/PyModule.h diff --git a/python_bindings/src/halide/halide_/PyParam.cpp b/python_bindings/halide/src/halide_/PyParam.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyParam.cpp rename to python_bindings/halide/src/halide_/PyParam.cpp diff --git a/python_bindings/src/halide/halide_/PyParam.h b/python_bindings/halide/src/halide_/PyParam.h similarity index 100% rename from python_bindings/src/halide/halide_/PyParam.h rename to python_bindings/halide/src/halide_/PyParam.h diff --git a/python_bindings/src/halide/halide_/PyParameter.cpp b/python_bindings/halide/src/halide_/PyParameter.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyParameter.cpp rename to python_bindings/halide/src/halide_/PyParameter.cpp diff --git a/python_bindings/src/halide/halide_/PyParameter.h b/python_bindings/halide/src/halide_/PyParameter.h similarity index 100% rename from python_bindings/src/halide/halide_/PyParameter.h rename to python_bindings/halide/src/halide_/PyParameter.h diff --git a/python_bindings/src/halide/halide_/PyPipeline.cpp b/python_bindings/halide/src/halide_/PyPipeline.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyPipeline.cpp rename to python_bindings/halide/src/halide_/PyPipeline.cpp diff --git a/python_bindings/src/halide/halide_/PyPipeline.h b/python_bindings/halide/src/halide_/PyPipeline.h similarity index 100% rename from python_bindings/src/halide/halide_/PyPipeline.h rename to python_bindings/halide/src/halide_/PyPipeline.h diff --git a/python_bindings/src/halide/halide_/PyRDom.cpp b/python_bindings/halide/src/halide_/PyRDom.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyRDom.cpp rename to python_bindings/halide/src/halide_/PyRDom.cpp diff --git a/python_bindings/src/halide/halide_/PyRDom.h b/python_bindings/halide/src/halide_/PyRDom.h similarity index 100% rename from python_bindings/src/halide/halide_/PyRDom.h rename to python_bindings/halide/src/halide_/PyRDom.h diff --git a/python_bindings/src/halide/halide_/PyScheduleMethods.h b/python_bindings/halide/src/halide_/PyScheduleMethods.h similarity index 100% rename from python_bindings/src/halide/halide_/PyScheduleMethods.h rename to python_bindings/halide/src/halide_/PyScheduleMethods.h diff --git a/python_bindings/src/halide/halide_/PySerialization.cpp b/python_bindings/halide/src/halide_/PySerialization.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PySerialization.cpp rename to python_bindings/halide/src/halide_/PySerialization.cpp diff --git a/python_bindings/src/halide/halide_/PySerialization.h b/python_bindings/halide/src/halide_/PySerialization.h similarity index 100% rename from python_bindings/src/halide/halide_/PySerialization.h rename to python_bindings/halide/src/halide_/PySerialization.h diff --git a/python_bindings/src/halide/halide_/PyStage.cpp b/python_bindings/halide/src/halide_/PyStage.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyStage.cpp rename to python_bindings/halide/src/halide_/PyStage.cpp diff --git a/python_bindings/src/halide/halide_/PyStage.h b/python_bindings/halide/src/halide_/PyStage.h similarity index 100% rename from python_bindings/src/halide/halide_/PyStage.h rename to python_bindings/halide/src/halide_/PyStage.h diff --git a/python_bindings/src/halide/halide_/PyTarget.cpp b/python_bindings/halide/src/halide_/PyTarget.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyTarget.cpp rename to python_bindings/halide/src/halide_/PyTarget.cpp diff --git a/python_bindings/src/halide/halide_/PyTarget.h b/python_bindings/halide/src/halide_/PyTarget.h similarity index 100% rename from python_bindings/src/halide/halide_/PyTarget.h rename to python_bindings/halide/src/halide_/PyTarget.h diff --git a/python_bindings/src/halide/halide_/PyTuple.cpp b/python_bindings/halide/src/halide_/PyTuple.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyTuple.cpp rename to python_bindings/halide/src/halide_/PyTuple.cpp diff --git a/python_bindings/src/halide/halide_/PyTuple.h b/python_bindings/halide/src/halide_/PyTuple.h similarity index 100% rename from python_bindings/src/halide/halide_/PyTuple.h rename to python_bindings/halide/src/halide_/PyTuple.h diff --git a/python_bindings/src/halide/halide_/PyType.cpp b/python_bindings/halide/src/halide_/PyType.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyType.cpp rename to python_bindings/halide/src/halide_/PyType.cpp diff --git a/python_bindings/src/halide/halide_/PyType.h b/python_bindings/halide/src/halide_/PyType.h similarity index 100% rename from python_bindings/src/halide/halide_/PyType.h rename to python_bindings/halide/src/halide_/PyType.h diff --git a/python_bindings/src/halide/halide_/PyVar.cpp b/python_bindings/halide/src/halide_/PyVar.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyVar.cpp rename to python_bindings/halide/src/halide_/PyVar.cpp diff --git a/python_bindings/src/halide/halide_/PyVar.h b/python_bindings/halide/src/halide_/PyVar.h similarity index 100% rename from python_bindings/src/halide/halide_/PyVar.h rename to python_bindings/halide/src/halide_/PyVar.h diff --git a/python_bindings/src/halide/halide_/PyVarOrRVar.cpp b/python_bindings/halide/src/halide_/PyVarOrRVar.cpp similarity index 100% rename from python_bindings/src/halide/halide_/PyVarOrRVar.cpp rename to python_bindings/halide/src/halide_/PyVarOrRVar.cpp diff --git a/python_bindings/src/halide/halide_/PyVarOrRVar.h b/python_bindings/halide/src/halide_/PyVarOrRVar.h similarity index 100% rename from python_bindings/src/halide/halide_/PyVarOrRVar.h rename to python_bindings/halide/src/halide_/PyVarOrRVar.h diff --git a/python_bindings/src/halide/imageio.py b/python_bindings/halide/src/imageio.py similarity index 100% rename from python_bindings/src/halide/imageio.py rename to python_bindings/halide/src/imageio.py diff --git a/python_bindings/stub/CMakeLists.txt b/python_bindings/halide/stub/CMakeLists.txt similarity index 100% rename from python_bindings/stub/CMakeLists.txt rename to python_bindings/halide/stub/CMakeLists.txt diff --git a/python_bindings/stub/PyStubImpl.cpp b/python_bindings/halide/stub/PyStubImpl.cpp similarity index 100% rename from python_bindings/stub/PyStubImpl.cpp rename to python_bindings/halide/stub/PyStubImpl.cpp diff --git a/python_bindings/test/CMakeLists.txt b/python_bindings/halide/test/CMakeLists.txt similarity index 100% rename from python_bindings/test/CMakeLists.txt rename to python_bindings/halide/test/CMakeLists.txt diff --git a/python_bindings/test/correctness/CMakeLists.txt b/python_bindings/halide/test/correctness/CMakeLists.txt similarity index 100% rename from python_bindings/test/correctness/CMakeLists.txt rename to python_bindings/halide/test/correctness/CMakeLists.txt diff --git a/python_bindings/test/correctness/addconstant_test.py b/python_bindings/halide/test/correctness/addconstant_test.py similarity index 100% rename from python_bindings/test/correctness/addconstant_test.py rename to python_bindings/halide/test/correctness/addconstant_test.py diff --git a/python_bindings/test/correctness/atomics.py b/python_bindings/halide/test/correctness/atomics.py similarity index 100% rename from python_bindings/test/correctness/atomics.py rename to python_bindings/halide/test/correctness/atomics.py diff --git a/python_bindings/test/correctness/autodiff.py b/python_bindings/halide/test/correctness/autodiff.py similarity index 100% rename from python_bindings/test/correctness/autodiff.py rename to python_bindings/halide/test/correctness/autodiff.py diff --git a/python_bindings/test/correctness/basics.py b/python_bindings/halide/test/correctness/basics.py similarity index 100% rename from python_bindings/test/correctness/basics.py rename to python_bindings/halide/test/correctness/basics.py diff --git a/python_bindings/test/correctness/bit_test.py b/python_bindings/halide/test/correctness/bit_test.py similarity index 100% rename from python_bindings/test/correctness/bit_test.py rename to python_bindings/halide/test/correctness/bit_test.py diff --git a/python_bindings/test/correctness/boundary_conditions.py b/python_bindings/halide/test/correctness/boundary_conditions.py similarity index 100% rename from python_bindings/test/correctness/boundary_conditions.py rename to python_bindings/halide/test/correctness/boundary_conditions.py diff --git a/python_bindings/test/correctness/buffer.py b/python_bindings/halide/test/correctness/buffer.py similarity index 100% rename from python_bindings/test/correctness/buffer.py rename to python_bindings/halide/test/correctness/buffer.py diff --git a/python_bindings/test/correctness/callable.py b/python_bindings/halide/test/correctness/callable.py similarity index 100% rename from python_bindings/test/correctness/callable.py rename to python_bindings/halide/test/correctness/callable.py diff --git a/python_bindings/test/correctness/compile_to.py b/python_bindings/halide/test/correctness/compile_to.py similarity index 100% rename from python_bindings/test/correctness/compile_to.py rename to python_bindings/halide/test/correctness/compile_to.py diff --git a/python_bindings/test/correctness/division.py b/python_bindings/halide/test/correctness/division.py similarity index 100% rename from python_bindings/test/correctness/division.py rename to python_bindings/halide/test/correctness/division.py diff --git a/python_bindings/test/correctness/extern.py b/python_bindings/halide/test/correctness/extern.py similarity index 100% rename from python_bindings/test/correctness/extern.py rename to python_bindings/halide/test/correctness/extern.py diff --git a/python_bindings/test/correctness/float_precision_test.py b/python_bindings/halide/test/correctness/float_precision_test.py similarity index 100% rename from python_bindings/test/correctness/float_precision_test.py rename to python_bindings/halide/test/correctness/float_precision_test.py diff --git a/python_bindings/test/correctness/iroperator.py b/python_bindings/halide/test/correctness/iroperator.py similarity index 100% rename from python_bindings/test/correctness/iroperator.py rename to python_bindings/halide/test/correctness/iroperator.py diff --git a/python_bindings/test/correctness/memoize.py b/python_bindings/halide/test/correctness/memoize.py similarity index 100% rename from python_bindings/test/correctness/memoize.py rename to python_bindings/halide/test/correctness/memoize.py diff --git a/python_bindings/test/correctness/multi_method_module_test.py b/python_bindings/halide/test/correctness/multi_method_module_test.py similarity index 100% rename from python_bindings/test/correctness/multi_method_module_test.py rename to python_bindings/halide/test/correctness/multi_method_module_test.py diff --git a/python_bindings/test/correctness/multipass_constraints.py b/python_bindings/halide/test/correctness/multipass_constraints.py similarity index 100% rename from python_bindings/test/correctness/multipass_constraints.py rename to python_bindings/halide/test/correctness/multipass_constraints.py diff --git a/python_bindings/test/correctness/negate_test.py b/python_bindings/halide/test/correctness/negate_test.py similarity index 100% rename from python_bindings/test/correctness/negate_test.py rename to python_bindings/halide/test/correctness/negate_test.py diff --git a/python_bindings/test/correctness/pystub.py b/python_bindings/halide/test/correctness/pystub.py similarity index 100% rename from python_bindings/test/correctness/pystub.py rename to python_bindings/halide/test/correctness/pystub.py diff --git a/python_bindings/test/correctness/rdom.py b/python_bindings/halide/test/correctness/rdom.py similarity index 100% rename from python_bindings/test/correctness/rdom.py rename to python_bindings/halide/test/correctness/rdom.py diff --git a/python_bindings/test/correctness/realize_warnings.py b/python_bindings/halide/test/correctness/realize_warnings.py similarity index 100% rename from python_bindings/test/correctness/realize_warnings.py rename to python_bindings/halide/test/correctness/realize_warnings.py diff --git a/python_bindings/test/correctness/runtime_prefixes.py b/python_bindings/halide/test/correctness/runtime_prefixes.py similarity index 100% rename from python_bindings/test/correctness/runtime_prefixes.py rename to python_bindings/halide/test/correctness/runtime_prefixes.py diff --git a/python_bindings/test/correctness/serialization.py b/python_bindings/halide/test/correctness/serialization.py similarity index 100% rename from python_bindings/test/correctness/serialization.py rename to python_bindings/halide/test/correctness/serialization.py diff --git a/python_bindings/test/correctness/target.py b/python_bindings/halide/test/correctness/target.py similarity index 100% rename from python_bindings/test/correctness/target.py rename to python_bindings/halide/test/correctness/target.py diff --git a/python_bindings/test/correctness/the_sort_function.c b/python_bindings/halide/test/correctness/the_sort_function.c similarity index 100% rename from python_bindings/test/correctness/the_sort_function.c rename to python_bindings/halide/test/correctness/the_sort_function.c diff --git a/python_bindings/test/correctness/tuple_select.py b/python_bindings/halide/test/correctness/tuple_select.py similarity index 100% rename from python_bindings/test/correctness/tuple_select.py rename to python_bindings/halide/test/correctness/tuple_select.py diff --git a/python_bindings/test/correctness/type.py b/python_bindings/halide/test/correctness/type.py similarity index 100% rename from python_bindings/test/correctness/type.py rename to python_bindings/halide/test/correctness/type.py diff --git a/python_bindings/test/correctness/user_context_test.py b/python_bindings/halide/test/correctness/user_context_test.py similarity index 100% rename from python_bindings/test/correctness/user_context_test.py rename to python_bindings/halide/test/correctness/user_context_test.py diff --git a/python_bindings/test/correctness/var.py b/python_bindings/halide/test/correctness/var.py similarity index 100% rename from python_bindings/test/correctness/var.py rename to python_bindings/halide/test/correctness/var.py diff --git a/python_bindings/test/generators/CMakeLists.txt b/python_bindings/halide/test/generators/CMakeLists.txt similarity index 100% rename from python_bindings/test/generators/CMakeLists.txt rename to python_bindings/halide/test/generators/CMakeLists.txt diff --git a/python_bindings/test/generators/addconstantcpp_generator.cpp b/python_bindings/halide/test/generators/addconstantcpp_generator.cpp similarity index 100% rename from python_bindings/test/generators/addconstantcpp_generator.cpp rename to python_bindings/halide/test/generators/addconstantcpp_generator.cpp diff --git a/python_bindings/test/generators/addconstantpy_generator.py b/python_bindings/halide/test/generators/addconstantpy_generator.py similarity index 100% rename from python_bindings/test/generators/addconstantpy_generator.py rename to python_bindings/halide/test/generators/addconstantpy_generator.py diff --git a/python_bindings/test/generators/bitcpp_generator.cpp b/python_bindings/halide/test/generators/bitcpp_generator.cpp similarity index 100% rename from python_bindings/test/generators/bitcpp_generator.cpp rename to python_bindings/halide/test/generators/bitcpp_generator.cpp diff --git a/python_bindings/test/generators/bitpy_generator.py b/python_bindings/halide/test/generators/bitpy_generator.py similarity index 100% rename from python_bindings/test/generators/bitpy_generator.py rename to python_bindings/halide/test/generators/bitpy_generator.py diff --git a/python_bindings/test/generators/complexcpp_generator.cpp b/python_bindings/halide/test/generators/complexcpp_generator.cpp similarity index 100% rename from python_bindings/test/generators/complexcpp_generator.cpp rename to python_bindings/halide/test/generators/complexcpp_generator.cpp diff --git a/python_bindings/test/generators/complexpy_generator.py b/python_bindings/halide/test/generators/complexpy_generator.py similarity index 100% rename from python_bindings/test/generators/complexpy_generator.py rename to python_bindings/halide/test/generators/complexpy_generator.py diff --git a/python_bindings/test/generators/simplecpp_generator.cpp b/python_bindings/halide/test/generators/simplecpp_generator.cpp similarity index 100% rename from python_bindings/test/generators/simplecpp_generator.cpp rename to python_bindings/halide/test/generators/simplecpp_generator.cpp diff --git a/python_bindings/test/generators/simplepy_generator.py b/python_bindings/halide/test/generators/simplepy_generator.py similarity index 100% rename from python_bindings/test/generators/simplepy_generator.py rename to python_bindings/halide/test/generators/simplepy_generator.py diff --git a/python_bindings/test/generators/user_context_generator.cpp b/python_bindings/halide/test/generators/user_context_generator.cpp similarity index 100% rename from python_bindings/test/generators/user_context_generator.cpp rename to python_bindings/halide/test/generators/user_context_generator.cpp diff --git a/python_bindings/test/runtime/CMakeLists.txt b/python_bindings/halide/test/runtime/CMakeLists.txt similarity index 100% rename from python_bindings/test/runtime/CMakeLists.txt rename to python_bindings/halide/test/runtime/CMakeLists.txt diff --git a/python_bindings/test/runtime/aot_module_stub.c b/python_bindings/halide/test/runtime/aot_module_stub.c similarity index 100% rename from python_bindings/test/runtime/aot_module_stub.c rename to python_bindings/halide/test/runtime/aot_module_stub.c diff --git a/python_bindings/test/runtime/call_convention.py b/python_bindings/halide/test/runtime/call_convention.py similarity index 100% rename from python_bindings/test/runtime/call_convention.py rename to python_bindings/halide/test/runtime/call_convention.py diff --git a/python_bindings/test/runtime/callconv_generator.cpp b/python_bindings/halide/test/runtime/callconv_generator.cpp similarity index 100% rename from python_bindings/test/runtime/callconv_generator.cpp rename to python_bindings/halide/test/runtime/callconv_generator.cpp diff --git a/python_bindings/test/runtime/check_no_libhalide.cmake b/python_bindings/halide/test/runtime/check_no_libhalide.cmake similarity index 100% rename from python_bindings/test/runtime/check_no_libhalide.cmake rename to python_bindings/halide/test/runtime/check_no_libhalide.cmake diff --git a/python_bindings/test/runtime/gpu.py b/python_bindings/halide/test/runtime/gpu.py similarity index 100% rename from python_bindings/test/runtime/gpu.py rename to python_bindings/halide/test/runtime/gpu.py diff --git a/python_bindings/test/runtime/gpu_generator.cpp b/python_bindings/halide/test/runtime/gpu_generator.cpp similarity index 100% rename from python_bindings/test/runtime/gpu_generator.cpp rename to python_bindings/halide/test/runtime/gpu_generator.cpp diff --git a/python_bindings/test/runtime/load_aot.py b/python_bindings/halide/test/runtime/load_aot.py similarity index 100% rename from python_bindings/test/runtime/load_aot.py rename to python_bindings/halide/test/runtime/load_aot.py diff --git a/python_bindings/test/runtime/runtimeadd_generator.cpp b/python_bindings/halide/test/runtime/runtimeadd_generator.cpp similarity index 100% rename from python_bindings/test/runtime/runtimeadd_generator.cpp rename to python_bindings/halide/test/runtime/runtimeadd_generator.cpp diff --git a/python_bindings/tutorial/CMakeLists.txt b/python_bindings/halide/tutorial/CMakeLists.txt similarity index 100% rename from python_bindings/tutorial/CMakeLists.txt rename to python_bindings/halide/tutorial/CMakeLists.txt diff --git a/python_bindings/tutorial/lesson_01_basics.py b/python_bindings/halide/tutorial/lesson_01_basics.py similarity index 100% rename from python_bindings/tutorial/lesson_01_basics.py rename to python_bindings/halide/tutorial/lesson_01_basics.py diff --git a/python_bindings/tutorial/lesson_02_input_image.py b/python_bindings/halide/tutorial/lesson_02_input_image.py similarity index 100% rename from python_bindings/tutorial/lesson_02_input_image.py rename to python_bindings/halide/tutorial/lesson_02_input_image.py diff --git a/python_bindings/tutorial/lesson_03_debugging_1.py b/python_bindings/halide/tutorial/lesson_03_debugging_1.py similarity index 100% rename from python_bindings/tutorial/lesson_03_debugging_1.py rename to python_bindings/halide/tutorial/lesson_03_debugging_1.py diff --git a/python_bindings/tutorial/lesson_04_debugging_2.py b/python_bindings/halide/tutorial/lesson_04_debugging_2.py similarity index 100% rename from python_bindings/tutorial/lesson_04_debugging_2.py rename to python_bindings/halide/tutorial/lesson_04_debugging_2.py diff --git a/python_bindings/tutorial/lesson_05_scheduling_1.py b/python_bindings/halide/tutorial/lesson_05_scheduling_1.py similarity index 100% rename from python_bindings/tutorial/lesson_05_scheduling_1.py rename to python_bindings/halide/tutorial/lesson_05_scheduling_1.py diff --git a/python_bindings/tutorial/lesson_06_realizing_over_shifted_domains.py b/python_bindings/halide/tutorial/lesson_06_realizing_over_shifted_domains.py similarity index 100% rename from python_bindings/tutorial/lesson_06_realizing_over_shifted_domains.py rename to python_bindings/halide/tutorial/lesson_06_realizing_over_shifted_domains.py diff --git a/python_bindings/tutorial/lesson_07_multi_stage_pipelines.py b/python_bindings/halide/tutorial/lesson_07_multi_stage_pipelines.py similarity index 100% rename from python_bindings/tutorial/lesson_07_multi_stage_pipelines.py rename to python_bindings/halide/tutorial/lesson_07_multi_stage_pipelines.py diff --git a/python_bindings/tutorial/lesson_08_scheduling_2.py b/python_bindings/halide/tutorial/lesson_08_scheduling_2.py similarity index 100% rename from python_bindings/tutorial/lesson_08_scheduling_2.py rename to python_bindings/halide/tutorial/lesson_08_scheduling_2.py diff --git a/python_bindings/tutorial/lesson_09_update_definitions.py b/python_bindings/halide/tutorial/lesson_09_update_definitions.py similarity index 100% rename from python_bindings/tutorial/lesson_09_update_definitions.py rename to python_bindings/halide/tutorial/lesson_09_update_definitions.py diff --git a/python_bindings/tutorial/lesson_10_aot_compilation_generate.py b/python_bindings/halide/tutorial/lesson_10_aot_compilation_generate.py similarity index 100% rename from python_bindings/tutorial/lesson_10_aot_compilation_generate.py rename to python_bindings/halide/tutorial/lesson_10_aot_compilation_generate.py diff --git a/python_bindings/tutorial/lesson_10_aot_compilation_run.py b/python_bindings/halide/tutorial/lesson_10_aot_compilation_run.py similarity index 100% rename from python_bindings/tutorial/lesson_10_aot_compilation_run.py rename to python_bindings/halide/tutorial/lesson_10_aot_compilation_run.py diff --git a/python_bindings/tutorial/lesson_11_cross_compilation.py b/python_bindings/halide/tutorial/lesson_11_cross_compilation.py similarity index 100% rename from python_bindings/tutorial/lesson_11_cross_compilation.py rename to python_bindings/halide/tutorial/lesson_11_cross_compilation.py diff --git a/python_bindings/tutorial/lesson_12_using_the_gpu.py b/python_bindings/halide/tutorial/lesson_12_using_the_gpu.py similarity index 100% rename from python_bindings/tutorial/lesson_12_using_the_gpu.py rename to python_bindings/halide/tutorial/lesson_12_using_the_gpu.py diff --git a/python_bindings/tutorial/lesson_13_tuples.py b/python_bindings/halide/tutorial/lesson_13_tuples.py similarity index 100% rename from python_bindings/tutorial/lesson_13_tuples.py rename to python_bindings/halide/tutorial/lesson_13_tuples.py diff --git a/python_bindings/tutorial/lesson_14_types.py b/python_bindings/halide/tutorial/lesson_14_types.py similarity index 100% rename from python_bindings/tutorial/lesson_14_types.py rename to python_bindings/halide/tutorial/lesson_14_types.py diff --git a/python_bindings/tutorial/lesson_15_generators.py b/python_bindings/halide/tutorial/lesson_15_generators.py similarity index 100% rename from python_bindings/tutorial/lesson_15_generators.py rename to python_bindings/halide/tutorial/lesson_15_generators.py diff --git a/python_bindings/tutorial/lesson_15_runtime.py b/python_bindings/halide/tutorial/lesson_15_runtime.py similarity index 100% rename from python_bindings/tutorial/lesson_15_runtime.py rename to python_bindings/halide/tutorial/lesson_15_runtime.py diff --git a/python_bindings/tutorial/lesson_16_rgb_generate.py b/python_bindings/halide/tutorial/lesson_16_rgb_generate.py similarity index 100% rename from python_bindings/tutorial/lesson_16_rgb_generate.py rename to python_bindings/halide/tutorial/lesson_16_rgb_generate.py diff --git a/python_bindings/tutorial/lesson_16_rgb_run.py b/python_bindings/halide/tutorial/lesson_16_rgb_run.py similarity index 100% rename from python_bindings/tutorial/lesson_16_rgb_run.py rename to python_bindings/halide/tutorial/lesson_16_rgb_run.py diff --git a/python_bindings/tutorial/lesson_17_predicated_rdom.py b/python_bindings/halide/tutorial/lesson_17_predicated_rdom.py similarity index 100% rename from python_bindings/tutorial/lesson_17_predicated_rdom.py rename to python_bindings/halide/tutorial/lesson_17_predicated_rdom.py diff --git a/python_bindings/tutorial/lesson_18_parallel_associative_reductions.py b/python_bindings/halide/tutorial/lesson_18_parallel_associative_reductions.py similarity index 100% rename from python_bindings/tutorial/lesson_18_parallel_associative_reductions.py rename to python_bindings/halide/tutorial/lesson_18_parallel_associative_reductions.py diff --git a/python_bindings/tutorial/lesson_19_wrapper_funcs.py b/python_bindings/halide/tutorial/lesson_19_wrapper_funcs.py similarity index 100% rename from python_bindings/tutorial/lesson_19_wrapper_funcs.py rename to python_bindings/halide/tutorial/lesson_19_wrapper_funcs.py diff --git a/python_bindings/tutorial/lesson_20_cloning_funcs.py b/python_bindings/halide/tutorial/lesson_20_cloning_funcs.py similarity index 100% rename from python_bindings/tutorial/lesson_20_cloning_funcs.py rename to python_bindings/halide/tutorial/lesson_20_cloning_funcs.py diff --git a/python_bindings/tutorial/lesson_21_auto_scheduler_generate.py b/python_bindings/halide/tutorial/lesson_21_auto_scheduler_generate.py similarity index 100% rename from python_bindings/tutorial/lesson_21_auto_scheduler_generate.py rename to python_bindings/halide/tutorial/lesson_21_auto_scheduler_generate.py diff --git a/python_bindings/tutorial/lesson_21_auto_scheduler_run.py b/python_bindings/halide/tutorial/lesson_21_auto_scheduler_run.py similarity index 100% rename from python_bindings/tutorial/lesson_21_auto_scheduler_run.py rename to python_bindings/halide/tutorial/lesson_21_auto_scheduler_run.py diff --git a/python_bindings/tutorial/lesson_22_jit_performance.py b/python_bindings/halide/tutorial/lesson_22_jit_performance.py similarity index 100% rename from python_bindings/tutorial/lesson_22_jit_performance.py rename to python_bindings/halide/tutorial/lesson_22_jit_performance.py diff --git a/python_bindings/tutorial/lesson_23_serialization.py b/python_bindings/halide/tutorial/lesson_23_serialization.py similarity index 100% rename from python_bindings/tutorial/lesson_23_serialization.py rename to python_bindings/halide/tutorial/lesson_23_serialization.py diff --git a/python_bindings/tutorial/lesson_24_async.py b/python_bindings/halide/tutorial/lesson_24_async.py similarity index 100% rename from python_bindings/tutorial/lesson_24_async.py rename to python_bindings/halide/tutorial/lesson_24_async.py diff --git a/python_bindings/src/CMakeLists.txt b/python_bindings/src/CMakeLists.txt deleted file mode 100644 index aa44c7e36f7f..000000000000 --- a/python_bindings/src/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(halide) diff --git a/uv.lock b/uv.lock index 0ced1555937f..ebd169bdf315 100644 --- a/uv.lock +++ b/uv.lock @@ -2,28 +2,28 @@ version = 1 revision = 3 requires-python = ">=3.10" resolution-markers = [ - "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", + "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] conflicts = [[ - { package = "halide", group = "ci-llvm-20" }, - { package = "halide", group = "ci-llvm-21" }, - { package = "halide", group = "ci-llvm-22" }, - { package = "halide", group = "ci-llvm-main" }, + { package = "halide-workspace", group = "ci-llvm-21" }, + { package = "halide-workspace", group = "ci-llvm-22" }, + { package = "halide-workspace", group = "ci-llvm-main" }, ]] +[manifest] +members = [ + "halide", + "halide-bin", + "halide-runtime", + "halide-workspace", +] + [[package]] name = "accessible-pygments" version = "0.0.5" @@ -72,9 +72,9 @@ name = "breathe" version = "4.36.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/01/56/99bf7d0799d95ad485d95596dc01c2a5b3dda58ebf50a94f6f73b33bacdf/breathe-4.36.0.tar.gz", hash = "sha256:14860b73118ac140b7a3f55446890c777d1b67149cb024279fe3710dad7f535c", size = 154842, upload-time = "2025-02-22T18:36:03.36Z" } wheels = [ @@ -331,10 +331,8 @@ name = "docutils" version = "0.21.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", + "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444, upload-time = "2024-04-23T18:57:18.24Z" } wheels = [ @@ -346,16 +344,11 @@ name = "docutils" version = "0.22.4" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", + "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] sdist = { url = "https://files.pythonhosted.org/packages/ae/b6/03bb70946330e88ffec97aefd3ea75ba575cb2e762061e0e62a213befee8/docutils-0.22.4.tar.gz", hash = "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968", size = 2291750, upload-time = "2025-12-18T19:00:26.443Z" } wheels = [ @@ -367,7 +360,7 @@ name = "exceptiongroup" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [ @@ -385,22 +378,136 @@ wheels = [ [[package]] name = "halide" -source = { editable = "." } +source = { editable = "python_bindings/halide" } +dependencies = [ + { name = "halide-bin" }, + { name = "halide-runtime" }, + { name = "imageio", version = "2.37.4", source = { registry = "https://piwheels.org/simple" }, marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "imageio", version = "2.37.4", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pillow", version = "12.3.0", source = { registry = "https://piwheels.org/simple" }, marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, +] + +[package.metadata] +requires-dist = [ + { name = "halide-bin", editable = "python_bindings/halide-bin" }, + { name = "halide-runtime", editable = "python_bindings/halide-runtime" }, + { name = "imageio", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=2" }, + { name = "imageio", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=2", index = "https://piwheels.org/simple" }, + { name = "pillow", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", index = "https://piwheels.org/simple" }, +] + +[[package]] +name = "halide-bin" +source = { editable = "python_bindings/halide-bin" } + +[[package]] +name = "halide-llvm" +version = "21.1.8" +source = { registry = "https://pypi.halide-lang.org/simple" } +resolution-markers = [ + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", + "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", +] +wheels = [ + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3a5efde3893e1bd5da3729a4dc4697cc38d26d5accae3ff0869f4650a3d5d98b" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:9a5ade930a37fbb6bc449a32d83e7897e36dae3d6f074086df4e2b40f5b76f46" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:645c64a735f3294ed9983335273d51ad24d14de96d37fe4b8fc0eb13d5aec436" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f78909fd6d3acf71d8fe2ba8e61c9ed6d87b400240e95c764b56849e07e5d52f" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-manylinux_2_28_i686.whl", hash = "sha256:049b15a407ea249947fbf08e3d912ec352bbfad9f7afb1e1fa815e7dfc5a9db5" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-manylinux_2_31_armv7l.whl", hash = "sha256:06fdbe2904735a1510d7959c60a9cd6034bed61bdf2e402a3b5eb289e8f769b6" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-win32.whl", hash = "sha256:b573660ce26091b9067dc3b63f2d8ee085719ee1f025296a3b52bcc9f105608c" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-win_amd64.whl", hash = "sha256:4c437b2831534b5d490276d8e5bdc112b0649f3d8fc40eee92aac37e7e425a8e" }, +] + +[[package]] +name = "halide-llvm" +version = "22.1.7" +source = { registry = "https://pypi.halide-lang.org/simple" } +resolution-markers = [ + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", + "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", +] +wheels = [ + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1f997a871da192c64abb267615cb0aee4491627ce6c705cad849fa6677f352f2" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:2dab547e28434bf3ac1202975969b753c208c6944bdeb786a8cabc3f02f840e9" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b81610ef7d7feb56540661dad5c59d71380a075cf193767c75c450707d15bd66" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b1eacd19a601a55c23b0ddc329a1caec039270fd29c5a3f94f3a913b3b42a937" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-manylinux_2_28_i686.whl", hash = "sha256:7a36e7e0f65cea51d4c3f5f85852dbd4ba94100970a893ef98fe2f2b7f154b44" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-manylinux_2_31_armv7l.whl", hash = "sha256:e9db509c0a3747e3ed0aba53e2d49246ca985efe0b8a1211b7a3c70d4866a3a6" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-win32.whl", hash = "sha256:1f1611454eb9e6dc1a12197ba4c87c6a4caa3fecc7e5ac5ecb767a8d21f025eb" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-win_amd64.whl", hash = "sha256:cefb720b2d4df5532ee4742445d55e7004140f3c1257daff8cfa0158d632e986" }, +] + +[[package]] +name = "halide-llvm" +version = "23.0.0.dev100667+g9bf20bdf" +source = { registry = "https://pypi.halide-lang.org/simple" } +resolution-markers = [ + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", + "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", +] +wheels = [ + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-macosx_11_0_arm64.whl", hash = "sha256:bc6ecef649b0eeb2d9b5827e8664652d6722ffe4ee98bac3febd3e223629d0d0" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:0fc4450b99b599300ff0088ed798082e1c7129e72a71a55a7ed29fd942d15886" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c00ff01a0c1b43e321cf0491d70d568868c65dc738d59ba054df550b36de6f1" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9dfc5476b8647fb1eab8d6441303d34f065aabfea2d11d547afec94adb27b71b" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-manylinux_2_28_i686.whl", hash = "sha256:182725f20d81737cd3d03ea384eaf9f05fbb6070fe57d22880d5efd90b6eae78" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-manylinux_2_31_armv7l.whl", hash = "sha256:c14abaadf6781b2fbec4495c2d0558ae7fe25c17de05dde8e1b5e88f4de8fe33" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-win32.whl", hash = "sha256:0bff9d935c76af54c0d656f76dd9f9c935784ccc549bf194eb4fedf9f26ce36e" }, + { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-win_amd64.whl", hash = "sha256:0b32ab7ab02d63fb66664061da597dee70d5039c7be381a3f5ca73d30733b06f" }, +] + +[[package]] +name = "halide-runtime" +source = { editable = "python_bindings/halide-runtime" } +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, +] + +[package.metadata] +requires-dist = [ + { name = "numpy", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=1.26" }, + { name = "numpy", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=1.26", index = "https://piwheels.org/simple" }, +] + +[[package]] +name = "halide-workspace" +version = "0" +source = { virtual = "." } [package.dev-dependencies] apps = [ - { name = "onnx", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "protobuf", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "pytest", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "onnx", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "protobuf", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pytest", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] ci-base = [ { name = "cmake" }, { name = "ninja" }, - { name = "onnx", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "onnx", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "pre-commit" }, - { name = "protobuf", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "protobuf", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "pybind11" }, - { name = "pytest", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "pytest", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "ruff" }, { name = "scikit-build-core" }, { name = "setuptools-scm" }, @@ -455,15 +562,15 @@ dev = [ ] docs = [ { name = "breathe" }, - { name = "myst-parser", version = "4.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "myst-parser", version = "5.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "pydata-sphinx-theme", version = "0.19.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "pydata-sphinx-theme", version = "0.20.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx-design", version = "0.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx-design", version = "0.7.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "myst-parser", version = "4.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "myst-parser", version = "5.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pydata-sphinx-theme", version = "0.19.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pydata-sphinx-theme", version = "0.20.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx-design", version = "0.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx-design", version = "0.7.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "sphinxcontrib-video" }, ] tools = [ @@ -559,114 +666,60 @@ tools = [ ] [[package]] -name = "halide-llvm" -version = "21.1.8" -source = { registry = "https://pypi.halide-lang.org/simple" } -resolution-markers = [ - "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", -] +name = "identify" +version = "2.6.17" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/84/376a3b96e5a8d33a7aa2c5b3b31a4b3c364117184bf0b17418055f6ace66/identify-2.6.17.tar.gz", hash = "sha256:f816b0b596b204c9fdf076ded172322f2723cf958d02f9c3587504834c8ff04d", size = 99579, upload-time = "2026-03-01T20:04:12.702Z" } wheels = [ - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3a5efde3893e1bd5da3729a4dc4697cc38d26d5accae3ff0869f4650a3d5d98b" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:9a5ade930a37fbb6bc449a32d83e7897e36dae3d6f074086df4e2b40f5b76f46" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:645c64a735f3294ed9983335273d51ad24d14de96d37fe4b8fc0eb13d5aec436" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f78909fd6d3acf71d8fe2ba8e61c9ed6d87b400240e95c764b56849e07e5d52f" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-manylinux_2_28_i686.whl", hash = "sha256:049b15a407ea249947fbf08e3d912ec352bbfad9f7afb1e1fa815e7dfc5a9db5" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-manylinux_2_31_armv7l.whl", hash = "sha256:06fdbe2904735a1510d7959c60a9cd6034bed61bdf2e402a3b5eb289e8f769b6" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-win32.whl", hash = "sha256:b573660ce26091b9067dc3b63f2d8ee085719ee1f025296a3b52bcc9f105608c" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4021.1.8/halide_llvm-21.1.8-py3-none-win_amd64.whl", hash = "sha256:4c437b2831534b5d490276d8e5bdc112b0649f3d8fc40eee92aac37e7e425a8e" }, + { url = "https://files.pythonhosted.org/packages/40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/identify-2.6.17-py2.py3-none-any.whl", hash = "sha256:be5f8412d5ed4b20f2bd41a65f920990bdccaa6a4a18a08f1eefdcd0bdd885f0", size = 99382, upload-time = "2026-03-01T20:04:11.439Z" }, ] [[package]] -name = "halide-llvm" -version = "22.1.7" -source = { registry = "https://pypi.halide-lang.org/simple" } -resolution-markers = [ - "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", -] +name = "idna" +version = "3.18" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" } wheels = [ - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1f997a871da192c64abb267615cb0aee4491627ce6c705cad849fa6677f352f2" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:2dab547e28434bf3ac1202975969b753c208c6944bdeb786a8cabc3f02f840e9" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b81610ef7d7feb56540661dad5c59d71380a075cf193767c75c450707d15bd66" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b1eacd19a601a55c23b0ddc329a1caec039270fd29c5a3f94f3a913b3b42a937" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-manylinux_2_28_i686.whl", hash = "sha256:7a36e7e0f65cea51d4c3f5f85852dbd4ba94100970a893ef98fe2f2b7f154b44" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-manylinux_2_31_armv7l.whl", hash = "sha256:e9db509c0a3747e3ed0aba53e2d49246ca985efe0b8a1211b7a3c70d4866a3a6" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-win32.whl", hash = "sha256:1f1611454eb9e6dc1a12197ba4c87c6a4caa3fecc7e5ac5ecb767a8d21f025eb" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4022.1.7/halide_llvm-22.1.7-py3-none-win_amd64.whl", hash = "sha256:cefb720b2d4df5532ee4742445d55e7004140f3c1257daff8cfa0158d632e986" }, + { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" }, ] [[package]] -name = "halide-llvm" -version = "23.0.0.dev100667+g9bf20bdf" -source = { registry = "https://pypi.halide-lang.org/simple" } +name = "imageio" +version = "2.37.4" +source = { registry = "https://piwheels.org/simple" } resolution-markers = [ - "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", ] -wheels = [ - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-macosx_11_0_arm64.whl", hash = "sha256:bc6ecef649b0eeb2d9b5827e8664652d6722ffe4ee98bac3febd3e223629d0d0" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:0fc4450b99b599300ff0088ed798082e1c7129e72a71a55a7ed29fd942d15886" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c00ff01a0c1b43e321cf0491d70d568868c65dc738d59ba054df550b36de6f1" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9dfc5476b8647fb1eab8d6441303d34f065aabfea2d11d547afec94adb27b71b" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-manylinux_2_28_i686.whl", hash = "sha256:182725f20d81737cd3d03ea384eaf9f05fbb6070fe57d22880d5efd90b6eae78" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-manylinux_2_31_armv7l.whl", hash = "sha256:c14abaadf6781b2fbec4495c2d0558ae7fe25c17de05dde8e1b5e88f4de8fe33" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-win32.whl", hash = "sha256:0bff9d935c76af54c0d656f76dd9f9c935784ccc549bf194eb4fedf9f26ce36e" }, - { url = "https://github.com/halide/pypi/releases/download/halide-llvm%4023.0.0.dev100667%2Bg9bf20bdf/halide_llvm-23.0.0.dev100667%2Bg9bf20bdf-py3-none-win_amd64.whl", hash = "sha256:0b32ab7ab02d63fb66664061da597dee70d5039c7be381a3f5ca73d30733b06f" }, +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pillow", version = "12.3.0", source = { registry = "https://piwheels.org/simple" }, marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] - -[[package]] -name = "identify" -version = "2.6.17" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/84/376a3b96e5a8d33a7aa2c5b3b31a4b3c364117184bf0b17418055f6ace66/identify-2.6.17.tar.gz", hash = "sha256:f816b0b596b204c9fdf076ded172322f2723cf958d02f9c3587504834c8ff04d", size = 99579, upload-time = "2026-03-01T20:04:12.702Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/identify-2.6.17-py2.py3-none-any.whl", hash = "sha256:be5f8412d5ed4b20f2bd41a65f920990bdccaa6a4a18a08f1eefdcd0bdd885f0", size = 99382, upload-time = "2026-03-01T20:04:11.439Z" }, + { url = "https://piwheels.org/simple/imageio/imageio-2.37.4-py3-none-any.whl", hash = "sha256:dfc5560c0b3e15049ca298470002b549e4a2f93ad5e54ba9498e88cdd31953cc" }, ] [[package]] -name = "idna" -version = "3.18" +name = "imageio" +version = "2.37.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" } +resolution-markers = [ + "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", +] +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pillow", version = "12.3.0", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/48/62/aa770a9307508d2a2a2c62d536a49347bffe9e55322db27838d3c93d0b07/imageio-2.37.4.tar.gz", hash = "sha256:e45cbc5e83502047fb138f7f585f7f105a136a57eea5f4b3cfc6ce1b52720bd3", size = 390173, upload-time = "2026-07-20T05:26:11.369Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" }, + { url = "https://files.pythonhosted.org/packages/3e/2d/ca050652104bab2cf55e569db2a178b1b61cb041fef28307f2db383f6d9f/imageio-2.37.4-py3-none-any.whl", hash = "sha256:1ab2e22c8debf700f24c3ac43e8f95f3b3a8110c83b93411e97b4b0b2cd1c7e6", size = 318000, upload-time = "2026-07-20T05:26:09.874Z" }, ] [[package]] @@ -704,13 +757,11 @@ name = "markdown-it-py" version = "3.0.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", + "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ - { name = "mdurl", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "mdurl", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } wheels = [ @@ -722,19 +773,14 @@ name = "markdown-it-py" version = "4.2.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", + "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ - { name = "mdurl", marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "mdurl", marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } wheels = [ @@ -831,8 +877,8 @@ name = "mdit-py-plugins" version = "0.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "markdown-it-py", version = "4.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "markdown-it-py", version = "4.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/59/fc/f8d0863f8862f25602c0404d75568e89fb6b4109804645e5cdfb1be5cf56/mdit_py_plugins-0.6.1.tar.gz", hash = "sha256:a2bca0f039f39dbd35fb74ae1b5f998608c437463371f0ff7f49a19a17a114d0", size = 56114, upload-time = "2026-05-13T09:03:38.91Z" } wheels = [ @@ -853,8 +899,8 @@ name = "ml-dtypes" version = "0.5.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0e/4a/c27b42ed9b1c7d13d9ba8b6905dece787d6259152f2309338aed29b2447b/ml_dtypes-0.5.4.tar.gz", hash = "sha256:8ab06a50fb9bf9666dd0fe5dfb4676fa2b0ac0f31ecff72a6c3af8e22c063453", size = 692314, upload-time = "2025-11-17T22:32:31.031Z" } wheels = [ @@ -899,18 +945,16 @@ name = "myst-parser" version = "4.0.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", + "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ - { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "jinja2", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "mdit-py-plugins", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "pyyaml", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "jinja2", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "mdit-py-plugins", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pyyaml", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/a5/9626ba4f73555b3735ad86247a8077d4603aa8628537687c839ab08bfe44/myst_parser-4.0.1.tar.gz", hash = "sha256:5cfea715e4f3574138aecbf7d54132296bfd72bb614d31168f48c477a830a7c4", size = 93985, upload-time = "2025-02-12T10:53:03.833Z" } wheels = [ @@ -922,25 +966,20 @@ name = "myst-parser" version = "5.1.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", + "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "jinja2", marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "markdown-it-py", version = "4.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "mdit-py-plugins", marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "pyyaml", marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "jinja2", marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "markdown-it-py", version = "4.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "mdit-py-plugins", marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pyyaml", marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/21/dc/603751677fff302f34396e206b610f556a59d7fe58b9a2145f54e96b48e8/myst_parser-5.1.0.tar.gz", hash = "sha256:ab69322dc6719dcc7f296479dbb70181b66df6ed315064f92dbc85c0e1bf2f02", size = 101182, upload-time = "2026-05-13T09:38:19.361Z" } wheels = [ @@ -980,13 +1019,26 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, ] +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://piwheels.org/simple" } +resolution-markers = [ + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", +] +wheels = [ + { url = "https://piwheels.org/simple/numpy/numpy-2.2.6-cp311-cp311-linux_armv6l.whl", hash = "sha256:9d5168644d4f18fda98839f03a5e6ede9b1b780ac4a187c188971a3dc4b0382e" }, + { url = "https://piwheels.org/simple/numpy/numpy-2.2.6-cp311-cp311-linux_armv7l.whl", hash = "sha256:9d5168644d4f18fda98839f03a5e6ede9b1b780ac4a187c188971a3dc4b0382e" }, + { url = "https://piwheels.org/simple/numpy/numpy-2.2.6-cp313-cp313-linux_armv6l.whl", hash = "sha256:495b42b52f5be434ff56e549d9deac19ac50de272f1f803755408e21c5e5e8cc" }, + { url = "https://piwheels.org/simple/numpy/numpy-2.2.6-cp313-cp313-linux_armv7l.whl", hash = "sha256:495b42b52f5be434ff56e549d9deac19ac50de272f1f803755408e21c5e5e8cc" }, +] + [[package]] name = "numpy" version = "2.2.6" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } wheels = [ @@ -1051,12 +1103,9 @@ name = "numpy" version = "2.4.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] sdist = { url = "https://files.pythonhosted.org/packages/57/fd/0005efbd0af48e55eb3c7208af93f2862d4b1a56cd78e84309a2d959208d/numpy-2.4.2.tar.gz", hash = "sha256:659a6107e31a83c4e33f763942275fd278b21d095094044eb35569e86a21ddae", size = 20723651, upload-time = "2026-01-31T23:13:10.135Z" } wheels = [ @@ -1133,16 +1182,40 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/de/e5/b7d20451657664b07986c2f6e3be564433f5dcaf3482d68eaecd79afaf03/numpy-2.4.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:be71bf1edb48ebbbf7f6337b5bfd2f895d1902f6335a5830b20141fc126ffba0", size = 12502577, upload-time = "2026-01-31T23:13:07.08Z" }, ] +[[package]] +name = "numpy" +version = "2.4.6" +source = { registry = "https://piwheels.org/simple" } +resolution-markers = [ + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", +] +wheels = [ + { url = "https://piwheels.org/simple/numpy/numpy-2.4.6-cp311-cp311-linux_armv6l.whl", hash = "sha256:a74f04fb7f02e62d9d2f3c9758a5dab22ebefda6f87d6c703b9f968b06485fbb" }, + { url = "https://piwheels.org/simple/numpy/numpy-2.4.6-cp311-cp311-linux_armv7l.whl", hash = "sha256:a74f04fb7f02e62d9d2f3c9758a5dab22ebefda6f87d6c703b9f968b06485fbb" }, +] + +[[package]] +name = "numpy" +version = "2.5.2" +source = { registry = "https://piwheels.org/simple" } +resolution-markers = [ + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", +] +wheels = [ + { url = "https://piwheels.org/simple/numpy/numpy-2.5.2-cp313-cp313-linux_armv6l.whl", hash = "sha256:cea39dc91a59c3e2087e37107ee5e6fb8e37ab306d0f49d1e2fe0296508c57c5" }, + { url = "https://piwheels.org/simple/numpy/numpy-2.5.2-cp313-cp313-linux_armv7l.whl", hash = "sha256:cea39dc91a59c3e2087e37107ee5e6fb8e37ab306d0f49d1e2fe0296508c57c5" }, +] + [[package]] name = "onnx" version = "1.19.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ml-dtypes", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "protobuf", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "typing-extensions", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "ml-dtypes", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "protobuf", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "typing-extensions", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/5b/bf/b0a63ee9f3759dcd177b28c6f2cb22f2aecc6d9b3efecaabc298883caa5f/onnx-1.19.0.tar.gz", hash = "sha256:aa3f70b60f54a29015e41639298ace06adf1dd6b023b9b30f1bca91bb0db9473", size = 11949859, upload-time = "2025-08-27T02:34:27.107Z" } wheels = [ @@ -1194,6 +1267,122 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl", hash = "sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723", size = 55206, upload-time = "2026-01-27T03:59:45.137Z" }, ] +[[package]] +name = "pillow" +version = "12.3.0" +source = { registry = "https://piwheels.org/simple" } +resolution-markers = [ + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", +] +wheels = [ + { url = "https://piwheels.org/simple/pillow/pillow-12.3.0-cp311-cp311-linux_armv6l.whl", hash = "sha256:402669e2c8551ae30ffafa9bb013d8797d7cd7132dd8ed5db14edb6f303c5d2a" }, + { url = "https://piwheels.org/simple/pillow/pillow-12.3.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:402669e2c8551ae30ffafa9bb013d8797d7cd7132dd8ed5db14edb6f303c5d2a" }, + { url = "https://piwheels.org/simple/pillow/pillow-12.3.0-cp313-cp313-linux_armv6l.whl", hash = "sha256:d8b2b201942a627bca287184e7330d3ccbf4a6cce11ccc6ca8d2fb3bd1b08dff" }, + { url = "https://piwheels.org/simple/pillow/pillow-12.3.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:d8b2b201942a627bca287184e7330d3ccbf4a6cce11ccc6ca8d2fb3bd1b08dff" }, +] + +[[package]] +name = "pillow" +version = "12.3.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/c2/669d88644cddb1485bd9534e63e8cf476c8e51cb3c3a1297677023505c0e/pillow-12.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6c0016e7b354317c4e9e525b937ac8596c38d2d232b419529b9cd7a1cd46e39a", size = 5392418, upload-time = "2026-07-01T11:53:27.808Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ba/3762f376a2948e3036488d773a146e0ae6ecc2ca03ac20e2615bd0b2ba02/pillow-12.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bcc33feacfaefce60c12fd500a277533bdc02b10a19f7f6d348763d8140bbba7", size = 4785287, upload-time = "2026-07-01T11:53:29.761Z" }, + { url = "https://files.pythonhosted.org/packages/07/50/b5d688cc9c52d4482f3d5bcab6ce20bc2a74a85d2343841c907444a3be2c/pillow-12.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5594fc43d548a7ed94949d139aa1341b270f1863f11cfd37f5a6c8b778a6b67f", size = 6253754, upload-time = "2026-07-01T11:53:32.298Z" }, + { url = "https://files.pythonhosted.org/packages/4e/89/36f4cd76cf4baf05c50ababb976249153f18c959171c7f6ba09a6f217260/pillow-12.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0606c8bf2cdefea14a43530f7657cbbb7ecf1c4222512492ef4a4434a9501ec", size = 6925605, upload-time = "2026-07-01T11:53:34.487Z" }, + { url = "https://files.pythonhosted.org/packages/eb/c0/4de58cf6633b9e3a6061ef4be6fb91fc3c90b812ece886f531e3c523d777/pillow-12.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:85f998ea1848bc6757289e739cfbdda3a04adfd58b02fc018ce54d754a5ce468", size = 6327788, upload-time = "2026-07-01T11:53:36.433Z" }, + { url = "https://files.pythonhosted.org/packages/87/3c/14d53682a19550dbbaf3b598f807d5457646c510805a44c7d7891cd1cd1a/pillow-12.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:25b9b82bb22e6e2b3cd07b39c68b7b862001226cb3dff7130d1cb914121b39ed", size = 7036288, upload-time = "2026-07-01T11:53:38.712Z" }, + { url = "https://files.pythonhosted.org/packages/38/1d/36279e3c77efe034e4cc2b0393ee74ffdb5a62391dacbf9b916154f5f0b8/pillow-12.3.0-cp310-cp310-win32.whl", hash = "sha256:37dc8f7bbb66efe481bb60defacef820c950c24713fb44962ed6aa2a50966de1", size = 6472396, upload-time = "2026-07-01T11:53:40.781Z" }, + { url = "https://files.pythonhosted.org/packages/48/7c/8fa0039574c476d7c6fa57dd7c32a130436877c6ec1e5ce1cc8ec44878c1/pillow-12.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:300557495eb45ebb8aec96c2da9c4be642fbf7cd937278b4013ba894ea8eb0eb", size = 7226887, upload-time = "2026-07-01T11:53:42.764Z" }, + { url = "https://files.pythonhosted.org/packages/fa/17/e324be141d173c1c919428066c3259f21c1b8982e564e01a4a81e96dbdcf/pillow-12.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:514435a37670e3e5e08f3945b68718b6ed329bb84367777e16f9f4dfe1e61a0f", size = 2568039, upload-time = "2026-07-01T11:53:45.372Z" }, + { url = "https://files.pythonhosted.org/packages/fb/c8/0a78b0e02d7ac54bc03e5321c9220da52f0c2ea83b21f7c40e7f3169c502/pillow-12.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:00808c5e14ef63ac5161091d242999076604ff74b883423a11e5d7bbb38bf756", size = 5392415, upload-time = "2026-07-01T11:53:47.162Z" }, + { url = "https://files.pythonhosted.org/packages/b2/5b/a02d30018abd97ced9f5a6c63d28597694a00d066516b9c1c6de45859fc9/pillow-12.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37d6d0a00072fd2948eb22bce7e1475f34569d90c87c59f7a2ec59541b77f7a6", size = 4785266, upload-time = "2026-07-01T11:53:49.079Z" }, + { url = "https://files.pythonhosted.org/packages/c8/98/766667a4be768150a202836acd9fad19c06824ca86c4286d3cf6b274964e/pillow-12.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bcb46e2f9feff8d06323983bd83ed00c201fdcab3d74973e7072a889b3979fcd", size = 6263814, upload-time = "2026-07-01T11:53:51.32Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2d/ede717bc1144f63886c21fd349bb95860b0d1a21149ff16f2bb362b612b6/pillow-12.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23d27a3e0307ec2244cc51e7287b919aa68d097504ebe19df4e76a98a3eea5bd", size = 6934408, upload-time = "2026-07-01T11:53:53.487Z" }, + { url = "https://files.pythonhosted.org/packages/a3/48/9c58b685e69d49c31af6c8eb9012055fab7e665785165c84796e2c73ce72/pillow-12.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4f883547d4b7f0495ebe7056b0cc2aea76094e7a4abc8e933540f3271df27d9c", size = 6337160, upload-time = "2026-07-01T11:53:55.457Z" }, + { url = "https://files.pythonhosted.org/packages/ff/fa/dc2a5c0ba6df93f67c31d34b808b7ce440b40cdbf96f0b81cde1d1e6fa93/pillow-12.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:236ff70b9312fb68943c703aa842ca6a758abfa45ac187a5e7c1452e96ef72b5", size = 7045172, upload-time = "2026-07-01T11:53:57.736Z" }, + { url = "https://files.pythonhosted.org/packages/86/a5/444817a4d4c4c2417df00513086ca196f388d8f9ef40c2e4ccd1ad1af54b/pillow-12.3.0-cp311-cp311-win32.whl", hash = "sha256:10e41f0fbf1eec8cfd234b8fe17a4caac7c9d0db4c204d3c173a8f9f6ef3232b", size = 6472232, upload-time = "2026-07-01T11:53:59.767Z" }, + { url = "https://files.pythonhosted.org/packages/63/c6/4bad1b18d132a50b27e1365e1ab163616f7a5bb56d330f66f9d1d9d4f9d4/pillow-12.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8e95e1385e4998ae9694eeaa4730ba5457ff61185b3a55e2e7bea0880aef452a", size = 7233653, upload-time = "2026-07-01T11:54:02.066Z" }, + { url = "https://files.pythonhosted.org/packages/fd/16/00f91ab7760dc842f5aad55217e80fc4a7067a0604535249bc8a2d6d9870/pillow-12.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:ebaea975e03d3141d9d3a507df75c9b3ec90fa9d2ffd07567b3a978d9d790b26", size = 2568195, upload-time = "2026-07-01T11:54:04.622Z" }, + { url = "https://files.pythonhosted.org/packages/37/bf/fb3ebff8ddcb76aac5a01389251bbbb9519922a9b520d8247c1ca864a25d/pillow-12.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ba09209fbe443b4acccebe845d8a138b89a8f4fbaeedd44953490b5315d5e965", size = 5345969, upload-time = "2026-07-01T11:54:06.397Z" }, + { url = "https://files.pythonhosted.org/packages/d8/66/9a386a92561f402389a4fc70c18838bf6d35eb5eb5c6850b4b2dc64f5048/pillow-12.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffd0c5368496f41b0944be820fcb7a838aa6e623d250b01acf2643939c3f99d7", size = 4780323, upload-time = "2026-07-01T11:54:09.351Z" }, + { url = "https://files.pythonhosted.org/packages/25/27/ac8f99618ffd3dde21db0f4d4b1d2ab00c0880595bfd17df103f7f39fd0c/pillow-12.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9c7f76c0673154f044e9d78c8655fb4213f6ca31a836df48b40fe5d187717b9", size = 6266838, upload-time = "2026-07-01T11:54:11.71Z" }, + { url = "https://files.pythonhosted.org/packages/84/21/a35af28dcc61f37ed850a2d64c65c701321dfbf25085e469d5559360cbbf/pillow-12.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91", size = 6940830, upload-time = "2026-07-01T11:54:13.732Z" }, + { url = "https://files.pythonhosted.org/packages/eb/51/8b08617af3ad95e33ce6d7dd2c99ed6c8298f7fb131636303956be022e25/pillow-12.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e491916b378fba47242221bb9ead245211b70d504f495d105d17b14a24b4907c", size = 6344383, upload-time = "2026-07-01T11:54:15.756Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/cf78ac9780bb93c28328f408973845a309d4d145041665f734572ced1b52/pillow-12.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0dd2064cbc55aaec028ef5fbb60fa47bb6c3e7918e07ff17935284b227a9d2df", size = 7052934, upload-time = "2026-07-01T11:54:17.721Z" }, + { url = "https://files.pythonhosted.org/packages/20/20/25e0f4dc178a6bc0696793720055519a0de89e7661dae886992decbd2f81/pillow-12.3.0-cp312-cp312-win32.whl", hash = "sha256:dbce0b29841537a2fa4a214c2bbf14de3587c9680caa9b4e217568472490b28f", size = 6472684, upload-time = "2026-07-01T11:54:19.839Z" }, + { url = "https://files.pythonhosted.org/packages/45/89/da2f7971a317f83d807fdd4065c0af40208e59e692cc43d315a71a0e96d1/pillow-12.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a2b55dd6b2a4c4b7d87ffa56bdb33fdc5fdb9a462173861a7bc097f17d91cb09", size = 7227137, upload-time = "2026-07-01T11:54:22.025Z" }, + { url = "https://files.pythonhosted.org/packages/de/47/4845a0a6c0dbf1db8456bd9fc791f13c5ced7ced20606d08a0aacfd25b49/pillow-12.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:331b624368d4f1d069149002f25f44bc61c8919ce8ddb3c45bdad8f6e2d89510", size = 2568267, upload-time = "2026-07-01T11:54:24.051Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ac/31fb64e1e7efb5a4b50cd3d92049ba89ac6e4d8d3bb6a74e15048ca3353e/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:21900ce7ba264168cd50defae43cd75d25c833ad4ad6e73ffc5596d12e25ac89", size = 4161684, upload-time = "2026-07-01T11:54:25.934Z" }, + { url = "https://files.pythonhosted.org/packages/87/b4/9805e23d2b4d77842b468513841fda254ee42f0289d25088340e4ff46e2d/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4e8c2a84d977f50b9daed6eeaf3baef67d00d5d74d932288f02cb94518ee3ace", size = 4255487, upload-time = "2026-07-01T11:54:27.935Z" }, + { url = "https://files.pythonhosted.org/packages/df/39/ecf519435a200c693fe053a6ee4d835b41cf963a4dfc2551c4e637cb2a71/pillow-12.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:ae26d61dfa7a47befdc7572b521024e8745f3d809bd95ca9505a7bba9ef849ec", size = 3696433, upload-time = "2026-07-01T11:54:29.813Z" }, + { url = "https://files.pythonhosted.org/packages/42/92/2fc3ffad878ae8dd5469ec1bc8eb83b71f48e13efdf68f02709003982a32/pillow-12.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7a743ff716f746fc19a9557f60dab1600d4613255f8a7aeb3cdde4db7eb15a66", size = 5345889, upload-time = "2026-07-01T11:54:31.97Z" }, + { url = "https://files.pythonhosted.org/packages/10/76/8803c13605b763d33d156c4678fc77f8443389c0c51c8aef707bb02015f4/pillow-12.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d69141514cc30b774ceea5e3ed3a6635c8d8a96edf664689b890f4089111fb35", size = 4780109, upload-time = "2026-07-01T11:54:34.026Z" }, + { url = "https://files.pythonhosted.org/packages/1f/01/e18aff37cb0b4aac47ac90f016d347a49aca667ef97f190b06ac2aabc928/pillow-12.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f7401aebd7f581d7f83a439d87d474999317ee099218e5ad25d125290990ba65", size = 6263736, upload-time = "2026-07-01T11:54:36.131Z" }, + { url = "https://files.pythonhosted.org/packages/f7/62/de5bdd77d935331f4f802edc11e4d82950f642caad6cb2f949837b8560e2/pillow-12.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0847a763afefb695bc912d7c131e7e0632d4edc1d8698f58ddabec8e46b8b6d3", size = 6937129, upload-time = "2026-07-01T11:54:38.216Z" }, + { url = "https://files.pythonhosted.org/packages/70/4d/105627a13300c5e0df1d174230b32fd1273062c96f7745fd552b945d1e1d/pillow-12.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:571b9fcb07b97ef3a492028fb3d2dc0993ca23a06138b0315286566d29ef718a", size = 6339562, upload-time = "2026-07-01T11:54:40.354Z" }, + { url = "https://files.pythonhosted.org/packages/6b/1d/f13de01a553988ab895ba1c722e06cf3144d4f57656fd5b81b6d881f1179/pillow-12.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:756c768d0c9c2955feb7a56c37ea24aea2e369f8d36a88da270b6a9f19e62b5e", size = 7049439, upload-time = "2026-07-01T11:54:42.489Z" }, + { url = "https://files.pythonhosted.org/packages/c9/f9/066794cca041b969964f779ee5fa66a9498bbf34248ac39c5d7954e4198f/pillow-12.3.0-cp313-cp313-win32.whl", hash = "sha256:a876864214e136f0eb367788dbd7df045f4806801518e2cfe9e13229cfe06d8f", size = 6473287, upload-time = "2026-07-01T11:54:44.9Z" }, + { url = "https://files.pythonhosted.org/packages/a6/9b/7a58e61d62be561da3a356fe2384d4059a6345fc130e23ef1c36a5b81d24/pillow-12.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:1cca606cd25738df4ed873d5ad46bbdb3d83b5cbca291f6b4ff13a4df6b0bbe8", size = 7239691, upload-time = "2026-07-01T11:54:47.141Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b0/c4ed4f0ef8f8fa5ee8351537db6650bb8189f7e118842978dd6589065692/pillow-12.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:b629de27fda84b42cde7edef0d85f13b958b47f6e9bbcbba9b673c562a89bd8b", size = 2568185, upload-time = "2026-07-01T11:54:49.137Z" }, + { url = "https://files.pythonhosted.org/packages/dc/01/001f65b68192f0228cc1dbbc8d2530ab5d58b61037ba0587f946fea607cd/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:9cf95fe4d0f84c82d282745d9bb08ad9f926efa00be4697e767b814ce40d4330", size = 4161736, upload-time = "2026-07-01T11:54:51.156Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d2/0219746d0fd16fc8a84498e79452375be3797d3ce4044596ce565164b84f/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8728f216dcdb6e6d555cf971cb34076139ad74b31fc2c14da4fafc741c5f6217", size = 4255435, upload-time = "2026-07-01T11:54:53.414Z" }, + { url = "https://files.pythonhosted.org/packages/c8/02/8d0bc62ef0302318c46ff2a512822d2610e81c7aa46c9b3abe6cbaca5ad0/pillow-12.3.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:a45650e8ce7fafffd731db8550230db6b0d306d181a90b67d3e6bca2f1990930", size = 3696262, upload-time = "2026-07-01T11:54:55.739Z" }, + { url = "https://files.pythonhosted.org/packages/85/e2/73c77d218410b14f5f2d565e8a998d5317b7b9c75368d29985139f7a46f0/pillow-12.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ba54cfebe86920a559a7c4d6b9050791c20513650a1952ebe3368c7dc70306f8", size = 5350344, upload-time = "2026-07-01T11:54:57.657Z" }, + { url = "https://files.pythonhosted.org/packages/c7/da/32c752228ae345f489e3a42499d817b6c3996da7e8a3bc7a04fc806b243b/pillow-12.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e158cb00350dc278f3b91551101aa7d12415a66ebf2c91d8d5ac14e56ddd3ad0", size = 4780131, upload-time = "2026-07-01T11:54:59.713Z" }, + { url = "https://files.pythonhosted.org/packages/b1/9d/8b2c807dbef61a5197c047afe99823787eb66f63daf9fb2432f91d6f0462/pillow-12.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9aeb04d6aef139de265b29683e119b638208f88cf73cdd1658aa07221165321", size = 6263757, upload-time = "2026-07-01T11:55:01.778Z" }, + { url = "https://files.pythonhosted.org/packages/5c/44/c85361f65dbe00eea8576ee467c768d25129989efb76e94f205e9ca9bb46/pillow-12.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:251bf95b67017e27b13d82f5b326234ca62d70f9cf4c2b9032de2358a3b12c7b", size = 6936962, upload-time = "2026-07-01T11:55:03.93Z" }, + { url = "https://files.pythonhosted.org/packages/18/7e/e483414b35800b86b6f08dbbc7803fb5cd52c4d6f897f47d53ea2c7e6f65/pillow-12.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fe3cca2e4e8a592be0f269a1ca4835c25199d9f3ce815c8491048f785b0a0198", size = 6339171, upload-time = "2026-07-01T11:55:05.989Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f4/68c491844841ede6bed70189546b3ee9731cf9f2cbad396faff5e1ccba45/pillow-12.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:23aceaa007d6172b02c277f0cd359c79492bbb14f7072b4ede9fbcaf20648130", size = 7048116, upload-time = "2026-07-01T11:55:08.131Z" }, + { url = "https://files.pythonhosted.org/packages/a3/34/77f3f793fed8efc7d243f21b33c5a3f0d1c97ee70346d3db855587e155ff/pillow-12.3.0-cp314-cp314-win32.whl", hash = "sha256:af8d94b0db561cf68b88a267c5c44b49e134f525d0dc2cb7ed413a66bc23559a", size = 6467209, upload-time = "2026-07-01T11:55:10.408Z" }, + { url = "https://files.pythonhosted.org/packages/f1/e0/492879f69d94f91f60fc8cd05ba03650e9520afebb2fb7aa12777d7c7f38/pillow-12.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:fdafc9cce40277e0f7a0feabce0ee50dd2fa1800f3b38015e51296b5e814048d", size = 7237707, upload-time = "2026-07-01T11:55:12.745Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ac/6b11f2875f1c2ac040d84e1bbf9cf22a88038f901ca1037898b280b38365/pillow-12.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:e91206ee562682b51b98ef4b26a6ef48fd84e15fd4c4bc5ec768eb641d206838", size = 2565995, upload-time = "2026-07-01T11:55:14.736Z" }, + { url = "https://files.pythonhosted.org/packages/52/69/c2208e56af9bfc1913afb24020297a691eb1d4ef688474c8a04913f65e04/pillow-12.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:164b31cd1a0490ab6efae01aa5df49da7061be0af1b30e035b6e9a1bfe34ee6e", size = 5352503, upload-time = "2026-07-01T11:55:17.076Z" }, + { url = "https://files.pythonhosted.org/packages/07/70/e5686d753e898a45d778ff1718dba8516ead6ab6b95d85fc8c4b70650cf2/pillow-12.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5afb51d599ea772b8365ae807ae557f18bccfe46ab261fd1c2a9ed700fc6eb17", size = 4782956, upload-time = "2026-07-01T11:55:19.448Z" }, + { url = "https://files.pythonhosted.org/packages/d5/37/25c6692f06927ee973ff18c8d9ee98ad0b4d84ee67a09610c2dd1447958e/pillow-12.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3edce1d53195db527e0191f84b71d02022de0540bf43a16ed734ed7537b07385", size = 6322855, upload-time = "2026-07-01T11:55:21.613Z" }, + { url = "https://files.pythonhosted.org/packages/cc/91/420637fcb8f1bc11029e403b4538e6694744428d8246118e45719f944556/pillow-12.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf16ba1b4d0b6b7c8e534936632270cf70eb00dbe09005bc345b2677b726855c", size = 6989642, upload-time = "2026-07-01T11:55:24.006Z" }, + { url = "https://files.pythonhosted.org/packages/10/08/b94d7811281ccf0d143a1cf768d1c49e1e54af63e7b708ab2ee3eb87face/pillow-12.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:24870b09b224f7ae3c39ed07d10e819d06f8720bc551847b1d623832b5b0e28d", size = 6391281, upload-time = "2026-07-01T11:55:26.252Z" }, + { url = "https://files.pythonhosted.org/packages/d2/87/24233f785f55474dc02ce3e739c5528a77e3a862e9333d1dd7a25cc31f70/pillow-12.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:30f2aa603c41533cc25c05acd0da21636e84a315768feb631c937177db558931", size = 7096716, upload-time = "2026-07-01T11:55:28.318Z" }, + { url = "https://files.pythonhosted.org/packages/23/26/fcb2f6e37175b04f53570b59937867e2b80ee1685e744023153028fc14f9/pillow-12.3.0-cp314-cp314t-win32.whl", hash = "sha256:4b0a7fe987b14c31ebda6083f74f22b561fd3739bc0ac51e019622e3d72668c7", size = 6474125, upload-time = "2026-07-01T11:55:30.956Z" }, + { url = "https://files.pythonhosted.org/packages/90/de/3634abee5f1c9e13c56787b7d5517b0ba8d6de51700b95578cf338349c9f/pillow-12.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:962864dc93511324d51ddbb5b9f8731bf71675b93ca612a07441896f4688fb8c", size = 7242939, upload-time = "2026-07-01T11:55:34.044Z" }, + { url = "https://files.pythonhosted.org/packages/ce/2a/fd13f8eb24de5714a6eb444a3d67e2842c6c576e159a43793adf23051351/pillow-12.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0740a512dc522224c77d9aa5a8d70d8b7d73fb91f2c21125d8d025d3b8990e45", size = 2567506, upload-time = "2026-07-01T11:55:35.988Z" }, + { url = "https://files.pythonhosted.org/packages/5d/dc/8fdce34ec725a33c81c6ba122b904d6b9024e50ea9ac7bede62fab54506c/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0feb2e9d6ad6c9e3c06effe9d00f3f1e618a6643273576b016f591e9315a7139", size = 4162063, upload-time = "2026-07-01T11:55:37.941Z" }, + { url = "https://files.pythonhosted.org/packages/76/66/2044b9a63d3b84ff048228dfcb7cd9bf0df983e8470971bf7d4c57b693de/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:9e881fca225083806662a5c43d627d215f258ff43c890f831966c7d7ba9c7402", size = 4255549, upload-time = "2026-07-01T11:55:40.022Z" }, + { url = "https://files.pythonhosted.org/packages/52/7e/1f67e6f4ece6b582ee4b539decbcc9f848dc245a93ed8cd7338bafef72f1/pillow-12.3.0-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:4998562bf62a445225f22e07c896bb04b35b1b1f2eb6d760584c9c51d7a5f78c", size = 3696331, upload-time = "2026-07-01T11:55:41.98Z" }, + { url = "https://files.pythonhosted.org/packages/12/40/d306fc2c8e4d45d7f175c77edca7063be7b86fe7fe6e68f4353bf71d808c/pillow-12.3.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:dc624f6bc473dacdf7ef7eb8678d0d08edf15cd94fad6ae5c7d6cc67a4e4902f", size = 5350370, upload-time = "2026-07-01T11:55:44.028Z" }, + { url = "https://files.pythonhosted.org/packages/dd/44/668fb1437e8ce420f62d6106eb66e44a5971602a4d794615bdf79315d82d/pillow-12.3.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:71d6097b330eea8fd15097780c8e89cb1a8ce7838669f48c5bacd6f663dd4701", size = 4780147, upload-time = "2026-07-01T11:55:46.073Z" }, + { url = "https://files.pythonhosted.org/packages/0c/08/93fa2e70e30a2d81547e481b6ee2bb9522117221fb1e0ce4b5df70967677/pillow-12.3.0-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:28ce87c5ab450a9dd970b52e5aca5fe63ed432d18a2eaddd1979a00a1ba24ace", size = 6273659, upload-time = "2026-07-01T11:55:48.264Z" }, + { url = "https://files.pythonhosted.org/packages/f8/6d/043e96ff814fc31a33077e4cba86082167db520c93632afdf2042febbb0c/pillow-12.3.0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6b02afb9b97f65fbca5f31db6a2a3ba21aa93030225f150fa3f249717e938fb4", size = 6947439, upload-time = "2026-07-01T11:55:50.503Z" }, + { url = "https://files.pythonhosted.org/packages/af/92/ba71d2ee2ac0edf3fa33bd9d5ee9ee080da70b1766f3ca3934f9938ddac9/pillow-12.3.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:1182d52bc2d5e5d7d0949503aa7e36d12f42205dc287e4883f407b1988820d39", size = 6353577, upload-time = "2026-07-01T11:55:52.697Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ce/e63064e2122923ff687c8ad792d0d736a7b3920a56a46982e81a7fdd25d6/pillow-12.3.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e795b7eb908249c4e43c7c99fac7c2c75dab0c43566e37db472a355f63693d71", size = 7060394, upload-time = "2026-07-01T11:55:55.149Z" }, + { url = "https://files.pythonhosted.org/packages/54/76/a09cc3ccc8d773a7283d34c38bec1708f9e3cc932093cbc4c5e71ac4060b/pillow-12.3.0-cp315-cp315-win32.whl", hash = "sha256:57b3d78c95ba9059768b10e28b813002261d3f3dfc55cc48b0c988f625175827", size = 6467375, upload-time = "2026-07-01T11:55:57.769Z" }, + { url = "https://files.pythonhosted.org/packages/3e/03/1846c49ba3b1d5550392a4bbd06d6fb4578e1cd91a803198b5c90f5f7d53/pillow-12.3.0-cp315-cp315-win_amd64.whl", hash = "sha256:fa4ecea169a355be7a3ade2c783e2ed12f0e40d2c5621cda8b3297faf7fbb9f5", size = 7237048, upload-time = "2026-07-01T11:55:59.975Z" }, + { url = "https://files.pythonhosted.org/packages/fb/bb/89f35dcc79610423f9f195504d7def7f0d1416a711541b42867e25fe3412/pillow-12.3.0-cp315-cp315-win_arm64.whl", hash = "sha256:877c3f311ff35410f690861c4409e7ccbf0cd2f878e50628a28e5a0bb689e658", size = 2566006, upload-time = "2026-07-01T11:56:02.143Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/707027ba09942dfa2c28759b5c222d769290a41c6d20ea60ec250801941f/pillow-12.3.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:e9871b1ffbfa9656b60aeee92ed5136a5742696006fa322b29ea3d8da0ecc9cf", size = 5352509, upload-time = "2026-07-01T11:56:04.2Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6d/00352fa25332c2569cd387851f568cc5a4b75a9adbfb37ac4fbce4c02eec/pillow-12.3.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:53aa02d20d10c3d814d536aa4e5ac9b84ca0ff5a88377963b085ad6822f93e64", size = 4783167, upload-time = "2026-07-01T11:56:06.631Z" }, + { url = "https://files.pythonhosted.org/packages/13/4f/9e049dfa21af7c22427275720e2490267ba8138120add5c4c574deb69782/pillow-12.3.0-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:446c34dcc4324b084a53b705127dc15717b22c5e140ae0a3c38349d4efec071e", size = 6329237, upload-time = "2026-07-01T11:56:08.868Z" }, + { url = "https://files.pythonhosted.org/packages/36/16/cf6eeaae8d0fce8dd390a33437cf68c5d5bd73834a2bc6e2f14efda0ab45/pillow-12.3.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf1845d02ad822a369a49f2bb9345b1614744267682e7a03527dc3bf6eea1777", size = 6997047, upload-time = "2026-07-01T11:56:11.379Z" }, + { url = "https://files.pythonhosted.org/packages/1e/69/dbf769bdd55f48bf5733cac28edc6364ffaa072ec9ba336266e4fe66be55/pillow-12.3.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:186941b6aef820ad110fb01fb06eb925374dc3a21b17e37ec9a53b250c6fe2d1", size = 6400440, upload-time = "2026-07-01T11:56:13.908Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e1/ffc9cfc2eea0d178da8018e18e959301ad9d6bc9f3edb7181e748a474b97/pillow-12.3.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:f13c32a3abd6079a66d9526e18dad9b6d280384d49d7c54040cd57b6424041d9", size = 7105895, upload-time = "2026-07-01T11:56:16.575Z" }, + { url = "https://files.pythonhosted.org/packages/18/f0/a5595c1e8c3ae44b9828cb2f0fa8155e5095ef04d6327b8f61cf44a3df85/pillow-12.3.0-cp315-cp315t-win32.whl", hash = "sha256:1657923d2d45afb66526e5b933e5b3052e6bdea196c90d3abb2424e18c77dae8", size = 6474384, upload-time = "2026-07-01T11:56:18.855Z" }, + { url = "https://files.pythonhosted.org/packages/e4/04/62bcd9f844984c5938d3b05264a61d797a29d3e0812341a8204af70bbdee/pillow-12.3.0-cp315-cp315t-win_amd64.whl", hash = "sha256:8cd2f7bdda092d99c9fc2fb7391354f306d01443d22785d0cbfafa2e2c8bb418", size = 7243537, upload-time = "2026-07-01T11:56:21.214Z" }, + { url = "https://files.pythonhosted.org/packages/3d/68/1f3066acedf37673694a7141381d8f811ae97f30d34413d236abe7d489f1/pillow-12.3.0-cp315-cp315t-win_arm64.whl", hash = "sha256:06ff022112bc9cbf83b60f8e028d94ad87b60621706487e65f673de61610ab59", size = 2567491, upload-time = "2026-07-01T11:56:23.506Z" }, + { url = "https://files.pythonhosted.org/packages/75/18/2e8b40223153ccbc60df07f9e8928dc0c76202aa4e55ae9f53962b6510d6/pillow-12.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b3c777e849237620b022f7f297dd67705f9f5cf1685f09f02e46f93e92725468", size = 5302510, upload-time = "2026-07-01T11:56:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/46/3e/51fabf59d5ab801ceab709453d3ab6b180083496579549de4c45ced6528a/pillow-12.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:b343699e8308bdc51978310e1c959c584e7869cc8c40780058c87da7781a1e94", size = 4736058, upload-time = "2026-07-01T11:56:28.041Z" }, + { url = "https://files.pythonhosted.org/packages/bf/20/22fe9384b7949e25fb1293bcfc84fb82590ff4ea6b37c95b24d26d793d86/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbd139c8447d25dd750ab79ee274cc5e1fe80fc56340ab10b18a195e1b6eca3e", size = 5237776, upload-time = "2026-07-01T11:56:30.263Z" }, + { url = "https://files.pythonhosted.org/packages/08/14/f6ba68107680ffa74b39985f3f30884e41318fbc4250caa423c79b4788bb/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e7e480451b9fa137494bccd3a7d69adbe8ac65a87d97be61e11f1b1050a5bac3", size = 5860358, upload-time = "2026-07-01T11:56:32.68Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0169bc772ec491108b62f644f8ecf1fe5d8ae5ebafde2ee2142210166903/pillow-12.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:04f01d28a6aaff387bf842a13be313df23ba0597a44f1a976c9feb3c6ff4711a", size = 7231786, upload-time = "2026-07-01T11:56:35.046Z" }, +] + [[package]] name = "platformdirs" version = "4.9.4" @@ -1257,19 +1446,17 @@ name = "pydata-sphinx-theme" version = "0.19.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", + "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ - { name = "accessible-pygments", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "babel", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "beautifulsoup4", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "pygments", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "accessible-pygments", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "babel", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "beautifulsoup4", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pygments", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/39/7e/e3defb93f30557ae825a3b3fbc2c6728301e5e9505a85e00d8503345c42c/pydata_sphinx_theme-0.19.0.tar.gz", hash = "sha256:148ba092bd6937b3321385dc482cc69a29ad2ede36547b4f010ade782bc6a062", size = 5004933, upload-time = "2026-06-15T09:31:02.268Z" } wheels = [ @@ -1281,27 +1468,22 @@ name = "pydata-sphinx-theme" version = "0.20.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", + "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ - { name = "accessible-pygments", marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "babel", marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "beautifulsoup4", marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "jinja2", marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "pygments", marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "requests", marker = "python_full_version >= '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "accessible-pygments", marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "babel", marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "beautifulsoup4", marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "jinja2", marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pygments", marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "requests", marker = "python_full_version >= '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ae/8e/add936feaaa9dade7d5b87c6852566d85e518b38ad32224dea32ef958984/pydata_sphinx_theme-0.20.0.tar.gz", hash = "sha256:0da172d41e19a66de875f4002f7054b385372ec65763852193791e658d50bb4a", size = 5004756, upload-time = "2026-07-09T09:09:14.693Z" } wheels = [ @@ -1322,13 +1504,13 @@ name = "pytest" version = "9.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'win32') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "exceptiongroup", marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "iniconfig", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "packaging", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "pluggy", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "pygments", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "tomli", marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "colorama", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'win32') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (sys_platform != 'win32' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "exceptiongroup", marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "iniconfig", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "packaging", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pluggy", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pygments", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "tomli", marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" } wheels = [ @@ -1475,11 +1657,11 @@ name = "scikit-build-core" version = "1.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "exceptiongroup", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "packaging" }, { name = "pathspec" }, - { name = "tomli", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "tomli", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8d/7c/0f69b0c7150ce4bcee78c199fe3b7e03a6e01578451bd5d5d1a58beb32f9/scikit_build_core-1.0.3.tar.gz", hash = "sha256:a4d7a05978ee37975c37743510c8991e2debce7ef83afb0a07c0c576fd4f16e8", size = 477539, upload-time = "2026-07-12T05:08:30.298Z" } wheels = [ @@ -1502,7 +1684,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "packaging" }, { name = "setuptools" }, - { name = "tomli", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "tomli", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7b/b1/19587742aad604f1988a8a362e660e8c3ac03adccdb71c96d86526e5eb62/setuptools_scm-9.2.2.tar.gz", hash = "sha256:1c674ab4665686a0887d7e24c03ab25f24201c213e82ea689d2f3e169ef7ef57", size = 203385, upload-time = "2025-10-19T22:08:05.608Z" } wheels = [ @@ -1532,29 +1714,27 @@ name = "sphinx" version = "8.1.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", + "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ - { name = "alabaster", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "babel", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "colorama", marker = "(python_full_version < '3.11' and sys_platform == 'win32') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "imagesize", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "jinja2", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "packaging", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "pygments", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "requests", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "snowballstemmer", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "tomli", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "alabaster", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "babel", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "colorama", marker = "(python_full_version < '3.11' and sys_platform == 'win32') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (sys_platform != 'win32' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "imagesize", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "jinja2", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "packaging", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pygments", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "requests", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "snowballstemmer", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-applehelp", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-devhelp", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-htmlhelp", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-jsmath", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-qthelp", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-serializinghtml", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "tomli", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/be0b61178fe2cdcb67e2a92fc9ebb488e3c51c4f74a36a7824c0adf23425/sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927", size = 8184611, upload-time = "2024-10-13T20:27:13.93Z" } wheels = [ @@ -1566,29 +1746,27 @@ name = "sphinx" version = "9.0.4" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", + "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ - { name = "alabaster", marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "babel", marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "colorama", marker = "(python_full_version == '3.11.*' and sys_platform == 'win32') or (python_full_version != '3.11.*' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (python_full_version != '3.11.*' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version != '3.11.*' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version != '3.11.*' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version != '3.11.*' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version != '3.11.*' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "imagesize", marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "jinja2", marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "packaging", marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "pygments", marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "requests", marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "roman-numerals", marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "snowballstemmer", marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "alabaster", marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "babel", marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "colorama", marker = "(python_full_version == '3.11.*' and sys_platform == 'win32') or (python_full_version != '3.11.*' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version != '3.11.*' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version != '3.11.*' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (sys_platform != 'win32' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "imagesize", marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "jinja2", marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "packaging", marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pygments", marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "requests", marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "roman-numerals", marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "snowballstemmer", marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-applehelp", marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-devhelp", marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-htmlhelp", marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-jsmath", marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-qthelp", marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-serializinghtml", marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/50/a8c6ccc36d5eacdfd7913ddccd15a9cee03ecafc5ee2bc40e1f168d85022/sphinx-9.0.4.tar.gz", hash = "sha256:594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3", size = 8710502, upload-time = "2025-12-04T07:45:27.343Z" } wheels = [ @@ -1600,31 +1778,28 @@ name = "sphinx" version = "9.1.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", + "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ - { name = "alabaster", marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "babel", marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "colorama", marker = "(python_full_version >= '3.12' and sys_platform == 'win32') or (python_full_version < '3.12' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (python_full_version < '3.12' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version < '3.12' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version < '3.12' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (python_full_version < '3.12' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (python_full_version < '3.12' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "imagesize", marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "jinja2", marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "packaging", marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "pygments", marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "requests", marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "roman-numerals", marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "snowballstemmer", marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "alabaster", marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "babel", marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "colorama", marker = "(python_full_version >= '3.12' and sys_platform == 'win32') or (python_full_version < '3.12' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version < '3.12' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version < '3.12' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (sys_platform != 'win32' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (sys_platform != 'win32' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "imagesize", marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "jinja2", marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "packaging", marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pygments", marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "requests", marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "roman-numerals", marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "snowballstemmer", marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/bd/f08eb0f4eed5c83f1ba2a3bd18f7745a2b1525fad70660a1c00224ec468a/sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb", size = 8718324, upload-time = "2025-12-31T15:09:27.646Z" } wheels = [ @@ -1636,13 +1811,11 @@ name = "sphinx-design" version = "0.6.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version < '3.11' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", + "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/2b/69/b34e0cb5336f09c6866d53b4a19d76c227cdec1bbc7ac4de63ca7d58c9c7/sphinx_design-0.6.1.tar.gz", hash = "sha256:b44eea3719386d04d765c1a8257caca2b3e6f8421d7b3a5e742c0fd45f84e632", size = 2193689, upload-time = "2024-08-02T13:48:44.277Z" } wheels = [ @@ -1654,20 +1827,15 @@ name = "sphinx-design" version = "0.7.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform != 'armv7l' and sys_platform != 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l')", - "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform != 'armv7l' and sys_platform != 'armv8l'", - "(python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv7l' and sys_platform == 'armv8l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and sys_platform == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv7l') or (python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and sys_platform == 'armv8l')", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", + "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/13/7b/804f311da4663a4aecc6cf7abd83443f3d4ded970826d0c958edc77d4527/sphinx_design-0.7.0.tar.gz", hash = "sha256:d2a3f5b19c24b916adb52f97c5f00efab4009ca337812001109084a740ec9b7a", size = 2203582, upload-time = "2026-01-19T13:12:53.297Z" } wheels = [ @@ -1733,9 +1901,9 @@ name = "sphinxcontrib-video" version = "0.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cc/18/ca17d2f66d519f1a9d0020da0bcdf33881e02471096377b3e993d1acb952/sphinxcontrib_video-0.4.2.tar.gz", hash = "sha256:18477fd9454ac8c69259e6d24e782d8b802345b6475de6216351c2305b06c898", size = 11992, upload-time = "2026-01-14T10:00:29.298Z" } wheels = [ @@ -1865,7 +2033,7 @@ dependencies = [ { name = "filelock" }, { name = "platformdirs" }, { name = "python-discovery" }, - { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-21') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-20' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-22') or (extra == 'group-6-halide-ci-llvm-21' and extra == 'group-6-halide-ci-llvm-main') or (extra == 'group-6-halide-ci-llvm-22' and extra == 'group-6-halide-ci-llvm-main')" }, + { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/aa/92/58199fe10049f9703c2666e809c4f686c54ef0a68b0f6afccf518c0b1eb9/virtualenv-21.2.0.tar.gz", hash = "sha256:1720dc3a62ef5b443092e3f499228599045d7fea4c79199770499df8becf9098", size = 5840618, upload-time = "2026-03-09T17:24:38.013Z" } wheels = [ From a7bacf636f04012d15a88680716a6df0e6071a6d Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Fri, 21 Aug 2026 16:58:59 -0400 Subject: [PATCH 07/39] Finish standalone Python runtime Buffer bindings --- .../src/halide/runtime/CMakeLists.txt | 17 +- .../src/halide/runtime/PyRuntime.cpp | 128 +---- .../src/halide/runtime/PyRuntimeBuffer.cpp | 488 ++++++++++++++++++ .../src/halide/runtime/PyRuntimeBuffer.h | 12 + .../src/halide/runtime/__init__.py | 4 +- python_bindings/halide/src/__init__.py | 27 +- .../halide/src/halide_/PyBuffer.cpp | 26 +- python_bindings/halide/src/halide_/PyType.cpp | 1 + .../halide/test/correctness/buffer.py | 31 ++ .../halide/test/runtime/load_aot.py | 3 +- 10 files changed, 602 insertions(+), 135 deletions(-) create mode 100644 python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp create mode 100644 python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.h diff --git a/python_bindings/halide-runtime/src/halide/runtime/CMakeLists.txt b/python_bindings/halide-runtime/src/halide/runtime/CMakeLists.txt index 5d05d2f54b83..bef174d57cfe 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/CMakeLists.txt +++ b/python_bindings/halide-runtime/src/halide/runtime/CMakeLists.txt @@ -14,7 +14,22 @@ set_target_properties(Halide_PythonRuntime EXPORT_NAME PythonRuntime ) -target_sources(Halide_PythonRuntime PRIVATE PyRuntime.cpp) +target_sources( + Halide_PythonRuntime + PRIVATE + PyRuntime.cpp + PyRuntimeBuffer.cpp + # float16_t is a standalone scalar utility whose implementation depends + # only on runtime headers and the C++ standard library. Reuse it here so + # Buffer's half support does not duplicate its conversion logic or link + # libHalide. + "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/Float16.cpp" + PRIVATE + FILE_SET runtime_support_headers + TYPE HEADERS + BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src" + FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/Float16.h" +) # PyRuntime.cpp #includes the shared marshalling core (it depends only on # + HalideRuntime.h). In an in-tree build it lives in the Halide diff --git a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp index 0a0e8c2892f0..ba1e516eef48 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp +++ b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp @@ -20,10 +20,12 @@ #include #include #include +#include #include #include #include "HalideRuntime.h" +#include "PyRuntimeBuffer.h" #ifdef _WIN32 #include @@ -409,118 +411,11 @@ class Kernel { }; std::string type_to_string(halide_type_t t) { - if (t.code == halide_type_uint && t.bits == 1) { - return "bool"; - } - const char *base; - switch (t.code) { - case halide_type_int: - base = "int"; - break; - case halide_type_uint: - base = "uint"; - break; - case halide_type_float: - base = "float"; - break; - default: - base = "handle"; - break; - } - return std::string(base) + std::to_string(t.bits); + std::ostringstream out; + out << t; + return out.str(); } -// A thin wrapper around a buffer-protocol object (e.g. a NumPy array) that -// exposes it as a halide_buffer_t. This is the interop bridge: it speaks the -// same `_get_raw_halide_buffer_t` protocol as halide.Buffer and the generated -// AOT extensions, so one object can be passed to both a load()'ed Kernel and a -// generated-extension function. It does not own or copy the underlying memory; -// the wrapped object is kept alive for the Buffer's lifetime. -class Buffer { -public: - explicit Buffer(py::object source) - : source_(std::move(source)) { - PyObject *obj = source_.ptr(); - - // Determine ndim so we can size the Halide dimension array. - Py_buffer probe; - if (PyObject_GetBuffer(obj, &probe, PyBUF_FORMAT | PyBUF_STRIDES) < 0) { - throw py::error_already_set(); - } - const int ndim = probe.ndim; - PyBuffer_Release(&probe); - - dims_.resize(ndim > 0 ? ndim : 1); - - // Prefer a writable view (so the buffer can be used as an output), but - // fall back to read-only for immutable inputs. - bool ok = Halide::PythonRuntime::unpack_buffer( - obj, PyBUF_WRITABLE, "buffer", 0, view_, dims_.data(), buf_, - view_valid_, needs_device_free_); - if (!ok) { - PyErr_Clear(); - ok = Halide::PythonRuntime::unpack_buffer( - obj, 0, "buffer", 0, view_, dims_.data(), buf_, - view_valid_, needs_device_free_); - } - if (!ok) { - throw py::error_already_set(); - } - } - - ~Buffer() { - if (needs_device_free_) { - halide_device_free(nullptr, &buf_); - } - if (view_valid_) { - PyBuffer_Release(&view_); - } - } - - Buffer(const Buffer &) = delete; - Buffer &operator=(const Buffer &) = delete; - - uintptr_t raw_halide_buffer_t() { - return reinterpret_cast(&buf_); - } - - int dimensions() const { - return buf_.dimensions; - } - - std::string type() const { - return type_to_string(buf_.type); - } - - // Shape in NumPy (row-major) axis order. - std::vector shape() const { - std::vector s(view_.ndim); - for (int i = 0; i < view_.ndim; i++) { - s[i] = (int)view_.shape[i]; - } - return s; - } - - // Re-export the underlying memory via the buffer protocol, in NumPy axis - // order, so `numpy.asarray(buffer)` is a zero-copy view of the same data. - py::buffer_info buffer_info() { - std::vector shape(view_.shape, view_.shape + view_.ndim); - std::vector strides(view_.strides, view_.strides + view_.ndim); - return py::buffer_info( - view_.buf, view_.itemsize, - std::string(view_.format ? view_.format : "B"), - view_.ndim, shape, strides, view_.readonly != 0); - } - -private: - py::object source_; - Py_buffer view_{}; - bool view_valid_ = false; - bool needs_device_free_ = false; - std::vector dims_; - halide_buffer_t buf_{}; -}; - std::shared_ptr load(const std::string &path, const py::object &name_obj) { LibHandle handle = open_library(path); if (!handle) { @@ -574,18 +469,7 @@ PYBIND11_MODULE(_runtime, m) { // Make our own runtime's errors non-fatal too (e.g. a failed copy-to-host). halide_set_error_handler(&runtime_error_handler); - py::class_(m, "Buffer", py::buffer_protocol()) - .def(py::init(), py::arg("source"), - "Wrap a buffer-protocol object (e.g. a NumPy array) as a Halide " - "runtime buffer, without copying.") - .def_buffer(&Buffer::buffer_info) - .def("_get_raw_halide_buffer_t", &Buffer::raw_halide_buffer_t) - .def_property_readonly("dimensions", &Buffer::dimensions) - .def_property_readonly("type", &Buffer::type) - .def_property_readonly("shape", &Buffer::shape) - .def("__repr__", [](const Buffer &b) { - return ""; - }); + Halide::PythonRuntimeBindings::define_buffer(m); py::class_>(m, "Kernel") .def("__call__", &Kernel::call) diff --git a/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp b/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp new file mode 100644 index 000000000000..4ad2d5e2c33a --- /dev/null +++ b/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp @@ -0,0 +1,488 @@ +#include "PyRuntimeBuffer.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "Float16.h" +#include "HalideBuffer.h" + +namespace py = pybind11; + +namespace Halide::PythonRuntimeBindings { +namespace { + +using RuntimeBuffer = Halide::Runtime::Buffer<>; +using BufferDimension = RuntimeBuffer::Dimension; + +std::string unique_name() { + static std::atomic next{0}; + return "b" + std::to_string(next++); +} + +template +std::string format_descriptor() { + return py::format_descriptor::format(); +} + +template<> +std::string format_descriptor() { + return "e"; +} + +halide_type_t format_descriptor_to_type(const std::string &format) { +#define HANDLE_TYPE(TYPE) \ + if (format == format_descriptor()) { \ + return Halide::Runtime::Buffer::static_halide_type(); \ + } + HANDLE_TYPE(bool) + HANDLE_TYPE(uint8_t) + HANDLE_TYPE(uint16_t) + HANDLE_TYPE(uint32_t) + HANDLE_TYPE(uint64_t) + HANDLE_TYPE(int8_t) + HANDLE_TYPE(int16_t) + HANDLE_TYPE(int32_t) + HANDLE_TYPE(int64_t) + HANDLE_TYPE(float16_t) + HANDLE_TYPE(float) + HANDLE_TYPE(double) +#undef HANDLE_TYPE + if (format == "l") { + return sizeof(long) == 8 ? Runtime::Buffer::static_halide_type() : Runtime::Buffer::static_halide_type(); + } + throw py::value_error("Unsupported Buffer<> type."); +} + +std::string type_to_format_descriptor(halide_type_t type) { +#define HANDLE_TYPE(TYPE) \ + if (type == Runtime::Buffer::static_halide_type()) { \ + return format_descriptor(); \ + } + HANDLE_TYPE(bool) + HANDLE_TYPE(uint8_t) + HANDLE_TYPE(uint16_t) + HANDLE_TYPE(uint32_t) + HANDLE_TYPE(uint64_t) + HANDLE_TYPE(int8_t) + HANDLE_TYPE(int16_t) + HANDLE_TYPE(int32_t) + HANDLE_TYPE(int64_t) + HANDLE_TYPE(float16_t) + HANDLE_TYPE(float) + HANDLE_TYPE(double) +#undef HANDLE_TYPE + throw py::value_error("Unsupported Buffer<> type."); +} + +std::string type_string(const halide_type_t &type) { + std::ostringstream out; + out << type; + return out.str(); +} + +template +T value_cast(const py::object &value) { + return value.cast(); +} + +template<> +float16_t value_cast(const py::object &value) { + return float16_t(value.cast()); +} + +class Buffer { +public: + Buffer() = default; + + Buffer(const Buffer &) = default; + Buffer(Buffer &&) noexcept = default; + Buffer &operator=(const Buffer &) = default; + Buffer &operator=(Buffer &&) noexcept = default; + + Buffer(py::buffer source, std::string name, bool reverse_axes) + : owner_(std::move(source)), identity_(std::make_shared()), name_(name.empty() ? unique_name() : std::move(name)), defined_(true) { + py::buffer_info info = py::reinterpret_borrow(owner_).request(true); + const halide_type_t type = format_descriptor_to_type(info.format); + std::vector dims(info.ndim); + for (int i = 0; i < info.ndim; ++i) { + const auto stride = info.strides[i] / type.bytes(); + if (info.shape[i] > INT32_MAX || stride < INT32_MIN || stride > INT32_MAX) { + throw py::value_error("Out of range dimensions in buffer conversion."); + } + const int dst = reverse_axes ? info.ndim - i - 1 : i; + dims[dst] = {0, static_cast(info.shape[i]), static_cast(stride)}; + } + buffer_ = RuntimeBuffer(type, info.ptr, info.ndim, dims.data()); + buffer_.set_host_dirty(); + } + + Buffer(halide_type_t type, const std::vector &sizes, std::string name) + : buffer_(type, sizes), identity_(std::make_shared()), name_(name.empty() ? unique_name() : std::move(name)), defined_(true) { + } + + Buffer(halide_type_t type, const std::vector &sizes, + const std::vector &storage_order, std::string name) + : buffer_(type, sizes, storage_order), identity_(std::make_shared()), name_(name.empty() ? unique_name() : std::move(name)), defined_(true) { + } + + static Buffer from_runtime(const RuntimeBuffer &buffer, std::string name, bool defined) { + Buffer result; + result.buffer_ = buffer; + result.identity_ = std::make_shared(); + result.name_ = std::move(name); + result.defined_ = defined; + return result; + } + + static Buffer from_compiler(const py::object &source) { + if (!py::hasattr(source, "_get_raw_halide_runtime_buffer") || + !py::hasattr(source, "defined") || + !py::hasattr(source, "name")) { + throw py::type_error("Expected a halide.Buffer."); + } + if (!source.attr("defined")().cast()) { + return Buffer(); + } + const uintptr_t address = source.attr("_get_raw_halide_runtime_buffer")().cast(); + if (address == 0) { + throw py::value_error("A defined Buffer cannot have a null runtime buffer."); + } + Buffer result = from_runtime( + *reinterpret_cast(address), + source.attr("name")().cast(), true); + result.owner_ = source; + return result; + } + + Buffer view(RuntimeBuffer buffer) const { + Buffer result = from_runtime(buffer, unique_name(), true); + result.owner_ = owner_; + result.identity_ = identity_; + return result; + } + + static Buffer make_bounds_query(halide_type_t type, const std::vector &sizes, std::string name) { + return from_runtime(RuntimeBuffer(type, nullptr, sizes), name.empty() ? unique_name() : std::move(name), true); + } + + static Buffer make_scalar(halide_type_t type, std::string name) { + return from_runtime(RuntimeBuffer::make_scalar(type), name.empty() ? unique_name() : std::move(name), true); + } + + static Buffer make_interleaved(halide_type_t type, int width, int height, int channels, std::string name) { + return from_runtime(RuntimeBuffer::make_interleaved(type, width, height, channels), + name.empty() ? unique_name() : std::move(name), true); + } + + static Buffer make_with_shape_of(const Buffer &source, std::string name) { + return from_runtime(RuntimeBuffer::make_with_shape_of(source.buffer_), + name.empty() ? unique_name() : std::move(name), true); + } + + RuntimeBuffer &runtime_buffer() { + return buffer_; + } + + const RuntimeBuffer &runtime_buffer() const { + return buffer_; + } + + uintptr_t raw_halide_buffer_t() { + return reinterpret_cast(buffer_.raw_buffer()); + } + + uintptr_t raw_runtime_buffer() { + return reinterpret_cast(&buffer_); + } + + bool defined() const { + return defined_; + } + + bool same_as(const Buffer &other) const { + return identity_ == other.identity_; + } + + const std::string &name() const { + return name_; + } + + void set_name(const std::string &name) { + name_ = name; + } + + py::buffer_info buffer_info(bool reverse_axes) { + require_defined(); + if (buffer_.data() == nullptr) { + throw py::value_error("Cannot convert a Buffer<> with null host ptr to a Python buffer."); + } + const int d = buffer_.dimensions(); + const int bytes = buffer_.type().bytes(); + std::vector shape(d), strides(d); + for (int i = 0; i < d; ++i) { + const int dst = reverse_axes ? d - i - 1 : i; + shape[dst] = buffer_.dim(i).extent(); + strides[dst] = static_cast(buffer_.dim(i).stride()) * bytes; + } + return py::buffer_info(buffer_.data(), bytes, type_to_format_descriptor(buffer_.type()), d, shape, strides); + } + + py::array numpy_view(bool reverse_axes) { + return py::array(buffer_info(reverse_axes), py::cast(this)); + } + + py::object getitem(const std::vector &pos) { + check_position(pos); + if (buffer_.type() == Runtime::Buffer::static_halide_type()) { + return py::float_(static_cast(buffer_.as()(pos.data()))); + } +#define HANDLE_TYPE(TYPE) \ + if (buffer_.type() == Runtime::Buffer::static_halide_type()) { \ + return py::cast(buffer_.as()(pos.data())); \ + } + HANDLE_TYPE(bool) + HANDLE_TYPE(uint8_t) + HANDLE_TYPE(uint16_t) + HANDLE_TYPE(uint32_t) + HANDLE_TYPE(uint64_t) + HANDLE_TYPE(int8_t) + HANDLE_TYPE(int16_t) + HANDLE_TYPE(int32_t) + HANDLE_TYPE(int64_t) + HANDLE_TYPE(float) + HANDLE_TYPE(double) +#undef HANDLE_TYPE + throw py::value_error("Unsupported Buffer<> type."); + } + + py::object setitem(const std::vector &pos, const py::object &value) { + check_position(pos); + if (buffer_.type() == Runtime::Buffer::static_halide_type()) { + buffer_.as()(pos.data()) = value_cast(value); + return value; + } +#define HANDLE_TYPE(TYPE) \ + if (buffer_.type() == Runtime::Buffer::static_halide_type()) { \ + return py::cast(buffer_.as()(pos.data()) = value_cast(value)); \ + } + HANDLE_TYPE(bool) + HANDLE_TYPE(uint8_t) + HANDLE_TYPE(uint16_t) + HANDLE_TYPE(uint32_t) + HANDLE_TYPE(uint64_t) + HANDLE_TYPE(int8_t) + HANDLE_TYPE(int16_t) + HANDLE_TYPE(int32_t) + HANDLE_TYPE(int64_t) + HANDLE_TYPE(float) + HANDLE_TYPE(double) +#undef HANDLE_TYPE + throw py::value_error("Unsupported Buffer<> type."); + } + + void fill(const py::object &value) { +#define HANDLE_TYPE(TYPE) \ + if (buffer_.type() == Runtime::Buffer::static_halide_type()) { \ + buffer_.as().fill(value_cast(value)); \ + return; \ + } + HANDLE_TYPE(bool) + HANDLE_TYPE(uint8_t) + HANDLE_TYPE(uint16_t) + HANDLE_TYPE(uint32_t) + HANDLE_TYPE(uint64_t) + HANDLE_TYPE(int8_t) + HANDLE_TYPE(int16_t) + HANDLE_TYPE(int32_t) + HANDLE_TYPE(int64_t) + HANDLE_TYPE(float16_t) + HANDLE_TYPE(float) + HANDLE_TYPE(double) +#undef HANDLE_TYPE + throw py::value_error("Unsupported Buffer<> type."); + } + + bool all_equal(const py::object &value) { +#define HANDLE_TYPE(TYPE) \ + if (buffer_.type() == Runtime::Buffer::static_halide_type()) { \ + return buffer_.as().all_equal(value_cast(value)); \ + } + HANDLE_TYPE(bool) + HANDLE_TYPE(uint8_t) + HANDLE_TYPE(uint16_t) + HANDLE_TYPE(uint32_t) + HANDLE_TYPE(uint64_t) + HANDLE_TYPE(int8_t) + HANDLE_TYPE(int16_t) + HANDLE_TYPE(int32_t) + HANDLE_TYPE(int64_t) + HANDLE_TYPE(float16_t) + HANDLE_TYPE(float) + HANDLE_TYPE(double) +#undef HANDLE_TYPE + throw py::value_error("Unsupported Buffer<> type."); + } + +private: + void require_defined() const { + if (!defined_) { + throw py::value_error("Undefined buffer"); + } + } + + void check_position(const std::vector &pos) const { + require_defined(); + if (pos.size() != static_cast(buffer_.dimensions())) { + throw py::value_error("Incorrect number of dimensions."); + } + for (int i = 0; i < buffer_.dimensions(); ++i) { + const auto dim = buffer_.dim(i); + if (pos[i] < dim.min() || pos[i] > dim.max()) { + std::ostringstream out; + out << "index " << pos[i] << " is out of bounds for axis " << i + << " with min=" << dim.min() << ", extent=" << dim.extent(); + throw py::index_error(out.str()); + } + } + } + + RuntimeBuffer buffer_; + py::object owner_; + std::shared_ptr identity_; + std::string name_; + bool defined_ = false; +}; + +} // namespace + +void define_buffer(py::module_ &m) { + py::class_(m, "Type") + .def(py::init([](int code, int bits) { + return halide_type_t(static_cast(code), static_cast(bits)); + }), + py::arg("code"), py::arg("bits")) + .def("code", [](const halide_type_t &type) { return static_cast(type.code); }) + .def("bits", [](const halide_type_t &type) { return type.bits; }) + .def("__eq__", [](const halide_type_t &a, const py::object &other) { + return py::isinstance(other) && a == other.cast(); + }) + .def("__str__", &type_string) + .def("__repr__", &type_string); + + py::class_(m, "BufferDimension") + .def("min", &BufferDimension::min) + .def("stride", &BufferDimension::stride) + .def("extent", &BufferDimension::extent) + .def("max", &BufferDimension::max); + + py::class_(m, "Buffer", py::buffer_protocol()) + .def(py::init<>()) + .def(py::init(), py::keep_alive<1, 2>()) + .def(py::init(), py::arg("buffer"), py::arg("name") = "", py::arg("reverse_axes") = true) + .def(py::init &, std::string>(), + py::arg("type"), py::arg("sizes"), py::arg("name") = "") + .def(py::init &, const std::vector &, std::string>(), + py::arg("type"), py::arg("sizes"), py::arg("storage_order"), py::arg("name") = "") + .def_static("from_compiler", &Buffer::from_compiler, py::arg("buffer")) + .def_static("make_bounds_query", &Buffer::make_bounds_query, py::arg("type"), py::arg("sizes"), py::arg("name") = "") + .def_static("make_scalar", &Buffer::make_scalar, py::arg("type"), py::arg("name") = "") + .def_static("make_interleaved", &Buffer::make_interleaved, py::arg("type"), py::arg("width"), py::arg("height"), py::arg("channels"), py::arg("name") = "") + .def_static("make_with_shape_of", &Buffer::make_with_shape_of, py::arg("src"), py::arg("name") = "") + .def_buffer([](Buffer &b) { return b.buffer_info(true); }) + .def("numpy_view", &Buffer::numpy_view, py::arg("reverse_axes") = true) + .def("set_name", &Buffer::set_name) + .def("name", &Buffer::name) + .def("defined", &Buffer::defined) + .def("same_as", &Buffer::same_as, py::arg("other")) + .def("type", [](const Buffer &b) { return b.runtime_buffer().type(); }) + .def("channels", [](const Buffer &b) { return b.runtime_buffer().channels(); }) + .def("dimensions", [](const Buffer &b) { return b.runtime_buffer().dimensions(); }) + .def("width", [](const Buffer &b) { return b.runtime_buffer().width(); }) + .def("height", [](const Buffer &b) { return b.runtime_buffer().height(); }) + .def("top", [](const Buffer &b) { return b.runtime_buffer().top(); }) + .def("bottom", [](const Buffer &b) { return b.runtime_buffer().bottom(); }) + .def("left", [](const Buffer &b) { return b.runtime_buffer().left(); }) + .def("right", [](const Buffer &b) { return b.runtime_buffer().right(); }) + .def("number_of_elements", [](const Buffer &b) { return b.runtime_buffer().number_of_elements(); }) + .def("size_in_bytes", [](const Buffer &b) { return b.runtime_buffer().size_in_bytes(); }) + .def("has_device_allocation", [](const Buffer &b) { return b.runtime_buffer().has_device_allocation(); }) + .def("host_dirty", [](const Buffer &b) { return b.runtime_buffer().host_dirty(); }) + .def("device_dirty", [](const Buffer &b) { return b.runtime_buffer().device_dirty(); }) + .def("set_host_dirty", [](Buffer &b, bool dirty) { b.runtime_buffer().set_host_dirty(dirty); }, py::arg("dirty") = true) + .def("set_device_dirty", [](Buffer &b, bool dirty) { b.runtime_buffer().set_device_dirty(dirty); }, py::arg("dirty") = true) + .def("copy", [](const Buffer &b) { return Buffer::from_runtime(b.runtime_buffer().copy(), unique_name(), true); }) + .def("copy_from", [](Buffer &b, const Buffer &other) { b.runtime_buffer().copy_from(other.runtime_buffer()); }) + .def("reverse_axes", [](const Buffer &b) { + std::vector order; + for (int i = b.runtime_buffer().dimensions() - 1; i >= 0; --i) order.push_back(i); + return b.view(b.runtime_buffer().transposed(order)); }) + .def("add_dimension", [](Buffer &b) { b.runtime_buffer().add_dimension(); }) + .def("allocate", [](Buffer &b) { b.runtime_buffer().allocate(nullptr, nullptr); }) + .def("deallocate", [](Buffer &b) { b.runtime_buffer().deallocate(); }) + .def("device_deallocate", [](Buffer &b) { b.runtime_buffer().device_deallocate(); }) + .def("crop", [](Buffer &b, int d, int min, int extent) { b.runtime_buffer().crop(d, min, extent); }, py::arg("dimension"), py::arg("min"), py::arg("extent")) + .def("crop", [](Buffer &b, const std::vector> &rect) { b.runtime_buffer().crop(rect); }, py::arg("rect")) + .def("cropped", [](const Buffer &b, int d, int min, int extent) { return b.view(b.runtime_buffer().cropped(d, min, extent)); }) + .def("cropped", [](const Buffer &b, const std::vector> &rect) { return b.view(b.runtime_buffer().cropped(rect)); }) + .def("embed", [](Buffer &b, int d, int pos) { b.runtime_buffer().embed(d, pos); }) + .def("embed", [](Buffer &b, int d) { b.runtime_buffer().embed(d); }) + .def("embedded", [](const Buffer &b, int d, int pos) { return b.view(b.runtime_buffer().embedded(d, pos)); }) + .def("embedded", [](const Buffer &b, int d) { return b.view(b.runtime_buffer().embedded(d)); }) + .def("slice", [](Buffer &b, int d, int pos) { b.runtime_buffer().slice(d, pos); }) + .def("slice", [](Buffer &b, int d) { b.runtime_buffer().slice(d); }) + .def("sliced", [](const Buffer &b, int d, int pos) { return b.view(b.runtime_buffer().sliced(d, pos)); }) + .def("sliced", [](const Buffer &b, int d) { return b.view(b.runtime_buffer().sliced(d)); }) + .def("translate", [](Buffer &b, int d, int dx) { b.runtime_buffer().translate(d, dx); }) + .def("translate", [](Buffer &b, const std::vector &delta) { b.runtime_buffer().translate(delta); }) + .def("translated", [](const Buffer &b, int d, int dx) { return b.view(b.runtime_buffer().translated(d, dx)); }) + .def("translated", [](const Buffer &b, const std::vector &delta) { return b.view(b.runtime_buffer().translated(delta)); }) + .def("transpose", [](Buffer &b, int d1, int d2) { b.runtime_buffer().transpose(d1, d2); }) + .def("transpose", [](Buffer &b, const std::vector &order) { b.runtime_buffer().transpose(order); }) + .def("transposed", [](const Buffer &b, int d1, int d2) { return b.view(b.runtime_buffer().transposed(d1, d2)); }) + .def("transposed", [](const Buffer &b, const std::vector &order) { return b.view(b.runtime_buffer().transposed(order)); }) + .def("dim", [](Buffer &b, int dimension) { return b.runtime_buffer().dim(dimension); }, py::keep_alive<0, 1>()) + .def("for_each_element", [](Buffer &b, const py::function &f) { + std::vector position(b.runtime_buffer().dimensions()); + b.runtime_buffer().for_each_element([&](const int *pos) { + std::copy(pos, pos + position.size(), position.begin()); + f(position); + }); }) + .def("fill", &Buffer::fill) + .def("all_equal", &Buffer::all_equal) + .def("copy_to_host", [](Buffer &b) { return b.runtime_buffer().copy_to_host(nullptr); }) + .def("device_detach_native", [](Buffer &b) { return b.runtime_buffer().device_detach_native(nullptr); }) + .def("device_free", [](Buffer &b) { return b.runtime_buffer().device_free(nullptr); }) + .def("device_sync", [](Buffer &b) { return b.runtime_buffer().device_sync(nullptr); }) + .def("set_min", [](Buffer &b, const std::vector &mins) { + if (mins.size() > static_cast(b.runtime_buffer().dimensions())) throw py::value_error("Too many arguments"); + b.runtime_buffer().set_min(mins); }) + .def("contains", [](const Buffer &b, const std::vector &coords) { + if (coords.size() > static_cast(b.runtime_buffer().dimensions())) throw py::value_error("Too many arguments"); + return b.runtime_buffer().contains(coords); }) + .def("__getitem__", [](Buffer &b, int pos) { return b.getitem({pos}); }) + .def("__getitem__", [](Buffer &b, const std::vector &pos) { return b.getitem(pos); }) + .def("__setitem__", [](Buffer &b, int pos, const py::object &value) { return b.setitem({pos}, value); }) + .def("__setitem__", [](Buffer &b, const std::vector &pos, const py::object &value) { return b.setitem(pos, value); }) + .def("__repr__", [](const Buffer &b) { + if (!b.defined()) return std::string(""); + std::ostringstream out; + out << "dim[i]; + out << "[" << d.min << "," << d.extent << "," << d.stride << "]"; + } + return out.str() + "]>"; }) + .def("_get_raw_halide_buffer_t", &Buffer::raw_halide_buffer_t) + .def("_get_raw_halide_runtime_buffer", &Buffer::raw_runtime_buffer); +} + +} // namespace Halide::PythonRuntimeBindings diff --git a/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.h b/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.h new file mode 100644 index 000000000000..acc6cf667491 --- /dev/null +++ b/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.h @@ -0,0 +1,12 @@ +#ifndef HALIDE_PYTHON_RUNTIME_BUFFER_H +#define HALIDE_PYTHON_RUNTIME_BUFFER_H + +#include + +namespace Halide::PythonRuntimeBindings { + +void define_buffer(pybind11::module_ &m); + +} // namespace Halide::PythonRuntimeBindings + +#endif diff --git a/python_bindings/halide-runtime/src/halide/runtime/__init__.py b/python_bindings/halide-runtime/src/halide/runtime/__init__.py index af5c26e5d2ab..e4cd17269a6e 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/__init__.py +++ b/python_bindings/halide-runtime/src/halide/runtime/__init__.py @@ -10,6 +10,6 @@ deployment environments that do not have the Halide compiler installed. """ -from ._runtime import Buffer, Kernel, load +from ._runtime import Buffer, BufferDimension, Kernel, Type, load -__all__ = ["Buffer", "Kernel", "load"] +__all__ = ["Buffer", "BufferDimension", "Kernel", "Type", "load"] diff --git a/python_bindings/halide/src/__init__.py b/python_bindings/halide/src/__init__.py index ee3ea64340e2..115943068a96 100644 --- a/python_bindings/halide/src/__init__.py +++ b/python_bindings/halide/src/__init__.py @@ -1,7 +1,15 @@ def install_dir(): - from . import bin + try: + from . import bin + + return bin.install_dir() + except ModuleNotFoundError as e: + if e.name != f"{__name__}.bin": + raise + # Traditional CMake build-tree layout (not a split wheel). + from pathlib import Path - return bin.install_dir() + return str(Path(__file__).resolve().parent) # --------------------------------------------------------------------------- @@ -72,7 +80,20 @@ def _load_compiler(): # import time, making the binary package the single authority. from importlib import import_module - import_module(".bin", __name__) + try: + import_module(".bin", __name__) + except ModuleNotFoundError as e: + # A traditional CMake build places halide_ and halide.runtime + # together in the build tree, with libHalide resolved by the build + # RPATH. It deliberately does not synthesize the separately + # packaged halide.bin support module. + if e.name != f"{__name__}.bin": + raise + + # Register the ABI-only Runtime types before loading the compiler + # extension. This lets methods such as Type.to_abi() return the actual + # halide.runtime.Type Python class. + import_module(".runtime", __name__) try: from . import halide_ diff --git a/python_bindings/halide/src/halide_/PyBuffer.cpp b/python_bindings/halide/src/halide_/PyBuffer.cpp index efff467fb005..350a1d93a4e1 100644 --- a/python_bindings/halide/src/halide_/PyBuffer.cpp +++ b/python_bindings/halide/src/halide_/PyBuffer.cpp @@ -340,12 +340,7 @@ py::buffer_info to_buffer_info(Buffer<> &b, bool reverse_axes) { void define_buffer(py::module &m) { using BufferDimension = Halide::Runtime::Buffer<>::Dimension; - auto buffer_dimension_class = - py::class_(m, "BufferDimension") - .def("min", &BufferDimension::min) - .def("stride", &BufferDimension::stride) - .def("extent", &BufferDimension::extent) - .def("max", &BufferDimension::max); + m.attr("BufferDimension") = py::module_::import("halide.runtime").attr("BufferDimension"); auto buffer_class = py::class_, PyBuffer>(m, "Buffer", py::buffer_protocol()) @@ -406,6 +401,22 @@ void define_buffer(py::module &m) { }, py::arg("src"), py::arg("name") = "") + .def_static("from_runtime", [](const py::object &source) -> Buffer<> { + if (!py::hasattr(source, "_get_raw_halide_runtime_buffer") || + !py::hasattr(source, "defined") || + !py::hasattr(source, "name")) { + throw py::type_error("Expected a halide.runtime.Buffer."); + } + if (!source.attr("defined")().cast()) { + return Buffer<>(); + } + const uintptr_t address = source.attr("_get_raw_halide_runtime_buffer")().cast(); + if (address == 0) { + throw py::value_error("A defined Buffer cannot have a null runtime buffer."); + } + const auto *buffer = reinterpret_cast *>(address); + return Buffer<>(Halide::Runtime::Buffer<>(*buffer), source.attr("name")().cast()); }, py::arg("buffer"), py::keep_alive<0, 1>()) + .def("set_name", &Buffer<>::set_name) .def("name", &Buffer<>::name) @@ -684,6 +695,9 @@ void define_buffer(py::module &m) { .def("_get_raw_halide_buffer_t", [](const Buffer<> &b) -> uintptr_t { return reinterpret_cast(b.raw_buffer()); // + }) + .def("_get_raw_halide_runtime_buffer", [](const Buffer<> &b) -> uintptr_t { + return reinterpret_cast(b.get()); // }); } diff --git a/python_bindings/halide/src/halide_/PyType.cpp b/python_bindings/halide/src/halide_/PyType.cpp index ad07f574da1e..31404826be05 100644 --- a/python_bindings/halide/src/halide_/PyType.cpp +++ b/python_bindings/halide/src/halide_/PyType.cpp @@ -58,6 +58,7 @@ void define_type(py::module &m) { .def("code", &Type::code) .def("bits", &Type::bits) .def("lanes", &Type::lanes) + .def("to_abi", &Type::to_abi) .def("with_code", &Type::with_code, py::arg("code")) .def("with_bits", &Type::with_bits, py::arg("bits")) .def("with_lanes", &Type::with_lanes, py::arg("lanes")) diff --git a/python_bindings/halide/test/correctness/buffer.py b/python_bindings/halide/test/correctness/buffer.py index 59ff87577a6e..8ce46dce8b10 100644 --- a/python_bindings/halide/test/correctness/buffer.py +++ b/python_bindings/halide/test/correctness/buffer.py @@ -2,6 +2,7 @@ import sys import halide as hl +import halide.runtime as hlr import numpy as np @@ -616,6 +617,35 @@ def test_ndarray_negative_strides(): assert b[5] == 0 +def test_runtime_buffer_is_distinct(): + assert hl.Buffer is not hlr.Buffer + assert hl.Type is not hlr.Type + assert hl.BufferDimension is hlr.BufferDimension + + runtime_type = hlr.Type(0, 32) + + runtime_buffer = hlr.Buffer(runtime_type, [4, 3], "runtime_buffer") + assert runtime_buffer.type() == runtime_type + runtime_buffer[1, 2] = 42 + + compiler_buffer = hl.Buffer.from_runtime(runtime_buffer) + assert isinstance(compiler_buffer, hl.Buffer) + assert compiler_buffer.type() == hl.Int(32) + assert compiler_buffer.name() == "runtime_buffer" + assert compiler_buffer[1, 2] == 42 + + compiler_buffer[2, 1] = 17 + runtime_copy = hlr.Buffer.from_compiler(compiler_buffer) + assert isinstance(runtime_copy, hlr.Buffer) + assert runtime_copy.type() == runtime_type + assert runtime_copy[2, 1] == 17 + + # Both adaptations are zero-copy views of the same underlying allocation. + runtime_copy[0, 0] = 9 + assert runtime_buffer[0, 0] == 9 + assert compiler_buffer[0, 0] == 9 + + if __name__ == "__main__": test_make_interleaved() test_interleaved_ndarray() @@ -626,6 +656,7 @@ def test_ndarray_negative_strides(): test_numpy_view() test_buffer_copy_no_reverse() test_ndarray_negative_strides() + test_runtime_buffer_is_distinct() test_for_each_element() test_fill_all_equal() test_bufferinfo_sharing() diff --git a/python_bindings/halide/test/runtime/load_aot.py b/python_bindings/halide/test/runtime/load_aot.py index 0a1afa71ca89..d564cbe008d8 100644 --- a/python_bindings/halide/test/runtime/load_aot.py +++ b/python_bindings/halide/test/runtime/load_aot.py @@ -41,7 +41,8 @@ def main(): # halide.runtime.Buffer interop: introspection + zero-copy NumPy round-trip. grid = np.arange(6, dtype=np.uint8).reshape(2, 3) buf = hlr.Buffer(grid) - assert buf.dimensions == 2 and buf.type == "uint8" and buf.shape == [2, 3] + assert buf.dimensions() == 2 and str(buf.type()) == "uint8" + assert [buf.dim(i).extent() for i in range(buf.dimensions())] == [3, 2] assert ( isinstance(buf._get_raw_halide_buffer_t(), int) and buf._get_raw_halide_buffer_t() != 0 From 21a13984ccef3eb8577fc0ee9fce21f3be7bcab2 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Fri, 21 Aug 2026 17:22:31 -0400 Subject: [PATCH 08/39] Update CI environment sync commands to use --frozen and --no-install-workspace --- .github/workflows/deploy-docs.yml | 2 +- .github/workflows/testing-arm-linux.yml | 2 +- .github/workflows/testing-linux.yml | 6 +++--- .github/workflows/testing-macos.yml | 2 +- .github/workflows/testing-windows.yml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index a1912bc92d3a..4766736633e7 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -57,7 +57,7 @@ jobs: - name: Sync CI environment run: | - uv sync --group ci-llvm-22 --group docs --no-install-project + uv sync --frozen --group ci-llvm-22 --group docs --no-install-workspace echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH" echo "VIRTUAL_ENV=${GITHUB_WORKSPACE}/.venv" >> "$GITHUB_ENV" diff --git a/.github/workflows/testing-arm-linux.yml b/.github/workflows/testing-arm-linux.yml index 22ec8b29246d..a6a54bcf5a41 100644 --- a/.github/workflows/testing-arm-linux.yml +++ b/.github/workflows/testing-arm-linux.yml @@ -85,7 +85,7 @@ jobs: - name: Sync CI environment run: | setarch ${{ matrix.arch }} bash -ec " - uv sync --python '${{ matrix.python }}' --group '${{ matrix.uv_group }}' --no-install-project + uv sync --frozen --python '${{ matrix.python }}' --group '${{ matrix.uv_group }}' --no-install-workspace echo '${GITHUB_WORKSPACE}/.venv/bin' >> '$GITHUB_PATH' echo 'VIRTUAL_ENV=${GITHUB_WORKSPACE}/.venv' >> '$GITHUB_ENV' " diff --git a/.github/workflows/testing-linux.yml b/.github/workflows/testing-linux.yml index 857c857a695d..d4c9de5863e3 100644 --- a/.github/workflows/testing-linux.yml +++ b/.github/workflows/testing-linux.yml @@ -82,7 +82,7 @@ jobs: run: | setarch ${{ matrix.arch }} bash -ec " CC='gcc -m${{ matrix.bits }}' CXX='g++ -m${{ matrix.bits }}' \ - uv sync --python '${{ matrix.python }}' --group '${{ matrix.uv_group }}' --no-install-project + uv sync --frozen --python '${{ matrix.python }}' --group '${{ matrix.uv_group }}' --no-install-workspace echo '${GITHUB_WORKSPACE}/.venv/bin' >> '$GITHUB_PATH' echo 'VIRTUAL_ENV=${GITHUB_WORKSPACE}/.venv' >> '$GITHUB_ENV' " @@ -141,7 +141,7 @@ jobs: - name: Sync CI environment run: | - uv sync --group ci-llvm-main --no-install-project + uv sync --frozen --group ci-llvm-main --no-install-workspace echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH" echo "VIRTUAL_ENV=${GITHUB_WORKSPACE}/.venv" >> "$GITHUB_ENV" @@ -226,7 +226,7 @@ jobs: - name: Sync CI environment run: | - uv sync --group ci-llvm-main --no-install-project + uv sync --frozen --group ci-llvm-main --no-install-workspace echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH" echo "VIRTUAL_ENV=${GITHUB_WORKSPACE}/.venv" >> "$GITHUB_ENV" diff --git a/.github/workflows/testing-macos.yml b/.github/workflows/testing-macos.yml index a67ef4dc77eb..8519557c8648 100644 --- a/.github/workflows/testing-macos.yml +++ b/.github/workflows/testing-macos.yml @@ -100,7 +100,7 @@ jobs: - name: Sync CI environment run: | - uv sync --python '${{ matrix.python }}' --group '${{ matrix.uv_group }}' --no-install-project + uv sync --frozen --python '${{ matrix.python }}' --group '${{ matrix.uv_group }}' --no-install-workspace echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH" echo "VIRTUAL_ENV=${GITHUB_WORKSPACE}/.venv" >> "$GITHUB_ENV" diff --git a/.github/workflows/testing-windows.yml b/.github/workflows/testing-windows.yml index 1c68493c58d0..1a230b325ff5 100644 --- a/.github/workflows/testing-windows.yml +++ b/.github/workflows/testing-windows.yml @@ -67,7 +67,7 @@ jobs: LLVM_VER=$(uv export --group '${{ matrix.uv_group }}' --no-emit-project \ | awk -F'==' '/^halide-llvm==/ { gsub(/ .*/, "", $2); print $2 }') - uv sync --python '${{ matrix.python }}' --group ci-base --no-install-project + uv sync --frozen --python '${{ matrix.python }}' --group ci-base --no-install-workspace uv pip install --python-platform i686-pc-windows-msvc --only-binary :all: \ --extra-index-url https://pypi.halide-lang.org/simple/ \ "halide-llvm==${LLVM_VER}" From 8ce420a36caa218eebf01dbec74bafdd8db73646 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Fri, 21 Aug 2026 17:32:36 -0400 Subject: [PATCH 09/39] Update Python package documentation --- .claude/CLAUDE.md | 2 +- README.md | 24 ++++++-- doc/BuildingHalideWithCMake.md | 74 +++++++++++++----------- doc/CMakeLists.txt | 2 +- doc/Python.md | 74 +++++++++++++++++++----- doc/api/index.md | 7 ++- python_bindings/halide-runtime/README.md | 5 ++ python_bindings/halide/README.md | 13 +++++ 8 files changed, 145 insertions(+), 56 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 87183813ae2d..417c363a3b3e 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -27,7 +27,7 @@ via a `uv`-managed Python virtual env; activate it before building so CMake can autodetect the LLVM install: ```shell -$ uv sync --group ci-llvm-22 --no-install-project +$ uv sync --frozen --group ci-llvm-22 --no-install-workspace $ source .venv/bin/activate ``` diff --git a/README.md b/README.md index 87c74e1fa559..373ce64998c2 100644 --- a/README.md +++ b/README.md @@ -36,12 +36,22 @@ We provide binary wheels on PyPI. Halide provides bindings for C++ and Python. Even if you only intend to use Halide from C++, pip may be the easiest way to get a binary build of Halide. -Full releases may be installed with `pip` like so: +Full releases may be installed with `pip` or added to a uv project like so: ```shell $ pip install halide +$ uv add halide ``` +The published Python artifacts are split into three distributions that share the +`halide` import package. The `halide` distribution provides the compiler Python +API and depends on matching versions of `halide-bin` (the compiler, headers, +tools, and CMake package) and `halide-runtime` (the standalone `halide.runtime` +API). Most users should install only `halide`; the package manager installs its +two dependencies automatically. Deployments that only call precompiled AOT +pipelines can instead install `halide-runtime`, avoiding the compiler and LLVM +entirely. + Every commit to `main` is published to our [package index][halide-pypi] as a development version. If you use [uv](https://docs.astral.sh/uv/), you can pin the nightly Halide in a project like so: @@ -158,13 +168,19 @@ any platform. From the Halide source tree, install with [uv](https://docs.astral.sh/uv/): ```shell -$ uv sync --group ci-llvm-22 --no-install-project +$ uv sync --frozen --group ci-llvm-22 --no-install-workspace $ export Halide_LLVM_ROOT=$(halide-llvm --prefix) ``` Replace `22` with the desired LLVM major version (`21`, `22`, `23`, or `main`). -Binary wheels are available for Linux (x86-64, x86-32, AArch64, ARMv7), macOS -(x86-64, ARM64), and Windows (x86-64, x86-32). +The repository root is a uv workspace containing the three Python distributions. +`--no-install-workspace` installs only the development tools and LLVM package +needed for a normal CMake build; `--frozen` uses the committed lockfile without +evaluating or building the workspace packages. To build and install all three +workspace packages into the uv environment instead, run +`uv sync --all-packages`; this includes a full compiler build. Binary wheels are +available for Linux (x86-64, x86-32, AArch64, ARMv7), macOS (x86-64, ARM64), and +Windows (x86-64, x86-32). On macOS, [Homebrew](https://brew.sh) is also a good option: `brew install llvm`. On Debian flavors of Linux, the diff --git a/doc/BuildingHalideWithCMake.md b/doc/BuildingHalideWithCMake.md index 805acfd6ba88..1f6c51db25df 100644 --- a/doc/BuildingHalideWithCMake.md +++ b/doc/BuildingHalideWithCMake.md @@ -196,7 +196,7 @@ Once Python is installed, you can install the Python module dependencies in a [virtual environment][venv] by running ```shell -$ uv sync +$ uv sync --frozen --no-install-workspace ``` from the root of the repository. @@ -237,9 +237,20 @@ dependencies. These are tabulated as constraints in `pyproject.toml` and resolved to specific versions in `uv.lock`. They may be installed by running: ```shell -$ uv sync --no-install-project +$ uv sync --frozen --no-install-workspace ``` +The repository root is a uv workspace for the three published Python +distributions. `--no-install-workspace` installs only the external development +dependencies, leaving the normal CMake build responsible for the Python +bindings. `--frozen` uses the committed lockfile without evaluating or building +the workspace packages. + +To build and install the three Python workspace packages instead, run +`uv sync --all-packages`. This performs a full compiler build. The +`--all-packages` option is necessary because the workspace root is a virtual +project and does not itself depend on its members. + ## Building Halide ### Basic build @@ -484,11 +495,24 @@ $ cmake --install .\build --prefix X:\path\to\Halide-install --config Release Of course, make sure that you build the corresponding config before attempting to install it. -## Building Halide with pip +## Building Halide's Python packages + +Halide's repository root is a uv workspace, not an installable package. It +contains three distributions under `python_bindings/`: `halide-bin` contains the +compiler, native tools, headers, and CMake package; `halide-runtime` contains +the standalone runtime bindings; and `halide` contains the compiler Python +bindings and depends on matching versions of the other two. + +Build them in dependency order with uv: + +```shell +$ uv build --package halide-bin +$ uv build --package halide-runtime --find-links dist +$ uv build --package halide --find-links dist +``` -Halide also supports installation via the standard Python packaging workflow. -Running `pip install .` at the root of the repository will build a wheel and -install it into the currently active Python environment. +The `--find-links dist` options make the matching, locally built `halide-bin` +available as a build dependency. All artifacts are written to `dist/`. However, this comes with a few caveats: @@ -501,16 +525,16 @@ However, this comes with a few caveats: 3. The generated wheel will likely only work on your system. In particular, it will not be repaired with `auditwheel` or `delocate`. -Even so, this is a very good method of installing Halide. It supports both -Python and C++ `find_package` workflows. +Even so, this is a useful way to produce local Halide artifacts. The complete +set of wheels supports both Python and C++ `find_package` workflows. -### Using ccache with pip builds +### Using ccache with Python package builds Because Python's build infrastructure creates temporary CMake build directories, simply setting `CMAKE_CXX_COMPILER_LAUNCHER` to `ccache` is insufficient to produce a well-cached build. The following settings should serve as a starting point to configure your environment (assuming `$PWD` is the repository root) for -using `ccache` with `pip install .`. +using `ccache` with `uv build --package halide-bin`. ```shell # Point CMake to ccache @@ -530,41 +554,21 @@ export CXXFLAGS="$CFLAGS" # Locate the temporary build beneath $PWD so that CCACHE_BASEDIR works export TMPDIR=$PWD/build/tmp -# If using uv, don't create a temporary venv +# Build in the workspace environment rather than a temporary environment export UV_NO_BUILD_ISOLATION=1 ``` See the CCache documentation on [compiling in different directories] and on using [precompiled headers] for more information about these settings. To check -that ccache is working, run, +that ccache is working, build `halide-bin` twice and inspect the cache +statistics: ```shell -$ uv pip install . # first run, populate cache -Resolved 4 packages in 397ms - Built halide @ file:///Users/areinking/dev/Halide -Prepared 1 package in 29.17s -Installed 1 package in 8ms - + halide==20.0.0.dev87+gf6c939fd3.d20250724 (from file:///Users/areinking/dev/Halide) +$ uv build --package halide-bin # first run, populate cache $ ccache -z Statistics zeroed -$ uv pip install . # second run, reload from cache -Resolved 4 packages in 338ms - Built halide @ file:///Users/areinking/dev/Halide -Prepared 1 package in 10.82s -Uninstalled 1 package in 7ms -Installed 1 package in 6ms - ~ halide==20.0.0.dev87+gf6c939fd3.d20250724 (from file:///Users/areinking/dev/Halide) +$ uv build --package halide-bin # second run, reuse cached objects $ ccache -s -Cacheable calls: 1079 / 1080 (99.91%) - Hits: 1079 / 1079 (100.0%) - Direct: 1079 / 1079 (100.0%) - Preprocessed: 0 / 1079 ( 0.00%) - Misses: 0 / 1079 ( 0.00%) -Uncacheable calls: 1 / 1080 ( 0.09%) -Local storage: - Cache size (GB): 2.2 / 30.0 ( 7.24%) - Hits: 1079 / 1079 (100.0%) - Misses: 0 / 1079 ( 0.00%) ``` On this test system (an M3 MacBook Pro), the build is three times faster, with a diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index ac555316ae3c..b32bc2657edd 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -14,7 +14,7 @@ if (_docs_python_deps_missing) message( FATAL_ERROR "WITH_DOCS requires the Python 'myst-parser', 'breathe', 'pydata-sphinx-theme', " "'sphinxcontrib-video', and 'sphinx-design' packages for the interpreter at ${Python3_EXECUTABLE}. " - "Run: uv sync --group docs" + "Run: uv sync --frozen --group docs --no-install-workspace" ) endif () diff --git a/doc/Python.md b/doc/Python.md index 93c421e529d1..62d9ba89806f 100644 --- a/doc/Python.md +++ b/doc/Python.md @@ -14,16 +14,37 @@ produce Python extensions that can be used within Python code. ## Acquiring the Python bindings -As of Halide 19.0.0, we provide binary wheels on PyPI which include the Python -bindings and the C++/CMake package for native development. Full releases may be -installed with `pip` like so: +As of Halide 19.0.0, we provide binary wheels on PyPI. Full releases may be +installed with `pip` or added to a uv project like so: ```shell $ pip install halide +$ uv add halide ``` -Every commit to `main` is published to a private PyPI index as a development -version and these may be installed with a few extra flags: +The published artifacts are split into three distributions that share the +`halide` import package: + +- `halide` provides the compiler Python API. It depends on matching versions of + the other two distributions. +- `halide-bin` provides `libHalide`, headers, command-line tools, + autoschedulers, and the CMake package. Its wheel has no Python ABI dependency. +- `halide-runtime` provides the standalone `halide.runtime` bindings for calling + precompiled AOT code without `libHalide`, the compiler, or LLVM. + +Most users should install only `halide`; pip or uv installs its dependencies +automatically. Install `halide-runtime` directly only for a runtime-only +deployment. Install `halide-bin` directly when only the C++ compiler tools and +development files are needed. + +Every commit to `main` is published to the Halide package index as a development +version. With uv, add one to a project with: + +```shell +$ uv add halide --prerelease=allow --index https://pypi.halide-lang.org/simple +``` + +Or install it directly with pip: ```shell $ pip install halide --pre --extra-index-url https://pypi.halide-lang.org/simple @@ -46,9 +67,27 @@ installed in your local Python environment. The best way to get set up is to use a virtual environment with `uv`: ```shell -$ uv sync --no-install-project +$ uv sync --frozen --no-install-workspace ``` +The repository root is a uv workspace containing `halide-bin`, `halide-runtime`, +and `halide`. For CMake-based development, `--no-install-workspace` installs +only external development dependencies and leaves the existing monolithic CMake +build in control of the bindings. `--frozen` uses `uv.lock` without evaluating +the workspace packages' dynamic build metadata. + +To build and install the complete Python workspace into `.venv`, including the +compiler, use: + +```shell +$ uv sync --all-packages +$ uv run python -c "import halide" +``` + +The compiler build can take considerable time. `--all-packages` is required +because the repository root is a virtual project; workspace membership alone +does not cause member packages to be installed. + If you don't have LLVM installed already, you can try using the same ones the buildbots use by adding `--group ci-llvm-` to the `uv sync` command, where `` is the LLVM major version number (e.g. `23`) or `main`. @@ -60,14 +99,22 @@ Ensure you have `flatbuffers` and `wabt` installed, too. (The wheel build does not use vcpkg for manylinux compatibility reasons, so these must be available as system packages or installed from source.) -### Using wheel infrastructure +### Building the wheel packages -When using `uv`, this entire workflow can be run via: +The repository root is not itself an installable Python package. Build the three +workspace members in dependency order instead: ```shell -$ uv pip install . --no-build-isolation +$ uv build --package halide-bin +$ uv build --package halide-runtime --find-links dist +$ uv build --package halide --find-links dist ``` +The first command performs the full compiler build. The later builds use the +matching `halide-bin` wheel in `dist/` as a build dependency. The resulting +wheels are also placed in `dist/`. These are local, unrepaired wheels; release +wheels are produced by the pip packaging workflow. + ### Using CMake directly Assuming dependencies are available, you can build the Python bindings directly @@ -603,12 +650,13 @@ build machine that has the full Halide toolchain, then ship only the resulting kernels plus this tiny runtime, and run them on machines that have neither the compiler nor LLVM installed. -`halide.runtime` is always included in the full `halide` package, but it is also -published as a separate, `libHalide`-free wheel for exactly this deployment -case: +The full `halide` distribution depends on `halide-runtime`, so `halide.runtime` +is available after installing `halide`. It is also published as a separate, +`libHalide`-free wheel for exactly this deployment case: ```shell -pip install halide-runtime +$ pip install halide-runtime +$ uv add halide-runtime ``` Importing `halide.runtime` never loads `libHalide`; in the full package, the diff --git a/doc/api/index.md b/doc/api/index.md index b34b079b2d73..233e7c3f32c2 100644 --- a/doc/api/index.md +++ b/doc/api/index.md @@ -15,8 +15,11 @@ directory has many small examples exercising individual features, and the If you're looking for a binary release, install a [stable release](https://pypi.org/project/halide) or a -[nightly build](https://pypi.halide-lang.org/simple/halide) with pip. If you're -building with CMake, see [the Halide CMake helpers](../HalideCMakePackage). +[nightly build](https://pypi.halide-lang.org/simple/halide) with pip or uv. +Installing `halide` includes the compiler bindings, native toolchain, and +standalone runtime bindings. Runtime-only deployments can install +`halide-runtime`. If you're building with CMake, see +[the Halide CMake helpers](../HalideCMakePackage). ## Where to start diff --git a/python_bindings/halide-runtime/README.md b/python_bindings/halide-runtime/README.md index 29ef62d30b7c..b1911b0f6d83 100644 --- a/python_bindings/halide-runtime/README.md +++ b/python_bindings/halide-runtime/README.md @@ -3,6 +3,11 @@ A tiny, standalone runtime for calling **precompiled Halide AOT kernels** from Python, with **no dependency on libHalide** (no compiler, no LLVM). +```shell +pip install halide-runtime +uv add halide-runtime +``` + ```python import numpy as np import halide.runtime as hlr diff --git a/python_bindings/halide/README.md b/python_bindings/halide/README.md index 317b3acc2b43..144200f439ea 100644 --- a/python_bindings/halide/README.md +++ b/python_bindings/halide/README.md @@ -12,6 +12,19 @@ of a Halide pipeline using Halide's Python API. You can then compile this representation to an object file, or JIT-compile it and run it in the same process. +Install the complete Python and native toolchain with: + +```shell +pip install halide +uv add halide +``` + +This distribution depends on matching versions of `halide-bin`, which provides +the compiler and C++ development files, and `halide-runtime`, which provides the +standalone `halide.runtime` API. Package managers install both automatically. +For a small deployment that only calls precompiled AOT kernels, install +`halide-runtime` directly instead. + ## Using Halide from C++ Halide is also available as a C++ library. This package provides the development From b4270152125312ea727a35b3c13c1b2ca5d24407 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Fri, 21 Aug 2026 21:25:52 -0400 Subject: [PATCH 10/39] Fix split Python package CI failures --- pyproject.toml | 35 +++++++ python_bindings/halide-bin/pyproject.toml | 2 +- .../src/halide/runtime/PyRuntimeBuffer.cpp | 22 +++-- uv.lock | 99 +++++++++++++++++-- 4 files changed, 142 insertions(+), 16 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index de993e2d74f2..9539bc26fdf2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,10 @@ members = [ [dependency-groups] dev = ["pybind11>=2.11.1", "scikit-build-core>=1.0.3", "setuptools-scm>=8.3.1"] apps = [ + "imageio>=2", + "numpy>=1.26", "onnx==1.19.0; platform_machine != 'armv8l' and platform_machine != 'armv7l'", + "pillow; platform_machine == 'armv8l' or platform_machine == 'armv7l'", "protobuf>=7; platform_machine != 'armv8l' and platform_machine != 'armv7l'", "pytest; platform_machine != 'armv8l' and platform_machine != 'armv7l'", ] @@ -69,6 +72,34 @@ conflicts = [ ], ] +# Both packages use build-backend hooks to pin their sibling distributions to +# the exact SCM-derived version in published artifacts. Supplying the otherwise +# static metadata here lets uv resolve the workspace without executing those +# hooks (and consequently trying to build halide-bin before LLVM is configured). +# uv requires a version for direct/workspace sources; these resolution-only +# base versions are kept in sync with the release version by tbump below. +[[tool.uv.dependency-metadata]] +name = "halide" +version = "22.0.0" +requires-python = ">=3.10" +requires-dist = [ + "halide-bin", + "halide-runtime", + "imageio>=2", + "pillow; platform_machine == 'armv8l' or platform_machine == 'armv7l'", +] + +[[tool.uv.dependency-metadata]] +name = "halide-runtime" +version = "22.0.0" +requires-python = ">=3.10" +requires-dist = ["numpy>=1.26"] + +[[tool.uv.dependency-metadata]] +name = "halide-bin" +version = "22.0.0" +requires-python = ">=3.10" + [tool.tbump] github_url = "https://github.com/halide/Halide/" @@ -88,6 +119,10 @@ search = "VERSION {current_version}" src = "python_bindings/CMakeLists.txt" search = "VERSION {current_version}" +[[tool.tbump.file]] +src = "pyproject.toml" +search = 'version = "{current_version}"' + [tool.ruff.lint] select = ["E4", "E7", "E9", "F", "FURB", "PERF", "RUF", "SIM", "UP"] ignore = ["UP045", "SIM108"] diff --git a/python_bindings/halide-bin/pyproject.toml b/python_bindings/halide-bin/pyproject.toml index 0a323b223675..c3c54b6a6872 100644 --- a/python_bindings/halide-bin/pyproject.toml +++ b/python_bindings/halide-bin/pyproject.toml @@ -65,7 +65,7 @@ sdist.include = [ "../../vcpkg-configuration.json" = "vcpkg-configuration.json" [tool.scikit-build.wheel.force-include] -"python_bindings/halide-bin/src/halide/bin/__init__.py" = "halide/bin/__init__.py" +"src/halide/bin/__init__.py" = "halide/bin/__init__.py" [tool.scikit-build.cmake.define] CMAKE_DISABLE_FIND_PACKAGE_JPEG = true diff --git a/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp b/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp index 4ad2d5e2c33a..4f5ca4701071 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp +++ b/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp @@ -162,7 +162,7 @@ class Buffer { return result; } - Buffer view(RuntimeBuffer buffer) const { + Buffer view(const RuntimeBuffer &buffer) const { Buffer result = from_runtime(buffer, unique_name(), true); result.owner_ = owner_; result.identity_ = identity_; @@ -422,7 +422,9 @@ void define_buffer(py::module_ &m) { .def("copy_from", [](Buffer &b, const Buffer &other) { b.runtime_buffer().copy_from(other.runtime_buffer()); }) .def("reverse_axes", [](const Buffer &b) { std::vector order; - for (int i = b.runtime_buffer().dimensions() - 1; i >= 0; --i) order.push_back(i); + for (int i = b.runtime_buffer().dimensions() - 1; i >= 0; --i) { + order.push_back(i); + } return b.view(b.runtime_buffer().transposed(order)); }) .def("add_dimension", [](Buffer &b) { b.runtime_buffer().add_dimension(); }) .def("allocate", [](Buffer &b) { b.runtime_buffer().allocate(nullptr, nullptr); }) @@ -462,21 +464,29 @@ void define_buffer(py::module_ &m) { .def("device_free", [](Buffer &b) { return b.runtime_buffer().device_free(nullptr); }) .def("device_sync", [](Buffer &b) { return b.runtime_buffer().device_sync(nullptr); }) .def("set_min", [](Buffer &b, const std::vector &mins) { - if (mins.size() > static_cast(b.runtime_buffer().dimensions())) throw py::value_error("Too many arguments"); + if (mins.size() > static_cast(b.runtime_buffer().dimensions())) { + throw py::value_error("Too many arguments"); + } b.runtime_buffer().set_min(mins); }) .def("contains", [](const Buffer &b, const std::vector &coords) { - if (coords.size() > static_cast(b.runtime_buffer().dimensions())) throw py::value_error("Too many arguments"); + if (coords.size() > static_cast(b.runtime_buffer().dimensions())) { + throw py::value_error("Too many arguments"); + } return b.runtime_buffer().contains(coords); }) .def("__getitem__", [](Buffer &b, int pos) { return b.getitem({pos}); }) .def("__getitem__", [](Buffer &b, const std::vector &pos) { return b.getitem(pos); }) .def("__setitem__", [](Buffer &b, int pos, const py::object &value) { return b.setitem({pos}, value); }) .def("__setitem__", [](Buffer &b, const std::vector &pos, const py::object &value) { return b.setitem(pos, value); }) .def("__repr__", [](const Buffer &b) { - if (!b.defined()) return std::string(""); + if (!b.defined()) { + return std::string(""); + } std::ostringstream out; out << "dim[i]; out << "[" << d.min << "," << d.extent << "," << d.stride << "]"; } diff --git a/uv.lock b/uv.lock index ebd169bdf315..b9bd40f62ca7 100644 --- a/uv.lock +++ b/uv.lock @@ -24,6 +24,23 @@ members = [ "halide-workspace", ] +[[manifest.dependency-metadata]] +name = "halide" +version = "22.0.0" +requires-dist = ["halide-bin", "halide-runtime", "imageio>=2", "pillow ; platform_machine == 'armv7l' or platform_machine == 'armv8l'"] +requires-python = ">=3.10" + +[[manifest.dependency-metadata]] +name = "halide-bin" +version = "22.0.0" +requires-python = ">=3.10" + +[[manifest.dependency-metadata]] +name = "halide-runtime" +version = "22.0.0" +requires-dist = ["numpy>=1.26"] +requires-python = ">=3.10" + [[package]] name = "accessible-pygments" version = "0.0.5" @@ -378,6 +395,7 @@ wheels = [ [[package]] name = "halide" +version = "22.0.0" source = { editable = "python_bindings/halide" } dependencies = [ { name = "halide-bin" }, @@ -389,15 +407,15 @@ dependencies = [ [package.metadata] requires-dist = [ - { name = "halide-bin", editable = "python_bindings/halide-bin" }, - { name = "halide-runtime", editable = "python_bindings/halide-runtime" }, - { name = "imageio", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=2" }, - { name = "imageio", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=2", index = "https://piwheels.org/simple" }, - { name = "pillow", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", index = "https://piwheels.org/simple" }, + { name = "halide-bin" }, + { name = "halide-runtime" }, + { name = "imageio", specifier = ">=2" }, + { name = "pillow", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'" }, ] [[package]] name = "halide-bin" +version = "22.0.0" source = { editable = "python_bindings/halide-bin" } [[package]] @@ -474,6 +492,7 @@ wheels = [ [[package]] name = "halide-runtime" +version = "22.0.0" source = { editable = "python_bindings/halide-runtime" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, @@ -484,10 +503,7 @@ dependencies = [ ] [package.metadata] -requires-dist = [ - { name = "numpy", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=1.26" }, - { name = "numpy", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=1.26", index = "https://piwheels.org/simple" }, -] +requires-dist = [{ name = "numpy", specifier = ">=1.26" }] [[package]] name = "halide-workspace" @@ -496,14 +512,30 @@ source = { virtual = "." } [package.dev-dependencies] apps = [ + { name = "imageio", version = "2.37.4", source = { registry = "https://piwheels.org/simple" }, marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "imageio", version = "2.37.4", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "onnx", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pillow", version = "12.3.0", source = { registry = "https://piwheels.org/simple" }, marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "protobuf", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "pytest", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, ] ci-base = [ { name = "cmake" }, + { name = "imageio", version = "2.37.4", source = { registry = "https://piwheels.org/simple" }, marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "imageio", version = "2.37.4", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "ninja" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "onnx", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "pillow", version = "12.3.0", source = { registry = "https://piwheels.org/simple" }, marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l' or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "pre-commit" }, { name = "protobuf", marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "pybind11" }, @@ -516,8 +548,16 @@ ci-base = [ ci-llvm-21 = [ { name = "cmake" }, { name = "halide-llvm", version = "21.1.8", source = { registry = "https://pypi.halide-lang.org/simple" } }, + { name = "imageio", version = "2.37.4", source = { registry = "https://piwheels.org/simple" }, marker = "(platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "imageio", version = "2.37.4", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra != 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "ninja" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21') or (python_full_version < '3.11' and platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra != 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra != 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "onnx", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'" }, + { name = "pillow", version = "12.3.0", source = { registry = "https://piwheels.org/simple" }, marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'" }, { name = "pre-commit" }, { name = "protobuf", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'" }, { name = "pybind11" }, @@ -530,8 +570,16 @@ ci-llvm-21 = [ ci-llvm-22 = [ { name = "cmake" }, { name = "halide-llvm", version = "22.1.7", source = { registry = "https://pypi.halide-lang.org/simple" } }, + { name = "imageio", version = "2.37.4", source = { registry = "https://piwheels.org/simple" }, marker = "(platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "imageio", version = "2.37.4", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "ninja" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version < '3.11' and platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "onnx", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'" }, + { name = "pillow", version = "12.3.0", source = { registry = "https://piwheels.org/simple" }, marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'" }, { name = "pre-commit" }, { name = "protobuf", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'" }, { name = "pybind11" }, @@ -544,8 +592,16 @@ ci-llvm-22 = [ ci-llvm-main = [ { name = "cmake" }, { name = "halide-llvm", version = "23.0.0.dev100667+g9bf20bdf", source = { registry = "https://pypi.halide-lang.org/simple" } }, + { name = "imageio", version = "2.37.4", source = { registry = "https://piwheels.org/simple" }, marker = "(platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "imageio", version = "2.37.4", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "ninja" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version < '3.11' and platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version >= '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version < '3.11' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version == '3.11.*' and platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version == '3.11.*' and platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://piwheels.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-main') or (python_full_version >= '3.12' and platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine != 'armv7l' and platform_machine != 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv7l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-22' and extra == 'group-16-halide-workspace-ci-llvm-main') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-22') or (platform_machine == 'armv8l' and extra == 'group-16-halide-workspace-ci-llvm-21' and extra == 'group-16-halide-workspace-ci-llvm-main')" }, { name = "onnx", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'" }, + { name = "pillow", version = "12.3.0", source = { registry = "https://piwheels.org/simple" }, marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'" }, { name = "pre-commit" }, { name = "protobuf", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'" }, { name = "pybind11" }, @@ -585,14 +641,24 @@ tools = [ [package.metadata.requires-dev] apps = [ + { name = "imageio", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=2" }, + { name = "imageio", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=2", index = "https://piwheels.org/simple" }, + { name = "numpy", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=1.26" }, + { name = "numpy", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=1.26", index = "https://piwheels.org/simple" }, { name = "onnx", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = "==1.19.0" }, + { name = "pillow", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", index = "https://piwheels.org/simple" }, { name = "protobuf", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=7" }, { name = "pytest", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'" }, ] ci-base = [ { name = "cmake", specifier = ">=3.28" }, + { name = "imageio", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=2" }, + { name = "imageio", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=2", index = "https://piwheels.org/simple" }, { name = "ninja", specifier = ">=1.11,!=1.13.0" }, + { name = "numpy", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=1.26" }, + { name = "numpy", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=1.26", index = "https://piwheels.org/simple" }, { name = "onnx", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = "==1.19.0" }, + { name = "pillow", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", index = "https://piwheels.org/simple" }, { name = "pre-commit", specifier = ">=4" }, { name = "protobuf", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=7" }, { name = "pybind11", specifier = ">=2.11.1" }, @@ -605,8 +671,13 @@ ci-base = [ ci-llvm-21 = [ { name = "cmake", specifier = ">=3.28" }, { name = "halide-llvm", specifier = "~=21.1.0", index = "https://pypi.halide-lang.org/simple" }, + { name = "imageio", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=2" }, + { name = "imageio", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=2", index = "https://piwheels.org/simple" }, { name = "ninja", specifier = ">=1.11,!=1.13.0" }, + { name = "numpy", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=1.26" }, + { name = "numpy", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=1.26", index = "https://piwheels.org/simple" }, { name = "onnx", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = "==1.19.0" }, + { name = "pillow", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", index = "https://piwheels.org/simple" }, { name = "pre-commit", specifier = ">=4" }, { name = "protobuf", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=7" }, { name = "pybind11", specifier = ">=2.11.1" }, @@ -619,8 +690,13 @@ ci-llvm-21 = [ ci-llvm-22 = [ { name = "cmake", specifier = ">=3.28" }, { name = "halide-llvm", specifier = "~=22.1.0", index = "https://pypi.halide-lang.org/simple" }, + { name = "imageio", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=2" }, + { name = "imageio", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=2", index = "https://piwheels.org/simple" }, { name = "ninja", specifier = ">=1.11,!=1.13.0" }, + { name = "numpy", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=1.26" }, + { name = "numpy", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=1.26", index = "https://piwheels.org/simple" }, { name = "onnx", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = "==1.19.0" }, + { name = "pillow", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", index = "https://piwheels.org/simple" }, { name = "pre-commit", specifier = ">=4" }, { name = "protobuf", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=7" }, { name = "pybind11", specifier = ">=2.11.1" }, @@ -633,8 +709,13 @@ ci-llvm-22 = [ ci-llvm-main = [ { name = "cmake", specifier = ">=3.28" }, { name = "halide-llvm", specifier = "~=23.0.0.dev0", index = "https://pypi.halide-lang.org/simple" }, + { name = "imageio", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=2" }, + { name = "imageio", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=2", index = "https://piwheels.org/simple" }, { name = "ninja", specifier = ">=1.11,!=1.13.0" }, + { name = "numpy", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=1.26" }, + { name = "numpy", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", specifier = ">=1.26", index = "https://piwheels.org/simple" }, { name = "onnx", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = "==1.19.0" }, + { name = "pillow", marker = "platform_machine == 'armv7l' or platform_machine == 'armv8l'", index = "https://piwheels.org/simple" }, { name = "pre-commit", specifier = ">=4" }, { name = "protobuf", marker = "platform_machine != 'armv7l' and platform_machine != 'armv8l'", specifier = ">=7" }, { name = "pybind11", specifier = ">=2.11.1" }, From d515c86b979cfa7952e442a26c2824c32706fc1f Mon Sep 17 00:00:00 2001 From: "halide-ci[bot]" <266445882+halide-ci[bot]@users.noreply.github.com> Date: Sat, 22 Aug 2026 01:30:53 +0000 Subject: [PATCH 11/39] Apply pre-commit auto-fixes --- uv.lock | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/uv.lock b/uv.lock index b9bd40f62ca7..34840d322686 100644 --- a/uv.lock +++ b/uv.lock @@ -2,12 +2,12 @@ version = 1 revision = 3 requires-python = ">=3.10" resolution-markers = [ - "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", - "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] conflicts = [[ @@ -361,10 +361,10 @@ name = "docutils" version = "0.22.4" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] sdist = { url = "https://files.pythonhosted.org/packages/ae/b6/03bb70946330e88ffec97aefd3ea75ba575cb2e762061e0e62a213befee8/docutils-0.22.4.tar.gz", hash = "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968", size = 2291750, upload-time = "2025-12-18T19:00:26.443Z" } @@ -423,12 +423,12 @@ name = "halide-llvm" version = "21.1.8" source = { registry = "https://pypi.halide-lang.org/simple" } resolution-markers = [ - "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", - "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] wheels = [ @@ -447,12 +447,12 @@ name = "halide-llvm" version = "22.1.7" source = { registry = "https://pypi.halide-lang.org/simple" } resolution-markers = [ - "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", - "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] wheels = [ @@ -471,12 +471,12 @@ name = "halide-llvm" version = "23.0.0.dev100667+g9bf20bdf" source = { registry = "https://pypi.halide-lang.org/simple" } resolution-markers = [ - "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", - "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version < '3.11' and platform_machine == 'armv7l') or (python_full_version < '3.11' and platform_machine == 'armv8l')", "python_full_version < '3.11' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] wheels = [ @@ -854,10 +854,10 @@ name = "markdown-it-py" version = "4.2.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ @@ -1047,10 +1047,10 @@ name = "myst-parser" version = "5.1.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ @@ -1549,10 +1549,10 @@ name = "pydata-sphinx-theme" version = "0.20.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ @@ -1859,8 +1859,8 @@ name = "sphinx" version = "9.1.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ @@ -1908,10 +1908,10 @@ name = "sphinx-design" version = "0.7.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", - "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", "python_full_version >= '3.13' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version >= '3.12' and platform_machine == 'armv7l') or (python_full_version >= '3.12' and platform_machine == 'armv8l')", "python_full_version == '3.12.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", + "(python_full_version == '3.11.*' and platform_machine == 'armv7l') or (python_full_version == '3.11.*' and platform_machine == 'armv8l')", "python_full_version == '3.11.*' and platform_machine != 'armv7l' and platform_machine != 'armv8l'", ] dependencies = [ From ecbcc966bac396e3c591dcfdeef28fc80921df48 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Fri, 21 Aug 2026 21:35:27 -0400 Subject: [PATCH 12/39] Avoid dangling-reference compiler warning --- src/AssociativeOpsTable.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/AssociativeOpsTable.cpp b/src/AssociativeOpsTable.cpp index 0ec6a7399001..b049df55ee93 100644 --- a/src/AssociativeOpsTable.cpp +++ b/src/AssociativeOpsTable.cpp @@ -375,7 +375,8 @@ const vector &get_ops_table(const vector &exprs) { Expr get_associative_identity(Type type, IRNodeType root) { std::scoped_lock lock_guard(ops_table_lock()); - const vector &table = get_ops_table_helper({type}, root, 1); + const vector types{type}; + const vector &table = get_ops_table_helper(types, root, 1); if (table.empty()) { return Expr(); } From 64787169849dd6caa946b8852dd44f7900ee766c Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Fri, 21 Aug 2026 21:42:38 -0400 Subject: [PATCH 13/39] Track the halide-bin Python stub --- .gitignore | 2 ++ .../halide-bin/src/halide/bin/__init__.py | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 python_bindings/halide-bin/src/halide/bin/__init__.py diff --git a/.gitignore b/.gitignore index 95769621ee19..4a013d25b796 100644 --- a/.gitignore +++ b/.gitignore @@ -109,6 +109,8 @@ stdout.txt # Directories bin/ +!python_bindings/halide-bin/src/halide/bin/ +!python_bindings/halide-bin/src/halide/bin/__init__.py distrib/ lib/ lib64/ diff --git a/python_bindings/halide-bin/src/halide/bin/__init__.py b/python_bindings/halide-bin/src/halide/bin/__init__.py new file mode 100644 index 000000000000..c51ac7587387 --- /dev/null +++ b/python_bindings/halide-bin/src/halide/bin/__init__.py @@ -0,0 +1,24 @@ +import ctypes +import os +from pathlib import Path + + +def install_dir(): + # CMake's binary payload is installed under the shared ``halide`` package. + return str(Path(__file__).resolve().parents[1]) + + +_root = Path(install_dir()) +_bin_dir = _root / "bin" +if hasattr(os, "add_dll_directory") and _bin_dir.is_dir(): + os.add_dll_directory(str(_bin_dir)) +for _relpath in ( + "bin/Halide.dll", + "lib/libHalide.dylib", + "lib64/libHalide.so", + "lib/libHalide.so", +): + _library = _root / _relpath + if _library.exists(): + ctypes.CDLL(str(_library)) + break From c4f40016345228fb1427c179c637a01637a34297 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Fri, 21 Aug 2026 22:26:21 -0400 Subject: [PATCH 14/39] Fix platform wheel repair commands --- .github/workflows/pip.yml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pip.yml b/.github/workflows/pip.yml index fa80718ab20b..559943b70698 100644 --- a/.github/workflows/pip.yml +++ b/.github/workflows/pip.yml @@ -233,13 +233,20 @@ jobs: CMAKE_GENERATOR=Ninja PIP_FIND_LINKS='${{ github.workspace }}\dist-bin' SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE='{local_scheme="no-local-version"}' - # halide_.pyd/.so now depends on a Halide.dll/libHalide supplied by the - # already-installed halide-bin package, not one bundled in this wheel -- - # `--exclude` stops delvewheel from vendoring a second copy of it, while - # `--add-path` lets its dependency scan actually resolve it. + # halide_.pyd/.so depends on Halide.dll/libHalide supplied by the + # separately installed halide-bin package. Tell each platform's wheel + # repair tool that this dependency is intentionally external instead + # of trying to vendor it into the halide wheel. + CIBW_REPAIR_WHEEL_COMMAND_LINUX: > + auditwheel repair --exclude libHalide.so -w {dest_dir} {wheel} + CIBW_REPAIR_WHEEL_COMMAND_MACOS: > + delocate-wheel --require-archs {delocate_archs} + --exclude libHalide.dylib -w {dest_dir} -v {wheel} + # delvewheel still needs to locate Halide.dll before it can exclude + # it, so point it at the unpacked halide-bin wheel on Windows. CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: > delvewheel repair --ignore-existing --exclude Halide.dll - --add-path '${{ github.workspace }}\opt\halide-bin\halide\bin' + --add-path ${{ github.workspace }}\opt\halide-bin\halide\bin -w {dest_dir} {wheel} # halide-bin isn't published yet during this CI run, so resolve it # from the wheel we just downloaded instead of the package index. From 34d75b85b572b6def4921ee86ceac6ebd2ddf13b Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Fri, 21 Aug 2026 22:29:16 -0400 Subject: [PATCH 15/39] Fix relocated Python test image paths --- python_bindings/halide/apps/CMakeLists.txt | 2 +- python_bindings/halide/tutorial/lesson_02_input_image.py | 2 +- .../halide/tutorial/lesson_07_multi_stage_pipelines.py | 2 +- python_bindings/halide/tutorial/lesson_09_update_definitions.py | 2 +- python_bindings/halide/tutorial/lesson_12_using_the_gpu.py | 2 +- python_bindings/halide/tutorial/lesson_23_serialization.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/python_bindings/halide/apps/CMakeLists.txt b/python_bindings/halide/apps/CMakeLists.txt index 55b9c1176466..65eeb53341be 100644 --- a/python_bindings/halide/apps/CMakeLists.txt +++ b/python_bindings/halide/apps/CMakeLists.txt @@ -26,7 +26,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") include(AddPythonTest) set(TEST_TMPDIR "$") -set(TEST_IMAGES_DIR "$") +set(TEST_IMAGES_DIR "$") set(APPS bilateral_grid blur identity interpolate local_laplacian) diff --git a/python_bindings/halide/tutorial/lesson_02_input_image.py b/python_bindings/halide/tutorial/lesson_02_input_image.py index bffd53743975..7bfb4e1527ec 100644 --- a/python_bindings/halide/tutorial/lesson_02_input_image.py +++ b/python_bindings/halide/tutorial/lesson_02_input_image.py @@ -14,7 +14,7 @@ def main(): # First we'll load the input image we wish to brighten. image_path = os.path.join( - os.path.dirname(__file__), "../../tutorial/images/rgb.png" + os.path.dirname(__file__), "../../../tutorial/images/rgb.png" ) # We create a hl.Buffer object to wrap the numpy array diff --git a/python_bindings/halide/tutorial/lesson_07_multi_stage_pipelines.py b/python_bindings/halide/tutorial/lesson_07_multi_stage_pipelines.py index 1b37f8e2fc9e..14f3d80ddf27 100755 --- a/python_bindings/halide/tutorial/lesson_07_multi_stage_pipelines.py +++ b/python_bindings/halide/tutorial/lesson_07_multi_stage_pipelines.py @@ -16,7 +16,7 @@ def main(): x, y, c = hl.Var("x"), hl.Var("y"), hl.Var("c") image_path = os.path.join( - os.path.dirname(__file__), "../../tutorial/images/rgb.png" + os.path.dirname(__file__), "../../../tutorial/images/rgb.png" ) # Now we'll express a multi-stage pipeline that blurs an image diff --git a/python_bindings/halide/tutorial/lesson_09_update_definitions.py b/python_bindings/halide/tutorial/lesson_09_update_definitions.py index 7a3a1390b49a..f41dc38799ea 100755 --- a/python_bindings/halide/tutorial/lesson_09_update_definitions.py +++ b/python_bindings/halide/tutorial/lesson_09_update_definitions.py @@ -18,7 +18,7 @@ def main(): # Load a grayscale image to use as an input. image_path = os.path.join( - os.path.dirname(__file__), "../../tutorial/images/gray.png" + os.path.dirname(__file__), "../../../tutorial/images/gray.png" ) input_data = halide.imageio.imread(image_path) if True: diff --git a/python_bindings/halide/tutorial/lesson_12_using_the_gpu.py b/python_bindings/halide/tutorial/lesson_12_using_the_gpu.py index f743dd769e68..3dfca6b13ce2 100755 --- a/python_bindings/halide/tutorial/lesson_12_using_the_gpu.py +++ b/python_bindings/halide/tutorial/lesson_12_using_the_gpu.py @@ -232,7 +232,7 @@ def test_correctness(self, reference_output): def main(): # Load an input image. image_path = os.path.join( - os.path.dirname(__file__), "../../tutorial/images/rgb.png" + os.path.dirname(__file__), "../../../tutorial/images/rgb.png" ) input = hl.Buffer(halide.imageio.imread(image_path)) diff --git a/python_bindings/halide/tutorial/lesson_23_serialization.py b/python_bindings/halide/tutorial/lesson_23_serialization.py index 4e6792948ccd..399d64226211 100755 --- a/python_bindings/halide/tutorial/lesson_23_serialization.py +++ b/python_bindings/halide/tutorial/lesson_23_serialization.py @@ -76,7 +76,7 @@ def main(): if True: # Lets load a color 8-bit input and connect it to an ImageParam image_path = os.path.join( - os.path.dirname(__file__), "../../tutorial/images/rgb.png" + os.path.dirname(__file__), "../../../tutorial/images/rgb.png" ) rgb_image = hl.Buffer(halide.imageio.imread(image_path)) input = hl.ImageParam(hl.UInt(8), 3, "input") From 85159d3816e448fe318248bb9305c27b028c65c2 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Fri, 21 Aug 2026 22:50:13 -0400 Subject: [PATCH 16/39] Resolve pip LLVM dependency from uv lock --- .github/workflows/pip.yml | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/.github/workflows/pip.yml b/.github/workflows/pip.yml index 559943b70698..141114a48089 100644 --- a/.github/workflows/pip.yml +++ b/.github/workflows/pip.yml @@ -8,8 +8,6 @@ on: types: [ published ] env: - # TODO: detect this from repo somehow: https://github.com/halide/Halide/issues/8406 - LLVM_VERSION: 22.1.0 FLATBUFFERS_VERSION: 23.5.26 WABT_VERSION: 1.0.39 @@ -47,6 +45,7 @@ jobs: fetch-depth: 0 fetch-tags: true + - uses: astral-sh/setup-uv@v7 - uses: ilammy/msvc-dev-cmd@v1 - uses: lukka/get-cmake@v4.4.2 with: @@ -56,13 +55,22 @@ jobs: # LLVM ######################################################################## + - name: Resolve Halide major version + id: halide-version + shell: bash + run: | + MAJOR=$(awk '$2 == "HALIDE_VERSION_MAJOR" { print $3 }' \ + src/runtime/HalideRuntime.h) + [[ "$MAJOR" =~ ^[0-9]+$ ]] + echo "major=$MAJOR" >> "$GITHUB_OUTPUT" + - name: Install LLVM if: matrix.os != 'ubuntu-latest' shell: bash run: | - pip install "halide-llvm==${{ env.LLVM_VERSION }}" \ - --extra-index-url https://pypi.halide-lang.org/simple/ - echo "Halide_LLVM_ROOT=$(halide-llvm --prefix)" >> "$GITHUB_ENV" + uv sync --frozen --group ci-llvm-${{ steps.halide-version.outputs.major }} \ + --no-install-workspace + echo "Halide_LLVM_ROOT=$(uv run --no-sync halide-llvm --prefix)" >> "$GITHUB_ENV" ######################################################################## # Wheel (no CPython ABI to matrix over -- halide-bin is a plain @@ -80,10 +88,12 @@ jobs: env: CIBW_BUILD: "cp312-${{ matrix.platform_tag }}" CIBW_BEFORE_ALL_LINUX: > - /opt/python/cp312-cp312/bin/pip install cmake ninja - "halide-llvm==${{ env.LLVM_VERSION }}" - --extra-index-url https://pypi.halide-lang.org/simple/ && - export PATH="/opt/python/cp312-cp312/bin:$PATH" && + /opt/python/cp312-cp312/bin/pip install uv && + cd {project} && + uv sync --frozen --python /opt/python/cp312-cp312/bin/python + --group ci-llvm-${{ steps.halide-version.outputs.major }} + --no-install-workspace && + export PATH="{project}/.venv/bin:$PATH" && mkdir -p {project}/opt && ln -s $(halide-llvm --prefix) {project}/opt/llvm && git clone --depth=1 -b v${{ env.FLATBUFFERS_VERSION }} From 21211bb39dfda6cabc2f78291aae1502f21b0ff2 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Fri, 21 Aug 2026 23:00:57 -0400 Subject: [PATCH 17/39] Use packaged wheel build dependencies Fixes #8406 --- .github/workflows/pip.yml | 58 ++--------------------- pyproject.toml | 2 + python_bindings/halide-bin/pyproject.toml | 7 ++- 3 files changed, 12 insertions(+), 55 deletions(-) diff --git a/.github/workflows/pip.yml b/.github/workflows/pip.yml index 141114a48089..fff1d276e884 100644 --- a/.github/workflows/pip.yml +++ b/.github/workflows/pip.yml @@ -7,10 +7,6 @@ on: release: types: [ published ] -env: - FLATBUFFERS_VERSION: 23.5.26 - WABT_VERSION: 1.0.39 - concurrency: group: '${{ github.workflow }}-${{ github.event.pull_request.head.label || github.head_ref || github.ref }}' cancel-in-progress: true @@ -95,64 +91,18 @@ jobs: --no-install-workspace && export PATH="{project}/.venv/bin:$PATH" && mkdir -p {project}/opt && - ln -s $(halide-llvm --prefix) {project}/opt/llvm && - git clone --depth=1 -b v${{ env.FLATBUFFERS_VERSION }} - https://github.com/google/flatbuffers /tmp/fb-src && - cmake -G Ninja -S /tmp/fb-src -B /tmp/fb-build - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX={project}/opt/flatbuffers - -DFLATBUFFERS_BUILD_TESTS=NO && - cmake --build /tmp/fb-build --target install && - git clone --depth=1 --recurse-submodules -b ${{ env.WABT_VERSION }} - https://github.com/WebAssembly/wabt /tmp/wabt-src && - cmake -G Ninja -S /tmp/wabt-src -B /tmp/wabt-build - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_POSITION_INDEPENDENT_CODE=ON - -DCMAKE_INSTALL_PREFIX={project}/opt/wabt - -DWITH_EXCEPTIONS=ON - -DBUILD_TESTS=OFF - -DBUILD_TOOLS=OFF - -DBUILD_LIBWASM=OFF - -DUSE_INTERNAL_SHA256=ON && - cmake --build /tmp/wabt-build --target install - CIBW_BEFORE_ALL_MACOS: > - git clone --depth=1 -b v${{ env.FLATBUFFERS_VERSION }} - https://github.com/google/flatbuffers /tmp/fb-src && - cmake -G Ninja -S /tmp/fb-src -B /tmp/fb-build - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX={project}/opt/flatbuffers - -DFLATBUFFERS_BUILD_TESTS=NO && - cmake --build /tmp/fb-build --target install && - git clone --depth=1 --recurse-submodules -b ${{ env.WABT_VERSION }} - https://github.com/WebAssembly/wabt /tmp/wabt-src && - cmake -G Ninja -S /tmp/wabt-src -B /tmp/wabt-build - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX={project}/opt/wabt - -DWITH_EXCEPTIONS=ON - -DBUILD_TESTS=OFF - -DBUILD_TOOLS=OFF - -DBUILD_LIBWASM=OFF - -DUSE_INTERNAL_SHA256=ON && - cmake --build /tmp/wabt-build --target install - CIBW_BEFORE_ALL_WINDOWS: > - git clone --depth=1 -b v${{ env.FLATBUFFERS_VERSION }} - https://github.com/google/flatbuffers %TEMP%\fb-src && - cmake -G Ninja -S %TEMP%\fb-src -B %TEMP%\fb-build - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX={project}/opt/flatbuffers - -DFLATBUFFERS_BUILD_TESTS=NO && - cmake --build %TEMP%\fb-build --target install + ln -s $(halide-llvm --prefix) {project}/opt/llvm CIBW_ENVIRONMENT_LINUX: > Halide_LLVM_ROOT=/project/opt/llvm - CMAKE_PREFIX_PATH=/project/opt + PIP_EXTRA_INDEX_URL=https://pypi.halide-lang.org/simple/ SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE_BIN='{local_scheme="no-local-version"}' CIBW_ENVIRONMENT_MACOS: > - CMAKE_PREFIX_PATH='${{ github.workspace }}/opt' + PIP_EXTRA_INDEX_URL=https://pypi.halide-lang.org/simple/ Python_ROOT_DIR='' SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE_BIN='{local_scheme="no-local-version"}' CIBW_ENVIRONMENT_WINDOWS: > CMAKE_GENERATOR=Ninja - CMAKE_PREFIX_PATH='${{ github.workspace }}\opt' + PIP_EXTRA_INDEX_URL=https://pypi.halide-lang.org/simple/ SETUPTOOLS_SCM_OVERRIDES_FOR_HALIDE_BIN='{local_scheme="no-local-version"}' CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: delvewheel repair --ignore-existing -w {dest_dir} {wheel} diff --git a/pyproject.toml b/pyproject.toml index 9539bc26fdf2..67447a75bb74 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,6 +46,8 @@ ci-llvm-21 = [{ include-group = "ci-base" }, "halide-llvm~=21.1.0"] [tool.uv.sources] halide-bin = { workspace = true } +halide-flatbuffers = { index = "halide" } +halide-wabt = { index = "halide" } halide-runtime = { workspace = true } halide-llvm = { index = "halide" } imageio = { index = "piwheels", marker = "platform_machine == 'armv8l' or platform_machine == 'armv7l'" } diff --git a/python_bindings/halide-bin/pyproject.toml b/python_bindings/halide-bin/pyproject.toml index c3c54b6a6872..be3445975786 100644 --- a/python_bindings/halide-bin/pyproject.toml +++ b/python_bindings/halide-bin/pyproject.toml @@ -1,5 +1,10 @@ [build-system] -requires = ["scikit-build-core~=1.0.3", "setuptools-scm>=8.3.1"] +requires = [ + "halide-flatbuffers==23.5.26", + "halide-wabt==1.0.39; sys_platform != 'win32'", + "scikit-build-core~=1.0.3", + "setuptools-scm>=8.3.1", +] build-backend = "scikit_build_core.build" [project] From 6b403707ad6bbe2c8ae99673479ed497345ebd75 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Fri, 21 Aug 2026 23:15:49 -0400 Subject: [PATCH 18/39] Fix split wheel repair and tests --- .github/workflows/pip.yml | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/.github/workflows/pip.yml b/.github/workflows/pip.yml index fff1d276e884..5afd31bfbac8 100644 --- a/.github/workflows/pip.yml +++ b/.github/workflows/pip.yml @@ -150,8 +150,9 @@ jobs: # all -- its dynamic metadata hook installs the matching halide-bin into # the isolated build environment, where find_package(Halide) discovers # it. Fetch the wheel this platform's build-halide-bin job just produced - # and expose it to pip via PIP_FIND_LINKS. Windows also needs an unpacked - # copy later so delvewheel can resolve (but not vendor) Halide.dll. + # and expose it to pip via PIP_FIND_LINKS. macOS and Windows also need an + # unpacked copy later so the repair tool can resolve (but not vendor) + # libHalide.dylib/Halide.dll. ######################################################################## - uses: actions/download-artifact@v8 @@ -164,8 +165,8 @@ jobs: name: wheels-runtime-${{ matrix.platform_tag }} path: dist-runtime - - name: Unpack halide-bin for Windows wheel repair - if: matrix.os == 'windows-latest' + - name: Unpack halide-bin for wheel repair + if: matrix.os != 'ubuntu-latest' shell: bash run: python -m zipfile -e dist-bin/*.whl opt/halide-bin @@ -200,6 +201,7 @@ jobs: CIBW_REPAIR_WHEEL_COMMAND_LINUX: > auditwheel repair --exclude libHalide.so -w {dest_dir} {wheel} CIBW_REPAIR_WHEEL_COMMAND_MACOS: > + DYLD_LIBRARY_PATH=${{ github.workspace }}/opt/halide-bin/halide/lib delocate-wheel --require-archs {delocate_archs} --exclude libHalide.dylib -w {dest_dir} -v {wheel} # delvewheel still needs to locate Halide.dll before it can exclude @@ -214,16 +216,16 @@ jobs: # bare) per-wheel manylinux test container -- macOS/Windows already # have them on PATH via the get-cmake action above. CIBW_BEFORE_TEST_LINUX: > - pip install cmake ninja && - pip install --no-index --find-links {project}/dist-bin --find-links {project}/dist-runtime halide-bin halide-runtime - CIBW_BEFORE_TEST: pip install --no-index --find-links {project}/dist-bin --find-links {project}/dist-runtime halide-bin halide-runtime + pip install cmake "ninja!=1.13.0" && + pip install --find-links {project}/dist-bin --find-links {project}/dist-runtime halide-bin halide-runtime + CIBW_BEFORE_TEST: pip install --find-links {project}/dist-bin --find-links {project}/dist-runtime halide-bin halide-runtime CIBW_TEST_COMMAND: > - cmake -G Ninja -S {project}/python_bindings/apps -B build -DCMAKE_BUILD_TYPE=Release && + cmake -G Ninja -S {project}/python_bindings/halide/apps -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build && ctest --test-dir build --output-on-failure # Windows puts the Python interpreter in /Scripts, rather than /bin, which CMake doesn't understand. CIBW_TEST_COMMAND_WINDOWS: > - cmake -G Ninja -S {project}/python_bindings/apps -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=%VIRTUAL_ENV% && + cmake -G Ninja -S {project}/python_bindings/halide/apps -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=%VIRTUAL_ENV% && cmake --build build && ctest --test-dir build --output-on-failure From 673d4022a8d7818a1ee5deb41e724c1aa4e26451 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Fri, 21 Aug 2026 23:51:46 -0400 Subject: [PATCH 19/39] Fix packaged wheel dependency discovery --- packaging/CMakeLists.txt | 11 ---- .../cmake/InstallPythonTrampoline.cmake | 22 +++++++ .../PythonTrampolineConfig.cmake.in} | 0 .../halide-bin/packaging/CMakeLists.txt | 64 ------------------- .../halide-bin/packaging/ScikitBuild.cmake | 64 +++++++++++++++++++ python_bindings/halide-bin/pyproject.toml | 2 + .../halide/packaging/CMakeLists.txt | 10 --- .../halide/packaging/ScikitBuild.cmake | 17 +++++ .../halide/packaging/cmake/CMakeLists.txt | 19 ------ .../packaging/cmake/TrampolineConfig.cmake.in | 5 -- python_bindings/halide/pyproject.toml | 2 + 11 files changed, 107 insertions(+), 109 deletions(-) create mode 100644 python_bindings/cmake/InstallPythonTrampoline.cmake rename python_bindings/{halide-bin/packaging/TrampolineConfig.cmake.in => cmake/PythonTrampolineConfig.cmake.in} (100%) delete mode 100644 python_bindings/halide-bin/packaging/CMakeLists.txt create mode 100644 python_bindings/halide-bin/packaging/ScikitBuild.cmake create mode 100644 python_bindings/halide/packaging/ScikitBuild.cmake delete mode 100644 python_bindings/halide/packaging/cmake/CMakeLists.txt delete mode 100644 python_bindings/halide/packaging/cmake/TrampolineConfig.cmake.in diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt index 0b3fb346d28b..b2b0db66157b 100644 --- a/packaging/CMakeLists.txt +++ b/packaging/CMakeLists.txt @@ -356,17 +356,6 @@ if (WITH_DOCS) ) endif () -## -# Pip overrides -## - -if (SKBUILD) - add_subdirectory( - "${Halide_SOURCE_DIR}/python_bindings/halide-bin/packaging" - "${CMAKE_CURRENT_BINARY_DIR}/pip" - ) -endif () - ## # General packaging variables. ## diff --git a/python_bindings/cmake/InstallPythonTrampoline.cmake b/python_bindings/cmake/InstallPythonTrampoline.cmake new file mode 100644 index 000000000000..47b356cc68e4 --- /dev/null +++ b/python_bindings/cmake/InstallPythonTrampoline.cmake @@ -0,0 +1,22 @@ +function(_Halide_install_python_trampoline) + cmake_parse_arguments( + PARSE_ARGV 0 arg "" + "PACKAGE;INSTALL_DIR;VERSION_FILE;OUTPUT_DIR;COMPONENT" "" + ) + + set(PACKAGE "${arg_PACKAGE}") + set(INSTALL_DIR "${arg_INSTALL_DIR}") + file(MAKE_DIRECTORY "${arg_OUTPUT_DIR}") + configure_file( + "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/PythonTrampolineConfig.cmake.in" + "${arg_OUTPUT_DIR}/${PACKAGE}Config.cmake" @ONLY + ) + + install( + FILES + "${arg_OUTPUT_DIR}/${PACKAGE}Config.cmake" + "${arg_VERSION_FILE}" + DESTINATION "${SKBUILD_DATA_DIR}/share/cmake/${PACKAGE}" + COMPONENT "${arg_COMPONENT}" + ) +endfunction() diff --git a/python_bindings/halide-bin/packaging/TrampolineConfig.cmake.in b/python_bindings/cmake/PythonTrampolineConfig.cmake.in similarity index 100% rename from python_bindings/halide-bin/packaging/TrampolineConfig.cmake.in rename to python_bindings/cmake/PythonTrampolineConfig.cmake.in diff --git a/python_bindings/halide-bin/packaging/CMakeLists.txt b/python_bindings/halide-bin/packaging/CMakeLists.txt deleted file mode 100644 index b05fea71a552..000000000000 --- a/python_bindings/halide-bin/packaging/CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -## -# Create a trampoline to the real *Config.cmake. -# -# The various wheel directories get grafted to one of an unpredictable set -# of paths determined by sysconfig. The trampoline finds platlib via sysconfig -# before jumping to the real *Config.cmake inside our pip package. - -function(configure_trampoline PACKAGE INSTALL_DIR) - configure_file(TrampolineConfig.cmake.in "${PACKAGE}Config.cmake" @ONLY) -endfunction() - -configure_trampoline(Halide "${Halide_INSTALL_CMAKEDIR}") -configure_trampoline(HalideCompiler "${Halide_INSTALL_COMPILERDIR}") -if (WITH_AUTOSCHEDULERS) - configure_trampoline(HalideAutoschedulers "${Halide_INSTALL_AUTOSCHEDULERSDIR}") -endif () - -install( - FILES - "${CMAKE_CURRENT_BINARY_DIR}/HalideConfig.cmake" - # It's better to duplicate the version file than to trampoline to it, as - # this would require calling find_package(Python) in the version file. - "${CMAKE_CURRENT_BINARY_DIR}/../HalideConfigVersion.cmake" - # It's okay to hard-code the destination because this code is only - # called by scikit-build-core. Installing to /data ultimately installs - # to the Python root installation directory, whose bin/ directory is - # located on the PATH. On Unix systems, this is directly compatible with - # find_package. Python on Windows unfortunately uses Scripts/ instead of - # bin/, which CMake does not understand. These users can add %VIRTUAL_ENV% - # to their CMAKE_PREFIX_PATH. - DESTINATION "${SKBUILD_DATA_DIR}/share/cmake/Halide" - COMPONENT Halide_Development -) - -# Same thing for HalideCompiler -install( - FILES - "${CMAKE_CURRENT_BINARY_DIR}/HalideCompilerConfig.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/../HalideCompilerConfigVersion.cmake" - DESTINATION "${SKBUILD_DATA_DIR}/share/cmake/HalideCompiler" - COMPONENT Halide_Development -) - -# Same thing for HalideAutoschedulers -if (WITH_AUTOSCHEDULERS) - install( - FILES - "${CMAKE_CURRENT_BINARY_DIR}/HalideAutoschedulersConfig.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/../HalideAutoschedulersConfigVersion.cmake" - DESTINATION "${SKBUILD_DATA_DIR}/share/cmake/HalideAutoschedulers" - COMPONENT Halide_Python - ) -endif () - -## -# Set up RPATH for the Python bindings plugin. - -if (WITH_PYTHON_BINDINGS) - _Halide_compute_rpath( - TARGETS Halide_Python - ORIGIN_DIR "${Halide_INSTALL_PYTHONDIR}" - LIB_DIR "${CMAKE_INSTALL_LIBDIR}" - ) -endif () diff --git a/python_bindings/halide-bin/packaging/ScikitBuild.cmake b/python_bindings/halide-bin/packaging/ScikitBuild.cmake new file mode 100644 index 000000000000..53f88be061ba --- /dev/null +++ b/python_bindings/halide-bin/packaging/ScikitBuild.cmake @@ -0,0 +1,64 @@ +# Python build requirements install their CMake packages beneath Python package +# directories rather than directly beneath site-packages. Add those prefixes +# before src resolves its dependencies. +cmake_path(ABSOLUTE_PATH CMAKE_MODULE_PATH BASE_DIRECTORY "${CMAKE_SOURCE_DIR}" NORMALIZE) +include(InstallPythonTrampoline) + +function(_Halide_find_python_build_requirement distribution package_dir result) + if (NOT Python_EXECUTABLE) + message(FATAL_ERROR "Python_EXECUTABLE is required to locate ${distribution}") + endif () + + execute_process( + COMMAND + "${Python_EXECUTABLE}" + -c "from importlib.metadata import distribution; print(distribution('${distribution}').locate_file('${package_dir}'))" + OUTPUT_VARIABLE prefix + OUTPUT_STRIP_TRAILING_WHITESPACE + COMMAND_ERROR_IS_FATAL ANY + ) + if (NOT IS_DIRECTORY "${prefix}") + message(FATAL_ERROR "Could not locate the ${distribution} build requirement") + endif () + + set("${result}" "${prefix}" PARENT_SCOPE) +endfunction() + +_Halide_find_python_build_requirement( + halide-flatbuffers halide-flatbuffers Halide_FLATBUFFERS_BUILD_PREFIX +) +list(PREPEND CMAKE_PREFIX_PATH "${Halide_FLATBUFFERS_BUILD_PREFIX}") + +if (Halide_WASM_BACKEND STREQUAL "wabt") + _Halide_find_python_build_requirement(halide-wabt halide-wabt Halide_WABT_BUILD_PREFIX) + list(PREPEND CMAKE_PREFIX_PATH "${Halide_WABT_BUILD_PREFIX}") +endif () + +# The files consumed here are produced by packaging/CMakeLists.txt, so append +# these wheel-only install rules after the ordinary top-level build graph. +function(_Halide_add_scikit_build_packaging) + set(pip_binary_dir "${Halide_BINARY_DIR}/packaging/pip") + _Halide_install_python_trampoline( + PACKAGE Halide + INSTALL_DIR "${Halide_INSTALL_CMAKEDIR}" + VERSION_FILE "${Halide_BINARY_DIR}/packaging/HalideConfigVersion.cmake" + OUTPUT_DIR "${pip_binary_dir}" + COMPONENT Halide_Development + ) + _Halide_install_python_trampoline( + PACKAGE HalideCompiler + INSTALL_DIR "${Halide_INSTALL_COMPILERDIR}" + VERSION_FILE "${Halide_BINARY_DIR}/packaging/HalideCompilerConfigVersion.cmake" + OUTPUT_DIR "${pip_binary_dir}" + COMPONENT Halide_Development + ) + _Halide_install_python_trampoline( + PACKAGE HalideAutoschedulers + INSTALL_DIR "${Halide_INSTALL_AUTOSCHEDULERSDIR}" + VERSION_FILE "${Halide_BINARY_DIR}/packaging/HalideAutoschedulersConfigVersion.cmake" + OUTPUT_DIR "${pip_binary_dir}" + COMPONENT Halide_Python + ) +endfunction() + +cmake_language(DEFER CALL _Halide_add_scikit_build_packaging) diff --git a/python_bindings/halide-bin/pyproject.toml b/python_bindings/halide-bin/pyproject.toml index be3445975786..d6d13406146a 100644 --- a/python_bindings/halide-bin/pyproject.toml +++ b/python_bindings/halide-bin/pyproject.toml @@ -73,6 +73,8 @@ sdist.include = [ "src/halide/bin/__init__.py" = "halide/bin/__init__.py" [tool.scikit-build.cmake.define] +CMAKE_MODULE_PATH = "python_bindings/cmake" +CMAKE_PROJECT_TOP_LEVEL_INCLUDES = "python_bindings/halide-bin/packaging/ScikitBuild.cmake" CMAKE_DISABLE_FIND_PACKAGE_JPEG = true CMAKE_DISABLE_FIND_PACKAGE_PNG = true FETCHCONTENT_FULLY_DISCONNECTED = true diff --git a/python_bindings/halide/packaging/CMakeLists.txt b/python_bindings/halide/packaging/CMakeLists.txt index b18e0a1c05ad..cc9d097085b6 100644 --- a/python_bindings/halide/packaging/CMakeLists.txt +++ b/python_bindings/halide/packaging/CMakeLists.txt @@ -118,13 +118,3 @@ if (WITH_PYTHON_BINDINGS OR WITH_PYTHON_STUBS) COMPONENT Halide_Python ) endif () - -## -# Pip overrides -## - -if (SKBUILD) - add_subdirectory( - "${Halide_Python_SOURCE_DIR}/halide/packaging/cmake" "${CMAKE_CURRENT_BINARY_DIR}/pip" - ) -endif () diff --git a/python_bindings/halide/packaging/ScikitBuild.cmake b/python_bindings/halide/packaging/ScikitBuild.cmake new file mode 100644 index 000000000000..c5185c833e7c --- /dev/null +++ b/python_bindings/halide/packaging/ScikitBuild.cmake @@ -0,0 +1,17 @@ +# The version file consumed here is produced by this package's ordinary +# packaging directory. Append the wheel-only trampoline rules once the rest of +# the Python bindings build graph has been configured. +cmake_path(ABSOLUTE_PATH CMAKE_MODULE_PATH BASE_DIRECTORY "${CMAKE_SOURCE_DIR}" NORMALIZE) +include(InstallPythonTrampoline) + +function(_Halide_Python_add_scikit_build_packaging) + _Halide_install_python_trampoline( + PACKAGE Halide_Python + INSTALL_DIR "${Halide_Python_INSTALL_CMAKEDIR}" + VERSION_FILE "${Halide_Python_BINARY_DIR}/halide/packaging/Halide_PythonConfigVersion.cmake" + OUTPUT_DIR "${Halide_Python_BINARY_DIR}/halide/packaging/pip" + COMPONENT Halide_Python + ) +endfunction() + +cmake_language(DEFER CALL _Halide_Python_add_scikit_build_packaging) diff --git a/python_bindings/halide/packaging/cmake/CMakeLists.txt b/python_bindings/halide/packaging/cmake/CMakeLists.txt deleted file mode 100644 index 6f97cd5678af..000000000000 --- a/python_bindings/halide/packaging/cmake/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -## -# Create a trampoline to the real Halide_PythonConfig.cmake. -# -# Same trick as the halide-bin CMake trampoline: the wheel -# directory gets grafted to one of an unpredictable set of paths determined -# by sysconfig, so this trampoline finds platlib via sysconfig before jumping -# to the real Halide_PythonConfig.cmake inside the halide package. - -configure_file(TrampolineConfig.cmake.in "Halide_PythonConfig.cmake" @ONLY) - -install( - FILES - "${CMAKE_CURRENT_BINARY_DIR}/Halide_PythonConfig.cmake" - # It's better to duplicate the version file than to trampoline to it, as - # this would require calling find_package(Python) in the version file. - "${CMAKE_CURRENT_BINARY_DIR}/../Halide_PythonConfigVersion.cmake" - DESTINATION "${SKBUILD_DATA_DIR}/share/cmake/Halide_Python" - COMPONENT Halide_Python -) diff --git a/python_bindings/halide/packaging/cmake/TrampolineConfig.cmake.in b/python_bindings/halide/packaging/cmake/TrampolineConfig.cmake.in deleted file mode 100644 index 45d40bad64a5..000000000000 --- a/python_bindings/halide/packaging/cmake/TrampolineConfig.cmake.in +++ /dev/null @@ -1,5 +0,0 @@ -cmake_minimum_required(VERSION 3.28) -include(CMakeFindDependencyMacro) -find_dependency(Python 3 COMPONENTS Interpreter Development.Module) - -include("${Python_SITEARCH}/halide/@Halide_Python_INSTALL_CMAKEDIR@/Halide_PythonConfig.cmake") diff --git a/python_bindings/halide/pyproject.toml b/python_bindings/halide/pyproject.toml index 9cd9f396e817..723b7dac11fa 100644 --- a/python_bindings/halide/pyproject.toml +++ b/python_bindings/halide/pyproject.toml @@ -101,6 +101,8 @@ sdist.exclude = ["dependencies/update-*.sh"] "../../vcpkg-configuration.json" = "vcpkg-configuration.json" [tool.scikit-build.cmake.define] +CMAKE_MODULE_PATH = "cmake" +CMAKE_PROJECT_TOP_LEVEL_INCLUDES = "halide/packaging/ScikitBuild.cmake" CMAKE_DISABLE_FIND_PACKAGE_JPEG = true CMAKE_DISABLE_FIND_PACKAGE_PNG = true Halide_ENABLE_EXCEPTIONS = true From c17da7667317fdcee1b5a197ba41b6db1cd793a8 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 00:40:58 -0400 Subject: [PATCH 20/39] Preserve shared package initializer on Windows --- .github/workflows/pip.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pip.yml b/.github/workflows/pip.yml index 5afd31bfbac8..e959a56481e3 100644 --- a/.github/workflows/pip.yml +++ b/.github/workflows/pip.yml @@ -205,9 +205,11 @@ jobs: delocate-wheel --require-archs {delocate_archs} --exclude libHalide.dylib -w {dest_dir} -v {wheel} # delvewheel still needs to locate Halide.dll before it can exclude - # it, so point it at the unpacked halide-bin wheel on Windows. + # it, so point it at the unpacked halide-bin wheel on Windows. This + # wheel contributes to the shared halide package but does not own its + # __init__.py; --namespace-pkg prevents delvewheel from creating one. CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: > - delvewheel repair --ignore-existing --exclude Halide.dll + delvewheel repair --ignore-existing --exclude Halide.dll --namespace-pkg halide --add-path ${{ github.workspace }}\opt\halide-bin\halide\bin -w {dest_dir} {wheel} # halide-bin isn't published yet during this CI run, so resolve it From 4e97b82fd0725198a36db1ca166b7c3f08b47084 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 07:14:18 -0400 Subject: [PATCH 21/39] Build the bundled runtime for the native target --- .../halide-runtime/src/halide/runtime/CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/python_bindings/halide-runtime/src/halide/runtime/CMakeLists.txt b/python_bindings/halide-runtime/src/halide/runtime/CMakeLists.txt index bef174d57cfe..487bde1e9220 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/CMakeLists.txt +++ b/python_bindings/halide-runtime/src/halide/runtime/CMakeLists.txt @@ -46,8 +46,12 @@ endif () # Runtime only: link a compiled Halide runtime (halide_copy_to_host, # halide_device_free, error/print handlers, ...) plus the header-only runtime # interface -- but NOT libHalide/the compiler. -add_halide_runtime(Halide_PythonRuntime_rt) -target_link_libraries(Halide_PythonRuntime PRIVATE Halide::Runtime Halide_PythonRuntime_rt) +# This runtime is linked into a native CPython extension, regardless of the +# default target used for Halide's AOT tests. In particular, the CI builds +# reconfigure this build tree with Halide_TARGET=wasm-32-..., which must not +# turn this archive into WebAssembly. +add_halide_runtime(Halide_PythonRuntime_rt TARGETS cmake) +target_link_libraries(Halide_PythonRuntime PRIVATE Halide_PythonRuntime_rt) # Place the module next to the compiler extension in normal CMake builds. The # package binary directory is set by python_bindings/CMakeLists.txt. From ad4fe8e1243e76527d83e292bc49f5d3153e80a7 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 07:25:06 -0400 Subject: [PATCH 22/39] Keep Python runtime bindings header-only --- .../src/halide/runtime/CMakeLists.txt | 12 ++------ .../src/halide/runtime/PyRuntime.cpp | 30 ++++++++++++------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/python_bindings/halide-runtime/src/halide/runtime/CMakeLists.txt b/python_bindings/halide-runtime/src/halide/runtime/CMakeLists.txt index 487bde1e9220..18f614c23fba 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/CMakeLists.txt +++ b/python_bindings/halide-runtime/src/halide/runtime/CMakeLists.txt @@ -43,15 +43,9 @@ if ( target_include_directories(Halide_PythonRuntime PRIVATE "${Halide_SOURCE_DIR}/src") endif () -# Runtime only: link a compiled Halide runtime (halide_copy_to_host, -# halide_device_free, error/print handlers, ...) plus the header-only runtime -# interface -- but NOT libHalide/the compiler. -# This runtime is linked into a native CPython extension, regardless of the -# default target used for Halide's AOT tests. In particular, the CI builds -# reconfigure this build tree with Halide_TARGET=wasm-32-..., which must not -# turn this archive into WebAssembly. -add_halide_runtime(Halide_PythonRuntime_rt TARGETS cmake) -target_link_libraries(Halide_PythonRuntime PRIVATE Halide_PythonRuntime_rt) +# Header-only runtime interface only: loaded AOT modules supply their own +# compiled Halide runtime. +target_link_libraries(Halide_PythonRuntime PRIVATE Halide::Runtime) # Place the module next to the compiler extension in normal CMake builds. The # package binary directory is set by python_bindings/CMakeLists.txt. diff --git a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp index ba1e516eef48..d814dd377670 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp +++ b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp @@ -84,11 +84,9 @@ std::string library_error() { // // By default the Halide runtime prints an error to stderr and aborts the // process. That is unacceptable in a library: a bad argument or a missing GPU -// driver would take down the interpreter. We install a handler that instead -// records the message so Kernel::call can raise it as a Python exception. Each -// AOT artifact carries its own copy of the runtime, so the handler must be -// installed both into this module's runtime and, at load time, into the -// runtime bundled in each loaded kernel. +// driver would take down the interpreter. Each AOT artifact carries its own +// copy of the runtime, so load() installs a handler into that runtime which +// records the message for Kernel::call to raise as a Python exception. // --------------------------------------------------------------------------- std::mutex &error_mutex() { @@ -115,6 +113,21 @@ std::string take_last_error() { using SetErrorHandlerFn = void (*)(void (*)(void *, const char *)); +// Device allocations belong to the runtime in the loaded AOT module. Dispatch +// through the interface stored on the buffer rather than linking a second, +// unrelated vanilla runtime into this extension. +void device_free(halide_buffer_t *buf) { + if (buf->device_interface) { + (void)buf->device_interface->device_free(nullptr, buf); + } +} + +void copy_to_host(halide_buffer_t *buf) { + if (buf->device_dirty()) { + (void)buf->device_interface->copy_to_host(nullptr, buf); + } +} + // Best-effort default filter name from a library path: strip the directory, // any file extension, and a leading "lib". e.g. "/x/libfoo.so" -> "foo". std::string default_filter_name(const std::string &path) { @@ -225,7 +238,7 @@ class Kernel { ~Cleanup() { for (auto &s : slots) { if (s.needs_device_free) { - halide_device_free(nullptr, &s.buffer); + device_free(&s.buffer); } if (s.py_buf_valid) { PyBuffer_Release(&s.py_buf); @@ -327,7 +340,7 @@ class Kernel { if (a.kind == halide_argument_kind_output_buffer) { auto *buf = static_cast(argv[i]); if (buf->device_dirty()) { - (void)halide_copy_to_host(nullptr, buf); + copy_to_host(buf); } } } @@ -466,9 +479,6 @@ PYBIND11_MODULE(_runtime, m) { m.doc() = "Standalone Halide runtime: load and call precompiled AOT kernels " "without depending on libHalide."; - // Make our own runtime's errors non-fatal too (e.g. a failed copy-to-host). - halide_set_error_handler(&runtime_error_handler); - Halide::PythonRuntimeBindings::define_buffer(m); py::class_>(m, "Kernel") From 725a51cd8e1337d6ac0a0050b8960a9dc5aa8c3a Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 07:30:43 -0400 Subject: [PATCH 23/39] Move runtime tests to halide-runtime --- python_bindings/halide-runtime/CMakeLists.txt | 8 ++++++++ .../test/runtime => halide-runtime/test}/CMakeLists.txt | 0 .../runtime => halide-runtime/test}/aot_module_stub.c | 0 .../runtime => halide-runtime/test}/call_convention.py | 0 .../test}/callconv_generator.cpp | 0 .../test}/check_no_libhalide.cmake | 2 +- .../{halide/test/runtime => halide-runtime/test}/gpu.py | 0 .../runtime => halide-runtime/test}/gpu_generator.cpp | 0 .../test/runtime => halide-runtime/test}/load_aot.py | 0 .../test}/runtimeadd_generator.cpp | 0 python_bindings/halide/test/CMakeLists.txt | 1 - 11 files changed, 9 insertions(+), 2 deletions(-) rename python_bindings/{halide/test/runtime => halide-runtime/test}/CMakeLists.txt (100%) rename python_bindings/{halide/test/runtime => halide-runtime/test}/aot_module_stub.c (100%) rename python_bindings/{halide/test/runtime => halide-runtime/test}/call_convention.py (100%) rename python_bindings/{halide/test/runtime => halide-runtime/test}/callconv_generator.cpp (100%) rename python_bindings/{halide/test/runtime => halide-runtime/test}/check_no_libhalide.cmake (94%) rename python_bindings/{halide/test/runtime => halide-runtime/test}/gpu.py (100%) rename python_bindings/{halide/test/runtime => halide-runtime/test}/gpu_generator.cpp (100%) rename python_bindings/{halide/test/runtime => halide-runtime/test}/load_aot.py (100%) rename python_bindings/{halide/test/runtime => halide-runtime/test}/runtimeadd_generator.cpp (100%) diff --git a/python_bindings/halide-runtime/CMakeLists.txt b/python_bindings/halide-runtime/CMakeLists.txt index 06c53d327e69..5d95d6904241 100644 --- a/python_bindings/halide-runtime/CMakeLists.txt +++ b/python_bindings/halide-runtime/CMakeLists.txt @@ -1 +1,9 @@ add_subdirectory(src/halide/runtime) + +if (WITH_TEST_PYTHON) + if (Halide_TARGET MATCHES "wasm") + message(WARNING "Python runtime tests are skipped under WASM.") + else () + add_subdirectory(test) + endif () +endif () diff --git a/python_bindings/halide/test/runtime/CMakeLists.txt b/python_bindings/halide-runtime/test/CMakeLists.txt similarity index 100% rename from python_bindings/halide/test/runtime/CMakeLists.txt rename to python_bindings/halide-runtime/test/CMakeLists.txt diff --git a/python_bindings/halide/test/runtime/aot_module_stub.c b/python_bindings/halide-runtime/test/aot_module_stub.c similarity index 100% rename from python_bindings/halide/test/runtime/aot_module_stub.c rename to python_bindings/halide-runtime/test/aot_module_stub.c diff --git a/python_bindings/halide/test/runtime/call_convention.py b/python_bindings/halide-runtime/test/call_convention.py similarity index 100% rename from python_bindings/halide/test/runtime/call_convention.py rename to python_bindings/halide-runtime/test/call_convention.py diff --git a/python_bindings/halide/test/runtime/callconv_generator.cpp b/python_bindings/halide-runtime/test/callconv_generator.cpp similarity index 100% rename from python_bindings/halide/test/runtime/callconv_generator.cpp rename to python_bindings/halide-runtime/test/callconv_generator.cpp diff --git a/python_bindings/halide/test/runtime/check_no_libhalide.cmake b/python_bindings/halide-runtime/test/check_no_libhalide.cmake similarity index 94% rename from python_bindings/halide/test/runtime/check_no_libhalide.cmake rename to python_bindings/halide-runtime/test/check_no_libhalide.cmake index da48400e2b35..a5f08650741a 100644 --- a/python_bindings/halide/test/runtime/check_no_libhalide.cmake +++ b/python_bindings/halide-runtime/test/check_no_libhalide.cmake @@ -1,6 +1,6 @@ # Verify that the given shared MODULE does not depend on libHalide (the # compiler). The standalone runtime must link only the header-only runtime -# interface plus a compiled Halide runtime, never libHalide. +# interface, never a compiled Halide runtime or libHalide. # # Invoked as: cmake -DMODULE= -P check_no_libhalide.cmake diff --git a/python_bindings/halide/test/runtime/gpu.py b/python_bindings/halide-runtime/test/gpu.py similarity index 100% rename from python_bindings/halide/test/runtime/gpu.py rename to python_bindings/halide-runtime/test/gpu.py diff --git a/python_bindings/halide/test/runtime/gpu_generator.cpp b/python_bindings/halide-runtime/test/gpu_generator.cpp similarity index 100% rename from python_bindings/halide/test/runtime/gpu_generator.cpp rename to python_bindings/halide-runtime/test/gpu_generator.cpp diff --git a/python_bindings/halide/test/runtime/load_aot.py b/python_bindings/halide-runtime/test/load_aot.py similarity index 100% rename from python_bindings/halide/test/runtime/load_aot.py rename to python_bindings/halide-runtime/test/load_aot.py diff --git a/python_bindings/halide/test/runtime/runtimeadd_generator.cpp b/python_bindings/halide-runtime/test/runtimeadd_generator.cpp similarity index 100% rename from python_bindings/halide/test/runtime/runtimeadd_generator.cpp rename to python_bindings/halide-runtime/test/runtimeadd_generator.cpp diff --git a/python_bindings/halide/test/CMakeLists.txt b/python_bindings/halide/test/CMakeLists.txt index 35e801a78715..786664317f17 100644 --- a/python_bindings/halide/test/CMakeLists.txt +++ b/python_bindings/halide/test/CMakeLists.txt @@ -10,4 +10,3 @@ endif () add_subdirectory(correctness) add_subdirectory(generators) -add_subdirectory(runtime) From 43d7e1cefec1a63d2bf5497bf76c3ed8b14cd87b Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 07:44:47 -0400 Subject: [PATCH 24/39] Restore project-wide version bumping --- pyproject.toml | 21 ++++++++++++++ python_bindings/halide/pyproject.toml | 40 --------------------------- 2 files changed, 21 insertions(+), 40 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 67447a75bb74..e454ec0378cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -125,6 +125,27 @@ search = "VERSION {current_version}" src = "pyproject.toml" search = 'version = "{current_version}"' +[[tool.tbump.file]] +src = "vcpkg.json" + +[[tool.tbump.file]] +src = "apps/vcpkg.json" + +[[tool.tbump.file]] +src = "src/runtime/HalideRuntime.h" +version_template = "{major}" +search = "#define HALIDE_VERSION_MAJOR {current_version}" + +[[tool.tbump.file]] +src = "src/runtime/HalideRuntime.h" +version_template = "{minor}" +search = "#define HALIDE_VERSION_MINOR {current_version}" + +[[tool.tbump.file]] +src = "src/runtime/HalideRuntime.h" +version_template = "{patch}" +search = "#define HALIDE_VERSION_PATCH {current_version}" + [tool.ruff.lint] select = ["E4", "E7", "E9", "F", "FURB", "PERF", "RUF", "SIM", "UP"] ignore = ["UP045", "SIM108"] diff --git a/python_bindings/halide/pyproject.toml b/python_bindings/halide/pyproject.toml index 723b7dac11fa..674cd5701d52 100644 --- a/python_bindings/halide/pyproject.toml +++ b/python_bindings/halide/pyproject.toml @@ -150,43 +150,3 @@ ignore = [ "UP045", # Don't replace Optional[T] with T | None "SIM108", # Don't replace an if statement with ternary ] - -[tool.tbump] -github_url = "https://github.com/halide/Halide/" - -[tool.tbump.version] -current = "22.0.0" -regex = '(?P\d+)\.(?P\d+)\.(?P\d+)' - -[tool.tbump.git] -message_template = "Bump version to {new_version}" -tag_template = "v{new_version}.dev0" - -[[tool.tbump.file]] -src = "CMakeLists.txt" -search = "VERSION {current_version}" - -[[tool.tbump.file]] -src = "python_bindings/CMakeLists.txt" -search = "VERSION {current_version}" - -[[tool.tbump.file]] -src = "vcpkg.json" - -[[tool.tbump.file]] -src = "apps/vcpkg.json" - -[[tool.tbump.file]] -src = "src/runtime/HalideRuntime.h" -version_template = "{major}" -search = "#define HALIDE_VERSION_MAJOR {current_version}" - -[[tool.tbump.file]] -src = "src/runtime/HalideRuntime.h" -version_template = "{minor}" -search = "#define HALIDE_VERSION_MINOR {current_version}" - -[[tool.tbump.file]] -src = "src/runtime/HalideRuntime.h" -version_template = "{patch}" -search = "#define HALIDE_VERSION_PATCH {current_version}" From b333d788123c31ea7aebd73b86a6c332cc216cd8 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 07:45:10 -0400 Subject: [PATCH 25/39] Honor disabled Python compiler bindings --- python_bindings/halide/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python_bindings/halide/CMakeLists.txt b/python_bindings/halide/CMakeLists.txt index ab0f089148cf..4b5666bd5645 100644 --- a/python_bindings/halide/CMakeLists.txt +++ b/python_bindings/halide/CMakeLists.txt @@ -1,4 +1,6 @@ -add_subdirectory(src) +if (WITH_PYTHON_BINDINGS) + add_subdirectory(src) +endif () if (WITH_PYTHON_STUBS) add_subdirectory(stub) From ea00208ae3868ccc67fd93f8b01ce7d243e10d34 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 07:46:28 -0400 Subject: [PATCH 26/39] Propagate runtime output copy failures --- .../src/halide/runtime/PyRuntime.cpp | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp index d814dd377670..0d51d0703064 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp +++ b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp @@ -122,10 +122,14 @@ void device_free(halide_buffer_t *buf) { } } -void copy_to_host(halide_buffer_t *buf) { - if (buf->device_dirty()) { - (void)buf->device_interface->copy_to_host(nullptr, buf); +int copy_to_host(halide_buffer_t *buf) { + if (!buf->device_dirty()) { + return halide_error_code_success; } + if (!buf->device_interface || !buf->device_interface->copy_to_host) { + return halide_error_code_no_device_interface; + } + return buf->device_interface->copy_to_host(nullptr, buf); } // Best-effort default filter name from a library path: strip the directory, @@ -339,8 +343,14 @@ class Kernel { const halide_filter_argument_t &a = md_->arguments[i]; if (a.kind == halide_argument_kind_output_buffer) { auto *buf = static_cast(argv[i]); - if (buf->device_dirty()) { - copy_to_host(buf); + const int copy_result = copy_to_host(buf); + if (copy_result != halide_error_code_success) { + const std::string msg = take_last_error(); + throw std::runtime_error( + msg.empty() ? ("Halide kernel '" + name() + + "' failed to copy output '" + a.name + + "' to host with error " + std::to_string(copy_result)) : + ("Halide kernel '" + name() + "': " + msg)); } } } From 192557b11b660d145c51c4bc06e68a4b3748c01f Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 07:47:13 -0400 Subject: [PATCH 27/39] Fix relocated Python tutorial discovery --- doc/CMakeLists.txt | 6 +++--- doc/tutorial_website/lesson.py | 4 +++- doc/tutorial_website/render.py | 5 +++-- python_bindings/halide/tutorial/CMakeLists.txt | 4 ++-- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index b32bc2657edd..ea3a8739ef6d 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -215,7 +215,7 @@ add_custom_command( ## # Tutorial pages: one MyST page per tutorial/lesson_*.cpp (or .sh), with # captured gdb/lldb output for interesting statements inlined, plus (where a -# same-stem file exists under python_bindings/tutorial/) the lesson's Python +# same-stem file exists under python_bindings/halide/tutorial/) the lesson's Python # translation with its own captured output, switchable via a sphinx-design # tab-set -- see generate_tutorial_website.py's docstring. WITH_DOCS depends # on WITH_TUTORIALS AND WITH_PYTHON_BINDINGS (top-level CMakeLists.txt), and @@ -362,8 +362,8 @@ foreach (_source_file IN LISTS _tutorial_source_files) ) # Mirrors lesson.py's _python_source(): a same-stem file under - # python_bindings/tutorial/ is that lesson's Python translation. - set(_python_source_file "${Halide_SOURCE_DIR}/python_bindings/tutorial/${_slug}.py") + # python_bindings/halide/tutorial/ is that lesson's Python translation. + set(_python_source_file "${Halide_SOURCE_DIR}/python_bindings/halide/tutorial/${_slug}.py") if (EXISTS "${_python_source_file}") list(APPEND _tutorial_lesson_depends "${_python_source_file}") endif () diff --git a/doc/tutorial_website/lesson.py b/doc/tutorial_website/lesson.py index c8043ef6b956..8983cb2d7d97 100644 --- a/doc/tutorial_website/lesson.py +++ b/doc/tutorial_website/lesson.py @@ -75,7 +75,9 @@ def _next_blank_line(lines: list[str], from_line: int) -> int: def _python_source(tutorial_dir: Path, slug: str) -> Path | None: - candidate = tutorial_dir.parent / "python_bindings" / "tutorial" / f"{slug}.py" + candidate = ( + tutorial_dir.parent / "python_bindings" / "halide" / "tutorial" / f"{slug}.py" + ) return candidate if candidate.exists() else None diff --git a/doc/tutorial_website/render.py b/doc/tutorial_website/render.py index a0c7a3b2ce2b..990957bccb13 100644 --- a/doc/tutorial_website/render.py +++ b/doc/tutorial_website/render.py @@ -32,8 +32,9 @@ # The C++ lessons use paths such as "images/rgb.png" from tutorial/'s build # directory; their Python translations refer to the same files relative to -# python_bindings/tutorial/. Both spellings identify inputs whose contents can -# affect captured output, so include them in the lesson command's depfile. +# python_bindings/halide/tutorial/. Both spellings identify inputs whose +# contents can affect captured output, so include them in the lesson command's +# depfile. _TUTORIAL_INPUT_IMAGE_RE = re.compile( r"(?:\.\./\.\./tutorial/)?images/([A-Za-z0-9_.-]+)" ) diff --git a/python_bindings/halide/tutorial/CMakeLists.txt b/python_bindings/halide/tutorial/CMakeLists.txt index a8e273b47776..7bc20b0df053 100644 --- a/python_bindings/halide/tutorial/CMakeLists.txt +++ b/python_bindings/halide/tutorial/CMakeLists.txt @@ -134,8 +134,8 @@ else () ## Lessons 15, 16, and 21 use Generator classes, so unlike the plain ## scripts above, they need add_halide_generator()/add_halide_library() ## to actually run the generator (mirroring tutorial/CMakeLists.txt's - ## C++ versions and python_bindings/apps/CMakeLists.txt's use of the same - ## machinery). The directory-wide EXCLUDE_FROM_ALL above keeps these + ## C++ versions and python_bindings/halide/apps/CMakeLists.txt's use of the + ## same machinery). The directory-wide EXCLUDE_FROM_ALL above keeps these ## targets from building as a side effect of a plain `cmake --build .`; ## each lesson's own test explicitly builds what it needs (via `cmake ## --build --target`), the same trick lesson 10 uses above, just without From 492d59209866910121dbe26ca96a5f0b3bc20e2d Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 07:48:01 -0400 Subject: [PATCH 28/39] Isolate runtime errors between Python threads --- .../halide-runtime/src/halide/runtime/PyRuntime.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp index 0d51d0703064..b55f3d789fc6 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp +++ b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -89,23 +88,16 @@ std::string library_error() { // records the message for Kernel::call to raise as a Python exception. // --------------------------------------------------------------------------- -std::mutex &error_mutex() { - static std::mutex m; - return m; -} - std::string &last_error() { - static std::string s; + static thread_local std::string s; return s; } extern "C" void runtime_error_handler(void * /*user_context*/, const char *msg) { - std::scoped_lock lock(error_mutex()); last_error() = msg ? msg : ""; } std::string take_last_error() { - std::scoped_lock lock(error_mutex()); std::string s = last_error(); last_error().clear(); return s; From 3638d03ab775ccff91e860633b7a4a79101305c1 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 07:49:26 -0400 Subject: [PATCH 29/39] Describe final split package design --- .github/workflows/pip.yml | 22 ++++++++----------- packaging/CMakeLists.txt | 2 +- pyproject.toml | 7 +++--- .../src/halide/runtime/PyRuntime.cpp | 5 ++--- .../halide/packaging/CMakeLists.txt | 6 ++--- python_bindings/halide/src/__init__.py | 2 +- 6 files changed, 19 insertions(+), 25 deletions(-) diff --git a/.github/workflows/pip.yml b/.github/workflows/pip.yml index e959a56481e3..9641fddb30aa 100644 --- a/.github/workflows/pip.yml +++ b/.github/workflows/pip.yml @@ -146,13 +146,11 @@ jobs: ######################################################################## # halide-bin # - # Building the Python bindings no longer needs LLVM/FlatBuffers/WABT at - # all -- its dynamic metadata hook installs the matching halide-bin into - # the isolated build environment, where find_package(Halide) discovers - # it. Fetch the wheel this platform's build-halide-bin job just produced - # and expose it to pip via PIP_FIND_LINKS. macOS and Windows also need an - # unpacked copy later so the repair tool can resolve (but not vendor) - # libHalide.dylib/Halide.dll. + # The Python bindings build against the matching halide-bin in its + # isolated build environment, where find_package(Halide) discovers the + # compiler package. Fetch this platform's wheel and expose it to pip via + # PIP_FIND_LINKS. macOS and Windows also need an unpacked copy so the + # repair tool can resolve (but not vendor) libHalide.dylib/Halide.dll. ######################################################################## - uses: actions/download-artifact@v8 @@ -271,12 +269,10 @@ jobs: ######################################################################## # halide-bin # - # The runtime module is compiled against an already-installed halide-bin - # (for the runtime headers, the shared marshalling source, and GenRT to - # generate its bundled Halide runtime), exactly like build-wheels above. - # PIP_FIND_LINKS makes the just-built wheel available to the isolated - # build resolver. Unlike that job, the resulting extension links no - # libHalide and the wheel has no runtime halide-bin dependency. + # The runtime module uses halide-bin as an isolated build requirement for + # the runtime headers and shared marshalling source. PIP_FIND_LINKS makes + # the just-built wheel available to the build resolver. The resulting + # extension links no libHalide, and halide-bin is not a runtime dependency. ######################################################################## - uses: actions/download-artifact@v8 diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt index b2b0db66157b..cfd134329d08 100644 --- a/packaging/CMakeLists.txt +++ b/packaging/CMakeLists.txt @@ -413,7 +413,7 @@ cpack_add_component( cpack_add_component( Halide_PythonRuntime DISPLAY_NAME "Python runtime bindings" - DESCRIPTION "Python package providing header-only Halide runtime bindings" + DESCRIPTION "Python bindings for Halide runtime types and AOT modules" ) cpack_add_component( diff --git a/pyproject.toml b/pyproject.toml index e454ec0378cd..7a259de5cc88 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,10 +74,9 @@ conflicts = [ ], ] -# Both packages use build-backend hooks to pin their sibling distributions to -# the exact SCM-derived version in published artifacts. Supplying the otherwise -# static metadata here lets uv resolve the workspace without executing those -# hooks (and consequently trying to build halide-bin before LLVM is configured). +# Package builds use build-backend hooks to resolve sibling requirements from +# the SCM-derived version. Supplying the resolution metadata here lets uv resolve +# the workspace without executing those hooks or building halide-bin first. # uv requires a version for direct/workspace sources; these resolution-only # base versions are kept in sync with the release version by tbump below. [[tool.uv.dependency-metadata]] diff --git a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp index b55f3d789fc6..d65b34fe07be 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp +++ b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp @@ -105,9 +105,8 @@ std::string take_last_error() { using SetErrorHandlerFn = void (*)(void (*)(void *, const char *)); -// Device allocations belong to the runtime in the loaded AOT module. Dispatch -// through the interface stored on the buffer rather than linking a second, -// unrelated vanilla runtime into this extension. +// Device allocations belong to the runtime in the loaded AOT module, so device +// operations dispatch through the interface stored on each buffer. void device_free(halide_buffer_t *buf) { if (buf->device_interface) { (void)buf->device_interface->device_free(nullptr, buf); diff --git a/python_bindings/halide/packaging/CMakeLists.txt b/python_bindings/halide/packaging/CMakeLists.txt index cc9d097085b6..8bf4dee13853 100644 --- a/python_bindings/halide/packaging/CMakeLists.txt +++ b/python_bindings/halide/packaging/CMakeLists.txt @@ -43,9 +43,9 @@ if (WITH_PYTHON_BINDINGS) ) # The standalone halide.runtime module. It links no libHalide, so it needs - # no RPATH patching. It gets its own install component so a libHalide-free - # runtime-only wheel can select just this (plus the *.py below); the full - # package installs every component and so includes it too. + # no RPATH patching. It gets its own install component for the + # halide-runtime wheel; monolithic CMake installs include this component + # alongside the compiler bindings. install( TARGETS Halide_PythonRuntime LIBRARY DESTINATION "${Halide_INSTALL_PYTHONDIR}/runtime" COMPONENT Halide_PythonRuntime diff --git a/python_bindings/halide/src/__init__.py b/python_bindings/halide/src/__init__.py index 115943068a96..8d8f2022a11c 100644 --- a/python_bindings/halide/src/__init__.py +++ b/python_bindings/halide/src/__init__.py @@ -6,7 +6,7 @@ def install_dir(): except ModuleNotFoundError as e: if e.name != f"{__name__}.bin": raise - # Traditional CMake build-tree layout (not a split wheel). + # Traditional monolithic CMake build-tree layout. from pathlib import Path return str(Path(__file__).resolve().parent) From c8b41d98ec11ea867b3cbe2ef4a5004415cd0c38 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 08:02:50 -0400 Subject: [PATCH 30/39] Construct compiler Buffers from runtime Buffers --- .../halide/src/halide_/PyBuffer.cpp | 48 +++++++++---------- .../halide/test/correctness/buffer.py | 11 ++++- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/python_bindings/halide/src/halide_/PyBuffer.cpp b/python_bindings/halide/src/halide_/PyBuffer.cpp index 350a1d93a4e1..0eba9610b408 100644 --- a/python_bindings/halide/src/halide_/PyBuffer.cpp +++ b/python_bindings/halide/src/halide_/PyBuffer.cpp @@ -276,11 +276,6 @@ py::object buffer_setitem_operator(Buffer<> &buf, const std::vector &pos, c class PyBuffer : public Buffer<> { py::buffer_info info; - PyBuffer(py::buffer_info &&info, const std::string &name, bool reverse_axes) - : Buffer<>(pybufferinfo_to_halidebuffer(info, reverse_axes), name), - info(std::move(info)) { - } - public: PyBuffer() : Buffer<>(), info() { @@ -291,7 +286,26 @@ class PyBuffer : public Buffer<> { } PyBuffer(const py::buffer &buffer, const std::string &name, bool reverse_axes) - : PyBuffer(buffer.request(/*writable*/ true), name, reverse_axes) { + : Buffer<>(), info() { + if (py::hasattr(buffer, "_get_raw_halide_runtime_buffer")) { + if (!py::hasattr(buffer, "defined")) { + throw py::type_error("Invalid halide.runtime.Buffer."); + } + if (!buffer.attr("defined")().cast()) { + return; + } + const uintptr_t address = buffer.attr("_get_raw_halide_runtime_buffer")().cast(); + if (address == 0) { + throw py::value_error("A defined Buffer cannot have a null runtime buffer."); + } + const auto *runtime_buffer = reinterpret_cast *>(address); + Buffer<>::operator=(Buffer<>(Halide::Runtime::Buffer<>(*runtime_buffer), name)); + return; + } + + info = buffer.request(/*writable*/ true); + Buffer<>::operator=(Buffer<>(pybufferinfo_to_halidebuffer(info, reverse_axes), name)); + // Default to setting host-dirty on any PyBuffer we create from an existing py::buffer; // this allows (e.g.) code like // @@ -370,13 +384,15 @@ void define_buffer(py::module &m) { .def(py::init_alias &>(), py::keep_alive<1, 2>()) // This py::init_alias allows us to use any buffer-like Python entity to create a - // Buffer<> (most notably, an ndarray). reverse_axes = True by default. + // Buffer<> (most notably, an ndarray). A halide.runtime.Buffer is copied + // directly, matching Halide::Buffer's C++ constructor and preserving its + // axis order. reverse_axes = True by default for other buffer objects. // // ! Note that the copy/default constructors are registered *above, before* the // py::buffer one before. This is because hl.Buffer also satisfies the buffer protocol, // and we want hl.Buffer(other_buffer) to be a "direct" copy (no axis reversal) rather // than routing through the axis-reversing buffer-protocol path. - .def(py::init_alias(), py::arg("buffer"), py::arg("name") = "", py::arg("reverse_axes") = true) + .def(py::init_alias(), py::arg("buffer"), py::arg("name") = "", py::arg("reverse_axes") = true, py::keep_alive<1, 2>()) .def(py::init([](Type type, const std::vector &sizes, const std::string &name) -> Buffer<> { return Buffer<>(type, sizes, name); @@ -401,22 +417,6 @@ void define_buffer(py::module &m) { }, py::arg("src"), py::arg("name") = "") - .def_static("from_runtime", [](const py::object &source) -> Buffer<> { - if (!py::hasattr(source, "_get_raw_halide_runtime_buffer") || - !py::hasattr(source, "defined") || - !py::hasattr(source, "name")) { - throw py::type_error("Expected a halide.runtime.Buffer."); - } - if (!source.attr("defined")().cast()) { - return Buffer<>(); - } - const uintptr_t address = source.attr("_get_raw_halide_runtime_buffer")().cast(); - if (address == 0) { - throw py::value_error("A defined Buffer cannot have a null runtime buffer."); - } - const auto *buffer = reinterpret_cast *>(address); - return Buffer<>(Halide::Runtime::Buffer<>(*buffer), source.attr("name")().cast()); }, py::arg("buffer"), py::keep_alive<0, 1>()) - .def("set_name", &Buffer<>::set_name) .def("name", &Buffer<>::name) diff --git a/python_bindings/halide/test/correctness/buffer.py b/python_bindings/halide/test/correctness/buffer.py index 8ce46dce8b10..b264261649f6 100644 --- a/python_bindings/halide/test/correctness/buffer.py +++ b/python_bindings/halide/test/correctness/buffer.py @@ -628,12 +628,19 @@ def test_runtime_buffer_is_distinct(): assert runtime_buffer.type() == runtime_type runtime_buffer[1, 2] = 42 - compiler_buffer = hl.Buffer.from_runtime(runtime_buffer) + compiler_buffer = hl.Buffer(runtime_buffer) assert isinstance(compiler_buffer, hl.Buffer) assert compiler_buffer.type() == hl.Int(32) - assert compiler_buffer.name() == "runtime_buffer" + assert compiler_buffer.dim(0).extent() == 4 + assert compiler_buffer.dim(1).extent() == 3 assert compiler_buffer[1, 2] == 42 + renamed_compiler_buffer = hl.Buffer(runtime_buffer, "compiler_buffer") + assert renamed_compiler_buffer.name() == "compiler_buffer" + + undefined_compiler_buffer = hl.Buffer(hlr.Buffer()) + assert not undefined_compiler_buffer.defined() + compiler_buffer[2, 1] = 17 runtime_copy = hlr.Buffer.from_compiler(compiler_buffer) assert isinstance(runtime_copy, hlr.Buffer) From 69d18519e872786b1e2b0213616cbed77ff7d271 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 08:24:49 -0400 Subject: [PATCH 31/39] Expose borrowed runtime Buffer views --- .../src/halide/runtime/PyRuntimeBuffer.cpp | 135 +++++++++++------- .../halide/src/halide_/PyBuffer.cpp | 10 +- .../halide/test/correctness/buffer.py | 23 ++- 3 files changed, 106 insertions(+), 62 deletions(-) diff --git a/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp b/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp index 4f5ca4701071..49ba04fffaf4 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp +++ b/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp @@ -102,10 +102,40 @@ class Buffer { public: Buffer() = default; - Buffer(const Buffer &) = default; - Buffer(Buffer &&) noexcept = default; - Buffer &operator=(const Buffer &) = default; - Buffer &operator=(Buffer &&) noexcept = default; + Buffer(const Buffer &other) + : buffer_(other.runtime_buffer()), + owner_(other.owner_), identity_(other.identity_), name_(other.name_), defined_(other.defined_) { + } + + Buffer(Buffer &&other) noexcept + : buffer_(std::move(other.buffer_)), borrowed_buffer_(other.borrowed_buffer_), + owner_(std::move(other.owner_)), identity_(std::move(other.identity_)), + name_(std::move(other.name_)), defined_(other.defined_) { + } + + Buffer &operator=(const Buffer &other) { + if (this != &other) { + buffer_ = other.runtime_buffer(); + borrowed_buffer_ = nullptr; + owner_ = other.owner_; + identity_ = other.identity_; + name_ = other.name_; + defined_ = other.defined_; + } + return *this; + } + + Buffer &operator=(Buffer &&other) noexcept { + if (this != &other) { + buffer_ = std::move(other.buffer_); + borrowed_buffer_ = other.borrowed_buffer_; + owner_ = std::move(other.owner_); + identity_ = std::move(other.identity_); + name_ = std::move(other.name_); + defined_ = other.defined_; + } + return *this; + } Buffer(py::buffer source, std::string name, bool reverse_axes) : owner_(std::move(source)), identity_(std::make_shared()), name_(name.empty() ? unique_name() : std::move(name)), defined_(true) { @@ -121,7 +151,7 @@ class Buffer { dims[dst] = {0, static_cast(info.shape[i]), static_cast(stride)}; } buffer_ = RuntimeBuffer(type, info.ptr, info.ndim, dims.data()); - buffer_.set_host_dirty(); + runtime_buffer().set_host_dirty(); } Buffer(halide_type_t type, const std::vector &sizes, std::string name) @@ -142,23 +172,16 @@ class Buffer { return result; } - static Buffer from_compiler(const py::object &source) { - if (!py::hasattr(source, "_get_raw_halide_runtime_buffer") || - !py::hasattr(source, "defined") || - !py::hasattr(source, "name")) { - throw py::type_error("Expected a halide.Buffer."); - } - if (!source.attr("defined")().cast()) { - return Buffer(); - } - const uintptr_t address = source.attr("_get_raw_halide_runtime_buffer")().cast(); + static Buffer from_borrowed(uintptr_t address, py::object owner, std::string name) { if (address == 0) { - throw py::value_error("A defined Buffer cannot have a null runtime buffer."); + return Buffer(); } - Buffer result = from_runtime( - *reinterpret_cast(address), - source.attr("name")().cast(), true); - result.owner_ = source; + Buffer result; + result.borrowed_buffer_ = reinterpret_cast(address); + result.owner_ = std::move(owner); + result.identity_ = std::make_shared(); + result.name_ = std::move(name); + result.defined_ = true; return result; } @@ -183,24 +206,24 @@ class Buffer { } static Buffer make_with_shape_of(const Buffer &source, std::string name) { - return from_runtime(RuntimeBuffer::make_with_shape_of(source.buffer_), + return from_runtime(RuntimeBuffer::make_with_shape_of(source.runtime_buffer()), name.empty() ? unique_name() : std::move(name), true); } RuntimeBuffer &runtime_buffer() { - return buffer_; + return borrowed_buffer_ ? *borrowed_buffer_ : buffer_; } const RuntimeBuffer &runtime_buffer() const { - return buffer_; + return borrowed_buffer_ ? *borrowed_buffer_ : buffer_; } uintptr_t raw_halide_buffer_t() { - return reinterpret_cast(buffer_.raw_buffer()); + return reinterpret_cast(runtime_buffer().raw_buffer()); } uintptr_t raw_runtime_buffer() { - return reinterpret_cast(&buffer_); + return reinterpret_cast(&runtime_buffer()); } bool defined() const { @@ -221,18 +244,19 @@ class Buffer { py::buffer_info buffer_info(bool reverse_axes) { require_defined(); - if (buffer_.data() == nullptr) { + RuntimeBuffer &buffer = runtime_buffer(); + if (buffer.data() == nullptr) { throw py::value_error("Cannot convert a Buffer<> with null host ptr to a Python buffer."); } - const int d = buffer_.dimensions(); - const int bytes = buffer_.type().bytes(); + const int d = buffer.dimensions(); + const int bytes = buffer.type().bytes(); std::vector shape(d), strides(d); for (int i = 0; i < d; ++i) { const int dst = reverse_axes ? d - i - 1 : i; - shape[dst] = buffer_.dim(i).extent(); - strides[dst] = static_cast(buffer_.dim(i).stride()) * bytes; + shape[dst] = buffer.dim(i).extent(); + strides[dst] = static_cast(buffer.dim(i).stride()) * bytes; } - return py::buffer_info(buffer_.data(), bytes, type_to_format_descriptor(buffer_.type()), d, shape, strides); + return py::buffer_info(buffer.data(), bytes, type_to_format_descriptor(buffer.type()), d, shape, strides); } py::array numpy_view(bool reverse_axes) { @@ -241,12 +265,13 @@ class Buffer { py::object getitem(const std::vector &pos) { check_position(pos); - if (buffer_.type() == Runtime::Buffer::static_halide_type()) { - return py::float_(static_cast(buffer_.as()(pos.data()))); + RuntimeBuffer &buffer = runtime_buffer(); + if (buffer.type() == Runtime::Buffer::static_halide_type()) { + return py::float_(static_cast(buffer.as()(pos.data()))); } -#define HANDLE_TYPE(TYPE) \ - if (buffer_.type() == Runtime::Buffer::static_halide_type()) { \ - return py::cast(buffer_.as()(pos.data())); \ +#define HANDLE_TYPE(TYPE) \ + if (buffer.type() == Runtime::Buffer::static_halide_type()) { \ + return py::cast(buffer.as()(pos.data())); \ } HANDLE_TYPE(bool) HANDLE_TYPE(uint8_t) @@ -265,13 +290,14 @@ class Buffer { py::object setitem(const std::vector &pos, const py::object &value) { check_position(pos); - if (buffer_.type() == Runtime::Buffer::static_halide_type()) { - buffer_.as()(pos.data()) = value_cast(value); + RuntimeBuffer &buffer = runtime_buffer(); + if (buffer.type() == Runtime::Buffer::static_halide_type()) { + buffer.as()(pos.data()) = value_cast(value); return value; } -#define HANDLE_TYPE(TYPE) \ - if (buffer_.type() == Runtime::Buffer::static_halide_type()) { \ - return py::cast(buffer_.as()(pos.data()) = value_cast(value)); \ +#define HANDLE_TYPE(TYPE) \ + if (buffer.type() == Runtime::Buffer::static_halide_type()) { \ + return py::cast(buffer.as()(pos.data()) = value_cast(value)); \ } HANDLE_TYPE(bool) HANDLE_TYPE(uint8_t) @@ -289,10 +315,11 @@ class Buffer { } void fill(const py::object &value) { -#define HANDLE_TYPE(TYPE) \ - if (buffer_.type() == Runtime::Buffer::static_halide_type()) { \ - buffer_.as().fill(value_cast(value)); \ - return; \ + RuntimeBuffer &buffer = runtime_buffer(); +#define HANDLE_TYPE(TYPE) \ + if (buffer.type() == Runtime::Buffer::static_halide_type()) { \ + buffer.as().fill(value_cast(value)); \ + return; \ } HANDLE_TYPE(bool) HANDLE_TYPE(uint8_t) @@ -311,9 +338,10 @@ class Buffer { } bool all_equal(const py::object &value) { -#define HANDLE_TYPE(TYPE) \ - if (buffer_.type() == Runtime::Buffer::static_halide_type()) { \ - return buffer_.as().all_equal(value_cast(value)); \ + RuntimeBuffer &buffer = runtime_buffer(); +#define HANDLE_TYPE(TYPE) \ + if (buffer.type() == Runtime::Buffer::static_halide_type()) { \ + return buffer.as().all_equal(value_cast(value)); \ } HANDLE_TYPE(bool) HANDLE_TYPE(uint8_t) @@ -340,11 +368,12 @@ class Buffer { void check_position(const std::vector &pos) const { require_defined(); - if (pos.size() != static_cast(buffer_.dimensions())) { + const RuntimeBuffer &buffer = runtime_buffer(); + if (pos.size() != static_cast(buffer.dimensions())) { throw py::value_error("Incorrect number of dimensions."); } - for (int i = 0; i < buffer_.dimensions(); ++i) { - const auto dim = buffer_.dim(i); + for (int i = 0; i < buffer.dimensions(); ++i) { + const auto dim = buffer.dim(i); if (pos[i] < dim.min() || pos[i] > dim.max()) { std::ostringstream out; out << "index " << pos[i] << " is out of bounds for axis " << i @@ -355,6 +384,7 @@ class Buffer { } RuntimeBuffer buffer_; + RuntimeBuffer *borrowed_buffer_ = nullptr; py::object owner_; std::shared_ptr identity_; std::string name_; @@ -391,7 +421,8 @@ void define_buffer(py::module_ &m) { py::arg("type"), py::arg("sizes"), py::arg("name") = "") .def(py::init &, const std::vector &, std::string>(), py::arg("type"), py::arg("sizes"), py::arg("storage_order"), py::arg("name") = "") - .def_static("from_compiler", &Buffer::from_compiler, py::arg("buffer")) + .def_static("_from_borrowed", &Buffer::from_borrowed, + py::arg("address"), py::arg("owner"), py::arg("name")) .def_static("make_bounds_query", &Buffer::make_bounds_query, py::arg("type"), py::arg("sizes"), py::arg("name") = "") .def_static("make_scalar", &Buffer::make_scalar, py::arg("type"), py::arg("name") = "") .def_static("make_interleaved", &Buffer::make_interleaved, py::arg("type"), py::arg("width"), py::arg("height"), py::arg("channels"), py::arg("name") = "") diff --git a/python_bindings/halide/src/halide_/PyBuffer.cpp b/python_bindings/halide/src/halide_/PyBuffer.cpp index 0eba9610b408..cb7e509204d6 100644 --- a/python_bindings/halide/src/halide_/PyBuffer.cpp +++ b/python_bindings/halide/src/halide_/PyBuffer.cpp @@ -693,11 +693,15 @@ void define_buffer(py::module &m) { return o.str(); // }) + .def("get", [](const py::object &self) -> py::object { + const auto &buffer = self.cast &>(); + return py::module_::import("halide.runtime") + .attr("Buffer") + .attr("_from_borrowed")( + reinterpret_cast(buffer.get()), self, buffer.name()); }) + .def("_get_raw_halide_buffer_t", [](const Buffer<> &b) -> uintptr_t { return reinterpret_cast(b.raw_buffer()); // - }) - .def("_get_raw_halide_runtime_buffer", [](const Buffer<> &b) -> uintptr_t { - return reinterpret_cast(b.get()); // }); } diff --git a/python_bindings/halide/test/correctness/buffer.py b/python_bindings/halide/test/correctness/buffer.py index b264261649f6..f957b955ee90 100644 --- a/python_bindings/halide/test/correctness/buffer.py +++ b/python_bindings/halide/test/correctness/buffer.py @@ -642,16 +642,25 @@ def test_runtime_buffer_is_distinct(): assert not undefined_compiler_buffer.defined() compiler_buffer[2, 1] = 17 - runtime_copy = hlr.Buffer.from_compiler(compiler_buffer) - assert isinstance(runtime_copy, hlr.Buffer) - assert runtime_copy.type() == runtime_type - assert runtime_copy[2, 1] == 17 - - # Both adaptations are zero-copy views of the same underlying allocation. - runtime_copy[0, 0] = 9 + runtime_view = compiler_buffer.get() + assert isinstance(runtime_view, hlr.Buffer) + assert runtime_view.type() == runtime_type + assert runtime_view[2, 1] == 17 + + # Buffer.get() borrows the compiler Buffer's actual Runtime::Buffer, so both + # data and descriptor mutations are visible through the compiler Buffer. + runtime_view[0, 0] = 9 assert runtime_buffer[0, 0] == 9 assert compiler_buffer[0, 0] == 9 + runtime_view.translate(0, 5) + assert compiler_buffer.dim(0).min() == 5 + + # The borrowed runtime view keeps its compiler Buffer alive. + runtime_view = hl.Buffer(hl.Int(32), [2]).get() + runtime_view[0] = 23 + assert runtime_view[0] == 23 + if __name__ == "__main__": test_make_interleaved() From ea6229d221ec4020d6c2a202210a7ca0d136233b Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 08:39:52 -0400 Subject: [PATCH 32/39] Use typed capsules for Python Buffer interop --- .../src/halide/runtime/PyRuntime.cpp | 24 ++++++------ .../src/halide/runtime/PyRuntimeBuffer.cpp | 26 +++++++------ .../src/halide/runtime/PyRuntimeBuffer.h | 11 ++++++ .../halide-runtime/test/load_aot.py | 7 +--- .../halide/src/halide_/PyBuffer.cpp | 37 +++++++++++++------ .../halide/test/correctness/buffer.py | 11 ++++++ src/PythonExtensionRuntime.template.cpp | 30 +++++++++------ 7 files changed, 96 insertions(+), 50 deletions(-) diff --git a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp index d65b34fe07be..dae713b4ab55 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp +++ b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp @@ -10,8 +10,8 @@ // Python extensions emitted by PythonExtensionGen, via the single source of // truth in src/PythonExtensionRuntime.template.cpp (included below). Interop // with `halide.Buffer` (from the compiler module) and with objects produced by -// generated extensions flows through the duck-typed `_get_raw_halide_buffer_t` -// protocol, so no libHalide types cross the boundary. +// generated extensions flows through a duck-typed, named-capsule protocol, so +// no libHalide types cross the boundary. #include #include @@ -354,7 +354,7 @@ class Kernel { } // Convert one buffer-protocol / Halide-buffer argument into a halide_buffer_t. - // Uses the shared `_get_raw_halide_buffer_t` fast path first, then falls back + // Uses the shared named-capsule fast path first, then falls back // to the shared unpack_buffer() implementation. halide_buffer_t *unpack_buffer_arg(const halide_filter_argument_t &a, py::handle value, @@ -362,18 +362,20 @@ class Kernel { ArgSlot &slot) { PyObject *obj = value.ptr(); - // Fast path: an object that already exposes a raw halide_buffer_t + // Fast path: an object that already exposes a halide_buffer_t capsule // (halide.Buffer, halide.runtime.Buffer, or another generated result). - if (PyObject_HasAttrString(obj, "_get_raw_halide_buffer_t")) { - PyObject *raw = PyObject_CallMethod(obj, "_get_raw_halide_buffer_t", nullptr); - if (raw && PyLong_Check(raw)) { - auto ptr = (uintptr_t)PyLong_AsUnsignedLongLong(raw); - Py_DECREF(raw); + if (PyObject_HasAttrString(obj, "_get_halide_buffer_t_capsule")) { + PyObject *capsule = PyObject_CallMethod(obj, "_get_halide_buffer_t_capsule", nullptr); + if (capsule && PyCapsule_CheckExact(capsule)) { + void *ptr = PyCapsule_GetPointer( + capsule, Halide::PythonRuntimeBindings::halide_buffer_capsule_name); + Py_DECREF(capsule); if (ptr) { - return reinterpret_cast(ptr); + return static_cast(ptr); } + PyErr_Clear(); } else { - Py_XDECREF(raw); + Py_XDECREF(capsule); PyErr_Clear(); } } diff --git a/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp b/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp index 49ba04fffaf4..ebba6d69236e 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp +++ b/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp @@ -172,12 +172,12 @@ class Buffer { return result; } - static Buffer from_borrowed(uintptr_t address, py::object owner, std::string name) { - if (address == 0) { - return Buffer(); - } + static Buffer from_borrowed(const py::capsule &capsule, py::object owner, std::string name) { Buffer result; - result.borrowed_buffer_ = reinterpret_cast(address); + result.borrowed_buffer_ = static_cast(PyCapsule_GetPointer(capsule.ptr(), runtime_buffer_capsule_name)); + if (!result.borrowed_buffer_) { + throw py::error_already_set(); + } result.owner_ = std::move(owner); result.identity_ = std::make_shared(); result.name_ = std::move(name); @@ -218,12 +218,14 @@ class Buffer { return borrowed_buffer_ ? *borrowed_buffer_ : buffer_; } - uintptr_t raw_halide_buffer_t() { - return reinterpret_cast(runtime_buffer().raw_buffer()); + py::capsule halide_buffer_t_capsule() { + require_defined(); + return py::capsule(runtime_buffer().raw_buffer(), halide_buffer_capsule_name); } - uintptr_t raw_runtime_buffer() { - return reinterpret_cast(&runtime_buffer()); + py::capsule runtime_buffer_capsule() { + require_defined(); + return py::capsule(&runtime_buffer(), runtime_buffer_capsule_name); } bool defined() const { @@ -422,7 +424,7 @@ void define_buffer(py::module_ &m) { .def(py::init &, const std::vector &, std::string>(), py::arg("type"), py::arg("sizes"), py::arg("storage_order"), py::arg("name") = "") .def_static("_from_borrowed", &Buffer::from_borrowed, - py::arg("address"), py::arg("owner"), py::arg("name")) + py::arg("capsule"), py::arg("owner"), py::arg("name")) .def_static("make_bounds_query", &Buffer::make_bounds_query, py::arg("type"), py::arg("sizes"), py::arg("name") = "") .def_static("make_scalar", &Buffer::make_scalar, py::arg("type"), py::arg("name") = "") .def_static("make_interleaved", &Buffer::make_interleaved, py::arg("type"), py::arg("width"), py::arg("height"), py::arg("channels"), py::arg("name") = "") @@ -522,8 +524,8 @@ void define_buffer(py::module_ &m) { out << "[" << d.min << "," << d.extent << "," << d.stride << "]"; } return out.str() + "]>"; }) - .def("_get_raw_halide_buffer_t", &Buffer::raw_halide_buffer_t) - .def("_get_raw_halide_runtime_buffer", &Buffer::raw_runtime_buffer); + .def("_get_halide_buffer_t_capsule", &Buffer::halide_buffer_t_capsule) + .def("_get_halide_runtime_buffer_capsule", &Buffer::runtime_buffer_capsule); } } // namespace Halide::PythonRuntimeBindings diff --git a/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.h b/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.h index acc6cf667491..471d96210100 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.h +++ b/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.h @@ -3,8 +3,19 @@ #include +#include "HalideRuntime.h" + namespace Halide::PythonRuntimeBindings { +#define HALIDE_PYTHON_STRINGIFY_IMPL(x) #x +#define HALIDE_PYTHON_STRINGIFY(x) HALIDE_PYTHON_STRINGIFY_IMPL(x) +inline constexpr char halide_buffer_capsule_name[] = + "halide.halide_buffer_t.v" HALIDE_PYTHON_STRINGIFY(HALIDE_VERSION_MAJOR); +inline constexpr char runtime_buffer_capsule_name[] = + "halide.runtime.Buffer.v" HALIDE_PYTHON_STRINGIFY(HALIDE_VERSION_MAJOR); +#undef HALIDE_PYTHON_STRINGIFY +#undef HALIDE_PYTHON_STRINGIFY_IMPL + void define_buffer(pybind11::module_ &m); } // namespace Halide::PythonRuntimeBindings diff --git a/python_bindings/halide-runtime/test/load_aot.py b/python_bindings/halide-runtime/test/load_aot.py index d564cbe008d8..07be7e04618e 100644 --- a/python_bindings/halide-runtime/test/load_aot.py +++ b/python_bindings/halide-runtime/test/load_aot.py @@ -43,16 +43,13 @@ def main(): buf = hlr.Buffer(grid) assert buf.dimensions() == 2 and str(buf.type()) == "uint8" assert [buf.dim(i).extent() for i in range(buf.dimensions())] == [3, 2] - assert ( - isinstance(buf._get_raw_halide_buffer_t(), int) - and buf._get_raw_halide_buffer_t() != 0 - ) + assert type(buf._get_halide_buffer_t_capsule()).__name__ == "PyCapsule" view = np.asarray(buf) assert np.array_equal(view, grid) view[0, 0] = 42 assert grid[0, 0] == 42, "Buffer must be a zero-copy view of its source" - # Pass Buffer objects to the kernel (via the _get_raw_halide_buffer_t bridge). + # Pass Buffer objects to the kernel (via the named-capsule bridge). out3 = np.zeros_like(rng) kernel(hlr.Buffer(rng), np.int32(7), hlr.Buffer(out3)) expected3 = ((rng.astype(np.int64) + 7) % 256).astype(np.uint8) diff --git a/python_bindings/halide/src/halide_/PyBuffer.cpp b/python_bindings/halide/src/halide_/PyBuffer.cpp index cb7e509204d6..80568d9b98ec 100644 --- a/python_bindings/halide/src/halide_/PyBuffer.cpp +++ b/python_bindings/halide/src/halide_/PyBuffer.cpp @@ -10,6 +10,15 @@ namespace PythonBindings { namespace { +#define HALIDE_PYTHON_STRINGIFY_IMPL(x) #x +#define HALIDE_PYTHON_STRINGIFY(x) HALIDE_PYTHON_STRINGIFY_IMPL(x) +constexpr char halide_buffer_capsule_name[] = + "halide.halide_buffer_t.v" HALIDE_PYTHON_STRINGIFY(HALIDE_VERSION_MAJOR); +constexpr char runtime_buffer_capsule_name[] = + "halide.runtime.Buffer.v" HALIDE_PYTHON_STRINGIFY(HALIDE_VERSION_MAJOR); +#undef HALIDE_PYTHON_STRINGIFY +#undef HALIDE_PYTHON_STRINGIFY_IMPL + // Standard stream output for halide_dimension_t std::ostream &operator<<(std::ostream &stream, const halide_dimension_t &d) { stream << "[" << d.min << "," << d.extent << "," << d.stride << "]"; @@ -287,18 +296,19 @@ class PyBuffer : public Buffer<> { PyBuffer(const py::buffer &buffer, const std::string &name, bool reverse_axes) : Buffer<>(), info() { - if (py::hasattr(buffer, "_get_raw_halide_runtime_buffer")) { + if (py::hasattr(buffer, "_get_halide_runtime_buffer_capsule")) { if (!py::hasattr(buffer, "defined")) { throw py::type_error("Invalid halide.runtime.Buffer."); } if (!buffer.attr("defined")().cast()) { return; } - const uintptr_t address = buffer.attr("_get_raw_halide_runtime_buffer")().cast(); - if (address == 0) { - throw py::value_error("A defined Buffer cannot have a null runtime buffer."); + const py::capsule capsule = buffer.attr("_get_halide_runtime_buffer_capsule")().cast(); + const auto *runtime_buffer = static_cast *>( + PyCapsule_GetPointer(capsule.ptr(), runtime_buffer_capsule_name)); + if (!runtime_buffer) { + throw py::error_already_set(); } - const auto *runtime_buffer = reinterpret_cast *>(address); Buffer<>::operator=(Buffer<>(Halide::Runtime::Buffer<>(*runtime_buffer), name)); return; } @@ -695,13 +705,18 @@ void define_buffer(py::module &m) { .def("get", [](const py::object &self) -> py::object { const auto &buffer = self.cast &>(); - return py::module_::import("halide.runtime") - .attr("Buffer") - .attr("_from_borrowed")( - reinterpret_cast(buffer.get()), self, buffer.name()); }) + py::object runtime_buffer = py::module_::import("halide.runtime").attr("Buffer"); + if (!buffer.defined()) { + return runtime_buffer(); + } + return runtime_buffer.attr("_from_borrowed")( + py::capsule(buffer.get(), runtime_buffer_capsule_name), self, buffer.name()); }) - .def("_get_raw_halide_buffer_t", [](const Buffer<> &b) -> uintptr_t { - return reinterpret_cast(b.raw_buffer()); // + .def("_get_halide_buffer_t_capsule", [](Buffer<> &b) -> py::capsule { + if (!b.defined()) { + throw py::value_error("Buffer is undefined."); + } + return py::capsule(b.raw_buffer(), halide_buffer_capsule_name); // }); } diff --git a/python_bindings/halide/test/correctness/buffer.py b/python_bindings/halide/test/correctness/buffer.py index f957b955ee90..1d69e4448f9a 100644 --- a/python_bindings/halide/test/correctness/buffer.py +++ b/python_bindings/halide/test/correctness/buffer.py @@ -640,6 +640,7 @@ def test_runtime_buffer_is_distinct(): undefined_compiler_buffer = hl.Buffer(hlr.Buffer()) assert not undefined_compiler_buffer.defined() + assert not undefined_compiler_buffer.get().defined() compiler_buffer[2, 1] = 17 runtime_view = compiler_buffer.get() @@ -656,6 +657,16 @@ def test_runtime_buffer_is_distinct(): runtime_view.translate(0, 5) assert compiler_buffer.dim(0).min() == 5 + # The two native pointer types use distinct capsule tags. + try: + hlr.Buffer._from_borrowed( + compiler_buffer._get_halide_buffer_t_capsule(), compiler_buffer, "" + ) + except ValueError: + pass + else: + assert False, "accepted a halide_buffer_t capsule as a Runtime::Buffer" + # The borrowed runtime view keeps its compiler Buffer alive. runtime_view = hl.Buffer(hl.Int(32), [2]).get() runtime_view[0] = 23 diff --git a/src/PythonExtensionRuntime.template.cpp b/src/PythonExtensionRuntime.template.cpp index ff9e6c0c1165..defe010f9410 100644 --- a/src/PythonExtensionRuntime.template.cpp +++ b/src/PythonExtensionRuntime.template.cpp @@ -111,11 +111,16 @@ inline bool unpack_buffer(PyObject *py_obj, namespace { +#define HALIDE_PYTHON_STRINGIFY_IMPL(x) #x +#define HALIDE_PYTHON_STRINGIFY(x) HALIDE_PYTHON_STRINGIFY_IMPL(x) + template struct PyHalideBuffer { // Must allocate at least 1, even if d=0 static constexpr int dims_to_allocate = (dimensions < 1) ? 1 : dimensions; - static constexpr const char *get_raw_halide_runtime_buffer_fn = "_get_raw_halide_buffer_t"; + static constexpr const char *get_halide_buffer_capsule_fn = "_get_halide_buffer_t_capsule"; + static constexpr const char *halide_buffer_capsule_name = + "halide.halide_buffer_t.v" HALIDE_PYTHON_STRINGIFY(HALIDE_VERSION_MAJOR); Py_buffer py_buf; halide_buffer_t *halide_buf = nullptr; @@ -123,29 +128,29 @@ struct PyHalideBuffer { bool needs_device_free = false; bool unpack_from_halide_buffer(PyObject *py_obj) { - if (!PyObject_HasAttrString(py_obj, get_raw_halide_runtime_buffer_fn)) { + if (!PyObject_HasAttrString(py_obj, get_halide_buffer_capsule_fn)) { return false; } - PyObject *py_raw_buffer = PyObject_CallMethod(py_obj, get_raw_halide_runtime_buffer_fn, nullptr); - if (!py_raw_buffer) { + PyObject *capsule = PyObject_CallMethod(py_obj, get_halide_buffer_capsule_fn, nullptr); + if (!capsule) { PyErr_Clear(); return false; } - if (!PyLong_Check(py_raw_buffer)) { - Py_DECREF(py_raw_buffer); + if (!PyCapsule_CheckExact(capsule)) { + Py_DECREF(capsule); return false; } - uintptr_t py_raw_buffer_ptr = (uintptr_t)PyLong_AsUnsignedLongLong(py_raw_buffer); - Py_DECREF(py_raw_buffer); - - if (py_raw_buffer_ptr == 0) { + void *ptr = PyCapsule_GetPointer(capsule, halide_buffer_capsule_name); + Py_DECREF(capsule); + if (!ptr) { + PyErr_Clear(); return false; } - halide_buf = reinterpret_cast(py_raw_buffer_ptr); + halide_buf = static_cast(ptr); return true; } @@ -183,4 +188,7 @@ struct PyHalideBuffer { halide_buffer_t unpacked_buf; }; +#undef HALIDE_PYTHON_STRINGIFY +#undef HALIDE_PYTHON_STRINGIFY_IMPL + } // namespace From e76210c291a577708e0000dfd7da5980756727dc Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 08:58:46 -0400 Subject: [PATCH 33/39] Preserve Python binding exceptions --- .../src/halide/runtime/PyRuntime.cpp | 30 +++++++++---------- .../halide/src/halide_/PyBuffer.cpp | 10 ++++--- python_bindings/halide/src/halide_/PyFunc.cpp | 4 ++- .../halide/src/halide_/PyHalide.cpp | 15 +++++----- src/PythonExtensionRuntime.template.cpp | 21 +++++++++---- 5 files changed, 46 insertions(+), 34 deletions(-) diff --git a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp index dae713b4ab55..f5fa615d0e9d 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp +++ b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp @@ -217,6 +217,7 @@ class Kernel { halide_buffer_t buffer{}; std::vector dims; Py_buffer py_buf{}; + py::object capsule; bool py_buf_valid = false; bool needs_device_free = false; }; @@ -360,30 +361,27 @@ class Kernel { py::handle value, bool writable, ArgSlot &slot) { - PyObject *obj = value.ptr(); - // Fast path: an object that already exposes a halide_buffer_t capsule // (halide.Buffer, halide.runtime.Buffer, or another generated result). - if (PyObject_HasAttrString(obj, "_get_halide_buffer_t_capsule")) { - PyObject *capsule = PyObject_CallMethod(obj, "_get_halide_buffer_t_capsule", nullptr); - if (capsule && PyCapsule_CheckExact(capsule)) { - void *ptr = PyCapsule_GetPointer( - capsule, Halide::PythonRuntimeBindings::halide_buffer_capsule_name); - Py_DECREF(capsule); - if (ptr) { - return static_cast(ptr); - } - PyErr_Clear(); - } else { - Py_XDECREF(capsule); - PyErr_Clear(); + py::object get_capsule = py::getattr(value, "_get_halide_buffer_t_capsule", py::none()); + if (!get_capsule.is_none()) { + py::object capsule = get_capsule(); + if (!py::isinstance(capsule)) { + throw py::type_error("_get_halide_buffer_t_capsule() must return a PyCapsule"); + } + void *ptr = PyCapsule_GetPointer( + capsule.ptr(), Halide::PythonRuntimeBindings::halide_buffer_capsule_name); + if (!ptr) { + throw py::error_already_set(); } + slot.capsule = std::move(capsule); + return static_cast(ptr); } // General path: buffer-protocol object (e.g. NumPy array). slot.dims.resize(a.dimensions > 0 ? a.dimensions : 1); bool ok = Halide::PythonRuntime::unpack_buffer( - obj, writable ? PyBUF_WRITABLE : 0, a.name, a.dimensions, + value.ptr(), writable ? PyBUF_WRITABLE : 0, a.name, a.dimensions, slot.py_buf, slot.dims.data(), slot.buffer, slot.py_buf_valid, slot.needs_device_free); if (!ok) { diff --git a/python_bindings/halide/src/halide_/PyBuffer.cpp b/python_bindings/halide/src/halide_/PyBuffer.cpp index 80568d9b98ec..fdc19c4dbac4 100644 --- a/python_bindings/halide/src/halide_/PyBuffer.cpp +++ b/python_bindings/halide/src/halide_/PyBuffer.cpp @@ -296,14 +296,16 @@ class PyBuffer : public Buffer<> { PyBuffer(const py::buffer &buffer, const std::string &name, bool reverse_axes) : Buffer<>(), info() { - if (py::hasattr(buffer, "_get_halide_runtime_buffer_capsule")) { - if (!py::hasattr(buffer, "defined")) { + py::object get_runtime_buffer = py::getattr(buffer, "_get_halide_runtime_buffer_capsule", py::none()); + if (!get_runtime_buffer.is_none()) { + py::object defined = py::getattr(buffer, "defined", py::none()); + if (defined.is_none()) { throw py::type_error("Invalid halide.runtime.Buffer."); } - if (!buffer.attr("defined")().cast()) { + if (!defined().cast()) { return; } - const py::capsule capsule = buffer.attr("_get_halide_runtime_buffer_capsule")().cast(); + const py::capsule capsule = get_runtime_buffer().cast(); const auto *runtime_buffer = static_cast *>( PyCapsule_GetPointer(capsule.ptr(), runtime_buffer_capsule_name)); if (!runtime_buffer) { diff --git a/python_bindings/halide/src/halide_/PyFunc.cpp b/python_bindings/halide/src/halide_/PyFunc.cpp index bf91bdb738b8..6630efa0edba 100644 --- a/python_bindings/halide/src/halide_/PyFunc.cpp +++ b/python_bindings/halide/src/halide_/PyFunc.cpp @@ -65,7 +65,9 @@ void define_set_func_ref(py::class_ &func_class) { std::ostringstream os; os << "Loss of precision detected when casting " << rhs << " to a single precision float. The difference is " << diff << "."; std::string msg = os.str(); - PyErr_WarnEx(nullptr, msg.c_str(), 1); + if (PyErr_WarnEx(PyExc_RuntimeWarning, msg.c_str(), 1) < 0) { + throw py::error_already_set(); + } } func(lhs) = Expr(f); }); diff --git a/python_bindings/halide/src/halide_/PyHalide.cpp b/python_bindings/halide/src/halide_/PyHalide.cpp index dc2755bf6994..5f79877a4a03 100644 --- a/python_bindings/halide/src/halide_/PyHalide.cpp +++ b/python_bindings/halide/src/halide_/PyHalide.cpp @@ -95,14 +95,13 @@ Expr double_to_expr_check(double v) { std::ostringstream oss; oss.precision(17); oss << std::fixed << v; - PyErr_WarnEx( - PyExc_RuntimeWarning, - ("The floating-point value " + - oss.str() + - " will be interpreted as a float32 by Halide and lose precision;" - " add an explicit `f32()` or `f64()`` cast to avoid this warning.") - .c_str(), - 0); + const std::string warning = + "The floating-point value " + oss.str() + + " will be interpreted as a float32 by Halide and lose precision;" + " add an explicit `f32()` or `f64()` cast to avoid this warning."; + if (PyErr_WarnEx(PyExc_RuntimeWarning, warning.c_str(), 0) < 0) { + throw py::error_already_set(); + } } return Expr(f); } diff --git a/src/PythonExtensionRuntime.template.cpp b/src/PythonExtensionRuntime.template.cpp index defe010f9410..d20a27c21887 100644 --- a/src/PythonExtensionRuntime.template.cpp +++ b/src/PythonExtensionRuntime.template.cpp @@ -124,32 +124,39 @@ struct PyHalideBuffer { Py_buffer py_buf; halide_buffer_t *halide_buf = nullptr; + PyObject *halide_buf_capsule = nullptr; bool py_buf_needs_release = false; bool needs_device_free = false; bool unpack_from_halide_buffer(PyObject *py_obj) { - if (!PyObject_HasAttrString(py_obj, get_halide_buffer_capsule_fn)) { + PyObject *get_capsule = PyObject_GetAttrString(py_obj, get_halide_buffer_capsule_fn); + if (!get_capsule) { + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } return false; } - PyObject *capsule = PyObject_CallMethod(py_obj, get_halide_buffer_capsule_fn, nullptr); + PyObject *capsule = PyObject_CallObject(get_capsule, nullptr); + Py_DECREF(get_capsule); if (!capsule) { - PyErr_Clear(); return false; } if (!PyCapsule_CheckExact(capsule)) { + PyErr_Format(PyExc_TypeError, "%s() must return a PyCapsule", get_halide_buffer_capsule_fn); Py_DECREF(capsule); return false; } void *ptr = PyCapsule_GetPointer(capsule, halide_buffer_capsule_name); - Py_DECREF(capsule); if (!ptr) { - PyErr_Clear(); + Py_DECREF(capsule); return false; } + // Keep the capsule alive for as long as we use the pointer it contains. + halide_buf_capsule = capsule; halide_buf = static_cast(ptr); return true; } @@ -158,6 +165,9 @@ struct PyHalideBuffer { if (unpack_from_halide_buffer(py_obj)) { return true; } + if (PyErr_Occurred()) { + return false; + } if (Halide::PythonRuntime::unpack_buffer( py_obj, py_getbuffer_flags, name, dimensions, py_buf, unpacked_dim, unpacked_buf, py_buf_needs_release, @@ -175,6 +185,7 @@ struct PyHalideBuffer { if (py_buf_needs_release) { PyBuffer_Release(&py_buf); } + Py_XDECREF(halide_buf_capsule); } PyHalideBuffer() = default; From 19e777f94691f0a5e6d40c991ca17b3baf35ec7a Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 09:00:57 -0400 Subject: [PATCH 34/39] Validate Python buffer metadata --- .../src/halide/runtime/PyRuntimeBuffer.cpp | 43 +++++++++++--- src/PythonExtensionRuntime.template.cpp | 57 +++++++++++++++---- 2 files changed, 82 insertions(+), 18 deletions(-) diff --git a/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp b/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp index ebba6d69236e..d5b6a86e1a50 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp +++ b/python_bindings/halide-runtime/src/halide/runtime/PyRuntimeBuffer.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -37,10 +38,28 @@ std::string format_descriptor() { return "e"; } -halide_type_t format_descriptor_to_type(const std::string &format) { -#define HANDLE_TYPE(TYPE) \ - if (format == format_descriptor()) { \ - return Halide::Runtime::Buffer::static_halide_type(); \ +halide_type_t format_descriptor_to_type(std::string format, py::ssize_t itemsize) { + char byte_order = '@'; + if (!format.empty() && std::strchr("@<>!=", format.front())) { + byte_order = format.front(); + format.erase(format.begin()); + } + const uint16_t endian_test = 1; + const bool native_is_little_endian = *reinterpret_cast(&endian_test) == 1; + const bool non_native_byte_order = + (native_is_little_endian && (byte_order == '>' || byte_order == '!')) || + (!native_is_little_endian && byte_order == '<'); + if (non_native_byte_order && itemsize > 1) { + throw py::value_error("Non-native byte order is not supported."); + } + +#define HANDLE_TYPE(TYPE) \ + if (format == format_descriptor()) { \ + const halide_type_t type = Halide::Runtime::Buffer::static_halide_type(); \ + if (type.bytes() != itemsize) { \ + throw py::value_error("Buffer item size does not match its format."); \ + } \ + return type; \ } HANDLE_TYPE(bool) HANDLE_TYPE(uint8_t) @@ -56,7 +75,11 @@ halide_type_t format_descriptor_to_type(const std::string &format) { HANDLE_TYPE(double) #undef HANDLE_TYPE if (format == "l") { - return sizeof(long) == 8 ? Runtime::Buffer::static_halide_type() : Runtime::Buffer::static_halide_type(); + const halide_type_t type = itemsize == 8 ? Runtime::Buffer::static_halide_type() : Runtime::Buffer::static_halide_type(); + if (type.bytes() != itemsize) { + throw py::value_error("Buffer item size does not match its format."); + } + return type; } throw py::value_error("Unsupported Buffer<> type."); } @@ -140,11 +163,17 @@ class Buffer { Buffer(py::buffer source, std::string name, bool reverse_axes) : owner_(std::move(source)), identity_(std::make_shared()), name_(name.empty() ? unique_name() : std::move(name)), defined_(true) { py::buffer_info info = py::reinterpret_borrow(owner_).request(true); - const halide_type_t type = format_descriptor_to_type(info.format); + if (info.ndim < 0 || info.ndim > INT32_MAX) { + throw py::value_error("Out of range dimensionality in buffer conversion."); + } + const halide_type_t type = format_descriptor_to_type(info.format, info.itemsize); std::vector dims(info.ndim); for (int i = 0; i < info.ndim; ++i) { + if (info.strides[i] % type.bytes() != 0) { + throw py::value_error("Buffer byte stride is not a multiple of its item size."); + } const auto stride = info.strides[i] / type.bytes(); - if (info.shape[i] > INT32_MAX || stride < INT32_MIN || stride > INT32_MAX) { + if (info.shape[i] < 0 || info.shape[i] > INT32_MAX || stride < INT32_MIN || stride > INT32_MAX) { throw py::value_error("Out of range dimensions in buffer conversion."); } const int dst = reverse_axes ? info.ndim - i - 1 : i; diff --git a/src/PythonExtensionRuntime.template.cpp b/src/PythonExtensionRuntime.template.cpp index d20a27c21887..0d4e84a5fa51 100644 --- a/src/PythonExtensionRuntime.template.cpp +++ b/src/PythonExtensionRuntime.template.cpp @@ -18,6 +18,7 @@ */ #include +#include #include #include @@ -39,7 +40,8 @@ inline bool unpack_buffer(PyObject *py_obj, memset(&py_buf, 0, sizeof(py_buf)); if (PyObject_GetBuffer(py_obj, &py_buf, PyBUF_FORMAT | PyBUF_STRIDED_RO | py_getbuffer_flags) < 0) { - PyErr_Format(PyExc_ValueError, "Invalid argument %s: Expected %d dimensions, got %d", name, dimensions, py_buf.ndim); + // Preserve the buffer exporter's exception (notably, the specific error + // reported when a writable view was requested from a read-only object). return false; } py_buf_valid = true; @@ -48,14 +50,31 @@ inline bool unpack_buffer(PyObject *py_obj, PyErr_Format(PyExc_ValueError, "Invalid argument %s: Expected %d dimensions, got %d", name, dimensions, py_buf.ndim); return false; } + if (py_buf.itemsize <= 0) { + PyErr_Format(PyExc_ValueError, "Invalid argument %s: Buffer item size must be positive", name); + return false; + } // Always reverse axes. // TODO(jiawen): Can probably consolidate this with similar code in PyCallable.cpp and // pybufferinfo_to_halidebuffer() in PyBuffer.h. for (int i = 0; i < py_buf.ndim; ++i) { const int j = py_buf.ndim - 1 - i; // numpy axis j maps to Halide dim i + if (py_buf.shape[j] < 0 || py_buf.shape[j] > INT32_MAX) { + PyErr_Format(PyExc_ValueError, "Invalid argument %s: Buffer extent is out of range", name); + return false; + } + if (py_buf.strides[j] % py_buf.itemsize != 0) { + PyErr_Format(PyExc_ValueError, "Invalid argument %s: Buffer byte stride is not a multiple of its item size", name); + return false; + } + const Py_ssize_t element_stride = py_buf.strides[j] / py_buf.itemsize; + if (element_stride < INT32_MIN || element_stride > INT32_MAX) { + PyErr_Format(PyExc_ValueError, "Invalid argument %s: Buffer stride is out of range", name); + return false; + } halide_dim[i].min = 0; - halide_dim[i].stride = (int)(py_buf.strides[j] / py_buf.itemsize); // Python strides are in bytes - halide_dim[i].extent = (int)py_buf.shape[j]; + halide_dim[i].stride = static_cast(element_stride); + halide_dim[i].extent = static_cast(py_buf.shape[j]); halide_dim[i].flags = 0; if (py_buf.suboffsets && py_buf.suboffsets[j] >= 0) { // Halide doesn't support arrays of pointers. But we should never see this @@ -66,16 +85,29 @@ inline bool unpack_buffer(PyObject *py_obj, } halide_buf = {}; - needs_device_free = true; if (!py_buf.format) { + if (py_buf.itemsize != 1) { + PyErr_Format(PyExc_ValueError, "Invalid data type for %s: Missing format for a multi-byte buffer", name); + return false; + } halide_buf.type.code = halide_type_uint; halide_buf.type.bits = 8; } else { /* Convert struct type code. See * https://docs.python.org/2/library/struct.html#module-struct */ - char *p = py_buf.format; - while (strchr("@<>!=", *p)) { - p++; // ignore little/bit endian (and alignment) + const char *p = py_buf.format; + char byte_order = '@'; + if (strchr("@<>!=", *p)) { + byte_order = *p++; + } + const uint16_t endian_test = 1; + const bool native_is_little_endian = *reinterpret_cast(&endian_test) == 1; + const bool non_native_byte_order = + (native_is_little_endian && (byte_order == '>' || byte_order == '!')) || + (!native_is_little_endian && byte_order == '<'); + if (non_native_byte_order && py_buf.itemsize > 1) { + PyErr_Format(PyExc_ValueError, "Invalid data type for %s: Non-native byte order %s is not supported", name, py_buf.format); + return false; } if (*p == 'f' || *p == 'd' || *p == 'e') { // 'f', 'd', and 'e' are float, double, and half, respectively. @@ -88,12 +120,14 @@ inline bool unpack_buffer(PyObject *py_obj, halide_buf.type.code = halide_type_uint; } const char *type_codes = "bBhHiIlLqQfde"; // integers and floats - if (*p == '?') { + if (*p == '?' && p[1] == '\0' && py_buf.itemsize == 1) { // Special-case bool, so that it is a distinct type vs uint8_t // (even though the memory layout is identical) halide_buf.type.bits = 1; - } else if (strchr(type_codes, *p)) { - halide_buf.type.bits = (uint8_t)py_buf.itemsize * 8; + } else if (strchr(type_codes, *p) && p[1] == '\0' && + (py_buf.itemsize == 1 || py_buf.itemsize == 2 || + py_buf.itemsize == 4 || py_buf.itemsize == 8)) { + halide_buf.type.bits = static_cast(py_buf.itemsize * 8); } else { // We don't handle 's' and 'p' (char[]) and 'P' (void*) PyErr_Format(PyExc_ValueError, "Invalid data type for %s: %s", name, py_buf.format); @@ -102,7 +136,8 @@ inline bool unpack_buffer(PyObject *py_obj, } halide_buf.dimensions = py_buf.ndim; halide_buf.dim = halide_dim; - halide_buf.host = (uint8_t *)py_buf.buf; + halide_buf.host = static_cast(py_buf.buf); + needs_device_free = true; return true; } From 8a706ede7c623497fedfd14858e0de02beeff87b Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 09:02:13 -0400 Subject: [PATCH 35/39] Narrow Python binding conversion catches --- .../src/halide/runtime/PyRuntime.cpp | 5 ++++- .../src/halide_/PyBoundaryConditions.cpp | 20 +++++++++---------- python_bindings/halide/src/halide_/PyFunc.cpp | 6 +++--- .../halide/src/halide_/PyHalide.cpp | 2 +- .../halide/src/halide_/PyPipeline.cpp | 6 +++--- .../halide/src/halide_/PyTuple.cpp | 4 ++-- 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp index f5fa615d0e9d..becb1b18c862 100644 --- a/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp +++ b/python_bindings/halide-runtime/src/halide/runtime/PyRuntime.cpp @@ -15,9 +15,11 @@ #include #include +#include #include #include +#include #include #include #include @@ -430,7 +432,8 @@ std::string type_to_string(halide_type_t t) { return out.str(); } -std::shared_ptr load(const std::string &path, const py::object &name_obj) { +std::shared_ptr load(const std::filesystem::path &path_obj, const py::object &name_obj) { + const std::string path = path_obj.string(); LibHandle handle = open_library(path); if (!handle) { throw std::runtime_error("Could not load '" + path + "': " + library_error()); diff --git a/python_bindings/halide/src/halide_/PyBoundaryConditions.cpp b/python_bindings/halide/src/halide_/PyBoundaryConditions.cpp index 3c3e1681fea4..55eae71d0d1b 100644 --- a/python_bindings/halide/src/halide_/PyBoundaryConditions.cpp +++ b/python_bindings/halide/src/halide_/PyBoundaryConditions.cpp @@ -37,12 +37,12 @@ void define_boundary_conditions(py::module &m) { "constant_exterior", [](const py::object &target, const Expr &exterior, const Region &bounds) -> Func { try { return constant_exterior(target.cast(), exterior, bounds); - } catch (...) { + } catch (const py::cast_error &) { // fall thru } try { return constant_exterior(to_func(target.cast>()), exterior, bounds); - } catch (...) { + } catch (const py::cast_error &) { // fall thru } throw py::value_error("Invalid arguments to constant_exterior"); @@ -65,12 +65,12 @@ void define_boundary_conditions(py::module &m) { "repeat_edge", [](const py::object &target, const Region &bounds) -> Func { try { return repeat_edge(target.cast(), bounds); - } catch (...) { + } catch (const py::cast_error &) { // fall thru } try { return repeat_edge(to_func(target.cast>()), bounds); - } catch (...) { + } catch (const py::cast_error &) { // fall thru } throw py::value_error("Invalid arguments to repeat_edge"); @@ -93,12 +93,12 @@ void define_boundary_conditions(py::module &m) { "repeat_image", [](const py::object &target, const Region &bounds) -> Func { try { return repeat_image(target.cast(), bounds); - } catch (...) { + } catch (const py::cast_error &) { // fall thru } try { return repeat_image(to_func(target.cast>()), bounds); - } catch (...) { + } catch (const py::cast_error &) { // fall thru } throw py::value_error("Invalid arguments to repeat_image"); @@ -121,12 +121,12 @@ void define_boundary_conditions(py::module &m) { "mirror_image", [](const py::object &target, const Region &bounds) -> Func { try { return mirror_image(target.cast(), bounds); - } catch (...) { + } catch (const py::cast_error &) { // fall thru } try { return mirror_image(to_func(target.cast>()), bounds); - } catch (...) { + } catch (const py::cast_error &) { // fall thru } throw py::value_error("Invalid arguments to mirror_image"); @@ -149,12 +149,12 @@ void define_boundary_conditions(py::module &m) { "mirror_interior", [](const py::object &target, const Region &bounds) -> Func { try { return mirror_interior(target.cast(), bounds); - } catch (...) { + } catch (const py::cast_error &) { // fall thru } try { return mirror_interior(to_func(target.cast>()), bounds); - } catch (...) { + } catch (const py::cast_error &) { // fall thru } throw py::value_error("Invalid arguments to mirror_interior"); diff --git a/python_bindings/halide/src/halide_/PyFunc.cpp b/python_bindings/halide/src/halide_/PyFunc.cpp index 6630efa0edba..a3cd4d9e4ece 100644 --- a/python_bindings/halide/src/halide_/PyFunc.cpp +++ b/python_bindings/halide/src/halide_/PyFunc.cpp @@ -392,7 +392,7 @@ void define_func(py::module &m) { Buffer<> b = dst.cast>(); f.infer_input_bounds(&juc, b, t); return; - } catch (...) { + } catch (const py::cast_error &) { // fall thru } @@ -400,7 +400,7 @@ void define_func(py::module &m) { std::vector> v = dst.cast>>(); f.infer_input_bounds(&juc, Realization(std::move(v)), t); return; - } catch (...) { + } catch (const py::cast_error &) { // fall thru } @@ -408,7 +408,7 @@ void define_func(py::module &m) { std::vector v = dst.cast>(); f.infer_input_bounds(&juc, v, t); return; - } catch (...) { + } catch (const py::cast_error &) { // fall thru } diff --git a/python_bindings/halide/src/halide_/PyHalide.cpp b/python_bindings/halide/src/halide_/PyHalide.cpp index 5f79877a4a03..fbccc1824744 100644 --- a/python_bindings/halide/src/halide_/PyHalide.cpp +++ b/python_bindings/halide/src/halide_/PyHalide.cpp @@ -115,7 +115,7 @@ std::vector collect_print_args(const py::args &args) { // to Expr, but in this unusual case we do. try { v.emplace_back(arg.cast()); - } catch (...) { + } catch (const py::cast_error &) { v.push_back(arg.cast()); } } diff --git a/python_bindings/halide/src/halide_/PyPipeline.cpp b/python_bindings/halide/src/halide_/PyPipeline.cpp index f9544c2f9f62..ec551a501e56 100644 --- a/python_bindings/halide/src/halide_/PyPipeline.cpp +++ b/python_bindings/halide/src/halide_/PyPipeline.cpp @@ -237,7 +237,7 @@ void define_pipeline(py::module &m) { Buffer<> b = dst.cast>(); p.infer_input_bounds(&juc, b, t); return; - } catch (...) { + } catch (const py::cast_error &) { // fall thru } @@ -245,7 +245,7 @@ void define_pipeline(py::module &m) { std::vector> v = dst.cast>>(); p.infer_input_bounds(&juc, Realization(std::move(v)), t); return; - } catch (...) { + } catch (const py::cast_error &) { // fall thru } @@ -253,7 +253,7 @@ void define_pipeline(py::module &m) { std::vector v = dst.cast>(); p.infer_input_bounds(&juc, v, t); return; - } catch (...) { + } catch (const py::cast_error &) { // fall thru } diff --git a/python_bindings/halide/src/halide_/PyTuple.cpp b/python_bindings/halide/src/halide_/PyTuple.cpp index 934008e20d8c..4f9bc9c97efd 100644 --- a/python_bindings/halide/src/halide_/PyTuple.cpp +++ b/python_bindings/halide/src/halide_/PyTuple.cpp @@ -7,7 +7,7 @@ Tuple to_halide_tuple(const py::object &o) { try { Expr e = o.cast(); return Tuple(e); - } catch (...) { + } catch (const py::cast_error &) { // fall thru } @@ -21,7 +21,7 @@ Tuple to_halide_tuple(const py::object &o) { v[i] = t[i].cast(); } return Tuple(v); - } catch (...) { + } catch (const py::cast_error &) { // fall thru } From 34b950e73b3f18ec996608ce7e98e19b195f6a6a Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 09:05:58 -0400 Subject: [PATCH 36/39] Test Python API error handling --- .../halide-runtime/test/call_convention.py | 24 ++++++++++ .../halide-runtime/test/load_aot.py | 46 ++++++++++++++++++- python_bindings/halide/apps/identity_app.py | 17 +++++++ .../test/correctness/float_precision_test.py | 11 +++++ .../test/correctness/multipass_constraints.py | 17 +++++++ 5 files changed, 114 insertions(+), 1 deletion(-) diff --git a/python_bindings/halide-runtime/test/call_convention.py b/python_bindings/halide-runtime/test/call_convention.py index 635f716f6987..633d189406eb 100644 --- a/python_bindings/halide-runtime/test/call_convention.py +++ b/python_bindings/halide-runtime/test/call_convention.py @@ -113,6 +113,30 @@ def main(): call_args["packed.1"], expected_total.astype(np.int32) ) + # Reject multi-byte arrays whose declared byte order differs from the host, + # rather than silently writing native-endian data into them. + invalid_args = call_args.copy() + invalid_args["total"] = np.zeros(shape, dtype=">i8") + try: + kernel(**invalid_args) + except ValueError as e: + assert "Non-native byte order" in str(e) + else: + assert False, "non-native-endian output was accepted" + + # Reject byte strides that cannot be represented as an integral Halide + # element stride. + invalid_args = call_args.copy() + invalid_args["packed.1"] = np.ndarray( + shape, dtype=np.int32, buffer=bytearray(32), strides=(1, 1) + ) + try: + kernel(**invalid_args) + except ValueError as e: + assert "stride" in str(e) + else: + assert False, "non-integral element stride was accepted" + # The enum GeneratorParam is a compile-time choice: the `combine=xor` build is # a different kernel with the *same* calling convention but different behavior. xor_kernel = hlr.load(xor_path, name="callconv_xor") diff --git a/python_bindings/halide-runtime/test/load_aot.py b/python_bindings/halide-runtime/test/load_aot.py index 07be7e04618e..9f198359f975 100644 --- a/python_bindings/halide-runtime/test/load_aot.py +++ b/python_bindings/halide-runtime/test/load_aot.py @@ -6,6 +6,7 @@ """ import sys +from pathlib import Path import numpy as np @@ -20,7 +21,8 @@ def main(): "importing halide.runtime pulled in the halide compiler extension" ) - kernel = hlr.load(aot_path, name="runtimeadd") + # load() accepts the standard os.PathLike protocol. + kernel = hlr.load(Path(aot_path), name="runtimeadd") assert kernel.name == "runtimeadd", kernel.name assert kernel.argument_names == ["input", "offset", "output"], kernel.argument_names @@ -55,6 +57,48 @@ def main(): expected3 = ((rng.astype(np.int64) + 7) % 256).astype(np.uint8) assert np.array_equal(out3, expected3), (out3, expected3) + # Exceptions raised by the capsule protocol must not be discarded in favor + # of an attempted buffer-protocol fallback. + class CapsuleError(Exception): + pass + + class BrokenCapsuleProvider: + def _get_halide_buffer_t_capsule(self): + raise CapsuleError("capsule failure") + + try: + kernel(BrokenCapsuleProvider(), 1, bytearray(1)) + except CapsuleError as e: + assert str(e) == "capsule failure" + else: + assert False, "capsule protocol exception was suppressed" + + # Preserve the buffer exporter's useful error for a read-only output. + try: + kernel(bytearray(1), 1, bytes(1)) + except BufferError as e: + assert "writable" in str(e) + else: + assert False, "read-only output was accepted" + + # Halide strides are measured in elements, so byte strides must divide + # evenly by the item size. + overlapping = np.ndarray((2,), dtype=np.int32, buffer=bytearray(8), strides=(1,)) + try: + hlr.Buffer(overlapping) + except ValueError as e: + assert "stride" in str(e) + else: + assert False, "non-integral element stride was accepted" + + # Multi-byte buffers must use native byte order. + try: + hlr.Buffer(np.zeros(1, dtype=">i4")) + except ValueError as e: + assert "byte order" in str(e) + else: + assert False, "non-native-endian buffer was accepted" + # Still no compiler after all of this. assert "halide.halide_" not in sys.modules diff --git a/python_bindings/halide/apps/identity_app.py b/python_bindings/halide/apps/identity_app.py index aa77755bb367..77a18c5522a8 100644 --- a/python_bindings/halide/apps/identity_app.py +++ b/python_bindings/halide/apps/identity_app.py @@ -31,6 +31,23 @@ def main(): if not np.array_equal(array, expected): sys.exit("hl.Buffer failure!") + # Generated extensions use the same named-capsule protocol as + # halide.runtime. Exceptions from that protocol must propagate rather than + # being discarded before a buffer-protocol fallback. + class CapsuleError(Exception): + pass + + class BrokenCapsuleArray(np.ndarray): + def _get_halide_buffer_t_capsule(self): + raise CapsuleError("capsule failure") + + try: + identity(array.view(BrokenCapsuleArray)) + except CapsuleError as e: + assert str(e) == "capsule failure" + else: + assert False, "capsule protocol exception was suppressed" + print("Success!") diff --git a/python_bindings/halide/test/correctness/float_precision_test.py b/python_bindings/halide/test/correctness/float_precision_test.py index 0308781eb8b8..c39bed7fa100 100644 --- a/python_bindings/halide/test/correctness/float_precision_test.py +++ b/python_bindings/halide/test/correctness/float_precision_test.py @@ -55,6 +55,17 @@ def test_pattern(c): x + 0.75 # 0.5 + 0.25 assert not ctx.occurred, "RuntimeWarning occurred." + # Warning filters may promote warnings to exceptions; propagate that + # RuntimeWarning rather than returning with a pending Python exception. + with warnings.catch_warnings(): + warnings.simplefilter("error", RuntimeWarning) + try: + x + 0.123456789012345678 + except RuntimeWarning: + pass + else: + assert False, "RuntimeWarning was not raised as an exception" + if __name__ == "__main__": test() diff --git a/python_bindings/halide/test/correctness/multipass_constraints.py b/python_bindings/halide/test/correctness/multipass_constraints.py index fd69c16ec980..b16219a91d74 100644 --- a/python_bindings/halide/test/correctness/multipass_constraints.py +++ b/python_bindings/halide/test/correctness/multipass_constraints.py @@ -58,5 +58,22 @@ def test_multipass_constraints(): assert False +def test_infer_input_bounds_preserves_halide_error(): + output = hl.Func("undefined_output") + query = hl.Buffer.make_bounds_query(type=hl.UInt(8), sizes=[4]) + + def expect_halide_error(infer): + try: + infer(query) + except hl.HalideError as e: + assert "undefined output Func" in str(e) + else: + assert False, "HalideError was suppressed by overload dispatch" + + expect_halide_error(output.infer_input_bounds) + expect_halide_error(hl.Pipeline(output).infer_input_bounds) + + if __name__ == "__main__": test_multipass_constraints() + test_infer_input_bounds_preserves_halide_error() From 9c32e5e23f99421dbb57dc3b2174febd933ecc2b Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 09:06:54 -0400 Subject: [PATCH 37/39] Make endian tests host-independent --- python_bindings/halide-runtime/test/call_convention.py | 3 ++- python_bindings/halide-runtime/test/load_aot.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/python_bindings/halide-runtime/test/call_convention.py b/python_bindings/halide-runtime/test/call_convention.py index 633d189406eb..2a8b3f0b9e2e 100644 --- a/python_bindings/halide-runtime/test/call_convention.py +++ b/python_bindings/halide-runtime/test/call_convention.py @@ -116,7 +116,8 @@ def main(): # Reject multi-byte arrays whose declared byte order differs from the host, # rather than silently writing native-endian data into them. invalid_args = call_args.copy() - invalid_args["total"] = np.zeros(shape, dtype=">i8") + non_native_i8 = ">i8" if sys.byteorder == "little" else " Date: Sat, 22 Aug 2026 09:21:07 -0400 Subject: [PATCH 38/39] Use filesystem paths in Python bindings --- python_bindings/halide/src/halide_/PyHalide.h | 51 ------------------- .../halide/src/halide_/PySerialization.cpp | 16 +++--- 2 files changed, 9 insertions(+), 58 deletions(-) diff --git a/python_bindings/halide/src/halide_/PyHalide.h b/python_bindings/halide/src/halide_/PyHalide.h index 6a5f3b3f92ca..64003c339bb3 100644 --- a/python_bindings/halide/src/halide_/PyHalide.h +++ b/python_bindings/halide/src/halide_/PyHalide.h @@ -37,58 +37,7 @@ Expr double_to_expr_check(double v); Target to_jit_target(const Target &target); Target to_aot_target(const Target &target); -// TODO: when out base toolchains are modern enough, we can just -// use std::filesystem::path, since pybind11 has a built-in type -// caster in . -// See: https://github.com/halide/Halide/issues/8723 -class PathLike { - std::string path; - -public: - PathLike() = default; - PathLike(const py::bytes &path) - : path(path) { - } - - operator const std::string &() const { - return path; - } - - PyObject *decode() const { - return PyUnicode_DecodeFSDefaultAndSize(path.c_str(), static_cast(path.size())); - } -}; - } // namespace PythonBindings } // namespace Halide -template<> -class pybind11::detail::type_caster { -public: - PYBIND11_TYPE_CASTER(Halide::PythonBindings::PathLike, const_name("os.PathLike")); - - bool load(handle src, bool) { - try { - PyObject *path = nullptr; - if (!PyUnicode_FSConverter(src.ptr(), &path)) { - throw error_already_set(); - } - value = reinterpret_steal(path); - return true; - } catch (error_already_set &) { - return false; - } - } - - static handle cast(const Halide::PythonBindings::PathLike &path, - return_value_policy, handle) { - if (auto *py_str = path.decode()) { - return module_::import("pathlib") - .attr("Path")(reinterpret_steal(py_str)) - .release(); - } - return nullptr; - } -}; - #endif // HALIDE_PYTHON_BINDINGS_PYHALIDE_H diff --git a/python_bindings/halide/src/halide_/PySerialization.cpp b/python_bindings/halide/src/halide_/PySerialization.cpp index 2146cf4f7a7d..49db1b45769d 100644 --- a/python_bindings/halide/src/halide_/PySerialization.cpp +++ b/python_bindings/halide/src/halide_/PySerialization.cpp @@ -1,5 +1,7 @@ #include "PySerialization.h" +#include + #include namespace Halide { @@ -8,13 +10,13 @@ namespace PythonBindings { void define_serialization(py::module &m) { // Serialize pipeline functions m.def("serialize_pipeline", // - [](const Pipeline &pipeline, const PathLike &filename, std::optional get_params) -> std::optional> { + [](const Pipeline &pipeline, const std::filesystem::path &filename, std::optional get_params) -> std::optional> { if (get_params.value_or(false)) { std::map params; - serialize_pipeline(pipeline, filename, params); + serialize_pipeline(pipeline, filename.string(), params); return params; } - serialize_pipeline(pipeline, filename); + serialize_pipeline(pipeline, filename.string()); return {}; // }, py::arg("pipeline"), // @@ -54,8 +56,8 @@ void define_serialization(py::module &m) { "Deserialize a Halide pipeline from bytes."); m.def("deserialize_pipeline", // - [](const PathLike &filename, const std::map &user_params) -> Pipeline { - return deserialize_pipeline(filename, user_params); // + [](const std::filesystem::path &filename, const std::map &user_params) -> Pipeline { + return deserialize_pipeline(filename.string(), user_params); // }, py::arg("filename"), // py::arg("user_params") = std::map{}, // @@ -74,8 +76,8 @@ void define_serialization(py::module &m) { "Deserialize external parameters from serialized pipeline bytes."); m.def("deserialize_parameters", // - [](const PathLike &filename) -> std::map { - return deserialize_parameters(filename); // + [](const std::filesystem::path &filename) -> std::map { + return deserialize_parameters(filename.string()); // }, py::arg("filename"), // "Deserialize external parameters from a serialized pipeline file. Accepts string or path-like objects."); From ad25832d4257f86defc8f332e6c569c1db1ea6cf Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sat, 22 Aug 2026 09:40:01 -0400 Subject: [PATCH 39/39] Invalidate Python workspace builds per commit --- python_bindings/halide-bin/pyproject.toml | 6 ++++++ python_bindings/halide-runtime/pyproject.toml | 6 ++++++ python_bindings/halide/pyproject.toml | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/python_bindings/halide-bin/pyproject.toml b/python_bindings/halide-bin/pyproject.toml index d6d13406146a..cd8233b6d86f 100644 --- a/python_bindings/halide-bin/pyproject.toml +++ b/python_bindings/halide-bin/pyproject.toml @@ -103,3 +103,9 @@ cmake.source-dir = "." [tool.setuptools_scm] root = "../.." + +[tool.uv] +cache-keys = [ + { file = "pyproject.toml" }, + { git = { commit = true, tags = true } }, +] diff --git a/python_bindings/halide-runtime/pyproject.toml b/python_bindings/halide-runtime/pyproject.toml index c52b6721fe7e..dd06086a827c 100644 --- a/python_bindings/halide-runtime/pyproject.toml +++ b/python_bindings/halide-runtime/pyproject.toml @@ -101,3 +101,9 @@ cmake.source-dir = "python_bindings" [tool.setuptools_scm] root = "../.." + +[tool.uv] +cache-keys = [ + { file = "pyproject.toml" }, + { git = { commit = true, tags = true } }, +] diff --git a/python_bindings/halide/pyproject.toml b/python_bindings/halide/pyproject.toml index 674cd5701d52..789163db7c41 100644 --- a/python_bindings/halide/pyproject.toml +++ b/python_bindings/halide/pyproject.toml @@ -133,6 +133,12 @@ cmake.source-dir = "python_bindings" [tool.setuptools_scm] root = "../.." +[tool.uv] +cache-keys = [ + { file = "pyproject.toml" }, + { git = { commit = true, tags = true } }, +] + [tool.ruff.lint] # docs: https://docs.astral.sh/ruff/rules/ select = [