diff --git a/src/finn/builder/build_dataflow.py b/src/finn/builder/build_dataflow.py index c4664a5471984e1f88a70f1d9bb6ce674e38c782..68733e59ba49a5e0e1b553e8e40d3e18ac3fc645 100644 --- a/src/finn/builder/build_dataflow.py +++ b/src/finn/builder/build_dataflow.py @@ -34,6 +34,7 @@ import pdb # NOQA import sys import time import traceback +from copy import deepcopy from finn.builder.build_dataflow_config import ( DataflowBuildConfig, @@ -66,6 +67,9 @@ def resolve_build_steps(cfg: DataflowBuildConfig, partial: bool = True): steps = cfg.steps if steps is None: steps = default_build_dataflow_steps + if cfg.expect_QONNX_as_input: + steps = deepcopy(steps) + steps.insert(0, "step_qonnx_to_finn") steps_as_fxns = [] for transform_step in steps: if type(transform_step) is str: diff --git a/src/finn/builder/build_dataflow_config.py b/src/finn/builder/build_dataflow_config.py index 052a6c701a639929f9c2dff682c2a8777b679788..ca1a108d2b74e66f380735c1ad7280046215709f 100644 --- a/src/finn/builder/build_dataflow_config.py +++ b/src/finn/builder/build_dataflow_config.py @@ -291,6 +291,11 @@ class DataflowBuildConfig: #: If given, stop at this step. stop_step: Optional[str] = None + #: If set to True, the dataflow builder will assume that the input ONNX file is + #: in the QONNX dialect. FINN will then try to convert the input to the + #: FINN-ONNX dialect. + expect_QONNX_as_input: Optional[bool] = False + def _resolve_hls_clk_period(self): if self.hls_clk_period_ns is None: # use same clk for synth and hls if not explicitly specified diff --git a/src/finn/builder/build_dataflow_steps.py b/src/finn/builder/build_dataflow_steps.py index b9c065ed2514cbbf9f92391ce496705aa3d4a822..9af273163d74dfe9a29008ee58e1ab5536791e9c 100644 --- a/src/finn/builder/build_dataflow_steps.py +++ b/src/finn/builder/build_dataflow_steps.py @@ -31,6 +31,7 @@ import numpy as np import os from copy import deepcopy from distutils.dir_util import copy_tree +from qonnx.util.cleanup import cleanup_model from shutil import copy import finn.transformation.fpgadataflow.convert_to_hls_layers as to_hls @@ -94,6 +95,7 @@ from finn.transformation.infer_datatypes import InferDataTypes from finn.transformation.infer_shapes import InferShapes from finn.transformation.lower_convs_to_matmul import LowerConvsToMatMul from finn.transformation.move_reshape import RemoveCNVtoFCFlatten +from finn.transformation.qonnx.convert_qonnx_to_finn import ConvertQONNXtoFINN from finn.transformation.streamline import Streamline from finn.transformation.streamline.reorder import MakeMaxPoolNHWC from finn.util.config import extract_model_config_to_json @@ -187,6 +189,22 @@ def prepare_for_stitched_ip_rtlsim(verify_model, cfg): return verify_model +def step_qonnx_to_finn(model: ModelWrapper, cfg: DataflowBuildConfig): + """ + This runs the tidy-up step from QONNX and then converts the QONNX model + to the FINN-ONNX dialect. + """ + # QONNX cleanup + model = cleanup_model(model) + # QONNX to FINN-ONNX + model = model.transform(ConvertQONNXtoFINN()) + + if VerificationStepType.TIDY_UP_PYTHON in cfg._resolve_verification_steps(): + verify_step(model, cfg, "initial_python", need_parent=False) + + return model + + def step_tidy_up(model: ModelWrapper, cfg: DataflowBuildConfig): """Run the tidy-up step on given model. This includes shape and datatype inference, constant folding, and giving nodes and tensors better names. @@ -618,6 +636,7 @@ def step_deployment_package(model: ModelWrapper, cfg: DataflowBuildConfig): #: map step name strings to step functions build_dataflow_step_lookup = { + "step_qonnx_to_finn": step_qonnx_to_finn, "step_tidy_up": step_tidy_up, "step_streamline": step_streamline, "step_convert_to_hls": step_convert_to_hls,