Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
dae62556
P
Paddle
项目概览
机器未来
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
dae62556
编写于
9月 16, 2020
作者:
W
Wilber
提交者:
GitHub
9月 16, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Enhance infer error info message (#26731)
上级
c89f269c
变更
19
显示空白变更内容
内联
并排
Showing
19 changed file
with
331 addition
and
174 deletion
+331
-174
paddle/fluid/inference/analysis/analyzer.cc
paddle/fluid/inference/analysis/analyzer.cc
+5
-3
paddle/fluid/inference/analysis/analyzer_tester.cc
paddle/fluid/inference/analysis/analyzer_tester.cc
+7
-2
paddle/fluid/inference/analysis/argument.h
paddle/fluid/inference/analysis/argument.h
+55
-44
paddle/fluid/inference/analysis/helper.h
paddle/fluid/inference/analysis/helper.h
+22
-9
paddle/fluid/inference/analysis/ir_pass_manager.cc
paddle/fluid/inference/analysis/ir_pass_manager.cc
+14
-8
paddle/fluid/inference/analysis/ir_passes/subgraph_util.cc
paddle/fluid/inference/analysis/ir_passes/subgraph_util.cc
+7
-2
paddle/fluid/inference/analysis/ir_passes/tensorrt_subgraph_pass.cc
...id/inference/analysis/ir_passes/tensorrt_subgraph_pass.cc
+12
-5
paddle/fluid/inference/analysis/passes/ir_analysis_pass.cc
paddle/fluid/inference/analysis/passes/ir_analysis_pass.cc
+6
-1
paddle/fluid/inference/analysis/passes/ir_graph_build_pass.cc
...le/fluid/inference/analysis/passes/ir_graph_build_pass.cc
+9
-4
paddle/fluid/inference/analysis/passes/ir_graph_clean_pass.cc
...le/fluid/inference/analysis/passes/ir_graph_clean_pass.cc
+2
-1
paddle/fluid/inference/analysis/passes/ir_params_sync_among_devices_pass.cc
...ence/analysis/passes/ir_params_sync_among_devices_pass.cc
+11
-4
paddle/fluid/inference/analysis/passes/memory_optimize_pass.cc
...e/fluid/inference/analysis/passes/memory_optimize_pass.cc
+6
-2
paddle/fluid/inference/api/analysis_config.cc
paddle/fluid/inference/api/analysis_config.cc
+2
-1
paddle/fluid/inference/api/analysis_predictor.cc
paddle/fluid/inference/api/analysis_predictor.cc
+52
-21
paddle/fluid/inference/api/api.cc
paddle/fluid/inference/api/api.cc
+9
-4
paddle/fluid/inference/api/api_impl.cc
paddle/fluid/inference/api/api_impl.cc
+33
-11
paddle/fluid/inference/api/helper.h
paddle/fluid/inference/api/helper.h
+8
-4
paddle/fluid/inference/api/mkldnn_quantizer.cc
paddle/fluid/inference/api/mkldnn_quantizer.cc
+69
-47
paddle/fluid/inference/tests/test_helper.h
paddle/fluid/inference/tests/test_helper.h
+2
-1
未找到文件。
paddle/fluid/inference/analysis/analyzer.cc
浏览文件 @
dae62556
...
...
@@ -27,8 +27,9 @@ Analyzer::Analyzer() {}
void
Analyzer
::
Run
(
Argument
*
argument
)
{
RunAnalysis
(
argument
);
}
void
Analyzer
::
RunAnalysis
(
Argument
*
argument
)
{
PADDLE_ENFORCE
(
argument
->
analysis_passes_valid
(),
"analsis_passes is not valid in the argument."
);
PADDLE_ENFORCE_EQ
(
argument
->
analysis_passes_valid
(),
true
,
platform
::
errors
::
InvalidArgument
(
"analsis_passes is not valid in the argument."
));
const
bool
disable_logs
=
argument
->
disable_logs
();
for
(
auto
&
pass
:
argument
->
analysis_passes
())
{
if
(
!
disable_logs
)
{
...
...
@@ -38,7 +39,8 @@ void Analyzer::RunAnalysis(Argument *argument) {
continue
;
auto
*
ptr
=
PassRegistry
::
Global
().
Retreive
(
pass
);
PADDLE_ENFORCE_NOT_NULL
(
ptr
,
"no analysis pass called %s"
,
pass
);
PADDLE_ENFORCE_NOT_NULL
(
ptr
,
platform
::
errors
::
PreconditionNotMet
(
"no analysis pass called %s"
,
pass
));
ptr
->
Run
(
argument
);
}
}
...
...
paddle/fluid/inference/analysis/analyzer_tester.cc
浏览文件 @
dae62556
...
...
@@ -75,9 +75,14 @@ void TestWord2vecPrediction(const std::string& model_path) {
std
::
vector
<
PaddleTensor
>
outputs
;
CHECK
(
predictor
->
Run
(
slots
,
&
outputs
));
PADDLE_ENFORCE_EQ
(
outputs
.
size
(),
1UL
);
PADDLE_ENFORCE_EQ
(
outputs
.
size
(),
1UL
,
platform
::
errors
::
PreconditionNotMet
(
"Output size should be 1, but got %d"
,
outputs
.
size
()));
// Check the output buffer size and result of each tid.
PADDLE_ENFORCE_EQ
(
outputs
.
front
().
data
.
length
(),
33168UL
);
PADDLE_ENFORCE_EQ
(
outputs
.
front
().
data
.
length
(),
33168UL
,
platform
::
errors
::
PreconditionNotMet
(
"Output's data length should be 33168 but got %d"
,
outputs
.
front
().
data
.
length
()));
float
result
[
5
]
=
{
0.00129761
,
0.00151112
,
0.000423564
,
0.00108815
,
0.000932706
};
const
size_t
num_elements
=
outputs
.
front
().
data
.
length
()
/
sizeof
(
float
);
...
...
paddle/fluid/inference/analysis/argument.h
浏览文件 @
dae62556
...
...
@@ -79,7 +79,9 @@ struct Argument {
#define DECL_ARGUMENT_FIELD(field__, Field, type__) \
public: \
type__& field__() { \
PADDLE_ENFORCE(Has(#field__), "There is no such field"); \
PADDLE_ENFORCE_EQ( \
Has(#field__), true, \
platform::errors::PreconditionNotMet("There is no such field")); \
return field__##_; \
} \
void Set##Field(const type__& x) { \
...
...
@@ -98,8 +100,11 @@ struct Argument {
#define DECL_ARGUMENT_UNIQUE_FIELD(field__, Field, type__) \
public: \
type__& field__() { \
PADDLE_ENFORCE_NOT_NULL(field__##_); \
PADDLE_ENFORCE(Has(#field__)); \
PADDLE_ENFORCE_NOT_NULL(field__##_, platform::errors::PreconditionNotMet( \
"filed should not be null.")); \
PADDLE_ENFORCE_EQ( \
Has(#field__), true, \
platform::errors::PreconditionNotMet("There is no such field")); \
return *static_cast<type__*>(field__##_.get()); \
} \
void Set##Field(type__* x) { \
...
...
@@ -113,11 +118,15 @@ struct Argument {
} \
DECL_ARGUMENT_FIELD_VALID(field__); \
type__* field__##_ptr() { \
PADDLE_ENFORCE(Has(#field__)); \
PADDLE_ENFORCE_EQ( \
Has(#field__), true, \
platform::errors::PreconditionNotMet("There is no such field")); \
return static_cast<type__*>(field__##_.get()); \
} \
type__* Release##Field() { \
PADDLE_ENFORCE(Has(#field__)); \
PADDLE_ENFORCE_EQ( \
Has(#field__), true, \
platform::errors::PreconditionNotMet("There is no such field")); \
valid_fields_.erase(#field__); \
return static_cast<type__*>(field__##_.release()); \
} \
...
...
@@ -227,8 +236,10 @@ struct Argument {
};
#define ARGUMENT_CHECK_FIELD(argument__, fieldname__) \
PADDLE_ENFORCE(argument__->Has(#fieldname__), \
"the argument field [%s] should be set", #fieldname__);
PADDLE_ENFORCE_EQ( \
argument__->Has(#fieldname__), true, \
platform::errors::PreconditionNotMet( \
"the argument field [%s] should be set", #fieldname__));
}
// namespace analysis
}
// namespace inference
...
...
paddle/fluid/inference/analysis/helper.h
浏览文件 @
dae62556
...
...
@@ -73,12 +73,15 @@ struct DataTypeNamer {
template
<
typename
T
>
const
std
::
string
&
repr
()
const
{
auto
x
=
std
::
type_index
(
typeid
(
T
));
PADDLE_ENFORCE
(
dic_
.
count
(
x
),
"unknown type for representation"
);
PADDLE_ENFORCE_GT
(
dic_
.
count
(
x
),
0
,
platform
::
errors
::
PreconditionNotMet
(
"unknown type for representation"
));
return
dic_
.
at
(
x
);
}
const
std
::
string
&
repr
(
const
std
::
type_index
&
type
)
const
{
// NOLINT
PADDLE_ENFORCE
(
dic_
.
count
(
type
),
"unknown type for representation"
);
PADDLE_ENFORCE_GT
(
dic_
.
count
(
type
),
0
,
platform
::
errors
::
PreconditionNotMet
(
"unknown type for representation"
));
return
dic_
.
at
(
type
);
}
...
...
@@ -116,7 +119,9 @@ template <typename T>
class
OrderedRegistry
{
public:
T
*
Register
(
const
std
::
string
&
name
,
T
*
x
)
{
PADDLE_ENFORCE
(
!
dic_
.
count
(
name
),
"duplicate key [%s]"
,
name
);
PADDLE_ENFORCE_EQ
(
dic_
.
count
(
name
),
0
,
platform
::
errors
::
PreconditionNotMet
(
"There exists duplicate key [%s]"
,
name
));
dic_
[
name
]
=
elements_
.
size
();
elements_
.
emplace_back
(
std
::
unique_ptr
<
T
>
(
x
));
return
elements_
.
back
().
get
();
...
...
@@ -136,14 +141,20 @@ class OrderedRegistry {
template
<
typename
T
>
T
&
GetFromScope
(
const
framework
::
Scope
&
scope
,
const
std
::
string
&
name
)
{
framework
::
Variable
*
var
=
scope
.
FindVar
(
name
);
PADDLE_ENFORCE
(
var
!=
nullptr
);
PADDLE_ENFORCE_NOT_NULL
(
var
,
platform
::
errors
::
PreconditionNotMet
(
"The var which name is %s should not be nullptr."
,
name
));
return
*
var
->
GetMutable
<
T
>
();
}
static
framework
::
proto
::
ProgramDesc
LoadProgramDesc
(
const
std
::
string
&
model_path
)
{
std
::
ifstream
fin
(
model_path
,
std
::
ios
::
in
|
std
::
ios
::
binary
);
PADDLE_ENFORCE
(
fin
.
is_open
(),
"Cannot open file %s"
,
model_path
);
PADDLE_ENFORCE_EQ
(
fin
.
is_open
(),
true
,
platform
::
errors
::
NotFound
(
"Cannot open file %s, please confirm whether the file exists"
,
model_path
));
fin
.
seekg
(
0
,
std
::
ios
::
end
);
std
::
string
buffer
(
fin
.
tellg
(),
' '
);
fin
.
seekg
(
0
,
std
::
ios
::
beg
);
...
...
@@ -188,10 +199,12 @@ static std::string GetDirRoot(const std::string &path) {
static
std
::
string
GetOrCreateModelOptCacheDir
(
const
std
::
string
&
model_root
)
{
std
::
string
opt_cache_dir
=
model_root
+
"/_opt_cache/"
;
if
(
!
PathExists
(
opt_cache_dir
))
{
PADDLE_ENFORCE
(
MKDIR
(
opt_cache_dir
.
c_str
())
!=
-
1
,
PADDLE_ENFORCE_NE
(
MKDIR
(
opt_cache_dir
.
c_str
()),
-
1
,
platform
::
errors
::
PreconditionNotMet
(
"Can not create optimize cache directory: %s, Make sure you "
"have permission to write"
,
opt_cache_dir
);
opt_cache_dir
)
);
}
return
opt_cache_dir
;
}
...
...
paddle/fluid/inference/analysis/ir_pass_manager.cc
浏览文件 @
dae62556
...
...
@@ -38,7 +38,9 @@ IRPassManager::IRPassManager(Argument *argument) {
graph_
=
std
::
unique_ptr
<
Graph
>
(
new
Graph
(
argument
->
main_program
()));
if
(
argument
->
Has
(
"scope"
))
{
auto
*
scope_ptr
=
argument
->
scope_ptr
();
PADDLE_ENFORCE
(
scope_ptr
);
PADDLE_ENFORCE_NOT_NULL
(
scope_ptr
,
platform
::
errors
::
PreconditionNotMet
(
"The scope ptr should not be nullptr."
));
graph_
->
SetNotOwned
(
framework
::
ir
::
kParamScopeAttr
,
scope_ptr
);
}
...
...
@@ -101,13 +103,17 @@ void IRPassManager::CreatePasses(Argument *argument,
std
::
string
optim_cache_dir
=
argument
->
optim_cache_dir
();
bool
int8_valid
=
!
(
model_from_memory
&&
optim_cache_dir
.
empty
()
&&
enable_int8
);
PADDLE_ENFORCE
(
int8_valid
,
PADDLE_ENFORCE_EQ
(
int8_valid
,
true
,
platform
::
errors
::
PreconditionNotMet
(
"When you are in TRT INT8 mode, and load model from "
"memory, you should set optim_cache_dir using "
"config.SetOptimCacheDir()"
);
PADDLE_ENFORCE
(
!
(
model_from_memory
&&
use_static_engine
),
"config.SetOptimCacheDir()"
));
PADDLE_ENFORCE_EQ
(
!
(
model_from_memory
&&
use_static_engine
),
true
,
platform
::
errors
::
PreconditionNotMet
(
"When you are using Paddle-TRT, and also using load model "
"from memory, you should set the use_static to false."
);
"from memory, you should set the use_static to false."
)
);
if
(
!
optim_cache_dir
.
empty
())
{
pass
->
Set
(
"model_opt_cache_dir"
,
new
std
::
string
(
optim_cache_dir
));
...
...
paddle/fluid/inference/analysis/ir_passes/subgraph_util.cc
浏览文件 @
dae62556
...
...
@@ -123,7 +123,9 @@ void RenameAndGetOutputs(
auto
add_block_var
=
[
&
](
const
std
::
string
&
graph_arg
,
const
std
::
string
&
block_arg
)
{
auto
arg_var_node
=
graph_var_map
.
find
(
graph_arg
);
PADDLE_ENFORCE
(
arg_var_node
!=
graph_var_map
.
end
());
PADDLE_ENFORCE_NE
(
arg_var_node
,
graph_var_map
.
end
(),
platform
::
errors
::
InvalidArgument
(
"Can not find %s in graph_var_map"
,
graph_arg
));
auto
*
var_t
=
block_desc
->
Var
(
block_arg
);
var_t
->
SetShape
(
arg_var_node
->
second
->
Var
()
->
GetShape
());
var_t
->
SetDataType
(
arg_var_node
->
second
->
Var
()
->
GetDataType
());
...
...
@@ -133,7 +135,10 @@ void RenameAndGetOutputs(
framework
::
proto
::
OpDesc
*
op
=
block_desc
->
Op
(
index
)
->
Proto
();
framework
::
OpDesc
op_desc
(
*
op
,
nullptr
);
auto
correspond_node
=
subgraph_nodes
[
index
];
PADDLE_ENFORCE_EQ
(
correspond_node
->
Name
(),
op
->
type
());
PADDLE_ENFORCE_EQ
(
correspond_node
->
Name
(),
op
->
type
(),
platform
::
errors
::
PreconditionNotMet
(
"We should get %s, but get %s"
,
op
->
type
(),
correspond_node
->
Name
()));
std
::
unordered_map
<
std
::
string
,
size_t
>
var2id
;
std
::
unordered_map
<
std
::
string
,
framework
::
ir
::
Node
*>
in_vars
;
...
...
paddle/fluid/inference/analysis/ir_passes/tensorrt_subgraph_pass.cc
浏览文件 @
dae62556
...
...
@@ -97,7 +97,9 @@ void TensorRtSubgraphPass::CreateTensorRTOp(
std
::
vector
<
std
::
string
>
*
repetitive_params
)
const
{
auto
*
op_desc
=
node
->
Op
();
auto
&
subgraph
=
*
framework
::
ir
::
Agent
(
node
).
subgraph
();
PADDLE_ENFORCE
(
!
subgraph
.
empty
());
PADDLE_ENFORCE_EQ
(
subgraph
.
empty
(),
false
,
platform
::
errors
::
PreconditionNotMet
(
"The subgraph should not be empty."
));
framework
::
ProgramDesc
*
program_desc
=
Get
<
framework
::
ProgramDesc
*>
(
"program"
);
...
...
@@ -194,12 +196,17 @@ void TensorRtSubgraphPass::CreateTensorRTOp(
// to Tensor.
std
::
vector
<
std
::
string
>
output_mapping
;
for
(
auto
name
:
output_names
)
{
PADDLE_ENFORCE
(
output_name_map
.
count
(
name
)
!=
0
);
PADDLE_ENFORCE_NE
(
output_name_map
.
count
(
name
),
0
,
platform
::
errors
::
PreconditionNotMet
(
"The output_name_map should have %s"
,
name
));
output_mapping
.
push_back
(
output_name_map
[
name
]);
}
PADDLE_ENFORCE
(
!
output_mapping
.
empty
());
PADDLE_ENFORCE
(
!
block_desc
.
Proto
()
->
vars
().
empty
(),
"the block has no var-desc"
);
PADDLE_ENFORCE_EQ
(
output_mapping
.
empty
(),
false
,
platform
::
errors
::
PreconditionNotMet
(
"The output_mapping should not be empty."
));
PADDLE_ENFORCE_EQ
(
!
block_desc
.
Proto
()
->
vars
().
empty
(),
true
,
platform
::
errors
::
PreconditionNotMet
(
"the block has no var-desc"
));
// Set attrs
op_desc
->
SetType
(
"tensorrt_engine"
);
...
...
paddle/fluid/inference/analysis/passes/ir_analysis_pass.cc
浏览文件 @
dae62556
...
...
@@ -13,6 +13,8 @@
// limitations under the License.
#include "paddle/fluid/inference/analysis/passes/ir_analysis_pass.h"
#include <memory>
#include <utility>
#include "paddle/fluid/framework/ir/fuse_pass_base.h"
#include "paddle/fluid/inference/analysis/ir_pass_manager.h"
...
...
@@ -31,7 +33,10 @@ void IrAnalysisPass::RunImpl(Argument* argument) {
// Apply passes.
IRPassManager
the_ir_manager
(
argument
);
graph
=
the_ir_manager
.
Apply
(
std
::
move
(
graph
));
PADDLE_ENFORCE_GT
(
graph
->
Nodes
().
size
(),
0
);
PADDLE_ENFORCE_GT
(
graph
->
Nodes
().
size
(),
0
,
platform
::
errors
::
PreconditionNotMet
(
"The graph nodes size should be greater than 0, but got 0"
));
argument
->
SetMainGraph
(
graph
.
release
());
CollectFusionStatis
(
argument
);
}
...
...
paddle/fluid/inference/analysis/passes/ir_graph_build_pass.cc
浏览文件 @
dae62556
...
...
@@ -31,7 +31,9 @@ void IrGraphBuildPass::RunImpl(Argument *argument) {
if
(
!
argument
->
scope_valid
())
{
argument
->
SetScope
(
new
framework
::
Scope
);
}
PADDLE_ENFORCE
(
argument
->
use_gpu_valid
());
PADDLE_ENFORCE_EQ
(
argument
->
use_gpu_valid
(),
true
,
platform
::
errors
::
PreconditionNotMet
(
"The use_gpu field should be valid"
));
// The load program should run on the same device with the inference program,
// so that the parameters will on the same device, or they will keep copying
...
...
@@ -51,14 +53,17 @@ void IrGraphBuildPass::RunImpl(Argument *argument) {
argument
->
model_from_memory_valid
()
&&
argument
->
model_from_memory
());
argument
->
SetMainProgram
(
program
.
release
());
}
else
{
PADDLE_THROW
(
"either model_dir or (program path and parameter path) should be set."
);
PADDLE_THROW
(
platform
::
errors
::
PreconditionNotMet
(
"either model_dir or (program path and parameter path) should be "
"set."
));
}
auto
graph
=
std
::
unique_ptr
<
Graph
>
(
new
Graph
(
argument
->
main_program
()));
argument
->
SetMainGraph
(
graph
.
release
());
auto
*
scope_ptr
=
argument
->
scope_ptr
();
PADDLE_ENFORCE
(
scope_ptr
);
PADDLE_ENFORCE_NOT_NULL
(
scope_ptr
,
platform
::
errors
::
PreconditionNotMet
(
"The scope ptr should not be nullptr."
));
argument
->
main_graph
().
SetNotOwned
(
framework
::
ir
::
kParamScopeAttr
,
scope_ptr
);
}
...
...
paddle/fluid/inference/analysis/passes/ir_graph_clean_pass.cc
浏览文件 @
dae62556
...
...
@@ -31,7 +31,8 @@ void IrInferCleanGraphPass::RunImpl(Argument* argument) {
std
::
unordered_set
<
const
framework
::
ir
::
Node
*>
invalid_nodes
;
int
valid_op
=
0
;
for
(
auto
*
node
:
graph
.
Nodes
())
{
PADDLE_ENFORCE_NOT_NULL
(
node
);
PADDLE_ENFORCE_NOT_NULL
(
node
,
platform
::
errors
::
PreconditionNotMet
(
"The node should not be nullptr."
));
if
(
is_valid_node
(
node
))
{
invalid_nodes
.
insert
(
node
);
}
else
if
(
node
->
IsOp
())
{
...
...
paddle/fluid/inference/analysis/passes/ir_params_sync_among_devices_pass.cc
浏览文件 @
dae62556
...
...
@@ -23,8 +23,12 @@ namespace inference {
namespace
analysis
{
void
IrParamsSyncAmongDevicesPass
::
RunImpl
(
Argument
*
argument
)
{
PADDLE_ENFORCE
(
argument
->
scope_valid
());
PADDLE_ENFORCE
(
argument
->
use_gpu_valid
());
PADDLE_ENFORCE_EQ
(
argument
->
scope_valid
(),
true
,
platform
::
errors
::
PreconditionNotMet
(
"The scope field should be valid"
));
PADDLE_ENFORCE_EQ
(
argument
->
use_gpu_valid
(),
true
,
platform
::
errors
::
PreconditionNotMet
(
"The use_gpu field should be valid"
));
platform
::
Place
place
;
...
...
@@ -40,7 +44,9 @@ void IrParamsSyncAmongDevicesPass::RunImpl(Argument *argument) {
LOG
(
INFO
)
<<
"Sync params from CPU to GPU"
;
PADDLE_ENFORCE
(
argument
->
gpu_device_id_valid
());
PADDLE_ENFORCE_EQ
(
argument
->
gpu_device_id_valid
(),
true
,
platform
::
errors
::
PreconditionNotMet
(
"The gpu_device_id field should be valid"
));
place
=
platform
::
CUDAPlace
(
argument
->
gpu_device_id
());
auto
*
scope
=
argument
->
scope_ptr
();
...
...
@@ -56,7 +62,8 @@ void IrParamsSyncAmongDevicesPass::RunImpl(Argument *argument) {
continue
;
}
auto
*
var
=
scope
->
FindLocalVar
(
var_name
);
PADDLE_ENFORCE
(
var
!=
nullptr
);
PADDLE_ENFORCE_NOT_NULL
(
var
,
platform
::
errors
::
PreconditionNotMet
(
"The var should not be nullptr"
));
if
(
var
->
IsType
<
framework
::
LoDTensor
>
()
||
var
->
IsType
<
framework
::
Tensor
>
())
{
auto
*
t
=
var
->
GetMutable
<
framework
::
LoDTensor
>
();
...
...
paddle/fluid/inference/analysis/passes/memory_optimize_pass.cc
浏览文件 @
dae62556
...
...
@@ -224,7 +224,9 @@ void UpdateOpDescsByReuse(
// modify the graph
for
(
auto
input_node
:
node
->
inputs
)
{
PADDLE_ENFORCE
(
input_node
->
IsVar
());
PADDLE_ENFORCE_EQ
(
input_node
->
IsVar
(),
true
,
platform
::
errors
::
PreconditionNotMet
(
"The input node should be a variable."
));
std
::
string
input_node_name
=
input_node
->
Name
();
if
(
reuse_table
.
count
(
input_node_name
)
&&
reuse_table
.
at
(
input_node_name
)
!=
input_node_name
)
{
...
...
@@ -246,7 +248,9 @@ void UpdateOpDescsByReuse(
// modify the graph
for
(
auto
out_node
:
node
->
outputs
)
{
PADDLE_ENFORCE
(
out_node
->
IsVar
());
PADDLE_ENFORCE_EQ
(
out_node
->
IsVar
(),
true
,
platform
::
errors
::
PreconditionNotMet
(
"The output node should be a variable."
));
std
::
string
out_node_name
=
out_node
->
Name
();
if
(
reuse_table
.
count
(
out_node_name
)
&&
reuse_table
.
at
(
out_node_name
)
!=
out_node_name
)
{
...
...
paddle/fluid/inference/api/analysis_config.cc
浏览文件 @
dae62556
...
...
@@ -230,7 +230,8 @@ void AnalysisConfig::EnableMkldnnBfloat16() {
MkldnnQuantizerConfig
*
AnalysisConfig
::
mkldnn_quantizer_config
()
const
{
PADDLE_ENFORCE_NOT_NULL
(
mkldnn_quantizer_config_
,
"MkldnnQuantizer was not enabled yet."
);
platform
::
errors
::
PreconditionNotMet
(
"MkldnnQuantizer was not enabled yet."
));
return
mkldnn_quantizer_config_
.
get
();
}
...
...
paddle/fluid/inference/api/analysis_predictor.cc
浏览文件 @
dae62556
...
...
@@ -169,7 +169,8 @@ bool AnalysisPredictor::PrepareScope(
if
(
parent_scope
)
{
PADDLE_ENFORCE_NOT_NULL
(
parent_scope
,
"Both program and parent_scope should be set in Clone mode."
);
platform
::
errors
::
PreconditionNotMet
(
"Both program and parent_scope should be set in Clone mode."
));
scope_
=
parent_scope
;
status_is_cloned_
=
true
;
}
else
{
...
...
@@ -235,7 +236,9 @@ bool AnalysisPredictor::PrepareExecutor() {
executor_
->
Prepare
(
sub_scope_
,
*
inference_program_
,
0
,
config_
.
use_feed_fetch_ops_
);
PADDLE_ENFORCE_NOT_NULL
(
sub_scope_
);
PADDLE_ENFORCE_NOT_NULL
(
sub_scope_
,
platform
::
errors
::
PreconditionNotMet
(
"The sub_scope should not be nullptr."
));
return
true
;
}
...
...
@@ -297,7 +300,8 @@ bool AnalysisPredictor::Run(const std::vector<PaddleTensor> &inputs,
timer
.
tic
();
// set feed variable
framework
::
Scope
*
scope
=
sub_scope_
?
sub_scope_
:
scope_
.
get
();
PADDLE_ENFORCE_NOT_NULL
(
scope
,
"The scope should not be nullptr."
);
PADDLE_ENFORCE_NOT_NULL
(
scope
,
platform
::
errors
::
PreconditionNotMet
(
"The scope should not be nullptr."
));
if
(
!
SetFeed
(
inputs
,
scope
))
{
LOG
(
ERROR
)
<<
"fail to set feed"
;
return
false
;
...
...
@@ -399,7 +403,11 @@ bool AnalysisPredictor::GetFetch(std::vector<PaddleTensor> *outputs,
outputs
->
resize
(
fetches_
.
size
());
for
(
size_t
i
=
0
;
i
<
fetches_
.
size
();
++
i
)
{
int
idx
=
BOOST_GET_CONST
(
int
,
fetches_
[
i
]
->
GetAttr
(
"col"
));
PADDLE_ENFORCE
((
size_t
)
idx
==
i
);
PADDLE_ENFORCE_EQ
(
static_cast
<
size_t
>
(
idx
),
i
,
platform
::
errors
::
InvalidArgument
(
"Fetch op's col attr(%d) should be equal to the index(%d)"
,
idx
,
i
));
framework
::
FetchType
&
fetch_var
=
framework
::
GetFetchVariable
(
*
scope
,
"fetch"
,
idx
);
auto
&
fetch
=
BOOST_GET
(
framework
::
LoDTensor
,
fetch_var
);
...
...
@@ -435,10 +443,12 @@ void AnalysisPredictor::PrepareArgument() {
if
(
!
config_
.
model_dir
().
empty
())
{
argument_
.
SetModelDir
(
config_
.
model_dir
());
}
else
{
PADDLE_ENFORCE
(
!
config_
.
params_file
().
empty
(),
"Either model_dir or (param_file, prog_file) should be set."
);
PADDLE_ENFORCE
(
!
config_
.
prog_file
().
empty
());
PADDLE_ENFORCE_EQ
(
config_
.
params_file
().
empty
(),
false
,
platform
::
errors
::
PreconditionNotMet
(
"Either model_dir or param_file should be set."
));
PADDLE_ENFORCE_EQ
(
config_
.
prog_file
().
empty
(),
false
,
platform
::
errors
::
PreconditionNotMet
(
"Either model_dir or prog_file should be set."
));
std
::
string
dir
=
inference
::
analysis
::
GetDirRoot
(
config_
.
prog_file
());
argument_
.
SetModelProgramPath
(
config_
.
prog_file
());
...
...
@@ -503,7 +513,9 @@ void AnalysisPredictor::OptimizeInferenceProgram() {
PrepareArgument
();
Analyzer
().
Run
(
&
argument_
);
PADDLE_ENFORCE
(
argument_
.
scope_valid
());
PADDLE_ENFORCE_EQ
(
argument_
.
scope_valid
(),
true
,
platform
::
errors
::
InvalidArgument
(
"The argument scope should be valid."
));
VLOG
(
5
)
<<
"to prepare executor"
;
ARGUMENT_CHECK_FIELD
((
&
argument_
),
ir_analyzed_program
);
inference_program_
.
reset
(
...
...
@@ -525,8 +537,10 @@ std::unique_ptr<PaddlePredictor> CreatePaddlePredictor<
FLAGS_minloglevel
=
2
;
// GLOG_ERROR
}
VLOG
(
3
)
<<
"create AnalysisConfig"
;
PADDLE_ENFORCE
(
config
.
is_valid
(),
"Note: Each config can only be used for one predictor."
);
PADDLE_ENFORCE_EQ
(
config
.
is_valid
(),
true
,
platform
::
errors
::
InvalidArgument
(
"Note: Each config can only be used for one predictor."
));
if
(
config
.
use_gpu
())
{
static
std
::
once_flag
gflags_initialized
;
...
...
@@ -623,7 +637,9 @@ bool AnalysisPredictor::MkldnnQuantize() {
}
void
AnalysisPredictor
::
PrepareFeedFetch
()
{
PADDLE_ENFORCE_NOT_NULL
(
sub_scope_
);
PADDLE_ENFORCE_NOT_NULL
(
sub_scope_
,
platform
::
errors
::
InvalidArgument
(
"The sub_scope should not be nullptr."
));
CreateFeedFetchVar
(
sub_scope_
);
for
(
auto
*
op
:
inference_program_
->
Block
(
0
).
AllOps
())
{
if
(
op
->
Type
()
==
"feed"
)
{
...
...
@@ -646,7 +662,8 @@ void AnalysisPredictor::PrepareFeedFetch() {
}
void
AnalysisPredictor
::
CreateFeedFetchVar
(
framework
::
Scope
*
scope
)
{
PADDLE_ENFORCE_NOT_NULL
(
scope
);
PADDLE_ENFORCE_NOT_NULL
(
scope
,
platform
::
errors
::
InvalidArgument
(
"The scope should not be nullptr."
));
auto
*
var
=
scope
->
Var
(
"feed"
);
var
->
GetMutable
<
framework
::
FeedList
>
();
var
=
scope
->
Var
(
"fetch"
);
...
...
@@ -667,7 +684,8 @@ AnalysisPredictor::GetInputTensorShape() {
std
::
vector
<
std
::
string
>
names
=
GetInputNames
();
for
(
std
::
string
name
:
names
)
{
auto
*
var
=
inference_program_
->
Block
(
0
).
FindVar
(
name
);
PADDLE_ENFORCE_NOT_NULL
(
var
,
"input %s does not exist."
,
name
);
PADDLE_ENFORCE_NOT_NULL
(
var
,
platform
::
errors
::
PreconditionNotMet
(
"Input %s does not exist."
,
name
));
input_shapes
[
name
]
=
var
->
GetShape
();
}
return
input_shapes
;
...
...
@@ -683,7 +701,11 @@ std::vector<std::string> AnalysisPredictor::GetOutputNames() {
std
::
unique_ptr
<
ZeroCopyTensor
>
AnalysisPredictor
::
GetInputTensor
(
const
std
::
string
&
name
)
{
PADDLE_ENFORCE
(
executor_
->
scope
()
->
FindVar
(
name
),
"no name called %s"
,
name
);
PADDLE_ENFORCE_NOT_NULL
(
executor_
->
scope
()
->
FindVar
(
name
),
platform
::
errors
::
PreconditionNotMet
(
"The variable named %s is not found in the scope of the exector."
,
name
));
std
::
unique_ptr
<
ZeroCopyTensor
>
res
(
new
ZeroCopyTensor
(
static_cast
<
void
*>
(
executor_
->
scope
())));
res
->
input_or_output_
=
true
;
...
...
@@ -700,7 +722,11 @@ std::unique_ptr<ZeroCopyTensor> AnalysisPredictor::GetInputTensor(
std
::
unique_ptr
<
ZeroCopyTensor
>
AnalysisPredictor
::
GetOutputTensor
(
const
std
::
string
&
name
)
{
PADDLE_ENFORCE
(
executor_
->
scope
()
->
FindVar
(
name
),
"no name called %s"
,
name
);
PADDLE_ENFORCE_NOT_NULL
(
executor_
->
scope
()
->
FindVar
(
name
),
platform
::
errors
::
PreconditionNotMet
(
"he variable named %s is not found in the scope of the exector."
,
name
));
std
::
unique_ptr
<
ZeroCopyTensor
>
res
(
new
ZeroCopyTensor
(
static_cast
<
void
*>
(
executor_
->
scope
())));
res
->
input_or_output_
=
false
;
...
...
@@ -761,8 +787,11 @@ bool AnalysisPredictor::LoadProgramDesc() {
std
::
string
pb_content
;
// Read binary
std
::
ifstream
fin
(
filename
,
std
::
ios
::
in
|
std
::
ios
::
binary
);
PADDLE_ENFORCE
(
static_cast
<
bool
>
(
fin
.
is_open
()),
"Cannot open file %s"
,
filename
);
PADDLE_ENFORCE_EQ
(
static_cast
<
bool
>
(
fin
.
is_open
()),
true
,
platform
::
errors
::
NotFound
(
"Cannot open file %s, please confirm whether the file is normal."
,
filename
));
fin
.
seekg
(
0
,
std
::
ios
::
end
);
pb_content
.
resize
(
fin
.
tellg
());
fin
.
seekg
(
0
,
std
::
ios
::
beg
);
...
...
@@ -779,7 +808,8 @@ bool AnalysisPredictor::LoadProgramDesc() {
bool
AnalysisPredictor
::
LoadParameters
()
{
PADDLE_ENFORCE_NOT_NULL
(
inference_program_
.
get
(),
"The inference program should be loaded first."
);
platform
::
errors
::
PreconditionNotMet
(
"The inference program should be loaded first."
));
const
auto
&
global_block
=
inference_program_
->
MutableBlock
(
0
);
...
...
@@ -855,8 +885,9 @@ void AnalysisPredictor::ClearIntermediateTensor() {
#if PADDLE_WITH_TENSORRT
bool
AnalysisPredictor
::
SaveTrtCalibToDisk
()
{
PADDLE_ENFORCE
(
config_
.
tensorrt_engine_enabled
(),
"This func can be invoked only in trt mode"
);
PADDLE_ENFORCE_EQ
(
config_
.
tensorrt_engine_enabled
(),
true
,
platform
::
errors
::
PreconditionNotMet
(
"This func can be invoked only in trt mode"
));
auto
&
block
=
inference_program_
->
Block
(
0
);
for
(
auto
&
op_desc
:
block
.
AllOps
())
{
if
(
op_desc
->
Type
()
==
"tensorrt_engine"
)
{
...
...
paddle/fluid/inference/api/api.cc
浏览文件 @
dae62556
...
...
@@ -62,9 +62,9 @@ PaddleBuf &PaddleBuf::operator=(const PaddleBuf &other) {
if
(
other
.
length
()
&&
other
.
data
())
memcpy
(
data_
,
other
.
data
(),
other
.
length
());
else
if
(
other
.
length
())
PADDLE_THROW
(
PADDLE_THROW
(
platform
::
errors
::
InvalidArgument
(
"Invalid argument, null pointer data with length %u is passed"
,
other
.
length
());
other
.
length
())
)
;
length_
=
other
.
length
();
memory_owned_
=
true
;
...
...
@@ -92,7 +92,8 @@ void PaddleBuf::Resize(size_t length) {
length_
=
length
;
memory_owned_
=
true
;
}
else
{
PADDLE_THROW
(
"The memory is allocated externally, can not Resized"
);
PADDLE_THROW
(
platform
::
errors
::
PreconditionNotMet
(
"The memory is allocated externally, can not Resized"
));
}
}
...
...
@@ -105,7 +106,11 @@ void PaddleBuf::Reset(void *data, size_t length) {
void
PaddleBuf
::
Free
()
{
if
(
memory_owned_
&&
data_
)
{
PADDLE_ENFORCE_GT
(
length_
,
0UL
);
PADDLE_ENFORCE_GT
(
length_
,
0UL
,
platform
::
errors
::
PreconditionNotMet
(
"The memory used in PaddleBuf %d should be greater than 0"
,
length_
));
delete
[]
static_cast
<
char
*>
(
data_
);
data_
=
nullptr
;
length_
=
0
;
...
...
paddle/fluid/inference/api/api_impl.cc
浏览文件 @
dae62556
...
...
@@ -87,7 +87,9 @@ bool NativePaddlePredictor::Init(
if
(
parent_scope
)
{
scope_
=
parent_scope
;
sub_scope_
=
&
(
parent_scope
->
NewScope
());
PADDLE_ENFORCE_NOT_NULL
(
sub_scope_
,
"create sub scope fail"
);
PADDLE_ENFORCE_NOT_NULL
(
sub_scope_
,
platform
::
errors
::
PreconditionNotMet
(
"The sub_scope should not be nullptr."
));
}
else
{
paddle
::
framework
::
InitDevices
(
false
);
scope_
.
reset
(
new
paddle
::
framework
::
Scope
());
...
...
@@ -182,7 +184,10 @@ std::unique_ptr<PaddlePredictor> NativePaddlePredictor::Clone() {
std
::
unique_ptr
<
PaddlePredictor
>
cls
(
new
NativePaddlePredictor
(
config_
));
// Hot fix the bug that result diff in multi-thread.
// TODO(Superjomn) re-implement a real clone here.
PADDLE_ENFORCE_NOT_NULL
(
dynamic_cast
<
NativePaddlePredictor
*>
(
cls
.
get
()));
PADDLE_ENFORCE_NOT_NULL
(
dynamic_cast
<
NativePaddlePredictor
*>
(
cls
.
get
()),
platform
::
errors
::
PreconditionNotMet
(
"Dynamic_cast from PaddlePredictor to NativePaddlePredictor failed"
));
if
(
!
dynamic_cast
<
NativePaddlePredictor
*>
(
cls
.
get
())
->
Init
(
nullptr
))
{
LOG
(
ERROR
)
<<
"fail to call Init"
;
return
nullptr
;
...
...
@@ -224,8 +229,13 @@ bool NativePaddlePredictor::SetFeed(const std::vector<PaddleTensor> &inputs,
return
false
;
}
PADDLE_ENFORCE_NOT_NULL
(
input_ptr
);
PADDLE_ENFORCE_NOT_NULL
(
inputs
[
i
].
data
.
data
());
PADDLE_ENFORCE_NOT_NULL
(
input_ptr
,
platform
::
errors
::
InvalidArgument
(
"The input_ptr should not be nullptr."
));
PADDLE_ENFORCE_NOT_NULL
(
inputs
[
i
].
data
.
data
(),
platform
::
errors
::
InvalidArgument
(
"The data of input tensor should not be null."
));
if
(
platform
::
is_cpu_place
(
place_
))
{
// TODO(panyx0718): Init LoDTensor from existing memcpy to save a copy.
std
::
memcpy
(
static_cast
<
void
*>
(
input_ptr
),
inputs
[
i
].
data
.
data
(),
...
...
@@ -241,7 +251,8 @@ bool NativePaddlePredictor::SetFeed(const std::vector<PaddleTensor> &inputs,
platform
::
CPUPlace
(),
inputs
[
i
].
data
.
data
(),
inputs
[
i
].
data
.
length
(),
dev_ctx
->
stream
());
#else
PADDLE_THROW
(
"Not compile with CUDA, should not reach here."
);
PADDLE_THROW
(
platform
::
errors
::
Unavailable
(
"Not compile with CUDA, should not reach here."
));
#endif
}
...
...
@@ -287,7 +298,11 @@ bool NativePaddlePredictor::GetFetch(std::vector<PaddleTensor> *outputs,
outputs
->
resize
(
fetchs_
.
size
());
for
(
size_t
i
=
0
;
i
<
fetchs_
.
size
();
++
i
)
{
int
idx
=
BOOST_GET_CONST
(
int
,
fetchs_
[
i
]
->
GetAttr
(
"col"
));
PADDLE_ENFORCE
((
size_t
)
idx
==
i
);
PADDLE_ENFORCE_EQ
(
static_cast
<
size_t
>
(
idx
),
i
,
platform
::
errors
::
InvalidArgument
(
"Fetch op's col attr(%d) should be equal to the index(%d)"
,
idx
,
i
));
framework
::
FetchType
&
fetch_var
=
framework
::
GetFetchVariable
(
*
scope
,
"fetch"
,
idx
);
auto
fetch
=
BOOST_GET_CONST
(
framework
::
LoDTensor
,
fetch_var
);
...
...
@@ -318,10 +333,15 @@ std::unique_ptr<PaddlePredictor> CreatePaddlePredictor<
VLOG
(
3
)
<<
"create NativePaddlePredictor"
;
if
(
config
.
use_gpu
)
{
// 1. GPU memory
PADDLE_ENFORCE_GE
(
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
);
PADDLE_ENFORCE_GE
(
config
.
fraction_of_gpu_memory
,
0.
f
,
platform
::
errors
::
InvalidArgument
(
"fraction_of_gpu_memory in the config should be set "
"to range (0., 1.]"
));
PADDLE_ENFORCE_GE
(
config
.
device
,
0
,
platform
::
errors
::
PreconditionNotMet
(
"Invalid device id %d, the device id should be "
"greater than or equal to 0."
,
config
.
device
));
std
::
vector
<
std
::
string
>
flags
;
if
(
config
.
fraction_of_gpu_memory
>=
0.0
f
||
config
.
fraction_of_gpu_memory
<=
0.95
f
)
{
...
...
@@ -336,7 +356,9 @@ std::unique_ptr<PaddlePredictor> CreatePaddlePredictor<
std
::
unique_ptr
<
PaddlePredictor
>
predictor
(
new
NativePaddlePredictor
(
config
));
PADDLE_ENFORCE_NOT_NULL
(
dynamic_cast
<
NativePaddlePredictor
*>
(
predictor
.
get
()));
dynamic_cast
<
NativePaddlePredictor
*>
(
predictor
.
get
()),
platform
::
errors
::
PreconditionNotMet
(
"Dynamic_cast from PaddlePredictor to NativePaddlePredictor failed"
));
if
(
!
dynamic_cast
<
NativePaddlePredictor
*>
(
predictor
.
get
())
->
Init
(
nullptr
))
{
return
nullptr
;
}
...
...
paddle/fluid/inference/api/helper.h
浏览文件 @
dae62556
...
...
@@ -112,16 +112,19 @@ static T convert(const std::string &item,
std
::
string
message
=
"invalid_argument exception when try to convert : "
+
item
;
LOG
(
ERROR
)
<<
message
;
PADDLE_THROW
(
message
);
PADDLE_THROW
(
platform
::
errors
::
InvalidArgument
(
"invalid_argument exception when try to convert %s."
,
item
));
}
catch
(
std
::
out_of_range
&
e
)
{
std
::
string
message
=
"out_of_range exception when try to convert : "
+
item
;
LOG
(
ERROR
)
<<
message
;
PADDLE_THROW
(
message
);
PADDLE_THROW
(
platform
::
errors
::
InvalidArgument
(
"out_of_range exception when try to convert %s."
,
item
));
}
catch
(...)
{
std
::
string
message
=
"unexpected exception when try to convert "
+
item
;
LOG
(
ERROR
)
<<
message
;
PADDLE_THROW
(
message
);
PADDLE_THROW
(
platform
::
errors
::
InvalidArgument
(
"unexpected exception when try to convert %s."
,
item
));
}
return
res
;
}
...
...
@@ -353,7 +356,8 @@ static void PrintTime(int batch_size, int repeat, int num_threads, int tid,
double
batch_latency
,
int
epoch
=
1
,
const
framework
::
proto
::
VarType
::
Type
data_type
=
framework
::
proto
::
VarType
::
FP32
)
{
PADDLE_ENFORCE_GT
(
batch_size
,
0
,
"Non-positive batch size."
);
PADDLE_ENFORCE_GT
(
batch_size
,
0
,
platform
::
errors
::
InvalidArgument
(
"Non-positive batch size."
));
double
sample_latency
=
batch_latency
/
batch_size
;
LOG
(
INFO
)
<<
"====== threads: "
<<
num_threads
<<
", thread id: "
<<
tid
<<
" ======"
;
...
...
paddle/fluid/inference/api/mkldnn_quantizer.cc
浏览文件 @
dae62556
...
...
@@ -62,9 +62,12 @@ bool AnalysisPredictor::MkldnnQuantizer::CalculateScales() {
if
(
scales_
.
find
(
var_name
)
!=
scales_
.
end
())
continue
;
auto
*
var
=
predictor_
.
sub_scope_
->
FindVar
(
var_name
);
PADDLE_ENFORCE
(
var
,
"%s is not in the scope"
,
var_name
);
PADDLE_ENFORCE
(
var
->
IsType
<
LoDTensor
>
(),
"Only support lod tensor now."
);
PADDLE_ENFORCE_NOT_NULL
(
var
,
platform
::
errors
::
PreconditionNotMet
(
"%s is not in the scope"
,
var_name
));
PADDLE_ENFORCE_EQ
(
var
->
IsType
<
LoDTensor
>
(),
true
,
platform
::
errors
::
PreconditionNotMet
(
"Only support lod tensor now."
));
LoDTensor
*
var_tensor
=
var
->
GetMutable
<
LoDTensor
>
();
// force unsigned type if already know it
...
...
@@ -82,9 +85,11 @@ bool AnalysisPredictor::MkldnnQuantizer::CalculateScales() {
}
else
if
(
op
->
Type
()
==
"transpose2"
||
op
->
Type
()
==
"reshape2"
||
op
->
Type
()
==
"pool2d"
)
{
auto
input_var_name
=
op
->
Input
(
"X"
)[
0
];
PADDLE_ENFORCE
(
scales_
.
find
(
input_var_name
)
!=
scales_
.
end
(),
PADDLE_ENFORCE_NE
(
scales_
.
find
(
input_var_name
),
scales_
.
end
(),
platform
::
errors
::
PreconditionNotMet
(
"Input scales must be calculated before the "
"output scales to infer if output is unsigned."
);
"output scales to infer if output is unsigned."
)
);
if
(
scales_
.
find
(
input_var_name
)
!=
scales_
.
end
())
{
scales_
[
var_name
]
=
scales_
[
input_var_name
];
}
...
...
@@ -94,10 +99,11 @@ bool AnalysisPredictor::MkldnnQuantizer::CalculateScales() {
is_unsigned
=
true
;
double
min_scale
=
std
::
numeric_limits
<
double
>::
max
();
for
(
auto
input_var_name
:
op
->
Input
(
"X"
))
{
PADDLE_ENFORCE
(
scales_
.
find
(
input_var_name
)
!=
scales_
.
end
(),
PADDLE_ENFORCE_NE
(
scales_
.
find
(
input_var_name
),
scales_
.
end
(),
platform
::
errors
::
PreconditionNotMet
(
"Input scales must be calculated before the "
"output scales to infer if output is unsigned."
);
"output scales to infer if output is unsigned."
)
);
is_unsigned
=
is_unsigned
&&
scales_
[
input_var_name
].
first
;
min_scale
=
std
::
min
(
min_scale
,
...
...
@@ -132,11 +138,12 @@ void AnalysisPredictor::MkldnnQuantizer::CalculateSingleScale(
auto
rule
=
qconfig_
->
scale_algo
(
op_type_name
,
conn_name
);
if
(
rule
==
ScaleAlgo
::
NONE
)
return
;
PADDLE_ENFORCE
(
var_tensor
.
numel
()
>
0
,
PADDLE_ENFORCE_GT
(
var_tensor
.
numel
(),
0
,
platform
::
errors
::
InvalidArgument
(
"MkldnnQuantizer: LoDTensor of variable %s for quantization of op "
"%s of connection %s should not be empty."
,
var_name
,
op_type_name
,
conn_name
);
var_name
,
op_type_name
,
conn_name
)
);
switch
(
rule
)
{
case
ScaleAlgo
::
MAX
:
...
...
@@ -205,10 +212,11 @@ AnalysisPredictor::MkldnnQuantizer::GetKLScalingFactor(
float
min_val
=
eigen_tensor
.
minCoeff
();
bool
is_positive
=
min_val
>=
0.0
f
;
if
(
is_unsigned
)
PADDLE_ENFORCE
(
is_positive
,
PADDLE_ENFORCE_EQ
(
is_positive
,
true
,
platform
::
errors
::
InvalidArgument
(
"Tensor is claimed to be unsigned, but its min value (%f) is < 0.0"
,
min_val
);
min_val
)
);
int
num_quantized_bins
=
255
;
...
...
@@ -316,10 +324,11 @@ AnalysisPredictor::MkldnnQuantizer::GetMaxScalingFactor(
float
max_abs
=
eigen_tensor
.
abs
().
maxCoeff
();
float
min_val
=
eigen_tensor
.
minCoeff
();
if
(
is_unsigned
)
PADDLE_ENFORCE
(
min_val
>=
0.0
f
,
PADDLE_ENFORCE_GE
(
min_val
,
0.0
f
,
platform
::
errors
::
InvalidArgument
(
"Tensor is claimed to be unsigned, but its min value (%f) is < 0.0"
,
min_val
);
min_val
)
);
LoDTensor
scale_tensor
=
CreateScaleTensor
();
scale_tensor
.
data
<
double
>
()[
0
]
=
1.0
/
max_abs
;
...
...
@@ -330,16 +339,19 @@ AnalysisPredictor::MkldnnQuantizer::GetMaxScalingFactor(
std
::
pair
<
bool
,
LoDTensor
>
AnalysisPredictor
::
MkldnnQuantizer
::
GetMaxChScalingFactor
(
const
LoDTensor
&
var_tensor
,
bool
is_unsigned
,
bool
is_transposed
)
const
{
PADDLE_ENFORCE
(
var_tensor
.
dims
().
size
()
>
0
,
"Tensor dimension is empty."
);
PADDLE_ENFORCE_GT
(
var_tensor
.
dims
().
size
(),
0
,
platform
::
errors
::
InvalidArgument
(
"Tensor dimension is empty."
));
ConstEigenVectorArrayMap
eigen_tensor
{
var_tensor
.
data
<
float
>
(),
var_tensor
.
numel
(),
1
};
float
min_val
=
eigen_tensor
.
minCoeff
();
if
(
is_unsigned
)
PADDLE_ENFORCE
(
min_val
>=
0.0
f
,
PADDLE_ENFORCE_GE
(
min_val
,
0.0
f
,
platform
::
errors
::
InvalidArgument
(
"Tensor is claimed to be unsigned, but its min value (%f) is < 0.0"
,
min_val
);
min_val
)
);
auto
dims
=
var_tensor
.
dims
();
constexpr
int
num_col_dims
=
1
;
...
...
@@ -367,17 +379,19 @@ AnalysisPredictor::MkldnnQuantizer::Histogram(
const
framework
::
LoDTensor
&
var_tensor
,
float
min_val
,
float
max_val
,
size_t
num_bins
)
const
{
PADDLE_ENFORCE_GT
(
num_bins
,
0
,
platform
::
errors
::
InvalidArgument
(
"MkldnnQuantizer: To calculate Histogram, num_bins ("
+
std
::
to_string
(
num_bins
)
+
") must be positive."
);
PADDLE_ENFORCE_GT
(
var_tensor
.
numel
(),
0
,
"MkldnnQuantizer: To calculate Histogram, the tensor must not be empty."
);
PADDLE_ENFORCE
(
max_val
>=
min_val
,
std
::
to_string
(
num_bins
)
+
") must be positive."
));
PADDLE_ENFORCE_GT
(
var_tensor
.
numel
(),
0
,
platform
::
errors
::
InvalidArgument
(
"MkldnnQuantizer: To calculate Histogram, the tensor "
"must not be empty."
));
PADDLE_ENFORCE_GE
(
max_val
,
min_val
,
platform
::
errors
::
InvalidArgument
(
"MkldnnQuantizer: To calculate Histogram, max_val ("
+
std
::
to_string
(
max_val
)
+
") must be greater or equal"
std
::
to_string
(
max_val
)
+
") must be greater or equal"
"to min_val ("
+
std
::
to_string
(
min_val
)
+
")."
);
std
::
to_string
(
min_val
)
+
")."
)
);
ConstEigenVectorArrayMap
eigen_tensor
{
var_tensor
.
data
<
float
>
(),
var_tensor
.
numel
(),
1
};
auto
bin_width
=
std
::
abs
(
max_val
-
min_val
)
/
num_bins
;
...
...
@@ -407,7 +421,8 @@ void AnalysisPredictor::MkldnnQuantizer::PrepareArgument() const {
auto
graph
=
std
::
unique_ptr
<
Graph
>
(
new
Graph
(
arg
.
main_program
()));
arg
.
SetMainGraph
(
graph
.
release
());
auto
*
scope_ptr
=
arg
.
scope_ptr
();
PADDLE_ENFORCE
(
scope_ptr
);
PADDLE_ENFORCE_NOT_NULL
(
scope_ptr
,
platform
::
errors
::
PreconditionNotMet
(
"The scope should not be nullptr."
));
arg
.
main_graph
().
SetNotOwned
(
framework
::
ir
::
kParamScopeAttr
,
scope_ptr
);
auto
*
builder
=
predictor_
.
config_
.
pass_builder
();
...
...
@@ -441,7 +456,9 @@ bool AnalysisPredictor::MkldnnQuantizer::RunQuantizePasses() const {
PrepareArgument
();
auto
&
arg
=
predictor_
.
argument_
;
Analyzer
().
Run
(
&
arg
);
PADDLE_ENFORCE
(
arg
.
scope_valid
());
PADDLE_ENFORCE_EQ
(
arg
.
scope_valid
(),
true
,
platform
::
errors
::
PreconditionNotMet
(
"The scope should be valid."
));
VLOG
(
5
)
<<
"to prepare executor"
;
ARGUMENT_CHECK_FIELD
((
&
arg
),
ir_analyzed_program
);
predictor_
.
inference_program_
.
reset
(
...
...
@@ -456,7 +473,8 @@ bool AnalysisPredictor::MkldnnQuantizer::RunWarmup() const {
VLOG
(
3
)
<<
"Predictor: run a quantization warmup iteration"
;
auto
warmup_data
=
qconfig_
->
warmup_data
();
PADDLE_ENFORCE_NOT_NULL
(
warmup_data
,
"Warmup data cannot be NULL in the config."
);
platform
::
errors
::
PreconditionNotMet
(
"Warmup data cannot be NULL in the config."
));
PrettyLogH1
(
"--- Running warmup iteration for quantization"
);
// Run the inference program
...
...
@@ -469,7 +487,10 @@ bool AnalysisPredictor::MkldnnQuantizer::RunWarmup() const {
float
AnalysisPredictor
::
MkldnnQuantizer
::
SafeEntropy
(
std
::
vector
<
int
>
reference_distr_P
,
int
P_sum
,
std
::
vector
<
int
>
candidate_distr_Q
,
int
Q_sum
)
const
{
PADDLE_ENFORCE_EQ
(
reference_distr_P
.
size
(),
candidate_distr_Q
.
size
());
PADDLE_ENFORCE_EQ
(
reference_distr_P
.
size
(),
candidate_distr_Q
.
size
(),
platform
::
errors
::
InvalidArgument
(
"The P size %d should be equal to Q size %d"
,
reference_distr_P
.
size
(),
candidate_distr_Q
.
size
()));
float
tmp_sum1
=
0
;
float
tmp_sum2
=
0
;
for
(
size_t
idx
=
0
;
idx
<
reference_distr_P
.
size
();
idx
++
)
{
...
...
@@ -479,10 +500,11 @@ float AnalysisPredictor::MkldnnQuantizer::SafeEntropy(
tmp_sum1
+=
0
;
tmp_sum2
+=
0
;
}
else
{
PADDLE_ENFORCE
(
q_idx
!=
0
,
"MkldnnQuantizer: Fatal error!, idx = "
+
std
::
to_string
(
idx
)
+
" qindex = 0! p_idx = "
+
std
::
to_string
(
p_idx
));
PADDLE_ENFORCE_NE
(
q_idx
,
0
,
platform
::
errors
::
PreconditionNotMet
(
"MkldnnQuantizer: Fatal error!, idx = "
+
std
::
to_string
(
idx
)
+
" qindex = 0! p_idx = "
+
std
::
to_string
(
p_idx
)));
}
tmp_sum1
+=
p_idx
*
(
log
(
Q_sum
*
p_idx
));
tmp_sum2
+=
p_idx
*
(
log
(
P_sum
*
q_idx
));
...
...
paddle/fluid/inference/tests/test_helper.h
浏览文件 @
dae62556
...
...
@@ -163,7 +163,8 @@ void TestInference(const std::string& dirname,
// int device_id = place.GetDeviceId();
paddle
::
platform
::
SetDeviceId
(
0
);
#else
PADDLE_THROW
(
"'CUDAPlace' is not supported in CPU only device."
);
PADDLE_THROW
(
paddle
::
platform
::
errors
::
Unavailable
(
"'CUDAPlace' is not supported in CPU only device."
));
#endif
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录