Files
2026-07-13 12:40:42 +08:00

192 lines
5.4 KiB
C++

// Copyright (c) 2025 CINN 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 "paddle/cinn/optim/ir_simplify.h"
#include <gtest/gtest.h>
#include "paddle/cinn/cinn.h"
#include "paddle/cinn/ir/ir.h"
#include "paddle/cinn/ir/ir_base.h"
#include "paddle/cinn/ir/ir_printer.h"
#include "paddle/cinn/ir/op/ir_operators.h"
#include "paddle/cinn/ir/schedule/ir_schedule.h"
#include "paddle/cinn/ir/utils/ir_nodes_collector.h"
#include "paddle/cinn/ir/utils/stmt_converter.h"
#include "paddle/cinn/utils/string.h"
namespace cinn {
namespace optim {
/*
i_j_fused: [0ll, 524288ll)
j_0: [0, 128)
Before Normalize:
(j_0 % 128)
After Normalize:
j_0
*/
TEST(IRSimplifyBound, SimplifyMod) {
Context::Global().ResetNameId();
// Create input IR matching the specified pattern
// Define loop variable
ir::Var var_j_0 = ir::Var(ir::Expr(0), ir::Expr(128), "j_0");
// Final expression
ir::Expr expr = ir::Mod::Make(var_j_0, ir::Expr(128));
VLOG(6) << "Before Simplify: " << expr;
auto res = expr.as_index().ir::IndexExpr::Normalize(
ir::IndexExpr::OptLevel::kLevel3);
VLOG(6) << "After Simplify: " << res;
// Expected output verification
std::string expected_ir = R"ROC(j_0)ROC";
EXPECT_EQ(utils::GetStreamCnt(res), utils::Trim(expected_ir));
}
/*
i_j_fused: [0ll, 524288ll)
j_0: [0, 128)
Before Normalize:
(j_0 / 128)
After Normalize:
0
*/
TEST(IRSimplifyBound, SimplifyDiv) {
Context::Global().ResetNameId();
// Create input IR matching the specified pattern
// Define loop variable
ir::Var var_j_0 = ir::Var(ir::Expr(0), ir::Expr(128), "j_0");
// Final expression
ir::Expr expr = ir::Div::Make(var_j_0, ir::Expr(128));
VLOG(6) << "Before Normalize: " << expr;
auto res = expr.as_index().ir::IndexExpr::Normalize(
ir::IndexExpr::OptLevel::kLevel3);
VLOG(6) << "After Normalize: " << res;
// Expected output verification
std::string expected_ir = R"ROC(0)ROC";
EXPECT_EQ(utils::GetStreamCnt(res), utils::Trim(expected_ir));
}
/*
i_j_fused: [0ll, 524288ll)
j_0: [0, 128)
Before Normalize:
((((i_j_fused % 16) * 128) + j_0) / 128)
After Normalize:
(i_j_fused % 16)
*/
TEST(IRSimplifyBound, SimplifyLinearDiv) {
Context::Global().ResetNameId();
// Create input IR matching the specified pattern
// Define loop variables
ir::Var var_i_j_fused = ir::Var(ir::Expr(0), ir::Expr(524288), "i_j_fused");
ir::Var var_j_0 = ir::Var(ir::Expr(0), ir::Expr(128), "j_0");
// Final expression
ir::Expr expr = ir::Div::Make(
ir::Add::Make(ir::Mul::Make(ir::Mod::Make(var_i_j_fused, ir::Expr(16)),
ir::Expr(128)),
var_j_0),
ir::Expr(128));
VLOG(6) << "Before Normalize: " << expr;
auto res = expr.as_index().ir::IndexExpr::Normalize(
ir::IndexExpr::OptLevel::kLevel3);
VLOG(6) << "After Normalize: " << res;
// Expected output verification
std::string expected_ir = R"ROC((i_j_fused % 16))ROC";
EXPECT_EQ(utils::GetStreamCnt(res), utils::Trim(expected_ir));
}
/*
i_j_fused: [0ll, 524288ll)
j_0: [0, 128)
Before Normalize:
((((i_j_fused % 16) * 128) + j_0) % 128)
After Normalize:
j_0
*/
TEST(IRSimplifyBound, SimplifyLinearMod) {
Context::Global().ResetNameId();
// Create input IR matching the specified pattern
// Define loop variables
ir::Var var_i_j_fused = ir::Var(ir::Expr(0), ir::Expr(524288), "i_j_fused");
ir::Var var_j_0 = ir::Var(ir::Expr(0), ir::Expr(128), "j_0");
// Final expression
ir::Expr expr = ir::Mod::Make(
ir::Add::Make(ir::Mul::Make(ir::Mod::Make(var_i_j_fused, ir::Expr(16)),
ir::Expr(128)),
var_j_0),
ir::Expr(128));
VLOG(6) << "Before Normalize: " << expr;
auto res = expr.as_index().ir::IndexExpr::Normalize(
ir::IndexExpr::OptLevel::kLevel3);
VLOG(6) << "After Normalize: " << res;
// Expected output verification
std::string expected_ir = R"ROC(j_0)ROC";
EXPECT_EQ(utils::GetStreamCnt(res), utils::Trim(expected_ir));
}
/*
loop_var_2: [0, 32)
loop_var_3: [0, 4)
Before Normalize:
(((loop_var_3 * 32ll) + loop_var_2) / 128ll)
After Normalize:
0
*/
TEST(IRSimplifyBound, SimplifyLinearDiv2) {
Context::Global().ResetNameId();
// Create input IR matching the specified pattern
// Define loop variables
ir::Var loop_var_2 = ir::Var(ir::Expr(0), ir::Expr(32), "loop_var_2");
ir::Var loop_var_3 = ir::Var(ir::Expr(0), ir::Expr(4), "loop_var_3");
// Final expression
ir::Expr expr = ir::Div::Make(
ir::Add::Make(ir::Mul::Make(loop_var_3, ir::Expr(32)), loop_var_2),
ir::Expr(128));
VLOG(6) << "Before Normalize: " << expr;
auto res = expr.as_index().ir::IndexExpr::Normalize(
ir::IndexExpr::OptLevel::kLevel3);
VLOG(6) << "After Normalize: " << res;
// Expected output verification
std::string expected_ir = R"ROC(0)ROC";
EXPECT_EQ(utils::GetStreamCnt(res), utils::Trim(expected_ir));
}
} // namespace optim
} // namespace cinn