@@ -1161,6 +1161,139 @@ def forward(self, x: Tensor) -> Tensor:
11611161 )
11621162
11631163
1164+ class TestAtan2IR :
1165+ def test_static (self ) -> None :
1166+ class Atan2Model (nn .Module ):
1167+ def forward (self , y : Tensor , x : Tensor ) -> Tensor :
1168+ return torch .atan2 (y , x )
1169+
1170+ ir = get_ir (Atan2Model ().eval (), y = torch .rand (2 , 3 ), x = torch .rand (2 , 3 ))
1171+ filecheck_pattern (
1172+ ir ,
1173+ check_file = """
1174+ // CHECK-LABEL: module {
1175+ // CHECK-NEXT: coreai.graph @main(%[[Y:.*]]: tensor<2x3xf32> {coreai.name = "y"}, %[[X:.*]]: tensor<2x3xf32> {coreai.name = "x"}) -> (tensor<2x3xf32> {coreai.name = "{{.*}}"}) attributes {__coreai_pure__} {
1176+ // CHECK: %[[NEG_INF:.*]] = coreai.constant dense<0xFF800000> : tensor<f32>
1177+ // CHECK: %[[POS_INF:.*]] = coreai.constant dense<0x7F800000> : tensor<f32>
1178+ // CHECK: %[[ZERO:.*]] = coreai.constant dense<0.000000e+00> : tensor<f32>
1179+ // CHECK: %[[ONE:.*]] = coreai.constant dense<1.000000e+00> : tensor<f32>
1180+ // CHECK: %[[PI:.*]] = coreai.constant dense<3.14159274> : tensor<f32>
1181+ // CHECK: %[[NEG_PI:.*]] = coreai.constant dense<-3.14159274> : tensor<f32>
1182+ // CHECK: %[[HPI:.*]] = coreai.constant dense<1.57079637> : tensor<f32>
1183+ // CHECK: %[[NHPI:.*]] = coreai.constant dense<-1.57079637> : tensor<f32>
1184+ // CHECK: %[[QPI:.*]] = coreai.constant dense<0.785398185> : tensor<f32>
1185+ // CHECK: %[[NQPI:.*]] = coreai.constant dense<-0.785398185> : tensor<f32>
1186+ // CHECK: %[[THREEQPI:.*]] = coreai.constant dense<2.3561945> : tensor<f32>
1187+ // CHECK: %[[NTHREEQPI:.*]] = coreai.constant dense<-2.3561945> : tensor<f32>
1188+ // CHECK: %[[Y_IS_ZERO:.*]] = coreai.decomposable.broadcasting_equal %[[Y]], %[[ZERO]]
1189+ // CHECK: %[[X_IS_ZERO:.*]] = coreai.decomposable.broadcasting_equal %[[X]], %[[ZERO]]
1190+ // CHECK: %[[Y_NEG_STRICT:.*]] = coreai.decomposable.broadcasting_greater %[[ZERO]], %[[Y]]
1191+ // CHECK: %[[RECIP_Y:.*]] = coreai.decomposable.broadcasting_divide %[[ONE]], %[[Y]]
1192+ // CHECK: %[[RECIP_Y_NEG:.*]] = coreai.decomposable.broadcasting_greater %[[ZERO]], %[[RECIP_Y]]
1193+ // CHECK: %[[Y_ZERO_NEG:.*]] = coreai.decomposable.broadcasting_and %[[Y_IS_ZERO]], %[[RECIP_Y_NEG]]
1194+ // CHECK: %[[Y_NEG:.*]] = coreai.decomposable.broadcasting_or %[[Y_NEG_STRICT]], %[[Y_ZERO_NEG]]
1195+ // CHECK: %[[X_NEG_STRICT:.*]] = coreai.decomposable.broadcasting_greater %[[ZERO]], %[[X]]
1196+ // CHECK: %[[RECIP_X:.*]] = coreai.decomposable.broadcasting_divide %[[ONE]], %[[X]]
1197+ // CHECK: %[[RECIP_X_NEG:.*]] = coreai.decomposable.broadcasting_greater %[[ZERO]], %[[RECIP_X]]
1198+ // CHECK: %[[X_ZERO_NEG:.*]] = coreai.decomposable.broadcasting_and %[[X_IS_ZERO]], %[[RECIP_X_NEG]]
1199+ // CHECK: %[[X_NEG:.*]] = coreai.decomposable.broadcasting_or %[[X_NEG_STRICT]], %[[X_ZERO_NEG]]
1200+ // CHECK: %[[X_IS_POS_INF:.*]] = coreai.decomposable.broadcasting_equal %[[X]], %[[POS_INF]]
1201+ // CHECK: %[[X_IS_NEG_INF:.*]] = coreai.decomposable.broadcasting_equal %[[X]], %[[NEG_INF]]
1202+ // CHECK: %[[X_IS_INF:.*]] = coreai.decomposable.broadcasting_or %[[X_IS_POS_INF]], %[[X_IS_NEG_INF]]
1203+ // CHECK: %[[Y_IS_POS_INF:.*]] = coreai.decomposable.broadcasting_equal %[[Y]], %[[POS_INF]]
1204+ // CHECK: %[[Y_IS_NEG_INF:.*]] = coreai.decomposable.broadcasting_equal %[[Y]], %[[NEG_INF]]
1205+ // CHECK: %[[Y_IS_INF:.*]] = coreai.decomposable.broadcasting_or %[[Y_IS_POS_INF]], %[[Y_IS_NEG_INF]]
1206+ // CHECK: %[[BOTH_INF:.*]] = coreai.decomposable.broadcasting_and %[[X_IS_INF]], %[[Y_IS_INF]]
1207+ // CHECK: %[[BASE:.*]] = coreai.atan
1208+ // CHECK: %[[RESULT:.*]] = coreai.decomposable.broadcasting_where %[[BOTH_INF]],
1209+ // CHECK-NEXT: coreai.output %[[RESULT]] : tensor<2x3xf32>
1210+ // CHECK-NEXT: }
1211+ // CHECK-NEXT: }
1212+ """ ,
1213+ )
1214+
1215+ def test_dynamic (self ) -> None :
1216+ class Atan2Model (nn .Module ):
1217+ def forward (self , y : Tensor , x : Tensor ) -> Tensor :
1218+ return torch .atan2 (y , x )
1219+
1220+ y = torch .rand (2 , 3 )
1221+ x = torch .rand (2 , 3 )
1222+ ir = get_ir (
1223+ Atan2Model ().eval (),
1224+ y = y ,
1225+ x = x ,
1226+ dynamic_shapes = {"y" : _all_dims_dynamic (y ), "x" : _all_dims_dynamic (x )},
1227+ )
1228+ filecheck_pattern (
1229+ ir ,
1230+ check_file = """
1231+ // CHECK-LABEL: module {
1232+ // CHECK-NEXT: coreai.graph @main(%[[Y:.*]]: tensor<?x?xf32> {coreai.name = "y"}, %[[X:.*]]: tensor<?x?xf32> {coreai.name = "x"}) -> (tensor<?x?xf32> {coreai.name = "{{.*}}"}) attributes {__coreai_pure__} {
1233+ // CHECK: %[[NEG_INF:.*]] = coreai.constant dense<0xFF800000> : tensor<f32>
1234+ // CHECK: %[[POS_INF:.*]] = coreai.constant dense<0x7F800000> : tensor<f32>
1235+ // CHECK: %[[ZERO:.*]] = coreai.constant dense<0.000000e+00> : tensor<f32>
1236+ // CHECK: %[[ONE:.*]] = coreai.constant dense<1.000000e+00> : tensor<f32>
1237+ // CHECK: %[[PI:.*]] = coreai.constant dense<3.14159274> : tensor<f32>
1238+ // CHECK: %[[NEG_PI:.*]] = coreai.constant dense<-3.14159274> : tensor<f32>
1239+ // CHECK: %[[HPI:.*]] = coreai.constant dense<1.57079637> : tensor<f32>
1240+ // CHECK: %[[NHPI:.*]] = coreai.constant dense<-1.57079637> : tensor<f32>
1241+ // CHECK: %[[QPI:.*]] = coreai.constant dense<0.785398185> : tensor<f32>
1242+ // CHECK: %[[NQPI:.*]] = coreai.constant dense<-0.785398185> : tensor<f32>
1243+ // CHECK: %[[THREEQPI:.*]] = coreai.constant dense<2.3561945> : tensor<f32>
1244+ // CHECK: %[[NTHREEQPI:.*]] = coreai.constant dense<-2.3561945> : tensor<f32>
1245+ // CHECK: %[[Y_IS_ZERO:.*]] = coreai.decomposable.broadcasting_equal %[[Y]], %[[ZERO]]
1246+ // CHECK: %[[X_IS_ZERO:.*]] = coreai.decomposable.broadcasting_equal %[[X]], %[[ZERO]]
1247+ // CHECK: %[[Y_NEG_STRICT:.*]] = coreai.decomposable.broadcasting_greater %[[ZERO]], %[[Y]]
1248+ // CHECK: %[[RECIP_Y:.*]] = coreai.decomposable.broadcasting_divide %[[ONE]], %[[Y]]
1249+ // CHECK: %[[RECIP_Y_NEG:.*]] = coreai.decomposable.broadcasting_greater %[[ZERO]], %[[RECIP_Y]]
1250+ // CHECK: %[[Y_ZERO_NEG:.*]] = coreai.decomposable.broadcasting_and %[[Y_IS_ZERO]], %[[RECIP_Y_NEG]]
1251+ // CHECK: %[[Y_NEG:.*]] = coreai.decomposable.broadcasting_or %[[Y_NEG_STRICT]], %[[Y_ZERO_NEG]]
1252+ // CHECK: %[[X_NEG_STRICT:.*]] = coreai.decomposable.broadcasting_greater %[[ZERO]], %[[X]]
1253+ // CHECK: %[[RECIP_X:.*]] = coreai.decomposable.broadcasting_divide %[[ONE]], %[[X]]
1254+ // CHECK: %[[RECIP_X_NEG:.*]] = coreai.decomposable.broadcasting_greater %[[ZERO]], %[[RECIP_X]]
1255+ // CHECK: %[[X_ZERO_NEG:.*]] = coreai.decomposable.broadcasting_and %[[X_IS_ZERO]], %[[RECIP_X_NEG]]
1256+ // CHECK: %[[X_NEG:.*]] = coreai.decomposable.broadcasting_or %[[X_NEG_STRICT]], %[[X_ZERO_NEG]]
1257+ // CHECK: %[[X_IS_POS_INF:.*]] = coreai.decomposable.broadcasting_equal %[[X]], %[[POS_INF]]
1258+ // CHECK: %[[X_IS_NEG_INF:.*]] = coreai.decomposable.broadcasting_equal %[[X]], %[[NEG_INF]]
1259+ // CHECK: %[[X_IS_INF:.*]] = coreai.decomposable.broadcasting_or %[[X_IS_POS_INF]], %[[X_IS_NEG_INF]]
1260+ // CHECK: %[[Y_IS_POS_INF:.*]] = coreai.decomposable.broadcasting_equal %[[Y]], %[[POS_INF]]
1261+ // CHECK: %[[Y_IS_NEG_INF:.*]] = coreai.decomposable.broadcasting_equal %[[Y]], %[[NEG_INF]]
1262+ // CHECK: %[[Y_IS_INF:.*]] = coreai.decomposable.broadcasting_or %[[Y_IS_POS_INF]], %[[Y_IS_NEG_INF]]
1263+ // CHECK: %[[BOTH_INF:.*]] = coreai.decomposable.broadcasting_and %[[X_IS_INF]], %[[Y_IS_INF]]
1264+ // CHECK: %[[BASE:.*]] = coreai.atan
1265+ // CHECK: %[[RESULT:.*]] = coreai.decomposable.broadcasting_where %[[BOTH_INF]],
1266+ // CHECK-NEXT: coreai.output %[[RESULT]] : tensor<?x?xf32>
1267+ // CHECK-NEXT: }
1268+ // CHECK-NEXT: }
1269+ """ ,
1270+ )
1271+
1272+ def test_1d (self ) -> None :
1273+ class Atan2Model (nn .Module ):
1274+ def forward (self , y : Tensor , x : Tensor ) -> Tensor :
1275+ return torch .atan2 (y , x )
1276+
1277+ ir = get_ir (Atan2Model ().eval (), y = torch .rand (4 ), x = torch .rand (4 ))
1278+ filecheck_pattern (
1279+ ir ,
1280+ check_file = """
1281+ // CHECK-LABEL: module {
1282+ // CHECK-NEXT: coreai.graph @main(%[[Y:.*]]: tensor<4xf32> {coreai.name = "y"}, %[[X:.*]]: tensor<4xf32> {coreai.name = "x"}) -> (tensor<4xf32> {coreai.name = "{{.*}}"}) attributes {__coreai_pure__} {
1283+ // CHECK: %[[ZERO:.*]] = coreai.constant dense<0.000000e+00> : tensor<f32>
1284+ // CHECK: %[[ONE:.*]] = coreai.constant dense<1.000000e+00> : tensor<f32>
1285+ // CHECK: %[[Y_NEG:.*]] = coreai.decomposable.broadcasting_or
1286+ // CHECK: %[[X_NEG:.*]] = coreai.decomposable.broadcasting_or
1287+ // CHECK: %[[BOTH_INF:.*]] = coreai.decomposable.broadcasting_and
1288+ // CHECK: %[[BASE:.*]] = coreai.atan
1289+ // CHECK: %[[RESULT:.*]] = coreai.decomposable.broadcasting_where %[[BOTH_INF]],
1290+ // CHECK-NEXT: coreai.output %[[RESULT]] : tensor<4xf32>
1291+ // CHECK-NEXT: }
1292+ // CHECK-NEXT: }
1293+ """ ,
1294+ )
1295+
1296+
11641297class TestAvgPool2dIR :
11651298 def test_static (self ) -> None :
11661299 class AvgPool2dModel (nn .Module ):
0 commit comments