From 15c2a2f7c0ce47b8c6dec66fcc846d11726e7dd3 Mon Sep 17 00:00:00 2001 From: Andrew Reusch Date: Mon, 27 Jul 2020 15:57:43 -0700 Subject: [PATCH] bring bundle_deploy back to life and add to CI --- apps/bundle_deploy/Makefile | 38 +++++++------- apps/bundle_deploy/build_model.py | 64 +++++++++++++---------- apps/bundle_deploy/bundle.c | 54 +++++++++---------- apps/bundle_deploy/bundle.cc | 1 + apps/bundle_deploy/demo_static.gcda | Bin 0 -> 1220 bytes apps/bundle_deploy/func_registry.gcda | Bin 0 -> 1068 bytes apps/bundle_deploy/runtime.cc | 37 +++++++++++++ tests/scripts/task_python_integration.sh | 2 +- 8 files changed, 118 insertions(+), 78 deletions(-) create mode 100644 apps/bundle_deploy/demo_static.gcda create mode 100644 apps/bundle_deploy/func_registry.gcda create mode 100644 apps/bundle_deploy/runtime.cc diff --git a/apps/bundle_deploy/Makefile b/apps/bundle_deploy/Makefile index edea08c86bfe..a2a559f563f2 100644 --- a/apps/bundle_deploy/Makefile +++ b/apps/bundle_deploy/Makefile @@ -42,15 +42,15 @@ demo_dynamic: $(build_dir)/demo_dynamic $(build_dir)/bundle.so $(build_dir)/bund TVM_NUM_THREADS=1 $(build_dir)/demo_dynamic $(build_dir)/bundle.so $(build_dir)/cat.bin TVM_NUM_THREADS=1 $(build_dir)/demo_dynamic $(build_dir)/bundle_c.so $(build_dir)/cat.bin -test_dynamic: $(build_dir)/test_dynamic $(build_dir)/test_bundle.so $(build_dir)/test_bundle_c.so $(build_dir)/test_data.bin $(build_dir)/test_output.bin - TVM_NUM_THREADS=1 $(build_dir)/test_dynamic $(build_dir)/test_bundle.so $(build_dir)/test_data.bin $(build_dir)/test_output.bin $(build_dir)/test_graph.json $(build_dir)/test_params.bin - TVM_NUM_THREADS=1 $(build_dir)/test_dynamic $(build_dir)/test_bundle_c.so $(build_dir)/test_data.bin $(build_dir)/test_output.bin $(build_dir)/test_graph.json $(build_dir)/test_params.bin +test_dynamic: $(build_dir)/test_dynamic $(build_dir)/test_bundle.so $(build_dir)/test_bundle_c.so $(build_dir)/test_data_c.bin $(build_dir)/test_output_c.bin $(build_dir)/test_data_cpp.bin $(build_dir)/test_output_cpp.bin + TVM_NUM_THREADS=1 $(build_dir)/test_dynamic $(build_dir)/test_bundle.so $(build_dir)/test_data_cpp.bin $(build_dir)/test_output_cpp.bin $(build_dir)/test_graph_cpp.json $(build_dir)/test_params_cpp.bin + TVM_NUM_THREADS=1 $(build_dir)/test_dynamic $(build_dir)/test_bundle_c.so $(build_dir)/test_data_c.bin $(build_dir)/test_output_c.bin $(build_dir)/test_graph_c.json $(build_dir)/test_params_c.bin demo_static: $(build_dir)/demo_static $(build_dir)/cat.bin TVM_NUM_THREADS=1 $(build_dir)/demo_static $(build_dir)/cat.bin -test_static: $(build_dir)/test_static $(build_dir)/test_data.bin $(build_dir)/test_output.bin - TVM_NUM_THREADS=1 $(build_dir)/test_static $(build_dir)/test_data.bin $(build_dir)/test_output.bin $(build_dir)/test_graph.json $(build_dir)/test_params.bin +test_static: $(build_dir)/test_static $(build_dir)/test_data_c.bin $(build_dir)/test_output_c.bin + TVM_NUM_THREADS=1 $(build_dir)/test_static $(build_dir)/test_data_c.bin $(build_dir)/test_output_c.bin $(build_dir)/test_graph_c.json $(build_dir)/test_params_c.bin $(build_dir)/crt/graph_runtime/libgraph_runtime.a: cd $(CRT_ROOT) && make QUIET= BUILD_DIR=$(abspath $(build_dir))/crt CRT_CONFIG=$(abspath crt_config/crt_config.h) graph_runtime @@ -58,19 +58,19 @@ $(build_dir)/crt/graph_runtime/libgraph_runtime.a: $(build_dir)/crt/common/libcommon.a: cd $(CRT_ROOT) && make QUIET= BUILD_DIR=$(abspath $(build_dir))/crt CRT_CONFIG=$(abspath crt_config/crt_config.h) common -$(build_dir)/demo_dynamic: demo.cc ${build_dir}/graph.json.c ${build_dir}/params.bin.c +$(build_dir)/demo_dynamic: demo.cc ${build_dir}/graph_c.json.c ${build_dir}/params_c.bin.c @mkdir -p $(@D) g++ $(PKG_CXXFLAGS) -o $@ demo.cc -ldl -$(build_dir)/test_dynamic: test.cc ${build_dir}/test_graph.json ${build_dir}/test_params.bin +$(build_dir)/test_dynamic: test.cc ${build_dir}/test_graph_c.json ${build_dir}/test_params_c.bin @mkdir -p $(@D) g++ $(PKG_CXXFLAGS) -o $@ test.cc -ldl -$(build_dir)/demo_static: demo_static.c ${build_dir}/bundle_static.o ${build_dir}/model.o ${build_dir}/graph.json.c ${build_dir}/params.bin.c ${build_dir}/crt/graph_runtime/libgraph_runtime.a ${build_dir}/crt/common/libcommon.a +$(build_dir)/demo_static: demo_static.c ${build_dir}/bundle_static.o ${build_dir}/model_c.o ${build_dir}/graph_c.json.c ${build_dir}/params_c.bin.c ${build_dir}/crt/graph_runtime/libgraph_runtime.a ${build_dir}/crt/common/libcommon.a @mkdir -p $(@D) gcc $(PKG_CFLAGS) -o $@ demo_static.c ${build_dir}/bundle_static.o ${build_dir}/model.o -lm ${build_dir}/crt/graph_runtime/libgraph_runtime.a ${build_dir}/crt/common/libcommon.a -$(build_dir)/test_static: test_static.c ${build_dir}/bundle_static.o ${build_dir}/test_model.o ${build_dir}/crt/graph_runtime/libgraph_runtime.a ${build_dir}/crt/common/libcommon.a +$(build_dir)/test_static: test_static.c ${build_dir}/bundle_static.o ${build_dir}/test_model_c.o ${build_dir}/crt/graph_runtime/libgraph_runtime.a ${build_dir}/crt/common/libcommon.a @mkdir -p $(@D) gcc $(PKG_CFLAGS) -o $@ $^ @@ -79,33 +79,33 @@ $(build_dir)/graph.json.c: $(build_dir)/graph.json xxd -i $^ > $@ # Serialize our params.bin file. -$(build_dir)/params.bin.c: $(build_dir)/params.bin +$(build_dir)/params_c.bin.c: $(build_dir)/params_c.bin xxd -i $^ > $@ -$(build_dir)/model.o $(build_dir)/graph.json $(build_dir)/params.bin $(build_dir)/cat.bin: build_model.py +$(build_dir)/params_cpp.bin.c: $(build_dir)/params_cpp.bin + xxd -i $^ > $@ + +$(build_dir)/model_c.o $(build_dir)/graph_c.json $(build_dir)/model_cpp.o $(build_dir)/graph_cpp.json $(build_dir)/params.bin $(build_dir)/cat.bin: build_model.py python3 $< -o $(build_dir) -$(build_dir)/test_model.c $(build_dir)/test_graph.json $(build_dir)/test_params.bin $(build_dir)/test_data.bin $(build_dir)/test_output.bin: build_model.py +$(build_dir)/test_model_c.o $(build_dir)/test_graph_c.json $(build_dir)/test_params_c.bin $(build_dir)/test_data_c.bin $(build_dir)/test_output_c.bin $(build_dir)/test_model_cpp.o $(build_dir)/test_graph_cpp.json $(build_dir)/test_params_cpp.bin $(build_dir)/test_data_cpp.bin $(build_dir)/test_output_cpp.bin: build_model.py python3 $< -o $(build_dir) --test -$(build_dir)/test_model.o: $(build_dir)/test_model.c - gcc $(PKG_CFLAGS) -c -o $@ $^ - # Build our bundle against the serialized bundle.c API, the runtime.cc API, and # the serialized graph.json and params.bin -$(build_dir)/bundle.so: bundle.cc $(build_dir)/model.o $(build_dir)/func_registry.o ${build_dir}/crt/graph_runtime/libgraph_runtime.a ${build_dir}/crt/common/libcommon.a +$(build_dir)/bundle.so: bundle.cc runtime.cc $(build_dir)/model_cpp.o @mkdir -p $(@D) g++ -shared $(PKG_CXXFLAGS) -fvisibility=hidden -o $@ $^ $(PKG_LDFLAGS) -$(build_dir)/bundle_c.so: bundle.c runtime.c $(build_dir)/model.o $(build_dir)/func_registry.c +$(build_dir)/bundle_c.so: bundle.c $(build_dir)/model_c.o $(build_dir)/func_registry.c @mkdir -p $(@D) gcc -shared $(PKG_CFLAGS) -fvisibility=hidden -o $@ $^ $(PKG_LDFLAGS) -$(build_dir)/test_bundle.so: bundle.cc runtime.cc $(build_dir)/test_model.o $(build_dir)/test_func_registry.c +$(build_dir)/test_bundle.so: bundle.cc runtime.cc $(build_dir)/test_model_cpp.o @mkdir -p $(@D) g++ -shared $(PKG_CXXFLAGS) -fvisibility=hidden -o $@ $^ $(PKG_LDFLAGS) -$(build_dir)/test_bundle_c.so: bundle.c runtime.c $(build_dir)/test_model.o $(build_dir)/test_func_registry.c +$(build_dir)/test_bundle_c.so: bundle.c $(build_dir)/test_model_c.o ${build_dir}/crt/graph_runtime/libgraph_runtime.a ${build_dir}/crt/common/libcommon.a @mkdir -p $(@D) gcc -shared $(PKG_CFLAGS) -fvisibility=hidden -o $@ $^ $(PKG_LDFLAGS) diff --git a/apps/bundle_deploy/build_model.py b/apps/bundle_deploy/build_model.py index 83d4070db975..e99623fbdcc0 100644 --- a/apps/bundle_deploy/build_model.py +++ b/apps/bundle_deploy/build_model.py @@ -24,6 +24,11 @@ import logging import json +RUNTIMES = { + 'c': '{name}_c.{ext}', + 'c++': '{name}_cpp.{ext}', +} + def build_module(opts): dshape = (1, 3, 224, 224) from mxnet.gluon.model_zoo.vision import get_model @@ -33,19 +38,20 @@ def build_module(opts): func = mod["main"] func = relay.Function(func.params, relay.nn.softmax(func.body), None, func.type_params, func.attrs) - with tvm.transform.PassContext(opt_level=3, config={'tir.disable_vectorize': True}): - graph, lib, params = relay.build( - func, 'llvm --runtime=c --system-lib', params=params) + for runtime_name, file_format_str in RUNTIMES.items(): + with tvm.transform.PassContext(opt_level=3, config={'tir.disable_vectorize': True}): + graph, lib, params = relay.build( + func, f'llvm --runtime={runtime_name} --system-lib', params=params) - build_dir = os.path.abspath(opts.out_dir) - if not os.path.isdir(build_dir): - os.makedirs(build_dir) + build_dir = os.path.abspath(opts.out_dir) + if not os.path.isdir(build_dir): + os.makedirs(build_dir) - lib.save(os.path.join(build_dir, 'model.o')) - with open(os.path.join(build_dir, 'graph.json'), 'w') as f_graph_json: - f_graph_json.write(graph) - with open(os.path.join(build_dir, 'params.bin'), 'wb') as f_params: - f_params.write(relay.save_param_dict(params)) + lib.save(os.path.join(build_dir, file_format_str.format(name='model', ext='o'))) + with open(os.path.join(build_dir, file_format_str.format(name='graph', ext='json')), 'w') as f_graph_json: + f_graph_json.write(graph) + with open(os.path.join(build_dir, file_format_str.format(name='params', ext='bin')), 'wb') as f_params: + f_params.write(relay.save_param_dict(params)) def build_test_module(opts): import numpy as np @@ -57,24 +63,26 @@ def build_test_module(opts): x_data = np.random.rand(10, 5).astype('float32') y_data = np.random.rand(1, 5).astype('float32') params = {"y": y_data} - with tvm.transform.PassContext(opt_level=3, config={'tir.disable_vectorize': True}): - graph, lib, params = relay.build( - tvm.IRModule.from_expr(func), "llvm --runtime=c --system-lib", params=params) - build_dir = os.path.abspath(opts.out_dir) - if not os.path.isdir(build_dir): - os.makedirs(build_dir) - - lib.save(os.path.join(build_dir, 'test_model.o')) - with open(os.path.join(build_dir, 'test_graph.json'), 'w') as f_graph_json: - f_graph_json.write(graph) - with open(os.path.join(build_dir, 'test_params.bin'), 'wb') as f_params: - f_params.write(relay.save_param_dict(params)) - with open(os.path.join(build_dir, "test_data.bin"), "wb") as fp: - fp.write(x_data.astype(np.float32).tobytes()) - x_output = x_data + y_data - with open(os.path.join(build_dir, "test_output.bin"), "wb") as fp: - fp.write(x_output.astype(np.float32).tobytes()) + for runtime_name, file_format_str in RUNTIMES.items(): + with tvm.transform.PassContext(opt_level=3, config={'tir.disable_vectorize': True}): + graph, lib, lowered_params = relay.build( + tvm.IRModule.from_expr(func), f"llvm --runtime={runtime_name} --system-lib", params=params) + + build_dir = os.path.abspath(opts.out_dir) + if not os.path.isdir(build_dir): + os.makedirs(build_dir) + + lib.save(os.path.join(build_dir, file_format_str.format(name='test_model', ext='o'))) + with open(os.path.join(build_dir, file_format_str.format(name='test_graph', ext='json')), 'w') as f_graph_json: + f_graph_json.write(graph) + with open(os.path.join(build_dir, file_format_str.format(name='test_params', ext='bin')), 'wb') as f_params: + f_params.write(relay.save_param_dict(lowered_params)) + with open(os.path.join(build_dir, file_format_str.format(name="test_data", ext="bin")), "wb") as fp: + fp.write(x_data.astype(np.float32).tobytes()) + x_output = x_data + y_data + with open(os.path.join(build_dir, file_format_str.format(name="test_output", ext="bin")), "wb") as fp: + fp.write(x_output.astype(np.float32).tobytes()) def build_inputs(opts): from tvm.contrib import download diff --git a/apps/bundle_deploy/bundle.c b/apps/bundle_deploy/bundle.c index d86c79e0c1bc..88e51cfcc2ec 100644 --- a/apps/bundle_deploy/bundle.c +++ b/apps/bundle_deploy/bundle.c @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include /*! \brief macro to do C API call */ #define TVM_CCALL(func) \ @@ -45,50 +48,41 @@ TVM_DLL void* tvm_runtime_create(const char* json_data, const char* params_data, ctx.device_id = device_id; // declare pointers - TVMModuleHandle (*SystemLibraryCreate)(); - TVMModuleHandle (*TVMGraphRuntimeCreate)(const char*, const TVMModuleHandle, const TVMContext*); - int (*TVMGraphRuntime_LoadParams)(TVMModuleHandle, const char*, const uint32_t); + TVM_CCALL(TVMInitializeRuntime()); + TVMPackedFunc pf; + TVMArgs args = TVMArgs_Create(NULL, NULL, 0); + TVM_CCALL(TVMPackedFunc_InitGlobalFunc(&pf, "runtime.SystemLib", &args)); + TVM_CCALL(TVMPackedFunc_Call(&pf)); - TVM_CCALL(TVMRuntimeInitialize()); - - // get pointers - TVM_CCALL(TVMFuncGetGlobal("runtime.SystemLib", (TVMFunctionHandle*)&SystemLibraryCreate)); - TVM_CCALL( - TVMFuncGetGlobal("tvm.graph_runtime.create", (TVMFunctionHandle*)&TVMGraphRuntimeCreate)); + TVMModuleHandle mod_syslib = TVMArgs_AsModuleHandle(&pf.ret_value, 0); // run modules - TVMModuleHandle mod_syslib = SystemLibraryCreate(); - TVMModuleHandle mod = TVMGraphRuntimeCreate(json_data, mod_syslib, &ctx); - TVM_CCALL( - TVMModGetFunction(mod, "load_params", 0, (TVMFunctionHandle*)&TVMGraphRuntime_LoadParams)); - TVMGraphRuntime_LoadParams(mod, params.data, params.size); + TVMGraphRuntime* graph_runtime = TVMGraphRuntime_Create(json_data, mod_syslib, &ctx); + TVMGraphRuntime_LoadParams(graph_runtime, params.data, params.size); - return mod; + return graph_runtime; } TVM_DLL void tvm_runtime_destroy(void* runtime) { - void (*TVMGraphRuntimeRelease)(TVMModuleHandle*); - TVM_CCALL( - TVMFuncGetGlobal("tvm.graph_runtime.release", (TVMFunctionHandle*)&TVMGraphRuntimeRelease)); - TVMGraphRuntimeRelease(&runtime); + TVMGraphRuntime_Release((TVMGraphRuntime**) &runtime); } TVM_DLL void tvm_runtime_set_input(void* runtime, const char* name, DLTensor* tensor) { - void (*TVMGraphRuntime_SetInput)(TVMModuleHandle, const char*, DLTensor*); - TVM_CCALL(TVMFuncGetGlobal("tvm.graph_runtime.set_input", - (TVMFunctionHandle*)&TVMGraphRuntime_SetInput)); - TVMGraphRuntime_SetInput(runtime, name, tensor); + TVMGraphRuntime* graph_runtime = (TVMGraphRuntime*)runtime; + TVMGraphRuntime_SetInput(graph_runtime, name, tensor); } TVM_DLL void tvm_runtime_run(void* runtime) { - void (*TVMGraphRuntime_Run)(TVMModuleHandle runtime); - TVM_CCALL(TVMFuncGetGlobal("tvm.graph_runtime.run", (TVMFunctionHandle*)&TVMGraphRuntime_Run)); - TVMGraphRuntime_Run(runtime); + TVMGraphRuntime* graph_runtime = (TVMGraphRuntime*)runtime; + TVMGraphRuntime_Run(graph_runtime); } TVM_DLL void tvm_runtime_get_output(void* runtime, int32_t index, DLTensor* tensor) { - int (*TVMGraphRuntime_GetOutput)(TVMModuleHandle, const int32_t, DLTensor*); - TVM_CCALL(TVMFuncGetGlobal("tvm.graph_runtime.get_output", - (TVMFunctionHandle*)&TVMGraphRuntime_GetOutput)); - TVMGraphRuntime_GetOutput(runtime, index, tensor); + TVMGraphRuntime* graph_runtime = (TVMGraphRuntime*)runtime; + TVMGraphRuntime_GetOutput(graph_runtime, index, tensor); +} + +void __attribute__((noreturn)) TVMPlatformAbort(int error_code) { + fprintf(stderr, "TVMPlatformAbort: %d\n", error_code); + exit(-1); } diff --git a/apps/bundle_deploy/bundle.cc b/apps/bundle_deploy/bundle.cc index d8ff683decc3..e3cc7d1730ce 100644 --- a/apps/bundle_deploy/bundle.cc +++ b/apps/bundle_deploy/bundle.cc @@ -34,6 +34,7 @@ TVM_BUNDLE_FUNCTION void* tvm_runtime_create(const char* build_graph_json, tvm::runtime::Module mod_syslib = (*tvm::runtime::Registry::Get("runtime.SystemLib"))(); int device_type = kDLCPU; int device_id = 0; + tvm::runtime::Module mod = (*tvm::runtime::Registry::Get("tvm.graph_runtime.create"))( json_data, mod_syslib, device_type, device_id); TVMByteArray params; diff --git a/apps/bundle_deploy/demo_static.gcda b/apps/bundle_deploy/demo_static.gcda new file mode 100644 index 0000000000000000000000000000000000000000..ef3225c8d0cd81384dfe3f0f34e9e8593ba7b74f GIT binary patch literal 1220 zcmcIjJ4jqn5S`UTO$f;5G*WG z$cj}+6Eu(y`K;vAq_9sBHl4)A#?G*rGiUBr7B*hkd(NCYZ)Wb?*{PZAY`VK=VB`Cz zJ`veI(QWbP*Y~>@L=wu!U;nC75GmFf1iam_^sfB7Twa6IDXZZW?U`!99UQAhe;193 zG&>^UW#`u&@mQCg4>B-5d+IfWHlr`0F+&jy5x7KlpfOS=$tu9} z74{hzd*luL;rE4>xdLacvz53GxJtfL#rM6bX1M3ef2{8kG|%_<5B(nln#c=Z;30zc zq$4nql@T@r5i)m7s-VqA7qvGFta%V-FSWRhjYfor52$@uBU;p9a@iu<^{2^GADQXyJO9OiR1FE-PQ%ejpSk*!2~IE91r^TP0dKj1i=IUmaU4-E=X_W%F@ literal 0 HcmV?d00001 diff --git a/apps/bundle_deploy/func_registry.gcda b/apps/bundle_deploy/func_registry.gcda new file mode 100644 index 0000000000000000000000000000000000000000..b5b794a4dfdd9479c38a0a1e47e2a66def7f96ad GIT binary patch literal 1068 zcmZuv%}Z2q6uo2Gq=Zh=Vv@868kQT!Mc4@eosVJ zPW5{I_t)mvT9JhEk+p*w1(DJvgMjVL^To&fv^gSS zgY&D7_%7uxEEY2dtUgZJWjw-)neCf{sm@$_yn7#;x2wWn2p)t}X$$Nn3E9@~a z?#KuD$NPnry$olq^Cs~VppksNhX1!!&CuuP|E#Ybn&&${qW?3%b@IYbc!*#;T@jeb zyXPDRB4oQws-o>i54CS|tT_ksF15ImgGPk@C)Boqp)+TLE9J$JdzGzKU6^IGUd?RBDhv)&5>ste5PUYr$KD1GhI}$>g8q d)hmI&u#o)F+uAepvG^vlDzcnFR`108&HxKnPZ$6I literal 0 HcmV?d00001 diff --git a/apps/bundle_deploy/runtime.cc b/apps/bundle_deploy/runtime.cc new file mode 100644 index 000000000000..8e294a05775d --- /dev/null +++ b/apps/bundle_deploy/runtime.cc @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +#include +#include +#include +#include + +#include "../../src/runtime/c_runtime_api.cc" +#include "../../src/runtime/cpu_device_api.cc" +#include "../../src/runtime/file_util.cc" +#include "../../src/runtime/graph/graph_runtime.cc" +#include "../../src/runtime/library_module.cc" +#include "../../src/runtime/module.cc" +#include "../../src/runtime/ndarray.cc" +#include "../../src/runtime/object.cc" +#include "../../src/runtime/registry.cc" +#include "../../src/runtime/system_library.cc" +#include "../../src/runtime/thread_pool.cc" +#include "../../src/runtime/threading_backend.cc" +#include "../../src/runtime/workspace_pool.cc" diff --git a/tests/scripts/task_python_integration.sh b/tests/scripts/task_python_integration.sh index f7539d6a55fd..d61895c45973 100755 --- a/tests/scripts/task_python_integration.sh +++ b/tests/scripts/task_python_integration.sh @@ -36,7 +36,7 @@ make cython3 # Test MISRA-C runtime cd apps/bundle_deploy rm -rf build -# make test_dynamic test_static +make test_dynamic test_static cd ../.. # Test extern package