Commit e2faf792 by Thierry Moreau Committed by Tianqi Chen

[DOC, EXAMPLE] Updated READMEs, tests, etc. (#41)

* bug fix for new drivers in new PYNQ image v2.1

* updating instructions for resnet inference

* updated the instructions for starting the RPC server

* deriving host/port from env for unit tests
parent e1db3cd6
### PYNQ RPC Server for VTA # PYNQ RPC Server for VTA
This guide describes how to setup a Pynq-based RPC server to accelerate deep learning workloads with VTA. This guide describes how to setup a Pynq-based RPC server to accelerate deep learning workloads with VTA.
## Pynq Setup ## Pynq Setup
Follow the getting started tutorial for the [Pynq board](http://pynq.readthedocs.io/en/latest/getting_started.html). Follow the getting started tutorial for the [Pynq board](http://pynq.readthedocs.io/en/latest/getting_started.html).
* For this RPC setup make sure to go with the *Connect to a Computer* Ethernet setup. * This assumes that you've downloaded the latest Pynq image, PYNQ-Z1 v2.1 (released 21 Feb 2018).
* For this RPC setup, follow the ["Connect to a Computer"](http://pynq.readthedocs.io/en/latest/getting_started.html#connect-to-a-computer) Pynq setup instructions.
* To be able to talk to the board, you'll need to make sure that you've followed the steps to [assign a static IP address](http://pynq.readthedocs.io/en/latest/appendix.html#assign-your-computer-a-static-ip)
Make sure that you can ssh into your Pynq board successfully: Make sure that you can talk to your Pynq board successfully:
```bash ```bash
ssh xilinx@192.168.2.99 ping 192.168.2.99
``` ```
When ssh-ing onto the board, the default password for the `xilinx` account is `xilinx`. When ssh-ing onto the board, the password for the `xilinx` username is `xilinx`.
For convenience let's go ahead and mount the Pynq board's file system to easily access it and maintain it: For convenience let's go ahead and mount the Pynq board's file system to easily access it (this will require sshfs to be installed):
```bash ```bash
mkdir <mountpoint>
sshfs xilinx@192.168.2.99:/home/xilinx <mountpoint> sshfs xilinx@192.168.2.99:/home/xilinx <mountpoint>
``` ```
...@@ -31,7 +34,7 @@ From there, clone the VTA repository: ...@@ -31,7 +34,7 @@ From there, clone the VTA repository:
git clone git@github.com:uwsaml/vta.git --recursive git clone git@github.com:uwsaml/vta.git --recursive
``` ```
Now, ssh into your **Pynq board** to build the TVM runtime with the following commands: Now, ssh into your **Pynq board** to build the TVM runtime with the following commands. This build should take about 5 minutes.
```bash ```bash
ssh xilinx@192.168.2.99 # ssh if you haven't done so ssh xilinx@192.168.2.99 # ssh if you haven't done so
cd ~/vta/nnvm/tvm cd ~/vta/nnvm/tvm
...@@ -40,21 +43,18 @@ echo USE_RPC=1 >> config.mk ...@@ -40,21 +43,18 @@ echo USE_RPC=1 >> config.mk
make runtime -j2 make runtime -j2
``` ```
## Pynq RPC server setup We're now ready to build the Pynq RPC server on the Pynq board, which should take less than 30 seconds.
We're now ready to build the Pynq RPC server on the Pynq board.
```bash ```bash
ssh xilinx@192.168.2.99 # ssh if you haven't done so ssh xilinx@192.168.2.99 # ssh if you haven't done so
cd ~/vta cd ~/vta
make make -j2
``` ```
The last stage will build the `192.168.2.99:home/xilinx/vta/lib/libvta.so` library file. We are now ready to launch the RPC server on the Pynq. In order to enable the FPGA drivers, we need to run the RPC server with administrator privileges (using `su`, account: `xilinx`, pwd: `xilinx`). The last stage will build the `vta/lib/libvta.so` library file. We are now ready to launch the RPC server on the Pynq. In order to enable the FPGA drivers, we need to run the RPC server with `sudo` privileges.
```bash ```bash
ssh xilinx@192.168.2.99 # ssh if you haven't done so ssh xilinx@192.168.2.99 # ssh if you haven't done so
cd ~/vta cd ~/vta
su sudo ./apps/pynq_rpc/start_rpc_server.sh # pw is xilinx
./apps/pynq_rpc/start_rpc_server.sh
``` ```
You should see the following being displayed when starting the RPC server: You should see the following being displayed when starting the RPC server:
......
...@@ -2,10 +2,14 @@ ...@@ -2,10 +2,14 @@
In order to run this example you'll need to have: In order to run this example you'll need to have:
* VTA installed * VTA installed
* LLVM 4.0 or newer installed
* TVM installed * TVM installed
* NNVM installed * NNVM installed
* MxNet installed * MxNet installed
* A Pynq-based RPC server running * A Pynq-based RPC server running
* Python packages installed
Required setup time from scratch: ~15 mins.
## VTA installation ## VTA installation
...@@ -19,6 +23,23 @@ Update your `~/.bashrc` file to include the VTA python libraries in your `PYTHON ...@@ -19,6 +23,23 @@ Update your `~/.bashrc` file to include the VTA python libraries in your `PYTHON
export PYTHONPATH=<vta root>/python:${PYTHONPATH} export PYTHONPATH=<vta root>/python:${PYTHONPATH}
``` ```
## LLVM installation
We provide the set of commands to install LLVM 6.0 (stable branch) on Ubuntu Xenial. Note that the [LLVM installation process](apt.llvm.org) can be adapted to different LLVM branches, and operating systems/distros.
```bash
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
sudo apt-add-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-6.0 main”
sudo apt-get update
apt-get install clang-6.0 lldb-6.0 lld-6.0
```
To ensure that LLVM 6.0 was properly installed, check that the following command gives the path to your `llvm-config` binary.
```bash
which llvm-config-6.0
```
## TVM installation ## TVM installation
Clone the TVM repository in the directory of your choosing: Clone the TVM repository in the directory of your choosing:
...@@ -29,6 +50,7 @@ git clone git@github.com:dmlc/tvm.git --recursive ...@@ -29,6 +50,7 @@ git clone git@github.com:dmlc/tvm.git --recursive
TVM is rapidly changing, and to ensure stability, we keep track of working TVM checkpoints. TVM is rapidly changing, and to ensure stability, we keep track of working TVM checkpoints.
As of now, the TVM checkpoint `168f099155106d1188dbc54ac00acc02900a3c6f` is known to work with VTA. As of now, the TVM checkpoint `168f099155106d1188dbc54ac00acc02900a3c6f` is known to work with VTA.
```bash ```bash
cd <tvm root>
git checkout 168f099155106d1188dbc54ac00acc02900a3c6f git checkout 168f099155106d1188dbc54ac00acc02900a3c6f
``` ```
...@@ -39,13 +61,13 @@ cp make/config.mk . ...@@ -39,13 +61,13 @@ cp make/config.mk .
``` ```
In the 'config.mk' file sure that: In the 'config.mk' file sure that:
* `LLVM_CONFIG` points to the llvm-config executable (e.g. `LLVM_CONFIG = /usr/bin/llvm-config-4.0`). You'll need to have llvm4.0 installed or later. * `LLVM_CONFIG` points to the `llvm-config` executable which path was derived in the TVM installation instructions above (e.g. `LLVM_CONFIG = /usr/bin/llvm-config-6.0`)
* `USE_RPC` should be set to 1 * `USE_RPC` should be set to 1
Launch the compilation, this takes about 5 minutes. Launch the compilation, this takes about 5-10 minutes on two threads.
```bash ```bash
cd <tvm root> cd <tvm root>
make -j4 make -j2
``` ```
Finally update your `~/.bashrc` file to include the TVM python libraries in your `PYTHONPATH` (don't forget to source the newly modified `.bashrc` file!): Finally update your `~/.bashrc` file to include the TVM python libraries in your `PYTHONPATH` (don't forget to source the newly modified `.bashrc` file!):
...@@ -60,16 +82,16 @@ Clone the NNVM repository from `tqchen` in the directory of your choosing: ...@@ -60,16 +82,16 @@ Clone the NNVM repository from `tqchen` in the directory of your choosing:
git clone git@github.com:tqchen/nnvm.git --recursive git clone git@github.com:tqchen/nnvm.git --recursive
``` ```
To run this example, we rely on a special branch of NNVM until these changes get merged back into the main repo: `qt`: To run this example, we rely on a special branch of NNVM `qt`:
```bash ```bash
cd <nnvm root> cd <nnvm root>
git checkout qt git checkout qt
``` ```
Launch the compilation, this takes less a minute. Launch the compilation, this takes about a minute on two threads.
```bash ```bash
cd <nnvm root> cd <nnvm root>
make -j4 make -j2
``` ```
Finally update your `~/.bashrc` file to include the NNVM python libraries in your `PYTHONPATH` (don't forget to source the newly modified `.bashrc` file!): Finally update your `~/.bashrc` file to include the NNVM python libraries in your `PYTHONPATH` (don't forget to source the newly modified `.bashrc` file!):
...@@ -85,8 +107,22 @@ Follow the [MxNet Installation Instructions](https://mxnet.incubator.apache.org) ...@@ -85,8 +107,22 @@ Follow the [MxNet Installation Instructions](https://mxnet.incubator.apache.org)
Follow the [Pynq RPC Server Guide](https://github.com/uwsaml/vta/tree/master/apps/pynq_rpc/README.md) Follow the [Pynq RPC Server Guide](https://github.com/uwsaml/vta/tree/master/apps/pynq_rpc/README.md)
## Python packages
You'll need the following packages to be installed for the example to run properly. You can use `pip` to install those packages:
* `decorator` (for TVM)
* `enum34` (for NNVM)
* `Pillow`
* `wget`
## Running the example ## Running the example
Configure your environment with the following:
```bash
export VTA_PYNQ_RPC_HOST=192.168.2.99
export VTA_PYNQ_RPC_PORT=9091
```
Simply run the following python script: Simply run the following python script:
```bash ```bash
python imagenet_predict.py python imagenet_predict.py
...@@ -94,7 +130,7 @@ python imagenet_predict.py ...@@ -94,7 +130,7 @@ python imagenet_predict.py
This will run imagenet classification using the ResNet18 architecture on a VTA design that performs 8-bit integer inference, to perform classification on a cat image `cat.jpg`. This will run imagenet classification using the ResNet18 architecture on a VTA design that performs 8-bit integer inference, to perform classification on a cat image `cat.jpg`.
The script reports runtime measured on the Pynq board, and the top-1 result category: The script reports runtime measured on the Pynq board (in seconds), and the top-1 result category:
``` ```
('x', (1, 3, 224, 224)) ('x', (1, 3, 224, 224))
Build complete... Build complete...
......
...@@ -28,9 +28,9 @@ extern "C" { ...@@ -28,9 +28,9 @@ extern "C" {
void* cma_alloc(size_t size, int cached); void* cma_alloc(size_t size, int cached);
void cma_free(void* buf); void cma_free(void* buf);
uint32_t cma_get_phy_addr(void* buf); uint32_t cma_get_phy_addr(void* buf);
#endif
void xlnkFlushCache(void* buf, int size); void xlnkFlushCache(void* buf, int size);
void xlnkInvalidateCache(void* buf, int size); void xlnkInvalidateCache(void* buf, int size);
#endif
void *VTAMapRegister(uint32_t addr, size_t length); void *VTAMapRegister(uint32_t addr, size_t length);
void VTAUnmapRegister(void *vta, size_t length); void VTAUnmapRegister(void *vta, size_t length);
......
...@@ -8,8 +8,8 @@ from collections import namedtuple ...@@ -8,8 +8,8 @@ from collections import namedtuple
from tvm.contrib import rpc, util from tvm.contrib import rpc, util
import pandas as pd import pandas as pd
host = "pynq" host = os.environ.get("VTA_PYNQ_RPC_HOST", "pynq")
port = 9091 port = int(os.environ.get("VTA_PYNQ_RPC_PORT", "9091"))
target = "llvm -target=armv7-none-linux-gnueabihf -mattr=+neon" target = "llvm -target=armv7-none-linux-gnueabihf -mattr=+neon"
Workload = namedtuple("Conv2DWorkload", Workload = namedtuple("Conv2DWorkload",
......
...@@ -3,6 +3,9 @@ import tvm ...@@ -3,6 +3,9 @@ import tvm
from tvm.contrib import rpc from tvm.contrib import rpc
from vta import get_bitstream_path, download_bitstream, program_fpga, reconfig_runtime from vta import get_bitstream_path, download_bitstream, program_fpga, reconfig_runtime
host = os.environ.get("VTA_PYNQ_RPC_HOST", "pynq")
port = int(os.environ.get("VTA_PYNQ_RPC_PORT", "9091"))
def program_rpc_bitstream(path=None): def program_rpc_bitstream(path=None):
"""Program the FPGA on the RPC server """Program the FPGA on the RPC server
...@@ -11,13 +14,6 @@ def program_rpc_bitstream(path=None): ...@@ -11,13 +14,6 @@ def program_rpc_bitstream(path=None):
path : path to bitstream (optional) path : path to bitstream (optional)
""" """
assert tvm.module.enabled("rpc") assert tvm.module.enabled("rpc")
host = os.environ.get("VTA_PYNQ_RPC_HOST", None)
if not host:
raise RuntimeError(
"Error: VTA_PYNQ_RPC_HOST environment variable not set.")
# If a path to a bitstream is passed, make sure that it point to a valid bitstream
port = os.environ.get("VTA_PYNQ_RPC_PORT", "9091")
port = int(port)
remote = rpc.connect(host, port) remote = rpc.connect(host, port)
program_fpga(remote, path) program_fpga(remote, path)
...@@ -25,10 +21,6 @@ def reconfig_rpc_runtime(): ...@@ -25,10 +21,6 @@ def reconfig_rpc_runtime():
"""Reconfig the RPC server runtime """Reconfig the RPC server runtime
""" """
assert tvm.module.enabled("rpc") assert tvm.module.enabled("rpc")
host = os.environ.get("VTA_PYNQ_RPC_HOST", None)
if host:
port = os.environ.get("VTA_PYNQ_RPC_PORT", "9091")
port = int(port)
remote = rpc.connect(host, port) remote = rpc.connect(host, port)
reconfig_runtime(remote) reconfig_runtime(remote)
......
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