Skip to content

Commit b2b5485

Browse files
[release/2.11] [inductor] Backport num_stages=1 pipelining-disable autotune fallback (#3408)
Cherry-pick of pytorch#180892 (30e2dee) minus the mix_order_reduction_allow_multi_stages default flip. The mix_order_reduction_allow_multi_stages flip is an unrelated mix-order-reduction perf feature that the pytorch#17189 conv OOM fix doesn't need — the num_stages=1 fallback delivers that on its own. It was dropped because it's tuned for NVIDIA's ~228 KB shared memory and on gfx942's 64 KB LDS would mostly cause double-compile churn and new overflow risk with no proven benefit, keeping this a conservative, fix-only backport. When every Triton config for a choice fails to build with an OutOfResources/OutOfMemoryError and pipelining is active (num_stages > 1), CachingAutotuner now recompiles that config with num_stages=1 and retries instead of raising. On gfx942 (64KB LDS) this recovers the BLOCK_K=64/128 triton_convolution2d configs that otherwise overflow shared memory, eliminating the "No valid triton configs ... out of resource" autotuning errors seen in ROCm/frameworks-internal#17189 and keeping those kernels available as real choices. Excludes the mix_order_reduction_allow_multi_stages opt-in -> default-on change from the original PR to keep this a fix-only backport. --------- Co-authored-by: shunting314 <shunting@meta.com>
1 parent 67d6647 commit b2b5485

4 files changed

Lines changed: 45 additions & 2 deletions

File tree

test/inductor/test_max_autotune_blackwell.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,19 @@ def addmm(x, a, b):
280280
"triton.enable_template_tma_store": tma_store,
281281
"test_configs.autotune_choice_name_regex": "blackwell_ws_persistent_device_tma",
282282
"test_configs.autotune_choice_desc_regex": epilogue_subtile_regex,
283+
# If we dynamically disable pipelining,
284+
# triton_blackwell_ws_persistent_device_tma template will
285+
# be picked and then cause mis-aligned memory access.
286+
# If we don't dynamically disable pipelining,
287+
# this template is skipped and triton_tem_fused_addmm_repeat_3
288+
# is used.
289+
#
290+
# Fundamentally we should fix the triton_blackwell_ws_persistent_device_tma template
291+
# The flag below work around the problem.
292+
#
293+
# This only happens in fbcode https://www.internalfb.com/diff/D101855575.
294+
# Can not repro it in OSS build.
295+
"triton.dynamic_disable_pipelining": False,
283296
}
284297
):
285298
c_actual, code = run_and_get_code(

torch/_inductor/codegen/triton.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5298,6 +5298,7 @@ def inductor_meta_common(cls):
52985298
"deterministic": config.deterministic,
52995299
"force_filter_reduction_configs": config.test_configs.force_filter_reduction_configs,
53005300
"mix_order_reduction_allow_multi_stages": config.triton.mix_order_reduction_allow_multi_stages,
5301+
"dynamic_disable_pipelining": config.triton.dynamic_disable_pipelining,
53015302
}
53025303

53035304
if config.write_are_deterministic_algorithms_enabled:

torch/_inductor/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,6 +1844,8 @@ class triton:
18441844
os.environ.get("TORCHINDUCTOR_TRITON_PROTON_PER_CTA_OCCUPANCY", "1") == "1"
18451845
)
18461846

1847+
dynamic_disable_pipelining = True
1848+
18471849

18481850
class aot_inductor:
18491851
"""

torch/_inductor/runtime/triton_heuristics.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,20 @@ def _dynamic_scale_rblock(self):
642642

643643
self._make_launchers()
644644

645+
def compile_by_disabling_pipelining(self, config):
646+
# self.fn.fn is dropped by prepare_for_pickle() after the initial
647+
# compile; reload it so triton.compile can access the source.
648+
if self.fn.fn is None:
649+
assert callable(self._reload_kernel)
650+
self.fn = self._reload_kernel().fn
651+
cfg = copy.deepcopy(config)
652+
cfg.num_stages = 1
653+
if "NUM_STAGES" in cfg.kwargs:
654+
cfg.kwargs["NUM_STAGES"] = 1
655+
result = self._precompile_config(cfg)
656+
self.compile_results = [result]
657+
return result.make_launcher()
658+
645659
def _make_launchers(self):
646660
if len(self.launchers) == len(self.compile_results):
647661
return
@@ -660,8 +674,21 @@ def _make_launchers(self):
660674

661675
except (OutOfResources, PTXASError, torch.cuda.OutOfMemoryError) as e:
662676
exc = e
663-
if len(launchers) == 0:
664-
raise RuntimeError(f"No valid triton configs. {type(exc).__name__}: {exc}")
677+
if len(launchers) == 0:
678+
result = self.compile_results[-1]
679+
config = result.config
680+
if (
681+
isinstance(exc, (OutOfResources, torch.cuda.OutOfMemoryError))
682+
and (
683+
config.num_stages > 1 or config.kwargs.get("NUM_STAGES", 1) > 1
684+
)
685+
and self.inductor_meta.get("dynamic_disable_pipelining", True)
686+
):
687+
self.launchers = [self.compile_by_disabling_pipelining(config)]
688+
return
689+
raise RuntimeError(
690+
f"No valid triton configs. {type(exc).__name__}: {exc}"
691+
)
665692
self.launchers = launchers
666693

667694
def prepare_for_pickle(self) -> tuple[Any, Any, Any, Any, Any, Any]:

0 commit comments

Comments
 (0)