Stacked PRs:
[Inductor] Handle hinted and fallback unbacked symbols
Inductor has several codegen paths that need to reason about unbacked symbolic extents without turning policy decisions into semantic guards. Layout constraint lowering needs to recognize common symbolic stride orderings, while fallback kernels can repropagate outputs whose unbacked symbols are graph-owned and must be bound for wrapper codegen.
For stride ordering, use a stride-specific symbolic greater-or-equal proof with ordinary guarded comparisons plus divisibility reasoning. This lets Inductor prove layouts such as u0 * 256 >= 256 without relying on concrete hints, while still rejecting unproved unbacked layouts. When require_strides proves the current layout already satisfies the requested order, freeze the current layout directly instead of forcing guarding_hints_or_throw() or bailing out for every unbacked stride.
For fallback outputs, temporarily re-enable fresh unbacked symbol tracking while rerunning the fallback fake kernel. That call is the binding site for output size and stride symbols that later wrapper code references, so those symbols should go through the normal pending-symbol and compute_unbacked_bindings() path instead of being created under ignore_fresh_unbacked_symbols() and rediscovered afterward.
The C++ wrapper path also has to treat input unbacked symbols as already declared before emitting output bindings. Otherwise a fallback output binding can redeclare a symbol such as u0 and can emit Python-only floordiv syntax for DivideByKey paths. Emit C++ integer division for that path and reuse the existing unbacked symbol declaration.
Finally, do not make the post-copy stride-order sanity check prove data-dependent unbacked stride inequalities. The copy has already been materialized with the requested stride order; requiring a symbolic proof there rejects valid layouts whose unbacked size may be zero or one.
These changes preserve symbolic semantics: hints are not used to create semantic layout guards, fallback output extents are bound through normal ShapeEnv tracking at the fallback output binding site, and stride/order changes copy data or freeze already-valid layouts rather than manufacturing semantic guards.
Fixes #183834
Fixes #185341
Test Plan:
python test/inductor/test_unbacked_symints.py TestUnbackedSymintsCPU.test_stride_order_uses_unbacked_optimization_hint_cpu TestUnbackedSymintsCPU.test_stride_ordered_uses_symbolic_divisibility_cpu TestUnbackedSymintsCPU.test_stride_ordered_rejects_unproved_unbacked_layout_cpu -qpython test/inductor/test_unbacked_symints.py TestUnbackedSymintsCUDA.test_standalone_compile_reuses_fallback_unbacked_binding_cuda TestUnbackedSymintsCUDA.test_sdfpa_unbacked_strides_cuda -qpython test/inductor/test_unbacked_symints.py TestUnbackedSymintsCPU.test_stride_ordered_uses_symbolic_divisibility_cpu TestUnbackedSymintsCPU.test_stride_ordered_rejects_unproved_unbacked_layout_cpu TestUnbackedSymintsCUDA.test_standalone_compile_reuses_fallback_unbacked_binding_cuda TestUnbackedSymintsCUDA.test_sdfpa_unbacked_strides_cuda -qTorchTitan graph_trainer H100 integration: aot_fx_trace_deepseek_v3_sdpa_full_inductor_ep_overlap_moe_seq
This PR was authored with the assistance of an AI assistant.
Pull Request resolved: #183840
Approved by: https://github.com/laithsakka