Skip to content

build(jit-cache): split flashinfer-jit-cache wheels by SM family - #3265

Closed
dierksen wants to merge 10 commits into
flashinfer-ai:mainfrom
dierksen:worktree-wheel-size
Closed

dierksen wants to merge 10 commits into
flashinfer-ai:mainfrom
dierksen:worktree-wheel-size

Conversation

@dierksen

@dierksen dierksen commented May 7, 2026

Copy link
Copy Markdown
Collaborator

The cu130 flashinfer-jit-cache wheel grew to 2.0 GB and started failing to upload as a GitHub Release asset (per-asset 2 GiB limit; see #3257). Each new SM target appended ~150-200 MB compressed to every wheel, and cu130 carries 8 (sm75/80/89/90a/100a/103a/110a/120f).

Split each (CUDA, CPU-arch) wheel into three by GPU SM family:

  • sm9x - Ampere/Ada/Hopper (<= sm90a)
  • sm10x - Datacenter Blackwell (sm100a/103a/110a)
  • sm12x - Consumer Blackwell (sm120f, future sm121a)

Same package name everywhere; the family is encoded in the PEP 440 local-version, so wheels resolve as e.g. 'flashinfer-jit-cache== 0.6.11+cu130.sm10x'. Existing 'pip install flashinfer-jit-cache' still works once the right pin is given.

Driven by a new 'flashinfer install-jit-cache-wheel' subcommand that detects FlashInfer version, CUDA version, and GPU compute capability (via torch.cuda.get_device_capability) and runs the matching pip install. Honors --cuda-version, --sm-family, --nightly, --dry-run. Modeled on the CLI scaffolding from #3142 with the family dimension added.

Build side: 'FLASHINFER_JIT_CACHE_SM_FAMILY' env var, when set, filters 'FLASHINFER_CUDA_ARCH_LIST' to the family's archs and appends '.' to the local-version suffix. Release / nightly workflows gain an 'sm_family' matrix dimension; the upload-to-release loop iterates over all three families. The wheel-index regex accepts the new local-version shape and remains compatible with the legacy '+cuXY' format.

Closes #3257
Closes #3033

📌 Description

🔍 Related Issues

🚀 Pull Request Checklist

Thank you for contributing to FlashInfer! Before we review your pull request, please make sure the following items are complete.

✅ Pre-commit Checks

  • I have installed pre-commit by running pip install pre-commit (or used your preferred method).
  • I have installed the hooks with pre-commit install.
  • I have run the hooks manually with pre-commit run --all-files and fixed any reported issues.

If you are unsure about how to set up pre-commit, see the pre-commit documentation.

🧪 Tests

  • Tests have been added or updated as needed.
  • All tests are passing (unittest, etc.).

Reviewer Notes

Testing Done

Local DGX Spark validation:

  • Confirmed host is aarch64 with NVIDIA GB10, compute capability 12.1; PyTorch sees CUDA 13.0 and reports the device as (12, 1).
  • Ran flashinfer install-jit-cache-wheel --dry-run from the source checkout. It now resolves from version.txt when package metadata is 0.0.0+unknown, detects CUDA 13.0, selects sm12x, and prints flashinfer-jit-cache==0.6.11+cu130.sm12x.
  • Verified uv-style venv behavior: this environment has no python -m pip, so the CLI now falls back to uv pip install --python ....
  • Ran the live install path against https://flashinfer.ai/whl/cu130; it reached the resolver cleanly and failed only because 0.6.11+cu130.sm12x is not yet published.
  • Downloaded the PR-built jit-cache-cu129-aarch64-sm12x artifact from Release run 25528598737, served it through a local simple index, installed it with explicit --cuda-version cu129 --sm-family sm12x --index-url ..., imported flashinfer_jit_cache, verified FLASHINFER_AOT_DIR points at the installed package cache, then uninstalled it because the local machine is CUDA 13.0.
  • Checked the Release run artifacts: the matching jit-cache-cu130-aarch64-sm12x artifact is absent because that job failed while downloading build dependencies (IncompleteRead for nvidia_cublas), not because of the CLI install path.

Merge/conflict validation:

  • Merged current upstream/main and resolved conflicts in pr-test.yml, release.yml, and nightly-release.yml, preserving both FLASHINFER_JIT_CACHE_SM_FAMILY forwarding and upstream sccache/NVCC env forwarding.
  • Parsed the touched workflow YAML files with yaml.safe_load.
  • Ran git diff --cached --check.
  • Ran python -m py_compile flashinfer/__main__.py flashinfer/jit/env.py tests/cli/test_cli_cmds.py.
  • Ran python -m pytest tests/cli/test_cli_cmds.py -q (18 passed).

Review-comment follow-up:

  • Reviewed the unresolved Gemini and CodeRabbit comments. Addressed Gemini's arch-list parsing case by accepting integer-style entries like 90, 100, and 120 in the SM-family filter, and moved the duplicated SM-family helpers into build_utils.py for reuse by both the CLI and jit-cache build backend.
  • Addressed CodeRabbit's --nightly concern by rejecting nightly installs when the resolved FlashInfer version is not a dev release; dev versions still exact-pin the matching SM-family wheel, e.g. flashinfer-jit-cache==0.6.11.dev20260508+cu130.sm12x.
  • Ran python -m py_compile build_utils.py flashinfer/__main__.py flashinfer-jit-cache/build_backend.py tests/cli/test_cli_cmds.py.
  • Ran python -m pytest tests/cli/test_cli_cmds.py -q (21 passed, with the expected PyTorch GB10 capability warning from this host's torch build).
  • Ran git diff --check.
  • Ran release CLI dry-run: flashinfer install-jit-cache-wheel --cuda-version cu130 --sm-family sm12x --dry-run, which resolves flashinfer-jit-cache==0.6.11+cu130.sm12x and the uv pip install --python ... command.
  • Ran nightly CLI dry-runs for both paths: stable 0.6.11 now fails early with the new explanatory error, while explicit 0.6.11.dev20260508 resolves flashinfer-jit-cache==0.6.11.dev20260508+cu130.sm12x against https://flashinfer.ai/whl/nightly/cu130 with --pre.

Human feedback follow-up:

  • Updated flashinfer install-jit-cache-wheel autodetection to inspect every visible CUDA device instead of only device 0. It selects a wheel only when the visible GPUs are covered by one jit-cache SM-family wheel, and otherwise fails with guidance to pass --sm-family or build from source with an explicit FLASHINFER_CUDA_ARCH_LIST.
  • Treated Blackwell-family wheels as sm80 base arch plus native Blackwell archs. The build-side family filter now keeps/adds 8.0 for sm10x and sm12x only when a native arch for that family is present.
  • Kept sm12x default arch lists on 12.0f; the family-specific sm120f target covers DGX Spark / GB10 (sm121) without adding an exact 12.1a target by default.
  • Added installed-wheel compatibility validation for flashinfer-jit-cache local-version SM suffixes. On CUDA hosts, a wrong-family installed wheel now fails fast; on this DGX Spark, 0.6.11+cu130.sm12x validates and 0.6.11+cu130.sm9x fails with an expected-family error.
  • Reused the shared Python family filter in the AOT build/import test script instead of maintaining a second shell implementation.
  • Ran python -m py_compile build_utils.py flashinfer/__main__.py flashinfer/jit/env.py flashinfer-jit-cache/build_backend.py tests/cli/test_cli_cmds.py.
  • Ran python -m pytest tests/cli/test_cli_cmds.py -q (27 passed, with the expected PyTorch GB10 capability warning from this host's torch build).
  • Ran uvx ruff check ... and uvx ruff format --check ... over the touched Python files.
  • Ran git diff --check, bash -n scripts/task_test_jit_cache_package_build_import.sh, and parsed the touched workflow YAML files with yaml.safe_load.
  • Verified the family filter outputs sm10x: 8.0 10.0a 10.3a 11.0a and sm12x: 8.0 12.0f for the CUDA 13.0 release arch list.
  • Re-ran the DGX Spark CLI dry-run; it still detects sm12x and resolves flashinfer-jit-cache==0.6.11+cu130.sm12x using the uv pip install --python ... fallback.

SM121 target cleanup:

  • Removed the temporary 12.1a additions from release/nightly/default jit-cache arch lists and docs; sm12x now defaults to 8.0 12.0f.
  • Kept explicit 12.1a support in the parser/filter if a user supplies it manually, but release artifacts no longer build it by default.
  • Re-ran python -m pytest tests/cli/test_cli_cmds.py -q (27 passed), uvx ruff check tests/cli/test_cli_cmds.py, uvx ruff format --check tests/cli/test_cli_cmds.py, bash -n scripts/task_test_jit_cache_package_build_import.sh, git diff --check, workflow YAML parsing, and the DGX Spark CLI dry-run.

SM110 architecture split:

  • Limited 11.0a / sm110 jit-cache build coverage to CUDA 13.0 aarch64 release, nightly, and PR AOT build/import arch lists. CUDA 13.0 x86_64 lists now omit 11.0a.
  • Updated source-build docs to omit 11.0a from the generic x86-oriented examples and call out adding it for Jetson AGX Thor / T5000 aarch64 targets.
  • Re-ran workflow YAML parsing, bash -n scripts/task_test_jit_cache_package_build_import.sh, git diff --check, uvx ruff check tests/cli/test_cli_cmds.py, and python -m pytest tests/cli/test_cli_cmds.py -q (27 passed).
  • Verified the generated CUDA 13 arch lists: x86_64 -> 7.5 8.0 8.9 9.0a 10.0a 10.3a 12.0f; aarch64 -> 7.5 8.0 8.9 9.0a 10.0a 10.3a 11.0a 12.0f.

Summary by CodeRabbit

  • New Features

    • Added a CLI command to detect CUDA/SM family and install per‑SM‑family JIT‑cache wheels (nightly, dry‑run, and explicit overrides supported).
  • Documentation

    • Updated README and installation docs with the new CLI, per‑SM‑family wheel scheme, offline init, source‑build flags, and nightly install guidance.
  • Tests / CI

    • CI matrices, workflows, and tests updated to build, name, upload, and consume JIT‑cache artifacts per (CUDA, arch, SM‑family).
  • Chores

    • Build/index tooling and version handling improved to produce and recognize SM‑family segmented wheels.

The cu130 flashinfer-jit-cache wheel grew to 2.0 GB and started failing
to upload as a GitHub Release asset (per-asset 2 GiB limit; see flashinfer-ai#3257).
Each new SM target appended ~150-200 MB compressed to every wheel, and
cu130 carries 8 (sm75/80/89/90a/100a/103a/110a/120f).

Split each (CUDA, CPU-arch) wheel into three by GPU SM family:
- sm9x   - Ampere/Ada/Hopper       (<= sm90a)
- sm10x  - Datacenter Blackwell    (sm100a/103a/110a)
- sm12x  - Consumer Blackwell      (sm120f, future sm121a)

Same package name everywhere; the family is encoded in the PEP 440
local-version, so wheels resolve as e.g. 'flashinfer-jit-cache==
0.6.11+cu130.sm10x'. Existing 'pip install flashinfer-jit-cache' still
works once the right pin is given.

Driven by a new 'flashinfer install-jit-cache-wheel' subcommand that
detects FlashInfer version, CUDA version, and GPU compute capability
(via torch.cuda.get_device_capability) and runs the matching pip
install. Honors --cuda-version, --sm-family, --nightly, --dry-run.
Modeled on the CLI scaffolding from flashinfer-ai#3142 with the family dimension
added.

Build side: 'FLASHINFER_JIT_CACHE_SM_FAMILY' env var, when set,
filters 'FLASHINFER_CUDA_ARCH_LIST' to the family's archs and appends
'.<family>' to the local-version suffix. Release / nightly workflows
gain an 'sm_family' matrix dimension; the upload-to-release loop
iterates over all three families. The wheel-index regex accepts the
new local-version shape and remains compatible with the legacy
'+cuXY' format.

Closes flashinfer-ai#3257

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds SM-family-aware JIT-cache wheel distribution: utilities to map/filter CUDA arches by SM family, build backend and metadata changes, a new install CLI with autodetection, CI matrix/artifact updates, wheel-index parsing, docs updates, and corresponding tests.

Changes

SM Family JIT Cache Wheels

Layer / File(s) Summary
SM Family Utilities
build_utils.py
Adds SM_FAMILY_ORDER, sm_family_for_capability, parse_cuda_arch_entry, and filter_arch_list_for_sm_family to parse and filter CUDA arch lists by SM family.
Build Backend SM Filtering
flashinfer-jit-cache/build_backend.py
Reads/validates FLASHINFER_JIT_CACHE_SM_FAMILY, filters FLASHINFER_CUDA_ARCH_LIST, errors if empty, and appends the family suffix to local build metadata; regenerates metadata during prepare.
Install CLI & Detection
flashinfer/__main__.py
Adds install-jit-cache-wheel command, PyTorch-based SM-family detection, CUDA-version parsing/normalization, requirement/index construction, and install command execution (supports --nightly and --dry-run).
Release Workflow
.github/workflows/release.yml
Adds sm_family axis to release build matrix, prints sm_family, sets FLASHINFER_JIT_CACHE_SM_FAMILY in container env, updates artifact names to include -{sm_family}, and expands release upload loop to iterate over sm_family.
Nightly Workflow
.github/workflows/nightly-release.yml
Extends nightly jit-cache matrix with sm_family, echoes and injects FLASHINFER_JIT_CACHE_SM_FAMILY, includes sm_family in artifact names, and iterates downloads/uploads per (cuda, arch, sm_family) with cleanup.
PR Test Matrix & Job Wiring
.github/workflows/pr-test.yml
Expands AOT Build Import test matrix with sm_family (with excludes), updates job display names, injects FLASHINFER_JIT_CACHE_SM_FAMILY into test runs and rerun generation.
Test Script Arch Filtering
scripts/task_test_jit_cache_package_build_import.sh
Optionally filters computed FLASHINFER_CUDA_ARCH_LIST by FLASHINFER_JIT_CACHE_SM_FAMILY, validates values, errors if none remain, and re-exports the filtered list.
Wheel Index Parsing
scripts/update_whl_index.py
Extends wheel-filename regex for flashinfer_jit_cache to accept an optional .sm... qualifier after the +cuXXX CUDA metadata segment.
JIT Env Version Normalization
flashinfer/jit/env.py
Adds _public_package_version() and uses it when comparing package versions for cubin and jit-cache directory selection.
Documentation Updates
README.md, docs/installation.rst
Replace hardcoded CUDA-specific pip instructions with flashinfer install-jit-cache-wheel CLI guidance; document per-(CUDA, SM family) wheels, supported families, Blackwell/cu13 notes, and source/nightly build flags.
CLI & Utility Tests
tests/cli/test_cli_cmds.py
Adds tests for install-jit-cache-wheel dry-run/nightly behavior, version resolution from version.txt, pip fallback to uv, public-version normalization, and arch-list filtering.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

run-ci

Suggested reviewers

  • yzh119
  • yongwww
  • sricketts
  • cyx-6
  • aleozlx
  • nvmbreughe

"I’m a rabbit in the CI glen, I split the wheels by family then ran,
sm9x, sm10x, sm12x in a tidy band,
builds now filter, CLI finds the right hand,
docs updated, tests hop along—cheers from this fluffy dev land!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.06% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'build(jit-cache): split flashinfer-jit-cache wheels by SM family' clearly and concisely describes the main change—splitting JIT cache wheels by GPU SM family to address size constraints.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering the problem statement, solution approach, implementation details, testing performed, and all follow-up iterations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new CLI command, flashinfer install-jit-cache-wheel, to automate the installation of flashinfer-jit-cache wheels by autodetecting the CUDA version and GPU SM family. This update supports a new distribution model where wheels are split by SM family to comply with GitHub's asset size limits. Feedback from the review suggests improving the robustness of CUDA architecture parsing to handle various string formats and refactoring duplicated SM family logic into a common utility to enhance maintainability.

Comment thread flashinfer-jit-cache/build_backend.py Outdated
Comment thread flashinfer-jit-cache/build_backend.py Outdated
Mirrors the per-family split in release/nightly so PR CI actually
exercises the per-family build path. Was previously running one job
per (cuda, arch) which still built every arch; now runs three jobs
per (cuda, arch) — one per SM family — each compiling only its
family's archs.

- pr-test.yml: 'aot-build-import' and 'aot-build-import-rerun' gain
  'sm_family: [sm9x, sm10x, sm12x]'. cu126 is excluded for sm10x and
  sm12x because that toolkit only supports archs <= sm90. The rerun
  matrix builder mirrors the same exclude. FLASHINFER_JIT_CACHE_SM_FAMILY
  is forwarded into the test container via ci/bash.sh's '-e' flag.
- task_test_jit_cache_package_build_import.sh: when
  FLASHINFER_JIT_CACHE_SM_FAMILY is set, filter FLASHINFER_CUDA_ARCH_LIST
  to that family's archs before running the wheel build and
  verify_all_modules_compiled.py. The build-side filter in
  build_backend.py mutates os.environ inside its own process only, so
  doing it once in the parent shell ensures both subprocesses see the
  same arch list.

Also fix black formatting flagged by pre-commit on PR flashinfer-ai#3265:
- build_backend.py: rewrite SM_FAMILIES lambdas as named functions to
  avoid black's awkward multi-line break of '<' chained comparisons.
- __main__.py: collapse a ClickException to single-line per black's
  preference.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@flashinfer-jit-cache/build_backend.py`:
- Around line 38-94: Run the project formatter (e.g. ruff format or pre-commit
run --all-files) and commit the resulting changes so the SM_FAMILIES dict and
the multi-line print in _apply_sm_family_filter are formatted to satisfy ruff;
specifically reformat the SM_FAMILIES declaration and the print(...) call in
_apply_sm_family_filter (and any other affected lines) and push the reformatted
file so CI passes.

In `@flashinfer/__main__.py`:
- Around line 267-279: Re-run the project's formatter (ruff format) to apply the
canonical formatting for the Click exception lines in the CUDA-version parsing
block: ensure the click.ClickException(...) call around the InvalidVersion
exception handling and the earlier validation (the calls that raise
click.ClickException when normalized startswith "cu" and in the except block
that wraps InvalidVersion) are formatted according to ruff so the pre-commit
check passes; after formatting, stage and commit the changes.
- Around line 350-403: The current install_jit_cache_wheel_cmd builds an exact
pinned requirement from resolved_flashinfer_version which breaks when --nightly
points at nightly index but the installed __version__ is a stable release;
modify install_jit_cache_wheel_cmd to detect nightly and, if nightly is True and
resolved_flashinfer_version is a release (no "dev" or "+"), construct a range
requirement instead of an exact pin (e.g.
"flashinfer-jit-cache>={base},<{next_major_or_minor}") by parsing
resolved_flashinfer_version with packaging.version to compute the next version
bound, or alternatively call a new flag-aware helper (update
_build_jit_cache_requirement or add _build_jit_cache_requirement_for_nightly)
that returns the looser requirement when nightly is set; ensure the printed
requirement and pip args use this new requirement variable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7e3e084a-a262-4e22-b1ba-8cc3a970463e

📥 Commits

Reviewing files that changed from the base of the PR and between 1aa32d0 and f5dc1e6.

📒 Files selected for processing (7)
  • .github/workflows/nightly-release.yml
  • .github/workflows/release.yml
  • README.md
  • docs/installation.rst
  • flashinfer-jit-cache/build_backend.py
  • flashinfer/__main__.py
  • scripts/update_whl_index.py

Comment thread flashinfer-jit-cache/build_backend.py Outdated
Comment thread flashinfer/__main__.py
Comment thread flashinfer/__main__.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/pr-test.yml:
- Around line 244-247: The run step invokes ci/bash.sh with an unquoted
${DOCKER_IMAGE}, which triggers SC2086 (word-splitting); update the command to
quote the variable as "$DOCKER_IMAGE" in the invocation (e.g., change ci/bash.sh
${DOCKER_IMAGE} --no-gpu ... to ci/bash.sh "$DOCKER_IMAGE" --no-gpu ...), and
make the same change in the equivalent rerun "Run Test" step that calls the same
command line so both occurrences use "$DOCKER_IMAGE".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4f367040-09e4-47ff-8782-3ddd358e6b36

📥 Commits

Reviewing files that changed from the base of the PR and between f5dc1e6 and c90d5b7.

📒 Files selected for processing (4)
  • .github/workflows/pr-test.yml
  • flashinfer-jit-cache/build_backend.py
  • flashinfer/__main__.py
  • scripts/task_test_jit_cache_package_build_import.sh

Comment thread .github/workflows/pr-test.yml Outdated
dierksen and others added 3 commits May 7, 2026 23:54
The Release workflow has a 'pull_request: paths: .github/workflows/
release.yml' trigger that runs the build jobs in dry-run mode whenever
release.yml changes. Its checkout used:

  ref: ${{ github.event_name == 'pull_request' && github.head_ref || inputs.tag }}

For a fork PR, github.head_ref resolves to a branch that doesn't exist
on flashinfer-ai/flashinfer (because actions/checkout defaults
'repository:' to the workflow's repo). 'git fetch' fails three times,
and the setup job dies before any actual build work runs.

The bug has been latent since flashinfer-ai#1910 (2025-10-10), where the trigger
and the buggy checkout were introduced together. It only fires on
fork-PRs that touch release.yml; PRs from branches on the main repo
work fine because the default 'repository:' already matches.

Fix all four affected checkouts to set 'repository:' explicitly to
the PR head's repo and pin to head.sha (which is also stable across
re-pushes during the run). On workflow_dispatch the existing
'inputs.tag' path is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dierksen

dierksen commented May 8, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@flashinfer/jit/env.py`:
- Around line 126-127: The compatibility check currently uses
_public_package_version(flashinfer_version) !=
_public_package_version(flashinfer_jit_cache_version) but strips the
local-version suffix so different SM-family suffixes (e.g. .sm9x vs .sm12x) are
ignored; update the logic to, when CUDA is available, extract the sm* suffix
from flashinfer_jit_cache_version (e.g. via a small regex on the local-version
segment) and compare it to the detected device family (use your CUDA detection
helper / device-family variable); if the sm suffix is present and does not match
the detected device family, raise the same incompatibility error (or fail fast)
instead of proceeding, while falling back to the existing
_public_package_version check for non-CUDA cases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 20101ea1-0e1a-416e-84cc-231857008350

📥 Commits

Reviewing files that changed from the base of the PR and between 67adb48 and 5c7081e.

📒 Files selected for processing (7)
  • .github/workflows/nightly-release.yml
  • .github/workflows/pr-test.yml
  • .github/workflows/release.yml
  • flashinfer/__main__.py
  • flashinfer/jit/env.py
  • scripts/task_test_jit_cache_package_build_import.sh
  • tests/cli/test_cli_cmds.py
🚧 Files skipped from review as they are similar to previous changes (4)
  • scripts/task_test_jit_cache_package_build_import.sh
  • .github/workflows/nightly-release.yml
  • .github/workflows/pr-test.yml
  • .github/workflows/release.yml

Comment thread flashinfer/jit/env.py Outdated
@flashinfer-bot

Copy link
Copy Markdown
Collaborator

GitLab MR !652 has been created, and the CI pipeline #50715933 is currently running. I'll report back once the pipeline job completes.

@kahyunnam kahyunnam left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: the 3 GPU SM families in the PR description, I think @aleozlx mentioned earlier in the thread that each device typically requires 8.0 plus their native arch -- should we add sm80a compialtion to sm10x and sm12x subwheels as well?

Comment thread flashinfer/__main__.py Outdated
@yongwww

yongwww commented May 14, 2026

Copy link
Copy Markdown
Member

sm10x - Datacenter Blackwell (sm100a/103a/110a), this is a bit confusing to me: sm10x does not seem to include sm_110a, and sm_110a maps to Thor/Tegra rather than datacenter Blackwell

Comment thread docs/installation.rst
@dierksen

Copy link
Copy Markdown
Collaborator Author

sm10x - Datacenter Blackwell (sm100a/103a/110a), this is a bit confusing to me: sm10x does not seem to include sm_110a, and sm_110a maps to Thor/Tegra rather than datacenter Blackwell

Yeah, that one in particular does rub me the wrong way, but if I understand correctly, SM110 (previously SM101) maps closer to the datacenter Blackwell chips than to the SM120f chips.

That said, maybe we should split things up more to align better with different systems? Using the table from https://developer.nvidia.com/cuda/gpus and our support matrix from https://github.com/flashinfer-ai/flashinfer/#gpu-support, we could probably split things up like:

SM75-89: x86_64 and aarch64
SM90: x86_64 and aarch64
SM100: x86_64 and aarch64
SM110: aarch64 only
SM120f: x86_64 and aarch64

Thor stands out as relatively unique, and this would help keep the binary size lower for all of them.

@dierksen

Copy link
Copy Markdown
Collaborator Author

Looking at the breakdown in jit-cache wheel sizes:

For cu130:

split x86_64 aarch64
SM75-89 ~474 MB ~469 MB
SM90 + SM80 ~526 MB ~517 MB
SM100 + SM80, without SM103 ~503 MB ~484 MB
SM100+SM103 + SM80 ~957 MB ~920 MB
SM103 + SM80, if separate ~431 MB ~418 MB
SM110 + SM80 n/a ~354 MB
SM120f + SM80 437 MB 428 MB

Currently in this PR:

wheel x86_64 aarch64
sm9x = 75/80/89/90 820 MB 808 MB
sm10x = 80/100/103 plus 110 on aarch64 957 MB 1,215 MB
sm12x = 80/120f 437 MB 428 MB

And the original:

wheel size
x86_64 1,883 MB
aarch64 2,139 MB

Another thing that changes is that if we align with PyTorch and shift to 12.6/13.0/13.2, we might be able to drop SM100+ on 12.x and only provide those for 13.x.

@dierksen

Copy link
Copy Markdown
Collaborator Author

Questions from meeting today:

  • should we just break the wheels down to individual SMs?
  • who else needs to review this for downstream dependencies?
  • can we make explicit dependencies for the higher-SM wheels on SM 80 and split that out?
  • could we potentially get these small enough to host on pypi?

@dierksen
dierksen requested a review from dhiraj113 as a code owner May 20, 2026 21:57
Comment thread README.md
Comment on lines +105 to +107
# JIT cache: autodetect CUDA + GPU SM family and run the matching pip install.
# Use --dry-run to preview, --sm-family / --cuda-version to override.
flashinfer install-jit-cache-wheel

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make sure to test this within regular python venvs and also with uv venvs? I commonly use uv pip install so I forget if there sometimes can be issues mixing pip install and uv pip install within the same environment

Comment thread build_utils.py
Comment on lines +25 to +29
SM_FAMILY_BASE_ARCHS = {
"sm10x": ("8.0",),
"sm110": ("8.0",),
"sm12x": ("8.0",),
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these all 8.0 for base arches?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8.0 is needed in all of the wheels as a baseline (IIUC, @aleozlx can clarify), and this is just how it's currently encoding that for the 10.0+ wheels. We could also change to just have everything explicitly list 8.0 in each of them.

@mgoin

mgoin commented May 22, 2026

Copy link
Copy Markdown
Contributor

Making a note from offline discussion that we will still need something like flashinfer download-jit-cache --all , because we need to download kernels for all SMs when building multi-arch docker images, like in vLLM

@dierksen

Copy link
Copy Markdown
Collaborator Author

Making a note from offline discussion that we will still need something like flashinfer download-jit-cache --all , because we need to download kernels for all SMs when building multi-arch docker images, like in vLLM

This might require some additional planning to implement. With the current setup, I'm not sure if the .so's would resolve properly if we download them separately and then try to access them.

What we might need to do instead is parcel out the existing wheel structure into shards that are under the 2GB release artifact limit enforced by GitHub, then reconstruct that after downloading the shards, only when using the --all flag proposed. That way, users who just want to use the standard pip install flashinfer-jit-cache --index-url=... can still do so with the smaller packages provided, or you can use the new flashinfer install-jit-cache-wheels --all to install the full 2GB+ package.

Any thoughts on this implementation or other suggestions? Right now we can't release at all due to the GitHub artifact cap, so we're kind of stuck until we change something.

@dierksen dierksen closed this Jul 8, 2026
aleozlx pushed a commit that referenced this pull request Sep 10, 2026
## 📌 Description

This PR turns `flashinfer-jit-cache` into a small top-level shim backed
by independently installable, architecture-specific provider wheels. It
retains legacy monolithic cache discovery as a fallback while adding:

- provider package metadata and entry-point discovery
- exact CUDA architecture matching, including suffixed targets such as
`sm90a`, `sm120f`, and `sm121a`
- a default installation mode whose shim dependencies name the complete
published provider set
- a minimal installation mode that selects only an explicitly requested
or locally detected provider, with no implicit SM80 baseline
- provider wheelhouse build, binary inventory, installation, and
JIT-disabled GPU smoke tooling
- AOT capability gating so unsupported modules, currently BGMV MoE on
SM80, are omitted from that provider rather than failing its build

The provider matrix is intentionally independent of the size-pruned
monolithic wheel matrix. Architecture-specific wheels may therefore
preserve useful native targets such as SM121a without adding them back
to every monolithic wheel. Native providers are SASS-only; the shim does
not rely on PTX or an SM80 compatibility baseline.

## 🔍 Related Issues

- Follow-up design to #3265
- Incorporates current-main behavior from #4469, #4527, #4682, #4711,
#4757, and #4760

## 🧪 Validation

### Provider canaries

Two end-to-end CUDA 13.0 canaries have exercised provider build, strict
binary inspection, shim/provider installation, provider discovery,
top-level import without CUTLASS DSL, and a JIT-disabled `silu_and_mul`
numerical smoke:

| System | Target | Provider result |
| --- | --- | --- |
| x86_64 A100 test system | A100 / SM80 | 113.8 MiB; every CUDA-bearing
module SM80-only; zero PTX |
| DGX Spark | aarch64 GB10 / SM121a | 173.0 MiB; 558 modules; every
CUDA-bearing module SM121a-only; zero PTX |

The x86_64 A100 artifact was built before the final BGMV capability
correction and contained 207 modules. Final-branch source-level SM80 AOT
enumeration produces 206 modules with `bgmv_moe` absent, and the
associated focused suite passed 30 tests. A final-head SM80 provider
wheel still needs to be rebuilt to confirm that exact packaged
inventory.

The Spark provider could load its packaged BGMV module, but a BGMV
numerical invocation exceeded the device's dynamic shared-memory limit
(approximately 216 KiB requested versus approximately 101 KiB
available). That is a pre-existing kernel/runtime limitation and is
outside this packaging change; the independent `silu_and_mul` provider
smoke passed.

### Current branch and CI

- CodeRabbit passes and all inline review threads are resolved.
- Pre-commit, documentation, and public API/documentation checks pass.
- The existing monolithic release workflow passes for cu129, cu130, and
cu134 on both x86_64 and aarch64. These jobs validate backward
compatibility, not provider-wheel publication.
- The manually authorized [full PR test
run](https://github.com/flashinfer-ai/flashinfer/actions/runs/33890607699)
passes all four cu129/cu130 x64/arm64 AOT build-import jobs, all five
A10G JIT shards, and the T4 JIT job. The H100 JIT job is still running
as of September 4, 2026.
- After the latest review fixes, the focused provider suite passed on an
x86_64 A100 test system in a disposable container: 25 passed, 1 warning.
`pre-commit`, `bash -n`, and `git diff --check` also pass.

The branch is currently mergeable. It will be rebased onto `main` once
more before merge; intervening main-branch changes reviewed so far do
not alter the provider packaging or AOT capability implementation.

## Remaining Validation

Before enabling provider publication in a release workflow:

- let the current H100 PR test finish and address any real failure
- rebuild the final-head SM80 provider and repeat strict inventory,
install, and GPU smoke validation
- build and inspect a real cu134 provider artifact; current cu134 CI
covers only the legacy wheel and static configuration paths
- validate default all-provider installation plus minimal auto-detected
and explicit-target installation against a multi-provider wheelhouse
- teach `scripts/update_whl_index.py` to recognize provider distribution
names
- add an artifact-only shadow provider matrix to nightly/release
automation and collect size, build-time, homogeneous GPU, and
heterogeneous GPU results before changing the public release format

## Reviewer Notes

The main policy question is the explicit provider coverage matrix for
each CUDA and CPU architecture. The current implementation makes the
conservative choices: exact target matching, literal shim dependencies,
no closest-lower-architecture inference, no implicit SM80 provider, and
normal JIT compilation when no compatible AOT provider is available.

This is ready for human review of the package contract, installation UX,
and release shape. The remaining items above are release-enablement
validation rather than evidence that the architectural split itself has
not been exercised.

## 🚀 Pull Request Checklist

Thank you for contributing to FlashInfer! Before we review your pull
request, please make sure the following items are complete.

### ✅ Pre-commit Checks

- [ ] I have installed `pre-commit` by running `pip install pre-commit`
(or used your preferred method).
- [ ] I have installed the hooks with `pre-commit install`.
- [ ] I have run the hooks manually with `pre-commit run --all-files`
and fixed any reported issues.

> If you are unsure about how to set up `pre-commit`, see [the
pre-commit documentation](https://pre-commit.com/).

## 🧪 Tests

- [x] Tests have been added or updated as needed.
- [ ] All tests are passing (`unittest`, etc.).

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added experimental architecture-specific JIT-cache provider wheels
with automatic discovery and legacy fallback.
* Added `install-jit-cache-wheel` options for full or minimal
installation and CUDA architecture selection.
  * Added tools to build, validate, and smoke-test provider packages.

* **Bug Fixes**
  * Improved architecture-aware AOT module selection and generation.
* Prevented incompatible architectures from being selected
automatically.

* **Documentation**
* Documented provider-wheel configuration, installation modes, and
experimental build options.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
dierksen added a commit that referenced this pull request Sep 15, 2026
## 📌 Description

This PR enables the architecture-specific JIT-cache provider wheels
introduced
by #4514 and removes the monolithic JIT-cache wheel mode from release,
build,
package, and runtime paths.

- Adds explicit provider inventories per CUDA and CPU platform in
  `ci/cuda-versions.json`.
- Derives the individual provider build matrix and the CUDA/CPU shim
matrix
  from that single inventory.
- Builds each binary provider, builds one platform-specific
`flashinfer-jit-cache` shim per CUDA/CPU pair, and validates the
assembled set
  before publication.
- Builds the patched CUDA 13.4 `sccache` binary once per CPU
architecture and
  shares it across the corresponding provider builds.
- Validates provider SASS using CUDA binary-compatibility rules while
continuing
to reject PTX and targets that cannot execute on the declared
architecture.
- Propagates the selected architecture flags through NVCC device linking
so
linked modules do not acquire the toolkit's default `sm52` or `sm75`
cubin.
- Selects the closest compatible installed provider at runtime, with
exact
targets preferred over family targets and family targets preferred over
  unsuffixed baselines.
- Requires each provider's full CUDA-specific version to match the
installed
shim, preventing a provider such as `+cu134` from being loaded by a
`+cu130`
  shim.
- Supports heterogeneous processes by resolving the best provider
independently
for every visible CUDA architecture, loading all selected copies of a
module,
  and dispatching each call according to its CUDA tensor devices.
- Keeps partial provider inventories usable: a module present only in
the SM103
provider can run on SM103 while an uncovered SM120 call falls back to
the
  normal multi-architecture JIT module.
- Registers the cubin callback for every selected provider library
instead of
  only the primary path.
- Makes minimal installation discover the provider inventory from the
exact
published shim wheel instead of maintaining a second architecture table.
- Drops separate SM86 provider builds because the unsuffixed SM80
provider is
  forward compatible within compute-capability major 8.
- Teaches wheel-index generation to recognize provider distribution
names.
- Removes monolithic wheel compilation, artifact publication, package
metadata,
  runtime discovery, and workflow selection paths.
- Keeps reusable provider validation independent from the disposable
one-off
  wheelhouse tooling.

Pull request runs exercise the complete split provider build, shim
assembly,
installation, and artifact-validation path without publishing artifacts.
Once
merged, scheduled nightlies and release dispatches build and publish
only the
split provider wheel set. Rollback requires reverting to a workflow
revision
that still builds monolithic wheels; there is no runtime format switch.

## 🔍 Related Issues

- Follow-up to #4514
- Design follow-up to #3265

## 🚀 Pull Request Checklist

Thank you for contributing to FlashInfer! Before we review your pull
request,
please make sure the following items are complete.

### ✅ Pre-commit Checks

- [ ] I have installed `pre-commit` by running `pip install pre-commit`
(or used your preferred method).
- [ ] I have installed the hooks with `pre-commit install`.
- [ ] I have run the hooks manually with `pre-commit run --all-files`
and fixed any reported issues.

> If you are unsure about how to set up pre-commit, see the [pre-commit
documentation](https://pre-commit.com/).

## 🧪 Tests

- [x] Tests have been added or updated as needed.
- [ ] All tests are passing (`unittest`, etc.).

Completed on the current revision:

- commit-time pre-commit checks for all changed files, including Ruff
and mypy
- `python3 ci/validate_cuda_versions.py`
- `pytest tests/test_env.py -q --noconftest` (`6 passed`), including
  heterogeneous provider resolution and nested tensor-device discovery
- Python byte-compilation and `git diff --check`

Completed on an earlier revision of this PR:

- `pytest -q --confcutdir=tests/jit tests/jit/test_jit_cache_release.py`
  (`6 passed` in a lightweight local environment)
- provider, release, and CLI suites in a CUDA container on an ARM64
SM121 test
  system (`86 passed`)
- focused NVCC device-link regression test and a direct `cuobjdump
--list-elf`
  check of an affected `sm103a` module (only `sm103a` cubins present)

The complete provider build matrix and assembled-wheel installation
checks are
exercised by this PR's release dry run. Actual same-process dispatch
across an
SM103 and an SM120 GPU remains a hardware validation gap. The updated
canary
supports that test as one invocation with
`--provider sm103a --provider sm120f` and JIT disabled.

## 🔬 Experimental Track

<!-- Only for PRs submitted under the experimental policy
(CONTRIBUTING.md → "Experimental APIs and Backends").
     Leave this section untouched for normal PRs. -->

- [ ] This PR is **experimental**: it adds or changes code under
`flashinfer/experimental/` and/or an `@flashinfer_experimental_api`.
Tracking issue: #
- [ ] The tracking issue names an owner, the reason for the experimental
path, and a graduation plan with a target release.
- [ ] Core changes are limited to a thin entry point (signature, shared
validation, feature-gate check, backend selection, handoff).
- [ ] Tests live in `tests/experimental/` and were validated on the
intended hardware; a runnable example is included.
- [ ] Nothing is registered in `flashinfer/aot.py`, and no experimental
backend is reachable from `backend="auto"` without
`FLASHINFER_ALLOW_EXPERIMENTAL_AUTO_BACKENDS=1`. (Calling an
`@flashinfer_experimental_api` or naming a backend explicitly is itself
the opt-in and needs no environment variable.)
- [ ] **Test scope declared below.** The experimental CI lane runs
exactly these targets, so keep them as narrow as the change allows.

```experimental-tests
# One target per line: a directory or a file. (A pytest ::selector is not
# supported -- the sharding runner cannot consume one.) Must be under
# tests/experimental/ and must exist. Delete these comment lines and add yours, e.g.
#
#   tests/experimental/test_my_backend.py
#   tests/experimental/my_backend/
#
# Declaring the whole tree (tests/experimental/) is allowed but means every
# experimental PR pays for every other feature's tests, in every matrix cell.
```

## Reviewer Notes

Please focus on the provider inventory policy, CUDA binary-compatibility
rules,
provider-only workflow fan-in, platform-specific shim tags and
dependencies,
artifact assembly, removal of monolithic paths, and the heterogeneous
AOT
dispatcher's tensor-device selection and JIT fallback behavior.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Releases and nightly builds now provide architecture-specific
JIT-cache provider wheels alongside a shim wheel.
  - Provider wheels include validation reports and SHA-256 checksums.
  - Installed providers are discovered and validated automatically.
  - CUDA provider architecture coverage has expanded.

- **Breaking Changes**
- Legacy monolithic JIT-cache wheel builds and format selection are no
longer supported.

- **Documentation**
- Updated JIT-cache documentation to describe provider-based releases
and validation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Vincent Tombari <Vinnie6167@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
passtoor-agi pushed a commit to passtoor-agi/flashinfer that referenced this pull request Sep 15, 2026
## 📌 Description

This PR enables the architecture-specific JIT-cache provider wheels
introduced
by flashinfer-ai#4514 and removes the monolithic JIT-cache wheel mode from release,
build,
package, and runtime paths.

- Adds explicit provider inventories per CUDA and CPU platform in
  `ci/cuda-versions.json`.
- Derives the individual provider build matrix and the CUDA/CPU shim
matrix
  from that single inventory.
- Builds each binary provider, builds one platform-specific
`flashinfer-jit-cache` shim per CUDA/CPU pair, and validates the
assembled set
  before publication.
- Builds the patched CUDA 13.4 `sccache` binary once per CPU
architecture and
  shares it across the corresponding provider builds.
- Validates provider SASS using CUDA binary-compatibility rules while
continuing
to reject PTX and targets that cannot execute on the declared
architecture.
- Propagates the selected architecture flags through NVCC device linking
so
linked modules do not acquire the toolkit's default `sm52` or `sm75`
cubin.
- Selects the closest compatible installed provider at runtime, with
exact
targets preferred over family targets and family targets preferred over
  unsuffixed baselines.
- Requires each provider's full CUDA-specific version to match the
installed
shim, preventing a provider such as `+cu134` from being loaded by a
`+cu130`
  shim.
- Supports heterogeneous processes by resolving the best provider
independently
for every visible CUDA architecture, loading all selected copies of a
module,
  and dispatching each call according to its CUDA tensor devices.
- Keeps partial provider inventories usable: a module present only in
the SM103
provider can run on SM103 while an uncovered SM120 call falls back to
the
  normal multi-architecture JIT module.
- Registers the cubin callback for every selected provider library
instead of
  only the primary path.
- Makes minimal installation discover the provider inventory from the
exact
published shim wheel instead of maintaining a second architecture table.
- Drops separate SM86 provider builds because the unsuffixed SM80
provider is
  forward compatible within compute-capability major 8.
- Teaches wheel-index generation to recognize provider distribution
names.
- Removes monolithic wheel compilation, artifact publication, package
metadata,
  runtime discovery, and workflow selection paths.
- Keeps reusable provider validation independent from the disposable
one-off
  wheelhouse tooling.

Pull request runs exercise the complete split provider build, shim
assembly,
installation, and artifact-validation path without publishing artifacts.
Once
merged, scheduled nightlies and release dispatches build and publish
only the
split provider wheel set. Rollback requires reverting to a workflow
revision
that still builds monolithic wheels; there is no runtime format switch.

## 🔍 Related Issues

- Follow-up to flashinfer-ai#4514
- Design follow-up to flashinfer-ai#3265

## 🚀 Pull Request Checklist

Thank you for contributing to FlashInfer! Before we review your pull
request,
please make sure the following items are complete.

### ✅ Pre-commit Checks

- [ ] I have installed `pre-commit` by running `pip install pre-commit`
(or used your preferred method).
- [ ] I have installed the hooks with `pre-commit install`.
- [ ] I have run the hooks manually with `pre-commit run --all-files`
and fixed any reported issues.

> If you are unsure about how to set up pre-commit, see the [pre-commit
documentation](https://pre-commit.com/).

## 🧪 Tests

- [x] Tests have been added or updated as needed.
- [ ] All tests are passing (`unittest`, etc.).

Completed on the current revision:

- commit-time pre-commit checks for all changed files, including Ruff
and mypy
- `python3 ci/validate_cuda_versions.py`
- `pytest tests/test_env.py -q --noconftest` (`6 passed`), including
  heterogeneous provider resolution and nested tensor-device discovery
- Python byte-compilation and `git diff --check`

Completed on an earlier revision of this PR:

- `pytest -q --confcutdir=tests/jit tests/jit/test_jit_cache_release.py`
  (`6 passed` in a lightweight local environment)
- provider, release, and CLI suites in a CUDA container on an ARM64
SM121 test
  system (`86 passed`)
- focused NVCC device-link regression test and a direct `cuobjdump
--list-elf`
  check of an affected `sm103a` module (only `sm103a` cubins present)

The complete provider build matrix and assembled-wheel installation
checks are
exercised by this PR's release dry run. Actual same-process dispatch
across an
SM103 and an SM120 GPU remains a hardware validation gap. The updated
canary
supports that test as one invocation with
`--provider sm103a --provider sm120f` and JIT disabled.

## 🔬 Experimental Track

<!-- Only for PRs submitted under the experimental policy
(CONTRIBUTING.md → "Experimental APIs and Backends").
     Leave this section untouched for normal PRs. -->

- [ ] This PR is **experimental**: it adds or changes code under
`flashinfer/experimental/` and/or an `@flashinfer_experimental_api`.
Tracking issue: #
- [ ] The tracking issue names an owner, the reason for the experimental
path, and a graduation plan with a target release.
- [ ] Core changes are limited to a thin entry point (signature, shared
validation, feature-gate check, backend selection, handoff).
- [ ] Tests live in `tests/experimental/` and were validated on the
intended hardware; a runnable example is included.
- [ ] Nothing is registered in `flashinfer/aot.py`, and no experimental
backend is reachable from `backend="auto"` without
`FLASHINFER_ALLOW_EXPERIMENTAL_AUTO_BACKENDS=1`. (Calling an
`@flashinfer_experimental_api` or naming a backend explicitly is itself
the opt-in and needs no environment variable.)
- [ ] **Test scope declared below.** The experimental CI lane runs
exactly these targets, so keep them as narrow as the change allows.

```experimental-tests
# One target per line: a directory or a file. (A pytest ::selector is not
# supported -- the sharding runner cannot consume one.) Must be under
# tests/experimental/ and must exist. Delete these comment lines and add yours, e.g.
#
#   tests/experimental/test_my_backend.py
#   tests/experimental/my_backend/
#
# Declaring the whole tree (tests/experimental/) is allowed but means every
# experimental PR pays for every other feature's tests, in every matrix cell.
```

## Reviewer Notes

Please focus on the provider inventory policy, CUDA binary-compatibility
rules,
provider-only workflow fan-in, platform-specific shim tags and
dependencies,
artifact assembly, removal of monolithic paths, and the heterogeneous
AOT
dispatcher's tensor-device selection and JIT fallback behavior.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Releases and nightly builds now provide architecture-specific
JIT-cache provider wheels alongside a shim wheel.
  - Provider wheels include validation reports and SHA-256 checksums.
  - Installed providers are discovered and validated automatically.
  - CUDA provider architecture coverage has expanded.

- **Breaking Changes**
- Legacy monolithic JIT-cache wheel builds and format selection are no
longer supported.

- **Documentation**
- Updated JIT-cache documentation to describe provider-based releases
and validation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Vincent Tombari <Vinnie6167@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]GitHub Release upload fails for flashinfer-jit-cache cu130 x86_64 wheel due to 2 GiB asset limit CLI utility that can aot download the jit cache

5 participants