99
1010class VitisAcceleratorBackend (VitisBackend ):
1111 def __init__ (self ):
12- super (VivadoBackend , self ).__init__ (name = ' VitisAccelerator' )
12+ super (VivadoBackend , self ).__init__ (name = " VitisAccelerator" )
1313 self ._register_layer_attributes ()
1414 self ._register_flows ()
1515
1616 def create_initial_config (
1717 self ,
18- board = ' alveo-u55c' ,
18+ board = " alveo-u55c" ,
1919 part = None ,
2020 clock_period = 5 ,
21- io_type = ' io_parallel' ,
21+ io_type = " io_parallel" ,
2222 num_kernel = 1 ,
2323 num_thread = 1 ,
2424 batchsize = 8192 ,
2525 hw_quant = False ,
26- vivado_directives = []
26+ vivado_directives = [],
2727 ):
28- '''
28+ """
2929 Create initial accelerator config with default parameters
3030
3131 Args:
@@ -38,26 +38,42 @@ def create_initial_config(
3838 vivado_directives: Directives passed down to Vivado that controls the hardware synthesis and implementation steps
3939 Returns:
4040 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"
4343 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
5151 return config
5252
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+ )
6177
6278 curr_dir = os .getcwd ()
6379 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
6884 if synth :
6985 os .system ("make cleanhls" )
7086 os .system ("rm -rf host" )
71-
87+
7288 if vsynth :
7389 if synth :
7490 target = "all "
@@ -90,35 +106,41 @@ def build(self, model, reset=False, synth=True, vsynth=True, csim=False, cosim=F
90106 command = "make " + target
91107
92108 # 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+ )
94112 for line in ldconfig_output .split ("\n " ):
95113 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+ )
97117 break
98118 os .system (command )
99-
119+
100120 os .chdir (curr_dir )
101121 else :
102122 raise Exception ("Currently untested on non-Linux OS" )
103123
104124 def numpy_to_dat (self , model , x ):
105125 if len (model .get_input_variables ()) != 1 :
106126 raise Exception ("Currently unsupported for multi-input/output projects" )
107-
127+
108128 # Verify numpy array of correct shape
109129 expected_shape = model .get_input_variables ()[0 ].size ()
110130 actual_shape = np .prod (x .shape [1 :])
111131 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+
114136 # Write to tb_data/tb_input_features.dat
115137 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" )
118140
119141 def dat_to_numpy (self , model ):
120142 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"
122144 y = np .loadtxt (output_file , dtype = float ).reshape (- 1 , expected_shape )
123145 return y
124146
@@ -134,21 +156,37 @@ def hardware_predict(self, model, x):
134156
135157 def _register_flows (self ):
136158 validation_passes = [
137- ' vitisaccelerator:validate_conv_implementation' ,
138- ' vitisaccelerator:validate_strategy' ,
159+ " vitisaccelerator:validate_conv_implementation" ,
160+ " vitisaccelerator:validate_strategy" ,
139161 ]
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+ )
141168
142169 # Any potential templates registered specifically for Vitis backend
143170 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 ,
145175 )
146176
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+ )
149181
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+ )
153189
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