Add sym_int prim op for symbolic integer casting#20679
Conversation
torch.export with dynamic shapes (Dim.AUTO) can emit sym_int nodes when symbolic float expressions need integer conversion. Without a registered prim op and C++ kernel, these models fail at export or crash at runtime. Adds Python op registration, mapping entry, and C++ kernel handling Int (passthrough), Double (truncate toward zero), and Bool (0/1).
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/20679
Note: Links to docs will display an error until the docs builds have been completed. ❌ 4 New Failures, 1 Cancelled Job, 2 Unrelated FailuresAs of commit 4ebf64a with merge base ee990d7 ( NEW FAILURES - The following jobs have failed:
CANCELLED JOB - The following job was cancelled. Please retry:
FLAKY - The following jobs failed but were likely due to flakiness present on trunk:
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
This PR needs a
|
There was a problem hiding this comment.
Pull request overview
This PR adds ExecuTorch support for torch.sym_int emitted by torch.export when symbolic float expressions must be cast back to integers for shape computations, preventing export failures and runtime crashes for dynamic-shape models.
Changes:
- Register a new ExecuTorch prim op
executorch_prim::sym_int.Scalarand implement its C++ kernel (int passthrough, double→int64 truncation toward zero, bool→0/1). - Add Python-side op schema/registration and map
torch.sym_intto the ExecuTorch prim op during lowering. - Add C++ and Python emit tests validating the new op is present in exported graphs and executes correctly at runtime.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| kernels/prim_ops/test/prim_ops_test.cpp | Extends prim-op registration tests and adds value-level correctness tests for sym_int. |
| kernels/prim_ops/register_prim_ops.cpp | Registers the executorch_prim::sym_int.Scalar kernel with type handling for int/double/bool. |
| exir/passes/executorch_prim_ops_registry.py | Adds schema + implementation binding for sym_int and maps torch.sym_int to the ExecuTorch prim op. |
| exir/emit/test/test_emit.py | Adds an end-to-end emit/export-to-runtime test that ensures torch.sym_int appears and executes correctly under dynamic shapes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The original model used sym_int(sym_float(n)) which is an identity round-trip that PyTorch's symbolic evaluator folds away at trace time. Use a bool→float→int chain instead, which can't be simplified. Also drop the fragile graph node assertion — the C++ unit test validates the kernel directly.
The bool→float→int chain (sym_not→sym_float→sym_int) produces TruncToInt(ToFloat(s0 <= 5)) which triggers a PyTorch value_ranges bug: simple_sympify can't handle ToFloat(False). Use the simple sym_float→sym_int round-trip instead. The symbolic evaluator folds it to identity, but the test still validates the full export→edge→executorch pipeline with dynamic shapes. The C++ unit test validates the sym_int kernel directly.
| } else if (a.isDouble()) { | ||
| out = EValue(static_cast<int64_t>(a.toDouble())); | ||
| } else if (a.isBool()) { |
| exported_program = torch.export.export( | ||
| model, (test_inputs[0],), dynamic_shapes=dynamic_shapes | ||
| ) | ||
|
|
||
| edge_program = to_edge( | ||
| exported_program, | ||
| compile_config=exir.EdgeCompileConfig(_check_ir_validity=False), | ||
| ) |
torch.export with dynamic shapes (Dim.AUTO) can emit sym_int nodes when symbolic float expressions need integer conversion. Without a registered prim op and C++ kernel, these models fail at export or crash at runtime.
Adds Python op registration, mapping entry, and C++ kernel handling Int (passthrough), Double (truncate toward zero), and Bool (0/1).