Skip to content

Commit 5fd2ffd

Browse files
authored
Merge pull request #13372 from tensor-tang/fea/ut/vis
add analysis vis ut
2 parents 036dc34 + 26fc698 commit 5fd2ffd

File tree

7 files changed

+188
-17
lines changed

7 files changed

+188
-17
lines changed

paddle/fluid/inference/api/analysis_predictor.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ bool AnalysisPredictor::Init(
7777

7878
OptimizeInferenceProgram();
7979
ctx_ = executor_->Prepare(*inference_program_, 0);
80+
if (config_._use_mkldnn) {
81+
executor_->EnableMKLDNN(*inference_program_);
82+
}
8083

8184
VLOG(5) << "to create variables";
8285
PADDLE_ENFORCE(scope_.get());

paddle/fluid/inference/api/api_impl.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ bool NativePaddlePredictor::Init(
106106
}
107107

108108
ctx_ = executor_->Prepare(*inference_program_, 0);
109+
if (config_._use_mkldnn) {
110+
executor_->EnableMKLDNN(*inference_program_);
111+
}
109112
executor_->CreateVariables(*inference_program_,
110113
sub_scope_ ? sub_scope_ : scope_.get(), 0);
111114

paddle/fluid/inference/api/paddle_inference_api.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class PaddleBuf {
4545
PaddleBuf(void* data, size_t length)
4646
: data_(data), length_(length), memory_owned_{false} {}
4747
// Own memory.
48-
PaddleBuf(size_t length)
48+
explicit PaddleBuf(size_t length)
4949
: data_(new char[length]), length_(length), memory_owned_(true) {}
5050
// Resize to `length` bytes.
5151
void Resize(size_t length);
@@ -121,6 +121,8 @@ struct NativeConfig : public PaddlePredictor::Config {
121121
bool use_gpu{false};
122122
int device{0};
123123
float fraction_of_gpu_memory{-1.f}; // Negative to notify initialization.
124+
// NOTE: NOT use it, just for the internal test, will discard later
125+
bool _use_mkldnn{false};
124126
// Specify the variable's name of each input.
125127
bool specify_input_name{false};
126128

paddle/fluid/inference/tests/api/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,19 @@ inference_analysis_test(test_analyzer_text_classification SRCS analyzer_text_cla
5555
EXTRA_DEPS ${INFERENCE_EXTRA_DEPS}
5656
ARGS --infer_model=${TEXT_CLASSIFICATION_INSTALL_DIR}/text-classification-Senta
5757
--infer_data=${TEXT_CLASSIFICATION_INSTALL_DIR}/data.txt)
58+
59+
# ocr
60+
set(OCR_MODEL_URL "http://paddlemodels.cdn.bcebos.com/inference-vis-demos%2Focr.tar.gz")
61+
set(OCR_INSTALL_DIR "${THIRD_PARTY_PATH}/inference_demo/ocr")
62+
if (NOT EXISTS ${OCR_INSTALL_DIR} AND WITH_INFERENCE)
63+
get_filename_component(filename ${OCR_MODEL_URL} NAME)
64+
message(STATUS "Download inference test stuff ${filename} from ${OCR_MODEL_URL}")
65+
execute_process(COMMAND bash -c "mkdir -p ${OCR_INSTALL_DIR}")
66+
execute_process(COMMAND bash -c "cd ${OCR_INSTALL_DIR} && wget -q ${OCR_MODEL_URL}")
67+
execute_process(COMMAND bash -c "cd ${OCR_INSTALL_DIR} && tar xzf ${filename}")
68+
message(STATUS "finish downloading ${filename}")
69+
endif()
70+
inference_analysis_test(test_analyzer_ocr SRCS analyzer_vis_tester.cc
71+
EXTRA_DEPS ${INFERENCE_EXTRA_DEPS}
72+
ARGS --infer_model=${OCR_INSTALL_DIR}/model
73+
--infer_data=${OCR_INSTALL_DIR}/data.txt)

paddle/fluid/inference/tests/api/analyzer_lac_tester.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,7 @@ const int64_t lac_ref_data[] = {24, 25, 25, 25, 38, 30, 31, 14, 15, 44, 24, 25,
110110

111111
void TestLACPrediction(const std::string &model_path,
112112
const std::string &data_file, const int batch_size,
113-
const int repeat, bool test_all_data,
114-
bool use_analysis = false) {
113+
const int repeat, bool use_analysis = false) {
115114
AnalysisConfig cfg;
116115
cfg.model_dir = model_path;
117116
cfg.use_gpu = false;
@@ -199,13 +198,13 @@ void TestLACPrediction(const std::string &model_path,
199198
TEST(Analyzer_LAC, native) {
200199
LOG(INFO) << "LAC with native";
201200
TestLACPrediction(FLAGS_infer_model, FLAGS_infer_data, FLAGS_batch_size,
202-
FLAGS_repeat, FLAGS_test_all_data);
201+
FLAGS_repeat);
203202
}
204203

205204
TEST(Analyzer_LAC, analysis) {
206205
LOG(INFO) << "LAC with analysis";
207206
TestLACPrediction(FLAGS_infer_model, FLAGS_infer_data, FLAGS_batch_size,
208-
FLAGS_repeat, FLAGS_test_all_data, true);
207+
FLAGS_repeat, true);
209208
}
210209

211210
} // namespace analysis
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License. */
14+
15+
#include <fstream>
16+
#include <iostream>
17+
#include "paddle/fluid/inference/tests/api/tester_helper.h"
18+
19+
namespace paddle {
20+
namespace inference {
21+
namespace analysis {
22+
23+
struct Record {
24+
std::vector<float> data;
25+
std::vector<int32_t> shape;
26+
};
27+
28+
Record ProcessALine(const std::string &line) {
29+
VLOG(3) << "process a line";
30+
std::vector<std::string> columns;
31+
split(line, '\t', &columns);
32+
CHECK_EQ(columns.size(), 2UL)
33+
<< "data format error, should be <data>\t<shape>";
34+
35+
Record record;
36+
std::vector<std::string> data_strs;
37+
split(columns[0], ' ', &data_strs);
38+
for (auto &d : data_strs) {
39+
record.data.push_back(std::stof(d));
40+
}
41+
42+
std::vector<std::string> shape_strs;
43+
split(columns[1], ' ', &shape_strs);
44+
for (auto &s : shape_strs) {
45+
record.shape.push_back(std::stoi(s));
46+
}
47+
VLOG(3) << "data size " << record.data.size();
48+
VLOG(3) << "data shape size " << record.shape.size();
49+
return record;
50+
}
51+
52+
/*
53+
* Use the native and analysis fluid engine to inference the demo.
54+
* ocr, mobilenet and se_resnext50
55+
*/
56+
void TestVisualPrediction(bool use_mkldnn) {
57+
std::unique_ptr<PaddlePredictor> predictor;
58+
AnalysisConfig cfg;
59+
cfg.param_file = FLAGS_infer_model + "/__params__";
60+
cfg.prog_file = FLAGS_infer_model + "/__model__";
61+
cfg.use_gpu = false;
62+
cfg._use_mkldnn = use_mkldnn;
63+
cfg.device = 0;
64+
cfg.enable_ir_optim = true;
65+
// TODO(TJ): fix fusion gru
66+
cfg.ir_passes.push_back("fc_gru_fuse_pass");
67+
#ifdef PADDLE_WITH_MKLDNN
68+
// disable mkldnn fuse since it should have some bugs
69+
cfg.ir_passes.push_back("conv_relu_mkldnn_fuse_pass");
70+
#endif
71+
predictor =
72+
CreatePaddlePredictor<AnalysisConfig, PaddleEngineKind::kAnalysis>(cfg);
73+
74+
// Only have single batch of data.
75+
std::string line;
76+
std::ifstream file(FLAGS_infer_data);
77+
std::getline(file, line);
78+
auto record = ProcessALine(line);
79+
file.close();
80+
81+
// Inference.
82+
PaddleTensor input;
83+
input.shape = record.shape;
84+
input.data =
85+
PaddleBuf(record.data.data(), record.data.size() * sizeof(float));
86+
input.dtype = PaddleDType::FLOAT32;
87+
88+
std::vector<PaddleTensor> outputs_slots;
89+
Timer timer;
90+
timer.tic();
91+
for (int i = 0; i < FLAGS_repeat; i++) {
92+
predictor->Run({input}, &outputs_slots);
93+
}
94+
PrintTime(/*batch size*/ 1, FLAGS_repeat, /*num threads*/ 1, /*thread id*/ 0,
95+
timer.toc() / FLAGS_repeat);
96+
97+
VLOG(3) << "output.size " << outputs_slots.size();
98+
99+
// run native as reference
100+
auto ref_predictor =
101+
CreatePaddlePredictor<NativeConfig, PaddleEngineKind::kNative>(cfg);
102+
std::vector<PaddleTensor> ref_outputs_slots;
103+
ref_predictor->Run({input}, &ref_outputs_slots);
104+
CompareResult(outputs_slots, ref_outputs_slots);
105+
// print what are fused
106+
AnalysisPredictor *analysis_predictor =
107+
dynamic_cast<AnalysisPredictor *>(predictor.get());
108+
auto &fuse_statis = analysis_predictor->analysis_argument()
109+
.Get<std::unordered_map<std::string, int>>(
110+
framework::ir::kFuseStatisAttr);
111+
for (auto &item : fuse_statis) {
112+
LOG(INFO) << "fused " << item.first << " " << item.second;
113+
}
114+
int num_ops = 0;
115+
for (auto &node :
116+
analysis_predictor->analysis_argument().main_dfg->nodes.nodes()) {
117+
if (node->IsFunction()) {
118+
++num_ops;
119+
}
120+
}
121+
LOG(INFO) << "has num ops: " << num_ops;
122+
}
123+
124+
TEST(Analyzer_vis, analysis) { TestVisualPrediction(/*use_mkldnn*/ false); }
125+
#ifdef PADDLE_WITH_MKLDNN
126+
TEST(Analyzer_vis, analysis_mkldnn) {
127+
TestVisualPrediction(/*use_mkldnn*/ true);
128+
}
129+
#endif
130+
131+
} // namespace analysis
132+
} // namespace inference
133+
} // namespace paddle

paddle/fluid/inference/tests/api/tester_helper.h

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,37 @@ namespace paddle {
3737
namespace inference {
3838

3939
void CompareResult(const std::vector<PaddleTensor> &outputs,
40-
const std::vector<PaddleTensor> &base_outputs) {
41-
PADDLE_ENFORCE_GT(outputs.size(), 0);
42-
PADDLE_ENFORCE_EQ(outputs.size(), base_outputs.size());
40+
const std::vector<PaddleTensor> &ref_outputs) {
41+
EXPECT_GT(outputs.size(), 0);
42+
EXPECT_EQ(outputs.size(), ref_outputs.size());
4343
for (size_t i = 0; i < outputs.size(); i++) {
4444
auto &out = outputs[i];
45-
auto &base_out = base_outputs[i];
45+
auto &ref_out = ref_outputs[i];
4646
size_t size = std::accumulate(out.shape.begin(), out.shape.end(), 1,
4747
[](int a, int b) { return a * b; });
48-
size_t size1 = std::accumulate(base_out.shape.begin(), base_out.shape.end(),
49-
1, [](int a, int b) { return a * b; });
50-
PADDLE_ENFORCE_EQ(size, size1);
51-
PADDLE_ENFORCE_GT(size, 0);
52-
float *data = static_cast<float *>(out.data.data());
53-
float *base_data = static_cast<float *>(base_out.data.data());
54-
for (size_t i = 0; i < size; i++) {
55-
EXPECT_NEAR(data[i], base_data[i], 1e-3);
48+
size_t ref_size =
49+
std::accumulate(ref_out.shape.begin(), ref_out.shape.end(), 1,
50+
[](int a, int b) { return a * b; });
51+
EXPECT_GT(size, 0);
52+
EXPECT_EQ(size, ref_size);
53+
EXPECT_EQ(out.dtype, ref_out.dtype);
54+
switch (out.dtype) {
55+
case PaddleDType::INT64: {
56+
int64_t *pdata = static_cast<int64_t *>(out.data.data());
57+
int64_t *pdata_ref = static_cast<int64_t *>(ref_out.data.data());
58+
for (size_t j = 0; j < size; ++j) {
59+
EXPECT_EQ(pdata_ref[j], pdata[j]);
60+
}
61+
break;
62+
}
63+
case PaddleDType::FLOAT32: {
64+
float *pdata = static_cast<float *>(out.data.data());
65+
float *pdata_ref = static_cast<float *>(ref_out.data.data());
66+
for (size_t j = 0; j < size; ++j) {
67+
EXPECT_NEAR(pdata_ref[j], pdata[j], 1e-3);
68+
}
69+
break;
70+
}
5671
}
5772
}
5873
}

0 commit comments

Comments
 (0)