-
Notifications
You must be signed in to change notification settings - Fork 3.9k
[Relax][ONNX] Add CastLike support and dynamic-k Trilu to expand backend coverage #19898
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 3 commits
79afc04
2b1cba2
dab4f74
2acccfb
a73ff50
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -1170,6 +1170,17 @@ def _impl_v13(cls, bb, inputs, attr, params): | |||||
| return relax.op.astype(inputs[0], to_type) | ||||||
|
|
||||||
|
|
||||||
| class CastLike(OnnxOpConverter): | ||||||
| """Convert an onnx CastLike node into an equivalent Relax expression.""" | ||||||
|
|
||||||
| @classmethod | ||||||
| def _impl_v15(cls, bb, inputs, attr, params): | ||||||
| data = inputs[0] | ||||||
| target = inputs[1] | ||||||
| target_dtype = target.ty.dtype.dtype | ||||||
| return relax.op.astype(data, target_dtype) | ||||||
|
|
||||||
|
|
||||||
| class Gather(OnnxOpConverter): | ||||||
| """Convert an onnx Gather node into an equivalent Relax expression.""" | ||||||
|
|
||||||
|
|
@@ -1506,19 +1517,29 @@ def _impl_v14(cls, bb, inputs, attr, params): | |||||
| x = inputs[0] | ||||||
| k = inputs[1] if len(inputs) > 1 else 0 | ||||||
|
|
||||||
| if len(inputs) > 1: | ||||||
| k = get_constant(inputs[1], params) | ||||||
| if isinstance(k, relax.Constant): | ||||||
| k = int(k.data.numpy().item()) | ||||||
| else: | ||||||
| raise ValueError("Currently only support constant k for Trilu op.") | ||||||
| else: | ||||||
| k = 0 | ||||||
| if isinstance(k, relax.Constant): | ||||||
| k = int(k.data.numpy().item()) | ||||||
| if isinstance(k, int): | ||||||
| if upper: | ||||||
| return relax.op.triu(x, k) | ||||||
| return relax.op.tril(x, k) | ||||||
|
|
||||||
| # Dynamic k: build the mask explicitly so it works with any scalar k. | ||||||
| shape = x.ty.shape | ||||||
| m, n = shape[-2], shape[-1] | ||||||
| row_idx = relax.op.reshape(relax.op.arange(0, m, dtype="int64"), (m, 1)) | ||||||
| col_idx = relax.op.reshape(relax.op.arange(0, n, dtype="int64"), (1, n)) | ||||||
| diff = relax.op.subtract( | ||||||
| relax.op.broadcast_to(col_idx, (m, n)), | ||||||
| relax.op.broadcast_to(row_idx, (m, n)), | ||||||
| ) | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The explicit diff = relax.op.subtract(col_idx, row_idx) |
||||||
| k_int64 = relax.op.astype(k, "int64") | ||||||
| if upper: | ||||||
| return relax.op.triu(x, k) | ||||||
| mask = relax.op.greater_equal(diff, k_int64) | ||||||
| else: | ||||||
| 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)) | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be consistent with the rest of the file (e.g., lines 372, 383), you should use
Suggested change
|
||||||
|
|
||||||
|
|
||||||
| class Relu(OnnxOpConverter): | ||||||
|
|
@@ -5241,6 +5262,7 @@ def _get_convert_map(): | |||||
| "Max": Max, | ||||||
| "Mean": Mean, | ||||||
| "Cast": Cast, | ||||||
| "CastLike": CastLike, | ||||||
| "Gemm": Gemm, | ||||||
| "MatMul": MatMul, | ||||||
| "MatMulInteger": MatMulInteger, | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accessing
target.ty.dtype.dtypedirectly assumes thattarget.tyis populated and is aTensorType. Iftargetis arelax.Varwithout type annotation or has a different type structure, this will raise anAttributeError. Consider using a safer fallback likegetattrto handle potentially missing type information, similar to how it is done in theCastconverter.