From c33758c1b59c5cfb5cb8960b3b5530c578e5e382 Mon Sep 17 00:00:00 2001 From: Yaman Umuroglu <maltanar@gmail.com> Date: Mon, 21 Sep 2020 15:53:31 +0200 Subject: [PATCH] [Notebook] update end-to-end notebooks --- .../end2end_example/cnv_end2end_example.ipynb | 1209 +++++------------ .../end2end_example/tfc_end2end_example.ipynb | 789 ++++++++--- 2 files changed, 950 insertions(+), 1048 deletions(-) diff --git a/notebooks/end2end_example/cnv_end2end_example.ipynb b/notebooks/end2end_example/cnv_end2end_example.ipynb index cecb1c9be..795f7f22f 100644 --- a/notebooks/end2end_example/cnv_end2end_example.ipynb +++ b/notebooks/end2end_example/cnv_end2end_example.ipynb @@ -55,7 +55,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -76,7 +76,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -86,7 +86,7 @@ "from finn.core.modelwrapper import ModelWrapper\n", "from finn.transformation.infer_shapes import InferShapes\n", "from finn.transformation.fold_constants import FoldConstants\n", - "from finn.transformation.general import GiveReadableTensorNames, GiveUniqueNodeNames\n", + "from finn.transformation.general import GiveReadableTensorNames, GiveUniqueNodeNames, RemoveStaticGraphInputs\n", "\n", "cnv = get_test_model_trained(\"CNV\", 1, 1)\n", "bo.export_finn_onnx(cnv, (1, 3, 32, 32), build_dir + \"/end2end_cnv_w1a1_export.onnx\")\n", @@ -95,6 +95,7 @@ "model = model.transform(FoldConstants())\n", "model = model.transform(GiveUniqueNodeNames())\n", "model = model.transform(GiveReadableTensorNames())\n", + "model = model.transform(RemoveStaticGraphInputs())\n", "model.save(build_dir + \"/end2end_cnv_w1a1_tidy.onnx\")" ] }, @@ -107,7 +108,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 27, "metadata": {}, "outputs": [ { @@ -131,10 +132,10 @@ " " ], "text/plain": [ - "<IPython.lib.display.IFrame at 0x7fc303685940>" + "<IPython.lib.display.IFrame at 0x7f25b19194a8>" ] }, - "execution_count": 6, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -150,6 +151,105 @@ "You can see that the network is composed of a repeating convolution-convolution-maxpool layer pattern to extract features using 3x3 convolution kernels (with weights binarized) and `Sign` activations, followed by fully connected layers acting as the classifier. Also notice the initial `MultiThreshold` layer at the beginning of the network, which is quantizing float inputs to 8-bit ones." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Adding Pre- and Postprocessing <a id='prepost'></a>\n", + "\n", + "TODO" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/workspace/finn/src/finn/transformation/infer_data_layouts.py:113: UserWarning: Assuming 4D input is NCHW\n", + " warnings.warn(\"Assuming 4D input is NCHW\")\n" + ] + } + ], + "source": [ + "from finn.util.pytorch import ToTensor\n", + "from finn.transformation.merge_onnx_models import MergeONNXModels\n", + "from finn.core.datatype import DataType\n", + "\n", + "model = ModelWrapper(build_dir+\"/end2end_cnv_w1a1_tidy.onnx\")\n", + "global_inp_name = model.graph.input[0].name\n", + "ishape = model.get_tensor_shape(global_inp_name)\n", + "# preprocessing: torchvision's ToTensor divides uint8 inputs by 255\n", + "totensor_pyt = ToTensor()\n", + "chkpt_preproc_name = build_dir+\"/end2end_cnv_w1a1_preproc.onnx\"\n", + "bo.export_finn_onnx(totensor_pyt, ishape, chkpt_preproc_name)\n", + "\n", + "# join preprocessing and core model\n", + "pre_model = ModelWrapper(chkpt_preproc_name)\n", + "model = model.transform(MergeONNXModels(pre_model))\n", + "# add input quantization annotation: UINT8 for all BNN-PYNQ models\n", + "global_inp_name = model.graph.input[0].name\n", + "model.set_tensor_datatype(global_inp_name, DataType.UINT8)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Stopping http://0.0.0.0:8081\n", + "Serving '/workspace/finn/end2end_cnv_w1a1_pre_post.onnx' at http://0.0.0.0:8081\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " <iframe\n", + " width=\"100%\"\n", + " height=\"400\"\n", + " src=\"http://0.0.0.0:8081/\"\n", + " frameborder=\"0\"\n", + " allowfullscreen\n", + " ></iframe>\n", + " " + ], + "text/plain": [ + "<IPython.lib.display.IFrame at 0x7f25b1919518>" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from finn.transformation.insert_topk import InsertTopK\n", + "from finn.transformation.infer_datatypes import InferDataTypes\n", + "\n", + "# postprocessing: insert Top-1 node at the end\n", + "model = model.transform(InsertTopK(k=1))\n", + "chkpt_name = build_dir+\"/end2end_cnv_w1a1_pre_post.onnx\"\n", + "# tidy-up again\n", + "model = model.transform(InferShapes())\n", + "model = model.transform(FoldConstants())\n", + "model = model.transform(GiveUniqueNodeNames())\n", + "model = model.transform(GiveReadableTensorNames())\n", + "model = model.transform(InferDataTypes())\n", + "model = model.transform(RemoveStaticGraphInputs())\n", + "model.save(chkpt_name)\n", + "\n", + "showInNetron(build_dir+\"/end2end_cnv_w1a1_pre_post.onnx\")" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -168,7 +268,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 30, "metadata": {}, "outputs": [], "source": [ @@ -176,15 +276,22 @@ "from finn.transformation.lower_convs_to_matmul import LowerConvsToMatMul\n", "from finn.transformation.bipolar_to_xnor import ConvertBipolarMatMulToXnorPopcount\n", "import finn.transformation.streamline.absorb as absorb\n", - "from finn.transformation.streamline.reorder import MakeMaxPoolNHWC\n", + "from finn.transformation.streamline.reorder import MakeMaxPoolNHWC, MoveScalarLinearPastInvariants\n", + "from finn.transformation.infer_data_layouts import InferDataLayouts\n", + "from finn.transformation.general import RemoveUnusedTensors\n", "\n", - "model = ModelWrapper(build_dir + \"/end2end_cnv_w1a1_tidy.onnx\")\n", + "model = ModelWrapper(build_dir + \"/end2end_cnv_w1a1_pre_post.onnx\")\n", + "model = model.transform(MoveScalarLinearPastInvariants())\n", "model = model.transform(Streamline())\n", "model = model.transform(LowerConvsToMatMul())\n", "model = model.transform(MakeMaxPoolNHWC())\n", "model = model.transform(absorb.AbsorbTransposeIntoMultiThreshold())\n", "model = model.transform(ConvertBipolarMatMulToXnorPopcount())\n", "model = model.transform(Streamline())\n", + "# absorb final add-mul nodes into TopK\n", + "model = model.transform(absorb.AbsorbScalarMulAddIntoTopK())\n", + "model = model.transform(InferDataLayouts())\n", + "model = model.transform(RemoveUnusedTensors())\n", "model.save(build_dir + \"/end2end_cnv_w1a1_streamlined.onnx\")" ] }, @@ -204,7 +311,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 31, "metadata": {}, "outputs": [ { @@ -230,10 +337,10 @@ " " ], "text/plain": [ - "<IPython.lib.display.IFrame at 0x7fc295ad28d0>" + "<IPython.lib.display.IFrame at 0x7f25b19a9470>" ] }, - "execution_count": 8, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -253,7 +360,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 32, "metadata": {}, "outputs": [], "source": [ @@ -271,10 +378,16 @@ "model = ModelWrapper(build_dir + \"/end2end_cnv_w1a1_streamlined.onnx\")\n", "model = model.transform(to_hls.InferBinaryStreamingFCLayer(mem_mode))\n", "model = model.transform(to_hls.InferQuantizedStreamingFCLayer(mem_mode))\n", + "# TopK to LabelSelect\n", + "model = model.transform(to_hls.InferLabelSelectLayer())\n", + "# input quantization (if any) to standalone thresholding\n", + "model = model.transform(to_hls.InferThresholdingLayer())\n", "model = model.transform(to_hls.InferConvInpGen())\n", "model = model.transform(to_hls.InferStreamingMaxPool())\n", "# get rid of Reshape(-1, 1) operation between hlslib nodes\n", "model = model.transform(RemoveCNVtoFCFlatten())\n", + "# get rid of Tranpose -> Tranpose identity seq\n", + "model = model.transform(absorb.AbsorbConsecutiveTransposes())\n", "# infer tensor data layouts\n", "model = model.transform(InferDataLayouts())\n", "parent_model = model.transform(CreateDataflowPartition())\n", @@ -296,7 +409,56 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 36, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Stopping http://0.0.0.0:8081\n", + "Serving '/workspace/finn/end2end_cnv_w1a1_dataflow_parent.onnx' at http://0.0.0.0:8081\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " <iframe\n", + " width=\"100%\"\n", + " height=\"400\"\n", + " src=\"http://0.0.0.0:8081/\"\n", + " frameborder=\"0\"\n", + " allowfullscreen\n", + " ></iframe>\n", + " " + ], + "text/plain": [ + "<IPython.lib.display.IFrame at 0x7f25b18b7668>" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "showInNetron(build_dir + \"/end2end_cnv_w1a1_dataflow_parent.onnx\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that pretty much everything has gone into the `StreamingDataflowPartition` node; the only operation remaining is to apply a `Transpose` to obtain NHWC input from a NCHW input (the ONNX default). " + ] + }, + { + "cell_type": "code", + "execution_count": 33, "metadata": {}, "outputs": [ { @@ -322,10 +484,10 @@ " " ], "text/plain": [ - "<IPython.lib.display.IFrame at 0x7fc295ec6f60>" + "<IPython.lib.display.IFrame at 0x7f25b18fe860>" ] }, - "execution_count": 15, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -343,7 +505,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 34, "metadata": {}, "outputs": [], "source": [ @@ -387,7 +549,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 35, "metadata": {}, "outputs": [ { @@ -413,10 +575,10 @@ " " ], "text/plain": [ - "<IPython.lib.display.IFrame at 0x7fc295b3d3c8>" + "<IPython.lib.display.IFrame at 0x7f252e5a6278>" ] }, - "execution_count": 17, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -438,12 +600,12 @@ "source": [ "## 4. Hardware Generation\n", "\n", - "From this point onward, the steps we have to follow do not depend on the particular network and will be exactly the same as the TFC-w1a1 example. **which may take about 30 minutes depending on your host computer**." + "From this point onward, the steps we have to follow do not depend on the particular network and will be exactly the same as the TFC-w1a1 example. **which may take about 30 minutes depending on your host computer**. For more details about what's going on in this step, please consult the [TFC end-to-end notebook](tfc_end2end_example.ipynb) or the appropriate section in the [FINN documentation](https://finn.readthedocs.io/en/latest/hw_build.html)." ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -467,7 +629,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -493,841 +655,76 @@ "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "/home/xilinx/finn_dev_maltanar/pynq_deployment_01nxn6ne:\r\n", - "total 4236\r\n", - "-rw-r--r-- 1 xilinx xilinx 9171 Aug 28 01:28 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 28 01:28 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 28 01:29 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 28 01:29 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 28 01:28 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 28 01:28 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 28 01:29 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_06f3kimz:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9154 Aug 27 13:30 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 27 13:30 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 27 13:45 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 27 13:45 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 27 13:30 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 27 13:30 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 27 13:45 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_06t_joa5:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9152 Aug 28 16:11 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 28 16:11 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 28 16:12 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 28 16:12 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 28 16:11 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246215 Aug 28 16:11 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 28 16:12 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_0qvh6x0y:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9154 Aug 29 04:50 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 29 04:50 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 29 04:50 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 29 04:51 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 29 04:50 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 29 04:50 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 29 04:51 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_1axnzb_3:\r\n", - "total 4288\r\n", - "-rw-r--r-- 1 xilinx xilinx 9230 Aug 21 09:39 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 21 09:39 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 21 09:39 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 21 09:40 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045675 Aug 21 09:39 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 301904 Aug 21 09:39 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 21 09:40 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_21w59oae:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9152 Aug 29 04:50 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 29 04:50 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 29 04:51 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 29 04:51 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 29 04:50 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246215 Aug 29 04:50 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 29 04:51 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_28bro9rw:\r\n", - "total 4220\r\n", - "-rw-r--r-- 1 xilinx xilinx 9409 Sep 4 03:35 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Sep 4 03:35 finn\r\n", - "-rw-r--r-- 1 root root 207 Sep 4 03:39 nw_metrics.txt\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Sep 4 03:35 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Sep 4 03:35 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Sep 4 03:39 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_3_7bkkrt:\r\n", - "total 4272\r\n", - "-rw-r--r-- 1 xilinx xilinx 9153 Aug 30 10:55 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 30 10:55 finn\r\n", - "-rw-r--r-- 1 root root 205 Aug 30 10:55 nw_metrics.txt\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045675 Aug 30 10:55 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 301916 Aug 30 10:55 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 30 10:55 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_3tl3zhf1:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 8827 Aug 19 10:38 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 10:38 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 19 10:38 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 19 10:38 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 19 10:38 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 19 10:38 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 10:38 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_4cf4kfxo:\r\n", - "total 4236\r\n", - "-rw-r--r-- 1 xilinx xilinx 9172 Aug 29 04:50 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 29 04:50 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 29 04:51 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 29 04:51 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 29 04:50 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 29 04:50 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 29 04:51 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment__6inegxp:\r\n", - "total 4260\r\n", - "-rw-r--r-- 1 xilinx xilinx 9147 Aug 30 09:52 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 30 09:52 finn\r\n", - "-rw-r--r-- 1 root root 206 Aug 30 09:54 nw_metrics.txt\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045675 Aug 30 09:52 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 287145 Aug 30 09:52 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 30 09:54 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_7887i7c6:\r\n", - "total 4236\r\n", - "-rw-r--r-- 1 xilinx xilinx 9172 Aug 28 01:28 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 28 01:28 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 28 01:28 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 28 01:28 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 28 01:28 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 28 01:28 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 28 01:28 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_7co5tvv7:\r\n", - "total 4272\r\n", - "-rw-r--r-- 1 xilinx xilinx 8826 Aug 19 08:34 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 08:34 finn\r\n", - "-rw-r--r-- 1 root root 205 Aug 19 08:35 nw_metrics.txt\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045675 Aug 19 08:34 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 301916 Aug 19 08:34 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 08:35 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_7rx94isg:\r\n", - "total 4228\r\n", - "-rw-r--r-- 1 xilinx xilinx 9154 Aug 30 12:29 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 30 12:29 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 30 12:29 input.npy\r\n", - "-rw-r--r-- 1 root root 205 Aug 30 12:49 nw_metrics.txt\r\n", - "-rw-r--r-- 1 root root 120 Aug 30 12:30 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 30 12:29 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 30 12:29 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 30 12:49 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_7uu4dz03:\r\n", - "total 4240\r\n", - "-rw-r--r-- 1 xilinx xilinx 9172 Aug 29 16:14 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 29 16:14 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 29 16:14 input.npy\r\n", - "-rw-r--r-- 1 root root 205 Aug 29 16:50 nw_metrics.txt\r\n", - "-rw-r--r-- 1 root root 120 Aug 29 16:14 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 29 16:14 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 29 16:14 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 29 16:51 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_81y7pbz6:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 8827 Aug 19 00:36 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 00:36 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 19 00:36 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 19 00:36 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 19 00:36 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246647 Aug 19 00:36 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 00:36 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_8oclwrec:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9154 Aug 28 16:11 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 28 16:11 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 28 16:11 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 28 16:11 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 28 16:11 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 28 16:11 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 28 16:11 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_8xmofsvg:\r\n", - "total 4228\r\n", - "-rw-r--r-- 1 xilinx xilinx 9219 Aug 16 13:19 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 16 13:19 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 16 13:19 input.npy\r\n", - "-rw-r--r-- 1 root root 204 Aug 16 13:43 nw_metrics.txt\r\n", - "-rw-r--r-- 1 root root 120 Aug 16 13:19 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 16 13:19 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246647 Aug 16 13:19 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 16 13:43 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_901qgs6r:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9154 Aug 27 06:06 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 27 06:06 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 27 06:06 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 27 06:06 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 27 06:06 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 27 06:06 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 27 06:06 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_93g2nqtq:\r\n", - "total 4260\r\n", - "-rw-r--r-- 1 xilinx xilinx 8820 Aug 19 07:32 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 07:32 finn\r\n", - "-rw-r--r-- 1 root root 203 Aug 19 07:35 nw_metrics.txt\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045675 Aug 19 07:32 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 287145 Aug 19 07:32 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 07:35 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_9ksrgg2h:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 8820 Aug 19 07:42 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 07:42 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 144 Aug 19 07:42 input.npy\r\n", - "-rw-r--r-- 1 root root 96 Aug 19 07:42 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 19 07:42 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246209 Aug 19 07:42 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 07:42 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_a6wquogd:\r\n", - "total 4236\r\n", - "-rw-r--r-- 1 xilinx xilinx 9171 Aug 28 01:28 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 28 01:28 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 28 01:28 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 28 01:28 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 28 01:28 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 28 01:28 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 28 01:28 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_ale2myrj:\r\n", - "total 4276\r\n", - "-rw-r--r-- 1 xilinx xilinx 8819 Aug 19 09:47 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 09:47 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 19 09:47 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 19 09:47 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045675 Aug 19 09:47 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 301911 Aug 19 09:47 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 09:47 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_ao3q4u89:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9152 Aug 27 15:49 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 27 15:49 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 27 23:39 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 27 23:39 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 27 15:49 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246215 Aug 27 15:49 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 27 23:39 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_cam682qh:\r\n", - "total 4220\r\n", - "-rw-r--r-- 1 xilinx xilinx 9389 Sep 4 03:35 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Sep 4 03:35 finn\r\n", - "-rw-r--r-- 1 root root 204 Sep 4 03:38 nw_metrics.txt\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Sep 4 03:35 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246215 Sep 4 03:35 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Sep 4 03:38 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_diprgb3z:\r\n", - "total 4236\r\n", - "-rw-r--r-- 1 xilinx xilinx 8841 Aug 20 02:05 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 20 02:05 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 20 04:11 input.npy\r\n", - "-rw-r--r-- 1 root root 84 Aug 20 04:12 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 20 02:05 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246207 Aug 20 02:05 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 20 04:12 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment__e5pd_a_:\r\n", - "total 4236\r\n", - "-rw-r--r-- 1 xilinx xilinx 9172 Aug 27 05:50 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 27 05:50 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 27 05:51 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 27 05:51 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 27 05:50 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 27 05:50 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 27 05:51 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_ecyflrb3:\r\n", - "total 4212\r\n", - "-rw-r--r-- 1 xilinx xilinx 9154 Aug 29 13:11 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 29 13:11 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 29 13:11 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 29 13:11 resizer.hwh\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_eh6_czd4:\r\n", - "total 4236\r\n", - "-rw-r--r-- 1 xilinx xilinx 9171 Aug 28 16:11 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 28 16:11 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 28 16:12 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 28 16:12 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 28 16:11 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 28 16:11 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 28 16:12 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_f_bruffc:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9219 Aug 15 11:46 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 15 11:46 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 15 11:46 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 15 11:46 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 15 11:46 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 15 11:46 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 15 11:46 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_fgopkgby:\r\n", - "total 4272\r\n", - "-rw-r--r-- 1 xilinx xilinx 9153 Aug 29 15:17 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 29 15:17 finn\r\n", - "-rw-r--r-- 1 root root 203 Aug 29 15:17 nw_metrics.txt\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045675 Aug 29 15:17 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 301916 Aug 29 15:17 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 29 15:17 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_fu_jf95u:\r\n", - "total 4220\r\n", - "-rw-r--r-- 1 xilinx xilinx 9408 Sep 4 03:35 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Sep 4 03:35 finn\r\n", - "-rw-r--r-- 1 root root 205 Sep 4 03:40 nw_metrics.txt\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Sep 4 03:35 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Sep 4 03:35 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Sep 4 03:40 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_gsss7jov:\r\n", - "total 4236\r\n", - "-rw-r--r-- 1 xilinx xilinx 9171 Aug 29 04:50 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 29 04:50 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 29 04:51 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 29 04:51 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 29 04:50 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 29 04:50 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 29 04:51 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_h8o7knmw:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9147 Aug 29 14:19 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 29 14:19 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 144 Aug 29 14:19 input.npy\r\n", - "-rw-r--r-- 1 root root 96 Aug 29 14:19 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 29 14:19 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246209 Aug 29 14:19 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 29 14:19 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_i705jzvl:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9152 Aug 29 04:50 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 29 04:50 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 29 04:51 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 29 04:51 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 29 04:50 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246215 Aug 29 04:50 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 29 04:51 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_i7w9f7gi:\r\n", - "total 4236\r\n", - "-rw-r--r-- 1 xilinx xilinx 9171 Aug 29 04:50 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 29 04:50 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 29 04:51 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 29 04:52 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 29 04:50 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 29 04:50 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 29 04:52 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_ih88epbh:\r\n", - "total 4260\r\n", - "-rw-r--r-- 1 xilinx xilinx 9147 Aug 29 14:15 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 29 14:15 finn\r\n", - "-rw-r--r-- 1 root root 207 Aug 29 14:18 nw_metrics.txt\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045675 Aug 29 14:15 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 287145 Aug 29 14:15 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 29 14:18 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_ii6xl1b5:\r\n", - "total 4240\r\n", - "-rw-r--r-- 1 xilinx xilinx 9237 Aug 16 13:02 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 16 13:02 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 16 13:02 input.npy\r\n", - "-rw-r--r-- 1 root root 207 Aug 16 13:45 nw_metrics.txt\r\n", - "-rw-r--r-- 1 root root 120 Aug 16 13:02 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 16 13:02 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246647 Aug 16 13:02 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 16 13:45 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_ilfexhs3:\r\n", - "total 4288\r\n", - "-rw-r--r-- 1 xilinx xilinx 8838 Aug 19 08:57 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 08:57 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 19 08:57 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 19 08:57 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045675 Aug 19 08:57 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 301904 Aug 19 08:57 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 11:00 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_it7n5qfu:\r\n", - "total 4236\r\n", - "-rw-r--r-- 1 xilinx xilinx 9172 Aug 27 15:49 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 27 15:49 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 27 23:40 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 27 23:40 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 27 15:49 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 27 15:49 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 27 23:40 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_iuszsd4p:\r\n", - "total 4212\r\n", - "-rw-r--r-- 1 xilinx xilinx 9409 Sep 4 13:08 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Sep 4 13:08 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Sep 4 13:08 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Sep 4 13:08 resizer.hwh\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_j8ixf__1:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9152 Aug 27 15:49 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 27 15:49 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 27 23:21 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 27 23:21 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 27 15:49 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246215 Aug 27 15:49 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 27 23:21 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_jdmw5vhc:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9219 Aug 16 02:18 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 16 02:18 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 16 02:19 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 16 02:19 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 16 02:18 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246647 Aug 16 02:18 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 16 02:19 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_jk8k3kdu:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 8825 Aug 19 10:56 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 10:56 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 19 10:56 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 19 10:56 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 19 10:56 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246215 Aug 19 10:56 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 10:56 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_jlcdo6uh:\r\n", - "total 4236\r\n", - "-rw-r--r-- 1 xilinx xilinx 8845 Aug 19 00:19 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 00:19 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 19 00:19 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 19 00:19 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 19 00:19 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246647 Aug 19 00:19 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 00:19 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_ke08eze6:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9154 Aug 25 05:14 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 25 05:14 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 25 05:14 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 25 05:15 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 25 05:14 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 25 05:14 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 25 05:15 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_lga6n0hz:\r\n", - "total 4236\r\n", - "-rw-r--r-- 1 xilinx xilinx 9172 Aug 28 16:11 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 28 16:11 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 28 16:12 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 28 16:12 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 28 16:11 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 28 16:11 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 28 16:12 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_lyzs0vjq:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9152 Aug 29 16:46 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 29 16:46 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 29 16:46 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 29 16:46 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 29 16:46 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246215 Aug 29 16:46 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 29 16:46 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_n1bf2coh:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9154 Aug 28 07:16 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 28 07:16 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 28 07:16 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 28 07:16 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 28 07:16 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 28 07:16 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 28 07:16 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_n6az3jmc:\r\n", - "total 4220\r\n", - "-rw-r--r-- 1 xilinx xilinx 9391 Sep 4 03:35 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Sep 4 03:35 finn\r\n", - "-rw-r--r-- 1 root root 205 Sep 4 03:36 nw_metrics.txt\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Sep 4 03:35 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Sep 4 03:35 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Sep 4 03:36 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_n_yhs0wi:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9265 Aug 15 04:42 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 15 02:25 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 15 02:25 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 15 04:42 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 15 02:25 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 15 02:25 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 15 04:42 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_om0rv8kw:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9219 Aug 16 02:01 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 16 02:01 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 16 02:01 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 16 02:01 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 16 02:01 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246647 Aug 16 02:01 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 16 02:01 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_p8vv_rbe:\r\n" - ] - }, + "data": { + "text/plain": [ + "'/home/xilinx/finn_dev_maltanar/pynq_deployment_obskagv5'" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "target_dir_pynq = target_dir + \"/\" + model.get_metadata_prop(\"pynq_deployment_dir\").split(\"/\")[-1]\n", + "target_dir_pynq" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 8820 Aug 19 13:19 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 13:19 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 144 Aug 19 13:19 input.npy\r\n", - "-rw-r--r-- 1 root root 96 Aug 19 13:19 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 19 13:19 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246645 Aug 19 13:19 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 13:19 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_ph6e_tf5:\r\n", - "total 4288\r\n", - "-rw-r--r-- 1 xilinx xilinx 9229 Aug 21 10:09 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 21 10:09 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 21 10:10 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 21 10:10 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045675 Aug 21 10:09 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 301904 Aug 21 10:09 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 21 10:10 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_pt546ihb:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9152 Aug 27 06:25 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 27 06:25 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 27 06:25 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 27 06:25 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 27 06:25 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246215 Aug 27 06:25 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 27 06:25 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_rkgdftut:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 8820 Aug 18 12:54 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 18 12:54 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 144 Aug 18 12:54 input.npy\r\n", - "-rw-r--r-- 1 root root 96 Aug 18 12:54 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 18 12:54 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246645 Aug 18 12:54 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 18 12:54 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_rpurccjo:\r\n", - "total 4288\r\n", - "-rw-r--r-- 1 xilinx xilinx 9230 Aug 15 08:31 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 15 08:31 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 15 08:31 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 15 08:31 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045675 Aug 15 08:31 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 301904 Aug 15 08:31 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 15 08:31 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_sal6h506:\r\n", - "total 4220\r\n", - "-rw-r--r-- 1 xilinx xilinx 9389 Sep 4 03:35 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Sep 4 03:35 finn\r\n", - "-rw-r--r-- 1 root root 205 Sep 4 03:37 nw_metrics.txt\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Sep 4 03:35 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246215 Sep 4 03:35 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Sep 4 03:37 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_sd_7cw4n:\r\n", - "total 4280\r\n", - "-rw-r--r-- 1 xilinx xilinx 8821 Aug 19 09:36 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 09:36 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 19 09:36 input.npy\r\n", - "-rw-r--r-- 1 root root 205 Aug 19 10:58 nw_metrics.txt\r\n", - "-rw-r--r-- 1 root root 120 Aug 19 09:36 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045675 Aug 19 09:36 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 301904 Aug 19 09:36 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 10:58 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_ss_xv2xy:\r\n", - "total 4220\r\n", - "-rw-r--r-- 1 xilinx xilinx 9408 Sep 4 03:35 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Sep 4 03:35 finn\r\n", - "-rw-r--r-- 1 root root 205 Sep 4 03:40 nw_metrics.txt\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Sep 4 03:35 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Sep 4 03:35 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Sep 4 03:40 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_t9yxn329:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9212 Aug 16 08:11 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 16 08:11 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 144 Aug 16 08:11 input.npy\r\n", - "-rw-r--r-- 1 root root 96 Aug 16 08:11 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 16 08:11 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246645 Aug 16 08:11 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 16 08:11 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_tc39mytd:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9219 Aug 16 05:44 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 16 05:44 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 16 05:44 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 16 05:44 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 16 05:44 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246647 Aug 16 05:44 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 16 05:44 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_tgt4myfy:\r\n", - "total 4276\r\n", - "-rw-r--r-- 1 xilinx xilinx 8814 Aug 19 07:32 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 07:32 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 144 Aug 19 07:32 input.npy\r\n", - "-rw-r--r-- 1 root root 96 Aug 19 07:32 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045675 Aug 19 07:32 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 301916 Aug 19 07:32 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 07:32 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_tp9a5_fy:\r\n", - "total 4236\r\n", - "-rw-r--r-- 1 xilinx xilinx 9171 Aug 28 16:11 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 28 16:11 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 28 16:13 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 28 16:13 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 28 16:11 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 28 16:11 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 28 16:13 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_tucd1097:\r\n", - "total 4228\r\n", - "-rw-r--r-- 1 xilinx xilinx 9154 Aug 29 16:29 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 29 16:29 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 29 16:29 input.npy\r\n", - "-rw-r--r-- 1 root root 206 Aug 29 16:48 nw_metrics.txt\r\n", - "-rw-r--r-- 1 root root 120 Aug 29 16:29 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 29 16:29 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 29 16:29 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 29 16:48 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_ub1tgpmc:\r\n", - "total 4228\r\n", - "-rw-r--r-- 1 xilinx xilinx 9219 Aug 22 12:43 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 22 12:43 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 22 12:43 input.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 120 Aug 23 04:02 output_golden.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 23 04:02 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 22 12:43 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 22 12:43 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 23 04:02 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_ucr_973r:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9152 Aug 30 12:47 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 30 12:47 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 30 12:47 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 30 12:47 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 30 12:47 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246215 Aug 30 12:47 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 30 12:47 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_uxodq9a4:\r\n", - "total 20\r\n", - "-rw-r--r-- 1 xilinx xilinx 8820 Aug 19 13:04 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 13:04 finn\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 13:04 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_w0ou6nez:\r\n", - "total 4220\r\n", - "-rw-r--r-- 1 xilinx xilinx 9391 Sep 4 01:13 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Sep 4 01:13 finn\r\n", - "-rw-r--r-- 1 root root 204 Sep 4 01:14 nw_metrics.txt\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Sep 4 01:13 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Sep 4 01:13 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Sep 4 01:14 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_wr1hljxk:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9219 Aug 15 10:07 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 15 10:07 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 15 10:07 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 15 10:07 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 15 10:07 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 15 10:07 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 15 10:07 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_wvxkayc8:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9152 Aug 28 16:11 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 28 16:11 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 28 16:12 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 28 16:12 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 28 16:11 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246215 Aug 28 16:11 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 28 16:12 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_x1yyq4s3:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9154 Aug 27 15:49 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 27 15:49 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 27 23:07 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 27 23:07 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 27 15:49 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 27 15:49 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 27 23:07 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_xec0no1y:\r\n", - "total 4276\r\n", - "-rw-r--r-- 1 xilinx xilinx 8819 Aug 19 09:59 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 09:59 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 19 09:59 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 19 09:59 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045675 Aug 19 09:59 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 301911 Aug 19 09:59 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 09:59 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_xf594c4i:\r\n", - "total 4288\r\n", - "-rw-r--r-- 1 xilinx xilinx 8837 Aug 19 09:27 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 09:27 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 19 09:27 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 19 09:27 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045675 Aug 19 09:27 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 301904 Aug 19 09:27 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 11:02 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_xuytd3ej:\r\n", - "total 4236\r\n", - "-rw-r--r-- 1 xilinx xilinx 8845 Aug 19 10:23 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 10:23 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 19 10:23 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 19 10:23 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 19 10:23 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 19 10:23 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 10:23 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_xxozg07g:\r\n", - "total 4240\r\n", - "-rw-r--r-- 1 xilinx xilinx 9172 Aug 30 12:14 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 30 12:14 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 12416 Aug 30 12:14 input.npy\r\n", - "-rw-r--r-- 1 root root 208 Aug 30 12:51 nw_metrics.txt\r\n", - "-rw-r--r-- 1 root root 120 Aug 30 12:15 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 30 12:14 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 30 12:14 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 30 12:51 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_y5v0yh_k:\r\n", - "total 4228\r\n", - "-rw-r--r-- 1 xilinx xilinx 8827 Aug 15 00:25 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 15 00:25 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 15 00:25 input.npy\r\n", - "-rw-r--r-- 1 root root 206 Aug 15 00:34 nw_metrics.txt\r\n", - "-rw-r--r-- 1 root root 120 Aug 15 00:26 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 15 00:25 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Aug 15 00:25 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 15 00:34 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_ybgtgj39:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9147 Aug 30 09:56 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 30 09:56 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 144 Aug 30 09:56 input.npy\r\n", - "-rw-r--r-- 1 root root 96 Aug 30 09:56 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 30 09:56 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246209 Aug 30 09:56 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 30 09:56 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_yqc16_8w:\r\n", - "total 20\r\n", - "-rw-r--r-- 1 xilinx xilinx 8820 Aug 18 12:40 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 18 12:40 finn\r\n", - "-rw-r--r-- 1 root root 32 Aug 18 12:40 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_yt2dpnht:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 9217 Aug 16 13:40 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 16 13:40 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 16 13:40 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 16 13:41 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 16 13:40 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246651 Aug 16 13:40 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 16 13:41 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_z5zzp4mm:\r\n", - "total 4212\r\n", - "-rw-r--r-- 1 xilinx xilinx 9409 Sep 4 13:07 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Sep 4 13:07 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Sep 4 13:07 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Sep 4 13:07 resizer.hwh\r\n", - "\r\n", - "/home/xilinx/finn_dev_maltanar/pynq_deployment_zn65nxuo:\r\n", - "total 4224\r\n", - "-rw-r--r-- 1 xilinx xilinx 8825 Aug 19 00:58 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Aug 19 00:58 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Aug 19 00:58 input.npy\r\n", - "-rw-r--r-- 1 root root 120 Aug 19 00:59 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Aug 19 00:58 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246651 Aug 19 00:58 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Aug 19 00:59 sds_trace_data.dat\r\n" + "total 4216\r\n", + "-rw-r--r-- 1 xilinx xilinx 8508 Sep 21 13:19 driver.py\r\n", + "drwxr-xr-x 4 xilinx xilinx 4096 Sep 21 13:19 finn\r\n", + "-rw-r--r-- 1 xilinx xilinx 4045671 Sep 21 13:19 resizer.bit\r\n", + "-rw-r--r-- 1 xilinx xilinx 246205 Sep 21 13:19 resizer.hwh\r\n", + "-rw-r--r-- 1 xilinx xilinx 1727 Sep 21 13:19 validate.py\r\n" ] } ], "source": [ - "! sshpass -p {password} ssh {username}@{ip} -p {port} 'ls -l {target_dir}/*'" + "! sshpass -p {password} ssh {username}@{ip} -p {port} 'ls -l {target_dir_pynq}'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "We only have two more steps to be able to remotely execute the deployed bitfile with some test data from the CIFAR-10 dataset. Let's load up some test data that comes bundled with FINN -- and before you ask, that's supposed to be a cat (CIFAR-10 class number 3)." + "We only have two more steps to be able to remotely execute the deployed bitfile with some test data from the CIFAR-10 dataset. Let's load up some test data that comes bundled with FINN -- *and before you ask, that's supposed to be a cat (CIFAR-10 class number 3)*." ] }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "<matplotlib.image.AxesImage at 0x7fc315a36198>" + "<matplotlib.image.AxesImage at 0x7f25af026da0>" ] }, - "execution_count": 24, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPsAAAD5CAYAAADhukOtAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/d3fzzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAe8klEQVR4nO2da4yc53Xf/2feuex9Z5dLLpdXURJlRVZiSqFVO1EV2akDRUkgGwhcu4ChAEYUBBEQA+kHwQVqF+gHp6ht+EPhgq5VK4ZrWbUtSEiE1LYcRDDsSKJu1IW6ULxIJJdcksu97+zcTj/MyKXU5//sksudpf38fwDB2efs875nnnnPvLPPf8455u4QQvz6k1tvB4QQnUHBLkQiKNiFSAQFuxCJoGAXIhEU7EIkQn41k83sDgBfA5AB+B/u/qXY7/d3533DQDF8rPh5Ltq3mKTo4Lbouci06PH40eJGj70Px/wP2yx2MjIHAGLK7KXJttyP2NHcL/4aaB2TrQenGX3Sl+ZH7NkxSzPiBvNxer6OxaVG0MlLDnYzywD8NwAfA3AcwNNm9qi7v8LmbBgo4gv/7vrw8bxJz1UshN20HA+IanWJ2uqNGj9XMfxmBACNZthHj7wqlmtQWy6jJnitlx8T/JiFYiU4nkVeastx/xvNOrXV6vw1azZJUBj3ox6+RgEAS+x4WC5wwz7G3tSrVX59NBqRdYxcw7nIa1Yl19U8X3osVMPH+/ZPTkR8uHRuAXDI3Q+7exXAgwDuWsXxhBBryGqCfSuAty/4+Xh7TAhxBbLmG3Rmdo+Z7Tez/XOLkc8lQog1ZTXBfgLA9gt+3tYeexfuvs/d97r73r7uVe0HCiFWwWqC/WkAu81sl5kVAXwKwKOXxy0hxOXmkm+17l43s3sB/B+0pLf73f3l6BwYquT9xX2RTyS7lSXwHesc+FZ3Ph/ZIb8ExcsKfNJStUpt9WbEx4j0lkV28fNkmjX5DjPqXLmI7SI3I/5XrSs43shKfE7seA2+HtbkPhpRE7oir1neuC2XjygXtcgaG/8T1skae0RnyLKwjzFlYlWfq939MQCPreYYQojOoG/QCZEICnYhEkHBLkQiKNiFSAQFuxCJ0OFvuTicJVY4l3+8EZ5jDS7VNGtc8sq6IzIOeDIDk7yaEemnWChQW925rVmLPLfI+er1sM0imVy5iMxnGU8M8iwsrwHAYiMssZ06x+Wp+Sr3cW6Oz8ucr0d/V3gdi8Zf54GebmrrLnEJrZnj11wuKqOFfeRXB1BjyVcR7U13diESQcEuRCIo2IVIBAW7EImgYBciETq6G2/uyDfIrnsW2S0mSRylLJIfn49tS0YSHUiCAQCaCFOPFQvLcT8KRb7ru/mq66htZuostZ09txA+V57vqucQSU6p80tk0bn/B4+FffTSMJ1Ty3hiU7WP7/zPTU9S24mJqeB4X4k/r8ap8BwA2DHK13FDP1/HrnysnFX4Oi5GLuEGUSBi5bZ0ZxciERTsQiSCgl2IRFCwC5EICnYhEkHBLkQirEO517A0YPkyn0HkhHqsA0eOy3LVOk9YKEZqpDUapFZYJDEFESmkGKmD9q/+zceo7Zmf/4LaTk6dC47PRyS0eoNLXseOn6G2Iyd495FSeSw4vm10F53jpX5qq+b561Lo20ht9cpccPzcxEk6p6fM5cHjc6eprUJqJQLAaD9Pa+kphBNhGrWwjAoArIlPpJOX7uxCpIKCXYhEULALkQgKdiESQcEuRCIo2IVIhFVJb2Z2FMAsgAaAurvvjf1+03JYyoXllemFHjqvQdoTDfVxeW0g43JYPlKPrRmR5ZisQevqIZ5Ft7Bwntp++vePUNvpKV6v7/Rc+HzHTvBzHRt/m9qyrj5qa2QD1NY7MBIcL/Tw4+W7eBZdKdKSqSvHpcOz1XBbsbFtO+icyuI8tR05wqW3yekKtWXGn/dVG8O2QoNLecbqMkak3suhs3/E3XnOpRDiikAf44VIhNUGuwP4kZk9Y2b3XA6HhBBrw2o/xt/q7ifMbBOAH5vZq+7+xIW/0H4TuAcAhvp5lQ8hxNqyqju7u59o/z8B4GEAtwR+Z5+773X3vX3d6/BVfCEEgFUEu5n1mln/O48B/AGAly6XY0KIy8tqbrWjAB5ub/XnAfwvd//H2IR603BmMZzhM1kr03lP/Pyfg+O/sZtLLh95f1j6AYChSHHLJslsA4AcadOTy/GMpobztkURNQlHjh2htslFngHmPUPB8ayPSz+5oVlq6y4PUlu1wqWmKmmvNDDEX7OBPm6bOHWK2mbO84KT/cXwJd7VzWW+t85zcanQv4nazpx6i9r6TvM13jwQ9qXbIpmKpAgrIrLyJQe7ux8G8IFLnS+E6CyS3oRIBAW7EImgYBciERTsQiSCgl2IROhsr7eshPxguODgwjn+vlMrhgsKTi6EpTAAWKjy3mADRZ7Z1iR9t9rG4HCW8Yy9SpVLPGd48hrOznIJMFYQcWhjOJtrvjlD54yA+5hFMtGqBb6Olfmw1FSZ437sHN1AbQtEQgOACZLZBgBWCMuU05O8mCMiBUQX53lGXFbk18HEDM86HCfZcjtH+PWdYwlxsRaH3CSE+HVCwS5EIijYhUgEBbsQiaBgFyIROrob39Xdi/f91v+XBQsAOP4vr9F5fYPh3fhbPhw+FgD0ZMeorUp2igEgl+dJLVYI70w3vEzn9G/aTm3PHzhEbX1lvjO9def7qc1z4d3nQmTnvLkUbhkFANVqpMVWZK0yksTx8gsH6JyBUqRFUi9PkumN1LU7eSpcM65OlBUAyMgOPgAM9XN1YrrBk57OT3LbkVPTwfEto5vpnDxTlCLZVbqzC5EICnYhEkHBLkQiKNiFSAQFuxCJoGAXIhE6Kr3lsjx6BsOS0s6rr6PzFolqsWPXtXTOSI1LK1NHuCxXiyTCNOrhRIdbbvs4nbPjat4Ra9dvHqW2Z557gdqG+rgkc3IiXD8t77yMd6nAJS/wZcRcJClkmtSFG+rl54qcCo2IVDayMSzNAsBSLfx6nj0flrsAwCItu/ojdfLyGQ+naoUn3hx++3hwfGOZy3y7t4XbqHnk/q07uxCJoGAXIhEU7EIkgoJdiERQsAuRCAp2IRJhWenNzO4H8McAJtz9xvbYMIDvAbgKwFEAn3R3XmTrnWPlcshK4Qylk6cP0nl7fvuDwfHeQV7zK5s9QW2NeqRFTqTW2eG3w9lytw6F6+oBAHq2UVN/L5djuvI8k6s7Uuusq0gytiJ11bZuGaO2V958k9qKRV7nb2Y2vFZXbdtN51x3/Q3UNjnJL6++gTK1nTw1ERy3HK/vVh7iNf6mI7Xksohk191TprbF2fB1cIhcbwDQXQyfq1aPZClSy//jWwDueM/YfQAed/fdAB5v/yyEuIJZNtjb/dbf+w2JuwA80H78AICPX163hBCXm0v9m33U3cfbj0+h1dFVCHEFs+oNOnd3RL7paGb3mNl+M9s/Pc1rhgsh1pZLDfbTZjYGAO3/w7sgANx9n7vvdfe9g4MDl3g6IcRqudRgfxTA3e3HdwN45PK4I4RYK1YivX0XwO0ARszsOIAvAPgSgIfM7LMAjgH45EpOZpah0BW+u1cqvCDi0lI47a0QkaB6evmniN5IS6NSxrPe+vLhfk3f2vdNOudP/u291FaYP0VtxVIkeynHfdx19dbg+MTkSTqnMsez1zZvGqG2yRkuHS5Vw6/n1dfyTMVrruWZj9PPPUtt87Nz1DYzH/ax3uAS1eJiuB0TAJTLg9TWcC6VDZR5tl+9Gn49sxzvD3Z8PPxhukqy/IAVBLu7f5qYfn+5uUKIKwd9g06IRFCwC5EICnYhEkHBLkQiKNiFSISOFpyEGSwLSxALEfmnsrAYHC9EenLNnuNZXsi49FYAL0Q4Vg5nSr1xkPdsO3mc27DA5bBjx49S202beY+7rTvDxSi3TPBvNM8f4gU4h0tlausvc1nu8OGjwfGxLWFpEACmZvg3LGsRqez0Gd6rrukWHLdIcciFiPRmOX5dhc/UojdSqBLNcJZd0cLXPQBUz4VlW4+U7dSdXYhEULALkQgKdiESQcEuRCIo2IVIBAW7EInQWenNAZCeXZlzaWVsJNwfrqeLS28/PcALJQ5FivLtHubZSV2lsOxSzHOp5szEUWprLvHihTuu4UUss8jz7hkYCo6PjPLCl+cmedbYdCSzrRFRNzeS/mv5iFxaIdlfQDyba7HCs8PqxEk2DgCVJZ6BWa/z++OGkU3UZsavq6KFr5+SRfoOejjjsxApeqk7uxCJoGAXIhEU7EIkgoJdiERQsAuRCB3djTcDCvlwMslgH09OKfeHbdbku5UzzhMPzp7nKQsj/XxJeovhHdVGLlwjDwCOnjxKbaNDvJ7Zzmt5K6QKPx2eeibcRuvEON/57+8L7+ADQKHAWzy9fOgt7gi5jzQj95elyG783DxPCikP83ZNdZIIM36aFkRGbz9/XfIZTzTp6eE1EYusLRcA1MKJPI35KTpldFN/cDxf4G2tdGcXIhEU7EIkgoJdiERQsAuRCAp2IRJBwS5EIqyk/dP9AP4YwIS739ge+yKAPwdwpv1rn3f3x1ZywszCUsjmTeHaaS0niYwTSYAY28YTSfZH5LAp45KdZ+E6eYMjPKlicIAnQBS6wvIJAFwVkd76BsOJQQDwP+//dnB8IbJWM4uT1LawyGsDFiJXz+ah8POuTPJ6d/Mk0QgABgf46/Lqa29Q2+nTZ4LjM5GWUeUyf2IDvX3UljnXRAtVvo4ZqUW4sZcfb7ArHEf5yO17JXf2bwG4IzD+VXff0/63okAXQqwfywa7uz8BgL/1CyF+JVjN3+z3mtkBM7vfzPhXsIQQVwSXGuxfB3ANgD0AxgF8mf2imd1jZvvNbP/U1NQlnk4IsVouKdjd/bS7N9y9CeAbAGjXAnff5+573X1vuVy+RDeFEKvlkoLdzMYu+PETAF66PO4IIdaKlUhv3wVwO4ARMzsO4AsAbjezPWhVlTsK4C9WcrJcLkezfwaGuPRWb4TdLOV5JtF1u3ZQ2/5nuOQ1U7iW2po2Gxwf3crltVcO/gu1/c7v/Rm1/eLnfN78fKRNUvVscHzi1Nt0Tuw9f67GbXlwaWgoF86y29rNfZ8+wyW0esa3hUY3cVujEc6kW4y0eKos8rp785EaevUml/NqlRPUtqkQzujb0sez6Jbq4Tmxu/eywe7unw4Mf3O5eUKIKwt9g06IRFCwC5EICnYhEkHBLkQiKNiFSISOFpzM5XLo7QtnLw2NjNB5dQu7WckV6ZyuvgFqK5d5QcG33j5Fbbd+8P1hP+Z4O6me/nDWFQCMnzhObYdef53a6g3enihH6g3Oz0zTOf0bxqhteprLUIN9vBjl+667MTj+9Auv0jnPvnqU2m69/Q+prVDkEtXhQ4eC49Oz/HnFimJWFrm8tnOUS7rdvbyg6vBweJ7neQHOejVc+NJJVimgO7sQyaBgFyIRFOxCJIKCXYhEULALkQgKdiESoaPSm3sTzXpY8hgc5oX85hfDhQgXGrzvVpbx97Ed27dR2+sv88yr6YWwxNbXyzPstl9DTTj2Oi++eOLkOLV9+MMfpLaFhbA01L9lK50zvIUX53xrkktli0tcciz2hvuvDWzcTufc1M9flzNnwv3QAODosReobX4xLFNOTXMJbePGjdQ26Px12dnHJdFNA7wHW8HCmYDVGu9v10skthx4TOjOLkQiKNiFSAQFuxCJoGAXIhEU7EIkQkd345v1GmbPhXczuyO1vZYq4V1Oa3L3zfiu5Mgwb5/0eu4wtU1Mhlv4nMv4rvRgH6+td/2NPCHn8DFeM67GuyRhaiasduzevZvO2b2LSwbHxnkCzcsvv0ht586Gk1OKJa66DPXxRJLjL3NV4NQ5XtfOSLJUFmm9FWsdtpPnmWBHP08M6srxpJalSvj6aTZ5bcNanRyPX/a6swuRCgp2IRJBwS5EIijYhUgEBbsQiaBgFyIRVtL+aTuAvwMwitbG/j53/5qZDQP4HoCr0GoB9Ul3D/f8abO0tITDh8LS1o7dv0HndeXC0luzyhMF8l0RGSRi6+/n0lDfQLiu3fXXv4/O+cmPHqO2hWle765neBO1HTo+QW3bt4WTcna972Y6p1Tkl8HVO3iSz9Qkf7lfORhOKGo61w1PTPFEkhmSDAUAlQaXbWemwlLkps086eatc7w+3fB2LpeeK3E/0OTPbaoefm6e59fpEjleFTzhZiV39jqAv3H3GwB8CMBfmdkNAO4D8Li77wbwePtnIcQVyrLB7u7j7v5s+/EsgIMAtgK4C8AD7V97AMDH18hHIcRl4KL+ZjezqwDcBOBJAKPuv0zuPYXWx3whxBXKioPdzPoA/ADA59z9Xd9PdHcH+aKemd1jZvvNbP/sLC8YIIRYW1YU7GZWQCvQv+PuP2wPnzazsbZ9DEBw18jd97n7XnffG9v8EkKsLcsGu5kZWv3YD7r7Vy4wPQrg7vbjuwE8cvndE0JcLlaS9fa7AD4D4EUze7499nkAXwLwkJl9FsAxAJ9c7kALS3U8fygsG+248RY6r4lwtpmxzB8AaPL0n5nZWWqbmjpLbRuG9wTH77zjI3TOng9cT20P/fBhajPjEsrg4BC1bd0SlpT6Bsp0TlYPry8ADG/ml8jYrhq1TXeHZaPnXuD14sbneEqZF3g7r8HNPItx5JqwVJZFZK2Gcz9e83D7MgA4dIrLg8WMH3OxUgmOL0Qu73ozfH3MNnh24LLB7u4/A8A8/f3l5gshrgz0DTohEkHBLkQiKNiFSAQFuxCJoGAXIhE6WnCy0jC8Pt0dtJ1t8AKAXghLE7kqL4boRJoAgFyO27aM8Wyzf/074cyxrgKXXHbt5G2X/uhPP0Vt33/4H6jt7Cn+vMenw8ULK5VDdE4RXOOZXOS2Q8d41h6qYVnOR3iG4NCmcJFKAGhGKim2vvNF5nWFj9m0cCFKAKhF2opNN/i5ugr8mF15Lr3NWzjLrlbg5/JmeH0bEclWd3YhEkHBLkQiKNiFSAQFuxCJoGAXIhEU7EIkQkelt6WG4fWp8PvLIz/jfcP27BwJjm8u8gyknkIkW2sz7782NsKzq665mhQpdF5McPzMOWq7/0Eurz37/CvUxnrfAQBNBHT+vu4NfrxGia9HI8eloTzCEms9Ig3Vc+E5ANAVu1IjWWqVavh5e47PyUcy4rIm7+vnFS5T1sHnFZphHzPjr1m1FvY/0uJQd3YhUkHBLkQiKNiFSAQFuxCJoGAXIhE6uhvfgGEuF04WePzZ1+m8N94Mt4y647dvoHOu2cLb9Bw5HG5NBAC3ffBGausiiQmzVb7D/NA/Pk1tz71yktoW6pFWQpHd4lwh/P7djNTkyxnfRY7tWjeaPAFoieww1xp8jhmvabeESFKI8+eWz5Od7ozf53p6eEJLEdz/Bt9wR8N4qDXIxHqNvy7F/nJw3HL8PLqzC5EICnYhEkHBLkQiKNiFSAQFuxCJoGAXIhGWld7MbDuAv0OrJbMD2OfuXzOzLwL4cwBn2r/6eXd/LHqyfB4bRjYGbZPnuXwyfn4qOP7zF3irm0ZtZ8QTLq1s3EySXQBYFpbDntr/Ep3zDz/9BbUtNXnNNeS59JbLXfx7dGOJJ7t4RJZrRuS1mOTFWigV8vySs4xLmMj4a5aPzMuy8PliTUazyPrmnMuDjUiyUTMiHTLNbvNmLh/3D4Rtb5Yi68Q9+CV1AH/j7s+aWT+AZ8zsx23bV939v67gGEKIdWYlvd7GAYy3H8+a2UEAvGSqEOKK5KI+D5rZVQBuAvBke+heMztgZvebGW8tKoRYd1Yc7GbWB+AHAD7n7jMAvg7gGgB70Lrzf5nMu8fM9pvZ/voib5UshFhbVhTs1qrC/wMA33H3HwKAu59294a7NwF8A0Cwwbq773P3ve6+N9/NG0EIIdaWZYPdzAzANwEcdPevXDA+dsGvfQIA35IWQqw7K9mN/10AnwHwopk93x77PIBPm9ketOS4owD+YrkDmRmVSQoFLjXVK2E54ejpGTpnaf4gtd1283XU1l0eo7bpSlgi+ecn99M5FeeZS7U6l3FKJZ7Z1ozUQVtYCLcSipFFMrKMJ70h0pEJJSJ5xbKyELFZicuU3d28dl2eSH21SEbZ7Pw8tTUiMuVSnb8ug0PhOooAMDoWtvVFCu8tzob/JPbItbGS3fifAQi95FFNXQhxZaFv0AmRCAp2IRJBwS5EIijYhUgEBbsQidDRgpNwR7NOsqhiGUNZWIaqgmc7TcwtUduzr/FCj3cucGll1sNyx4nz/JuBpT6eXVVf4P5Xlrj/PT0RqYm0vYodz3Lcj1ykXVMsg82JjOaR+0shIjfO1Xj2XbXOpTImy8Uy9mIS2nyk9VZfmctr5Y285Vi1Hj7ma6/yrM4CyUasVbl/urMLkQgKdiESQcEuRCIo2IVIBAW7EImgYBciETosvQFgWUPO5Y4sCxfrazqXhRo5XuDv6ASXyu5/iOf3fPT2vcHxIyfPBMcBYKERK0IYkaG6eOHArMhtPaSHWbGby1qLs1y6imWHeUSiKpCMrSzPX7PYubJIUclYH7vFhbmLnhM7V3lomNo2jPKMybPnJqlt6uyp8PhbvCfhtbt2hQ0RSVF3diESQcEuRCIo2IVIBAW7EImgYBciERTsQiRCR6W3LJ9huFwO2ioVLofNL4YzeYoZz/6qR2ShXKS45RNPHaC2IyfD2XLT87xw5OTcIrWRZCcAQG9vJFsuUlSwVAo/t3xEruvq5hllWSQjLl/gx2yQ+0g9InlZxObOfWzU+PpXa+FF7u7iUuTIhg3UNjTC5bVqJHNzqRgpHkn6szXzXD6er4Svq2ZEwtadXYhEULALkQgKdiESQcEuRCIo2IVIhGV3482sC8ATAErt3/++u3/BzHYBeBDABgDPAPiMu0f2lwFvOpbILmIp8raz1AjvthYyvhtc55vI8Bw/Wa6b74IfIwkvuUhyR73Gd5hjikGlUqG2+Uh7ohx5bmyXHgB6i3zXtzuSQJPLcf+LXeHzdffw9a1WeSLM2UmeSNIEn5cvhNdjaKCXzhkdLlPb5s08EWZqntf5m506T21z01PB8fIwP9fZM2eD4/VIMtFK7uxLAD7q7h9Aqz3zHWb2IQB/C+Cr7n4tgPMAPruCYwkh1ollg91bvJMnWGj/cwAfBfD99vgDAD6+Fg4KIS4PK+3PnrU7uE4A+DGANwFMuf+yRelxAFvXxEMhxGVhRcHu7g133wNgG4BbAFy/0hOY2T1mtt/M9tcWeItlIcTaclG78e4+BeCfAHwYQNnsl429twE4Qebsc/e97r630DOwGl+FEKtg2WA3s41mVm4/7gbwMQAH0Qr6P23/2t0AHlkjH4UQl4GVJMKMAXjAzDK03hwecve/N7NXADxoZv8ZwHMAvrncgZrNJpYWw5JSKTM6r4d42azxJJNI1yI0wSWjWCJBk7SbqlcjCRwN/rxiLYhitmYkEYZJb+fPc+lnMrKOA31cohqM1GMbILXwusClvEaTS1d5iyTrlPiLvVQJH7OU569L7Fz1hemIjfs/N3WO2pokWaerxCXRCquTZ5HnRS1t3P0AgJsC44fR+vtdCPErgL5BJ0QiKNiFSAQFuxCJoGAXIhEU7EIkgsUknst+MrMzAI61fxwBEE7d6Szy493Ij3fzq+bHTnffGDJ0NNjfdWKz/e4ebp4mP+SH/LjsfuhjvBCJoGAXIhHWM9j3reO5L0R+vBv58W5+bfxYt7/ZhRCdRR/jhUiEdQl2M7vDzF4zs0Nmdt96+ND246iZvWhmz5vZ/g6e934zmzCzly4YGzazH5vZG+3/h9bJjy+a2Yn2mjxvZnd2wI/tZvZPZvaKmb1sZn/dHu/omkT86OiamFmXmT1lZi+0/fhP7fFdZvZkO26+Z2a84moId+/oPwAZWmWtrgZQBPACgBs67Ufbl6MARtbhvLcBuBnASxeM/RcA97Uf3wfgb9fJjy8C+PcdXo8xADe3H/cDeB3ADZ1ek4gfHV0TAAagr/24AOBJAB8C8BCAT7XH/zuAv7yY467Hnf0WAIfc/bC3Sk8/COCudfBj3XD3JwC8tzbyXWgV7gQ6VMCT+NFx3H3c3Z9tP55FqzjKVnR4TSJ+dBRvcdmLvK5HsG8F8PYFP69nsUoH8CMze8bM7lknH95h1N3H249PARhdR1/uNbMD7Y/5a/7nxIWY2VVo1U94Euu4Ju/xA+jwmqxFkdfUN+hudfebAfwhgL8ys9vW2yGg9c6O1hvRevB1ANeg1SNgHMCXO3ViM+sD8AMAn3P3d1Un7eSaBPzo+Jr4Koq8MtYj2E8A2H7Bz7RY5Vrj7ifa/08AeBjrW3nntJmNAUD7/4n1cMLdT7cvtCaAb6BDa2JmBbQC7Dvu/sP2cMfXJOTHeq1J+9xTuMgir4z1CPanAexu7ywWAXwKwKOddsLMes2s/53HAP4AwEvxWWvKo2gV7gTWsYDnO8HV5hPowJqYmaFVw/Cgu3/lAlNH14T50ek1WbMir53aYXzPbuOdaO10vgngP6yTD1ejpQS8AODlTvoB4LtofRysofW312fR6pn3OIA3APwEwPA6+fFtAC8COIBWsI11wI9b0fqIfgDA8+1/d3Z6TSJ+dHRNAPwWWkVcD6D1xvIfL7hmnwJwCMD/BlC6mOPqG3RCJELqG3RCJIOCXYhEULALkQgKdiESQcEuRCIo2IVIBAW7EImgYBciEf4vt7E0CllzrOkAAAAASUVORK5CYII=\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" } ], "source": [ @@ -1336,109 +733,147 @@ "import numpy as np\n", "\n", "fn = pk.resource_filename(\"finn\", \"data/cifar10/cifar10-test-data-class3.npz\")\n", - "x = np.load(fn)[\"arr_0\"].astype(np.float32)\n", - "x = x / 255\n", - "plt.imshow(x.reshape(3, 32,32).transpose(1, 2, 0))" + "x = np.load(fn)[\"arr_0\"]\n", + "x = x.reshape(3, 32,32).transpose(1, 2, 0)\n", + "plt.imshow(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Recall that we partitioned our original network into a parent graph that contained the non-synthesizable nodes and a child graph that contained the bulk of the network, which we turned into a bitfile. We'll load up the parent graph, modify the `StreamingDataflowPartition` node so that it points to the deployed ONNX graph." + "Recall that we partitioned our original network into a parent graph that contained the non-synthesizable nodes and a child graph that contained the bulk of the network, which we turned into a bitfile. The only operator left outside the FPGA partition was a `Transpose` to convert NCHW images into NHWC ones. Thus, we can skip the execution in the parent as long as we ensure our image has the expected data layout, which we have done above." ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 43, "metadata": {}, "outputs": [], "source": [ - "# point to the PYNQ-deployed model as the StreamingDataflowPartition in the parent\n", - "parent_model = ModelWrapper(build_dir+\"/end2end_cnv_w1a1_dataflow_parent.onnx\")\n", - "sdp_node = parent_model.get_nodes_by_op_type(\"StreamingDataflowPartition\")[0]\n", - "sdp_node = getCustomOp(sdp_node)\n", - "sdp_node.set_nodeattr(\"model\", build_dir + \"/end2end_cnv_w1a1_pynq_deploy.onnx\")\n", - "parent_model.save(build_dir+\"/end2end_cnv_w1a1_dataflow_parent_with_remote_bitfile_exec.onnx\")" + "import numpy as np\n", + "from finn.core.onnx_exec import execute_onnx\n", + "\n", + "model = ModelWrapper(build_dir + \"/end2end_cnv_w1a1_pynq_deploy.onnx\")\n", + "iname = model.graph.input[0].name\n", + "oname = model.graph.output[0].name\n", + "ishape = model.get_tensor_shape(iname)\n", + "input_dict = {iname: x.astype(np.float32).reshape(ishape)}\n", + "ret = execute_onnx(model, input_dict, True)" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 44, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[3.]], dtype=float32)" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "Finally, we can call `execute_onnx` on the parent graph, which will internally call remote execution with the bitfile once the `StreamingDataflowPartition` node is reached, grab the results, then continue executing the last portion of the network. " + "ret[oname]" ] }, { - "cell_type": "code", - "execution_count": 26, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "import numpy as np\n", - "from finn.core.onnx_exec import execute_onnx\n", - "iname = parent_model.graph.input[0].name\n", - "oname = parent_model.graph.output[0].name\n", - "ishape = parent_model.get_tensor_shape(iname)\n", - "input_dict = {iname: x.reshape(ishape)}\n", - "ret = execute_onnx(parent_model, input_dict, True)" + "We see that the network correctly predicts this as a class 3 (\"cat\"). " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "We'll pass the output of the network through a softmax function to interpret it as probabilities, and plot the per-class probabilities as a bar chart." + "### Validating the Accuracy on a PYNQ Board <a id='validation'></a>\n", + "\n", + "All the command line prompts here are meant to be executed with `sudo` on the PYNQ board, so we'll use a workaround (`sshpass` and `echo password | sudo -S command`) to get that working from this notebook running on the host computer.\n", + "\n", + "**Ensure that your PYNQ board has a working internet connecting for the next steps, since some there is some downloading involved.**\n", + "\n", + "To validate the accuracy, we first need to install the [`dataset-loading`](https://github.com/fbcotter/dataset_loading) Python package to the PYNQ board. This will give us a convenient way of downloading and accessing the MNIST dataset.\n", + "\n", + "\n", + "Command to execute on PYNQ:\n", + "\n", + "```pip3 install git+https://github.com/fbcotter/dataset_loading.git@0.0.4#egg=dataset_loading```" ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 45, "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "<BarContainer object of 10 artists>" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "<Figure size 1440x216 with 1 Axes>" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" + "name": "stdout", + "output_type": "stream", + "text": [ + "[sudo] password for xilinx: Requirement already satisfied: dataset_loading from git+https://github.com/fbcotter/dataset_loading.git@0.0.4#egg=dataset_loading in /usr/local/lib/python3.6/dist-packages\n", + "Requirement already satisfied: Pillow in /usr/lib/python3/dist-packages (from dataset_loading)\n", + "Requirement already satisfied: scipy in /usr/lib/python3/dist-packages (from dataset_loading)\n", + "Connection to 192.168.2.99 closed.\n" + ] } ], "source": [ - "def softmax(x):\n", - " \"\"\"Compute softmax values for each sets of scores in x.\"\"\"\n", - " e_x = np.exp(x - np.max(x))\n", - " return e_x / e_x.sum()\n", - "\n", - "logits = ret[oname].flatten()\n", - "prob = softmax(logits)\n", + "! sshpass -p {password} ssh -t {username}@{ip} -p {port} 'echo {password} | sudo -S pip3 install git+https://github.com/fbcotter/dataset_loading.git@0.0.4#egg=dataset_loading'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can now use the `validate.py` script that was generated together with the driver to measure top-1 accuracy on the CIFAR-10 dataset.\n", "\n", - "classes = [\"airplane\", \"automobile\", \"bird\", \"cat\", \"deer\", \"dog\", \"frog\", \"horse\", \"ship\", \"truck\"]\n", + "Command to execute on PYNQ:\n", "\n", - "plt.figure(figsize=(20, 3)) \n", - "plt.bar(classes, prob)" + "`python3.6 validate.py --dataset cifar10 --batchsize 1000`" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[sudo] password for xilinx: Tar File found in dest_dir. Not Downloading again\n", + "Extracting Python CIFAR10 data.\n", + "Files extracted\n", + "batch 0 / 10 : total OK 851 NOK 149\n", + "batch 1 / 10 : total OK 1683 NOK 317\n", + "batch 2 / 10 : total OK 2522 NOK 478\n", + "batch 3 / 10 : total OK 3370 NOK 630\n", + "batch 4 / 10 : total OK 4207 NOK 793\n", + "batch 5 / 10 : total OK 5044 NOK 956\n", + "batch 6 / 10 : total OK 5887 NOK 1113\n", + "batch 7 / 10 : total OK 6728 NOK 1272\n", + "batch 8 / 10 : total OK 7570 NOK 1430\n", + "batch 9 / 10 : total OK 8419 NOK 1581\n", + "Final accuracy: 84.190000\n", + "Connection to 192.168.2.99 closed.\n" + ] + } + ], + "source": [ + "! sshpass -p {password} ssh -t {username}@{ip} -p {port} 'cd {target_dir_pynq}; echo {password} | sudo -S python3.6 validate.py --dataset cifar10 --batchsize 1000'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "We see that the network correctly predicts this as a class 3 (\"cat\") with high probability. This concludes our tutorial on how to take a convolutional BNN all the way down to hardware with FINN, and execute it remotely on a PYNQ board." + "We see that the final top-1 accuracy is 84.19%, which is very close to the 84.22% reported on the [BNN-PYNQ accuracy table in Brevitas](https://github.com/Xilinx/brevitas/tree/master/brevitas_examples/bnn_pynq). " ] }, { diff --git a/notebooks/end2end_example/tfc_end2end_example.ipynb b/notebooks/end2end_example/tfc_end2end_example.ipynb index 6b7c63087..a067c6f6f 100644 --- a/notebooks/end2end_example/tfc_end2end_example.ipynb +++ b/notebooks/end2end_example/tfc_end2end_example.ipynb @@ -61,8 +61,8 @@ "-------------\n", "1. [Brevitas export](#brev_exp)\n", "2. [Network preparation](#nw_prep)\n", - "3. [Vivado HLS and IPI](#vivado)\n", - "4. [PYNQ hardware generation and deployment](#hw_test)" + "3. [Hardware build](#vivado)\n", + "4. [PYNQ deployment](#hw_test)" ] }, { @@ -84,9 +84,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "Downloading: \"https://github.com/Xilinx/brevitas/releases/download/bnn_pynq-r0/tfc_1w1a-ff8140dc.pth\" to /home/maltanar/.cache/torch/checkpoints/tfc_1w1a-ff8140dc.pth\n", - "100%|██████████| 249052/249052 [00:00<00:00, 759439.97it/s]\n", - "/workspace/brevitas/brevitas_examples/bnn_pynq/models/FC.py:83: TracerWarning: torch.tensor results are registered as constants in the trace. You can safely ignore this warning if you use this function to create tensors out of constant variables that would be the same every time you call this function. In any other case, this might cause the trace to be incorrect.\n", + "Downloading: \"https://github.com/Xilinx/brevitas/releases/download/bnn_pynq-r1/tfc_1w1a-45185b4d.pth\" to /home/maltanar/.cache/torch/checkpoints/tfc_1w1a-45185b4d.pth\n", + "100%|██████████| 249073/249073 [00:00<00:00, 767315.58it/s]\n", + "/workspace/brevitas/brevitas_examples/bnn_pynq/models/FC.py:84: TracerWarning: torch.tensor results are registered as constants in the trace. You can safely ignore this warning if you use this function to create tensors out of constant variables that would be the same every time you call this function. In any other case, this might cause the trace to be incorrect.\n", " x = 2.0 * x - torch.tensor([1.0], device=x.device)\n" ] } @@ -134,7 +134,7 @@ " " ], "text/plain": [ - "<IPython.lib.display.IFrame at 0x7f1b8e6db128>" + "<IPython.lib.display.IFrame at 0x7fe30c65e828>" ] }, "execution_count": 3, @@ -221,7 +221,8 @@ "* GiveReadableTensorNames\n", "* InferShapes\n", "* InferDataTypes\n", - "* FoldConstants" + "* FoldConstants\n", + "* RemoveStaticGraphInputs" ] }, { @@ -230,7 +231,7 @@ "source": [ "In the first two transformations (`GiveUniqueNodeNames`, `GiveReadableTensorNames`) the nodes in the graph are first given unique (by enumeration) names, then the tensors are given human-readable names (based on the node names). The following two transformations (`InferShapes`, `InferDataTypes`) derive the shapes and data types of the tensors from the model properties and set them in the `ValueInfo` of the model. These transformations can almost always be applied without negative effects and do not affect the structure of the graph, ensuring that all the information needed is available.\n", "\n", - "The last listed transformation is `FoldConstants`, which performs constant folding. It identifies a node with constant inputs and determines its output. The result is then set as constant-only inputs for the following node and the old node is removed. Although this transformation changes the structure of the model, it is a transformation that is usually always desired and can be applied to any model." + "The next listed transformation is `FoldConstants`, which performs constant folding. It identifies a node with constant inputs and determines its output. The result is then set as constant-only inputs for the following node and the old node is removed. Although this transformation changes the structure of the model, it is a transformation that is usually always desired and can be applied to any model. And finally, we have `RemoveStaticGraphInputs` to remove any top-level graph inputs that already have ONNX initializers associated with them. " ] }, { @@ -242,11 +243,11 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ - "from finn.transformation.general import GiveReadableTensorNames, GiveUniqueNodeNames\n", + "from finn.transformation.general import GiveReadableTensorNames, GiveUniqueNodeNames, RemoveStaticGraphInputs\n", "from finn.transformation.infer_shapes import InferShapes\n", "from finn.transformation.infer_datatypes import InferDataTypes\n", "from finn.transformation.fold_constants import FoldConstants\n", @@ -256,6 +257,7 @@ "model = model.transform(GiveUniqueNodeNames())\n", "model = model.transform(GiveReadableTensorNames())\n", "model = model.transform(InferDataTypes())\n", + "model = model.transform(RemoveStaticGraphInputs())\n", "\n", "model.save(build_dir+\"/tfc_w1_a1_tidy.onnx\")" ] @@ -269,7 +271,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -295,10 +297,10 @@ " " ], "text/plain": [ - "<IPython.lib.display.IFrame at 0x7f1add273cf8>" + "<IPython.lib.display.IFrame at 0x7fe2d26a7da0>" ] }, - "execution_count": 6, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -307,6 +309,157 @@ "showInNetron(build_dir+\"/tfc_w1_a1_tidy.onnx\")" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Adding Pre- and Postprocessing <a id='prepost'></a>\n", + "\n", + "In many cases, it's common to apply some preprocessing to the raw data in a machine learning framework prior to training. For image classification networks, this may include conversion of raw 8-bit RGB values into floating point values between 0 and 1. Similarly, at the output of the network some postprocessing may be performed during deployment, such as extracting the indices of the classifications with the largest value (top-K indices).\n", + "\n", + "In FINN, we can bake some of these pre/postprocessing operatings into the graph, and in some cases these can be highly beneficial for performance by allowing our accelerator to directly consume raw data instead of going through CPU preprocessing. \n", + "\n", + "We'll demonstrate this for our small image classification network as follows. Brevitas preprocesses BNN-PYNQ network inputs with `torchvision.transforms.ToTensor()` [prior to training](https://github.com/Xilinx/brevitas/blob/master/brevitas_examples/bnn_pynq/trainer.py#L85), which converts 8-bit RGB values into floats between 0 and 1 by dividing the input by 255. We can achieve the same effect in FINN by exporting a single-node ONNX graph for division by 255 (which already exists as `finn.util.pytorch.ToTensor` and merging this with our original model. Finally, we're going to mark our input tensor as 8-bit to let FINN know which level of precision to use." + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Stopping http://0.0.0.0:8081\n", + "Serving '/workspace/finn/tfc_w1_a1_with_preproc.onnx' at http://0.0.0.0:8081\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/workspace/finn/src/finn/transformation/infer_data_layouts.py:113: UserWarning: Assuming 4D input is NCHW\n", + " warnings.warn(\"Assuming 4D input is NCHW\")\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " <iframe\n", + " width=\"100%\"\n", + " height=\"400\"\n", + " src=\"http://0.0.0.0:8081/\"\n", + " frameborder=\"0\"\n", + " allowfullscreen\n", + " ></iframe>\n", + " " + ], + "text/plain": [ + "<IPython.lib.display.IFrame at 0x7fe264171f98>" + ] + }, + "execution_count": 109, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from finn.util.pytorch import ToTensor\n", + "from finn.transformation.merge_onnx_models import MergeONNXModels\n", + "from finn.core.datatype import DataType\n", + "\n", + "model = ModelWrapper(build_dir+\"/tfc_w1_a1_tidy.onnx\")\n", + "global_inp_name = model.graph.input[0].name\n", + "ishape = model.get_tensor_shape(global_inp_name)\n", + "# preprocessing: torchvision's ToTensor divides uint8 inputs by 255\n", + "totensor_pyt = ToTensor()\n", + "chkpt_preproc_name = build_dir+\"/tfc_w1_a1_preproc.onnx\"\n", + "bo.export_finn_onnx(totensor_pyt, ishape, chkpt_preproc_name)\n", + "\n", + "# join preprocessing and core model\n", + "pre_model = ModelWrapper(chkpt_preproc_name)\n", + "model = model.transform(MergeONNXModels(pre_model))\n", + "# add input quantization annotation: UINT8 for all BNN-PYNQ models\n", + "global_inp_name = model.graph.input[0].name\n", + "model.set_tensor_datatype(global_inp_name, DataType.UINT8)\n", + "\n", + "model.save(build_dir+\"/tfc_w1_a1_with_preproc.onnx\")\n", + "showInNetron(build_dir+\"/tfc_w1_a1_with_preproc.onnx\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can observe two changes in the graph above: a `Div` node has appeared in the beginning to perform the input preprocessing, and the `global_in` tensor now has a quantization annotation to mark it as an unsigned 8-bit value.\n", + "\n", + "For the postprocessing we'll insert a TopK node for k=1 at the end of our graph. This will extract the index (class number) for the largest-valued output." + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Stopping http://0.0.0.0:8081\n", + "Serving '/workspace/finn/tfc_w1_a1_pre_post.onnx' at http://0.0.0.0:8081\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " <iframe\n", + " width=\"100%\"\n", + " height=\"400\"\n", + " src=\"http://0.0.0.0:8081/\"\n", + " frameborder=\"0\"\n", + " allowfullscreen\n", + " ></iframe>\n", + " " + ], + "text/plain": [ + "<IPython.lib.display.IFrame at 0x7fe2640f4588>" + ] + }, + "execution_count": 110, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from finn.transformation.insert_topk import InsertTopK\n", + "\n", + "# postprocessing: insert Top-1 node at the end\n", + "model = model.transform(InsertTopK(k=1))\n", + "chkpt_name = build_dir+\"/tfc_w1_a1_pre_post.onnx\"\n", + "# tidy-up again\n", + "model = model.transform(InferShapes())\n", + "model = model.transform(FoldConstants())\n", + "model = model.transform(GiveUniqueNodeNames())\n", + "model = model.transform(GiveReadableTensorNames())\n", + "model = model.transform(InferDataTypes())\n", + "model = model.transform(RemoveStaticGraphInputs())\n", + "model.save(chkpt_name)\n", + "\n", + "showInNetron(build_dir+\"/tfc_w1_a1_pre_post.onnx\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice the`TopK` node that has appeared at the end of the network. With our pre- and postprocessing in place, we can move on to the next step in the flow, which is streamlining." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -319,7 +472,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -378,7 +531,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 26, "metadata": {}, "outputs": [ { @@ -404,16 +557,22 @@ " " ], "text/plain": [ - "<IPython.lib.display.IFrame at 0x7f1adc25df60>" + "<IPython.lib.display.IFrame at 0x7fe2640f4d30>" ] }, - "execution_count": 8, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "model = ModelWrapper(build_dir+\"/tfc_w1_a1_tidy.onnx\")\n", + "from finn.transformation.streamline.reorder import MoveScalarLinearPastInvariants\n", + "import finn.transformation.streamline.absorb as absorb\n", + "\n", + "model = ModelWrapper(build_dir+\"/tfc_w1_a1_pre_post.onnx\")\n", + "# move initial Mul (from preproc) past the Reshape\n", + "model = model.transform(MoveScalarLinearPastInvariants())\n", + "# streamline\n", "model = model.transform(Streamline())\n", "model.save(build_dir+\"/tfc_w1_a1_streamlined.onnx\")\n", "showInNetron(build_dir+\"/tfc_w1_a1_streamlined.onnx\")" @@ -432,7 +591,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -458,24 +617,31 @@ " " ], "text/plain": [ - "<IPython.lib.display.IFrame at 0x7f1adc2548d0>" + "<IPython.lib.display.IFrame at 0x7fe30c65e898>" ] }, - "execution_count": 9, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from finn.transformation.bipolar_to_xnor import ConvertBipolarMatMulToXnorPopcount\n", - "import finn.transformation.streamline.absorb as absorb\n", "from finn.transformation.streamline.round_thresholds import RoundAndClipThresholds\n", + "from finn.transformation.infer_data_layouts import InferDataLayouts\n", + "from finn.transformation.general import RemoveUnusedTensors\n", "\n", "model = model.transform(ConvertBipolarMatMulToXnorPopcount())\n", "model = model.transform(absorb.AbsorbAddIntoMultiThreshold())\n", "model = model.transform(absorb.AbsorbMulIntoMultiThreshold())\n", + "# absorb final add-mul nodes into TopK\n", + "model = model.transform(absorb.AbsorbScalarMulAddIntoTopK())\n", "model = model.transform(RoundAndClipThresholds())\n", "\n", + "# bit of tidy-up\n", + "model = model.transform(InferDataLayouts())\n", + "model = model.transform(RemoveUnusedTensors())\n", + "\n", "model.save(build_dir+\"/tfc_w1a1_ready_for_hls_conversion.onnx\")\n", "showInNetron(build_dir+\"/tfc_w1a1_ready_for_hls_conversion.onnx\")" ] @@ -506,7 +672,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 29, "metadata": { "scrolled": false }, @@ -534,10 +700,10 @@ " " ], "text/plain": [ - "<IPython.lib.display.IFrame at 0x7f1adc254630>" + "<IPython.lib.display.IFrame at 0x7fe30c65e748>" ] }, - "execution_count": 10, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -546,6 +712,10 @@ "import finn.transformation.fpgadataflow.convert_to_hls_layers as to_hls\n", "model = ModelWrapper(build_dir+\"/tfc_w1a1_ready_for_hls_conversion.onnx\")\n", "model = model.transform(to_hls.InferBinaryStreamingFCLayer(\"decoupled\"))\n", + "# TopK to LabelSelect\n", + "model = model.transform(to_hls.InferLabelSelectLayer())\n", + "# input quantization (if any) to standalone thresholding\n", + "model = model.transform(to_hls.InferThresholdingLayer())\n", "model.save(build_dir+\"/tfc_w1_a1_hls_layers.onnx\")\n", "showInNetron(build_dir+\"/tfc_w1_a1_hls_layers.onnx\")" ] @@ -568,7 +738,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 30, "metadata": {}, "outputs": [ { @@ -594,10 +764,10 @@ " " ], "text/plain": [ - "<IPython.lib.display.IFrame at 0x7f1add27eba8>" + "<IPython.lib.display.IFrame at 0x7fe2640abc88>" ] }, - "execution_count": 11, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -620,7 +790,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 33, "metadata": {}, "outputs": [ { @@ -629,7 +799,7 @@ "text": [ "\n", "Stopping http://0.0.0.0:8081\n", - "Serving '/tmp/finn_dev_maltanar/dataflow_partition0_8y5bzo4x/df_model.onnx' at http://0.0.0.0:8081\n" + "Serving '/tmp/finn_dev_maltanar/dataflow_partition0_q1ym9aul/df_model.onnx' at http://0.0.0.0:8081\n" ] }, { @@ -646,17 +816,18 @@ " " ], "text/plain": [ - "<IPython.lib.display.IFrame at 0x7f1b7af8d240>" + "<IPython.lib.display.IFrame at 0x7fe264098f60>" ] }, - "execution_count": 12, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from finn.custom_op.registry import getCustomOp\n", - "sdp_node = getCustomOp(parent_model.graph.node[2])\n", + "sdp_node = parent_model.get_nodes_by_op_type(\"StreamingDataflowPartition\")[0]\n", + "sdp_node = getCustomOp(sdp_node)\n", "dataflow_model_filename = sdp_node.get_nodeattr(\"model\")\n", "showInNetron(dataflow_model_filename)" ] @@ -670,7 +841,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 34, "metadata": {}, "outputs": [], "source": [ @@ -697,34 +868,28 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "CustomOp wrapper is of class StreamingFCLayer_Batch\n" + "CustomOp wrapper is of class Thresholding_Batch\n" ] }, { "data": { "text/plain": [ "{'PE': ('i', True, 0),\n", - " 'SIMD': ('i', True, 0),\n", - " 'MW': ('i', True, 0),\n", - " 'MH': ('i', True, 0),\n", - " 'resType': ('s', True, ''),\n", - " 'ActVal': ('i', False, 0),\n", + " 'NumChannels': ('i', True, 0),\n", + " 'ram_style': ('s', False, 'distributed'),\n", " 'inputDataType': ('s', True, ''),\n", - " 'weightDataType': ('s', True, ''),\n", " 'outputDataType': ('s', True, ''),\n", - " 'accDataType': ('s', False, 'INT32'),\n", - " 'binaryXnorMode': ('i', False, 0),\n", - " 'noActivation': ('i', False, 0),\n", + " 'inFIFODepth': ('i', False, 2),\n", + " 'outFIFODepth': ('i', False, 2),\n", " 'numInputVectors': ('ints', False, [1]),\n", - " 'mem_mode': ('s', False, 'const'),\n", - " 'ram_style': ('s', False, 'auto'),\n", + " 'ActVal': ('i', False, 0),\n", " 'backend': ('s', True, 'fpgadataflow'),\n", " 'code_gen_dir_cppsim': ('s', False, ''),\n", " 'code_gen_dir_ipgen': ('s', False, ''),\n", @@ -740,12 +905,10 @@ " 'res_hls': ('s', False, ''),\n", " 'res_synth': ('s', False, ''),\n", " 'rtlsim_so': ('s', False, ''),\n", - " 'partition_id': ('i', False, 0),\n", - " 'inFIFODepth': ('i', False, 2),\n", - " 'outFIFODepth': ('i', False, 2)}" + " 'partition_id': ('i', False, 0)}" ] }, - "execution_count": 14, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -769,7 +932,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 41, "metadata": {}, "outputs": [], "source": [ @@ -787,7 +950,12 @@ " fcl_inst.set_nodeattr(\"SIMD\", simd)\n", " fcl_inst.set_nodeattr(\"inFIFODepth\", ififo)\n", " fcl_inst.set_nodeattr(\"outFIFODepth\", ofifo)\n", - " fcl_inst.set_nodeattr(\"ram_style\", ramstyle)" + " fcl_inst.set_nodeattr(\"ram_style\", ramstyle)\n", + " \n", + "# set parallelism for input quantizer to be same as first layer's SIMD\n", + "inp_qnt_node = model.get_nodes_by_op_type(\"Thresholding_Batch\")[0]\n", + "inp_qnt = getCustomOp(inp_qnt_node)\n", + "inp_qnt.set_nodeattr(\"PE\", 49)" ] }, { @@ -809,7 +977,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 42, "metadata": { "scrolled": true }, @@ -837,10 +1005,10 @@ " " ], "text/plain": [ - "<IPython.lib.display.IFrame at 0x7f1adc266ba8>" + "<IPython.lib.display.IFrame at 0x7fe2640712e8>" ] }, - "execution_count": 16, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -870,7 +1038,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 43, "metadata": {}, "outputs": [ { @@ -889,7 +1057,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 44, "metadata": {}, "outputs": [], "source": [ @@ -908,18 +1076,9 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 45, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/workspace/finn/src/finn/transformation/infer_data_layouts.py:107: UserWarning: Assuming 2D input is NC\n", - " warnings.warn(\"Assuming 2D input is NC\")\n" - ] - } - ], + "outputs": [], "source": [ "from finn.transformation.fpgadataflow.make_zynq_proj import ZynqBuild\n", "model = ModelWrapper(build_dir+\"/tfc_w1_a1_set_folding_factors.onnx\")\n", @@ -928,7 +1087,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 46, "metadata": {}, "outputs": [], "source": [ @@ -941,7 +1100,221 @@ "source": [ "### Examining the generated outputs <a id='gen_outputs'></a>\n", "\n", - "TODO" + "Let's start by viewing the post-synthesis model in Netron:" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Stopping http://0.0.0.0:8081\n", + "Serving '/workspace/finn/tfc_w1_a1_post_synthesis.onnx' at http://0.0.0.0:8081\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " <iframe\n", + " width=\"100%\"\n", + " height=\"400\"\n", + " src=\"http://0.0.0.0:8081/\"\n", + " frameborder=\"0\"\n", + " allowfullscreen\n", + " ></iframe>\n", + " " + ], + "text/plain": [ + "<IPython.lib.display.IFrame at 0x7fe2ef58eb00>" + ] + }, + "execution_count": 99, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "showInNetron(build_dir + \"/tfc_w1_a1_post_synthesis.onnx\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see that our sequence of HLS layers has been replaced with `StreamingDataflowPartition`s, each of which point to a different ONNX file. You can open a Netron session for each of them to view their contents. Here, the first and last partitions contain only an `IODMA` node, which was inserted automatically to move data between DRAM and the accelerator. Let's take a closer look at the middle partition, which contains all our layers:" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Stopping http://0.0.0.0:8081\n", + "Serving '/tmp/finn_dev_maltanar/dataflow_partition2_b6c72_s0/df_model.onnx' at http://0.0.0.0:8081\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " <iframe\n", + " width=\"100%\"\n", + " height=\"400\"\n", + " src=\"http://0.0.0.0:8081/\"\n", + " frameborder=\"0\"\n", + " allowfullscreen\n", + " ></iframe>\n", + " " + ], + "text/plain": [ + "<IPython.lib.display.IFrame at 0x7fe2ef5a0e48>" + ] + }, + "execution_count": 102, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model = ModelWrapper(build_dir + \"/tfc_w1_a1_post_synthesis.onnx\")\n", + "sdp_node_middle = getCustomOp(model.graph.node[1])\n", + "postsynth_layers = sdp_node_middle.get_nodeattr(\"model\")\n", + "\n", + "showInNetron(postsynth_layers)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see that `StreamingFIFO` and `StreamingDataWidthConverter` instances have been automatically inserted into the graph prior to hardware build. Transformations like `ZynqBuild` use the `metadata_props` of the model to put in additional metadata information relevant to the results of the transformation. Let's examine the metadata for the current graph containing all layers:" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[key: \"pynq_driver_dir\"\n", + "value: \"/tmp/finn_dev_maltanar/pynq_driver_kl300vbh\"\n", + ", key: \"vivado_stitch_proj\"\n", + "value: \"/tmp/finn_dev_maltanar/vivado_stitch_proj_yy5ixo91\"\n", + ", key: \"clk_ns\"\n", + "value: \"10\"\n", + ", key: \"wrapper_filename\"\n", + "value: \"/tmp/finn_dev_maltanar/vivado_stitch_proj_yy5ixo91/finn_vivado_stitch_proj.srcs/sources_1/bd/StreamingDataflowPartition_1/hdl/StreamingDataflowPartition_1_wrapper.v\"\n", + ", key: \"vivado_stitch_vlnv\"\n", + "value: \"xilinx_finn:finn:StreamingDataflowPartition_1:1.0\"\n", + ", key: \"vivado_stitch_ifnames\"\n", + "value: \"{\\'clk\\': [\\'ap_clk\\'], \\'rst\\': [\\'ap_rst_n\\'], \\'s_axis\\': [\\'s_axis_0\\'], \\'m_axis\\': [\\'m_axis_0\\'], \\'aximm\\': [], \\'axilite\\': []}\"\n", + ", key: \"platform\"\n", + "value: \"zynq-iodma\"\n", + "]" + ] + }, + "execution_count": 103, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model = ModelWrapper(postsynth_layers)\n", + "model.model.metadata_props" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we see that a Vivado project was built to create what we call the `stitched IP`, where all the IP blocks implementing various layers will be stitched together. You can view this stitched block design in Vivado, or [here](StreamingDataflowPartition_1.pdf) as an exported PDF." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Moving back to the top-level model, recall that `ZynqBuild` will create a Vivado project and synthesize it, so it will be creating metadata entries related to the paths and files that were created:" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[key: \"pynq_driver_dir\"\n", + "value: \"/tmp/finn_dev_maltanar/pynq_driver_kl300vbh\"\n", + ", key: \"vivado_pynq_proj\"\n", + "value: \"/tmp/finn_dev_maltanar/vivado_zynq_proj_kdf60v6f\"\n", + ", key: \"bitfile\"\n", + "value: \"/tmp/finn_dev_maltanar/vivado_zynq_proj_kdf60v6f/resizer.bit\"\n", + ", key: \"hw_handoff\"\n", + "value: \"/tmp/finn_dev_maltanar/vivado_zynq_proj_kdf60v6f/resizer.hwh\"\n", + ", key: \"vivado_synth_rpt\"\n", + "value: \"/tmp/finn_dev_maltanar/vivado_zynq_proj_kdf60v6f/synth_report.xml\"\n", + ", key: \"platform\"\n", + "value: \"zynq-iodma\"\n", + "]" + ] + }, + "execution_count": 97, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model = ModelWrapper(build_dir + \"/tfc_w1_a1_post_synthesis.onnx\")\n", + "model.model.metadata_props" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, we can see the directories that were created for the PYNQ driver (`pynq_driver_dir`) and the Vivado synthesis project (`vivado_pynq_proj`), as well as the locations of the bitfile, hardware handoff file and synthesis report." + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "NA\t\t\t finn_zynq_link.runs resizer.bit\t vivado.jou\r\n", + "finn_zynq_link.cache\t finn_zynq_link.srcs resizer.hwh\t vivado.log\r\n", + "finn_zynq_link.hw\t finn_zynq_link.xpr synth_project.sh\r\n", + "finn_zynq_link.ip_user_files ip_config.tcl\t synth_report.xml\r\n" + ] + } + ], + "source": [ + "! ls {model.get_metadata_prop(\"vivado_pynq_proj\")}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Feel free to examine the generated Vivado project to get a feel for how the system-level integration is performed for the FINN-generated \"stitched IP\", which appears as `StreamingDataflowPartition_1` in the top-level block design -- you can see it as a block diagram exported to PDF [here](top.pdf).\n" ] }, { @@ -951,6 +1324,7 @@ "## 4. PYNQ deployment <a id='hw_test'></a>\n", "\n", "* [Deployment and Remote Execution](#deploy)\n", + "* [Validation on PYNQ Board](#validation)\n", "* [Throughput Test on PYNQ Board](#throughput)\n", "\n", "\n", @@ -968,7 +1342,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 47, "metadata": {}, "outputs": [], "source": [ @@ -991,22 +1365,22 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[key: \"pynq_driver_dir\"\n", - "value: \"/tmp/finn_dev_maltanar/pynq_driver_ilfzbags\"\n", + "value: \"/tmp/finn_dev_maltanar/pynq_driver_kl300vbh\"\n", ", key: \"vivado_pynq_proj\"\n", - "value: \"/tmp/finn_dev_maltanar/vivado_zynq_proj_erwcr5nk\"\n", + "value: \"/tmp/finn_dev_maltanar/vivado_zynq_proj_kdf60v6f\"\n", ", key: \"bitfile\"\n", - "value: \"/tmp/finn_dev_maltanar/vivado_zynq_proj_erwcr5nk/resizer.bit\"\n", + "value: \"/tmp/finn_dev_maltanar/vivado_zynq_proj_kdf60v6f/resizer.bit\"\n", ", key: \"hw_handoff\"\n", - "value: \"/tmp/finn_dev_maltanar/vivado_zynq_proj_erwcr5nk/resizer.hwh\"\n", + "value: \"/tmp/finn_dev_maltanar/vivado_zynq_proj_kdf60v6f/resizer.hwh\"\n", ", key: \"vivado_synth_rpt\"\n", - "value: \"/tmp/finn_dev_maltanar/vivado_zynq_proj_erwcr5nk/synth_report.xml\"\n", + "value: \"/tmp/finn_dev_maltanar/vivado_zynq_proj_kdf60v6f/synth_report.xml\"\n", ", key: \"platform\"\n", "value: \"zynq-iodma\"\n", ", key: \"pynq_ip\"\n", @@ -1020,15 +1394,15 @@ ", key: \"pynq_target_dir\"\n", "value: \"/home/xilinx/finn_tfc_end2end_example\"\n", ", key: \"pynq_deployment_dir\"\n", - "value: \"/tmp/finn_dev_maltanar/pynq_deployment_eyiu4sxk\"\n", + "value: \"/tmp/finn_dev_maltanar/pynq_deployment_3wrnn2sp\"\n", ", key: \"pynq_deploy_dir\"\n", - "value: \"/tmp/finn_dev_maltanar/pynq_deployment_eyiu4sxk\"\n", + "value: \"/tmp/finn_dev_maltanar/pynq_deployment_3wrnn2sp\"\n", ", key: \"exec_mode\"\n", "value: \"remote_pynq\"\n", "]" ] }, - "execution_count": 22, + "execution_count": 48, "metadata": {}, "output_type": "execute_result" } @@ -1039,35 +1413,50 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 106, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'/home/xilinx/finn_tfc_end2end_example/pynq_deployment_3wrnn2sp'" + ] + }, + "execution_count": 106, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "target_dir_pynq = target_dir + \"/\" + model.get_metadata_prop(\"pynq_deployment_dir\").split(\"/\")[-1]\n", + "target_dir_pynq" + ] + }, + { + "cell_type": "code", + "execution_count": 107, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "/home/xilinx/finn_tfc_end2end_example/pynq_deployment_624bd_nc:\r\n", - "total 4228\r\n", - "-rw-r--r-- 1 xilinx xilinx 9391 Sep 4 10:37 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Sep 4 10:37 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 3264 Sep 4 10:38 input.npy\r\n", - "-rw-r--r-- 1 root root 205 Sep 4 10:39 nw_metrics.txt\r\n", - "-rw-r--r-- 1 root root 120 Sep 4 10:38 output.npy\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Sep 4 10:37 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Sep 4 10:37 resizer.hwh\r\n", - "-rw-r--r-- 1 root root 32 Sep 4 10:39 sds_trace_data.dat\r\n", - "\r\n", - "/home/xilinx/finn_tfc_end2end_example/pynq_deployment_eyiu4sxk:\r\n", - "total 4212\r\n", - "-rw-r--r-- 1 xilinx xilinx 8493 Sep 5 01:24 driver.py\r\n", - "drwxr-xr-x 4 xilinx xilinx 4096 Sep 5 01:24 finn\r\n", - "-rw-r--r-- 1 xilinx xilinx 4045671 Sep 5 01:24 resizer.bit\r\n", - "-rw-r--r-- 1 xilinx xilinx 246211 Sep 5 01:24 resizer.hwh\r\n" + "total 4236\r\n", + "-rw-r--r-- 1 xilinx xilinx 8490 Sep 21 11:06 driver.py\r\n", + "drwxr-xr-x 4 xilinx xilinx 4096 Sep 21 11:06 finn\r\n", + "-rw-r--r-- 1 xilinx xilinx 3264 Sep 21 12:05 input.npy\r\n", + "-rw-r--r-- 1 root root 205 Sep 21 12:34 nw_metrics.txt\r\n", + "-rw-r--r-- 1 root root 84 Sep 21 12:06 output.npy\r\n", + "drwxrwxr-x 2 xilinx xilinx 4096 Sep 21 11:34 __pycache__\r\n", + "-rw-r--r-- 1 xilinx xilinx 4045671 Sep 21 11:06 resizer.bit\r\n", + "-rw-r--r-- 1 xilinx xilinx 246211 Sep 21 11:06 resizer.hwh\r\n", + "-rw-r--r-- 1 root root 32 Sep 21 12:34 sds_trace_data.dat\r\n", + "-rw-r--r-- 1 xilinx xilinx 1727 Sep 21 11:06 validate.py\r\n" ] } ], "source": [ - "! sshpass -p {password} ssh {username}@{ip} -p {port} 'ls -l {target_dir}/*'" + "! sshpass -p {password} ssh {username}@{ip} -p {port} 'ls -l {target_dir_pynq}'" ] }, { @@ -1079,18 +1468,30 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "<matplotlib.image.AxesImage at 0x7f1b5b7cddd8>" + "<matplotlib.image.AxesImage at 0x7fe2dd62bf98>" ] }, - "execution_count": 24, + "execution_count": 53, "metadata": {}, "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" } ], "source": [ @@ -1103,100 +1504,166 @@ "plt.imshow(x.reshape(28,28), cmap='gray')" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Recall that we partitioned our original network into a parent graph that contained the non-synthesizable nodes and a child graph that contained the bulk of the network, which we turned into a bitfile. We'll load up the parent graph, modify the `StreamingDataflowPartition` node so that it points to the deployed ONNX graph." - ] - }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 92, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Expected network input shape is [1, 784]\n" + ] + } + ], "source": [ - "parent_model = ModelWrapper(build_dir+\"/tfc_w1_a1_dataflow_parent.onnx\")\n", - "sdp_node = parent_model.graph.node[2]\n", - "remote_exec_model = build_dir + \"/tfc_w1_a1_pynq_deploy.onnx\"\n", - "getCustomOp(sdp_node).set_nodeattr(\"model\", remote_exec_model)\n", - "parent_model.save(build_dir+\"/tfc_w1_a1_dataflow_parent_with_remote_bitfile_exec.onnx\")" + "model = ModelWrapper(build_dir + \"/tfc_w1_a1_pynq_deploy.onnx\")\n", + "iname = model.graph.input[0].name\n", + "oname = parent_model.graph.output[0].name\n", + "ishape = model.get_tensor_shape(iname)\n", + "print(\"Expected network input shape is \" + str(ishape))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Finally, we can call `execute_onnx` on the parent graph, which will internally call remote execution with the bitfile once the `StreamingDataflowPartition` node is reached, grab the results, then continue executing the last portion of the network. " + "Finally, we can call `execute_onnx` on the graph, which will internally call remote execution with the bitfile, grab the results and return a numpy array. You may recall that one \"reshape\" node was left out of the StreamingDataflowPartition. We'll do that manually with a numpy function call when passing in the input, but everything else in the network ended up inside the StreamingDataflowPartition so that's all we need to do." ] }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 95, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from finn.core.onnx_exec import execute_onnx\n", - "iname = parent_model.graph.input[0].name\n", - "oname = parent_model.graph.output[0].name\n", - "ishape = parent_model.get_tensor_shape(iname)\n", + "\n", "input_dict = {iname: x.reshape(ishape)}\n", - "ret = execute_onnx(parent_model, input_dict, True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We'll pass the output of the network through a softmax function to interpret it as probabilities, and plot the per-class probabilities as a bar chart." + "ret = execute_onnx(model, input_dict)" ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 96, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "<BarContainer object of 10 artists>" + "array([[2.]], dtype=float32)" ] }, - "execution_count": 27, + "execution_count": 96, "metadata": {}, "output_type": "execute_result" - }, + } + ], + "source": [ + "ret[oname]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that the network correctly predicts this as a digit 2." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Validating the Accuracy on a PYNQ Board <a id='validation'></a>\n", + "\n", + "All the command line prompts here are meant to be executed with `sudo` on the PYNQ board, so we'll use a workaround (`sshpass` and `echo password | sudo -S command`) to get that working from this notebook running on the host computer.\n", + "\n", + "**Ensure that your PYNQ board has a working internet connecting for the next steps, since some there is some downloading involved.**\n", + "\n", + "To validate the accuracy, we first need to install the [`dataset-loading`](https://github.com/fbcotter/dataset_loading) Python package to the PYNQ board. This will give us a convenient way of downloading and accessing the MNIST dataset.\n", + "\n", + "\n", + "Command to execute on PYNQ:\n", + "\n", + "```pip3 install git+https://github.com/fbcotter/dataset_loading.git@0.0.4#egg=dataset_loading```" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": {}, + "outputs": [ { - "data": { - "image/png": "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\n", - "text/plain": [ - "<Figure size 432x288 with 1 Axes>" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" + "name": "stdout", + "output_type": "stream", + "text": [ + "[sudo] password for xilinx: Collecting git+https://github.com/fbcotter/dataset_loading.git@0.0.4\n", + " Cloning https://github.com/fbcotter/dataset_loading.git (to 0.0.4) to /tmp/pip-hhwx4j3n-build\n", + " Requirement already satisfied (use --upgrade to upgrade): dataset-loading==0.0.4 from git+https://github.com/fbcotter/dataset_loading.git@0.0.4 in /usr/local/lib/python3.6/dist-packages\n", + "Requirement already satisfied: Pillow in /usr/lib/python3/dist-packages (from dataset-loading==0.0.4)\n", + "Requirement already satisfied: scipy in /usr/lib/python3/dist-packages (from dataset-loading==0.0.4)\n", + "Connection to 192.168.2.99 closed.\n" + ] } ], "source": [ - "def softmax(x):\n", - " \"\"\"Compute softmax values for each sets of scores in x.\"\"\"\n", - " e_x = np.exp(x - np.max(x))\n", - " return e_x / e_x.sum()\n", + "! sshpass -p {password} ssh -t {username}@{ip} -p {port} 'echo {password} | sudo -S pip3 install git+https://github.com/fbcotter/dataset_loading.git@0.0.4#egg=dataset_loading'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can now use the `validate.py` script that was generated together with the driver to measure top-1 accuracy on the MNIST dataset.\n", "\n", - "logits = ret[oname].flatten()\n", - "prob = softmax(logits)\n", + "Command to execute on PYNQ:\n", "\n", - "plt.bar(np.arange(10), prob)" + "`python3.6 validate.py --dataset mnist --batchsize 1000`" + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[sudo] password for xilinx: Looking for Train Imgs\n", + "Tar File found in data_dir. Not Downloading again\n", + "Looking for Train Labels\n", + "Tar File found in data_dir. Not Downloading again\n", + "Looking for Test Imgs\n", + "Tar File found in data_dir. Not Downloading again\n", + "Looking for Test Labels\n", + "Tar File found in data_dir. Not Downloading again\n", + "batch 0 / 10 : total OK 913 NOK 87\n", + "batch 1 / 10 : total OK 1800 NOK 200\n", + "batch 2 / 10 : total OK 2714 NOK 286\n", + "batch 3 / 10 : total OK 3619 NOK 381\n", + "batch 4 / 10 : total OK 4535 NOK 465\n", + "batch 5 / 10 : total OK 5488 NOK 512\n", + "batch 6 / 10 : total OK 6438 NOK 562\n", + "batch 7 / 10 : total OK 7399 NOK 601\n", + "batch 8 / 10 : total OK 8371 NOK 629\n", + "batch 9 / 10 : total OK 9296 NOK 704\n", + "Final accuracy: 92.960000\n", + "Connection to 192.168.2.99 closed.\n" + ] + } + ], + "source": [ + "! sshpass -p {password} ssh -t {username}@{ip} -p {port} 'cd {target_dir_pynq}; echo {password} | sudo -S python3.6 validate.py --dataset mnist --batchsize 1000'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "We see that the network correctly predicts this as a digit 2 with high probability. This concludes our tutorial on how to take a simple fully-connected BNN all the way down to hardware with FINN, and execute it remotely on a PYNQ board." + "We see that the final top-1 accuracy is 92.96%, which is very close to the 93.17% reported on the [BNN-PYNQ accuracy table in Brevitas](https://github.com/Xilinx/brevitas/tree/master/brevitas_examples/bnn_pynq). " ] }, { @@ -1210,7 +1677,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 104, "metadata": {}, "outputs": [ { @@ -1218,10 +1685,10 @@ "output_type": "stream", "text": [ "Network metrics:\n", - "runtime[ms]: 7.472753524780273\n", - "throughput[images/s]: 1338194.8122387773\n", - "DRAM_in_bandwidth[Mb/s]: 131.14309159940018\n", - "DRAM_out_bandwidth[Mb/s]: 13.381948122387772\n", + "runtime[ms]: 10.43391227722168\n", + "throughput[images/s]: 958413.2714850444\n", + "DRAM_in_bandwidth[Mb/s]: 751.3960048442748\n", + "DRAM_out_bandwidth[Mb/s]: 0.9584132714850445\n", "fclk[mhz]: 100.0\n", "N: 10000\n" ] @@ -1230,8 +1697,8 @@ "source": [ "from finn.core.throughput_test import throughput_test_remote\n", "\n", - "child_model = ModelWrapper(getCustomOp(sdp_node).get_nodeattr(\"model\"))\n", - "res = throughput_test_remote(child_model, 10000)\n", + "model = ModelWrapper(build_dir + \"/tfc_w1_a1_pynq_deploy.onnx\")\n", + "res = throughput_test_remote(model, 10000)\n", "print(\"Network metrics:\")\n", "for key in res:\n", " print(str(key) + \": \" + str(res[key]))" @@ -1246,14 +1713,14 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 105, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "We reach approximately 86% of the ideal performance.\n" + "We reach approximately 61% of the ideal performance.\n" ] } ], -- GitLab