|
53 | 53 | from ._utils import ( |
54 | 54 | get_operands as _get_operands, |
55 | 55 | ) |
| 56 | +from ._utils import ( |
| 57 | + replace_pad_with_mode as _replace_pad_with_mode, |
| 58 | +) |
56 | 59 |
|
57 | 60 | INT32_MAX: int = 2147483647 |
58 | 61 |
|
@@ -644,20 +647,28 @@ def replace_arange_start_step( |
644 | 647 | else coreai.constant(1, dtype=start.type.element_type) |
645 | 648 | ) |
646 | 649 |
|
647 | | - # coreai.range_ requires scalar (rank-0) operands that share an element |
648 | | - # type. aten.arange promotes mixed-type scalars internally; we replicate |
649 | | - # that here by squeezing each operand to rank-0 and casting to the FX |
650 | | - # node's output dtype before the op. |
| 650 | + # When ALL operands are integer-typed, keep them as si32 so coreai.range_ |
| 651 | + # can infer a static output shape, then cast the result to the requested |
| 652 | + # dtype. If any operand is float (e.g. arange(0, 5, 0.5)), fall back to |
| 653 | + # target_type — truncating a float step to si32 would corrupt the values. |
651 | 654 | target_type = get_output_element_type_from_node(node) |
| 655 | + si32 = IntegerType.get_signed(32) |
| 656 | + all_integer = all( |
| 657 | + isinstance(v.type.element_type, IntegerType) for v in (start, end, step) |
| 658 | + ) |
| 659 | + range_type = si32 if all_integer else target_type |
652 | 660 |
|
653 | 661 | def to_scalar(v: Value) -> Value: |
654 | 662 | if v.type.rank > 0: |
655 | 663 | v = coreai.shrink_dims(v, list(range(v.type.rank))) |
656 | | - if v.type.element_type != target_type: |
657 | | - v = coreai.cast(v, target_type) |
| 664 | + if v.type.element_type != range_type: |
| 665 | + v = coreai.cast(v, range_type) |
658 | 666 | return v |
659 | 667 |
|
660 | | - return coreai.range_(to_scalar(start), to_scalar(end), to_scalar(step)) |
| 668 | + result = coreai.range_(to_scalar(start), to_scalar(end), to_scalar(step)) |
| 669 | + if result.type.element_type != target_type: |
| 670 | + result = coreai.cast(result, target_type) |
| 671 | + return result |
661 | 672 |
|
662 | 673 |
|
663 | 674 | def replace_batch_norm( |
@@ -1109,6 +1120,20 @@ def replace_constant_pad_nd( |
1109 | 1120 | return result |
1110 | 1121 |
|
1111 | 1122 |
|
| 1123 | +def replace_reflection_pad( |
| 1124 | + values_map: dict[str, Value], node: fx.Node, loc: Location |
| 1125 | +) -> Value: |
| 1126 | + """aten.reflection_pad{1,2,3}d.default -> coreai.pad<reflect>.""" |
| 1127 | + return _replace_pad_with_mode(values_map, node, loc, "reflect") |
| 1128 | + |
| 1129 | + |
| 1130 | +def replace_replication_pad( |
| 1131 | + values_map: dict[str, Value], node: fx.Node, loc: Location |
| 1132 | +) -> Value: |
| 1133 | + """aten.replication_pad{1,2,3}d.default -> coreai.pad<replicate>.""" |
| 1134 | + return _replace_pad_with_mode(values_map, node, loc, "replicate") |
| 1135 | + |
| 1136 | + |
1112 | 1137 | def _conv_transpose( |
1113 | 1138 | x: Value, |
1114 | 1139 | weight: Value, |
@@ -3657,8 +3682,14 @@ def sdpa_maskless(q: Value, k: Value, v: Value) -> Value: |
3657 | 3682 | "prod.default": replace_prod_default, |
3658 | 3683 | "prod.dim_int": replace_prod_dim_int, |
3659 | 3684 | "reciprocal.default": replace_reciprocal, |
| 3685 | + "reflection_pad1d.default": replace_reflection_pad, |
| 3686 | + "reflection_pad2d.default": replace_reflection_pad, |
| 3687 | + "reflection_pad3d.default": replace_reflection_pad, |
3660 | 3688 | "relu.default": replace_unary_ops, |
3661 | 3689 | "remainder.Tensor": replace_remainder, |
| 3690 | + "replication_pad1d.default": replace_replication_pad, |
| 3691 | + "replication_pad2d.default": replace_replication_pad, |
| 3692 | + "replication_pad3d.default": replace_replication_pad, |
3662 | 3693 | "round.default": replace_unary_ops, |
3663 | 3694 | "round.decimals": replace_round_decimals, |
3664 | 3695 | "round": replace_unary_ops, |
|
0 commit comments