Util
Utility Modules
qonnx.util.basic
- qonnx.util.basic.auto_pad_to_explicit_padding(autopad_str: str, idim_h: int, idim_w: int, k_h: int, k_w: int, stride_h: int, stride_w: int, n_dims: int) list[int]
- qonnx.util.basic.calculate_matvec_accumulator_range(matrix: ndarray, vec_dt: BaseDataType) tuple[float, float]
Calculate the minimum and maximum possible result (accumulator) values for a dot product x * A, given matrix A of dims (MW, MH), and vector (1, MW) with datatype vec_dt. Returns (acc_min, acc_max).
- qonnx.util.basic.calculate_signed_dot_prod_range(dt_a: BaseDataType, dt_b: BaseDataType, len: int) tuple[int | float, int | float]
Returns the (min,max) values a dot product between two signed vectors of types dt_a and dt_b of len elements can take.
- qonnx.util.basic.gen_finn_dt_tensor(finn_dt: BaseDataType, tensor_shape: tuple[int, ...] | list[int]) ndarray
Generates random tensor in given shape and with given QONNX DataType.
- qonnx.util.basic.get_by_name(container, name: str, name_field: str = 'name')
Return item from protobuf container by .name field if it exists, None otherwise. Will throw an Exception if multiple items are found, since this violates the ONNX standard.
- qonnx.util.basic.get_execution_error_thresh() float
Return the max error that is allowed for rounding in QONNX execution.
- qonnx.util.basic.get_num_default_workers() int
Return the number of workers for parallel transformations. Controllable via the NUM_DEFAULT_WORKERS environment variable. If the env.var. is undefined, the default value of 1 is returned.
- qonnx.util.basic.get_preferred_onnx_opset() int
Return preferred ONNX opset version for QONNX
- qonnx.util.basic.get_preferred_qonnx_opset() int
Return preferred ONNX opset version for QONNX
- qonnx.util.basic.get_sanitize_quant_tensors() int
Return whether tensors with quantization annotations should be sanitized. Enabled by default, disabling will yield faster ONNX execution but may give incorrect results. Use with caution.
- qonnx.util.basic.interleave_matrix_outer_dim_from_partitions(matrix: ndarray, n_partitions: int) ndarray
Interleave the outermost dimension of a matrix from given partitions (n_partitions).
- qonnx.util.basic.is_finn_op(op_type: str) bool
Deprecated: Use is_custom_op from qonnx.custom_op.registry instead.
Return whether given op_type string is a QONNX or FINN custom op. This function uses hard-coded string matching and will be removed in QONNX v1.0. Use the registry-based is_custom_op for better accuracy and extensibility.
- qonnx.util.basic.pad_tensor_to_multiple_of(ndarray: ndarray, pad_to_dims: Sequence[int], val: float = 0, distr_pad: bool = False) ndarray
Pad each dimension of given NumPy ndarray using val, so that each dimension is a multiple of the respective value in pad_to_dims. -1 means do not pad that particular dimension. If distr_pad is False, all padding will be inserted after the existing values; otherwise it will be split evenly between before and after the existing values, with one extra value inserted after if the padding amount is not divisible by two.
- qonnx.util.basic.qonnx_make_model(graph_proto: GraphProto, **kwargs: object) ModelProto
Wrapper around ONNX make_model with preferred qonnx opset version
- qonnx.util.basic.random_string(stringLength: int = 6) str
Randomly generate a string of letters and digits.
- qonnx.util.basic.remove_by_name(container, name: str, name_field: str = 'name') None
Remove item from protobuf container by .name field if it exists.
- qonnx.util.basic.roundup_to_integer_multiple(x: int, factor: int) int
Round up integer x to the nearest integer multiple of integer factor. Returns x if factor is set to -1. Both x and factor must otherwise be positive.
- qonnx.util.basic.sanitize_quant_values(model: ModelWrapper, node_tensors: list[str], execution_context: dict[str, ndarray], check_values: bool = False) dict[str, ndarray]
Sanitize given list of tensors in execution_context by rounding values that are supposed to be integers (as indicated by their quantization annotation). Will raise an assertion if the amount of rounding is too large. Returns the sanitized execution context.
If check_values is specified, an extra DataType.allowed() check will be performed on any rounded tensors.
Background: QONNX uses floating point tensors as a carrier data type to represent integers. Floating point arithmetic can introduce rounding errors, e.g. (int_num * float_scale) / float_scale is not always equal to int_num. We use this function to ensure that the values that are supposed to be integers are indeed integers.
qonnx.util.cleanup
- qonnx.util.cleanup.cleanup(in_file, *, out_file=None, preserve_qnt_ops=True, override_inpsize: str | None = None, extract_conv_bias=False)
Execute a set of graph transformations to clean-up the given ONNX file.
- Parameters:
in_file – Filename for the input ONNX model
preserve_qnt_ops – Preserve weight quantization operators
out_file – If set, filename for the output ONNX model. Set to in_file with _clean suffix otherwise.
override_inpsize – If specified, override the input size (e.g. “(1,3,224,224)” to set all or just 1 to set batchsize to 1) for the ONNX graph
extract_conv_bias – If specified, separate Conv bias into its own Add node
- qonnx.util.cleanup.cleanup_model(model, preserve_qnt_ops=True, override_inpsize=None, extract_conv_bias=False)
Execute the transformations for the cleanup function on a model level. This allows the reuse of the cleanup transformations, without needing to read/write the model from/to disk.
- Parameters:
model – A raw QONNX model from as example Brevitas.
- Return model_clean:
The cleaned model
- qonnx.util.cleanup.main()
qonnx.util.config
- qonnx.util.config.extract_model_config_to_json(model, json_filename, attr_names_to_extract)
Create a json file with layer name -> attribute mappings extracted from the model.
qonnx.util.convert
- qonnx.util.convert.convert(input_model_file, *, output_style: functools.partial(<function _use_class at 0x77d7ab539000>, <class 'clize.parser.use_mixin.<locals>._PosWithMixin'>, <class 'clize.parser.use_mixin.<locals>._VarargsWithMixin'>, <class 'clize.parser.use_mixin.<locals>._NamedWithMixin'>, <function unimplemented_parameter at 0x77d7ab538b80>, {'case_sensitive': None, 'list_name': 'list', 'values': [('qcdq', ['qcdq', ]'Convert from Quant to QCDQ'), ('quant', ['quant', ]'Convert from QCDQ to Quant')]}), output_file: str | None = None)
Convert an ONNX file from one style of quantization to another, where possible. Please see the documentation on the QuantToQCDQ and QCDQToQuant transformations to learn more about the particular limitations.
- Parameters:
input_model_file – Filename for the input ONNX model.
output_style – Quantization style for the output.
output_file – If specified, write the output ONNX model to this filename. Otherwise, will default to the input file with an _output_style suffix.
- qonnx.util.convert.main()
qonnx.util.exec_qonnx
- qonnx.util.exec_qonnx.exec_qonnx(qonnx_model_file, *in_npy, override_batchsize: int | None = None, override_opset: int | None = None, expose_intermediates: str | None = None, output_prefix: str = 'out_', output_mode: functools.partial(<function _use_class at 0x77d7ab539000>, <class 'clize.parser.use_mixin.<locals>._PosWithMixin'>, <class 'clize.parser.use_mixin.<locals>._VarargsWithMixin'>, <class 'clize.parser.use_mixin.<locals>._NamedWithMixin'>, <function unimplemented_parameter at 0x77d7ab538b80>, {'case_sensitive': None, 'list_name': 'list', 'values': [('tensor_index', ['tensor_index', ]'Output files named by index'), ('tensor_name', ['tensor_name', ]'Output files named by tensor')]}) = 'tensor_name', argmax_verify_npy: str | None = None, save_modified_model: str | None = None, input_pix2float=False, input_zerocenter=False, maxiters: int | None = None, output_nosave=False)
Execute a given QONNX model by initializing its inputs from .npy files, and write outputs as .npy files. The input model have been previously cleaned by the cleanup transformation or commandline tool.
- Parameters:
qonnx_model_file – Filename for the input ONNX model
in_npy – List of .npy files to supply as inputs. If not specified, inputs will be set to zero.
override_batchsize – If specified, override the batch size for the ONNX graph
override_opset – If specified, override the imported ONNX opset to this version.
expose_intermediates – Comma-separated list of tensor name patterns. Matched patterns will expose intermediate outputs as top-level outputs.
output_prefix – Prefix for the generated output files.
output_mode – Naming mode for generated output files.
argmax_verify_npy – If specified, take argmax of output and compare to this file for top-1 accuracy measurement
save_modified_model – If specified, save the modified model (after batchsize changes or exposed intermediate tensors) with this filename
input_pix2float – If specified, do uint8 [0,255] -> fp32 [0,1] mapping for input
input_zerocenter – If specified together with pix2float, do uint8 [0,255] -> fp32 [-1,+1] mapping for input
maxiters – If specified, limit maximum number of iterations (batches) to be processed
output_nosave – If specified, do not save output tensors to files
- qonnx.util.exec_qonnx.main()
qonnx.util.inference_cost
- qonnx.util.inference_cost.assign_mem_bits_and_elems(res_dict)
- qonnx.util.inference_cost.compute_bops_and_macs(inf_cost_dict)
- qonnx.util.inference_cost.compute_mem_bits_and_elems(inf_cost_dict, filter_string='mem_w')
- qonnx.util.inference_cost.inference_cost(model_filename_or_wrapper, *, output_json=None, output_onnx=None, preprocess=True, discount_sparsity=True, cost_breakdown=False)
Return the inference cost estimate metric for given ONNX model. Supports the Quant op for weight/activation quantization.
- Parameters:
model_filename_or_wrapper – Filename or ModelWrapper for ONNX model
output_json – Optional JSON filename to save the inference cost dict
output_onnx – Optional ONNX filename to save the final model after any preprocessing
preprocess – If set, run preprocessing steps such as shape inference, datatype inference and constant folding. Strongly recommended.
discount_sparsity – If set, will discount op cost of MAC ops with a constant zero weight, and the mem cost of constant zero weights.
cost_breakdown – If set, include per-node (by name) and per-node-type breakdowns as part of the returned inference cost dict.
- qonnx.util.inference_cost.main()
qonnx.util.onnx
- qonnx.util.onnx.is_eltwise_monotonic_optype(optype)
Checks whether given ONNX optype is a monotonic elementwise op.
- qonnx.util.onnx.is_eltwise_optype(optype)
Checks whether given ONNX optype is an elementwise op.
- qonnx.util.onnx.nchw_to_nhwc(t, model, idx, reverse=False)
Converts between NCHW <-> NHWC layouts for tensor t by inserting a transpose. If reverse=False, t is assumed NCHW and we insert transpose to convert NCHW -> NHWC If reverse=True, t is assumed NHWC and we insert transpose to convert NHWC -> NCHW.
- qonnx.util.onnx.valueinfo_to_tensor(vi)
Creates an all-zeroes numpy tensor from a ValueInfoProto.
qonnx.util.prune_channels
- qonnx.util.prune_channels.main()
- qonnx.util.prune_channels.prune_channels(input_filename, prunespec_filename, *, lossy=True, output_filename='')
Prune channels from specified tensors and their dependencies from a model. The model must have already been cleaned up by qonnx-cleanup, including the –extract-conv-bias=True –preserve-qnt-ops=False options.
- Parameters:
input_filename – Filename for the input ONNX model
prunespec_filename – Filename for the pruning specification, formatted as a Python dict formatted as {tensor_name : {axis : {channels}}}. See test_pruning.py for examples.
lossy – Whether to perform lossy pruning, see the PruneChannels transformation for description.
output_filename – If specified, write the resulting pruned model to this filename. Otherwise, the input_filename will be used with a _pruned suffix.
qonnx.util.random_reseed
- qonnx.util.random_reseed.reseed(newseed)
qonnx.util.range_analysis
- qonnx.util.range_analysis.calc_conv_range(node, model, range_dict)
- qonnx.util.range_analysis.calc_convtranspose_range(node, model, range_dict)
- qonnx.util.range_analysis.calc_gemm_range(node, model, range_dict)
- qonnx.util.range_analysis.calc_matmul_range(node, model, range_dict)
- qonnx.util.range_analysis.calc_monotonic_range(node, model, range_dict, i_channel_axis=1)
- qonnx.util.range_analysis.calc_range_outdtype(node, model, range_dict)
- qonnx.util.range_analysis.calculate_matvec_accumulator_extremum(matrix: ndarray, vec_min, vec_max)
Calculate the minimum and maximum possible result (accumulator) values for a dot product A*x, given matrix A of dims (MH, MW), and vector (MW) with range (vec_min, vec_max). vec_min and vec_max are either scalars, or 1D arrays of length MW. Returns (acc_min, acc_max) where acc_min and acc_max are 1D arrays of length MH.
- qonnx.util.range_analysis.get_minmax_prototype_tensors(irange, ishp, inp_vi, i_channel_axis=1)
- qonnx.util.range_analysis.is_dyn_input(x, model)
- qonnx.util.range_analysis.main()
- qonnx.util.range_analysis.range_analysis(model_filename_or_wrapper, *, irange='', key_filter: str = '', report_mode: functools.partial(<function _use_class at 0x77d7ab539000>, <class 'clize.parser.use_mixin.<locals>._PosWithMixin'>, <class 'clize.parser.use_mixin.<locals>._VarargsWithMixin'>, <class 'clize.parser.use_mixin.<locals>._NamedWithMixin'>, <function unimplemented_parameter at 0x77d7ab538b80>, {'case_sensitive': None, 'list_name': 'list', 'values': [('range', ['range', ]'Report ranges'), ('stuck_channel', ['stuck_channel', ]'Report stuck channels'), ('zerostuck_channel', ['zerostuck_channel', ]'Report 0-stuck channels')]}) = 'stuck_channel', prettyprint=False, do_cleanup=False)
- qonnx.util.range_analysis.simplify_range(range)
Where possible, simplify a range that is expressed as channelwise ranges back to a scalar range if all channels’ ranges were equal.
qonnx.util.test
- qonnx.util.test.download_model(test_model: functools.partial(<function _use_class at 0x77d7ab539000>, <class 'clize.parser.use_mixin.<locals>._PosWithMixin'>, <class 'clize.parser.use_mixin.<locals>._VarargsWithMixin'>, <class 'clize.parser.use_mixin.<locals>._NamedWithMixin'>, <function unimplemented_parameter at 0x77d7ab538b80>, {'case_sensitive': None, 'list_name': 'list', 'values': [('FINN-CNV_W2A2', ['FINN-CNV_W2A2', ]'2-bit VGG-10-like CNN on CIFAR-10'), ('FINN-CNV_W1A2', ['FINN-CNV_W1A2', ]'1/2-bit VGG-10-like CNN on CIFAR-10'), ('FINN-CNV_W1A1', ['FINN-CNV_W1A1', ]'1-bit VGG-10-like CNN on CIFAR-10'), ('FINN-TFC_W1A1', ['FINN-TFC_W1A1', ]'1-bit tiny MLP on MNIST'), ('FINN-TFC_W1A2', ['FINN-TFC_W1A2', ]'1/2-bit tiny MLP on MNIST'), ('FINN-TFC_W2A2', ['FINN-TFC_W2A2', ]'2-bit tiny MLP on MNIST'), ('RadioML_VGG10', ['RadioML_VGG10', ]'8-bit VGG-10-like CNN on RadioML 2018'), ('Conv_bias_example', ['Conv_bias_example', ]''), ('MobileNetv1-w4a4', ['MobileNetv1-w4a4', ]'4-bit MobileNet-v1 on ImageNet'), ('rn18_w4a4_a2q_16b', ['rn18_w4a4_a2q_16b', ]'4-bit ResNet-18 on CIFAR-10, A2Q 16-bit accumulators'), ('rn18_w4a4_a2q_15b', ['rn18_w4a4_a2q_15b', ]'4-bit ResNet-18 on CIFAR-10, A2Q 15-bit accumulators'), ('rn18_w4a4_a2q_14b', ['rn18_w4a4_a2q_14b', ]'4-bit ResNet-18 on CIFAR-10, A2Q 14-bit accumulators'), ('rn18_w4a4_a2q_13b', ['rn18_w4a4_a2q_13b', ]'4-bit ResNet-18 on CIFAR-10, A2Q 13-bit accumulators'), ('rn18_w4a4_a2q_12b', ['rn18_w4a4_a2q_12b', ]'4-bit ResNet-18 on CIFAR-10, A2Q 12-bit accumulators'), ('rn18_w4a4_a2q_plus_16b', ['rn18_w4a4_a2q_plus_16b', ]'4-bit ResNet-18 on CIFAR-10, A2Q+ 16-bit accumulators'), ('rn18_w4a4_a2q_plus_15b', ['rn18_w4a4_a2q_plus_15b', ]'4-bit ResNet-18 on CIFAR-10, A2Q+ 15-bit accumulators'), ('rn18_w4a4_a2q_plus_14b', ['rn18_w4a4_a2q_plus_14b', ]'4-bit ResNet-18 on CIFAR-10, A2Q+ 14-bit accumulators'), ('rn18_w4a4_a2q_plus_13b', ['rn18_w4a4_a2q_plus_13b', ]'4-bit ResNet-18 on CIFAR-10, A2Q+ 13-bit accumulators'), ('rn18_w4a4_a2q_plus_12b', ['rn18_w4a4_a2q_plus_12b', ]'4-bit ResNet-18 on CIFAR-10, A2Q+ 12-bit accumulators')]}), *, dl_dir='/tmp', do_cleanup=False, return_modelwrapper=False)
- qonnx.util.test.get_golden_in_and_output(test_model, seed=42)
- qonnx.util.test.get_random_input(test_model, seed=42)
- qonnx.util.test.qonnx_download_model()
qonnx.util.to_channels_last
- qonnx.util.to_channels_last.main()
- qonnx.util.to_channels_last.to_channels_last(in_file, *, make_input_channels_last=False, out_file=None)
Execute a set of graph transformations to convert an ONNX file to the channels last data format. The input file have been previously cleaned by the cleanup transformation or commandline tool.
- Parameters:
in_file – Filename for the input ONNX model
make_input_channels_last – Sets if the input of the model should also be converted to the channels last data layout (True) or if a transpose node should be left at the beginning of the graph (False). Defaults to False.
out_file – If set, filename for the output ONNX model. Set to in_file with _chan_last suffix otherwise.
finn.util.basic
- class finn.util.basic.CppBuilder
Bases:
objectBuilds the g++ compiler command to produces the executable of the c++ code in code_gen_dir which is passed to the function build() of this class.
- append_includes(library_path)
Adds given library path to include_paths list.
- append_sources(cpp_file)
Adds given c++ file to cpp_files list.
- build(code_gen_dir)
Builds the g++ compiler command according to entries in include_paths and cpp_files lists. Saves it in bash script in given folder and executes it.
- set_executable_path(path)
Sets member variable “executable_path” to given path.
- finn.util.basic.get_driver_shapes(model: ModelWrapper) Dict
- finn.util.basic.get_dsp_block(fpgapart)
- finn.util.basic.get_finn_root()
Return the root directory that FINN is cloned into.
- finn.util.basic.get_liveness_threshold_cycles()
Return the number of no-output cycles rtlsim will wait before assuming the simulation is not finishing and throwing an exception.
- finn.util.basic.get_memutil_alternatives(req_mem_spec, mem_primitives={'BRAM18_18x1024': (18, 1024), 'BRAM18_36x512': (36, 512), 'BRAM18_9x2048': (9, 2048), 'LUTRAM': (1, 64), 'URAM_18x16384': (18, 16384), 'URAM_36x8192': (36, 8192), 'URAM_72x4096': (72, 4096), 'URAM_9x32768': (9, 32768)}, sort_min_waste=True)
Computes how many instances of a memory primitive are necessary to implement a desired memory size, where req_mem_spec is the desired size and the primitive_spec is the primitve size. The sizes are expressed as tuples of (mem_width, mem_depth). Returns a list of tuples of the form (primitive_name, (primitive_count, efficiency, waste)) where efficiency in range [0,1] indicates how much of the total capacity is utilized, and waste indicates how many bits of storage are wasted. If sort_min_waste is True, the list is sorted by increasing waste.
- finn.util.basic.get_rtlsim_trace_depth()
Return the trace depth for rtlsim. Controllable via the RTLSIM_TRACE_DEPTH environment variable. If the env.var. is undefined, the default value of 1 is returned. A trace depth of 1 will only show top-level signals and yield smaller .vcd files.
The following depth values are of interest for whole-network stitched IP rtlsim: - level 1 shows top-level input/output streams - level 2 shows per-layer input/output streams - level 3 shows per full-layer I/O including FIFO count signals
- finn.util.basic.get_vivado_root()
Return the root directory that Vivado is installed into.
- finn.util.basic.get_vivado_version() Tuple[int, int] | None
Extract Vivado version as (year, minor) tuple from XILINX_VIVADO.
- finn.util.basic.is_versal(fpgapart)
Returns whether board is part of the Versal family
- finn.util.basic.launch_process_helper(args, proc_env=None, cwd=None, check=False)
Launch a process and capture its output for logging with Python loggers.
Returns
(cmd_out, cmd_err)as UTF-8 strings, with undecodable bytes in tool output replaced rather than raised. Both streams are also written through tosys.stdout/sys.stderr.When
checkis True and the process exits non-zero, raisessubprocess.CalledProcessErrorwithoutputandstderrset to the captured strings. The write-through happens before the raise, so the tool log is still visible on failure. That is why the return code is checked by hand rather than relying onsubprocess.run(check=True).
- finn.util.basic.make_build_dir(prefix='')
Creates a folder with given prefix to be used as a build dir. Use this function instead of tempfile.mkdtemp to ensure any generated files will survive on the host after the FINN Docker container exits.
- finn.util.basic.memutil(req_mem_spec, primitive_spec)
Computes how many instances of a memory primitive are necessary to implemented a desired memory size, where req_mem_spec is the desired size and the primitive_spec is the primitve size. The sizes are expressed as tuples of (mem_width, mem_depth). Returns (primitive_count, efficiency, waste) where efficiency in range [0,1] indicates how much of the total capacity is utilized, and waste indicates how many bits of storage are wasted.
- finn.util.basic.resolve_xilinx_tool(tool_name)
Resolve the command used to invoke a Xilinx tool. Update the following list if new tools use this resolver.
Default names: - vivado - vitis_hls - vitis-run - v++ - xelab - slashkit
With FINN_TOOL_DIR_OVERRIDE set, the command resolves to <override>/<tool_name>, otherwise the bare tool_name is used. The single directory override is all a tool-wrapping site (e.g. an LSF bsub dispatcher) needs: point it at a shim dir whose filenames match the bare tool names. Raises FileNotFoundError when the resolved command is not found, so all the default names must have a corresponding shim filename.
- finn.util.basic.robust_rmtree(path, retries=6, initial_delay=0.1, backoff=2.0)
Remove a directory tree with retries for transient NFS cleanup races. Retries
ENOTEMPTY/EBUSY. Other errors propagate immediately.
- finn.util.basic.which(program)
Python equivalent of the shell cmd ‘which’.
finn.util.create
- finn.util.create.adjacency_list(model, filter_function)
Returns adjacency list of nodes based on filter function.
- finn.util.create.hls_mlp_maker(layer_spec)
Create an MLP of given specification using HLSCustomOp instances.
- finn.util.create.hls_random_mlp_maker(layer_spec)
Create an MLP of given specification using HLSCustomOp instances. Generate random weights/thresholds of appropriate size.
finn.util.data_packing
- finn.util.data_packing.array2hexstring(array, dtype, pad_to_nbits, prefix='0x', reverse=False)
Pack given one-dimensional NumPy array with FINN DataType dtype into a hex string. Any BIPOLAR values will be converted to a single bit with a 0 representing -1. pad_to_nbits is used to prepend leading zeros to ensure packed strings of fixed width. The minimum value for pad_to_nbits is 4, since a single hex digit is four bits. reverse can be used to reverse the array prior to packing.
Examples:
array2hexstring([1, 1, 1, 0], DataType[“BINARY”], 4) = “0xe”
array2hexstring([1, 1, 1, 0], DataType[“BINARY”], 8) = “0x0e”
array2hexstring([1, 1, 0, 1], DataType[“BINARY”], 4, reverse=True) = “0xb”
array2hexstring([1, 1, 1, 0], DataType[“BINARY”], 8, reverse=True) = “0x07”
- finn.util.data_packing.data_prepared_to_finnpy_bipolar(data_prepared)
- finn.util.data_packing.data_prepared_to_finnpy_fixed(data_prepared, dtype)
- finn.util.data_packing.data_prepared_to_finnpy_int(data_prepared, dtype)
- finn.util.data_packing.data_prepared_to_finnpy_ternary(data_prepared)
- finn.util.data_packing.finnpy_to_int_array(ndarray, dtype)
Encode a float32 container ndarray into an unsigned-integer ndarray whose values are the target_bits-wide bit pattern of each element. Container is the smallest uint that fits target_bits.
- finn.util.data_packing.finnpy_to_packed_bytearray(ndarray, dtype, reverse_inner=False, reverse_endian=False)
Given a numpy ndarray with FINN DataType dtype, pack the innermost dimension and return the packed representation as an ndarray of uint8. The packed innermost dimension will be padded to the nearest multiple of 8 bits. The returned ndarray has the same number of dimensions as the input.
Three packing paths are tried in order: * whole-byte dtypes in a matching native container -> byte views/flips only * 1-bit dtypes with no padding and both reverses -> direct np.packbits * everything else -> general bit-level packing
Can return a non-contiguous ndarray. Use np.ascontiguousarray or np.copy to make it contiguous.
- finn.util.data_packing.hexstring2npbytearray(hexstring, remove_prefix='0x')
Convert a hex string into a NumPy array of dtype uint8.
Example:
hexstring2npbytearray(“0f01”) = array([15, 1], dtype=uint8)
- finn.util.data_packing.int_array_to_packed_bytearray(int_array, target_bits)
Pack the innermost dimension of an unsigned-integer ndarray into uint8 bytes, MSB-first with value 0 occupying the most significant bits and the word left-padded to the nearest multiple of 8 bits.
- finn.util.data_packing.npbytearray2hexstring(npbytearray, prefix='0x')
Convert a NumPy array of uint8 dtype into a hex string.
Example:
npbytearray2hexstring(array([15, 1], dtype=uint8)) = “0x0f01”
- finn.util.data_packing.npy_to_rtlsim_input(input_file, input_dtype, pad_to_nbits, reverse_inner=True)
Convert the multidimensional NumPy array of integers (stored as floats) from input_file into a flattened sequence of Python arbitrary-precision integers, packing the innermost dimension. See finn.util.basic.pack_innermost_dim_as_hex_string() for more info on how the packing works. If reverse_inner is set, the innermost dimension will be reversed prior to packing.
- finn.util.data_packing.numpy_to_hls_code(ndarray, dtype, hls_var_name, pack_innermost_dim=True, no_decl=False)
Return C++ code representation of a numpy ndarray with FINN DataType dtype, using hls_var_name as the resulting C++ variable name. If pack_innermost_dim is specified, the innermost dimension of the ndarray will be packed into a hex string using array2hexstring. If no_decl is set to True, no variable name and type will be generated as part of the emitted string.
- finn.util.data_packing.pack_innermost_dim_as_hex_string(ndarray, dtype, pad_to_nbits, reverse_inner=False, prefix='0x')
Pack the innermost dimension of the given numpy ndarray into hex strings using array2hexstring.
Examples:
A = [[1, 1, 1, 0], [0, 1, 1, 0]]
eA = [“0e”, “06”]
pack_innermost_dim_as_hex_string(A, DataType[“BINARY”], 8) == eA
B = [[[3, 3], [3, 3]], [[1, 3], [3, 1]]]
eB = [[ “0f”, “0f”], [“07”, “0d”]]
pack_innermost_dim_as_hex_string(B, DataType[“UINT2”], 8) == eB
- finn.util.data_packing.packed_bytearray_to_finnpy(packed_bytearray, dtype, output_shape, reverse_inner=False, reverse_endian=False)
Given a packed numpy uint8 ndarray, unpack it into a FINN array of given DataType.
output_shape must be specified to remove padding from the packed dimension
- finn.util.data_packing.packed_bytearray_to_finnpy_fast(packed_bytearray, dtype, output_shape)
- finn.util.data_packing.packed_bytearray_to_finnpy_float(packed_bytearray, dtype, reverse_inner=False, reverse_endian=False)
- finn.util.data_packing.prepare_values(packed_bytearray, dtype, output_shape, reverse_inner, reverse_endian)
- finn.util.data_packing.rtlsim_output_to_npy(output, path, dtype, shape, packedBits, targetBits, reverse_inner=True)
Convert a flattened sequence of Python arbitrary-precision integers output into a NumPy array, saved as npy file at path. Each arbitrary-precision integer is assumed to be a packed array of targetBits-bit elements, which will be unpacked as the innermost dimension of the NumPy array. If path is not None it will also be saved as a npy file.
- finn.util.data_packing.to_external_tensor(init, w_dtype)
Return an appropriately formatted and packed numpy byte array for given external parameter tensor.
- finn.util.data_packing.unpack_innermost_dim_from_hex_string(ndarray, dtype, out_shape, packedBits, reverse_inner=False)
Convert a NumPy array of hex strings into a FINN NumPy array by unpacking the hex strings into the specified data type. out_shape can be specified such that any padding in the packing dimension is removed. If reverse_inner is set, the innermost unpacked dimension will be reversed.
- finn.util.data_packing.unsiged_array_to_signed(data_array, bitsize)
finn.util.fpgadataflow
- finn.util.fpgadataflow.detect_hls_rtl_dsp_conflict(model, check_subgraphs=True)
Detect if model contains both floating-point HLS ops and RTL LayerNorm.
This combination causes incorrect simulation results in xsim due to DSP primitive initialization conflicts. The hardware is correct - only simulation is affected.
HLS ops that use floating-point and trigger the conflict: - HLS Elementwise ops with FLOAT32 datatypes - HWSoftmax_hls (uses hls::exp) - LayerNorm_hls (uses hls::rsqrt) - Requant_hls with FLOAT32 input
- Args:
model: ModelWrapper to check check_subgraphs: If True, also check inside FINNLoop bodies
- Returns:
Tuple of (has_conflict, hls_fp_ops, rtl_dsp_ops) - has_conflict: bool, True if both types of ops are present - hls_fp_ops: list of floating-point HLS node names - rtl_dsp_ops: list of RTL LayerNorm node names
- finn.util.fpgadataflow.is_fpgadataflow_node(node)
Returns True if given node is fpgadataflow node. Otherwise False.
- finn.util.fpgadataflow.is_hls_node(node)
Returns True if given node is hls node. Otherwise False.
- finn.util.fpgadataflow.is_mlo(model: ModelWrapper) bool
Returns True if the model is an MLO model (contains FINNLoop), False otherwise.
- finn.util.fpgadataflow.is_rtl_node(node)
Returns True if given node is rtl node. Otherwise False.
- finn.util.fpgadataflow.warn_hls_rtl_dsp_conflict(model, verification_type, output_dir=None)
Check for HLS+RTL DSP conflict and issue warning if detected.
This is used to warn users before running rtlsim verification when the model contains both HLS floating-point ops and RTL LayerNorm. This combination causes incorrect simulation results in xsim due to conflicting DSP primitive initializations.
- Args:
model: ModelWrapper to check. verification_type: String describing the verification type. output_dir: Optional directory for verification outputs (writes warning file if provided).
- Returns:
bool: True if conflict was detected (and verification should be skipped)
finn.util.hls
- class finn.util.hls.CallHLS
Bases:
objectCall vitis_hls to run HLS build tcl scripts.
- append_tcl(tcl_script)
Sets the tcl script to be executed.
- build(code_gen_dir)
Builds the bash script with given parameters and saves it in given folder. To guarantee the generation in the correct folder the bash script contains a cd command.
- set_ipgen_path(path)
Sets member variable ipgen_path to given path.
finn.util.imagenet
finn.util.platforms
- class finn.util.platforms.Alveo_NxU200_Platform(ndevices=1, limits=array([0.7, 0.5, 0.8, 0.8, 0.8]), avg_constraints=[((2, 3, 4), 0.7)])
Bases:
Platform- property compute_resources
- class finn.util.platforms.Alveo_NxU250_Platform(ndevices=1, limits=array([0.7, 0.5, 0.8, 0.8, 0.8]), avg_constraints=[((2, 3, 4), 0.7)])
Bases:
Platform- property compute_resources
- class finn.util.platforms.Alveo_NxU280_Platform(ndevices=1, limits=array([0.7, 0.5, 0.8, 0.8, 0.8]), avg_constraints=[((2, 3, 4), 0.7)])
Bases:
Platform- property compute_resources
- class finn.util.platforms.Alveo_NxU50_Platform(ndevices=1, limits=array([0.7, 0.5, 0.8, 0.8, 0.8]), avg_constraints=[((2, 3, 4), 0.7)])
Bases:
Platform- property compute_resources
- class finn.util.platforms.Alveo_NxU55C_Platform(ndevices=1, limits=array([0.7, 0.5, 0.8, 0.8, 0.8]), avg_constraints=[((2, 3, 4), 0.7)])
Bases:
Platform- property compute_resources
- class finn.util.platforms.Platform(nslr=1, ndevices=1, sll_count=[], hbm_slr=-1, ddr_slr=[0], eth_slr=0, eth_gbps=0, limits=array([0.7, 0.5, 0.8, 0.8, 0.8]), avg_constraints=[((2, 3, 4), 0.7)])
Bases:
object- property compute_connection_cost
- property compute_connection_resource
- abstract property compute_resources
- property guide_resources
- map_device_to_slr(idx)
Given a global SLR index, return device id and local slr index
- property resource_count_dict
- class finn.util.platforms.ZU28DR_Platform(ndevices=1, limits=array([0.7, 0.5, 0.8, 0.8, 0.8]), avg_constraints=[((2, 3, 4), 0.7)])
Bases:
Platform- property compute_resources
- class finn.util.platforms.ZU3EG_Platform(ndevices=1, limits=array([0.7, 0.5, 0.8, 0.8, 0.8]), avg_constraints=[((2, 3, 4), 0.7)])
Bases:
Platform- property compute_resources
- class finn.util.platforms.ZU7EV_Platform(ndevices=1, limits=array([0.7, 0.5, 0.8, 0.8, 0.8]), avg_constraints=[((2, 3, 4), 0.7)])
Bases:
Platform- property compute_resources
finn.util.pytorch
- class finn.util.pytorch.Normalize(mean, std, channels)
Bases:
Module- forward(x)
Define the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Moduleinstance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- class finn.util.pytorch.NormalizePreProc(mean, std, channels)
Bases:
Module- forward(x)
Define the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Moduleinstance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- class finn.util.pytorch.ToTensor
Bases:
Module- forward(x)
Define the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Moduleinstance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
finn.util.test
finn.util.visualization
- finn.util.visualization.showInNetron(model_filename: str, localhost_url: str | None = None, port: int | None = None)
Shows a ONNX model file in the Jupyter Notebook using Netron.
- Parameters:
model_filename (str) – The path to the ONNX model file.
localhost_url (str, optional) – The IP address used by the Jupyter IFrame to show the model. Defaults to localhost or LOCALHOST_URL environment variable.
port (int, optional) – The port number used by Netron and the Jupyter IFrame to show the ONNX model. Defaults to NETRON_PORT environment variable or 8081.
- Returns:
The IFrame displaying the ONNX model.
- Return type:
IPython.lib.display.IFrame
- finn.util.visualization.showSrc(what)
finn.util.rtlsim
finn.util.vivado
- finn.util.vivado.parse_ooc_synth_results(report_dir)
Parse OOC synthesis results from Vivado report files.
This function parses the utilization, timing, and power reports generated by CreateStitchedIP with run_pnr=True. The reports are in Vivado’s native text format, which is parsed on the Python side for better maintainability.
- Args:
- report_dir: Path to the directory containing the OOC report files
(ooc_utilization.rpt, ooc_timing.rpt, ooc_power.rpt, ooc_metadata.txt)
- Returns:
Dictionary with resource utilization, timing, and power metrics including calculated fmax_mhz, or None if the report files don’t exist.