analysis/code-clean
commit
6d01f10d56
@ -0,0 +1,126 @@
|
||||
// Copyright (c) 2018 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/contrib/inference/paddle_inference_api.h"
|
||||
#include "paddle/contrib/inference/paddle_inference_api_impl.h"
|
||||
#include "paddle/fluid/inference/analysis/analyzer.h"
|
||||
#include "paddle/fluid/inference/utils/singleton.h"
|
||||
|
||||
namespace paddle {
|
||||
|
||||
using inference::analysis::Argument;
|
||||
using inference::Singleton;
|
||||
using inference::analysis::Analyzer;
|
||||
using framework::proto::ProgramDesc;
|
||||
|
||||
class TensorRTSubgraphPredictor : public NativePaddlePredictor {
|
||||
public:
|
||||
explicit TensorRTSubgraphPredictor(const TensorRTConfig& config)
|
||||
: NativePaddlePredictor(config), config_(config) {}
|
||||
|
||||
bool Init(const std::shared_ptr<framework::Scope>& parent_scope) {
|
||||
VLOG(3) << "Predictor::init()";
|
||||
|
||||
if (config_.use_gpu) {
|
||||
place_ = paddle::platform::CUDAPlace(config_.device);
|
||||
} else {
|
||||
place_ = paddle::platform::CPUPlace();
|
||||
}
|
||||
if (parent_scope) {
|
||||
scope_ = parent_scope;
|
||||
sub_scope_ = &(parent_scope->NewScope());
|
||||
} else {
|
||||
paddle::framework::InitDevices(false);
|
||||
scope_.reset(new paddle::framework::Scope());
|
||||
}
|
||||
|
||||
executor_.reset(new paddle::framework::Executor(place_));
|
||||
|
||||
// Initialize the inference program
|
||||
if (!config_.model_dir.empty()) {
|
||||
// Parameters are saved in separate files sited in
|
||||
// the specified `dirname`.
|
||||
inference_program_ = paddle::inference::Load(
|
||||
executor_.get(), scope_.get(), config_.model_dir);
|
||||
} else if (!config_.prog_file.empty() && !config_.param_file.empty()) {
|
||||
// All parameters are saved in a single file.
|
||||
// The file names should be consistent with that used
|
||||
// in Python API `fluid.io.save_inference_model`.
|
||||
inference_program_ = paddle::inference::Load(
|
||||
executor_.get(), scope_.get(), config_.prog_file, config_.param_file);
|
||||
} else {
|
||||
LOG(ERROR) << "fail to load inference model.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Analyze inference_program
|
||||
Argument argument;
|
||||
argument.origin_program_desc.reset(
|
||||
new ProgramDesc(*inference_program_->Proto()));
|
||||
Singleton<Analyzer>::Global().Run(&argument);
|
||||
CHECK(argument.transformed_program_desc);
|
||||
VLOG(5) << "transformed program:\n"
|
||||
<< argument.transformed_program_desc->SerializeAsString();
|
||||
VLOG(5) << "to prepare executor";
|
||||
*inference_program_->Proto() = *argument.transformed_program_desc;
|
||||
ctx_ = executor_->Prepare(*inference_program_, 0);
|
||||
|
||||
VLOG(5) << "to create variables";
|
||||
executor_->CreateVariables(
|
||||
*inference_program_, sub_scope_ ? sub_scope_ : scope_.get(), 0);
|
||||
|
||||
// Get the feed_target_names and fetch_target_names
|
||||
feed_target_names_ = inference_program_->GetFeedTargetNames();
|
||||
fetch_target_names_ = inference_program_->GetFetchTargetNames();
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
TensorRTConfig config_;
|
||||
};
|
||||
|
||||
template <>
|
||||
std::unique_ptr<PaddlePredictor>
|
||||
CreatePaddlePredictor<TensorRTConfig, PaddleEngineKind::kAutoMixedTensorRT>(
|
||||
const TensorRTConfig& config) {
|
||||
VLOG(3) << "create TensorRTSubgraphPredictor";
|
||||
if (config.use_gpu) {
|
||||
// 1. GPU memeroy
|
||||
PADDLE_ENFORCE_GT(
|
||||
config.fraction_of_gpu_memory,
|
||||
0.f,
|
||||
"fraction_of_gpu_memory in the config should be set to range (0., 1.]");
|
||||
PADDLE_ENFORCE_GE(config.device, 0, "Invalid device id %d", config.device);
|
||||
std::vector<std::string> flags;
|
||||
if (config.fraction_of_gpu_memory >= 0.0f ||
|
||||
config.fraction_of_gpu_memory <= 0.95f) {
|
||||
flags.push_back("dummpy");
|
||||
std::string flag = "--fraction_of_gpu_memory_to_use=" +
|
||||
std::to_string(config.fraction_of_gpu_memory);
|
||||
flags.push_back(flag);
|
||||
VLOG(3) << "set flag: " << flag;
|
||||
framework::InitGflags(flags);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<PaddlePredictor> predictor(
|
||||
new TensorRTSubgraphPredictor(config));
|
||||
if (!dynamic_cast<TensorRTSubgraphPredictor*>(predictor.get())
|
||||
->Init(nullptr)) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::move(predictor);
|
||||
}
|
||||
|
||||
} // namespace paddle
|
@ -0,0 +1,64 @@
|
||||
// Copyright (c) 2018 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 <gflags/gflags.h>
|
||||
#include <glog/logging.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include "paddle/contrib/inference/paddle_inference_api.h"
|
||||
|
||||
namespace paddle {
|
||||
|
||||
DEFINE_string(dirname, "", "Directory of the inference model.");
|
||||
|
||||
void Main(bool use_gpu) {
|
||||
//# 1. Create PaddlePredictor with a config.
|
||||
TensorRTConfig config;
|
||||
config.model_dir = FLAGS_dirname + "word2vec.inference.model";
|
||||
config.use_gpu = use_gpu;
|
||||
config.fraction_of_gpu_memory = 0.15;
|
||||
config.device = 0;
|
||||
auto predictor =
|
||||
CreatePaddlePredictor<TensorRTConfig,
|
||||
PaddleEngineKind::kAutoMixedTensorRT>(config);
|
||||
|
||||
for (int batch_id = 0; batch_id < 3; batch_id++) {
|
||||
//# 2. Prepare input.
|
||||
int64_t data[4] = {1, 2, 3, 4};
|
||||
|
||||
PaddleTensor tensor{.name = "",
|
||||
.shape = std::vector<int>({4, 1}),
|
||||
.data = PaddleBuf(data, sizeof(data)),
|
||||
.dtype = PaddleDType::INT64};
|
||||
|
||||
// For simplicity, we set all the slots with the same data.
|
||||
std::vector<PaddleTensor> slots(4, tensor);
|
||||
|
||||
//# 3. Run
|
||||
std::vector<PaddleTensor> outputs;
|
||||
CHECK(predictor->Run(slots, &outputs));
|
||||
|
||||
//# 4. Get output.
|
||||
ASSERT_EQ(outputs.size(), 1UL);
|
||||
LOG(INFO) << "output buffer size: " << outputs.front().data.length();
|
||||
const size_t num_elements = outputs.front().data.length() / sizeof(float);
|
||||
// The outputs' buffers are in CPU memory.
|
||||
for (size_t i = 0; i < std::min(5UL, num_elements); i++) {
|
||||
LOG(INFO) << static_cast<float*>(outputs.front().data.data())[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(paddle_inference_api_tensorrt_subgraph_engine, main) { Main(true); }
|
||||
|
||||
} // namespace paddle
|
@ -0,0 +1,82 @@
|
||||
// Copyright (c) 2018 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/inference/analysis/analyzer.h"
|
||||
#include "paddle/fluid/inference/analysis/data_flow_graph_to_fluid_pass.h"
|
||||
#include "paddle/fluid/inference/analysis/dfg_graphviz_draw_pass.h"
|
||||
#include "paddle/fluid/inference/analysis/fluid_to_data_flow_graph_pass.h"
|
||||
#include "paddle/fluid/inference/analysis/pass_manager.h"
|
||||
#include "paddle/fluid/inference/analysis/tensorrt_subgraph_node_mark_pass.h"
|
||||
#include "paddle/fluid/inference/analysis/tensorrt_subgraph_pass.h"
|
||||
|
||||
namespace paddle {
|
||||
namespace inference {
|
||||
namespace analysis {
|
||||
|
||||
DEFINE_bool(inference_analysis_enable_tensorrt_subgraph_engine, false,
|
||||
"Enable subgraph to TensorRT engine for acceleration");
|
||||
|
||||
DEFINE_string(inference_analysis_graphviz_log_root, "./",
|
||||
"Graphviz debuger for data flow graphs.");
|
||||
|
||||
class DfgPassManagerImpl final : public DfgPassManager {
|
||||
public:
|
||||
DfgPassManagerImpl() {
|
||||
// TODO(Superjomn) set the key with pass reprs.
|
||||
AddPass("fluid-to-data-flow-graph", new FluidToDataFlowGraphPass);
|
||||
if (FLAGS_inference_analysis_enable_tensorrt_subgraph_engine) {
|
||||
auto trt_teller = [](const Node* node) {
|
||||
if (!node->IsFunction()) return false;
|
||||
return static_cast<const Function*>(node)->func_type() == "mul";
|
||||
};
|
||||
AddPass("tensorrt-subgraph-marker",
|
||||
new TensorRTSubgraphNodeMarkPass(trt_teller));
|
||||
AddPass("tensorrt-subgraph", new TensorRTSubGraphPass(trt_teller));
|
||||
}
|
||||
AddPass("data-flow-graph-to-fluid", new DataFlowGraphToFluidPass);
|
||||
}
|
||||
|
||||
std::string repr() const override { return "dfg-pass-manager"; }
|
||||
std::string description() const override { return "DFG pass manager."; }
|
||||
|
||||
private:
|
||||
void AddPass(const std::string& name, Pass* pass) {
|
||||
LOG(INFO) << "Adding pass " << name;
|
||||
Register(name, pass);
|
||||
AddGraphvizDebugerPass(pass);
|
||||
}
|
||||
|
||||
// Add the graphviz debuger pass if the parent pass has one.
|
||||
void AddGraphvizDebugerPass(Pass* pass) {
|
||||
auto* debuger_pass = pass->CreateGraphvizDebugerPass();
|
||||
if (debuger_pass) {
|
||||
LOG(INFO) << " - register debug pass [" << debuger_pass->repr() << "]";
|
||||
Register(debuger_pass->repr(), debuger_pass);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Analyzer::Analyzer() { Register("manager1", new DfgPassManagerImpl); }
|
||||
|
||||
void Analyzer::Run(Argument* argument) {
|
||||
for (auto& x : data_) {
|
||||
PADDLE_ENFORCE(x->Initialize(argument));
|
||||
x->RunAll();
|
||||
PADDLE_ENFORCE(x->Finalize());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace analysis
|
||||
} // namespace inference
|
||||
} // namespace paddle
|
@ -0,0 +1,66 @@
|
||||
/* Copyright (c) 2018 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. */
|
||||
|
||||
/*
|
||||
* This file contains Analyzer, an class that exposed as a library that analyze
|
||||
* and optimize
|
||||
* Fluid ProgramDesc for inference. Similar to LLVM, it has multiple flags to
|
||||
* control whether
|
||||
* an process is applied on the program.
|
||||
*
|
||||
* The processes are called Passes in analysis, the Passes are placed in a
|
||||
* pipeline, the first
|
||||
* Pass is the FluidToDataFlowGraphPass which transforms a Fluid ProgramDesc to
|
||||
* a data flow
|
||||
* graph, the last Pass is DataFlowGraphToFluidPass which transforms a data flow
|
||||
* graph to a
|
||||
* Fluid ProgramDesc. The passes in the middle of the pipeline can be any Passes
|
||||
* which take a
|
||||
* node or data flow graph as input.
|
||||
*
|
||||
* The Analyzer can be used in two methods, the first is a executable file which
|
||||
* can be used to
|
||||
* pre-process the inference model and can be controlled by passing difference
|
||||
* command flags;
|
||||
* the other way is to compose inside the inference API as a runtime pre-process
|
||||
* phase in the
|
||||
* inference service.
|
||||
*/
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
#include "paddle/fluid/inference/analysis/pass.h"
|
||||
#include "paddle/fluid/inference/analysis/pass_manager.h"
|
||||
|
||||
namespace paddle {
|
||||
namespace inference {
|
||||
namespace analysis {
|
||||
|
||||
// TODO(Superjomn) add a definition flag like PADDLE_WITH_TENSORRT and hide this
|
||||
// flag if not available.
|
||||
DECLARE_bool(inference_analysis_enable_tensorrt_subgraph_engine);
|
||||
DECLARE_string(inference_analysis_graphviz_log_root);
|
||||
|
||||
class Analyzer : public OrderedRegistry<PassManager> {
|
||||
public:
|
||||
// Register all the pass-managers.
|
||||
Analyzer();
|
||||
|
||||
void Run(Argument* argument);
|
||||
|
||||
DISABLE_COPY_AND_ASSIGN(Analyzer);
|
||||
};
|
||||
|
||||
} // namespace analysis
|
||||
} // namespace inference
|
||||
} // namespace paddle
|
@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2018 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/inference/analysis/analyzer.h"
|
||||
#include "paddle/fluid/inference/analysis/ut_helper.h"
|
||||
|
||||
namespace paddle {
|
||||
namespace inference {
|
||||
namespace analysis {
|
||||
|
||||
TEST_F(DFG_Tester, main) {
|
||||
Analyzer analyser;
|
||||
analyser.Run(&argument);
|
||||
}
|
||||
|
||||
} // namespace analysis
|
||||
} // namespace inference
|
||||
} // namespace paddle
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue