Files
paddlepaddle--paddle/test/cpp/pir/shape_dialect/simplify_dim_expr_test.cc
T
2026-07-13 12:40:42 +08:00

309 lines
10 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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 <atomic>
#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<DimExpr>{{lhs, rhs}};
}
DimExpr MakeSymbolic() {
static std::atomic<int64_t> 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<DimExpr>{{sym0, sym1, sym2}};
ASSERT_EQ(SimplifyDimExpr(origin), expected);
}
TEST(Simplify, NumberAdd) {
List<DimExpr> num_lists{DimExpr(5), Negative<DimExpr>(5)};
DimExpr dim_expr{Add<DimExpr>{num_lists}};
DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr);
ASSERT_TRUE((simplified_dim_expr.Has<std::int64_t>()));
ASSERT_EQ((simplified_dim_expr.Get<std::int64_t>()), 0);
}
TEST(Simplify, DoubleNegative) {
DimExpr inner_expr{Negative<DimExpr>(DimExpr{1})};
DimExpr expr{Negative<DimExpr>(inner_expr)};
DimExpr simplified_dim_expr = SimplifyDimExpr(expr);
ASSERT_TRUE((simplified_dim_expr.Has<std::int64_t>()));
ASSERT_EQ((simplified_dim_expr.Get<std::int64_t>()), 1);
}
TEST(Simplify, UnitNegative) {
DimExpr unit{Negative<DimExpr>{DimExpr{0}}};
DimExpr simplified_dim_expr = SimplifyDimExpr(unit);
ASSERT_TRUE((simplified_dim_expr.Has<std::int64_t>()));
ASSERT_EQ((simplified_dim_expr.Get<std::int64_t>()), 0);
}
TEST(Simplify, NumberNaiveMul) {
List<DimExpr> num_lists{DimExpr(5), DimExpr(5)};
DimExpr dim_expr{Mul<DimExpr>{num_lists}};
DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr);
ASSERT_TRUE((simplified_dim_expr.Has<std::int64_t>()));
ASSERT_EQ((simplified_dim_expr.Get<std::int64_t>()), 25);
}
TEST(Simplify, NumberNaiveDiv) {
DimExpr dim_expr{Div<DimExpr>{DimExpr(5), DimExpr(5)}};
DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr);
ASSERT_TRUE((simplified_dim_expr.Has<std::int64_t>()));
ASSERT_EQ((simplified_dim_expr.Get<std::int64_t>()), 1);
}
TEST(Simplify, NestNumberAddDiv) {
DimExpr div_expr{Div<DimExpr>{DimExpr(5), DimExpr(5)}};
List<DimExpr> sum_lists{DimExpr(0), div_expr};
DimExpr dim_expr{Add<DimExpr>{sum_lists}};
DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr);
ASSERT_TRUE((simplified_dim_expr.Has<std::int64_t>()));
ASSERT_EQ((simplified_dim_expr.Get<std::int64_t>()), 1);
}
TEST(Simplify, NestNumberMulAdd) {
List<DimExpr> num_lists{DimExpr(5), Negative<DimExpr>(5)};
List<DimExpr> product_lists{DimExpr(5), Add<DimExpr>{num_lists}};
DimExpr dim_expr{Mul<DimExpr>{product_lists}};
DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr);
ASSERT_TRUE((simplified_dim_expr.Has<std::int64_t>()));
ASSERT_EQ((simplified_dim_expr.Get<std::int64_t>()), 0);
}
TEST(Simplify, SymbolicMul) {
DimExpr sym = MakeSymbolic();
List<DimExpr> num_lists{DimExpr(1), sym};
DimExpr dim_expr{Mul<DimExpr>{num_lists}};
DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr);
ASSERT_TRUE((simplified_dim_expr.Has<std::string>()));
ASSERT_TRUE((simplified_dim_expr == sym));
}
TEST(Simplify, SymbolicDiv) {
DimExpr sym = MakeSymbolic();
List<DimExpr> num_lists{sym, DimExpr(1)};
DimExpr dim_expr{Mul<DimExpr>{num_lists}};
DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr);
ASSERT_TRUE((simplified_dim_expr.Has<std::string>()));
ASSERT_TRUE((simplified_dim_expr == sym));
}
TEST(Simplify, SymbolicMulUnit) {
DimExpr sym = MakeSymbolic();
List<DimExpr> num_lists{sym, DimExpr(1)};
DimExpr dim_expr{Mul<DimExpr>{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<DimExpr>{Mul<DimExpr>{List<DimExpr>{DimExpr(2), sym}}, sym}};
DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr);
ASSERT_TRUE((simplified_dim_expr.Has<std::int64_t>()));
ASSERT_EQ((simplified_dim_expr.Get<std::int64_t>()), 2);
}
TEST(Simplify, NestSymbolicMulAddUnit) {
DimExpr sym = MakeSymbolic();
List<DimExpr> sum_lists{DimExpr(6), Negative<DimExpr>{DimExpr(5)}};
List<DimExpr> product_lists = List<DimExpr>{Add<DimExpr>{sum_lists}, sym};
DimExpr dim_expr{Mul<DimExpr>{product_lists}};
DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr);
ASSERT_TRUE((simplified_dim_expr.Has<std::string>()));
ASSERT_TRUE((simplified_dim_expr == sym));
}
TEST(Simplify, NestSymbolicDivAddUnit) {
DimExpr sym = MakeSymbolic();
List<DimExpr> sum_lists{DimExpr(6), Negative<DimExpr>{DimExpr(5)}};
DimExpr dim_expr{Div<DimExpr>{sym, Add<DimExpr>{sum_lists}}};
DimExpr simplified_dim_expr = SimplifyDimExpr(dim_expr);
ASSERT_TRUE((simplified_dim_expr.Has<std::string>()));
ASSERT_TRUE((simplified_dim_expr == sym));
}
TEST(Simplify, ConstantMaxMin) {
List<DimExpr> max_lists{DimExpr(4), DimExpr(6)};
DimExpr dim_expr1{Max<DimExpr>{max_lists}};
DimExpr simplified_dim_expr1 = SimplifyDimExpr(dim_expr1);
ASSERT_TRUE((simplified_dim_expr1.Has<std::int64_t>()));
ASSERT_EQ((simplified_dim_expr1.Get<std::int64_t>()), 6);
List<DimExpr> min_lists{DimExpr(2), DimExpr(3)};
DimExpr dim_expr2{Min<DimExpr>{min_lists}};
DimExpr simplified_dim_expr2 = SimplifyDimExpr(dim_expr2);
ASSERT_TRUE((simplified_dim_expr2.Has<std::int64_t>()));
ASSERT_EQ((simplified_dim_expr2.Get<std::int64_t>()), 2);
}
TEST(Simplify, SimplifyBc) {
// Broadcast(S0, Add(S0, -1)) => S0
DimExpr S0{"S0"};
DimExpr add{Add<DimExpr>{{S0, Negative<DimExpr>{1}}}};
DimExpr bc{Broadcast<DimExpr>{{S0, add}}};
ASSERT_TRUE((SimplifyDimExpr(bc) != Add<DimExpr>{{S0, -1}}));
// TODO(ooooo): improve the simplify ability
DimExpr now_accept{Broadcast<DimExpr>{{Add<DimExpr>{{S0, -1}}, S0}}};
ASSERT_TRUE((SimplifyDimExpr(bc) == now_accept));
}
TEST(Simplify, FoldBroadcast) {
DimExpr sym0{"S0"};
DimExpr sym1{"S1"};
DimExpr mul{Mul<DimExpr>{{sym0, sym1}}};
DimExpr broadcast0{Broadcast<DimExpr>{{mul, sym0}}};
DimExpr broadcast1{Broadcast<DimExpr>{{sym1, mul}}};
DimExpr simplify_broadcast0 = SimplifyDimExpr(broadcast0);
DimExpr simplify_broadcast1 = SimplifyDimExpr(broadcast1);
DimExpr add{Add<DimExpr>{{sym0, sym1}}};
DimExpr broadcast2{Broadcast<DimExpr>{{add, sym0}}};
DimExpr broadcast3{Broadcast<DimExpr>{{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<DimExpr>{{S0, S0, S1, S1}}};
DimExpr simplify_bc = SimplifyDimExpr(bc);
ASSERT_TRUE((simplify_bc == Broadcast<DimExpr>{{S0, S1}}));
}
TEST(Simplify, SimplifyDoubleNegForMulAndDiv) {
// Negative(Mul(S0, Negative(1))) => S0
DimExpr S0{"S0"};
DimExpr mul{Mul<DimExpr>{{S0, Negative<DimExpr>{DimExpr(1)}}}};
DimExpr neg_mul{Negative<DimExpr>{mul}};
DimExpr simplify_neg_mul = SimplifyDimExpr(neg_mul);
ASSERT_TRUE((simplify_neg_mul == S0));
// Negative(Div(S0, Negative(1))) => S0
DimExpr div{Div<DimExpr>{S0, Negative<DimExpr>{DimExpr(1)}}};
DimExpr neg_div{Negative<DimExpr>{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<DimExpr>{{S11, S8}};
DimExpr S10{"S10"};
DimExpr S13{"S13"};
DimExpr S4{"S4"};
DimExpr S7{"S7"};
DimExpr mul_op2 = Broadcast<DimExpr>{{S10, S13, S4, S7}};
DimExpr S12{"S12"};
DimExpr S3{"S3"};
DimExpr S6{"S6"};
DimExpr S9{"S9"};
DimExpr mul_op3 = Broadcast<DimExpr>{{S12, S3, S6, S9}};
DimExpr S0{"S0"};
DimExpr mul_op4 =
Div<DimExpr>{Mul<DimExpr>{List<DimExpr>{mul_op1, mul_op2, mul_op3}}, S0};
DimExpr dim_expr = Div<DimExpr>{
Mul<DimExpr>{List<DimExpr>{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, 71, 2))
DimExpr S2{"S2"};
DimExpr S3{"S3"};
DimExpr mul_op1 =
Mul<DimExpr>{List<DimExpr>{S2, S3, DimExpr(8), DimExpr(7), DimExpr(7)}};
DimExpr S0{"S0"};
DimExpr S1{"S1"};
DimExpr mul_op2 = Mul<DimExpr>{List<DimExpr>{Div<DimExpr>{S0, DimExpr(7)},
Div<DimExpr>{S1, DimExpr(7)},
DimExpr(8),
DimExpr(7),
DimExpr(7),
DimExpr(1),
DimExpr(2)}};
DimExpr dim_expr{Div<DimExpr>{mul_op1, mul_op2}};
DimExpr expected = Div<DimExpr>{
Mul<DimExpr>{List<DimExpr>{S2, S3}},
Mul<DimExpr>{List<DimExpr>{
Div<DimExpr>{S0, DimExpr(7)}, Div<DimExpr>{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<DimExpr>{List<DimExpr>{
Div<DimExpr>{Mul<DimExpr>{List<DimExpr>{S3, S4, S5}},
Mul<DimExpr>{List<DimExpr>{S7, S8}}},
Div<DimExpr>{Mul<DimExpr>{List<DimExpr>{S3, S4, S5}},
Div<DimExpr>{Mul<DimExpr>{List<DimExpr>{S3, S4, S5}},
Mul<DimExpr>{List<DimExpr>{S7, S8}}}}}};
ASSERT_TRUE((SimplifyDimExpr(dim_expr) == dim_expr)); // Need to simplify
}
} // namespace symbol::test