示例#1
0
def test_end2end_ext_weights_build():
    model_file = get_checkpoint_name("download")
    load_test_checkpoint_or_skip(model_file)
    build_env = get_build_env(build_kind, target_clk_ns)
    folding_config_file = pk.resource_filename(
        "finn.qnn-data", "test_ext_weights/tfc-w1a1-extw.json")
    output_dir = make_build_dir("test_end2end_ext_weights_build")
    cfg = build.DataflowBuildConfig(
        output_dir=output_dir,
        folding_config_file=folding_config_file,
        synth_clk_period_ns=target_clk_ns,
        board=build_env["board"],
        shell_flow_type=build_cfg.ShellFlowType.VIVADO_ZYNQ,
        generate_outputs=[
            build_cfg.DataflowOutputType.ESTIMATE_REPORTS,
            build_cfg.DataflowOutputType.BITFILE,
            build_cfg.DataflowOutputType.PYNQ_DRIVER,
            build_cfg.DataflowOutputType.DEPLOYMENT_PACKAGE,
        ],
    )
    build.build_dataflow_cfg(model_file, cfg)
    assert os.path.isfile(output_dir + "/deploy/bitfile/finn-accel.bit")
    assert os.path.isfile(output_dir + "/deploy/bitfile/finn-accel.hwh")
    assert os.path.isfile(output_dir + "/deploy/driver/driver.py")
    assert os.path.isfile(output_dir +
                          "/deploy/driver/runtime_weights/idma0.npy")
    if os.path.isdir(get_checkpoint_name("build")):
        shutil.rmtree(get_checkpoint_name("build"))
    shutil.copytree(output_dir + "/deploy", get_checkpoint_name("build"))
示例#2
0
def test_end2end_mobilenet_create_dataflow_partition():
    model = load_test_checkpoint_or_skip(build_dir + "/end2end_mobilenet_folded.onnx")
    parent_model = model.transform(CreateDataflowPartition())
    parent_model.save(build_dir + "/end2end_mobilenet_dataflow_parent.onnx")
    sdp_node = parent_model.get_nodes_by_op_type("StreamingDataflowPartition")[0]
    sdp_node = getCustomOp(sdp_node)
    dataflow_model_filename = sdp_node.get_nodeattr("model")
    dataflow_model = load_test_checkpoint_or_skip(dataflow_model_filename)
    dataflow_model = dataflow_model.transform(RemoveUnusedTensors())
    dataflow_model.save(build_dir + "/end2end_mobilenet_dataflow_model.onnx")
示例#3
0
 def test_fold(self, topology, wbits, abits):
     prev_chkpt_name = get_checkpoint_name(topology, wbits, abits,
                                           "dataflow_model")
     model = load_test_checkpoint_or_skip(prev_chkpt_name)
     folding_fxn = get_folding_function(topology, wbits, abits)
     model = folding_fxn(model)
     model.save(get_checkpoint_name(topology, wbits, abits, "fold"))
示例#4
0
 def test_create_dataflow_partition(self, topology, wbits, abits):
     prev_chkpt_name = get_checkpoint_name(topology, wbits, abits,
                                           "convert_to_hls_layers")
     model = load_test_checkpoint_or_skip(prev_chkpt_name)
     parent_model = model.transform(CreateDataflowPartition())
     parent_model_chkpt = get_checkpoint_name(topology, wbits, abits,
                                              "dataflow_parent")
     parent_model.save(parent_model_chkpt)
     sdp_node = parent_model.get_nodes_by_op_type(
         "StreamingDataflowPartition")[0]
     sdp_node = getCustomOp(sdp_node)
     dataflow_model_filename = sdp_node.get_nodeattr("model")
     dataflow_model = load_test_checkpoint_or_skip(dataflow_model_filename)
     dataflow_model_chkpt = get_checkpoint_name(topology, wbits, abits,
                                                "dataflow_model")
     dataflow_model.save(dataflow_model_chkpt)
示例#5
0
 def test_convert_to_hls_layers(self, topology, wbits, abits):
     prev_chkpt_name = get_checkpoint_name(topology, wbits, abits,
                                           "streamline")
     model = load_test_checkpoint_or_skip(prev_chkpt_name)
     if topology == "tfc" and wbits == 1 and abits == 1:
         # use standalone thresholds for tfc-w1a1 to also exercise that option
         model = model.transform(to_hls.InferThresholdingLayer())
     # needed for bipolar MatMul layers
     model = model.transform(to_hls.InferBinaryStreamingFCLayer(mem_mode))
     # needed for non-bipolar MatMul layers
     model = model.transform(
         to_hls.InferQuantizedStreamingFCLayer(mem_mode))
     # TopK to LabelSelect
     model = model.transform(to_hls.InferLabelSelectLayer())
     # input quantization (if any) to standalone thresholding
     model = model.transform(to_hls.InferThresholdingLayer())
     # needed for convolutions
     if "fc" not in topology:
         model = model.transform(to_hls.InferConvInpGen())
         model = model.transform(to_hls.InferStreamingMaxPool())
         model = model.transform(RemoveCNVtoFCFlatten())
     # get rid of Tranpose -> Tranpose identity seq
     model = model.transform(absorb.AbsorbConsecutiveTransposes())
     model = model.transform(GiveUniqueNodeNames())
     model = model.transform(InferDataLayouts())
     model.save(
         get_checkpoint_name(topology, wbits, abits,
                             "convert_to_hls_layers"))
示例#6
0
def test_end2end_mobilenet_cppsim():
    model = load_test_checkpoint_or_skip(build_dir +
                                         "/end2end_mobilenet_folded.onnx")
    x = np.load(build_dir + "/end2end_mobilenet_input.npy")
    inp_name = model.graph.input[0].name
    out_name = model.graph.output[0].name
    inp_dict = {inp_name: x}
    start = time.time()
    # cppsim
    model = model.transform(PrepareCppSim())
    model = model.transform(CompileCppSim())
    model = model.transform(SetExecMode("cppsim"))
    end = time.time()
    elapsed_time = end - start
    f = open(build_dir + "/end2end_mobilenet_compile_time.txt", "w+")
    f.write("Execution time in seconds: " + str(elapsed_time))
    f.close()
    model.save(build_dir + "/end2end_mobilenet_cppsim.onnx")
    ret_cppsim = execute_onnx(model, inp_dict, True)
    res_cppsim = ret_cppsim[out_name]
    np.save(build_dir + "/end2end_mobilenet_result_cppsim.npy", res_cppsim)
    a0 = np.load(build_dir + "/end2end_mobilenet_topk_scale.npy")
    res_cppsim_prob = ret_cppsim[model.graph.node[-2].output[0]] * a0
    np.save(build_dir + "/end2end_mobilenet_result_cppsim_prob.npy",
            res_cppsim_prob)

    # check result with golden values
    golden = np.load(build_dir + "/end2end_mobilenet_golden_top5.npy")
    golden_prob = np.load(build_dir +
                          "/end2end_mobilenet_golden_top5_prob.npy")

    assert (golden == res_cppsim).all()
    assert np.isclose(golden_prob, res_cppsim_prob).all()
示例#7
0
def test_set_folding(target_fps, platform):

    model = make_multi_fclayer_model(128, DataType.INT4, DataType.INT2,
                                     DataType.INT16, 5)

    model = model.transform(GiveUniqueNodeNames())
    parent_model = model.transform(CreateDataflowPartition())
    sdp_node = parent_model.get_nodes_by_op_type(
        "StreamingDataflowPartition")[0]
    sdp_node = getCustomOp(sdp_node)
    dataflow_model_filename = sdp_node.get_nodeattr("model")
    dataflow_model = load_test_checkpoint_or_skip(dataflow_model_filename)

    clk_ns = 5
    target_cycles_per_frame = int((10**9 / clk_ns) / target_fps)
    dataflow_model = dataflow_model.transform(
        SetFolding(target_cycles_per_frame))

    exp_cycles_dict = dataflow_model.analysis(exp_cycles_per_layer)
    achieved_cycles_per_frame = max(exp_cycles_dict.values())

    min_cycles = dict()
    min_cycles["Pynq-Z1"] = 128
    min_cycles["Ultra96"] = 64
    min_cycles["U200"] = 1

    assert achieved_cycles_per_frame <= max(
        min_cycles[platform],
        target_cycles_per_frame), "Folding target not met"
示例#8
0
def test_end2end_mobilenet_folding():
    model = load_test_checkpoint_or_skip(build_dir +
                                         "/end2end_mobilenet_hls_layers.onnx")
    # optional extra folding to use fewer resources
    # applied while setting the attributes on each node
    assert extra_fold in [1, 2, 4]
    # set up folding for the depthwise conv layers impl'd by VVAUs
    # each value is PE for a layer
    fc_layers = model.get_nodes_by_op_type("StreamingFCLayer_Batch")
    # each tuple is (PE, SIMD, ram_style) for a layer
    folding = [
        (32, 3, "block"),
        (16, 16, "block"),
        (16, 16, "block"),
        (32, 16, "block"),
        (16, 16, "block"),
        (32, 16, "block"),
        (16, 16, "block"),
        (32, 16, "block"),
        (32, 16, "block"),
        (32, 16, "block"),
        (32, 16, "block"),
        (32, 16, "block"),
        (16, 16, "block"),
        (32, 16, "block"),
        (4, 4, "block"),
    ]
    for fcl, (pe, simd, ramstyle) in zip(fc_layers, folding):
        fcl_inst = getCustomOp(fcl)
        fcl_inst.set_nodeattr("PE", pe // extra_fold)
        fcl_inst.set_nodeattr("SIMD", simd)
        fcl_inst.set_nodeattr("ram_style", ramstyle)
    # first layer uses 8-bit weights & activations
    # control its compute resource type explicitly
    getCustomOp(fc_layers[0]).set_nodeattr("resType", first_layer_res_type)
    # set up folding for the depthwise conv layers impl'd by VVAUs
    # each value is PE for a layer
    vvau_layers = model.get_nodes_by_op_type("Vector_Vector_Activate_Batch")
    folding = [32, 32, 64, 16, 32, 8, 16, 16, 16, 16, 16, 4, 8]
    for vvau, pe in zip(vvau_layers, folding):
        vvau_inst = getCustomOp(vvau)
        vvau_inst.set_nodeattr("PE", pe // extra_fold)
        # set SIMD in preceeding ConvInputGen to same value
        convinputgen = model.find_direct_predecessors(vvau)[0]
        convinputgen_inst = getCustomOp(convinputgen)
        convinputgen_inst.set_nodeattr("SIMD", pe // extra_fold)
        # set SIMD in preceeding FMPadding to same value
        padding = model.find_direct_predecessors(convinputgen)[0]
        if padding.op_type == "FMPadding_Batch":
            padding_inst = getCustomOp(padding)
            padding_inst.set_nodeattr("SIMD", pe // extra_fold)
    # adjust final pooling layer + its inpgen
    pool_node = model.get_nodes_by_op_type("Pool_Batch")[0]
    pool_inst = getCustomOp(pool_node)
    pool_inst.set_nodeattr("PE", 4 // extra_fold)
    pool_inpgen = model.find_direct_predecessors(pool_node)[0]
    pool_inpgen_inst = getCustomOp(pool_inpgen)
    pool_inpgen_inst.set_nodeattr("SIMD", 4 // extra_fold)
    model = model.transform(InferDataLayouts())
    model.save(build_dir + "/end2end_mobilenet_folded.onnx")
示例#9
0
def test_end2end_mobilenet_rtlsim():
    model = load_test_checkpoint_or_skip(build_dir +
                                         "/end2end_mobilenet_ipgen.onnx")
    x = np.load(build_dir + "/end2end_mobilenet_input.npy")
    inp_name = model.graph.input[0].name
    out_name = model.graph.output[0].name
    inp_dict = {inp_name: x}
    # node-by-node rtlsim
    model = model.transform(SetExecMode("rtlsim"))
    model = model.transform(PrepareRTLSim())
    model.save(build_dir + "/end2end_mobilenet_ipgen_nodebynode_rtlsim.onnx")
    ret_rtlsim_nodebynode = execute_onnx(model, inp_dict, True)
    res_rtlsim_nodebynode = ret_rtlsim_nodebynode[out_name]
    np.save(
        build_dir + "/end2end_mobilenet_result_rtlsim_nodebynode.npy",
        res_rtlsim_nodebynode,
    )
    a0 = np.load(build_dir + "/end2end_mobilenet_topk_scale.npy")
    res_rtlsim_nodebynode_prob = (
        ret_rtlsim_nodebynode[model.graph.node[-2].output[0]] * a0)
    np.save(
        build_dir + "/end2end_mobilenet_result_rtlsim_nodebynode_prob.npy",
        res_rtlsim_nodebynode_prob,
    )

    # check result with golden values
    golden = np.load(build_dir + "/end2end_mobilenet_golden_top5.npy")
    golden_prob = np.load(build_dir +
                          "/end2end_mobilenet_golden_top5_prob.npy")

    assert (golden == res_rtlsim_nodebynode).all()
    assert np.isclose(golden_prob, res_rtlsim_nodebynode_prob).all()
示例#10
0
def test_end2end_mobilenet_streamline():
    model = load_test_checkpoint_or_skip(build_dir +
                                         "/end2end_mobilenet_tidy.onnx")
    model = model.transform(Streamline())
    additional_streamline_transformations = [
        DoubleToSingleFloat(),
        reorder.MoveMulPastDWConv(),
        absorb.AbsorbMulIntoMultiThreshold(),
        ChangeDataLayoutQuantAvgPool2d(),
        InferDataLayouts(),
        reorder.MoveTransposePastScalarMul(),
        absorb.AbsorbTransposeIntoFlatten(),
        reorder.MoveFlattenPastAffine(),
        reorder.MoveFlattenPastTopK(),
        reorder.MoveScalarMulPastMatMul(),
        CollapseRepeatedMul(),
        RemoveIdentityOps(),
        RoundAndClipThresholds(),
    ]
    for trn in additional_streamline_transformations:
        model = model.transform(trn)
        model = model.transform(GiveUniqueNodeNames())
        model = model.transform(GiveReadableTensorNames())
        model = model.transform(InferDataTypes())
    model.save(build_dir + "/end2end_mobilenet_streamlined.onnx")
    assert (len(model.get_nodes_by_op_type("Add")) == 1
            )  # only final quantized bias Add op remains
    assert len(model.get_nodes_by_op_type("Mul")) == 0  # no Mul ops remain
示例#11
0
 def test_add_pre_and_postproc(self, topology, wbits, abits):
     prev_chkpt_name = get_checkpoint_name(topology, wbits, abits, "import_and_tidy")
     model = load_test_checkpoint_or_skip(prev_chkpt_name)
     global_inp_name = model.graph.input[0].name
     ishape = model.get_tensor_shape(global_inp_name)
     # preprocessing: torchvision's ToTensor divides uint8 inputs by 255
     totensor_pyt = ToTensor()
     chkpt_preproc_name = get_checkpoint_name(topology, wbits, abits, "preproc")
     bo.export_finn_onnx(totensor_pyt, ishape, chkpt_preproc_name)
     assert os.path.isfile(chkpt_preproc_name)
     # join preprocessing and core model
     pre_model = ModelWrapper(chkpt_preproc_name)
     model = model.transform(MergeONNXModels(pre_model))
     # add input quantization annotation: UINT8 for all BNN-PYNQ models
     global_inp_name = model.graph.input[0].name
     model.set_tensor_datatype(global_inp_name, DataType.UINT8)
     # postprocessing: insert Top-1 node at the end
     model = model.transform(InsertTopK(k=1))
     chkpt_name = get_checkpoint_name(topology, wbits, abits, "pre_post")
     # tidy-up again
     model = model.transform(InferShapes())
     model = model.transform(FoldConstants())
     model = model.transform(GiveUniqueNodeNames())
     model = model.transform(GiveReadableTensorNames())
     model = model.transform(InferDataTypes())
     model = model.transform(RemoveStaticGraphInputs())
     model.save(chkpt_name)
     assert os.path.isfile(chkpt_name)
示例#12
0
def test_end2end_cybsec_mlp_build(QONNX_export):
    model_file = get_checkpoint_name("export", QONNX_export)
    load_test_checkpoint_or_skip(model_file)
    build_env = get_build_env(build_kind, target_clk_ns)
    output_dir = make_build_dir(
        f"test_end2end_cybsec_mlp_build_QONNX-{QONNX_export}")

    cfg = build.DataflowBuildConfig(
        output_dir=output_dir,
        target_fps=1000000,
        synth_clk_period_ns=target_clk_ns,
        board=build_env["board"],
        shell_flow_type=build_cfg.ShellFlowType.VIVADO_ZYNQ,
        generate_outputs=[
            build_cfg.DataflowOutputType.ESTIMATE_REPORTS,
            build_cfg.DataflowOutputType.BITFILE,
            build_cfg.DataflowOutputType.PYNQ_DRIVER,
            build_cfg.DataflowOutputType.DEPLOYMENT_PACKAGE,
        ],
    )
    build.build_dataflow_cfg(model_file, cfg)
    # check the generated files
    assert os.path.isfile(output_dir + "/time_per_step.json")
    assert os.path.isfile(output_dir + "/final_hw_config.json")
    assert os.path.isfile(output_dir + "/driver/driver.py")
    est_cycles_report = output_dir + "/report/estimate_layer_cycles.json"
    assert os.path.isfile(est_cycles_report)
    est_res_report = output_dir + "/report/estimate_layer_resources.json"
    assert os.path.isfile(est_res_report)
    assert os.path.isfile(output_dir +
                          "/report/estimate_network_performance.json")
    assert os.path.isfile(output_dir + "/bitfile/finn-accel.bit")
    assert os.path.isfile(output_dir + "/bitfile/finn-accel.hwh")
    assert os.path.isfile(output_dir + "/report/post_synth_resources.xml")
    assert os.path.isfile(output_dir + "/report/post_route_timing.rpt")
    # examine the report contents
    with open(est_cycles_report, "r") as f:
        est_cycles_dict = json.load(f)
        assert est_cycles_dict["StreamingFCLayer_Batch_0"] == 80
        assert est_cycles_dict["StreamingFCLayer_Batch_1"] == 64
    with open(est_res_report, "r") as f:
        est_res_dict = json.load(f)
        assert est_res_dict["total"]["LUT"] == 11360.0
        assert est_res_dict["total"]["BRAM_18K"] == 36.0
    shutil.copytree(output_dir + "/deploy",
                    get_checkpoint_name("build", QONNX_export))
示例#13
0
    def test_throughput_hw(self, topology, wbits, abits, kind):
        prev_chkpt_name = get_checkpoint_name(topology, wbits, abits, "deploy_" + kind)
        end2end_example = "%s_w%da%d_%s" % (topology, wbits, abits, kind)
        model = load_test_checkpoint_or_skip(prev_chkpt_name)  # NOQA
        cfg = get_build_env(kind, target_clk_ns)
        if cfg["ip"] == "":
            pytest.skip("PYNQ board IP address not specified")
        ret = dict()
        # try a range of batch sizes, some may fail due to insufficient DMA
        # buffers
        bsize_range_in = [8 ** i for i in range(5)]
        bsize_range = []
        for bsize in bsize_range_in:
            res = throughput_test_remote(model, bsize)
            if res is not None:
                ret[bsize] = res
                bsize_range.append(bsize)
            else:
                # assume we reached largest possible N
                break
        y = [ret[key]["runtime[ms]"] for key in bsize_range]
        lrret = linregress(bsize_range, y)
        ret_str = ""
        ret_str += "\n" + "%s Throughput Test Results" % end2end_example
        ret_str += "\n" + "-----------------------------"
        ret_str += "\n" + "From linear regression:"
        ret_str += "\n" + "Invocation overhead: %f ms" % lrret.intercept
        ret_str += "\n" + "Time per sample: %f ms" % lrret.slope
        ret_str += "\n" + "Raw data:"

        ret_str += "\n" + "{:<8} {:<16} {:<16} {:<16} {:<16} {:<16}".format(
            "N", "runtime[ms]", "fclk[mhz]", "fps", "DRAM rd[Mb/s]", "DRAM wr[Mb/s]"
        )
        for k in bsize_range:
            v = ret[k]
            ret_str += "\n" + "{:<8} {:<16} {:<16} {:<16} {:<16} {:<16}".format(
                k,
                np.round(v["runtime[ms]"], 4),
                v["fclk[mhz]"],
                np.round(v["throughput[images/s]"], 2),
                np.round(v["DRAM_in_bandwidth[Mb/s]"], 2),
                np.round(v["DRAM_out_bandwidth[Mb/s]"], 2),
            )
        ret_str += "\n" + "-----------------------------"
        warnings.warn(ret_str)
        largest_bsize = bsize_range[-1]
        update_dashboard_data(
            topology, wbits, abits, "fclk[mhz]", ret[largest_bsize]["fclk[mhz]"]
        )
        update_dashboard_data(
            topology,
            wbits,
            abits,
            "throughput[images/s]",
            ret[largest_bsize]["throughput[images/s]"],
        )
示例#14
0
def test_end2end_mobilenet_lowering():
    model = load_test_checkpoint_or_skip(build_dir +
                                         "/end2end_mobilenet_streamlined.onnx")
    model = model.transform(LowerConvsToMatMul())
    model = model.transform(absorb.AbsorbTransposeIntoMultiThreshold())
    model = model.transform(GiveUniqueNodeNames())
    model = model.transform(GiveReadableTensorNames())
    model = model.transform(InferDataTypes())
    model = model.transform(RoundAndClipThresholds())
    model.save(build_dir + "/end2end_mobilenet_lowered.onnx")
示例#15
0
 def test_ipgen(self, topology, wbits, abits, kind):
     if kind == "alveo" and ("VITIS_PATH" not in os.environ):
         pytest.skip("VITIS_PATH not set")
     prev_chkpt_name = get_checkpoint_name(topology, wbits, abits, "fold")
     model = load_test_checkpoint_or_skip(prev_chkpt_name)
     test_fpga_part = get_build_env(kind, target_clk_ns)["part"]
     model = model.transform(GiveUniqueNodeNames())
     model = model.transform(PrepareIP(test_fpga_part, target_clk_ns))
     model = model.transform(HLSSynthIP())
     model.save(get_checkpoint_name(topology, wbits, abits, "ipgen_" + kind))
示例#16
0
def test_end2end_mobilenet_tidy_and_merge_with_preproc():
    preproc_model = load_test_checkpoint_or_skip(
        build_dir + "/end2end_mobilenet_preproc.onnx")
    model = load_test_checkpoint_or_skip(build_dir +
                                         "/end2end_mobilenet_export.onnx")
    model = model.transform(InferShapes())
    model = model.transform(FoldConstants())
    model = model.transform(InsertTopK())
    # get initializer from Mul that will be absorbed into topk
    a0 = model.get_initializer(model.graph.node[-2].input[1])
    np.save(build_dir + "/end2end_mobilenet_topk_scale.npy", a0)
    model = model.transform(absorb.AbsorbScalarMulAddIntoTopK())
    model = model.transform(InferShapes())
    model = model.transform(InferDataTypes())
    model = model.transform(InferDataLayouts())
    model = model.transform(GiveUniqueNodeNames())
    model = model.transform(GiveUniqueParameterTensors())
    model = model.transform(GiveReadableTensorNames())
    model = model.transform(MergeONNXModels(preproc_model))
    model.save(build_dir + "/end2end_mobilenet_tidy.onnx")
示例#17
0
 def test_import_and_tidy(self, topology, wbits, abits):
     prev_chkpt_name = get_checkpoint_name(topology, wbits, abits, "export")
     model = load_test_checkpoint_or_skip(prev_chkpt_name)
     model = model.transform(InferShapes())
     model = model.transform(FoldConstants())
     model = model.transform(GiveUniqueNodeNames())
     model = model.transform(GiveReadableTensorNames())
     model = model.transform(InferDataTypes())
     model = model.transform(RemoveStaticGraphInputs())
     chkpt = get_checkpoint_name(topology, wbits, abits, "import_and_tidy")
     model.save(chkpt)
示例#18
0
 def test_run_on_hw(self, topology, wbits, abits, kind):
     prev_chkpt_name = get_checkpoint_name(topology, wbits, abits, "deploy_" + kind)
     model = load_test_checkpoint_or_skip(prev_chkpt_name)  # NOQA
     cfg = get_build_env(kind, target_clk_ns)
     if cfg["ip"] == "":
         pytest.skip("PYNQ board IP address not specified")
     (input_tensor_npy, output_tensor_npy) = get_golden_io_pair(
         topology, wbits, abits, return_topk=1
     )
     parent_model = load_test_checkpoint_or_skip(
         get_checkpoint_name(topology, wbits, abits, "dataflow_parent")
     )
     iname = parent_model.graph.input[0].name
     oname = parent_model.graph.output[0].name
     sdp_node = parent_model.get_nodes_by_op_type("StreamingDataflowPartition")[0]
     sdp_node = getCustomOp(sdp_node)
     sdp_node.set_nodeattr("model", prev_chkpt_name)
     ret = execute_onnx(parent_model, {iname: input_tensor_npy}, True)
     y = ret[oname]
     assert np.isclose(y, output_tensor_npy).all()
示例#19
0
def test_end2end_mobilenet_convert_to_hls_layers():
    model = load_test_checkpoint_or_skip(build_dir + "/end2end_mobilenet_lowered.onnx")
    model = model.transform(to_hls.InferPool_Batch())
    model = model.transform(to_hls.InferConvInpGen())
    model = model.transform(to_hls.InferVVAU())
    model = model.transform(to_hls.InferQuantizedStreamingFCLayer(mem_mode))
    model = model.transform(to_hls.InferChannelwiseLinearLayer())
    model = model.transform(to_hls.InferLabelSelectLayer())
    model = model.transform(InferShapes())
    model = model.transform(GiveUniqueNodeNames())
    model = model.transform(GiveReadableTensorNames())
    model.save(build_dir + "/end2end_mobilenet_hls_layers.onnx")
示例#20
0
 def test_make_pynq_driver(self, topology, wbits, abits, QONNX_export,
                           kind):
     if kind == "alveo" and ("VITIS_PATH" not in os.environ):
         pytest.skip("VITIS_PATH not set")
     prev_chkpt_name = get_checkpoint_name(topology, wbits, abits,
                                           QONNX_export, "build_" + kind)
     model = load_test_checkpoint_or_skip(prev_chkpt_name)
     kind_to_driver_platform = {"zynq": "zynq-iodma", "alveo": "alveo"}
     model = model.transform(MakePYNQDriver(kind_to_driver_platform[kind]))
     model.save(
         get_checkpoint_name(topology, wbits, abits, QONNX_export,
                             "driver_" + kind))
示例#21
0
 def test_throughput_rtlsim(self, topology, wbits, abits, kind):
     prev_chkpt_name = get_checkpoint_name(topology, wbits, abits,
                                           "ipstitch_rtlsim_" + kind)
     model = load_test_checkpoint_or_skip(prev_chkpt_name)
     n_nodes = len(model.graph.node)
     perf_est = model.analysis(dataflow_performance)
     latency = int(model.get_metadata_prop("cycles_rtlsim"))
     cycles_per_sample_est = perf_est["max_cycles"]
     batchsize = 2 * n_nodes
     ret = throughput_test_rtlsim(model, batchsize=batchsize)
     res_cycles = ret["cycles"]
     est_cycles = latency + cycles_per_sample_est * batchsize
     assert (abs(res_cycles - est_cycles) / res_cycles) < 0.15
示例#22
0
def test_end2end_mobilenet_build():
    model = load_test_checkpoint_or_skip(build_dir +
                                         "/end2end_mobilenet_fifodepth.onnx")
    model = model.transform(
        VitisBuild(
            test_fpga_part,
            target_clk_ns,
            test_platform,
            strategy=VitisOptStrategy.PERFORMANCE_BEST,
        ))
    model.save(build_dir + "/end2end_mobilenet_build.onnx")
    model = model.transform(AnnotateResources("synth"))
    model.save(build_dir + "/end2end_mobilenet_final.onnx")
示例#23
0
 def test_build(self, topology, wbits, abits, kind):
     if kind == "alveo" and ("VITIS_PATH" not in os.environ):
         pytest.skip("VITIS_PATH not set")
     prev_chkpt_name = get_checkpoint_name(topology, wbits, abits, "ipgen_" + kind)
     model = load_test_checkpoint_or_skip(prev_chkpt_name)
     cfg = get_build_env(kind, target_clk_ns)
     model = model.transform(cfg["build_fxn"])
     model = model.transform(AnnotateResources("synth"))
     synth_dct = eval(model.get_metadata_prop("res_total_top_synth"))
     for (k, v) in synth_dct.items():
         update_dashboard_data(topology, wbits, abits, k, v)
     update_dashboard_data(topology, wbits, abits, "board", cfg["board"])
     model.save(get_checkpoint_name(topology, wbits, abits, "build_" + kind))
示例#24
0
 def test_cppsim(self, topology, wbits, abits):
     prev_chkpt_name = get_checkpoint_name(topology, wbits, abits, "fold")
     model = load_test_checkpoint_or_skip(prev_chkpt_name)
     model = model.transform(PrepareCppSim())
     model = model.transform(CompileCppSim())
     model = model.transform(SetExecMode("cppsim"))
     cppsim_chkpt = get_checkpoint_name(topology, wbits, abits, "cppsim")
     model.save(cppsim_chkpt)
     parent_chkpt = get_checkpoint_name(topology, wbits, abits, "dataflow_parent")
     (input_tensor_npy, output_tensor_npy) = get_golden_io_pair(
         topology, wbits, abits, return_topk=1
     )
     y = execute_parent(parent_chkpt, cppsim_chkpt, input_tensor_npy)
     assert np.isclose(y, output_tensor_npy).all()
示例#25
0
def test_fpgadataflow_ipstitch_do_stitch(mem_mode):
    model = load_test_checkpoint_or_skip(
        ip_stitch_model_dir +
        "/test_fpgadataflow_ipstitch_gen_model_%s.onnx" % mem_mode)
    model = model.transform(CreateStitchedIP(test_fpga_part, 5))
    vivado_stitch_proj_dir = model.get_metadata_prop("vivado_stitch_proj")
    assert vivado_stitch_proj_dir is not None
    assert os.path.isdir(vivado_stitch_proj_dir)
    assert os.path.isfile(vivado_stitch_proj_dir + "/ip/component.xml")
    vivado_stitch_vlnv = model.get_metadata_prop("vivado_stitch_vlnv")
    assert vivado_stitch_vlnv is not None
    assert vivado_stitch_vlnv == "xilinx_finn:finn:finn_design:1.0"
    model.save(ip_stitch_model_dir +
               "/test_fpgadataflow_ip_stitch_%s.onnx" % mem_mode)
示例#26
0
 def test_set_fifo_depths(self, topology, wbits, abits, kind):
     prev_chkpt_name = get_checkpoint_name(topology, wbits, abits, "ipgen_" + kind)
     model = load_test_checkpoint_or_skip(prev_chkpt_name)
     test_fpga_part = get_build_env(kind, target_clk_ns)["part"]
     model = model.transform(InsertAndSetFIFODepths(test_fpga_part, target_clk_ns))
     fifo_layers = model.get_nodes_by_op_type("StreamingFIFO")
     assert len(fifo_layers) > 0
     hls_layers = model.get_finn_nodes()
     for node in hls_layers:
         if node.op_type != "StreamingFIFO":
             op_inst = getCustomOp(node)
             assert op_inst.get_nodeattr("inFIFODepth") == 0
             assert op_inst.get_nodeattr("outFIFODepth") == 0
     model.save(get_checkpoint_name(topology, wbits, abits, "fifodepth_" + kind))
示例#27
0
def test_fpgadataflow_ipstitch_zynqbuild(board):
    model = create_two_fc_model()
    if model.graph.node[0].op_type == "StreamingDataflowPartition":
        sdp_node = getCustomOp(model.graph.node[0])
        assert sdp_node.__class__.__name__ == "StreamingDataflowPartition"
        assert os.path.isfile(sdp_node.get_nodeattr("model"))
        model = load_test_checkpoint_or_skip(sdp_node.get_nodeattr("model"))
    # bitfile using ZynqBuild
    model = model.transform(ZynqBuild(board, 10))
    model.save(ip_stitch_model_dir +
               "/test_fpgadataflow_ipstitch_customzynq.onnx")

    bitfile_name = model.get_metadata_prop("bitfile")
    assert bitfile_name is not None
    assert os.path.isfile(bitfile_name)
示例#28
0
def test_end2end_mobilenet_gen_hls_ip():
    model = load_test_checkpoint_or_skip(
        build_dir + "/end2end_mobilenet_dataflow_model.onnx")
    start = time.time()
    model = model.transform(PrepareIP(test_fpga_part, target_clk_ns))
    model = model.transform(HLSSynthIP())
    model = model.transform(ReplaceVerilogRelPaths())
    end = time.time()
    elapsed_time = end - start
    f = open(build_dir + "/end2end_mobilenet_ipgen_time.txt", "w+")
    f.write("Execution time in seconds: " + str(elapsed_time))
    f.close()

    model = model.transform(AnnotateResources("hls"))
    model.save(build_dir + "/end2end_mobilenet_ipgen.onnx")
示例#29
0
def test_fpgadataflow_ipstitch_iodma_floorplan():
    model = create_one_fc_model()
    if model.graph.node[0].op_type == "StreamingDataflowPartition":
        sdp_node = getCustomOp(model.graph.node[0])
        assert sdp_node.__class__.__name__ == "StreamingDataflowPartition"
        assert os.path.isfile(sdp_node.get_nodeattr("model"))
        model = load_test_checkpoint_or_skip(sdp_node.get_nodeattr("model"))
    model = model.transform(InferDataLayouts())
    model = model.transform(InsertIODMA())
    model = model.transform(Floorplan())
    assert getCustomOp(model.graph.node[0]).get_nodeattr("partition_id") == 0
    assert getCustomOp(model.graph.node[1]).get_nodeattr("partition_id") == 2
    assert getCustomOp(model.graph.node[2]).get_nodeattr("partition_id") == 1
    model.save(ip_stitch_model_dir +
               "/test_fpgadataflow_ipstitch_iodma_floorplan.onnx")
def test_dataflow_partition_tlastmarker():
    model = load_test_checkpoint_or_skip(
        build_dir + "/test_dataflow_partition_create.onnx")
    model_path = getCustomOp(model.graph.node[2]).get_nodeattr("model")
    model = ModelWrapper(model_path)
    model = model.transform(InsertTLastMarker())
    assert model.graph.node[-1].op_type == "TLastMarker"
    assert model.graph.node[-1].domain == "finn"
    tl_node = getCustomOp(model.graph.node[-1])
    assert tl_node.get_nodeattr("NumIters") == 1
    assert tl_node.get_nodeattr("StreamWidth") == 320
    assert tl_node.get_nodeattr("ElemWidth") == 32
    model.save(build_dir + "/test_dataflow_partition_tlastmarker.onnx")
    model = model.transform(InsertTLastMarker())
    model.save(build_dir + "/test_dataflow_partition_tlastmarker2.onnx")