[Relax][ONNX] Support AffineGrid align_corners false#19854
Conversation
There was a problem hiding this comment.
Code Review
This pull request adds support for the align_corners attribute in the affine_grid operator across TVM Relax, TOPI, and the ONNX frontend, including corresponding tests. The review feedback highlights critical backward-compatibility issues with older IR/models where affine_grid may not have attributes. Specifically, strictly requiring attrs to be non-null in C++ struct info inference and directly accessing call.attrs.align_corners in Python legalization without checking if call.attrs is None can lead to failures.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| const auto* attrs = call->attrs.as<AffineGridAttrs>(); | ||
| TVM_FFI_ICHECK(attrs) << "Invalid Call"; |
| topi.image.affine_grid, | ||
| call.args[0], | ||
| target_shape=target_shape, | ||
| align_corners=call.attrs.align_corners, |
There was a problem hiding this comment.
If call.attrs is None (which is the case for older IR/models where affine_grid had no attributes), accessing call.attrs.align_corners will raise an AttributeError. To prevent this and ensure backward compatibility, we should default align_corners to True if call.attrs is None.
| align_corners=call.attrs.align_corners, | |
| align_corners=call.attrs.align_corners if call.attrs else True, |
There was a problem hiding this comment.
Pull request overview
Adds support for ONNX AffineGrid’s default align_corners=0 behavior in the Relax ONNX frontend by plumbing an align_corners attribute through the Relax image.affine_grid op, legalization, and TOPI implementation, while preserving existing Relax default behavior (align_corners=True).
Changes:
- Introduce
AffineGridAttrs(align_corners)forrelax.image.affine_gridand thread it through Relax op construction and legalization. - Extend TOPI
affine_grid(and its Python reference) to generate grids for bothalign_corners=True/False. - Update ONNX
AffineGridimport to honor ONNX’salign_cornersattribute default (0), and add tests for both alignment modes.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| include/tvm/relax/attrs/image.h | Adds AffineGridAttrs with align_corners and reflection metadata. |
| src/relax/op/image/resize.h | Updates C++ Relax op constructor signature to accept align_corners. |
| src/relax/op/image/resize.cc | Registers AffineGridAttrs, attaches attrs to calls, and updates op registration to use attrs type. |
| python/tvm/relax/op/op_attrs.py | Registers Python-side AffineGridAttrs object wrapper. |
| python/tvm/relax/op/image/image.py | Extends Relax Python API for affine_grid(..., align_corners=...) (default True). |
| python/tvm/relax/transform/legalize_ops/image.py | Passes align_corners through legalization to TOPI. |
| python/tvm/topi/image/grid_sample.py | Extends TOPI affine_grid to support both align_corners modes. |
| python/tvm/topi/testing/grid_sample_python.py | Extends NumPy reference affine_grid_python for both align_corners modes. |
| python/tvm/relax/frontend/onnx/onnx_frontend.py | Uses ONNX align_corners attribute (default 0) and forwards it into Relax affine_grid. |
| tests/python/relax/test_op_image.py | Adds attribute test + struct-info inference coverage + E2E numeric coverage for both alignments. |
| tests/python/relax/test_transform_legalize_ops_image.py | Adds legalization test coverage for align_corners=False expected TIR. |
| tests/python/relax/test_frontend_onnx.py | Parameterizes ONNX AffineGrid test to cover omitted attr (default), 0, and 1. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
aa94487 to
548af1f
Compare
548af1f to
06da467
Compare
Motivation
ONNX AffineGrid has an
align_cornersattribute, and the ONNX default isalign_corners=0. The Relax ONNX frontend previously rejected that default withNotImplementedError, so an ONNX model that omitted the attribute could not beimported.
Fixes #19690.
Changes
This PR threads
align_cornersthrough Relaximage.affine_grid, legalization,and the TOPI implementation. The Relax API keeps the existing
align_corners=Truedefault to preserve current behavior, while the ONNXfrontend reads the ONNX attribute and uses ONNX's default value of
0.The tests cover Relax struct-info inference, legalization, numerical execution,
and ONNX import/execution for both
align_corners=0andalign_corners=1.Testing
cmake --build build --parallel $(nproc)pre-commit run --files include/tvm/relax/attrs/image.h python/tvm/relax/frontend/onnx/ onnx_frontend.py python/tvm/relax/op/image/image.py python/tvm/relax/op/op_attrs.py python/ tvm/relax/transform/legalize_ops/image.py python/tvm/topi/image/grid_sample.py python/tvm/ topi/testing/grid_sample_python.py src/relax/op/image/resize.cc src/relax/op/image/resize.h tests/python/relax/test_frontend_onnx.py tests/python/relax/test_op_image.py tests/python/ relax/test_transform_legalize_ops_image.pypytest tests/python/relax/test_op_image.py tests/python/relax/ test_transform_legalize_ops_image.py -qpytest tests/python/relax/test_frontend_onnx.py -k 'affine_grid or grid_sample' -q