From 9e7a6674170f23d41afd59ce89967558ad76db5c Mon Sep 17 00:00:00 2001 From: Tianqi Chen Date: Fri, 29 Sep 2017 13:54:10 -0700 Subject: [PATCH] [DOCS] How to deploy TVM Modules (#499) * [DOCS] How to deploy TVM Modules * More comments --- apps/README.md | 3 +- apps/cpp_deploy/Makefile | 19 ------- apps/cpp_deploy/README.md | 10 ---- apps/cpp_deploy/run_example.sh | 8 --- apps/howto_deploy/Makefile | 34 ++++++++++++ apps/howto_deploy/README.md | 11 ++++ .../cpp_deploy.cc | 0 .../prepare_test_libs.py | 7 ++- apps/howto_deploy/run_example.sh | 13 +++++ apps/howto_deploy/tvm_runtime_pack.cc | 53 +++++++++++++++++++ docs/how_to/deploy.md | 36 +++++++++++++ docs/how_to/install.md | 7 ++- docs/index.rst | 1 + topi/python/setup.py | 26 +++++++++ 14 files changed, 183 insertions(+), 45 deletions(-) delete mode 100644 apps/cpp_deploy/Makefile delete mode 100644 apps/cpp_deploy/README.md delete mode 100755 apps/cpp_deploy/run_example.sh create mode 100644 apps/howto_deploy/Makefile create mode 100644 apps/howto_deploy/README.md rename apps/{cpp_deploy => howto_deploy}/cpp_deploy.cc (100%) rename apps/{cpp_deploy => howto_deploy}/prepare_test_libs.py (89%) create mode 100755 apps/howto_deploy/run_example.sh create mode 100644 apps/howto_deploy/tvm_runtime_pack.cc create mode 100644 docs/how_to/deploy.md create mode 100644 topi/python/setup.py diff --git a/apps/README.md b/apps/README.md index e468dd5e3886..f513b68d1892 100644 --- a/apps/README.md +++ b/apps/README.md @@ -8,5 +8,4 @@ If you are interested in writing optimized kernels with TVM, checkout [TOPI: TVM - [graph_executor](graph_executor) Build nnvm graph executor with TVM. - [ios_rpc](ios_rpc) iOS RPC server. - [android_rpc](android_rpc) Android RPC server. -- [cpp_deploy](cpp_deploy) Example to deploy with C++ runtime. - +- [howto_deploy](howto_depploy) Tutorial on how to deploy TVM with minimum code dependency. diff --git a/apps/cpp_deploy/Makefile b/apps/cpp_deploy/Makefile deleted file mode 100644 index 629c2e98fe22..000000000000 --- a/apps/cpp_deploy/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# Minimum Makefile for the extension package -TVM_ROOT=$(shell cd ../..; pwd) -NNVM_PATH=nnvm -DMLC_CORE=${TVM_ROOT}/dmlc-core - -PKG_CFLAGS = -std=c++11 -O2 -fPIC\ - -I${TVM_ROOT}/include\ - -I${DMLC_CORE}/include\ - -I${TVM_ROOT}/dlpack/include\ - -PKG_LDFLAGS = -L${TVM_ROOT}/lib -ltvm_runtime - - -lib/cpp_deploy: cpp_deploy.cc lib/test_addone_sys.o - @mkdir -p $(@D) - $(CXX) $(PKG_CFLAGS) -o $@ $^ $(PKG_LDFLAGS) - -lib/test_addone_sys.o: prepare_test_libs.py - python prepare_test_libs.py diff --git a/apps/cpp_deploy/README.md b/apps/cpp_deploy/README.md deleted file mode 100644 index 8da204a15446..000000000000 --- a/apps/cpp_deploy/README.md +++ /dev/null @@ -1,10 +0,0 @@ -C++ Deployment API Example -========================== -This folder contains an example to demonstrate how to use TVM C++ Runtime -API to load and run modules built by TVM. - -Type the following command to run the example under current folder(need to build TVM first). -```bash -./run_example.sh -``` - diff --git a/apps/cpp_deploy/run_example.sh b/apps/cpp_deploy/run_example.sh deleted file mode 100755 index ddc137db9238..000000000000 --- a/apps/cpp_deploy/run_example.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -echo "Build the libraries.." -mkdir -p lib -make -echo "Run the example" -export LD_LIBRARY_PATH=../../lib -export DYLD_LIBRARY_PATH=../../lib -lib/cpp_deploy diff --git a/apps/howto_deploy/Makefile b/apps/howto_deploy/Makefile new file mode 100644 index 000000000000..8e59084c60ae --- /dev/null +++ b/apps/howto_deploy/Makefile @@ -0,0 +1,34 @@ +# Makefile Example to deploy TVM modules. +TVM_ROOT=$(shell cd ../..; pwd) +NNVM_PATH=nnvm +DMLC_CORE=${TVM_ROOT}/dmlc-core + +PKG_CFLAGS = -std=c++11 -O2 -fPIC\ + -I${TVM_ROOT}/include\ + -I${DMLC_CORE}/include\ + -I${TVM_ROOT}/dlpack/include\ + +PKG_LDFLAGS = -L${TVM_ROOT}/lib -ldl -lpthread + +.PHONY: clean all + +all: lib/cpp_deploy_pack lib/cpp_deploy_normal + +# Build rule for all in one TVM package library +lib/libtvm_runtime_pack.o: tvm_runtime_pack.cc + @mkdir -p $(@D) + $(CXX) -c $(PKG_CFLAGS) -o $@ $^ + +# The code library built by TVM +lib/test_addone_sys.o: prepare_test_libs.py + python prepare_test_libs.py + +# Deploy using the all in one TVM package library +lib/cpp_deploy_pack: cpp_deploy.cc lib/test_addone_sys.o lib/libtvm_runtime_pack.o + @mkdir -p $(@D) + $(CXX) $(PKG_CFLAGS) -o $@ $^ $(PKG_LDFLAGS) + +# Deploy using pre-built libtvm_runtime.so +lib/cpp_deploy_normal: cpp_deploy.cc lib/test_addone_sys.o + @mkdir -p $(@D) + $(CXX) $(PKG_CFLAGS) -o $@ $^ $(PKG_LDFLAGS) -ltvm_runtime diff --git a/apps/howto_deploy/README.md b/apps/howto_deploy/README.md new file mode 100644 index 000000000000..6c732879a6a5 --- /dev/null +++ b/apps/howto_deploy/README.md @@ -0,0 +1,11 @@ +How to Deploy TVM Modules +========================= +This folder contains an example on how to deploy TVM modules. +It also contains an example code to deploy with C++. + +Type the following command to run the sample code under the current folder(need to build TVM first). +```bash +./run_example.sh +``` + +Checkout [How to Deploy TVM Modules](http://docs.tvmlang.org/how_to/deploy.html) for more information. diff --git a/apps/cpp_deploy/cpp_deploy.cc b/apps/howto_deploy/cpp_deploy.cc similarity index 100% rename from apps/cpp_deploy/cpp_deploy.cc rename to apps/howto_deploy/cpp_deploy.cc diff --git a/apps/cpp_deploy/prepare_test_libs.py b/apps/howto_deploy/prepare_test_libs.py similarity index 89% rename from apps/cpp_deploy/prepare_test_libs.py rename to apps/howto_deploy/prepare_test_libs.py index 106f3c8ec049..f8dd1684dd62 100644 --- a/apps/cpp_deploy/prepare_test_libs.py +++ b/apps/howto_deploy/prepare_test_libs.py @@ -7,11 +7,14 @@ def prepare_test_libs(base_path): A = tvm.placeholder((n,), name='A') B = tvm.compute(A.shape, lambda *i: A(*i) + 1.0, name='B') s = tvm.create_schedule(B.op) + # Compile library as dynamic library fadd_dylib = tvm.build(s, [A, B], "llvm", name="addone") - fadd_syslib = tvm.build(s, [A, B], "llvm --system-lib", name="addonesys") dylib_path = os.path.join(base_path, "test_addone_dll.so") - syslib_path = os.path.join(base_path, "test_addone_sys.o") fadd_dylib.export_library(dylib_path) + + # Compile library in system library mode + fadd_syslib = tvm.build(s, [A, B], "llvm --system-lib", name="addonesys") + syslib_path = os.path.join(base_path, "test_addone_sys.o") fadd_syslib.save(syslib_path) if __name__ == "__main__": diff --git a/apps/howto_deploy/run_example.sh b/apps/howto_deploy/run_example.sh new file mode 100755 index 000000000000..8c49e860c538 --- /dev/null +++ b/apps/howto_deploy/run_example.sh @@ -0,0 +1,13 @@ +#!/bin/bash +echo "Build the libraries.." +mkdir -p lib +make +echo "Run the example" +export LD_LIBRARY_PATH=../../lib:${LD_LIBRARY_PATH} +export DYLD_LIBRARY_PATH=../../lib:${DYLD_LIBRARY_PATH} + +echo "Run the deployment with all in one packed library..." +lib/cpp_deploy_pack + +echo "Run the deployment with all in normal library..." +lib/cpp_deploy_normal diff --git a/apps/howto_deploy/tvm_runtime_pack.cc b/apps/howto_deploy/tvm_runtime_pack.cc new file mode 100644 index 000000000000..e5c65b66b71a --- /dev/null +++ b/apps/howto_deploy/tvm_runtime_pack.cc @@ -0,0 +1,53 @@ +/*! + * \brief This is an all in one TVM runtime file. + * + * You only have to use this file to compile libtvm_runtime to + * include in your project. + * + * - Copy this file into your project which depends on tvm runtime. + * - Compile with -std=c++11 + * - Add the following include path + * - /path/to/tvm/include/ + * - /path/to/tvm/dmlc-core/include/ + * - /path/to/tvm/dlpack/include/ + * - Add -lpthread -ldl to the linked library. + * - You are good to go. + * - See the Makefile in the same folder for example. + * + * The include files here are presented with relative path + * You need to remember to change it to point to the right file. + * + */ +#include "../../src/runtime/c_runtime_api.cc" +#include "../../src/runtime/cpu_device_api.cc" +#include "../../src/runtime/workspace_pool.cc" +#include "../../src/runtime/module_util.cc" +#include "../../src/runtime/module.cc" +#include "../../src/runtime/registry.cc" +#include "../../src/runtime/file_util.cc" +#include "../../src/runtime/thread_pool.cc" + +// NOTE: all the files after this are optional modules +// that you can include remove, depending on how much feature you use. + +// Likely we only need to enable one of the following +// If you use Module::Load, use dso_module +// For system packed library, use system_lib_module +#include "../../src/runtime/dso_module.cc" +#include "../../src/runtime/system_lib_module.cc" + +// Graph runtime +#include "../../src/runtime/graph/graph_runtime.cc" + +// Uncomment the following lines to enable RPC +// #include "../../src/runtime/rpc/rpc_session.cc" +// #include "../../src/runtime/rpc/rpc_event_impl.cc" +// #include "../../src/runtime/rpc/rpc_server_env.cc" + +// Uncomment the following lines to enable Metal +// #include "../../src/runtime/metal/metal_device_api.mm" +// #include "../../src/runtime/metal/metal_module.mm" + +// Uncomment the following lines to enable OpenCL +// #include "../../src/runtime/opencl/opencl_device_api.cc" +// #include "../../src/runtime/opencl/opencl_module.cc" diff --git a/docs/how_to/deploy.md b/docs/how_to/deploy.md new file mode 100644 index 000000000000..b9f219acc335 --- /dev/null +++ b/docs/how_to/deploy.md @@ -0,0 +1,36 @@ +How to Deploy TVM Modules +========================= +We provide an example on how to deploy TVM modules in [apps/howto_deploy](https://github.com/dmlc/tvm/tree/master/apps/howto_deploy) + +To run the example, you can use the following command + +```bash +cd apps/howto_deploy +./run_example.sh +``` + +Get TVM Runtime Library +----------------------- + +![](http://www.tvmlang.org/images/release/tvm_flexible.png) + +The only thing we need is to link to a TVM runtime in your target platform. +TVM provides a minimum runtime, which costs around 300K to 600K depending on how much modules we use. +In most cases, we can use ```libtvm_runtime.so``` that comes with the build. + +If somehow you find it is hard to build ```libtvm_runtime```, checkout [tvm_runtime_pack.cc](https://github.com/dmlc/tvm/tree/master/apps/howto_deploy/tvm_runtime_pack.cc). +It is an example all in one file that gives you TVM runtime. +You can compile this file using your build system and include this into your project. + +You can also checkout [apps](https://github.com/dmlc/tvm/tree/master/apps/) for example applications build with TVM on iOS, Android and others. + +Dynamic Library vs. System Module +--------------------------------- +TVM provides two ways to use the compiled library. +You can checkout [prepare_test_libs.py](https://github.com/dmlc/tvm/tree/master/apps/howto_deploy/prepare_test_libs.py) +on how to generate the library and [cpp_deploy.cc](https://github.com/dmlc/tvm/tree/master/apps/howto_deploy/cpp_deploy.cc) on how to use them. + +- Store library as a shared library and dynamically load the library into your project. +- Bundle the compiled library into your project in system module mode. + +Dynamic loading is more flexible and can load new modules on the fly. System module is a more ```static``` approach. We can use system module in places where dynamic library loading is banned. diff --git a/docs/how_to/install.md b/docs/how_to/install.md index 791cd09cd083..54db42281623 100644 --- a/docs/how_to/install.md +++ b/docs/how_to/install.md @@ -77,7 +77,7 @@ There are several ways to install the package: The changes will be immediately reflected once you pulled the code and rebuild the project (no need to call ```setup``` again) ```bash - export PYTHONPATH=/path/to/tvm/python:${PYTHONPATH} + export PYTHONPATH=/path/to/tvm/python:/path/to/tvm/topi/python:${PYTHONPATH} ``` 2. Install tvm python bindings by `setup.py`: @@ -87,7 +87,6 @@ There are several ways to install the package: # NOTE: if you installed python via homebrew, --user is not needed during installaiton # it will be automatically installed to your user directory. # providing --user flag may trigger error during installation in such case. - cd python; python setup.py install --user - # or install tvm package system wide - cd python; sudo python setup.py install + cd python; python setup.py install --user; cd .. + cd topi/python; python setup.py install --user; cd ../.. ``` diff --git a/docs/index.rst b/docs/index.rst index 9a4cfff3b477..9fa690e00fd9 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -14,6 +14,7 @@ Contents how_to/install tutorials/index faq + how_to/deploy how_to/contribute api/python/index dev/index diff --git a/topi/python/setup.py b/topi/python/setup.py new file mode 100644 index 000000000000..e2a8a5d77a4f --- /dev/null +++ b/topi/python/setup.py @@ -0,0 +1,26 @@ +# pylint: disable=invalid-name, exec-used +"""Setup TOPI package.""" +from __future__ import absolute_import +import sys + +from setuptools import find_packages +from setuptools.dist import Distribution + +if "--inplace" in sys.argv: + from distutils.core import setup + from distutils.extension import Extension +else: + from setuptools import setup + from setuptools.extension import Extension + +__version__ = "0.1.0" + +setup(name='topi', + version=__version__, + description="TOPI: TVM operator index", + install_requires=[ + "numpy", + "decorator", + ], + packages=find_packages(), + url='https://github.com/dmlc/tvm')