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

171 lines
7.1 KiB
C++

// 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 <glog/logging.h>
#include <gtest/gtest.h>
#include <memory>
#include <sstream>
#include "paddle/cinn/hlir/dialect/operator/ir/op_dialect.h"
#include "paddle/cinn/ir/group_schedule/config/database.h"
#include "paddle/cinn/ir/group_schedule/config/file_database.h"
#include "paddle/cinn/ir/group_schedule/config/group_tile_config.h"
#include "paddle/cinn/ir/group_schedule/search/config_searcher.h"
#include "paddle/cinn/ir/group_schedule/search/measurer.h"
#include "paddle/cinn/utils/string.h"
#include "paddle/common/performance_statistician.h"
#include "paddle/fluid/pir/dialect/operator/ir/op_dialect.h"
#include "paddle/fluid/pir/dialect/operator/ir/pd_api.h"
#include "paddle/fluid/pir/dialect/operator/ir/pd_op.h"
#include "paddle/pir/include/core/builtin_type.h"
#include "paddle/pir/include/core/ir_context.h"
#include "paddle/pir/include/core/program.h"
COMMON_DECLARE_bool(print_ir);
PD_DECLARE_string(cinn_tile_config_filename_label);
#define MKDIR(path) mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)
bool PathExists(const std::string& path) {
struct stat statbuf;
if (stat(path.c_str(), &statbuf) != -1) {
if (S_ISDIR(statbuf.st_mode)) {
return true;
}
}
return false;
}
void RemoveDir(const cinn::common::Target target,
const cinn::ir::IterSpaceType& iter_space_type) {
std::string dirname = "";
std::string filename = "";
for (auto i : iter_space_type) {
dirname += i.first;
dirname += "_";
filename += i.first + i.second;
filename += "_";
}
const std::string kDirSuffix = "_EREBE";
dirname = dirname.substr(0, dirname.size() - 1) + kDirSuffix;
filename = filename.substr(0, filename.size() - 1);
auto removedir = [](const std::string& test_path,
const std::string& file_name) {
if (PathExists(test_path)) {
std::string full_test_name = test_path + file_name;
std::remove(full_test_name.c_str());
LOG(INFO) << "File exist.";
} else {
LOG(INFO) << "File doesn't exist.";
}
};
std::string root_path = FLAGS_cinn_tile_config_filename_label;
const std::string kTestFileDir = "./tile_file_test/";
if (root_path == "") {
root_path = kTestFileDir;
}
std::string target_str = target.arch_str() + "_" + target.device_name_str();
std::string file_name = "/" + filename + ".json";
removedir(root_path + target_str + "/" + dirname, file_name);
LOG(INFO) << "Dump_path "
<< root_path + target_str + "/" + dirname + " has been removed";
}
TEST(ConfigSearcher, TestReduceDemo) {
constexpr int kThreadsPerWarp = 32;
constexpr int kMaxThreadsPerBlock = 1024;
// Step 1: Construct iter space and tile config.
cinn::ir::BucketInfo bucket_info;
int s_dimension_lower = 13;
int s_dimension_upper = 13;
auto s_dimension_type = "S";
auto s_dimension_is_dynamic = true;
int r_dimension_lower = 4096;
int r_dimension_upper = 4096;
auto r_dimension_type = "R";
auto r_dimension_is_dynamic = true;
bucket_info.space.push_back(
cinn::ir::BucketInfo::Dimension{s_dimension_lower,
s_dimension_upper,
s_dimension_type,
s_dimension_is_dynamic});
bucket_info.space.push_back(
cinn::ir::BucketInfo::Dimension{r_dimension_lower,
r_dimension_upper,
r_dimension_type,
r_dimension_is_dynamic});
cinn::ir::ScheduleConfig::TileConfig tile_config;
tile_config.spatial_inner_num = 9;
tile_config.warp_num = 14;
tile_config.tree_reduce_num = 512;
// Use kTestFileDir in this test.
const std::string prev_flag = FLAGS_cinn_tile_config_filename_label;
const std::string kTestFileDir = "./tile_file_test/";
FLAGS_cinn_tile_config_filename_label = kTestFileDir;
std::vector<std::pair<std::string, std::string>> iter_space_type = {
std::make_pair(s_dimension_type,
s_dimension_is_dynamic == true ? "dynamic" : "static"),
std::make_pair(r_dimension_type,
r_dimension_is_dynamic == true ? "dynamic" : "static")};
// If test file has been created, remove it.
RemoveDir(cinn::common::DefaultTarget(), iter_space_type);
// Step 2: Add to json / Read from json
cinn::ir::FileTileConfigDatabase file_database;
file_database.AddConfig(
cinn::common::DefaultTarget(), bucket_info, tile_config, 2);
cinn::ir::TileConfigMap tile_config_map =
file_database.GetConfigs(cinn::common::DefaultTarget(), iter_space_type);
// Delete the file
RemoveDir(cinn::common::DefaultTarget(), iter_space_type);
// Check the correctness
for (auto& it : tile_config_map) {
LOG(INFO) << "bucket info is: ";
auto dims = it.first.space.size();
for (int i = 0; i < dims; i++) {
LOG(INFO) << "Dimension " << i
<< " 's lower_bound is: " << it.first.space[i].lower_bound;
LOG(INFO) << "Dimension " << i
<< " 's upper_bound is: " << it.first.space[i].upper_bound;
auto dimension_lower = i == 0 ? s_dimension_lower : r_dimension_lower;
auto dimension_upper = i == 0 ? s_dimension_upper : r_dimension_upper;
PADDLE_ENFORCE_EQ(it.first.space[i].lower_bound,
dimension_lower,
::common::errors::InvalidArgument(
"GetConfigs function gets wrong dimension_lower"));
PADDLE_ENFORCE_EQ(it.first.space[i].upper_bound,
dimension_upper,
::common::errors::InvalidArgument(
"GetConfigs function gets wrong dimension_upper"));
}
LOG(INFO) << "tile config is " << it.second.spatial_inner_num << " "
<< it.second.warp_num << " " << it.second.tree_reduce_num;
PADDLE_ENFORCE_EQ(it.second.spatial_inner_num,
tile_config.spatial_inner_num,
::common::errors::InvalidArgument(
"GetConfigs function gets wrong spatial_inner_num"));
PADDLE_ENFORCE_EQ(it.second.warp_num,
tile_config.warp_num,
::common::errors::InvalidArgument(
"GetConfigs function gets wrong warp_num"));
PADDLE_ENFORCE_EQ(it.second.tree_reduce_num,
tile_config.tree_reduce_num,
::common::errors::InvalidArgument(
"GetConfigs function gets wrong tree_reduce_num"));
}
// Restore the previous flag
FLAGS_cinn_tile_config_filename_label = prev_flag;
}