Skip to content

Commit ec52125

Browse files
authored
Add complex dtype support to edge dialect for specific ops (#20828)
The edge dialect dtype constraint tables did not include complex dtypes (ComplexFloat, ComplexDouble), causing the verifier to incorrectly reject models that use complex tensors. The runtime already supports these types (scalar_type.h indices 9-10). Registers ComplexFloat and ComplexDouble as recognized dtype names and adds them to the following shape-manipulation ops that are dtype-agnostic: unsqueeze_copy, squeeze_copy, permute_copy, slice_copy, expand_copy. This was forcing downstream exporters to monkey-patch _check_tensor_args_matching_op_allowed_dtype to suppress SpecViolationError for complex dtype violations.
1 parent aceeb40 commit ec52125

3 files changed

Lines changed: 59 additions & 6 deletions

File tree

exir/dialects/edge/dtype/supported.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
torch.float: "Float",
2828
torch.double: "Double",
2929
torch.uint16: "UInt16",
30+
torch.complex64: "ComplexFloat",
31+
torch.complex128: "ComplexDouble",
3032
}
3133

3234
regular_tensor_str_to_dtypes = {

exir/dialects/edge/edge.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3777,7 +3777,7 @@
37773777
namespace: edge
37783778
inherits: aten::expand_copy
37793779
type_alias:
3780-
T0: [Bool, Byte, Char, Double, Float, Half, BFloat16, Int, Long, Short, UInt16]
3780+
T0: [Bool, Byte, Char, Double, Float, Half, BFloat16, Int, Long, Short, UInt16, ComplexFloat, ComplexDouble]
37813781
type_constraint:
37823782
- self: T0
37833783
__ret_0: T0
@@ -6523,7 +6523,7 @@
65236523
namespace: edge
65246524
inherits: aten::permute_copy
65256525
type_alias:
6526-
T0: [Bool, Byte, Char, Double, Float, Half, BFloat16, Int, Long, Short, UInt16]
6526+
T0: [Bool, Byte, Char, Double, Float, Half, BFloat16, Int, Long, Short, UInt16, ComplexFloat, ComplexDouble]
65276527
type_constraint:
65286528
- self: T0
65296529
__ret_0: T0
@@ -7185,7 +7185,7 @@
71857185
namespace: edge
71867186
inherits: aten::slice_copy.Tensor
71877187
type_alias:
7188-
T0: [Bool, Byte, Char, Double, Float, Half, BFloat16, Int, Long, Short, UInt16]
7188+
T0: [Bool, Byte, Char, Double, Float, Half, BFloat16, Int, Long, Short, UInt16, ComplexFloat, ComplexDouble]
71897189
type_constraint:
71907190
- self: T0
71917191
__ret_0: T0
@@ -7272,7 +7272,7 @@
72727272
namespace: edge
72737273
inherits: aten::squeeze_copy.dim
72747274
type_alias:
7275-
T0: [Bool, Byte, Char, Double, Float, Half, BFloat16, Int, Long, Short, UInt16]
7275+
T0: [Bool, Byte, Char, Double, Float, Half, BFloat16, Int, Long, Short, UInt16, ComplexFloat, ComplexDouble]
72767276
type_constraint:
72777277
- self: T0
72787278
__ret_0: T0
@@ -7281,7 +7281,7 @@
72817281
namespace: edge
72827282
inherits: aten::squeeze_copy.dims
72837283
type_alias:
7284-
T0: [Bool, Byte, Char, Double, Float, Half, BFloat16, Int, Long, Short, UInt16]
7284+
T0: [Bool, Byte, Char, Double, Float, Half, BFloat16, Int, Long, Short, UInt16, ComplexFloat, ComplexDouble]
72857285
type_constraint:
72867286
- self: T0
72877287
__ret_0: T0
@@ -7821,7 +7821,7 @@
78217821
namespace: edge
78227822
inherits: aten::unsqueeze_copy
78237823
type_alias:
7824-
T0: [Bool, Byte, Char, Double, Float, Half, BFloat16, Int, Long, Short, UInt16]
7824+
T0: [Bool, Byte, Char, Double, Float, Half, BFloat16, Int, Long, Short, UInt16, ComplexFloat, ComplexDouble]
78257825
type_constraint:
78267826
- self: T0
78277827
__ret_0: T0

exir/tests/test_verification.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,3 +273,54 @@ def forward(self, x):
273273
.exported_program()
274274
.graph_module
275275
)
276+
277+
def test_edge_unsqueeze_complex_dtype(self) -> None:
278+
class TestModel(torch.nn.Module):
279+
def forward(self, x):
280+
return x.unsqueeze(0)
281+
282+
m = TestModel()
283+
for dtype in (torch.complex64, torch.complex128):
284+
edge_gm = (
285+
to_edge(
286+
export(
287+
m,
288+
(torch.randn(4, 8).to(dtype=dtype),),
289+
strict=True,
290+
)
291+
)
292+
.exported_program()
293+
.graph_module
294+
)
295+
self.assertTrue(
296+
any("unsqueeze_copy" in str(n.target) for n in edge_gm.graph.nodes),
297+
"Expected unsqueeze to lower to unsqueeze_copy",
298+
)
299+
verifier = EXIREdgeDialectVerifier()
300+
verifier(edge_gm)
301+
self.assertTrue(verifier.is_valid(edge_gm))
302+
303+
def test_edge_shape_ops_complex_dtype(self) -> None:
304+
class TestModel(torch.nn.Module):
305+
def forward(self, x):
306+
x = x.expand(4, 8)
307+
x = x.permute(1, 0)
308+
x = x[:, :2]
309+
x = x.squeeze(0)
310+
return x
311+
312+
m = TestModel()
313+
edge_gm = (
314+
to_edge(
315+
export(
316+
m,
317+
(torch.randn(1, 8).to(dtype=torch.complex64),),
318+
strict=True,
319+
)
320+
)
321+
.exported_program()
322+
.graph_module
323+
)
324+
verifier = EXIREdgeDialectVerifier()
325+
verifier(edge_gm)
326+
self.assertTrue(verifier.is_valid(edge_gm))

0 commit comments

Comments
 (0)