@@ -1132,6 +1132,123 @@ def forward(self, x: Tensor) -> Tensor:
11321132 )
11331133
11341134
1135+ class TestAtan2IR :
1136+ def test_static (self ) -> None :
1137+ class Atan2Model (nn .Module ):
1138+ def forward (self , y : Tensor , x : Tensor ) -> Tensor :
1139+ return torch .atan2 (y , x )
1140+
1141+ ir = get_ir (Atan2Model ().eval (), y = torch .rand (2 , 3 ), x = torch .rand (2 , 3 ))
1142+ filecheck_pattern (
1143+ ir ,
1144+ check_file = """
1145+ // CHECK-LABEL: module {
1146+ // CHECK-NEXT: coreai.graph @main(%[[ARG0:.*]]: tensor<2x3xf32> {coreai.name = "y"}, %[[ARG1:.*]]: tensor<2x3xf32> {coreai.name = "x"}) -> (tensor<2x3xf32> {coreai.name = "{{.*}}"}) attributes {__coreai_pure__} {
1147+ // CHECK-NEXT: %[[C1:.*]] = coreai.constant dense<1.000000e+00> : tensor<f32>
1148+ // CHECK-NEXT: %[[C0:.*]] = coreai.constant dense<0.000000e+00> : tensor<f32>
1149+ // CHECK-NEXT: %[[PI:.*]] = coreai.constant dense<3.14159274> : tensor<f32>
1150+ // CHECK-NEXT: %[[HPI:.*]] = coreai.constant dense<1.57079637> : tensor<f32>
1151+ // CHECK-NEXT: %[[NHPI:.*]] = coreai.constant dense<-1.57079637> : tensor<f32>
1152+ // CHECK-NEXT: %[[X_IS_ZERO:.*]] = coreai.decomposable.broadcasting_equal %[[ARG1]], %[[C0]] : (tensor<2x3xf32>, tensor<f32>) -> tensor<2x3xi1>
1153+ // CHECK-NEXT: %[[X_SAFE:.*]] = coreai.decomposable.broadcasting_where %[[X_IS_ZERO]], %[[C1]], %[[ARG1]] : (tensor<2x3xi1>, tensor<f32>, tensor<2x3xf32>) -> tensor<2x3xf32>
1154+ // CHECK-NEXT: %[[RATIO:.*]] = coreai.decomposable.broadcasting_divide %[[ARG0]], %[[X_SAFE]] : (tensor<2x3xf32>, tensor<2x3xf32>) -> tensor<2x3xf32>
1155+ // CHECK-NEXT: %[[BASE:.*]] = coreai.atan %[[RATIO]] : tensor<2x3xf32> -> tensor<2x3xf32>
1156+ // CHECK-NEXT: %[[X_NEG:.*]] = coreai.decomposable.broadcasting_greater %[[C0]], %[[ARG1]] : (tensor<f32>, tensor<2x3xf32>) -> tensor<2x3xi1>
1157+ // CHECK-NEXT: %[[Y_NEG:.*]] = coreai.decomposable.broadcasting_greater %[[C0]], %[[ARG0]] : (tensor<f32>, tensor<2x3xf32>) -> tensor<2x3xi1>
1158+ // CHECK-NEXT: %[[Y_POS:.*]] = coreai.decomposable.broadcasting_greater %[[ARG0]], %[[C0]] : (tensor<2x3xf32>, tensor<f32>) -> tensor<2x3xi1>
1159+ // CHECK-NEXT: %[[BASE_MINUS_PI:.*]] = coreai.decomposable.broadcasting_sub %[[BASE]], %[[PI]] : (tensor<2x3xf32>, tensor<f32>) -> tensor<2x3xf32>
1160+ // CHECK-NEXT: %[[BASE_PLUS_PI:.*]] = coreai.decomposable.broadcasting_add %[[BASE]], %[[PI]] : (tensor<2x3xf32>, tensor<f32>) -> tensor<2x3xf32>
1161+ // CHECK-NEXT: %[[CORRECTION:.*]] = coreai.decomposable.broadcasting_where %[[Y_NEG]], %[[BASE_MINUS_PI]], %[[BASE_PLUS_PI]] : (tensor<2x3xi1>, tensor<2x3xf32>, tensor<2x3xf32>) -> tensor<2x3xf32>
1162+ // CHECK-NEXT: %[[NONZERO:.*]] = coreai.decomposable.broadcasting_where %[[X_NEG]], %[[CORRECTION]], %[[BASE]] : (tensor<2x3xi1>, tensor<2x3xf32>, tensor<2x3xf32>) -> tensor<2x3xf32>
1163+ // CHECK-NEXT: %[[ZERO_NEG:.*]] = coreai.decomposable.broadcasting_where %[[Y_NEG]], %[[NHPI]], %[[C0]] : (tensor<2x3xi1>, tensor<f32>, tensor<f32>) -> tensor<2x3xf32>
1164+ // CHECK-NEXT: %[[ZERO_RES:.*]] = coreai.decomposable.broadcasting_where %[[Y_POS]], %[[HPI]], %[[ZERO_NEG]] : (tensor<2x3xi1>, tensor<f32>, tensor<2x3xf32>) -> tensor<2x3xf32>
1165+ // CHECK-NEXT: %[[RESULT:.*]] = coreai.decomposable.broadcasting_where %[[X_IS_ZERO]], %[[ZERO_RES]], %[[NONZERO]] : (tensor<2x3xi1>, tensor<2x3xf32>, tensor<2x3xf32>) -> tensor<2x3xf32>
1166+ // CHECK-NEXT: coreai.output %[[RESULT]] : tensor<2x3xf32>
1167+ // CHECK-NEXT: }
1168+ // CHECK-NEXT: }
1169+ """ ,
1170+ )
1171+
1172+ def test_dynamic (self ) -> None :
1173+ class Atan2Model (nn .Module ):
1174+ def forward (self , y : Tensor , x : Tensor ) -> Tensor :
1175+ return torch .atan2 (y , x )
1176+
1177+ y = torch .rand (2 , 3 )
1178+ x = torch .rand (2 , 3 )
1179+ ir = get_ir (
1180+ Atan2Model ().eval (),
1181+ y = y ,
1182+ x = x ,
1183+ dynamic_shapes = {"y" : _all_dims_dynamic (y ), "x" : _all_dims_dynamic (x )},
1184+ )
1185+ filecheck_pattern (
1186+ ir ,
1187+ check_file = """
1188+ // CHECK-LABEL: module {
1189+ // CHECK-NEXT: coreai.graph @main(%[[ARG0:.*]]: tensor<?x?xf32> {coreai.name = "y"}, %[[ARG1:.*]]: tensor<?x?xf32> {coreai.name = "x"}) -> (tensor<?x?xf32> {coreai.name = "{{.*}}"}) attributes {__coreai_pure__} {
1190+ // CHECK-NEXT: %[[C1:.*]] = coreai.constant dense<1.000000e+00> : tensor<f32>
1191+ // CHECK-NEXT: %[[C0:.*]] = coreai.constant dense<0.000000e+00> : tensor<f32>
1192+ // CHECK-NEXT: %[[PI:.*]] = coreai.constant dense<3.14159274> : tensor<f32>
1193+ // CHECK-NEXT: %[[HPI:.*]] = coreai.constant dense<1.57079637> : tensor<f32>
1194+ // CHECK-NEXT: %[[NHPI:.*]] = coreai.constant dense<-1.57079637> : tensor<f32>
1195+ // CHECK-NEXT: %[[X_IS_ZERO:.*]] = coreai.decomposable.broadcasting_equal %[[ARG1]], %[[C0]] : (tensor<?x?xf32>, tensor<f32>) -> tensor<?x?xi1>
1196+ // CHECK-NEXT: %[[X_SAFE:.*]] = coreai.decomposable.broadcasting_where %[[X_IS_ZERO]], %[[C1]], %[[ARG1]] : (tensor<?x?xi1>, tensor<f32>, tensor<?x?xf32>) -> tensor<?x?xf32>
1197+ // CHECK-NEXT: %[[RATIO:.*]] = coreai.decomposable.broadcasting_divide %[[ARG0]], %[[X_SAFE]] : (tensor<?x?xf32>, tensor<?x?xf32>) -> tensor<?x?xf32>
1198+ // CHECK-NEXT: %[[BASE:.*]] = coreai.atan %[[RATIO]] : tensor<?x?xf32> -> tensor<?x?xf32>
1199+ // CHECK-NEXT: %[[X_NEG:.*]] = coreai.decomposable.broadcasting_greater %[[C0]], %[[ARG1]] : (tensor<f32>, tensor<?x?xf32>) -> tensor<?x?xi1>
1200+ // CHECK-NEXT: %[[Y_NEG:.*]] = coreai.decomposable.broadcasting_greater %[[C0]], %[[ARG0]] : (tensor<f32>, tensor<?x?xf32>) -> tensor<?x?xi1>
1201+ // CHECK-NEXT: %[[Y_POS:.*]] = coreai.decomposable.broadcasting_greater %[[ARG0]], %[[C0]] : (tensor<?x?xf32>, tensor<f32>) -> tensor<?x?xi1>
1202+ // CHECK-NEXT: %[[BASE_MINUS_PI:.*]] = coreai.decomposable.broadcasting_sub %[[BASE]], %[[PI]] : (tensor<?x?xf32>, tensor<f32>) -> tensor<?x?xf32>
1203+ // CHECK-NEXT: %[[BASE_PLUS_PI:.*]] = coreai.decomposable.broadcasting_add %[[BASE]], %[[PI]] : (tensor<?x?xf32>, tensor<f32>) -> tensor<?x?xf32>
1204+ // CHECK-NEXT: %[[CORRECTION:.*]] = coreai.decomposable.broadcasting_where %[[Y_NEG]], %[[BASE_MINUS_PI]], %[[BASE_PLUS_PI]] : (tensor<?x?xi1>, tensor<?x?xf32>, tensor<?x?xf32>) -> tensor<?x?xf32>
1205+ // CHECK-NEXT: %[[NONZERO:.*]] = coreai.decomposable.broadcasting_where %[[X_NEG]], %[[CORRECTION]], %[[BASE]] : (tensor<?x?xi1>, tensor<?x?xf32>, tensor<?x?xf32>) -> tensor<?x?xf32>
1206+ // CHECK-NEXT: %[[ZERO_NEG:.*]] = coreai.decomposable.broadcasting_where %[[Y_NEG]], %[[NHPI]], %[[C0]] : (tensor<?x?xi1>, tensor<f32>, tensor<f32>) -> tensor<?x?xf32>
1207+ // CHECK-NEXT: %[[ZERO_RES:.*]] = coreai.decomposable.broadcasting_where %[[Y_POS]], %[[HPI]], %[[ZERO_NEG]] : (tensor<?x?xi1>, tensor<f32>, tensor<?x?xf32>) -> tensor<?x?xf32>
1208+ // CHECK-NEXT: %[[RESULT:.*]] = coreai.decomposable.broadcasting_where %[[X_IS_ZERO]], %[[ZERO_RES]], %[[NONZERO]] : (tensor<?x?xi1>, tensor<?x?xf32>, tensor<?x?xf32>) -> tensor<?x?xf32>
1209+ // CHECK-NEXT: coreai.output %[[RESULT]] : tensor<?x?xf32>
1210+ // CHECK-NEXT: }
1211+ // CHECK-NEXT: }
1212+ """ ,
1213+ )
1214+
1215+ def test_1d (self ) -> None :
1216+ class Atan2Model (nn .Module ):
1217+ def forward (self , y : Tensor , x : Tensor ) -> Tensor :
1218+ return torch .atan2 (y , x )
1219+
1220+ ir = get_ir (Atan2Model ().eval (), y = torch .rand (4 ), x = torch .rand (4 ))
1221+ filecheck_pattern (
1222+ ir ,
1223+ check_file = """
1224+ // CHECK-LABEL: module {
1225+ // CHECK-NEXT: coreai.graph @main(%[[ARG0:.*]]: tensor<4xf32> {coreai.name = "y"}, %[[ARG1:.*]]: tensor<4xf32> {coreai.name = "x"}) -> (tensor<4xf32> {coreai.name = "{{.*}}"}) attributes {__coreai_pure__} {
1226+ // CHECK-NEXT: %[[C1:.*]] = coreai.constant dense<1.000000e+00> : tensor<f32>
1227+ // CHECK-NEXT: %[[C0:.*]] = coreai.constant dense<0.000000e+00> : tensor<f32>
1228+ // CHECK-NEXT: %[[PI:.*]] = coreai.constant dense<3.14159274> : tensor<f32>
1229+ // CHECK-NEXT: %[[HPI:.*]] = coreai.constant dense<1.57079637> : tensor<f32>
1230+ // CHECK-NEXT: %[[NHPI:.*]] = coreai.constant dense<-1.57079637> : tensor<f32>
1231+ // CHECK-NEXT: %[[X_IS_ZERO:.*]] = coreai.decomposable.broadcasting_equal %[[ARG1]], %[[C0]] : (tensor<4xf32>, tensor<f32>) -> tensor<4xi1>
1232+ // CHECK-NEXT: %[[X_SAFE:.*]] = coreai.decomposable.broadcasting_where %[[X_IS_ZERO]], %[[C1]], %[[ARG1]] : (tensor<4xi1>, tensor<f32>, tensor<4xf32>) -> tensor<4xf32>
1233+ // CHECK-NEXT: %[[RATIO:.*]] = coreai.decomposable.broadcasting_divide %[[ARG0]], %[[X_SAFE]] : (tensor<4xf32>, tensor<4xf32>) -> tensor<4xf32>
1234+ // CHECK-NEXT: %[[BASE:.*]] = coreai.atan %[[RATIO]] : tensor<4xf32> -> tensor<4xf32>
1235+ // CHECK-NEXT: %[[X_NEG:.*]] = coreai.decomposable.broadcasting_greater %[[C0]], %[[ARG1]] : (tensor<f32>, tensor<4xf32>) -> tensor<4xi1>
1236+ // CHECK-NEXT: %[[Y_NEG:.*]] = coreai.decomposable.broadcasting_greater %[[C0]], %[[ARG0]] : (tensor<f32>, tensor<4xf32>) -> tensor<4xi1>
1237+ // CHECK-NEXT: %[[Y_POS:.*]] = coreai.decomposable.broadcasting_greater %[[ARG0]], %[[C0]] : (tensor<4xf32>, tensor<f32>) -> tensor<4xi1>
1238+ // CHECK-NEXT: %[[BASE_MINUS_PI:.*]] = coreai.decomposable.broadcasting_sub %[[BASE]], %[[PI]] : (tensor<4xf32>, tensor<f32>) -> tensor<4xf32>
1239+ // CHECK-NEXT: %[[BASE_PLUS_PI:.*]] = coreai.decomposable.broadcasting_add %[[BASE]], %[[PI]] : (tensor<4xf32>, tensor<f32>) -> tensor<4xf32>
1240+ // CHECK-NEXT: %[[CORRECTION:.*]] = coreai.decomposable.broadcasting_where %[[Y_NEG]], %[[BASE_MINUS_PI]], %[[BASE_PLUS_PI]] : (tensor<4xi1>, tensor<4xf32>, tensor<4xf32>) -> tensor<4xf32>
1241+ // CHECK-NEXT: %[[NONZERO:.*]] = coreai.decomposable.broadcasting_where %[[X_NEG]], %[[CORRECTION]], %[[BASE]] : (tensor<4xi1>, tensor<4xf32>, tensor<4xf32>) -> tensor<4xf32>
1242+ // CHECK-NEXT: %[[ZERO_NEG:.*]] = coreai.decomposable.broadcasting_where %[[Y_NEG]], %[[NHPI]], %[[C0]] : (tensor<4xi1>, tensor<f32>, tensor<f32>) -> tensor<4xf32>
1243+ // CHECK-NEXT: %[[ZERO_RES:.*]] = coreai.decomposable.broadcasting_where %[[Y_POS]], %[[HPI]], %[[ZERO_NEG]] : (tensor<4xi1>, tensor<f32>, tensor<4xf32>) -> tensor<4xf32>
1244+ // CHECK-NEXT: %[[RESULT:.*]] = coreai.decomposable.broadcasting_where %[[X_IS_ZERO]], %[[ZERO_RES]], %[[NONZERO]] : (tensor<4xi1>, tensor<4xf32>, tensor<4xf32>) -> tensor<4xf32>
1245+ // CHECK-NEXT: coreai.output %[[RESULT]] : tensor<4xf32>
1246+ // CHECK-NEXT: }
1247+ // CHECK-NEXT: }
1248+ """ ,
1249+ )
1250+
1251+
11351252class TestAvgPool2dIR :
11361253 def test_static (self ) -> None :
11371254 class AvgPool2dModel (nn .Module ):
0 commit comments