Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

µTVM CRT modifications for on-device RPC server #5921

Merged
merged 32 commits into from
Jul 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
15a4ca0
Reorganize CRT into parts, public API, and add standalone build.
areusch Jun 19, 2020
da7daab
Add TVMFuncRegistry, CRT test infrastructure, and tests.
areusch Jun 19, 2020
4e2688c
Add TVMErrorf()
areusch Jun 22, 2020
cf36cb3
[API_CHANGE] Integrate func registry into CRT.
areusch Jun 22, 2020
f664bbf
Generalize arena-based memory manager.
areusch Jun 22, 2020
4e1e1c8
lint
areusch Jun 25, 2020
5c724c0
Fix git-clang-format arg parsing
areusch Jun 25, 2020
a451506
add apache header
areusch Jun 25, 2020
fa4f0e6
add mutable func registry tests
areusch Jun 26, 2020
ea426db
Merge remote-tracking branch 'tvm/master' into utvm-crt-changes
areusch Jun 30, 2020
ad1a72a
git-clang-format
areusch Jun 30, 2020
9ce722f
fix more lint
areusch Jun 30, 2020
5ec235e
Move memory_test to crttests.
areusch Jun 30, 2020
c71fed9
fix tests
areusch Jul 1, 2020
d0988e1
checkpoint
areusch Jul 1, 2020
99b8b95
checkpoint
areusch Jul 2, 2020
349c04c
bundle_deploy demo_static works
areusch Jul 3, 2020
e7a251e
rm debug printf
areusch Jul 3, 2020
773ae77
git-clang-format
areusch Jul 3, 2020
d496349
Merge remote-tracking branch 'tvm/master' into utvm-crt-changes
areusch Jul 3, 2020
1c69010
fix lint
areusch Jul 3, 2020
408d820
add asf header
areusch Jul 3, 2020
2a9d157
pylint
areusch Jul 3, 2020
c19a346
update build configs for jenkins
areusch Jul 3, 2020
008d92b
make regression compiler happy
areusch Jul 3, 2020
099c254
fix build errors in regression GCC
areusch Jul 6, 2020
622a66e
Merge remote-tracking branch 'tvm/master' into utvm-crt-changes
areusch Jul 8, 2020
f0ee8a6
address comments
areusch Jul 9, 2020
d1a7b42
git-clang-format
areusch Jul 9, 2020
d2cc3b9
fix for 32-bit cpp regression
areusch Jul 9, 2020
0595624
fix incorrect use of memcpy and tests for 32-bit
areusch Jul 9, 2020
9acf614
clang-format
areusch Jul 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ endif(USE_EXAMPLE_EXT_RUNTIME)

# Module rules
include(cmake/modules/VTA.cmake)
include(cmake/modules/StandaloneCrt.cmake)
include(cmake/modules/CUDA.cmake)
include(cmake/modules/Hexagon.cmake)
include(cmake/modules/OpenCL.cmake)
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ vta:
cpptest:
@mkdir -p build && cd build && cmake .. && $(MAKE) cpptest

crttest:
@mkdir -p build && cd build && cmake .. && $(MAKE) crttest

# EMCC; Web related scripts
EMCC_FLAGS= -std=c++11 -DDMLC_LOG_STACK_TRACE=0\
-Oz -s RESERVED_FUNCTION_POINTERS=2 -s MAIN_MODULE=1 -s NO_EXIT_RUNTIME=1\
Expand Down
48 changes: 34 additions & 14 deletions apps/bundle_deploy/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,25 @@

# Setup build environment
TVM_ROOT=$(shell cd ../..; pwd)
CRT_ROOT ?= ../../src/runtime/crt

DMLC_CORE=${TVM_ROOT}/3rdparty/dmlc-core
PKG_CXXFLAGS = -Wall -std=c++14 -O2 -fPIC \
PKG_CXXFLAGS = -g -Wall -std=c++14 -O2 -fPIC \
-I${TVM_ROOT}/include \
-I${DMLC_CORE}/include \
-I${TVM_ROOT}/3rdparty/dlpack/include
PKG_CFLAGS = -Wall -std=c99 -O2 -fPIC \
-I${TVM_ROOT}/3rdparty/dlpack/include \
-Icrt_config
PKG_CFLAGS = -g -Wall -std=c99 -O2 -fPIC \
-I${TVM_ROOT}/include \
-I${DMLC_CORE}/include \
-I${TVM_ROOT}/3rdparty/dlpack/include
-I${TVM_ROOT}/3rdparty/dlpack/include \
-Icrt_config

PKG_LDFLAGS = -pthread

build_dir := build


demo_dynamic: $(build_dir)/demo_dynamic $(build_dir)/bundle.so $(build_dir)/bundle_c.so $(build_dir)/cat.bin
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
Expand All @@ -47,6 +52,12 @@ demo_static: $(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

$(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

$(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
@mkdir -p $(@D)
g++ $(PKG_CXXFLAGS) -o $@ demo.cc -ldl
Expand All @@ -55,11 +66,14 @@ $(build_dir)/test_dynamic: test.cc ${build_dir}/test_graph.json ${build_dir}/tes
@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)/model.o: $(build_dir)/model.c
gcc $(PKG_CFLAGS) -c -o $@ $^

$(build_dir)/demo_static: demo_static.c ${build_dir}/bundle_static.o ${build_dir}/func_registry.c ${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
@mkdir -p $(@D)
gcc $(PKG_CFLAGS) -o $@ demo_static.c ${build_dir}/bundle_static.o ${build_dir}/model.o -lm
gcc $(PKG_CFLAGS) -o $@ demo_static.c ${build_dir}/bundle_static.o ${build_dir}/func_registry.c ${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)/test_static: test_static.c ${build_dir}/bundle_static.o ${build_dir}/test_func_registry.c ${build_dir}/test_model.o ${build_dir}/crt/graph_runtime/libgraph_runtime.a ${build_dir}/crt/common/libcommon.a
@mkdir -p $(@D)
gcc $(PKG_CFLAGS) -o $@ $^

Expand All @@ -71,27 +85,33 @@ $(build_dir)/graph.json.c: $(build_dir)/graph.json
$(build_dir)/params.bin.c: $(build_dir)/params.bin
xxd -i $^ > $@

$(build_dir)/model.o $(build_dir)/graph.json $(build_dir)/params.bin $(build_dir)/cat.bin: build_model.py
$(build_dir)/func_registry.c $(build_dir)/model.c $(build_dir)/graph.json $(build_dir)/params.bin $(build_dir)/cat.bin: build_model.py
python3 $< -o $(build_dir)

$(build_dir)/test_model.o $(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_func_registry.c $(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
python3 $< -o $(build_dir) --test

$(build_dir)/test_model.o: $(build_dir)/test_model.c
gcc $(PKG_CFLAGS) -c -o $@ $^

$(build_dir)/func_registry.o: $(build_dir)/func_registry.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 runtime.cc $(build_dir)/model.o
$(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
@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)/bundle_c.so: bundle.c runtime.c $(build_dir)/model.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_bundle.so: bundle.cc runtime.cc $(build_dir)/test_model.o $(build_dir)/test_func_registry.c
@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_bundle_c.so: bundle.c runtime.c $(build_dir)/test_model.o $(build_dir)/test_func_registry.c
@mkdir -p $(@D)
gcc -shared $(PKG_CFLAGS) -fvisibility=hidden -o $@ $^ $(PKG_LDFLAGS)

Expand All @@ -100,7 +120,7 @@ $(build_dir)/bundle_static.o: bundle_static.c
gcc -c $(PKG_CFLAGS) -o $@ $^

clean:
rm -rf $(build_dir)/bundle.so $(build_dir)/bundle_c.so $(build_dir)/test_bundle.so $(build_dir)/test_bundle_c.so
rm -rf $(build_dir)/bundle.so $(build_dir)/bundle_c.so $(build_dir)/test_bundle.so $(build_dir)/test_bundle_c.so $(build_dir)/crt

cleanall:
rm -rf $(build_dir)
18 changes: 12 additions & 6 deletions apps/bundle_deploy/build_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from tvm import relay
import tvm
from tvm import te
from tvm.micro import func_registry
import logging
import json

Expand All @@ -33,19 +34,21 @@ 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):
with tvm.transform.PassContext(opt_level=3, config={'tir.disable_vectorize': True}):
graph, lib, params = relay.build(
func, 'llvm --system-lib', params=params)
func, 'c', params=params)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why should we change this default behavior?

Copy link
Contributor Author

@areusch areusch Jul 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i changed this at first because llvm didn't work on my mac. then, I needed to keep it changed to handle --system-lib for now:

--system-lib is being handled using python/tvm/micro/function_registry.py. in a follow-on I should be able to fold that in to C++ (I.e. as something like --system-lib --runtime=crt). is it ok to leave as c for this PR?

Copy link
Member

@liangfu liangfu Jul 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest keeping llvm --system-lib, since we are targeting uTVM, not just mac :-)


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'))
lib.save(os.path.join(build_dir, 'model.c'), 'cc')
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))
func_registry.graph_json_to_c_func_registry(os.path.join(build_dir, 'graph.json'),
os.path.join(build_dir, 'func_registry.c'))

def build_test_module(opts):
import numpy as np
Expand All @@ -57,20 +60,23 @@ 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}
graph, lib, params = relay.build(
tvm.IRModule.from_expr(func), "llvm --system-lib", params=params)
with tvm.transform.PassContext(opt_level=3, config={'tir.disable_vectorize': True}):
graph, lib, params = relay.build(
tvm.IRModule.from_expr(func), "c", 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'))
lib.save(os.path.join(build_dir, 'test_model.c'), 'cc')
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())
func_registry.graph_json_to_c_func_registry(os.path.join(build_dir, 'test_graph.json'),
os.path.join(build_dir, 'test_func_registry.c'))
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())
Expand Down
2 changes: 2 additions & 0 deletions apps/bundle_deploy/bundle.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ TVM_DLL void* tvm_runtime_create(const char* json_data, const char* params_data,
TVMModuleHandle (*TVMGraphRuntimeCreate)(const char*, const TVMModuleHandle, const TVMContext*);
int (*TVMGraphRuntime_LoadParams)(TVMModuleHandle, const char*, const uint32_t);

TVM_CCALL(TVMRuntimeInitialize());

// get pointers
TVM_CCALL(TVMFuncGetGlobal("runtime.SystemLib", (TVMFunctionHandle*)&SystemLibraryCreate));
TVM_CCALL(
Expand Down
63 changes: 37 additions & 26 deletions apps/bundle_deploy/bundle_static.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,21 @@

#include <stdio.h>
#include <stdlib.h>
#include <tvm/runtime/crt/crt.h>
#include <tvm/runtime/crt/graph_runtime.h>
#include <tvm/runtime/crt/packed_func.h>

#include "bundle.h"
#include "runtime.c"

/*! \brief macro to do C API call */
#define TVM_CCALL(func) \
do { \
tvm_crt_error_t ret = (func); \
if (ret != kTvmErrorNoError) { \
fprintf(stderr, "%s: %d: error: %s\n", __FILE__, __LINE__, TVMGetLastError()); \
exit(ret); \
} \
} while (0)

TVM_DLL void* tvm_runtime_create(const char* json_data, const char* params_data,
const uint64_t params_size) {
Expand All @@ -36,44 +48,43 @@ TVM_DLL void* tvm_runtime_create(const char* json_data, const char* params_data,
ctx.device_type = (DLDeviceType)device_type;
ctx.device_id = device_id;

// declare pointers
void* (*SystemLibraryCreate)();
TVMGraphRuntime* (*TVMGraphRuntimeCreate)(const char*, const TVMModuleHandle, const TVMContext*);
int (*TVMGraphRuntime_LoadParams)(TVMModuleHandle, const char*, const uint32_t);

// get pointers
TVMFuncGetGlobal("runtime.SystemLib", (TVMFunctionHandle*)&SystemLibraryCreate);
TVMFuncGetGlobal("tvm.graph_runtime.create", (TVMFunctionHandle*)&TVMGraphRuntimeCreate);
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));

TVMModuleHandle mod_syslib = TVMArgs_AsModuleHandle(&pf.ret_value, 0);

// run modules
TVMModuleHandle mod_syslib = SystemLibraryCreate();
TVMModuleHandle mod = TVMGraphRuntimeCreate(json_data, mod_syslib, &ctx);
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*);
TVMFuncGetGlobal("tvm.graph_runtime.release", (TVMFunctionHandle*)&TVMGraphRuntimeRelease);
TVMGraphRuntimeRelease(&runtime);
TVMGraphRuntime* graph_runtime = (TVMGraphRuntime*)runtime;
TVMGraphRuntime_Release(&graph_runtime);
}

TVM_DLL void tvm_runtime_set_input(void* runtime, const char* name, DLTensor* tensor) {
void (*TVMGraphRuntime_SetInput)(TVMModuleHandle, const char*, DLTensor*);
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);
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*);
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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
* under the License.
*/

/* Explicitly declare posix_memalign function */
#if _POSIX_C_SOURCE < 200112L
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#endif
/*!
* \file apps/bundle_deploy/crt_config.h
* \brief CRT configuration for bundle_deploy app.
*/
#ifndef TVM_RUNTIME_CRT_CONFIG_H_
#define TVM_RUNTIME_CRT_CONFIG_H_

/*! Support low-level debugging in MISRA-C runtime */
#define TVM_CRT_DEBUG 0
Expand Down Expand Up @@ -56,11 +57,12 @@
#define TVM_CRT_LOG_VIRT_MEM_SIZE 24

/*! \brief Page size for virtual memory allocation */
#define TVM_CRT_PAGE_BYTES 4096
#define TVM_CRT_PAGE_BYTES_LOG 12

/*! Maximum number of registered modules. */
#define TVM_CRT_MAX_REGISTERED_MODULES 2

/*! Size of the global function registry, in bytes. */
#define TVM_CRT_GLOBAL_FUNC_REGISTRY_SIZE_BYTES 200

#include "../../src/runtime/crt/crt_backend_api.c"
#include "../../src/runtime/crt/crt_runtime_api.c"
#include "../../src/runtime/crt/graph_runtime.c"
#include "../../src/runtime/crt/load_json.c"
#include "../../src/runtime/crt/memory.c"
#include "../../src/runtime/crt/ndarray.c"
#endif // TVM_RUNTIME_CRT_CONFIG_H_
3 changes: 3 additions & 0 deletions cmake/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,6 @@ set(USE_FALLBACK_STL_MAP OFF)
# Whether to use hexagon device
set(USE_HEXAGON_DEVICE OFF)
set(USE_HEXAGON_SDK /path/to/sdk)

# Whether to compile the standalone C runtime.
set(USE_STANDALONE_CRT ON)
Loading