Repository navigation
Keep cat_out's nnlib input arrays off variable-length stack arrays (#24319) - #24319
zonglinpeng wants to merge 2 commits into
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/24319
Note: Links to docs will display an error until the docs builds have been completed. ❌ 2 New Failures, 2 PendingAs of commit bec367b with merge base 822cb60 ( NEW FAILURES - The following jobs have failed:
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
@zonglinpeng has exported this pull request. If you are a Meta employee, you can view the originating Diff in D128236590. |
This PR needs a
|
Summary: `rlx_arbitrary_image_stylization` fails in the ExecuTorch emitter: `InternalError: Tensor has a memory_format that is unsupported in ExecuTorch: torch.channels_last` (`exir/tensor.py` `memory_format_enum` raises `KeyError: torch.channels_last`). Its export carries `clone(memory_format=torch.channels_last)` on ops that stay on the CPU. Cadence lowers with `_skip_dim_order=True`, and so does Helios, which runs Cadence's remove passes. Every edge tensor is therefore contiguous and a memory format has no runtime representation. The emitter accepts only contiguous and preserve. The upstream `RemoveCloneOpsTransform` deliberately keeps clones that change memory format, because with dim order they carry a real layout, and Cadence's wrapper `RemoveCloneOpsTransformImported` ran it unchanged. Nothing removed the clone. The wrapper becomes one pass, renamed `RemoveCloneOpsPass`: a `RemoveCloneOpsTransform` subclass that also treats an `aten.clone` with any memory format as a plain copy, so the clone is removed. `_clone_dim_order` keeps the upstream behavior. Dead-code elimination still runs afterwards, as it did in the wrapper. The upstream transform is unchanged. The rename touches every caller in fbcode and xplat: Cadence passes, Helios sharding transforms, Jarvis, the SAS compiler and the xr_sonic gleam export. This replaces the Helios-only `StripCloneMemoryFormat` pass from the earlier version of this diff. Differential Revision: D125145150
…ytorch#24319) Summary: `impl::G3::native::cat_out` declared variable-length arrays sized by the number of inputs (about 76 B per input) before it checked whether the `xa_nn_cat` path applies. A 256-input int64 cat in RT-DETR (`rtdetr_r18vd`, int8) therefore grew the frame by about 19 KB on the DSP thread that runs the operator, overflowed that thread's 7488 B stack and tripped the Zephyr stack sentinel on the first inference. Raising the stack did not help: 8 KB, 11.5 KB and 16 KB stacks all overflowed. The nnlib path now runs only for same-dtype, supported-dtype cats with at most 16 inputs, and uses fixed-size arrays. Larger cats take the existing generic loop. The frame is a fixed 1440 B: the number of dynamic stack adjustments in `cat_out` goes from 11 to 0 in the built DSP image. Adds a 40-input `cat` test case so the fallback branch is covered. The 256 inputs are one tensor repeated: every entry of that cat references the same value and buffer. RT-DETR's decoder gathers with `topk_ind.unsqueeze(-1).repeat(1, 1, d_model)`, and Cadence's `ReplaceRepeatWithCatPass` lowers a `repeat` as a cat of the same tensor, so `d_model` = 256 becomes a 256-entry cat. The kernel is still the place to fix the overflow: the arrays are sized by entry count, not by distinct tensors, and a 100-entry cat of distinct inputs (EfficientDet-Lite0's full graph) would need about 7.6 KB of them, more than the whole 7488 B stack. Lowering `repeat` as a broadcast copy would remove RT-DETR's long list but leave genuinely wide cats exposed, so it is at most a later optimization. Differential Revision: D128236590
ea355db to
bec367b
Compare
Summary:
impl::G3::native::cat_outdeclared variable-length arrays sized by the number of inputs (about 76 B per input) before it checked whether thexa_nn_catpath applies. A 256-input int64 cat in RT-DETR (rtdetr_r18vd, int8) therefore grew the frame by about 19 KB on the DSP thread that runs the operator, overflowed that thread's 7488 B stack and tripped the Zephyr stack sentinel on the first inference. Raising the stack did not help: 8 KB, 11.5 KB and 16 KB stacks all overflowed.The nnlib path now runs only for same-dtype, supported-dtype cats with at most 16 inputs, and uses fixed-size arrays. Larger cats take the existing generic loop. The frame is a fixed 1440 B: the number of dynamic stack adjustments in
cat_outgoes from 11 to 0 in the built DSP image.Adds a 40-input
cattest case so the fallback branch is covered.The 256 inputs are one tensor repeated: every entry of that cat references the same value and buffer. RT-DETR's decoder gathers with
topk_ind.unsqueeze(-1).repeat(1, 1, d_model), and Cadence'sReplaceRepeatWithCatPasslowers arepeatas a cat of the same tensor, sod_model= 256 becomes a 256-entry cat. The kernel is still the place to fix the overflow: the arrays are sized by entry count, not by distinct tensors, and a 100-entry cat of distinct inputs (EfficientDet-Lite0's full graph) would need about 7.6 KB of them, more than the whole 7488 B stack. Loweringrepeatas a broadcast copy would remove RT-DETR's long list but leave genuinely wide cats exposed, so it is at most a later optimization.Differential Revision: D128236590