Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle
提交
07cb64ad
P
Paddle
项目概览
PaddlePaddle
/
Paddle
1 年多 前同步成功
通知
2302
Star
20931
Fork
5422
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1423
列表
看板
标记
里程碑
合并请求
543
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1,423
Issue
1,423
列表
看板
标记
里程碑
合并请求
543
合并请求
543
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
07cb64ad
编写于
8月 31, 2018
作者:
L
luotao1
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add unit-test for chinese_ner
上级
823c4f87
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
271 addition
and
87 deletion
+271
-87
paddle/fluid/inference/analysis/CMakeLists.txt
paddle/fluid/inference/analysis/CMakeLists.txt
+23
-12
paddle/fluid/inference/analysis/analyzer_tester.cc
paddle/fluid/inference/analysis/analyzer_tester.cc
+6
-6
paddle/fluid/inference/analysis/chinese_ner_tester.cc
paddle/fluid/inference/analysis/chinese_ner_tester.cc
+154
-0
paddle/fluid/inference/api/api_impl.cc
paddle/fluid/inference/api/api_impl.cc
+69
-63
paddle/fluid/inference/api/api_impl.h
paddle/fluid/inference/api/api_impl.h
+3
-1
paddle/fluid/inference/api/helper.h
paddle/fluid/inference/api/helper.h
+16
-5
未找到文件。
paddle/fluid/inference/analysis/CMakeLists.txt
浏览文件 @
07cb64ad
...
@@ -40,23 +40,20 @@ function (inference_analysis_test TARGET)
...
@@ -40,23 +40,20 @@ function (inference_analysis_test TARGET)
endif
(
WITH_TESTING
)
endif
(
WITH_TESTING
)
endfunction
(
inference_analysis_test
)
endfunction
(
inference_analysis_test
)
set
(
DITU_RNN_MODEL_URL
"http://paddle-inference-dist.bj.bcebos.com/ditu_rnn_fluid%2Fmodel.tar.gz"
)
function
(
inference_download_and_uncompress install_dir url gz_filename
)
set
(
DITU_RNN_DATA_URL
"http://paddle-inference-dist.bj.bcebos.com/ditu_rnn_fluid%2Fdata.txt.tar.gz"
)
set
(
DITU_INSTALL_DIR
"
${
THIRD_PARTY_PATH
}
/install/ditu_rnn"
CACHE PATH
"Ditu RNN model and data root."
FORCE
)
set
(
DITU_RNN_MODEL
${
DITU_INSTALL_DIR
}
/model
)
set
(
DITU_RNN_DATA
${
DITU_INSTALL_DIR
}
/data.txt
)
function
(
inference_download_and_uncompress target url gz_filename
)
message
(
STATUS
"Download inference test stuff
${
gz_filename
}
from
${
url
}
"
)
message
(
STATUS
"Download inference test stuff
${
gz_filename
}
from
${
url
}
"
)
execute_process
(
COMMAND bash -c
"mkdir -p
${
DITU_INSTALL_DIR
}
"
)
execute_process
(
COMMAND bash -c
"mkdir -p
${
install_dir
}
"
)
execute_process
(
COMMAND bash -c
"cd
${
DITU_INSTALL_DIR
}
&& wget -q
${
url
}
"
)
execute_process
(
COMMAND bash -c
"cd
${
install_dir
}
&& wget -q
${
url
}
"
)
execute_process
(
COMMAND bash -c
"cd
${
DITU_INSTALL_DIR
}
&& tar xzf
${
gz_filename
}
"
)
execute_process
(
COMMAND bash -c
"cd
${
install_dir
}
&& tar xzf
${
gz_filename
}
"
)
message
(
STATUS
"finish downloading
${
gz_filename
}
"
)
message
(
STATUS
"finish downloading
${
gz_filename
}
"
)
endfunction
(
inference_download_and_uncompress
)
endfunction
(
inference_download_and_uncompress
)
set
(
DITU_RNN_MODEL_URL
"http://paddle-inference-dist.bj.bcebos.com/ditu_rnn_fluid%2Fmodel.tar.gz"
)
set
(
DITU_RNN_DATA_URL
"http://paddle-inference-dist.bj.bcebos.com/ditu_rnn_fluid%2Fdata.txt.tar.gz"
)
set
(
DITU_INSTALL_DIR
"
${
THIRD_PARTY_PATH
}
/inference_demo/ditu_rnn"
CACHE PATH
"Ditu RNN model and data root."
FORCE
)
if
(
NOT EXISTS
${
DITU_INSTALL_DIR
}
)
if
(
NOT EXISTS
${
DITU_INSTALL_DIR
}
)
inference_download_and_uncompress
(
ditu_rnn_model
${
DITU_RNN_MODEL_URL
}
"ditu_rnn_fluid%2Fmodel.tar.gz"
)
inference_download_and_uncompress
(
${
DITU_INSTALL_DIR
}
${
DITU_RNN_MODEL_URL
}
"ditu_rnn_fluid%2Fmodel.tar.gz"
)
inference_download_and_uncompress
(
ditu_rnn_data
${
DITU_RNN_DATA_URL
}
"ditu_rnn_fluid%2Fdata.txt.tar.gz"
)
inference_download_and_uncompress
(
${
DITU_INSTALL_DIR
}
${
DITU_RNN_DATA_URL
}
"ditu_rnn_fluid%2Fdata.txt.tar.gz"
)
endif
()
endif
()
inference_analysis_test
(
test_analyzer SRCS analyzer_tester.cc
inference_analysis_test
(
test_analyzer SRCS analyzer_tester.cc
...
@@ -87,3 +84,17 @@ inference_analysis_test(test_tensorrt_subgraph_pass SRCS tensorrt_subgraph_pass_
...
@@ -87,3 +84,17 @@ inference_analysis_test(test_tensorrt_subgraph_pass SRCS tensorrt_subgraph_pass_
inference_analysis_test
(
test_pass_manager SRCS pass_manager_tester.cc
)
inference_analysis_test
(
test_pass_manager SRCS pass_manager_tester.cc
)
inference_analysis_test
(
test_tensorrt_subgraph_node_mark_pass SRCS tensorrt_subgraph_node_mark_pass_tester.cc
)
inference_analysis_test
(
test_tensorrt_subgraph_node_mark_pass SRCS tensorrt_subgraph_node_mark_pass_tester.cc
)
inference_analysis_test
(
test_model_store_pass SRCS model_store_pass_tester.cc
)
inference_analysis_test
(
test_model_store_pass SRCS model_store_pass_tester.cc
)
set
(
CHINESE_NER_MODEL_URL
"http://paddle-inference-dist.bj.bcebos.com/chinese_ner_model.tar.gz"
)
set
(
CHINESE_NER_DATA_URL
"http://paddle-inference-dist.bj.bcebos.com/chinese_ner-data.txt.tar.gz"
)
set
(
CHINESE_NER_INSTALL_DIR
"
${
THIRD_PARTY_PATH
}
/inference_demo/chinese_ner"
CACHE PATH
"Chinese ner model and data root."
FORCE
)
if
(
NOT EXISTS
${
CHINESE_NER_INSTALL_DIR
}
)
inference_download_and_uncompress
(
${
CHINESE_NER_INSTALL_DIR
}
${
CHINESE_NER_MODEL_URL
}
"chinese_ner_model.tar.gz"
)
inference_download_and_uncompress
(
${
CHINESE_NER_INSTALL_DIR
}
${
CHINESE_NER_DATA_URL
}
"chinese_ner-data.txt.tar.gz"
)
endif
()
inference_analysis_test
(
test_chinese_ner SRCS chinese_ner_tester.cc
EXTRA_DEPS paddle_inference_api paddle_fluid_api
ARGS --inference_model_dir=
${
PYTHON_TESTS_DIR
}
/book/word2vec.inference.model
--infer_model=
${
CHINESE_NER_INSTALL_DIR
}
/model
--infer_data=
${
CHINESE_NER_INSTALL_DIR
}
/data.txt
)
paddle/fluid/inference/analysis/analyzer_tester.cc
浏览文件 @
07cb64ad
...
@@ -196,13 +196,13 @@ void PrepareInputs(std::vector<PaddleTensor> *input_slots, DataRecord *data,
...
@@ -196,13 +196,13 @@ void PrepareInputs(std::vector<PaddleTensor> *input_slots, DataRecord *data,
minute_tensor
.
lod
.
assign
({
one_batch
.
lod3
});
minute_tensor
.
lod
.
assign
({
one_batch
.
lod3
});
// clang-format on
// clang-format on
// assign data
// assign data
TensorAssignData
(
&
lod_attention_tensor
,
TensorAssignData
<
float
>
(
&
lod_attention_tensor
,
std
::
vector
<
std
::
vector
<
float
>>
({{
0
,
0
}}));
std
::
vector
<
std
::
vector
<
float
>>
({{
0
,
0
}}));
std
::
vector
<
float
>
tmp_zeros
(
batch_size
*
15
,
0.
);
std
::
vector
<
float
>
tmp_zeros
(
batch_size
*
15
,
0.
);
TensorAssignData
(
&
init_zero_tensor
,
{
tmp_zeros
});
TensorAssignData
<
float
>
(
&
init_zero_tensor
,
{
tmp_zeros
});
TensorAssignData
(
&
lod_tensor_tensor
,
one_batch
.
rnn_link_data
);
TensorAssignData
<
float
>
(
&
lod_tensor_tensor
,
one_batch
.
rnn_link_data
);
TensorAssignData
(
&
week_tensor
,
one_batch
.
rnn_week_datas
);
TensorAssignData
<
float
>
(
&
week_tensor
,
one_batch
.
rnn_week_datas
);
TensorAssignData
(
&
minute_tensor
,
one_batch
.
rnn_minute_datas
);
TensorAssignData
<
float
>
(
&
minute_tensor
,
one_batch
.
rnn_minute_datas
);
// Set inputs.
// Set inputs.
auto
init_zero_tensor1
=
init_zero_tensor
;
auto
init_zero_tensor1
=
init_zero_tensor
;
init_zero_tensor1
.
name
=
"hidden_init"
;
init_zero_tensor1
.
name
=
"hidden_init"
;
...
...
paddle/fluid/inference/analysis/chinese_ner_tester.cc
0 → 100644
浏览文件 @
07cb64ad
// 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 <google/protobuf/text_format.h>
#include <gtest/gtest.h>
#include "paddle/fluid/framework/ir/pass.h"
#include "paddle/fluid/inference/analysis/analyzer.h"
#include "paddle/fluid/inference/analysis/ut_helper.h"
#include "paddle/fluid/inference/api/helper.h"
#include "paddle/fluid/inference/api/paddle_inference_api.h"
#include "paddle/fluid/platform/profiler.h"
DEFINE_string
(
infer_model
,
""
,
"model path"
);
DEFINE_string
(
infer_data
,
""
,
"data path"
);
DEFINE_int32
(
batch_size
,
10
,
"batch size."
);
DEFINE_int32
(
repeat
,
1
,
"Running the inference program repeat times."
);
namespace
paddle
{
namespace
inference
{
struct
DataRecord
{
std
::
vector
<
std
::
vector
<
int64_t
>>
word_data_all
,
mention_data_all
;
std
::
vector
<
std
::
vector
<
int64_t
>>
rnn_word_datas
,
rnn_mention_datas
;
std
::
vector
<
size_t
>
lod
;
// two inputs have the same lod info.
size_t
batch_iter
{
0
};
size_t
batch_size
{
1
};
DataRecord
()
=
default
;
explicit
DataRecord
(
const
std
::
string
&
path
,
int
batch_size
=
1
)
:
batch_size
(
batch_size
)
{
Load
(
path
);
}
DataRecord
NextBatch
()
{
DataRecord
data
;
size_t
batch_end
=
batch_iter
+
batch_size
;
// NOTE skip the final batch, if no enough data is provided.
if
(
batch_end
<=
word_data_all
.
size
())
{
data
.
word_data_all
.
assign
(
word_data_all
.
begin
()
+
batch_iter
,
word_data_all
.
begin
()
+
batch_end
);
data
.
mention_data_all
.
assign
(
mention_data_all
.
begin
()
+
batch_iter
,
mention_data_all
.
begin
()
+
batch_end
);
// Prepare LoDs
data
.
lod
.
push_back
(
0
);
CHECK
(
!
data
.
word_data_all
.
empty
());
CHECK
(
!
data
.
mention_data_all
.
empty
());
CHECK_EQ
(
data
.
word_data_all
.
size
(),
data
.
mention_data_all
.
size
());
for
(
size_t
j
=
0
;
j
<
data
.
word_data_all
.
size
();
j
++
)
{
data
.
rnn_word_datas
.
push_back
(
data
.
word_data_all
[
j
]);
data
.
rnn_mention_datas
.
push_back
(
data
.
mention_data_all
[
j
]);
// calculate lod
data
.
lod
.
push_back
(
data
.
lod
.
back
()
+
data
.
word_data_all
[
j
].
size
());
}
}
batch_iter
+=
batch_size
;
return
data
;
}
void
Load
(
const
std
::
string
&
path
)
{
std
::
ifstream
file
(
path
);
std
::
string
line
;
int
num_lines
=
0
;
while
(
std
::
getline
(
file
,
line
))
{
num_lines
++
;
std
::
vector
<
std
::
string
>
data
;
split
(
line
,
';'
,
&
data
);
// load word data
std
::
vector
<
int64_t
>
word_data
;
split_to_int64
(
data
[
1
],
' '
,
&
word_data
);
// load mention data
std
::
vector
<
int64_t
>
mention_data
;
split_to_int64
(
data
[
3
],
' '
,
&
mention_data
);
word_data_all
.
push_back
(
std
::
move
(
word_data
));
mention_data_all
.
push_back
(
std
::
move
(
mention_data
));
}
}
};
void
PrepareInputs
(
std
::
vector
<
PaddleTensor
>
*
input_slots
,
DataRecord
*
data
,
int
batch_size
)
{
PaddleTensor
lod_word_tensor
,
lod_mention_tensor
;
lod_word_tensor
.
name
=
"word"
;
lod_mention_tensor
.
name
=
"mention"
;
auto
one_batch
=
data
->
NextBatch
();
int
size
=
one_batch
.
lod
[
one_batch
.
lod
.
size
()
-
1
];
// token batch size
lod_word_tensor
.
shape
.
assign
({
size
,
1
});
lod_word_tensor
.
lod
.
assign
({
one_batch
.
lod
});
lod_mention_tensor
.
shape
.
assign
({
size
,
1
});
lod_mention_tensor
.
lod
.
assign
({
one_batch
.
lod
});
// assign data
TensorAssignData
<
int64_t
>
(
&
lod_word_tensor
,
one_batch
.
rnn_word_datas
);
TensorAssignData
<
int64_t
>
(
&
lod_mention_tensor
,
one_batch
.
rnn_mention_datas
);
// Set inputs.
input_slots
->
assign
({
lod_word_tensor
,
lod_mention_tensor
});
for
(
auto
&
tensor
:
*
input_slots
)
{
tensor
.
dtype
=
PaddleDType
::
INT64
;
}
}
// the first inference result
const
int
chinese_ner_result_data
[]
=
{
30
,
45
,
41
,
48
,
17
,
26
,
48
,
39
,
38
,
16
,
25
};
void
TestChineseNERPrediction
()
{
NativeConfig
config
;
config
.
prog_file
=
FLAGS_infer_model
+
"/__model__"
;
config
.
param_file
=
FLAGS_infer_model
+
"/param"
;
config
.
use_gpu
=
false
;
config
.
device
=
0
;
config
.
specify_input_name
=
true
;
auto
predictor
=
CreatePaddlePredictor
<
NativeConfig
,
PaddleEngineKind
::
kNative
>
(
config
);
std
::
vector
<
PaddleTensor
>
input_slots
;
DataRecord
data
(
FLAGS_infer_data
,
FLAGS_batch_size
);
// Prepare inputs.
PrepareInputs
(
&
input_slots
,
&
data
,
FLAGS_batch_size
);
std
::
vector
<
PaddleTensor
>
outputs
;
Timer
timer
;
timer
.
tic
();
for
(
int
i
=
0
;
i
<
FLAGS_repeat
;
i
++
)
{
predictor
->
Run
(
input_slots
,
&
outputs
);
}
LOG
(
INFO
)
<<
"===========profile result==========="
;
LOG
(
INFO
)
<<
"batch_size: "
<<
FLAGS_batch_size
<<
", repeat: "
<<
FLAGS_repeat
<<
", latency: "
<<
timer
.
toc
()
/
FLAGS_repeat
<<
"ms"
;
LOG
(
INFO
)
<<
"====================================="
;
PADDLE_ENFORCE
(
outputs
.
size
(),
1UL
);
auto
&
out
=
outputs
[
0
];
size_t
size
=
std
::
accumulate
(
out
.
shape
.
begin
(),
out
.
shape
.
end
(),
1
,
[](
int
a
,
int
b
)
{
return
a
*
b
;
});
PADDLE_ENFORCE_GT
(
size
,
0
);
int64_t
*
result
=
static_cast
<
int64_t
*>
(
out
.
data
.
data
());
for
(
size_t
i
=
0
;
i
<
std
::
min
(
11UL
,
size
);
i
++
)
{
PADDLE_ENFORCE
(
result
[
i
],
chinese_ner_result_data
[
i
]);
}
}
// Directly infer with the original model.
TEST
(
Analyzer
,
Chinese_ner
)
{
TestChineseNERPrediction
();
}
}
// namespace inference
}
// namespace paddle
paddle/fluid/inference/api/api_impl.cc
浏览文件 @
07cb64ad
...
@@ -62,14 +62,14 @@ void NativePaddlePredictor::PrepareFeedFetch() {
...
@@ -62,14 +62,14 @@ void NativePaddlePredictor::PrepareFeedFetch() {
for
(
auto
*
op
:
inference_program_
->
Block
(
0
).
AllOps
())
{
for
(
auto
*
op
:
inference_program_
->
Block
(
0
).
AllOps
())
{
if
(
op
->
Type
()
==
"feed"
)
{
if
(
op
->
Type
()
==
"feed"
)
{
int
idx
=
boost
::
get
<
int
>
(
op
->
GetAttr
(
"col"
));
int
idx
=
boost
::
get
<
int
>
(
op
->
GetAttr
(
"col"
));
if
(
feeds_
.
size
()
<=
idx
)
{
if
(
feeds_
.
size
()
<=
(
size_t
)
idx
)
{
feeds_
.
resize
(
idx
+
1
);
feeds_
.
resize
(
idx
+
1
);
}
}
feeds_
[
idx
]
=
op
;
feeds_
[
idx
]
=
op
;
feed_names_
[
op
->
Output
(
"Out"
)[
0
]]
=
idx
;
feed_names_
[
op
->
Output
(
"Out"
)[
0
]]
=
idx
;
}
else
if
(
op
->
Type
()
==
"fetch"
)
{
}
else
if
(
op
->
Type
()
==
"fetch"
)
{
int
idx
=
boost
::
get
<
int
>
(
op
->
GetAttr
(
"col"
));
int
idx
=
boost
::
get
<
int
>
(
op
->
GetAttr
(
"col"
));
if
(
fetchs_
.
size
()
<=
idx
)
{
if
(
fetchs_
.
size
()
<=
(
size_t
)
idx
)
{
fetchs_
.
resize
(
idx
+
1
);
fetchs_
.
resize
(
idx
+
1
);
}
}
fetchs_
[
idx
]
=
op
;
fetchs_
[
idx
]
=
op
;
...
@@ -222,6 +222,62 @@ bool NativePaddlePredictor::SetFeed(const std::vector<PaddleTensor> &inputs,
...
@@ -222,6 +222,62 @@ bool NativePaddlePredictor::SetFeed(const std::vector<PaddleTensor> &inputs,
}
}
return
true
;
return
true
;
}
}
template
<
typename
T
>
void
NativePaddlePredictor
::
GetFetchOne
(
const
framework
::
LoDTensor
&
fetch
,
PaddleTensor
*
output
)
{
std
::
vector
<
int
>
shape
;
auto
dims_i
=
fetch
.
dims
();
auto
lod
=
fetch
.
lod
();
const
T
*
output_ptr
=
fetch
.
data
<
T
>
();
auto
num
=
fetch
.
numel
();
std
::
vector
<
T
>
data
;
if
(
0
==
lod
.
size
())
{
std
::
copy
(
output_ptr
,
output_ptr
+
num
,
std
::
back_inserter
(
data
));
for
(
int
j
=
0
;
j
<
dims_i
.
size
();
++
j
)
{
shape
.
push_back
(
dims_i
[
j
]);
}
}
else
{
// for batch detection
// image[0] -> output[0] shape {145, 6}
// image[1] -> output[1] shape {176, 6}
// then,
// the batch output shape {321, 6}
// the lod {{0, 145, 321}}
// so we should append output[0] to {176, 6}
size_t
max_dim
=
0
;
for
(
size_t
j
=
1
;
j
<
lod
[
0
].
size
();
j
++
)
{
max_dim
=
std
::
max
(
max_dim
,
lod
[
0
][
j
]
-
lod
[
0
][
j
-
1
]);
}
size_t
common_dim
=
lod
[
0
].
back
()
==
0
?
0
:
num
/
lod
[
0
].
back
();
if
(
max_dim
>
0
)
{
data
.
resize
((
lod
[
0
].
size
()
-
1
)
*
max_dim
*
common_dim
,
0
);
}
for
(
size_t
j
=
1
;
j
<
lod
[
0
].
size
();
j
++
)
{
size_t
start
=
lod
[
0
][
j
-
1
]
*
common_dim
;
size_t
end
=
lod
[
0
][
j
]
*
common_dim
;
if
(
end
>
start
)
{
std
::
copy
(
output_ptr
+
start
,
output_ptr
+
end
,
data
.
begin
()
+
(
j
-
1
)
*
max_dim
*
common_dim
);
}
}
shape
.
push_back
(
lod
[
0
].
size
()
-
1
);
shape
.
push_back
(
max_dim
);
for
(
int
j
=
1
;
j
<
dims_i
.
size
();
++
j
)
{
shape
.
push_back
(
dims_i
[
j
]);
}
}
output
->
shape
=
shape
;
auto
&
buffer
=
output
->
data
;
if
(
buffer
.
empty
()
||
buffer
.
length
()
<
sizeof
(
T
)
*
data
.
size
())
{
buffer
.
Resize
(
sizeof
(
T
)
*
data
.
size
());
}
std
::
memcpy
(
buffer
.
data
(),
data
.
data
(),
buffer
.
length
());
// copy LoD
for
(
const
auto
&
level
:
fetch
.
lod
())
{
output
->
lod
.
emplace_back
(
level
);
}
}
bool
NativePaddlePredictor
::
GetFetch
(
std
::
vector
<
PaddleTensor
>
*
outputs
,
bool
NativePaddlePredictor
::
GetFetch
(
std
::
vector
<
PaddleTensor
>
*
outputs
,
framework
::
Scope
*
scope
)
{
framework
::
Scope
*
scope
)
{
...
@@ -229,70 +285,20 @@ bool NativePaddlePredictor::GetFetch(std::vector<PaddleTensor> *outputs,
...
@@ -229,70 +285,20 @@ bool NativePaddlePredictor::GetFetch(std::vector<PaddleTensor> *outputs,
outputs
->
resize
(
fetchs_
.
size
());
outputs
->
resize
(
fetchs_
.
size
());
for
(
size_t
i
=
0
;
i
<
fetchs_
.
size
();
++
i
)
{
for
(
size_t
i
=
0
;
i
<
fetchs_
.
size
();
++
i
)
{
int
idx
=
boost
::
get
<
int
>
(
fetchs_
[
i
]
->
GetAttr
(
"col"
));
int
idx
=
boost
::
get
<
int
>
(
fetchs_
[
i
]
->
GetAttr
(
"col"
));
PADDLE_ENFORCE
(
idx
==
i
);
PADDLE_ENFORCE
(
(
size_t
)
idx
==
i
);
framework
::
LoDTensor
&
output
=
framework
::
LoDTensor
&
fetch
=
framework
::
GetFetchVariable
(
*
scope
,
"fetch"
,
idx
);
framework
::
GetFetchVariable
(
*
scope
,
"fetch"
,
idx
);
// TODO(panyx0718): Support fetch of other types.
auto
type
=
fetch
.
type
();
if
(
output
.
type
()
!=
typeid
(
float
))
{
auto
output
=
&
(
outputs
->
at
(
i
));
LOG
(
ERROR
)
<<
"only support fetching float now."
;
if
(
type
==
typeid
(
float
))
{
return
false
;
GetFetchOne
<
float
>
(
fetch
,
output
);
}
output
->
dtype
=
PaddleDType
::
FLOAT32
;
}
else
if
(
type
==
typeid
(
int64_t
))
{
std
::
vector
<
int
>
shape
;
GetFetchOne
<
int64_t
>
(
fetch
,
output
);
auto
dims_i
=
output
.
dims
();
output
->
dtype
=
PaddleDType
::
INT64
;
auto
lod
=
output
.
lod
();
const
float
*
output_ptr
=
output
.
data
<
float
>
();
// const int64_t* output_ptr = fetchs[i].data<int64_t>();
auto
num
=
output
.
numel
();
std
::
vector
<
float
>
data
;
if
(
0
==
lod
.
size
())
{
std
::
copy
(
output_ptr
,
output_ptr
+
num
,
std
::
back_inserter
(
data
));
for
(
int
j
=
0
;
j
<
dims_i
.
size
();
++
j
)
{
shape
.
push_back
(
dims_i
[
j
]);
}
}
else
{
}
else
{
// for batch detection
LOG
(
ERROR
)
<<
"unknown type, only support float32 and int64 now."
;
// image[0] -> output[0] shape {145, 6}
// image[1] -> output[1] shape {176, 6}
// then,
// the batch output shape {321, 6}
// the lod {{0, 145, 321}}
// so we should append output[0] to {176, 6}
size_t
max_dim
=
0
;
for
(
size_t
j
=
1
;
j
<
lod
[
0
].
size
();
j
++
)
{
max_dim
=
std
::
max
(
max_dim
,
lod
[
0
][
j
]
-
lod
[
0
][
j
-
1
]);
}
size_t
common_dim
=
lod
[
0
].
back
()
==
0
?
0
:
num
/
lod
[
0
].
back
();
if
(
max_dim
>
0
)
{
data
.
resize
((
lod
[
0
].
size
()
-
1
)
*
max_dim
*
common_dim
,
0
);
}
for
(
size_t
j
=
1
;
j
<
lod
[
0
].
size
();
j
++
)
{
size_t
start
=
lod
[
0
][
j
-
1
]
*
common_dim
;
size_t
end
=
lod
[
0
][
j
]
*
common_dim
;
if
(
end
>
start
)
{
std
::
copy
(
output_ptr
+
start
,
output_ptr
+
end
,
data
.
begin
()
+
(
j
-
1
)
*
max_dim
*
common_dim
);
}
}
shape
.
push_back
(
lod
[
0
].
size
()
-
1
);
shape
.
push_back
(
max_dim
);
for
(
int
j
=
1
;
j
<
dims_i
.
size
();
++
j
)
{
shape
.
push_back
(
dims_i
[
j
]);
}
}
outputs
->
at
(
i
).
shape
=
shape
;
auto
&
buffer
=
outputs
->
at
(
i
).
data
;
if
(
buffer
.
empty
()
||
buffer
.
length
()
<
sizeof
(
float
)
*
data
.
size
())
{
buffer
.
Resize
(
sizeof
(
float
)
*
data
.
size
());
}
std
::
memcpy
(
buffer
.
data
(),
data
.
data
(),
buffer
.
length
());
// copy LoD
for
(
const
auto
&
level
:
output
.
lod
())
{
outputs
->
at
(
i
).
lod
.
emplace_back
(
level
);
}
}
outputs
->
at
(
i
).
dtype
=
PaddleDType
::
FLOAT32
;
// TODO(panyx0718): support other types? fill tensor name? avoid a copy.
}
}
return
true
;
return
true
;
}
}
...
...
paddle/fluid/inference/api/api_impl.h
浏览文件 @
07cb64ad
...
@@ -51,7 +51,9 @@ class NativePaddlePredictor : public PaddlePredictor {
...
@@ -51,7 +51,9 @@ class NativePaddlePredictor : public PaddlePredictor {
framework
::
Scope
*
scope
);
framework
::
Scope
*
scope
);
bool
GetFetch
(
std
::
vector
<
PaddleTensor
>
*
output_data
,
bool
GetFetch
(
std
::
vector
<
PaddleTensor
>
*
output_data
,
framework
::
Scope
*
scope
);
framework
::
Scope
*
scope
);
template
<
typename
T
>
void
GetFetchOne
(
const
framework
::
LoDTensor
&
fetchs
,
PaddleTensor
*
output_data
);
void
PrepareFeedFetch
();
void
PrepareFeedFetch
();
NativeConfig
config_
;
NativeConfig
config_
;
...
...
paddle/fluid/inference/api/helper.h
浏览文件 @
07cb64ad
...
@@ -68,6 +68,13 @@ static void split_to_float(const std::string &str, char sep,
...
@@ -68,6 +68,13 @@ static void split_to_float(const std::string &str, char sep,
std
::
transform
(
pieces
.
begin
(),
pieces
.
end
(),
std
::
back_inserter
(
*
fs
),
std
::
transform
(
pieces
.
begin
(),
pieces
.
end
(),
std
::
back_inserter
(
*
fs
),
[](
const
std
::
string
&
v
)
{
return
std
::
stof
(
v
);
});
[](
const
std
::
string
&
v
)
{
return
std
::
stof
(
v
);
});
}
}
static
void
split_to_int64
(
const
std
::
string
&
str
,
char
sep
,
std
::
vector
<
int64_t
>
*
is
)
{
std
::
vector
<
std
::
string
>
pieces
;
split
(
str
,
sep
,
&
pieces
);
std
::
transform
(
pieces
.
begin
(),
pieces
.
end
(),
std
::
back_inserter
(
*
is
),
[](
const
std
::
string
&
v
)
{
return
std
::
stoi
(
v
);
});
}
template
<
typename
T
>
template
<
typename
T
>
std
::
string
to_string
(
const
std
::
vector
<
T
>
&
vec
)
{
std
::
string
to_string
(
const
std
::
vector
<
T
>
&
vec
)
{
std
::
stringstream
ss
;
std
::
stringstream
ss
;
...
@@ -84,14 +91,18 @@ template <>
...
@@ -84,14 +91,18 @@ template <>
std
::
string
to_string
<
std
::
vector
<
std
::
vector
<
float
>>>
(
std
::
string
to_string
<
std
::
vector
<
std
::
vector
<
float
>>>
(
const
std
::
vector
<
std
::
vector
<
std
::
vector
<
float
>>>
&
vec
);
const
std
::
vector
<
std
::
vector
<
std
::
vector
<
float
>>>
&
vec
);
// clang-format off
template
<
typename
T
>
static
void
TensorAssignData
(
PaddleTensor
*
tensor
,
const
std
::
vector
<
std
::
vector
<
float
>>
&
data
)
{
static
void
TensorAssignData
(
PaddleTensor
*
tensor
,
const
std
::
vector
<
std
::
vector
<
T
>>
&
data
)
{
// Assign buffer
// Assign buffer
int
dim
=
std
::
accumulate
(
tensor
->
shape
.
begin
(),
tensor
->
shape
.
end
(),
1
,
[](
int
a
,
int
b
)
{
return
a
*
b
;
});
int
dim
=
std
::
accumulate
(
tensor
->
shape
.
begin
(),
tensor
->
shape
.
end
(),
1
,
tensor
->
data
.
Resize
(
sizeof
(
float
)
*
dim
);
[](
int
a
,
int
b
)
{
return
a
*
b
;
});
tensor
->
data
.
Resize
(
sizeof
(
T
)
*
dim
);
int
c
=
0
;
int
c
=
0
;
for
(
const
auto
&
f
:
data
)
{
for
(
const
auto
&
f
:
data
)
{
for
(
float
v
:
f
)
{
static_cast
<
float
*>
(
tensor
->
data
.
data
())[
c
++
]
=
v
;
}
for
(
T
v
:
f
)
{
static_cast
<
T
*>
(
tensor
->
data
.
data
())[
c
++
]
=
v
;
}
}
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录