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 0x7f233e3f01f0>, <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 0x7f233e3e7d00>, {'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 0x7f233e3f01f0>, <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 0x7f233e3e7d00>, {'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.mlo_sim
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.onnxscript_helpers
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 0x7f233e3f01f0>, <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 0x7f233e3e7d00>, {'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 0x7f233e3f01f0>, <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 0x7f233e3e7d00>, {'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
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_packed_bytearray(ndarray, dtype, reverse_inner=False, reverse_endian=False, fast_mode=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.
If fast_mode is enabled, will attempt to use shortcuts to save on runtime for certain cases: * 8-bit ndarray -> 8-bit * ndarray -> 1-bit and total bits % 8 == 0 This mode is currently not well-tested, use at your own risk!
- 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.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 Elementwise 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.
Note: Only HLS Elementwise ops using floating-point datatypes are flagged, as integer-only HLS Elementwise ops don’t use DSP primitives.
- Args:
model: ModelWrapper to check check_subgraphs: If True, also check inside FINNLoop bodies
- Returns:
Tuple of (has_conflict, hls_elementwise_ops, rtl_dsp_ops) - has_conflict: bool, True if both types of ops are present - hls_elementwise_ops: list of floating-point HLS Elementwise 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_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 Elementwise ops and RTL ops that use DSPFP32. 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: Directory where verification outputs would be saved (optional)
If provided, writes warning to a .txt file there
- 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.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.