chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
paddle_test(symbol_dim_expr_test SRCS symbol_dim_expr_test.cc)
|
||||
paddle_test(simplify_dim_expr_test SRCS simplify_dim_expr_test.cc)
|
||||
paddle_test(dim_expr_util_test SRCS dim_expr_util_test.cc)
|
||||
paddle_test(constraints_manager_test SRCS constraints_manager_test.cc)
|
||||
|
||||
if(WITH_ONNXRUNTIME AND WIN32)
|
||||
# Copy onnxruntime for some c++ test in Windows, since the test will
|
||||
# be build only in CI, so suppose the generator in Windows is Ninja.
|
||||
copy_onnx(symbol_dim_expr_test)
|
||||
endif()
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright (c) 2024 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 "gtest/gtest.h"
|
||||
|
||||
#include "paddle/pir/include/dialect/shape/utils/constraints_manager.h"
|
||||
#include "paddle/pir/include/dialect/shape/utils/dim_expr_builder.h"
|
||||
|
||||
namespace symbol::test {
|
||||
|
||||
TEST(ConstraintsManager, EqualCstr) {
|
||||
ConstraintsManager cstr_mgr;
|
||||
DimExprBuilder builder;
|
||||
|
||||
// Eq(Mul(S0,S1),Mul(S2,S3))
|
||||
DimExpr sym_expr_0 = builder.Symbol("S0");
|
||||
DimExpr sym_expr_1 = builder.Symbol("S1");
|
||||
DimExpr sym_expr_2 = builder.Symbol("S2");
|
||||
DimExpr sym_expr_3 = builder.Symbol("S3");
|
||||
DimExpr mul_expr_0 = builder.Mul(sym_expr_0, sym_expr_1);
|
||||
DimExpr mul_expr_1 = builder.Mul(sym_expr_2, sym_expr_3);
|
||||
cstr_mgr.AddEqCstr(mul_expr_0, mul_expr_1);
|
||||
ASSERT_TRUE(cstr_mgr.IsEqual(mul_expr_0, mul_expr_1));
|
||||
|
||||
// Eq(Add(S0,S1),Add(S0,1))
|
||||
DimExpr int_expr_1 = builder.ConstSize(1);
|
||||
DimExpr add_expr_0 = builder.Add(sym_expr_0, sym_expr_1);
|
||||
DimExpr add_expr_1 = builder.Add(sym_expr_0, int_expr_1);
|
||||
cstr_mgr.AddEqCstr(add_expr_0, add_expr_1);
|
||||
ASSERT_FALSE(cstr_mgr.IsEqual(add_expr_0, add_expr_1));
|
||||
DimExpr mul_expr_2 = builder.Mul(sym_expr_0, int_expr_1);
|
||||
ASSERT_TRUE(cstr_mgr.IsEqual(mul_expr_2, mul_expr_1));
|
||||
}
|
||||
|
||||
TEST(ConstraintsManager, GreatThanOneCstr) {
|
||||
ConstraintsManager cstr_mgr;
|
||||
DimExpr sym_expr_0 = DimExpr("S0");
|
||||
DimExpr int_expr = DimExpr(5);
|
||||
ASSERT_TRUE(cstr_mgr.IsGTOne(int_expr + sym_expr_0));
|
||||
ASSERT_TRUE(cstr_mgr.IsGTOne(int_expr * sym_expr_0));
|
||||
cstr_mgr.AddGTOneCstr(sym_expr_0);
|
||||
ASSERT_TRUE(cstr_mgr.IsGTOne(sym_expr_0));
|
||||
}
|
||||
|
||||
TEST(ConstraintsManager, BroadcastableCstr) {
|
||||
ConstraintsManager cstr_mgr;
|
||||
DimExpr sym_expr_0 = DimExpr("S0");
|
||||
DimExpr int_expr = DimExpr(5);
|
||||
cstr_mgr.AddBroadcastableCstr(sym_expr_0, int_expr);
|
||||
ASSERT_TRUE(cstr_mgr.IsBroadcastable(sym_expr_0, int_expr));
|
||||
}
|
||||
|
||||
TEST(ConstraintsManager, Case1) {
|
||||
// BC(S0, S1) == S2 => BC(S0, S2) == S2
|
||||
ConstraintsManager cstr_mgr;
|
||||
DimExpr s0 = DimExpr("S0");
|
||||
DimExpr s1 = DimExpr("S1");
|
||||
DimExpr s2 = DimExpr("S2");
|
||||
DimExpr bc_s0_s1 = Broadcast<DimExpr>{{s0, s1}};
|
||||
cstr_mgr.AddEqCstr(bc_s0_s1, s2);
|
||||
cstr_mgr.AddBroadcastableCstr(s0, s1);
|
||||
DimExpr bc_s0_s2 = Broadcast<DimExpr>{{s0, s2}};
|
||||
cstr_mgr.AddBroadcastableCstr(s0, s2);
|
||||
ASSERT_TRUE(cstr_mgr.IsEqual(bc_s0_s2, s2));
|
||||
}
|
||||
|
||||
} // namespace symbol::test
|
||||
@@ -0,0 +1,111 @@
|
||||
// Copyright (c) 2024 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 "gtest/gtest.h"
|
||||
|
||||
#include "paddle/pir/include/dialect/shape/utils/dim_expr_builder.h"
|
||||
#include "paddle/pir/include/dialect/shape/utils/dim_expr_util.h"
|
||||
|
||||
namespace symbol::test {
|
||||
|
||||
namespace {
|
||||
|
||||
// (S0 - S1) * 2 / S0
|
||||
DimExpr CreateExampleDimExpr() {
|
||||
DimExpr sym0 = DimExpr("S0");
|
||||
DimExpr sym1 = DimExpr("S1");
|
||||
DimExpr constant = DimExpr(2);
|
||||
return (sym0 - sym1) * constant / sym0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(DimExprUtil, SimplifyNeg) {
|
||||
DimExpr dim_expr = Negative<DimExpr>{-1};
|
||||
DimExpr ret = SimplifyDimExpr(dim_expr);
|
||||
ASSERT_TRUE(ret.Has<std::int64_t>());
|
||||
ASSERT_EQ(ret.Get<std::int64_t>(), 1);
|
||||
DimExpr double_neg_expr = Negative<DimExpr>{dim_expr};
|
||||
ret = SimplifyDimExpr(double_neg_expr);
|
||||
ASSERT_TRUE(ret.Has<std::int64_t>());
|
||||
ASSERT_EQ(ret.Get<std::int64_t>(), -1);
|
||||
}
|
||||
|
||||
TEST(DimExprUtil, Substitute) {
|
||||
DimExpr dim_expr = CreateExampleDimExpr();
|
||||
std::unordered_map<symbol::DimExpr, symbol::DimExpr> naive_to_full_name{
|
||||
{DimExpr("S0"), DimExpr("symbol0")}, {DimExpr("S1"), DimExpr("symbol1")}};
|
||||
std::unordered_map<symbol::DimExpr, symbol::DimExpr> full_name_to_naive{
|
||||
{DimExpr("symbol0"), DimExpr("S0")}, {DimExpr("symbol1"), DimExpr("S1")}};
|
||||
|
||||
const auto& mid_expr = SubstituteDimExpr(dim_expr, naive_to_full_name);
|
||||
const auto& ret_expr = SubstituteDimExpr(mid_expr, full_name_to_naive);
|
||||
ASSERT_EQ(ret_expr, dim_expr);
|
||||
}
|
||||
|
||||
TEST(DimExprUtil, Calculate) {
|
||||
// (S0 - S1) * 2 / S0
|
||||
DimExpr dim_expr = CreateExampleDimExpr();
|
||||
// (4 - 2) * 2 / 4 => 1
|
||||
DimExpr substitute_expr = SubstituteDimExpr(dim_expr, {{"S0", 4}, {"S1", 2}});
|
||||
DimExpr ret = SimplifyDimExpr(substitute_expr);
|
||||
ASSERT_TRUE(ret.Has<std::int64_t>());
|
||||
ASSERT_EQ(ret.Get<std::int64_t>(), 1);
|
||||
}
|
||||
|
||||
TEST(DimExprUtil, GetDimExprPriority) {
|
||||
DimExprBuilder builder;
|
||||
int priority_int = GetDimExprPriority(builder.ConstSize(1));
|
||||
ASSERT_EQ(priority_int, 0);
|
||||
int priority_sym = GetDimExprPriority(builder.Symbol("S0"));
|
||||
ASSERT_EQ(priority_sym, 1);
|
||||
int priority_add =
|
||||
GetDimExprPriority(builder.Add(DimExpr("S1"), DimExpr("S2")));
|
||||
ASSERT_EQ(priority_add, 2);
|
||||
int priority_bc =
|
||||
GetDimExprPriority(builder.Broadcast(DimExpr("S3"), DimExpr("S4")));
|
||||
ASSERT_EQ(priority_bc, 2);
|
||||
}
|
||||
|
||||
TEST(DimExprUtil, CompareDimExprPriority) {
|
||||
DimExprBuilder builder;
|
||||
DimExpr sym_expr_0 = builder.Symbol("S0");
|
||||
DimExpr sym_expr_1 = builder.Symbol("S1");
|
||||
DimExpr add_expr = builder.Add(DimExpr("S2"), DimExpr("S3"));
|
||||
DimExpr bc_expr = builder.Broadcast(DimExpr("S4"), DimExpr("S5"));
|
||||
ASSERT_EQ(CompareDimExprPriority(sym_expr_0, sym_expr_1),
|
||||
PriorityComparisonStatus::HIGHER);
|
||||
ASSERT_EQ(CompareDimExprPriority(add_expr, sym_expr_0),
|
||||
PriorityComparisonStatus::LOWER);
|
||||
ASSERT_EQ(CompareDimExprPriority(add_expr, bc_expr),
|
||||
PriorityComparisonStatus::EQUAL);
|
||||
}
|
||||
|
||||
TEST(DimExpr, CollectDimExprSymbol) {
|
||||
DimExpr dim_expr = [&]() -> DimExpr {
|
||||
DimExprBuilder builder;
|
||||
DimExpr max_expr = builder.Max(DimExpr("S2"), DimExpr("S3"));
|
||||
DimExpr min_expr = builder.Min(max_expr, DimExpr("S4"));
|
||||
DimExpr broadcast_expr = builder.Broadcast(min_expr, DimExpr("S5"));
|
||||
return CreateExampleDimExpr() + broadcast_expr;
|
||||
}();
|
||||
std::unordered_set<std::string> symbols = CollectDimExprSymbols(dim_expr);
|
||||
std::unordered_set<std::string> expected = {
|
||||
"S0", "S1", "S2", "S3", "S4", "S5"};
|
||||
ASSERT_EQ(symbols.size(), 6UL);
|
||||
for (const auto& symbol : symbols) {
|
||||
ASSERT_TRUE(expected.find(symbol) != expected.end());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace symbol::test
|
||||
@@ -0,0 +1,308 @@
|
||||
// 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, 7,1, 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
|
||||
@@ -0,0 +1,157 @@
|
||||
// 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 "gtest/gtest.h"
|
||||
#include "paddle/pir/include/dialect/shape/utils/dim_expr_builder.h"
|
||||
|
||||
#include "paddle/fluid/pir/dialect/operator/ir/op_dialect.h"
|
||||
#include "paddle/fluid/pir/dialect/operator/ir/pd_op.h"
|
||||
#include "paddle/pir/include/core/ir_context.h"
|
||||
|
||||
namespace symbol::test {
|
||||
|
||||
// Construct DimExpr by overloaded operator(+, - , *, /)
|
||||
TEST(DimExpr, DimExprNaive) {
|
||||
DimExpr sym0 = DimExpr("S0");
|
||||
DimExpr sym1 = DimExpr("S1");
|
||||
DimExpr constant1 = DimExpr(1);
|
||||
DimExpr output = (sym0 + sym1) * constant1;
|
||||
}
|
||||
|
||||
// Construct DimExpr by DimExprBuilder
|
||||
TEST(DimExpr, DimExprBuilder) {
|
||||
DimExprBuilder builder;
|
||||
DimExpr sym0 = DimExpr("S0");
|
||||
DimExpr sym1 = DimExpr("S1");
|
||||
DimExpr constant1 = DimExpr(1);
|
||||
DimExpr add = builder.Add(sym0, sym1);
|
||||
DimExpr out = builder.Broadcast(add, constant1);
|
||||
}
|
||||
|
||||
/*
|
||||
Simulate the ShapeOrDataDimExprs result of below codes:
|
||||
def (x, y):
|
||||
extend_x = x.shape
|
||||
out = pd.reshape(y, extend_x)
|
||||
*/
|
||||
TEST(DimExpr, DataShapeExpr) {
|
||||
// Show ideal ShapeOrDataDimExprs of each pir::Value
|
||||
std::vector<DimExpr> x_shapes{DimExpr("S0"), DimExpr(2)};
|
||||
std::vector<DimExpr> y_shapes{DimExpr(1), DimExpr("S1"), DimExpr(2)};
|
||||
// x => {shape: [S0, 2], data: nullopt}
|
||||
ShapeOrDataDimExprs x_data_shape{symbol::TensorShapeOrDataDimExprs(x_shapes)};
|
||||
// y => {shape: [1, S1, 2], data: nullopt}
|
||||
ShapeOrDataDimExprs y_data_shape{symbol::TensorShapeOrDataDimExprs(y_shapes)};
|
||||
// out => {shape: [S0, 2], data: nullopt}
|
||||
ShapeOrDataDimExprs out_value_shape{
|
||||
symbol::TensorShapeOrDataDimExprs(x_shapes)};
|
||||
}
|
||||
|
||||
/*
|
||||
Simulate the ShapeOrDataDimExprs result of below codes:
|
||||
def (x, y):
|
||||
out = pd.combine(x, y)
|
||||
*/
|
||||
TEST(DimExpr, TensorListShapeOrDataDimExprs) {
|
||||
std::vector<DimExpr> x_shapes{DimExpr("S0"), DimExpr("S1"), DimExpr(2)};
|
||||
std::vector<DimExpr> y_shapes{DimExpr(1), DimExpr("S3"), DimExpr(2)};
|
||||
// x => {shape: [S0, S1, 2], data: nullopt}
|
||||
ShapeOrDataDimExprs x_data_shape{symbol::TensorShapeOrDataDimExprs(x_shapes)};
|
||||
// y => {shape: [1, S3, 2], data: nullopt}
|
||||
ShapeOrDataDimExprs y_data_shape{symbol::TensorShapeOrDataDimExprs(y_shapes)};
|
||||
|
||||
// out => {shape: [S0, S1, 2], data: nullopt, shape: [1, S3, 2], data:
|
||||
// nullopt}
|
||||
ShapeOrDataDimExprs out_data_shape_list(
|
||||
{symbol::TensorShapeOrDataDimExprs(x_shapes),
|
||||
symbol::TensorShapeOrDataDimExprs(y_shapes)});
|
||||
}
|
||||
|
||||
TEST(Simplify, NumberArithmetic) {
|
||||
DimExpr number = DimExpr(5);
|
||||
DimExpr add_minus = number + number - number;
|
||||
ASSERT_TRUE((add_minus.Has<std::int64_t>()));
|
||||
ASSERT_EQ((add_minus.Get<std::int64_t>()), 5);
|
||||
DimExpr mul_div = number * DimExpr(1) / number;
|
||||
ASSERT_TRUE((mul_div.Has<std::int64_t>()));
|
||||
ASSERT_EQ((mul_div.Get<std::int64_t>()), 1);
|
||||
}
|
||||
|
||||
TEST(DimExpr, Equal) {
|
||||
DimExprBuilder builder;
|
||||
DimExpr sym0 = DimExpr("S0");
|
||||
DimExpr sym1 = DimExpr("S1");
|
||||
DimExpr constant1 = DimExpr(1);
|
||||
ASSERT_EQ(sym0 + sym1, sym0 + sym1);
|
||||
ASSERT_EQ(sym0 + sym1, sym1 + sym0);
|
||||
ASSERT_EQ(sym0 + constant1, DimExpr("S0") + constant1);
|
||||
ASSERT_EQ(sym0 - sym1, sym0 - sym1);
|
||||
ASSERT_NE(sym0 - sym1, sym1 - sym0);
|
||||
ASSERT_EQ(sym0 - constant1, DimExpr("S0") - constant1);
|
||||
ASSERT_EQ(sym0 * sym1, sym0 * sym1);
|
||||
ASSERT_EQ(sym0 * sym1, sym1 * sym0);
|
||||
ASSERT_EQ(sym0 * constant1, DimExpr("S0") * constant1);
|
||||
ASSERT_EQ(sym0 / sym1, sym0 / sym1);
|
||||
ASSERT_NE(sym0 / sym1, sym1 / sym0);
|
||||
ASSERT_EQ(sym0 / constant1, DimExpr("S0") / constant1);
|
||||
ASSERT_EQ(builder.Max(sym0, sym1), builder.Max(sym0, sym1));
|
||||
ASSERT_NE(builder.Max(sym0, sym1), builder.Max(sym1, sym0));
|
||||
ASSERT_EQ(builder.Max(sym0, constant1),
|
||||
builder.Max(DimExpr("S0"), constant1));
|
||||
ASSERT_EQ(builder.Min(sym0, sym1), builder.Min(sym0, sym1));
|
||||
ASSERT_NE(builder.Min(sym0, sym1), builder.Min(sym1, sym0));
|
||||
ASSERT_EQ(builder.Min(sym0, constant1),
|
||||
builder.Min(DimExpr("S0"), constant1));
|
||||
ASSERT_EQ(builder.Broadcast(sym0, sym1), builder.Broadcast(sym0, sym1));
|
||||
ASSERT_EQ(builder.Broadcast(sym0, sym1), builder.Broadcast(sym1, sym0));
|
||||
ASSERT_EQ(builder.Broadcast(sym0, constant1),
|
||||
builder.Broadcast(DimExpr("S0"), constant1));
|
||||
}
|
||||
|
||||
TEST(DimExpr, Print) {
|
||||
DimExprBuilder builder;
|
||||
DimExpr sym0 = DimExpr("S0");
|
||||
DimExpr sym1 = DimExpr("S1");
|
||||
ASSERT_EQ((ToString(sym0 + sym1)), "Add(S0, S1)");
|
||||
ASSERT_EQ((ToString(sym0 - sym1)), "Add(S0, -S1)");
|
||||
ASSERT_EQ((ToString(sym0 * sym1)), "Mul(S0, S1)");
|
||||
ASSERT_EQ((ToString(sym0 / sym1)), "Div(S0, S1)");
|
||||
ASSERT_EQ((ToString(builder.Max(sym0, sym1))), "Max(S0, S1)");
|
||||
ASSERT_EQ((ToString(builder.Min(sym0, sym1))), "Min(S0, S1)");
|
||||
ASSERT_EQ((ToString(builder.Broadcast(sym0, sym1))), "Broadcast(S0, S1)");
|
||||
}
|
||||
|
||||
TEST(DimExpr, Hash) {
|
||||
DimExprBuilder builder;
|
||||
DimExpr sym0 = DimExpr("S0");
|
||||
DimExpr sym1 = DimExpr("S1");
|
||||
ASSERT_EQ((std::hash<DimExpr>()(sym0 + sym1)),
|
||||
(std::hash<DimExpr>()(sym0 + sym1)));
|
||||
ASSERT_EQ((std::hash<DimExpr>()(sym0 + sym1)),
|
||||
(std::hash<DimExpr>()(sym1 + sym0)));
|
||||
ASSERT_NE((std::hash<DimExpr>()(sym0 + sym1)),
|
||||
(std::hash<DimExpr>()(sym0 - sym1)));
|
||||
ASSERT_NE((std::hash<DimExpr>()(sym0 + sym1)),
|
||||
(std::hash<DimExpr>()(sym0 * sym1)));
|
||||
ASSERT_NE((std::hash<DimExpr>()(sym0 + sym1)),
|
||||
(std::hash<DimExpr>()(sym0 / sym1)));
|
||||
ASSERT_NE((std::hash<DimExpr>()(sym0 + sym1)),
|
||||
(std::hash<DimExpr>()(builder.Max(sym0, sym1))));
|
||||
ASSERT_NE((std::hash<DimExpr>()(sym0 + sym1)),
|
||||
(std::hash<DimExpr>()(builder.Min(sym0, sym1))));
|
||||
ASSERT_NE((std::hash<DimExpr>()(sym0 + sym1)),
|
||||
(std::hash<DimExpr>()(builder.Broadcast(sym0, sym1))));
|
||||
}
|
||||
|
||||
} // namespace symbol::test
|
||||
Reference in New Issue
Block a user