提交 bd942fe7 编写于 作者: 叶剑武

Merge branch 'refactor-converter' into 'master'

Refactor converter

See merge request !642
......@@ -9,6 +9,7 @@ mace/codegen/opencl_bin/
mace/codegen/tuning/
mace/codegen/version/
mace/codegen/engine/
mace/codegen/lib/
build/
docs/_build/
*.a
......
......@@ -69,8 +69,6 @@ extra_tests:
platform_compatible_tests:
stage: platform_compatible_tests
script:
- mkdir -p mace/codegen/version && bash mace/tools/git/gen_version_source.sh mace/codegen/version/version.cc
- mkdir -p mace/codegen/tuning && python mace/python/tools/binary_codegen.py --output_path=mace/codegen/tuning/tuning_params.cc
- bazel build mace/core:core
ndk_versions_compatible_tests:
......@@ -101,5 +99,8 @@ python_tools_tests:
- rm -rf mace-models
- GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" git clone git@github.com:XiaoMi/mace-models.git
- CONF_FILE=mace-models/mobilenet-v2/mobilenet-v2.yml
- sh -c "python tools/converter.py build --config=${CONF_FILE} --disable_tuning && python tools/converter.py run --config=${CONF_FILE} --round=1 --validate && python tools/converter.py run --config=${CONF_FILE} --example --round=1 --validate" || exit 1
- >
python tools/converter.py convert --config=${CONF_FILE} --model_graph_format=file --model_data_format=file || exit 1;
python tools/converter.py run --config=${CONF_FILE} --round=1 --validate --model_graph_format=file --model_data_format=file || exit 1;
python tools/converter.py run --config=${CONF_FILE} --example --round=1 --validate --model_graph_format=file --model_data_format=file || exit 1;
- rm -rf mace-models
workspace(name = "mace")
# generate version and opencl kernel code.
load("//repository/git:git_configure.bzl", "git_version_repository")
load("//repository/opencl-kernel:opencl_kernel_configure.bzl", "encrypt_opencl_kernel_repository")
git_version_repository(name="local_version_config")
encrypt_opencl_kernel_repository(name="local_opencl_kernel_encrypt")
# proto_library rules implicitly depend on @com_google_protobuf//:protoc,
# which is the proto-compiler.
# This statement defines the @com_google_protobuf repo.
......
......@@ -73,8 +73,33 @@ cc_library(
visibility = ["//visibility:public"],
)
cc_library(
genrule(
name = "libmace_static",
srcs = ["libmace.a"],
srcs = [
"//mace/codegen:generated_opencl",
"//mace/codegen:generated_version",
"//mace/core",
"//mace/kernels",
"//mace/ops",
"//mace/utils",
"//mace/proto:mace_cc",
"@com_google_protobuf//:protobuf_lite",
],
outs = ["libmace.a"],
cmd = "tmp_mri_file=$$(mktemp mace-static-lib-mri.XXXXXXXXXX);" +
"mri_stream=$$(python $(location //mace/python/tools:archive_static_lib) " +
"$(locations //mace/codegen:generated_opencl) " +
"$(locations //mace/codegen:generated_version) " +
"$(locations //mace/core:core) " +
"$(locations //mace/kernels:kernels) " +
"$(locations //mace/ops:ops) " +
"$(locations //mace/utils:utils) " +
"$(locations //mace/proto:mace_cc) " +
"$(locations @com_google_protobuf//:protobuf_lite) " +
"$@ " +
"$$tmp_mri_file);" +
"$(AR) -M <$$tmp_mri_file;" +
"rm -rf $$tmp_mri_file;",
tools = ["//mace/python/tools:archive_static_lib"],
visibility = ["//visibility:public"],
)
......@@ -36,11 +36,12 @@ cc_binary(
"//external:gflags_nothreads",
"//mace/codegen:generated_models",
"//mace/codegen:generated_mace_engine_factory",
"//mace/ops:ops",
],
)
cc_binary(
name = "benchmark_model_shared",
name = "benchmark_model_dynamic",
srcs = [
"benchmark_model.cc",
],
......
......@@ -26,7 +26,9 @@
#include "mace/utils/logging.h"
#include "mace/utils/utils.h"
#include "mace/benchmark/statistics.h"
#ifdef MODEL_GRAPH_FORMAT_CODE
#include "mace/codegen/engine/mace_engine_factory.h"
#endif
namespace mace {
namespace benchmark {
......@@ -191,6 +193,9 @@ DEFINE_int32(warmup_runs, 1, "how many runs to initialize model");
DEFINE_string(opencl_binary_file,
"",
"compiled opencl binary file path");
DEFINE_string(opencl_parameter_file,
"",
"tuned OpenCL parameter file path");
DEFINE_string(model_data_file, "",
"model data file name, used when EMBED_MODEL_DATA set to 0");
DEFINE_string(model_file, "",
......@@ -267,6 +272,8 @@ int Main(int argc, char **argv) {
std::vector<std::string> opencl_binary_paths = {FLAGS_opencl_binary_file};
mace::SetOpenCLBinaryPaths(opencl_binary_paths);
mace::SetOpenCLParameterPath(FLAGS_opencl_parameter_file);
}
#endif // MACE_ENABLE_OPENCL
......@@ -285,27 +292,30 @@ int Main(int argc, char **argv) {
// Create Engine
const char *model_data_file_ptr =
FLAGS_model_data_file.empty() ? nullptr : FLAGS_model_data_file.c_str();
std::vector<unsigned char> model_pb_data;
if (FLAGS_model_file != "") {
std::vector<unsigned char> model_pb_data;
if (!mace::ReadBinaryFile(&model_pb_data, FLAGS_model_file)) {
LOG(FATAL) << "Failed to read file: " << FLAGS_model_file;
}
create_engine_status =
CreateMaceEngineFromProto(model_pb_data,
model_data_file_ptr,
input_names,
output_names,
device_type,
&engine);
} else {
create_engine_status =
}
#ifdef MODEL_GRAPH_FORMAT_CODE
create_engine_status =
CreateMaceEngineFromCode(FLAGS_model_name,
model_data_file_ptr,
input_names,
output_names,
device_type,
&engine);
}
#else
create_engine_status =
CreateMaceEngineFromProto(model_pb_data,
model_data_file_ptr,
input_names,
output_names,
device_type,
&engine);
#endif
if (create_engine_status != MaceStatus::MACE_SUCCESS) {
LOG(FATAL) << "Create engine error, please check the arguments";
}
......
......@@ -5,6 +5,8 @@ package(
default_visibility = ["//visibility:public"],
)
load("//mace:mace.bzl", "mace_version_genrule", "encrypt_opencl_kernel_genrule")
cc_library(
name = "generated_models",
srcs = glob(["models/*/*.cc"]),
......@@ -12,19 +14,16 @@ cc_library(
copts = ["-Werror", "-Wextra", "-Wno-missing-field-initializers"],
deps = [
"//mace/core",
"//mace/ops",
],
)
cc_library(
name = "generated_opencl",
srcs = glob(["opencl/*.cc"]),
copts = ["-Werror", "-Wextra", "-Wno-missing-field-initializers"],
)
mace_version_genrule()
encrypt_opencl_kernel_genrule()
cc_library(
name = "generated_tuning_params",
srcs = ["tuning/tuning_params.cc"],
name = "generated_opencl",
srcs = ["opencl/encrypt_opencl_kernel.cc"],
copts = ["-Werror", "-Wextra", "-Wno-missing-field-initializers"],
)
......@@ -36,9 +35,22 @@ cc_library(
cc_library(
name = "generated_mace_engine_factory",
hdrs = ["engine/mace_engine_factory.h"],
hdrs = glob(["engine/*.h"]),
copts = ["-Werror", "-Wextra", "-Wno-missing-field-initializers"],
deps = [
"//mace/public",
],
)
cc_library(
name = "generated_libmace",
srcs = glob(["lib/*.so"]),
visibility = ["//visibility:public"],
)
cc_library(
name = "generated_libmace_static",
srcs = glob(["lib/*.a"]),
linkstatic = 1,
visibility = ["//visibility:public"],
)
......@@ -61,7 +61,6 @@ cc_library(
]),
deps = [
"//mace/codegen:generated_version",
"//mace/codegen:generated_tuning_params",
"//mace/proto:mace_cc",
"//mace/utils",
] + if_android([
......
......@@ -24,4 +24,10 @@ void SetKVStorageFactory(std::shared_ptr<KVStorageFactory> storage_factory) {
kStorageFactory = storage_factory;
}
std::string kOpenCLParameterPath; // NOLINT(runtime/string)
void SetOpenCLParameterPath(const std::string &path) {
kOpenCLParameterPath = path;
}
}; // namespace mace
Examples
=======
* Build the example (e.g., with armeabi-v7a target)
```
# To enable debug mode build, use '-c dbg' flag.
# To check the underlying commands executed, use '-s' flag.
# TO check the failed command, use '--verbose_failures' flag.
bazel build -c opt mace/examples:helloworld \
--crosstool_top=//external:android/crosstool \
--host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
--cpu=arm64-v8a
```
* To run adb inside docker, the container network should use 'host'
```
docker run -it --net=host mace-dev /bin/bash
```
* Push and run the example
```
adb shell "mkdir /data/local/tmp"
adb push bazel-bin/mace/examples/helloworld /data/local/tmp/
adb shell /data/local/tmp/helloworld
```
* Check the logs
```
adb logcat | grep native
```
......@@ -23,14 +23,14 @@ cc_binary(
deps = [
"//external:gflags_nothreads",
"//mace/codegen:generated_mace_engine_factory",
"//mace:libmace_static",
"//mace/codegen:generated_libmace_static",
] + if_hexagon_enabled([
"//third_party/nnlib:libhexagon",
]),
)
cc_binary(
name = "example_shared",
name = "example_dynamic",
srcs = ["example.cc"],
copts = [
"-Werror",
......@@ -39,13 +39,20 @@ cc_binary(
] + if_android([
"-DMACE_ENABLE_OPENCL",
]),
linkopts = ["-lm", "-pie", "-fPIE"] + if_openmp_enabled(["-fopenmp"]),
linkopts = [
"-lm",
] + if_openmp_enabled([
"-fopenmp"
]) + if_android([
"-ldl",
"-pie",
"-llog",
]),
linkstatic = 0,
deps = [
"//external:gflags_nothreads",
"//mace/codegen:generated_mace_engine_factory",
"//mace/utils:utils",
"//mace:libmace",
"//mace/codegen:generated_libmace",
],
)
Examples
=======
* Convert model
```
python tools/converter.py convert --config=/path/to/your/model_deployment_file
```
* Run example
```
python tools/converter.py run --config=/path/to/your/model_deployment_file --example
```
* Validate result
```
python tools/converter.py run --config=/path/to/your/model_deployment_file --example --example
```
* Check the logs
```
adb logcat
```
......@@ -23,7 +23,7 @@
#include "mace/public/mace.h"
#include "mace/public/mace_runtime.h"
// if convert model to code.
#ifdef CODE_TYPE
#ifdef MODEL_GRAPH_FORMAT_CODE
#include "mace/codegen/engine/mace_engine_factory.h"
#endif
......@@ -108,6 +108,9 @@ DEFINE_string(output_file,
DEFINE_string(opencl_binary_file,
"",
"compiled opencl binary file path");
DEFINE_string(opencl_parameter_file,
"",
"tuned OpenCL parameter file path");
DEFINE_string(model_data_file,
"",
"model data file name, used when EMBED_MODEL_DATA set to 0");
......@@ -123,7 +126,7 @@ DEFINE_int32(gpu_priority_hint, 3, "0:DEFAULT/1:LOW/2:NORMAL/3:HIGH");
DEFINE_int32(omp_num_threads, -1, "num of openmp threads");
DEFINE_int32(cpu_affinity_policy, 1,
"0:AFFINITY_NONE/1:AFFINITY_BIG_ONLY/2:AFFINITY_LITTLE_ONLY");
#ifndef CODE_TYPE
#ifndef MODEL_GRAPH_FORMAT_CODE
namespace {
bool ReadBinaryFile(std::vector<unsigned char> *data,
const std::string &filename) {
......@@ -172,6 +175,8 @@ bool RunModel(const std::vector<std::string> &input_names,
// you should update the binary when OpenCL Driver changed.
std::vector<std::string> opencl_binary_paths = {FLAGS_opencl_binary_file};
mace::SetOpenCLBinaryPaths(opencl_binary_paths);
mace::SetOpenCLParameterPath(FLAGS_opencl_parameter_file);
}
#endif // MACE_ENABLE_OPENCL
......@@ -191,7 +196,7 @@ bool RunModel(const std::vector<std::string> &input_names,
MaceStatus create_engine_status;
// Only choose one of the two type based on the `build_type`
// in model deployment file(.yml).
#ifdef CODE_TYPE
#ifdef MODEL_GRAPH_FORMAT_CODE
create_engine_status =
CreateMaceEngineFromCode(FLAGS_model_name,
FLAGS_model_data_file,
......
......@@ -47,3 +47,21 @@ def if_openmp_enabled(a):
"//mace:openmp_enabled": a,
"//conditions:default": [],
})
def mace_version_genrule():
native.genrule(
name = "mace_version_gen",
srcs = [str(Label("@local_version_config//:gen/version"))],
outs = ["version/version.cc"],
cmd = "cat $(SRCS) > $@;"
)
def encrypt_opencl_kernel_genrule():
native.genrule(
name = "encrypt_opencl_kernel_gen",
srcs = [str(Label("@local_opencl_kernel_encrypt//:gen/encrypt_opencl_kernel"))],
outs = ["opencl/encrypt_opencl_kernel.cc"],
cmd = "cat $(SRCS) > $@;"
)
......@@ -6,6 +6,7 @@ mace {
*FileStorageFactory*;
*SetKVStorageFactory*;
*SetOpenCLBinaryPaths*;
*SetOpenCLParameterPath*;
*SetGPUHints*;
*SetOpenMPThreadPolicy*;
*SetOpenMPThreadAffinity*;
......
......@@ -90,6 +90,14 @@ void SetKVStorageFactory(std::shared_ptr<KVStorageFactory> storage_factory);
__attribute__((visibility("default")))
void SetOpenCLBinaryPaths(const std::vector<std::string> &paths);
// Just call once. (Not thread-safe)
// Set the path of Generated OpenCL parameter file
// if you use gpu for specific soc.
// The parameters is the local work group size tuned for specific SOC, which
// may be faster than the general parameters.
__attribute__((visibility("default")))
void SetOpenCLParameterPath(const std::string &path);
// Set GPU hints, currently only supports Adreno GPU.
//
// Caution: this function may hurt performance if improper parameters provided.
......
......@@ -48,3 +48,10 @@ py_binary(
"@six_archive//:six",
],
)
py_binary(
name = "archive_static_lib",
srcs = ["archive_static_lib.py"],
srcs_version = "PY2AND3",
visibility = ["//visibility:public"],
)
# Copyright 2018 Xiaomi, Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
def is_static_lib(lib_name):
return lib_name.endswith('.a') or lib_name.endswith('.lo')
def merge_libs(input_libs,
output_lib_path,
mri_script):
# make static library
mri_stream = ""
mri_stream += "create %s\n" % output_lib_path
for lib in input_libs:
if is_static_lib(lib):
mri_stream += ("addlib %s\n" % lib)
mri_stream += "save\n"
mri_stream += "end\n"
with open(mri_script, 'w') as tmp:
tmp.write(mri_stream)
if __name__ == '__main__':
merge_libs(sys.argv[1:-2], sys.argv[-2], sys.argv[-1])
......@@ -198,7 +198,7 @@ def main(unused_args):
FLAGS.output_dir, FLAGS.runtime,
FLAGS.embed_model_data,
FLAGS.winograd, FLAGS.data_type,
FLAGS.model_build_type)
FLAGS.model_graph_format)
def str2bool(v):
......@@ -277,10 +277,10 @@ def parse_args():
default=True,
help="embed model data.")
parser.add_argument(
"--model_build_type",
"--model_graph_format",
type=str,
default="code",
help="[proto|code] build models to code" +
default="file",
help="[file|code] build models to code" +
"or `Protobuf` file.")
parser.add_argument(
"--data_type",
......
......@@ -14,6 +14,7 @@
import argparse
import os
import shutil
import sys
import jinja2
......@@ -68,8 +69,21 @@ def encrypt_opencl_codegen(cl_kernel_dir, output_path):
data_type='unsigned char',
variable_name='kEncryptedProgramMap')
if os.path.isfile(output_path):
os.remove(output_path)
output_dir = os.path.dirname(output_path)
if os.path.exists(output_dir):
if os.path.isdir(output_dir):
try:
shutil.rmtree(output_dir)
except OSError:
raise RuntimeError(
"Cannot delete directory %s due to permission "
"error, inspect and remove manually" % output_dir)
else:
raise RuntimeError(
"Cannot delete non-directory %s, inspect ",
"and remove manually" % output_dir)
os.makedirs(output_dir)
with open(output_path, "w") as w_file:
w_file.write(cpp_cl_encrypted_kernel)
......
......@@ -24,7 +24,6 @@
namespace mace {
{% if model_type == 'code' %}
{% for tag in model_tags %}
namespace {{tag}} {
......@@ -59,7 +58,6 @@ MaceStatus CreateMaceEngineFromCode(
if (engine == nullptr) {
return MaceStatus::MACE_INVALID_ARGS;
}
const unsigned char * model_data = nullptr;
std::shared_ptr<NetDef> net_def;
MaceStatus status = MaceStatus::MACE_SUCCESS;
switch (model_name_map[model_name]) {
......@@ -69,7 +67,7 @@ MaceStatus CreateMaceEngineFromCode(
engine->reset(new mace::MaceEngine(device_type));
{% if embed_model_data %}
(void)model_data_file;
model_data =
const unsigned char * model_data =
mace::{{model_tags[i]}}::LoadModelData();
status = (*engine)->Init(net_def.get(), input_nodes, output_nodes, model_data);
{% else %}
......@@ -83,22 +81,5 @@ MaceStatus CreateMaceEngineFromCode(
return status;
}
{% else %}
MaceStatus CreateMaceEngineFromCode(
const std::string &model_name,
const std::string &model_data_file,
const std::vector<std::string> &input_nodes,
const std::vector<std::string> &output_nodes,
const DeviceType device_type,
std::shared_ptr<MaceEngine> *engine) {
(void)(model_name);
(void)(model_data_file);
(void)(input_nodes);
(void)(output_nodes);
(void)(device_type);
(void)(engine);
return MaceStatus::MACE_INVALID_ARGS;
}
{% endif %}
} // namespace mace
......@@ -20,7 +20,7 @@ from jinja2 import Environment, FileSystemLoader
FLAGS = None
def gen_mace_engine_factory(model_tags, template_dir, model_type,
def gen_mace_engine_factory(model_tags, template_dir,
embed_model_data, output_dir):
# Create the jinja2 environment.
j2_env = Environment(
......@@ -30,33 +30,6 @@ def gen_mace_engine_factory(model_tags, template_dir, model_type,
source = j2_env.get_template(template_name).render(
model_tags=model_tags,
embed_model_data=embed_model_data,
model_type=model_type,
)
with open(output_dir + '/mace_engine_factory.h', "wb") as f:
f.write(source)
def parse_args():
"""Parses command line arguments."""
parser = argparse.ArgumentParser()
parser.add_argument(
"--model_tag",
type=str,
default="",
help="model tag")
parser.add_argument(
"--template_dir", type=str, default="", help="template path")
parser.add_argument(
"--output_dir", type=str, default="", help="output path")
parser.add_argument(
"--model_type",
type=str,
default="",
help="[source|pb] model load type")
return parser.parse_known_args()
if __name__ == '__main__':
FLAGS, unparsed = parse_args()
gen_mace_engine_creator(FLAGS.model_tag, FLAGS.template_dir,
FLAGS.model_type, FLAGS.output_dir)
......@@ -14,7 +14,6 @@
// This is a generated file. DO NOT EDIT!
#include <vector>
#include <string>
#include "mace/core/macros.h"
......
......@@ -33,6 +33,11 @@ GPUDataType = \
Enum('GPUDataType', [(ele, ele) for ele in GPUDataTypeStrs], type=str)
class ModelFormat(object):
file = "file"
code = "code"
def generate_obfuscated_name(namespace, name):
md5 = hashlib.md5()
md5.update(namespace)
......@@ -240,15 +245,15 @@ def save_model_to_code(net_def, model_tag, runtime,
counter += 1
# generate tensor data
model_data = extract_model_data(net_def)
template_name = 'tensor_data.jinja2'
source = j2_env.get_template(template_name).render(
tag=model_tag,
embed_model_data=embed_model_data,
model_data_size=len(model_data),
model_data=model_data)
with open(output_dir + 'tensor_data' + '.cc', "wb") as f:
f.write(source)
if embed_model_data:
model_data = extract_model_data(net_def)
template_name = 'tensor_data.jinja2'
source = j2_env.get_template(template_name).render(
tag=model_tag,
model_data_size=len(model_data),
model_data=model_data)
with open(output_dir + 'tensor_data' + '.cc', "wb") as f:
f.write(source)
# generate op source files
template_name = 'operator.jinja2'
......@@ -293,7 +298,7 @@ def save_model_to_code(net_def, model_tag, runtime,
def save_model(net_def, model_checksum, weight_checksum, template_dir,
obfuscate, model_tag, output_dir, runtime, embed_model_data,
winograd_conv, data_type, model_build_type):
winograd_conv, data_type, model_graph_format):
if obfuscate:
obfuscate_name(net_def)
else:
......@@ -303,10 +308,10 @@ def save_model(net_def, model_checksum, weight_checksum, template_dir,
# update tensor type
update_tensor_infos(net_def, runtime, data_type)
if model_build_type == 'proto' or not embed_model_data:
if model_graph_format == ModelFormat.file or not embed_model_data:
save_model_data(net_def, model_tag, output_dir)
if model_build_type == 'proto':
if model_graph_format == ModelFormat.file:
save_model_to_proto(net_def, model_tag, output_dir)
else:
save_model_to_code(net_def, model_tag, runtime,
......
......@@ -14,28 +14,17 @@
// This is a generated file. DO NOT EDIT!
#include <vector>
#include <string>
#include "mace/core/macros.h"
#include "mace/public/mace.h"
#include "mace/utils/env_time.h"
#include "mace/utils/logging.h"
namespace mace {
namespace {{tag}} {
{% if embed_model_data %}
alignas(4) const unsigned char model_data[{{ model_data_size }}] = {
{% for d in model_data %}{{"0x%02X, " % d }}{%endfor%}
};
{% endif %}
{% if embed_model_data %}
const unsigned char *LoadModelData() {
return model_data;
}
{% endif %}
} // namespace {{tag}}
} // namespace mace
......
......@@ -14,9 +14,6 @@
// This is a generated file. DO NOT EDIT!
#include <vector>
#include <string>
#include "mace/proto/mace.pb.h"
#include "mace/public/mace.h"
#include "mace/utils/env_time.h"
......
......@@ -13,12 +13,23 @@
# See the License for the specific language governing permissions and
# limitations under the License.
MACE_SOURCE_DIR=$(dirname $0)
OUTPUT_FILENAME=$1
if [[ -z "${OUTPUT_FILENAME}}" ]]; then
echo "Usage: $0 <filename>"
exit 1
fi
OUTPUT_DIR=$(dirname $OUTPUT_FILENAME)
if [ -d $OUTPUT_DIR ]; then
rm -rf $OUTPUT_DIR
fi
mkdir -p $OUTPUT_DIR
pushd $MACE_SOURCE_DIR
DATE_STR=$(date +%Y%m%d)
GIT_VERSION=$(git describe --long --tags)
if [[ $? != 0 ]]; then
......@@ -49,3 +60,5 @@ __attribute__((visibility("default")))
const char *MaceVersion() { return "MACEVER-${GIT_VERSION}" + 8; }
} // namespace mace
EOF
popd
......@@ -16,11 +16,12 @@ cc_binary(
"//external:gflags_nothreads",
"//mace/codegen:generated_mace_engine_factory",
"//mace/codegen:generated_models",
"//mace/ops:ops",
],
)
cc_binary(
name = "mace_run_shared",
name = "mace_run_dynamic",
srcs = ["mace_run.cc"],
copts = [
"-Werror",
......@@ -33,7 +34,7 @@ cc_binary(
deps = [
"//external:gflags_nothreads",
"//mace/codegen:generated_mace_engine_factory",
"//mace/utils:utils",
"//mace:libmace",
"//mace/utils:utils",
],
)
......@@ -38,7 +38,9 @@
#include "mace/utils/logging.h"
#include "mace/utils/utils.h"
#ifdef MODEL_GRAPH_FORMAT_CODE
#include "mace/codegen/engine/mace_engine_factory.h"
#endif
namespace mace {
namespace tools {
......@@ -175,6 +177,9 @@ DEFINE_string(output_file,
DEFINE_string(opencl_binary_file,
"",
"compiled opencl binary file path");
DEFINE_string(opencl_parameter_file,
"",
"tuned OpenCL parameter file path");
DEFINE_string(model_data_file,
"",
"model data file name, used when EMBED_MODEL_DATA set to 0 or 2");
......@@ -212,6 +217,8 @@ bool RunModel(const std::string &model_name,
std::vector<std::string> opencl_binary_paths = {FLAGS_opencl_binary_file};
mace::SetOpenCLBinaryPaths(opencl_binary_paths);
mace::SetOpenCLParameterPath(FLAGS_opencl_parameter_file);
}
#endif // MACE_ENABLE_OPENCL
......@@ -238,23 +245,24 @@ bool RunModel(const std::string &model_name,
while (true) {
// Create Engine
int64_t t0 = NowMicros();
if (FLAGS_model_file != "") {
create_engine_status =
CreateMaceEngineFromProto(model_pb_data,
FLAGS_model_data_file,
input_names,
output_names,
device_type,
&engine);
} else {
create_engine_status =
#ifdef MODEL_GRAPH_FORMAT_CODE
create_engine_status =
CreateMaceEngineFromCode(model_name,
FLAGS_model_data_file,
input_names,
output_names,
device_type,
&engine);
}
#else
(void)(model_name);
create_engine_status =
CreateMaceEngineFromProto(model_pb_data,
FLAGS_model_data_file,
input_names,
output_names,
device_type,
&engine);
#endif
int64_t t1 = NowMicros();
if (create_engine_status != MACE_SUCCESS) {
......@@ -311,23 +319,23 @@ bool RunModel(const std::string &model_name,
LOG(ERROR) << "Warmup runtime error, retry ... errcode: "
<< warmup_status;
do {
if (FLAGS_model_file != "") {
create_engine_status =
CreateMaceEngineFromProto(model_pb_data,
FLAGS_model_data_file,
input_names,
output_names,
device_type,
&engine);
} else {
create_engine_status =
CreateMaceEngineFromCode(model_name,
FLAGS_model_data_file,
input_names,
output_names,
device_type,
&engine);
}
#ifdef MODEL_GRAPH_FORMAT_CODE
create_engine_status =
CreateMaceEngineFromCode(model_name,
FLAGS_model_data_file,
input_names,
output_names,
device_type,
&engine);
#else
create_engine_status =
CreateMaceEngineFromProto(model_pb_data,
FLAGS_model_data_file,
input_names,
output_names,
device_type,
&engine);
#endif
} while (create_engine_status != MACE_SUCCESS);
} else {
int64_t t4 = NowMicros();
......@@ -351,23 +359,23 @@ bool RunModel(const std::string &model_name,
LOG(ERROR) << "Mace run model runtime error, retry ... errcode: "
<< run_status;
do {
if (FLAGS_model_file != "") {
create_engine_status =
CreateMaceEngineFromProto(model_pb_data,
FLAGS_model_data_file,
input_names,
output_names,
device_type,
&engine);
} else {
create_engine_status =
CreateMaceEngineFromCode(model_name,
FLAGS_model_data_file,
input_names,
output_names,
device_type,
&engine);
}
#ifdef MODEL_GRAPH_FORMAT_CODE
create_engine_status =
CreateMaceEngineFromCode(model_name,
FLAGS_model_data_file,
input_names,
output_names,
device_type,
&engine);
#else
create_engine_status =
CreateMaceEngineFromProto(model_pb_data,
FLAGS_model_data_file,
input_names,
output_names,
device_type,
&engine);
#endif
} while (create_engine_status != MACE_SUCCESS);
} else {
int64_t t1 = NowMicros();
......
......@@ -31,7 +31,6 @@ cc_library(
copts = ["-Werror", "-Wextra", "-Wno-missing-field-initializers"],
deps = [
"//mace/public",
"//mace/codegen:generated_tuning_params",
],
)
......@@ -49,6 +48,7 @@ cc_test(
linkstatic = 1,
deps = [
":utils",
"//mace/core",
"@gtest//:gtest",
"@gtest//:gtest_main",
],
......
......@@ -117,13 +117,31 @@ class Tuner {
}
inline void ReadRunParamters() {
extern const std::map<std::string, std::vector<unsigned int>>
kTuningParamsData;
if (!kTuningParamsData.empty()) {
for (auto it = kTuningParamsData.begin(); it != kTuningParamsData.end();
++it) {
param_table_.emplace(it->first, std::vector<unsigned int>(
it->second.begin(), it->second.end()));
extern std::string kOpenCLParameterPath;
if (!kOpenCLParameterPath.empty()) {
std::ifstream ifs(kOpenCLParameterPath, std::ios::binary | std::ios::in);
if (ifs.is_open()) {
int64_t num_params = 0;
ifs.read(reinterpret_cast<char *>(&num_params), sizeof(num_params));
while (num_params--) {
int32_t key_size = 0;
ifs.read(reinterpret_cast<char *>(&key_size), sizeof(key_size));
std::string key(key_size, ' ');
ifs.read(&key[0], key_size);
int32_t params_size = 0;
ifs.read(reinterpret_cast<char *>(&params_size), sizeof(params_size));
int32_t params_count = params_size / sizeof(unsigned int);
std::vector<unsigned int> params(params_count);
for (int i = 0; i < params_count; ++i) {
ifs.read(reinterpret_cast<char *>(&params[i]),
sizeof(unsigned int));
}
param_table_.emplace(key, params);
}
ifs.close();
} else {
LOG(WARNING) << "Read OpenCL tuned parameters file failed.";
}
} else {
LOG(INFO) << "There is no tuned parameters.";
......
# Description:
# Borrow from tensorflow
# Exports generated files used to generate mace/codegen/version/version.cc
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
exports_files(
glob(["gen/*"]),
)
\ No newline at end of file
"""Repository rule for Git autoconfiguration, borrow from tensorflow
"""
def _git_version_conf_impl(repository_ctx):
repository_ctx.template(
"BUILD",
Label("//repository/git:BUILD.tpl"))
mace_root_path = str(repository_ctx.path(Label("@mace//:BUILD")))[:-len("BUILD")]
generated_files_path = repository_ctx.path("gen")
repository_ctx.execute([
'bash', '%s/mace/tools/git/gen_version_source.sh' % mace_root_path
, '%s/version' % generated_files_path
], quiet=False)
git_version_repository = repository_rule(
implementation = _git_version_conf_impl,
local=True,
)
# Description:
# Exports generated files used to generate mace/codegen/opencl/opencl_encrypt_program.cc
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
exports_files(
glob(["gen/*"]),
)
\ No newline at end of file
"""Repository rule for opencl encrypt kernel autoconfiguration, borrow from tensorflow
"""
def _opencl_encrypt_kernel_impl(repository_ctx):
repository_ctx.template(
"BUILD",
Label("//repository/opencl-kernel:BUILD.tpl"))
mace_root_path = str(repository_ctx.path(Label("@mace//:BUILD")))[:-len("BUILD")]
generated_files_path = repository_ctx.path("gen")
python_bin_path = repository_ctx.which("python")
repository_ctx.execute([
python_bin_path, '%s/mace/python/tools/encrypt_opencl_codegen.py' % mace_root_path,
'--cl_kernel_dir=%s/mace/kernels/opencl/cl' % mace_root_path,
'--output_path=%s/encrypt_opencl_kernel' % generated_files_path
], quiet=False)
encrypt_opencl_kernel_repository = repository_rule(
implementation = _opencl_encrypt_kernel_impl,
local=True,
)
......@@ -130,11 +130,6 @@ def main(unused_args):
host_bin_path, bin_name = sh_commands.bazel_target_to_bin(target)
target_abis = FLAGS.target_abis.split(',')
# generate sources
sh_commands.gen_encrypted_opencl_source()
sh_commands.gen_mace_version()
sh_commands.gen_tuning_param_code([])
for target_abi in target_abis:
sh_commands.bazel_build(target, abi=target_abi,
enable_neon=FLAGS.enable_neon,
......
......@@ -21,28 +21,44 @@ python mace/python/tools/binary_codegen.py --output_path=mace/codegen/tuning/tun
# copy include headers
cp mace/public/*.h $INCLUDE_DIR/
echo "build lib for armeabi-v7a"
# make directories
rm -rf $LIB_DIR/armeabi-v7a
mkdir -p $LIB_DIR/armeabi-v7a
bazel build --config android --config optimization mace:libmace --cpu=armeabi-v7a --define neon=true --define openmp=true
cp bazel-bin/mace/libmace.so $LIB_DIR/armeabi-v7a/
echo "build lib for armeabi-v7a with hexagon dsp"
rm -rf $LIB_DIR/armeabi-v7a/hexagon-dsp
mkdir -p $LIB_DIR/armeabi-v7a/hexagon-dsp
bazel build --config android --config optimization mace:libmace --cpu=armeabi-v7a --define neon=true --define openmp=true --define hexagon=true
cp bazel-bin/mace/libmace.so $LIB_DIR/armeabi-v7a/hexagon-dsp/
cp third_party/nnlib/*so $LIB_DIR/armeabi-v7a/hexagon-dsp/
echo "build lib for arm64-v8a"
rm -rf $LIB_DIR/arm64-v8a
mkdir -p $LIB_DIR/arm64-v8a
bazel build --config android --config optimization mace:libmace --cpu=arm64-v8a --define neon=true --define openmp=true
cp bazel-bin/mace/libmace.so $LIB_DIR/arm64-v8a/
echo "build lib for linux-x86-64"
rm -rf $LIB_DIR/linux-x86-64
mkdir -p $LIB_DIR/linux-x86-64
bazel build --config optimization mace:libmace --define openmp=true
# build shared libraries
echo "build shared lib for armeabi-v7a"
bazel build --config android --config optimization mace:libmace --define neon=true --define openmp=true --define hexagon=true --cpu=armeabi-v7a
cp bazel-bin/mace/libmace.so $LIB_DIR/armeabi-v7a/
cp third_party/nnlib/*so $LIB_DIR/armeabi-v7a/
echo "build shared lib for arm64-v8a"
bazel build --config android --config optimization mace:libmace --define neon=true --define openmp=true --cpu=arm64-v8a
cp bazel-bin/mace/libmace.so $LIB_DIR/arm64-v8a/
echo "build shared lib for linux-x86-64"
bazel build mace:libmace --config optimization --define openmp=true
cp bazel-bin/mace/libmace.so $LIB_DIR/linux-x86-64/
# build static libraries
echo "build static lib for armeabi-v7a"
bazel build --config android --config optimization mace:libmace_static --define neon=true --define openmp=true --define hexagon=true --cpu=armeabi-v7a
cp bazel-genfiles/mace/libmace.a $LIB_DIR/armeabi-v7a/
cp third_party/nnlib/*so $LIB_DIR/armeabi-v7a/
echo "build static lib for arm64-v8a"
bazel build --config android --config optimization mace:libmace_static --define neon=true --define openmp=true --cpu=arm64-v8a
cp bazel-genfiles/mace/libmace.a $LIB_DIR/arm64-v8a/
echo "build static lib for linux-x86-64"
bazel build mace:libmace --config optimization --define openmp=true
cp bazel-genfiles/mace/libmace.a $LIB_DIR/linux-x86-64/
echo "LIB PATH: $LIB_DIR"
echo "INCLUDE FILE PATH: $INCLUDE_DIR"
......@@ -28,6 +28,7 @@ from enum import Enum
import sh_commands
from sh_commands import BuildType
from sh_commands import ModelFormat
from common import CaffeEnvType
from common import DeviceType
......@@ -53,16 +54,33 @@ BUILD_TMP_GENERAL_OUTPUT_DIR_NAME = 'general'
OUTPUT_LIBRARY_DIR_NAME = 'lib'
OUTPUT_OPENCL_BINARY_DIR_NAME = 'opencl'
OUTPUT_OPENCL_BINARY_FILE_NAME = 'compiled_opencl_kernel'
OUTPUT_OPENCL_PARAMETER_FILE_NAME = 'tuned_opencl_parameter'
CL_COMPILED_BINARY_FILE_NAME = "mace_cl_compiled_program.bin"
CL_TUNED_PARAMETER_FILE_NAME = "mace_run.config"
CODEGEN_BASE_DIR = 'mace/codegen'
MODEL_CODEGEN_DIR = CODEGEN_BASE_DIR + '/models'
ENGINE_CODEGEN_DIR = CODEGEN_BASE_DIR + '/engine'
LIB_CODEGEN_DIR = CODEGEN_BASE_DIR + '/lib'
LIBMACE_SO_TARGET = "//mace:libmace.so"
LIBMACE_STATIC_TARGET = "//mace:libmace_static"
LIBMACE_STATIC_PATH = "bazel-genfiles/mace/libmace.a"
LIBMACE_DYNAMIC_PATH = "bazel-bin/mace/libmace.so"
MODEL_LIB_TARGET = "//mace/codegen:generated_models"
MODEL_LIB_PATH = "bazel-bin/mace/codegen/libgenerated_models.a"
MACE_RUN_STATIC_NAME = "mace_run_static"
MACE_RUN_SHARED_NAME = "mace_run_shared"
EXAMPLE_STATIC_NAME = "example_static"
EXAMPLE_SHARED_NAME = "example_shared"
MACE_RUN_DYNAMIC_NAME = "mace_run_dynamic"
MACE_RUN_STATIC_TARGET = "//mace/tools/validation:" + MACE_RUN_STATIC_NAME
MACE_RUN_SHARED_TARGET = "//mace/tools/validation:" + MACE_RUN_SHARED_NAME
MACE_RUN_DYNAMIC_TARGET = "//mace/tools/validation:" + MACE_RUN_DYNAMIC_NAME
EXAMPLE_STATIC_NAME = "example_static"
EXAMPLE_DYNAMIC_NAME = "example_dynamic"
EXAMPLE_STATIC_TARGET = "//mace/examples/cli:" + EXAMPLE_STATIC_NAME
EXAMPLE_DYNAMIC_TARGET = "//mace/examples/cli:" + EXAMPLE_DYNAMIC_NAME
BM_MODEL_STATIC_NAME = "benchmark_model_static"
BM_MODEL_DYNAMIC_NAME = "benchmark_model_dynamic"
BM_MODEL_STATIC_TARGET = "//mace/benchmark:" + BM_MODEL_STATIC_NAME
BM_MODEL_DYNAMIC_TARGET = "//mace/benchmark:" + BM_MODEL_DYNAMIC_NAME
DEVICE_INTERIOR_DIR = PHONE_DATA_DIR + "/interior"
BUILD_TMP_OPENCL_BIN_DIR = 'opencl_bin'
ALL_SOC_TAG = 'all'
ABITypeStrs = [
......@@ -78,6 +96,17 @@ class ABIType(object):
host = 'host'
ModelFormatStrs = [
"file",
"code",
]
class MACELibType(object):
static = 0
dynamic = 1
PlatformTypeStrs = [
"tensorflow",
"caffe",
......@@ -126,6 +155,7 @@ WinogradParameters = [0, 2, 4]
class DefaultValues(object):
mace_lib_type = MACELibType.static
omp_num_threads = -1,
cpu_affinity_policy = 1,
gpu_perf_hint = 3,
......@@ -136,9 +166,8 @@ class YAMLKeyword(object):
library_name = 'library_name'
target_abis = 'target_abis'
target_socs = 'target_socs'
build_type = 'build_type'
embed_model_data = 'embed_model_data'
linkshared = 'linkshared'
model_graph_format = 'model_graph_format'
model_data_format = 'model_data_format'
models = 'models'
platform = 'platform'
model_file_path = 'model_file_path'
......@@ -281,45 +310,30 @@ def format_model_config(flags):
"Build specified SOC library, "
"you must plug in a phone using the SOC")
build_type = BuildType.code
if flags.build_type:
build_type_str = flags.build_type
if flags.model_graph_format:
model_graph_format = flags.model_graph_format
else:
build_type_str = configs.get(YAMLKeyword.build_type, "")
if build_type_str == BuildType.proto:
build_type = BuildType.proto
elif build_type_str == BuildType.code:
build_type = BuildType.code
model_graph_format = configs.get(YAMLKeyword.model_graph_format, "")
mace_check(model_graph_format in ModelFormatStrs,
ModuleName.YAML_CONFIG,
'You must set model_graph_format and '
"model_graph_format must be in " + str(ModelFormatStrs))
configs[YAMLKeyword.model_graph_format] = model_graph_format
if flags.model_data_format:
model_data_format = flags.model_data_format
else:
MaceLogger.error(ModuleName.YAML_CONFIG,
"Invalid build type " + build_type_str
+ ". only support [proto|code] format, "
+ "proto for converting model to ProtoBuf file, "
+ "code for converting model to c++ code.")
configs[YAMLKeyword.build_type] = build_type
embed_model_data = configs.get(YAMLKeyword.embed_model_data, "")
if embed_model_data == "" or not isinstance(embed_model_data, int) or \
embed_model_data < 0 or embed_model_data > 1:
MaceLogger.error(ModuleName.YAML_CONFIG,
"embed_model_data must be 0 or 1. "
"0 for embed model data to code, 1 not.")
if build_type == BuildType.proto:
configs[YAMLKeyword.embed_model_data] = 0
linkshared = configs.get(YAMLKeyword.linkshared, "")
if linkshared == "":
configs[YAMLKeyword.linkshared] = 0
linkshared = 0
if not isinstance(linkshared, int) or linkshared < 0 or \
linkshared > 1:
MaceLogger.error(ModuleName.YAML_CONFIG,
"linkshared must be 0 or 1. "
"default is 0, for link mace lib statically, "
"1 for dynamic linking.")
if build_type == BuildType.code and linkshared == 1:
MaceLogger.error(ModuleName.YAML_CONFIG,
"'linkshared == 1' only support when "
"'build_type == proto'")
model_data_format = configs.get(YAMLKeyword.model_data_format, "")
configs[YAMLKeyword.model_data_format] = model_data_format
mace_check(model_data_format in ModelFormatStrs,
ModuleName.YAML_CONFIG,
'You must set model_data_format and '
"model_data_format must be in " + str(ModelFormatStrs))
mace_check(not (model_graph_format == ModelFormat.file
and model_data_format == ModelFormat.code),
ModuleName.YAML_CONFIG,
"If model_graph format is 'file',"
" the model_data_format must be 'file' too")
model_names = configs.get(YAMLKeyword.models, [])
mace_check(len(model_names) > 0, ModuleName.YAML_CONFIG,
......@@ -450,18 +464,9 @@ def format_model_config(flags):
return configs
def get_build_binary_dir(library_name, target_abi, target_soc,
serial_num):
if not target_soc or not serial_num:
binary_path_digest = md5sum(target_abi)
binary_path_digest = "%s_%s" % (target_abi, binary_path_digest)
else:
device_name = sh_commands.adb_get_device_name_by_serialno(serial_num)
binary_path_digest = md5sum(target_abi + target_soc + serial_num)
binary_path_digest = "%s_%s_%s" % \
(device_name, target_soc, binary_path_digest)
def get_build_binary_dir(library_name, target_abi):
return "%s/%s/%s/%s" % (
BUILD_OUTPUT_DIR, library_name, BUILD_TMP_DIR_NAME, binary_path_digest)
BUILD_OUTPUT_DIR, library_name, BUILD_TMP_DIR_NAME, target_abi)
def get_build_model_dirs(library_name, model_name, target_abi, target_soc,
......@@ -505,24 +510,62 @@ def get_opencl_binary_output_path(library_name, target_abi,
target_soc)
def get_shared_library_dir(library_name, abi):
return '%s/%s/%s/%s' % (BUILD_OUTPUT_DIR,
library_name,
OUTPUT_LIBRARY_DIR_NAME,
abi)
def get_opencl_parameter_output_path(library_name, target_abi,
target_soc, serial_num):
device_name = \
sh_commands.adb_get_device_name_by_serialno(serial_num)
return '%s/%s/%s/%s/%s_%s.%s.%s.bin' % \
(BUILD_OUTPUT_DIR,
library_name,
OUTPUT_OPENCL_BINARY_DIR_NAME,
target_abi,
library_name,
OUTPUT_OPENCL_PARAMETER_FILE_NAME,
device_name,
target_soc)
################################
# build
################################
def pull_opencl_binary_and_tuning_param(target_abi,
serialno,
model_output_dirs):
sh_commands.pull_binaries(target_abi, serialno, model_output_dirs,
CL_COMPILED_BINARY_FILE_NAME)
def clear_build_dirs(library_name):
# make build dir
if not os.path.exists(BUILD_OUTPUT_DIR):
os.makedirs(BUILD_OUTPUT_DIR)
# clear temp build dir
tmp_build_dir = os.path.join(BUILD_OUTPUT_DIR, library_name,
BUILD_TMP_DIR_NAME)
if os.path.exists(tmp_build_dir):
sh.rm('-rf', tmp_build_dir)
os.makedirs(tmp_build_dir)
# clear lib dir
lib_output_dir = os.path.join(
BUILD_OUTPUT_DIR, library_name, OUTPUT_LIBRARY_DIR_NAME)
if os.path.exists(lib_output_dir):
sh.rm('-rf', lib_output_dir)
def check_model_converted(library_name, model_name,
model_graph_format, model_data_format):
model_output_dir = \
'%s/%s/%s' % (BUILD_OUTPUT_DIR, library_name, MODEL_OUTPUT_DIR_NAME)
if model_graph_format == ModelFormat.file:
mace_check(os.path.exists("%s/%s.pb" % (model_output_dir, model_name)),
ModuleName.RUN,
"You shuold convert model first.")
else:
mace_check(os.path.exists("%s/%s.a" %
(model_output_dir, library_name)),
ModuleName.RUN,
"You shuold convert model first.")
if model_data_format == ModelFormat.file:
mace_check(os.path.exists("%s/%s.data" %
(model_output_dir, model_name)),
ModuleName.RUN,
"You shuold convert model first.")
def print_configuration(flags, configs):
################################
# convert
################################
def print_configuration(configs):
title = "Common Configuration"
header = ["key", "value"]
data = list()
......@@ -532,13 +575,10 @@ def print_configuration(flags, configs):
configs[YAMLKeyword.target_abis]])
data.append([YAMLKeyword.target_socs,
configs[YAMLKeyword.target_socs]])
data.append([YAMLKeyword.build_type,
configs[YAMLKeyword.build_type]])
data.append([YAMLKeyword.embed_model_data,
configs[YAMLKeyword.embed_model_data]])
data.append([YAMLKeyword.linkshared,
configs[YAMLKeyword.linkshared]])
data.append(["Tuning", flags.disable_tuning])
data.append([YAMLKeyword.model_graph_format,
configs[YAMLKeyword.model_graph_format]])
data.append([YAMLKeyword.model_data_format,
configs[YAMLKeyword.model_data_format]])
MaceLogger.summary(StringFormatter.table(header, data, title))
......@@ -596,26 +636,29 @@ def convert_model(configs):
'%s/%s/%s' % (BUILD_OUTPUT_DIR, library_name, MODEL_OUTPUT_DIR_NAME)
model_header_dir = \
'%s/%s/%s' % (BUILD_OUTPUT_DIR, library_name, MODEL_HEADER_DIR_PATH)
# clear output dir
if os.path.exists(model_output_dir):
sh.rm("-rf", model_output_dir)
os.makedirs(model_output_dir)
if os.path.exists(model_header_dir):
sh.rm("-rf", model_header_dir)
os.makedirs(model_header_dir)
# copy header files
sh.cp("-f", glob.glob("mace/public/*.h"), model_header_dir)
sh_commands.gen_mace_engine_factory_source(
configs[YAMLKeyword.models].keys(),
configs[YAMLKeyword.build_type],
configs[YAMLKeyword.embed_model_data])
if configs[YAMLKeyword.build_type] == BuildType.code:
embed_model_data = \
configs[YAMLKeyword.model_data_format] == ModelFormat.code
if os.path.exists(MODEL_CODEGEN_DIR):
sh.rm("-rf", MODEL_CODEGEN_DIR)
if os.path.exists(ENGINE_CODEGEN_DIR):
sh.rm("-rf", ENGINE_CODEGEN_DIR)
if configs[YAMLKeyword.model_graph_format] == ModelFormat.code:
os.makedirs(model_header_dir)
sh_commands.gen_mace_engine_factory_source(
configs[YAMLKeyword.models].keys(),
embed_model_data)
sh.cp("-f", glob.glob("mace/codegen/engine/*.h"),
model_header_dir)
embed_model_data = configs[YAMLKeyword.embed_model_data]
sh_commands.clear_model_codegen()
for model_name in configs[YAMLKeyword.models]:
MaceLogger.header(
StringFormatter.block("Convert %s model" % model_name))
......@@ -650,11 +693,11 @@ def convert_model(configs):
embed_model_data,
model_config[YAMLKeyword.winograd],
model_config[YAMLKeyword.obfuscate],
configs[YAMLKeyword.build_type],
configs[YAMLKeyword.model_graph_format],
data_type,
",".join(model_config.get(YAMLKeyword.graph_optimize_options, [])))
if configs[YAMLKeyword.build_type] == BuildType.proto:
if configs[YAMLKeyword.model_graph_format] == ModelFormat.file:
sh.mv("-f",
'%s/%s.pb' % (model_codegen_dir, model_name),
model_output_dir)
......@@ -673,202 +716,34 @@ def convert_model(configs):
StringFormatter.block("Model %s converted" % model_name))
def build_specific_lib(target_abi, target_soc, serial_num,
configs, tuning, enable_openmp,
address_sanitizer):
library_name = configs[YAMLKeyword.library_name]
build_type = configs[YAMLKeyword.build_type]
embed_model_data = configs[YAMLKeyword.embed_model_data]
linkshared = configs[YAMLKeyword.linkshared]
hexagon_mode = get_hexagon_mode(configs)
model_output_dirs = []
build_tmp_binary_dir = get_build_binary_dir(library_name, target_abi,
target_soc, serial_num)
if os.path.exists(build_tmp_binary_dir):
sh.rm("-rf", build_tmp_binary_dir)
os.makedirs(build_tmp_binary_dir)
sh_commands.gen_tuning_param_code(model_output_dirs)
if linkshared == 0:
mace_run_name = MACE_RUN_STATIC_NAME
mace_run_target = MACE_RUN_STATIC_TARGET
else:
mace_run_name = MACE_RUN_SHARED_NAME
mace_run_target = MACE_RUN_SHARED_TARGET
sh_commands.bazel_build(
LIBMACE_SO_TARGET,
abi=target_abi,
hexagon_mode=hexagon_mode,
enable_openmp=enable_openmp,
address_sanitizer=address_sanitizer
)
sh_commands.update_libmace_shared_library(serial_num,
target_abi,
library_name,
BUILD_OUTPUT_DIR,
OUTPUT_LIBRARY_DIR_NAME)
sh_commands.bazel_build(
mace_run_target,
abi=target_abi,
hexagon_mode=hexagon_mode,
enable_openmp=enable_openmp,
address_sanitizer=address_sanitizer
)
sh_commands.update_mace_run_lib(build_tmp_binary_dir, linkshared)
binary_changed = False
for model_name in configs[YAMLKeyword.models]:
model_config = configs[YAMLKeyword.models][model_name]
model_runtime = model_config[YAMLKeyword.runtime]
# Create model build directory
model_output_base_dir, model_output_dir, mace_model_dir = \
get_build_model_dirs(library_name, model_name, target_abi,
target_soc, serial_num,
model_config[YAMLKeyword.model_file_path])
model_output_dirs.append(model_output_dir)
def get_model_lib_output_path(library_name):
library_out_dir = os.path.join(BUILD_OUTPUT_DIR, library_name,
MODEL_OUTPUT_DIR_NAME)
lib_output_path = "%s/%s.a" % (library_out_dir, library_name)
return lib_output_path
if os.path.exists(model_output_dir):
sh.rm("-rf", model_output_dir)
os.makedirs(model_output_dir)
# build for specified soc
if not address_sanitizer and target_abi != ABIType.host \
and target_soc is not None and \
model_runtime in [RuntimeType.gpu, RuntimeType.cpu_gpu]:
sh_commands.clear_phone_data_dir(serial_num, PHONE_DATA_DIR)
def build_model_lib(configs, address_sanitizer):
MaceLogger.header(StringFormatter.block("Building model library"))
subgraphs = model_config[YAMLKeyword.subgraphs]
# generate input data
sh_commands.gen_random_input(
model_output_dir,
subgraphs[0][YAMLKeyword.input_tensors],
subgraphs[0][YAMLKeyword.input_shapes],
subgraphs[0][YAMLKeyword.validation_inputs_data],
input_ranges=subgraphs[0][YAMLKeyword.input_ranges])
device_type = parse_device_type(RuntimeType.gpu)
sh_commands.tuning_run(
abi=target_abi,
serialno=serial_num,
target_dir=build_tmp_binary_dir,
target_name=mace_run_name,
vlog_level=0,
embed_model_data=embed_model_data,
model_output_dir=model_output_dir,
input_nodes=subgraphs[0][YAMLKeyword.input_tensors],
output_nodes=subgraphs[0][YAMLKeyword.output_tensors],
input_shapes=subgraphs[0][YAMLKeyword.input_shapes],
output_shapes=subgraphs[0][YAMLKeyword.output_shapes],
mace_model_dir=mace_model_dir,
model_tag=model_name,
device_type=device_type,
running_round=0,
restart_round=1,
limit_opencl_kernel_time=model_config[YAMLKeyword.limit_opencl_kernel_time], # noqa
tuning=tuning,
out_of_range_check=False,
phone_data_dir=PHONE_DATA_DIR,
build_type=build_type,
opencl_binary_file="",
shared_library_dir=get_shared_library_dir(library_name, target_abi), # noqa
linkshared=linkshared,
)
# create model library dir
library_name = configs[YAMLKeyword.library_name]
model_lib_output_path = get_model_lib_output_path(library_name)
library_out_dir = os.path.dirname(model_lib_output_path)
if not os.path.exists(library_out_dir):
os.makedirs(library_out_dir)
pull_opencl_binary_and_tuning_param(target_abi, serial_num,
[model_output_dir])
sh_commands.touch_tuned_file_flag(build_tmp_binary_dir)
binary_changed = True
for target_abi in configs[YAMLKeyword.target_abis]:
hexagon_mode = get_hexagon_mode(configs)
if binary_changed:
opencl_output_bin_path = get_opencl_binary_output_path(
library_name, target_abi, target_soc, serial_num
)
sh_commands.merge_opencl_binaries(
model_output_dirs, CL_COMPILED_BINARY_FILE_NAME,
opencl_output_bin_path)
sh_commands.gen_tuning_param_code(model_output_dirs)
sh_commands.bazel_build(
mace_run_target,
MODEL_LIB_TARGET,
abi=target_abi,
hexagon_mode=hexagon_mode,
enable_openmp=enable_openmp,
address_sanitizer=address_sanitizer
)
sh_commands.update_mace_run_lib(build_tmp_binary_dir, linkshared)
if target_abi == ABIType.host:
sh_commands.build_host_libraries(build_type, target_abi)
# build benchmark_model binary
sh_commands.build_benchmark_model(target_abi,
build_tmp_binary_dir,
hexagon_mode,
enable_openmp,
linkshared)
# generate library
if linkshared == 0:
sh_commands.merge_libs(target_soc,
serial_num,
target_abi,
library_name,
BUILD_OUTPUT_DIR,
OUTPUT_LIBRARY_DIR_NAME,
build_type,
hexagon_mode)
# build example binary
sh_commands.build_example(target_soc, serial_num, target_abi,
library_name, BUILD_OUTPUT_DIR,
OUTPUT_LIBRARY_DIR_NAME,
build_tmp_binary_dir, build_type,
hexagon_mode, enable_openmp, linkshared)
def generate_library(configs, tuning, enable_openmp, address_sanitizer):
MaceLogger.header(StringFormatter.block("Building library"))
# generate source
MaceLogger.info('* generate common source files...')
sh_commands.gen_mace_version()
sh_commands.gen_encrypted_opencl_source()
MaceLogger.info('generate common source files done')
# create build dirs
library_name = configs[YAMLKeyword.library_name]
if not os.path.exists(BUILD_OUTPUT_DIR):
os.makedirs(BUILD_OUTPUT_DIR)
tmp_build_dir = os.path.join(BUILD_OUTPUT_DIR, library_name,
BUILD_TMP_DIR_NAME)
if not os.path.exists(tmp_build_dir):
os.makedirs(tmp_build_dir)
library_out_dir = os.path.join(BUILD_OUTPUT_DIR, library_name,
OUTPUT_LIBRARY_DIR_NAME)
if os.path.exists(library_out_dir):
sh.rm('-rf', library_out_dir)
target_socs = configs[YAMLKeyword.target_socs]
for target_abi in configs[YAMLKeyword.target_abis]:
if not target_socs or target_abi == ABIType.host:
build_specific_lib(target_abi, None, None, configs,
tuning, enable_openmp, address_sanitizer)
else:
if ALL_SOC_TAG in target_socs:
target_socs = sh_commands.adb_get_all_socs()
for target_soc in target_socs:
serial_nums = \
sh_commands.get_target_socs_serialnos([target_soc])
for serial_num in serial_nums:
with sh_commands.device_lock(serial_num):
build_specific_lib(target_abi, target_soc, serial_num,
configs, tuning, enable_openmp,
address_sanitizer)
# package library
sh_commands.packaging_lib(BUILD_OUTPUT_DIR,
configs[YAMLKeyword.library_name])
sh.cp("-f", MODEL_LIB_PATH, model_lib_output_path)
def print_library_summary(configs):
......@@ -876,21 +751,27 @@ def print_library_summary(configs):
title = "Library"
header = ["key", "value"]
data = list()
data.append(["library package",
"%s/%s/libmace_%s.tar.gz"
% (BUILD_OUTPUT_DIR, library_name, library_name)])
data.append(["MACE Model Path",
"%s/%s/%s"
% (BUILD_OUTPUT_DIR, library_name, MODEL_OUTPUT_DIR_NAME)])
if configs[YAMLKeyword.model_graph_format] == ModelFormat.code:
data.append(["MACE Model Header Path",
"%s/%s/%s"
% (BUILD_OUTPUT_DIR, library_name,
MODEL_HEADER_DIR_PATH)])
MaceLogger.summary(StringFormatter.table(header, data, title))
def build_library(flags):
def convert_func(flags):
configs = format_model_config(flags)
print_configuration(flags, configs)
print_configuration(configs)
convert_model(configs)
generate_library(configs, flags.disable_tuning,
flags.disable_openmp, flags.address_sanitizer)
if configs[YAMLKeyword.model_graph_format] == ModelFormat.code:
build_model_lib(configs, flags.address_sanitizer)
print_library_summary(configs)
......@@ -926,7 +807,7 @@ def report_run_statistics(stdout,
if not os.path.exists(report_filename):
with open(report_filename, 'w') as f:
f.write("model_name,device_name,soc,abi,runtime,"
"init,warmup,run_avg,tuned\n")
"init(ms),warmup(ms),run_avg(ms),tuned\n")
data_str = "{model_name},{device_name},{soc},{abi},{device_type}," \
"{init},{warmup},{run_avg},{tuned}\n" \
......@@ -938,52 +819,222 @@ def report_run_statistics(stdout,
init=metrics[0],
warmup=metrics[1],
run_avg=metrics[2],
tuned=tuned,
)
tuned=tuned)
with open(report_filename, 'a') as f:
f.write(data_str)
def build_mace_run(configs, target_abi, enable_openmp, address_sanitizer,
mace_lib_type):
library_name = configs[YAMLKeyword.library_name]
hexagon_mode = get_hexagon_mode(configs)
build_tmp_binary_dir = get_build_binary_dir(library_name, target_abi)
if os.path.exists(build_tmp_binary_dir):
sh.rm("-rf", build_tmp_binary_dir)
os.makedirs(build_tmp_binary_dir)
mace_run_target = MACE_RUN_STATIC_TARGET
if mace_lib_type == MACELibType.dynamic:
mace_run_target = MACE_RUN_DYNAMIC_TARGET
build_arg = ""
if configs[YAMLKeyword.model_graph_format] == ModelFormat.code:
mace_check(os.path.exists(ENGINE_CODEGEN_DIR),
ModuleName.RUN,
"You shuold convert model first.")
build_arg = "--per_file_copt=mace/tools/validation/mace_run.cc@-DMODEL_GRAPH_FORMAT_CODE" # noqa
sh_commands.bazel_build(
mace_run_target,
abi=target_abi,
hexagon_mode=hexagon_mode,
enable_openmp=enable_openmp,
address_sanitizer=address_sanitizer,
extra_args=build_arg
)
sh_commands.update_mace_run_binary(build_tmp_binary_dir,
mace_lib_type == MACELibType.dynamic)
def build_example(configs, target_abi, enable_openmp, mace_lib_type):
library_name = configs[YAMLKeyword.library_name]
hexagon_mode = get_hexagon_mode(configs)
build_tmp_binary_dir = get_build_binary_dir(library_name, target_abi)
if os.path.exists(build_tmp_binary_dir):
sh.rm("-rf", build_tmp_binary_dir)
os.makedirs(build_tmp_binary_dir)
libmace_target = LIBMACE_STATIC_TARGET
if mace_lib_type == MACELibType.dynamic:
libmace_target = LIBMACE_SO_TARGET
sh_commands.bazel_build(libmace_target,
abi=target_abi,
enable_openmp=enable_openmp,
hexagon_mode=hexagon_mode)
if os.path.exists(LIB_CODEGEN_DIR):
sh.rm("-rf", LIB_CODEGEN_DIR)
sh.mkdir("-p", LIB_CODEGEN_DIR)
build_arg = ""
if mace_lib_type == MACELibType.dynamic:
example_target = EXAMPLE_DYNAMIC_TARGET
sh.cp("-f", LIBMACE_DYNAMIC_PATH, LIB_CODEGEN_DIR)
else:
sh.cp("-f", LIBMACE_STATIC_PATH, LIB_CODEGEN_DIR)
if configs[YAMLKeyword.model_graph_format] == ModelFormat.code:
mace_check(os.path.exists(ENGINE_CODEGEN_DIR),
ModuleName.RUN,
"You shuold convert model first.")
model_lib_path = get_model_lib_output_path(library_name)
sh.cp("-f", model_lib_path, LIB_CODEGEN_DIR)
build_arg = "--per_file_copt=mace/examples/cli/example.cc@-DMODEL_GRAPH_FORMAT_CODE" # noqa
example_target = EXAMPLE_STATIC_TARGET
sh_commands.bazel_build(example_target,
abi=target_abi,
enable_openmp=enable_openmp,
hexagon_mode=hexagon_mode,
extra_args=build_arg)
target_bin = "/".join(sh_commands.bazel_target_to_bin(example_target))
sh.cp("-f", target_bin, build_tmp_binary_dir)
if os.path.exists(LIB_CODEGEN_DIR):
sh.rm("-rf", LIB_CODEGEN_DIR)
def tuning(library_name, model_name, model_config,
model_graph_format, model_data_format,
target_abi, target_soc, serial_num,
mace_lib_type):
print('* Tuning, it may take some time...')
# clear opencl output dir
opencl_output_dir = os.path.join(
BUILD_OUTPUT_DIR, library_name, OUTPUT_OPENCL_BINARY_DIR_NAME)
if os.path.exists(opencl_output_dir):
sh.rm('-rf', opencl_output_dir)
build_tmp_binary_dir = get_build_binary_dir(library_name, target_abi)
mace_run_name = MACE_RUN_STATIC_NAME
link_dynamic = False
if mace_lib_type == MACELibType.dynamic:
mace_run_name = MACE_RUN_DYNAMIC_NAME
link_dynamic = True
embed_model_data = model_data_format == ModelFormat.code
model_output_base_dir, model_output_dir, mace_model_dir = \
get_build_model_dirs(library_name, model_name, target_abi,
target_soc, serial_num,
model_config[YAMLKeyword.model_file_path])
# build for specified soc
sh_commands.clear_phone_data_dir(serial_num, PHONE_DATA_DIR)
subgraphs = model_config[YAMLKeyword.subgraphs]
# generate input data
sh_commands.gen_random_input(
model_output_dir,
subgraphs[0][YAMLKeyword.input_tensors],
subgraphs[0][YAMLKeyword.input_shapes],
subgraphs[0][YAMLKeyword.validation_inputs_data],
input_ranges=subgraphs[0][YAMLKeyword.input_ranges])
sh_commands.tuning_run(
abi=target_abi,
serialno=serial_num,
target_dir=build_tmp_binary_dir,
target_name=mace_run_name,
vlog_level=0,
embed_model_data=embed_model_data,
model_output_dir=model_output_dir,
input_nodes=subgraphs[0][YAMLKeyword.input_tensors],
output_nodes=subgraphs[0][YAMLKeyword.output_tensors],
input_shapes=subgraphs[0][YAMLKeyword.input_shapes],
output_shapes=subgraphs[0][YAMLKeyword.output_shapes],
mace_model_dir=mace_model_dir,
model_tag=model_name,
device_type=DeviceType.GPU,
running_round=0,
restart_round=1,
limit_opencl_kernel_time=model_config[YAMLKeyword.limit_opencl_kernel_time], # noqa
tuning=True,
out_of_range_check=False,
phone_data_dir=PHONE_DATA_DIR,
model_graph_format=model_graph_format,
opencl_binary_file="",
opencl_parameter_file="",
libmace_dynamic_library_path=LIBMACE_DYNAMIC_PATH,
link_dynamic=link_dynamic,
)
# pull opencl binary
sh_commands.pull_file_from_device(
serial_num,
DEVICE_INTERIOR_DIR,
CL_COMPILED_BINARY_FILE_NAME,
"%s/%s" % (model_output_dir, BUILD_TMP_OPENCL_BIN_DIR))
# pull opencl parameter
sh_commands.pull_file_from_device(
serial_num,
PHONE_DATA_DIR,
CL_TUNED_PARAMETER_FILE_NAME,
"%s/%s" % (model_output_dir, BUILD_TMP_OPENCL_BIN_DIR))
print('Tuning done\n')
def run_specific_target(flags, configs, target_abi,
target_soc, serial_num):
library_name = configs[YAMLKeyword.library_name]
build_type = configs[YAMLKeyword.build_type]
embed_model_data = configs[YAMLKeyword.embed_model_data]
mace_lib_type = flags.mace_lib_type
embed_model_data = \
configs[YAMLKeyword.model_data_format] == ModelFormat.code
opencl_output_bin_path = ""
linkshared = configs[YAMLKeyword.linkshared]
if not configs[YAMLKeyword.target_socs] or target_abi == ABIType.host:
build_tmp_binary_dir = get_build_binary_dir(library_name, target_abi,
None, None)
else:
build_tmp_binary_dir = get_build_binary_dir(library_name, target_abi,
target_soc, serial_num)
opencl_parameter_path = ""
build_tmp_binary_dir = get_build_binary_dir(library_name, target_abi)
if configs[YAMLKeyword.target_socs] and target_abi != ABIType.host:
opencl_output_bin_path = get_opencl_binary_output_path(
library_name, target_abi, target_soc, serial_num
)
mace_check(os.path.exists(build_tmp_binary_dir),
ModuleName.RUN,
'You should build before run.')
opencl_parameter_path = get_opencl_parameter_output_path(
library_name, target_abi, target_soc, serial_num
)
# get target name for run
if flags.example:
if linkshared == 0:
if mace_lib_type == MACELibType.static:
target_name = EXAMPLE_STATIC_NAME
else:
target_name = EXAMPLE_SHARED_NAME
target_name = EXAMPLE_DYNAMIC_NAME
else:
if linkshared == 0:
if mace_lib_type == MACELibType.static:
target_name = MACE_RUN_STATIC_NAME
else:
target_name = MACE_RUN_SHARED_NAME
target_name = MACE_RUN_DYNAMIC_NAME
link_dynamic = mace_lib_type == MACELibType.dynamic
model_output_dirs = []
for model_name in configs[YAMLKeyword.models]:
check_model_converted(library_name, model_name,
configs[YAMLKeyword.model_graph_format],
configs[YAMLKeyword.model_data_format])
if target_abi == ABIType.host:
device_name = ABIType.host
else:
device_name =\
device_name = \
sh_commands.adb_get_device_name_by_serialno(serial_num)
sh_commands.clear_phone_data_dir(serial_num, PHONE_DATA_DIR)
MaceLogger.header(
StringFormatter.block(
"Run model %s on %s" % (model_name, device_name)))
model_config = configs[YAMLKeyword.models][model_name]
model_runtime = model_config[YAMLKeyword.runtime]
subgraphs = model_config[YAMLKeyword.subgraphs]
......@@ -998,12 +1049,24 @@ def run_specific_target(flags, configs, target_abi,
get_build_model_dirs(library_name, model_name, target_abi,
target_soc, serial_num,
model_config[YAMLKeyword.model_file_path])
mace_check(os.path.exists(model_output_dir)
and os.path.exists(mace_model_dir),
ModuleName.RUN,
'You should build before run.')
if target_abi != ABIType.host:
sh_commands.clear_phone_data_dir(serial_num, PHONE_DATA_DIR)
if os.path.exists(model_output_dir):
sh.rm("-rf", model_output_dir)
os.makedirs(model_output_dir)
# tuning for specified soc
if not flags.address_sanitizer \
and not flags.example \
and target_abi != ABIType.host \
and configs[YAMLKeyword.target_socs] \
and target_soc \
and model_runtime in [RuntimeType.gpu, RuntimeType.cpu_gpu] \
and not flags.disable_tuning:
tuning(library_name, model_name, model_config,
configs[YAMLKeyword.model_graph_format],
configs[YAMLKeyword.model_data_format],
target_abi, target_soc, serial_num,
mace_lib_type)
model_output_dirs.append(model_output_dir)
# generate input data
sh_commands.gen_random_input(
......@@ -1012,6 +1075,7 @@ def run_specific_target(flags, configs, target_abi,
subgraphs[0][YAMLKeyword.input_shapes],
subgraphs[0][YAMLKeyword.validation_inputs_data],
input_ranges=subgraphs[0][YAMLKeyword.input_ranges])
runtime_list = []
if target_abi == ABIType.host:
runtime_list.extend([RuntimeType.cpu])
......@@ -1021,7 +1085,7 @@ def run_specific_target(flags, configs, target_abi,
runtime_list.extend([model_runtime])
for runtime in runtime_list:
device_type = parse_device_type(runtime)
# run for specified soc
run_output = sh_commands.tuning_run(
abi=target_abi,
serialno=serial_num,
......@@ -1043,7 +1107,7 @@ def run_specific_target(flags, configs, target_abi,
tuning=False,
out_of_range_check=flags.gpu_out_of_range_check,
phone_data_dir=PHONE_DATA_DIR,
build_type=build_type,
model_graph_format=configs[YAMLKeyword.model_graph_format],
omp_num_threads=flags.omp_num_threads,
cpu_affinity_policy=flags.cpu_affinity_policy,
gpu_perf_hint=flags.gpu_perf_hint,
......@@ -1051,8 +1115,9 @@ def run_specific_target(flags, configs, target_abi,
runtime_failure_ratio=flags.runtime_failure_ratio,
address_sanitizer=flags.address_sanitizer,
opencl_binary_file=opencl_output_bin_path,
shared_library_dir=get_shared_library_dir(library_name, target_abi), # noqa
linkshared=linkshared,
opencl_parameter_file=opencl_parameter_path,
libmace_dynamic_library_path=LIBMACE_DYNAMIC_PATH,
link_dynamic=link_dynamic,
)
if flags.validate:
model_file_path, weight_file_path = get_model_files(
......@@ -1077,20 +1142,60 @@ def run_specific_target(flags, configs, target_abi,
phone_data_dir=PHONE_DATA_DIR,
caffe_env=flags.caffe_env)
if flags.report and flags.round > 0:
opencl_parameter_bin_path = get_opencl_parameter_output_path(
library_name, target_abi, target_soc, serial_num
)
tuned = device_type == DeviceType.GPU\
and os.path.exists(opencl_parameter_bin_path)
report_run_statistics(
run_output, target_abi, serial_num,
model_name, device_type, flags.report_dir,
sh_commands.is_binary_tuned(build_tmp_binary_dir))
tuned)
if model_output_dirs:
opencl_output_bin_path = get_opencl_binary_output_path(
library_name, target_abi, target_soc, serial_num
)
opencl_parameter_bin_path = get_opencl_parameter_output_path(
library_name, target_abi, target_soc, serial_num
)
# merge all models' OpenCL binaries together
sh_commands.merge_opencl_binaries(
model_output_dirs, CL_COMPILED_BINARY_FILE_NAME,
opencl_output_bin_path)
# merge all models' OpenCL parameters together
sh_commands.merge_opencl_parameters(
model_output_dirs, CL_TUNED_PARAMETER_FILE_NAME,
opencl_parameter_bin_path)
def run_mace(flags):
configs = format_model_config(flags)
if flags.mace_lib_type == MACELibType.dynamic and \
configs[YAMLKeyword.model_graph_format] == ModelFormat.code:
MaceLogger.error(ModuleName.YAML_CONFIG,
"If you want to link MACE dynamic library, "
"you must use file-type MACE model.")
clear_build_dirs(configs[YAMLKeyword.library_name])
target_socs = configs[YAMLKeyword.target_socs]
if not target_socs or ALL_SOC_TAG in target_socs:
target_socs = sh_commands.adb_get_all_socs()
for target_abi in configs[YAMLKeyword.target_abis]:
# build target
if flags.example:
build_example(configs, target_abi,
not flags.disable_openmp,
flags.mace_lib_type)
else:
build_mace_run(configs, target_abi,
not flags.disable_openmp,
flags.address_sanitizer,
flags.mace_lib_type)
# run
if target_abi == ABIType.host:
run_specific_target(flags, configs, target_abi, None, None)
else:
......@@ -1109,26 +1214,64 @@ def run_mace(flags):
################################
# benchmark model
################################
def build_benchmark_model(configs, target_abi, enable_openmp, mace_lib_type):
library_name = configs[YAMLKeyword.library_name]
hexagon_mode = get_hexagon_mode(configs)
link_dynamic = mace_lib_type == MACELibType.dynamic
if link_dynamic:
benchmark_target = BM_MODEL_DYNAMIC_TARGET
else:
benchmark_target = BM_MODEL_STATIC_TARGET
build_arg = ""
if configs[YAMLKeyword.model_graph_format] == ModelFormat.code:
mace_check(os.path.exists(ENGINE_CODEGEN_DIR),
ModuleName.BENCHMARK,
"You shuold convert model first.")
build_arg = "--per_file_copt=mace/benchmark/benchmark_model.cc@-DMODEL_GRAPH_FORMAT_CODE" # noqa
sh_commands.bazel_build(benchmark_target,
abi=target_abi,
enable_openmp=enable_openmp,
hexagon_mode=hexagon_mode,
extra_args=build_arg)
# clear tmp binary dir
build_tmp_binary_dir = get_build_binary_dir(library_name, target_abi)
if os.path.exists(build_tmp_binary_dir):
sh.rm("-rf", build_tmp_binary_dir)
os.makedirs(build_tmp_binary_dir)
target_bin = "/".join(sh_commands.bazel_target_to_bin(benchmark_target))
sh.cp("-f", target_bin, build_tmp_binary_dir)
def bm_specific_target(flags, configs, target_abi, target_soc, serial_num):
library_name = configs[YAMLKeyword.library_name]
build_type = configs[YAMLKeyword.build_type]
embed_model_data = configs[YAMLKeyword.embed_model_data]
embed_model_data = \
configs[YAMLKeyword.model_data_format] == ModelFormat.code
opencl_output_bin_path = ""
linkshared = configs[YAMLKeyword.linkshared]
if not configs[YAMLKeyword.target_socs] or target_abi == ABIType.host:
build_tmp_binary_dir = get_build_binary_dir(library_name, target_abi,
None, None)
opencl_parameter_path = ""
link_dynamic = flags.mace_lib_type == MACELibType.dynamic
if link_dynamic:
bm_model_binary_name = BM_MODEL_DYNAMIC_NAME
else:
build_tmp_binary_dir = get_build_binary_dir(library_name, target_abi,
target_soc, serial_num)
bm_model_binary_name = BM_MODEL_STATIC_NAME
build_tmp_binary_dir = get_build_binary_dir(library_name, target_abi)
if configs[YAMLKeyword.target_socs] and target_abi != ABIType.host:
opencl_output_bin_path = get_opencl_binary_output_path(
library_name, target_abi, target_soc, serial_num
)
mace_check(os.path.exists(build_tmp_binary_dir),
ModuleName.BENCHMARK,
'You should build before benchmark.')
opencl_parameter_path = get_opencl_parameter_output_path(
library_name, target_abi, target_soc, serial_num
)
for model_name in configs[YAMLKeyword.models]:
check_model_converted(library_name, model_name,
configs[YAMLKeyword.model_graph_format],
configs[YAMLKeyword.model_data_format])
if target_abi == ABIType.host:
device_name = ABIType.host
else:
......@@ -1151,10 +1294,10 @@ def bm_specific_target(flags, configs, target_abi, target_soc, serial_num):
get_build_model_dirs(library_name, model_name, target_abi,
target_soc, serial_num,
model_config[YAMLKeyword.model_file_path])
mace_check(os.path.exists(model_output_dir)
and os.path.exists(mace_model_dir),
ModuleName.BENCHMARK,
'You should build before benchmark.')
if os.path.exists(model_output_dir):
sh.rm("-rf", model_output_dir)
os.makedirs(model_output_dir)
if target_abi != ABIType.host:
sh_commands.clear_phone_data_dir(serial_num, PHONE_DATA_DIR)
......@@ -1177,6 +1320,7 @@ def bm_specific_target(flags, configs, target_abi, target_soc, serial_num):
abi=target_abi,
serialno=serial_num,
benchmark_binary_dir=build_tmp_binary_dir,
benchmark_binary_name=bm_model_binary_name,
vlog_level=0,
embed_model_data=embed_model_data,
model_output_dir=model_output_dir,
......@@ -1188,24 +1332,37 @@ def bm_specific_target(flags, configs, target_abi, target_soc, serial_num):
model_tag=model_name,
device_type=device_type,
phone_data_dir=PHONE_DATA_DIR,
build_type=build_type,
model_graph_format=configs[YAMLKeyword.model_graph_format],
omp_num_threads=flags.omp_num_threads,
cpu_affinity_policy=flags.cpu_affinity_policy,
gpu_perf_hint=flags.gpu_perf_hint,
gpu_priority_hint=flags.gpu_priority_hint,
opencl_binary_file=opencl_output_bin_path,
shared_library_dir=get_shared_library_dir(library_name, target_abi), # noqa
linkshared=linkshared)
opencl_parameter_file=opencl_parameter_path,
libmace_dynamic_library_path=LIBMACE_DYNAMIC_PATH,
link_dynamic=link_dynamic)
def benchmark_model(flags):
configs = format_model_config(flags)
if flags.mace_lib_type == MACELibType.dynamic and \
configs[YAMLKeyword.model_graph_format] == ModelFormat.code:
MaceLogger.error(ModuleName.YAML_CONFIG,
"If you want to link MACE dynamic library, "
"you must use file-type MACE model.")
clear_build_dirs(configs[YAMLKeyword.library_name])
target_socs = configs[YAMLKeyword.target_socs]
if not target_socs or ALL_SOC_TAG in target_socs:
target_socs = sh_commands.adb_get_all_socs()
for target_abi in configs[YAMLKeyword.target_abis]:
# build benchmark_model binary
build_benchmark_model(configs, target_abi,
not flags.disable_openmp,
flags.mace_lib_type)
if target_abi == ABIType.host:
bm_specific_target(flags, configs, target_abi, None, None)
else:
......@@ -1242,6 +1399,15 @@ def str_to_caffe_env_type(v):
raise argparse.ArgumentTypeError('[docker | local] expected.')
def str_to_mace_lib_type(v):
if v.lower() == 'dynamic':
return MACELibType.dynamic
elif v.lower() == 'static':
return MACELibType.static
else:
raise argparse.ArgumentTypeError('[dynamic| static] expected.')
def parse_args():
"""Parses command line arguments."""
all_type_parent_parser = argparse.ArgumentParser(add_help=False)
......@@ -1252,10 +1418,15 @@ def parse_args():
required=True,
help="the path of model yaml configuration file.")
all_type_parent_parser.add_argument(
"--build_type",
"--model_graph_format",
type=str,
default="",
help="Model build type, can be ['proto', 'code'].")
help="[file, code], MACE Model graph format.")
all_type_parent_parser.add_argument(
"--model_data_format",
type=str,
default="",
help="['file', 'code'], MACE Model data format.")
all_type_parent_parser.add_argument(
"--target_abis",
type=str,
......@@ -1266,12 +1437,21 @@ def parse_args():
type=str,
default="",
help="Target SOCs, comma seperated list.")
build_run_parent_parser = argparse.ArgumentParser(add_help=False)
build_run_parent_parser.add_argument(
convert_run_parent_parser = argparse.ArgumentParser(add_help=False)
convert_run_parent_parser.add_argument(
'--address_sanitizer',
action="store_true",
help="Whether to use address sanitizer to check memory error")
run_bm_parent_parser = argparse.ArgumentParser(add_help=False)
run_bm_parent_parser.add_argument(
"--mace_lib_type",
type=str_to_mace_lib_type,
default=DefaultValues.mace_lib_type,
help="[static | dynamic], Which type MACE library to use.")
run_bm_parent_parser.add_argument(
"--disable_openmp",
action="store_true",
help="Disable openmp for multiple thread.")
run_bm_parent_parser.add_argument(
"--omp_num_threads",
type=int,
......@@ -1295,25 +1475,21 @@ def parse_args():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
build = subparsers.add_parser(
'build',
parents=[all_type_parent_parser, build_run_parent_parser],
help='build model library and test tools')
build.set_defaults(func=build_library)
build.add_argument(
'--disable_tuning',
action="store_false",
help="Disable tuning the parameters for the GPU of specified SoC.")
build.add_argument(
"--disable_openmp",
action="store_false",
help="Disable openmp for multiple thread.")
convert = subparsers.add_parser(
'convert',
parents=[all_type_parent_parser, convert_run_parent_parser],
help='convert to mace model (file or code)')
convert.set_defaults(func=convert_func)
run = subparsers.add_parser(
'run',
parents=[all_type_parent_parser, run_bm_parent_parser,
build_run_parent_parser],
convert_run_parent_parser],
help='run model in command line')
run.set_defaults(func=run_mace)
run.add_argument(
"--disable_tuning",
action="store_true",
help="Disable tuning for specific thread.")
run.add_argument(
"--round",
type=int,
......@@ -1364,8 +1540,7 @@ def parse_args():
help="whether to run example.")
benchmark = subparsers.add_parser(
'benchmark',
parents=[all_type_parent_parser, run_bm_parent_parser,
build_run_parent_parser],
parents=[all_type_parent_parser, run_bm_parent_parser],
help='benchmark model for detail information')
benchmark.set_defaults(func=benchmark_model)
return parser.parse_known_args()
......
......@@ -85,6 +85,11 @@ class BuildType(object):
code = 'code'
class ModelFormat(object):
file = 'file'
code = 'code'
def stdout_success(stdout):
stdout_lines = stdout.split("\n")
for line in stdout_lines:
......@@ -104,11 +109,6 @@ def clear_phone_data_dir(serialno, phone_data_dir):
"rm -rf %s" % phone_data_dir)
def clear_model_codegen(model_codegen_dir="mace/codegen/models"):
if os.path.exists(model_codegen_dir):
sh.rm("-rf", model_codegen_dir)
################################
# adb commands
################################
......@@ -144,23 +144,6 @@ def get_target_socs_serialnos(target_socs=None):
return serialnos
def get_soc_serial_number_map():
serial_numbers = adb_devices()
soc_serial_number_map = {}
for num in serial_numbers:
props = adb_getprop_by_serialno(num)
soc_serial_number_map[props["ro.board.platform"]] = num
return soc_serial_number_map
def get_target_soc_serial_number(target_soc):
soc_serial_number_map = get_soc_serial_number_map()
serial_number = None
if target_soc in soc_serial_number_map:
serial_number = soc_serial_number_map[target_soc]
return serial_number
def adb_getprop_by_serialno(serialno):
outputs = sh.adb("-s", serialno, "shell", "getprop")
raw_props = split_stdout(outputs)
......@@ -285,6 +268,12 @@ def find_asan_rt_library(abi, asan_rt_path=''):
return "%s/%s" % (asan_rt_path, asan_rt_library_names(abi))
def find_gnustl_shared_path(abi):
return \
"%s/sources/cxx-stl/gnu-libstdc++/4.9/libs/%s/libgnustl_shared.so" % \
(os.environ["ANDROID_NDK_HOME"], abi)
################################
# bazel commands
################################
......@@ -322,6 +311,7 @@ def bazel_build(target,
bazel_args += ("--config", "optimization")
if extra_args:
bazel_args += (extra_args, )
print bazel_args
sh.bazel(
_fg=True,
*bazel_args)
......@@ -360,7 +350,6 @@ def gen_encrypted_opencl_source(codegen_path="mace/codegen"):
def gen_mace_engine_factory_source(model_tags,
model_load_type,
embed_model_data,
codegen_path="mace/codegen"):
print("* Generate mace engine creator source")
......@@ -370,31 +359,18 @@ def gen_mace_engine_factory_source(model_tags,
gen_mace_engine_factory(
model_tags,
"mace/python/tools",
model_load_type,
embed_model_data,
codegen_tools_dir)
print("Generate mace engine creator source done!\n")
def pull_binaries(abi, serialno, model_output_dirs,
cl_built_kernel_file_name):
compiled_opencl_dir = "/data/local/tmp/mace_run/interior/"
mace_run_param_file = "mace_run.config"
cl_bin_dirs = []
for d in model_output_dirs:
cl_bin_dirs.append(os.path.join(d, "opencl_bin"))
cl_bin_dirs_str = ",".join(cl_bin_dirs)
if cl_bin_dirs:
cl_bin_dir = cl_bin_dirs_str
if os.path.exists(cl_bin_dir):
sh.rm("-rf", cl_bin_dir)
sh.mkdir("-p", cl_bin_dir)
if abi != "host":
adb_pull(compiled_opencl_dir + cl_built_kernel_file_name,
cl_bin_dir, serialno)
adb_pull("/data/local/tmp/mace_run/%s" % mace_run_param_file,
cl_bin_dir, serialno)
def pull_file_from_device(serial_num, file_path, file_name, output_dir):
if not os.path.exists(output_dir):
sh.mkdir("-p", output_dir)
output_path = "%s/%s" % (output_dir, file_path)
if os.path.exists(output_path):
sh.rm('-rf', output_path)
adb_pull(file_path + '/' + file_name, output_dir, serial_num)
def merge_opencl_binaries(binaries_dirs,
......@@ -454,29 +430,52 @@ def merge_opencl_binaries(binaries_dirs,
np.array(output_byte_array).tofile(output_file_path)
def gen_tuning_param_code(model_output_dirs,
codegen_path="mace/codegen"):
mace_run_param_file = "mace_run.config"
def merge_opencl_parameters(binaries_dirs,
cl_parameter_file_name,
output_file_path):
cl_bin_dirs = []
for d in model_output_dirs:
for d in binaries_dirs:
cl_bin_dirs.append(os.path.join(d, "opencl_bin"))
cl_bin_dirs_str = ",".join(cl_bin_dirs)
# create opencl binary output dir
opencl_binary_dir = os.path.dirname(output_file_path)
if not os.path.exists(opencl_binary_dir):
sh.mkdir("-p", opencl_binary_dir)
kvs = {}
for binary_dir in cl_bin_dirs:
binary_path = os.path.join(binary_dir, cl_parameter_file_name)
if not os.path.exists(binary_path):
continue
tuning_codegen_dir = "%s/tuning/" % codegen_path
if not os.path.exists(tuning_codegen_dir):
sh.mkdir("-p", tuning_codegen_dir)
print 'generate opencl parameter from', binary_path
with open(binary_path, "rb") as f:
binary_array = np.fromfile(f, dtype=np.uint8)
tuning_param_variable_name = "kTuningParamsData"
tuning_param_codegen(cl_bin_dirs_str,
mace_run_param_file,
"%s/tuning_params.cc" % tuning_codegen_dir,
tuning_param_variable_name)
idx = 0
size, = struct.unpack("Q", binary_array[idx:idx + 8])
idx += 8
for _ in xrange(size):
key_size, = struct.unpack("i", binary_array[idx:idx + 4])
idx += 4
key, = struct.unpack(
str(key_size) + "s", binary_array[idx:idx + key_size])
idx += key_size
value_size, = struct.unpack("i", binary_array[idx:idx + 4])
idx += 4
kvs[key] = binary_array[idx:idx + value_size]
idx += value_size
output_byte_array = bytearray()
data_size = len(kvs)
output_byte_array.extend(struct.pack("Q", data_size))
for key, value in kvs.iteritems():
key_size = len(key)
output_byte_array.extend(struct.pack("i", key_size))
output_byte_array.extend(struct.pack(str(key_size) + "s", key))
value_size = len(value)
output_byte_array.extend(struct.pack("i", value_size))
output_byte_array.extend(value)
def gen_mace_version(codegen_path="mace/codegen"):
sh.mkdir("-p", "%s/version" % codegen_path)
sh.bash("mace/tools/git/gen_version_source.sh",
"%s/version/version.cc" % codegen_path)
np.array(output_byte_array).tofile(output_file_path)
def gen_model_code(model_codegen_dir,
......@@ -494,7 +493,7 @@ def gen_model_code(model_codegen_dir,
embed_model_data,
winograd,
obfuscate,
model_build_type,
model_graph_format,
data_type,
graph_optimize_options):
bazel_build_common("//mace/python/tools:converter")
......@@ -521,7 +520,7 @@ def gen_model_code(model_codegen_dir,
"--winograd=%s" % winograd,
"--obfuscate=%s" % obfuscate,
"--output_dir=%s" % model_codegen_dir,
"--model_build_type=%s" % model_build_type,
"--model_graph_format=%s" % model_graph_format,
"--data_type=%s" % data_type,
"--graph_optimize_options=%s" % graph_optimize_options,
_fg=True)
......@@ -572,58 +571,28 @@ def gen_random_input(model_output_dir,
sh.cp("-f", input_file_list[i], dst_input_file)
def update_mace_run_lib(build_tmp_binary_dir, linkshared=0):
if linkshared == 0:
mace_run_filepath = build_tmp_binary_dir + "/mace_run_static"
def update_mace_run_binary(build_tmp_binary_dir, link_dynamic=False):
if link_dynamic:
mace_run_filepath = build_tmp_binary_dir + "/mace_run_dynamic"
else:
mace_run_filepath = build_tmp_binary_dir + "/mace_run_shared"
mace_run_filepath = build_tmp_binary_dir + "/mace_run_static"
if os.path.exists(mace_run_filepath):
sh.rm("-rf", mace_run_filepath)
if linkshared == 0:
sh.cp("-f", "bazel-bin/mace/tools/validation/mace_run_static",
if link_dynamic:
sh.cp("-f", "bazel-bin/mace/tools/validation/mace_run_dynamic",
build_tmp_binary_dir)
else:
sh.cp("-f", "bazel-bin/mace/tools/validation/mace_run_shared",
sh.cp("-f", "bazel-bin/mace/tools/validation/mace_run_static",
build_tmp_binary_dir)
def touch_tuned_file_flag(build_tmp_binary_dir):
sh.touch(build_tmp_binary_dir + '/tuned')
def is_binary_tuned(build_tmp_binary_dir):
return os.path.exists(build_tmp_binary_dir + '/tuned')
def create_internal_storage_dir(serialno, phone_data_dir):
internal_storage_dir = "%s/interior/" % phone_data_dir
sh.adb("-s", serialno, "shell", "mkdir", "-p", internal_storage_dir)
return internal_storage_dir
def update_libmace_shared_library(serial_num,
abi,
project_name,
build_output_dir,
library_output_dir):
library_dir = "%s/%s/%s/%s" % (
build_output_dir, project_name, library_output_dir, abi)
if os.path.exists(library_dir):
sh.rm("-rf", library_dir)
sh.mkdir("-p", library_dir)
sh.cp("-f", "bazel-bin/mace/libmace.so", library_dir)
sh.cp("-f",
"%s/sources/cxx-stl/gnu-libstdc++/4.9/libs/%s/libgnustl_shared.so" %
(os.environ["ANDROID_NDK_HOME"], abi),
library_dir)
if os.path.exists("mace/libmace.so"):
sh.rm("-f", "mace/libmace.so")
sh.cp("-f", "bazel-bin/mace/libmace.so", "mace/")
def tuning_run(abi,
serialno,
target_dir,
......@@ -644,9 +613,10 @@ def tuning_run(abi,
tuning,
out_of_range_check,
phone_data_dir,
build_type,
model_graph_format,
opencl_binary_file,
shared_library_dir,
opencl_parameter_file,
libmace_dynamic_library_path,
omp_num_threads=-1,
cpu_affinity_policy=1,
gpu_perf_hint=3,
......@@ -655,7 +625,7 @@ def tuning_run(abi,
output_file_name="model_out",
runtime_failure_ratio=0.0,
address_sanitizer=False,
linkshared=0):
link_dynamic=False):
print("* Run '%s' with round=%s, restart_round=%s, tuning=%s, "
"out_of_range_check=%s, omp_num_threads=%s, cpu_affinity_policy=%s, "
"gpu_perf_hint=%s, gpu_priority_hint=%s" %
......@@ -663,7 +633,7 @@ def tuning_run(abi,
str(out_of_range_check), omp_num_threads, cpu_affinity_policy,
gpu_perf_hint, gpu_priority_hint))
mace_model_path = ""
if build_type == BuildType.proto:
if model_graph_format == ModelFormat.file:
mace_model_path = "%s/%s.pb" % (mace_model_dir, model_tag)
if abi == "host":
p = subprocess.Popen(
......@@ -695,7 +665,6 @@ def tuning_run(abi,
stdout = err + out
print stdout
print("Running finished!\n")
return stdout
else:
sh.adb("-s", serialno, "shell", "mkdir", "-p", phone_data_dir)
internal_storage_dir = create_internal_storage_dir(
......@@ -713,24 +682,26 @@ def tuning_run(abi,
adb_push("%s/%s.data" % (mace_model_dir, model_tag),
phone_data_dir, serialno)
if device_type == common.DeviceType.GPU\
and os.path.exists(opencl_binary_file):
adb_push(opencl_binary_file, phone_data_dir, serialno)
if device_type == common.DeviceType.GPU:
if os.path.exists(opencl_binary_file):
adb_push(opencl_binary_file, phone_data_dir, serialno)
if os.path.exists(opencl_parameter_file):
adb_push(opencl_parameter_file, phone_data_dir, serialno)
adb_push("third_party/nnlib/libhexagon_controller.so",
phone_data_dir, serialno)
mace_model_phone_path = ""
if build_type == BuildType.proto:
if model_graph_format == ModelFormat.file:
mace_model_phone_path = "%s/%s.pb" % (phone_data_dir, model_tag)
adb_push(mace_model_path,
mace_model_phone_path,
serialno)
if linkshared == 1:
adb_push("%s/libmace.so" % shared_library_dir, phone_data_dir,
if link_dynamic:
adb_push(libmace_dynamic_library_path, phone_data_dir,
serialno)
adb_push("%s/libgnustl_shared.so" % shared_library_dir,
adb_push(find_gnustl_shared_path(abi),
phone_data_dir,
serialno)
......@@ -774,6 +745,8 @@ def tuning_run(abi,
"--model_file=%s" % mace_model_phone_path,
"--opencl_binary_file=%s/%s" %
(phone_data_dir, os.path.basename(opencl_binary_file)),
"--opencl_parameter_file=%s/%s" %
(phone_data_dir, os.path.basename(opencl_parameter_file)),
])
adb_cmd = ' '.join(adb_cmd)
cmd_file_name = "%s-%s-%s" % ('cmd_file', model_tag, str(time.time()))
......@@ -926,152 +899,9 @@ def validate_model(abi,
print("Validation done!\n")
def build_host_libraries(model_build_type, abi):
bazel_build("@com_google_protobuf//:protobuf_lite", abi=abi)
bazel_build("//mace/proto:mace_cc", abi=abi)
bazel_build("//mace/codegen:generated_opencl", abi=abi)
bazel_build("//mace/codegen:generated_tuning_params", abi=abi)
bazel_build("//mace/codegen:generated_version", abi=abi)
bazel_build("//mace/utils:utils", abi=abi)
bazel_build("//mace/core:core", abi=abi)
bazel_build("//mace/kernels:kernels", abi=abi)
bazel_build("//mace/ops:ops", abi=abi)
if model_build_type == BuildType.code:
bazel_build(
"//mace/codegen:generated_models",
abi=abi)
################################
# library
################################
def get_lib_path(target_soc, serial_num, abi, project_name, build_output_dir,
library_output_dir):
project_output_dir = "%s/%s" % (build_output_dir, project_name)
library_dir = "%s/%s" % (project_output_dir, library_output_dir)
model_bin_dir = "%s/%s/" % (library_dir, abi)
if abi == "host":
lib_path = "%s/libmace_%s.a" % \
(model_bin_dir, project_name)
else:
if not target_soc:
lib_path = "%s/libmace_%s.a" % \
(model_bin_dir, project_name)
else:
device_name = adb_get_device_name_by_serialno(serial_num)
lib_path = "%s/libmace_%s.%s.%s.a" % \
(model_bin_dir, project_name,
device_name, target_soc)
return lib_path
def merge_libs(target_soc,
serial_num,
abi,
project_name,
build_output_dir,
library_output_dir,
model_build_type,
hexagon_mode):
print("* Merge mace lib")
project_output_dir = "%s/%s" % (build_output_dir, project_name)
hexagon_lib_file = "third_party/nnlib/libhexagon_controller.so"
library_dir = "%s/%s" % (project_output_dir, library_output_dir)
model_bin_dir = "%s/%s/" % (library_dir, abi)
if not os.path.exists(model_bin_dir):
sh.mkdir("-p", model_bin_dir)
if hexagon_mode:
sh.cp("-f", hexagon_lib_file, library_dir)
lib_path = get_lib_path(target_soc, serial_num, abi,
project_name, build_output_dir, library_output_dir)
# make static library
mri_stream = ""
if abi == "host":
mri_stream += "create %s\n" % lib_path
mri_stream += (
"addlib "
"bazel-bin/mace/codegen/libgenerated_opencl.pic.a\n")
mri_stream += (
"addlib "
"bazel-bin/mace/codegen/libgenerated_tuning_params.pic.a\n")
mri_stream += (
"addlib "
"bazel-bin/mace/codegen/libgenerated_version.pic.a\n")
mri_stream += (
"addlib "
"bazel-bin/mace/core/libcore.pic.lo\n")
mri_stream += (
"addlib "
"bazel-bin/mace/kernels/libkernels.pic.a\n")
mri_stream += (
"addlib "
"bazel-bin/mace/utils/libutils.pic.a\n")
mri_stream += (
"addlib "
"bazel-bin/mace/proto/libmace_cc.pic.a\n")
mri_stream += (
"addlib "
"bazel-bin/external/com_google_protobuf/libprotobuf_lite.pic.a\n")
mri_stream += (
"addlib "
"bazel-bin/mace/ops/libops.pic.lo\n")
if model_build_type == BuildType.code:
mri_stream += (
"addlib "
"bazel-bin/mace/codegen/libgenerated_models.pic.a\n")
else:
mri_stream += "create %s\n" % lib_path
if model_build_type == BuildType.code:
mri_stream += (
"addlib "
"bazel-bin/mace/codegen/libgenerated_models.a\n")
mri_stream += (
"addlib "
"bazel-bin/mace/codegen/libgenerated_opencl.a\n")
mri_stream += (
"addlib "
"bazel-bin/mace/codegen/libgenerated_tuning_params.a\n")
mri_stream += (
"addlib "
"bazel-bin/mace/codegen/libgenerated_version.a\n")
mri_stream += (
"addlib "
"bazel-bin/mace/core/libcore.lo\n")
mri_stream += (
"addlib "
"bazel-bin/mace/kernels/libkernels.a\n")
mri_stream += (
"addlib "
"bazel-bin/mace/utils/libutils.a\n")
mri_stream += (
"addlib "
"bazel-bin/mace/proto/libmace_cc.a\n")
mri_stream += (
"addlib "
"bazel-bin/external/com_google_protobuf/libprotobuf_lite.a\n")
mri_stream += (
"addlib "
"bazel-bin/mace/ops/libops.lo\n")
mri_stream += "save\n"
mri_stream += "end\n"
which_sys = platform.system()
if which_sys == "Linux":
cmd = sh.Command("%s/toolchains/" % os.environ["ANDROID_NDK_HOME"] +
"aarch64-linux-android-4.9/prebuilt/linux-x86_64/" +
"bin/aarch64-linux-android-ar")
elif which_sys == "Darwin":
cmd = sh.Command("%s/toolchains/" % os.environ["ANDROID_NDK_HOME"] +
"aarch64-linux-android-4.9/prebuilt/darwin-x86_64/" +
"bin/aarch64-linux-android-ar")
cmd("-M", _in=mri_stream)
print("Libs merged!\n")
def packaging_lib(libmace_output_dir, project_name):
print("* Package libs for %s" % project_name)
tar_package_name = "libmace_%s.tar.gz" % project_name
......@@ -1102,80 +932,13 @@ def packaging_lib(libmace_output_dir, project_name):
print("Packaging Done!\n")
################################
# example
################################
def build_example(target_soc,
serial_num,
abi,
project_name,
build_output_dir,
library_output_dir,
model_output_dir,
build_type,
hexagon_mode,
enable_openmp,
linkshared=False):
static_lib_name = "mace/libmace.a"
if not linkshared:
target_name = "example_static"
lib_path = get_lib_path(target_soc, serial_num, abi, project_name,
build_output_dir, library_output_dir)
sh.cp("-f", lib_path, static_lib_name)
else:
target_name = "example_shared"
example_target = "//mace/examples/cli:%s" % target_name
if build_type == BuildType.code:
build_arg = "--per_file_copt=//mace/examples/cli:example.cc@-DCODE_TYPE" # noqa
else:
build_arg = ""
bazel_build(example_target,
abi=abi,
enable_openmp=enable_openmp,
hexagon_mode=hexagon_mode,
extra_args=build_arg)
example_binary_file = "%s/%s" % (model_output_dir, target_name)
if os.path.exists(example_binary_file):
sh.rm("-rf", example_binary_file)
target_bin = "/".join(bazel_target_to_bin(example_target))
sh.cp("-f", target_bin, model_output_dir)
sh.rm("-rf", static_lib_name)
################################
# benchmark
################################
def build_benchmark_model(abi,
model_output_dir,
hexagon_mode,
enable_openmp,
linkshared=False):
if not linkshared:
target_name = "benchmark_model_static"
else:
target_name = "benchmark_model_shared"
benchmark_target = "//mace/benchmark:%s" % target_name
bazel_build(benchmark_target,
abi=abi,
enable_openmp=enable_openmp,
hexagon_mode=hexagon_mode)
benchmark_binary_file = "%s/%s" % (model_output_dir, target_name)
if os.path.exists(benchmark_binary_file):
sh.rm("-rf", benchmark_binary_file)
target_bin = "/".join(bazel_target_to_bin(benchmark_target))
sh.cp("-f", target_bin, model_output_dir)
def benchmark_model(abi,
serialno,
benchmark_binary_dir,
benchmark_binary_name,
vlog_level,
embed_model_data,
model_output_dir,
......@@ -1187,31 +950,27 @@ def benchmark_model(abi,
model_tag,
device_type,
phone_data_dir,
build_type,
model_graph_format,
opencl_binary_file,
shared_library_dir,
opencl_parameter_file,
libmace_dynamic_library_path,
omp_num_threads=-1,
cpu_affinity_policy=1,
gpu_perf_hint=3,
gpu_priority_hint=3,
input_file_name="model_input",
linkshared=0):
link_dynamic=False):
print("* Benchmark for %s" % model_tag)
if linkshared == 0:
benchmark_model_target = "benchmark_model_static"
else:
benchmark_model_target = "benchmark_model_shared"
mace_model_path = ""
if build_type == BuildType.proto:
if model_graph_format == ModelFormat.file:
mace_model_path = "%s/%s.pb" % (mace_model_dir, model_tag)
if abi == "host":
p = subprocess.Popen(
[
"env",
"MACE_CPP_MIN_VLOG_LEVEL=%s" % vlog_level,
"%s/%s" % (benchmark_binary_dir, benchmark_model_target),
"%s/%s" % (benchmark_binary_dir, benchmark_binary_name),
"--model_name=%s" % model_tag,
"--input_node=%s" % ",".join(input_nodes),
"--output_node=%s" % ",".join(output_nodes),
......@@ -1240,23 +999,25 @@ def benchmark_model(abi,
if not embed_model_data:
adb_push("%s/%s.data" % (mace_model_dir, model_tag),
phone_data_dir, serialno)
if device_type == common.DeviceType.GPU \
and os.path.exists(opencl_binary_file):
adb_push(opencl_binary_file, phone_data_dir, serialno)
if device_type == common.DeviceType.GPU:
if os.path.exists(opencl_binary_file):
adb_push(opencl_binary_file, phone_data_dir, serialno)
if os.path.exists(opencl_parameter_file):
adb_push(opencl_parameter_file, phone_data_dir, serialno)
mace_model_phone_path = ""
if build_type == BuildType.proto:
if model_graph_format == ModelFormat.file:
mace_model_phone_path = "%s/%s.pb" % (phone_data_dir, model_tag)
adb_push(mace_model_path,
mace_model_phone_path,
serialno)
if linkshared == 1:
adb_push("%s/libmace.so" % shared_library_dir, phone_data_dir,
if link_dynamic:
adb_push(libmace_dynamic_library_path, phone_data_dir,
serialno)
adb_push("%s/libgnustl_shared.so" % shared_library_dir,
adb_push(find_gnustl_shared_path(abi),
phone_data_dir,
serialno)
adb_push("%s/%s" % (benchmark_binary_dir, benchmark_model_target),
adb_push("%s/%s" % (benchmark_binary_dir, benchmark_binary_name),
phone_data_dir,
serialno)
......@@ -1267,7 +1028,7 @@ def benchmark_model(abi,
phone_data_dir,
"MACE_INTERNAL_STORAGE_PATH=%s" % internal_storage_dir,
"MACE_OPENCL_PROFILING=1",
"%s/%s" % (phone_data_dir, benchmark_model_target),
"%s/%s" % (phone_data_dir, benchmark_binary_name),
"--model_name=%s" % model_tag,
"--input_node=%s" % ",".join(input_nodes),
"--output_node=%s" % ",".join(output_nodes),
......@@ -1283,6 +1044,8 @@ def benchmark_model(abi,
"--model_file=%s" % mace_model_phone_path,
"--opencl_binary_file=%s/%s" %
(phone_data_dir, os.path.basename(opencl_binary_file)),
"--opencl_parameter_file=%s/%s" %
(phone_data_dir, os.path.basename(opencl_parameter_file)),
]
adb_cmd = ' '.join(adb_cmd)
cmd_file_name = "%s-%s-%s" % ('cmd_file', model_tag, str(time.time()))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册