提交 6da30d22 编写于 作者: L Liangliang He

Enable python style check

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