Skip to content

Key cubin checksums by full path to prevent cross-pin collisions - #4203

Open
aleozlx wants to merge 1 commit into
flashinfer-ai:mainfrom
aleozlx:fix/cubin-checksum-key-collision-main
Open

aleozlx wants to merge 1 commit into
flashinfer-ai:mainfrom
aleozlx:fix/cubin-checksum-key-collision-main

Conversation

@aleozlx

@aleozlx aleozlx commented Jul 28, 2026

Copy link
Copy Markdown
Member

📌 Description

get_checksums() flattens every subdir's checksums.txt into one dict keyed by bare filename, namespacing only .h entries:

if ".h" in filename:
    filename = safe_urljoin(subdir, filename)
checksums[filename] = sha256

Bare filenames are not unique across subdirs. Per-arch cubin pins publish the same sm100f/sm103a kernel names built from different sources, so whichever subdir is processed last silently overwrites the earlier one's hashes. Every shared name is then verified against the wrong pin's hash, and download_artifacts() fails with Failed to download cubins: checksum mismatch. get_subdir_file_list() compounded it by looking cubins up as checksums[name] while headers already used the full path.

main cannot trigger this today — it defines only a single BMM/GEMM pin. This PR is therefore a latent-bug fix, not a live one.

It did trigger on release-v0.6.16, which carries a second, Rubin-specific pin. Measured against the live published manifests:

pin pair shared filenames same hash conflicting
TRTLLM_GEN_BMM vs _RUBIN 2534 0 2534
TRTLLM_GEN_GEMM vs _RUBIN 108 3 105

2640 of 8055 files resolved to the wrong hash, taking down build-flashinfer-cubin for the entire release. Fixed there in #4200. Porting it here so the landmine does not re-arm the moment a second pin lands on main (e.g. when SM107 support returns).

Fix: key every entry by full path, and look cubins up the same way headers already were.

🔍 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.).

tests/test_artifacts.py: 5 passed (4 existing + 1 new).

The new test is deliberately pin-independent — it feeds get_checksums() two synthetic subdirs publishing the same kernel name with different hashes, so it does not depend on main ever defining a second ArtifactPath. Against the unfixed version it fails:

AssertionError: assert Bmm_Bfloat16_E2m1E2m1_Fp32_shared_name_sm100f.cubin not in {...}

Reviewer Notes

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Fixed checksum handling for artifacts with identical filenames in different subdirectories.
    • Ensured each artifact consistently uses its full path when locating and validating checksums.
    • Preserved distinct kernel and header checksums across artifact versions, preventing incorrect matches.
  • Tests

    • Added coverage confirming checksum entries remain correctly separated across subdirectories.

get_checksums() flattens every subdir's checksums.txt into one dict keyed by
bare filename, namespacing only ".h" entries. Bare filenames are not unique
across subdirs: per-arch cubin pins publish the same sm100f/sm103a kernel
names built from different sources, so whichever subdir is processed last
silently overwrites the earlier one's hashes. Every shared name is then
verified against the wrong pin's hash and download_artifacts() fails with
"Failed to download cubins: checksum mismatch".

main cannot trigger this today because it defines only a single BMM/GEMM pin.
It did trigger on release-v0.6.16, which carries a second, Rubin-specific pin:
all 2534 shared BMM filenames and 105 of 108 shared GEMM filenames resolved to
the wrong hash, taking down build-flashinfer-cubin for the whole release. This
is a latent landmine on main that arms itself the moment a second pin lands.

Key every entry by full path, and look cubins up the same way headers already
were. Add a pin-independent regression test that feeds get_checksums() two
subdirs publishing the same kernel name with different hashes; against the
unfixed version it fails on the bare filename still being present as a key.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1312ea59-10c7-4676-96fc-e0b88a34a13c

📥 Commits

Reviewing files that changed from the base of the PR and between e1eb406 and 117f527.

📒 Files selected for processing (2)
  • flashinfer/artifacts.py
  • tests/test_artifacts.py

📝 Walkthrough

Walkthrough

Checksum parsing and cubin lookup now consistently use full relative paths, preventing collisions for identical filenames across subdirectories. Tests verify namespaced kernel and header checksum entries.

Changes

Checksum path namespacing

Layer / File(s) Summary
Path-keyed checksum lookup
flashinfer/artifacts.py
Checksum mappings and cubin lookups now use full relative paths including the artifact subdirectory.
Checksum collision regression coverage
tests/test_artifacts.py
Adds coverage proving identical cubin filenames in separate subdirectories retain distinct kernel and header hashes.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: yzh119, limin2021

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 clearly summarizes the main change: full-path checksum keys to avoid cross-pin collisions.
Description check ✅ Passed The description includes the required description, related issues, checklist, tests, and reviewer notes sections.
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.
✨ 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.

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.

2 participants