sh_commands.py 43.4 KB
Newer Older
Y
yejianwu 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# 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.

Y
yejianwu 已提交
15 16
import falcon_cli
import filelock
Y
yejianwu 已提交
17
import glob
L
liuqi 已提交
18
import logging
19
import numpy as np
Y
yejianwu 已提交
20
import os
21
import re
Y
yejianwu 已提交
22
import sh
23
import struct
Y
yejianwu 已提交
24
import subprocess
25
import sys
26
import time
W
wuchenghui 已提交
27
import urllib
A
Allen 已提交
28
import platform
29
from enum import Enum
30

L
liuqi 已提交
31
import common
L
Liangliang He 已提交
32

33 34 35 36 37 38
sys.path.insert(0, "mace/python/tools")
try:
    from encrypt_opencl_codegen import encrypt_opencl_codegen
    from binary_codegen import tuning_param_codegen
    from generate_data import generate_input_data
    from validate import validate
39
    from mace_engine_factory_codegen import gen_mace_engine_factory
Y
yejianwu 已提交
40 41
except Exception as e:
    print("Import error:\n%s" % e)
42 43
    exit(1)

44 45 46
################################
# common
################################
L
liuqi 已提交
47 48


49
def strip_invalid_utf8(str):
L
Liangliang He 已提交
50 51
    return sh.iconv(str, "-c", "-t", "UTF-8")

52

53 54 55 56 57 58
def split_stdout(stdout_str):
    stdout_str = strip_invalid_utf8(stdout_str)
    # Filter out last empty line
    return [l.strip() for l in stdout_str.split('\n') if len(l.strip()) > 0]


59
def make_output_processor(buff):
L
Liangliang He 已提交
60
    def process_output(line):
L
Liangliang He 已提交
61
        print(line.rstrip())
L
Liangliang He 已提交
62 63 64 65
        buff.append(line)

    return process_output

66

67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
def device_lock_path(serialno):
    return "/tmp/device-lock-%s" % serialno


def device_lock(serialno, timeout=3600):
    return filelock.FileLock(device_lock_path(serialno), timeout=timeout)


def is_device_locked(serialno):
    try:
        with device_lock(serialno, timeout=0.000001):
            return False
    except filelock.Timeout:
        return True


83 84 85 86 87
class BuildType(object):
    proto = 'proto'
    code = 'code'


88 89 90 91 92
class ModelFormat(object):
    file = 'file'
    code = 'code'


93 94 95 96 97 98 99 100 101
def stdout_success(stdout):
    stdout_lines = stdout.split("\n")
    for line in stdout_lines:
        if "Aborted" in line or "FAILED" in line or \
                        "Segmentation fault" in line:
            return False
    return True


Y
yejianwu 已提交
102 103 104
################################
# clear data
################################
105 106 107 108 109
def clear_phone_data_dir(serialno, phone_data_dir):
    sh.adb("-s",
           serialno,
           "shell",
           "rm -rf %s" % phone_data_dir)
110 111


112 113 114
################################
# adb commands
################################
W
wuchenghui 已提交
115 116
def adb_devices():
    serialnos = []
117
    p = re.compile(r'(\w+)\s+device')
118
    for line in split_stdout(sh.adb("devices")):
119 120
        m = p.match(line)
        if m:
W
wuchenghui 已提交
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
            serialnos.append(m.group(1))

    return serialnos


def get_soc_serialnos_map():
    serialnos = adb_devices()
    soc_serialnos_map = {}
    for serialno in serialnos:
        props = adb_getprop_by_serialno(serialno)
        soc_serialnos_map.setdefault(props["ro.board.platform"], [])\
            .append(serialno)

    return soc_serialnos_map


def get_target_socs_serialnos(target_socs=None):
    soc_serialnos_map = get_soc_serialnos_map()
    serialnos = []
    if target_socs is None:
        target_socs = soc_serialnos_map.keys()
    for target_soc in target_socs:
        serialnos.extend(soc_serialnos_map[target_soc])
    return serialnos
L
Liangliang He 已提交
145

146 147

def adb_getprop_by_serialno(serialno):
L
Liangliang He 已提交
148
    outputs = sh.adb("-s", serialno, "shell", "getprop")
149
    raw_props = split_stdout(outputs)
L
Liangliang He 已提交
150
    props = {}
151
    p = re.compile(r'\[(.+)\]: \[(.+)\]')
L
Liangliang He 已提交
152 153 154 155 156 157
    for raw_prop in raw_props:
        m = p.match(raw_prop)
        if m:
            props[m.group(1)] = m.group(2)
    return props

158

W
wuchenghui 已提交
159 160
def adb_get_device_name_by_serialno(serialno):
    props = adb_getprop_by_serialno(serialno)
L
liuqi 已提交
161
    return props.get("ro.product.model", "").replace(' ', '')
W
wuchenghui 已提交
162 163


164
def adb_supported_abis(serialno):
L
Liangliang He 已提交
165 166 167 168 169
    props = adb_getprop_by_serialno(serialno)
    abilist_str = props["ro.product.cpu.abilist"]
    abis = [abi.strip() for abi in abilist_str.split(',')]
    return abis

170

171
def adb_get_all_socs():
L
Liangliang He 已提交
172 173 174 175 176
    socs = []
    for d in adb_devices():
        props = adb_getprop_by_serialno(d)
        socs.append(props["ro.board.platform"])
    return set(socs)
177

L
Liangliang He 已提交
178

Y
yejianwu 已提交
179 180 181 182 183 184 185 186 187 188 189 190 191
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)


192 193
def adb_run(abi,
            serialno,
L
Liangliang He 已提交
194 195
            host_bin_path,
            bin_name,
196
            args="",
L
liuqi 已提交
197
            opencl_profiling=True,
198
            vlog_level=0,
199
            device_bin_path="/data/local/tmp/mace",
L
liuqi 已提交
200
            out_of_range_check=True,
201
            address_sanitizer=False):
L
Liangliang He 已提交
202 203 204 205 206 207
    host_bin_full_path = "%s/%s" % (host_bin_path, bin_name)
    device_bin_full_path = "%s/%s" % (device_bin_path, bin_name)
    props = adb_getprop_by_serialno(serialno)
    print(
        "====================================================================="
    )
L
Liangliang He 已提交
208
    print("Trying to lock device %s" % serialno)
209 210 211 212
    with device_lock(serialno):
        print("Run on device: %s, %s, %s" %
              (serialno, props["ro.board.platform"],
               props["ro.product.model"]))
Y
yejianwu 已提交
213 214
        sh.adb("-s", serialno, "shell", "rm -rf %s" % device_bin_path)
        sh.adb("-s", serialno, "shell", "mkdir -p %s" % device_bin_path)
Y
yejianwu 已提交
215
        adb_push(host_bin_full_path, device_bin_full_path, serialno)
216 217 218 219 220
        ld_preload = ""
        if address_sanitizer:
            adb_push(find_asan_rt_library(abi), device_bin_path, serialno)
            ld_preload = "LD_PRELOAD=%s/%s" % (device_bin_path,
                                               asan_rt_library_names(abi)),
L
liuqi 已提交
221 222
        opencl_profiling = 1 if opencl_profiling else 0
        out_of_range_check = 1 if out_of_range_check else 0
Y
yejianwu 已提交
223
        print("Run %s" % device_bin_full_path)
224

Y
yejianwu 已提交
225 226
        stdout_buff = []
        process_output = make_output_processor(stdout_buff)
L
liuqi 已提交
227
        sh.adb(
Y
yejianwu 已提交
228 229 230
            "-s",
            serialno,
            "shell",
231 232 233 234
            ld_preload,
            "MACE_OUT_OF_RANGE_CHECK=%d" % out_of_range_check,
            "MACE_OPENCL_PROFILING=%d" % opencl_profiling,
            "MACE_CPP_MIN_VLOG_LEVEL=%d" % vlog_level,
235 236 237
            device_bin_full_path,
            args,
            _tty_in=True,
Y
yejianwu 已提交
238
            _out=process_output,
239
            _err_to_out=True)
Y
yejianwu 已提交
240
        return "".join(stdout_buff)
241 242


243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
################################
# Toolchain
################################
def asan_rt_library_names(abi):
    asan_rt_names = {
        "armeabi-v7a": "libclang_rt.asan-arm-android.so",
        "arm64-v8a": "libclang_rt.asan-aarch64-android.so",
    }
    return asan_rt_names[abi]


def find_asan_rt_library(abi, asan_rt_path=''):
    if not asan_rt_path:
        find_path = os.environ['ANDROID_NDK_HOME']
        candidates = split_stdout(sh.find(find_path, "-name",
                                          asan_rt_library_names(abi)))
        if len(candidates) == 0:
            common.MaceLogger.error(
                "Toolchain",
                "Can't find AddressSanitizer runtime library in % s" %
                find_path)
        elif len(candidates) > 1:
            common.MaceLogger.info(
                "More than one AddressSanitizer runtime library, use the 1st")
        return candidates[0]
    return "%s/%s" % (asan_rt_path, asan_rt_library_names(abi))
269 270


271 272 273 274 275 276
def find_gnustl_shared_path(abi):
    return \
        "%s/sources/cxx-stl/gnu-libstdc++/4.9/libs/%s/libgnustl_shared.so" % \
        (os.environ["ANDROID_NDK_HOME"], abi)


277 278 279
################################
# bazel commands
################################
Y
yejianwu 已提交
280 281 282
def bazel_build(target,
                abi="armeabi-v7a",
                hexagon_mode=False,
李寅 已提交
283
                enable_openmp=True,
284
                enable_neon=True,
Y
yejianwu 已提交
285
                enable_opencl=True,
L
liuqi 已提交
286 287
                address_sanitizer=False,
                extra_args=""):
Y
yejianwu 已提交
288 289
    print("* Build %s with ABI %s" % (target, abi))
    if abi == "host":
W
wuchenghui 已提交
290
        bazel_args = (
Y
yejianwu 已提交
291 292
            "build",
            "--define",
W
wuchenghui 已提交
293
            "openmp=%s" % str(enable_openmp).lower(),
294
            target,
W
wuchenghui 已提交
295
        )
Y
yejianwu 已提交
296 297 298 299
    else:
        bazel_args = (
            "build",
            target,
300 301
            "--config",
            "android",
Y
yejianwu 已提交
302 303
            "--cpu=%s" % abi,
            "--define",
李寅 已提交
304
            "neon=%s" % str(enable_neon).lower(),
Y
yejianwu 已提交
305
            "--define",
W
wuchenghui 已提交
306
            "openmp=%s" % str(enable_openmp).lower(),
Y
yejianwu 已提交
307
            "--define",
Y
yejianwu 已提交
308 309
            "opencl=%s" % str(enable_opencl).lower(),
            "--define",
Y
yejianwu 已提交
310
            "hexagon=%s" % str(hexagon_mode).lower())
311 312 313 314
    if address_sanitizer:
        bazel_args += ("--config", "asan")
    else:
        bazel_args += ("--config", "optimization")
L
liuqi 已提交
315 316
    if extra_args:
        bazel_args += (extra_args, )
317
        print bazel_args
L
liuqi 已提交
318 319
    sh.bazel(
        _fg=True,
320 321
        *bazel_args)
    print("Build done!\n")
Y
yejianwu 已提交
322 323 324


def bazel_build_common(target, build_args=""):
L
Liangliang He 已提交
325 326
    stdout_buff = []
    process_output = make_output_processor(stdout_buff)
L
liuqi 已提交
327
    sh.bazel(
L
Liangliang He 已提交
328
        "build",
Y
yejianwu 已提交
329
        target + build_args,
330
        _tty_in=True,
L
Liangliang He 已提交
331
        _out=process_output,
332
        _err_to_out=True)
L
Liangliang He 已提交
333 334
    return "".join(stdout_buff)

335 336

def bazel_target_to_bin(target):
L
Liangliang He 已提交
337 338 339 340 341 342 343 344
    # change //mace/a/b:c to bazel-bin/mace/a/b/c
    prefix, bin_name = target.split(':')
    prefix = prefix.replace('//', '/')
    if prefix.startswith('/'):
        prefix = prefix[1:]
    host_bin_path = "bazel-bin/%s" % prefix
    return host_bin_path, bin_name

345 346 347 348 349

################################
# mace commands
################################
def gen_encrypted_opencl_source(codegen_path="mace/codegen"):
L
Liangliang He 已提交
350
    sh.mkdir("-p", "%s/opencl" % codegen_path)
351 352
    encrypt_opencl_codegen("./mace/kernels/opencl/cl/",
                           "mace/codegen/opencl/opencl_encrypt_program.cc")
L
Liangliang He 已提交
353

354

Y
yejianwu 已提交
355
def gen_mace_engine_factory_source(model_tags,
B
Bin Li 已提交
356
                                   embed_model_data,
Y
yejianwu 已提交
357
                                   codegen_path="mace/codegen"):
B
Bin Li 已提交
358
    print("* Generate mace engine creator source")
359 360 361
    codegen_tools_dir = "%s/engine" % codegen_path
    sh.rm("-rf", codegen_tools_dir)
    sh.mkdir("-p", codegen_tools_dir)
362
    gen_mace_engine_factory(
363 364
        model_tags,
        "mace/python/tools",
B
Bin Li 已提交
365
        embed_model_data,
366
        codegen_tools_dir)
B
Bin Li 已提交
367
    print("Generate mace engine creator source done!\n")
368 369


370 371 372 373 374 375 376
def pull_file_from_device(serial_num, file_path, file_name, output_dir):
    if not os.path.exists(output_dir):
        sh.mkdir("-p", output_dir)
    output_path = "%s/%s" % (output_dir, file_path)
    if os.path.exists(output_path):
        sh.rm('-rf', output_path)
    adb_pull(file_path + '/' + file_name, output_dir, serial_num)
Y
yejianwu 已提交
377 378


379 380 381 382
def merge_opencl_binaries(binaries_dirs,
                          cl_compiled_program_file_name,
                          output_file_path):
    platform_info_key = 'mace_opencl_precompiled_platform_info_key'
Y
yejianwu 已提交
383
    cl_bin_dirs = []
384
    for d in binaries_dirs:
Y
yejianwu 已提交
385
        cl_bin_dirs.append(os.path.join(d, "opencl_bin"))
386 387
    # create opencl binary output dir
    opencl_binary_dir = os.path.dirname(output_file_path)
L
liuqi 已提交
388 389
    if not os.path.exists(opencl_binary_dir):
        sh.mkdir("-p", opencl_binary_dir)
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
    kvs = {}
    for binary_dir in cl_bin_dirs:
        binary_path = os.path.join(binary_dir, cl_compiled_program_file_name)
        if not os.path.exists(binary_path):
            continue

        print 'generate opencl code from', binary_path
        with open(binary_path, "rb") as f:
            binary_array = np.fromfile(f, dtype=np.uint8)

        idx = 0
        size, = struct.unpack("Q", binary_array[idx:idx + 8])
        idx += 8
        for _ in xrange(size):
            key_size, = struct.unpack("i", binary_array[idx:idx + 4])
            idx += 4
            key, = struct.unpack(
                str(key_size) + "s", binary_array[idx:idx + key_size])
            idx += key_size
            value_size, = struct.unpack("i", binary_array[idx:idx + 4])
            idx += 4
            if key == platform_info_key and key in kvs:
                common.mace_check(
                    (kvs[key] == binary_array[idx:idx + value_size]).all(),
                    "",
                    "There exists more than one OpenCL version for models:"
                    " %s vs %s " %
                    (kvs[key], binary_array[idx:idx + value_size]))
            else:
                kvs[key] = binary_array[idx:idx + value_size]
            idx += value_size

    output_byte_array = bytearray()
    data_size = len(kvs)
    output_byte_array.extend(struct.pack("Q", data_size))
    for key, value in kvs.iteritems():
        key_size = len(key)
        output_byte_array.extend(struct.pack("i", key_size))
        output_byte_array.extend(struct.pack(str(key_size) + "s", key))
        value_size = len(value)
        output_byte_array.extend(struct.pack("i", value_size))
        output_byte_array.extend(value)

    np.array(output_byte_array).tofile(output_file_path)
Y
yejianwu 已提交
434 435


L
liuqi 已提交
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
def merge_opencl_parameters(binaries_dirs,
                            cl_parameter_file_name,
                            output_file_path):
    cl_bin_dirs = []
    for d in binaries_dirs:
        cl_bin_dirs.append(os.path.join(d, "opencl_bin"))
    # create opencl binary output dir
    opencl_binary_dir = os.path.dirname(output_file_path)
    if not os.path.exists(opencl_binary_dir):
        sh.mkdir("-p", opencl_binary_dir)
    kvs = {}
    for binary_dir in cl_bin_dirs:
        binary_path = os.path.join(binary_dir, cl_parameter_file_name)
        if not os.path.exists(binary_path):
            continue

        print 'generate opencl parameter from', binary_path
        with open(binary_path, "rb") as f:
            binary_array = np.fromfile(f, dtype=np.uint8)

        idx = 0
        size, = struct.unpack("Q", binary_array[idx:idx + 8])
        idx += 8
        for _ in xrange(size):
            key_size, = struct.unpack("i", binary_array[idx:idx + 4])
            idx += 4
            key, = struct.unpack(
                str(key_size) + "s", binary_array[idx:idx + key_size])
            idx += key_size
            value_size, = struct.unpack("i", binary_array[idx:idx + 4])
            idx += 4
            kvs[key] = binary_array[idx:idx + value_size]
            idx += value_size

    output_byte_array = bytearray()
    data_size = len(kvs)
    output_byte_array.extend(struct.pack("Q", data_size))
    for key, value in kvs.iteritems():
        key_size = len(key)
        output_byte_array.extend(struct.pack("i", key_size))
        output_byte_array.extend(struct.pack(str(key_size) + "s", key))
        value_size = len(value)
        output_byte_array.extend(struct.pack("i", value_size))
        output_byte_array.extend(value)

    np.array(output_byte_array).tofile(output_file_path)


Y
yejianwu 已提交
484 485 486 487 488
def gen_model_code(model_codegen_dir,
                   platform,
                   model_file_path,
                   weight_file_path,
                   model_sha256_checksum,
489
                   weight_sha256_checksum,
Y
yejianwu 已提交
490 491 492 493 494 495 496
                   input_nodes,
                   output_nodes,
                   runtime,
                   model_tag,
                   input_shapes,
                   dsp_mode,
                   embed_model_data,
497
                   winograd,
Y
yejianwu 已提交
498
                   obfuscate,
499
                   model_graph_format,
李寅 已提交
500
                   data_type,
李寅 已提交
501
                   graph_optimize_options):
Y
yejianwu 已提交
502
    bazel_build_common("//mace/python/tools:converter")
Y
yejianwu 已提交
503

Y
yejianwu 已提交
504 505 506
    if os.path.exists(model_codegen_dir):
        sh.rm("-rf", model_codegen_dir)
    sh.mkdir("-p", model_codegen_dir)
Y
yejianwu 已提交
507

L
liuqi 已提交
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
    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,
              "--weight_checksum=%s" % weight_sha256_checksum,
              "--input_node=%s" % input_nodes,
              "--output_node=%s" % output_nodes,
              "--runtime=%s" % runtime,
              "--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,
523
              "--winograd=%s" % winograd,
L
liuqi 已提交
524 525
              "--obfuscate=%s" % obfuscate,
              "--output_dir=%s" % model_codegen_dir,
526
              "--model_graph_format=%s" % model_graph_format,
L
liuqi 已提交
527
              "--data_type=%s" % data_type,
李寅 已提交
528
              "--graph_optimize_options=%s" % graph_optimize_options,
L
liuqi 已提交
529
              _fg=True)
Y
yejianwu 已提交
530 531 532 533 534 535


def gen_random_input(model_output_dir,
                     input_nodes,
                     input_shapes,
                     input_files,
536 537
                     input_ranges,
                     input_file_name="model_input"):
Y
yejianwu 已提交
538
    for input_name in input_nodes:
L
liuqi 已提交
539 540
        formatted_name = common.formatted_file_name(
            input_file_name, input_name)
541 542
        if os.path.exists("%s/%s" % (model_output_dir, formatted_name)):
            sh.rm("%s/%s" % (model_output_dir, formatted_name))
Y
yejianwu 已提交
543 544
    input_nodes_str = ",".join(input_nodes)
    input_shapes_str = ":".join(input_shapes)
545
    input_ranges_str = ":".join(input_ranges)
546 547
    generate_input_data("%s/%s" % (model_output_dir, input_file_name),
                        input_nodes_str,
李寅 已提交
548 549
                        input_shapes_str,
                        input_ranges_str)
Y
yejianwu 已提交
550 551 552 553 554 555 556 557

    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 = []
W
wuchenghui 已提交
558 559
        if isinstance(input_nodes, list):
            input_name_list.extend(input_nodes)
Y
yejianwu 已提交
560
        else:
W
wuchenghui 已提交
561
            input_name_list.append(input_nodes)
Y
yejianwu 已提交
562 563 564 565 566 567
        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 + '/' + \
L
liuqi 已提交
568 569
                        common.formatted_file_name(input_file_name,
                                                   input_name_list[i])
Y
yejianwu 已提交
570 571 572 573
                if input_file_list[i].startswith("http://") or \
                        input_file_list[i].startswith("https://"):
                    urllib.urlretrieve(input_file_list[i], dst_input_file)
                else:
574
                    sh.cp("-f", input_file_list[i], dst_input_file)
Y
yejianwu 已提交
575 576


577 578 579
def update_mace_run_binary(build_tmp_binary_dir, link_dynamic=False):
    if link_dynamic:
        mace_run_filepath = build_tmp_binary_dir + "/mace_run_dynamic"
Y
yejianwu 已提交
580
    else:
581
        mace_run_filepath = build_tmp_binary_dir + "/mace_run_static"
Y
yejianwu 已提交
582

Y
yejianwu 已提交
583 584
    if os.path.exists(mace_run_filepath):
        sh.rm("-rf", mace_run_filepath)
585 586
    if link_dynamic:
        sh.cp("-f", "bazel-bin/mace/tools/validation/mace_run_dynamic",
Y
yejianwu 已提交
587 588
              build_tmp_binary_dir)
    else:
589
        sh.cp("-f", "bazel-bin/mace/tools/validation/mace_run_static",
Y
yejianwu 已提交
590
              build_tmp_binary_dir)
591 592


593 594 595 596
def create_internal_storage_dir(serialno, phone_data_dir):
    internal_storage_dir = "%s/interior/" % phone_data_dir
    sh.adb("-s", serialno, "shell", "mkdir", "-p", internal_storage_dir)
    return internal_storage_dir
597 598


W
wuchenghui 已提交
599 600
def tuning_run(abi,
               serialno,
L
liuqi 已提交
601 602
               target_dir,
               target_name,
Y
yejianwu 已提交
603 604 605 606 607 608 609
               vlog_level,
               embed_model_data,
               model_output_dir,
               input_nodes,
               output_nodes,
               input_shapes,
               output_shapes,
Y
yejianwu 已提交
610
               mace_model_dir,
Y
yejianwu 已提交
611 612 613 614 615 616 617
               model_tag,
               device_type,
               running_round,
               restart_round,
               limit_opencl_kernel_time,
               tuning,
               out_of_range_check,
618
               phone_data_dir,
619
               model_graph_format,
620
               opencl_binary_file,
L
liuqi 已提交
621
               opencl_parameter_file,
622
               libmace_dynamic_library_path,
W
wuchenghui 已提交
623 624 625 626
               omp_num_threads=-1,
               cpu_affinity_policy=1,
               gpu_perf_hint=3,
               gpu_priority_hint=3,
Y
yejianwu 已提交
627
               input_file_name="model_input",
628 629
               output_file_name="model_out",
               runtime_failure_ratio=0.0,
Y
yejianwu 已提交
630
               address_sanitizer=False,
631
               link_dynamic=False):
632
    print("* Run '%s' with round=%s, restart_round=%s, tuning=%s, "
W
wuchenghui 已提交
633 634
          "out_of_range_check=%s, omp_num_threads=%s, cpu_affinity_policy=%s, "
          "gpu_perf_hint=%s, gpu_priority_hint=%s" %
635
          (model_tag, running_round, restart_round, str(tuning),
W
wuchenghui 已提交
636 637
           str(out_of_range_check), omp_num_threads, cpu_affinity_policy,
           gpu_perf_hint, gpu_priority_hint))
638
    mace_model_path = ""
639
    if model_graph_format == ModelFormat.file:
640
        mace_model_path = "%s/%s.pb" % (mace_model_dir, model_tag)
Y
yejianwu 已提交
641
    if abi == "host":
W
wuchenghui 已提交
642 643
        p = subprocess.Popen(
            [
Y
yejianwu 已提交
644 645
                "env",
                "MACE_CPP_MIN_VLOG_LEVEL=%s" % vlog_level,
李寅 已提交
646
                "MACE_RUNTIME_FAILURE_RATIO=%f" % runtime_failure_ratio,
L
liuqi 已提交
647
                "%s/%s" % (target_dir, target_name),
648
                "--model_name=%s" % model_tag,
Y
yejianwu 已提交
649 650 651 652 653 654
                "--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),
655
                "--model_data_file=%s/%s.data" % (mace_model_dir, model_tag),
Y
yejianwu 已提交
656 657 658
                "--device=%s" % device_type,
                "--round=%s" % running_round,
                "--restart_round=%s" % restart_round,
W
wuchenghui 已提交
659 660 661 662
                "--omp_num_threads=%s" % omp_num_threads,
                "--cpu_affinity_policy=%s" % cpu_affinity_policy,
                "--gpu_perf_hint=%s" % gpu_perf_hint,
                "--gpu_priority_hint=%s" % gpu_priority_hint,
Y
yejianwu 已提交
663
                "--model_file=%s" % mace_model_path,
W
wuchenghui 已提交
664 665 666
            ],
            stderr=subprocess.PIPE,
            stdout=subprocess.PIPE)
Y
yejianwu 已提交
667 668 669 670
        out, err = p.communicate()
        stdout = err + out
        print stdout
        print("Running finished!\n")
Y
yejianwu 已提交
671 672
    else:
        sh.adb("-s", serialno, "shell", "mkdir", "-p", phone_data_dir)
673 674
        internal_storage_dir = create_internal_storage_dir(
            serialno, phone_data_dir)
Y
yejianwu 已提交
675 676

        for input_name in input_nodes:
L
liuqi 已提交
677 678
            formatted_name = common.formatted_file_name(input_file_name,
                                                        input_name)
Y
yejianwu 已提交
679 680
            adb_push("%s/%s" % (model_output_dir, formatted_name),
                     phone_data_dir, serialno)
681 682 683
        if address_sanitizer:
            adb_push(find_asan_rt_library(abi), phone_data_dir, serialno)

Y
yejianwu 已提交
684
        if not embed_model_data:
685
            adb_push("%s/%s.data" % (mace_model_dir, model_tag),
Y
yejianwu 已提交
686
                     phone_data_dir, serialno)
687

L
liuqi 已提交
688 689 690 691 692
        if device_type == common.DeviceType.GPU:
            if os.path.exists(opencl_binary_file):
                adb_push(opencl_binary_file, phone_data_dir, serialno)
            if os.path.exists(opencl_parameter_file):
                adb_push(opencl_parameter_file, phone_data_dir, serialno)
693

W
wuchenghui 已提交
694
        adb_push("third_party/nnlib/libhexagon_controller.so",
Y
yejianwu 已提交
695 696
                 phone_data_dir, serialno)

697
        mace_model_phone_path = ""
698
        if model_graph_format == ModelFormat.file:
699 700 701
            mace_model_phone_path = "%s/%s.pb" % (phone_data_dir, model_tag)
            adb_push(mace_model_path,
                     mace_model_phone_path,
Y
yejianwu 已提交
702
                     serialno)
703

704 705
        if link_dynamic:
            adb_push(libmace_dynamic_library_path, phone_data_dir,
Y
yejianwu 已提交
706
                     serialno)
707
            adb_push(find_gnustl_shared_path(abi),
Y
yejianwu 已提交
708 709 710
                     phone_data_dir,
                     serialno)

L
liuqi 已提交
711
        adb_push("%s/%s" % (target_dir, target_name), phone_data_dir,
712
                 serialno)
Y
yejianwu 已提交
713

Y
yejianwu 已提交
714 715
        stdout_buff = []
        process_output = make_output_processor(stdout_buff)
716
        adb_cmd = [
W
wuchenghui 已提交
717 718 719 720
            "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,
721
            "MACE_RUN_PARAMETER_PATH=%s/mace_run.config" % phone_data_dir,
722
            "MACE_INTERNAL_STORAGE_PATH=%s" % internal_storage_dir,
723
            "MACE_LIMIT_OPENCL_KERNEL_TIME=%s" % limit_opencl_kernel_time,
李寅 已提交
724
            "MACE_RUNTIME_FAILURE_RATIO=%f" % runtime_failure_ratio,
725
        ]
726
        if address_sanitizer:
727
            adb_cmd.extend([
728 729
                "LD_PRELOAD=%s/%s" % (phone_data_dir,
                                      asan_rt_library_names(abi))
730 731
            ])
        adb_cmd.extend([
L
liuqi 已提交
732
            "%s/%s" % (phone_data_dir, target_name),
733
            "--model_name=%s" % model_tag,
W
wuchenghui 已提交
734 735 736 737 738 739 740 741 742 743 744 745 746 747
            "--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,
            "--omp_num_threads=%s" % omp_num_threads,
            "--cpu_affinity_policy=%s" % cpu_affinity_policy,
            "--gpu_perf_hint=%s" % gpu_perf_hint,
            "--gpu_priority_hint=%s" % gpu_priority_hint,
748
            "--model_file=%s" % mace_model_phone_path,
749 750
            "--opencl_binary_file=%s/%s" %
            (phone_data_dir, os.path.basename(opencl_binary_file)),
L
liuqi 已提交
751 752
            "--opencl_parameter_file=%s/%s" %
            (phone_data_dir, os.path.basename(opencl_parameter_file)),
753 754
        ])
        adb_cmd = ' '.join(adb_cmd)
李滨 已提交
755 756 757 758
        cmd_file_name = "%s-%s-%s" % ('cmd_file', model_tag, str(time.time()))
        adb_cmd_file = "%s/%s" % (phone_data_dir, cmd_file_name)
        tmp_cmd_file = "%s/%s" % ('/tmp', cmd_file_name)
        with open(tmp_cmd_file, 'w') as cmd_file:
李寅 已提交
759
            cmd_file.write(adb_cmd)
李滨 已提交
760 761
        adb_push(tmp_cmd_file, adb_cmd_file, serialno)
        os.remove(tmp_cmd_file)
李寅 已提交
762

L
liuqi 已提交
763
        sh.adb(
764 765 766
            "-s",
            serialno,
            "shell",
李寅 已提交
767 768
            "sh",
            adb_cmd_file,
769
            _tty_in=True,
W
wuchenghui 已提交
770
            _out=process_output,
771
            _err_to_out=True)
772 773 774
        stdout = "".join(stdout_buff)
        if not stdout_success(stdout):
            common.MaceLogger.error("Mace Run", "Mace run failed.")
李滨 已提交
775 776 777 778 779 780 781 782 783

        sh.adb(
            "-s",
            serialno,
            "shell",
            "rm",
            adb_cmd_file,
            _fg=True)

Y
yejianwu 已提交
784
        print("Running finished!\n")
李滨 已提交
785

L
liuqi 已提交
786
    return stdout
Y
yejianwu 已提交
787 788


W
wuchenghui 已提交
789 790
def validate_model(abi,
                   serialno,
Y
yejianwu 已提交
791 792 793
                   model_file_path,
                   weight_file_path,
                   platform,
794
                   device_type,
Y
yejianwu 已提交
795 796 797 798 799
                   input_nodes,
                   output_nodes,
                   input_shapes,
                   output_shapes,
                   model_output_dir,
800
                   phone_data_dir,
L
liuqi 已提交
801
                   caffe_env,
Y
yejianwu 已提交
802 803 804
                   input_file_name="model_input",
                   output_file_name="model_out"):
    print("* Validate with %s" % platform)
L
liuqi 已提交
805 806 807 808 809 810 811 812 813
    if abi != "host":
        for output_name in output_nodes:
            formatted_name = common.formatted_file_name(
                output_file_name, output_name)
            if os.path.exists("%s/%s" % (model_output_dir,
                                         formatted_name)):
                sh.rm("-rf", "%s/%s" % (model_output_dir, formatted_name))
            adb_pull("%s/%s" % (phone_data_dir, formatted_name),
                     model_output_dir, serialno)
Y
yejianwu 已提交
814 815

    if platform == "tensorflow":
816 817
        validate(platform, model_file_path, "",
                 "%s/%s" % (model_output_dir, input_file_name),
818
                 "%s/%s" % (model_output_dir, output_file_name), device_type,
819 820
                 ":".join(input_shapes), ":".join(output_shapes),
                 ",".join(input_nodes), ",".join(output_nodes))
Y
yejianwu 已提交
821 822 823 824
    elif platform == "caffe":
        image_name = "mace-caffe:latest"
        container_name = "mace_caffe_validator"

L
liuqi 已提交
825 826 827 828 829 830 831 832
        if caffe_env == common.CaffeEnvType.LOCAL:
            import imp
            try:
                imp.find_module('caffe')
            except ImportError:
                logger.error('There is no caffe python module.')
            validate(platform, model_file_path, weight_file_path,
                     "%s/%s" % (model_output_dir, input_file_name),
833 834
                     "%s/%s" % (model_output_dir, output_file_name),
                     device_type,
L
liuqi 已提交
835 836 837 838 839 840 841
                     ":".join(input_shapes), ":".join(output_shapes),
                     ",".join(input_nodes), ",".join(output_nodes))
        elif caffe_env == common.CaffeEnvType.DOCKER:
            docker_image_id = sh.docker("images", "-q", image_name)
            if not docker_image_id:
                print("Build caffe docker")
                sh.docker("build", "-t", image_name,
L
Liangliang He 已提交
842
                          "third_party/caffe")
L
liuqi 已提交
843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868

            container_id = sh.docker("ps", "-qa", "-f",
                                     "name=%s" % container_name)
            if container_id and not sh.docker("ps", "-qa", "--filter",
                                              "status=running", "-f",
                                              "name=%s" % container_name):
                sh.docker("rm", "-f", container_name)
                container_id = ""
            if not container_id:
                print("Run caffe container")
                sh.docker(
                        "run",
                        "-d",
                        "-it",
                        "--name",
                        container_name,
                        image_name,
                        "/bin/bash")

            for input_name in input_nodes:
                formatted_input_name = common.formatted_file_name(
                        input_file_name, input_name)
                sh.docker(
                        "cp",
                        "%s/%s" % (model_output_dir, formatted_input_name),
                        "%s:/mace" % container_name)
Y
yejianwu 已提交
869 870

            for output_name in output_nodes:
L
liuqi 已提交
871 872 873 874 875 876 877 878
                formatted_output_name = common.formatted_file_name(
                        output_file_name, output_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)
L
liuqi 已提交
879
            sh.docker("cp", "tools/common.py", "%s:/mace" % container_name)
L
liuqi 已提交
880 881 882 883
            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)

L
liuqi 已提交
884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900
            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,
                "--device_type=%s" % device_type,
                "--input_node=%s" % ",".join(input_nodes),
                "--output_node=%s" % ",".join(output_nodes),
                "--input_shape=%s" % ":".join(input_shapes),
                "--output_shape=%s" % ":".join(output_shapes),
                _fg=True)
Y
yejianwu 已提交
901 902 903 904

    print("Validation done!\n")


L
liuqi 已提交
905 906 907
################################
# library
################################
Y
yejianwu 已提交
908 909 910 911 912 913 914 915 916 917
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))
A
Allen 已提交
918 919 920 921 922 923 924 925 926 927 928
    which_sys = platform.system()
    if which_sys == "Linux":
        sh.tar(
            "cvzf",
            "%s" % tar_package_path,
            glob.glob("%s/*" % project_dir),
            "--exclude",
            "%s/_tmp" % project_dir,
            _fg=True)
    elif which_sys == "Darwin":
        sh.tar(
A
Allen 已提交
929 930 931 932 933 934
            "--exclude",
            "%s/_tmp" % project_dir,
            "-cvzf",
            "%s" % tar_package_path,
            glob.glob("%s/*" % project_dir),
            _fg=True)
Y
yejianwu 已提交
935 936 937
    print("Packaging Done!\n")


L
liuqi 已提交
938 939 940
################################
# benchmark
################################
W
wuchenghui 已提交
941 942
def benchmark_model(abi,
                    serialno,
943
                    benchmark_binary_dir,
944
                    benchmark_binary_name,
Y
yejianwu 已提交
945 946 947
                    vlog_level,
                    embed_model_data,
                    model_output_dir,
Y
yejianwu 已提交
948
                    mace_model_dir,
Y
yejianwu 已提交
949 950 951 952 953 954
                    input_nodes,
                    output_nodes,
                    input_shapes,
                    output_shapes,
                    model_tag,
                    device_type,
955
                    phone_data_dir,
956
                    model_graph_format,
957
                    opencl_binary_file,
L
liuqi 已提交
958
                    opencl_parameter_file,
959
                    libmace_dynamic_library_path,
W
wuchenghui 已提交
960 961 962 963
                    omp_num_threads=-1,
                    cpu_affinity_policy=1,
                    gpu_perf_hint=3,
                    gpu_priority_hint=3,
Y
yejianwu 已提交
964
                    input_file_name="model_input",
965
                    link_dynamic=False):
Y
yejianwu 已提交
966 967
    print("* Benchmark for %s" % model_tag)

968
    mace_model_path = ""
969
    if model_graph_format == ModelFormat.file:
970
        mace_model_path = "%s/%s.pb" % (mace_model_dir, model_tag)
Y
yejianwu 已提交
971
    if abi == "host":
W
wuchenghui 已提交
972 973
        p = subprocess.Popen(
            [
Y
yejianwu 已提交
974 975
                "env",
                "MACE_CPP_MIN_VLOG_LEVEL=%s" % vlog_level,
976
                "%s/%s" % (benchmark_binary_dir, benchmark_binary_name),
977
                "--model_name=%s" % model_tag,
Y
yejianwu 已提交
978 979 980 981 982
                "--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),
983
                "--model_data_file=%s/%s.data" % (mace_model_dir, model_tag),
Y
yejianwu 已提交
984
                "--device=%s" % device_type,
W
wuchenghui 已提交
985 986 987 988
                "--omp_num_threads=%s" % omp_num_threads,
                "--cpu_affinity_policy=%s" % cpu_affinity_policy,
                "--gpu_perf_hint=%s" % gpu_perf_hint,
                "--gpu_priority_hint=%s" % gpu_priority_hint,
Y
yejianwu 已提交
989
                "--model_file=%s" % mace_model_path,
W
wuchenghui 已提交
990
            ])
Y
yejianwu 已提交
991 992 993
        p.wait()
    else:
        sh.adb("-s", serialno, "shell", "mkdir", "-p", phone_data_dir)
994 995
        internal_storage_dir = create_internal_storage_dir(
            serialno, phone_data_dir)
Y
yejianwu 已提交
996 997

        for input_name in input_nodes:
L
liuqi 已提交
998 999
            formatted_name = common.formatted_file_name(input_file_name,
                                                        input_name)
Y
yejianwu 已提交
1000 1001 1002
            adb_push("%s/%s" % (model_output_dir, formatted_name),
                     phone_data_dir, serialno)
        if not embed_model_data:
1003
            adb_push("%s/%s.data" % (mace_model_dir, model_tag),
Y
yejianwu 已提交
1004
                     phone_data_dir, serialno)
L
liuqi 已提交
1005 1006 1007 1008 1009
        if device_type == common.DeviceType.GPU:
            if os.path.exists(opencl_binary_file):
                adb_push(opencl_binary_file, phone_data_dir, serialno)
            if os.path.exists(opencl_parameter_file):
                adb_push(opencl_parameter_file, phone_data_dir, serialno)
1010
        mace_model_phone_path = ""
1011
        if model_graph_format == ModelFormat.file:
1012 1013 1014
            mace_model_phone_path = "%s/%s.pb" % (phone_data_dir, model_tag)
            adb_push(mace_model_path,
                     mace_model_phone_path,
Y
yejianwu 已提交
1015
                     serialno)
Y
yejianwu 已提交
1016

1017 1018
        if link_dynamic:
            adb_push(libmace_dynamic_library_path, phone_data_dir,
Y
yejianwu 已提交
1019
                     serialno)
1020
            adb_push(find_gnustl_shared_path(abi),
Y
yejianwu 已提交
1021 1022
                     phone_data_dir,
                     serialno)
1023
        adb_push("%s/%s" % (benchmark_binary_dir, benchmark_binary_name),
Y
yejianwu 已提交
1024
                 phone_data_dir,
1025
                 serialno)
Y
yejianwu 已提交
1026

李寅 已提交
1027
        adb_cmd = [
W
wuchenghui 已提交
1028 1029 1030 1031
            "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,
1032
            "MACE_INTERNAL_STORAGE_PATH=%s" % internal_storage_dir,
W
wuchenghui 已提交
1033
            "MACE_OPENCL_PROFILING=1",
1034
            "%s/%s" % (phone_data_dir, benchmark_binary_name),
1035
            "--model_name=%s" % model_tag,
W
wuchenghui 已提交
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046
            "--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,
            "--omp_num_threads=%s" % omp_num_threads,
            "--cpu_affinity_policy=%s" % cpu_affinity_policy,
            "--gpu_perf_hint=%s" % gpu_perf_hint,
            "--gpu_priority_hint=%s" % gpu_priority_hint,
1047
            "--model_file=%s" % mace_model_phone_path,
1048 1049
            "--opencl_binary_file=%s/%s" %
            (phone_data_dir, os.path.basename(opencl_binary_file)),
L
liuqi 已提交
1050 1051
            "--opencl_parameter_file=%s/%s" %
            (phone_data_dir, os.path.basename(opencl_parameter_file)),
李寅 已提交
1052 1053
        ]
        adb_cmd = ' '.join(adb_cmd)
李滨 已提交
1054 1055 1056 1057
        cmd_file_name = "%s-%s-%s" % ('cmd_file', model_tag, str(time.time()))
        adb_cmd_file = "%s/%s" % (phone_data_dir, cmd_file_name)
        tmp_cmd_file = "%s/%s" % ('/tmp', cmd_file_name)
        with open(tmp_cmd_file, 'w') as cmd_file:
李寅 已提交
1058
            cmd_file.write(adb_cmd)
李滨 已提交
1059 1060
        adb_push(tmp_cmd_file, adb_cmd_file, serialno)
        os.remove(tmp_cmd_file)
李寅 已提交
1061 1062 1063 1064 1065 1066 1067

        sh.adb(
            "-s",
            serialno,
            "shell",
            "sh",
            adb_cmd_file,
L
liuqi 已提交
1068
            _fg=True)
Y
yejianwu 已提交
1069

李滨 已提交
1070 1071 1072 1073 1074 1075 1076 1077
        sh.adb(
            "-s",
            serialno,
            "shell",
            "rm",
            adb_cmd_file,
            _fg=True)

Y
yejianwu 已提交
1078 1079 1080
    print("Benchmark done!\n")


W
wuchenghui 已提交
1081 1082
def build_run_throughput_test(abi,
                              serialno,
Y
yejianwu 已提交
1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094
                              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,
1095
                              phone_data_dir,
Y
yejianwu 已提交
1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
                              strip="always",
                              input_file_name="model_input"):
    print("* Build and run throughput_test")

    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

1111
    sh.cp("-f", merged_lib_file, "mace/benchmark/libmace_merged.a")
L
liuqi 已提交
1112
    sh.bazel(
Y
yejianwu 已提交
1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131
        "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,
L
liuqi 已提交
1132
        _fg=True)
Y
yejianwu 已提交
1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157

    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)
L
Liangliang He 已提交
1158
    adb_push("third_party/nnlib/libhexagon_controller.so",
Y
yejianwu 已提交
1159 1160 1161
             phone_data_dir,
             serialno)

L
liuqi 已提交
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183
    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,
        _fg=True)
Y
yejianwu 已提交
1184 1185 1186 1187

    print("throughput_test done!\n")


1188 1189 1190
################################
# falcon
################################
L
Liangliang He 已提交
1191
def falcon_tags(tags_dict):
L
Liangliang He 已提交
1192 1193 1194 1195 1196 1197 1198
    tags = ""
    for k, v in tags_dict.iteritems():
        if tags == "":
            tags = "%s=%s" % (k, v)
        else:
            tags = tags + ",%s=%s" % (k, v)
    return tags
L
Liangliang He 已提交
1199

1200

L
Liangliang He 已提交
1201 1202
def falcon_push_metrics(server, metrics, endpoint="mace_dev", tags={}):
    cli = falcon_cli.FalconCli.connect(server=server, port=8433, debug=False)
L
Liangliang He 已提交
1203 1204 1205 1206 1207 1208 1209
    ts = int(time.time())
    falcon_metrics = [{
        "endpoint": endpoint,
        "metric": key,
        "tags": falcon_tags(tags),
        "timestamp": ts,
        "value": value,
L
Liangliang He 已提交
1210
        "step": 600,
L
Liangliang He 已提交
1211 1212 1213
        "counterType": "GAUGE"
    } for key, value in metrics.iteritems()]
    cli.update(falcon_metrics)