From 86065273527fe0b87a947226f52658c4ed248b7e Mon Sep 17 00:00:00 2001 From: Yanzhan Yang Date: Fri, 5 Jul 2019 10:27:42 +0800 Subject: [PATCH] enhance tooling script and fix crash of tensor float * constructor (#1726) * enhance scripts * fix crash of tensor float * constructor --- CMakeLists.txt | 8 +++ src/framework/tensor.h | 10 ++-- test/net/test_net.cpp | 59 +++++++++++++--------- tools/python/fluidtools/run.py | 43 ++++++++++++---- tools/python/misc/restore-git.py | 54 ++++++++++++++++++++ tools/python/misc/test-fluid-op-feature.py | 13 +++++ tools/shell/check-bitcode.sh | 34 +++++++++++++ tools/shell/check-filename.sh | 41 +++++++++++++++ 8 files changed, 223 insertions(+), 39 deletions(-) mode change 100755 => 100644 src/framework/tensor.h create mode 100644 tools/python/misc/restore-git.py create mode 100644 tools/python/misc/test-fluid-op-feature.py create mode 100644 tools/shell/check-bitcode.sh create mode 100644 tools/shell/check-filename.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d25d5022f..d34e9738a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -278,3 +278,11 @@ if(WITH_TEST AND WITH_SYMBOL) elseif(FPGA) add_subdirectory(test) endif() + +# # if you want to combine third party static librares into paddle mobile so, please uncomment this code block +# target_link_libraries( +# paddle-mobile +# -Wl,--whole-archive +# "path_to_third_party_static_library" +# -Wl,--no-whole-archive +# ) diff --git a/src/framework/tensor.h b/src/framework/tensor.h old mode 100755 new mode 100644 index 5008a50bcc..de70d55735 --- a/src/framework/tensor.h +++ b/src/framework/tensor.h @@ -17,6 +17,7 @@ limitations under the License. */ #include #include #include +#include #include #include #include @@ -59,7 +60,8 @@ class Tensor : public TensorBase { template Tensor(T *input, DDim ddim) { - // PADDLE_MOBILE_ENFORCE( + // input pointer is allocated by external sources. can't calculate its + // length. PADDLE_MOBILE_ENFORCE( // (sizeof(input) / sizeof(input[0])) == framework::product(ddim), // "input vector'length should be equal to tensor's length"); @@ -209,7 +211,7 @@ class Tensor : public TensorBase { struct PlaceholderImpl : public Placeholder { PlaceholderImpl(size_t size, const kTypeId_t type) : ptr_(static_cast(memory::Alloc(size)), - memory::PODDeleter()), + [](uint8_t *ptr) { memory::PODDeleter()(ptr); }), size_(size), capatity_(size), type_(type) { @@ -218,7 +220,7 @@ class Tensor : public TensorBase { } PlaceholderImpl(size_t size, const kTypeId_t type, uint8_t *ptr) - : ptr_(ptr, memory::PODDeleter()), + : ptr_(ptr, [](uint8_t *ptr) {}), size_(size), capatity_(size), type_(type) { @@ -242,7 +244,7 @@ class Tensor : public TensorBase { size_ = size; } - std::unique_ptr> ptr_; + std::unique_ptr> ptr_; /*! the size of memory block. */ size_t size_; diff --git a/test/net/test_net.cpp b/test/net/test_net.cpp index 33e312e678..dc0fc887d4 100644 --- a/test/net/test_net.cpp +++ b/test/net/test_net.cpp @@ -79,7 +79,11 @@ void test(int argc, char *argv[]) { int var_count = std::stoi(argv[arg_index]); arg_index++; - int sample_step = std::stoi(argv[arg_index]); + bool is_sample_step = std::stoi(argv[arg_index]) == 1; + arg_index++; + int sample_arg = std::stoi(argv[arg_index]); + int sample_step = sample_arg; + int sample_num = sample_arg; arg_index++; std::vector var_names; for (int i = 0; i < var_count; i++) { @@ -130,30 +134,31 @@ void test(int argc, char *argv[]) { } } - // 预热10次 - for (int i = 0; i < 10; i++) { - if (is_lod) { - auto out = paddle_mobile.Predict(input_lod_tensor); - } else { - paddle_mobile.Feed(var_names[0], input_tensor); - paddle_mobile.Predict(); - } - } + // // 预热10次 + // for (int i = 0; i < 10; i++) { + // if (is_lod) { + // auto out = paddle_mobile.Predict(input_lod_tensor); + // } else { + // paddle_mobile.Feed(var_names[0], input_tensor); + // paddle_mobile.Predict(); + // } + // } - // 测速 - auto time5 = time(); - for (int i = 0; i < 50; i++) { - if (is_lod) { - auto out = paddle_mobile.Predict(input_lod_tensor); - } else { - paddle_mobile.Feed(var_names[0], input_tensor); - paddle_mobile.Predict(); - } - } - auto time6 = time(); - std::cout << "auto-test" - << " predict-time-cost " << time_diff(time5, time6) / 50 << "ms" - << std::endl; + // // 测速 + // auto time5 = time(); + // for (int i = 0; i < 50; i++) { + // if (is_lod) { + // auto out = paddle_mobile.Predict(input_lod_tensor); + // } else { + // paddle_mobile.Feed(var_names[0], input_tensor); + // paddle_mobile.Predict(); + // } + // } + // auto time6 = time(); + // std::cout << "auto-test" + // << " predict-time-cost " << time_diff(time5, time6) / 50 << + // "ms" + // << std::endl; // 测试正确性 if (is_lod) { @@ -173,6 +178,12 @@ void test(int argc, char *argv[]) { } auto data = out->data(); std::string sample = ""; + if (!is_sample_step) { + sample_step = len / sample_num; + } + if (sample_step <= 0) { + sample_step = 1; + } for (int i = 0; i < len; i += sample_step) { sample += " " + std::to_string(data[i]); } diff --git a/tools/python/fluidtools/run.py b/tools/python/fluidtools/run.py index 804062b76f..eb31c875d2 100644 --- a/tools/python/fluidtools/run.py +++ b/tools/python/fluidtools/run.py @@ -14,6 +14,9 @@ diff_threshold = 0.01 is_lod = False mobile_model_path = "" fast_check = False +is_sample_step = False +sample_step = 1 +sample_num = 20 np.set_printoptions(linewidth=150) @@ -108,7 +111,7 @@ def resave_model(feed_kv): def gen_feed_kv(): feed_kv = {} for feed_name in feeds: - feed_shape = get_var_shape(feed_name) + feed_shape = get_feed_var_shape(feed_name) data = np.random.random(feed_shape).astype("float32") feed_kv[feed_name] = data return feed_kv @@ -140,7 +143,7 @@ def load_feed_kv(): pp_yellow(dot + dot + " checking feed info") pp_green("feed data is saved into directory 【{}】".format(feed_path), 1) for feed_name in feeds: - feed_shape = get_var_shape(feed_name) + feed_shape = get_feed_var_shape(feed_name) pp_tab("feed var name : {}; feed var shape : {}".format(feed_name, feed_shape), 1) file_name = feed_name.replace("/", "_") last_feed_var_name = feed_name @@ -194,6 +197,12 @@ def get_var_shape(var_name): shape[i] = 1 return shape +# 获取输入变量形状 +def get_feed_var_shape(var_name): + # 如果想写死输入形状,放开以下语句 + # return [1, 3, 224, 224] + return get_var_shape(var_name) + # 获取var的数据 def get_var_data(var_name, feed_kv=None): # 强制var为可持久化 @@ -201,22 +210,25 @@ def get_var_data(var_name, feed_kv=None): persistable = v.persistable if not persistable: v.persistable = True - outputs = run_model(feed_kv=feed_kv) + # outputs = run_model(feed_kv=feed_kv) output = np.array(fluid.global_scope().find_var(var_name).get_tensor()) # 恢复var的可持久化属性 v.persistable = persistable return output output_var_cache = {} -sample_step = 1 def tensor_sample(tensor): - # step = math.floor(len(tensor) / 20) + if is_sample_step: + step = sample_step + else: + step = math.floor(len(tensor) / sample_num) + step = max(step, 1) sample = [] - for i in range(0, len(tensor), sample_step): + for i in range(0, len(tensor), step): sample.append(tensor[i]) return sample -op_cache = {} +op_cache = {} # 获取每层输出的数据 def save_all_op_output(feed_kv=None): if not os.path.exists(output_path): @@ -245,8 +257,12 @@ def save_all_op_output(feed_kv=None): op_cache[i] = (var_name, op) file_name = var_name.replace("/", "_") out_file = open(output_path + "/" + file_name, "w") - for item in data: - out_file.write("{}\n".format(item)) + if var_name in feed_names: + for item in data: + out_file.write("{}\n".format(item)) + else: + for item in sample: + out_file.write("{}\n".format(item)) out_file.close() except: pass @@ -265,6 +281,7 @@ def check_mobile_results(args, fuse, mem_opt): args = "{} {} {}".format("1" if fuse else "0", "1" if mem_opt else "0", args) res = sh("adb shell \"cd {} && export LD_LIBRARY_PATH=. && ./test-net {}\"".format(mobile_exec_root, args)) lines = res.split("\n") + print(lines) for line in lines: if line.startswith("auto-test-debug"): print(line) @@ -375,7 +392,7 @@ def main(): push(feed_path + "/" + last_feed_file_name, "input.txt") push(mobile_src_root + "/build/release/arm-v7a/build/libpaddle-mobile.so") push(mobile_src_root + "/test/build/test-net") - last_feed_var_shape = get_var_shape(last_feed_var_name) + last_feed_var_shape = get_feed_var_shape(last_feed_var_name) args = str(len(last_feed_var_shape)) for dim in last_feed_var_shape: args += " " + str(dim) @@ -387,7 +404,11 @@ def main(): else: args += " 0" args += " " + str(len(output_var_cache)) - args += " " + str(sample_step) + args += " " + str(1 if is_sample_step else 0) + if is_sample_step: + args += " " + str(sample_step) + else: + args += " " + str(sample_num) for var_name in output_var_cache.keys(): args += " " + var_name if not fast_check: diff --git a/tools/python/misc/restore-git.py b/tools/python/misc/restore-git.py new file mode 100644 index 0000000000..c0613bcb1d --- /dev/null +++ b/tools/python/misc/restore-git.py @@ -0,0 +1,54 @@ +import os +import sys +import subprocess + +username = "" +email = "" +home = "" +desktop = "{}/Desktop".format(home) +dir_1 = "{}/1".format(desktop) +dir_2 = "{}/2".format(desktop) +src_dir = dir_1 +dest_dir = dir_2 +src_mobile_dir = "{}/paddle-mobile".format(src_dir) +dest_mobile_dir = "{}/paddle-mobile".format(dest_dir) + +def clone_repo(dir): + os.chdir(dir) + os.system("git clone git@github.com:{}/paddle-mobile.git".format(username)) + os.chdir("{}/paddle-mobile".format(dir)) + os.system("git remote add upstream git@github.com:PaddlePaddle/paddle-mobile.git") + os.system("git config user.name {}".format(username)) + os.system("git config user.email {}".format(email)) + +def get_output(command): + out = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + stdout, stderr = out.communicate() + return stdout.decode("utf-8").split("\n") + +if __name__ == "__main__": + # if not os.path.isdir(src_dir): + # print("dir 1 not found") + # sys.exit(-1) + + if not os.path.isdir(dest_dir): + os.mkdir(dest_dir) + if not os.path.isdir(dest_mobile_dir): + clone_repo(dest_dir) + sys.exit() + + items = [] + # items = ["metal/.gitignore", "metal/VideoSuperResolution"] + os.chdir(src_mobile_dir) + for line in get_output("git status --porcelain"): + line = line.strip() + items.append(line.split(" ")[-1]) + + for item in items: + src = item + if len(src) <= 0: + continue + dest = dest_mobile_dir + "/" + item + cmd = "cp -R " + src + " " + dest + print(cmd) + os.system(cmd) diff --git a/tools/python/misc/test-fluid-op-feature.py b/tools/python/misc/test-fluid-op-feature.py new file mode 100644 index 0000000000..1657fd2477 --- /dev/null +++ b/tools/python/misc/test-fluid-op-feature.py @@ -0,0 +1,13 @@ +import numpy as np +import paddle.fluid as fluid + +exe = fluid.Executor(fluid.CPUPlace()) +exe.run(fluid.default_startup_program()) + +data = np.array([5.0]) +x = fluid.layers.data(name="x", shape=[1], dtype="float32") +y = fluid.layers.relu6(x, threshold=4.0) + +prog = fluid.default_main_program() +outputs = exe.run(prog, feed={"x": data}, fetch_list=[y]) +print(outputs) diff --git a/tools/shell/check-bitcode.sh b/tools/shell/check-bitcode.sh new file mode 100644 index 0000000000..a13cfac9c7 --- /dev/null +++ b/tools/shell/check-bitcode.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +archs=(armv7 armv7s arm64) +libraries=(*.a) +libtool="/usr/bin/libtool" + +echo "checking bitcode in ${libraries[*]}..." + +for library in ${libraries[*]} +do + lipo -info $library + + # Extract individual architectures for this library + for arch in ${archs[*]} + do + lipo -extract $arch $library -o ${library}_${arch}.a + done +done + +for arch in ${archs[*]} +do + source_libraries="" + + for library in ${libraries[*]} + do + echo "checking ${library}_${arch}.a" + printf "\tbitcode symbol number " + otool -l ${library}_${arch}.a | grep bitcode | wc -l + # Delete intermediate files + rm ${library}_${arch}.a + done +done + +echo "bitcode checking complete." diff --git a/tools/shell/check-filename.sh b/tools/shell/check-filename.sh new file mode 100644 index 0000000000..53eacc8c0e --- /dev/null +++ b/tools/shell/check-filename.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +archs=(armv7 armv7s arm64) +libraries=(*.a) +libtool="/usr/bin/libtool" + +echo "checking filename in ${libraries[*]}..." + +for library in ${libraries[*]} +do + lipo -info $library + + # Extract individual architectures for this library + for arch in ${archs[*]} + do + lipo $library -thin armv7 -output ${library}_${arch}.a + done +done + +for arch in ${archs[*]} +do + source_libraries="" + + for library in ${libraries[*]} + do + archlib=${library}_${arch}.a + echo "checking $archlib" + mkdir tmp_check_dir + cp $archlib tmp_check_dir + cd tmp_check_dir + ar -x $archlib + ls -alh | grep $1 + echo "" + cd .. + # Delete intermediate files + rm ${library}_${arch}.a + rm -rf tmp_check_dir + done +done + +echo "filename checking complete." -- GitLab