Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Xiaomi
Mace
提交
b04e0e66
Mace
项目概览
Xiaomi
/
Mace
通知
107
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看板
提交
b04e0e66
编写于
12月 19, 2017
作者:
L
Liangliang He
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'binary' into 'master'
Add opencl binary program support See merge request !169
上级
792ca746
60fda80e
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
221 addition
and
48 deletion
+221
-48
mace/BUILD
mace/BUILD
+8
-0
mace/codegen/BUILD
mace/codegen/BUILD
+26
-0
mace/core/BUILD
mace/core/BUILD
+3
-2
mace/core/runtime/opencl/opencl_runtime.cc
mace/core/runtime/opencl/opencl_runtime.cc
+17
-3
mace/examples/BUILD
mace/examples/BUILD
+3
-4
mace/mace.bzl
mace/mace.bzl
+7
-1
mace/python/tools/opencl_codegen.py
mace/python/tools/opencl_codegen.py
+65
-0
mace/python/tools/opencl_compiled_program.cc.tmpl
mace/python/tools/opencl_compiled_program.cc.tmpl
+31
-0
mace/python/tools/source_converter_lib.py
mace/python/tools/source_converter_lib.py
+1
-1
tools/validate_gcn.sh
tools/validate_gcn.sh
+60
-37
未找到文件。
mace/BUILD
浏览文件 @
b04e0e66
...
...
@@ -31,3 +31,11 @@ config_setting(
},
visibility
=
[
"//visibility:public"
],
)
config_setting
(
name
=
"embed_binary_program"
,
define_values
=
{
"embed_binary_program"
:
"true"
,
},
visibility
=
[
"//visibility:public"
],
)
mace/codegen/BUILD
0 → 100644
浏览文件 @
b04e0e66
# Description:
# Generated model and runtime code.
#
package
(
default_visibility
=
[
"//visibility:public"
],
)
load
(
"//mace:mace.bzl"
,
"if_embed_binary_program"
)
cc_library
(
name
=
"generated_models_lib"
,
srcs
=
glob
([
"models/*/*.cc"
]),
copts
=
[
"-std=c++11"
,
"-D_GLIBCXX_USE_C99_MATH_TR1"
],
linkstatic
=
1
,
deps
=
[
"//mace/core"
,
"//mace/ops"
,
]
+
if_embed_binary_program
([
'//mace/codegen:generated_opencl_lib'
]),
)
cc_library
(
name
=
"generated_opencl_lib"
,
srcs
=
glob
([
"opencl/*.cc"
]),
copts
=
[
"-std=c++11"
,
"-D_GLIBCXX_USE_C99_MATH_TR1"
],
linkstatic
=
1
,
)
mace/core/BUILD
浏览文件 @
b04e0e66
...
...
@@ -7,7 +7,7 @@ package(
licenses
([
"notice"
])
# Apache 2.0
load
(
"//mace:mace.bzl"
,
"if_android"
,
"if_profiling_enabled"
)
load
(
"//mace:mace.bzl"
,
"if_android"
,
"if_profiling_enabled"
,
"if_embed_binary_program"
)
cc_library
(
name
=
"opencl_runtime"
,
...
...
@@ -19,7 +19,8 @@ cc_library(
"runtime/opencl/*.h"
,
]),
copts
=
[
"-std=c++11"
,
"-D_GLIBCXX_USE_C99_MATH_TR1"
]
+
if_profiling_enabled
([
"-DMACE_OPENCL_PROFILING"
]),
if_profiling_enabled
([
"-DMACE_OPENCL_PROFILING"
])
+
if_embed_binary_program
([
"-DMACE_EMBED_BINARY_PROGRAM"
]),
linkopts
=
[
"-ldl"
],
deps
=
[
":core"
,
...
...
mace/core/runtime/opencl/opencl_runtime.cc
浏览文件 @
b04e0e66
...
...
@@ -180,6 +180,17 @@ void OpenCLRuntime::BuildProgram(const std::string &program_file_name,
cl
::
Program
*
program
)
{
MACE_CHECK_NOTNULL
(
program
);
#ifdef MACE_EMBED_BINARY_PROGRAM
extern
const
std
::
map
<
std
::
string
,
std
::
vector
<
unsigned
char
>>
kCompiledProgramMap
;
VLOG
(
1
)
<<
"Create program with merged binary map"
;
auto
it_binary
=
kCompiledProgramMap
.
find
(
binary_file_name_prefix
);
if
(
it_binary
==
kCompiledProgramMap
.
end
())
{
LOG
(
FATAL
)
<<
"Cannot found the binary key '"
<<
binary_file_name_prefix
<<
"' in kCompiledProgramMap"
;
}
std
::
vector
<
unsigned
char
>
binary
=
it_binary
->
second
;
*
program
=
cl
::
Program
(
this
->
context
(),
{
device
()},
{
binary
});
#else
std
::
string
source_filename
=
kernel_path_
+
program_file_name
;
std
::
string
binary_filename
=
kernel_path_
+
binary_file_name_prefix
+
".bin"
;
...
...
@@ -187,10 +198,10 @@ void OpenCLRuntime::BuildProgram(const std::string &program_file_name,
bool
is_binary_filename_exist
=
std
::
ifstream
(
binary_filename
).
is_open
();
if
(
is_binary_filename_exist
)
{
VLOG
(
1
)
<<
"Create program with binary: "
<<
binary_filename
;
std
::
vector
<
unsigned
char
>
binar
ies
;
MACE_CHECK
(
ReadFile
(
binary_filename
,
true
,
&
binar
ies
));
std
::
vector
<
unsigned
char
>
binar
y
;
MACE_CHECK
(
ReadFile
(
binary_filename
,
true
,
&
binar
y
));
*
program
=
cl
::
Program
(
this
->
context
(),
{
device
()},
{
binar
ies
});
*
program
=
cl
::
Program
(
this
->
context
(),
{
device
()},
{
binar
y
});
}
else
if
(
std
::
ifstream
(
source_filename
).
is_open
())
{
VLOG
(
1
)
<<
"Create program with source: "
<<
source_filename
;
...
...
@@ -206,6 +217,7 @@ void OpenCLRuntime::BuildProgram(const std::string &program_file_name,
LOG
(
FATAL
)
<<
"Failed to open kernel file "
<<
binary_filename
<<
" or "
<<
source_filename
;
}
#endif
// Build program
std
::
string
build_options_str
=
...
...
@@ -223,6 +235,7 @@ void OpenCLRuntime::BuildProgram(const std::string &program_file_name,
LOG
(
FATAL
)
<<
"Build program failed: "
<<
ret
;
}
#ifndef MACE_EMBED_BINARY_PROGRAM
// Write binary if necessary
if
(
!
is_binary_filename_exist
)
{
size_t
device_list_size
=
1
;
...
...
@@ -250,6 +263,7 @@ void OpenCLRuntime::BuildProgram(const std::string &program_file_name,
MACE_CHECK
(
WriteFile
(
binary_filename
,
true
,
content
));
}
#endif
}
cl
::
Kernel
OpenCLRuntime
::
BuildKernel
(
...
...
mace/examples/BUILD
浏览文件 @
b04e0e66
# Examples
load
(
"//mace:mace.bzl"
,
"if_android"
)
load
(
"//mace:mace.bzl"
,
"if_android"
,
"if_embed_binary_program"
)
cc_binary
(
name
=
"helloworld"
,
...
...
@@ -30,13 +30,12 @@ cc_test(
cc_binary
(
name
=
"mace_run"
,
srcs
=
glob
([
"models/*/*.cc"
]
+
[
"mace_run.cc"
])
,
srcs
=
[
"mace_run.cc"
]
,
copts
=
[
"-std=c++11"
,
"-D_GLIBCXX_USE_C99_MATH_TR1"
],
linkopts
=
[
"-fopenmp"
],
linkstatic
=
1
,
deps
=
[
"//mace/core"
,
"//mace/ops"
,
"//mace/codegen:generated_models_lib"
,
"//mace/utils:command_line_flags"
,
],
)
mace/mace.bzl
浏览文件 @
b04e0e66
...
...
@@ -28,4 +28,10 @@ def if_profiling_enabled(a):
return
select
({
"//mace:profiling_enabled"
:
a
,
"//conditions:default"
:
[],
})
})
def
if_embed_binary_program
(
a
):
return
select
({
"//mace:embed_binary_program"
:
a
,
"//conditions:default"
:
[],
})
mace/python/tools/opencl_codegen.py
0 → 100644
浏览文件 @
b04e0e66
import
argparse
import
os
import
subprocess
import
sys
import
numpy
as
np
import
jinja2
# python mace/python/tools/opencl_codegen.py \
# --cl_binary_dir=${CL_BIN_DIR} --output_path=${CL_HEADER_PATH}
FLAGS
=
None
def
generate_cpp_source
():
maps
=
{
"binary_maps"
:
[]}
for
file_name
in
os
.
listdir
(
FLAGS
.
cl_binary_dir
):
file_path
=
os
.
path
.
join
(
FLAGS
.
cl_binary_dir
,
file_name
)
if
file_path
[
-
4
:]
==
".bin"
:
# read binary
f
=
open
(
file_path
,
"rb"
)
binary_array
=
np
.
fromfile
(
f
,
dtype
=
np
.
uint8
)
f
.
close
()
binary_dict
=
{
"name"
:
file_name
[:
-
4
],
"content"
:
[]}
for
ele
in
binary_array
:
binary_dict
[
"content"
].
append
(
hex
(
ele
))
maps
[
"binary_maps"
].
append
(
binary_dict
)
env
=
jinja2
.
Environment
(
loader
=
jinja2
.
FileSystemLoader
(
sys
.
path
[
0
]))
return
env
.
get_template
(
'opencl_compiled_program.cc.tmpl'
).
render
(
maps
)
def
main
(
unused_args
):
if
not
os
.
path
.
exists
(
FLAGS
.
cl_binary_dir
):
print
(
"Input cl_binary_dir "
+
FLAGS
.
cl_binary_dir
+
" doesn't exist!"
)
cpp_cl_binary_source
=
generate_cpp_source
()
if
os
.
path
.
isfile
(
FLAGS
.
output_path
):
os
.
remove
(
FLAGS
.
output_path
)
w_file
=
open
(
FLAGS
.
output_path
,
"w"
)
w_file
.
write
(
cpp_cl_binary_source
)
w_file
.
close
()
def
parse_args
():
"""Parses command line arguments."""
parser
=
argparse
.
ArgumentParser
()
parser
.
add_argument
(
"--cl_binary_dir"
,
type
=
str
,
default
=
"./cl_bin/"
,
help
=
"The cl binaries directory."
)
parser
.
add_argument
(
"--output_path"
,
type
=
str
,
default
=
"./mace/examples/codegen/opencl/opencl_compiled_program.cc"
,
help
=
"The path of generated C++ header file which contains cl binaries."
)
return
parser
.
parse_known_args
()
if
__name__
==
'__main__'
:
FLAGS
,
unparsed
=
parse_args
()
main
(
unused_args
=
[
sys
.
argv
[
0
]]
+
unparsed
)
mace/python/tools/opencl_compiled_program.cc.tmpl
0 → 100644
浏览文件 @
b04e0e66
//
// Copyright (c) 2017 XiaoMi All rights reserved.
//
// This is a generated file, DO NOT EDIT
#include <map>
#include <string>
#include <vector>
namespace mace {
{% for map in binary_maps %}
// {{map.name}}
{% endfor %}
extern const std::map<std::string, std::vector<unsigned char>> kCompiledProgramMap =
{
{% for map in binary_maps %}
{
"{{map.name}}",
{
{%- for ele in map.content -%}
{{ele}},
{%- endfor -%}
}
}, // {{map.name}}
{% endfor %}
};
} // namespace
mace/python/tools/source_converter_lib.py
浏览文件 @
b04e0e66
...
...
@@ -106,7 +106,7 @@ def convert_to_source(net_def, template, confuse, model_tag, output):
tag
=
model_tag
,
mode
=
0
,
)
with
gfile
.
GFile
(
output_dir
+
str
(
counter
)
+
'.cc'
,
"wb"
)
as
f
:
with
gfile
.
GFile
(
output_dir
+
'tensor'
+
str
(
counter
)
+
'.cc'
,
"wb"
)
as
f
:
f
.
write
(
source
)
counter
+=
1
...
...
tools/validate_gcn.sh
浏览文件 @
b04e0e66
...
...
@@ -21,20 +21,62 @@ PHONE_DATA_DIR="/data/local/tmp/${MACE_MODEL_NAME}"
KERNEL_DIR
=
"
${
PHONE_DATA_DIR
}
/cl/"
IMAGE_SIZE
=
$2
MODEL_TAG
=
GCN
${
IMAGE_SIZE
}
CODEGEN_DIR
=
${
MACE_SOURCE_DIR
}
/mace/codegen
MODEL_CODEGEN_DIR
=
${
CODEGEN_DIR
}
/models/gcn-
$IMAGE_SIZE
CL_CODEGEN_DIR
=
${
CODEGEN_DIR
}
/opencl
CL_BIN_DIR
=
${
CODEGEN_DIR
}
/opencl_bin
build_and_run
()
{
EMBED_OPENCL_BINARY
=
$1
if
[
"
$EMBED_OPENCL_BINARY
"
=
true
]
;
then
EMBED_OPENCL_BINARY_BUILD_FLAGS
=
"--define embed_binary_program=true"
fi
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
\
$EMBED_OPENCL_BINARY_BUILD_FLAGS
\
--copt
=
-DMACE_MODEL_FUNCTION
=
Create
${
MODEL_TAG
}
adb shell
"rm -rf
${
PHONE_DATA_DIR
}
"
adb shell
"mkdir -p
${
PHONE_DATA_DIR
}
"
if
[
"
$EMBED_OPENCL_BINARY
"
=
false
]
;
then
adb shell
"mkdir -p
${
KERNEL_DIR
}
"
adb push mace/kernels/opencl/cl/
${
KERNEL_DIR
}
fi
adb push
${
MODEL_DIR
}
/
${
INPUT_FILE_NAME
}
${
PHONE_DATA_DIR
}
adb push bazel-bin/mace/examples/mace_run
${
PHONE_DATA_DIR
}
num_threads
=
${
1
:-
4
}
adb </dev/null shell
MACE_CPP_MIN_VLOG_LEVEL
=
0
\
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,
${
IMAGE_SIZE
}
,
${
IMAGE_SIZE
}
,3"
\
--input_file
=
${
PHONE_DATA_DIR
}
/
${
INPUT_FILE_NAME
}
\
--output_file
=
${
PHONE_DATA_DIR
}
/
${
OUTPUT_FILE_NAME
}
\
--device
=
OPENCL
\
--round
=
1
}
# Step 1: Generate input data
echo
"Step 1: Generate input data"
python tools/validate.py
--generate_data
true
--random_seed
1
\
--input_file
=
${
MODEL_DIR
}
/
${
INPUT_FILE_NAME
}
\
--input_shape
=
"
${
IMAGE_SIZE
}
,
${
IMAGE_SIZE
}
,3"
# Step 2: convert tf model to mace model
echo
"Step 2: convert tf model to mace model and optimize memory"
echo
"Step 2: Convert tf model to mace model and optimize memory"
bazel build //mace/python/tools:tf_converter
rm
-rf
${
M
ACE_SOURCE_DIR
}
/mace/examples/models/gcn
mkdir
-p
${
M
ACE_SOURCE_DIR
}
/mace/examples/models/gcn
rm
-rf
${
M
ODEL_CODEGEN_DIR
}
mkdir
-p
${
M
ODEL_CODEGEN_DIR
}
bazel-bin/mace/python/tools/tf_converter
--input
=
${
TF_MODEL_FILE_PATH
}
\
--output
=
${
M
ACE_SOURCE_DIR
}
/mace/examples/models/gcn/mace_gcn
.cc
\
--output
=
${
M
ODEL_CODEGEN_DIR
}
/mace_gcn
${
IMAGE_SIZE
}
.cc
\
--input_node
=
input
\
--output_node
=
GCN/br_result_2/fcn_br
\
--data_type
=
DT_HALF
\
...
...
@@ -44,44 +86,25 @@ bazel-bin/mace/python/tools/tf_converter --input=${TF_MODEL_FILE_PATH} \
--model_tag
=
${
MODEL_TAG
}
\
--confuse
=
True
# Step 3: Run model on the phone
echo
"Step 3: Run model on the phone"
echo
Create
${
MODEL_TAG
}
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
\
--copt
=
-DMACE_MODEL_FUNCTION
=
Create
${
MODEL_TAG
}
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
}
/
${
INPUT_FILE_NAME
}
${
PHONE_DATA_DIR
}
adb push bazel-bin/mace/examples/mace_run
${
PHONE_DATA_DIR
}
build_and_run
false
num_threads
=
${
1
:-
4
}
echo
"Step 4: Generate OpenCL binary program and config code"
rm
-rf
${
CL_BIN_DIR
}
/
*
adb pull
${
KERNEL_DIR
}
${
CL_BIN_DIR
}
rm
-rf
${
CL_CODEGEN_DIR
}
mkdir
-p
${
CL_CODEGEN_DIR
}
python mace/python/tools/opencl_codegen.py
\
--cl_binary_dir
=
${
CL_BIN_DIR
}
--output_path
=
${
CL_CODEGEN_DIR
}
/opencl_compiled_program.cc
adb </dev/null shell
MACE_CPP_MIN_VLOG_LEVEL
=
0
\
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,
${
IMAGE_SIZE
}
,
${
IMAGE_SIZE
}
,3"
\
--input_file
=
${
PHONE_DATA_DIR
}
/
${
INPUT_FILE_NAME
}
\
--output_file
=
${
PHONE_DATA_DIR
}
/
${
OUTPUT_FILE_NAME
}
\
--device
=
OPENCL
\
--round
=
1
echo
"Step 5: Run model on the phone"
build_and_run
true
# Step 4: pull the mace run result.
echo
"Step 4: pull the mace run result."
echo
"Step 6: Pull the mace run result."
rm
-rf
${
MODEL_DIR
}
/
${
OUTPUT_FILE_NAME
}
adb </dev/null pull
${
PHONE_DATA_DIR
}
/
${
OUTPUT_FILE_NAME
}
${
MODEL_DIR
}
# Step 5: validate the result
echo
"Step 5: validate the result"
echo
"Step 7: 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
}
\
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录