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"))
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")
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"))
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)
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"))
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()
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"
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")
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()
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
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)
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))
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]"], )
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")
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))
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")
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)
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()
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")
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))
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
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")
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))
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()
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)
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))
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)
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")
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")