Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
as350144
Mace
提交
33d4454d
Mace
项目概览
as350144
/
Mace
与 Fork 源项目一致
Fork自
Xiaomi / Mace
通知
2
Star
1
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Mace
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
33d4454d
编写于
12月 05, 2017
作者:
L
liuqi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add gcn validation tools.
上级
1635046e
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
256 addition
and
20 deletion
+256
-20
mace/examples/mace_run.cc
mace/examples/mace_run.cc
+2
-0
mace/kernels/opencl/fused_conv_2d_opencl.cc
mace/kernels/opencl/fused_conv_2d_opencl.cc
+17
-16
mace/python/tools/tf_converter.py
mace/python/tools/tf_converter.py
+1
-1
mace/python/tools/tf_converter_lib.py
mace/python/tools/tf_converter_lib.py
+33
-3
tools/validate.py
tools/validate.py
+126
-0
tools/validate_gcn.sh
tools/validate_gcn.sh
+77
-0
未找到文件。
mace/examples/mace_run.cc
浏览文件 @
33d4454d
...
...
@@ -100,8 +100,10 @@ int main(int argc, char **argv) {
in_file
.
close
();
}
VLOG
(
0
)
<<
"Before Init"
;
// Init model
auto
net
=
CreateNet
(
net_def
,
&
ws
,
device_type
,
NetMode
::
INIT
);
VLOG
(
0
)
<<
"Before Run"
;
net
->
Run
();
// run model
...
...
mace/kernels/opencl/fused_conv_2d_opencl.cc
浏览文件 @
33d4454d
...
...
@@ -28,6 +28,11 @@ extern void Conv2dOpenclK3x3S2(const Tensor *input, const Tensor *filter,
const
int
*
padding
,
const
DataType
dt
,
Tensor
*
output
);
extern
void
Conv2dOpencl
(
const
Tensor
*
input
,
const
Tensor
*
filter
,
const
Tensor
*
bias
,
const
bool
fused_relu
,
const
uint32_t
stride
,
const
int
*
padding
,
const
DataType
dt
,
Tensor
*
output
);
template
<
typename
T
>
void
FusedConv2dFunctor
<
DeviceType
::
OPENCL
,
T
>::
operator
()(
const
Tensor
*
input
,
const
Tensor
*
filter
,
...
...
@@ -44,20 +49,15 @@ void FusedConv2dFunctor<DeviceType::OPENCL, T>::operator()(const Tensor *input,
{
Conv2dOpenclK3x3S1
,
Conv2dOpenclK3x3S2
},
{
nullptr
,
nullptr
},
{
nullptr
,
nullptr
}};
index_t
kernel_h
=
filter
->
dim
(
0
);
index_t
kernel_w
=
filter
->
dim
(
1
);
if
(
kernel_h
!=
kernel_w
||
kernel_h
>
5
||
strides_
[
0
]
!=
strides_
[
1
]
||
strides_
[
0
]
>
2
||
dilations_
[
0
]
!=
1
||
dilations_
[
1
]
!=
1
||
selector
[
kernel_h
-
1
][
strides_
[
0
]
-
1
]
==
nullptr
)
{
if
(
!
input
->
is_image
()
||
strides_
[
0
]
!=
strides_
[
1
]
||
strides_
[
0
]
>
2
||
dilations_
[
0
]
!=
1
||
dilations_
[
1
]
!=
1
)
{
LOG
(
WARNING
)
<<
"OpenCL conv2d kernel with "
<<
"filter"
<<
kernel_h
<<
"x"
<<
kernel_w
<<
","
<<
" stride "
<<
strides_
[
0
]
<<
"x"
<<
strides_
[
1
]
<<
" is not implemented yet, using slow version"
;
// TODO(heliangliang) The CPU/NEON kernel should map the buffer
FusedConv2dFunctor
<
DeviceType
::
CPU
,
T
>
(
strides_
,
paddings_
,
dilations_
)(
input
,
filter
,
bias
,
output
);
return
;
MACE_NOT_IMPLEMENTED
;
}
std
::
vector
<
index_t
>
output_shape
(
4
);
...
...
@@ -66,16 +66,17 @@ void FusedConv2dFunctor<DeviceType::OPENCL, T>::operator()(const Tensor *input,
input
->
shape
().
data
(),
filter
->
shape
().
data
(),
dilations_
,
strides_
,
paddings_
,
output_shape
.
data
(),
paddings
.
data
());
if
(
input
->
is_image
())
{
std
::
vector
<
size_t
>
output_image_shape
;
CalImage2DShape
(
output_shape
,
BufferType
::
IN_OUT
,
output_image_shape
);
output
->
ResizeImage
(
output_shape
,
output_image_shape
);
std
::
vector
<
size_t
>
output_image_shape
;
CalImage2DShape
(
output_shape
,
BufferType
::
IN_OUT
,
output_image_shape
);
output
->
ResizeImage
(
output_shape
,
output_image_shape
);
if
(
kernel_h
==
kernel_w
&&
kernel_h
<=
5
&&
selector
[
kernel_h
-
1
][
strides_
[
0
]
-
1
]
!=
nullptr
)
{
auto
conv2d_func
=
selector
[
kernel_h
-
1
][
strides_
[
0
]
-
1
];
conv2d_func
(
input
,
filter
,
bias
,
false
,
paddings
.
data
(),
DataTypeToEnum
<
T
>::
value
,
output
);
}
else
{
output
->
Resize
(
output_shape
);
Conv2dOpencl
(
input
,
filter
,
bias
,
false
,
strides_
[
0
],
paddings
.
data
(),
DataTypeToEnum
<
T
>::
value
,
output
);
}
auto
conv2d_func
=
selector
[
kernel_h
-
1
][
strides_
[
0
]
-
1
];
conv2d_func
(
input
,
filter
,
bias
,
true
,
paddings
.
data
(),
DataTypeToEnum
<
T
>::
value
,
output
);
}
template
...
...
mace/python/tools/tf_converter.py
浏览文件 @
33d4454d
...
...
@@ -24,7 +24,7 @@ def main(unused_args):
input_graph_def
,
FLAGS
.
input_node
,
FLAGS
.
output_node
,
FLAGS
.
prequantize
)
else
:
output_graph_def
=
tf_converter_lib
.
convert_to_mace_pb
(
input_graph_def
,
FLAGS
.
runtime
)
input_graph_def
,
FLAGS
.
input_node
,
FLAGS
.
output_node
,
FLAGS
.
runtime
)
with
gfile
.
GFile
(
FLAGS
.
output
,
"wb"
)
as
f
:
f
.
write
(
output_graph_def
.
SerializeToString
())
...
...
mace/python/tools/tf_converter_lib.py
浏览文件 @
33d4454d
...
...
@@ -45,9 +45,11 @@ def get_input_tensor(op, index):
def
add_buffer_to_image
(
input_name
,
input_type
,
net_def
):
output_name
=
input_name
[:
-
2
]
+
"_b2i"
+
input_name
[
-
2
:]
op_def
=
net_def
.
op
.
add
()
op_def
.
name
=
output_name
op_def
.
name
=
output_name
[:
-
2
]
op_def
.
type
=
'BufferToImage'
op_def
.
input
.
extend
([
input_name
])
op_def
.
output
.
extend
([
output_name
])
epsilon_arg
=
op_def
.
arg
.
add
()
epsilon_arg
.
name
=
'buffer_type'
epsilon_arg
.
i
=
buffer_type_map
[
input_type
]
...
...
@@ -56,6 +58,30 @@ def add_buffer_to_image(input_name, input_type, net_def):
epsilon_arg
.
i
=
0
return
output_name
def
add_input_transform
(
name
,
net_def
):
new_input_name
=
"mace_input_node:0"
op_def
=
net_def
.
op
.
add
()
op_def
.
name
=
name
op_def
.
type
=
'BufferToImage'
op_def
.
input
.
extend
([
new_input_name
])
op_def
.
output
.
extend
([
name
+
':0'
])
epsilon_arg
=
op_def
.
arg
.
add
()
epsilon_arg
.
name
=
'buffer_type'
epsilon_arg
.
i
=
buffer_type_map
[
'IN_OUT'
]
def
add_output_transform
(
name
,
net_def
):
output_name
=
"mace_output_node:0"
op_def
=
net_def
.
op
.
add
()
op_def
.
name
=
output_name
[:
-
2
]
op_def
.
type
=
'ImageToBuffer'
op_def
.
input
.
extend
([
name
+
':0'
])
op_def
.
output
.
extend
([
output_name
])
epsilon_arg
=
op_def
.
arg
.
add
()
epsilon_arg
.
name
=
'buffer_type'
epsilon_arg
.
i
=
buffer_type_map
[
'IN_OUT'
]
def
convert_ops
(
unresolved_ops
,
net_def
,
device
):
ops_count
=
len
(
unresolved_ops
)
resolved_count
=
1
...
...
@@ -257,7 +283,7 @@ def convert_ops(unresolved_ops, net_def, device):
size_arg
.
ints
.
extend
(
get_input_tensor
(
first_op
,
1
).
eval
().
astype
(
np
.
int32
).
flat
)
size_arg
=
op_def
.
arg
.
add
()
size_arg
.
name
=
'align_corners'
size_arg
.
i
nts
.
extend
(
first_op
.
get_attr
(
'align_corners'
)
)
size_arg
.
i
=
first_op
.
get_attr
(
'align_corners'
)
output_shapes
=
[]
for
output
in
first_op
.
outputs
:
output_shape
=
mace_pb2
.
OutputShape
()
...
...
@@ -284,7 +310,7 @@ def convert_ops(unresolved_ops, net_def, device):
del
unresolved_ops
[
0
]
def
convert_to_mace_pb
(
input_graph_def
,
device
):
def
convert_to_mace_pb
(
input_graph_def
,
input_node
,
output_node
,
device
):
net_def
=
mace_pb2
.
NetDef
()
with
tf
.
Session
()
as
session
:
...
...
@@ -292,8 +318,12 @@ def convert_to_mace_pb(input_graph_def, device):
tf
.
import_graph_def
(
input_graph_def
,
name
=
""
)
ops
=
graph
.
get_operations
()
unresolved_ops
=
ops
if
device
==
'gpu'
:
add_input_transform
(
input_node
,
net_def
)
while
len
(
unresolved_ops
)
>
0
:
convert_ops
(
unresolved_ops
,
net_def
,
device
)
if
device
==
'gpu'
:
add_output_transform
(
output_node
,
net_def
)
print
"PB Parsed."
...
...
tools/validate.py
0 → 100644
浏览文件 @
33d4454d
import
argparse
import
sys
import
tensorflow
as
tf
import
numpy
as
np
from
tensorflow
import
gfile
# Validation Flow:
# 1. Generate input data
# python validate_icnet.py --generate_data 1 \
# --random_seed 1
# 2. Use mace_run to run icnet on phone.
# 3. adb pull the result.
# 4. Compare output data of mace and tf
# python validate_icnet.py --model_file opt_icnet.pb \
# --input_file input_file \
# --mace_out_file icnet.out
def
generate_data
(
shape
):
np
.
random
.
seed
(
FLAGS
.
random_seed
)
data
=
np
.
random
.
random
(
shape
)
print
FLAGS
.
input_file
data
.
astype
(
np
.
float32
).
tofile
(
FLAGS
.
input_file
)
print
"Generate input file done."
def
load_data
(
file
):
return
np
.
fromfile
(
file
=
file
,
dtype
=
np
.
float32
)
def
valid_output
(
out_shape
,
mace_out_file
,
tf_out_value
):
mace_out_value
=
load_data
(
mace_out_file
)
mace_out_value
=
mace_out_value
.
reshape
(
out_shape
)
res
=
np
.
allclose
(
tf_out_value
,
mace_out_value
,
rtol
=
0
,
atol
=
1e-5
)
print
'Passed! Haha'
if
res
else
'Failed! Oops'
def
run_model
(
input_shape
):
if
not
gfile
.
Exists
(
FLAGS
.
model_file
):
print
(
"Input graph file '"
+
FLAGS
.
model_file
+
"' does not exist!"
)
return
-
1
input_graph_def
=
tf
.
GraphDef
()
with
gfile
.
Open
(
FLAGS
.
model_file
,
"rb"
)
as
f
:
data
=
f
.
read
()
input_graph_def
.
ParseFromString
(
data
)
tf
.
import_graph_def
(
input_graph_def
,
name
=
""
)
with
tf
.
Session
()
as
session
:
with
session
.
graph
.
as_default
()
as
graph
:
tf
.
import_graph_def
(
input_graph_def
,
name
=
""
)
input_node
=
graph
.
get_tensor_by_name
(
FLAGS
.
input_node
+
':0'
)
output_node
=
graph
.
get_tensor_by_name
(
FLAGS
.
output_node
+
':0'
)
input_value
=
load_data
(
FLAGS
.
input_file
)
input_value
=
input_value
.
reshape
(
input_shape
)
output_value
=
session
.
run
(
output_node
,
feed_dict
=
{
input_node
:
[
input_value
]})
return
output_value
def
main
(
unused_args
):
input_shape
=
[
int
(
x
)
for
x
in
FLAGS
.
input_shape
.
split
(
','
)]
output_shape
=
[
int
(
x
)
for
x
in
FLAGS
.
output_shape
.
split
(
','
)]
if
FLAGS
.
generate_data
:
generate_data
(
input_shape
)
else
:
output_value
=
run_model
(
input_shape
)
valid_output
(
output_shape
,
FLAGS
.
mace_out_file
,
output_value
)
def
parse_args
():
"""Parses command line arguments."""
parser
=
argparse
.
ArgumentParser
()
parser
.
register
(
"type"
,
"bool"
,
lambda
v
:
v
.
lower
()
==
"true"
)
parser
.
add_argument
(
"--model_file"
,
type
=
str
,
default
=
""
,
help
=
"TensorFlow
\'
GraphDef
\'
file to load."
)
parser
.
add_argument
(
"--input_file"
,
type
=
str
,
default
=
""
,
help
=
"input file."
)
parser
.
add_argument
(
"--mace_out_file"
,
type
=
str
,
default
=
""
,
help
=
"mace output file to load."
)
parser
.
add_argument
(
"--input_shape"
,
type
=
str
,
default
=
"512,512,3"
,
help
=
"input shape."
)
parser
.
add_argument
(
"--output_shape"
,
type
=
str
,
default
=
"1,512,512,2"
,
help
=
"output shape."
)
parser
.
add_argument
(
"--input_node"
,
type
=
str
,
default
=
"input_node"
,
help
=
"input node"
)
parser
.
add_argument
(
"--output_node"
,
type
=
str
,
default
=
"output_node"
,
help
=
"output node"
)
parser
.
add_argument
(
"--generate_data"
,
type
=
'bool'
,
default
=
"false"
,
help
=
"Random seed for generate test case."
)
parser
.
add_argument
(
"--random_seed"
,
type
=
int
,
default
=
"0"
,
help
=
"Random seed for generate test case."
)
return
parser
.
parse_known_args
()
if
__name__
==
'__main__'
:
FLAGS
,
unparsed
=
parse_args
()
main
(
unused_args
=
[
sys
.
argv
[
0
]]
+
unparsed
)
tools/validate_gcn.sh
0 → 100644
浏览文件 @
33d4454d
#!/bin/bash
# Must run at root dir of mace project.
set
-e
Usage
()
{
echo
'Usage: bash tools/validate_gcn.sh tf_model_file'
}
if
[
$#
!=
1
]
;
then
Usage
exit
-1
fi
TF_MODEL_FILE_PATH
=
$1
MODEL_DIR
=
$(
dirname
${
TF_MODEL_FILE_PATH
}
)
MACE_MODEL_NAME
=
'mace_model.pb'
INPUT_FILE_NAME
=
'model_input'
OUTPUT_FILE_NAME
=
'gcn.out'
PHONE_DATA_DIR
=
"/data/local/tmp/
${
MACE_MODEL_NAME
}
"
KERNEL_DIR
=
"
${
PHONE_DATA_DIR
}
/cl/"
# Step 1: convert tf model to mace model
#echo "Step 1: convert tf model to mace model"
#bazel build //mace/python/tools:tf_converter
#bazel-bin/mace/python/tools/tf_converter --input=${TF_MODEL_FILE_PATH} \
# --output=${MODEL_DIR}/${MACE_MODEL_NAME} \
# --input_node=input \
# --output_node=GCN/br_result_2/fcn_br \
# --runtime=gpu
#
## Step 2: Generate input data
#echo "Step 2: Generate input data"
#python tools/validate.py --generate_data true --random_seed 1 \
# --input_file=${MODEL_DIR}/${INPUT_FILE_NAME} \
# --input_shape=512,512,3
# Step 3: Run model on the phone
echo
"Step 3: Run model on the phone"
bazel build
-c
opt
--strip
always mace/examples:mace_run
\
--crosstool_top
=
//external:android/crosstool
\
--host_crosstool_top
=
@bazel_tools//tools/cpp:toolchain
\
--cpu
=
arm64-v8a
adb shell
"mkdir -p
${
PHONE_DATA_DIR
}
"
adb shell
"mkdir -p
${
KERNEL_DIR
}
"
adb push mace/kernels/opencl/cl/
*
${
KERNEL_DIR
}
adb push
${
MODEL_DIR
}
/
${
MACE_MODEL_NAME
}
${
PHONE_DATA_DIR
}
adb push
${
MODEL_DIR
}
/
${
INPUT_FILE_NAME
}
${
PHONE_DATA_DIR
}
adb push bazel-bin/mace/examples/mace_run
${
PHONE_DATA_DIR
}
num_threads
=
${
1
:-
1
}
adb shell
MACE_RUN_PARAMETER_PATH
=
${
PHONE_DATA_DIR
}
/mace_run.config
\
MACE_KERNEL_PATH
=
$KERNEL_DIR
\
OMP_NUM_THREADS
=
$num_threads
\
${
PHONE_DATA_DIR
}
/mace_run
\
--model
=
${
PHONE_DATA_DIR
}
/
${
MACE_MODEL_NAME
}
\
--input
=
mace_input_node
\
--output
=
mace_output_node
\
--input_shape
=
1,512,512,3
\
--input_file
=
${
PHONE_DATA_DIR
}
/
${
MACE_INPUT_FILE_NAME
}
\
--output_file
=
${
PHONE_DATA_DIR
}
/
${
OUTPUT_FILE_NAME
}
\
--device
=
OPENCL
# Step 4: pull the mace run result.
echo
"Step 4: pull the mace run result."
adb pull
${
PHONE_DATA_DIR
}
/
${
OUTPUT_FILE_NAME
}
${
MODEL_DIR
}
# Step 5: validate the result
echo
"Step 5: validate the result"
python tools/validate.py
--model_file
${
TF_MODEL_FILE_PATH
}
\
--input_file
${
MODEL_DIR
}
/
${
INPUT_FILE_NAME
}
\
--mace_out_file
${
MODEL_DIR
}
/
${
OUTPUT_FILE_NAME
}
\
--input_node
input
\
--output_node
GCN/br_result_2/fcn_br
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录