Skip to content

Commit c7e1be2

Browse files
authored
Merge pull request #1 from alex-yang-upenn/integ_vitis_accel_dev
First Step Towards Integration
2 parents 55ff7e2 + ea332d2 commit c7e1be2

21 files changed

+1629
-659
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"alveo-u55c": {
3+
"board_type": "alveo",
4+
"part": "xcu55c-fsvh2892-2L-e",
5+
"platform": "xilinx_u55c_gen3x16_xdma_3_202210_1",
6+
"memory": {"type": "hbm", "channels": 32, "capacity": 16}
7+
},
8+
"alveo-u50": {
9+
"board_type": "alveo",
10+
"part": "xcu50-fsvh2104-2-e",
11+
"platform": "xilinx_u50_gen3x16_xdma_5_202210_1",
12+
"memory": {"type": "hbm", "channels": 32, "capacity": 8}
13+
},
14+
"alveo-u250": {
15+
"board_type": "alveo",
16+
"part": "xcu250-figd2104-2L-e",
17+
"platform": "xilinx_u250_xdma_201830_2",
18+
"memory": {"type": "ddr", "channels": 4, "capacity": 64}
19+
},
20+
"vck5000": {
21+
"board_type": "versal",
22+
"part": "xcvc1902-2msevsvd1760",
23+
"platform": "xilinx_vck5000_gen4x8_qdma_2_202220_1",
24+
"memory":{"type": "ddr", "channels": 3, "capacity": 12}
25+
}
26+
}
Lines changed: 64 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import os
2+
import sys
3+
import subprocess
4+
15
from hls4ml.backends import VitisBackend, VivadoBackend
26
from hls4ml.model.flow import get_flow, register_flow
37

@@ -8,38 +12,15 @@ def __init__(self):
812
self._register_layer_attributes()
913
self._register_flows()
1014

11-
def _register_flows(self):
12-
validation_passes = [
13-
'vitisaccelerator:validate_conv_implementation',
14-
'vitisaccelerator:validate_strategy',
15-
]
16-
validation_flow = register_flow('validation', validation_passes, requires=['vivado:init_layers'], backend=self.name)
17-
18-
# Any potential templates registered specifically for Vitis backend
19-
template_flow = register_flow(
20-
'apply_templates', self._get_layer_templates, requires=['vivado:init_layers'], backend=self.name
21-
)
22-
23-
writer_passes = ['make_stamp', 'vitisaccelerator:write_hls']
24-
self._writer_flow = register_flow('write', writer_passes, requires=['vitis:ip'], backend=self.name)
25-
26-
ip_flow_requirements = get_flow('vivado:ip').requires.copy()
27-
ip_flow_requirements.insert(ip_flow_requirements.index('vivado:init_layers'), validation_flow)
28-
ip_flow_requirements.insert(ip_flow_requirements.index('vivado:apply_templates'), template_flow)
29-
30-
self._default_flow = register_flow('ip', None, requires=ip_flow_requirements, backend=self.name)
31-
3215
def create_initial_config(
3316
self,
34-
board='pynq-z2',
17+
board='alveo-u55c',
3518
part=None,
3619
clock_period=5,
3720
io_type='io_parallel',
38-
interface='axi_stream',
39-
driver='python',
40-
input_type='float',
41-
output_type='float',
42-
platform='xilinx_u250_xdma_201830_2',
21+
num_kernel=1,
22+
num_thread=1,
23+
batchsize=8192
4324
):
4425
'''
4526
Create initial accelerator config with default parameters
@@ -48,32 +29,66 @@ def create_initial_config(
4829
board: one of the keys defined in supported_boards.json
4930
clock_period: clock period passed to hls project
5031
io_type: io_parallel or io_stream
51-
interface: `axi_stream`: generate hardware designs and drivers which exploit axi stream channels.
52-
`axi_master`: generate hardware designs and drivers which exploit axi master channels.
53-
`axi_lite` : generate hardware designs and drivers which exploit axi lite channels. (Don't use it
54-
to exchange large amount of data)
55-
driver: `python`: generates the python driver to use the accelerator in the PYNQ stack.
56-
`c`: generates the c driver to use the accelerator bare-metal.
57-
input_type: the wrapper input precision. Can be `float` or an `ap_type`. Note: VivadoAcceleratorBackend
58-
will round the number of bits used to the next power-of-2 value.
59-
output_type: the wrapper output precision. Can be `float` or an `ap_type`. Note:
60-
VivadoAcceleratorBackend will round the number of bits used to the next power-of-2 value.
61-
platform: development target platform
62-
32+
num_kernel: how many compute units to create on the fpga
33+
num_thread: how many threads the host cpu uses to drive the fpga
6334
Returns:
6435
populated config
6536
'''
66-
board = board if board is not None else 'pynq-z2'
37+
board = board if board is not None else 'alveo-u55c'
6738
config = super().create_initial_config(part, clock_period, io_type)
6839
config['AcceleratorConfig'] = {}
6940
config['AcceleratorConfig']['Board'] = board
70-
config['AcceleratorConfig']['Interface'] = interface # axi_stream, axi_master, axi_lite
71-
config['AcceleratorConfig']['Driver'] = driver
72-
config['AcceleratorConfig']['Precision'] = {}
73-
config['AcceleratorConfig']['Precision']['Input'] = {}
74-
config['AcceleratorConfig']['Precision']['Output'] = {}
75-
config['AcceleratorConfig']['Precision']['Input'] = input_type # float, double or ap_fixed<a,b>
76-
config['AcceleratorConfig']['Precision']['Output'] = output_type # float, double or ap_fixed<a,b>
77-
config['AcceleratorConfig']['Platform'] = platform
78-
41+
config['AcceleratorConfig']['Num_Kernel'] = num_kernel
42+
config['AcceleratorConfig']['Num_Thread'] = num_thread
43+
config['AcceleratorConfig']['Batchsize'] = batchsize
7944
return config
45+
46+
def build(self, model, target="all"):
47+
if 'linux' in sys.platform:
48+
if 'XILINX_VITIS' not in os.environ:
49+
raise Exception("XILINX_VITIS environmental variable missing. Please install XRT and Vitis, and run the setup scripts before building")
50+
if 'XILINX_XRT' not in os.environ:
51+
raise Exception("XILINX_XRT environmental variable missing. Please install XRT and Vitis, and run the setup scripts before building")
52+
if 'XILINX_VIVADO' not in os.environ:
53+
raise Exception("XILINX_VIVADO environmental variable missing. Please install XRT and Vitis, and run the setup scripts before building")
54+
55+
if target not in ["all", "host", "hls", "xclbin"]:
56+
raise Exception("Invalid build target")
57+
58+
curr_dir = os.getcwd()
59+
os.chdir(model.config.get_output_dir())
60+
command = "make " + target
61+
# Pre-loading libudev
62+
ldconfig_output = subprocess.check_output(["ldconfig", "-p"]).decode("utf-8")
63+
for line in ldconfig_output.split("\n"):
64+
if "libudev.so" in line and "x86" in line:
65+
command = "LD_PRELOAD=" + line.split("=>")[1].strip() + " " + command
66+
break
67+
os.system(command)
68+
os.chdir(curr_dir)
69+
else:
70+
raise Exception("Currently untested on non-Linux OS")
71+
72+
def predict(self, model, x):
73+
raise Exception("TODO: Needs to be implemented")
74+
75+
def _register_flows(self):
76+
validation_passes = [
77+
'vitisaccelerator:validate_conv_implementation',
78+
'vitisaccelerator:validate_strategy',
79+
]
80+
validation_flow = register_flow('validation', validation_passes, requires=['vivado:init_layers'], backend=self.name)
81+
82+
# Any potential templates registered specifically for Vitis backend
83+
template_flow = register_flow(
84+
'apply_templates', self._get_layer_templates, requires=['vivado:init_layers'], backend=self.name
85+
)
86+
87+
writer_passes = ['make_stamp', 'vitisaccelerator:write_hls']
88+
self._writer_flow = register_flow('write', writer_passes, requires=['vitis:ip'], backend=self.name)
89+
90+
ip_flow_requirements = get_flow('vivado:ip').requires.copy()
91+
ip_flow_requirements.insert(ip_flow_requirements.index('vivado:init_layers'), validation_flow)
92+
ip_flow_requirements.insert(ip_flow_requirements.index('vivado:apply_templates'), template_flow)
93+
94+
self._default_flow = register_flow('ip', None, requires=ip_flow_requirements, backend=self.name)
Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,54 @@
1+
import json
2+
import os
3+
14
class VitisAcceleratorConfig:
25
def __init__(self, config):
36
self.config = config.config
7+
accel_config = self.config.get('AcceleratorConfig', None)
8+
if accel_config is None:
9+
raise Exception('Missing AcceleratorConfig')
10+
11+
self.board = accel_config.get('Board', 'alveo-u55c')
12+
self.supported_boards = json.load(open(os.path.dirname(__file__) + '/supported_boards.json'))
13+
if self.board in self.supported_boards.keys():
14+
board_info = self.supported_boards[self.board]
15+
self.board_type = board_info['board_type']
16+
self.part = board_info['part']
17+
self.platform = board_info['platform']
18+
self.memory_type = board_info['memory']['type']
19+
self.memory_channel_count = board_info['memory']['channels']
20+
else:
21+
raise Exception('The board does not appear in supported_boards.json file')
22+
23+
if self.config.get('Part') is not None:
24+
if self.config.get('Part') != self.part:
25+
print(
26+
'WARNING: You set a Part that does not correspond to the Board you specified.'
27+
'The correct Part is now set.'
28+
)
29+
self.config['Part'] = self.part
30+
31+
self.num_kernel = accel_config.get('Num_Kernel')
32+
self.num_thread = accel_config.get('Num_Thread')
33+
self.batchsize = accel_config.get('Batchsize')
434

5-
self.platform = self.config['AcceleratorConfig'].get(
6-
'Platform', 'xilinx_u250_xdma_201830_2'
7-
) # Get platform folder name
35+
def get_board_type(self):
36+
return self.board_type
837

938
def get_platform(self):
1039
return self.platform
40+
41+
def get_num_thread(self):
42+
return self.num_thread
43+
44+
def get_num_kernel(self):
45+
return self.num_kernel
46+
47+
def get_batchsize(self):
48+
return self.batchsize
49+
50+
def get_memory_type(self):
51+
return self.memory_type
52+
53+
def get_memory_channel_count(self):
54+
return self.memory_channel_count

hls4ml/model/graph.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,9 @@ def _compute_n_samples(self, x):
734734
return int(n_sample)
735735

736736
def predict(self, x):
737+
if self.config.config.get('Backend', 'Vivado') == 'VitisAccelerator':
738+
return self.config.backend.predict(self, x)
739+
737740
top_function, ctype = self._get_top_function(x)
738741
n_samples = self._compute_n_samples(x)
739742
n_inputs = len(self.get_input_variables())
Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,58 @@
1-
.PHONY: clean
2-
3-
PLATFORM=myplatform
1+
# Absolute path to top directory of accelerator project
2+
PWD = $(shell readlink -f .)
43

5-
app.exe: ./myproject_host.cpp
6-
g++ -g -std=c++14 ./myproject_host.cpp -o app.exe \
7-
-I firmware/ap_types -I/opt/xilinx/xrt/include \
8-
-L${XILINX_XRT}/lib/ -lxrt_coreutil -lOpenCL -pthread -lrt -lstdc++
4+
# Checks for XILINX_VITIS
5+
ifndef XILINX_VITIS
6+
$(error XILINX_VITIS variable is not set, please set correctly and rerun)
7+
endif
98

10-
myproject_kernel.xo: myproject_kernel.cpp
11-
v++ --target hw --compile -I"./" --config accelerator_card.cfg -o"build/myproject_kernel.xo" "myproject_kernel.cpp"
9+
# Checks for XILINX_XRT
10+
ifndef XILINX_XRT
11+
$(error XILINX_XRT variable is not set, please set correctly and rerun)
12+
endif
1213

13-
ifneq (,$(findstring vck5000,$(PLATFORM)))
14-
myproject_kernel.xsa: ./build/myproject_kernel.xo
15-
v++ -l -t hw --config ./accelerator_card.cfg ./build/myproject_kernel.xo -o myproject_kernel.xsa
14+
# Checks for XILINX_VIVADO
15+
ifndef XILINX_VIVADO
16+
$(error XILINX_VIVADO variable is not set, please set correctly and rerun)
17+
endif
1618

17-
myproject_kernel.xclbin: ./myproject_kernel.xsa
18-
v++ --package -t hw --config ./accelerator_card.cfg ./myproject_kernel.xsa -o myproject_kernel.xclbin
19-
else
20-
myproject_kernel.xclbin: ./myproject_kernel.xo
21-
v++ -l -t hw --config ./accelerator_card.cfg ./build/myproject_kernel.xo -o myproject_kernel.xclbin
19+
# Checks for g++
20+
ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1)
21+
CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++
22+
$(warning [WARNING]: g++ version older. Using g++ provided by the tool : $(CXX))
2223
endif
2324

24-
emconfig.json:
25-
emconfigutil --platform xilinx_vck5000_gen4x8_qdma_2_202220_1 --nd 1
25+
KERN_LIBRARIES += -I./ -I./firmware/ -I./firmware/weights -I./firmware/nnet_utils/
2626

27-
clean:
28-
rm -f KERAS_3layer.json KERAS_3layer_weights.h5 prj_tuto_vitis_stream.tar.gz
29-
rm -rf myproject_kernel* myproject_kernel* .exe *json *csv *log *summary _x xilinx* .run .Xil .ipcache *.jou
27+
.PHONY: all
28+
all: host xclbin
29+
30+
# Building kernel
31+
./build/myproject_kernel.xo: kernel_wrapper.cpp
32+
mkdir -p ./build && mkdir -p ./build/xo
33+
v++ -c -t hw --config ./accelerator_card.cfg --temp_dir build/xo kernel_wrapper.cpp firmware/myproject.cpp -o ./build/myproject_kernel.xo $(KERN_LIBRARIES)
3034

31-
# Unless specified, use the current directory name as the v++ build target
32-
TARGET ?= $(notdir $(CURDIR))
35+
# hls-fpga-machine-learning packaging
36+
37+
# Building Host
38+
INCLUDES += -I$(XILINX_XRT)/include/ -I$(XILINX_VIVADO)/include/ -I$(XILINX_HLS)/include/ \
39+
-I$(PWD)/libs/ -I$(PWD)/firmware/ -I$(PWD)/firmware/nnet_utils/
40+
CXXFLAGS += -Wall -std=c++11 -Wno-unknown-pragmas -g -O0
41+
LDFLAGS = -L$(XILINX_XRT)/lib/ -lstdc++ -lpthread -lrt -lOpenCL
42+
43+
host: myproject_host_cl.cpp libs/xcl2.cpp
44+
$(CXX) $(CXXFLAGS) $^ -o $@ $(INCLUDES) $(LDFLAGS)
45+
46+
.PHONY: hls
47+
hls: ./build/myproject_kernel.xo
48+
49+
.PHONY: xclbin
50+
xclbin: ./build/kernel_wrapper.xclbin
51+
52+
# Cleaning stuff
53+
.PHONY: clean
54+
clean:
55+
-rm -rf host
56+
-rm -rf *.xclbin*
57+
-rm -rf build*
58+
-rm -rf *.log *.jou *.rpt *.csv *.mdb *.ltx
Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
1-
platform=myplatform
1+
kernel=kernel_wrapper
2+
messageDb=build/kernel_wrapper.mdb
3+
platform=MYPLATFORM
24
save-temps=1
3-
kernel=myproject_kernel
4-
messageDb=build/myproject_kernel.mdb
5-
temp_dir=build
6-
report_dir=build/reports
7-
log_dir=build/logs
85

96
[advanced]
10-
misc=solution_name=myproject_kernel
7+
prop=kernel.kernel_wrapper.kernel_flags=-std=c++11
8+
9+
[hls]
10+
pre_tcl=./hls_config.tcl
11+
12+
# hls-fpga-machine-learning kernel control
13+
14+
[vivado]
15+
prop=run.impl_1.STEPS.OPT_DESIGN.IS_ENABLED=true
16+
prop=run.impl_1.STEPS.OPT_DESIGN.ARGS.DIRECTIVE=Explore
17+
18+
prop=run.impl_1.STEPS.PLACE_DESIGN.ARGS.DIRECTIVE=AltSpreadLogic_high
19+
20+
prop=run.impl_1.STEPS.PHYS_OPT_DESIGN.IS_ENABLED=true
21+
prop=run.imp1_1.STEPS.PHYS_OPT_DESIGN.ARGS.DIRECTIVE=AggressiveExplore
22+
23+
prop=run.impl_1.STEPS.ROUTE_DESIGN.ARGS.DIRECTIVE=Explore
24+
25+
prop=run.impl_1.STEPS.POST_ROUTE_PHYS_OPT_DESIGN.IS_ENABLED=true
26+
prop=run.impl_1.STEPS.POST_ROUTE_PHYS_OPT_DESIGN.ARGS.DIRECTIVE=AggressiveExplore
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
config_interface -m_axi_auto_max_ports=true
2+
config_interface -m_axi_offset slave
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef KERNEL_WRAPPER_H
2+
#define KERNEL_WRAPPER_H
3+
4+
#include "firmware/defines.h"
5+
6+
// hls-fpga-machine-learning accelerator parameters
7+
8+
// hls-fpga-machine-learning accelerator io
9+
10+
#endif

0 commit comments

Comments
 (0)