未验证 提交 f9e1b2d2 编写于 作者: A Aurelius84 提交者: GitHub

[NewIR]Support Instruction.Run in CINN for Runtime::Program (#55680)

上级 c737f0ae
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
#pragma once #pragma once
#include <absl/types/variant.h>
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
#include "paddle/cinn/common/context.h" #include "paddle/cinn/common/context.h"
...@@ -30,9 +31,15 @@ namespace cinn { ...@@ -30,9 +31,15 @@ namespace cinn {
namespace hlir { namespace hlir {
namespace framework { namespace framework {
// TODO(Aurelius): Need add name mapping logic in REGISTER_CINN_OP struct CompatibleInfo {
// macros or attempt to unify Op name with Paddle and CINN. static constexpr char* kInputPrefix = "input_";
static const std::unordered_map<std::string, std::string> OP_NAMES = { static constexpr char* kOutputPrefix = "output_";
// TODO(Aurelius): Need add name mapping logic in REGISTER_CINN_OP
// macros or attempt to unify Op name with Paddle and CINN.
static const std::unordered_map<std::string, std::string> OP_NAMES;
};
const std::unordered_map<std::string, std::string> CompatibleInfo::OP_NAMES = {
{"pd.full", "fill_constant"}, {"pd.matmul", "matmul"}}; {"pd.full", "fill_constant"}, {"pd.matmul", "matmul"}};
// TODO(Aurelius84): Need abstract this logic to implement Proxy for // TODO(Aurelius84): Need abstract this logic to implement Proxy for
...@@ -70,18 +77,32 @@ class NewIRCompiler final { ...@@ -70,18 +77,32 @@ class NewIRCompiler final {
compiler_->Build(build_module, ""); compiler_->Build(build_module, "");
auto instructions = BuildInstructions(groups); auto instructions = BuildInstructions(groups);
// TODO(Aurelius84): Instantiate all tensors on compile-time, which is
// controlled by 'options.with_instantiate_variables' in GraphCompiler.
// Moreover, it's better to implement InsertBufferHandlers() logic
// to automatically insert Malloc and Free instructions.
for (auto& name : scope_->var_names()) {
std::string var_name({name.data(), name.size()});
VLOG(4) << "Instantiate " << var_name << " on compile-time";
auto* var = scope_->Var<Tensor>(var_name);
auto& tensor = absl::get<Tensor>(*var);
tensor->mutable_data(target_, tensor->type());
}
return std::make_unique<Program>(scope_, std::move(instructions)); return std::make_unique<Program>(scope_, std::move(instructions));
} }
std::vector<ir::LoweredFunc> GetOpFunc(const ::ir::Operation& op, int idx) { std::vector<ir::LoweredFunc> GetOpFunc(const ::ir::Operation& op, int idx) {
std::vector<ir::Tensor> inputs; std::vector<ir::Tensor> inputs;
std::vector<common::CINNValue> cinn_inputs; std::vector<common::CINNValue> cinn_inputs;
VLOG(4) << "GetOpFunc for op: " << op.name(); auto op_name = op.name();
VLOG(4) << "GetOpFunc for op: " << op_name;
// step 1: Deal with Oprands // step 1: Deal with Oprands
for (int i = 0; i < op.num_operands(); ++i) { for (int i = 0; i < op.num_operands(); ++i) {
auto in_value = op.operand(i); auto in_value = op.operand(i);
// TODO(Aurelius84): For now, use addr as name but it's not wise. // TODO(Aurelius84): For now, use addr as name but it's not wise.
std::string input_id = std::to_string(std::hash<::ir::Value>()(in_value)); std::string input_id = CompatibleInfo::kInputPrefix +
std::to_string(std::hash<::ir::Value>()(in_value));
// NOTE(Aurelius84): whether need to support other Type? // NOTE(Aurelius84): whether need to support other Type?
auto type_info = auto type_info =
in_value.type().dyn_cast<paddle::dialect::DenseTensorType>(); in_value.type().dyn_cast<paddle::dialect::DenseTensorType>();
...@@ -100,8 +121,7 @@ class NewIRCompiler final { ...@@ -100,8 +121,7 @@ class NewIRCompiler final {
cinn_inputs.push_back(common::CINNValue(temp)); cinn_inputs.push_back(common::CINNValue(temp));
} }
for (auto out_name : OpGetOutputNames(op)) { for (auto out_name : OpGetOutputNames(op)) {
cinn_inputs.push_back( cinn_inputs.push_back(common::CINNValue(out_name));
common::CINNValue(op.name().substr(3) + "_" + out_name));
} }
VLOG(4) << "inputs.size(): " << inputs.size(); VLOG(4) << "inputs.size(): " << inputs.size();
...@@ -124,14 +144,14 @@ class NewIRCompiler final { ...@@ -124,14 +144,14 @@ class NewIRCompiler final {
{ {
VLOG(4) << "op.attributes():" << op.attributes().size(); VLOG(4) << "op.attributes():" << op.attributes().size();
auto attrs = utils::ConvertAttributes(op.attributes()); auto attrs = utils::ConvertAttributes(op.attributes());
node_attrs.node_name = OP_NAMES.at(op.name()); node_attrs.node_name = CompatibleInfo::OP_NAMES.at(op_name);
node_attrs.attr_store = std::move(attrs); node_attrs.attr_store = std::move(attrs);
} }
auto& strategy = Operator::GetAttrs<StrategyFunction>("CINNStrategy"); auto& strategy = Operator::GetAttrs<StrategyFunction>("CINNStrategy");
// NOTE(Aurelius84): Do we need replace all hlir::framework Operator with // NOTE(Aurelius84): Do we need replace all hlir::framework Operator with
// ::ir::Program ? // ::ir::Program ?
const hlir::framework::Operator* cinn_op = const hlir::framework::Operator* cinn_op =
Operator::Get(OP_NAMES.at(op.name())); Operator::Get(CompatibleInfo::OP_NAMES.at(op_name));
auto impl = OpStrategy::SelectImpl( auto impl = OpStrategy::SelectImpl(
strategy[cinn_op](node_attrs, inputs, out_types, out_shapes, target_)); strategy[cinn_op](node_attrs, inputs, out_types, out_shapes, target_));
common::CINNValuePack C = common::CINNValuePack C =
...@@ -223,7 +243,8 @@ class NewIRCompiler final { ...@@ -223,7 +243,8 @@ class NewIRCompiler final {
std::unordered_set<std::string> repeat; std::unordered_set<std::string> repeat;
for (int i = 0; i < op.num_operands(); ++i) { for (int i = 0; i < op.num_operands(); ++i) {
auto value = op.operand(i); auto value = op.operand(i);
std::string name = std::to_string(std::hash<::ir::Value>()(value)); std::string name = CompatibleInfo::kInputPrefix +
std::to_string(std::hash<::ir::Value>()(value));
if (repeat.count(name)) { if (repeat.count(name)) {
continue; continue;
} }
...@@ -237,7 +258,8 @@ class NewIRCompiler final { ...@@ -237,7 +258,8 @@ class NewIRCompiler final {
std::vector<std::string> names; std::vector<std::string> names;
for (int i = 0; i < op.num_results(); ++i) { for (int i = 0; i < op.num_results(); ++i) {
auto value = op.result(i); auto value = op.result(i);
std::string name = std::to_string(std::hash<::ir::Value>()(value)); std::string name = CompatibleInfo::kOutputPrefix +
std::to_string(std::hash<::ir::Value>()(value));
names.push_back(std::move(name)); names.push_back(std::move(name));
} }
return names; return names;
...@@ -257,11 +279,12 @@ std::shared_ptr<Scope> BuildScope(const Target& target, ...@@ -257,11 +279,12 @@ std::shared_ptr<Scope> BuildScope(const Target& target,
std::unordered_set<::ir::Value> visited; std::unordered_set<::ir::Value> visited;
auto scope = std::make_shared<Scope>(); auto scope = std::make_shared<Scope>();
auto create_var = [&](::ir::Value value) { auto create_var = [&](const std::string& name_prefix, ::ir::Value value) {
if (visited.count(value) > 0) return; if (visited.count(value) > 0) return;
visited.emplace(value); visited.emplace(value);
std::string name = std::to_string(std::hash<::ir::Value>()(value)); std::string name =
name_prefix + std::to_string(std::hash<::ir::Value>()(value));
auto type_info = value.type().dyn_cast<paddle::dialect::DenseTensorType>(); auto type_info = value.type().dyn_cast<paddle::dialect::DenseTensorType>();
auto* var = scope->Var<Tensor>(name); auto* var = scope->Var<Tensor>(name);
auto& tensor = absl::get<Tensor>(*var); auto& tensor = absl::get<Tensor>(*var);
...@@ -279,12 +302,12 @@ std::shared_ptr<Scope> BuildScope(const Target& target, ...@@ -279,12 +302,12 @@ std::shared_ptr<Scope> BuildScope(const Target& target,
// visit OpOprands // visit OpOprands
for (auto i = 0; i < (*it)->num_operands(); ++i) { for (auto i = 0; i < (*it)->num_operands(); ++i) {
auto in_value = (*it)->operand(i); auto in_value = (*it)->operand(i);
create_var(in_value); create_var(CompatibleInfo::kInputPrefix, in_value);
} }
for (auto i = 0; i < (*it)->num_results(); ++i) { for (auto i = 0; i < (*it)->num_results(); ++i) {
auto out_value = (*it)->result(i); auto out_value = (*it)->result(i);
create_var(out_value); create_var(CompatibleInfo::kOutputPrefix, out_value);
} }
} }
return scope; return scope;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "paddle/cinn/frontend/net_builder.h" #include "paddle/cinn/frontend/net_builder.h"
#include "paddle/cinn/frontend/optimize.h" #include "paddle/cinn/frontend/optimize.h"
#include "paddle/cinn/hlir/framework/graph_compiler.h" #include "paddle/cinn/hlir/framework/graph_compiler.h"
#include "paddle/cinn/utils/data_util.h"
#include "paddle/cinn/hlir/framework/new_ir_compiler.h" #include "paddle/cinn/hlir/framework/new_ir_compiler.h"
...@@ -33,15 +34,16 @@ TEST(GraphCompier, TestNewIR) { ...@@ -33,15 +34,16 @@ TEST(GraphCompier, TestNewIR) {
::ir::Program program(ctx); ::ir::Program program(ctx);
::ir::Builder builder = ::ir::Builder(ctx, program.block()); ::ir::Builder builder = ::ir::Builder(ctx, program.block());
const float value = 2.0;
auto full_op_x = auto full_op_x =
builder.Build<paddle::dialect::FullOp>(std::vector<int64_t>{64, 128}, builder.Build<paddle::dialect::FullOp>(std::vector<int64_t>{64, 128},
1.0, value,
phi::DataType::FLOAT32, phi::DataType::FLOAT32,
phi::CPUPlace()); phi::CPUPlace());
auto full_op_y = auto full_op_y =
builder.Build<paddle::dialect::FullOp>(std::vector<int64_t>{128, 64}, builder.Build<paddle::dialect::FullOp>(std::vector<int64_t>{128, 64},
2.0, value,
phi::DataType::FLOAT32, phi::DataType::FLOAT32,
phi::CPUPlace()); phi::CPUPlace());
// TODO(Aurelius84): test more op // TODO(Aurelius84): test more op
...@@ -61,7 +63,15 @@ TEST(GraphCompier, TestNewIR) { ...@@ -61,7 +63,15 @@ TEST(GraphCompier, TestNewIR) {
cinn::hlir::framework::NewIRCompiler ir_compiler(program, target, scope); cinn::hlir::framework::NewIRCompiler ir_compiler(program, target, scope);
auto runtime_program = ir_compiler.Build(); auto runtime_program = ir_compiler.Build();
// FIXME(Aurelius84): It raised illegal memory access while deconstructor ASSERT_NO_THROW(runtime_program->Execute());
// after running all instruction, but it's ok under GLOG_v=10.
// ASSERT_NO_THROW(runtime_program->Execute()); for (auto& var_name : scope->var_names()) {
std::string name = {var_name.begin(), var_name.end()};
std::vector<float> data =
cinn::GetTensorData<float>(scope->GetTensor(name), target);
for (int i = 0; i < data.size(); ++i) {
LOG_FIRST_N(INFO, 3) << "data: " << data[i];
ASSERT_NEAR(data[i], value, 1e-5);
}
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册