From cd3befd333c6a04bc6e6bb47c801363eb99b2a0d Mon Sep 17 00:00:00 2001 From: Caleb Kim Date: Thu, 23 Jul 2026 05:10:52 +0000 Subject: [PATCH] [autotuner][cute] demote tcgen05_tvm_ffi_launch to a seed-only knob Pinned to EnumFragment((True,)) in the search view, the FFI-launch flag caused (1) population collapse -- every candidate forced ffi=True so the promotion normalizer deduped the whole surface to one seed -- and (2) an encoder crash when a partial seed back-filled default False into a (True,)-only slot ("Invalid enum value False"). Fix: EnumFragment((True, False), search_choices=(False,)). Search draws only False (FFI enters solely via the existing eligibility-gated CuteTcgen05ClusterM2FfiHeuristic seed, #2681); choices carries True so the seed round-trips and default_config() still promotes on eligible shapes. Effect (single B200): distinct configs in a 400-draw search population on S3 2048x4096x4096 bf16, 2 -> 17, and a full S3 autotune now runs to completion with heuristics on, with zero "Invalid enum value False" encoder crashes (the partial formula seed that omits the key no longer aborts surrogate encoding at config #2). SCOPE: this fixes one of the SIX clauses in _target1_tvm_ffi_promotion_requested, which is what gates the wholesale projection onto the FFI seed. The other five (tcgen05_flat_role_coordinates, tcgen05_layout_strategy='explicit_epi_tile', and the three tcgen05_layout_overrides_* keys) are still independent search draws, so ~95% of candidates continue to trip the gate and be overwritten (measured on this commit: 293/300 candidates -> 1 distinct config, with 0 of 30 keys varying). The 2 -> 17 gain above is real but partial: it comes from restoring the small subset of draws that escape all six clauses. The follow-up commit repairs those candidates away from the FFI envelope instead of onto it, which is what actually restores a multi-config search (299/300 distinct). Co-Authored-By: Claude Opus 4.8 (1M context) stack-info: PR: https://github.com/pytorch/helion/pull/3149, branch: calebmkim/stack/33 --- helion/_compiler/cute/tcgen05_config.py | 36 ++++++++++++++++++++----- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/helion/_compiler/cute/tcgen05_config.py b/helion/_compiler/cute/tcgen05_config.py index 6680c1b88..17d518fc1 100644 --- a/helion/_compiler/cute/tcgen05_config.py +++ b/helion/_compiler/cute/tcgen05_config.py @@ -1659,13 +1659,15 @@ def flatten_missing_field_default( config: dict[str, object], ) -> tuple[bool, object]: if key == TCGEN05_TVM_FFI_LAUNCH_CONFIG_KEY: - # The autotuner search surface for this key is the collapsed - # ``EnumFragment((True,))``; autotuner-generated configs always - # set it via ``default_flat()`` mutation. ``flatten`` only hits - # this branch on user-supplied configs that omit the key, where - # absence means "no FFI promotion requested" — matches the + # The search surface for this key draws False only + # (``EnumFragment((True, False), search_choices=(False,))``), so an + # absent key can only come from a config that did not go through the + # search: a user-supplied config, a partial seed, or a cache entry. + # Absence there means "no FFI promotion requested" — matching the # validation-view default and the special case at - # ``normalize_pre_pid_type``. + # ``normalize_pre_pid_type``. Back-filling False (rather than the + # fragment default, True) is also what keeps a partial seed from + # encoding an FFI request it never made. return True, False if key != TCGEN05_PERSISTENCE_MODEL_CONFIG_KEY: return False, None @@ -2019,8 +2021,28 @@ def optional_fragments( # Validation exposes the two direct-entry controls for explicit # configs. Layout overrides already have a generic validation path # below; only the seed/search surface narrows them to its fixed tile. + # + # FFI direct-entry is a seed, not a search dimension: + # ``search_choices=(False,)`` makes the search only ever draw + # False, so the FFI envelope enters solely via the + # eligibility-gated ``CuteTcgen05ClusterM2FfiHeuristic`` seed + # (which still round-trips ``tvm_ffi_launch=True`` verbatim + # because ``choices`` carries True and the round-trip reads the + # stored value, not ``_active_choices()``). Keeping True *first* + # preserves ``EnumFragment.default() == choices[0] == True`` so + # the no-autotune ``default_config()`` still promotes to the + # validated full-tile FFI envelope on eligible shapes (the + # search view and the fragment-default path share this + # fragment). ``choices`` carrying both values also lets the + # surrogate encode the seed's True without raising + # ``Invalid enum value`` (``encode()`` uses full ``choices``, + # config_fragment.py). Validation keeps a Boolean surface so an + # absent user-config key still means "no FFI promotion + # requested" (default False). tvm_ffi_launch_fragment: ConfigSpecFragment = ( - EnumFragment((True,)) if for_search else BooleanFragment() + EnumFragment((True, False), search_choices=(False,)) + if for_search + else BooleanFragment() ) fragments.update( {