Commit 9e7a6674 by Tianqi Chen Committed by GitHub

[DOCS] How to deploy TVM Modules (#499)

* [DOCS] How to deploy TVM Modules

* More comments
parent 5d9647e2
...@@ -8,5 +8,4 @@ If you are interested in writing optimized kernels with TVM, checkout [TOPI: TVM ...@@ -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. - [graph_executor](graph_executor) Build nnvm graph executor with TVM.
- [ios_rpc](ios_rpc) iOS RPC server. - [ios_rpc](ios_rpc) iOS RPC server.
- [android_rpc](android_rpc) Android 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.
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
```
# Minimum Makefile for the extension package # Makefile Example to deploy TVM modules.
TVM_ROOT=$(shell cd ../..; pwd) TVM_ROOT=$(shell cd ../..; pwd)
NNVM_PATH=nnvm NNVM_PATH=nnvm
DMLC_CORE=${TVM_ROOT}/dmlc-core DMLC_CORE=${TVM_ROOT}/dmlc-core
...@@ -8,12 +8,27 @@ PKG_CFLAGS = -std=c++11 -O2 -fPIC\ ...@@ -8,12 +8,27 @@ PKG_CFLAGS = -std=c++11 -O2 -fPIC\
-I${DMLC_CORE}/include\ -I${DMLC_CORE}/include\
-I${TVM_ROOT}/dlpack/include\ -I${TVM_ROOT}/dlpack/include\
PKG_LDFLAGS = -L${TVM_ROOT}/lib -ltvm_runtime PKG_LDFLAGS = -L${TVM_ROOT}/lib -ldl -lpthread
.PHONY: clean all
lib/cpp_deploy: cpp_deploy.cc lib/test_addone_sys.o 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) @mkdir -p $(@D)
$(CXX) $(PKG_CFLAGS) -o $@ $^ $(PKG_LDFLAGS) $(CXX) -c $(PKG_CFLAGS) -o $@ $^
# The code library built by TVM
lib/test_addone_sys.o: prepare_test_libs.py lib/test_addone_sys.o: prepare_test_libs.py
python 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
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.
...@@ -7,11 +7,14 @@ def prepare_test_libs(base_path): ...@@ -7,11 +7,14 @@ def prepare_test_libs(base_path):
A = tvm.placeholder((n,), name='A') A = tvm.placeholder((n,), name='A')
B = tvm.compute(A.shape, lambda *i: A(*i) + 1.0, name='B') B = tvm.compute(A.shape, lambda *i: A(*i) + 1.0, name='B')
s = tvm.create_schedule(B.op) s = tvm.create_schedule(B.op)
# Compile library as dynamic library
fadd_dylib = tvm.build(s, [A, B], "llvm", name="addone") 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") 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) 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) fadd_syslib.save(syslib_path)
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -3,6 +3,11 @@ echo "Build the libraries.." ...@@ -3,6 +3,11 @@ echo "Build the libraries.."
mkdir -p lib mkdir -p lib
make make
echo "Run the example" echo "Run the example"
export LD_LIBRARY_PATH=../../lib export LD_LIBRARY_PATH=../../lib:${LD_LIBRARY_PATH}
export DYLD_LIBRARY_PATH=../../lib export DYLD_LIBRARY_PATH=../../lib:${DYLD_LIBRARY_PATH}
lib/cpp_deploy
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
/*!
* \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"
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.
...@@ -77,7 +77,7 @@ There are several ways to install the package: ...@@ -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) The changes will be immediately reflected once you pulled the code and rebuild the project (no need to call ```setup``` again)
```bash ```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`: 2. Install tvm python bindings by `setup.py`:
...@@ -87,7 +87,6 @@ There are several ways to install the package: ...@@ -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 # NOTE: if you installed python via homebrew, --user is not needed during installaiton
# it will be automatically installed to your user directory. # it will be automatically installed to your user directory.
# providing --user flag may trigger error during installation in such case. # providing --user flag may trigger error during installation in such case.
cd python; python setup.py install --user cd python; python setup.py install --user; cd ..
# or install tvm package system wide cd topi/python; python setup.py install --user; cd ../..
cd python; sudo python setup.py install
``` ```
...@@ -14,6 +14,7 @@ Contents ...@@ -14,6 +14,7 @@ Contents
how_to/install how_to/install
tutorials/index tutorials/index
faq faq
how_to/deploy
how_to/contribute how_to/contribute
api/python/index api/python/index
dev/index dev/index
......
# 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')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment