[Relax][ONNX] Add CastLike support and dynamic-k Trilu to expand backend coverage#19898
[Relax][ONNX] Add CastLike support and dynamic-k Trilu to expand backend coverage#19898Aharrypotter wants to merge 5 commits into
Conversation
- Add a CastLike converter to the Relax ONNX frontend (opset 15+). - CastLike casts the first input to the dtype of the second input, which is required by the expanded form of Relu in opset 18. - Add relu to the backend test allowlist. - Add a focused CastLike regression test. Relates to issue apache#19505.
- Remove the constant-k restriction from the Trilu converter. - For constant k, keep using the optimized relax.op.tril/triu. - For dynamic k, build the lower/upper-triangular mask explicitly with arange and broadcast it to the input shape. - Add tril and triu to the backend test allowlist. - Add a regression test for Trilu with dynamic k. Relates to issue apache#19505.
There was a problem hiding this comment.
Code Review
This pull request introduces the CastLike ONNX operator converter and updates the Trilu converter to support dynamic k values by building a mask explicitly. It also expands the ONNX backend test suite to include several new operators. The review feedback suggests making the CastLike type retrieval safer to prevent potential AttributeErrors, removing redundant explicit broadcasts in the dynamic k mask generation, and using x.ty.dtype.dtype instead of x.ty.dtype for consistency when calling relax.const.
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.
| def _impl_v15(cls, bb, inputs, attr, params): | ||
| data = inputs[0] | ||
| target = inputs[1] | ||
| target_dtype = target.ty.dtype.dtype |
There was a problem hiding this comment.
Accessing target.ty.dtype.dtype directly assumes that target.ty is populated and is a TensorType. If target is a relax.Var without type annotation or has a different type structure, this will raise an AttributeError. Consider using a safer fallback like getattr to handle potentially missing type information, similar to how it is done in the Cast converter.
| diff = relax.op.subtract( | ||
| relax.op.broadcast_to(col_idx, (m, n)), | ||
| relax.op.broadcast_to(row_idx, (m, n)), | ||
| ) |
There was a problem hiding this comment.
The explicit relax.op.broadcast_to calls on col_idx and row_idx are redundant. In TVM Relax, element-wise binary operators like relax.op.subtract support implicit broadcasting natively. Removing these explicit broadcasts simplifies the generated Relax graph and avoids creating unnecessary intermediate operators.
diff = relax.op.subtract(col_idx, row_idx)| return relax.op.tril(x, k) | ||
| mask = relax.op.less_equal(diff, k_int64) | ||
| mask = relax.op.broadcast_to(mask, shape) | ||
| return relax.op.where(mask, x, relax.const(0, x.ty.dtype)) |
There was a problem hiding this comment.
To be consistent with the rest of the file (e.g., lines 372, 383), you should use x.ty.dtype.dtype to retrieve the string representation of the data type for relax.const, rather than passing the DataType object x.ty.dtype directly.
| return relax.op.where(mask, x, relax.const(0, x.ty.dtype)) | |
| return relax.op.where(mask, x, relax.const(0, x.ty.dtype.dtype)) |
Summary
This PR adds
CastLikesupport and dynamic-ksupport forTriluin the RelaxONNX frontend, then adds
relu,tril, andtriuto the official ONNX backendtest allowlist.
Goal
Increase the Relax ONNX frontend's coverage in the official ONNX Backend Test
Suite by enabling operators that already have hand-written frontend tests but
still fail some official node-level tests.
What changed
CastLikeconverter.krestriction from theTriluconverter.relu,tril, andtriuto_INCLUDE_OPS._EXCLUDE_PATTERNSto filter out a few model-level tests whose namescollide with the node-level include patterns.
Result
This PR directly addresses part of #19505.
Design
CastLike support
ONNX
CastLike(opset 15+) takes two inputs: the data to cast and a tensorwhose dtype determines the output dtype. The opset-18 expanded form of
Reludecomposes the operator into a subgraph that uses
CastLike, so importing anyopset-18
Relumodel previously failed with:The new
CastLikeconverter reads the dtype of the second input and emitsrelax.op.astype(data, target_dtype). It handles both constant and dynamictarget tensors because the dtype is taken from the input's type information.
Trilu dynamic
kThe existing
Triluconverter only accepted a constantkdiagonal offset andraised
ValueErrorfor any dynamic / graph-inputk. Several official ONNXnode tests (
test_tril_neg,test_triu_zero, etc.) supplykas a graphinput, so those tests could not pass.
The converter now branches:
kis a constant or omitted, use the optimizedrelax.op.tril/relax.op.triupaths.kis dynamic, construct the lower/upper-triangular mask explicitly:relax.op.arange.col_index - row_index.k.relax.op.whereto zerothe excluded elements.
Updated Allowlist
_INCLUDE_OPSrelutriltriuTotal backend suite progress: 388 passed → 451 passed (all CPU; CUDA tests
are registered but skipped because the backend adapter only supports CPU).
Safety Checks
CastLikereturnsrelax.op.astype(data, target_dtype)wheretarget_dtypeis the dtype of the second input.kinTrilukeeps the existing optimizedrelax.op.tril/relax.op.triulowering.kinTriluis implemented without callingrelax.op.tril/triuwith a non-constant diagonal offset._INCLUDE_OPSremains the gate for which backend tests run; a small_EXCLUDE_PATTERNSlist filters model-level name collisions so the suitestays green without limiting the registered test classes.
Out of Scope / Non-Goals
tests (
cast,equal,gather,reshape,shape,reduce_*). Those willbe handled in follow-up PRs.
Reluitself; it onlyunblocks the expanded form by adding
CastLike.Tests
test_castlike_irCastLikeconverter, structural IR checktest_trilu/test_trilu_with_const_ktest_trilu_dynamic_k_irk(upper=True/False)test_frontend_onnx_backend.pyrelu,tril,triuLocal validation:
python -m pytest tests/python/relax/test_frontend_onnx.py::test_castlike_ir -xvs python -m pytest tests/python/relax/test_frontend_onnx.py -k "trilu" -xvs python -m pytest tests/python/relax/test_frontend_onnx_backend.py -q python -m ruff format --check \ python/tvm/relax/frontend/onnx/onnx_frontend.py \ tests/python/relax/test_frontend_onnx.py \ tests/python/relax/test_frontend_onnx_backend.py python -m ruff check \ python/tvm/relax/frontend/onnx/onnx_frontend.py \ tests/python/relax/test_frontend_onnx.py \ tests/python/relax/test_frontend_onnx_backend.pyResult:
References
[Relax][ONNX] Use ONNX Backend Tests to improve frontend coverage.