Repository navigation
Fix two crashes caused by constant_prop_pass - #24224
Open
pytorchbot wants to merge 1 commit into
Open
pytorchbot wants to merge 1 commit into
pytorchbot wants to merge 1 commit into
Conversation
## What is wrong today Programs that go through `constant_prop_pass` can crash in two ways: one inside the pass, and one later when the program is lowered. **1. A folded value that is not a tensor.** The pass also folds values such as the int from `.item()` on a buffer, and the bools that `torch._check` turns into runtime checks. When a node that stays in the graph reads such a value, the pass tries to turn it into a constant tensor input and fails: ```python n = self.n.item() # self.n is a buffer torch._check(n >= 1) torch._check(n <= x.shape[0]) return x[:n] * self.w[:n] ``` ``` TypeError: cannot create weak reference to 'bool' object ``` **2. A folded parameter that still requires grad.** Folding `self.w.t()`, or one chunk of a packed weight, gives a view that still has `requires_grad=True`, because `torch.no_grad()` does not clear that flag on a view. For some views, such as a transposed one, `to_edge` then copies the constant into a non-leaf tensor, and lowering to a backend can fail when it deep-copies the program: ``` RuntimeError: Only Tensors created explicitly by the user (graph leaves) support the deepcopy protocol at the moment. ``` An op can also return the parameter itself, like `self.w.to(torch.float32)` on a float32 parameter. Then the pass stores the `nn.Parameter` as a constant, and `to_edge` fails with `AttributeError: ... is not a buffer`. ## What this change does Two commits, one per crash: 1. Only tensors can become constant inputs. So a non-tensor value that a node outside the fold reads now stays in the graph, together with the non-tensor values it is computed from. Tensors computed from it still fold: `self.w[:n]` still becomes one constant. Programs that `constant_prop_pass` handled before are unchanged. 2. A folded constant must be a plain tensor that does not require grad, so the pass now detaches every folded tensor. ## What was tested On macOS arm64: - Two new tests in `exir/tests/test_passes.py`, one per commit. Each fails before its commit and passes after: the first with `TypeError: cannot create weak reference to 'int' object`, the second with the `AttributeError` above. - The first covers a scalar read at runtime, one returned as an output, one whose first reader is folded, and one read only by folded nodes (it folds away). The program also lowers with `to_edge(...).to_executorch()`. - The second covers the transposed view and the `to` case, and checks that the output matches eager. - The rest of `exir/tests/test_passes.py`, `exir/emit/test/test_emit.py` and `exir/tests/test_quant_fusion_pass.py`. Five tests in those files fail the same way with and without this change, because they need the quantized and custom op libraries. (cherry picked from commit cedc66f)
pytorchbot
requested review from
JacobSzwejbka and
larryliu0820
as code owners
October 28, 2026 03:47
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/24224
Note: Links to docs will display an error until the docs builds have been completed. ✅ No FailuresAs of commit 9f8a6e9 with merge base 4db778e ( This comment was automatically generated by Dr. CI and updates every 15 minutes. |
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is wrong today
Programs that go through
constant_prop_passcan crash in two ways: one inside the pass, and one later when the program is lowered.1. A folded value that is not a tensor. The pass also folds values such as the int from
.item()on a buffer, and the bools thattorch._checkturns into runtime checks. When a node that stays in the graph reads such a value, the pass tries to turn it into a constant tensor input and fails:2. A folded parameter that still requires grad. Folding
self.w.t(), or one chunk of a packed weight, gives a view that still hasrequires_grad=True, becausetorch.no_grad()does not clear that flag on a view. For some views, such as a transposed one,to_edgethen copies the constant into a non-leaf tensor, and lowering to a backend can fail when it deep-copies the program:An op can also return the parameter itself, like
self.w.to(torch.float32)on a float32 parameter. Then the pass stores thenn.Parameteras a constant, andto_edgefails withAttributeError: ... is not a buffer.What this change does
Two commits, one per crash:
self.w[:n]still becomes one constant. Programs thatconstant_prop_passhandled before are unchanged.What was tested
On macOS arm64:
exir/tests/test_passes.py, one per commit. Each fails before its commit and passes after: the first withTypeError: cannot create weak reference to 'int' object, the second with theAttributeErrorabove.to_edge(...).to_executorch().tocase, and checks that the output matches eager.exir/tests/test_passes.py,exir/emit/test/test_emit.pyandexir/tests/test_quant_fusion_pass.py. Five tests in those files fail the same way with and without this change, because they need the quantized and custom op libraries.