// Copyright (c) 2023 PaddlePaddle Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include "gtest/gtest.h" #include "paddle/pir/include/dialect/shape/utils/dim_expr_util.h" namespace symbol::test { namespace { DimExpr BD(const DimExpr& lhs, const DimExpr& rhs) { return Broadcast{{lhs, rhs}}; } DimExpr MakeSymbolic() { static std::atomic cnt(0); return DimExpr{std::to_string(cnt++)}; } DimExpr MakeConstant(std::int64_t value) { return DimExpr{value}; } } // namespace TEST(DimExpr, flatten_bd) { DimExpr sym0 = MakeSymbolic(); DimExpr sym1 = MakeSymbolic(); DimExpr sym2 = MakeSymbolic(); DimExpr origin = BD(BD(sym0, sym1), sym2); DimExpr expected = Broadcast{{sym0, sym1, sym2}}; ASSERT_EQ(SimplifyDimExpr(origin), expected); } TEST(Simplify, NumberAdd) { List num_lists{DimExpr(5), Negative(5)}; DimExpr dim_expr{Add{num_lists}}; DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr); ASSERT_TRUE((simplified_dim_expr.Has())); ASSERT_EQ((simplified_dim_expr.Get()), 0); } TEST(Simplify, DoubleNegative) { DimExpr inner_expr{Negative(DimExpr{1})}; DimExpr expr{Negative(inner_expr)}; DimExpr simplified_dim_expr = SimplifyDimExpr(expr); ASSERT_TRUE((simplified_dim_expr.Has())); ASSERT_EQ((simplified_dim_expr.Get()), 1); } TEST(Simplify, UnitNegative) { DimExpr unit{Negative{DimExpr{0}}}; DimExpr simplified_dim_expr = SimplifyDimExpr(unit); ASSERT_TRUE((simplified_dim_expr.Has())); ASSERT_EQ((simplified_dim_expr.Get()), 0); } TEST(Simplify, NumberNaiveMul) { List num_lists{DimExpr(5), DimExpr(5)}; DimExpr dim_expr{Mul{num_lists}}; DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr); ASSERT_TRUE((simplified_dim_expr.Has())); ASSERT_EQ((simplified_dim_expr.Get()), 25); } TEST(Simplify, NumberNaiveDiv) { DimExpr dim_expr{Div{DimExpr(5), DimExpr(5)}}; DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr); ASSERT_TRUE((simplified_dim_expr.Has())); ASSERT_EQ((simplified_dim_expr.Get()), 1); } TEST(Simplify, NestNumberAddDiv) { DimExpr div_expr{Div{DimExpr(5), DimExpr(5)}}; List sum_lists{DimExpr(0), div_expr}; DimExpr dim_expr{Add{sum_lists}}; DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr); ASSERT_TRUE((simplified_dim_expr.Has())); ASSERT_EQ((simplified_dim_expr.Get()), 1); } TEST(Simplify, NestNumberMulAdd) { List num_lists{DimExpr(5), Negative(5)}; List product_lists{DimExpr(5), Add{num_lists}}; DimExpr dim_expr{Mul{product_lists}}; DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr); ASSERT_TRUE((simplified_dim_expr.Has())); ASSERT_EQ((simplified_dim_expr.Get()), 0); } TEST(Simplify, SymbolicMul) { DimExpr sym = MakeSymbolic(); List num_lists{DimExpr(1), sym}; DimExpr dim_expr{Mul{num_lists}}; DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr); ASSERT_TRUE((simplified_dim_expr.Has())); ASSERT_TRUE((simplified_dim_expr == sym)); } TEST(Simplify, SymbolicDiv) { DimExpr sym = MakeSymbolic(); List num_lists{sym, DimExpr(1)}; DimExpr dim_expr{Mul{num_lists}}; DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr); ASSERT_TRUE((simplified_dim_expr.Has())); ASSERT_TRUE((simplified_dim_expr == sym)); } TEST(Simplify, SymbolicMulUnit) { DimExpr sym = MakeSymbolic(); List num_lists{sym, DimExpr(1)}; DimExpr dim_expr{Mul{num_lists}}; DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr); ASSERT_TRUE((simplified_dim_expr == sym)); } TEST(Simplify, SymbolicDivUnit) { DimExpr sym = MakeSymbolic(); DimExpr dim_expr{ Div{Mul{List{DimExpr(2), sym}}, sym}}; DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr); ASSERT_TRUE((simplified_dim_expr.Has())); ASSERT_EQ((simplified_dim_expr.Get()), 2); } TEST(Simplify, NestSymbolicMulAddUnit) { DimExpr sym = MakeSymbolic(); List sum_lists{DimExpr(6), Negative{DimExpr(5)}}; List product_lists = List{Add{sum_lists}, sym}; DimExpr dim_expr{Mul{product_lists}}; DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr); ASSERT_TRUE((simplified_dim_expr.Has())); ASSERT_TRUE((simplified_dim_expr == sym)); } TEST(Simplify, NestSymbolicDivAddUnit) { DimExpr sym = MakeSymbolic(); List sum_lists{DimExpr(6), Negative{DimExpr(5)}}; DimExpr dim_expr{Div{sym, Add{sum_lists}}}; DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr); ASSERT_TRUE((simplified_dim_expr.Has())); ASSERT_TRUE((simplified_dim_expr == sym)); } TEST(Simplify, ConstantMaxMin) { List max_lists{DimExpr(4), DimExpr(6)}; DimExpr dim_expr1{Max{max_lists}}; DimExpr simplified_dim_expr1 = SimplifyDimExpr(dim_expr1); ASSERT_TRUE((simplified_dim_expr1.Has())); ASSERT_EQ((simplified_dim_expr1.Get()), 6); List min_lists{DimExpr(2), DimExpr(3)}; DimExpr dim_expr2{Min{min_lists}}; DimExpr simplified_dim_expr2 = SimplifyDimExpr(dim_expr2); ASSERT_TRUE((simplified_dim_expr2.Has())); ASSERT_EQ((simplified_dim_expr2.Get()), 2); } TEST(Simplify, SimplifyBc) { // Broadcast(S0, Add(S0, -1)) => S0 DimExpr S0{"S0"}; DimExpr add{Add{{S0, Negative{1}}}}; DimExpr bc{Broadcast{{S0, add}}}; ASSERT_TRUE((SimplifyDimExpr(bc) != Add{{S0, -1}})); // TODO(ooooo): improve the simplify ability DimExpr now_accept{Broadcast{{Add{{S0, -1}}, S0}}}; ASSERT_TRUE((SimplifyDimExpr(bc) == now_accept)); } TEST(Simplify, FoldBroadcast) { DimExpr sym0{"S0"}; DimExpr sym1{"S1"}; DimExpr mul{Mul{{sym0, sym1}}}; DimExpr broadcast0{Broadcast{{mul, sym0}}}; DimExpr broadcast1{Broadcast{{sym1, mul}}}; DimExpr simplify_broadcast0 = SimplifyDimExpr(broadcast0); DimExpr simplify_broadcast1 = SimplifyDimExpr(broadcast1); DimExpr add{Add{{sym0, sym1}}}; DimExpr broadcast2{Broadcast{{add, sym0}}}; DimExpr broadcast3{Broadcast{{sym1, add}}}; DimExpr simplify_broadcast2 = SimplifyDimExpr(broadcast2); DimExpr simplify_broadcast3 = SimplifyDimExpr(broadcast3); ASSERT_TRUE(simplify_broadcast0 == mul); ASSERT_TRUE(simplify_broadcast1 == mul); ASSERT_TRUE(simplify_broadcast2 == add); ASSERT_TRUE(simplify_broadcast3 == add); } TEST(Simplify, FoldRedundantBroadcast) { DimExpr S0{"S0"}; DimExpr S1{"S1"}; DimExpr bc{Broadcast{{S0, S0, S1, S1}}}; DimExpr simplify_bc = SimplifyDimExpr(bc); ASSERT_TRUE((simplify_bc == Broadcast{{S0, S1}})); } TEST(Simplify, SimplifyDoubleNegForMulAndDiv) { // Negative(Mul(S0, Negative(1))) => S0 DimExpr S0{"S0"}; DimExpr mul{Mul{{S0, Negative{DimExpr(1)}}}}; DimExpr neg_mul{Negative{mul}}; DimExpr simplify_neg_mul = SimplifyDimExpr(neg_mul); ASSERT_TRUE((simplify_neg_mul == S0)); // Negative(Div(S0, Negative(1))) => S0 DimExpr div{Div{S0, Negative{DimExpr(1)}}}; DimExpr neg_div{Negative{div}}; DimExpr simplify_neg_div = SimplifyDimExpr(neg_div); ASSERT_TRUE((simplify_neg_div == S0)); } TEST(Simplify, Case1) { // Div(Mul(Div(Mul(Broadcast(S11, S8), Broadcast(S10, S13, S4, S7), // Broadcast(S12, S3, S6, S9)), S0)), 16), 49) DimExpr S11{"S11"}; DimExpr S8{"S8"}; DimExpr mul_op1 = Broadcast{{S11, S8}}; DimExpr S10{"S10"}; DimExpr S13{"S13"}; DimExpr S4{"S4"}; DimExpr S7{"S7"}; DimExpr mul_op2 = Broadcast{{S10, S13, S4, S7}}; DimExpr S12{"S12"}; DimExpr S3{"S3"}; DimExpr S6{"S6"}; DimExpr S9{"S9"}; DimExpr mul_op3 = Broadcast{{S12, S3, S6, S9}}; DimExpr S0{"S0"}; DimExpr mul_op4 = Div{Mul{List{mul_op1, mul_op2, mul_op3}}, S0}; DimExpr dim_expr = Div{ Mul{List{mul_op4, DimExpr{16}}}, DimExpr(49)}; ASSERT_TRUE((SimplifyDimExpr(dim_expr)) == dim_expr); } TEST(Simplify, Case2) { // Div(Mul(S2, S3, 8, 7, 7), Mul( Div(S0, 7), Div(S1, 7), 8, 7, 7,1, 2)) DimExpr S2{"S2"}; DimExpr S3{"S3"}; DimExpr mul_op1 = Mul{List{S2, S3, DimExpr(8), DimExpr(7), DimExpr(7)}}; DimExpr S0{"S0"}; DimExpr S1{"S1"}; DimExpr mul_op2 = Mul{List{Div{S0, DimExpr(7)}, Div{S1, DimExpr(7)}, DimExpr(8), DimExpr(7), DimExpr(7), DimExpr(1), DimExpr(2)}}; DimExpr dim_expr{Div{mul_op1, mul_op2}}; DimExpr expected = Div{ Mul{List{S2, S3}}, Mul{List{ Div{S0, DimExpr(7)}, Div{S1, DimExpr(7)}, 2}}}; ASSERT_TRUE((SimplifyDimExpr(dim_expr)) == expected); } TEST(Simplify, Case3) { DimExpr S3{"S3"}; DimExpr S4{"S4"}; DimExpr S5{"S5"}; DimExpr S7{"S7"}; DimExpr S8{"S8"}; DimExpr dim_expr = Mul{List{ Div{Mul{List{S3, S4, S5}}, Mul{List{S7, S8}}}, Div{Mul{List{S3, S4, S5}}, Div{Mul{List{S3, S4, S5}}, Mul{List{S7, S8}}}}}}; ASSERT_TRUE((SimplifyDimExpr(dim_expr) == dim_expr)); // Need to simplify } } // namespace symbol::test