Skip to content

kernel: avoid partial Triton lazy initialization#4553

Open
nascheme wants to merge 1 commit into
pytorch:mainfrom
nascheme:ft-audit-kernel-lazy-init
Open

kernel: avoid partial Triton lazy initialization#4553
nascheme wants to merge 1 commit into
pytorch:mainfrom
nascheme:ft-audit-kernel-lazy-init

Conversation

@nascheme

@nascheme nascheme commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

blockwise_quantization.py and bsr_triton_ops.py both used a module-level _triton_initialized = False flag set to True before the kernel handles were assigned. Under free-threaded Python, one thread can set the flag and yield during the slow import triton, while another thread observes the flag set but the kernel globals still None.

Replace the bool-flag pattern with a lock-guarded builder that publishes an immutable dataclass of the built handles only once construction completes, so callers either see nothing or the fully-built set.

Build Triton kernel handles under an explicit lock and publish them only
after initialization completes. This avoids exposing partially initialized
module state to concurrent first callers.

Assisted-by: Claude Opus 4.7
@pytorch-bot

pytorch-bot Bot commented Jul 3, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/ao/4553

Note: Links to docs will display an error until the docs builds have been completed.

❌ 3 New Failures

As of commit 1d28ff8 with merge base d1e0e2d (image):

NEW FAILURES - The following jobs have failed:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jul 3, 2026
@vkuzo

vkuzo commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

@claude review

@claude

claude Bot commented Jul 10, 2026

Copy link
Copy Markdown

Claude finished @vkuzo's task in 1m 30s —— View job


Code Review: avoid partial Triton lazy initialization

  • Read the diff and both changed files
  • Analyze correctness of the new lazy-init pattern
  • Check for behavior changes and edge cases

Nice fix. The core change is correct: replacing the _triton_initialized = True (set before the kernels are assigned) with a lock-guarded builder that publishes an immutable, fully-constructed dataclass in a single atomic reference assignment. Under free-threaded Python, a reader now sees either None or the complete _BlockwiseFp8Impls/_BsrTritonImpls — never a half-built state. The double-checked locking (fast unlocked read, re-check under the lock) is the right idiom here and is safe because the published object is frozen=True and constructed entirely before assignment.

A few observations:

1. Behavior change in bsr_dense_addmm (worth confirming intent) — bsr_triton_ops.py:276

Previously bsr_dense_addmm called _lazy_init_triton() with no availability check. When Triton was absent, _bsr_strided_addmm_kernel stayed None and the function ran on until None[grid](...) raised a cryptic TypeError. The new code adds:

impls = _get_triton_impls()
if not impls.available:
    raise AssertionError("unsupported without triton")

This is a strict improvement (fail fast, clear message) and matches the pattern in blockwise_quantization.py, but it is a new early raise on a path that previously didn't have one. Just flagging it as intentional — I don't think anything relied on the old late-failure behavior.

2. AssertionError for a runtime capability check — minor

Both files raise AssertionError("unsupported without triton"). Assertions are stripped under python -O, which would let execution fall through to impls.gemm(...) where gemm is NoneTypeError. RuntimeError (or NotImplementedError) would be more robust. That said, the blockwise_quantization.py calls already used AssertionError before this PR, so this only introduces the pattern newly in bsr_triton_ops.py. Non-blocking; feel free to leave for consistency.

3. The global _bsr_strided_addmm_kernel declaration was correctly removed

bsr_dense_addmm no longer needs the global statement it had before — good cleanup, and I confirmed there are no remaining references to the old module-level names (_triton_initialized, _bsr_strided_addmm_kernel, _triton_available, _blockwise_fp8_gemm_impl, _lazy_init_triton) anywhere in torchao/ or test/.

4. Optional: dedup the identical _get_triton_impls boilerplate

The _get_triton_impls() double-checked-locking helper is now byte-for-byte identical between the two modules (only the dataclass type differs). Not worth blocking on, but a small shared helper (e.g. a lazy_singleton(builder, lock) in torchao/kernel/) would prevent the two copies from drifting. Minor.

Overall this looks correct and is a solid concurrency fix. Nothing blocking from my side — points 1 and 2 are the only ones I'd ask you to confirm are intentional.
ft-audit-kernel-lazy-init

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants