From 00dfe61b8390b0c1158942f6c762efcc22850ffc Mon Sep 17 00:00:00 2001
From: Yaman Umuroglu <maltanar@gmail.com>
Date: Wed, 13 May 2020 14:55:51 +0100
Subject: [PATCH] [Transform] bugfix in MoveReshape, rename to
 RemoveCNVtoFCFlatten

---
 notebooks/end2end_example/cnv_end2end_example.ipynb | 6 +++---
 src/finn/transformation/move_reshape.py             | 4 ++--
 tests/end2end/test_end2end_cnv_w1a1.py              | 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/notebooks/end2end_example/cnv_end2end_example.ipynb b/notebooks/end2end_example/cnv_end2end_example.ipynb
index f4bff38ce..ce8c9decf 100644
--- a/notebooks/end2end_example/cnv_end2end_example.ipynb
+++ b/notebooks/end2end_example/cnv_end2end_example.ipynb
@@ -274,7 +274,7 @@
     "from finn.transformation.fpgadataflow.create_dataflow_partition import (\n",
     "    CreateDataflowPartition,\n",
     ")\n",
-    "from finn.transformation.move_reshape import MoveReshape\n",
+    "from finn.transformation.move_reshape import RemoveCNVtoFCFlatten\n",
     "from finn.custom_op.registry import getCustomOp\n",
     "\n",
     "# choose the memory mode for the MVTU units, decoupled or const\n",
@@ -286,7 +286,7 @@
     "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(MoveReshape())\n",
+    "model = model.transform(RemoveCNVtoFCFlatten())\n",
     "parent_model = model.transform(CreateDataflowPartition())\n",
     "parent_model.save(build_dir + \"/end2end_cnv_w1a1_dataflow_parent.onnx\")\n",
     "sdp_node = parent_model.get_nodes_by_op_type(\"StreamingDataflowPartition\")[0]\n",
@@ -301,7 +301,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "Notice the additional `MoveReshape` transformation that was not used for TFC-w1a1. In the last Netron visualization you may have noticed a `Reshape` operation towards the end of the network where the convolutional part of the network ends and the fully-connected layers started. That `Reshape` is essentialy a tensor flattening operation, which we can remove for the purposes of hardware implementation. We can examine the contents of the dataflow partition with Netron, and observe the `ConvolutionInputGenerator`, `StreamingFCLayer_Batch` and `StreamingMaxPool_Batch` nodes that implement the sliding window, matrix multiply and maxpool operations in hlslib. *Note that the StreamingFCLayer instances following the ConvolutionInputGenerator nodes are really implementing the convolutions, despite the name. The final three StreamingFCLayer instances implement actual FC layers.*"
+    "Notice the additional `RemoveCNVtoFCFlatten` transformation that was not used for TFC-w1a1. In the last Netron visualization you may have noticed a `Reshape` operation towards the end of the network where the convolutional part of the network ends and the fully-connected layers started. That `Reshape` is essentialy a tensor flattening operation, which we can remove for the purposes of hardware implementation. We can examine the contents of the dataflow partition with Netron, and observe the `ConvolutionInputGenerator`, `StreamingFCLayer_Batch` and `StreamingMaxPool_Batch` nodes that implement the sliding window, matrix multiply and maxpool operations in hlslib. *Note that the StreamingFCLayer instances following the ConvolutionInputGenerator nodes are really implementing the convolutions, despite the name. The final three StreamingFCLayer instances implement actual FC layers.*"
    ]
   },
   {
diff --git a/src/finn/transformation/move_reshape.py b/src/finn/transformation/move_reshape.py
index 6a30fd93c..2ddaf4f84 100644
--- a/src/finn/transformation/move_reshape.py
+++ b/src/finn/transformation/move_reshape.py
@@ -17,7 +17,7 @@ def _is_fpgadataflow_node(node):
         return False
 
 
-class MoveReshape(Transformation):
+class RemoveCNVtoFCFlatten(Transformation):
     """Removes a node that implements a (1, -1) reshape if it is
     between two fpgadataflow nodes"""
 
@@ -27,13 +27,13 @@ class MoveReshape(Transformation):
         graph_modified = False
         for n in graph.node:
             if n.op_type == "Reshape":
-                graph_modified = True
                 shape = model.get_initializer(n.input[1])
                 if (shape == [1, -1]).all():
                     producer = model.find_producer(n.input[0])
                     if _is_fpgadataflow_node(producer) is True:
                         consumer = model.find_consumer(n.output[0])
                         if _is_fpgadataflow_node(consumer) is True:
+                            graph_modified = True
                             consumer.input[0] = n.input[0]
                             graph.node.remove(n)
 
diff --git a/tests/end2end/test_end2end_cnv_w1a1.py b/tests/end2end/test_end2end_cnv_w1a1.py
index d7f59ef35..703cb7ad9 100644
--- a/tests/end2end/test_end2end_cnv_w1a1.py
+++ b/tests/end2end/test_end2end_cnv_w1a1.py
@@ -41,7 +41,7 @@ from finn.custom_op.registry import getCustomOp
 from finn.core.onnx_exec import execute_onnx
 from finn.transformation.double_to_single_float import DoubleToSingleFloat
 from finn.transformation.infer_shapes import InferShapes
-from finn.transformation.move_reshape import MoveReshape
+from finn.transformation.move_reshape import RemoveCNVtoFCFlatten
 from finn.transformation.fold_constants import FoldConstants
 from finn.transformation.general import GiveReadableTensorNames, GiveUniqueNodeNames
 from finn.transformation.streamline import Streamline
@@ -117,7 +117,7 @@ def test_end2end_cnv_w1a1_convert_to_hls_layers():
     model = model.transform(to_hls.InferQuantizedStreamingFCLayer(mem_mode))
     model = model.transform(to_hls.InferConvInpGen())
     model = model.transform(to_hls.InferStreamingMaxPool())
-    model = model.transform(MoveReshape())
+    model = model.transform(RemoveCNVtoFCFlatten())
     model.save(build_dir + "/end2end_cnv_w1a1_hls_layers.onnx")
 
 
-- 
GitLab