From 1e96ef6496f0ac6266aa30a95e34a048964cdf88 Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Wed, 13 Oct 2021 11:23:41 +0000 Subject: [PATCH 01/16] add cinn graph symbolization --- .../framework/paddle2cinn/CMakeLists.txt | 2 + .../paddle2cinn/cinn_graph_symbolization.cc | 183 ++++++++++++++++++ .../paddle2cinn/cinn_graph_symbolization.h | 96 +++++++++ .../cinn_graph_symbolization_test.cc | 52 +++++ 4 files changed, 333 insertions(+) create mode 100644 paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc create mode 100644 paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h create mode 100644 paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc diff --git a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt index 8621c7363a09f..b42b6b6545bfa 100644 --- a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt +++ b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt @@ -1,7 +1,9 @@ cc_library(cinn_cache_key SRCS cinn_cache_key.cc DEPS boost graph graph_helper lod_tensor proto_desc) cc_library(cinn_compiled_object SRCS cinn_compiled_object.cc DEPS feed_fetch_method graph lod_tensor proto_desc) cc_library(cinn_runner SRCS cinn_runner.cc DEPS cinn_cache_key cinn_compiled_object feed_fetch_method graph lod_tensor scope) +cc_library(cinn_graph_symbolization SRCS cinn_graph_symbolization.cc DEPS lod_tensor graph transform_desc cinnapi.so) cc_test(cinn_cache_key_test SRCS cinn_cache_key_test.cc DEPS cinn_cache_key) cc_test(cinn_runner_test SRCS cinn_runner_test.cc DEPS cinn_runner proto_desc) cc_test(cinn_compiled_object_test SRCS cinn_compiled_object_test.cc DEPS cinn_compiled_object) +cc_test(test_cinn_graph_symbolization SRCS cinn_graph_symbolization_test.cc DEPS cinn_graph_symbolization) diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc new file mode 100644 index 0000000000000..73678b5c78b82 --- /dev/null +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc @@ -0,0 +1,183 @@ +/* Copyright (c) 2021 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 "paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h" + +#include +#include +#include +#include +#include + +#include "paddle/fluid/framework/paddle2cinn/transform_desc.h" + +#include "cinn/frontend/op_mappers/use_op_mappers.h" +#include "cinn/frontend/var_type_utils.h" + +namespace paddle { +namespace framework { +namespace paddle2cinn { +namespace utils { +struct CinnVarInfo { + std::vector shape; + ::cinn::common::Type type; +}; + +CinnVarInfo GetCinnVarInfoFromTensor(const Tensor* tensor) { + CinnVarInfo info; + const auto& dim = tensor->dims(); + for (int i = 0; i < dim.size(); i++) { + info.shape.emplace_back(sttic_cast(dim[i])); + } + + auto proto_var_type = tensor->type(); + auto cinn_var_type = TransformVarTypeToCinn(proto_var_type); + info.type = ::cinn::frontend::utils::CppVarType2CommonType(cinn_var_type); + return info; +} +} // namespace utils + +using ::cinn::frontend::OpMapperContext; +using ::cinn::frontend::Program; + +void CinnGraphSymbolization::AddFeedVarIntoCinn( + const OpMapperContext& ctx) const { + for (auto& feed_pair : *feed_targets_) { + const auto& var_name = feed_pair.first; + const auto* tensor = feed_pair.second; + + auto var = utils::GetCinnVarInfoFromTensor(tensor); + auto input = ctx.Builder()->CreateInput(var.type, var.shape, var_name); + ctx.AddVar(var_name, input); + VLOG(4) << "Add feed variable [" << var_name << "]"; + } +} + +std::vector CinnGraphSymbolization::TopoSortGraph() const { + std::vector cluster_sorted; + + std::unordered_set cluster_set; + const auto& nodes = graph_.Nodes(); + std::copy_if(nodes.begin(), nodes.end(), cluster_set.begin(), + [](Node* node) { return node->IsOp(); }); + + std::unordered_map indegree; + std::unordered_map> adj_list; + std::queue topo_queue; + + // record all op's input op and output op + for (auto* n : cluster_set) { + // the op's input is var + for (auto* in_var : n->inputs) { + // the var's input is op + for (auto* in_op : in_var->inputs) { + if (cluster_set.find(in_op) != cluster_set.end()) { + ++indegree[n]; + ++adj_list[in_op][n]; + } + } + } + } + + // find topology entrance + for (auto* n : cluster_set) { + if (indegree[n] == 0) { + topo_queue.push(n); + } + } + + // topological sorting + while (!topo_queue.empty()) { + auto* cur_op = topo_queue.front(); + topo_queue.pop(); + + cluster_sorted.emplace_back(cur_op); + for (const auto& adj_pair : adj_list[cur_op]) { + // decrease output op's in-degree + indegree.at(adj_pair.first) -= adj_pair.second; + + // if empty, push into queue + if (indegree.at(adj_pair.first) == 0) { + topo_queue.push(adj_pair.first); + } + } + } + + PADDLE_ENFORCE_EQ(cluster_sorted.size(), cluster_set.size(), + platform::errors::PreconditionNotMet( + "Cluster Sub-Graph shouldn't contain cycle.")); + return cluster_sorted; +} + +decltype(auto) CinnGraphSymbolization::TransformAllGraphOpToCinn() const { + std::vector> cinn_op_descs_; + + const auto& sorted_ops = TopoSortGraph(); + for (auto* node : sorted_ops) { + cinn_op_descs_.emplace_back(std::make_unique()); + auto& cinn_desc = cinn_op_descs_.back(); + + TransformOpDescToCinn(node->Op(), cinn_desc.get()); + } + return std::move(cinn_op_descs_); +} + +void CinnGraphSymbolization::RunOp(const CinnOpDesc& op_desc, + const OpMapperContext& ctx) const { + const auto& op_type = op_desc.Type(); + auto kernel = ::cinn::frontend::OpMapperRegistry::Global()->Find(op_type); + PADDLE_ENFORCE_NE( + kernel, nullptr, + platform::errors::NotFound("Op %s Not Support by CINN", op_type.c_str())); + VLOG(4) << "Running Op " << op_type; + kernel->Run(op_desc, ctx); +} + +void CinnGraphSymbolization::RunGraph(const OpMapperContext& ctx) const { + auto cinn_op_descs_ = TransformAllGraphOpToCinn(); + // run the CINN op one by one, note that all ops + // have been sorted at constructor. + for (auto* op_desc : cinn_op_descs_) { + RunOp(*op_desc, ctx); + } +} + +Program CinnGraphSymbolization::operator()() const { + std::string builder_name = "graph_"; + builder_name.append(std::to_string(graph_id_)); + builder_name.append("_of_"); + static uint64_t unique_invoke_number = 0; + builder_name.append(std::to_string(unique_invoke_number++)); + VLOG(4) << "NetBuilder Name " << builder_name; + + ::cinn::frontend::NetBuilder builder(builder_name); + + auto scope = ::cinn::hlir::framework::Scope::Create(); + auto target = ::cinn::common::DefaultHostTarget(); + + absl::flat_hash_map var_map; + absl::flat_hash_map var_model_to_program_map; + + OpMapperContext ctx(scope.get(), target, &builder, &var_map, + &var_model_to_program_map); + + AddFeedVarIntoCinn(ctx); + RunGraph(ctx); + + return builder.Build(); +} + +} // namespace paddle2cinn +} // namespace framework +} // namespace paddle diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h new file mode 100644 index 0000000000000..7ab5fd9361fba --- /dev/null +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h @@ -0,0 +1,96 @@ +/* Copyright (c) 2021 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. */ + +#pragma once + +#include + +#include "paddle/fluid/framework/ir/graph.h" +#include "paddle/fluid/framework/lod_tensor.h" + +#include "cinn/frontend/net_builder.h" +#include "cinn/frontend/op_mapper_registry.h" + +namespace paddle { +namespace framework { +namespace paddle2cinn { + +// An executor accept subgraph which is generated by BuildCinnPass, +// run each op's CINN Op Mapper, finally return the graph's CINN NetBuilder. +// +// Parameter: +// 1. graph_id: +// the unique graph id, used for generating unique NetBuilder name. +// 2. graph: +// the CINN subgraph whose op are all supported by CINN, and the +// graph is independently of other graph. +// 3. feed_targets: +// all input var nodes of CINN subgraph, they are necessary for +// we need pass the shape and data type into CINN, otherwise the +// NetBuilder may error for the shape not meet the precondition. +// +// Describe: +// The main function is operator(), it will run all op function by CINN +// OpMapper and finally return a program object. +// The executor operator() consisted by the following step: +// 1. create a NetBuilder, it's name is unique for each graph; +// 2. create OpMapperContext, contain scope, target, local var_map and +// local var_model_to_program_map; +// 3. add all feed var into OpMapperContext to pass the shape and type +// into CINN; +// 4. topological sorting graph op nodes; +// 5. transform all op from paddle opdesc format to cinn opdesc format; +// 5. run the CINN op in graph one by one. Note that the graph have been +// topo sorted; +// 6. return the NetBuilder.Build() after all op run. +class CinnGraphSymbolization { + public: + CinnGraphSymbolization( + int64_t graph_id, const ir::Graph& graph, + const std::map* feed_targets) + : graph_id_(graph_id), graph_(graph), feed_targets_(feed_targets) {} + + // run all CINN op in graph by topo sorting then return its NetBuilder + ::cinn::frontend::Program operator()() const; + + private: + const int64_t graph_id_; + const ir::Graph& graph_; + const std::map* feed_targets_; + + // transform all paddle var desc in feed list into cinn_var_descs_ + void AddFeedVarIntoCinn(const OpMapperContext& ctx) const; + + // transform all paddle op desc in graph into cinn op desc + using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; + std::vector> TransformAllGraphOpToCinn() const; + + // topo sort graph and return sorted op list, + // called in TransformAllOpDescToCinn. + std::vector TopoSortGraph() const; + + // RunOp accept OpDesc and global run context then run + // it's kernel registered in OpMapper. + // called in RunGraph. + void RunOp(const CinnOpDesc& op_desc, const OpMapperContext& ctx) const; + + // preserve var desc, run the op one by one. + void RunGraph(const OpMapperContext& ctx) const; + + friend class CinnGraphSymbolizationTest; +}; + +} // namespace paddle2cinn +} // namespace framework +} // namespace paddle diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc new file mode 100644 index 0000000000000..3af6432a0310e --- /dev/null +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc @@ -0,0 +1,52 @@ +/* Copyright (c) 2021 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/fluid/framework/paddle2cinn/cinn_graph_symbolization.h" + +namespace paddle { +namespace framework { +namespace paddle2cinn { + +// only used for test CinnGraphSymbolization class +class CinnGraphSymbolizationTest : public ::testing::Test { + public: + void AddFeedVarIntoCinn(const OpMapperContext& ctx) const; + + using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; + std::vector> TransformAllGraphOpToCinn() const; + + std::vector TopoSortGraph() const; + + void RunOp(const CinnOpDesc& op_desc, const OpMapperContext& ctx) const; + + void RunGraph(const OpMapperContext& ctx) const; + + protected: + void SetUp() override { + // TODO(jiangcheng05): initial CinnGraphSymbolization + } + + private: + CinnGraphSymbolization cinn_symbol_; +}; + +TEST_F(CinnGraphSymbolizationTest, basic) { + // TODO(jiangcheng05): fill the single test code +} + +} // namespace paddle2cinn +} // namespace framework +} // namespace paddle From f7757799f5175507614ecb1ad6555ac41cead304 Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Wed, 13 Oct 2021 12:02:45 +0000 Subject: [PATCH 02/16] fix some bug --- .../paddle2cinn/cinn_graph_symbolization.cc | 16 ++++++---------- .../paddle2cinn/cinn_graph_symbolization.h | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc index 73678b5c78b82..497d3af9cdad4 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc @@ -15,6 +15,7 @@ limitations under the License. */ #include "paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h" #include +#include #include #include #include @@ -48,9 +49,6 @@ CinnVarInfo GetCinnVarInfoFromTensor(const Tensor* tensor) { } } // namespace utils -using ::cinn::frontend::OpMapperContext; -using ::cinn::frontend::Program; - void CinnGraphSymbolization::AddFeedVarIntoCinn( const OpMapperContext& ctx) const { for (auto& feed_pair : *feed_targets_) { @@ -69,7 +67,8 @@ std::vector CinnGraphSymbolization::TopoSortGraph() const { std::unordered_set cluster_set; const auto& nodes = graph_.Nodes(); - std::copy_if(nodes.begin(), nodes.end(), cluster_set.begin(), + std::copy_if(nodes.begin(), nodes.end(), + std::inserter(cluster_set, cluster_set.begin()), [](Node* node) { return node->IsOp(); }); std::unordered_map indegree; @@ -153,7 +152,7 @@ void CinnGraphSymbolization::RunGraph(const OpMapperContext& ctx) const { } } -Program CinnGraphSymbolization::operator()() const { +::cinn::frontend::Program CinnGraphSymbolization::operator()() const { std::string builder_name = "graph_"; builder_name.append(std::to_string(graph_id_)); builder_name.append("_of_"); @@ -166,11 +165,8 @@ Program CinnGraphSymbolization::operator()() const { auto scope = ::cinn::hlir::framework::Scope::Create(); auto target = ::cinn::common::DefaultHostTarget(); - absl::flat_hash_map var_map; - absl::flat_hash_map var_model_to_program_map; - - OpMapperContext ctx(scope.get(), target, &builder, &var_map, - &var_model_to_program_map); + OpMapperContext ctx(scope.get(), target, &builder, &var_map_, + &var_model_to_program_map_); AddFeedVarIntoCinn(ctx); RunGraph(ctx); diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h index 7ab5fd9361fba..ceb6f17308572 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h @@ -14,6 +14,7 @@ limitations under the License. */ #pragma once +#include #include #include "paddle/fluid/framework/ir/graph.h" @@ -64,11 +65,24 @@ class CinnGraphSymbolization { // run all CINN op in graph by topo sorting then return its NetBuilder ::cinn::frontend::Program operator()() const; + // return the internal variable map + const decltype(auto)& var_map() const { return var_map_; } + + // return the map from the variable name in paddle model to cinn program. + const decltype(auto)& var_model_to_program_map() const { + return var_model_to_program_map_; + } + private: const int64_t graph_id_; const ir::Graph& graph_; const std::map* feed_targets_; + // preserve local variable map + absl::flat_hash_map var_map_; + absl::flat_hash_map var_model_to_program_map_; + + using OpMapperContext = ::cinn::frontend::OpMapperContext; // transform all paddle var desc in feed list into cinn_var_descs_ void AddFeedVarIntoCinn(const OpMapperContext& ctx) const; @@ -78,7 +92,7 @@ class CinnGraphSymbolization { // topo sort graph and return sorted op list, // called in TransformAllOpDescToCinn. - std::vector TopoSortGraph() const; + std::vector TopoSortGraph() const; // RunOp accept OpDesc and global run context then run // it's kernel registered in OpMapper. From ac23d17a3ff8abc7207d0302d6be741a2a8eb1a2 Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Thu, 14 Oct 2021 10:05:54 +0000 Subject: [PATCH 03/16] add paddle scope to cinn scope --- .../paddle2cinn/cinn_graph_symbolization.cc | 59 ++++++++++++------- .../paddle2cinn/cinn_graph_symbolization.h | 9 +-- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc index 497d3af9cdad4..b863fd5e6aaf2 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc @@ -22,6 +22,7 @@ limitations under the License. */ #include #include "paddle/fluid/framework/paddle2cinn/transform_desc.h" +#include "paddle/fluid/framework/variable.h" #include "cinn/frontend/op_mappers/use_op_mappers.h" #include "cinn/frontend/var_type_utils.h" @@ -30,35 +31,50 @@ namespace paddle { namespace framework { namespace paddle2cinn { namespace utils { -struct CinnVarInfo { - std::vector shape; - ::cinn::common::Type type; -}; - -CinnVarInfo GetCinnVarInfoFromTensor(const Tensor* tensor) { - CinnVarInfo info; - const auto& dim = tensor->dims(); + +using PdTensor = framework::Tensor; +using CinnTensor = ::cinn::hlir::framework::Tensor; + +auto GetCinnVarInfoFromTensor(const PdTensor& tensor) { + OpMapperContext::VarInfo info; + const auto& dim = tensor.dims(); for (int i = 0; i < dim.size(); i++) { info.shape.emplace_back(sttic_cast(dim[i])); } - auto proto_var_type = tensor->type(); - auto cinn_var_type = TransformVarTypeToCinn(proto_var_type); + auto cinn_var_type = TransformVarTypeToCinn(tensor.type()); info.type = ::cinn::frontend::utils::CppVarType2CommonType(cinn_var_type); return info; } + +void TransformPaddleVariableToCinn(const framework::Variable& pd_var, + ::cinn::hlir::framework::Variable* cinn_var, + const ::cinn::common::Target& target) { + const auto& tensor = pd_var.Get(); +} + +auto TransformPaddleScopeToCinn(const framework::Scope& pd_scope, + const ::cinn::common::Target& target) { + auto cinn_scope = ::cinn::hlir::framework::Scope::Create(); + + for (const auto& var_name : pd_scope->LocalVarNames()) { + auto* pd_var = pd_scope.FindVar(var_name); + auto* cinn_var = cinn_scope->Var( + ::cinn::utils::TransValidVarName(var.name())); + + TransformPaddleVariableToCinn(*pd_var, cinn_var, target); + } + + return cinn_scope; +} } // namespace utils -void CinnGraphSymbolization::AddFeedVarIntoCinn( - const OpMapperContext& ctx) const { +void CinnGraphSymbolization::AddVarInfoIntoContext(OpMapperContext* ctx) const { for (auto& feed_pair : *feed_targets_) { const auto& var_name = feed_pair.first; const auto* tensor = feed_pair.second; - auto var = utils::GetCinnVarInfoFromTensor(tensor); - auto input = ctx.Builder()->CreateInput(var.type, var.shape, var_name); - ctx.AddVar(var_name, input); - VLOG(4) << "Add feed variable [" << var_name << "]"; + ctx->AddVarInfo(var_name, utils::GetCinnVarInfoFromTensor(*tensor)); } } @@ -119,7 +135,7 @@ std::vector CinnGraphSymbolization::TopoSortGraph() const { return cluster_sorted; } -decltype(auto) CinnGraphSymbolization::TransformAllGraphOpToCinn() const { +auto CinnGraphSymbolization::TransformAllGraphOpToCinn() const { std::vector> cinn_op_descs_; const auto& sorted_ops = TopoSortGraph(); @@ -152,7 +168,8 @@ void CinnGraphSymbolization::RunGraph(const OpMapperContext& ctx) const { } } -::cinn::frontend::Program CinnGraphSymbolization::operator()() const { +::cinn::frontend::Program CinnGraphSymbolization::operator()( + framework::Scope* scope) const { std::string builder_name = "graph_"; builder_name.append(std::to_string(graph_id_)); builder_name.append("_of_"); @@ -162,13 +179,13 @@ ::cinn::frontend::Program CinnGraphSymbolization::operator()() const { ::cinn::frontend::NetBuilder builder(builder_name); - auto scope = ::cinn::hlir::framework::Scope::Create(); auto target = ::cinn::common::DefaultHostTarget(); + auto cinn_scope = TransformPaddleScopeToCinn(*scope, target); - OpMapperContext ctx(scope.get(), target, &builder, &var_map_, + OpMapperContext ctx(*cinn_scope, target, &builder, &var_map_, &var_model_to_program_map_); - AddFeedVarIntoCinn(ctx); + AddVarInfoIntoContext(&ctx); RunGraph(ctx); return builder.Build(); diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h index ceb6f17308572..72ec0178117d5 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h @@ -19,6 +19,7 @@ limitations under the License. */ #include "paddle/fluid/framework/ir/graph.h" #include "paddle/fluid/framework/lod_tensor.h" +#include "paddle/fluid/framework/scope.h" #include "cinn/frontend/net_builder.h" #include "cinn/frontend/op_mapper_registry.h" @@ -63,13 +64,13 @@ class CinnGraphSymbolization { : graph_id_(graph_id), graph_(graph), feed_targets_(feed_targets) {} // run all CINN op in graph by topo sorting then return its NetBuilder - ::cinn::frontend::Program operator()() const; + ::cinn::frontend::Program operator()(framework::Scope* scope) const; // return the internal variable map - const decltype(auto)& var_map() const { return var_map_; } + const auto& var_map() const { return var_map_; } // return the map from the variable name in paddle model to cinn program. - const decltype(auto)& var_model_to_program_map() const { + const auto& var_model_to_program_map() const { return var_model_to_program_map_; } @@ -84,7 +85,7 @@ class CinnGraphSymbolization { using OpMapperContext = ::cinn::frontend::OpMapperContext; // transform all paddle var desc in feed list into cinn_var_descs_ - void AddFeedVarIntoCinn(const OpMapperContext& ctx) const; + void AddVarInfoIntoContext(OpMapperContext* ctx) const; // transform all paddle op desc in graph into cinn op desc using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; From 0d01f3e02db2f9a6ec8c06ae1660240f2e0638ce Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Fri, 15 Oct 2021 06:20:17 +0000 Subject: [PATCH 04/16] add paddle scope to CINN scope in Symbolization, and add feed op when build cinn pass --- .../framework/paddle2cinn/build_cinn_pass.cc | 48 ++++++++++- .../paddle2cinn/cinn_graph_symbolization.cc | 85 +++++++++++++------ .../paddle2cinn/cinn_graph_symbolization.h | 24 ++++-- 3 files changed, 123 insertions(+), 34 deletions(-) diff --git a/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc b/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc index ffdbb46bd7c06..0fb1effac0753 100644 --- a/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc +++ b/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc @@ -64,10 +64,38 @@ using framework::ir::Node; using GraphNodeVec = std::vector; using GraphNodeSet = std::unordered_set; +void AddFeedOpAndVar(const std::unordered_set& feed_vars, + const GraphNodeSet& cluster, + const std::unordered_map& old_op2new_op, + Graph* graph) { + for (auto* node : feed_vars) { + // create feed op + OpDesc desc; + desc.SetType("feed"); + desc.SetOutput("Out", {node->Name()}); + auto op = graph->CreateOpNode(&desc); + + // create new feed var node (SSAGraph) + auto var = graph->CreateVarNode(node->Var()); + + // link feed op and feed var + op->outputs = {var}; + var->inputs = {op}; + + // link feed var to cluster op + std::copy_if() for (auto* old_op : node->outputs) { + if (cluster.count(old_op)) { + var->outputs.emplace_back(old_op2new_op[old_op]); + } + } + } +} + // Create new subgraph with and op nodes are cluster nodes, and all // var node are from internal nodes -std::unique_ptr CreateNewSubGraph( - const GraphNodeSet& cluster, const GraphNodeSet& cluster_internals) { +std::unique_ptr CreateNewSubGraph(const GraphNodeSet& cluster, + const GraphNodeSet& cluster_internals, + const GraphNodeSet& cluster_inputs) { // Graph's constructor must has one parameter, and in our code, // the ProgramDesc is useless, so here we pass a temporary object. auto sub_graph = std::make_unique(framework::ProgramDesc()); @@ -84,6 +112,7 @@ std::unique_ptr CreateNewSubGraph( old_var2new_var[var] = sub_node; } + std::unordered_set need_feed_vars; // the subgraph is independently, so here we only need link // to the node in new subgraph, and discard the link to // out-graph. @@ -91,6 +120,19 @@ std::unique_ptr CreateNewSubGraph( for (auto* var : op->inputs) { if (cluster_internals.count(var)) { old_op2new_op[op]->inputs.emplace_back(old_var2new_var[var]); + } else if (cluster_inputs.count(var)) { + if (var->Var()->IsParameter()) { + // When the var is subgraph input and the var is not parameter, + // we need add a new feed op to feed the var. + need_feed_vars.insert(var); + } else { + // Parameters have been preserved in scope, so we do not feed + // and create new var node, re-use the old graph's var node + // is satisfactory. + // The var is used for check whether we need preserve the tensor + // when transform paddle scope to CINN scope. + old_op2new_op[op]->inputs.emplace_back(var); + } } } for (auto* var : op->outputs) { @@ -100,6 +142,8 @@ std::unique_ptr CreateNewSubGraph( } } + AddFeedOpAndVar(need_feed_vars, cluster, old_op2new_op, sub_graph.get()); + for (auto* var : cluster_internals) { for (auto* op : var->inputs) { if (cluster.count(op)) { diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc index b863fd5e6aaf2..a16eb8b548f59 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc @@ -17,8 +17,6 @@ limitations under the License. */ #include #include #include -#include -#include #include #include "paddle/fluid/framework/paddle2cinn/transform_desc.h" @@ -30,13 +28,15 @@ limitations under the License. */ namespace paddle { namespace framework { namespace paddle2cinn { -namespace utils { -using PdTensor = framework::Tensor; +using ir::Graph; +using ir::Node; using CinnTensor = ::cinn::hlir::framework::Tensor; -auto GetCinnVarInfoFromTensor(const PdTensor& tensor) { - OpMapperContext::VarInfo info; +namespace utils { + +auto GetCinnFeedInfoFromTensor(const Tensor& tensor) { + OpMapperContext::FeedInfo info; const auto& dim = tensor.dims(); for (int i = 0; i < dim.size(); i++) { info.shape.emplace_back(sttic_cast(dim[i])); @@ -47,34 +47,68 @@ auto GetCinnVarInfoFromTensor(const PdTensor& tensor) { return info; } -void TransformPaddleVariableToCinn(const framework::Variable& pd_var, - ::cinn::hlir::framework::Variable* cinn_var, - const ::cinn::common::Target& target) { - const auto& tensor = pd_var.Get(); +void TransformPaddleVariableToCinn( + const Variable& pd_var, ::cinn::hlir::framework::Variable* cinn_var) { + const auto& pd_tensor = pd_var.Get(); + auto& cinn_tensor = absl::get(*cinn_var); + + auto feed_info = GetCinnFeedInfoFromTensor(pd_tensor); + // here we only need preserve dtype and shape, do not need preserve data + cinn_tensor.set_type(feed_info.type); + cinn_tensor.Resize(::cinn::hlir::framework::Shape(feed_info.shape)); +} +} // namespace utils + +// get the graph's op input Parameter var name set +auto CinnGraphSymbolization::GetGraphInputParameterNames() const { + std::unordered_set names; + + for (auto* node : graph_.Nodes()) { + if (node->IsOp()) { + for (auto* var : node->inputs) { + if (var->Var()->IsParameter()) { + // Only need preserve the input parameter var of graph, + // others do not. + names.insert(var->Name()); + } + } + } + } + + return names; } -auto TransformPaddleScopeToCinn(const framework::Scope& pd_scope, - const ::cinn::common::Target& target) { +// Transform paddle scope to cinn, note that we only preserve the graph’s +// input parameter variable and ignore others. +auto CinnGraphSymbolization::TransformPaddleScopeToCinn() const { auto cinn_scope = ::cinn::hlir::framework::Scope::Create(); - for (const auto& var_name : pd_scope->LocalVarNames()) { - auto* pd_var = pd_scope.FindVar(var_name); + // get the graph's input parameter variable name list + auto parameter_names = GetGraphInputParameterNames(); + + for (const auto& var_name : scope_.LocalVarNames()) { + // if cannot find var in graph input, skip + if (parameter_names.count(var_name) == 0) continue; + + auto* pd_var = scope_.FindLocalVar(var_name); + + // scope accepte the CINN format name, so here we need transform + // paddle format name to CINN format. auto* cinn_var = cinn_scope->Var( ::cinn::utils::TransValidVarName(var.name())); - TransformPaddleVariableToCinn(*pd_var, cinn_var, target); + utils::TransformPaddleVariableToCinn(*pd_var, cinn_var); } return cinn_scope; } -} // namespace utils -void CinnGraphSymbolization::AddVarInfoIntoContext(OpMapperContext* ctx) const { - for (auto& feed_pair : *feed_targets_) { - const auto& var_name = feed_pair.first; +void CinnGraphSymbolization::AddFeedVarIntoContext(OpMapperContext* ctx) const { + for (auto& feed_pair : feed_targets_) { + const auto& feed_name = feed_pair.first; const auto* tensor = feed_pair.second; - ctx->AddVarInfo(var_name, utils::GetCinnVarInfoFromTensor(*tensor)); + ctx.AddFeedInfo(feed_name, utils::GetCinnFeedInfoFromTensor(*tensor)); } } @@ -87,8 +121,8 @@ std::vector CinnGraphSymbolization::TopoSortGraph() const { std::inserter(cluster_set, cluster_set.begin()), [](Node* node) { return node->IsOp(); }); - std::unordered_map indegree; - std::unordered_map> adj_list; + absl::flat_hash_map indegree; + absl::flat_hash_map> adj_list; std::queue topo_queue; // record all op's input op and output op @@ -168,8 +202,7 @@ void CinnGraphSymbolization::RunGraph(const OpMapperContext& ctx) const { } } -::cinn::frontend::Program CinnGraphSymbolization::operator()( - framework::Scope* scope) const { +::cinn::frontend::Program CinnGraphSymbolization::operator()() const { std::string builder_name = "graph_"; builder_name.append(std::to_string(graph_id_)); builder_name.append("_of_"); @@ -180,12 +213,12 @@ ::cinn::frontend::Program CinnGraphSymbolization::operator()( ::cinn::frontend::NetBuilder builder(builder_name); auto target = ::cinn::common::DefaultHostTarget(); - auto cinn_scope = TransformPaddleScopeToCinn(*scope, target); + auto cinn_scope = TransformPaddleScopeToCinn(); OpMapperContext ctx(*cinn_scope, target, &builder, &var_map_, &var_model_to_program_map_); - AddVarInfoIntoContext(&ctx); + AddFeedVarIntoContext(&ctx); RunGraph(ctx); return builder.Build(); diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h index 72ec0178117d5..f36140b4e9783 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h @@ -16,6 +16,7 @@ limitations under the License. */ #include #include +#include #include "paddle/fluid/framework/ir/graph.h" #include "paddle/fluid/framework/lod_tensor.h" @@ -59,12 +60,15 @@ namespace paddle2cinn { class CinnGraphSymbolization { public: CinnGraphSymbolization( - int64_t graph_id, const ir::Graph& graph, - const std::map* feed_targets) - : graph_id_(graph_id), graph_(graph), feed_targets_(feed_targets) {} + int64_t graph_id, const ir::Graph& graph, const Scope& scope, + const std::map& feed_targets) + : graph_id_(graph_id), + graph_(graph), + scope_(scope), + feed_targets_(feed_targets) {} // run all CINN op in graph by topo sorting then return its NetBuilder - ::cinn::frontend::Program operator()(framework::Scope* scope) const; + ::cinn::frontend::Program operator()() const; // return the internal variable map const auto& var_map() const { return var_map_; } @@ -77,7 +81,8 @@ class CinnGraphSymbolization { private: const int64_t graph_id_; const ir::Graph& graph_; - const std::map* feed_targets_; + const Scope& scope_; + const std::map& feed_targets_; // preserve local variable map absl::flat_hash_map var_map_; @@ -85,7 +90,7 @@ class CinnGraphSymbolization { using OpMapperContext = ::cinn::frontend::OpMapperContext; // transform all paddle var desc in feed list into cinn_var_descs_ - void AddVarInfoIntoContext(OpMapperContext* ctx) const; + void AddFeedVarIntoContext(OpMapperContext* ctx) const; // transform all paddle op desc in graph into cinn op desc using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; @@ -103,6 +108,13 @@ class CinnGraphSymbolization { // preserve var desc, run the op one by one. void RunGraph(const OpMapperContext& ctx) const; + // Transform paddle scope to cinn scope + std::shared_ptr<::cinn::hlir::framework::Scope> TransformPaddleScopeToCinn() + const; + + // get the graph op's input persistable var name set + std::unordered_set GetGraphInputParameterNames() const; + friend class CinnGraphSymbolizationTest; }; From c85696ea6ad0e18d37f020056d169f76d341b77c Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Fri, 15 Oct 2021 06:23:45 +0000 Subject: [PATCH 05/16] fix some bug --- paddle/fluid/framework/paddle2cinn/CMakeLists.txt | 2 +- paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt index fece8bfc831ec..0033cb838b70b 100644 --- a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt +++ b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt @@ -1,7 +1,7 @@ cc_library(cinn_cache_key SRCS cinn_cache_key.cc DEPS boost graph graph_helper lod_tensor proto_desc) cc_library(cinn_compiled_object SRCS cinn_compiled_object.cc DEPS feed_fetch_method graph lod_tensor proto_desc) cc_library(cinn_runner SRCS cinn_runner.cc DEPS cinn_cache_key cinn_compiled_object feed_fetch_method graph lod_tensor scope) -cc_library(build_cinn_pass SRCS build_cinn_pass.cc DEPS pass subgraph_detector)cc_library(cinn_graph_symbolization SRCS cinn_graph_symbolization.cc DEPS lod_tensor graph transform_desc cinnapi.so) +cc_library(build_cinn_pass SRCS build_cinn_pass.cc DEPS pass subgraph_detector) cc_library(cinn_graph_symbolization SRCS cinn_graph_symbolization.cc DEPS lod_tensor graph transform_desc cinnapi.so) cc_test(cinn_cache_key_test SRCS cinn_cache_key_test.cc DEPS cinn_cache_key) diff --git a/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc b/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc index 0fb1effac0753..d6cbbf801df7e 100644 --- a/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc +++ b/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc @@ -83,7 +83,7 @@ void AddFeedOpAndVar(const std::unordered_set& feed_vars, var->inputs = {op}; // link feed var to cluster op - std::copy_if() for (auto* old_op : node->outputs) { + for (auto* old_op : node->outputs) { if (cluster.count(old_op)) { var->outputs.emplace_back(old_op2new_op[old_op]); } From 5df7f48ec240712884109f1648d30c0ae9182684 Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Mon, 18 Oct 2021 06:13:44 +0000 Subject: [PATCH 06/16] fix some bug by review advices --- .../framework/paddle2cinn/CMakeLists.txt | 4 +- .../framework/paddle2cinn/build_cinn_pass.cc | 106 ++++++++++++++---- .../paddle2cinn/cinn_graph_symbolization.cc | 76 ++----------- .../paddle2cinn/cinn_graph_symbolization.h | 18 +-- 4 files changed, 106 insertions(+), 98 deletions(-) diff --git a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt index 0033cb838b70b..f9e4223ccc0b0 100644 --- a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt +++ b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt @@ -2,7 +2,9 @@ cc_library(cinn_cache_key SRCS cinn_cache_key.cc DEPS boost graph graph_helper l cc_library(cinn_compiled_object SRCS cinn_compiled_object.cc DEPS feed_fetch_method graph lod_tensor proto_desc) cc_library(cinn_runner SRCS cinn_runner.cc DEPS cinn_cache_key cinn_compiled_object feed_fetch_method graph lod_tensor scope) cc_library(build_cinn_pass SRCS build_cinn_pass.cc DEPS pass subgraph_detector) -cc_library(cinn_graph_symbolization SRCS cinn_graph_symbolization.cc DEPS lod_tensor graph transform_desc cinnapi.so) + +cc_library(cinn_graph_symbolization SRCS cinn_graph_symbolization.cc DEPS lod_tensor graph transform_desc) +target_link_libraries(cinn_graph_symbolization cinnapi.so) cc_test(cinn_cache_key_test SRCS cinn_cache_key_test.cc DEPS cinn_cache_key) cc_test(cinn_runner_test SRCS cinn_runner_test.cc DEPS cinn_runner proto_desc) diff --git a/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc b/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc index d6cbbf801df7e..751ded659cad7 100644 --- a/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc +++ b/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc @@ -64,28 +64,76 @@ using framework::ir::Node; using GraphNodeVec = std::vector; using GraphNodeSet = std::unordered_set; +// Deal with subgraph's feed input var node: +// create a new input var node and it's feed op node void AddFeedOpAndVar(const std::unordered_set& feed_vars, const GraphNodeSet& cluster, const std::unordered_map& old_op2new_op, Graph* graph) { - for (auto* node : feed_vars) { + for (auto* old_var : feed_vars) { // create feed op OpDesc desc; desc.SetType("feed"); - desc.SetOutput("Out", {node->Name()}); + desc.SetOutput("Out", {old_var->Name()}); auto op = graph->CreateOpNode(&desc); // create new feed var node (SSAGraph) - auto var = graph->CreateVarNode(node->Var()); + auto var = graph->CreateVarNode(old_var->Var()); // link feed op and feed var op->outputs = {var}; var->inputs = {op}; // link feed var to cluster op - for (auto* old_op : node->outputs) { + var->outputs.clear(); + for (auto* old_op : old_var->outputs) { if (cluster.count(old_op)) { var->outputs.emplace_back(old_op2new_op[old_op]); + old_op2new_op[old_op]->inputs.emplace_back(var); + } + // Do not need relink old op or old var here, they will be + // fixed in RemoveLinkFromCluster, here we just deal with + // new subgraph's node. + } + } +} + +// Deal with subgraph's parameter var node: +// create a new input var node, it's data will get by scope, +// so it don't need feed op +void AddParamVar(const std::unordered_set& param_vars, + const GraphNodeSet& cluster, + const std::unordered_map& old_op2new_op, + Graph* graph) { + for (auto* old_var : param_vars) { + auto var = graph->CreateVarNode(old_var->Var()); + + var->inputs.clear(); + var->outputs.clear(); + for (auto* old_op : old_var->outputs) { + if (cluster.count(old_op)) { + var->outputs.emplace_back(old_op2new_op[old_op]); + old_op2new_op[old_op]->inputs.emplace_back(var); + } + } + } +} + +// Deal with subgraph's outputs var node: +// create a new output var node and it's fetch op +void AddOutputVar(const std::unordered_set& output_vars, + const GraphNodeSet& cluster, + const std::unordered_map& old_op2new_op, + Graph* graph) { + for (auto* old_var : output_vars) { + auto var = graph->CreateVarNode(old_var->Var()); + + var->inputs.clear(); + var->outputs.clear(); + for (auto* old_op : old_var->inputs) { + if (cluster.count(old_op)) { + var->inputs.emplace_back(old_op2new_op[old_op]); + old_op2new_op[old_op]->outputs.emplace_back(var); } } } @@ -103,16 +151,21 @@ std::unique_ptr CreateNewSubGraph(const GraphNodeSet& cluster, std::unordered_map old_op2new_op; for (auto* op : cluster) { auto sub_node = sub_graph->CreateOpNode(op->Op()); + sub_node->inputs.clear(); + sub_node->outputs.clear(); old_op2new_op[op] = sub_node; } std::unordered_map old_var2new_var; for (auto* var : cluster_internals) { auto sub_node = sub_graph->CreateVarNode(var->Var()); + sub_node->inputs.clear(); + sub_node->outputs.clear(); old_var2new_var[var] = sub_node; } std::unordered_set need_feed_vars; + std::unordered_set param_vars, output_vars; // the subgraph is independently, so here we only need link // to the node in new subgraph, and discard the link to // out-graph. @@ -122,22 +175,26 @@ std::unique_ptr CreateNewSubGraph(const GraphNodeSet& cluster, old_op2new_op[op]->inputs.emplace_back(old_var2new_var[var]); } else if (cluster_inputs.count(var)) { if (var->Var()->IsParameter()) { + // Parameters have been preserved in scope, compared to feed var, + // param just need add new var and don't need add feed op. + // The var is used for check whether we need preserve the tensor + // when transform paddle scope to CINN scope. + param_vars.insert(var); + } else { // When the var is subgraph input and the var is not parameter, // we need add a new feed op to feed the var. need_feed_vars.insert(var); - } else { - // Parameters have been preserved in scope, so we do not feed - // and create new var node, re-use the old graph's var node - // is satisfactory. - // The var is used for check whether we need preserve the tensor - // when transform paddle scope to CINN scope. - old_op2new_op[op]->inputs.emplace_back(var); } } } for (auto* var : op->outputs) { if (cluster_internals.count(var)) { old_op2new_op[op]->outputs.emplace_back(old_var2new_var[var]); + } else { + // Create new output var node to guarantee the independency of + // subgraph. In other words, the subgraph has no connection with + // other graph, even the input graph. + output_vars.insert(var); } } } @@ -162,10 +219,12 @@ std::unique_ptr CreateNewSubGraph(const GraphNodeSet& cluster, // This interface is used to classify all variables involved in a cluster into // three types: inputs, outputs, and internals. -// Specially, the internal node is a node that only used by sub-graph, and +// The input node is some subgraph op's input but not any subgraph op's output. +// The output node is some subgraph op's output and some out-graph op's input. +// Specially, the internal node is a node that only used by subgraph, and // out-graph should not using this node at all. -// inputs & outputs & internals == NULL -// inputs | outputs | internals == all graph node +// cluster_inputs & cluster_outputs & cluster_internals == NULL +// cluster_outputs | cluster_internals == all graph op's outputs node void AnalyseClusterVariables(const GraphNodeSet& cluster, GraphNodeSet* cluster_inputs, GraphNodeSet* cluster_outputs, @@ -198,10 +257,6 @@ void AnalyseClusterVariables(const GraphNodeSet& cluster, } } - // if a output node also exists in input list, remove. - for (auto* var_node : *cluster_inputs) { - cluster_outputs->erase(var_node); - } // if a output node also exists in internal list, remove. for (auto* var_node : *cluster_internals) { cluster_outputs->erase(var_node); @@ -250,14 +305,21 @@ void RemoveLinkFromCluster(const GraphNodeSet& cluster, // removing useless link from cluster_inputs to cluster for (auto* var_node : cluster_inputs) { - auto preserved_nodes = get_preserved_ops(var_node->outputs); - var_node->outputs.assign(preserved_nodes.begin(), preserved_nodes.end()); + auto preserved_ops = get_preserved_ops(var_node->outputs); + var_node->outputs.assign(preserved_ops.begin(), preserved_ops.end()); + // The cluster_inputs var nodes are not any subgraph op's output, + // so it's input op must be out-graph op. } // removing useless link from cluster to cluster_outputs for (auto* var_node : cluster_outputs) { - auto preserved_nodes = get_preserved_ops(var_node->inputs); - var_node->inputs.assign(preserved_nodes.begin(), preserved_nodes.end()); + auto preserved_ops = get_preserved_ops(var_node->inputs); + var_node->inputs.assign(preserved_ops.begin(), preserved_ops.end()); + + // Note that cluster_outputs var node maybe some subgraph op's input, + // here we need remove them. + preserved_ops = get_preserved_ops(var_node->outputs); + var_node->outputs.assign(preserved_ops.begin(), preserved_ops.end()); } } diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc index a16eb8b548f59..3a888703e50f3 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc @@ -35,7 +35,7 @@ using CinnTensor = ::cinn::hlir::framework::Tensor; namespace utils { -auto GetCinnFeedInfoFromTensor(const Tensor& tensor) { +OpMapperContext::FeedInfo GetCinnFeedInfoFromTensor(const Tensor& tensor) { OpMapperContext::FeedInfo info; const auto& dim = tensor.dims(); for (int i = 0; i < dim.size(); i++) { @@ -60,7 +60,8 @@ void TransformPaddleVariableToCinn( } // namespace utils // get the graph's op input Parameter var name set -auto CinnGraphSymbolization::GetGraphInputParameterNames() const { +std::unordered_set +CinnGraphSymbolization::GetGraphInputParameterNames() const { std::unordered_set names; for (auto* node : graph_.Nodes()) { @@ -80,7 +81,8 @@ auto CinnGraphSymbolization::GetGraphInputParameterNames() const { // Transform paddle scope to cinn, note that we only preserve the graph’s // input parameter variable and ignore others. -auto CinnGraphSymbolization::TransformPaddleScopeToCinn() const { +std::shared_ptr<::cinn::hlir::framework::Scope> +CinnGraphSymbolization::TransformPaddleScopeToCinn() const { auto cinn_scope = ::cinn::hlir::framework::Scope::Create(); // get the graph's input parameter variable name list @@ -112,67 +114,10 @@ void CinnGraphSymbolization::AddFeedVarIntoContext(OpMapperContext* ctx) const { } } -std::vector CinnGraphSymbolization::TopoSortGraph() const { - std::vector cluster_sorted; - - std::unordered_set cluster_set; - const auto& nodes = graph_.Nodes(); - std::copy_if(nodes.begin(), nodes.end(), - std::inserter(cluster_set, cluster_set.begin()), - [](Node* node) { return node->IsOp(); }); - - absl::flat_hash_map indegree; - absl::flat_hash_map> adj_list; - std::queue topo_queue; - - // record all op's input op and output op - for (auto* n : cluster_set) { - // the op's input is var - for (auto* in_var : n->inputs) { - // the var's input is op - for (auto* in_op : in_var->inputs) { - if (cluster_set.find(in_op) != cluster_set.end()) { - ++indegree[n]; - ++adj_list[in_op][n]; - } - } - } - } - - // find topology entrance - for (auto* n : cluster_set) { - if (indegree[n] == 0) { - topo_queue.push(n); - } - } - - // topological sorting - while (!topo_queue.empty()) { - auto* cur_op = topo_queue.front(); - topo_queue.pop(); - - cluster_sorted.emplace_back(cur_op); - for (const auto& adj_pair : adj_list[cur_op]) { - // decrease output op's in-degree - indegree.at(adj_pair.first) -= adj_pair.second; - - // if empty, push into queue - if (indegree.at(adj_pair.first) == 0) { - topo_queue.push(adj_pair.first); - } - } - } - - PADDLE_ENFORCE_EQ(cluster_sorted.size(), cluster_set.size(), - platform::errors::PreconditionNotMet( - "Cluster Sub-Graph shouldn't contain cycle.")); - return cluster_sorted; -} - auto CinnGraphSymbolization::TransformAllGraphOpToCinn() const { std::vector> cinn_op_descs_; - const auto& sorted_ops = TopoSortGraph(); + const auto& sorted_ops = ir::TopologySortOperations(graph_); for (auto* node : sorted_ops) { cinn_op_descs_.emplace_back(std::make_unique()); auto& cinn_desc = cinn_op_descs_.back(); @@ -203,19 +148,14 @@ void CinnGraphSymbolization::RunGraph(const OpMapperContext& ctx) const { } ::cinn::frontend::Program CinnGraphSymbolization::operator()() const { - std::string builder_name = "graph_"; - builder_name.append(std::to_string(graph_id_)); - builder_name.append("_of_"); - static uint64_t unique_invoke_number = 0; - builder_name.append(std::to_string(unique_invoke_number++)); + std::string builder_name = "NetBuilder_of_graph_" + std::to_string(graph_id_); VLOG(4) << "NetBuilder Name " << builder_name; ::cinn::frontend::NetBuilder builder(builder_name); - auto target = ::cinn::common::DefaultHostTarget(); auto cinn_scope = TransformPaddleScopeToCinn(); - OpMapperContext ctx(*cinn_scope, target, &builder, &var_map_, + OpMapperContext ctx(*cinn_scope, target_, &builder, &var_map_, &var_model_to_program_map_); AddFeedVarIntoContext(&ctx); diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h index f36140b4e9783..53e9abde76c87 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h @@ -30,7 +30,8 @@ namespace framework { namespace paddle2cinn { // An executor accept subgraph which is generated by BuildCinnPass, -// run each op's CINN Op Mapper, finally return the graph's CINN NetBuilder. +// run each op's CINN Op Mapper, finally return a frontend::Program object +// corresponding to the subgraph. // // Parameter: // 1. graph_id: @@ -61,20 +62,26 @@ class CinnGraphSymbolization { public: CinnGraphSymbolization( int64_t graph_id, const ir::Graph& graph, const Scope& scope, + const ::cinn::common::Target& target, const std::map& feed_targets) : graph_id_(graph_id), graph_(graph), scope_(scope), + target_(target), feed_targets_(feed_targets) {} // run all CINN op in graph by topo sorting then return its NetBuilder ::cinn::frontend::Program operator()() const; // return the internal variable map - const auto& var_map() const { return var_map_; } + const absl::flat_hash_map& var_map() + const { + return var_map_; + } // return the map from the variable name in paddle model to cinn program. - const auto& var_model_to_program_map() const { + const absl::flat_hash_map& + var_model_to_program_map() const { return var_model_to_program_map_; } @@ -82,6 +89,7 @@ class CinnGraphSymbolization { const int64_t graph_id_; const ir::Graph& graph_; const Scope& scope_; + const ::cinn::common::Target& target_; const std::map& feed_targets_; // preserve local variable map @@ -96,10 +104,6 @@ class CinnGraphSymbolization { using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; std::vector> TransformAllGraphOpToCinn() const; - // topo sort graph and return sorted op list, - // called in TransformAllOpDescToCinn. - std::vector TopoSortGraph() const; - // RunOp accept OpDesc and global run context then run // it's kernel registered in OpMapper. // called in RunGraph. From 5f9535d61ad0c5255b3b5df0cb6e9393cf2200f3 Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Mon, 18 Oct 2021 06:23:02 +0000 Subject: [PATCH 07/16] optimize code problem --- .../framework/paddle2cinn/CMakeLists.txt | 2 +- .../paddle2cinn/cinn_graph_symbolization.cc | 27 ++++++++++--------- .../paddle2cinn/cinn_graph_symbolization.h | 2 +- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt index f9e4223ccc0b0..bc767ad80bb49 100644 --- a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt +++ b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt @@ -3,7 +3,7 @@ cc_library(cinn_compiled_object SRCS cinn_compiled_object.cc DEPS feed_fetch_met cc_library(cinn_runner SRCS cinn_runner.cc DEPS cinn_cache_key cinn_compiled_object feed_fetch_method graph lod_tensor scope) cc_library(build_cinn_pass SRCS build_cinn_pass.cc DEPS pass subgraph_detector) -cc_library(cinn_graph_symbolization SRCS cinn_graph_symbolization.cc DEPS lod_tensor graph transform_desc) +cc_library(cinn_graph_symbolization SRCS cinn_graph_symbolization.cc DEPS lod_tensor graph graph_helper transform_desc) target_link_libraries(cinn_graph_symbolization cinnapi.so) cc_test(cinn_cache_key_test SRCS cinn_cache_key_test.cc DEPS cinn_cache_key) diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc index 3a888703e50f3..a72a8753b96da 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc @@ -19,6 +19,7 @@ limitations under the License. */ #include #include +#include "paddle/fluid/framework/ir/graph_helper.h" #include "paddle/fluid/framework/paddle2cinn/transform_desc.h" #include "paddle/fluid/framework/variable.h" @@ -59,6 +60,16 @@ void TransformPaddleVariableToCinn( } } // namespace utils +void CinnGraphSymbolization::AddFeedInfoIntoContext( + OpMapperContext* ctx) const { + for (auto& feed_pair : feed_targets_) { + const auto& feed_name = feed_pair.first; + const auto* tensor = feed_pair.second; + + ctx.AddFeedInfo(feed_name, utils::GetCinnFeedInfoFromTensor(*tensor)); + } +} + // get the graph's op input Parameter var name set std::unordered_set CinnGraphSymbolization::GetGraphInputParameterNames() const { @@ -105,16 +116,8 @@ CinnGraphSymbolization::TransformPaddleScopeToCinn() const { return cinn_scope; } -void CinnGraphSymbolization::AddFeedVarIntoContext(OpMapperContext* ctx) const { - for (auto& feed_pair : feed_targets_) { - const auto& feed_name = feed_pair.first; - const auto* tensor = feed_pair.second; - - ctx.AddFeedInfo(feed_name, utils::GetCinnFeedInfoFromTensor(*tensor)); - } -} - -auto CinnGraphSymbolization::TransformAllGraphOpToCinn() const { +std::vector> +CinnGraphSymbolization::TransformAllGraphOpToCinn() const { std::vector> cinn_op_descs_; const auto& sorted_ops = ir::TopologySortOperations(graph_); @@ -124,7 +127,7 @@ auto CinnGraphSymbolization::TransformAllGraphOpToCinn() const { TransformOpDescToCinn(node->Op(), cinn_desc.get()); } - return std::move(cinn_op_descs_); + return cinn_op_descs_; } void CinnGraphSymbolization::RunOp(const CinnOpDesc& op_desc, @@ -158,7 +161,7 @@ ::cinn::frontend::Program CinnGraphSymbolization::operator()() const { OpMapperContext ctx(*cinn_scope, target_, &builder, &var_map_, &var_model_to_program_map_); - AddFeedVarIntoContext(&ctx); + AddFeedInfoIntoContext(&ctx); RunGraph(ctx); return builder.Build(); diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h index 53e9abde76c87..fcfb1e704a7b3 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h @@ -98,7 +98,7 @@ class CinnGraphSymbolization { using OpMapperContext = ::cinn::frontend::OpMapperContext; // transform all paddle var desc in feed list into cinn_var_descs_ - void AddFeedVarIntoContext(OpMapperContext* ctx) const; + void AddFeedInfoIntoContext(OpMapperContext* ctx) const; // transform all paddle op desc in graph into cinn op desc using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; From 47478d310d95a693ece9c265f898c7ed0261ffe1 Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Mon, 18 Oct 2021 07:29:08 +0000 Subject: [PATCH 08/16] revert build_cinn_pass and move the change to https://github.com/PaddlePaddle/Paddle/pull/36503 --- .../framework/paddle2cinn/build_cinn_pass.cc | 132 ++---------------- 1 file changed, 13 insertions(+), 119 deletions(-) diff --git a/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc b/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc index 751ded659cad7..ffdbb46bd7c06 100644 --- a/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc +++ b/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc @@ -64,86 +64,10 @@ using framework::ir::Node; using GraphNodeVec = std::vector; using GraphNodeSet = std::unordered_set; -// Deal with subgraph's feed input var node: -// create a new input var node and it's feed op node -void AddFeedOpAndVar(const std::unordered_set& feed_vars, - const GraphNodeSet& cluster, - const std::unordered_map& old_op2new_op, - Graph* graph) { - for (auto* old_var : feed_vars) { - // create feed op - OpDesc desc; - desc.SetType("feed"); - desc.SetOutput("Out", {old_var->Name()}); - auto op = graph->CreateOpNode(&desc); - - // create new feed var node (SSAGraph) - auto var = graph->CreateVarNode(old_var->Var()); - - // link feed op and feed var - op->outputs = {var}; - var->inputs = {op}; - - // link feed var to cluster op - var->outputs.clear(); - for (auto* old_op : old_var->outputs) { - if (cluster.count(old_op)) { - var->outputs.emplace_back(old_op2new_op[old_op]); - old_op2new_op[old_op]->inputs.emplace_back(var); - } - // Do not need relink old op or old var here, they will be - // fixed in RemoveLinkFromCluster, here we just deal with - // new subgraph's node. - } - } -} - -// Deal with subgraph's parameter var node: -// create a new input var node, it's data will get by scope, -// so it don't need feed op -void AddParamVar(const std::unordered_set& param_vars, - const GraphNodeSet& cluster, - const std::unordered_map& old_op2new_op, - Graph* graph) { - for (auto* old_var : param_vars) { - auto var = graph->CreateVarNode(old_var->Var()); - - var->inputs.clear(); - var->outputs.clear(); - for (auto* old_op : old_var->outputs) { - if (cluster.count(old_op)) { - var->outputs.emplace_back(old_op2new_op[old_op]); - old_op2new_op[old_op]->inputs.emplace_back(var); - } - } - } -} - -// Deal with subgraph's outputs var node: -// create a new output var node and it's fetch op -void AddOutputVar(const std::unordered_set& output_vars, - const GraphNodeSet& cluster, - const std::unordered_map& old_op2new_op, - Graph* graph) { - for (auto* old_var : output_vars) { - auto var = graph->CreateVarNode(old_var->Var()); - - var->inputs.clear(); - var->outputs.clear(); - for (auto* old_op : old_var->inputs) { - if (cluster.count(old_op)) { - var->inputs.emplace_back(old_op2new_op[old_op]); - old_op2new_op[old_op]->outputs.emplace_back(var); - } - } - } -} - // Create new subgraph with and op nodes are cluster nodes, and all // var node are from internal nodes -std::unique_ptr CreateNewSubGraph(const GraphNodeSet& cluster, - const GraphNodeSet& cluster_internals, - const GraphNodeSet& cluster_inputs) { +std::unique_ptr CreateNewSubGraph( + const GraphNodeSet& cluster, const GraphNodeSet& cluster_internals) { // Graph's constructor must has one parameter, and in our code, // the ProgramDesc is useless, so here we pass a temporary object. auto sub_graph = std::make_unique(framework::ProgramDesc()); @@ -151,21 +75,15 @@ std::unique_ptr CreateNewSubGraph(const GraphNodeSet& cluster, std::unordered_map old_op2new_op; for (auto* op : cluster) { auto sub_node = sub_graph->CreateOpNode(op->Op()); - sub_node->inputs.clear(); - sub_node->outputs.clear(); old_op2new_op[op] = sub_node; } std::unordered_map old_var2new_var; for (auto* var : cluster_internals) { auto sub_node = sub_graph->CreateVarNode(var->Var()); - sub_node->inputs.clear(); - sub_node->outputs.clear(); old_var2new_var[var] = sub_node; } - std::unordered_set need_feed_vars; - std::unordered_set param_vars, output_vars; // the subgraph is independently, so here we only need link // to the node in new subgraph, and discard the link to // out-graph. @@ -173,34 +91,15 @@ std::unique_ptr CreateNewSubGraph(const GraphNodeSet& cluster, for (auto* var : op->inputs) { if (cluster_internals.count(var)) { old_op2new_op[op]->inputs.emplace_back(old_var2new_var[var]); - } else if (cluster_inputs.count(var)) { - if (var->Var()->IsParameter()) { - // Parameters have been preserved in scope, compared to feed var, - // param just need add new var and don't need add feed op. - // The var is used for check whether we need preserve the tensor - // when transform paddle scope to CINN scope. - param_vars.insert(var); - } else { - // When the var is subgraph input and the var is not parameter, - // we need add a new feed op to feed the var. - need_feed_vars.insert(var); - } } } for (auto* var : op->outputs) { if (cluster_internals.count(var)) { old_op2new_op[op]->outputs.emplace_back(old_var2new_var[var]); - } else { - // Create new output var node to guarantee the independency of - // subgraph. In other words, the subgraph has no connection with - // other graph, even the input graph. - output_vars.insert(var); } } } - AddFeedOpAndVar(need_feed_vars, cluster, old_op2new_op, sub_graph.get()); - for (auto* var : cluster_internals) { for (auto* op : var->inputs) { if (cluster.count(op)) { @@ -219,12 +118,10 @@ std::unique_ptr CreateNewSubGraph(const GraphNodeSet& cluster, // This interface is used to classify all variables involved in a cluster into // three types: inputs, outputs, and internals. -// The input node is some subgraph op's input but not any subgraph op's output. -// The output node is some subgraph op's output and some out-graph op's input. -// Specially, the internal node is a node that only used by subgraph, and +// Specially, the internal node is a node that only used by sub-graph, and // out-graph should not using this node at all. -// cluster_inputs & cluster_outputs & cluster_internals == NULL -// cluster_outputs | cluster_internals == all graph op's outputs node +// inputs & outputs & internals == NULL +// inputs | outputs | internals == all graph node void AnalyseClusterVariables(const GraphNodeSet& cluster, GraphNodeSet* cluster_inputs, GraphNodeSet* cluster_outputs, @@ -257,6 +154,10 @@ void AnalyseClusterVariables(const GraphNodeSet& cluster, } } + // if a output node also exists in input list, remove. + for (auto* var_node : *cluster_inputs) { + cluster_outputs->erase(var_node); + } // if a output node also exists in internal list, remove. for (auto* var_node : *cluster_internals) { cluster_outputs->erase(var_node); @@ -305,21 +206,14 @@ void RemoveLinkFromCluster(const GraphNodeSet& cluster, // removing useless link from cluster_inputs to cluster for (auto* var_node : cluster_inputs) { - auto preserved_ops = get_preserved_ops(var_node->outputs); - var_node->outputs.assign(preserved_ops.begin(), preserved_ops.end()); - // The cluster_inputs var nodes are not any subgraph op's output, - // so it's input op must be out-graph op. + auto preserved_nodes = get_preserved_ops(var_node->outputs); + var_node->outputs.assign(preserved_nodes.begin(), preserved_nodes.end()); } // removing useless link from cluster to cluster_outputs for (auto* var_node : cluster_outputs) { - auto preserved_ops = get_preserved_ops(var_node->inputs); - var_node->inputs.assign(preserved_ops.begin(), preserved_ops.end()); - - // Note that cluster_outputs var node maybe some subgraph op's input, - // here we need remove them. - preserved_ops = get_preserved_ops(var_node->outputs); - var_node->outputs.assign(preserved_ops.begin(), preserved_ops.end()); + auto preserved_nodes = get_preserved_ops(var_node->inputs); + var_node->inputs.assign(preserved_nodes.begin(), preserved_nodes.end()); } } From 96075e3fe80dd5824f5571b2d42ea34a493fd1aa Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Tue, 19 Oct 2021 04:13:52 +0000 Subject: [PATCH 09/16] fix some bug after co-compilation --- .../framework/paddle2cinn/CMakeLists.txt | 4 +- .../paddle2cinn/cinn_graph_symbolization.cc | 28 ++-- .../paddle2cinn/cinn_graph_symbolization.h | 4 +- .../cinn_graph_symbolization_test.cc | 152 ++++++++++++++++-- 4 files changed, 155 insertions(+), 33 deletions(-) diff --git a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt index bc767ad80bb49..7fc37bd94d95a 100644 --- a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt +++ b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt @@ -2,9 +2,7 @@ cc_library(cinn_cache_key SRCS cinn_cache_key.cc DEPS boost graph graph_helper l cc_library(cinn_compiled_object SRCS cinn_compiled_object.cc DEPS feed_fetch_method graph lod_tensor proto_desc) cc_library(cinn_runner SRCS cinn_runner.cc DEPS cinn_cache_key cinn_compiled_object feed_fetch_method graph lod_tensor scope) cc_library(build_cinn_pass SRCS build_cinn_pass.cc DEPS pass subgraph_detector) - -cc_library(cinn_graph_symbolization SRCS cinn_graph_symbolization.cc DEPS lod_tensor graph graph_helper transform_desc) -target_link_libraries(cinn_graph_symbolization cinnapi.so) +cc_library(cinn_graph_symbolization SRCS cinn_graph_symbolization.cc DEPS lod_tensor graph graph_helper transform_desc cinn) cc_test(cinn_cache_key_test SRCS cinn_cache_key_test.cc DEPS cinn_cache_key) cc_test(cinn_runner_test SRCS cinn_runner_test.cc DEPS cinn_runner proto_desc) diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc index a72a8753b96da..fb9f6e003dc81 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc @@ -33,6 +33,8 @@ namespace paddle2cinn { using ir::Graph; using ir::Node; using CinnTensor = ::cinn::hlir::framework::Tensor; +using OpMapperContext = ::cinn::frontend::OpMapperContext; +using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; namespace utils { @@ -40,7 +42,7 @@ OpMapperContext::FeedInfo GetCinnFeedInfoFromTensor(const Tensor& tensor) { OpMapperContext::FeedInfo info; const auto& dim = tensor.dims(); for (int i = 0; i < dim.size(); i++) { - info.shape.emplace_back(sttic_cast(dim[i])); + info.shape.emplace_back(static_cast(dim[i])); } auto cinn_var_type = TransformVarTypeToCinn(tensor.type()); @@ -55,8 +57,8 @@ void TransformPaddleVariableToCinn( auto feed_info = GetCinnFeedInfoFromTensor(pd_tensor); // here we only need preserve dtype and shape, do not need preserve data - cinn_tensor.set_type(feed_info.type); - cinn_tensor.Resize(::cinn::hlir::framework::Shape(feed_info.shape)); + cinn_tensor->set_type(feed_info.type); + cinn_tensor->Resize(::cinn::hlir::framework::Shape(feed_info.shape)); } } // namespace utils @@ -66,7 +68,7 @@ void CinnGraphSymbolization::AddFeedInfoIntoContext( const auto& feed_name = feed_pair.first; const auto* tensor = feed_pair.second; - ctx.AddFeedInfo(feed_name, utils::GetCinnFeedInfoFromTensor(*tensor)); + ctx->AddFeedInfo(feed_name, utils::GetCinnFeedInfoFromTensor(*tensor)); } } @@ -107,8 +109,8 @@ CinnGraphSymbolization::TransformPaddleScopeToCinn() const { // scope accepte the CINN format name, so here we need transform // paddle format name to CINN format. - auto* cinn_var = cinn_scope->Var( - ::cinn::utils::TransValidVarName(var.name())); + auto* cinn_var = + cinn_scope->Var(::cinn::utils::TransValidVarName(var_name)); utils::TransformPaddleVariableToCinn(*pd_var, cinn_var); } @@ -118,16 +120,16 @@ CinnGraphSymbolization::TransformPaddleScopeToCinn() const { std::vector> CinnGraphSymbolization::TransformAllGraphOpToCinn() const { - std::vector> cinn_op_descs_; + std::vector> cinn_op_descs; const auto& sorted_ops = ir::TopologySortOperations(graph_); for (auto* node : sorted_ops) { - cinn_op_descs_.emplace_back(std::make_unique()); - auto& cinn_desc = cinn_op_descs_.back(); + cinn_op_descs.emplace_back(std::make_unique()); + auto& cinn_desc = cinn_op_descs.back(); TransformOpDescToCinn(node->Op(), cinn_desc.get()); } - return cinn_op_descs_; + return cinn_op_descs; } void CinnGraphSymbolization::RunOp(const CinnOpDesc& op_desc, @@ -142,15 +144,15 @@ void CinnGraphSymbolization::RunOp(const CinnOpDesc& op_desc, } void CinnGraphSymbolization::RunGraph(const OpMapperContext& ctx) const { - auto cinn_op_descs_ = TransformAllGraphOpToCinn(); + auto cinn_op_descs = TransformAllGraphOpToCinn(); // run the CINN op one by one, note that all ops // have been sorted at constructor. - for (auto* op_desc : cinn_op_descs_) { + for (auto& op_desc : cinn_op_descs) { RunOp(*op_desc, ctx); } } -::cinn::frontend::Program CinnGraphSymbolization::operator()() const { +::cinn::frontend::Program CinnGraphSymbolization::operator()() { std::string builder_name = "NetBuilder_of_graph_" + std::to_string(graph_id_); VLOG(4) << "NetBuilder Name " << builder_name; diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h index fcfb1e704a7b3..82046faa07c6a 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h @@ -71,7 +71,7 @@ class CinnGraphSymbolization { feed_targets_(feed_targets) {} // run all CINN op in graph by topo sorting then return its NetBuilder - ::cinn::frontend::Program operator()() const; + ::cinn::frontend::Program operator()(); // return the internal variable map const absl::flat_hash_map& var_map() @@ -119,7 +119,7 @@ class CinnGraphSymbolization { // get the graph op's input persistable var name set std::unordered_set GetGraphInputParameterNames() const; - friend class CinnGraphSymbolizationTest; + friend class CinnGraphSymbolizationForTest; }; } // namespace paddle2cinn diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc index 3af6432a0310e..58367b62020ab 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc @@ -20,31 +20,153 @@ namespace paddle { namespace framework { namespace paddle2cinn { +using ir::Graph; +using ir::Node; +using CinnTensor = ::cinn::hlir::framework::Tensor; +using OpMapperContext = ::cinn::frontend::OpMapperContext; +using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; + // only used for test CinnGraphSymbolization class -class CinnGraphSymbolizationTest : public ::testing::Test { +class CinnGraphSymbolizationForTest { public: - void AddFeedVarIntoCinn(const OpMapperContext& ctx) const; + void AddFeedInfoIntoContext(CinnGraphSymbolization* cinn_symbol_, + OpMapperContext* ctx) const { + cinn_symbol_->AddFeedInfoIntoContext(ctx); + } + + std::vector> TransformAllGraphOpToCinn( + CinnGraphSymbolization* cinn_symbol_) const { + return cinn_symbol_->TransformAllGraphOpToCinn(); + } + + void RunOp(CinnGraphSymbolization* cinn_symbol_, const CinnOpDesc& op_desc, + const OpMapperContext& ctx) const { + cinn_symbol_->RunOp(op_desc, ctx); + } + + std::shared_ptr<::cinn::hlir::framework::Scope> TransformPaddleScopeToCinn( + CinnGraphSymbolization* cinn_symbol_) const { + return cinn_symbol_->TransformPaddleScopeToCinn(); + } + + void RunGraph(CinnGraphSymbolization* cinn_symbol_, + const OpMapperContext& ctx) const { + cinn_symbol_->RunGraph(ctx); + } +}; + +std::unique_ptr BuildAllOpSupportCinnGraph() { + ProgramDesc prog; + auto g = std::make_unique(prog); + + // v1 -- + // | --> mul --> v3 -- + // v2 -- | --> add --> v5 --> relu --> v6 + // v4 -- + + OpDesc add_op; + add_op.SetType("add"); + OpDesc mul_op; + mul_op.SetType("mul"); + OpDesc relu_op; + relu_op.SetType("relu"); + + VarDesc var1("var1"); + VarDesc var2("var2"); + var2.SetPersistable(true); + var2.SetIsParameter(true); + VarDesc var3("var3"); + VarDesc var4("var4"); + VarDesc var5("var5"); + VarDesc var6("var6"); + + ir::Node* add = g->CreateOpNode(&add_op); + ir::Node* mul = g->CreateOpNode(&mul_op); + ir::Node* relu = g->CreateOpNode(&relu_op); - using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; - std::vector> TransformAllGraphOpToCinn() const; + ir::Node* v1 = g->CreateVarNode(&var1); + ir::Node* v2 = g->CreateVarNode(&var2); + ir::Node* v3 = g->CreateVarNode(&var3); + ir::Node* v4 = g->CreateVarNode(&var4); + ir::Node* v5 = g->CreateVarNode(&var5); + ir::Node* v6 = g->CreateVarNode(&var6); - std::vector TopoSortGraph() const; + // fill op node + mul->inputs = {v1, v2}; + mul->outputs = {v3}; + add->inputs = {v3, v4}; + add->outputs = {v5}; + relu->inputs = {v5}; + relu->outputs = {v6}; - void RunOp(const CinnOpDesc& op_desc, const OpMapperContext& ctx) const; + // fill variable node + v1->outputs = {mul}; + v2->outputs = {mul}; - void RunGraph(const OpMapperContext& ctx) const; + v3->inputs = {mul}; + v3->outputs = {add}; - protected: - void SetUp() override { - // TODO(jiangcheng05): initial CinnGraphSymbolization + v4->outputs = {add}; + + v5->inputs = {add}; + v5->outputs = {relu}; + + v6->inputs = {relu}; + + return g; +} + +::cinn::common::Target CreateDefaultTarget(bool use_gpu = false) { +#ifdef PADDLE_WITH_CUDA + if (use_gpu) { + return ::cinn::common::DefaultNVGPUTarget(); } +#endif + return ::cinn::common::DefaultHostTarget(); +} - private: - CinnGraphSymbolization cinn_symbol_; -}; +std::unique_ptr CreateScope() { + std::unique_ptr scope; + scope->Var("var2"); + return scope; +} + +std::map CreateFeedTarget() { + std::map feed_targets; + + auto create_tensor = []() { + LoDTensor tensor; + DDim dims = {256, 1024, 1024}; + tensor.Resize(dims); + return tensor; + }; +#define FillFeedList(Name) feed_targets[#Name] = create_tensor(); + + FillFeedList(var1) FillFeedList(var3) FillFeedList(var4) FillFeedList(var5) + FillFeedList(var6) +#undef FillFeedList +} + +std::map ConvertFeedType( + const std::map& feed_targets) { + std::map res; + for (auto& feed_pair : feed_targets) { + res[feed_pair.first] = &feed_pair.second; + } + return res; +} + +TEST(CinnGraphSymbolizationTest, basic) { + auto graph = BuildAllOpSupportCinnGraph(); + auto scope = CreateScope(); + auto target = CreateDefaultTarget(); + auto feed_object = CreateFeedTarget(); + auto feed_targets = ConvertFeedType(feed_object); -TEST_F(CinnGraphSymbolizationTest, basic) { - // TODO(jiangcheng05): fill the single test code + CinnGraphSymbolization symbol(100, *graph, *scope, target, feed_targets); + ASSERT_NO_THROW(symbol()); + ASSERT_FALSE(symbol.var_map().empty()); + ASSERT_FALSE(symbol.var_model_to_program_map().empty()); } } // namespace paddle2cinn From 2d1abd9c7e92d91c7cd5c8464a2e9e3402801ac4 Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Tue, 19 Oct 2021 07:50:10 +0000 Subject: [PATCH 10/16] perfect single test script --- .../framework/paddle2cinn/CMakeLists.txt | 2 + .../cinn_graph_symbolization_test.cc | 309 +++++++++++------- 2 files changed, 200 insertions(+), 111 deletions(-) diff --git a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt index 7fc37bd94d95a..bb3bd6ec8b457 100644 --- a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt +++ b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt @@ -2,10 +2,12 @@ cc_library(cinn_cache_key SRCS cinn_cache_key.cc DEPS boost graph graph_helper l cc_library(cinn_compiled_object SRCS cinn_compiled_object.cc DEPS feed_fetch_method graph lod_tensor proto_desc) cc_library(cinn_runner SRCS cinn_runner.cc DEPS cinn_cache_key cinn_compiled_object feed_fetch_method graph lod_tensor scope) cc_library(build_cinn_pass SRCS build_cinn_pass.cc DEPS pass subgraph_detector) +cc_library(transform_desc SRCS transform_desc.cc DEPS proto_desc cinn) cc_library(cinn_graph_symbolization SRCS cinn_graph_symbolization.cc DEPS lod_tensor graph graph_helper transform_desc cinn) cc_test(cinn_cache_key_test SRCS cinn_cache_key_test.cc DEPS cinn_cache_key) cc_test(cinn_runner_test SRCS cinn_runner_test.cc DEPS cinn_runner proto_desc) cc_test(cinn_compiled_object_test SRCS cinn_compiled_object_test.cc DEPS cinn_compiled_object) cc_test(test_build_cinn_pass SRCS build_cinn_pass_test.cc DEPS build_cinn_pass) +cc_test(test_transform_desc SRCS transform_desc_test.cc DEPS transform_desc) cc_test(test_cinn_graph_symbolization SRCS cinn_graph_symbolization_test.cc DEPS cinn_graph_symbolization) diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc index 58367b62020ab..e93a975a3b5dd 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc @@ -25,148 +25,235 @@ using ir::Node; using CinnTensor = ::cinn::hlir::framework::Tensor; using OpMapperContext = ::cinn::frontend::OpMapperContext; using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; +using ::cinn::frontend::NetBuilder; // only used for test CinnGraphSymbolization class class CinnGraphSymbolizationForTest { public: - void AddFeedInfoIntoContext(CinnGraphSymbolization* cinn_symbol_, - OpMapperContext* ctx) const { + explicit CinnGraphSymbolizationForTest(CinnGraphSymbolization* cinn_symbol) + : cinn_symbol_(cinn_symbol) {} + + std::unordered_set GetGraphInputParameterNames() { + return cinn_symbol_->GetGraphInputParameterNames(); + } + + std::shared_ptr<::cinn::hlir::framework::Scope> TransformPaddleScopeToCinn() { + return cinn_symbol_->TransformPaddleScopeToCinn(); + } + + OpMapperContext CreateNewContext(NetBuilder* builder) { + return OpMapperContext(*cinn_symbol_->TransformPaddleScopeToCinn(), + cinn_symbol_->target_, builder, + &cinn_symbol_->var_map_, + &cinn_symbol_->var_model_to_program_map_); + } + + void AddFeedInfoIntoContext(OpMapperContext* ctx) { cinn_symbol_->AddFeedInfoIntoContext(ctx); } - std::vector> TransformAllGraphOpToCinn( - CinnGraphSymbolization* cinn_symbol_) const { + std::vector> TransformAllGraphOpToCinn() { return cinn_symbol_->TransformAllGraphOpToCinn(); } - void RunOp(CinnGraphSymbolization* cinn_symbol_, const CinnOpDesc& op_desc, - const OpMapperContext& ctx) const { + void RunOp(const CinnOpDesc& op_desc, const OpMapperContext& ctx) { cinn_symbol_->RunOp(op_desc, ctx); } - std::shared_ptr<::cinn::hlir::framework::Scope> TransformPaddleScopeToCinn( - CinnGraphSymbolization* cinn_symbol_) const { - return cinn_symbol_->TransformPaddleScopeToCinn(); + private: + CinnGraphSymbolization* cinn_symbol_; +}; + +class CinnGraphSymbolizationTest : public ::testing::Test { + public: + std::unique_ptr symbol_; + std::unique_ptr test_; + + OpMapperContext CreateNewContext() { + return test_->CreateNewContext(builder_.get()); } - void RunGraph(CinnGraphSymbolization* cinn_symbol_, - const OpMapperContext& ctx) const { - cinn_symbol_->RunGraph(ctx); + protected: + void SetUp() override { + int64_t graph_id = 100; + graph_ = BuildAllOpSupportCinnGraph(); + scope_ = CreateScope(); + target_ = CreateDefaultTarget(); + feed_tensors_ = CreateFeedTensors(); + feed_targets_ = ConvertFeedType(feed_tensors_); + symbol_ = std::make_unique( + graph_id, *graph_, *scope_, target_, feed_targets_); + builder_ = std::make_unique("NetBuilder_of_graph_" + + std::to_string(graph_id)); + test_ = std::make_unique(symbol_.get()); } -}; -std::unique_ptr BuildAllOpSupportCinnGraph() { - ProgramDesc prog; - auto g = std::make_unique(prog); - - // v1 -- - // | --> mul --> v3 -- - // v2 -- | --> add --> v5 --> relu --> v6 - // v4 -- - - OpDesc add_op; - add_op.SetType("add"); - OpDesc mul_op; - mul_op.SetType("mul"); - OpDesc relu_op; - relu_op.SetType("relu"); - - VarDesc var1("var1"); - VarDesc var2("var2"); - var2.SetPersistable(true); - var2.SetIsParameter(true); - VarDesc var3("var3"); - VarDesc var4("var4"); - VarDesc var5("var5"); - VarDesc var6("var6"); - - ir::Node* add = g->CreateOpNode(&add_op); - ir::Node* mul = g->CreateOpNode(&mul_op); - ir::Node* relu = g->CreateOpNode(&relu_op); - - ir::Node* v1 = g->CreateVarNode(&var1); - ir::Node* v2 = g->CreateVarNode(&var2); - ir::Node* v3 = g->CreateVarNode(&var3); - ir::Node* v4 = g->CreateVarNode(&var4); - ir::Node* v5 = g->CreateVarNode(&var5); - ir::Node* v6 = g->CreateVarNode(&var6); - - // fill op node - mul->inputs = {v1, v2}; - mul->outputs = {v3}; - add->inputs = {v3, v4}; - add->outputs = {v5}; - relu->inputs = {v5}; - relu->outputs = {v6}; - - // fill variable node - v1->outputs = {mul}; - v2->outputs = {mul}; - - v3->inputs = {mul}; - v3->outputs = {add}; - - v4->outputs = {add}; - - v5->inputs = {add}; - v5->outputs = {relu}; - - v6->inputs = {relu}; - - return g; -} + private: + std::unique_ptr graph_; + std::unique_ptr scope_; + ::cinn::common::Target target_; + std::map feed_tensors_; + std::map feed_targets_; + std::unique_ptr builder_; + + std::unique_ptr BuildAllOpSupportCinnGraph() { + ProgramDesc prog; + auto g = std::make_unique(prog); + + // v1 -- + // | --> mul --> v3 -- + // v2 -- | --> add --> v5 --> relu --> v6 + // v4 -- + + OpDesc add_op; + add_op.SetType("add"); + OpDesc mul_op; + mul_op.SetType("mul"); + OpDesc relu_op; + relu_op.SetType("relu"); + + VarDesc var1("var1"); + VarDesc var2("var2"); + var2.SetPersistable(true); + var2.SetIsParameter(true); + VarDesc var3("var3"); + VarDesc var4("var4"); + VarDesc var5("var5"); + VarDesc var6("var6"); + + ir::Node* add = g->CreateOpNode(&add_op); + ir::Node* mul = g->CreateOpNode(&mul_op); + ir::Node* relu = g->CreateOpNode(&relu_op); + + ir::Node* v1 = g->CreateVarNode(&var1); + ir::Node* v2 = g->CreateVarNode(&var2); + ir::Node* v3 = g->CreateVarNode(&var3); + ir::Node* v4 = g->CreateVarNode(&var4); + ir::Node* v5 = g->CreateVarNode(&var5); + ir::Node* v6 = g->CreateVarNode(&var6); + + // fill op node + mul->inputs = {v1, v2}; + mul->outputs = {v3}; + add->inputs = {v3, v4}; + add->outputs = {v5}; + relu->inputs = {v5}; + relu->outputs = {v6}; + + // fill variable node + v1->outputs = {mul}; + v2->outputs = {mul}; + + v3->inputs = {mul}; + v3->outputs = {add}; + + v4->outputs = {add}; + + v5->inputs = {add}; + v5->outputs = {relu}; + + v6->inputs = {relu}; + + return g; + } -::cinn::common::Target CreateDefaultTarget(bool use_gpu = false) { + ::cinn::common::Target CreateDefaultTarget(bool use_gpu = false) { #ifdef PADDLE_WITH_CUDA - if (use_gpu) { - return ::cinn::common::DefaultNVGPUTarget(); - } + if (use_gpu) { + return ::cinn::common::DefaultNVGPUTarget(); + } #endif - return ::cinn::common::DefaultHostTarget(); -} + return ::cinn::common::DefaultHostTarget(); + } -std::unique_ptr CreateScope() { - std::unique_ptr scope; - scope->Var("var2"); - return scope; -} + std::unique_ptr CreateScope() { + std::unique_ptr scope; + auto var2 = scope->Var("var2"); + auto* tensor = var2->GetMutable(); + DDim dims = {256, 1024, 1024}; + tensor->Resize(dims); + // tensor has no set_type api, default FP32 + return scope; + } -std::map CreateFeedTarget() { - std::map feed_targets; + std::map CreateFeedTensors() { + std::map feed_targets; - auto create_tensor = []() { - LoDTensor tensor; - DDim dims = {256, 1024, 1024}; - tensor.Resize(dims); - return tensor; - }; + auto create_tensor = []() { + LoDTensor tensor; + DDim dims = {256, 1024, 1024}; + tensor.Resize(dims); + return tensor; + }; #define FillFeedList(Name) feed_targets[#Name] = create_tensor(); - FillFeedList(var1) FillFeedList(var3) FillFeedList(var4) FillFeedList(var5) - FillFeedList(var6) + FillFeedList(var1) FillFeedList(var3) FillFeedList(var4) FillFeedList(var5) + FillFeedList(var6) #undef FillFeedList + } + + std::map ConvertFeedType( + const std::map& feed_targets) { + std::map res; + for (auto& feed_pair : feed_targets) { + res[feed_pair.first] = &feed_pair.second; + } + return res; + } +}; + +TEST_F(CinnGraphSymbolizationTest, basic) { + ASSERT_NO_THROW((*symbol_)()); + ASSERT_FALSE(symbol_->var_map().empty()); + ASSERT_FALSE(symbol_->var_model_to_program_map().empty()); } -std::map ConvertFeedType( - const std::map& feed_targets) { - std::map res; - for (auto& feed_pair : feed_targets) { - res[feed_pair.first] = &feed_pair.second; +TEST_F(CinnGraphSymbolizationTest, scope) { + auto prame_names = test_->GetGraphInputParameterNames(); + ASSERT_EQ(prame_names, std::unordered_set({"var2"})); + + auto cinn_scope = test_->TransformPaddleScopeToCinn(); + + auto* var1 = cinn_scope->FindVar("var1"); + ASSERT_EQ(var1, nullptr); + auto* var2 = cinn_scope->FindVar("var2"); + ASSERT_NE(var2, nullptr); + + auto& cinn_tensor = absl::get(*var2); + ASSERT_EQ(cinn_tensor->shape().data(), std::vector({256, 1024, 1024})); + ASSERT_EQ(cinn_tensor->type(), ::cinn::common::F32()); +} + +TEST_F(CinnGraphSymbolizationTest, context) { + auto ctx = CreateNewContext(); + test_->AddFeedInfoIntoContext(&ctx); + + ASSERT_NO_THROW(ctx.GetFeedInfo("var1")); + ASSERT_ANY_THROW(ctx.GetFeedInfo("var2")); + + auto feed_info = ctx.GetFeedInfo("var1"); + ASSERT_EQ(feed_info.shape, std::vector({256, 1024, 1024})); + ASSERT_EQ(feed_info.type, ::cinn::common::F32()); +} + +TEST_F(CinnGraphSymbolizationTest, sortgraph) { + auto cinn_op_descs = test_->TransformAllGraphOpToCinn(); + ASSERT_FALSE(cinn_op_descs.empty()); + std::vector sort_names; + for (auto& desc : cinn_op_descs) { + sort_names.emplace_back(desc->Type()); } - return res; + ASSERT_EQ(sort_names, std::vector({"mul", "add", "relu"})); } -TEST(CinnGraphSymbolizationTest, basic) { - auto graph = BuildAllOpSupportCinnGraph(); - auto scope = CreateScope(); - auto target = CreateDefaultTarget(); - auto feed_object = CreateFeedTarget(); - auto feed_targets = ConvertFeedType(feed_object); - - CinnGraphSymbolization symbol(100, *graph, *scope, target, feed_targets); - ASSERT_NO_THROW(symbol()); - ASSERT_FALSE(symbol.var_map().empty()); - ASSERT_FALSE(symbol.var_model_to_program_map().empty()); +TEST_F(CinnGraphSymbolizationTest, runop) { + auto cinn_op_descs = test_->TransformAllGraphOpToCinn(); + auto ctx = CreateNewContext(); + ASSERT_NO_THROW(test_->RunOp(*cinn_op_descs[0], ctx)); + + CinnOpDesc desc; + desc.SetType("fake"); + ASSERT_ANY_THROW(test_->RunOp(desc, ctx)); } } // namespace paddle2cinn From 2d9a34cf95ae954119c58c9be42f867bb5ee658d Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Tue, 19 Oct 2021 12:35:20 +0000 Subject: [PATCH 11/16] remove scope and rename feed_target to input_tensor --- .../paddle2cinn/cinn_graph_symbolization.cc | 52 ++++++------- .../paddle2cinn/cinn_graph_symbolization.h | 22 +++--- .../cinn_graph_symbolization_test.cc | 76 +++++++++---------- 3 files changed, 72 insertions(+), 78 deletions(-) diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc index fb9f6e003dc81..dd707fa876e67 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc @@ -35,6 +35,7 @@ using ir::Node; using CinnTensor = ::cinn::hlir::framework::Tensor; using OpMapperContext = ::cinn::frontend::OpMapperContext; using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; +using FeedInfoMap = absl::flat_hash_map; namespace utils { @@ -49,27 +50,17 @@ OpMapperContext::FeedInfo GetCinnFeedInfoFromTensor(const Tensor& tensor) { info.type = ::cinn::frontend::utils::CppVarType2CommonType(cinn_var_type); return info; } - -void TransformPaddleVariableToCinn( - const Variable& pd_var, ::cinn::hlir::framework::Variable* cinn_var) { - const auto& pd_tensor = pd_var.Get(); - auto& cinn_tensor = absl::get(*cinn_var); - - auto feed_info = GetCinnFeedInfoFromTensor(pd_tensor); - // here we only need preserve dtype and shape, do not need preserve data - cinn_tensor->set_type(feed_info.type); - cinn_tensor->Resize(::cinn::hlir::framework::Shape(feed_info.shape)); -} } // namespace utils -void CinnGraphSymbolization::AddFeedInfoIntoContext( - OpMapperContext* ctx) const { - for (auto& feed_pair : feed_targets_) { +FeedInfoMap CinnGraphSymbolization::GetFeedInfoMapFromInput() const { + FeedInfoMap feed_map; + for (auto& feed_pair : input_tensors_) { const auto& feed_name = feed_pair.first; const auto* tensor = feed_pair.second; - ctx->AddFeedInfo(feed_name, utils::GetCinnFeedInfoFromTensor(*tensor)); + feed_map[feed_name] = utils::GetCinnFeedInfoFromTensor(*tensor); } + return feed_map; } // get the graph's op input Parameter var name set @@ -95,24 +86,24 @@ CinnGraphSymbolization::GetGraphInputParameterNames() const { // Transform paddle scope to cinn, note that we only preserve the graph’s // input parameter variable and ignore others. std::shared_ptr<::cinn::hlir::framework::Scope> -CinnGraphSymbolization::TransformPaddleScopeToCinn() const { +CinnGraphSymbolization::CreateCinnScope(const FeedInfoMap& feed_map) const { auto cinn_scope = ::cinn::hlir::framework::Scope::Create(); // get the graph's input parameter variable name list auto parameter_names = GetGraphInputParameterNames(); - for (const auto& var_name : scope_.LocalVarNames()) { - // if cannot find var in graph input, skip - if (parameter_names.count(var_name) == 0) continue; - - auto* pd_var = scope_.FindLocalVar(var_name); - + for (const auto& param_name : parameter_names) { + // if cannot find var in graph input, skip. // scope accepte the CINN format name, so here we need transform // paddle format name to CINN format. - auto* cinn_var = - cinn_scope->Var(::cinn::utils::TransValidVarName(var_name)); - - utils::TransformPaddleVariableToCinn(*pd_var, cinn_var); + auto* cinn_var = cinn_scope->Var( + ::cinn::utils::TransValidVarName(param_name)); + + auto& cinn_tensor = absl::get(*cinn_var); + // here we only need preserve dtype and shape, do not need preserve data + auto feed_info = feed_map.at(param_name); + cinn_tensor->set_type(feed_info.type); + cinn_tensor->Resize(::cinn::hlir::framework::Shape(feed_info.shape)); } return cinn_scope; @@ -158,12 +149,15 @@ ::cinn::frontend::Program CinnGraphSymbolization::operator()() { ::cinn::frontend::NetBuilder builder(builder_name); - auto cinn_scope = TransformPaddleScopeToCinn(); + auto feed_map = GetFeedInfoMapFromInput(); + auto cinn_scope = CreateCinnScope(feed_map); OpMapperContext ctx(*cinn_scope, target_, &builder, &var_map_, &var_model_to_program_map_); - - AddFeedInfoIntoContext(&ctx); + // add all tensor's feed info into context + for (auto& feed_pair : feed_map) { + ctx.AddFeedInfo(feed_pair.first, feed_pair.second); + } RunGraph(ctx); return builder.Build(); diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h index 82046faa07c6a..1f5cf80d490fd 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h @@ -39,7 +39,7 @@ namespace paddle2cinn { // 2. graph: // the CINN subgraph whose op are all supported by CINN, and the // graph is independently of other graph. -// 3. feed_targets: +// 3. input_tensors: // all input var nodes of CINN subgraph, they are necessary for // we need pass the shape and data type into CINN, otherwise the // NetBuilder may error for the shape not meet the precondition. @@ -61,14 +61,13 @@ namespace paddle2cinn { class CinnGraphSymbolization { public: CinnGraphSymbolization( - int64_t graph_id, const ir::Graph& graph, const Scope& scope, + int64_t graph_id, const ir::Graph& graph, const ::cinn::common::Target& target, - const std::map& feed_targets) + const std::map& input_tensors) : graph_id_(graph_id), graph_(graph), - scope_(scope), target_(target), - feed_targets_(feed_targets) {} + input_tensors_(input_tensors) {} // run all CINN op in graph by topo sorting then return its NetBuilder ::cinn::frontend::Program operator()(); @@ -88,17 +87,18 @@ class CinnGraphSymbolization { private: const int64_t graph_id_; const ir::Graph& graph_; - const Scope& scope_; const ::cinn::common::Target& target_; - const std::map& feed_targets_; + const std::map& input_tensors_; // preserve local variable map absl::flat_hash_map var_map_; absl::flat_hash_map var_model_to_program_map_; using OpMapperContext = ::cinn::frontend::OpMapperContext; + using FeedInfoMap = + absl::flat_hash_map; // transform all paddle var desc in feed list into cinn_var_descs_ - void AddFeedInfoIntoContext(OpMapperContext* ctx) const; + FeedInfoMap GetFeedInfoMapFromInput() const; // transform all paddle op desc in graph into cinn op desc using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; @@ -112,9 +112,9 @@ class CinnGraphSymbolization { // preserve var desc, run the op one by one. void RunGraph(const OpMapperContext& ctx) const; - // Transform paddle scope to cinn scope - std::shared_ptr<::cinn::hlir::framework::Scope> TransformPaddleScopeToCinn() - const; + // create cinn scope and add parameter's feed info into scope + std::shared_ptr<::cinn::hlir::framework::Scope> CreateCinnScope( + const FeedInfoMap& feed_map) const; // get the graph op's input persistable var name set std::unordered_set GetGraphInputParameterNames() const; diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc index e93a975a3b5dd..4bfc902503b69 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc @@ -22,10 +22,11 @@ namespace paddle2cinn { using ir::Graph; using ir::Node; +using ::cinn::frontend::NetBuilder; using CinnTensor = ::cinn::hlir::framework::Tensor; using OpMapperContext = ::cinn::frontend::OpMapperContext; using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; -using ::cinn::frontend::NetBuilder; +using FeedInfoMap = absl::flat_hash_map; // only used for test CinnGraphSymbolization class class CinnGraphSymbolizationForTest { @@ -37,19 +38,21 @@ class CinnGraphSymbolizationForTest { return cinn_symbol_->GetGraphInputParameterNames(); } - std::shared_ptr<::cinn::hlir::framework::Scope> TransformPaddleScopeToCinn() { - return cinn_symbol_->TransformPaddleScopeToCinn(); + std::shared_ptr<::cinn::hlir::framework::Scope> CreateCinnScope( + const FeedInfoMap& feed_map) { + return cinn_symbol_->CreateCinnScope(feed_map); } - OpMapperContext CreateNewContext(NetBuilder* builder) { - return OpMapperContext(*cinn_symbol_->TransformPaddleScopeToCinn(), + OpMapperContext CreateNewContext(NetBuilder* builder, + const FeedInfoMap& feed_map) { + return OpMapperContext(*cinn_symbol_->CreateCinnScope(feed_map), cinn_symbol_->target_, builder, &cinn_symbol_->var_map_, &cinn_symbol_->var_model_to_program_map_); } - void AddFeedInfoIntoContext(OpMapperContext* ctx) { - cinn_symbol_->AddFeedInfoIntoContext(ctx); + FeedInfoMap GetFeedInfoMapFromInput() { + return cinn_symbol_->GetFeedInfoMapFromInput(); } std::vector> TransformAllGraphOpToCinn() { @@ -70,31 +73,35 @@ class CinnGraphSymbolizationTest : public ::testing::Test { std::unique_ptr test_; OpMapperContext CreateNewContext() { - return test_->CreateNewContext(builder_.get()); + return test_->CreateNewContext(builder_.get(), feed_map_); + } + + std::shared_ptr<::cinn::hlir::framework::Scope> CreateCinnScope() { + return test_->CreateCinnScope(feed_map_); } protected: void SetUp() override { int64_t graph_id = 100; graph_ = BuildAllOpSupportCinnGraph(); - scope_ = CreateScope(); target_ = CreateDefaultTarget(); feed_tensors_ = CreateFeedTensors(); feed_targets_ = ConvertFeedType(feed_tensors_); - symbol_ = std::make_unique( - graph_id, *graph_, *scope_, target_, feed_targets_); + symbol_ = std::make_unique(graph_id, *graph_, + target_, feed_targets_); builder_ = std::make_unique("NetBuilder_of_graph_" + std::to_string(graph_id)); test_ = std::make_unique(symbol_.get()); + feed_map_ = test_->GetFeedInfoMapFromInput(); } private: std::unique_ptr graph_; - std::unique_ptr scope_; ::cinn::common::Target target_; std::map feed_tensors_; std::map feed_targets_; std::unique_ptr builder_; + FeedInfoMap feed_map_; std::unique_ptr BuildAllOpSupportCinnGraph() { ProgramDesc prog; @@ -166,16 +173,6 @@ class CinnGraphSymbolizationTest : public ::testing::Test { return ::cinn::common::DefaultHostTarget(); } - std::unique_ptr CreateScope() { - std::unique_ptr scope; - auto var2 = scope->Var("var2"); - auto* tensor = var2->GetMutable(); - DDim dims = {256, 1024, 1024}; - tensor->Resize(dims); - // tensor has no set_type api, default FP32 - return scope; - } - std::map CreateFeedTensors() { std::map feed_targets; @@ -186,9 +183,12 @@ class CinnGraphSymbolizationTest : public ::testing::Test { return tensor; }; #define FillFeedList(Name) feed_targets[#Name] = create_tensor(); - - FillFeedList(var1) FillFeedList(var3) FillFeedList(var4) FillFeedList(var5) - FillFeedList(var6) + FillFeedList(var1); + FillFeedList(var2); + FillFeedList(var3); + FillFeedList(var4); + FillFeedList(var5); + FillFeedList(var6) #undef FillFeedList } @@ -208,11 +208,23 @@ TEST_F(CinnGraphSymbolizationTest, basic) { ASSERT_FALSE(symbol_->var_model_to_program_map().empty()); } +TEST_F(CinnGraphSymbolizationTest, feed_map) { + auto feed_map = test_->GetFeedInfoMapFromInput(); + auto ctx = CreateNewContext(); + + ASSERT_TRUE(feed_map.count("var1")); + ASSERT_TRUE(feed_map.count("var2")); + + auto feed_info = feed_map.at("var1"); + ASSERT_EQ(feed_info.shape, std::vector({256, 1024, 1024})); + ASSERT_EQ(feed_info.type, ::cinn::common::F32()); +} + TEST_F(CinnGraphSymbolizationTest, scope) { auto prame_names = test_->GetGraphInputParameterNames(); ASSERT_EQ(prame_names, std::unordered_set({"var2"})); - auto cinn_scope = test_->TransformPaddleScopeToCinn(); + auto cinn_scope = CreateCinnScope(); auto* var1 = cinn_scope->FindVar("var1"); ASSERT_EQ(var1, nullptr); @@ -224,18 +236,6 @@ TEST_F(CinnGraphSymbolizationTest, scope) { ASSERT_EQ(cinn_tensor->type(), ::cinn::common::F32()); } -TEST_F(CinnGraphSymbolizationTest, context) { - auto ctx = CreateNewContext(); - test_->AddFeedInfoIntoContext(&ctx); - - ASSERT_NO_THROW(ctx.GetFeedInfo("var1")); - ASSERT_ANY_THROW(ctx.GetFeedInfo("var2")); - - auto feed_info = ctx.GetFeedInfo("var1"); - ASSERT_EQ(feed_info.shape, std::vector({256, 1024, 1024})); - ASSERT_EQ(feed_info.type, ::cinn::common::F32()); -} - TEST_F(CinnGraphSymbolizationTest, sortgraph) { auto cinn_op_descs = test_->TransformAllGraphOpToCinn(); ASSERT_FALSE(cinn_op_descs.empty()); From 7ed7efedb4ced0325b2314a3c19e24aa1c49eb3c Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Wed, 20 Oct 2021 02:15:00 +0000 Subject: [PATCH 12/16] using std::unordered_map instead of absl::flat_hash_map --- .../paddle2cinn/cinn_graph_symbolization.cc | 6 +++--- .../paddle2cinn/cinn_graph_symbolization.h | 21 ++++++++++--------- .../cinn_graph_symbolization_test.cc | 6 +++--- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc index dd707fa876e67..f726b5863bb69 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc @@ -33,9 +33,9 @@ namespace paddle2cinn { using ir::Graph; using ir::Node; using CinnTensor = ::cinn::hlir::framework::Tensor; -using OpMapperContext = ::cinn::frontend::OpMapperContext; -using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; -using FeedInfoMap = absl::flat_hash_map; +using OpMapperContext = CinnGraphSymbolization::OpMapperContext; +using CinnOpDesc = CinnGraphSymbolization::CinnOpDesc; +using FeedInfoMap = CinnGraphSymbolization::FeedInfoMap; namespace utils { diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h index 1f5cf80d490fd..b6b4b24c6ee3d 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.h @@ -14,8 +14,8 @@ limitations under the License. */ #pragma once -#include #include +#include #include #include "paddle/fluid/framework/ir/graph.h" @@ -73,17 +73,22 @@ class CinnGraphSymbolization { ::cinn::frontend::Program operator()(); // return the internal variable map - const absl::flat_hash_map& var_map() + const std::unordered_map& var_map() const { return var_map_; } // return the map from the variable name in paddle model to cinn program. - const absl::flat_hash_map& - var_model_to_program_map() const { + const std::unordered_map& var_model_to_program_map() + const { return var_model_to_program_map_; } + using OpMapperContext = ::cinn::frontend::OpMapperContext; + using FeedInfoMap = + std::unordered_map; + using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; + private: const int64_t graph_id_; const ir::Graph& graph_; @@ -91,17 +96,13 @@ class CinnGraphSymbolization { const std::map& input_tensors_; // preserve local variable map - absl::flat_hash_map var_map_; - absl::flat_hash_map var_model_to_program_map_; + std::unordered_map var_map_; + std::unordered_map var_model_to_program_map_; - using OpMapperContext = ::cinn::frontend::OpMapperContext; - using FeedInfoMap = - absl::flat_hash_map; // transform all paddle var desc in feed list into cinn_var_descs_ FeedInfoMap GetFeedInfoMapFromInput() const; // transform all paddle op desc in graph into cinn op desc - using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; std::vector> TransformAllGraphOpToCinn() const; // RunOp accept OpDesc and global run context then run diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc index 4bfc902503b69..4534fe28995ef 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc @@ -24,9 +24,9 @@ using ir::Graph; using ir::Node; using ::cinn::frontend::NetBuilder; using CinnTensor = ::cinn::hlir::framework::Tensor; -using OpMapperContext = ::cinn::frontend::OpMapperContext; -using CinnOpDesc = ::cinn::frontend::paddle::cpp::OpDesc; -using FeedInfoMap = absl::flat_hash_map; +using OpMapperContext = CinnGraphSymbolization::OpMapperContext; +using CinnOpDesc = CinnGraphSymbolization::CinnOpDesc; +using FeedInfoMap = CinnGraphSymbolization::FeedInfoMap; // only used for test CinnGraphSymbolization class class CinnGraphSymbolizationForTest { From a2a68cefc776b8bc5a1c77811505a334bd0336d2 Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Fri, 22 Oct 2021 09:13:16 +0000 Subject: [PATCH 13/16] fix single test bug --- .../framework/paddle2cinn/CMakeLists.txt | 2 +- .../framework/paddle2cinn/build_cinn_pass.cc | 32 +------ .../paddle2cinn/cinn_graph_symbolization.cc | 4 +- .../cinn_graph_symbolization_test.cc | 88 +++++++++++++------ 4 files changed, 69 insertions(+), 57 deletions(-) diff --git a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt index bb3bd6ec8b457..d732b561ec8ba 100644 --- a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt +++ b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt @@ -1,7 +1,7 @@ cc_library(cinn_cache_key SRCS cinn_cache_key.cc DEPS boost graph graph_helper lod_tensor proto_desc) cc_library(cinn_compiled_object SRCS cinn_compiled_object.cc DEPS feed_fetch_method graph lod_tensor proto_desc) cc_library(cinn_runner SRCS cinn_runner.cc DEPS cinn_cache_key cinn_compiled_object feed_fetch_method graph lod_tensor scope) -cc_library(build_cinn_pass SRCS build_cinn_pass.cc DEPS pass subgraph_detector) +cc_library(build_cinn_pass SRCS build_cinn_pass.cc DEPS pass subgraph_detector cinn) cc_library(transform_desc SRCS transform_desc.cc DEPS proto_desc cinn) cc_library(cinn_graph_symbolization SRCS cinn_graph_symbolization.cc DEPS lod_tensor graph graph_helper transform_desc cinn) diff --git a/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc b/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc index caddc8fbb7381..57c6a52c01622 100644 --- a/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc +++ b/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc @@ -20,39 +20,11 @@ limitations under the License. */ #include #include +#include "cinn/frontend/op_mapper_registry.h" +#include "cinn/frontend/op_mappers/use_op_mappers.h" #include "paddle/fluid/framework/ir/graph.h" #include "paddle/fluid/framework/ir/node.h" #include "paddle/fluid/framework/ir/subgraph_detector.h" -// #include "cinn/frontend/op_mapper_registry.h" -// #include "cinn/frontend/op_mappers/use_op_mappers.h" - -// TODO(jiangcheng05): just for local compile, remove after -// paddle and CINN have been binded -// The APIs are the same as CINN: -// https://github.com/PaddlePaddle/CINN/blob/develop/cinn/utils/registry.h -namespace cinn { -namespace frontend { -class OpMapperRegistry { - public: - static OpMapperRegistry* Global() { - static OpMapperRegistry inst; - return &inst; - } - - inline const OpMapperRegistry* Find(const std::string& name) { - std::unordered_set fmap_ = {"mul", "add", "relu", "sigmoid", - "softmax"}; - auto p = fmap_.find(name); - if (p != fmap_.end()) { - return this; - } else { - return nullptr; - } - } -}; - -} // namespace frontend -} // namespace cinn namespace paddle { namespace framework { diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc index f726b5863bb69..3482f99f8dda5 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc @@ -46,7 +46,7 @@ OpMapperContext::FeedInfo GetCinnFeedInfoFromTensor(const Tensor& tensor) { info.shape.emplace_back(static_cast(dim[i])); } - auto cinn_var_type = TransformVarTypeToCinn(tensor.type()); + auto cinn_var_type = TransformVarDataTypeToCinn(tensor.type()); info.type = ::cinn::frontend::utils::CppVarType2CommonType(cinn_var_type); return info; } @@ -93,6 +93,7 @@ CinnGraphSymbolization::CreateCinnScope(const FeedInfoMap& feed_map) const { auto parameter_names = GetGraphInputParameterNames(); for (const auto& param_name : parameter_names) { + VLOG(4) << "add param var [" << param_name << "] info scope"; // if cannot find var in graph input, skip. // scope accepte the CINN format name, so here we need transform // paddle format name to CINN format. @@ -157,6 +158,7 @@ ::cinn::frontend::Program CinnGraphSymbolization::operator()() { // add all tensor's feed info into context for (auto& feed_pair : feed_map) { ctx.AddFeedInfo(feed_pair.first, feed_pair.second); + VLOG(4) << "add feed var [" << feed_pair.first << "] info context"; } RunGraph(ctx); diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc index 4534fe28995ef..940228314a1d4 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization_test.cc @@ -69,19 +69,7 @@ class CinnGraphSymbolizationForTest { class CinnGraphSymbolizationTest : public ::testing::Test { public: - std::unique_ptr symbol_; - std::unique_ptr test_; - - OpMapperContext CreateNewContext() { - return test_->CreateNewContext(builder_.get(), feed_map_); - } - - std::shared_ptr<::cinn::hlir::framework::Scope> CreateCinnScope() { - return test_->CreateCinnScope(feed_map_); - } - - protected: - void SetUp() override { + CinnGraphSymbolizationTest() { int64_t graph_id = 100; graph_ = BuildAllOpSupportCinnGraph(); target_ = CreateDefaultTarget(); @@ -95,11 +83,22 @@ class CinnGraphSymbolizationTest : public ::testing::Test { feed_map_ = test_->GetFeedInfoMapFromInput(); } + std::unique_ptr symbol_; + std::unique_ptr test_; + std::map feed_targets_; + + OpMapperContext CreateNewContext() { + return test_->CreateNewContext(builder_.get(), feed_map_); + } + + std::shared_ptr<::cinn::hlir::framework::Scope> CreateCinnScope() { + return test_->CreateCinnScope(feed_map_); + } + private: std::unique_ptr graph_; ::cinn::common::Target target_; std::map feed_tensors_; - std::map feed_targets_; std::unique_ptr builder_; FeedInfoMap feed_map_; @@ -114,10 +113,28 @@ class CinnGraphSymbolizationTest : public ::testing::Test { OpDesc add_op; add_op.SetType("add"); + add_op.SetInput("X", {"var3"}); + add_op.SetInput("Y", {"var4"}); + add_op.SetOutput("Out", {"var5"}); + OpDesc mul_op; mul_op.SetType("mul"); + mul_op.SetInput("X", {"var1"}); + mul_op.SetInput("Y", {"var2"}); + mul_op.SetOutput("Out", {"var3"}); + OpDesc relu_op; relu_op.SetType("relu"); + relu_op.SetInput("X", {"var5"}); + relu_op.SetOutput("Out", {"var6"}); + + OpDesc feed_var1; + feed_var1.SetType("feed"); + feed_var1.SetOutput("Out", {"var1"}); + + OpDesc feed_var4; + feed_var4.SetType("feed"); + feed_var4.SetOutput("Out", {"var4"}); VarDesc var1("var1"); VarDesc var2("var2"); @@ -132,6 +149,9 @@ class CinnGraphSymbolizationTest : public ::testing::Test { ir::Node* mul = g->CreateOpNode(&mul_op); ir::Node* relu = g->CreateOpNode(&relu_op); + ir::Node* feed1 = g->CreateOpNode(&feed_var1); + ir::Node* feed4 = g->CreateOpNode(&feed_var4); + ir::Node* v1 = g->CreateVarNode(&var1); ir::Node* v2 = g->CreateVarNode(&var2); ir::Node* v3 = g->CreateVarNode(&var3); @@ -140,6 +160,8 @@ class CinnGraphSymbolizationTest : public ::testing::Test { ir::Node* v6 = g->CreateVarNode(&var6); // fill op node + feed1->outputs = {v1}; + feed4->outputs = {v4}; mul->inputs = {v1, v2}; mul->outputs = {v3}; add->inputs = {v3, v4}; @@ -148,12 +170,15 @@ class CinnGraphSymbolizationTest : public ::testing::Test { relu->outputs = {v6}; // fill variable node + v1->inputs = {feed1}; v1->outputs = {mul}; + v2->outputs = {mul}; v3->inputs = {mul}; v3->outputs = {add}; + v4->inputs = {feed4}; v4->outputs = {add}; v5->inputs = {add}; @@ -178,8 +203,9 @@ class CinnGraphSymbolizationTest : public ::testing::Test { auto create_tensor = []() { LoDTensor tensor; - DDim dims = {256, 1024, 1024}; + DDim dims = {256, 1024}; tensor.Resize(dims); + tensor.mutable_data(platform::CPUPlace(), proto::VarType::FP32); return tensor; }; #define FillFeedList(Name) feed_targets[#Name] = create_tensor(); @@ -188,8 +214,12 @@ class CinnGraphSymbolizationTest : public ::testing::Test { FillFeedList(var3); FillFeedList(var4); FillFeedList(var5); - FillFeedList(var6) + FillFeedList(var6); #undef FillFeedList + DDim y_dim = {1024, 1024}; + feed_targets["var2"].Resize(y_dim); + + return feed_targets; } std::map ConvertFeedType( @@ -202,12 +232,6 @@ class CinnGraphSymbolizationTest : public ::testing::Test { } }; -TEST_F(CinnGraphSymbolizationTest, basic) { - ASSERT_NO_THROW((*symbol_)()); - ASSERT_FALSE(symbol_->var_map().empty()); - ASSERT_FALSE(symbol_->var_model_to_program_map().empty()); -} - TEST_F(CinnGraphSymbolizationTest, feed_map) { auto feed_map = test_->GetFeedInfoMapFromInput(); auto ctx = CreateNewContext(); @@ -216,7 +240,7 @@ TEST_F(CinnGraphSymbolizationTest, feed_map) { ASSERT_TRUE(feed_map.count("var2")); auto feed_info = feed_map.at("var1"); - ASSERT_EQ(feed_info.shape, std::vector({256, 1024, 1024})); + ASSERT_EQ(feed_info.shape, std::vector({256, 1024})); ASSERT_EQ(feed_info.type, ::cinn::common::F32()); } @@ -232,7 +256,7 @@ TEST_F(CinnGraphSymbolizationTest, scope) { ASSERT_NE(var2, nullptr); auto& cinn_tensor = absl::get(*var2); - ASSERT_EQ(cinn_tensor->shape().data(), std::vector({256, 1024, 1024})); + ASSERT_EQ(cinn_tensor->shape().data(), std::vector({1024, 1024})); ASSERT_EQ(cinn_tensor->type(), ::cinn::common::F32()); } @@ -243,12 +267,20 @@ TEST_F(CinnGraphSymbolizationTest, sortgraph) { for (auto& desc : cinn_op_descs) { sort_names.emplace_back(desc->Type()); } - ASSERT_EQ(sort_names, std::vector({"mul", "add", "relu"})); + ASSERT_EQ(sort_names, + std::vector({"feed", "mul", "feed", "add", "relu"})); } TEST_F(CinnGraphSymbolizationTest, runop) { auto cinn_op_descs = test_->TransformAllGraphOpToCinn(); + auto feed_map = test_->GetFeedInfoMapFromInput(); + auto ctx = CreateNewContext(); + // add all tensor's feed info into context + for (auto& feed_pair : feed_map) { + ctx.AddFeedInfo(feed_pair.first, feed_pair.second); + } + ASSERT_NO_THROW(test_->RunOp(*cinn_op_descs[0], ctx)); CinnOpDesc desc; @@ -256,6 +288,12 @@ TEST_F(CinnGraphSymbolizationTest, runop) { ASSERT_ANY_THROW(test_->RunOp(desc, ctx)); } +TEST_F(CinnGraphSymbolizationTest, basic) { + ASSERT_NO_THROW((*symbol_)()); + ASSERT_FALSE(symbol_->var_map().empty()); + ASSERT_FALSE(symbol_->var_model_to_program_map().empty()); +} + } // namespace paddle2cinn } // namespace framework } // namespace paddle From 6428c7bcb2ea570dafd5580a6a129526f8931b1e Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Fri, 22 Oct 2021 10:46:42 +0000 Subject: [PATCH 14/16] revert to preverion for WITH_CINN has add in later PR --- .../framework/paddle2cinn/CMakeLists.txt | 14 +++++--- .../framework/paddle2cinn/build_cinn_pass.cc | 32 +++++++++++++++++-- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt index d732b561ec8ba..42716d4c45c63 100644 --- a/paddle/fluid/framework/paddle2cinn/CMakeLists.txt +++ b/paddle/fluid/framework/paddle2cinn/CMakeLists.txt @@ -1,13 +1,17 @@ cc_library(cinn_cache_key SRCS cinn_cache_key.cc DEPS boost graph graph_helper lod_tensor proto_desc) cc_library(cinn_compiled_object SRCS cinn_compiled_object.cc DEPS feed_fetch_method graph lod_tensor proto_desc) cc_library(cinn_runner SRCS cinn_runner.cc DEPS cinn_cache_key cinn_compiled_object feed_fetch_method graph lod_tensor scope) -cc_library(build_cinn_pass SRCS build_cinn_pass.cc DEPS pass subgraph_detector cinn) -cc_library(transform_desc SRCS transform_desc.cc DEPS proto_desc cinn) -cc_library(cinn_graph_symbolization SRCS cinn_graph_symbolization.cc DEPS lod_tensor graph graph_helper transform_desc cinn) +cc_library(build_cinn_pass SRCS build_cinn_pass.cc DEPS pass subgraph_detector) + +if (WITH_CINN) + cc_library(transform_desc SRCS transform_desc.cc DEPS proto_desc cinn) + cc_library(cinn_graph_symbolization SRCS cinn_graph_symbolization.cc DEPS lod_tensor graph graph_helper transform_desc cinn) + + cc_test(test_transform_desc SRCS transform_desc_test.cc DEPS transform_desc) + cc_test(test_cinn_graph_symbolization SRCS cinn_graph_symbolization_test.cc DEPS cinn_graph_symbolization) +endif() cc_test(cinn_cache_key_test SRCS cinn_cache_key_test.cc DEPS cinn_cache_key) cc_test(cinn_runner_test SRCS cinn_runner_test.cc DEPS cinn_runner proto_desc) cc_test(cinn_compiled_object_test SRCS cinn_compiled_object_test.cc DEPS cinn_compiled_object) cc_test(test_build_cinn_pass SRCS build_cinn_pass_test.cc DEPS build_cinn_pass) -cc_test(test_transform_desc SRCS transform_desc_test.cc DEPS transform_desc) -cc_test(test_cinn_graph_symbolization SRCS cinn_graph_symbolization_test.cc DEPS cinn_graph_symbolization) diff --git a/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc b/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc index 57c6a52c01622..caddc8fbb7381 100644 --- a/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc +++ b/paddle/fluid/framework/paddle2cinn/build_cinn_pass.cc @@ -20,11 +20,39 @@ limitations under the License. */ #include #include -#include "cinn/frontend/op_mapper_registry.h" -#include "cinn/frontend/op_mappers/use_op_mappers.h" #include "paddle/fluid/framework/ir/graph.h" #include "paddle/fluid/framework/ir/node.h" #include "paddle/fluid/framework/ir/subgraph_detector.h" +// #include "cinn/frontend/op_mapper_registry.h" +// #include "cinn/frontend/op_mappers/use_op_mappers.h" + +// TODO(jiangcheng05): just for local compile, remove after +// paddle and CINN have been binded +// The APIs are the same as CINN: +// https://github.com/PaddlePaddle/CINN/blob/develop/cinn/utils/registry.h +namespace cinn { +namespace frontend { +class OpMapperRegistry { + public: + static OpMapperRegistry* Global() { + static OpMapperRegistry inst; + return &inst; + } + + inline const OpMapperRegistry* Find(const std::string& name) { + std::unordered_set fmap_ = {"mul", "add", "relu", "sigmoid", + "softmax"}; + auto p = fmap_.find(name); + if (p != fmap_.end()) { + return this; + } else { + return nullptr; + } + } +}; + +} // namespace frontend +} // namespace cinn namespace paddle { namespace framework { From 4b795f9b643dfcaaeef89ec5fc6e36bd9d2d85e3 Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Fri, 22 Oct 2021 10:53:31 +0000 Subject: [PATCH 15/16] full error information for CI --- .../fluid/framework/paddle2cinn/cinn_graph_symbolization.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc index 3482f99f8dda5..65605d579674e 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc @@ -130,7 +130,9 @@ void CinnGraphSymbolization::RunOp(const CinnOpDesc& op_desc, auto kernel = ::cinn::frontend::OpMapperRegistry::Global()->Find(op_type); PADDLE_ENFORCE_NE( kernel, nullptr, - platform::errors::NotFound("Op %s Not Support by CINN", op_type.c_str())); + platform::errors::NotFound("Op %s Not Support by CINN, Please Register" + " it in CINN", + op_type.c_str())); VLOG(4) << "Running Op " << op_type; kernel->Run(op_desc, ctx); } From 9f269c42da37a86a9364971fdbeef588d036ce74 Mon Sep 17 00:00:00 2001 From: jiangcheng Date: Sat, 23 Oct 2021 02:26:44 +0000 Subject: [PATCH 16/16] full enfore information for CI pass --- .../paddle2cinn/cinn_graph_symbolization.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc index 65605d579674e..e4e16498b8440 100644 --- a/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc +++ b/paddle/fluid/framework/paddle2cinn/cinn_graph_symbolization.cc @@ -127,12 +127,12 @@ CinnGraphSymbolization::TransformAllGraphOpToCinn() const { void CinnGraphSymbolization::RunOp(const CinnOpDesc& op_desc, const OpMapperContext& ctx) const { const auto& op_type = op_desc.Type(); - auto kernel = ::cinn::frontend::OpMapperRegistry::Global()->Find(op_type); - PADDLE_ENFORCE_NE( - kernel, nullptr, - platform::errors::NotFound("Op %s Not Support by CINN, Please Register" - " it in CINN", - op_type.c_str())); + auto* kernel = ::cinn::frontend::OpMapperRegistry::Global()->Find(op_type); + PADDLE_ENFORCE_NE(kernel, nullptr, + platform::errors::NotFound( + "Op %s is Not Supported by CINN, please register" + " this op in the CINN repo.", + op_type.c_str())); VLOG(4) << "Running Op " << op_type; kernel->Run(op_desc, ctx); }