Skip to content

Commit

Permalink
Merge pull request #11 from Xilinx/dev
Browse files Browse the repository at this point in the history
finn-examples v0.0.2b
  • Loading branch information
maltanar authored Jun 6, 2021
2 parents 68dd349 + 02844af commit eaebe90
Show file tree
Hide file tree
Showing 18 changed files with 4,120 additions and 232 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

name: Upload Python Package

on:
release:
types: [created]

jobs:
deploy:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
python setup.py sdist
twine upload dist/*
10 changes: 10 additions & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
============
Contributors
============

* Yaman Umuroglu (@maltanar) (maintainer)
* Jakoba Petri-Koenig (@auphelia)
* Lucian Petrica (@quetric)
* Tobias Alonso (@Tobi-Alonso)
* Hendrik Borras (@HenniOVP)
* Felix Paul Jentzsch (@felixpj)
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ pre-built bitfiles, PYNQ Python drivers and Jupyter notebooks to get started,
and you can rebuild them from source.
Both PYNQ on Zynq and Alveo are supported.

Need help with a problem in this repo, or got a question? Feel free to ask for help in the [FINN Gitter channel](https://gitter.im/xilinx-finn/community).

## Quickstart


*For Alveo we recommend setting up everything inside a virtualenv as described [here](https://pynq.readthedocs.io/en/v2.6.1/getting_started/alveo_getting_started.html?highlight=alveo#install-conda).*
*For PYNQ boards, all commands below must be prefixed with `sudo` or by first going into `sudo su`.*

First, ensure that your `pip` and `setuptools` installations are up-to-date
on your PYNQ board or Alveo server:
Expand Down Expand Up @@ -62,11 +65,11 @@ dummy_out = accel.execute(dummy_in)
|----------------------------------------------------------------|-------------------------|------------------------------------------------------------|------------------|
| <img src="docs/img/cifar-10.png" width="150"/><br/>CIFAR-10 | CNV (VGG-11-like) | several variants:<br>1/2-bit weights/activations | all |
| <img src="docs/img/mnist.jpg" width="150"/><br/><br>MNIST | 3-layer fully-connected | several variants:<br>1/2-bit weights/activations | all |
| <img src="docs/img/imagenet.jpg" width="150"/><br/><br>ImageNet | MobileNet-v1 | 4-bit weights and activations<br>8-bit first layer weights | Alveo U250 |
| <img src="docs/img/imagenet.jpg" width="150"/><br/><br>ImageNet | MobileNet-v1 | 4-bit weights and activations<br>8-bit first layer weights | Alveo U250<br>ZCU104 |

## Supported Boards

*Note that the larger NNs are only available on Alveo boards.*
*Note that the larger NNs are only available on Alveo or selected Zynq boards.*

`finn-examples` provides pre-built FPGA bitfiles for the following boards:

Expand Down
3 changes: 1 addition & 2 deletions build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ Please see the READMEs under the respective subfolders here for instructions on

All examples in this repo use the same Python PYNQ driver, located under
`finn_examples/driver.py` in the repo. This driver can support any FINN-generated
accelerator that doesn't use external weights, the only thing that needs to be
specified is the configuration for the input and output tensors in the `io_shape_dict`. Have a look at `finn_examples/models.py` to see how this is done for the example models in this repo:
accelerator, the only thing that needs to be specified is the configuration for the input and output tensors in the `io_shape_dict`. Have a look at `finn_examples/models.py` to see how this is done for the example models in this repo:

```python
_cifar10_cnv_io_shape_dict = {
Expand Down
2 changes: 1 addition & 1 deletion build/get-finn.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
# URL for git repo to be cloned
REPO_URL=https://github.com/Xilinx/finn
# commit hash for repo
REPO_COMMIT=4fee6ffd8e13f91314ec9086e9ce9b2ea9de15c7
REPO_COMMIT=e5da788bdc74fc9c234bb0176521ad51e830c22e
# directory (under the same folder as this script) to clone to
REPO_DIR=finn

Expand Down
3 changes: 2 additions & 1 deletion build/mobilenet-v1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ It requires about 2 MB of weight storage and 1.1 GMACs per inference, yielding
Due to the depthwise separable convolutions in MobileNet-v1,
we use a specialized build script that replaces a few of the standard steps
in FINN with custom ones.
**MobileNet-v1 is currently only supported on Alveo U250.**
**MobileNet-v1 is currently only supported on Alveo U250 and ZCU104.**
We also provide a folding configuration for the **ZCU102**, but there is no pre-built Pynq image available for this board.

0. Ensure you have performed the *Setup* steps in the top-level README for setting up the FINN requirements and environment variables.

Expand Down
174 changes: 134 additions & 40 deletions build/mobilenet-v1/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,53 +28,147 @@

import finn.builder.build_dataflow as build
import finn.builder.build_dataflow_config as build_cfg
from finn.util.basic import alveo_default_platform
import os
import shutil

# custom steps for mobilenetv1
from custom_steps import (
step_mobilenet_streamline,
step_mobilenet_convert_to_hls_layers,
step_mobilenet_convert_to_hls_layers_separate_th,
step_mobilenet_lower_convs,
step_mobilenet_slr_floorplan,
)

model_name = "mobilenetv1-w4a4"
board = "U250"
vitis_platform = "xilinx_u250_xdma_201830_2"
synth_clk_period_ns = 3.0

mobilenet_build_steps = [
step_mobilenet_streamline,
step_mobilenet_lower_convs,
step_mobilenet_convert_to_hls_layers,
"step_create_dataflow_partition",
"step_apply_folding_config",
"step_generate_estimate_reports",
"step_hls_ipgen",
"step_set_fifo_depths",
"step_create_stitched_ip",
"step_make_pynq_driver",
"step_synthesize_bitfile",
"step_deployment_package",
]


cfg = build_cfg.DataflowBuildConfig(
steps=mobilenet_build_steps,
output_dir="output_%s_%s" % (model_name, board),
folding_config_file="folding_config/%s_folding_config.json" % board,
synth_clk_period_ns=synth_clk_period_ns,
board=board,
shell_flow_type=build_cfg.ShellFlowType.VITIS_ALVEO,
# folding config comes with FIFO depths already
auto_fifo_depths=False,
vitis_platform=vitis_platform,
# enable extra performance optimizations (physopt)
vitis_opt_strategy=build_cfg.VitisOptStrategyCfg.PERFORMANCE_BEST,
generate_outputs=[
build_cfg.DataflowOutputType.PYNQ_DRIVER,
build_cfg.DataflowOutputType.ESTIMATE_REPORTS,
build_cfg.DataflowOutputType.BITFILE,
build_cfg.DataflowOutputType.DEPLOYMENT_PACKAGE,
],
)
model_file = "models/%s_pre_post_tidy.onnx" % model_name
build.build_dataflow_cfg(model_file, cfg)
# which platforms to build the networks for
zynq_platforms = ["ZCU102", "ZCU104"]
#alveo_platforms = ["U50", "U200", "U250", "U280"]
alveo_platforms = ["U250"]
platforms_to_build = zynq_platforms + alveo_platforms


# determine which shell flow to use for a given platform
def platform_to_shell(platform):
if platform in zynq_platforms:
return build_cfg.ShellFlowType.VIVADO_ZYNQ
elif platform in alveo_platforms:
return build_cfg.ShellFlowType.VITIS_ALVEO
else:
raise Exception("Unknown platform, can't determine ShellFlowType")


# select target clock frequency
def select_clk_period(platform):
if platform in zynq_platforms:
return 5.4
elif platform in alveo_platforms:
return 3.0


# select build steps (ZCU104/102 folding config is based on separate thresholding nodes)
def select_build_steps(platform):
if platform in zynq_platforms:
return [
step_mobilenet_streamline,
step_mobilenet_lower_convs,
step_mobilenet_convert_to_hls_layers_separate_th,
"step_create_dataflow_partition",
"step_apply_folding_config",
"step_generate_estimate_reports",
"step_hls_codegen",
"step_hls_ipgen",
"step_set_fifo_depths",
"step_create_stitched_ip",
"step_synthesize_bitfile",
"step_make_pynq_driver",
"step_deployment_package",
]
elif platform in alveo_platforms:
return [
step_mobilenet_streamline,
step_mobilenet_lower_convs,
step_mobilenet_convert_to_hls_layers,
"step_create_dataflow_partition",
"step_apply_folding_config",
"step_generate_estimate_reports",
"step_hls_codegen",
"step_hls_ipgen",
"step_set_fifo_depths",
step_mobilenet_slr_floorplan,
"step_synthesize_bitfile",
"step_make_pynq_driver",
"step_deployment_package",
]


# create a release dir, used for finn-examples release packaging
os.makedirs("release", exist_ok=True)


for platform_name in platforms_to_build:
shell_flow_type = platform_to_shell(platform_name)
if shell_flow_type == build_cfg.ShellFlowType.VITIS_ALVEO:
vitis_platform = alveo_default_platform[platform_name]
# for Alveo, use the Vitis platform name as the release name
# e.g. xilinx_u250_xdma_201830_2
release_platform_name = vitis_platform
else:
vitis_platform = None
# for Zynq, use the board name as the release name
# e.g. ZCU104
release_platform_name = platform_name
platform_dir = "release/%s" % release_platform_name
os.makedirs(platform_dir, exist_ok=True)

cfg = build_cfg.DataflowBuildConfig(
steps=select_build_steps(platform_name),
output_dir="output_%s_%s" % (model_name, release_platform_name),
folding_config_file="folding_config/%s_folding_config.json" % platform_name,
synth_clk_period_ns=select_clk_period(platform_name),
board=platform_name,
shell_flow_type=shell_flow_type,
vitis_platform=vitis_platform,
# folding config comes with FIFO depths already
auto_fifo_depths=False,
# enable extra performance optimizations (physopt)
vitis_opt_strategy=build_cfg.VitisOptStrategyCfg.PERFORMANCE_BEST,
generate_outputs=[
build_cfg.DataflowOutputType.PYNQ_DRIVER,
build_cfg.DataflowOutputType.ESTIMATE_REPORTS,
build_cfg.DataflowOutputType.BITFILE,
build_cfg.DataflowOutputType.DEPLOYMENT_PACKAGE,
],
)
model_file = "models/%s_pre_post_tidy.onnx" % model_name
build.build_dataflow_cfg(model_file, cfg)

# copy bitfiles and runtime weights into release dir if found
bitfile_gen_dir = cfg.output_dir + "/bitfile"
files_to_check_and_copy = [
"finn-accel.bit",
"finn-accel.hwh",
"finn-accel.xclbin",
]
for f in files_to_check_and_copy:
src_file = bitfile_gen_dir + "/" + f
dst_file = platform_dir + "/" + f.replace("finn-accel", model_name)
if os.path.isfile(src_file):
shutil.copy(src_file, dst_file)

weight_gen_dir = cfg.output_dir + "/driver/runtime_weights"
weight_dst_dir = platform_dir + "/%s_runtime_weights" % model_name
if os.path.isdir(weight_gen_dir):
weight_files = os.listdir(weight_gen_dir)
if weight_files:
shutil.copytree(weight_gen_dir, weight_dst_dir)

# create zipfile for all examples for this platform
shutil.make_archive(
"release/" + release_platform_name,
"zip",
root_dir="release",
base_dir=release_platform_name,
)
39 changes: 38 additions & 1 deletion build/mobilenet-v1/custom_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from finn.core.modelwrapper import ModelWrapper
from finn.builder.build_dataflow_config import DataflowBuildConfig
from finn.builder.build_dataflow_config import (
DataflowBuildConfig,
ShellFlowType,
)
from finn.transformation.streamline import Streamline
from finn.transformation.double_to_single_float import DoubleToSingleFloat
import finn.transformation.streamline.absorb as absorb
Expand All @@ -39,6 +42,7 @@
from finn.transformation.general import (
GiveReadableTensorNames,
GiveUniqueNodeNames,
ApplyConfig,
)
import finn.transformation.fpgadataflow.convert_to_hls_layers as to_hls
from finn.transformation.infer_shapes import InferShapes
Expand Down Expand Up @@ -94,3 +98,36 @@ def step_mobilenet_convert_to_hls_layers(model: ModelWrapper, cfg: DataflowBuild
model = model.transform(GiveUniqueNodeNames())
model = model.transform(GiveReadableTensorNames())
return model


def step_mobilenet_slr_floorplan(model: ModelWrapper, cfg: DataflowBuildConfig):
if cfg.shell_flow_type == ShellFlowType.VITIS_ALVEO:
try:
from finn.analysis.partitioning import partition
# apply partitioning of the model, restricting the first and last layers to SLR0
default_slr = 0
abs_anchors = [(0,[default_slr]),(-1,[default_slr])]
floorplan = partition(model, cfg.synth_clk_period_ns, cfg.board, abs_anchors=abs_anchors, multivariant=False)[0]
# apply floorplan to model
model = model.transform(ApplyConfig(floorplan))
print("SLR floorplanning applied")
except:
print("No SLR floorplanning applied")
return model


def step_mobilenet_convert_to_hls_layers_separate_th(
model: ModelWrapper, cfg: DataflowBuildConfig
):
mem_mode = cfg.default_mem_mode.value
model = model.transform(to_hls.InferPool_Batch())
model = model.transform(to_hls.InferConvInpGen())
model = model.transform(to_hls.InferThresholdingLayer())
model = model.transform(to_hls.InferVVAU())
model = model.transform(to_hls.InferQuantizedStreamingFCLayer(mem_mode))
model = model.transform(to_hls.InferChannelwiseLinearLayer())
model = model.transform(to_hls.InferLabelSelectLayer())
model = model.transform(InferShapes())
model = model.transform(GiveUniqueNodeNames())
model = model.transform(GiveReadableTensorNames())
return model
Loading

0 comments on commit eaebe90

Please sign in to comment.