From e2faf792000de7c56dbe04a3004efdaa5b3ba3e0 Mon Sep 17 00:00:00 2001 From: Thierry Moreau Date: Thu, 24 May 2018 20:13:15 -0700 Subject: [PATCH] [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 --- vta/apps/pynq_rpc/README.md | 30 +++++------ vta/examples/resnet18/pynq/README.md | 52 ++++++++++++++++--- vta/src/pynq/pynq_driver.h | 2 +- .../python/pynq/test_benchmark_conv2d.py | 4 +- vta/tests/python/pynq/test_program_rpc.py | 18 ++----- 5 files changed, 67 insertions(+), 39 deletions(-) diff --git a/vta/apps/pynq_rpc/README.md b/vta/apps/pynq_rpc/README.md index 2025cac23abb..fb9688853690 100644 --- a/vta/apps/pynq_rpc/README.md +++ b/vta/apps/pynq_rpc/README.md @@ -1,21 +1,24 @@ -### 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. ## Pynq Setup 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 -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 +mkdir sshfs xilinx@192.168.2.99:/home/xilinx ``` @@ -31,7 +34,7 @@ From there, clone the VTA repository: 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 ssh xilinx@192.168.2.99 # ssh if you haven't done so cd ~/vta/nnvm/tvm @@ -40,21 +43,18 @@ echo USE_RPC=1 >> config.mk make runtime -j2 ``` -## Pynq RPC server setup - -We're now ready to build the Pynq RPC server on the Pynq board. +We're now ready to build the Pynq RPC server on the Pynq board, which should take less than 30 seconds. ```bash ssh xilinx@192.168.2.99 # ssh if you haven't done so 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 ssh xilinx@192.168.2.99 # ssh if you haven't done so cd ~/vta -su -./apps/pynq_rpc/start_rpc_server.sh +sudo ./apps/pynq_rpc/start_rpc_server.sh # pw is xilinx ``` You should see the following being displayed when starting the RPC server: @@ -65,4 +65,4 @@ INFO:root:RPCServer: bind to 0.0.0.0:9091 Note that it should be listening on port `9091`. -To kill the RPC server, just enter the `Ctrl + c` command. \ No newline at end of file +To kill the RPC server, just enter the `Ctrl + c` command. diff --git a/vta/examples/resnet18/pynq/README.md b/vta/examples/resnet18/pynq/README.md index aa521392a077..1906ca082378 100644 --- a/vta/examples/resnet18/pynq/README.md +++ b/vta/examples/resnet18/pynq/README.md @@ -2,10 +2,14 @@ In order to run this example you'll need to have: * VTA installed +* LLVM 4.0 or newer installed * TVM installed * NNVM installed * MxNet installed * A Pynq-based RPC server running +* Python packages installed + +Required setup time from scratch: ~15 mins. ## VTA installation @@ -19,6 +23,23 @@ Update your `~/.bashrc` file to include the VTA python libraries in your `PYTHON export PYTHONPATH=/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 Clone the TVM repository in the directory of your choosing: @@ -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. As of now, the TVM checkpoint `168f099155106d1188dbc54ac00acc02900a3c6f` is known to work with VTA. ```bash +cd git checkout 168f099155106d1188dbc54ac00acc02900a3c6f ``` @@ -39,13 +61,13 @@ cp make/config.mk . ``` 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 -Launch the compilation, this takes about 5 minutes. +Launch the compilation, this takes about 5-10 minutes on two threads. ```bash cd -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!): @@ -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 ``` -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 cd git checkout qt ``` -Launch the compilation, this takes less a minute. +Launch the compilation, this takes about a minute on two threads. ```bash cd -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!): @@ -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) +## 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 +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: ```bash python imagenet_predict.py @@ -94,10 +130,10 @@ 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`. -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)) Build complete... ('TVM prediction top-1:', 281, 'tabby, tabby cat') t-cost=0.41906 -``` \ No newline at end of file +``` diff --git a/vta/src/pynq/pynq_driver.h b/vta/src/pynq/pynq_driver.h index 74da67d7c035..7aba00441abd 100644 --- a/vta/src/pynq/pynq_driver.h +++ b/vta/src/pynq/pynq_driver.h @@ -28,9 +28,9 @@ extern "C" { void* cma_alloc(size_t size, int cached); void cma_free(void* buf); uint32_t cma_get_phy_addr(void* buf); +#endif void xlnkFlushCache(void* buf, int size); void xlnkInvalidateCache(void* buf, int size); -#endif void *VTAMapRegister(uint32_t addr, size_t length); void VTAUnmapRegister(void *vta, size_t length); diff --git a/vta/tests/python/pynq/test_benchmark_conv2d.py b/vta/tests/python/pynq/test_benchmark_conv2d.py index 7b54e3dc27ce..e02448a8d993 100644 --- a/vta/tests/python/pynq/test_benchmark_conv2d.py +++ b/vta/tests/python/pynq/test_benchmark_conv2d.py @@ -8,8 +8,8 @@ from tvm.contrib import rpc, util import pandas as pd -host = "pynq" -port = 9091 +host = os.environ.get("VTA_PYNQ_RPC_HOST", "pynq") +port = int(os.environ.get("VTA_PYNQ_RPC_PORT", "9091")) target = "llvm -target=armv7-none-linux-gnueabihf -mattr=+neon" Workload = namedtuple("Conv2DWorkload", diff --git a/vta/tests/python/pynq/test_program_rpc.py b/vta/tests/python/pynq/test_program_rpc.py index 22a1e69dec6b..8c998a58a6c8 100644 --- a/vta/tests/python/pynq/test_program_rpc.py +++ b/vta/tests/python/pynq/test_program_rpc.py @@ -3,6 +3,9 @@ from tvm.contrib import rpc 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): """Program the FPGA on the RPC server @@ -11,13 +14,6 @@ def program_rpc_bitstream(path=None): path : path to bitstream (optional) """ 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) program_fpga(remote, path) @@ -25,12 +21,8 @@ def reconfig_rpc_runtime(): """Reconfig the RPC server runtime """ 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) - reconfig_runtime(remote) + remote = rpc.connect(host, port) + reconfig_runtime(remote) program_rpc_bitstream() reconfig_rpc_runtime()