Transformation - fpgadataflow
Transformations (fpgadataflow)
finn.transformation.fpgadataflow.annotate_cycles
- class finn.transformation.fpgadataflow.annotate_cycles.AnnotateCycles
Bases:
TransformationAnnotate the estimate of clock cycles per sample taken by each fpgadataflow node as an attribute on the node.
- apply(model)
finn.transformation.fpgadataflow.annotate_resources
- class finn.transformation.fpgadataflow.annotate_resources.AnnotateResources(mode, fpgapart, override_res_dict=None)
Bases:
TransformationAnnotate the amount of FPGA resources taken by each fpgadataflow node as an attribute on the node, depending on the mode parameter: * ‘estimate’ – use the analytical estimation model * ‘hls’ – use results from the HLS synthesis report * ‘synth’ – use post-synthesis (Vivado or Vitis) report
No annotations can be provided unless the relevant transformation for the chosen mode (e.g. HLSSynthIP for hls) was previously run.
- apply(model)
finn.transformation.fpgadataflow.cleanup
- class finn.transformation.fpgadataflow.cleanup.CleanUp
Bases:
TransformationRemove any generated files for fpgadataflow nodes.
- apply(model)
finn.transformation.fpgadataflow.compile_cppsim
- class finn.transformation.fpgadataflow.compile_cppsim.CompileCppSim(num_workers=None)
Bases:
NodeLocalTransformationFor every node: compile C++ code in node attribute “code_gen_dir_cppsim” and save path to executables in node attribute “executable_path”. All nodes in the graph must have the fpgadataflow backend attribute.
To use these executables, exec_mode must be set to “cppsim” (using transformation SetExecMode) and the model has to be executed using execute_onnx() from finn.core.onnx_exec
num_workers (int or None) number of parallel workers, see documentation in NodeLocalTransformation for more details.
- applyNodeLocal(node)
finn.transformation.fpgadataflow.convert_to_hw_layers
finn.transformation.fpgadataflow.create_dataflow_partition
- class finn.transformation.fpgadataflow.create_dataflow_partition.CreateDataflowPartition(partition_model_dir=None)
Bases:
TransformationSplit a graph into two graphs; one which contains non-FINN-dataflow nodes and a StreamingDataflowPartition node, and another which only contains FINN dataflow nodes. The StreamingDataflowPartition has a model attribute that indicates the filename for the second graph that only contains dataflow nodes. No action is taken if there are no dataflow nodes.
- apply(model)
finn.transformation.fpgadataflow.create_stitched_ip
- class finn.transformation.fpgadataflow.create_stitched_ip.CreateStitchedIP(fpgapart, clk_ns, ip_name='finn_design', run_synth=False, run_pnr=False, signature=[])
Bases:
TransformationCreate a Vivado IP Block Design project from all the generated IPs of a graph. All nodes in the graph must have the fpgadataflow backend attribute, and the PrepareIP transformation must have been previously run on the graph. The resulting block design is also packaged as IP. The transformation gets the fpgapart as a string.
Outcome if successful: sets the vivado_stitch_proj attribute in the ONNX ModelProto’s metadata_props field, with the created project dir as the value. A make_project.tcl script is also placed under the same folder, which is called to instantiate the per-layer IPs and stitch them together. The packaged block design IP can be found under the ip subdirectory.
- apply(model)
- connect_ap_none_external(node)
- connect_axi(node, model)
- connect_clk_rst(node)
- connect_m_axis_external(node, idx=None)
- connect_s_axis_external(node, idx=None)
- insert_signature(checksum_count)
- is_double_pumped(node)
- finn.transformation.fpgadataflow.create_stitched_ip.is_external_input(model, node, i)
- finn.transformation.fpgadataflow.create_stitched_ip.is_external_output(model, node, i)
finn.transformation.fpgadataflow.derive_characteristic
- class finn.transformation.fpgadataflow.derive_characteristic.DeriveCharacteristic(period, num_workers=None, manual_bypass=False)
Bases:
NodeLocalTransformationFor each node in the graph, run rtlsim to obtain the i/o characteristic function for FIFO sizing and set the attribute. It is assumed that the PrepareRTLSim transformation was already called on the graph.
This transformation performs rtlsim for each node, so it will run for some time (minutes to hours depending on configuration).
period (int) desired period over which the characteristic function will be derived.
num_workers (int or None) number of parallel workers, see documentation in NodeLocalTransformation for more details.
- apply(model: ModelWrapper)
- applyNodeLocal(node)
- class finn.transformation.fpgadataflow.derive_characteristic.DeriveFIFOSizes(num_workers=None, io_fifo_depth=32)
Bases:
NodeLocalTransformationPrerequisite: DeriveCharacteristic already called on graph. For each node in the graph, use the accumulated I/O characteristic function to perform FIFO sizing, setting the in/outFIFODepths attributes of HLSCustomOp nodes.
num_workers (int or None) number of parallel workers, see documentation in NodeLocalTransformation for more details.
- applyNodeLocal(node)
finn.transformation.fpgadataflow.externalize_params
- class finn.transformation.fpgadataflow.externalize_params.ExternalizeParams
Bases:
TransformationCreate top-level graph inputs for IODMAs serving layers where weights are marked as external using mem_mode=”external”.
- apply(model)
finn.transformation.fpgadataflow.floorplan
- class finn.transformation.fpgadataflow.floorplan.Floorplan(floorplan=None)
Bases:
TransformationPerform Floorplanning of the dataflow design:
- floorplan: path to a JSON containing a dictionary with SLR assignments
for each node in the ONNX graph. Must be parse-able by the ApplyConfig transform.
The transform applies the properties in the supplied JSON then: -Separates DMAs into their own partitions IDs, -If not explicitly assigned, assigns DWCs to SLRs to minimize SLLs required -If not explicitly assigned, assigns FIFOs to the SLR of the upstream node
- apply(model)
finn.transformation.fpgadataflow.hlssynth_ip
- class finn.transformation.fpgadataflow.hlssynth_ip.HLSSynthIP(fpgapart=None, num_workers=None)
Bases:
NodeLocalTransformationFor each HLS node: generate IP block from code in folder that is referenced in node attribute “code_gen_dir_ipgen” and save path of generated project in node attribute “ipgen_path”. All nodes in the graph must have the fpgadataflow backend attribute. Any nodes that already have a ipgen_path attribute pointing to a valid path will be skipped.
This transformation calls Vitis HLS for synthesis, so it will run for some time (minutes to hours depending on configuration).
num_workers (int or None) number of parallel workers, see documentation in NodeLocalTransformation for more details.
- applyNodeLocal(node)
finn.transformation.fpgadataflow.infer_pixel_padding_deconv
- class finn.transformation.fpgadataflow.infer_pixel_padding_deconv.InferPixelPaddingDeconv
Bases:
TransformationLowering and conversion of ConvTranspose (NCHW) nodes to FMPadding_Pixel + Im2Col + MatMul (NHWC) surrounded by Transpose nodes note: this transformation produces a mix of hw layers and non hw layers to implement this on an FPGA the Im2Col and MatMul nodes need to be converted to hw layers after applying this transformation and the resulting transpose nodes need to be streamlined. See deconv test case under tests/fpgadataflow for an example.
- apply(model)
finn.transformation.fpgadataflow.insert_dwc
- class finn.transformation.fpgadataflow.insert_dwc.InsertDWC
Bases:
TransformationAdd data width converters between layers where necessary.
- apply(model)
finn.transformation.fpgadataflow.insert_fifo
- class finn.transformation.fpgadataflow.insert_fifo.InsertFIFO(create_shallow_fifos=False, max_qsrl_depth=None, vivado_ram_style='auto')
Bases:
TransformationInserting FIFOs in the beginning and end of the graph as well as between fpgadataflow nodes.
Takes the setting for the depth from the surrounding nodes by extracting node attribute ‘outFIFODepths’ of the previous and node attribute ‘inFIFODepths’ of the subsequent node. max() of these two values sets the FIFO depth.
Constructor arguments:
- Parameters:
max_qsrl_depth – FIFOs deeper than this will use Vivado IP instead of Verilog FIFOs (Q_srl.v)
vivado_ram_style – the StreamingFIFO.ram_style attribute to be used for large FIFOs implemented by Vivado
create_shallow_fifos – Normally, shallow-depth (<=2) FIFOs won’t be created since HLS streaming interfaces already have a degree of buffering. Override with this parameter.
The other node attributes necessary to create a FIFO node are taken from the node the FIFO node is inserted after: ‘folded_shape’ and ‘dtype’
- apply(model)
finn.transformation.fpgadataflow.insert_hook
- class finn.transformation.fpgadataflow.insert_hook.InsertHook
Bases:
TransformationInserting hook layer after each layer that has the node attribute ‘output_hook’ specified
- apply(model)
finn.transformation.fpgadataflow.insert_iodma
- class finn.transformation.fpgadataflow.insert_iodma.InsertIODMA(max_intfwidth=32, insert_input=True, insert_output=True, insert_extmemw=True)
Bases:
TransformationInsert DMA nodes on inputs and outputs, or as specified by filters in the constructor.
- apply(model)
- get_mem_init(weights, pe, simd)
Returns matrix ready for pack_innermost_dim_as_hex_string with reverse=False (finn.util.data_packing) to return the memory init file little endian packed. That is, get_mem_init returns: elem(pe,simd) addr = 0: [(pe-1,simd-1),(pe-1,simd-2),…(0,1),(0,0)] addr = 1: [(pe-1,simd*2-1),…….(0,simd+1),(0,simd)] .
finn.transformation.fpgadataflow.insert_tlastmarker
- class finn.transformation.fpgadataflow.insert_tlastmarker.InsertTLastMarker(both=False, external=True, dynamic=True)
Bases:
TransformationEnsure that the graph is started/terminated with a TLastMarker_hls node, inserting one if necessary. Use constructor args to determine type of TLastMarker to be inserted. More information available on the TLastMarker documentation.
- apply(model)
finn.transformation.fpgadataflow.loop_rolling
- class finn.transformation.fpgadataflow.loop_rolling.LoopBodyInputType(value)
Bases:
EnumAn enumeration.
- ACTIVATION = 1
- CONDITION = 5
- CONSTANT = 2
- ITERATOR = 4
- PARAMETER = 3
- UNDEFINED = 0
- class finn.transformation.fpgadataflow.loop_rolling.LoopBodyTemplate(filename)
Bases:
object- build_function_match_pattern(graph, use_iteration_ext=True)
- load(filename)
- property output_signature
- save(filename)
- set_signature_index(index, stype)
- update()
- class finn.transformation.fpgadataflow.loop_rolling.LoopExtraction(hierarchy_list: List[List[str]])
Bases:
Transformation- apply(model: ModelWrapper) Tuple[ModelWrapper, bool]
- class finn.transformation.fpgadataflow.loop_rolling.LoopRolling(loop_body_template)
Bases:
TransformationBoilerplate Transformation for loop rolling in fpgadataflow.
- apply(model: ModelWrapper) Tuple[ModelWrapper, bool]
- finn.transformation.fpgadataflow.loop_rolling.add_finn_datatype_if_needed(tensor)
- finn.transformation.fpgadataflow.loop_rolling.build_loop_replace_pattern(graph, LoopBody)
- finn.transformation.fpgadataflow.loop_rolling.finn_datatypes_match(datatype_a, datatype_b)
- finn.transformation.fpgadataflow.loop_rolling.get_constant_from_value(value)
Get the constant value of a tensor.
- finn.transformation.fpgadataflow.loop_rolling.same_values(inputs)
Check if all inputs have the same constant value.
- finn.transformation.fpgadataflow.loop_rolling.tensor_has_finn_datatype(tensor)
- finn.transformation.fpgadataflow.loop_rolling.tensor_shapes_match(value_a, value_b)
- finn.transformation.fpgadataflow.loop_rolling.tensor_types_match(value_a, value_b)
- finn.transformation.fpgadataflow.loop_rolling.validate_loop_attributes(loop_node: Node)
- finn.transformation.fpgadataflow.loop_rolling.validate_loop_io_tensor_pair(tensor_a, tensor_b)
- finn.transformation.fpgadataflow.loop_rolling.validate_loop_io_tensors(loop_node: Node)
- finn.transformation.fpgadataflow.loop_rolling.validate_loop_node(loop_node: Node)
- finn.transformation.fpgadataflow.loop_rolling.validate_loop_type(loop_node: Node)
finn.transformation.fpgadataflow.make_pynq_driver
- class finn.transformation.fpgadataflow.make_driver.MakeCPPDriver(platform: str, version: str)
Bases:
TransformationCreate CPP code to correctly interface the generated accelerator, including data packing/unpacking. Should be called after conversion to HLS layers, folding and the creation of dataflow partitions for correct operation. platform: has to be “vitis-xrt”, otherwise an error is thrown Outcome if successful: sets the cpp_driver_dir attribute in the ONNX ModelProto’s metadata_props field, with the created driver dir as the value. runtime writeable weights not yet supported.
- apply(model: ModelWrapper) Tuple[ModelWrapper, bool]
- resolve_dt_name() str
- class finn.transformation.fpgadataflow.make_driver.MakePYNQDriver(platform)
Bases:
TransformationCreate PYNQ Python code to correctly interface the generated accelerator, including data packing/unpacking. Should be called after conversion to HLS layers, folding and the creation of dataflow partitions for correct operation.
platform: one of [“zynq-iodma”, “vitis-xrt”]
Outcome if successful: sets the pynq_driver_dir attribute in the ONNX ModelProto’s metadata_props field, with the created driver dir as the value. If any layers use runtime-writable parameters, those will be gathered under the runtime_weights/ subfolder of the pynq_driver_dir.
- apply(model)
finn.transformation.fpgadataflow.make_zynq_proj
finn.transformation.fpgadataflow.minimize_accumulator_width
- class finn.transformation.fpgadataflow.minimize_accumulator_width.MinimizeAccumulatorWidth
Bases:
TransformationFor relevant nodes, call the accumulator width minimization functions to save on resources. May alter tensor DataType for certain nodes if they produce an accumulator as result.
- apply(model)
finn.transformation.fpgadataflow.minimize_weight_bit_width
- class finn.transformation.fpgadataflow.minimize_weight_bit_width.MinimizeWeightBitWidth
Bases:
TransformationFor relevant nodes, call the weight bit width minimization functions to save on resources. May alter tensor weightDataType if the node does not have runtime writeable weights.
- apply(model)
finn.transformation.fpgadataflow.prepare_cppsim
- class finn.transformation.fpgadataflow.prepare_cppsim.PrepareCppSim(num_workers=None)
Bases:
TransformationCall custom implementation to generate code for single custom node and create folder that contains all the generated files. All nodes in the graph must have the fpgadataflow backend attribute.
Outcome if succesful: Node attribute “code_gen_dir_cppsim” contains path to folder that contains generated C++ code that can be used to simulate node using cppsim. The subsequent transformation is CompileCppSim
- apply(model)
- prepareCppSim_node(node)
finn.transformation.fpgadataflow.prepare_ip
- class finn.transformation.fpgadataflow.prepare_ip.PrepareIP(fpgapart, clk)
Bases:
TransformationCall custom implementation to generate code for single custom node and create folder that contains all the generated files. All nodes in the graph must have the fpgadataflow backend attribute and transformation gets additional arguments:
fpgapart (string)
clk in ns (int)
Any nodes that already have a code_gen_dir_ipgen attribute pointing to a valid path will be skipped.
Outcome if succesful: Node attribute “code_gen_dir_ipgen” contains path to folder that contains:
For HLS layers: generated C++ code that can be used to generate a Vivado IP block. The necessary subsequent transformation is HLSSynthIP.
For RTL layers: filled template verilog files that can be used to instantiate as module during IP stitching.
- apply(model)
finn.transformation.fpgadataflow.prepare_rtlsim
- class finn.transformation.fpgadataflow.prepare_rtlsim.PrepareRTLSim(behav=False, num_workers=None)
Bases:
NodeLocalTransformationFor a graph with generated RTL sources (after HLSSynthIP), create an emulation library for each node to prepare for rtlsim execution and set the rtlsim_so property to the path to the generated emulation library.
To use these libraries, exec_mode must be set to “rtlsim” (using SetExecMode) and the model has to be executed using execute_onnx() from finn.core.onnx_exec
num_workers (int or None) number of parallel workers, see documentation in NodeLocalTransformation for more details.
- apply(model)
- applyNodeLocal(node)
finn.transformation.fpgadataflow.raise_scalar_to_rank1
finn.transformation.fpgadataflow.replace_verilog_relpaths
- class finn.transformation.fpgadataflow.replace_verilog_relpaths.ReplaceVerilogRelPaths
Bases:
TransformationConvert ./ relative file paths to absolute ones for generated Verilog
- apply(model)
finn.transformation.fpgadataflow.set_exec_mode
- class finn.transformation.fpgadataflow.set_exec_mode.SetExecMode(mode)
Bases:
TransformationSet attribute exec_mode in all fpgadataflow nodes to specify which kind of execution should be used (“cppsim” or “rtlsim”). Note that RTL components do not support cppsim. When cppsim is selected for RTL components, by default the execution of the HW op parent is executed.
- apply(model)
finn.transformation.fpgadataflow.set_fifo_depths
finn.transformation.fpgadataflow.set_folding
finn.transformation.fpgadataflow.set_loop_boundary
- class finn.transformation.fpgadataflow.set_loop_boundary.SetLoopBoundary(node_metadata, node_range=None, tensor_range=None)
Bases:
TransformationSets metadata attributes to nodes between defined node or tensor ranges in an ONNX model.
- Parameters:
node_metadata – Dictionary containing metadata attributes to set on the nodes.
node_range – Tuple containing start and end node names (start_node, end_node).
tensor_range – Tuple containing start and end tensor names (start_tensor, end_tensor).
- apply(model)