提交 f2fc2197 编写于 作者: 刘琦

Merge branch 'update_mace_tools_to_python' into 'master'

update mace_tools to python sh

See merge request !400
......@@ -21,9 +21,9 @@
#include <unistd.h>
#include <algorithm>
#include <cstring>
#include <memory>
#include <utility>
#include <cstring>
#include "mace/utils/logging.h"
......
# 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 argparse
import os
import sys
......@@ -15,10 +29,10 @@ import numpy as np
FLAGS = None
def generate_cpp_source():
def generate_cpp_source(binary_dirs, binary_file_name, variable_name):
data_map = {}
for binary_dir in FLAGS.binary_dirs.split(","):
binary_path = os.path.join(binary_dir, FLAGS.binary_file_name)
for binary_dir in binary_dirs.split(","):
binary_path = os.path.join(binary_dir, binary_file_name)
if not os.path.exists(binary_path):
continue
......@@ -49,16 +63,19 @@ def generate_cpp_source():
return env.get_template('str2vec_maps.cc.jinja2').render(
maps=data_map,
data_type='unsigned int',
variable_name=FLAGS.variable_name)
variable_name=variable_name)
def main(unused_args):
cpp_binary_source = generate_cpp_source()
if os.path.isfile(FLAGS.output_path):
os.remove(FLAGS.output_path)
w_file = open(FLAGS.output_path, "w")
def tuning_param_codegen(binary_dirs,
binary_file_name,
output_path,
variable_name):
cpp_binary_source = generate_cpp_source(
binary_dirs, binary_file_name, variable_name)
if os.path.isfile(output_path):
os.remove(output_path)
with open(output_path, "w") as w_file:
w_file.write(cpp_binary_source)
w_file.close()
def parse_args():
......@@ -87,4 +104,7 @@ def parse_args():
if __name__ == '__main__':
FLAGS, unparsed = parse_args()
main(unused_args=[sys.argv[0]] + unparsed)
tuning_param_codegen(FLAGS.binary_dirs,
FLAGS.binary_file_name,
FLAGS.output_path,
FLAGS.variable_name)
# 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.
from mace.proto import mace_pb2
from mace.proto import caffe_pb2
from mace.python.tools import memory_optimizer
......
# 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 tensorflow as tf
from mace.proto import mace_pb2
......
# 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 argparse
import sys
import hashlib
......
# 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.
class DspOps(object):
def __init__(self):
self.dsp_ops = {
......
# 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 argparse
import os
import sys
......@@ -22,22 +36,22 @@ def encrypt_code(code_str):
return encrypted_arr
def main(unused_args):
if not os.path.exists(FLAGS.cl_kernel_dir):
print("Input cl_kernel_dir " + FLAGS.cl_kernel_dir + " doesn't exist!")
def encrypt_opencl_codegen(cl_kernel_dir, output_path):
if not os.path.exists(cl_kernel_dir):
print("Input cl_kernel_dir " + cl_kernel_dir + " doesn't exist!")
header_code = ""
for file_name in os.listdir(FLAGS.cl_kernel_dir):
file_path = os.path.join(FLAGS.cl_kernel_dir, file_name)
for file_name in os.listdir(cl_kernel_dir):
file_path = os.path.join(cl_kernel_dir, file_name)
if file_path[-2:] == ".h":
f = open(file_path, "r")
with open(file_path, "r") as f:
header_code += f.read()
encrypted_code_maps = {}
for file_name in os.listdir(FLAGS.cl_kernel_dir):
file_path = os.path.join(FLAGS.cl_kernel_dir, file_name)
for file_name in os.listdir(cl_kernel_dir):
file_path = os.path.join(cl_kernel_dir, file_name)
if file_path[-3:] == ".cl":
f = open(file_path, "r")
with open(file_path, "r") as f:
code_str = ""
for line in f.readlines():
if "#include <common.h>" in line:
......@@ -54,11 +68,10 @@ def main(unused_args):
data_type='unsigned char',
variable_name='kEncryptedProgramMap')
if os.path.isfile(FLAGS.output_path):
os.remove(FLAGS.output_path)
w_file = open(FLAGS.output_path, "w")
if os.path.isfile(output_path):
os.remove(output_path)
with open(output_path, "w") as w_file:
w_file.write(cpp_cl_encrypted_kernel)
w_file.close()
print("Generate encrypted opencl source done!")
......@@ -81,4 +94,4 @@ def parse_args():
if __name__ == '__main__':
FLAGS, unparsed = parse_args()
main(unused_args=[sys.argv[0]] + unparsed)
encrypt_opencl_codegen(FLAGS.cl_kernel_dir, FLAGS.output_path)
# 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 tensorflow as tf
from mace.proto import mace_pb2
from collections import OrderedDict
......
# 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
import operator
from mace.proto import mace_pb2
......
# 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 argparse
import os
import sys
......@@ -13,12 +27,14 @@ import jinja2
FLAGS = None
def generate_cpp_source():
def generate_cpp_source(cl_binary_dirs,
built_kernel_file_name,
platform_info_file_name):
maps = {}
platform_info = ''
binary_dirs = FLAGS.cl_binary_dirs.strip().split(",")
binary_dirs = cl_binary_dirs.strip().split(",")
for binary_dir in binary_dirs:
binary_path = os.path.join(binary_dir, FLAGS.built_kernel_file_name)
binary_path = os.path.join(binary_dir, built_kernel_file_name)
if not os.path.exists(binary_path):
continue
......@@ -45,7 +61,7 @@ def generate_cpp_source():
maps[key].append(hex(ele))
cl_platform_info_path = os.path.join(binary_dir,
FLAGS.platform_info_file_name)
platform_info_file_name)
with open(cl_platform_info_path, 'r') as f:
curr_platform_info = f.read()
if platform_info != "":
......@@ -61,14 +77,17 @@ def generate_cpp_source():
)
def main(unused_args):
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")
def opencl_codegen(output_path,
cl_binary_dirs="",
built_kernel_file_name="",
platform_info_file_name=""):
cpp_cl_binary_source = generate_cpp_source(cl_binary_dirs,
built_kernel_file_name,
platform_info_file_name)
if os.path.isfile(output_path):
os.remove(output_path)
with open(output_path, "w") as w_file:
w_file.write(cpp_cl_binary_source)
w_file.close()
def parse_args():
......@@ -99,4 +118,7 @@ def parse_args():
if __name__ == '__main__':
FLAGS, unparsed = parse_args()
main(unused_args=[sys.argv[0]] + unparsed)
opencl_codegen(FLAGS.output_path,
FLAGS.cl_binary_dirs,
FLAGS.built_kernel_file_name,
FLAGS.platform_info_file_name)
# 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 os
import uuid
import numpy as np
......@@ -159,9 +173,8 @@ def convert_to_source(net_def, mode_pb_checksum, template_dir, obfuscate,
with open(output_dir + 'tensor_data' + '.cc', "wb") as f:
f.write(source)
if not embed_model_data:
f = open(output_dir + model_tag + '.data', "wb")
with open(output_dir + model_tag + '.data', "wb") as f:
f.write(bytearray(model_data))
f.close()
# generate op source files
template_name = 'operator.jinja2'
......
# 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.
from mace.proto import mace_pb2
import tensorflow as tf
import numpy as np
......
# 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.
from mace.proto import mace_pb2
import tensorflow as tf
from tensorflow import gfile
......
# 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 operator
import functools
import argparse
......
#!/usr/bin/env python
# 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.
# Must run at root dir of libmace project.
# python tools/bazel_adb_run.py \
......@@ -103,7 +115,8 @@ def main(unused_args):
sh_commands.gen_mace_version()
for target_abi in target_abis:
sh_commands.bazel_build(target, abi=target_abi)
sh_commands.bazel_build(target, abi=target_abi,
disable_no_tuning_warning=True)
if FLAGS.run_target:
for serialno in target_devices:
if target_abi not in set(
......
#!/bin/bash
Usage() {
echo "Usage: bash tools/benchmark.sh target_soc model_output_dir option_args"
}
if [ $# -lt 1 ]; then
Usage
exit 1
fi
CURRENT_DIR=`dirname $0`
source ${CURRENT_DIR}/env.sh
TARGET_SOC=$1
MODEL_OUTPUT_DIR=$2
OPTION_ARGS=$3
echo $OPTION_ARGS
RESULT_VALUE=`echo_device_id_by_soc $TARGET_SOC`
if [ $? -ne 0 ]; then
echo $RESULT_VALUE
exit 1
else
DEVICE_ID=$RESULT_VALUE
fi
if [ -f "$MODEL_OUTPUT_DIR/benchmark_model" ]; then
rm -rf $MODEL_OUTPUT_DIR/benchmark_model
fi
if [ "$EMBED_MODEL_DATA" = 0 ]; then
cp codegen/models/${MODEL_TAG}/${MODEL_TAG}.data $MODEL_OUTPUT_DIR
fi
if [ x"$TARGET_ABI" == x"host" ]; then
bazel build --verbose_failures -c opt --strip always \
//mace/benchmark:benchmark_model \
--copt="-std=c++11" \
--copt="-D_GLIBCXX_USE_C99_MATH_TR1" \
--copt="-Werror=return-type" \
--copt="-DMACE_MODEL_TAG=${MODEL_TAG}" \
--copt="-O3" \
--define openmp=true \
--define production=true || exit 1
cp bazel-bin/benchmark/benchmark_model $MODEL_OUTPUT_DIR
MACE_CPP_MIN_VLOG_LEVEL=$VLOG_LEVEL \
${MODEL_OUTPUT_DIR}/benchmark_model \
--model_data_file=${PHONE_DATA_DIR}/${MODEL_TAG}.data \
--device=${DEVICE_TYPE} \
--input_node="${INPUT_NODES}" \
--input_shape="${INPUT_SHAPES}"\
--output_node="${OUTPUT_NODES}" \
--output_shape="${OUTPUT_SHAPES}"\
--input_file=${MODEL_OUTPUT_DIR}/${INPUT_FILE_NAME}_${INPUT_NODES} \
$OPTION_ARGS || exit 1
else
bazel build --verbose_failures -c opt --strip always \
//mace/benchmark:benchmark_model \
--crosstool_top=//external:android/crosstool \
--host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
--cpu=${TARGET_ABI} \
--copt="-std=c++11" \
--copt="-D_GLIBCXX_USE_C99_MATH_TR1" \
--copt="-Werror=return-type" \
--copt="-DMACE_OBFUSCATE_LITERALS" \
--copt="-DMACE_MODEL_TAG=${MODEL_TAG}" \
--define openmp=true \
--define neon=true \
--copt="-O3" \
--define production=true || exit 1
cp bazel-bin/mace/benchmark/benchmark_model $MODEL_OUTPUT_DIR
adb -s $DEVICE_ID shell "mkdir -p ${PHONE_DATA_DIR}" || exit 1
IFS=',' read -r -a INPUT_NAMES <<< "${INPUT_NODES}"
for NAME in "${INPUT_NAMES[@]}";do
FORMATTED_NAME=$(sed s/[^[:alnum:]]/_/g <<< ${NAME})
adb -s $DEVICE_ID push ${MODEL_OUTPUT_DIR}/${INPUT_FILE_NAME}_${FORMATTED_NAME} \
${PHONE_DATA_DIR} > /dev/null || exit 1
done
adb -s $DEVICE_ID push ${MODEL_OUTPUT_DIR}/benchmark_model \
${PHONE_DATA_DIR} > /dev/null || exit 1
if [ "$EMBED_MODEL_DATA" = 0 ]; then
adb -s $DEVICE_ID push ${MODEL_OUTPUT_DIR}/${MODEL_TAG}.data \
${PHONE_DATA_DIR} > /dev/null || exit 1
fi
adb -s $DEVICE_ID </dev/null shell \
LD_LIBRARY_PATH=${PHONE_DATA_DIR} \
MACE_CPP_MIN_VLOG_LEVEL=$VLOG_LEVEL \
MACE_RUN_PARAMETER_PATH=${PHONE_DATA_DIR}/mace_run.config \
MACE_LIMIT_OPENCL_KERNEL_TIME=${LIMIT_OPENCL_KERNEL_TIME} \
MACE_OPENCL_PROFILING=1 \
${PHONE_DATA_DIR}/benchmark_model \
--model_data_file=${PHONE_DATA_DIR}/${MODEL_TAG}.data \
--device=${DEVICE_TYPE} \
--input_node="${INPUT_NODES}" \
--input_shape="${INPUT_SHAPES}"\
--output_node="${OUTPUT_NODES}" \
--output_shape="${OUTPUT_SHAPES}"\
--input_file=${PHONE_DATA_DIR}/${INPUT_FILE_NAME} \
$OPTION_ARGS || exit 1
fi
#!/bin/bash
Usage() {
echo "Usage: bash tools/build_mace_run.sh production_mode model_output_dir hexagon_mode"
}
if [ $# -lt 3 ]; then
Usage
exit 1
fi
CURRENT_DIR=`dirname $0`
source ${CURRENT_DIR}/env.sh
PRODUCTION_MODE=$1
MODEL_OUTPUT_DIR=$2
HEXAGON_MODE=$3
if [ "$PRODUCTION_MODE" = 1 ]; then
PRODUCTION_MODE_BUILD_FLAGS="--define production=true"
fi
if [ x"$TARGET_ABI" = x"host" ]; then
bazel build --verbose_failures -c opt --strip always //mace/codegen:generated_models \
--copt="-std=c++11" \
--copt="-D_GLIBCXX_USE_C99_MATH_TR1" \
--copt="-Werror=return-type" \
--copt="-DMACE_MODEL_TAG=${MODEL_TAG}" \
--define openmp=true \
--copt="-O3" \
$PRODUCTION_MODE_BUILD_FLAGS || exit 1
bazel build --verbose_failures -c opt --strip always //mace/tools/validation:mace_run \
--copt="-std=c++11" \
--copt="-D_GLIBCXX_USE_C99_MATH_TR1" \
--copt="-Werror=return-type" \
--copt="-DMACE_MODEL_TAG=${MODEL_TAG}" \
--define openmp=true \
--copt="-O3" \
$PRODUCTION_MODE_BUILD_FLAGS || exit 1
else
if [ "$HEXAGON_MODE" = 1 ]; then
HEXAGON_MODE_BUILD_FLAG="--define hexagon=true"
fi
if [ x"$TARGET_ABI" = x"arm64-v8a" ]; then
NEON_ENABLE_FLAG="--define neon=true"
fi
bazel build --verbose_failures -c opt --strip always //mace/tools/validation:mace_run \
--crosstool_top=//external:android/crosstool \
--host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
--cpu=${TARGET_ABI} \
--copt="-std=c++11" \
--copt="-D_GLIBCXX_USE_C99_MATH_TR1" \
--copt="-Werror=return-type" \
--copt="-DMACE_OBFUSCATE_LITERALS" \
--copt="-DMACE_MODEL_TAG=${MODEL_TAG}" \
--define openmp=true \
--define neon=true \
--copt="-O3" \
$NEON_ENABLE_FLAG \
$PRODUCTION_MODE_BUILD_FLAGS \
$HEXAGON_MODE_BUILD_FLAG || exit 1
fi
rm -rf $MODEL_OUTPUT_DIR/libmace_${MODEL_TAG}.a
cp $GENERATED_MODEL_LIB_PATH $MODEL_OUTPUT_DIR/libmace_${MODEL_TAG}.a
if [ -f "$MODEL_OUTPUT_DIR/mace_run" ]; then
rm -rf $MODEL_OUTPUT_DIR/mace_run
fi
cp bazel-bin/mace/tools/validation/mace_run $MODEL_OUTPUT_DIR
if [ "$EMBED_MODEL_DATA" = 0 ]; then
cp mace/codegen/models/${MODEL_TAG}/${MODEL_TAG}.data $MODEL_OUTPUT_DIR
fi
# copy model header file to build output dir
cp mace/codegen/models/${MODEL_TAG}/${MODEL_TAG}.h $MODEL_OUTPUT_DIR
#!/bin/bash
Usage() {
echo "Usage: bash tools/build_production_code.sh"
}
CURRENT_DIR=`dirname $0`
source ${CURRENT_DIR}/env.sh
build_host_target()
{
BAZEL_TARGET=$1
bazel build --verbose_failures -c opt --strip always $BAZEL_TARGET \
--copt="-std=c++11" \
--copt="-D_GLIBCXX_USE_C99_MATH_TR1" \
--copt="-Werror=return-type" \
--copt="-DMACE_OBFUSCATE_LITERALS" \
--copt="-O3" \
--define openmp=true || exit -1
}
build_target()
{
BAZEL_TARGET=$1
bazel build --verbose_failures -c opt --strip always $BAZEL_TARGET \
--crosstool_top=//external:android/crosstool \
--host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
--cpu=$TARGET_ABI \
--copt="-std=c++11" \
--copt="-D_GLIBCXX_USE_C99_MATH_TR1" \
--copt="-Werror=return-type" \
--copt="-O3" \
--define openmp=true \
--copt="-DMACE_OBFUSCATE_LITERALS" || exit 1
}
if [ x"$TARGET_ABI" = x"host" ]; then
build_host_target //mace/codegen:generated_opencl
build_host_target //mace/codegen:generated_tuning_params
else
build_target //mace/codegen:generated_opencl
build_target //mace/codegen:generated_tuning_params
fi
#!/bin/bash
Usage() {
echo "Usage: bash tools/build_run_throughput_test.sh target_soc run_seconds merged_lib_file model_input_dir"
}
if [ $# -lt 4 ]; then
Usage
exit 1
fi
CURRENT_DIR=`dirname $0`
source ${CURRENT_DIR}/env.sh
TARGET_SOC=$1
RUN_SECONDS=$2
MERGED_LIB_FILE=$3
MODEL_INPUT_DIR=$4
RESULT_VALUE=`echo_device_id_by_soc $TARGET_SOC`
if [ $? -ne 0 ]; then
echo $RESULT_VALUE
exit 1
else
DEVICE_ID=$RESULT_VALUE
fi
if [ "$CPU_MODEL_TAG" != '' ]; then
CPU_MODEL_TAG_BUILD_FLAGS="--copt=-DMACE_CPU_MODEL_TAG=${CPU_MODEL_TAG}"
fi
if [ "$GPU_MODEL_TAG" != '' ]; then
GPU_MODEL_TAG_BUILD_FLAGS="--copt=-DMACE_GPU_MODEL_TAG=${GPU_MODEL_TAG}"
fi
if [ "$DSP_MODEL_TAG" != '' ]; then
DSP_MODEL_TAG_BUILD_FLAGS="--copt=-DMACE_DSP_MODEL_TAG=${DSP_MODEL_TAG}"
fi
cp $MERGED_LIB_FILE mace/benchmark/libmace_merged.a
bazel build --verbose_failures -c opt --strip always //mace/benchmark:model_throughput_test \
--crosstool_top=//external:android/crosstool \
--host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
--cpu=${TARGET_ABI} \
--copt="-std=c++11" \
--copt="-D_GLIBCXX_USE_C99_MATH_TR1" \
--copt="-Werror=return-type" \
${CPU_MODEL_TAG_BUILD_FLAGS} \
${GPU_MODEL_TAG_BUILD_FLAGS} \
${DSP_MODEL_TAG_BUILD_FLAGS} \
--define openmp=true \
--copt="-O3" || exit 1
rm mace/benchmark/libmace_merged.a
adb -s $DEVICE_ID shell "mkdir -p ${PHONE_DATA_DIR}" || exit 1
adb -s $DEVICE_ID push ${MODEL_INPUT_DIR}/${INPUT_FILE_NAME}_${INPUT_NODES} ${PHONE_DATA_DIR} || exit 1
adb -s $DEVICE_ID push bazel-bin/mace/benchmark/model_throughput_test ${PHONE_DATA_DIR} || exit 1
if [ "$EMBED_MODEL_DATA" = 0 ]; then
adb -s $DEVICE_ID push codegen/models/${CPU_MODEL_TAG}/${CPU_MODEL_TAG}.data ${PHONE_DATA_DIR} || exit 1
adb -s $DEVICE_ID push codegen/models/${GPU_MODEL_TAG}/${GPU_MODEL_TAG}.data ${PHONE_DATA_DIR} || exit 1
adb -s $DEVICE_ID push codegen/models/${DSP_MODEL_TAG}/${DSP_MODEL_TAG}.data ${PHONE_DATA_DIR} || exit 1
fi
adb -s $DEVICE_ID push mace/core/runtime/hexagon/libhexagon_controller.so ${PHONE_DATA_DIR} || exit 1
adb -s $DEVICE_ID </dev/null shell \
LD_LIBRARY_PATH=${PHONE_DATA_DIR} \
MACE_CPP_MIN_VLOG_LEVEL=$VLOG_LEVEL \
MACE_RUN_PARAMETER_PATH=${PHONE_DATA_DIR}/mace_run.config \
MACE_KERNEL_PATH=$KERNEL_DIR \
MACE_LIMIT_OPENCL_KERNEL_TIME=${LIMIT_OPENCL_KERNEL_TIME} \
${PHONE_DATA_DIR}/model_throughput_test \
--input_node="${INPUT_NODES}" \
--input_shape="${INPUT_SHAPES}" \
--output_node="${OUTPUT_NODES}" \
--output_shape="${OUTPUT_SHAPES}" \
--input_file=${PHONE_DATA_DIR}/${INPUT_FILE_NAME} \
--cpu_model_data_file=${PHONE_DATA_DIR}/${CPU_MODEL_TAG}.data \
--gpu_model_data_file=${PHONE_DATA_DIR}/${GPU_MODEL_TAG}.data \
--dsp_model_data_file=${PHONE_DATA_DIR}/${DSP_MODEL_TAG}.data \
--run_seconds=$RUN_SECONDS || exit 1
#!/bin/bash
Usage() {
echo "Usage: bash tools/clear_env.sh target_soc"
}
if [ $# -lt 1 ]; then
Usage
exit 1
fi
CURRENT_DIR=`dirname $0`
source ${CURRENT_DIR}/env.sh
TARGET_SOC=$1
RESULT_VALUE=`echo_device_id_by_soc $TARGET_SOC`
if [ $? -ne 0 ]; then
echo $RESULT_VALUE
exit 1
else
DEVICE_ID=$RESULT_VALUE
fi
if [ x"$TARGET_ABI" != x"host" ]; then
adb -s $DEVICE_ID shell rm -rf $PHONE_DATA_DIR || exit 1
fi
rm -rf mace/codegen/models
#!/usr/bin/env bash
LIBMACE_TAG=`git describe --abbrev=0 --tags`
MACE_SOURCE_DIR=`/bin/pwd`
PHONE_DATA_DIR="/data/local/tmp/mace_run"
COMPILED_PROGRAM_DIR="${PHONE_DATA_DIR}/cl_program/"
CODEGEN_DIR=${MACE_SOURCE_DIR}/mace/codegen
MODEL_CODEGEN_DIR=${CODEGEN_DIR}/models/${MODEL_TAG}
CL_CODEGEN_DIR=${CODEGEN_DIR}/opencl
TUNING_CODEGEN_DIR=${CODEGEN_DIR}/tuning
VERSION_SOURCE_PATH=${CODEGEN_DIR}/version
CL_BUILT_KERNEL_FILE_NAME=mace_cl_compiled_program.bin
CL_PLATFORM_INFO_FILE_NAME=mace_cl_platform_info.txt
if [ -z ${EMBED_MODEL_DATA} ]; then
EMBED_MODEL_DATA=1
fi
if [ x"$RUNTIME" = x"dsp" ]; then
DATA_TYPE="DT_UINT8"
DEVICE_TYPE="HEXAGON"
LIB_FOLDER_NAME="${LIB_FOLDER_NAME}_dsp"
elif [ x"$RUNTIME" = x"gpu" ]; then
DATA_TYPE="DT_HALF"
DEVICE_TYPE="OPENCL"
elif [ x"$RUNTIME" = x"cpu" ]; then
DATA_TYPE="DT_FLOAT"
DEVICE_TYPE="CPU"
elif [ x"$RUNTIME" = x"neon" ]; then
DATA_TYPE="DT_FLOAT"
DEVICE_TYPE="NEON"
fi
GENERATED_MODEL_LIB_NAME="libgenerated_models.a"
if [ x"$TARGET_ABI" = x"host" ]; then
GENERATED_MODEL_LIB_NAME="libgenerated_models.pic.a"
fi
GENERATED_MODEL_LIB_PATH="bazel-bin/mace/codegen/${GENERATED_MODEL_LIB_NAME}"
echo_device_id_by_soc()
{
TARGET_SOC=$1
for device in `adb devices | grep "^[A-Za-z0-9]\+[[:space:]]\+device$"| cut -f1`; do
device_soc=`adb -s ${device} shell getprop | grep ro.board.platform | cut -d [ -f3 | cut -d ] -f1`
if [ x"$TARGET_SOC" = x"$device_soc" ]; then
echo "$device"
return 0
fi
done
echo "MACE ERROR: Not found device with soc ${TARGET_SOC}"
return 1
}
# 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 json
import socket
import itertools
......
# 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 argparse
import sys
import numpy as np
......@@ -12,22 +26,22 @@ import re
#
def generate_data(name, shape):
def generate_data(name, shape, input_file):
np.random.seed()
data = np.random.random(shape) * 2 - 1
input_file_name = FLAGS.input_file + "_" + re.sub('[^0-9a-zA-Z]+', '_',
input_file_name = input_file + "_" + re.sub('[^0-9a-zA-Z]+', '_',
name)
print 'Generate input file: ', input_file_name
data.astype(np.float32).tofile(input_file_name)
def main(unused_args):
input_names = [name for name in FLAGS.input_node.split(',')]
input_shapes = [shape for shape in FLAGS.input_shape.split(':')]
def generate_input_data(input_file, input_node, input_shape):
input_names = [name for name in input_node.split(',')]
input_shapes = [shape for shape in input_shape.split(':')]
assert len(input_names) == len(input_shapes)
for i in range(len(input_names)):
shape = [int(x) for x in input_shapes[i].split(',')]
generate_data(input_names[i], shape)
generate_data(input_names[i], shape, input_file)
print "Generate input file done."
......@@ -47,4 +61,4 @@ def parse_args():
if __name__ == '__main__':
FLAGS, unparsed = parse_args()
main(unused_args=[sys.argv[0]] + unparsed)
generate_input_data(FLAGS.input_file, FLAGS.input_node, FLAGS.input_shape)
#!/bin/bash
CURRENT_DIR=`dirname $0`
source ${CURRENT_DIR}/env.sh
bazel build //mace/python/tools:converter || exit 1
rm -rf ${MODEL_CODEGEN_DIR}
mkdir -p ${MODEL_CODEGEN_DIR}
if [ ${DSP_MODE} ]; then
DSP_MODE_FLAG="--dsp_mode=${DSP_MODE}"
fi
PYTHONUNBUFFERED=1 bazel-bin/mace/python/tools/converter --platform=${PLATFORM} \
--model_file=${MODEL_FILE_PATH} \
--weight_file=${WEIGHT_FILE_PATH} \
--model_checksum=${MODEL_SHA256_CHECKSUM} \
--output=${MODEL_CODEGEN_DIR}/model.cc \
--input_node=${INPUT_NODES} \
--output_node=${OUTPUT_NODES} \
--data_type=${DATA_TYPE} \
--runtime=${RUNTIME} \
--output_type=source \
--template=${MACE_SOURCE_DIR}/mace/python/tools \
--model_tag=${MODEL_TAG} \
--input_shape=${INPUT_SHAPES} \
${DSP_MODE_FLAG} \
--embed_model_data=${EMBED_MODEL_DATA} \
--winograd=${FAST_CONV} \
--obfuscate=${OBFUSCATE} || exit 1
#!/usr/bin/env bash
Usage() {
echo "Usage: bash tools/genenrate_opencl_code.sh type [target_soc] [cl_bin_dirs] [pull_or_not]"
}
if [ $# -lt 1 ]; then
Usage
exit 1
fi
CURRENT_DIR=`dirname $0`
source ${CURRENT_DIR}/env.sh
TYPE=$1
TARGET_SOC=$2
CL_BIN_DIRS=$3
PULL_OR_NOT=$4
mkdir -p ${CL_CODEGEN_DIR}
if [ x"$TYPE" == x"source" ];then
python mace/python/tools/encrypt_opencl_codegen.py \
--cl_kernel_dir=./mace/kernels/opencl/cl/ \
--output_path=${CODEGEN_DIR}/opencl/opencl_encrypt_program.cc || exit 1
elif [ x"$#" == x"1" ];then
python mace/python/tools/opencl_codegen.py \
--built_kernel_file_name=${CL_BUILT_KERNEL_FILE_NAME} \
--platform_info_file_name=${CL_PLATFORM_INFO_FILE_NAME} \
--output_path=${CL_CODEGEN_DIR}/opencl_compiled_program.cc || exit 1
else
RESULT_VALUE=`echo_device_id_by_soc $TARGET_SOC`
if [ $? -ne 0 ]; then
echo $RESULT_VALUE
exit 1
else
DEVICE_ID=$RESULT_VALUE
fi
if [ "$PULL_OR_NOT" = 1 ]; then
CL_BIN_DIR=${CL_BIN_DIRS}
mkdir -p ${CL_BIN_DIR}
rm -rf ${CL_BIN_DIR}/${CL_BUILT_KERNEL_FILE_NAME}
rm -rf ${CL_BIN_DIR}/${CL_PLATFORM_INFO_FILE_NAME}
if [ x"$TARGET_ABI" != x"host" ]; then
adb -s $DEVICE_ID pull ${COMPILED_PROGRAM_DIR}/. ${CL_BIN_DIR} > /dev/null
fi
fi
python mace/python/tools/opencl_codegen.py \
--built_kernel_file_name=${CL_BUILT_KERNEL_FILE_NAME} \
--platform_info_file_name=${CL_PLATFORM_INFO_FILE_NAME} \
--cl_binary_dirs=${CL_BIN_DIRS} \
--output_path=${CL_CODEGEN_DIR}/opencl_compiled_program.cc || exit 1
fi
#!/bin/bash
CURRENT_DIR=`dirname $0`
source ${CURRENT_DIR}/env.sh
mkdir -p ${TUNING_CODEGEN_DIR}
if [ "$#" -eq "0" ]; then
python mace/python/tools/binary_codegen.py \
--binary_file_name=mace_run.config \
--output_path=${TUNING_CODEGEN_DIR}/tuning_params.cc
else
TARGET_SOC=$1
BIN_DIRS=$2
PULL_OR_NOT=$3
RESULT_VALUE=`echo_device_id_by_soc $TARGET_SOC`
if [ $? -ne 0 ]; then
echo $RESULT_VALUE
exit 1
else
DEVICE_ID=$RESULT_VALUE
fi
if [ "$PULL_OR_NOT" = 1 ]; then
mkdir -p ${BIN_DIRS}
rm -rf ${BIN_DIRS}/mace_run.config
if [ x"$TARGET_ABI" != x"host" ]; then
adb -s $DEVICE_ID pull ${PHONE_DATA_DIR}/mace_run.config ${BIN_DIRS} > /dev/null
fi
fi
python mace/python/tools/binary_codegen.py \
--binary_dirs=${BIN_DIRS} \
--binary_file_name=mace_run.config \
--output_path=${TUNING_CODEGEN_DIR}/tuning_params.cc
fi
#!/bin/bash
CL_KERNEL_DIR_TAG=$1
CURRENT_DIR=`dirname $0`
source ${CURRENT_DIR}/env.sh
rm -rf ${CODEGEN_DIR}/version
mkdir ${CODEGEN_DIR}/version
bash mace/tools/git/gen_version_source.sh ${CODEGEN_DIR}/version/version.cc || exit 1
#!/usr/bin/env python
# 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.
# Must run at root dir of libmace project.
# python tools/mace_tools.py \
# --config=tools/example.yaml \
# --round=100 \
# --mode=all
import argparse
import filelock
import hashlib
import os
import sh
import shutil
import subprocess
import sys
import urllib
......@@ -22,24 +33,50 @@ import sh_commands
from ConfigParser import ConfigParser
def run_command(command):
print("Run command: {}".format(command))
result = subprocess.Popen(
command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = result.communicate()
def get_target_socs(configs):
available_socs = sh_commands.adb_get_all_socs()
target_socs = available_socs
if hasattr(configs, "target_socs"):
target_socs = set(configs["target_socs"])
target_socs = target_socs & available_socs
if FLAGS.target_socs != "all":
socs = set(FLAGS.target_socs.split(','))
target_socs = target_socs & socs
missing_socs = socs.difference(target_socs)
if len(missing_socs) > 0:
print(
"Error: devices with SoCs are not connected %s" % missing_socs)
exit(1)
if not target_socs:
print("Error: no device to run")
exit(1)
return target_socs
if out:
print("Stdout msg:\n{}".format(out))
if err:
print("Stderr msg:\n{}".format(err))
def get_data_and_device_type(runtime):
data_type = ""
device_type = ""
if result.returncode != 0:
raise Exception(
"Exit not 0 from bash with code: {}, command: {}".format(
result.returncode, command))
if runtime == "dsp":
data_type = "DT_UINT8"
device_type = "HEXAGON"
elif runtime == "gpu":
data_type = "DT_HALF"
device_type = "OPENCL"
elif runtime == "cpu":
data_type = "DT_FLOAT"
device_type = "CPU"
elif runtime == "neon":
data_type = "DT_FLOAT"
device_type = "NEON"
return data_type, device_type
def get_global_runtime(configs):
def get_hexagon_mode(configs):
runtime_list = []
for model_name in configs["models"]:
model_runtime = configs["models"][model_name]["runtime"]
......@@ -47,141 +84,37 @@ def get_global_runtime(configs):
global_runtime = ""
if "dsp" in runtime_list:
global_runtime = "dsp"
elif "gpu" in runtime_list:
global_runtime = "gpu"
elif "cpu" in runtime_list:
global_runtime = "cpu"
elif "neon" in runtime_list:
global_runtime = "neon"
else:
raise Exception("Not found available RUNTIME in config files!")
return global_runtime
def generate_version_code():
command = "bash tools/generate_version_code.sh"
run_command(command)
def generate_opencl_source_code():
command = "bash tools/generate_opencl_code.sh source"
run_command(command)
def generate_opencl_binay_code(target_soc, model_output_dirs, pull_or_not):
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 not cl_bin_dirs:
command = "bash tools/generate_opencl_code.sh binary"
else:
command = "bash tools/generate_opencl_code.sh {} {} {} {}".format(
'binary', target_soc, cl_bin_dirs_str, int(pull_or_not))
run_command(command)
def generate_tuning_param_code(target_soc, model_output_dirs, pull_or_not):
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 not cl_bin_dirs:
command = "bash tools/generate_tuning_param_code.sh"
else:
command = "bash tools/generate_tuning_param_code.sh {} {} {}".format(
target_soc, cl_bin_dirs_str, int(pull_or_not))
run_command(command)
def generate_code(target_soc, model_output_dirs, pull_or_not):
generate_opencl_binay_code(target_soc, model_output_dirs, pull_or_not)
generate_tuning_param_code(target_soc, model_output_dirs, pull_or_not)
def clear_env(target_soc):
command = "bash tools/clear_env.sh {}".format(target_soc)
run_command(command)
def input_file_name(input_name):
return os.environ['INPUT_FILE_NAME'] + '_' + \
re.sub('[^0-9a-zA-Z]+', '_', input_name)
def generate_random_input(target_soc, model_output_dir, input_names,
input_files):
generate_data_or_not = True
command = "bash tools/validate_tools.sh {} {} {}".format(
target_soc, model_output_dir, int(generate_data_or_not))
run_command(command)
input_file_list = []
if isinstance(input_files, list):
input_file_list.extend(input_files)
else:
input_file_list.append(input_files)
if len(input_file_list) != 0:
input_name_list = []
if isinstance(input_names, list):
input_name_list.extend(input_names)
else:
input_name_list.append(input_names)
if len(input_file_list) != len(input_name_list):
raise Exception('If input_files set, the input files should '
'match the input names.')
for i in range(len(input_file_list)):
if input_file_list[i] is not None:
dst_input_file = model_output_dir + '/' + input_file_name(
input_name_list[i])
if input_file_list[i].startswith("http://") or \
input_file_list[i].startswith("https://"):
urllib.urlretrieve(input_file_list[i], dst_input_file)
else:
shutil.copy(input_file_list[i], dst_input_file)
def generate_model_code():
command = "bash tools/generate_model_code.sh"
run_command(command)
def build_mace_run(production_mode, model_output_dir, hexagon_mode):
command = "bash tools/build_mace_run.sh {} {} {}".format(
int(production_mode), model_output_dir, int(hexagon_mode))
run_command(command)
def tuning_run(model_name,
target_runtime,
return True
return False
def gen_opencl_and_tuning_code(target_soc,
target_abi,
model_output_dirs,
pull_or_not):
if pull_or_not:
sh_commands.pull_binaries(
target_soc, target_abi, model_output_dirs)
codegen_path = "mace/codegen"
# generate opencl binary code
sh_commands.gen_opencl_binary_code(target_soc, model_output_dirs)
sh_commands.gen_tuning_param_code(
target_soc, model_output_dirs)
def model_benchmark_stdout_processor(stdout,
target_soc,
model_output_dir,
running_round,
tuning,
restart_round,
option_args='',
out_of_range_check=False):
# TODO(yejianwu) refactoring the hackish code
stdout_buff = []
process_output = sh_commands.make_output_processor(stdout_buff)
p = sh.bash(
"tools/tuning_run.sh",
target_soc,
model_output_dir,
abi,
runtime,
running_round,
int(tuning),
restart_round,
option_args,
int(out_of_range_check),
_out=process_output,
_bg=True,
_err_to_out=True)
p.wait()
tuning):
metrics = {}
for line in stdout_buff:
for line in stdout:
if "Aborted" in line:
raise Exception("Command failed")
line = line.strip()
parts = line.split()
if len(parts) == 6 and parts[0].startswith("time"):
......@@ -195,8 +128,8 @@ def tuning_run(model_name,
float(parts[5]))
tags = {
"ro.board.platform": target_soc,
"abi": target_abi,
# "runtime": target_runtime, # TODO(yejianwu) Add the actual runtime
"abi": abi,
"runtime": runtime,
"round": running_round, # TODO(yejianwu) change this to source/binary
"tuning": tuning
}
......@@ -204,113 +137,131 @@ def tuning_run(model_name,
metrics, endpoint="mace_model_benchmark", tags=tags)
def benchmark_model(target_soc, model_output_dir, option_args=''):
command = "bash tools/benchmark.sh {} {} \"{}\"".format(
target_soc, model_output_dir, option_args)
run_command(command)
def run_model(model_name, target_runtime, target_abi, target_soc,
model_output_dir, running_round, restart_round, option_args,
out_of_range_check):
tuning_run(model_name, target_runtime, target_abi, target_soc,
model_output_dir, running_round, False, restart_round,
option_args, out_of_range_check)
def generate_production_code(target_soc, model_output_dirs, pull_or_not):
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)
command = "bash tools/generate_production_code.sh {} {} {}".format(
target_soc, cl_bin_dirs_str, int(pull_or_not))
run_command(command)
def build_mace_run_prod(model_name, target_runtime, target_abi, target_soc,
model_output_dir, tuning):
if "dsp" == target_runtime:
hexagon_mode = True
else:
hexagon_mode = False
generate_code(target_soc, [], False)
production_or_not = False
build_mace_run(production_or_not, model_output_dir, hexagon_mode)
tuning_run(
model_name,
target_runtime,
target_abi,
def tuning_run(runtime,
target_soc,
target_abi,
vlog_level,
embed_model_data,
model_output_dir,
running_round=0,
tuning=False,
restart_round=1,
out_of_range_check=True)
tuning_run(
input_nodes,
output_nodes,
input_shapes,
output_shapes,
model_name,
target_runtime,
target_abi,
device_type,
running_round,
restart_round,
out_of_range_check,
phone_data_dir,
tuning=False,
limit_opencl_kernel_time=0,
option_args=""):
stdout = sh_commands.tuning_run(
target_soc,
target_abi,
vlog_level,
embed_model_data,
model_output_dir,
running_round=0,
tuning=tuning,
restart_round=1)
generate_code(target_soc, [model_output_dir], True)
production_or_not = True
build_mace_run(production_or_not, model_output_dir, hexagon_mode)
def build_run_throughput_test(target_soc, run_seconds, merged_lib_file,
model_input_dir):
command = "bash tools/build_run_throughput_test.sh {} {} {} {}".format(
target_soc, run_seconds, merged_lib_file, model_input_dir)
run_command(command)
def validate_model(target_soc, model_output_dir):
generate_data_or_not = False
command = "bash tools/validate_tools.sh {} {} {}".format(
target_soc, model_output_dir, int(generate_data_or_not))
run_command(command)
def build_production_code():
command = "bash tools/build_production_code.sh"
run_command(command)
input_nodes,
output_nodes,
input_shapes,
output_shapes,
model_name,
device_type,
running_round,
restart_round,
limit_opencl_kernel_time,
tuning,
out_of_range_check,
phone_data_dir,
option_args)
model_benchmark_stdout_processor(stdout,
target_soc,
target_abi,
runtime,
running_round,
tuning)
def merge_libs_and_tuning_results(target_soc, output_dir, model_output_dirs):
generate_code(target_soc, model_output_dirs, False)
build_production_code()
model_output_dirs_str = ",".join(model_output_dirs)
command = "bash tools/merge_libs.sh {} {} {}".format(
target_soc, output_dir, model_output_dirs_str)
run_command(command)
def build_mace_run_prod(hexagon_mode, runtime, target_soc, target_abi,
vlog_level, embed_model_data, model_output_dir,
input_nodes, output_nodes, input_shapes, output_shapes,
model_name, device_type, running_round, restart_round,
tuning, limit_opencl_kernel_time, phone_data_dir):
gen_opencl_and_tuning_code(target_soc, target_abi, [], False)
production_or_not = False
mace_run_target = "//mace/tools/validation:mace_run"
sh_commands.bazel_build(
mace_run_target,
abi=target_abi,
model_tag=model_name,
production_mode=False,
hexagon_mode=hexagon_mode)
sh_commands.update_mace_run_lib(model_output_dir, target_abi, model_name,
embed_model_data)
tuning_run(runtime, target_soc, target_abi, vlog_level, embed_model_data,
model_output_dir, input_nodes, output_nodes, input_shapes,
output_shapes, model_name, device_type, running_round=0,
restart_round=1, out_of_range_check=True,
phone_data_dir=phone_data_dir, tuning=False)
tuning_run(runtime, target_soc, target_abi, vlog_level, embed_model_data,
model_output_dir, input_nodes, output_nodes, input_shapes,
output_shapes, model_name, device_type, running_round=0,
restart_round=1, out_of_range_check=False,
phone_data_dir=phone_data_dir, tuning=tuning,
limit_opencl_kernel_time=limit_opencl_kernel_time)
gen_opencl_and_tuning_code(
target_soc, target_abi, [model_output_dir], True)
production_or_not = True
sh_commands.bazel_build(
mace_run_target,
abi=target_abi,
model_tag=model_name,
production_mode=True,
hexagon_mode=hexagon_mode)
sh_commands.update_mace_run_lib(model_output_dir, target_abi, model_name,
embed_model_data)
def packaging_lib_file(output_dir):
command = "bash tools/packaging_lib.sh {}".format(output_dir)
run_command(command)
def merge_libs_and_tuning_results(target_soc,
target_abi,
project_name,
output_dir,
model_output_dirs,
hexagon_mode,
embed_model_data):
gen_opencl_and_tuning_code(
target_soc, target_abi, model_output_dirs, False)
sh_commands.build_production_code(target_abi)
sh_commands.merge_libs(target_soc,
target_abi,
project_name,
output_dir,
model_output_dirs,
hexagon_mode,
embed_model_data)
def download_model_files(model_file_path,
model_output_dir,
weight_file_path=""):
model_file = ""
weight_file = ""
if model_file_path.startswith("http://") or \
model_file_path.startswith("https://"):
os.environ["MODEL_FILE_PATH"] = model_output_dir + "/model.pb"
urllib.urlretrieve(model_file_path, os.environ["MODEL_FILE_PATH"])
model_file = model_output_dir + "/model.pb"
urllib.urlretrieve(model_file_path, model_file)
if weight_file_path.startswith("http://") or \
weight_file_path.startswith("https://"):
os.environ["WEIGHT_FILE_PATH"] = model_output_dir + "/model.caffemodel"
urllib.urlretrieve(weight_file_path, os.environ["WEIGHT_FILE_PATH"])
weight_file = model_output_dir + "/model.caffemodel"
urllib.urlretrieve(weight_file_path, weight_file)
return model_file, weight_file
def md5sum(str):
......@@ -368,142 +319,230 @@ def parse_args():
return parser.parse_known_args()
def set_environment(configs):
os.environ["EMBED_MODEL_DATA"] = str(configs["embed_model_data"])
os.environ["VLOG_LEVEL"] = str(configs["vlog_level"])
os.environ["PROJECT_NAME"] = os.path.splitext(
os.path.basename(FLAGS.config))[0]
os.environ['INPUT_FILE_NAME'] = "model_input"
os.environ['OUTPUT_FILE_NAME'] = "model_out"
def main(unused_args):
configs = parse_model_configs()
if FLAGS.mode == "validate":
FLAGS.round = 1
FLAGS.restart_round = 1
set_environment(configs)
if FLAGS.mode == "build" or FLAGS.mode == "all":
# Remove previous output dirs
if not os.path.exists(FLAGS.output_dir):
os.makedirs(FLAGS.output_dir)
elif os.path.exists(os.path.join(FLAGS.output_dir, "libmace")):
shutil.rmtree(
os.path.join(FLAGS.output_dir, os.environ["PROJECT_NAME"]))
os.makedirs(
os.path.join(FLAGS.output_dir, os.environ["PROJECT_NAME"]))
generate_version_code()
generate_opencl_source_code()
option_args = ' '.join(
[arg for arg in unused_args if arg.startswith('--')])
available_socs = sh_commands.adb_get_all_socs()
target_socs = available_socs
if hasattr(configs, "target_socs"):
target_socs = set(configs["target_socs"])
target_socs = target_socs & available_socs
if FLAGS.target_socs != "all":
socs = set(FLAGS.target_socs.split(','))
target_socs = target_socs & socs
missing_socs = socs.difference(target_socs)
if len(missing_socs) > 0:
print(
"Error: devices with SoCs are not connected %s" % missing_socs)
exit(1)
for target_soc in target_socs:
for target_abi in configs["target_abis"]:
global_runtime = get_global_runtime(configs)
# Transfer params by environment
os.environ["TARGET_ABI"] = target_abi
def process_models(project_name, configs, embed_model_data, vlog_level,
target_soc, target_abi, phone_data_dir, option_args):
hexagon_mode = get_hexagon_mode(configs)
model_output_dirs = []
for model_name in configs["models"]:
print '===================', model_name, '==================='
# Transfer params by environment
os.environ["MODEL_TAG"] = model_name
model_config = configs["models"][model_name]
input_file_list = model_config.get("validation_inputs_data",
[])
for key in model_config:
if key in ['input_nodes', 'output_nodes'] and isinstance(
model_config[key], list):
os.environ[key.upper()] = ",".join(model_config[key])
elif key in ['input_shapes', 'output_shapes'
] and isinstance(model_config[key], list):
os.environ[key.upper()] = ":".join(model_config[key])
else:
os.environ[key.upper()] = str(model_config[key])
data_type, device_type = get_data_and_device_type(
model_config["runtime"])
for key in ["input_nodes", "output_nodes", "input_shapes",
"output_shapes"]:
if not isinstance(model_config[key], list):
model_config[key] = [model_config[key]]
# Create model build directory
model_path_digest = md5sum(model_config["model_file_path"])
model_output_dir = "%s/%s/%s/%s/%s/%s/%s" % (
FLAGS.output_dir, os.environ["PROJECT_NAME"], "build",
FLAGS.output_dir, project_name, "build",
model_name, model_path_digest, target_soc, target_abi)
model_output_dirs.append(model_output_dir)
if FLAGS.mode == "build" or FLAGS.mode == "all":
if os.path.exists(model_output_dir):
shutil.rmtree(model_output_dir)
sh.rm("-rf", model_output_dir)
os.makedirs(model_output_dir)
clear_env(target_soc)
sh_commands.clear_mace_run_data(
target_abi, target_soc, phone_data_dir)
download_model_files(model_config["model_file_path"],
model_file_path, weight_file_path = download_model_files(
model_config["model_file_path"],
model_output_dir,
model_config.get("weight_file_path", ""))
if FLAGS.mode == "build" or FLAGS.mode == "run" or \
FLAGS.mode == "validate" or \
FLAGS.mode == "benchmark" or FLAGS.mode == "all":
generate_random_input(target_soc, model_output_dir,
model_config['input_nodes'],
sh_commands.gen_random_input(model_output_dir,
model_config["input_nodes"],
model_config["input_shapes"],
input_file_list)
if FLAGS.mode == "build" or FLAGS.mode == "all":
generate_model_code()
build_mace_run_prod(model_name, global_runtime, target_abi,
target_soc, model_output_dir,
FLAGS.tuning)
sh_commands.gen_model_code(
"mace/codegen/models/%s" % model_name,
model_config["platform"],
model_file_path,
weight_file_path,
model_config["model_sha256_checksum"],
",".join(model_config["input_nodes"]),
",".join(model_config["output_nodes"]),
data_type,
model_config["runtime"],
model_name,
":".join(model_config["input_shapes"]),
model_config["dsp_mode"],
embed_model_data,
model_config["fast_conv"],
model_config["obfuscate"])
build_mace_run_prod(hexagon_mode,
model_config["runtime"],
target_soc,
target_abi,
vlog_level,
embed_model_data,
model_output_dir,
model_config["input_nodes"],
model_config["output_nodes"],
model_config["input_shapes"],
model_config["output_shapes"],
model_name,
device_type,
FLAGS.round,
FLAGS.restart_round,
FLAGS.tuning,
model_config["limit_opencl_kernel_time"],
phone_data_dir)
if FLAGS.mode == "run" or FLAGS.mode == "validate" or \
FLAGS.mode == "all":
run_model(model_name, global_runtime, target_abi,
target_soc, model_output_dir, FLAGS.round,
FLAGS.restart_round, option_args,
FLAGS.out_of_range_check)
tuning_run(model_config["runtime"],
target_soc,
target_abi,
vlog_level,
embed_model_data,
model_output_dir,
model_config["input_nodes"],
model_config["output_nodes"],
model_config["input_shapes"],
model_config["output_shapes"],
model_name,
device_type,
FLAGS.round,
FLAGS.restart_round,
FLAGS.out_of_range_check,
phone_data_dir)
if FLAGS.mode == "benchmark":
benchmark_model(target_soc, model_output_dir, option_args)
sh_commands.benchmark_model(target_soc,
target_abi,
vlog_level,
embed_model_data,
model_output_dir,
model_config["input_nodes"],
model_config["output_nodes"],
model_config["input_shapes"],
model_config["output_shapes"],
model_name,
device_type,
hexagon_mode,
phone_data_dir,
option_args)
if FLAGS.mode == "validate" or FLAGS.mode == "all":
validate_model(target_soc, model_output_dir)
sh_commands.validate_model(target_soc,
target_abi,
model_file_path,
weight_file_path,
model_config["platform"],
model_config["runtime"],
model_config["input_nodes"],
model_config["output_nodes"],
model_config["input_shapes"],
model_config["output_shapes"],
model_output_dir,
phone_data_dir)
if FLAGS.mode == "build" or FLAGS.mode == "merge" or \
FLAGS.mode == "all":
merge_libs_and_tuning_results(
target_soc,
FLAGS.output_dir + "/" + os.environ["PROJECT_NAME"],
model_output_dirs)
target_abi,
project_name,
FLAGS.output_dir,
model_output_dirs,
hexagon_mode,
embed_model_data)
if FLAGS.mode == "throughput_test":
merged_lib_file = FLAGS.output_dir + \
"/%s/%s/libmace_%s.%s.a" % \
(os.environ["PROJECT_NAME"], target_abi,
os.environ["PROJECT_NAME"], target_soc)
generate_random_input(target_soc, FLAGS.output_dir, [], [])
(project_name, target_abi, project_name, target_soc)
first_model = configs["models"].values()[0]
throughput_test_output_dir = "%s/%s/%s/%s" % (
FLAGS.output_dir, project_name, "build",
"throughput_test")
if os.path.exists(throughput_test_output_dir):
sh.rm("-rf", throughput_test_output_dir)
os.makedirs(throughput_test_output_dir)
input_file_list = model_config.get("validation_inputs_data",
[])
sh_commands.gen_random_input(throughput_test_output_dir,
first_model["input_nodes"],
first_model["input_shapes"],
input_file_list)
model_tag_dict = {}
for model_name in configs["models"]:
runtime = configs["models"][model_name]["runtime"]
os.environ["%s_MODEL_TAG" % runtime.upper()] = model_name
build_run_throughput_test(target_soc, FLAGS.run_seconds,
merged_lib_file, FLAGS.output_dir)
model_tag_dict[runtime] = model_name
sh_commands.build_run_throughput_test(target_soc,
target_abi,
vlog_level,
FLAGS.run_seconds,
merged_lib_file,
throughput_test_output_dir,
embed_model_data,
model_config["input_nodes"],
model_config["output_nodes"],
model_config["input_shapes"],
model_config["output_shapes"],
model_tag_dict.get("cpu", ""),
model_tag_dict.get("gpu", ""),
model_tag_dict.get("dsp", ""),
phone_data_dir)
def main(unused_args):
configs = parse_model_configs()
if FLAGS.mode == "validate":
FLAGS.round = 1
FLAGS.restart_round = 1
project_name = os.path.splitext(os.path.basename(FLAGS.config))[0]
if FLAGS.mode == "build" or FLAGS.mode == "all":
# Remove previous output dirs
if not os.path.exists(FLAGS.output_dir):
os.makedirs(FLAGS.output_dir)
elif os.path.exists(os.path.join(FLAGS.output_dir, "libmace")):
sh.rm("-rf", os.path.join(FLAGS.output_dir, project_name))
os.makedirs(os.path.join(FLAGS.output_dir, project_name))
# generate source
sh_commands.gen_mace_version()
sh_commands.gen_encrypted_opencl_source()
option_args = ' '.join(
[arg for arg in unused_args if arg.startswith('--')])
target_socs = get_target_socs(configs)
embed_model_data = configs.get("embed_model_data", 1)
vlog_level = configs.get("vlog_level", 0)
phone_data_dir = "/data/local/tmp/mace_run/"
for target_soc in target_socs:
for target_abi in configs["target_abis"]:
serialno = sh_commands.adb_devices([target_soc]).pop()
props = sh_commands.adb_getprop_by_serialno(serialno)
print(
"============================================================="
)
print("Trying to lock device", serialno)
with sh_commands.device_lock(serialno):
print("Run on device: %s, %s, %s" % (
serialno, props["ro.board.platform"],
props["ro.product.model"]))
process_models(project_name, configs, embed_model_data,
vlog_level, target_soc, target_abi,
phone_data_dir, option_args)
if FLAGS.mode == "build" or FLAGS.mode == "all":
packaging_lib_file(FLAGS.output_dir)
sh_commands.packaging_lib(FLAGS.output_dir, project_name)
if __name__ == "__main__":
......
#!/bin/bash
Usage() {
echo "Usage: bash tools/merge_libs.sh target_soc libmace_output_dir model_output_dirs"
}
if [ $# -lt 3 ]; then
Usage
exit 1
fi
CURRENT_DIR=`dirname $0`
source ${CURRENT_DIR}/env.sh
TARGET_SOC=$1
LIBMACE_BUILD_DIR=$2
MODEL_OUTPUT_DIRS=$3
MODEL_OUTPUT_DIRS_ARR=(${MODEL_OUTPUT_DIRS//,/ })
MODEL_HEADER_DIR=${LIBMACE_BUILD_DIR}/include/mace/public
MODEL_DATA_DIR=${LIBMACE_BUILD_DIR}/data
if [ ! -d "${MODEL_HEADER_DIR}" ]; then
mkdir -p ${MODEL_HEADER_DIR}
fi
cp -rf ${MACE_SOURCE_DIR}/mace/public/*.h ${LIBMACE_BUILD_DIR}/include/mace/public/
if [ ! -d "${LIBMACE_BUILD_DIR}/${TARGET_ABI}" ]; then
mkdir -p ${LIBMACE_BUILD_DIR}/${TARGET_ABI}
fi
if [ ! -d "${MODEL_DATA_DIR}" ]; then
mkdir -p ${MODEL_DATA_DIR}
fi
if [ x"${TARGET_ABI}" = x"armeabi-v7a" ]; then
cp ${MACE_SOURCE_DIR}/mace/core/runtime/hexagon/libhexagon_controller.so ${LIBMACE_BUILD_DIR}/${TARGET_ABI}/
fi
LIBMACE_TEMP_DIR=`mktemp -d -t libmace.XXXX`
# Merge all libraries in to one
echo "create ${LIBMACE_BUILD_DIR}/${TARGET_ABI}/libmace_${PROJECT_NAME}.${TARGET_SOC}.a" > ${LIBMACE_TEMP_DIR}/libmace_${PROJECT_NAME}.mri
if [ x"$TARGET_ABI" = x"host" ]; then
echo "addlib bazel-bin/mace/codegen/libgenerated_opencl.pic.a" >> ${LIBMACE_TEMP_DIR}/libmace_${PROJECT_NAME}.mri
echo "addlib bazel-bin/mace/codegen/libgenerated_tuning_params.pic.a" >> ${LIBMACE_TEMP_DIR}/libmace_${PROJECT_NAME}.mri
else
echo "addlib bazel-bin/mace/codegen/libgenerated_opencl.a" >> ${LIBMACE_TEMP_DIR}/libmace_${PROJECT_NAME}.mri
echo "addlib bazel-bin/mace/codegen/libgenerated_tuning_params.a" >> ${LIBMACE_TEMP_DIR}/libmace_${PROJECT_NAME}.mri
echo "addlib bazel-bin/mace/codegen/libgenerated_version.a" >> ${LIBMACE_TEMP_DIR}/libmace_${PROJECT_NAME}.mri
echo "addlib bazel-bin/mace/core/libcore.a" >> ${LIBMACE_TEMP_DIR}/libmace_${PROJECT_NAME}.mri
echo "addlib bazel-bin/mace/kernels/libkernels.a" >> ${LIBMACE_TEMP_DIR}/libmace_${PROJECT_NAME}.mri
echo "addlib bazel-bin/mace/utils/libutils.a" >> ${LIBMACE_TEMP_DIR}/libmace_${PROJECT_NAME}.mri
echo "addlib bazel-bin/mace/utils/libutils_prod.a" >> ${LIBMACE_TEMP_DIR}/libmace_${PROJECT_NAME}.mri
echo "addlib bazel-bin/mace/ops/libops.lo" >> ${LIBMACE_TEMP_DIR}/libmace_${PROJECT_NAME}.mri
fi
for model_output_dir in ${MODEL_OUTPUT_DIRS_ARR[@]}; do
for lib in ${model_output_dir}/*.a; do
echo "addlib ${lib}" >> ${LIBMACE_TEMP_DIR}/libmace_${PROJECT_NAME}.mri
done
if [ "${EMBED_MODEL_DATA}" == "0" ];then
for data_file in ${model_output_dir}/*.data; do
cp ${data_file} ${MODEL_DATA_DIR}
done
fi
for header_file in ${model_output_dir}/*.h; do
cp ${header_file} ${MODEL_HEADER_DIR}
done
done
echo "save" >> ${LIBMACE_TEMP_DIR}/libmace_${PROJECT_NAME}.mri
echo "end" >> ${LIBMACE_TEMP_DIR}/libmace_${PROJECT_NAME}.mri
$ANDROID_NDK_HOME/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar \
-M < ${LIBMACE_TEMP_DIR}/libmace_${PROJECT_NAME}.mri || exit 1
rm -rf ${LIBMACE_TEMP_DIR}
echo "Libs merged!"
#!/bin/bash
Usage() {
echo "Usage: bash tools/packaging_lib.sh libmace_output_dir"
}
if [ $# -lt 1 ]; then
Usage
exit 1
fi
CURRENT_DIR=`dirname $0`
source ${CURRENT_DIR}/env.sh
LIBMACE_BUILD_DIR=$1
TAR_PACKAGE_NAME=libmace_${PROJECT_NAME}.tar.gz
pushd $LIBMACE_BUILD_DIR/$PROJECT_NAME
if [ -f $TAR_PACKAGE_NAME ]; then
rm -f $TAR_PACKAGE_NAME
fi
ls | grep -v build | xargs tar cvzf $TAR_PACKAGE_NAME
popd
echo "Packaging done!"
# 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 falcon_cli
import filelock
import glob
import os
import re
import sh
import subprocess
import sys
import time
sys.path.insert(0, "mace/python/tools")
try:
from encrypt_opencl_codegen import encrypt_opencl_codegen
from opencl_codegen import opencl_codegen
from binary_codegen import tuning_param_codegen
from generate_data import generate_input_data
from validate import validate
except Exception:
print("Error: import error.")
print("Does the script run at the root dir of mace project?")
exit(1)
################################
# common
################################
......@@ -36,6 +67,28 @@ def is_device_locked(serialno):
return True
def formatted_file_name(input_name, input_file_name):
return input_file_name + '_' + \
re.sub('[^0-9a-zA-Z]+', '_', input_name)
################################
# clear data
################################
def clear_mace_run_data(abi,
target_soc,
phone_data_dir,
model_codegen_dir="mace/codegen/models"):
if abi != "host":
serialno = adb_devices([target_soc]).pop()
sh.adb("-s",
serialno,
"shell",
"rm -rf %s" % phone_data_dir)
if os.path.exists(model_codegen_dir):
sh.rm("-rf", model_codegen_dir)
################################
# adb commands
################################
......@@ -92,6 +145,19 @@ def adb_get_all_socs():
return set(socs)
def adb_push(src_path, dst_path, serialno):
print("Push %s to %s" % (src_path, dst_path))
sh.adb("-s", serialno, "push", src_path, dst_path)
def adb_pull(src_path, dst_path, serialno):
print("Pull %s to %s" % (src_path, dst_path))
try:
sh.adb("-s", serialno, "pull", src_path, dst_path)
except Exception as e:
print("Error msg: %s" % e.stderr)
def adb_run(serialno,
host_bin_path,
bin_name,
......@@ -113,9 +179,7 @@ def adb_run(serialno,
props["ro.product.model"]))
sh.adb("-s", serialno, "shell", "rm -rf %s" % device_bin_path)
sh.adb("-s", serialno, "shell", "mkdir -p %s" % device_bin_path)
print("Push %s to %s" % (host_bin_full_path, device_bin_full_path))
sh.adb("-s", serialno, "push", host_bin_full_path,
device_bin_full_path)
adb_push(host_bin_full_path, device_bin_full_path, serialno)
print("Run %s" % device_bin_full_path)
stdout_buff = []
process_output = make_output_processor(stdout_buff)
......@@ -137,11 +201,40 @@ def adb_run(serialno,
################################
# bazel commands
################################
def bazel_build(target, strip="always", abi="armeabi-v7a"):
print("Build %s with ABI %s" % (target, abi))
def bazel_build(target,
strip="always",
abi="armeabi-v7a",
model_tag="",
production_mode=False,
hexagon_mode=False,
disable_no_tuning_warning=False):
print("* Build %s with ABI %s" % (target, abi))
stdout_buff = []
process_output = make_output_processor(stdout_buff)
if abi == "host":
p = sh.bazel(
"build",
"-c",
"opt",
"--strip",
strip,
"--verbose_failures",
target,
"--copt=-std=c++11",
"--copt=-D_GLIBCXX_USE_C99_MATH_TR1",
"--copt=-Werror=return-type",
"--copt=-DMACE_MODEL_TAG=%s" % model_tag,
"--copt=-O3",
"--define",
"openmp=true",
"--define",
"production=%s" % str(production_mode).lower(),
_out=process_output,
_bg=True,
_err_to_out=True)
p.wait()
else:
bazel_args = (
"build",
"-c",
"opt",
......@@ -154,13 +247,36 @@ def bazel_build(target, strip="always", abi="armeabi-v7a"):
"--cpu=%s" % abi,
"--copt=-std=c++11",
"--copt=-D_GLIBCXX_USE_C99_MATH_TR1",
"--copt=-DMACE_DISABLE_NO_TUNING_WARNING",
"--copt=-Werror=return-type",
"--copt=-DMACE_OBFUSCATE_LITERALS",
"--copt=-DMACE_MODEL_TAG=%s" % model_tag,
"--copt=-O3",
"--define",
"neon=true",
"--define",
"openmp=true",
"--define",
"production=%s" % str(production_mode).lower(),
"--define",
"hexagon=%s" % str(hexagon_mode).lower())
if disable_no_tuning_warning:
bazel_args += ("--copt=-DMACE_DISABLE_NO_TUNING_WARNING",)
p = sh.bazel(
_out=process_output,
_bg=True,
_err_to_out=True,
*bazel_args)
p.wait()
print("Building done!\n")
return "".join(stdout_buff)
def bazel_build_common(target, build_args=""):
stdout_buff = []
process_output = make_output_processor(stdout_buff)
p = sh.bazel(
"build",
target + build_args,
_out=process_output,
_bg=True,
_err_to_out=True)
......@@ -181,13 +297,69 @@ def bazel_target_to_bin(target):
################################
# mace commands
################################
# TODO this should be refactored
def gen_encrypted_opencl_source(codegen_path="mace/codegen"):
sh.mkdir("-p", "%s/opencl" % codegen_path)
sh.python(
"mace/python/tools/encrypt_opencl_codegen.py",
"--cl_kernel_dir=./mace/kernels/opencl/cl/",
"--output_path=%s/opencl/opencl_encrypt_program.cc" % codegen_path)
encrypt_opencl_codegen("./mace/kernels/opencl/cl/",
"mace/codegen/opencl/opencl_encrypt_program.cc")
def pull_binaries(target_soc, abi, model_output_dirs):
serialno = adb_devices([target_soc]).pop()
compiled_opencl_dir = "/data/local/tmp/mace_run/cl_program/"
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_bin_dir, serialno)
adb_pull("/data/local/tmp/mace_run/%s" % mace_run_param_file,
cl_bin_dir, serialno)
def gen_opencl_binary_code(target_soc,
model_output_dirs,
codegen_path="mace/codegen"):
cl_built_kernel_file_name = "mace_cl_compiled_program.bin"
cl_platform_info_file_name = "mace_cl_platform_info.txt"
opencl_codegen_file = "%s/opencl/opencl_compiled_program.cc" % codegen_path
serialno = adb_devices([target_soc]).pop()
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)
opencl_codegen(opencl_codegen_file,
cl_bin_dirs_str,
cl_built_kernel_file_name,
cl_platform_info_file_name)
def gen_tuning_param_code(target_soc,
model_output_dirs,
codegen_path="mace/codegen"):
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)
tuning_codegen_dir = "%s/tuning/" % codegen_path
if not os.path.exists(tuning_codegen_dir):
sh.mkdir("-p", tuning_codegen_dir)
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)
def gen_mace_version(codegen_path="mace/codegen"):
......@@ -197,10 +369,655 @@ def gen_mace_version(codegen_path="mace/codegen"):
def gen_compiled_opencl_source(codegen_path="mace/codegen"):
opencl_codegen_file = "%s/opencl/opencl_compiled_program.cc" % codegen_path
sh.mkdir("-p", "%s/opencl" % codegen_path)
sh.python(
"mace/python/tools/opencl_codegen.py",
"--output_path=%s/opencl/opencl_compiled_program.cc" % codegen_path)
opencl_codegen(opencl_codegen_file)
def gen_model_code(model_codegen_dir,
platform,
model_file_path,
weight_file_path,
model_sha256_checksum,
input_nodes,
output_nodes,
data_type,
runtime,
model_tag,
input_shapes,
dsp_mode,
embed_model_data,
fast_conv,
obfuscate):
print("* Genearte model code")
bazel_build_common("//mace/python/tools:converter")
if os.path.exists(model_codegen_dir):
sh.rm("-rf", model_codegen_dir)
sh.mkdir("-p", model_codegen_dir)
sh.python("bazel-bin/mace/python/tools/converter",
"-u",
"--platform=%s" % platform,
"--model_file=%s" % model_file_path,
"--weight_file=%s" % weight_file_path,
"--model_checksum=%s" % model_sha256_checksum,
"--output=%s" % model_codegen_dir + "/model.cc",
"--input_node=%s" % input_nodes,
"--output_node=%s" % output_nodes,
"--data_type=%s" % data_type,
"--runtime=%s" % runtime,
"--output_type=source",
"--template=%s" % "mace/python/tools",
"--model_tag=%s" % model_tag,
"--input_shape=%s" % input_shapes,
"--dsp_mode=%s" % dsp_mode,
"--embed_model_data=%s" % embed_model_data,
"--winograd=%s" % fast_conv,
"--obfuscate=%s" % obfuscate)
print("Model code gen done!\n")
def gen_random_input(model_output_dir,
input_nodes,
input_shapes,
input_files,
input_file_name="model_input"):
for input_name in input_nodes:
formatted_name = formatted_file_name(input_name, input_file_name)
if os.path.exists(formatted_name):
sh.rm(formatted_name)
input_nodes_str = ",".join(input_nodes)
input_shapes_str = ":".join(input_shapes)
generate_input_data("%s/%s" % (model_output_dir, input_file_name),
input_nodes_str,
input_shapes_str)
input_file_list = []
if isinstance(input_files, list):
input_file_list.extend(input_files)
else:
input_file_list.append(input_files)
if len(input_file_list) != 0:
input_name_list = []
if isinstance(input_names, list):
input_name_list.extend(input_names)
else:
input_name_list.append(input_names)
if len(input_file_list) != len(input_name_list):
raise Exception('If input_files set, the input files should '
'match the input names.')
for i in range(len(input_file_list)):
if input_file_list[i] is not None:
dst_input_file = model_output_dir + '/' + \
formatted_file_name(input_name_list[i],
input_file_name)
if input_file_list[i].startswith("http://") or \
input_file_list[i].startswith("https://"):
urllib.urlretrieve(input_file_list[i], dst_input_file)
else:
sh.cp("-f", input_file_list[i], dst_input_file)
def update_mace_run_lib(model_output_dir,
abi,
model_tag,
embed_model_data,
generated_model_lib_dir="bazel-bin/mace/codegen/"):
model_lib_path = model_output_dir + "/libmace_%s.a" % model_tag
if abi == "host":
bazel_build(
"//mace/codegen:generated_models",
abi=abi,
model_tag=model_tag)
generated_model_lib_name = "libgenerated_models.pic.a"
else:
generated_model_lib_name = "libgenerated_models.a"
if os.path.exists(model_lib_path):
sh.rm("-rf", model_lib_path)
sh.cp("-f", generated_model_lib_dir + "/" + generated_model_lib_name,
model_lib_path)
mace_run_filepath = model_output_dir + "/mace_run"
if os.path.exists(mace_run_filepath):
sh.rm("-rf", mace_run_filepath)
sh.cp("-f", "bazel-bin/mace/tools/validation/mace_run", model_output_dir)
if embed_model_data == 0:
sh.cp("-f", "mace/codegen/models/%s/%s.data" % (model_tag, model_tag),
model_output_dir)
sh.cp("-f", "mace/codegen/models/%s/%s.h" % (model_tag, model_tag),
model_output_dir)
def tuning_run(target_soc,
abi,
vlog_level,
embed_model_data,
model_output_dir,
input_nodes,
output_nodes,
input_shapes,
output_shapes,
model_tag,
device_type,
running_round,
restart_round,
limit_opencl_kernel_time,
tuning,
out_of_range_check,
phone_data_dir,
option_args="",
input_file_name="model_input",
output_file_name="model_out"):
print("* Run '%s' with round=%s, restart_round=%s, tuning=%s" %
(model_tag, running_round, restart_round, str(tuning)))
stdout_buff = []
process_output = make_output_processor(stdout_buff)
if abi == "host":
p = subprocess.Popen([
"env",
"MACE_CPP_MIN_VLOG_LEVEL=%s" % vlog_level,
"%s/mace_run" % model_output_dir,
"--input_node=%s" % ",".join(input_nodes),
"--output_node=%s" % ",".join(output_nodes),
"--input_shape=%s" % ":".join(input_shapes),
"--output_shape=%s" % ":".join(output_shapes),
"--input_file=%s/%s" % (model_output_dir, input_file_name),
"--output_file=%s/%s" % (model_output_dir, output_file_name),
"--model_data_file=%s/%s.data" % (model_output_dir, model_tag),
"--device=%s" % device_type,
"--round=%s" % running_round,
"--restart_round=%s" % restart_round,
"%s" % option_args])
p.wait()
else:
serialno = adb_devices([target_soc]).pop()
sh.adb("-s", serialno, "shell", "mkdir", "-p", phone_data_dir)
compiled_opencl_dir = "/data/local/tmp/mace_run/cl_program/"
sh.adb("-s", serialno, "shell", "mkdir", "-p", compiled_opencl_dir)
for input_name in input_nodes:
formatted_name = formatted_file_name(input_name,
input_file_name)
adb_push("%s/%s" % (model_output_dir, formatted_name),
phone_data_dir, serialno)
adb_push("%s/mace_run" % model_output_dir, phone_data_dir,
serialno)
if not embed_model_data:
adb_push("%s/%s.data" % (model_output_dir, model_tag),
phone_data_dir, serialno)
adb_push("mace/core/runtime/hexagon/libhexagon_controller.so",
phone_data_dir, serialno)
p = sh.adb(
"-s",
serialno,
"shell",
"LD_LIBRARY_PATH=%s" % phone_data_dir,
"MACE_TUNING=%s" % int(tuning),
"MACE_OUT_OF_RANGE_CHECK=%s" % int(out_of_range_check),
"MACE_CPP_MIN_VLOG_LEVEL=%s" % vlog_level,
"MACE_RUN_PARAMETER_PATH=%s/mace_run.config" %
phone_data_dir,
"MACE_CL_PROGRAM_PATH=%s/cl_program" % phone_data_dir,
"MACE_LIMIT_OPENCL_KERNEL_TIME=%s" %
limit_opencl_kernel_time,
"%s/mace_run" % phone_data_dir,
"--input_node=%s" % ",".join(input_nodes),
"--output_node=%s" % ",".join(output_nodes),
"--input_shape=%s" % ":".join(input_shapes),
"--output_shape=%s" % ":".join(output_shapes),
"--input_file=%s/%s" % (phone_data_dir, input_file_name),
"--output_file=%s/%s" % (phone_data_dir, output_file_name),
"--model_data_file=%s/%s.data" % (phone_data_dir, model_tag),
"--device=%s" % device_type,
"--round=%s" % running_round,
"--restart_round=%s" % restart_round,
"%s" % option_args,
_out=process_output,
_bg=True,
_err_to_out=True)
p.wait()
print("Running finished!\n")
return "".join(stdout_buff)
def validate_model(target_soc,
abi,
model_file_path,
weight_file_path,
platform,
runtime,
input_nodes,
output_nodes,
input_shapes,
output_shapes,
model_output_dir,
phone_data_dir,
input_file_name="model_input",
output_file_name="model_out"):
print("* Validate with %s" % platform)
serialno = adb_devices([target_soc]).pop()
if platform == "tensorflow":
if abi != "host":
for output_name in output_nodes:
formatted_name = formatted_file_name(
output_name, output_file_name)
if os.path.exists(formatted_name):
sh.rm(formatted_name)
adb_pull("%s/%s" % (phone_data_dir, formatted_name),
model_output_dir, serialno)
validate(platform, model_file_path, "",
"%s/%s" % (model_output_dir, input_file_name),
"%s/%s" % (model_output_dir, output_file_name), runtime,
":".join(input_shapes), ":".join(output_shapes),
",".join(input_nodes), ",".join(output_nodes))
elif platform == "caffe":
image_name = "mace-caffe:latest"
container_name = "mace_caffe_validator"
res_file = "validation.result"
docker_image_id = sh.docker("images", "-q", image_name)
if not docker_image_id:
print("Build caffe docker")
sh.docker("build", "-t", image_name, "docker/caffe")
container_id = sh.docker("ps", "-qa", "-f", "name=%s" % container_name)
if not container_id:
print("Run caffe container")
sh.docker(
"run",
"-d",
"-it",
"--name",
container_name,
image_name,
"/bin/bash")
container_status = sh.docker("inspect",
"-f",
"{{.State.Running}}",
container_name)
if container_status == "false":
print("Start caffe container")
sh.docker("start", container_name)
for input_name in input_nodes:
formatted_input_name = formatted_file_name(
input_name, input_file_name)
sh.docker(
"cp",
"%s/%s" % (model_output_dir, formatted_input_name),
"%s:/mace" % container_name)
if abi != "host":
for output_name in output_nodes:
formatted_output_name = formatted_file_name(
output_name, output_file_name)
sh.rm("-rf",
"%s/%s" % (model_output_dir, formatted_output_name))
adb_pull("%s/%s" % (phone_data_dir, formatted_output_name),
model_output_dir, serialno)
for output_name in output_nodes:
formatted_output_name = formatted_file_name(
output_name, output_file_name)
sh.docker(
"cp",
"%s/%s" % (model_output_dir, formatted_output_name),
"%s:/mace" % container_name)
model_file_name = os.path.basename(model_file_path)
weight_file_name = os.path.basename(weight_file_path)
sh.docker("cp", "tools/validate.py", "%s:/mace" % container_name)
sh.docker("cp", model_file_path, "%s:/mace" % container_name)
sh.docker("cp", weight_file_path, "%s:/mace" % container_name)
stdout_buff = []
process_output = make_output_processor(stdout_buff)
p = sh.docker(
"exec",
container_name,
"python",
"-u",
"/mace/validate.py",
"--platform=caffe",
"--model_file=/mace/%s" % model_file_name,
"--weight_file=/mace/%s" % weight_file_name,
"--input_file=/mace/%s" % input_file_name,
"--mace_out_file=/mace/%s" % output_file_name,
"--mace_runtime=%s" % runtime,
"--input_node=%s" % ",".join(input_nodes),
"--output_node=%s" % ",".join(output_nodes),
"--input_shape=%s" % ":".join(input_shapes),
"--output_shape=%s" % ":".join(output_shapes),
_out=process_output,
_bg=True,
_err_to_out=True)
p.wait()
print("Validation done!\n")
def build_production_code(abi):
bazel_build("//mace/codegen:generated_opencl", abi=abi)
bazel_build("//mace/codegen:generated_tuning_params", abi=abi)
def merge_libs(target_soc,
abi,
project_name,
libmace_output_dir,
model_output_dirs,
hexagon_mode,
embed_model_data):
print("* Merge mace lib")
project_output_dir = "%s/%s" % (libmace_output_dir, project_name)
model_header_dir = "%s/include/mace/public" % project_output_dir
model_data_dir = "%s/data" % project_output_dir
hexagon_lib_file = "mace/core/runtime/hexagon/libhexagon_controller.so"
model_bin_dir = "%s/%s/" % (project_output_dir, abi)
if not os.path.exists(model_bin_dir):
sh.mkdir("-p", model_bin_dir)
if not os.path.exists(model_header_dir):
sh.mkdir("-p", model_header_dir)
sh.cp("-f", glob.glob("mace/public/*.h"), model_header_dir)
if not os.path.exists(model_data_dir):
sh.mkdir("-p", model_data_dir)
if hexagon_mode:
sh.cp("-f", hexagon_lib_file, model_bin_dir)
mri_stream = ""
mri_stream += "create %s/libmace_%s.%s.a\n" % \
(model_bin_dir, project_name, target_soc)
if abi == "host":
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")
else:
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.a\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/utils/libutils_prod.a\n")
mri_stream += (
"addlib "
"bazel-bin/mace/ops/libops.lo\n")
for model_output_dir in model_output_dirs:
for lib in sh.ls(glob.glob("%s/*.a" % model_output_dir), "-1"):
mri_stream += "addlib %s\n" % lib
if not embed_model_data:
sh.cp("-f", glob.glob("%s/*.data" % model_output_dir),
model_data_dir)
sh.cp("-f", glob.glob("%s/*.h" % model_output_dir), model_header_dir)
mri_stream += "save\n"
mri_stream += "end\n"
cmd = sh.Command("%s/toolchains/" % os.environ["ANDROID_NDK_HOME"] +
"aarch64-linux-android-4.9/prebuilt/linux-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
project_dir = "%s/%s" % (libmace_output_dir, project_name)
tar_package_path = "%s/%s" % (project_dir, tar_package_name)
if os.path.exists(tar_package_path):
sh.rm("-rf", tar_package_path)
print("Start packaging '%s' libs into %s" % (project_name,
tar_package_path))
# ls ${project_dir} -1 | grep -v build | grep -v .tar.gz | xargs -I {} \
# tar cvzf ${project_dir}/${tar_package_name} ${project_name}/{}
sh.xargs(
sh.grep(
sh.grep(
sh.ls(project_dir, "-1"),
"-v", "build"),
"-v", ".tar.gz"),
"-I",
"{}",
"tar",
"cvzf",
"%s" % tar_package_path,
"%s/{}" % project_dir)
print("Packaging Done!\n")
def benchmark_model(target_soc,
abi,
vlog_level,
embed_model_data,
model_output_dir,
input_nodes,
output_nodes,
input_shapes,
output_shapes,
model_tag,
device_type,
hexagon_mode,
phone_data_dir,
option_args="",
input_file_name="model_input",
output_file_name="model_out"):
print("* Benchmark for %s" % model_tag)
benchmark_binary_file = "%s/benchmark_model" % model_output_dir
if os.path.exists(benchmark_binary_file):
sh.rm("-rf", benchmark_binary_file)
if not embed_model_data:
sh.cp("-f", "codegen/models/%s/%s.data" % (model_tag, model_tag),
model_output_dir)
benchmark_target = "//mace/benchmark:benchmark_model"
bazel_build(benchmark_target,
abi=abi,
model_tag=model_tag,
hexagon_mode=hexagon_mode)
target_bin = "/".join(bazel_target_to_bin(benchmark_target))
sh.cp("-f", target_bin, model_output_dir)
stdout_buff = []
process_output = make_output_processor(stdout_buff)
if abi == "host":
p = subprocess.Popen([
"env",
"MACE_CPP_MIN_VLOG_LEVEL=%s" % vlog_level,
"%s/benchmark_model" % model_output_dir,
"--input_node=%s" % ",".join(input_nodes),
"--output_node=%s" % ",".join(output_nodes),
"--input_shape=%s" % ":".join(input_shapes),
"--output_shape=%s" % ":".join(output_shapes),
"--input_file=%s/%s" % (model_output_dir, input_file_name),
"--model_data_file=%s/%s.data" % (model_output_dir, model_tag),
"--device=%s" % device_type,
"%s" % option_args])
p.wait()
else:
serialno = adb_devices([target_soc]).pop()
sh.adb("-s", serialno, "shell", "mkdir", "-p", phone_data_dir)
for input_name in input_nodes:
formatted_name = formatted_file_name(input_name,
input_file_name)
adb_push("%s/%s" % (model_output_dir, formatted_name),
phone_data_dir, serialno)
adb_push("%s/benchmark_model" % model_output_dir, phone_data_dir,
serialno)
if not embed_model_data:
adb_push("%s/%s.data" % (model_output_dir, model_tag),
phone_data_dir, serialno)
p = sh.adb(
"-s",
serialno,
"shell",
"LD_LIBRARY_PATH=%s" % phone_data_dir,
"MACE_CPP_MIN_VLOG_LEVEL=%s" % vlog_level,
"MACE_RUN_PARAMETER_PATH=%s/mace_run.config" %
phone_data_dir,
"MACE_OPENCL_PROFILING=1",
"%s/benchmark_model" % phone_data_dir,
"--input_node=%s" % ",".join(input_nodes),
"--output_node=%s" % ",".join(output_nodes),
"--input_shape=%s" % ":".join(input_shapes),
"--output_shape=%s" % ":".join(output_shapes),
"--input_file=%s/%s" % (phone_data_dir, input_file_name),
"--model_data_file=%s/%s.data" % (phone_data_dir, model_tag),
"--device=%s" % device_type,
"%s" % option_args,
_out=process_output,
_bg=True,
_err_to_out=True)
p.wait()
print("Benchmark done!\n")
return "".join(stdout_buff)
def build_run_throughput_test(target_soc,
abi,
vlog_level,
run_seconds,
merged_lib_file,
model_input_dir,
embed_model_data,
input_nodes,
output_nodes,
input_shapes,
output_shapes,
cpu_model_tag,
gpu_model_tag,
dsp_model_tag,
phone_data_dir,
strip="always",
input_file_name="model_input"):
print("* Build and run throughput_test")
serialno = adb_devices([target_soc]).pop()
model_tag_build_flag = ""
if cpu_model_tag:
model_tag_build_flag += "--copt=-DMACE_CPU_MODEL_TAG=%s " % \
cpu_model_tag
if gpu_model_tag:
model_tag_build_flag += "--copt=-DMACE_GPU_MODEL_TAG=%s " % \
gpu_model_tag
if dsp_model_tag:
model_tag_build_flag += "--copt=-DMACE_DSP_MODEL_TAG=%s " % \
dsp_model_tag
sh.cp("-f", merged_lib_file, "mace/benchmark/libmace_merged.a")
stdout_buff = []
process_output = make_output_processor(stdout_buff)
p = sh.bazel(
"build",
"-c",
"opt",
"--strip",
strip,
"--verbose_failures",
"//mace/benchmark:model_throughput_test",
"--crosstool_top=//external:android/crosstool",
"--host_crosstool_top=@bazel_tools//tools/cpp:toolchain",
"--cpu=%s" % abi,
"--copt=-std=c++11",
"--copt=-D_GLIBCXX_USE_C99_MATH_TR1",
"--copt=-Werror=return-type",
"--copt=-O3",
"--define",
"neon=true",
"--define",
"openmp=true",
model_tag_build_flag,
_out=process_output,
_bg=True,
_err_to_out=True)
p.wait()
sh.rm("mace/benchmark/libmace_merged.a")
sh.adb("-s",
serialno,
"shell",
"mkdir",
"-p",
phone_data_dir)
adb_push("%s/%s_%s" % (model_input_dir, input_file_name,
",".join(input_nodes)),
phone_data_dir,
serialno)
adb_push("bazel-bin/mace/benchmark/model_throughput_test",
phone_data_dir,
serialno)
if not embed_model_data:
adb_push("codegen/models/%s/%s.data" % cpu_model_tag,
phone_data_dir,
serialno)
adb_push("codegen/models/%s/%s.data" % gpu_model_tag,
phone_data_dir,
serialno)
adb_push("codegen/models/%s/%s.data" % dsp_model_tag,
phone_data_dir,
serialno)
adb_push("mace/core/runtime/hexagon/libhexagon_controller.so",
phone_data_dir,
serialno)
p = sh.adb(
"-s",
serialno,
"shell",
"LD_LIBRARY_PATH=%s" % phone_data_dir,
"MACE_CPP_MIN_VLOG_LEVEL=%s" % vlog_level,
"MACE_RUN_PARAMETER_PATH=%s/mace_run.config" %
phone_data_dir,
"%s/model_throughput_test" % phone_data_dir,
"--input_node=%s" % ",".join(input_nodes),
"--output_node=%s" % ",".join(output_nodes),
"--input_shape=%s" % ":".join(input_shapes),
"--output_shape=%s" % ":".join(output_shapes),
"--input_file=%s/%s" % (phone_data_dir, input_file_name),
"--cpu_model_data_file=%s/%s.data" % (phone_data_dir,
cpu_model_tag),
"--gpu_model_data_file=%s/%s.data" % (phone_data_dir,
gpu_model_tag),
"--dsp_model_data_file=%s/%s.data" % (phone_data_dir,
dsp_model_tag),
"--run_seconds=%s" % run_seconds,
_out=process_output,
_bg=True,
_err_to_out=True)
p.wait()
print("throughput_test done!\n")
################################
......
#!/bin/bash
Usage() {
echo "Usage: bash tools/tuning_run.sh target_soc model_output_dir round tuning restart_round opt_args out_of_range_check"
}
if [ $# -lt 7 ]; then
Usage
exit 1
fi
CURRENT_DIR=`dirname $0`
source ${CURRENT_DIR}/env.sh
TARGET_SOC=$1
MODEL_OUTPUT_DIR=$2
ROUND=$3
TUNING_OR_NOT=$4
RESTART_ROUND=$5
OPTION_ARGS=$6
OUT_OF_RANGE_CHECK_OR_NOT=$7
echo $OPTION_ARGS
RESULT_VALUE=`echo_device_id_by_soc $TARGET_SOC`
if [ $? -ne 0 ]; then
echo $RESULT_VALUE
exit 1
else
DEVICE_ID=$RESULT_VALUE
fi
if [ x"$TARGET_ABI" = x"host" ]; then
MACE_CPP_MIN_VLOG_LEVEL=$VLOG_LEVEL \
${MODEL_OUTPUT_DIR}/mace_run \
--input_node="${INPUT_NODES}" \
--input_shape="${INPUT_SHAPES}"\
--output_node="${OUTPUT_NODES}" \
--output_shape="${OUTPUT_SHAPES}"\
--input_file=${MODEL_OUTPUT_DIR}/${INPUT_FILE_NAME} \
--output_file=${MODEL_OUTPUT_DIR}/${OUTPUT_FILE_NAME} \
--model_data_file=${MODEL_OUTPUT_DIR}/${MODEL_TAG}.data \
--device=${DEVICE_TYPE} \
--round=1 \
--restart_round=1 \
$OPTION_ARGS || exit 1
else
if [[ "${TUNING_OR_NOT}" != "0" ]];then
tuning_flag=1
else
tuning_flag=0
fi
if [[ "${OUT_OF_RANGE_CHECK_OR_NOT}" != "0" ]]; then
out_of_range_check_flag=1
else
out_of_range_check_flag=0
fi
adb -s $DEVICE_ID shell "mkdir -p ${PHONE_DATA_DIR}" || exit 1
adb -s $DEVICE_ID shell "mkdir -p ${COMPILED_PROGRAM_DIR}" || exit 1
IFS=',' read -r -a INPUT_NAMES <<< "${INPUT_NODES}"
for NAME in "${INPUT_NAMES[@]}";do
FORMATTED_NAME=$(sed s/[^[:alnum:]]/_/g <<< ${NAME})
adb -s $DEVICE_ID push ${MODEL_OUTPUT_DIR}/${INPUT_FILE_NAME}_${FORMATTED_NAME} ${PHONE_DATA_DIR} > /dev/null || exit 1
done
adb -s $DEVICE_ID </dev/null push ${MODEL_OUTPUT_DIR}/mace_run ${PHONE_DATA_DIR} > /dev/null || exit 1
if [ "$EMBED_MODEL_DATA" = 0 ]; then
adb -s $DEVICE_ID push ${MODEL_OUTPUT_DIR}/${MODEL_TAG}.data ${PHONE_DATA_DIR} > /dev/null || exit 1
fi
adb -s $DEVICE_ID push mace/core/runtime/hexagon/libhexagon_controller.so ${PHONE_DATA_DIR} > /dev/null || exit 1
ADB_CMD_STR="LD_LIBRARY_PATH=${PHONE_DATA_DIR} \
MACE_TUNING=${tuning_flag} \
MACE_OUT_OF_RANGE_CHECK=${out_of_range_check_flag} \
MACE_CPP_MIN_VLOG_LEVEL=$VLOG_LEVEL \
MACE_RUN_PARAMETER_PATH=${PHONE_DATA_DIR}/mace_run.config \
MACE_CL_PROGRAM_PATH=$COMPILED_PROGRAM_DIR \
MACE_LIMIT_OPENCL_KERNEL_TIME=${LIMIT_OPENCL_KERNEL_TIME} \
${PHONE_DATA_DIR}/mace_run \
--input_node="${INPUT_NODES}" \
--input_shape="${INPUT_SHAPES}"\
--output_node="${OUTPUT_NODES}" \
--output_shape="${OUTPUT_SHAPES}"\
--input_file=${PHONE_DATA_DIR}/${INPUT_FILE_NAME} \
--output_file=${PHONE_DATA_DIR}/${OUTPUT_FILE_NAME} \
--model_data_file=${PHONE_DATA_DIR}/${MODEL_TAG}.data \
--device=${DEVICE_TYPE} \
--round=$ROUND \
--restart_round=$RESTART_ROUND \
$OPTION_ARGS; echo \$?"
echo $ADB_CMD_STR
mace_adb_output=`adb -s $DEVICE_ID </dev/null shell "$ADB_CMD_STR"` || exit 1
echo "$mace_adb_output" | head -n -1
mace_adb_return_code=`echo "$mace_adb_output" | tail -1`
if ! [[ ${mace_adb_return_code%?} = 0 || ${mace_adb_return_code} = 0 ]]; then
exit 1
fi
fi
# 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 argparse
import sys
import os
......@@ -32,18 +46,19 @@ def format_name(name):
return re.sub('[^0-9a-zA-Z]+', '_', name)
def compare_output(output_name, mace_out_value, out_value):
def compare_output(platform, mace_runtime, output_name, mace_out_value,
out_value):
if mace_out_value.size != 0:
out_value = out_value.reshape(-1)
mace_out_value = mace_out_value.reshape(-1)
assert len(out_value) == len(mace_out_value)
similarity = (1 - spatial.distance.cosine(out_value, mace_out_value))
print output_name, 'MACE VS', FLAGS.platform.upper(
print output_name, 'MACE VS', platform.upper(
), 'similarity: ', similarity
if (FLAGS.mace_runtime == "cpu" and similarity > 0.999) or \
(FLAGS.mace_runtime == "neon" and similarity > 0.999) or \
(FLAGS.mace_runtime == "gpu" and similarity > 0.995) or \
(FLAGS.mace_runtime == "dsp" and similarity > 0.930):
if (mace_runtime == "cpu" and similarity > 0.999) or \
(mace_runtime == "neon" and similarity > 0.999) or \
(mace_runtime == "gpu" and similarity > 0.995) or \
(mace_runtime == "dsp" and similarity > 0.930):
print '===================Similarity Test Passed=================='
else:
print '===================Similarity Test Failed=================='
......@@ -53,14 +68,15 @@ def compare_output(output_name, mace_out_value, out_value):
sys.exit(-1)
def validate_tf_model(input_names, input_shapes, output_names):
def validate_tf_model(platform, mace_runtime, model_file, input_file,
mace_out_file, input_names, input_shapes, output_names):
import tensorflow as tf
if not os.path.isfile(FLAGS.model_file):
print("Input graph file '" + FLAGS.model_file + "' does not exist!")
if not os.path.isfile(model_file):
print("Input graph file '" + model_file + "' does not exist!")
sys.exit(-1)
input_graph_def = tf.GraphDef()
with open(FLAGS.model_file, "rb") as f:
with open(model_file, "rb") as f:
data = f.read()
input_graph_def.ParseFromString(data)
tf.import_graph_def(input_graph_def, name="")
......@@ -71,7 +87,7 @@ def validate_tf_model(input_names, input_shapes, output_names):
input_dict = {}
for i in range(len(input_names)):
input_value = load_data(
FLAGS.input_file + "_" + format_name(input_names[i]))
input_file + "_" + format_name(input_names[i]))
input_value = input_value.reshape(input_shapes[i])
input_node = graph.get_tensor_by_name(
input_names[i] + ':0')
......@@ -83,31 +99,31 @@ def validate_tf_model(input_names, input_shapes, output_names):
[graph.get_tensor_by_name(name + ':0')])
output_values = session.run(output_nodes, feed_dict=input_dict)
for i in range(len(output_names)):
output_file_name = FLAGS.mace_out_file + "_" + \
output_file_name = mace_out_file + "_" + \
format_name(output_names[i])
mace_out_value = load_data(output_file_name)
compare_output(output_names[i], mace_out_value,
output_values[i])
compare_output(platform, mace_runtime, output_names[i],
mace_out_value, output_values[i])
def validate_caffe_model(input_names, input_shapes, output_names,
output_shapes):
os.environ['GLOG_minloglevel'] = '1' # suppress Caffe verbose prints
def validate_caffe_model(platform, mace_runtime, model_file, input_file,
mace_out_file, weight_file, input_names, input_shapes,
output_names, output_shapes):
os.environ['GLOG_minloglevel'] = '1' # suprress Caffe verbose prints
import caffe
if not os.path.isfile(FLAGS.model_file):
print("Input graph file '" + FLAGS.model_file + "' does not exist!")
if not os.path.isfile(model_file):
print("Input graph file '" + model_file + "' does not exist!")
sys.exit(-1)
if not os.path.isfile(FLAGS.weight_file):
print("Input weight file '" + FLAGS.weight_file + "' does not exist!")
if not os.path.isfile(weight_file):
print("Input weight file '" + weight_file + "' does not exist!")
sys.exit(-1)
caffe.set_mode_cpu()
net = caffe.Net(FLAGS.model_file, caffe.TEST, weights=FLAGS.weight_file)
net = caffe.Net(model_file, caffe.TEST, weights=weight_file)
for i in range(len(input_names)):
input_value = load_data(FLAGS.input_file + "_" +
format_name(input_names[i]))
input_value = load_data(input_file + "_" + format_name(input_names[i]))
input_value = input_value.reshape(input_shapes[i]).transpose((0, 3, 1,
2))
input_blob_name = input_names[i]
......@@ -126,28 +142,33 @@ def validate_caffe_model(input_names, input_shapes, output_names,
out_shape[1], out_shape[2], out_shape[3] = out_shape[3], out_shape[
1], out_shape[2]
value = value.reshape(out_shape).transpose((0, 2, 3, 1))
output_file_name = FLAGS.mace_out_file + "_" + format_name(
output_file_name = mace_out_file + "_" + format_name(
output_names[i])
mace_out_value = load_data(output_file_name)
compare_output(output_names[i], mace_out_value, value)
compare_output(platform, mace_runtime, output_names[i], mace_out_value,
value)
def main(unused_args):
input_names = [name for name in FLAGS.input_node.split(',')]
input_shape_strs = [shape for shape in FLAGS.input_shape.split(':')]
def validate(platform, model_file, weight_file, input_file, mace_out_file,
mace_runtime, input_shape, output_shape, input_node, output_node):
input_names = [name for name in input_node.split(',')]
input_shape_strs = [shape for shape in input_shape.split(':')]
input_shapes = [[int(x) for x in shape.split(',')]
for shape in input_shape_strs]
output_names = [name for name in FLAGS.output_node.split(',')]
output_names = [name for name in output_node.split(',')]
assert len(input_names) == len(input_shapes)
if FLAGS.platform == 'tensorflow':
validate_tf_model(input_names, input_shapes, output_names)
elif FLAGS.platform == 'caffe':
output_shape_strs = [shape for shape in FLAGS.output_shape.split(':')]
if platform == 'tensorflow':
validate_tf_model(platform, mace_runtime, model_file, input_file,
mace_out_file, input_names, input_shapes,
output_names)
elif platform == 'caffe':
output_shape_strs = [shape for shape in output_shape.split(':')]
output_shapes = [[int(x) for x in shape.split(',')]
for shape in output_shape_strs]
validate_caffe_model(input_names, input_shapes, output_names,
output_shapes)
validate_caffe_model(platform, mace_runtime, model_file, input_file,
mace_out_file, weight_file, input_names,
input_shapes, output_names, output_shapes)
def parse_args():
......@@ -189,4 +210,13 @@ def parse_args():
if __name__ == '__main__':
FLAGS, unparsed = parse_args()
main(unused_args=[sys.argv[0]] + unparsed)
validate(FLAGS.platform,
FLAGS.model_file,
FLAGS.weight_file,
FLAGS.input_file,
FLAGS.mace_out_file,
FLAGS.mace_runtime,
FLAGS.input_shape,
FLAGS.output_shape,
FLAGS.input_node,
FLAGS.output_node)
#!/bin/bash
Usage() {
echo "Usage: bash tools/validate_tools.sh target_soc model_output_dir generate_data_or_not"
}
if [ $# -lt 3 ]; then
Usage
exit 1
fi
CURRENT_DIR=`dirname $0`
source ${CURRENT_DIR}/env.sh
TARGET_SOC=$1
MODEL_OUTPUT_DIR=$2
GENERATE_DATA_OR_NOT=$3
RESULT_VALUE=`echo_device_id_by_soc $TARGET_SOC`
if [ $? -ne 0 ]; then
echo $RESULT_VALUE
exit 1
else
DEVICE_ID=$RESULT_VALUE
fi
IFS=',' read -r -a INPUT_NAMES <<< "${INPUT_NODES}"
IFS=',' read -r -a OUTPUT_NAMES <<< "${OUTPUT_NODES}"
echo $MODEL_OUTPUT_DIR
if [ "$GENERATE_DATA_OR_NOT" = 1 ]; then
for NAME in "${INPUT_NAMES[@]}";do
FORMATTED_NAME=$(sed s/[^[:alnum:]]/_/g <<< ${NAME})
rm -rf ${MODEL_OUTPUT_DIR}/${INPUT_FILE_NAME}_${FORMATTED_NAME}
done
python -u tools/generate_data.py --input_node=${INPUT_NODES} \
--input_file=${MODEL_OUTPUT_DIR}/${INPUT_FILE_NAME} \
--input_shape="${INPUT_SHAPES}" || exit 1
exit 0
fi
if [ "$PLATFORM" == "tensorflow" ];then
if [[ x"$TARGET_ABI" != x"host" ]]; then
for NAME in "${OUTPUT_NAMES[@]}";do
FORMATTED_NAME=$(sed s/[^[:alnum:]]/_/g <<< ${NAME})
rm -rf ${MODEL_OUTPUT_DIR}/${OUTPUT_FILE_NAME}_${FORMATTED_NAME}
adb -s $DEVICE_ID pull ${PHONE_DATA_DIR}/${OUTPUT_FILE_NAME}_${FORMATTED_NAME} ${MODEL_OUTPUT_DIR} > /dev/null || exit 1
done
fi
python -u tools/validate.py --platform=tensorflow \
--model_file ${MODEL_FILE_PATH} \
--input_file ${MODEL_OUTPUT_DIR}/${INPUT_FILE_NAME} \
--mace_out_file ${MODEL_OUTPUT_DIR}/${OUTPUT_FILE_NAME} \
--mace_runtime ${RUNTIME} \
--input_node ${INPUT_NODES} \
--output_node ${OUTPUT_NODES} \
--input_shape ${INPUT_SHAPES} \
--output_shape ${OUTPUT_SHAPES} || exit 1
elif [ "$PLATFORM" == "caffe" ];then
IMAGE_NAME=mace-caffe:latest
CONTAINER_NAME=mace_caffe_validator
RES_FILE=validation.result
if [[ "$(docker images -q mace-caffe:latest 2> /dev/null)" == "" ]]; then
echo "Build caffe docker"
docker build -t ${IMAGE_NAME} docker/caffe || exit 1
fi
if [ ! "$(docker ps -qa -f name=${CONTAINER_NAME})" ]; then
echo "Run caffe container"
docker run -d -it --name ${CONTAINER_NAME} ${IMAGE_NAME} /bin/bash || exit 1
fi
if [ "$(docker inspect -f {{.State.Running}} ${CONTAINER_NAME})" == "false" ];then
echo "Start caffe container"
docker start ${CONTAINER_NAME}
fi
for NAME in "${INPUT_NAMES[@]}";do
FORMATTED_NAME=$(sed s/[^[:alnum:]]/_/g <<< ${NAME})
docker cp ${MODEL_OUTPUT_DIR}/${INPUT_FILE_NAME}_${FORMATTED_NAME} ${CONTAINER_NAME}:/mace
done
if [[ x"$TARGET_ABI" != x"host" ]]; then
for NAME in "${OUTPUT_NAMES[@]}";do
FORMATTED_NAME=$(sed s/[^[:alnum:]]/_/g <<< ${NAME})
rm -rf ${MODEL_OUTPUT_DIR}/${OUTPUT_FILE_NAME}_${FORMATTED_NAME}
adb -s $DEVICE_ID pull ${PHONE_DATA_DIR}/${OUTPUT_FILE_NAME}_${FORMATTED_NAME} ${MODEL_OUTPUT_DIR} > /dev/null || exit 1
done
fi
for NAME in "${OUTPUT_NAMES[@]}";do
FORMATTED_NAME=$(sed s/[^[:alnum:]]/_/g <<< ${NAME})
docker cp ${MODEL_OUTPUT_DIR}/${OUTPUT_FILE_NAME}_${FORMATTED_NAME} ${CONTAINER_NAME}:/mace
done
MODEL_FILE_NAME=$(basename ${MODEL_FILE_PATH})
WEIGHT_FILE_NAME=$(basename ${WEIGHT_FILE_PATH})
docker cp tools/validate.py ${CONTAINER_NAME}:/mace
docker cp ${MODEL_FILE_PATH} ${CONTAINER_NAME}:/mace
docker cp ${WEIGHT_FILE_PATH} ${CONTAINER_NAME}:/mace
docker exec ${CONTAINER_NAME} python -u /mace/validate.py \
--platform=caffe \
--model_file /mace/${MODEL_FILE_NAME} \
--weight_file /mace/${WEIGHT_FILE_NAME} \
--input_file /mace/${INPUT_FILE_NAME} \
--mace_out_file /mace/${OUTPUT_FILE_NAME} \
--mace_runtime ${RUNTIME} \
--input_node ${INPUT_NODES} \
--output_node ${OUTPUT_NODES} \
--input_shape ${INPUT_SHAPES} \
--output_shape ${OUTPUT_SHAPES} || exit 1
fi
# 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 numpy as np
import math
import tensorflow as tf
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册