Repository navigation
Commit 5ef2767
authored
Preserve in-place result aliases and lifetimes during memory planning (pytorch#23526)
### Summary
With `run_reinplace_pass=True`, an in-place result can remain live after
the memory planner considers its storage dead. A subsequent allocation
then overwrites it. This reproduces with `cache =
torch.zeros_like(x).index_put((indices,), values); scratch = x + 10;
return cache + scratch, cache` and caused incorrect, non-repeatable
Whisper static-prefill logits and KV caches.
Propagate in-place result aliases in `SpecPropPass`, before downstream
outputs and getitems capture their specs. Include those aliased specs in
lifetime collection instead of skipping in-place nodes. Shared
TensorSpecs remain deduplicated for allocation. The four regression
cases cover greedy and naive planning, with the cache either returned or
used only as an intermediate; all four fail before this fix and pass
afterward. In-place nodes are no longer skipped in
`collect_specs_from_nodes`: if aliasing is skipped for a return (no
matching `Tensor(a!)` annotation, or the mutated input can't be
resolved), that result now gets its own planned buffer, where before it
was never allocated.
`MemoryPlanningPass.run` now also verifies, before planning, that every
write-aliased in-place result shares its mutated input's TensorSpec, and
raises `InternalError` otherwise. Without this check, an in-place op
introduced after `SpecPropPass` would silently get its own planned
buffer that the kernel never writes. The check covers only returns that
the schema declares as aliasing an input, and skips the same cases
aliasing skips, so ops without alias annotations are unaffected. A fifth
test breaks the alias before planning and confirms the check raises.
This addresses allocation lifetimes after a legal in-place rewrite. It
is independent of pytorch#23488, which prevents an illegal rewrite when the
original value is also returned.
### Test plan
Local validation in a Python 3.12 environment with the native runtime
built from source: **131 tests passed** across
`executorch.exir.tests.test_memory_planning`,
`test_banked_memory_planning`, `test_reinplace_pass`, and
`test_remove_view_copy`; all seven `TestPasses.test_spec_prop_pass*`
cases passed; and all 33 Cadence
`backends/cadence/aot/tests/test_memory_passes.py` tests passed, so the
new check does not trip in Cadence's planner. `lintrunner` on the
changed files and `git diff --check` passed.
The minimal runtime reproducer returns both tensors exactly as eager
PyTorch after the fix, including on repeated calls. For `x=arange(8)`,
indices `[0,3]`, and values `[9,17]`, its first result changes from the
incorrect `[20,22,24,26,28,30,32,34]` to `[19,11,12,30,14,15,16,17]`.
Also validated cached pretrained `openai/whisper-tiny`, FP32, through
the Transformers exporter and XNNPACK, with four CPU threads. Default
and reinplace outputs match bit-for-bit across encoder, dynamic-cache
prefill/decode, and static-cache prefill/decode, including repeat
executions. Static-prefill maximum absolute logit error against eager is
`4.39e-5` for both variants. The corrected static-prefill arena is
31,219,232 bytes versus 33,899,072 bytes without reinplace.
Local static-prefill A/B/B/A median latencies after the fix
(milliseconds):
| A1 default | B1 reinplace | B2 reinplace | A2 default |
| ---: | ---: | ---: | ---: |
| 232.730 | 26.247 | 25.989 | 232.396 |
This is an 8.90× component speedup from enabling reinplace with correct
outputs, not a full-transcription measurement. Each block was a fresh
process with ten warmups and 150 measured calls, fixed inputs restored
outside timing, and four pinned guest CPU cores. Other components had
byte-identical A/B artifacts. The original comparison used PyTorch
2.13.0+cpu and the same installed ExecuTorch 1.5.0 native runtime for
both variants.
Authored with AI assistance using Codex at the submitter's direction.1 parent 2c36163 commit 5ef2767
9 files changed
Lines changed: 298 additions & 160 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
168 | 168 | | |
169 | 169 | | |
170 | 170 | | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
171 | 184 | | |
172 | 185 | | |
173 | 186 | | |
| |||
177 | 190 | | |
178 | 191 | | |
179 | 192 | | |
| 193 | + | |
180 | 194 | | |
181 | 195 | | |
182 | 196 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
638 | 638 | | |
639 | 639 | | |
640 | 640 | | |
641 | | - | |
642 | | - | |
| 641 | + | |
| 642 | + | |
643 | 643 | | |
644 | 644 | | |
645 | 645 | | |
| |||
2093 | 2093 | | |
2094 | 2094 | | |
2095 | 2095 | | |
2096 | | - | |
2097 | | - | |
2098 | | - | |
| 2096 | + | |
| 2097 | + | |
2099 | 2098 | | |
2100 | 2099 | | |
2101 | 2100 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
0 commit comments