Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
magicwindyyd
mindspore
提交
3818de15
M
mindspore
项目概览
magicwindyyd
/
mindspore
与 Fork 源项目一致
Fork自
MindSpore / mindspore
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
mindspore
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
3818de15
编写于
8月 28, 2020
作者:
C
cjh9368
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
benchmark support int8 calib data
上级
da1c32a7
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
137 addition
and
83 deletion
+137
-83
mindspore/lite/tools/benchmark/benchmark.cc
mindspore/lite/tools/benchmark/benchmark.cc
+48
-76
mindspore/lite/tools/benchmark/benchmark.h
mindspore/lite/tools/benchmark/benchmark.h
+87
-1
mindspore/lite/tools/converter/legacy_optimizer/graph/dtype_trans_pass.cc
...ools/converter/legacy_optimizer/graph/dtype_trans_pass.cc
+2
-6
未找到文件。
mindspore/lite/tools/benchmark/benchmark.cc
浏览文件 @
3818de15
...
...
@@ -18,10 +18,8 @@
#define __STDC_FORMAT_MACROS
#include <cinttypes>
#undef __STDC_FORMAT_MACROS
#include <cmath>
#include <algorithm>
#include <utility>
#include <cfloat>
#include "src/common/common.h"
#include "include/ms_tensor.h"
#include "include/context.h"
...
...
@@ -167,71 +165,6 @@ int Benchmark::ReadCalibData() {
return
RET_OK
;
}
// tensorData need to be converter first
float
Benchmark
::
CompareData
(
const
std
::
string
&
nodeName
,
std
::
vector
<
int
>
msShape
,
float
*
msTensorData
)
{
auto
iter
=
this
->
calibData
.
find
(
nodeName
);
if
(
iter
!=
this
->
calibData
.
end
())
{
std
::
vector
<
size_t
>
castedMSShape
;
size_t
shapeSize
=
1
;
for
(
int64_t
dim
:
msShape
)
{
castedMSShape
.
push_back
(
size_t
(
dim
));
shapeSize
*=
dim
;
}
CheckTensor
*
calibTensor
=
iter
->
second
;
if
(
calibTensor
->
shape
!=
castedMSShape
)
{
std
::
ostringstream
oss
;
oss
<<
"Shape of mslite output("
;
for
(
auto
dim
:
castedMSShape
)
{
oss
<<
dim
<<
","
;
}
oss
<<
") and shape source model output("
;
for
(
auto
dim
:
calibTensor
->
shape
)
{
oss
<<
dim
<<
","
;
}
oss
<<
") are different"
;
std
::
cerr
<<
oss
.
str
()
<<
std
::
endl
;
MS_LOG
(
ERROR
)
<<
oss
.
str
().
c_str
();
return
RET_ERROR
;
}
size_t
errorCount
=
0
;
float
meanError
=
0
;
std
::
cout
<<
"Data of node "
<<
nodeName
<<
" : "
;
for
(
size_t
j
=
0
;
j
<
shapeSize
;
j
++
)
{
if
(
j
<
50
)
{
std
::
cout
<<
msTensorData
[
j
]
<<
" "
;
}
if
(
std
::
isnan
(
msTensorData
[
j
])
||
std
::
isinf
(
msTensorData
[
j
]))
{
std
::
cerr
<<
"Output tensor has nan or inf data, compare fail"
<<
std
::
endl
;
MS_LOG
(
ERROR
)
<<
"Output tensor has nan or inf data, compare fail"
;
return
RET_ERROR
;
}
auto
tolerance
=
absoluteTolerance
+
relativeTolerance
*
fabs
(
calibTensor
->
data
.
at
(
j
));
auto
absoluteError
=
std
::
fabs
(
msTensorData
[
j
]
-
calibTensor
->
data
.
at
(
j
));
if
(
absoluteError
>
tolerance
)
{
// just assume that atol = rtol
meanError
+=
absoluteError
/
(
fabs
(
calibTensor
->
data
.
at
(
j
))
+
FLT_MIN
);
errorCount
++
;
}
}
std
::
cout
<<
std
::
endl
;
if
(
meanError
>
0.0
f
)
{
meanError
/=
errorCount
;
}
if
(
meanError
<=
0.0000001
)
{
std
::
cout
<<
"Mean bias of node "
<<
nodeName
<<
" : 0%"
<<
std
::
endl
;
}
else
{
std
::
cout
<<
"Mean bias of node "
<<
nodeName
<<
" : "
<<
meanError
*
100
<<
"%"
<<
std
::
endl
;
}
return
meanError
;
}
else
{
MS_LOG
(
INFO
)
<<
"%s is not in Source Model output"
,
nodeName
.
c_str
();
return
RET_ERROR
;
}
}
int
Benchmark
::
CompareOutput
()
{
std
::
cout
<<
"================ Comparing Output data ================"
<<
std
::
endl
;
...
...
@@ -255,7 +188,24 @@ int Benchmark::CompareOutput() {
auto
&
tensor
=
tensors
.
front
();
MS_ASSERT
(
tensor
->
GetDataType
()
==
DataType_DT_FLOAT
);
MS_ASSERT
(
tensor
->
GetData
()
!=
nullptr
);
float
bias
=
CompareData
(
nodeName
,
tensor
->
shape
(),
static_cast
<
float
*>
(
tensor
->
MutableData
()));
float
bias
=
0
;
switch
(
msCalibDataType
)
{
case
TypeId
::
kNumberTypeFloat
:
{
bias
=
CompareData
<
float
>
(
nodeName
,
tensor
->
shape
(),
static_cast
<
float
*>
(
tensor
->
MutableData
()));
break
;
}
case
TypeId
::
kNumberTypeInt8
:
{
bias
=
CompareData
<
int8_t
>
(
nodeName
,
tensor
->
shape
(),
static_cast
<
int8_t
*>
(
tensor
->
MutableData
()));
break
;
}
case
TypeId
::
kNumberTypeInt32
:
{
bias
=
CompareData
<
int32_t
>
(
nodeName
,
tensor
->
shape
(),
static_cast
<
int32_t
*>
(
tensor
->
MutableData
()));
break
;
}
default:
MS_LOG
(
ERROR
)
<<
"Datatype "
<<
msCalibDataType
<<
" is not supported."
;
return
RET_ERROR
;
}
if
(
bias
>=
0
)
{
totalBias
+=
bias
;
totalSize
++
;
...
...
@@ -343,14 +293,26 @@ int Benchmark::MarkAccuracy() {
MS_LOG
(
INFO
)
<<
"MarkAccuracy"
;
std
::
cout
<<
"MarkAccuracy"
<<
std
::
endl
;
for
(
size_t
i
=
0
;
i
<
msInputs
.
size
();
i
++
)
{
MS_ASSERT
(
msInputs
.
at
(
i
)
!=
nullptr
);
MS_ASSERT
(
msInputs
.
at
(
i
)
->
data_type
()
==
TypeId
::
kNumberTypeFloat32
);
auto
inData
=
reinterpret_cast
<
float
*>
(
msInputs
.
at
(
i
)
->
MutableData
());
std
::
cout
<<
"InData"
<<
i
<<
": "
;
for
(
size_t
j
=
0
;
j
<
20
;
j
++
)
{
std
::
cout
<<
inData
[
j
]
<<
" "
;
}
std
::
cout
<<
std
::
endl
;
switch
(
msInputs
.
at
(
i
)
->
data_type
())
{
case
TypeId
::
kNumberTypeFloat
:
PrintInputData
<
float
>
(
msInputs
.
at
(
i
));
break
;
case
TypeId
::
kNumberTypeFloat32
:
PrintInputData
<
float
>
(
msInputs
.
at
(
i
));
break
;
case
TypeId
::
kNumberTypeInt8
:
PrintInputData
<
int8_t
>
(
msInputs
.
at
(
i
));
break
;
case
TypeId
::
kNumberTypeUInt8
:
PrintInputData
<
uint8_t
>
(
msInputs
.
at
(
i
));
break
;
case
TypeId
::
kNumberTypeInt32
:
PrintInputData
<
int
>
(
msInputs
.
at
(
i
));
break
;
default:
MS_LOG
(
ERROR
)
<<
"Datatype "
<<
msInputs
.
at
(
i
)
->
data_type
()
<<
" is not supported."
;
return
RET_ERROR
;
}
}
auto
status
=
session
->
RunGraph
();
if
(
status
!=
RET_OK
)
{
...
...
@@ -555,6 +517,16 @@ int Benchmark::Init() {
this
->
_flags
->
inDataType
=
this
->
_flags
->
inDataTypeIn
==
"img"
?
kImage
:
kBinary
;
if
(
!
_flags
->
calibDataType
.
empty
())
{
if
(
dataTypeMap
.
find
(
_flags
->
calibDataType
)
==
dataTypeMap
.
end
())
{
MS_LOG
(
ERROR
)
<<
"CalibDataType not supported: "
<<
_flags
->
calibDataType
.
c_str
();
return
RET_ERROR
;
}
msCalibDataType
=
dataTypeMap
.
at
(
_flags
->
calibDataType
);
MS_LOG
(
INFO
)
<<
"CalibDataType = "
<<
_flags
->
calibDataType
.
c_str
();
std
::
cout
<<
"CalibDataType = "
<<
_flags
->
calibDataType
.
c_str
()
<<
std
::
endl
;
}
if
(
_flags
->
modelPath
.
empty
())
{
MS_LOG
(
ERROR
)
<<
"modelPath is required"
;
std
::
cerr
<<
"modelPath is required"
<<
std
::
endl
;
...
...
mindspore/lite/tools/benchmark/benchmark.h
浏览文件 @
3818de15
...
...
@@ -23,9 +23,11 @@
#include <fstream>
#include <iostream>
#include <map>
#include <cmath>
#include <string>
#include <vector>
#include <memory>
#include <cfloat>
#include "include/model.h"
#include "tools/common/flag_parser.h"
#include "src/common/file_utils.h"
...
...
@@ -66,6 +68,7 @@ class MS_API BenchmarkFlags : public virtual FlagParser {
AddFlag
(
&
BenchmarkFlags
::
warmUpLoopCount
,
"warmUpLoopCount"
,
"Run warm up loop"
,
3
);
// MarkAccuracy
AddFlag
(
&
BenchmarkFlags
::
calibDataPath
,
"calibDataPath"
,
"Calibration data file path"
,
""
);
AddFlag
(
&
BenchmarkFlags
::
calibDataType
,
"calibDataType"
,
"Calibration data type. FLOAT | INT32 | INT8"
,
"FLOAT"
);
AddFlag
(
&
BenchmarkFlags
::
accuracyThreshold
,
"accuracyThreshold"
,
"Threshold of accuracy"
,
0.5
);
// Resize
AddFlag
(
&
BenchmarkFlags
::
resizeDimsIn
,
"resizeDims"
,
"Dims to resize to"
,
""
);
...
...
@@ -92,6 +95,7 @@ class MS_API BenchmarkFlags : public virtual FlagParser {
int
warmUpLoopCount
;
// MarkAccuracy
std
::
string
calibDataPath
;
std
::
string
calibDataType
;
float
accuracyThreshold
;
// Resize
std
::
string
resizeDimsIn
;
...
...
@@ -126,7 +130,85 @@ class MS_API Benchmark {
int
CompareOutput
();
float
CompareData
(
const
std
::
string
&
nodeName
,
std
::
vector
<
int
>
msShape
,
float
*
msTensorData
);
template
<
typename
T
>
void
PrintInputData
(
tensor
::
MSTensor
*
input
)
{
MS_ASSERT
(
input
!=
nullptr
);
static
int
i
=
0
;
auto
inData
=
reinterpret_cast
<
T
*>
(
input
->
MutableData
());
std
::
cout
<<
"InData"
<<
i
++
<<
": "
;
// int printSize = std::min(20, input->ElementsNum());
for
(
size_t
j
=
0
;
j
<
20
;
j
++
)
{
std
::
cout
<<
static_cast
<
float
>
(
inData
[
j
])
<<
" "
;
}
std
::
cout
<<
std
::
endl
;
}
// tensorData need to be converter first
template
<
typename
T
>
float
CompareData
(
const
std
::
string
&
nodeName
,
std
::
vector
<
int
>
msShape
,
T
*
msTensorData
)
{
auto
iter
=
this
->
calibData
.
find
(
nodeName
);
if
(
iter
!=
this
->
calibData
.
end
())
{
std
::
vector
<
size_t
>
castedMSShape
;
size_t
shapeSize
=
1
;
for
(
int64_t
dim
:
msShape
)
{
castedMSShape
.
push_back
(
size_t
(
dim
));
shapeSize
*=
dim
;
}
CheckTensor
*
calibTensor
=
iter
->
second
;
if
(
calibTensor
->
shape
!=
castedMSShape
)
{
std
::
ostringstream
oss
;
oss
<<
"Shape of mslite output("
;
for
(
auto
dim
:
castedMSShape
)
{
oss
<<
dim
<<
","
;
}
oss
<<
") and shape source model output("
;
for
(
auto
dim
:
calibTensor
->
shape
)
{
oss
<<
dim
<<
","
;
}
oss
<<
") are different"
;
std
::
cerr
<<
oss
.
str
()
<<
std
::
endl
;
MS_LOG
(
ERROR
)
<<
oss
.
str
().
c_str
();
return
RET_ERROR
;
}
size_t
errorCount
=
0
;
float
meanError
=
0
;
std
::
cout
<<
"Data of node "
<<
nodeName
<<
" : "
;
for
(
size_t
j
=
0
;
j
<
shapeSize
;
j
++
)
{
if
(
j
<
50
)
{
std
::
cout
<<
static_cast
<
float
>
(
msTensorData
[
j
])
<<
" "
;
}
if
(
std
::
isnan
(
msTensorData
[
j
])
||
std
::
isinf
(
msTensorData
[
j
]))
{
std
::
cerr
<<
"Output tensor has nan or inf data, compare fail"
<<
std
::
endl
;
MS_LOG
(
ERROR
)
<<
"Output tensor has nan or inf data, compare fail"
;
return
RET_ERROR
;
}
auto
tolerance
=
absoluteTolerance
+
relativeTolerance
*
fabs
(
calibTensor
->
data
.
at
(
j
));
auto
absoluteError
=
std
::
fabs
(
msTensorData
[
j
]
-
calibTensor
->
data
.
at
(
j
));
if
(
absoluteError
>
tolerance
)
{
// just assume that atol = rtol
meanError
+=
absoluteError
/
(
fabs
(
calibTensor
->
data
.
at
(
j
))
+
FLT_MIN
);
errorCount
++
;
}
}
std
::
cout
<<
std
::
endl
;
if
(
meanError
>
0.0
f
)
{
meanError
/=
errorCount
;
}
if
(
meanError
<=
0.0000001
)
{
std
::
cout
<<
"Mean bias of node "
<<
nodeName
<<
" : 0%"
<<
std
::
endl
;
}
else
{
std
::
cout
<<
"Mean bias of node "
<<
nodeName
<<
" : "
<<
meanError
*
100
<<
"%"
<<
std
::
endl
;
}
return
meanError
;
}
else
{
MS_LOG
(
INFO
)
<<
"%s is not in Source Model output"
,
nodeName
.
c_str
();
return
RET_ERROR
;
}
}
int
MarkPerformance
();
...
...
@@ -138,6 +220,10 @@ class MS_API Benchmark {
std
::
vector
<
mindspore
::
tensor
::
MSTensor
*>
msInputs
;
std
::
unordered_map
<
std
::
string
,
std
::
vector
<
mindspore
::
tensor
::
MSTensor
*>>
msOutputs
;
std
::
unordered_map
<
std
::
string
,
CheckTensor
*>
calibData
;
std
::
unordered_map
<
std
::
string
,
TypeId
>
dataTypeMap
{
{
"FLOAT"
,
TypeId
::
kNumberTypeFloat
},
{
"INT8"
,
TypeId
::
kNumberTypeInt8
},
{
"INT32"
,
TypeId
::
kNumberTypeInt32
}};
// TypeId msInputBinDataType = TypeId::kNumberTypeFloat;
TypeId
msCalibDataType
=
TypeId
::
kNumberTypeFloat
;
};
int
MS_API
RunBenchmark
(
int
argc
,
const
char
**
argv
);
...
...
mindspore/lite/tools/converter/legacy_optimizer/graph/dtype_trans_pass.cc
浏览文件 @
3818de15
...
...
@@ -104,7 +104,7 @@ STATUS DTypeTransPass::DoModelOutputDTypeTrans(schema::MetaGraphT *graph) {
if
(
outputDataDType
==
TypeId
::
kNumberTypeInt8
)
{
return
RET_OK
;
}
MS_ASSERT
(
in
putDataDType
==
TypeId
::
kNumberTypeFloat
);
MS_ASSERT
(
out
putDataDType
==
TypeId
::
kNumberTypeFloat
);
auto
&
graphOutIdxes
=
graph
->
outputIndex
;
for
(
auto
graphOutIdx
:
graphOutIdxes
)
{
for
(
auto
iter
=
graph
->
nodes
.
begin
();
iter
!=
graph
->
nodes
.
end
();
iter
++
)
{
...
...
@@ -115,11 +115,7 @@ STATUS DTypeTransPass::DoModelOutputDTypeTrans(schema::MetaGraphT *graph) {
if
(
node
->
outputIndex
.
at
(
outputIndexIdx
)
==
graphOutIdx
)
{
// insert transNode
STATUS
status
=
RET_OK
;
if
(
inputDataDType
==
TypeId
::
kNumberTypeFloat
)
{
iter
=
InsertDTypeTransNode
(
graph
,
iter
,
kAfter
,
outputIndexIdx
,
kInt8ToFP32
,
&
status
);
}
else
{
iter
=
InsertDTypeTransNode
(
graph
,
iter
,
kAfter
,
outputIndexIdx
,
kInt8ToUInt8
,
&
status
);
}
iter
=
InsertDTypeTransNode
(
graph
,
iter
,
kAfter
,
outputIndexIdx
,
kInt8ToFP32
,
&
status
);
if
(
status
!=
RET_OK
)
{
MS_LOG
(
ERROR
)
<<
"InsertDTypeTransNode after "
<<
nodeName
.
c_str
()
<<
" failed"
;
return
status
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录