Ejemplo n.º 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"))
Ejemplo n.º 2
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]"],
        )
Ejemplo n.º 3
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))
Ejemplo n.º 4
0
def test_end2end_cybsec_mlp_run_on_hw():
    build_env = get_build_env(build_kind, target_clk_ns)
    assets_dir = pk.resource_filename("finn.qnn-data", "cybsec-mlp/")
    deploy_dir = get_checkpoint_name("build")
    if not os.path.isdir(deploy_dir):
        pytest.skip(deploy_dir +
                    " not found from previous test step, skipping")
    driver_dir = deploy_dir + "/driver"
    assert os.path.isdir(driver_dir)
    # put all assets into driver dir
    shutil.copy(assets_dir + "/validate-unsw-nb15.py", driver_dir)
    # put a copy of binarized dataset into driver dir
    dataset_url = (
        "https://zenodo.org/record/4519767/files/unsw_nb15_binarized.npz?download=1"
    )
    dataset_local = driver_dir + "/unsw_nb15_binarized.npz"
    if not os.path.isfile(dataset_local):
        wget.download(dataset_url, out=dataset_local)
    assert os.path.isfile(dataset_local)
    # create a shell script for running validation: 10 batches x 10 imgs
    with open(driver_dir + "/validate.sh", "w") as f:
        f.write("""#!/bin/bash
cd %s/driver
echo %s | sudo -S python3.6 validate-unsw-nb15.py --batchsize=10 --limit_batches=10
        """ % (
            build_env["target_dir"] + "/end2end_cybsecmlp_build",
            build_env["password"],
        ))
    # set up rsync command
    remote_target = "%s@%s:%s" % (
        build_env["username"],
        build_env["ip"],
        build_env["target_dir"],
    )
    rsync_res = subprocess.run(["rsync", "-avz", deploy_dir, remote_target])
    assert rsync_res.returncode == 0
    remote_verif_cmd = [
        "ssh",
        "%s@%s" % (build_env["username"], build_env["ip"]),
        "sh",
        build_env["target_dir"] +
        "/end2end_cybsecmlp_build/driver/validate.sh",
    ]
    verif_res = subprocess.run(
        remote_verif_cmd,
        stdout=subprocess.PIPE,
        universal_newlines=True,
        input=build_env["password"],
    )
    assert verif_res.returncode == 0
    log_output = verif_res.stdout.split("\n")
    assert log_output[-3] == "batch 10 / 10 : total OK 93 NOK 7"
    assert log_output[-2] == "Final accuracy: 93.000000"
Ejemplo n.º 5
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))
Ejemplo n.º 6
0
def test_end2end_ext_weights_dataset():
    # make sure we have local copies of mnist dataset files
    subprocess.check_output(["mkdir", "-p", mnist_local])
    for f in mnist_files:
        if not os.path.isfile(mnist_local + "/" + f):
            wget.download(mnist_url + "/" + f, out=mnist_local + "/" + f)
        assert os.path.isfile(mnist_local + "/" + f)
    # rsync to board
    build_env = get_build_env(build_kind, target_clk_ns)
    mnist_target = "%s@%s:%s" % (build_env["username"], build_env["ip"],
                                 "/tmp/")

    rsync_dataset_cmd = ["rsync", "-rv", mnist_local + "/", mnist_target]
    subprocess.check_output(rsync_dataset_cmd)
Ejemplo n.º 7
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))
Ejemplo n.º 8
0
 def test_deploy(self, topology, wbits, abits, kind):
     prev_chkpt_name = get_checkpoint_name(topology, wbits, abits, "build_" + kind)
     model = load_test_checkpoint_or_skip(prev_chkpt_name)
     cfg = get_build_env(kind, target_clk_ns)
     if cfg["ip"] == "":
         pytest.skip("PYNQ board IP address not specified")
     model = model.transform(
         DeployToPYNQ(
             cfg["ip"],
             cfg["port"],
             cfg["username"],
             cfg["password"],
             cfg["target_dir"],
         )
     )
     # save the model to be able to link it to the parent
     model.save(get_checkpoint_name(topology, wbits, abits, "deploy_" + kind))
Ejemplo n.º 9
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))
Ejemplo n.º 10
0
def test_end2end_ext_weights_run_on_hw():
    build_env = get_build_env(build_kind, target_clk_ns)
    deploy_dir = get_checkpoint_name("build")
    if not os.path.isdir(deploy_dir):
        pytest.skip(deploy_dir +
                    " not found from previous test step, skipping")
    driver_dir = deploy_dir + "/driver"
    assert os.path.isdir(driver_dir)
    # create a shell script for running validation: 10 batches x 10 imgs
    with open(driver_dir + "/validate.sh", "w") as f:
        f.write("""#!/bin/bash
cd %s/driver
echo %s | sudo -S python3.6 validate.py --dataset mnist --bitfile %s
        """ % (
            build_env["target_dir"] + "/end2end_ext_weights_build",
            build_env["password"],
            "../bitfile/finn-accel.bit",
        ))
    # set up rsync command
    remote_target = "%s@%s:%s" % (
        build_env["username"],
        build_env["ip"],
        build_env["target_dir"],
    )
    rsync_res = subprocess.run(["rsync", "-avz", deploy_dir, remote_target])
    assert rsync_res.returncode == 0
    remote_verif_cmd = [
        "ssh",
        "%s@%s" % (build_env["username"], build_env["ip"]),
        "sh",
        build_env["target_dir"] +
        "/end2end_ext_weights_build/driver/validate.sh",
    ]
    verif_res = subprocess.run(
        remote_verif_cmd,
        stdout=subprocess.PIPE,
        universal_newlines=True,
        input=build_env["password"],
    )
    assert verif_res.returncode == 0
    log_output = verif_res.stdout.split("\n")
    assert log_output[-3] == "batch 100 / 100 : total OK 9296 NOK 704"
    assert log_output[-2] == "Final accuracy: 92.960000"
Ejemplo n.º 11
0
 def test_ipstitch_rtlsim(self, topology, wbits, abits, kind):
     prev_chkpt_name = get_checkpoint_name(
         topology, wbits, abits, "fifodepth_" + kind
     )
     model = load_test_checkpoint_or_skip(prev_chkpt_name)
     test_fpga_part = get_build_env(kind, target_clk_ns)["part"]
     model = model.transform(InsertDWC())
     model = model.transform(GiveUniqueNodeNames())
     model = model.transform(AnnotateCycles())
     perf = model.analysis(dataflow_performance)
     latency = perf["critical_path_cycles"]
     # rtlsim only supports impl_style=rtl for StreamingFIFO, ensure that
     for fifo_layer in model.get_nodes_by_op_type("StreamingFIFO"):
         getCustomOp(fifo_layer).set_nodeattr("impl_style", "rtl")
     model = model.transform(PrepareIP(test_fpga_part, target_clk_ns))
     model = model.transform(HLSSynthIP())
     model = model.transform(CreateStitchedIP(test_fpga_part, target_clk_ns))
     model = model.transform(PrepareRTLSim())
     model.set_metadata_prop("exec_mode", "rtlsim")
     os.environ["LIVENESS_THRESHOLD"] = str(int(latency * 1.1))
     if rtlsim_trace:
         model.set_metadata_prop(
             "rtlsim_trace", "%s_w%da%d.vcd" % (topology, wbits, abits)
         )
         os.environ["RTLSIM_TRACE_DEPTH"] = "3"
     rtlsim_chkpt = get_checkpoint_name(
         topology, wbits, abits, "ipstitch_rtlsim_" + kind
     )
     model.save(rtlsim_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, rtlsim_chkpt, input_tensor_npy)
     model = ModelWrapper(rtlsim_chkpt)
     perf["cycles_rtlsim"] = model.get_metadata_prop("cycles_rtlsim")
     # warnings.warn("Estimated & rtlsim performance: " + str(perf))
     # for (k, v) in perf.items():
     #    update_dashboard_data(topology, wbits, abits, k, v)
     update_dashboard_data(
         topology, wbits, abits, "cycles_rtlsim", perf["cycles_rtlsim"]
     )
     assert np.isclose(y, output_tensor_npy).all()
Ejemplo n.º 12
0
def test_end2end_access_board():
    build_env = get_build_env("zynq", 5)
    if build_env["ip"] == "":
        pytest.skip("PYNQ board IP address not specified")
    remote_cmd_base = [
        "ssh",
        "-o",
        "PreferredAuthentications=publickey",
        "-o",
        "PasswordAuthentication=no",
        "%s@%s" % (build_env["username"], build_env["ip"]),
    ]
    test_text = "BoardIsAccessible"
    touch_cmd = remote_cmd_base + ["echo %s" % test_text]
    verif_res = subprocess.run(touch_cmd,
                               stdout=subprocess.PIPE,
                               universal_newlines=True)
    assert verif_res.returncode == 0
    assert verif_res.stdout.split("\n")[0] == test_text
Ejemplo n.º 13
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()