From 9f79d52148bd13def4e1dc91de4b502cbdb36692 Mon Sep 17 00:00:00 2001
From: Yaman Umuroglu <maltanar@gmail.com>
Date: Tue, 20 Apr 2021 10:19:07 +0100
Subject: [PATCH] [HLSCustomOp] move StreamingDataflowPartition to fpgadataflow
 ops

note: SDP isn't a "proper" fpgadataflow op as it's not derived
from HLSCustomOp, but still better to have it here instead of
in finn-base
---
 src/finn/custom_op/fpgadataflow/__init__.py   |  4 +
 .../streamingdataflowpartition.py             | 94 +++++++++++++++++++
 .../fpgadataflow/create_dataflow_partition.py |  2 +-
 3 files changed, 99 insertions(+), 1 deletion(-)
 create mode 100644 src/finn/custom_op/fpgadataflow/streamingdataflowpartition.py

diff --git a/src/finn/custom_op/fpgadataflow/__init__.py b/src/finn/custom_op/fpgadataflow/__init__.py
index 068950b89..a68a29755 100644
--- a/src/finn/custom_op/fpgadataflow/__init__.py
+++ b/src/finn/custom_op/fpgadataflow/__init__.py
@@ -49,6 +49,9 @@ from finn.custom_op.fpgadataflow.vector_vector_activate_batch import (
 )
 from finn.custom_op.fpgadataflow.channelwise_op_batch import ChannelwiseOp_Batch
 from finn.custom_op.fpgadataflow.iodma import IODMA
+from finn.custom_op.fpgadataflow.streamingdataflowpartition import (
+    StreamingDataflowPartition,
+)
 
 custom_op = dict()
 
@@ -71,3 +74,4 @@ custom_op["DuplicateStreams_Batch"] = DuplicateStreams_Batch
 custom_op["Vector_Vector_Activate_Batch"] = Vector_Vector_Activate_Batch
 custom_op["ChannelwiseOp_Batch"] = ChannelwiseOp_Batch
 custom_op["IODMA"] = IODMA
+custom_op["StreamingDataflowPartition"] = StreamingDataflowPartition
diff --git a/src/finn/custom_op/fpgadataflow/streamingdataflowpartition.py b/src/finn/custom_op/fpgadataflow/streamingdataflowpartition.py
new file mode 100644
index 000000000..53446ff1f
--- /dev/null
+++ b/src/finn/custom_op/fpgadataflow/streamingdataflowpartition.py
@@ -0,0 +1,94 @@
+# Copyright (c) 2020 Xilinx, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+#
+# * Neither the name of Xilinx nor the names of its
+#   contributors may be used to endorse or promote products derived from
+#   this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from finn.custom_op.base import CustomOp
+
+# TODO move StreamingDataflowPartition to HLSCustomOp base class
+
+
+class StreamingDataflowPartition(CustomOp):
+    """Class that corresponds to the meta/container node StreamingDataflowPartition
+    which is a placeholder for a group of fpgadataflow nodes that have been separated
+    out into a FINN-ONNX model of its own. Note that is does not produce any HLS or
+    bitfile by itself."""
+
+    def get_nodeattr_types(self):
+        return {
+            "model": ("s", True, ""),
+            "res_estimate": ("s", False, ""),
+            "res_hls": ("s", False, ""),
+            "res_synth": ("s", False, ""),
+            "slr": ("i", False, -1),
+            "partition_id": ("i", False, 0),
+            "device_id": ("i", False, 0),
+            "mem_port": ("s", False, ""),
+        }
+
+    def make_shape_compatible_op(self, model):
+        pass
+
+    def infer_node_datatype(self, model):
+        pass
+
+    def execute_node(self, context, graph):
+        # TODO add RPC execution with synthesized bitfile?
+        # whole-design rtlsim with PyVerilator may also be an alternative
+        pass
+
+    def verify_node(self):
+        info_messages = []
+
+        # verify number of attributes
+        num_of_attr = 1
+        if len(self.onnx_node.attribute) == num_of_attr:
+            info_messages.append("The number of attributes is correct")
+        else:
+            info_messages.append(
+                """The number of attributes is incorrect,
+            {} should have {} attributes""".format(
+                    self.onnx_node.op_type, num_of_attr
+                )
+            )
+        # verify that all necessary attributes exist
+        try:
+            self.get_nodeattr("model")
+            info_messages.append("All necessary attributes exist")
+        except Exception:
+            info_messages.append(
+                """The necessary attributes do not exist.
+                StreamingDataflowPartition needs the following attribute(s):
+                model"""
+            )
+
+        # verify the number of inputs
+        if len(self.onnx_node.input) >= 1:
+            info_messages.append("The number of inputs is correct")
+        else:
+            info_messages.append("StreamingDataflowPartition needs 1 data input")
+
+        return info_messages
diff --git a/src/finn/transformation/fpgadataflow/create_dataflow_partition.py b/src/finn/transformation/fpgadataflow/create_dataflow_partition.py
index 56bfb4306..419a6d8c4 100644
--- a/src/finn/transformation/fpgadataflow/create_dataflow_partition.py
+++ b/src/finn/transformation/fpgadataflow/create_dataflow_partition.py
@@ -148,7 +148,7 @@ class CreateDataflowPartition(Transformation):
                     [df_out],
                     # use the model attribute to mark the df model
                     model=df_model_filename,
-                    domain="finn.custom_op.general",
+                    domain="finn.custom_op.fpgadataflow",
                     partition_id=target_partition_id,
                     slr=slr,
                     mem_port=mem_port,
-- 
GitLab