Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Xiaomi
Mace
提交
6da30d22
Mace
项目概览
Xiaomi
/
Mace
通知
106
Star
40
Fork
27
代码
文件
提交
分支
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,发现更多精彩内容 >>
提交
6da30d22
编写于
4月 10, 2018
作者:
L
Liangliang He
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Enable python style check
上级
e54825c5
变更
22
展开全部
隐藏空白更改
内联
并排
Showing
22 changed file
with
4594 addition
and
4287 deletion
+4594
-4287
.gitlab-ci.yml
.gitlab-ci.yml
+7
-1
docker/Dockerfile
docker/Dockerfile
+2
-1
mace/python/tools/binary_codegen.py
mace/python/tools/binary_codegen.py
+62
-61
mace/python/tools/caffe_converter_lib.py
mace/python/tools/caffe_converter_lib.py
+1098
-1024
mace/python/tools/convert_util.py
mace/python/tools/convert_util.py
+0
-1
mace/python/tools/converter.py
mace/python/tools/converter.py
+149
-159
mace/python/tools/dsp_ops.py
mace/python/tools/dsp_ops.py
+60
-62
mace/python/tools/encrypt_opencl_codegen.py
mace/python/tools/encrypt_opencl_codegen.py
+62
-58
mace/python/tools/graph_util.py
mace/python/tools/graph_util.py
+7
-2
mace/python/tools/memory_optimizer.py
mace/python/tools/memory_optimizer.py
+123
-112
mace/python/tools/opencl_codegen.py
mace/python/tools/opencl_codegen.py
+77
-74
mace/python/tools/source_converter_lib.py
mace/python/tools/source_converter_lib.py
+176
-162
mace/python/tools/tf_converter_lib.py
mace/python/tools/tf_converter_lib.py
+1162
-1125
mace/python/tools/tf_dsp_converter_lib.py
mace/python/tools/tf_dsp_converter_lib.py
+472
-403
mace/python/tools/tf_ops_stats.py
mace/python/tools/tf_ops_stats.py
+162
-136
tools/bazel_adb_run.py
tools/bazel_adb_run.py
+99
-91
tools/falcon_cli.py
tools/falcon_cli.py
+12
-10
tools/generate_data.py
tools/generate_data.py
+30
-35
tools/mace_tools.py
tools/mace_tools.py
+378
-340
tools/sh_commands.py
tools/sh_commands.py
+152
-119
tools/validate.py
tools/validate.py
+152
-155
tools/wino_conv.py
tools/wino_conv.py
+152
-156
未找到文件。
.gitlab-ci.yml
浏览文件 @
6da30d22
stages
:
stages
:
-
cpplint
-
cpplint
-
pycodestyle
-
ops_test
-
ops_test
-
ops_benchmark
-
ops_benchmark
...
@@ -7,7 +8,12 @@ cpplint:
...
@@ -7,7 +8,12 @@ cpplint:
stage
:
cpplint
stage
:
cpplint
script
:
script
:
-
curl -o cpplint.py https://raw.githubusercontent.com/google/styleguide/gh-pages/cpplint/cpplint.py
-
curl -o cpplint.py https://raw.githubusercontent.com/google/styleguide/gh-pages/cpplint/cpplint.py
-
python cpplint.py --linelength=80 --counting=detailed $(find mace -name *.h -or -name *.cc)
-
python cpplint.py --linelength=80 --counting=detailed $(find mace -name "*.h" -or -name "*.cc")
pycodestyle
:
stage
:
pycodestyle
script
:
-
pycodestyle $(find -name "*.py")
ops_test
:
ops_test
:
stage
:
ops_test
stage
:
ops_test
...
...
docker/Dockerfile
浏览文件 @
6da30d22
...
@@ -113,7 +113,8 @@ RUN pip install -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
...
@@ -113,7 +113,8 @@ RUN pip install -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
scipy
\
scipy
\
jinja2
\
jinja2
\
pyyaml
\
pyyaml
\
sh
sh
\
pycodestyle
# Download tensorflow tools
# Download tensorflow tools
RUN
wget http://cnbj1-inner-fds.api.xiaomi.net/mace/tool/transform_graph
&&
\
RUN
wget http://cnbj1-inner-fds.api.xiaomi.net/mace/tool/transform_graph
&&
\
...
...
mace/python/tools/binary_codegen.py
浏览文件 @
6da30d22
...
@@ -16,74 +16,75 @@ FLAGS = None
...
@@ -16,74 +16,75 @@ FLAGS = None
def
generate_cpp_source
():
def
generate_cpp_source
():
data_map
=
{}
data_map
=
{}
for
binary_dir
in
FLAGS
.
binary_dirs
.
split
(
","
):
for
binary_dir
in
FLAGS
.
binary_dirs
.
split
(
","
):
binary_path
=
os
.
path
.
join
(
binary_dir
,
FLAGS
.
binary_file_name
)
binary_path
=
os
.
path
.
join
(
binary_dir
,
FLAGS
.
binary_file_name
)
if
not
os
.
path
.
exists
(
binary_path
):
if
not
os
.
path
.
exists
(
binary_path
):
continue
continue
with
open
(
binary_path
,
"rb"
)
as
f
:
with
open
(
binary_path
,
"rb"
)
as
f
:
binary_array
=
np
.
fromfile
(
f
,
dtype
=
np
.
uint8
)
binary_array
=
np
.
fromfile
(
f
,
dtype
=
np
.
uint8
)
print
"Generate binary from"
,
binary_path
print
"Generate binary from"
,
binary_path
idx
=
0
idx
=
0
size
,
=
struct
.
unpack
(
"Q"
,
binary_array
[
idx
:
idx
+
8
])
size
,
=
struct
.
unpack
(
"Q"
,
binary_array
[
idx
:
idx
+
8
])
idx
+=
8
idx
+=
8
for
_
in
xrange
(
size
):
for
_
in
xrange
(
size
):
key_size
,
=
struct
.
unpack
(
"i"
,
binary_array
[
idx
:
idx
+
4
])
key_size
,
=
struct
.
unpack
(
"i"
,
binary_array
[
idx
:
idx
+
4
])
idx
+=
4
idx
+=
4
key
,
=
struct
.
unpack
(
str
(
key_size
)
+
"s"
,
binary_array
[
idx
:
idx
+
key_size
])
key
,
=
struct
.
unpack
(
idx
+=
key_size
str
(
key_size
)
+
"s"
,
binary_array
[
idx
:
idx
+
key_size
])
params_size
,
=
struct
.
unpack
(
"i"
,
binary_array
[
idx
:
idx
+
4
])
idx
+=
key_size
idx
+=
4
params_size
,
=
struct
.
unpack
(
"i"
,
binary_array
[
idx
:
idx
+
4
])
data_map
[
key
]
=
[]
idx
+=
4
count
=
params_size
/
4
data_map
[
key
]
=
[]
params
=
struct
.
unpack
(
str
(
count
)
+
"i"
,
binary_array
[
idx
:
idx
+
params_size
])
count
=
params_size
/
4
for
i
in
params
:
params
=
struct
.
unpack
(
data_map
[
key
].
append
(
i
)
str
(
count
)
+
"i"
,
binary_array
[
idx
:
idx
+
params_size
])
idx
+=
params_size
for
i
in
params
:
data_map
[
key
].
append
(
i
)
idx
+=
params_size
env
=
jinja2
.
Environment
(
loader
=
jinja2
.
FileSystemLoader
(
sys
.
path
[
0
]))
return
env
.
get_template
(
'str2vec_maps.cc.jinja2'
).
render
(
maps
=
data_map
,
data_type
=
'unsigned int'
,
variable_name
=
FLAGS
.
variable_name
)
env
=
jinja2
.
Environment
(
loader
=
jinja2
.
FileSystemLoader
(
sys
.
path
[
0
]))
return
env
.
get_template
(
'str2vec_maps.cc.jinja2'
).
render
(
maps
=
data_map
,
data_type
=
'unsigned int'
,
variable_name
=
FLAGS
.
variable_name
)
def
main
(
unused_args
):
def
main
(
unused_args
):
cpp_binary_source
=
generate_cpp_source
()
cpp_binary_source
=
generate_cpp_source
()
if
os
.
path
.
isfile
(
FLAGS
.
output_path
):
if
os
.
path
.
isfile
(
FLAGS
.
output_path
):
os
.
remove
(
FLAGS
.
output_path
)
os
.
remove
(
FLAGS
.
output_path
)
w_file
=
open
(
FLAGS
.
output_path
,
"w"
)
w_file
=
open
(
FLAGS
.
output_path
,
"w"
)
w_file
.
write
(
cpp_binary_source
)
w_file
.
write
(
cpp_binary_source
)
w_file
.
close
()
w_file
.
close
()
def
parse_args
():
def
parse_args
():
"""Parses command line arguments."""
"""Parses command line arguments."""
parser
=
argparse
.
ArgumentParser
()
parser
=
argparse
.
ArgumentParser
()
parser
.
add_argument
(
parser
.
add_argument
(
"--binary_dirs"
,
"--binary_dirs"
,
type
=
str
,
default
=
""
,
help
=
"The binaries file path."
)
type
=
str
,
parser
.
add_argument
(
default
=
""
,
"--binary_file_name"
,
help
=
"The binaries file path."
)
type
=
str
,
parser
.
add_argument
(
default
=
"mace_run.config"
,
"--binary_file_name"
,
help
=
"The binary file name."
)
type
=
str
,
parser
.
add_argument
(
default
=
"mace_run.config"
,
"--output_path"
,
help
=
"The binary file name."
)
type
=
str
,
parser
.
add_argument
(
default
=
""
,
"--output_path"
,
help
=
"The path of generated C++ source file which contains the binary."
type
=
str
,
)
default
=
""
,
parser
.
add_argument
(
help
=
"The path of generated C++ source file which contains the binary."
)
"--variable_name"
,
parser
.
add_argument
(
type
=
str
,
"--variable_name"
,
default
=
"kTuningParamsData"
,
type
=
str
,
help
=
"global variable name."
)
default
=
"kTuningParamsData"
,
return
parser
.
parse_known_args
()
help
=
"global variable name."
)
return
parser
.
parse_known_args
()
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
FLAGS
,
unparsed
=
parse_args
()
FLAGS
,
unparsed
=
parse_args
()
main
(
unused_args
=
[
sys
.
argv
[
0
]]
+
unparsed
)
main
(
unused_args
=
[
sys
.
argv
[
0
]]
+
unparsed
)
mace/python/tools/caffe_converter_lib.py
浏览文件 @
6da30d22
此差异已折叠。
点击以展开。
mace/python/tools/convert_util.py
浏览文件 @
6da30d22
...
@@ -26,4 +26,3 @@ def tf_dtype_2_mace_dtype(tf_dtype):
...
@@ -26,4 +26,3 @@ def tf_dtype_2_mace_dtype(tf_dtype):
if
not
mace_dtype
:
if
not
mace_dtype
:
raise
Exception
(
"Not supported tensorflow dtype: "
+
tf_dtype
)
raise
Exception
(
"Not supported tensorflow dtype: "
+
tf_dtype
)
return
mace_dtype
return
mace_dtype
mace/python/tools/converter.py
浏览文件 @
6da30d22
...
@@ -4,176 +4,166 @@ import hashlib
...
@@ -4,176 +4,166 @@ import hashlib
import
os.path
import
os.path
from
mace.python.tools
import
source_converter_lib
from
mace.python.tools
import
source_converter_lib
# ./bazel-bin/mace/python/tools/tf_converter --model_file quantized_test.pb --output quantized_test_dsp.pb --runtime dsp --input_dim input_node,1,28,28,3
# ./bazel-bin/mace/python/tools/tf_converter --model_file quantized_test.pb \
# --output quantized_test_dsp.pb \
# --runtime dsp \
# --input_dim input_node,1,28,28,3
FLAGS
=
None
FLAGS
=
None
def
file_checksum
(
fname
):
def
file_checksum
(
fname
):
hash_func
=
hashlib
.
sha256
()
hash_func
=
hashlib
.
sha256
()
with
open
(
fname
,
"rb"
)
as
f
:
with
open
(
fname
,
"rb"
)
as
f
:
for
chunk
in
iter
(
lambda
:
f
.
read
(
4096
),
b
""
):
for
chunk
in
iter
(
lambda
:
f
.
read
(
4096
),
b
""
):
hash_func
.
update
(
chunk
)
hash_func
.
update
(
chunk
)
return
hash_func
.
hexdigest
()
return
hash_func
.
hexdigest
()
def
main
(
unused_args
):
def
main
(
unused_args
):
if
not
os
.
path
.
isfile
(
FLAGS
.
model_file
):
if
not
os
.
path
.
isfile
(
FLAGS
.
model_file
):
print
(
"Input graph file '"
+
FLAGS
.
model_file
+
"' does not exist!"
)
print
(
"Input graph file '"
+
FLAGS
.
model_file
+
"' does not exist!"
)
sys
.
exit
(
-
1
)
sys
.
exit
(
-
1
)
model_checksum
=
file_checksum
(
FLAGS
.
model_file
)
model_checksum
=
file_checksum
(
FLAGS
.
model_file
)
if
FLAGS
.
model_checksum
!=
""
and
FLAGS
.
model_checksum
!=
model_checksum
:
if
FLAGS
.
model_checksum
!=
""
and
FLAGS
.
model_checksum
!=
model_checksum
:
print
(
"Model checksum mismatch: %s != %s"
%
(
model_checksum
,
FLAGS
.
model_checksum
))
print
(
"Model checksum mismatch: %s != %s"
%
(
model_checksum
,
sys
.
exit
(
-
1
)
FLAGS
.
model_checksum
))
sys
.
exit
(
-
1
)
if
FLAGS
.
platform
==
'caffe'
:
if
not
os
.
path
.
isfile
(
FLAGS
.
weight_file
):
if
FLAGS
.
platform
==
'caffe'
:
print
(
"Input weight file '"
+
FLAGS
.
weight_file
+
"' does not exist!"
)
if
not
os
.
path
.
isfile
(
FLAGS
.
weight_file
):
sys
.
exit
(
-
1
)
print
(
"Input weight file '"
+
FLAGS
.
weight_file
+
"' does not exist!"
)
weight_checksum
=
file_checksum
(
FLAGS
.
weight_file
)
sys
.
exit
(
-
1
)
if
FLAGS
.
weight_checksum
!=
""
and
FLAGS
.
weight_checksum
!=
weight_checksum
:
print
(
"Weight checksum mismatch: %s != %s"
%
(
weight_checksum
,
FLAGS
.
weight_checksum
))
weight_checksum
=
file_checksum
(
FLAGS
.
weight_file
)
sys
.
exit
(
-
1
)
if
FLAGS
.
weight_checksum
!=
""
and
\
FLAGS
.
weight_checksum
!=
weight_checksum
:
if
FLAGS
.
runtime
==
'dsp'
:
print
(
"Weight checksum mismatch: %s != %s"
%
print
(
"DSP not support caffe model yet."
)
(
weight_checksum
,
FLAGS
.
weight_checksum
))
sys
.
exit
(
-
1
)
sys
.
exit
(
-
1
)
from
mace.python.tools
import
caffe_converter_lib
if
FLAGS
.
runtime
==
'dsp'
:
output_graph_def
=
caffe_converter_lib
.
convert_to_mace_pb
(
print
(
"DSP not support caffe model yet."
)
FLAGS
.
model_file
,
FLAGS
.
weight_file
,
FLAGS
.
input_node
,
FLAGS
.
input_shape
,
FLAGS
.
output_node
,
sys
.
exit
(
-
1
)
FLAGS
.
data_type
,
FLAGS
.
runtime
,
FLAGS
.
winograd
)
elif
FLAGS
.
platform
==
'tensorflow'
:
from
mace.python.tools
import
caffe_converter_lib
if
FLAGS
.
runtime
==
'dsp'
:
output_graph_def
=
caffe_converter_lib
.
convert_to_mace_pb
(
from
mace.python.tools
import
tf_dsp_converter_lib
FLAGS
.
model_file
,
FLAGS
.
weight_file
,
FLAGS
.
input_node
,
output_graph_def
=
tf_dsp_converter_lib
.
convert_to_mace_pb
(
FLAGS
.
input_shape
,
FLAGS
.
output_node
,
FLAGS
.
data_type
,
FLAGS
.
model_file
,
FLAGS
.
input_node
,
FLAGS
.
output_node
,
FLAGS
.
dsp_mode
)
FLAGS
.
runtime
,
FLAGS
.
winograd
)
elif
FLAGS
.
platform
==
'tensorflow'
:
if
FLAGS
.
runtime
==
'dsp'
:
from
mace.python.tools
import
tf_dsp_converter_lib
output_graph_def
=
tf_dsp_converter_lib
.
convert_to_mace_pb
(
FLAGS
.
model_file
,
FLAGS
.
input_node
,
FLAGS
.
output_node
,
FLAGS
.
dsp_mode
)
else
:
from
mace.python.tools
import
tf_converter_lib
output_graph_def
=
tf_converter_lib
.
convert_to_mace_pb
(
FLAGS
.
model_file
,
FLAGS
.
input_node
,
FLAGS
.
input_shape
,
FLAGS
.
output_node
,
FLAGS
.
data_type
,
FLAGS
.
runtime
,
FLAGS
.
winograd
)
if
FLAGS
.
output_type
==
'source'
:
source_converter_lib
.
convert_to_source
(
output_graph_def
,
model_checksum
,
FLAGS
.
template
,
FLAGS
.
obfuscate
,
FLAGS
.
model_tag
,
FLAGS
.
output
,
FLAGS
.
runtime
,
FLAGS
.
embed_model_data
)
else
:
else
:
from
mace.python.tools
import
tf_converter_lib
with
open
(
FLAGS
.
output
,
"wb"
)
as
f
:
output_graph_def
=
tf_converter_lib
.
convert_to_mace_pb
(
f
.
write
(
output_graph_def
.
SerializeToString
())
FLAGS
.
model_file
,
FLAGS
.
input_node
,
FLAGS
.
input_shape
,
FLAGS
.
output_node
,
with
open
(
FLAGS
.
output
+
'_txt'
,
"wb"
)
as
f
:
FLAGS
.
data_type
,
FLAGS
.
runtime
,
FLAGS
.
winograd
)
# output_graph_def.ClearField('tensors')
f
.
write
(
str
(
output_graph_def
))
if
FLAGS
.
output_type
==
'source'
:
print
(
"Model conversion is completed."
)
source_converter_lib
.
convert_to_source
(
output_graph_def
,
model_checksum
,
FLAGS
.
template
,
FLAGS
.
obfuscate
,
FLAGS
.
model_tag
,
FLAGS
.
output
,
FLAGS
.
runtime
,
FLAGS
.
embed_model_data
)
else
:
with
open
(
FLAGS
.
output
,
"wb"
)
as
f
:
f
.
write
(
output_graph_def
.
SerializeToString
())
with
open
(
FLAGS
.
output
+
'_txt'
,
"wb"
)
as
f
:
# output_graph_def.ClearField('tensors')
f
.
write
(
str
(
output_graph_def
))
print
(
"Model conversion is completed."
)
def
str2bool
(
v
):
def
str2bool
(
v
):
if
v
.
lower
()
in
(
'yes'
,
'true'
,
't'
,
'y'
,
'1'
):
if
v
.
lower
()
in
(
'yes'
,
'true'
,
't'
,
'y'
,
'1'
):
return
True
return
True
elif
v
.
lower
()
in
(
'no'
,
'false'
,
'f'
,
'n'
,
'0'
):
elif
v
.
lower
()
in
(
'no'
,
'false'
,
'f'
,
'n'
,
'0'
):
return
False
return
False
else
:
else
:
raise
argparse
.
ArgumentTypeError
(
'Boolean value expected.'
)
raise
argparse
.
ArgumentTypeError
(
'Boolean value expected.'
)
def
parse_args
():
def
parse_args
():
"""Parses command line arguments."""
"""Parses command line arguments."""
parser
=
argparse
.
ArgumentParser
()
parser
=
argparse
.
ArgumentParser
()
parser
.
register
(
"type"
,
"bool"
,
lambda
v
:
v
.
lower
()
==
"true"
)
parser
.
register
(
"type"
,
"bool"
,
lambda
v
:
v
.
lower
()
==
"true"
)
parser
.
add_argument
(
parser
.
add_argument
(
"--model_file"
,
"--model_file"
,
type
=
str
,
type
=
str
,
default
=
""
,
default
=
""
,
help
=
"TensorFlow
\'
GraphDef
\'
file to load, Caffe prototxt file to load."
)
help
=
"TensorFlow
\'
GraphDef
\'
file to load, "
parser
.
add_argument
(
"Caffe prototxt file to load."
)
"--weight_file"
,
parser
.
add_argument
(
type
=
str
,
"--weight_file"
,
type
=
str
,
default
=
""
,
help
=
"Caffe data file to load."
)
default
=
""
,
parser
.
add_argument
(
help
=
"Caffe data file to load."
)
"--model_checksum"
,
parser
.
add_argument
(
type
=
str
,
"--model_checksum"
,
default
=
""
,
type
=
str
,
help
=
"Model file sha256 checksum"
)
default
=
""
,
parser
.
add_argument
(
help
=
"Model file sha256 checksum"
)
"--weight_checksum"
,
parser
.
add_argument
(
type
=
str
,
"--weight_checksum"
,
default
=
""
,
type
=
str
,
help
=
"Weight file sha256 checksum"
)
default
=
""
,
parser
.
add_argument
(
help
=
"Weight file sha256 checksum"
)
"--output"
,
parser
.
add_argument
(
type
=
str
,
"--output"
,
default
=
""
,
type
=
str
,
help
=
"File to save the output graph to."
)
default
=
""
,
parser
.
add_argument
(
help
=
"File to save the output graph to."
)
"--runtime"
,
type
=
str
,
default
=
"cpu"
,
help
=
"Runtime: cpu/gpu/dsp"
)
parser
.
add_argument
(
parser
.
add_argument
(
"--runtime"
,
"--input_node"
,
type
=
str
,
type
=
str
,
default
=
"cpu"
,
default
=
"input_node"
,
help
=
"Runtime: cpu/gpu/dsp"
)
help
=
"e.g., input_node"
)
parser
.
add_argument
(
parser
.
add_argument
(
"--input_node"
,
"--output_node"
,
type
=
str
,
default
=
"softmax"
,
help
=
"e.g., softmax"
)
type
=
str
,
parser
.
add_argument
(
default
=
"input_node"
,
"--data_type"
,
help
=
"e.g., input_node"
)
type
=
str
,
parser
.
add_argument
(
default
=
'DT_FLOAT'
,
"--output_node"
,
help
=
"e.g., DT_HALF/DT_FLOAT"
)
type
=
str
,
parser
.
add_argument
(
default
=
"softmax"
,
"--output_type"
,
type
=
str
,
default
=
"pb"
,
help
=
"output type: source/pb"
)
help
=
"e.g., softmax"
)
parser
.
add_argument
(
parser
.
add_argument
(
"--template"
,
type
=
str
,
default
=
""
,
help
=
"template path"
)
"--data_type"
,
parser
.
add_argument
(
type
=
str
,
"--obfuscate"
,
default
=
'DT_FLOAT'
,
type
=
str2bool
,
help
=
"e.g., DT_HALF/DT_FLOAT"
)
nargs
=
'?'
,
parser
.
add_argument
(
const
=
False
,
"--output_type"
,
default
=
False
,
type
=
str
,
help
=
"obfuscate model names"
)
default
=
"pb"
,
parser
.
add_argument
(
help
=
"output type: source/pb"
)
"--model_tag"
,
parser
.
add_argument
(
type
=
str
,
"--template"
,
default
=
""
,
type
=
str
,
help
=
"model tag for generated function and namespace"
)
default
=
""
,
parser
.
add_argument
(
help
=
"template path"
)
"--winograd"
,
parser
.
add_argument
(
type
=
str2bool
,
"--obfuscate"
,
nargs
=
'?'
,
type
=
str2bool
,
const
=
False
,
nargs
=
'?'
,
default
=
False
,
const
=
False
,
help
=
"open winograd convolution or not"
)
default
=
False
,
parser
.
add_argument
(
help
=
"obfuscate model names"
)
"--dsp_mode"
,
type
=
int
,
default
=
0
,
help
=
"dsp run mode, defalut=0"
)
parser
.
add_argument
(
parser
.
add_argument
(
"--model_tag"
,
"--input_shape"
,
type
=
str
,
default
=
""
,
help
=
"input shape."
)
type
=
str
,
parser
.
add_argument
(
default
=
""
,
"--platform"
,
type
=
str
,
default
=
"tensorflow"
,
help
=
"tensorflow/caffe"
)
help
=
"model tag for generated function and namespace"
)
parser
.
add_argument
(
parser
.
add_argument
(
"--embed_model_data"
,
type
=
str2bool
,
default
=
True
,
help
=
"input shape."
)
"--winograd"
,
return
parser
.
parse_known_args
()
type
=
str2bool
,
nargs
=
'?'
,
const
=
False
,
default
=
False
,
help
=
"open winograd convolution or not"
)
parser
.
add_argument
(
"--dsp_mode"
,
type
=
int
,
default
=
0
,
help
=
"dsp run mode, defalut=0"
)
parser
.
add_argument
(
"--input_shape"
,
type
=
str
,
default
=
""
,
help
=
"input shape."
)
parser
.
add_argument
(
"--platform"
,
type
=
str
,
default
=
"tensorflow"
,
help
=
"tensorflow/caffe"
)
parser
.
add_argument
(
"--embed_model_data"
,
type
=
str2bool
,
default
=
True
,
help
=
"input shape."
)
return
parser
.
parse_known_args
()
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
FLAGS
,
unparsed
=
parse_args
()
FLAGS
,
unparsed
=
parse_args
()
main
(
unused_args
=
[
sys
.
argv
[
0
]]
+
unparsed
)
main
(
unused_args
=
[
sys
.
argv
[
0
]]
+
unparsed
)
mace/python/tools/dsp_ops.py
浏览文件 @
6da30d22
class
DspOps
(
object
):
class
DspOps
(
object
):
def
__init__
(
self
):
def
__init__
(
self
):
self
.
dsp_ops
=
{
self
.
dsp_ops
=
{
'INPUT'
:
'INPUT"'
,
'INPUT'
:
'INPUT"'
,
'OUTPUT'
:
'OUTPUT'
,
'OUTPUT'
:
'OUTPUT'
,
'NoOp'
:
'Nop'
,
'NoOp'
:
'Nop'
,
'FLATTEN'
:
'Flatten'
,
'FLATTEN'
:
'Flatten'
,
'Identity'
:
'Nop'
,
'Identity'
:
'Nop'
,
'Placeholder'
:
'INPUT'
,
'Placeholder'
:
'INPUT'
,
'Const'
:
'Const'
,
'Const'
:
'Const'
,
'QuantizedConv2D'
:
'QuantizedConv2d_8x8to32'
,
'QuantizedConv2D'
:
'QuantizedConv2d_8x8to32'
,
'QuantizedMatMul'
:
'QuantizedMatMul_8x8to32'
,
'QuantizedMatMul'
:
'QuantizedMatMul_8x8to32'
,
'QuantizeDownAndShrinkRange'
:
'QuantizeDownAndShrinkRange_32to8'
,
'QuantizeDownAndShrinkRange'
:
'QuantizeDownAndShrinkRange_32to8'
,
'QuantizedRelu'
:
'QuantizedRelu_8'
,
'QuantizedRelu'
:
'QuantizedRelu_8'
,
'QuantizedReluX'
:
'QuantizedReluX_8'
,
'QuantizedReluX'
:
'QuantizedReluX_8'
,
'QuantizedMaxPool'
:
'QuantizedMaxPool_8'
,
'QuantizedMaxPool'
:
'QuantizedMaxPool_8'
,
'QuantizedAvgPool'
:
'QuantizedAvgPool_8'
,
'QuantizedAvgPool'
:
'QuantizedAvgPool_8'
,
'QuantizedConcat'
:
'QuantizedConcat_8'
,
'QuantizedConcat'
:
'QuantizedConcat_8'
,
'QuantizedBiasAdd'
:
'QuantizedBiasAdd_8p8to32'
,
'QuantizedBiasAdd'
:
'QuantizedBiasAdd_8p8to32'
,
'QuantizedResizeBilinear'
:
'QuantizedResizeBilinear_8'
,
'QuantizedResizeBilinear'
:
'QuantizedResizeBilinear_8'
,
'QuantizedSpaceToBatchND'
:
'QuantizedSpaceToBatchND_8'
,
'QuantizedSpaceToBatchND'
:
'QuantizedSpaceToBatchND_8'
,
'QuantizedBatchToSpaceND'
:
'QuantizedBatchToSpaceND_8'
,
'QuantizedBatchToSpaceND'
:
'QuantizedBatchToSpaceND_8'
,
'QuantizedSoftmax'
:
'QuantizedSoftmax_8'
,
'QuantizedSoftmax'
:
'QuantizedSoftmax_8'
,
'QuantizedTanh'
:
'QuantizedTanh_8'
,
'QuantizedTanh'
:
'QuantizedTanh_8'
,
'Min'
:
'Min_f'
,
'Min'
:
'Min_f'
,
'Max'
:
'Max_f'
,
'Max'
:
'Max_f'
,
'QuantizeV2'
:
'Quantize'
,
'QuantizeV2'
:
'Quantize'
,
'Dequantize'
:
'Dequantize'
,
'Dequantize'
:
'Dequantize'
,
'Softmax'
:
'Softmax_f'
,
'Softmax'
:
'Softmax_f'
,
'Reshape'
:
'Reshape'
,
'Reshape'
:
'Reshape'
,
'QuantizedReshape'
:
'QuantizedReshape'
,
'QuantizedReshape'
:
'QuantizedReshape'
,
'Sigmoid'
:
'Sigmoid_f'
,
'Sigmoid'
:
'Sigmoid_f'
,
'Slice'
:
'Slice_f'
,
'Slice'
:
'Slice_f'
,
'Add'
:
'Add_f'
,
'Add'
:
'Add_f'
,
'Mul'
:
'Mul_f'
,
'Mul'
:
'Mul_f'
,
'Requantize'
:
'Requantize_32to8'
,
'Requantize'
:
'Requantize_32to8'
,
'RequantizationRange'
:
'RequantizationRange_32'
,
'RequantizationRange'
:
'RequantizationRange_32'
,
'Sub'
:
'Sub_f'
,
'Sub'
:
'Sub_f'
,
'Pack'
:
'Pack_int32'
,
'Pack'
:
'Pack_int32'
,
'StridedSlice'
:
'StridedSlice_f'
,
'StridedSlice'
:
'StridedSlice_f'
,
'ExpandDims'
:
'ExpandDims_f'
,
'ExpandDims'
:
'ExpandDims_f'
,
'QuantizedMul'
:
'QuantizedMul_8x8to32'
,
'QuantizedMul'
:
'QuantizedMul_8x8to32'
,
'QuantizedAdd'
:
'QuantizedAdd_8p8to32'
,
'QuantizedAdd'
:
'QuantizedAdd_8p8to32'
,
'Pad'
:
'Pad_f'
,
'Pad'
:
'Pad_f'
,
'SpaceToBatchND'
:
'SpaceToBatchND_f'
,
'SpaceToBatchND'
:
'SpaceToBatchND_f'
,
'BatchToSpaceND'
:
'BatchToSpaceND_f'
,
'BatchToSpaceND'
:
'BatchToSpaceND_f'
,
'ResizeBilinear'
:
'ResizeBilinear_f'
,
'ResizeBilinear'
:
'ResizeBilinear_f'
,
'ConcatV2'
:
'ConcatV2_f'
,
'ConcatV2'
:
'ConcatV2_f'
,
'Conv2DBackpropInput'
:
'Deconv_f'
,
'Conv2DBackpropInput'
:
'Deconv_f'
,
'Tanh'
:
'Tanh_f'
,
'Tanh'
:
'Tanh_f'
,
'Split'
:
'Split_f'
,
'Split'
:
'Split_f'
,
'Transpose'
:
'Transpose_f'
,
'Transpose'
:
'Transpose_f'
,
'Concat'
:
'Concat_f'
,
'Concat'
:
'Concat_f'
,
'AddN'
:
'AddN_f'
,
'AddN'
:
'AddN_f'
,
}
}
def
has_op
(
self
,
tf_op
):
return
tf_op
in
self
.
dsp_ops
def
map_nn_op
(
self
,
tf_op
):
if
tf_op
not
in
self
.
dsp_ops
:
raise
Exception
(
'Could not map nn op for: '
,
tf_op
)
return
self
.
dsp_ops
[
tf_op
]
def
has_op
(
self
,
tf_op
):
return
tf_op
in
self
.
dsp_ops
def
map_nn_op
(
self
,
tf_op
):
if
tf_op
not
in
self
.
dsp_ops
:
raise
Exception
(
'Could not map nn op for: '
,
tf_op
)
return
self
.
dsp_ops
[
tf_op
]
mace/python/tools/encrypt_opencl_codegen.py
浏览文件 @
6da30d22
...
@@ -4,77 +4,81 @@ import sys
...
@@ -4,77 +4,81 @@ import sys
import
jinja2
import
jinja2
# python encrypt_opencl_codegen.py --cl_kernel_dir=./mace/kernels/opencl/cl/
\
# python encrypt_opencl_codegen.py --cl_kernel_dir=./mace/kernels/opencl/cl/ \
# --output_path=./mace/codegen/opencl_encrypt/opencl_encrypted_program.cc
# --output_path=./mace/codegen/opencl_encrypt/opencl_encrypted_program.cc
FLAGS
=
None
FLAGS
=
None
encrypt_lookup_table
=
"Xiaomi-AI-Platform-Mace"
encrypt_lookup_table
=
"Xiaomi-AI-Platform-Mace"
def
encrypt_code
(
code_str
):
def
encrypt_code
(
code_str
):
encrypted_arr
=
[]
encrypted_arr
=
[]
for
i
in
range
(
len
(
code_str
)):
for
i
in
range
(
len
(
code_str
)):
encrypted_char
=
hex
(
ord
(
code_str
[
i
])
^
ord
(
encrypt_lookup_table
[
i
%
len
(
encrypt_lookup_table
)]))
encrypted_char
=
hex
(
encrypted_arr
.
append
(
encrypted_char
)
ord
(
code_str
[
i
])
^
ord
(
return
encrypted_arr
encrypt_lookup_table
[
i
%
len
(
encrypt_lookup_table
)]))
encrypted_arr
.
append
(
encrypted_char
)
return
encrypted_arr
def
main
(
unused_args
):
def
main
(
unused_args
):
if
not
os
.
path
.
exists
(
FLAGS
.
cl_kernel_dir
):
if
not
os
.
path
.
exists
(
FLAGS
.
cl_kernel_dir
):
print
(
"Input cl_kernel_dir "
+
FLAGS
.
cl_kernel_dir
+
" doesn't exist!"
)
print
(
"Input cl_kernel_dir "
+
FLAGS
.
cl_kernel_dir
+
" doesn't exist!"
)
header_code
=
""
header_code
=
""
for
file_name
in
os
.
listdir
(
FLAGS
.
cl_kernel_dir
):
for
file_name
in
os
.
listdir
(
FLAGS
.
cl_kernel_dir
):
file_path
=
os
.
path
.
join
(
FLAGS
.
cl_kernel_dir
,
file_name
)
file_path
=
os
.
path
.
join
(
FLAGS
.
cl_kernel_dir
,
file_name
)
if
file_path
[
-
2
:]
==
".h"
:
if
file_path
[
-
2
:]
==
".h"
:
f
=
open
(
file_path
,
"r"
)
f
=
open
(
file_path
,
"r"
)
header_code
+=
f
.
read
()
header_code
+=
f
.
read
()
encrypted_code_maps
=
{}
encrypted_code_maps
=
{}
for
file_name
in
os
.
listdir
(
FLAGS
.
cl_kernel_dir
):
for
file_name
in
os
.
listdir
(
FLAGS
.
cl_kernel_dir
):
file_path
=
os
.
path
.
join
(
FLAGS
.
cl_kernel_dir
,
file_name
)
file_path
=
os
.
path
.
join
(
FLAGS
.
cl_kernel_dir
,
file_name
)
if
file_path
[
-
3
:]
==
".cl"
:
if
file_path
[
-
3
:]
==
".cl"
:
f
=
open
(
file_path
,
"r"
)
f
=
open
(
file_path
,
"r"
)
code_str
=
""
code_str
=
""
for
line
in
f
.
readlines
():
for
line
in
f
.
readlines
():
if
"#include <common.h>"
in
line
:
if
"#include <common.h>"
in
line
:
code_str
+=
header_code
code_str
+=
header_code
else
:
else
:
code_str
+=
line
code_str
+=
line
encrypted_code_arr
=
encrypt_code
(
code_str
)
encrypted_code_arr
=
encrypt_code
(
code_str
)
encrypted_code_maps
[
file_name
[:
-
3
]]
=
encrypted_code_arr
encrypted_code_maps
[
file_name
[:
-
3
]]
=
encrypted_code_arr
env
=
jinja2
.
Environment
(
loader
=
jinja2
.
FileSystemLoader
(
sys
.
path
[
0
]))
env
=
jinja2
.
Environment
(
loader
=
jinja2
.
FileSystemLoader
(
sys
.
path
[
0
]))
cpp_cl_encrypted_kernel
=
env
.
get_template
(
'str2vec_maps.cc.jinja2'
).
render
(
cpp_cl_encrypted_kernel
=
env
.
get_template
(
maps
=
encrypted_code_maps
,
'str2vec_maps.cc.jinja2'
).
render
(
data_type
=
'unsigned char'
,
maps
=
encrypted_code_maps
,
variable_name
=
'kEncryptedProgramMap'
)
data_type
=
'unsigned char'
,
variable_name
=
'kEncryptedProgramMap'
)
if
os
.
path
.
isfile
(
FLAGS
.
output_path
):
os
.
remove
(
FLAGS
.
output_path
)
if
os
.
path
.
isfile
(
FLAGS
.
output_path
):
w_file
=
open
(
FLAGS
.
output_path
,
"w"
)
os
.
remove
(
FLAGS
.
output_path
)
w_file
.
write
(
cpp_cl_encrypted_kernel
)
w_file
=
open
(
FLAGS
.
output_path
,
"w"
)
w_file
.
close
()
w_file
.
write
(
cpp_cl_encrypted_kernel
)
w_file
.
close
()
print
(
"Generate encrypted opencl source done!"
)
print
(
"Generate encrypted opencl source done!"
)
def
parse_args
():
def
parse_args
():
"""Parses command line arguments."""
"""Parses command line arguments."""
parser
=
argparse
.
ArgumentParser
()
parser
=
argparse
.
ArgumentParser
()
parser
.
add_argument
(
parser
.
add_argument
(
"--cl_kernel_dir"
,
"--cl_kernel_dir"
,
type
=
str
,
type
=
str
,
default
=
"./mace/kernels/opencl/cl/"
,
default
=
"./mace/kernels/opencl/cl/"
,
help
=
"The cl kernels directory."
)
help
=
"The cl kernels directory."
)
parser
.
add_argument
(
parser
.
add_argument
(
"--output_path"
,
"--output_path"
,
type
=
str
,
type
=
str
,
default
=
"./mace/examples/codegen/opencl/opencl_encrypted_program.cc"
,
default
=
"./mace/examples/codegen/opencl/opencl_encrypted_program.cc"
,
help
=
"The path of encrypted opencl kernels."
)
help
=
"The path of encrypted opencl kernels."
)
return
parser
.
parse_known_args
()
return
parser
.
parse_known_args
()
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
FLAGS
,
unparsed
=
parse_args
()
FLAGS
,
unparsed
=
parse_args
()
main
(
unused_args
=
[
sys
.
argv
[
0
]]
+
unparsed
)
main
(
unused_args
=
[
sys
.
argv
[
0
]]
+
unparsed
)
mace/python/tools/graph_util.py
浏览文件 @
6da30d22
...
@@ -2,18 +2,21 @@ import tensorflow as tf
...
@@ -2,18 +2,21 @@ import tensorflow as tf
from
mace.proto
import
mace_pb2
from
mace.proto
import
mace_pb2
from
collections
import
OrderedDict
from
collections
import
OrderedDict
def
sort_tf_node
(
node
,
nodes_map
,
ordered_nodes_map
):
def
sort_tf_node
(
node
,
nodes_map
,
ordered_nodes_map
):
if
node
.
name
not
in
ordered_nodes_map
:
if
node
.
name
not
in
ordered_nodes_map
:
for
input_tensor_name
in
node
.
input
:
for
input_tensor_name
in
node
.
input
:
input_node_name
=
input_tensor_name
.
split
(
':'
)[
input_node_name
=
input_tensor_name
.
split
(
':'
)[
0
]
if
':'
in
input_tensor_name
else
input_tensor_name
0
]
if
':'
in
input_tensor_name
else
input_tensor_name
if
input_node_name
not
in
nodes_map
or
input_node_name
in
ordered_nodes_map
:
if
input_node_name
not
in
nodes_map
or
\
input_node_name
in
ordered_nodes_map
:
continue
continue
input_node
=
nodes_map
[
input_node_name
]
input_node
=
nodes_map
[
input_node_name
]
sort_tf_node
(
input_node
,
nodes_map
,
ordered_nodes_map
)
sort_tf_node
(
input_node
,
nodes_map
,
ordered_nodes_map
)
ordered_nodes_map
[
node
.
name
]
=
node
ordered_nodes_map
[
node
.
name
]
=
node
def
sort_tf_graph
(
graph_def
):
def
sort_tf_graph
(
graph_def
):
nodes_map
=
{}
nodes_map
=
{}
ordered_nodes_map
=
OrderedDict
()
ordered_nodes_map
=
OrderedDict
()
...
@@ -31,13 +34,15 @@ def sort_mace_node(node, nodes_map, ordered_nodes_map):
...
@@ -31,13 +34,15 @@ def sort_mace_node(node, nodes_map, ordered_nodes_map):
for
input_tensor_name
in
node
.
input
:
for
input_tensor_name
in
node
.
input
:
input_node_name
=
input_tensor_name
.
split
(
':'
)[
input_node_name
=
input_tensor_name
.
split
(
':'
)[
0
]
if
':'
in
input_tensor_name
else
input_tensor_name
0
]
if
':'
in
input_tensor_name
else
input_tensor_name
if
input_node_name
not
in
nodes_map
or
input_node_name
in
ordered_nodes_map
:
if
input_node_name
not
in
nodes_map
or
\
input_node_name
in
ordered_nodes_map
:
continue
continue
input_node
=
nodes_map
[
input_node_name
]
input_node
=
nodes_map
[
input_node_name
]
sort_mace_node
(
input_node
,
nodes_map
,
ordered_nodes_map
)
sort_mace_node
(
input_node
,
nodes_map
,
ordered_nodes_map
)
ordered_nodes_map
[
node
.
name
]
=
node
ordered_nodes_map
[
node
.
name
]
=
node
def
sort_mace_graph
(
graph_def
,
output_name
):
def
sort_mace_graph
(
graph_def
,
output_name
):
nodes_map
=
{}
nodes_map
=
{}
ordered_nodes_map
=
OrderedDict
()
ordered_nodes_map
=
OrderedDict
()
...
...
mace/python/tools/memory_optimizer.py
浏览文件 @
6da30d22
...
@@ -2,120 +2,131 @@ import sys
...
@@ -2,120 +2,131 @@ import sys
import
operator
import
operator
from
mace.proto
import
mace_pb2
from
mace.proto
import
mace_pb2
class
MemoryOptimizer
(
object
):
class
MemoryOptimizer
(
object
):
def
__init__
(
self
,
net_def
):
def
__init__
(
self
,
net_def
):
self
.
net_def
=
net_def
self
.
net_def
=
net_def
self
.
idle_mem
=
set
()
self
.
idle_mem
=
set
()
self
.
op_mem
=
{}
# op_name->mem_id
self
.
op_mem
=
{}
# op_name->mem_id
self
.
mem_block
=
{}
# mem_id->[x, y]
self
.
mem_block
=
{}
# mem_id->[x, y]
self
.
total_mem_count
=
0
self
.
total_mem_count
=
0
self
.
ref_counter
=
{}
self
.
ref_counter
=
{}
consumers
=
{}
consumers
=
{}
for
op
in
net_def
.
op
:
for
op
in
net_def
.
op
:
if
self
.
is_buffer_image_op
(
op
):
if
self
.
is_buffer_image_op
(
op
):
continue
continue
for
ipt
in
op
.
input
:
for
ipt
in
op
.
input
:
if
ipt
not
in
consumers
:
if
ipt
not
in
consumers
:
consumers
[
ipt
]
=
[]
consumers
[
ipt
]
=
[]
consumers
[
ipt
].
append
(
op
)
consumers
[
ipt
].
append
(
op
)
# only ref op's output tensor
# only ref op's output tensor
for
op
in
net_def
.
op
:
for
op
in
net_def
.
op
:
if
self
.
is_buffer_image_op
(
op
):
if
self
.
is_buffer_image_op
(
op
):
continue
continue
for
output
in
op
.
output
:
for
output
in
op
.
output
:
tensor_name
=
output
tensor_name
=
output
if
tensor_name
in
consumers
:
if
tensor_name
in
consumers
:
self
.
ref_counter
[
tensor_name
]
=
len
(
consumers
[
tensor_name
])
self
.
ref_counter
[
tensor_name
]
=
len
(
consumers
[
tensor_name
])
else
:
self
.
ref_counter
[
tensor_name
]
=
0
def
is_buffer_image_op
(
self
,
op
):
return
op
.
type
==
'BufferToImage'
or
op
.
type
==
'ImageToBuffer'
def
get_mem_size
(
self
,
op_type
,
output_shape
):
mem_size
=
[
0
,
0
]
if
op_type
==
'WinogradTransform'
or
op_type
==
'MatMul'
:
mem_size
[
0
]
=
output_shape
[
2
]
*
output_shape
[
3
]
mem_size
[
1
]
=
output_shape
[
0
]
*
int
((
output_shape
[
1
]
+
3
)
/
4
)
else
:
else
:
self
.
ref_counter
[
tensor_name
]
=
0
mem_size
[
0
]
=
output_shape
[
2
]
*
int
((
output_shape
[
3
]
+
3
)
/
4
)
mem_size
[
1
]
=
output_shape
[
0
]
*
output_shape
[
1
]
def
is_buffer_image_op
(
self
,
op
):
return
mem_size
return
op
.
type
==
'BufferToImage'
or
op
.
type
==
'ImageToBuffer'
def
mem_area
(
self
,
memory_size
):
def
get_mem_size
(
self
,
op_type
,
output_shape
):
return
memory_size
[
0
]
*
memory_size
[
1
]
mem_size
=
[
0
,
0
]
if
op_type
==
'WinogradTransform'
or
op_type
==
'MatMul'
:
def
optimize
(
self
):
mem_size
[
0
]
=
output_shape
[
2
]
*
output_shape
[
3
]
for
op
in
self
.
net_def
.
op
:
mem_size
[
1
]
=
output_shape
[
0
]
*
int
((
output_shape
[
1
]
+
3
)
/
4
)
if
self
.
is_buffer_image_op
(
op
):
else
:
continue
mem_size
[
0
]
=
output_shape
[
2
]
*
int
((
output_shape
[
3
]
+
3
)
/
4
)
if
not
op
.
output_shape
:
mem_size
[
1
]
=
output_shape
[
0
]
*
output_shape
[
1
]
print
(
'WARNING: There is no output shape information to '
return
mem_size
'do memory optimization.'
)
return
def
mem_area
(
self
,
memory_size
):
if
len
(
op
.
output_shape
)
!=
len
(
op
.
output
):
return
memory_size
[
0
]
*
memory_size
[
1
]
print
(
'WARNING: the number of output shape is not equal to '
'the number of output.'
)
def
optimize
(
self
):
return
for
op
in
self
.
net_def
.
op
:
for
i
in
range
(
len
(
op
.
output
)):
if
self
.
is_buffer_image_op
(
op
):
op_mem_size
=
self
.
get_mem_size
(
op
.
type
,
continue
op
.
output_shape
[
i
].
dims
)
if
not
op
.
output_shape
:
mem_id
=
-
1
print
(
'WARNING: There is no output shape information to do memory optimization.'
)
if
len
(
self
.
idle_mem
)
>
0
:
return
best_mem_candidate_id
=
-
1
if
len
(
op
.
output_shape
)
!=
len
(
op
.
output
):
best_mem_candidate_delta_area
=
sys
.
maxint
print
(
'WARNING: the number of output shape is not equal to the number of output.'
)
best_mem_candidate_shape
=
[]
return
for
mid
in
self
.
idle_mem
:
for
i
in
range
(
len
(
op
.
output
)):
reuse_mem_size
=
self
.
mem_block
[
mid
]
op_mem_size
=
self
.
get_mem_size
(
op
.
type
,
op
.
output_shape
[
i
].
dims
)
resize_mem_size
=
[
mem_id
=
-
1
max
(
reuse_mem_size
[
0
],
op_mem_size
[
0
]),
if
len
(
self
.
idle_mem
)
>
0
:
max
(
reuse_mem_size
[
1
],
op_mem_size
[
1
])
best_mem_candidate_id
=
-
1
]
best_mem_candidate_delta_area
=
sys
.
maxint
delta_mem_area
=
self
.
mem_area
(
best_mem_candidate_shape
=
[]
resize_mem_size
)
-
self
.
mem_area
(
reuse_mem_size
)
for
mid
in
self
.
idle_mem
:
if
delta_mem_area
<
best_mem_candidate_delta_area
:
reuse_mem_size
=
self
.
mem_block
[
mid
]
best_mem_candidate_id
=
mid
resize_mem_size
=
[
max
(
reuse_mem_size
[
0
],
op_mem_size
[
0
]),
max
(
reuse_mem_size
[
1
],
op_mem_size
[
1
])]
best_mem_candidate_delta_area
=
delta_mem_area
delta_mem_area
=
self
.
mem_area
(
resize_mem_size
)
-
self
.
mem_area
(
reuse_mem_size
)
best_mem_candidate_shape
=
resize_mem_size
if
delta_mem_area
<
best_mem_candidate_delta_area
:
best_mem_candidate_id
=
mid
if
best_mem_candidate_delta_area
<=
self
.
mem_area
(
best_mem_candidate_delta_area
=
delta_mem_area
op_mem_size
):
best_mem_candidate_shape
=
resize_mem_size
# reuse
self
.
mem_block
[
if
best_mem_candidate_delta_area
<=
self
.
mem_area
(
op_mem_size
):
best_mem_candidate_id
]
=
best_mem_candidate_shape
# reuse
mem_id
=
best_mem_candidate_id
self
.
mem_block
[
best_mem_candidate_id
]
=
best_mem_candidate_shape
self
.
idle_mem
.
remove
(
mem_id
)
mem_id
=
best_mem_candidate_id
self
.
idle_mem
.
remove
(
mem_id
)
if
mem_id
==
-
1
:
mem_id
=
self
.
total_mem_count
if
mem_id
==
-
1
:
self
.
total_mem_count
+=
1
mem_id
=
self
.
total_mem_count
self
.
mem_block
[
mem_id
]
=
op_mem_size
self
.
total_mem_count
+=
1
self
.
mem_block
[
mem_id
]
=
op_mem_size
op
.
mem_id
.
extend
([
mem_id
])
self
.
op_mem
[
op
.
output
[
i
]]
=
mem_id
op
.
mem_id
.
extend
([
mem_id
])
self
.
op_mem
[
op
.
output
[
i
]]
=
mem_id
# de-ref input tensor mem
for
ipt
in
op
.
input
:
# de-ref input tensor mem
if
ipt
in
self
.
ref_counter
:
for
ipt
in
op
.
input
:
self
.
ref_counter
[
ipt
]
-=
1
if
ipt
in
self
.
ref_counter
:
if
self
.
ref_counter
[
ipt
]
==
0
:
self
.
ref_counter
[
ipt
]
-=
1
self
.
idle_mem
.
add
(
self
.
op_mem
[
ipt
])
if
self
.
ref_counter
[
ipt
]
==
0
:
elif
self
.
ref_counter
[
ipt
]
<
0
:
self
.
idle_mem
.
add
(
self
.
op_mem
[
ipt
])
raise
Exception
(
'ref count is less than 0'
)
elif
self
.
ref_counter
[
ipt
]
<
0
:
raise
Exception
(
'ref count is less than 0'
)
for
mem
in
self
.
mem_block
:
arena
=
self
.
net_def
.
mem_arena
for
mem
in
self
.
mem_block
:
block
=
arena
.
mem_block
.
add
()
arena
=
self
.
net_def
.
mem_arena
block
.
mem_id
=
mem
block
=
arena
.
mem_block
.
add
()
block
.
x
=
self
.
mem_block
[
mem
][
0
]
block
.
mem_id
=
mem
block
.
y
=
self
.
mem_block
[
mem
][
1
]
block
.
x
=
self
.
mem_block
[
mem
][
0
]
block
.
y
=
self
.
mem_block
[
mem
][
1
]
print
(
'total op: %d'
,
len
(
self
.
net_def
.
op
))
origin_mem_size
=
0
print
(
'total op: %d'
,
len
(
self
.
net_def
.
op
))
optimized_mem_size
=
0
origin_mem_size
=
0
for
op
in
self
.
net_def
.
op
:
optimized_mem_size
=
0
if
self
.
is_buffer_image_op
(
op
):
for
op
in
self
.
net_def
.
op
:
continue
if
self
.
is_buffer_image_op
(
op
):
origin_mem_size
+=
reduce
(
operator
.
mul
,
op
.
output_shape
[
0
].
dims
,
1
)
continue
for
mem
in
self
.
mem_block
:
origin_mem_size
+=
reduce
(
operator
.
mul
,
op
.
output_shape
[
0
].
dims
,
1
)
print
mem
,
self
.
mem_block
[
mem
]
for
mem
in
self
.
mem_block
:
optimized_mem_size
+=
reduce
(
operator
.
mul
,
self
.
mem_block
[
mem
],
4
)
print
mem
,
self
.
mem_block
[
mem
]
optimized_mem_size
+=
reduce
(
operator
.
mul
,
self
.
mem_block
[
mem
],
4
)
print
(
'origin mem: %d, optimized mem: %d'
,
origin_mem_size
,
optimized_mem_size
)
print
(
'origin mem: %d, optimized mem: %d'
,
origin_mem_size
,
optimized_mem_size
)
def
optimize_memory
(
net_def
):
def
optimize_memory
(
net_def
):
mem_optimizer
=
MemoryOptimizer
(
net_def
)
mem_optimizer
=
MemoryOptimizer
(
net_def
)
mem_optimizer
.
optimize
()
mem_optimizer
.
optimize
()
mace/python/tools/opencl_codegen.py
浏览文件 @
6da30d22
...
@@ -14,86 +14,89 @@ FLAGS = None
...
@@ -14,86 +14,89 @@ FLAGS = None
def
generate_cpp_source
():
def
generate_cpp_source
():
maps
=
{}
maps
=
{}
platform_info
=
''
platform_info
=
''
binary_dirs
=
FLAGS
.
cl_binary_dirs
.
strip
().
split
(
","
)
binary_dirs
=
FLAGS
.
cl_binary_dirs
.
strip
().
split
(
","
)
for
binary_dir
in
binary_dirs
:
for
binary_dir
in
binary_dirs
:
binary_path
=
os
.
path
.
join
(
binary_dir
,
FLAGS
.
built_kernel_file_name
)
binary_path
=
os
.
path
.
join
(
binary_dir
,
FLAGS
.
built_kernel_file_name
)
if
not
os
.
path
.
exists
(
binary_path
):
if
not
os
.
path
.
exists
(
binary_path
):
continue
continue
print
'generate opencl code from'
,
binary_path
print
'generate opencl code from'
,
binary_path
with
open
(
binary_path
,
"rb"
)
as
f
:
with
open
(
binary_path
,
"rb"
)
as
f
:
binary_array
=
np
.
fromfile
(
f
,
dtype
=
np
.
uint8
)
binary_array
=
np
.
fromfile
(
f
,
dtype
=
np
.
uint8
)
idx
=
0
idx
=
0
size
,
=
struct
.
unpack
(
"Q"
,
binary_array
[
idx
:
idx
+
8
])
size
,
=
struct
.
unpack
(
"Q"
,
binary_array
[
idx
:
idx
+
8
])
idx
+=
8
idx
+=
8
for
_
in
xrange
(
size
):
for
_
in
xrange
(
size
):
key_size
,
=
struct
.
unpack
(
"i"
,
binary_array
[
idx
:
idx
+
4
])
key_size
,
=
struct
.
unpack
(
"i"
,
binary_array
[
idx
:
idx
+
4
])
idx
+=
4
idx
+=
4
key
,
=
struct
.
unpack
(
str
(
key_size
)
+
"s"
,
binary_array
[
idx
:
idx
+
key_size
])
key
,
=
struct
.
unpack
(
idx
+=
key_size
str
(
key_size
)
+
"s"
,
binary_array
[
idx
:
idx
+
key_size
])
value_size
,
=
struct
.
unpack
(
"i"
,
binary_array
[
idx
:
idx
+
4
])
idx
+=
key_size
idx
+=
4
value_size
,
=
struct
.
unpack
(
"i"
,
binary_array
[
idx
:
idx
+
4
])
maps
[
key
]
=
[]
idx
+=
4
value
=
struct
.
unpack
(
str
(
value_size
)
+
"B"
,
maps
[
key
]
=
[]
binary_array
[
idx
:
idx
+
value_size
])
value
=
struct
.
unpack
(
idx
+=
value_size
str
(
value_size
)
+
"B"
,
binary_array
[
idx
:
idx
+
value_size
])
for
ele
in
value
:
idx
+=
value_size
maps
[
key
].
append
(
hex
(
ele
))
for
ele
in
value
:
maps
[
key
].
append
(
hex
(
ele
))
cl_platform_info_path
=
os
.
path
.
join
(
binary_dir
,
FLAGS
.
platform_info_file_name
)
with
open
(
cl_platform_info_path
,
'r'
)
as
f
:
cl_platform_info_path
=
os
.
path
.
join
(
binary_dir
,
curr_platform_info
=
f
.
read
()
FLAGS
.
platform_info_file_name
)
if
platform_info
!=
""
:
with
open
(
cl_platform_info_path
,
'r'
)
as
f
:
assert
(
curr_platform_info
==
platform_info
)
curr_platform_info
=
f
.
read
()
platform_info
=
curr_platform_info
if
platform_info
!=
""
:
assert
(
curr_platform_info
==
platform_info
)
env
=
jinja2
.
Environment
(
loader
=
jinja2
.
FileSystemLoader
(
sys
.
path
[
0
]))
platform_info
=
curr_platform_info
return
env
.
get_template
(
'opencl_compiled_kernel.cc.jinja2'
).
render
(
maps
=
maps
,
env
=
jinja2
.
Environment
(
loader
=
jinja2
.
FileSystemLoader
(
sys
.
path
[
0
]))
data_type
=
'unsigned char'
,
return
env
.
get_template
(
'opencl_compiled_kernel.cc.jinja2'
).
render
(
variable_name
=
'kCompiledProgramMap'
,
maps
=
maps
,
platform_info
=
platform_info
,
data_type
=
'unsigned char'
,
)
variable_name
=
'kCompiledProgramMap'
,
platform_info
=
platform_info
,
)
def
main
(
unused_args
):
def
main
(
unused_args
):
cpp_cl_binary_source
=
generate_cpp_source
()
cpp_cl_binary_source
=
generate_cpp_source
()
if
os
.
path
.
isfile
(
FLAGS
.
output_path
):
if
os
.
path
.
isfile
(
FLAGS
.
output_path
):
os
.
remove
(
FLAGS
.
output_path
)
os
.
remove
(
FLAGS
.
output_path
)
w_file
=
open
(
FLAGS
.
output_path
,
"w"
)
w_file
=
open
(
FLAGS
.
output_path
,
"w"
)
w_file
.
write
(
cpp_cl_binary_source
)
w_file
.
write
(
cpp_cl_binary_source
)
w_file
.
close
()
w_file
.
close
()
def
parse_args
():
def
parse_args
():
"""Parses command line arguments."""
"""Parses command line arguments."""
parser
=
argparse
.
ArgumentParser
()
parser
=
argparse
.
ArgumentParser
()
parser
.
add_argument
(
parser
.
add_argument
(
"--cl_binary_dirs"
,
"--cl_binary_dirs"
,
type
=
str
,
type
=
str
,
default
=
""
,
default
=
""
,
help
=
"The cl binaries directories."
)
help
=
"The cl binaries directories."
)
parser
.
add_argument
(
parser
.
add_argument
(
"--built_kernel_file_name"
,
"--built_kernel_file_name"
,
type
=
str
,
type
=
str
,
default
=
""
,
default
=
""
,
help
=
"The cl binaries directories."
)
help
=
"The cl binaries directories."
)
parser
.
add_argument
(
parser
.
add_argument
(
"--platform_info_file_name"
,
"--platform_info_file_name"
,
type
=
str
,
type
=
str
,
default
=
""
,
default
=
""
,
help
=
"The cl binaries directories."
)
help
=
"The cl binaries directories."
)
parser
.
add_argument
(
parser
.
add_argument
(
"--output_path"
,
"--output_path"
,
type
=
str
,
type
=
str
,
default
=
"./mace/examples/codegen/opencl/opencl_compiled_program.cc"
,
default
=
"./mace/examples/codegen/opencl/opencl_compiled_program.cc"
,
help
=
"The path of generated C++ header file which contains
cl binaries."
)
help
=
"The path of generated C++ header file for
cl binaries."
)
return
parser
.
parse_known_args
()
return
parser
.
parse_known_args
()
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
FLAGS
,
unparsed
=
parse_args
()
FLAGS
,
unparsed
=
parse_args
()
main
(
unused_args
=
[
sys
.
argv
[
0
]]
+
unparsed
)
main
(
unused_args
=
[
sys
.
argv
[
0
]]
+
unparsed
)
mace/python/tools/source_converter_lib.py
浏览文件 @
6da30d22
...
@@ -6,182 +6,196 @@ import hashlib
...
@@ -6,182 +6,196 @@ import hashlib
from
mace.proto
import
mace_pb2
from
mace.proto
import
mace_pb2
from
jinja2
import
Environment
,
FileSystemLoader
from
jinja2
import
Environment
,
FileSystemLoader
GENERATED_NAME
=
set
()
GENERATED_NAME
=
set
()
def
generate_obfuscated_name
(
namespace
,
name
):
def
generate_obfuscated_name
(
namespace
,
name
):
md5
=
hashlib
.
md5
()
md5
=
hashlib
.
md5
()
md5
.
update
(
namespace
)
md5
.
update
(
namespace
)
md5
.
update
(
name
)
md5
.
update
(
name
)
md5_digest
=
md5
.
hexdigest
()
md5_digest
=
md5
.
hexdigest
()
name
=
md5_digest
[:
8
]
name
=
md5_digest
[:
8
]
while
name
in
GENERATED_NAME
:
while
name
in
GENERATED_NAME
:
name
=
md5_digest
name
=
md5_digest
assert
name
not
in
GENERATED_NAME
assert
name
not
in
GENERATED_NAME
GENERATED_NAME
.
add
(
name
)
GENERATED_NAME
.
add
(
name
)
return
name
return
name
def
generate_tensor_map
(
tensors
):
def
generate_tensor_map
(
tensors
):
tensor_map
=
{}
tensor_map
=
{}
for
t
in
tensors
:
for
t
in
tensors
:
if
not
tensor_map
.
has_key
(
t
.
name
):
if
t
.
name
not
in
tensor_map
:
tensor_map
[
t
.
name
]
=
generate_obfuscated_name
(
"tensor"
,
t
.
name
)
tensor_map
[
t
.
name
]
=
generate_obfuscated_name
(
"tensor"
,
t
.
name
)
return
tensor_map
return
tensor_map
def
generate_in_out_map
(
ops
,
tensor_map
):
def
generate_in_out_map
(
ops
,
tensor_map
):
in_out_map
=
{}
in_out_map
=
{}
for
op
in
ops
:
for
op
in
ops
:
op
.
name
=
generate_obfuscated_name
(
"op"
,
op
.
name
)
op
.
name
=
generate_obfuscated_name
(
"op"
,
op
.
name
)
for
input_name
in
op
.
input
:
for
input_name
in
op
.
input
:
if
not
in_out_map
.
has_key
(
input_name
):
if
input_name
not
in
in_out_map
:
if
tensor_map
.
has_key
(
input_name
):
if
input_name
in
tensor_map
:
in_out_map
[
input_name
]
=
tensor_map
[
input_name
]
in_out_map
[
input_name
]
=
tensor_map
[
input_name
]
else
:
else
:
in_out_map
[
input_name
]
=
generate_obfuscated_name
(
"in"
,
input_name
)
in_out_map
[
input_name
]
=
generate_obfuscated_name
(
for
output_name
in
op
.
output
:
"in"
,
input_name
)
if
not
in_out_map
.
has_key
(
output_name
):
for
output_name
in
op
.
output
:
if
tensor_map
.
has_key
(
output_name
):
if
output_name
not
in
in_out_map
:
in_out_map
[
output_name
]
=
tensor_map
[
output_name
]
if
output_name
in
tensor_map
:
else
:
in_out_map
[
output_name
]
=
tensor_map
[
output_name
]
in_out_map
[
output_name
]
=
generate_obfuscated_name
(
"out"
,
output_name
)
else
:
return
in_out_map
in_out_map
[
output_name
]
=
generate_obfuscated_name
(
"out"
,
output_name
)
return
in_out_map
def
obfuscate_name
(
net_def
):
def
obfuscate_name
(
net_def
):
input_node
=
"mace_input_node"
input_node
=
"mace_input_node"
output_node
=
"mace_output_node"
output_node
=
"mace_output_node"
tensor_map
=
generate_tensor_map
(
net_def
.
tensors
)
tensor_map
=
generate_tensor_map
(
net_def
.
tensors
)
in_out_map
=
generate_in_out_map
(
net_def
.
op
,
tensor_map
)
in_out_map
=
generate_in_out_map
(
net_def
.
op
,
tensor_map
)
for
t
in
net_def
.
tensors
:
for
t
in
net_def
.
tensors
:
if
input_node
not
in
t
.
name
and
output_node
not
in
t
.
name
:
if
input_node
not
in
t
.
name
and
output_node
not
in
t
.
name
:
t
.
name
=
tensor_map
[
t
.
name
]
t
.
name
=
tensor_map
[
t
.
name
]
for
op
in
net_def
.
op
:
for
op
in
net_def
.
op
:
for
i
in
range
(
len
(
op
.
input
)):
for
i
in
range
(
len
(
op
.
input
)):
if
input_node
not
in
op
.
input
[
i
]:
if
input_node
not
in
op
.
input
[
i
]:
op
.
input
[
i
]
=
in_out_map
[
op
.
input
[
i
]]
op
.
input
[
i
]
=
in_out_map
[
op
.
input
[
i
]]
for
i
in
range
(
len
(
op
.
output
)):
for
i
in
range
(
len
(
op
.
output
)):
if
output_node
not
in
op
.
output
[
i
]:
if
output_node
not
in
op
.
output
[
i
]:
op
.
output
[
i
]
=
in_out_map
[
op
.
output
[
i
]]
op
.
output
[
i
]
=
in_out_map
[
op
.
output
[
i
]]
def
rename_tensor
(
net_def
):
def
rename_tensor
(
net_def
):
tensor_map
=
{}
tensor_map
=
{}
for
t
in
net_def
.
tensors
:
for
t
in
net_def
.
tensors
:
if
not
tensor_map
.
has_key
(
t
.
name
):
if
t
.
name
not
in
tensor_map
:
tensor_map
[
t
.
name
]
=
"_"
+
t
.
name
[:
-
2
].
replace
(
"/"
,
"_"
)
tensor_map
[
t
.
name
]
=
"_"
+
t
.
name
[:
-
2
].
replace
(
"/"
,
"_"
)
t
.
name
=
tensor_map
[
t
.
name
]
t
.
name
=
tensor_map
[
t
.
name
]
for
op
in
net_def
.
op
:
for
op
in
net_def
.
op
:
for
i
in
range
(
len
(
op
.
input
)):
for
i
in
range
(
len
(
op
.
input
)):
if
tensor_map
.
has_key
(
op
.
input
[
i
]):
if
op
.
input
[
i
]
in
tensor_map
:
op
.
input
[
i
]
=
tensor_map
[
op
.
input
[
i
]]
op
.
input
[
i
]
=
tensor_map
[
op
.
input
[
i
]]
for
i
in
range
(
len
(
op
.
output
)):
for
i
in
range
(
len
(
op
.
output
)):
if
tensor_map
.
has_key
(
op
.
output
[
i
]):
if
op
.
output
[
i
]
in
tensor_map
:
op
.
output
[
i
]
=
tensor_map
[
op
.
output
[
i
]]
op
.
output
[
i
]
=
tensor_map
[
op
.
output
[
i
]]
class
TensorInfo
:
class
TensorInfo
:
def
__init__
(
self
,
id
,
t
,
runtime
):
def
__init__
(
self
,
id
,
t
,
runtime
):
self
.
id
=
id
self
.
id
=
id
self
.
data_type
=
mace_pb2
.
DataType
.
Name
(
t
.
data_type
)
self
.
data_type
=
mace_pb2
.
DataType
.
Name
(
t
.
data_type
)
if
t
.
data_type
==
mace_pb2
.
DT_FLOAT
:
if
t
.
data_type
==
mace_pb2
.
DT_FLOAT
:
if
runtime
==
'gpu'
:
if
runtime
==
'gpu'
:
self
.
data_type
=
mace_pb2
.
DT_HALF
self
.
data_type
=
mace_pb2
.
DT_HALF
self
.
data
=
bytearray
(
np
.
array
(
t
.
float_data
).
astype
(
np
.
float16
).
tobytes
())
self
.
data
=
bytearray
(
else
:
np
.
array
(
t
.
float_data
).
astype
(
np
.
float16
).
tobytes
())
self
.
data_type
=
mace_pb2
.
DT_FLOAT
else
:
self
.
data
=
bytearray
(
np
.
array
(
t
.
float_data
).
astype
(
np
.
float32
).
tobytes
())
self
.
data_type
=
mace_pb2
.
DT_FLOAT
elif
t
.
data_type
==
mace_pb2
.
DT_INT32
:
self
.
data
=
bytearray
(
self
.
data
=
bytearray
(
np
.
array
(
t
.
int32_data
).
astype
(
np
.
int32
).
tobytes
())
np
.
array
(
t
.
float_data
).
astype
(
np
.
float32
).
tobytes
())
elif
t
.
data_type
==
mace_pb2
.
DT_UINT8
:
elif
t
.
data_type
==
mace_pb2
.
DT_INT32
:
self
.
data
=
bytearray
(
np
.
array
(
t
.
int32_data
).
astype
(
np
.
uint8
).
tolist
())
self
.
data
=
bytearray
(
np
.
array
(
t
.
int32_data
).
astype
(
np
.
int32
).
tobytes
())
elif
t
.
data_type
==
mace_pb2
.
DT_UINT8
:
self
.
data
=
bytearray
(
np
.
array
(
t
.
int32_data
).
astype
(
np
.
uint8
).
tolist
())
def
stringfy
(
value
):
def
stringfy
(
value
):
return
', '
.
join
(
'"{0}"'
.
format
(
w
)
for
w
in
value
)
return
', '
.
join
(
'"{0}"'
.
format
(
w
)
for
w
in
value
)
def
convert_to_source
(
net_def
,
mode_pb_checksum
,
template_dir
,
obfuscate
,
model_tag
,
output
,
runtime
,
embed_model_data
):
if
obfuscate
:
def
convert_to_source
(
net_def
,
mode_pb_checksum
,
template_dir
,
obfuscate
,
obfuscate_name
(
net_def
)
model_tag
,
output
,
runtime
,
embed_model_data
):
else
:
if
obfuscate
:
rename_tensor
(
net_def
)
obfuscate_name
(
net_def
)
else
:
# Capture our current directory
rename_tensor
(
net_def
)
print
template_dir
# Capture our current directory
# Create the jinja2 environment.
print
template_dir
j2_env
=
Environment
(
loader
=
FileSystemLoader
(
template_dir
),
trim_blocks
=
True
)
j2_env
.
filters
[
'stringfy'
]
=
stringfy
# Create the jinja2 environment.
output_dir
=
os
.
path
.
dirname
(
output
)
+
'/'
j2_env
=
Environment
(
# generate tensor source files
loader
=
FileSystemLoader
(
template_dir
),
trim_blocks
=
True
)
template_name
=
'tensor_source.jinja2'
j2_env
.
filters
[
'stringfy'
]
=
stringfy
model_data
=
[]
output_dir
=
os
.
path
.
dirname
(
output
)
+
'/'
offset
=
0
# generate tensor source files
counter
=
0
template_name
=
'tensor_source.jinja2'
for
t
in
net_def
.
tensors
:
model_data
=
[]
tensor_info
=
TensorInfo
(
counter
,
t
,
runtime
)
offset
=
0
# align
counter
=
0
if
tensor_info
.
data_type
!=
'DT_UINT8'
and
offset
%
4
!=
0
:
for
t
in
net_def
.
tensors
:
padding
=
4
-
offset
%
4
tensor_info
=
TensorInfo
(
counter
,
t
,
runtime
)
model_data
.
extend
(
bytearray
([
0
]
*
padding
))
# align
offset
+=
padding
if
tensor_info
.
data_type
!=
'DT_UINT8'
and
offset
%
4
!=
0
:
padding
=
4
-
offset
%
4
model_data
.
extend
(
bytearray
([
0
]
*
padding
))
offset
+=
padding
source
=
j2_env
.
get_template
(
template_name
).
render
(
tensor_info
=
tensor_info
,
tensor
=
t
,
tag
=
model_tag
,
runtime
=
runtime
,
offset
=
offset
,
)
model_data
.
extend
(
tensor_info
.
data
)
offset
+=
len
(
tensor_info
.
data
)
with
open
(
output_dir
+
'tensor'
+
str
(
counter
)
+
'.cc'
,
"wb"
)
as
f
:
f
.
write
(
source
)
counter
+=
1
# generate tensor data
template_name
=
'tensor_data.jinja2'
source
=
j2_env
.
get_template
(
template_name
).
render
(
source
=
j2_env
.
get_template
(
template_name
).
render
(
tensor_info
=
tensor_info
,
tag
=
model_tag
,
tensor
=
t
,
embed_model_data
=
embed_model_data
,
tag
=
model_tag
,
model_data_size
=
offset
,
runtime
=
runtime
,
model_data
=
model_data
)
offset
=
offset
,
with
open
(
output_dir
+
'tensor_data'
+
'.cc'
,
"wb"
)
as
f
:
)
f
.
write
(
source
)
model_data
.
extend
(
tensor_info
.
data
)
if
not
embed_model_data
:
offset
+=
len
(
tensor_info
.
data
)
f
=
open
(
output_dir
+
model_tag
+
'.data'
,
"wb"
)
with
open
(
output_dir
+
'tensor'
+
str
(
counter
)
+
'.cc'
,
"wb"
)
as
f
:
f
.
write
(
bytearray
(
model_data
))
f
.
write
(
source
)
f
.
close
()
counter
+=
1
# generate op source files
# generate tensor data
template_name
=
'operator.jinja2'
template_name
=
'tensor_data.jinja2'
counter
=
0
source
=
j2_env
.
get_template
(
template_name
).
render
(
op_size
=
len
(
net_def
.
op
)
tag
=
model_tag
,
for
start
in
range
(
0
,
op_size
,
10
):
embed_model_data
=
embed_model_data
,
source
=
j2_env
.
get_template
(
template_name
).
render
(
model_data_size
=
offset
,
start
=
start
,
model_data
=
model_data
end
=
min
(
start
+
10
,
op_size
),
)
net
=
net_def
,
with
open
(
output_dir
+
'tensor_data'
+
'.cc'
,
"wb"
)
as
f
:
tag
=
model_tag
,
f
.
write
(
source
)
runtime
=
runtime
,
if
not
embed_model_data
:
)
f
=
open
(
output_dir
+
model_tag
+
'.data'
,
"wb"
)
with
open
(
output_dir
+
'op'
+
str
(
counter
)
+
'.cc'
,
"wb"
)
as
f
:
f
.
write
(
bytearray
(
model_data
))
f
.
write
(
source
)
f
.
close
()
counter
+=
1
# generate op source files
# generate model source files
template_name
=
'operator.jinja2'
template_name
=
'model.jinja2'
counter
=
0
tensors
=
[
op_size
=
len
(
net_def
.
op
)
TensorInfo
(
i
,
net_def
.
tensors
[
i
],
runtime
)
for
start
in
range
(
0
,
op_size
,
10
):
for
i
in
range
(
len
(
net_def
.
tensors
))
]
source
=
j2_env
.
get_template
(
template_name
).
render
(
source
=
j2_env
.
get_template
(
template_name
).
render
(
start
=
start
,
tensors
=
tensors
,
end
=
min
(
start
+
10
,
op_size
),
net
=
net_def
,
net
=
net_def
,
tag
=
model_tag
,
tag
=
model_tag
,
runtime
=
runtime
,
runtime
=
runtime
,
model_pb_checksum
=
mode_pb_checksum
)
)
with
open
(
output
,
"wb"
)
as
f
:
with
open
(
output_dir
+
'op'
+
str
(
counter
)
+
'.cc'
,
"wb"
)
as
f
:
f
.
write
(
source
)
f
.
write
(
source
)
counter
+=
1
# generate model header file
template_name
=
'model_header.jinja2'
# generate model source files
source
=
j2_env
.
get_template
(
template_name
).
render
(
tag
=
model_tag
,
)
template_name
=
'model.jinja2'
with
open
(
output_dir
+
model_tag
+
'.h'
,
"wb"
)
as
f
:
tensors
=
[
TensorInfo
(
i
,
net_def
.
tensors
[
i
],
runtime
)
for
i
in
range
(
len
(
net_def
.
tensors
))]
f
.
write
(
source
)
source
=
j2_env
.
get_template
(
template_name
).
render
(
tensors
=
tensors
,
net
=
net_def
,
tag
=
model_tag
,
runtime
=
runtime
,
model_pb_checksum
=
mode_pb_checksum
)
with
open
(
output
,
"wb"
)
as
f
:
f
.
write
(
source
)
# generate model header file
template_name
=
'model_header.jinja2'
source
=
j2_env
.
get_template
(
template_name
).
render
(
tag
=
model_tag
,
)
with
open
(
output_dir
+
model_tag
+
'.h'
,
"wb"
)
as
f
:
f
.
write
(
source
)
mace/python/tools/tf_converter_lib.py
浏览文件 @
6da30d22
此差异已折叠。
点击以展开。
mace/python/tools/tf_dsp_converter_lib.py
浏览文件 @
6da30d22
此差异已折叠。
点击以展开。
mace/python/tools/tf_ops_stats.py
浏览文件 @
6da30d22
...
@@ -10,148 +10,174 @@ from tensorflow import gfile
...
@@ -10,148 +10,174 @@ from tensorflow import gfile
FLAGS
=
None
FLAGS
=
None
def
hist_inc
(
hist
,
key
):
def
hist_inc
(
hist
,
key
):
if
key
in
hist
:
if
key
in
hist
:
hist
[
key
]
+=
1
hist
[
key
]
+=
1
else
:
else
:
hist
[
key
]
=
1
hist
[
key
]
=
1
def
to_int_list
(
long_list
):
def
to_int_list
(
long_list
):
int_list
=
[]
int_list
=
[]
for
value
in
long_list
:
for
value
in
long_list
:
int_list
.
append
(
int
(
value
))
int_list
.
append
(
int
(
value
))
return
int_list
return
int_list
def
main
(
unused_args
):
def
main
(
unused_args
):
if
not
FLAGS
.
input
or
not
gfile
.
Exists
(
FLAGS
.
input
):
if
not
FLAGS
.
input
or
not
gfile
.
Exists
(
FLAGS
.
input
):
print
(
'Input graph file '
+
FLAGS
.
input
+
' does not exist!'
)
print
(
'Input graph file '
+
FLAGS
.
input
+
' does not exist!'
)
return
-
1
return
-
1
input_graph_def
=
tf
.
GraphDef
()
input_graph_def
=
tf
.
GraphDef
()
with
gfile
.
Open
(
FLAGS
.
input
,
'rb'
)
as
f
:
with
gfile
.
Open
(
FLAGS
.
input
,
'rb'
)
as
f
:
data
=
f
.
read
()
data
=
f
.
read
()
input_graph_def
.
ParseFromString
(
data
)
input_graph_def
.
ParseFromString
(
data
)
with
tf
.
Session
()
as
session
:
with
tf
.
Session
()
as
session
:
with
session
.
graph
.
as_default
()
as
graph
:
with
session
.
graph
.
as_default
()
as
graph
:
tf
.
import_graph_def
(
input_graph_def
,
name
=
''
)
tf
.
import_graph_def
(
input_graph_def
,
name
=
''
)
stats
=
{}
stats
=
{}
ops
=
graph
.
get_operations
()
ops
=
graph
.
get_operations
()
# extract kernel size for conv_2d
# extract kernel size for conv_2d
tensor_shapes
=
{}
tensor_shapes
=
{}
tensor_values
=
{}
tensor_values
=
{}
print
(
"=========================consts============================"
)
print
(
"=========================consts============================"
)
for
op
in
ops
:
for
op
in
ops
:
if
op
.
type
==
'Const'
:
if
op
.
type
==
'Const'
:
for
output
in
op
.
outputs
:
for
output
in
op
.
outputs
:
tensor_name
=
output
.
name
tensor_name
=
output
.
name
tensor
=
output
.
eval
()
tensor
=
output
.
eval
()
tensor_shape
=
list
(
tensor
.
shape
)
tensor_shape
=
list
(
tensor
.
shape
)
tensor_shapes
[
tensor_name
]
=
tensor_shape
tensor_shapes
[
tensor_name
]
=
tensor_shape
print
(
"Const %s: %s, %d"
%
(
tensor_name
,
tensor_shape
,
functools
.
reduce
(
operator
.
mul
,
tensor_shape
,
1
)))
print
(
"Const %s: %s, %d"
%
if
len
(
tensor_shape
)
==
1
and
tensor_shape
[
0
]
<
10
:
(
tensor_name
,
tensor_shape
,
tensor_values
[
tensor_name
]
=
list
(
tensor
)
functools
.
reduce
(
operator
.
mul
,
tensor_shape
,
1
)))
if
len
(
tensor_shape
)
==
1
and
tensor_shape
[
0
]
<
10
:
print
(
"=========================ops============================"
)
tensor_values
[
tensor_name
]
=
list
(
tensor
)
for
op
in
ops
:
if
op
.
type
in
[
'Conv2D'
]:
print
(
"=========================ops============================"
)
padding
=
op
.
get_attr
(
'padding'
)
for
op
in
ops
:
strides
=
to_int_list
(
op
.
get_attr
(
'strides'
))
if
op
.
type
in
[
'Conv2D'
]:
data_format
=
op
.
get_attr
(
'data_format'
)
padding
=
op
.
get_attr
(
'padding'
)
ksize
=
'Unknown'
strides
=
to_int_list
(
op
.
get_attr
(
'strides'
))
for
input
in
op
.
inputs
:
data_format
=
op
.
get_attr
(
'data_format'
)
input_name
=
input
.
name
ksize
=
'Unknown'
if
input_name
.
endswith
(
'weights/read:0'
):
for
input
in
op
.
inputs
:
ksize
=
input
.
shape
.
as_list
()
input_name
=
input
.
name
break
if
input_name
.
endswith
(
'weights/read:0'
):
if
input_name
.
endswith
(
'weights:0'
)
and
input_name
in
tensor_shapes
:
ksize
=
input
.
shape
.
as_list
()
ksize
=
tensor_shapes
[
input_name
]
break
break
if
input_name
.
endswith
(
print
(
'%s(padding=%s, strides=%s, ksize=%s, format=%s) %s => %s'
%
(
op
.
type
,
padding
,
strides
,
ksize
,
data_format
,
op
.
inputs
[
0
].
shape
,
op
.
outputs
[
0
].
shape
))
'weights:0'
)
and
input_name
in
tensor_shapes
:
key
=
'%s(padding=%s, strides=%s, ksize=%s, format=%s)'
%
(
op
.
type
,
padding
,
strides
,
ksize
,
data_format
)
ksize
=
tensor_shapes
[
input_name
]
hist_inc
(
stats
,
key
)
break
elif
op
.
type
in
[
'FusedResizeAndPadConv2D'
]:
print
(
padding
=
op
.
get_attr
(
'padding'
)
'%s(padding=%s, strides=%s, ksize=%s, format=%s) %s => %s'
strides
=
to_int_list
(
op
.
get_attr
(
'strides'
))
%
(
op
.
type
,
padding
,
strides
,
ksize
,
data_format
,
resize_align_corners
=
op
.
get_attr
(
'resize_align_corners'
)
op
.
inputs
[
0
].
shape
,
op
.
outputs
[
0
].
shape
))
ksize
=
'Unknown'
key
=
'%s(padding=%s, strides=%s, ksize=%s, format=%s)'
%
(
for
input
in
op
.
inputs
:
op
.
type
,
padding
,
strides
,
ksize
,
data_format
)
input_name
=
input
.
name
hist_inc
(
stats
,
key
)
if
input_name
.
endswith
(
'weights:0'
)
and
input_name
in
tensor_shapes
:
elif
op
.
type
in
[
'FusedResizeAndPadConv2D'
]:
ksize
=
tensor_shapes
[
input_name
]
padding
=
op
.
get_attr
(
'padding'
)
break
strides
=
to_int_list
(
op
.
get_attr
(
'strides'
))
key
=
'%s(padding=%s, strides=%s, ksize=%s, resize_align_corners=%s)'
%
(
op
.
type
,
padding
,
strides
,
ksize
,
resize_align_corners
)
resize_align_corners
=
op
.
get_attr
(
'resize_align_corners'
)
hist_inc
(
stats
,
key
)
ksize
=
'Unknown'
elif
op
.
type
in
[
'ResizeBilinear'
]:
for
input
in
op
.
inputs
:
align_corners
=
op
.
get_attr
(
'align_corners'
)
input_name
=
input
.
name
size
=
'Unknown'
if
input_name
.
endswith
(
for
input
in
op
.
inputs
:
'weights:0'
)
and
input_name
in
tensor_shapes
:
input_name
=
input
.
name
ksize
=
tensor_shapes
[
input_name
]
if
input_name
.
endswith
(
'size:0'
)
and
input_name
in
tensor_values
:
break
size
=
tensor_values
[
input_name
]
key
=
'%s(padding=%s, strides=%s, ksize=%s, '
\
break
'resize_align_corners=%s)'
%
(
op
.
type
,
padding
,
strides
,
key
=
'%s(size=%s, align_corners=%s)'
%
(
op
.
type
,
size
,
align_corners
)
ksize
,
resize_align_corners
)
print
(
key
)
hist_inc
(
stats
,
key
)
hist_inc
(
stats
,
key
)
elif
op
.
type
in
[
'ResizeBilinear'
]:
elif
op
.
type
in
[
'AvgPool'
,
'MaxPool'
]:
align_corners
=
op
.
get_attr
(
'align_corners'
)
padding
=
op
.
get_attr
(
'padding'
)
size
=
'Unknown'
strides
=
to_int_list
(
op
.
get_attr
(
'strides'
))
for
input
in
op
.
inputs
:
ksize
=
to_int_list
(
op
.
get_attr
(
'ksize'
))
input_name
=
input
.
name
data_format
=
op
.
get_attr
(
'data_format'
)
if
input_name
.
endswith
(
key
=
'%s(padding=%s, strides=%s, ksize=%s)'
%
(
op
.
type
,
padding
,
strides
,
ksize
)
'size:0'
)
and
input_name
in
tensor_values
:
hist_inc
(
stats
,
key
)
size
=
tensor_values
[
input_name
]
elif
op
.
type
in
[
'SpaceToBatchND'
,
'BatchToSpaceND'
]:
break
block_shape
=
'Unknown'
key
=
'%s(size=%s, align_corners=%s)'
%
(
op
.
type
,
size
,
for
input
in
op
.
inputs
:
align_corners
)
input_name
=
input
.
name
print
(
key
)
if
input_name
.
endswith
(
'block_shape:0'
)
and
input_name
in
tensor_values
:
hist_inc
(
stats
,
key
)
block_shape
=
tensor_values
[
input_name
]
elif
op
.
type
in
[
'AvgPool'
,
'MaxPool'
]:
break
padding
=
op
.
get_attr
(
'padding'
)
paddings
=
'Unknown'
strides
=
to_int_list
(
op
.
get_attr
(
'strides'
))
for
input
in
op
.
inputs
:
ksize
=
to_int_list
(
op
.
get_attr
(
'ksize'
))
input_name
=
input
.
name
data_format
=
op
.
get_attr
(
'data_format'
)
if
input_name
.
endswith
(
'paddings:0'
)
and
input_name
in
tensor_values
:
key
=
'%s(padding=%s, strides=%s, ksize=%s)'
%
(
op
.
type
,
paddings
=
tensor_values
[
input_name
]
padding
,
break
strides
,
ksize
)
crops
=
'Unknown'
hist_inc
(
stats
,
key
)
for
input
in
op
.
inputs
:
elif
op
.
type
in
[
'SpaceToBatchND'
,
'BatchToSpaceND'
]:
input_name
=
input
.
name
block_shape
=
'Unknown'
if
input_name
.
endswith
(
'crops:0'
)
and
input_name
in
tensor_values
:
for
input
in
op
.
inputs
:
paddings
=
tensor_values
[
input_name
]
input_name
=
input
.
name
break
if
input_name
.
endswith
(
if
op
.
type
==
'SpaceToBatchND'
:
'block_shape:0'
)
and
input_name
in
tensor_values
:
key
=
'%s(block_shape=%s, paddings=%s)'
%
(
op
.
type
,
block_shape
,
paddings
)
block_shape
=
tensor_values
[
input_name
]
else
:
break
key
=
'%s(block_shape=%s, crops=%s)'
%
(
op
.
type
,
block_shape
,
crops
)
paddings
=
'Unknown'
print
(
key
)
for
input
in
op
.
inputs
:
hist_inc
(
stats
,
key
)
input_name
=
input
.
name
elif
op
.
type
==
'Pad'
:
if
input_name
.
endswith
(
paddings
=
'Unknown'
'paddings:0'
)
and
input_name
in
tensor_values
:
for
input
in
op
.
inputs
:
paddings
=
tensor_values
[
input_name
]
input_name
=
input
.
name
break
if
input_name
.
endswith
(
'paddings:0'
)
and
input_name
in
tensor_values
:
crops
=
'Unknown'
paddings
=
tensor_values
[
input_name
]
for
input
in
op
.
inputs
:
break
input_name
=
input
.
name
key
=
'%s(paddings=%s)'
%
(
op
.
type
,
paddings
)
if
input_name
.
endswith
(
hist_inc
(
stats
,
key
)
'crops:0'
)
and
input_name
in
tensor_values
:
else
:
paddings
=
tensor_values
[
input_name
]
hist_inc
(
stats
,
op
.
type
)
break
if
op
.
type
==
'SpaceToBatchND'
:
print
(
"=========================stats============================"
)
key
=
'%s(block_shape=%s, paddings=%s)'
%
(
op
.
type
,
for
key
,
value
in
sorted
(
six
.
iteritems
(
stats
)):
block_shape
,
print
(
'%s: %d'
%
(
key
,
value
))
paddings
)
else
:
key
=
'%s(block_shape=%s, crops=%s)'
%
(
op
.
type
,
block_shape
,
crops
)
print
(
key
)
hist_inc
(
stats
,
key
)
elif
op
.
type
==
'Pad'
:
paddings
=
'Unknown'
for
input
in
op
.
inputs
:
input_name
=
input
.
name
if
input_name
.
endswith
(
'paddings:0'
)
and
input_name
in
tensor_values
:
paddings
=
tensor_values
[
input_name
]
break
key
=
'%s(paddings=%s)'
%
(
op
.
type
,
paddings
)
hist_inc
(
stats
,
key
)
else
:
hist_inc
(
stats
,
op
.
type
)
print
(
"=========================stats============================"
)
for
key
,
value
in
sorted
(
six
.
iteritems
(
stats
)):
print
(
'%s: %d'
%
(
key
,
value
))
def
parse_args
():
def
parse_args
():
'''Parses command line arguments.'''
'''Parses command line arguments.'''
parser
=
argparse
.
ArgumentParser
()
parser
=
argparse
.
ArgumentParser
()
parser
.
add_argument
(
parser
.
add_argument
(
'--input'
,
'--input'
,
type
=
str
,
type
=
str
,
default
=
''
,
default
=
''
,
help
=
'TensorFlow
\'
GraphDef
\'
file to load.'
)
help
=
'TensorFlow
\'
GraphDef
\'
file to load.'
)
return
parser
.
parse_known_args
()
return
parser
.
parse_known_args
()
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
FLAGS
,
unparsed
=
parse_args
()
FLAGS
,
unparsed
=
parse_args
()
main
(
unused_args
=
[
sys
.
argv
[
0
]]
+
unparsed
)
main
(
unused_args
=
[
sys
.
argv
[
0
]]
+
unparsed
)
tools/bazel_adb_run.py
浏览文件 @
6da30d22
此差异已折叠。
点击以展开。
tools/falcon_cli.py
浏览文件 @
6da30d22
#-*- coding:utf8 -*-
import
json
import
socket
import
itertools
import
json
,
socket
,
itertools
class
FalconCli
(
object
):
class
FalconCli
(
object
):
def
__init__
(
self
,
addr
,
debug
=
True
,
buf_size
=
1000
):
def
__init__
(
self
,
addr
,
debug
=
True
,
buf_size
=
1000
):
self
.
socket_
=
socket
.
create_connection
(
addr
)
self
.
socket_
=
socket
.
create_connection
(
addr
)
self
.
stream
=
self
.
socket_
.
makefile
()
self
.
stream
=
self
.
socket_
.
makefile
()
...
@@ -16,16 +16,19 @@ class FalconCli(object):
...
@@ -16,16 +16,19 @@ class FalconCli(object):
self
.
stream
.
close
()
self
.
stream
.
close
()
@
classmethod
@
classmethod
def
connect
(
cls
,
server
=
"transfer.falcon.miliao.srv"
,
port
=
8433
,
debug
=
True
,
buf_size
=
1000
):
def
connect
(
cls
,
server
=
"transfer.falcon.miliao.srv"
,
port
=
8433
,
debug
=
True
,
buf_size
=
1000
):
try
:
try
:
return
FalconCli
((
server
,
port
),
debug
,
buf_size
)
return
FalconCli
((
server
,
port
),
debug
,
buf_size
)
except
socket
.
error
,
exc
:
except
socket
.
error
,
exc
:
print
"error: connect to %s:%s error: %s"
%
(
server
,
port
,
exc
)
print
"error: connect to %s:%s error: %s"
%
(
server
,
port
,
exc
)
def
call
(
self
,
name
,
*
params
):
def
call
(
self
,
name
,
*
params
):
request
=
dict
(
id
=
next
(
self
.
id_counter
),
request
=
dict
(
params
=
list
(
params
),
id
=
next
(
self
.
id_counter
),
params
=
list
(
params
),
method
=
name
)
method
=
name
)
payload
=
json
.
dumps
(
request
).
encode
()
payload
=
json
.
dumps
(
request
).
encode
()
if
self
.
debug
:
if
self
.
debug
:
print
"--> req:"
,
payload
print
"--> req:"
,
payload
...
@@ -49,7 +52,7 @@ class FalconCli(object):
...
@@ -49,7 +52,7 @@ class FalconCli(object):
resp
=
[]
resp
=
[]
while
True
:
while
True
:
buf
=
lines
[
s
:
s
+
self
.
buf_size
]
buf
=
lines
[
s
:
s
+
self
.
buf_size
]
s
=
s
+
self
.
buf_size
s
=
s
+
self
.
buf_size
if
len
(
buf
)
==
0
:
if
len
(
buf
)
==
0
:
break
break
...
@@ -57,4 +60,3 @@ class FalconCli(object):
...
@@ -57,4 +60,3 @@ class FalconCli(object):
resp
.
append
(
r
)
resp
.
append
(
r
)
return
resp
return
resp
tools/generate_data.py
浏览文件 @
6da30d22
此差异已折叠。
点击以展开。
tools/mace_tools.py
浏览文件 @
6da30d22
此差异已折叠。
点击以展开。
tools/sh_commands.py
浏览文件 @
6da30d22
此差异已折叠。
点击以展开。
tools/validate.py
浏览文件 @
6da30d22
此差异已折叠。
点击以展开。
tools/wino_conv.py
浏览文件 @
6da30d22
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录