9
9
10
10
class VitisAcceleratorBackend (VitisBackend ):
11
11
def __init__ (self ):
12
- super (VivadoBackend , self ).__init__ (name = ' VitisAccelerator' )
12
+ super (VivadoBackend , self ).__init__ (name = " VitisAccelerator" )
13
13
self ._register_layer_attributes ()
14
14
self ._register_flows ()
15
15
16
16
def create_initial_config (
17
17
self ,
18
- board = ' alveo-u55c' ,
18
+ board = " alveo-u55c" ,
19
19
part = None ,
20
20
clock_period = 5 ,
21
- io_type = ' io_parallel' ,
21
+ io_type = " io_parallel" ,
22
22
num_kernel = 1 ,
23
23
num_thread = 1 ,
24
24
batchsize = 8192 ,
25
25
hw_quant = False ,
26
- vivado_directives = []
26
+ vivado_directives = [],
27
27
):
28
- '''
28
+ """
29
29
Create initial accelerator config with default parameters
30
30
31
31
Args:
@@ -38,26 +38,42 @@ def create_initial_config(
38
38
vivado_directives: Directives passed down to Vivado that controls the hardware synthesis and implementation steps
39
39
Returns:
40
40
populated config
41
- '''
42
- board = board if board is not None else ' alveo-u55c'
41
+ """
42
+ board = board if board is not None else " alveo-u55c"
43
43
config = super ().create_initial_config (part , clock_period , io_type )
44
- config [' AcceleratorConfig' ] = {}
45
- config [' AcceleratorConfig' ][ ' Board' ] = board
46
- config [' AcceleratorConfig' ][ ' Num_Kernel' ] = num_kernel
47
- config [' AcceleratorConfig' ][ ' Num_Thread' ] = num_thread
48
- config [' AcceleratorConfig' ][ ' Batchsize' ] = batchsize
49
- config [' AcceleratorConfig' ][ ' HW_Quant' ] = hw_quant
50
- config [' AcceleratorConfig' ][ ' Vivado_Directives' ] = vivado_directives
44
+ config [" AcceleratorConfig" ] = {}
45
+ config [" AcceleratorConfig" ][ " Board" ] = board
46
+ config [" AcceleratorConfig" ][ " Num_Kernel" ] = num_kernel
47
+ config [" AcceleratorConfig" ][ " Num_Thread" ] = num_thread
48
+ config [" AcceleratorConfig" ][ " Batchsize" ] = batchsize
49
+ config [" AcceleratorConfig" ][ " HW_Quant" ] = hw_quant
50
+ config [" AcceleratorConfig" ][ " Vivado_Directives" ] = vivado_directives
51
51
return config
52
52
53
- def build (self , model , reset = False , synth = True , vsynth = True , csim = False , cosim = False , debug = False , ** kwargs ):
54
- if 'linux' in sys .platform :
55
- if 'XILINX_VITIS' not in os .environ :
56
- raise Exception ("XILINX_VITIS environmental variable missing. Please install XRT and Vitis, and run the setup scripts before building" )
57
- if 'XILINX_XRT' not in os .environ :
58
- raise Exception ("XILINX_XRT environmental variable missing. Please install XRT and Vitis, and run the setup scripts before building" )
59
- if 'XILINX_VIVADO' not in os .environ :
60
- raise Exception ("XILINX_VIVADO environmental variable missing. Please install XRT and Vitis, and run the setup scripts before building" )
53
+ def build (
54
+ self ,
55
+ model ,
56
+ reset = False ,
57
+ synth = True ,
58
+ vsynth = True ,
59
+ csim = False ,
60
+ cosim = False ,
61
+ debug = False ,
62
+ ** kwargs ,
63
+ ):
64
+ if "linux" in sys .platform :
65
+ if "XILINX_VITIS" not in os .environ :
66
+ raise Exception (
67
+ "XILINX_VITIS environmental variable missing. Please install XRT and Vitis, and run the setup scripts before building"
68
+ )
69
+ if "XILINX_XRT" not in os .environ :
70
+ raise Exception (
71
+ "XILINX_XRT environmental variable missing. Please install XRT and Vitis, and run the setup scripts before building"
72
+ )
73
+ if "XILINX_VIVADO" not in os .environ :
74
+ raise Exception (
75
+ "XILINX_VIVADO environmental variable missing. Please install XRT and Vitis, and run the setup scripts before building"
76
+ )
61
77
62
78
curr_dir = os .getcwd ()
63
79
os .chdir (model .config .get_output_dir ())
@@ -68,7 +84,7 @@ def build(self, model, reset=False, synth=True, vsynth=True, csim=False, cosim=F
68
84
if synth :
69
85
os .system ("make cleanhls" )
70
86
os .system ("rm -rf host" )
71
-
87
+
72
88
if vsynth :
73
89
if synth :
74
90
target = "all "
@@ -90,35 +106,41 @@ def build(self, model, reset=False, synth=True, vsynth=True, csim=False, cosim=F
90
106
command = "make " + target
91
107
92
108
# Pre-loading libudev
93
- ldconfig_output = subprocess .check_output (["ldconfig" , "-p" ]).decode ("utf-8" )
109
+ ldconfig_output = subprocess .check_output (["ldconfig" , "-p" ]).decode (
110
+ "utf-8"
111
+ )
94
112
for line in ldconfig_output .split ("\n " ):
95
113
if "libudev.so" in line and "x86" in line :
96
- command = "LD_PRELOAD=" + line .split ("=>" )[1 ].strip () + " " + command
114
+ command = (
115
+ "LD_PRELOAD=" + line .split ("=>" )[1 ].strip () + " " + command
116
+ )
97
117
break
98
118
os .system (command )
99
-
119
+
100
120
os .chdir (curr_dir )
101
121
else :
102
122
raise Exception ("Currently untested on non-Linux OS" )
103
123
104
124
def numpy_to_dat (self , model , x ):
105
125
if len (model .get_input_variables ()) != 1 :
106
126
raise Exception ("Currently unsupported for multi-input/output projects" )
107
-
127
+
108
128
# Verify numpy array of correct shape
109
129
expected_shape = model .get_input_variables ()[0 ].size ()
110
130
actual_shape = np .prod (x .shape [1 :])
111
131
if expected_shape != actual_shape :
112
- raise Exception (f'Input shape mismatch, got { x .shape } , expected (_, { expected_shape } )' )
113
-
132
+ raise Exception (
133
+ f"Input shape mismatch, got { x .shape } , expected (_, { expected_shape } )"
134
+ )
135
+
114
136
# Write to tb_data/tb_input_features.dat
115
137
samples = x .reshape (x .shape [0 ], - 1 )
116
- input_dat = f' { model .config .get_output_dir ()} /tb_data/tb_input_features.dat'
117
- np .savetxt (input_dat , samples , fmt = ' %.4e' )
138
+ input_dat = f" { model .config .get_output_dir ()} /tb_data/tb_input_features.dat"
139
+ np .savetxt (input_dat , samples , fmt = " %.4e" )
118
140
119
141
def dat_to_numpy (self , model ):
120
142
expected_shape = model .get_output_variables ()[0 ].size ()
121
- output_file = f' { model .config .get_output_dir ()} /tb_data/hw_results.dat'
143
+ output_file = f" { model .config .get_output_dir ()} /tb_data/hw_results.dat"
122
144
y = np .loadtxt (output_file , dtype = float ).reshape (- 1 , expected_shape )
123
145
return y
124
146
@@ -134,21 +156,37 @@ def hardware_predict(self, model, x):
134
156
135
157
def _register_flows (self ):
136
158
validation_passes = [
137
- ' vitisaccelerator:validate_conv_implementation' ,
138
- ' vitisaccelerator:validate_strategy' ,
159
+ " vitisaccelerator:validate_conv_implementation" ,
160
+ " vitisaccelerator:validate_strategy" ,
139
161
]
140
- validation_flow = register_flow ('validation' , validation_passes , requires = ['vivado:init_layers' ], backend = self .name )
162
+ validation_flow = register_flow (
163
+ "validation" ,
164
+ validation_passes ,
165
+ requires = ["vivado:init_layers" ],
166
+ backend = self .name ,
167
+ )
141
168
142
169
# Any potential templates registered specifically for Vitis backend
143
170
template_flow = register_flow (
144
- 'apply_templates' , self ._get_layer_templates , requires = ['vivado:init_layers' ], backend = self .name
171
+ "apply_templates" ,
172
+ self ._get_layer_templates ,
173
+ requires = ["vivado:init_layers" ],
174
+ backend = self .name ,
145
175
)
146
176
147
- writer_passes = ['make_stamp' , 'vitisaccelerator:write_hls' ]
148
- self ._writer_flow = register_flow ('write' , writer_passes , requires = ['vitis:ip' ], backend = self .name )
177
+ writer_passes = ["make_stamp" , "vitisaccelerator:write_hls" ]
178
+ self ._writer_flow = register_flow (
179
+ "write" , writer_passes , requires = ["vitis:ip" ], backend = self .name
180
+ )
149
181
150
- ip_flow_requirements = get_flow ('vivado:ip' ).requires .copy ()
151
- ip_flow_requirements .insert (ip_flow_requirements .index ('vivado:init_layers' ), validation_flow )
152
- ip_flow_requirements .insert (ip_flow_requirements .index ('vivado:apply_templates' ), template_flow )
182
+ ip_flow_requirements = get_flow ("vivado:ip" ).requires .copy ()
183
+ ip_flow_requirements .insert (
184
+ ip_flow_requirements .index ("vivado:init_layers" ), validation_flow
185
+ )
186
+ ip_flow_requirements .insert (
187
+ ip_flow_requirements .index ("vivado:apply_templates" ), template_flow
188
+ )
153
189
154
- self ._default_flow = register_flow ('ip' , None , requires = ip_flow_requirements , backend = self .name )
190
+ self ._default_flow = register_flow (
191
+ "ip" , None , requires = ip_flow_requirements , backend = self .name
192
+ )
0 commit comments