[torchlib] Reimplement as_strided without an ONNX loop - #2928
Conversation
|
Copilot the inputs marked as SymInt can be dynamic. Can you update the logic to account for this situation? |
Added a dynamic path in 93d3247: when any of |
|
Copilot can you add good coverage on the new logic in tests/function_libs/torch_lib/e2e_ops_tests.py? |
|
Copilot also add more detailed comment to explain what each line of the implementation is doing in relation to the torch op, as it is a more complicated op, for readability |
Added e2e coverage in |
Added detailed line-by-line comments to |
There was a problem hiding this comment.
Pull request overview
This PR refactors the torchlib lowering for aten::as_strided to avoid generating an ONNX Loop/Scan when constructing gather indices, enabling simpler downstream constant-folding. It introduces a static fast path that precomputes the index tensor with NumPy when all size/stride/storage_offset values are known at trace time, and a dynamic path that builds the same index math using ONNX ops without loops.
Changes:
- Reimplemented
aten_as_stridedinops/core.pyas aReshape([-1]) + Gatherwith (1) a NumPy-constant index fast path and (2) an ONNX-op dynamic index path (noLoop/Scan). - Removed the now-unused private
_aten_as_strided_onnxlowering and unblocked type-constraint deduction by removing it from the “skip loop/scan” list. - Added new E2E tests covering several
as_stridedscenarios (static and dynamic shapes/offsets).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
tests/function_libs/torch_lib/e2e_ops_tests.py |
Adds E2E export coverage for torch.as_strided across static and dynamic cases. |
onnxscript/function_libs/torch_lib/ops/core.py |
Replaces loop-based index construction with static NumPy-constant and dynamic ONNX-op paths. |
onnxscript/function_libs/tools/torch_lib/deduce_type_constraints_test.py |
Removes _aten_as_strided_onnx from the loop/scan skip list since it no longer exists. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2928 +/- ##
==========================================
+ Coverage 72.66% 72.70% +0.03%
==========================================
Files 265 265
Lines 32297 32298 +1
Branches 3056 3059 +3
==========================================
+ Hits 23469 23481 +12
+ Misses 7791 7779 -12
- Partials 1037 1038 +1 ☔ View full report in Codecov by Harness. |
Multi-reviewer summary (readability, code, critical, deep-semantic, integration)Genuine improvement — replacing the un-foldable Major
Minor
Readability
The architectural comment block explaining the storage-offset formula is excellent documentation. |
|
Thanks. SymInts are always int64. Others I will fix |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
awesome to see this PR. I've been using a similar custom implementation for a while now. |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Addressed in 4d70d2b:
Validation completed before commit:
|
There was a problem hiding this comment.
🟡 Changes recommended
A newly added test compares an IR shape object directly to a Python list, which is likely to fail despite matching dimensions.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 1
- Review effort level: Lite
aten_as_stridedpreviously lowered through a private ONNX function that built gather indices with sequence operations and a loop-like construction that was difficult to fold. This change computes the same flat-storage indices without emitting ONNXLooporScan.Implementation
For each output position, the storage index is:
The input is flattened and gathered with those indices:
Range/Mul/Unsqueeze/Addoperations. Static constants are limited to512 * 512elements, matching the optimizer's default folded-output size limit.storage_offset=Noneto zero.ONNX exposes logical tensor values rather than backing storage. Therefore, flattening is correct only when logical row-major order matches storage order; non-contiguous input views remain unsupported, consistent with the previous lowering.
Other changes
_aten_as_strided_onnxfunction and its type-constraint-test skip.Sequence[INT64]for thesizeandstrideparameters ofaten_as_strided_copy,aten_as_strided_scatter,aten_empty_strided, andaten_new_empty_strided.empty_shapetoscalar_shapeand hoist the shared trailing comment.Validation
python -m pytest -q tests/function_libs/torch_lib/e2e_ops_tests.py -k "aten_as_strided"— 7 passedpython -m pytest -q tests/function_libs/torch_lib/ops_test.py -k "new_empty_strided"— 5 passed, 1 skippedpython -m pytest -q onnxscript/function_libs/tools/torch_lib/deduce_type_constraints_test.py— 43 passedlintrunner -aon all three PR-changed files — no lint issues