Skip to main content

fused_kernel_available

Function fused_kernel_available 

Source
pub fn fused_kernel_available(id: FusedOpId, backend: BackendId) -> bool
Expand description

The capability predicate the optimizer’s gate consults: is there an admissible kernel for (id, backend) — static or runtime-registered? The dispatch layer passes |id| fused_kernel_available(id, backend) to capability_gated_rules, so a runtime op fuses only once its kernel is bound. Id-level (coarse) by design; the dtype-precise check is the dispatch-time binding lookup itself.

SHARED-CONSUMER COORDINATION (dd-shapes / flash-arm registry seam, 2026-07-08; carried through the binding-key fold). Two independent callers with different invariants, and any change here must hold both:

  • the Tier-2 runtime-fusion / JIT program calls this for runtime ids (id.is_runtime(), allocated by adopt_runtime_fused) — those resolve only through their BindingKey::RuntimeFused rows (KernelBindingTable::has_runtime_fused), never the static registry and never the static-id bridge below (which returns false immediately for a runtime id);
  • the decode flash-arm gate (crate::decode_flash::FlashArmCapability::production) calls this for the static id FusedOps::FLASH_ATTN on BackendId::Cuda, whose CUDA flash_decoding kernel registers ONLY into the binding table under (OpKind::FlashAttn, [f16|bf16;4], Cuda) — never default_kernel_registry (a frozen CPU-only OnceLock). The static_binding_table_bridge arm makes that reachable: for a static id with a known OpKind mapping, consult the binding table for ANY entry on backend (dtype-blind — this predicate answers “is a kernel bound”; dtype admissibility is a separate gate, e.g. crate::decode_flash::flash_decode_admissible).

LOCK DISCIPLINE (post binding-key fold, 2026-07-08; nesting eliminated 2026-07-13 — Spec B Task 1). This re-acquires the global_bindings() READ lock (once per || operand it actually evaluates — the checks are independent, short-lived acquisitions, not one held across the whole chain). One constraint remains:

  • Never call it — nor adopt_runtime_fused / clear_runtime_fused_for_tests, which take the WRITE lock — while holding a global_bindings() guard on the same thread. Same-thread read-then-write (or write-then-anything) self-deadlocks. (Tests scope their read guards around each optimize call and never hold one across an adopt/reset; production adopts on the G7 background thread, never the realize thread that holds read guards.)

The nested-read hazard this doc used to warn about — the optimizer’s runtime-fusion pathfinder calling this while optimize_graph already holds a caller-passed &KernelBindingTable derived from a global_bindings() read guard — is now eliminated: the pathfinder calls fused_kernel_available_in against that already-held table (threaded in via OptimizationContext::bindings) instead of calling this function and re-acquiring the lock. This function stays the global entry point for callers with no table already in hand (the decode flash-arm gate, jit_adopt’s post-adopt check).