From 239d716b48d9478674ce9932cd137d2b16ed3db1 Mon Sep 17 00:00:00 2001 From: superjomn Date: Tue, 16 Apr 2019 20:41:49 +0800 Subject: [PATCH] init optimizer and kernel_executor --- paddle/fluid/lite/api/CMakeLists.txt | 2 +- paddle/fluid/lite/api/cxx_api.h | 2 +- paddle/fluid/lite/api/cxx_api_test.cc | 2 +- paddle/fluid/lite/core/CMakeLists.txt | 6 +- paddle/fluid/lite/core/kernel_executor.cc | 19 ++++++ paddle/fluid/lite/core/kernel_executor.h | 50 +++++++++++++++ paddle/fluid/lite/core/mir/CMakeLists.txt | 1 + .../lite/core/mir/graph_visualize_pass.cc | 4 +- paddle/fluid/lite/core/mir/pass_manager.cc | 2 - paddle/fluid/lite/core/mir/ssa_graph.h | 7 ++- paddle/fluid/lite/core/mir/ssa_graph_test.cc | 10 +-- .../lite/core/{executor.cc => op_executor.cc} | 0 .../lite/core/{executor.h => op_executor.h} | 6 +- .../{executor_test.cc => op_executor_test.cc} | 2 +- paddle/fluid/lite/core/optimizer.cc | 13 ++++ paddle/fluid/lite/core/optimizer.h | 63 +++++++++++++++++++ 16 files changed, 169 insertions(+), 20 deletions(-) create mode 100644 paddle/fluid/lite/core/kernel_executor.cc create mode 100644 paddle/fluid/lite/core/kernel_executor.h rename paddle/fluid/lite/core/{executor.cc => op_executor.cc} (100%) rename paddle/fluid/lite/core/{executor.h => op_executor.h} (93%) rename paddle/fluid/lite/core/{executor_test.cc => op_executor_test.cc} (97%) create mode 100644 paddle/fluid/lite/core/optimizer.cc create mode 100644 paddle/fluid/lite/core/optimizer.h diff --git a/paddle/fluid/lite/api/CMakeLists.txt b/paddle/fluid/lite/api/CMakeLists.txt index 9997b83ee20..06e49d363bb 100644 --- a/paddle/fluid/lite/api/CMakeLists.txt +++ b/paddle/fluid/lite/api/CMakeLists.txt @@ -1,3 +1,3 @@ -cc_library(cxx_api_lite SRCS cxx_api.cc DEPS scope_lite executor_lite host_kernels ops_lite) +cc_library(cxx_api_lite SRCS cxx_api.cc DEPS scope_lite op_executor_lite host_kernels ops_lite) cc_test(test_cxx_api_lite SRCS cxx_api_test.cc DEPS cxx_api_lite model_parser_lite) diff --git a/paddle/fluid/lite/api/cxx_api.h b/paddle/fluid/lite/api/cxx_api.h index 255d55cede5..9b561e3be25 100644 --- a/paddle/fluid/lite/api/cxx_api.h +++ b/paddle/fluid/lite/api/cxx_api.h @@ -13,7 +13,7 @@ // limitations under the License. #pragma once -#include "paddle/fluid/lite/core/executor.h" +#include "paddle/fluid/lite/core/op_executor.h" #include "paddle/fluid/lite/core/op_lite.h" #include "paddle/fluid/lite/model_parser/model_parser.h" diff --git a/paddle/fluid/lite/api/cxx_api_test.cc b/paddle/fluid/lite/api/cxx_api_test.cc index 157bf41ee1a..e1058de04a2 100644 --- a/paddle/fluid/lite/api/cxx_api_test.cc +++ b/paddle/fluid/lite/api/cxx_api_test.cc @@ -14,7 +14,7 @@ #include "paddle/fluid/lite/api/cxx_api.h" #include -#include "paddle/fluid/lite/core/executor.h" +#include "paddle/fluid/lite/core/op_executor.h" #include "paddle/fluid/lite/core/op_registry.h" namespace paddle { diff --git a/paddle/fluid/lite/core/CMakeLists.txt b/paddle/fluid/lite/core/CMakeLists.txt index 08ba80410c9..6fd696d5d8c 100644 --- a/paddle/fluid/lite/core/CMakeLists.txt +++ b/paddle/fluid/lite/core/CMakeLists.txt @@ -5,16 +5,18 @@ cc_library(variable_lite SRCS variable.cc) cc_library(op_registry_lite SRCS op_registry.cc) cc_library(scope_lite SRCS scope.cc) cc_library(op_lite SRCS op_lite.cc DEPS scope_lite op_registry_lite) -cc_library(executor_lite SRCS executor.cc DEPS scope_lite tensor_lite op_lite op_registry_lite +cc_library(op_executor_lite SRCS op_executor.cc DEPS scope_lite tensor_lite op_lite op_registry_lite #TODO(Superjomn) remove these dependencies from original framework proto_desc) +cc_library(kernel_executor_lite SRCS kernel_executor.cc DEPS mir_ssa_graph kernel_lite) cc_library(type_system SRCS type_system.cc DEPS tensor_lite) +cc_library(optimizer_lite SRCS optimizer.cc DEPS mir_pass_manager) cc_test(test_scope_lite SRCS scope_test.cc DEPS scope_lite) cc_test(test_kernel_lite SRCS kernel_test.cc DEPS target_wrapper_x86) cc_test(test_op_lite SRCS op_lite_test.cc DEPS op_lite) cc_test(test_tensor_lite SRCS tensor_test.cc) -cc_test(test_executor_lite SRCS executor_test.cc DEPS executor_lite ops_lite host_kernels) +cc_test(test_op_executor_lite SRCS op_executor_test.cc DEPS op_executor_lite ops_lite host_kernels) cc_test(test_type_system SRCS type_system_test.cc DEPS type_system) add_subdirectory(mir) diff --git a/paddle/fluid/lite/core/kernel_executor.cc b/paddle/fluid/lite/core/kernel_executor.cc new file mode 100644 index 00000000000..4ca0d20d465 --- /dev/null +++ b/paddle/fluid/lite/core/kernel_executor.cc @@ -0,0 +1,19 @@ +// Copyright (c) 2019 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/lite/core/kernel_executor.h" + +namespace paddle { +namespace lite {} // namespace lite +} // namespace paddle \ No newline at end of file diff --git a/paddle/fluid/lite/core/kernel_executor.h b/paddle/fluid/lite/core/kernel_executor.h new file mode 100644 index 00000000000..b933c13bfc1 --- /dev/null +++ b/paddle/fluid/lite/core/kernel_executor.h @@ -0,0 +1,50 @@ +// Copyright (c) 2019 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 "paddle/fluid/lite/core/mir/ssa_graph.h" + +namespace paddle { +namespace lite { + +/* + * KernelExecutor executes a list of kernels. + */ +class KernelExecutorBase { + public: + KernelExecutorBase(std::unique_ptr&& program); + + // Prepare runtime context. + void PrepareWorkspace(); + + void Run(); + + private: + lite::Scope* scope_{}; + lite::Scope* exec_scope_{}; +}; + +/* + * KernelExecutor executes the kernels without concurrency, works in X86 place. + */ +class SerialKernelExecutor : public KernelExecutorBase {}; + +/* + * KernelExecutor executes the kernels with CUDA like stream parallel support, + * works in CUDA like devices. + */ +class StreamKernelExecutor : public KernelExecutorBase {}; + +} // namespace lite +} // namespace paddle diff --git a/paddle/fluid/lite/core/mir/CMakeLists.txt b/paddle/fluid/lite/core/mir/CMakeLists.txt index 6bdf8cb2f48..5e789829abb 100644 --- a/paddle/fluid/lite/core/mir/CMakeLists.txt +++ b/paddle/fluid/lite/core/mir/CMakeLists.txt @@ -17,4 +17,5 @@ cc_test(test_ssa_graph SRCS ssa_graph_test.cc DEPS proto_desc ops_lite host_kernels mir_passes + mir_pass_manager ) diff --git a/paddle/fluid/lite/core/mir/graph_visualize_pass.cc b/paddle/fluid/lite/core/mir/graph_visualize_pass.cc index 675ef29fe9c..99c53a310d1 100644 --- a/paddle/fluid/lite/core/mir/graph_visualize_pass.cc +++ b/paddle/fluid/lite/core/mir/graph_visualize_pass.cc @@ -20,6 +20,8 @@ namespace paddle { namespace lite { namespace mir { +using inference::analysis::Dot; + void GraphVisualizePass::Apply(std::unique_ptr& graph) { Visualize(graph.get()); } @@ -39,7 +41,7 @@ std::string Visualize(mir::SSAGraph* graph) { } if (node.IsInstruct()) { - dot.AddNode(key, {}); + dot.AddNode(key, {Dot::Attr("shape", "box")}); for (auto& x : node.inlinks) { auto name = x->AsArgument().name; if (!exists_args.count(name)) { diff --git a/paddle/fluid/lite/core/mir/pass_manager.cc b/paddle/fluid/lite/core/mir/pass_manager.cc index 2767218f468..6e1c0cd9f5f 100644 --- a/paddle/fluid/lite/core/mir/pass_manager.cc +++ b/paddle/fluid/lite/core/mir/pass_manager.cc @@ -24,5 +24,3 @@ PassManager::PassManager() {} } // namespace mir } // namespace lite } // namespace paddle - -USE_MIR_PASS(demo); diff --git a/paddle/fluid/lite/core/mir/ssa_graph.h b/paddle/fluid/lite/core/mir/ssa_graph.h index 03aebd7ad91..6dee98c76df 100644 --- a/paddle/fluid/lite/core/mir/ssa_graph.h +++ b/paddle/fluid/lite/core/mir/ssa_graph.h @@ -30,9 +30,10 @@ namespace mir { // - main block, which is a list of OpLite // - scope: which contains all the weights struct Program { - std::list inputs; + std::list tmp_vars; + std::list weights; std::list> ops; - std::unique_ptr scope; + lite::Scope *scope; }; // An Graph for MIR. It is built from a list of Op and a scope. @@ -44,7 +45,7 @@ class SSAGraph : GraphBase { // @param valid_places: the valid places user set for the system. void Build(const Program &program, const std::vector &valid_places) { // create inputs - for (const auto &name : program.inputs) { + for (const auto &name : program.tmp_vars) { node_storage_.emplace_back(); auto &new_node = node_storage_.back(); auto &arg = new_node.AsArgument(); diff --git a/paddle/fluid/lite/core/mir/ssa_graph_test.cc b/paddle/fluid/lite/core/mir/ssa_graph_test.cc index a492590edee..0db9164e7e2 100644 --- a/paddle/fluid/lite/core/mir/ssa_graph_test.cc +++ b/paddle/fluid/lite/core/mir/ssa_graph_test.cc @@ -34,7 +34,7 @@ void BuildFc(framework::ProgramDesc* desc, const std::string& x, Program FakeProgram() { Program program; - program.scope.reset(new lite::Scope); + program.scope = new lite::Scope; auto add_fc = [&](int id, std::string x) { // create variables @@ -55,12 +55,12 @@ Program FakeProgram() { desc.Flush(); // add to input - program.inputs.push_back(w1); - program.inputs.push_back(b1); + program.tmp_vars.push_back(w1); + program.tmp_vars.push_back(b1); auto fc_op = LiteOpRegistry::Global().Create("fc"); fc_op->PickKernel({Place{TARGET(kHost), PRECISION(kFloat)}}); - fc_op->Attach(desc, program.scope.get()); + fc_op->Attach(desc, program.scope); program.ops.emplace_back(std::move(fc_op)); w1v->Resize({100, 100}); @@ -74,7 +74,7 @@ Program FakeProgram() { // out1, w2, b2 -fc-> out2 std::string x = "x"; - program.inputs.push_back(x); + program.tmp_vars.push_back(x); auto* xv = program.scope->Var(x)->GetMutable(); xv->Resize({100, 100}); diff --git a/paddle/fluid/lite/core/executor.cc b/paddle/fluid/lite/core/op_executor.cc similarity index 100% rename from paddle/fluid/lite/core/executor.cc rename to paddle/fluid/lite/core/op_executor.cc diff --git a/paddle/fluid/lite/core/executor.h b/paddle/fluid/lite/core/op_executor.h similarity index 93% rename from paddle/fluid/lite/core/executor.h rename to paddle/fluid/lite/core/op_executor.h index d53eb2b90c6..afe491652f7 100644 --- a/paddle/fluid/lite/core/executor.h +++ b/paddle/fluid/lite/core/op_executor.h @@ -24,7 +24,7 @@ namespace lite { // The Executor is used to run the operators. class Executor { public: - Executor(lite::Scope* scope, const std::vector& valid_places) + Executor(lite::Scope* scope, const std::vector& valid_places) : scope_(scope), valid_places_(valid_places) {} // Create temporary variables. @@ -52,7 +52,7 @@ class Executor { ops_.emplace_back(LiteOpRegistry::Global().Create(op_type)); // pick initial kernel ops_.back()->PickKernel(valid_places_); - ops_.back()->AttachImpl(*op_desc, exec_scope_); + ops_.back()->Attach(*op_desc, exec_scope_); } } @@ -73,7 +73,7 @@ class Executor { private: std::vector> ops_; lite::Scope* scope_{}; - std::vector valid_places_; + std::vector valid_places_; lite::Scope* exec_scope_{}; }; diff --git a/paddle/fluid/lite/core/executor_test.cc b/paddle/fluid/lite/core/op_executor_test.cc similarity index 97% rename from paddle/fluid/lite/core/executor_test.cc rename to paddle/fluid/lite/core/op_executor_test.cc index 17b67410894..650d2bb1e7f 100644 --- a/paddle/fluid/lite/core/executor_test.cc +++ b/paddle/fluid/lite/core/op_executor_test.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "paddle/fluid/lite/core/executor.h" +#include "paddle/fluid/lite/core/op_executor.h" #include #include diff --git a/paddle/fluid/lite/core/optimizer.cc b/paddle/fluid/lite/core/optimizer.cc new file mode 100644 index 00000000000..ce71e4de2b8 --- /dev/null +++ b/paddle/fluid/lite/core/optimizer.cc @@ -0,0 +1,13 @@ +// Copyright (c) 2019 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. diff --git a/paddle/fluid/lite/core/optimizer.h b/paddle/fluid/lite/core/optimizer.h new file mode 100644 index 00000000000..76bfb6c7b38 --- /dev/null +++ b/paddle/fluid/lite/core/optimizer.h @@ -0,0 +1,63 @@ +// Copyright (c) 2019 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 +#include "paddle/fluid/lite/core/mir/pass_manager.h" +#include "paddle/fluid/lite/core/mir/pass_manager.h" +#include "paddle/fluid/lite/core/mir/ssa_graph.h" + +namespace paddle { +namespace lite { + +/* + * lite::Optimizer optimize a program. It utilize the mir passes to analysis the + * program and export an optimized program. + */ +class Optimizer { + public: + void Run(std::unique_ptr&& program, + const std::vector& valid_places, + const std::vector& passes = {}) { + CHECK(!graph_) << "duplicate optimize found"; + graph_.reset(new mir::SSAGraph); + graph_->Build(*program, valid_places); + RunPasses(); + } + + // Generate a new program based on the mir graph. + std::unique_ptr GenProgram() {} + + // Generate C++ code which combines the inference program, model and weights. + void GenCode(const std::string& code_dir); + + const mir::SSAGraph& ssa_graph() const { + CHECK(graph_); + return *graph_; + } + + protected: + // Run the default passes registered in the PassManager. + void RunPasses() { mir::PassManager::Global().Run(); } + + // Specify the passes and run them. + void RunPasses(std::vector& passes); + + private: + std::unique_ptr graph_; +}; + +} // namespace lite +} // namespace paddle -- GitLab