From 73b92978da73108196287683563f07d77b0260c0 Mon Sep 17 00:00:00 2001
From: auphelia <jakobapk@web.de>
Date: Thu, 19 Dec 2019 15:13:40 +0000
Subject: [PATCH] [Execution] First draft of sliding window custom op

---
 .../fpgadataflow/convolutioninputgenerator.py | 113 ++++++++++++++++++
 1 file changed, 113 insertions(+)
 create mode 100644 src/finn/custom_op/fpgadataflow/convolutioninputgenerator.py

diff --git a/src/finn/custom_op/fpgadataflow/convolutioninputgenerator.py b/src/finn/custom_op/fpgadataflow/convolutioninputgenerator.py
new file mode 100644
index 000000000..8d94495af
--- /dev/null
+++ b/src/finn/custom_op/fpgadataflow/convolutioninputgenerator.py
@@ -0,0 +1,113 @@
+# import os
+
+# import numpy as np
+
+# from finn.backend.fpgadataflow.utils import numpy_to_hls_code
+from finn.core.datatype import DataType
+# from finn.core.utils import interleave_matrix_outer_dim_from_partitions
+from finn.custom_op.fpgadataflow import HLSCustomOp
+
+
+class ConvolutionInputGenerator(HLSCustomOp):
+    def __init__(self, onnx_node):
+        super().__init__(onnx_node)
+
+    def get_nodeattr_types(self):
+        my_attrs = {
+            "ConvKernelDim": ("i", True, 0),
+            "IFMChannels": ("i", True, 0),
+            "Input_precision": ("i", True, 0),
+            "IFMDim": ("i", True, 0),
+            "OFMDim": ("i", True, 0),
+            "SIMD": ("i", True, 0),
+            "Stride": ("i", True, 0),
+            # FINN DataTypes for inputs, weights, outputs
+            "inputDataType": ("s", True, ""),
+            "outputDataType": ("s", True, ""),
+        }
+        my_attrs.update(super().get_nodeattr_types())
+        return my_attrs
+
+    def make_shape_compatible_op(self):
+        pass
+
+    def infer_node_datatype(self, model):
+        pass
+
+    def verify_node(self):
+        pass
+
+    def get_input_datatype(self):
+        return DataType[self.get_nodeattr("inputDataType")]
+
+    def get_output_datatype(self):
+        return DataType[self.get_nodeattr("outputDataType")]
+
+    def get_instream_width(self):
+        return self.get_nodeattr("IFMDim") * self.get_nodeattr("Input_precision")
+
+    def get_outstream_width(self):
+        o_bits = self.get_output_datatype().bitwidth()
+        return self.get_nodeattr("OFMDim")
+
+    def execute_node(self, context, graph):
+        pass
+
+    def global_includes(self):
+        self.code_gen_dict["$GLOBALS$"] = ['#include "slidingwindow.h"']
+
+    def defines(self):
+        numReps = 1
+        self.code_gen_dict["$DEFINES$"] = [
+            """#define ConvKernelDim1 {}\n #define IFMChannels1 {}
+            #define Input_precision1 {}\n #define IFMDim1 {}\n #define OFMDim1 {}
+            #define SIMD1 {}\n #define Stride1 {}\n #define numReps {}""".format(
+                self.get_nodeattr("ConvKernelDim"),
+                self.get_nodeattr("IFMChannels"),
+                self.get_nodeattr("Input_precision"),
+                self.get_nodeattr("IFMDim"),
+                self.get_nodeattr("OFMDim"),
+                self.get_nodeattr("SIMD"),
+                self.get_nodeattr("Stride"),
+                numReps,
+            )
+        ]
+
+    def read_npy_data(self):
+        code_gen_dir = self.get_nodeattr("code_gen_dir")
+        dtype = self.get_input_datatype()
+        elem_bits = dtype.bitwidth()
+        packed_bits = self.get_instream_width()
+        packed_hls_type = "ap_uint<%d>" % packed_bits
+        elem_hls_type = dtype.get_hls_datatype_str()
+        npy_type = "float"
+        npy_in = "%s/input_0.npy" % code_gen_dir
+        self.code_gen_dict["$READNPYDATA$"] = []
+        self.code_gen_dict["$READNPYDATA$"].append(
+            'npy2apintstream<%s, %s, %d, %s>("%s", in0);'
+            % (packed_hls_type, elem_hls_type, elem_bits, npy_type, npy_in)
+        )
+
+    def strm_decl(self):
+        self.code_gen_dict["$STREAMDECLARATIONS$"] = []
+        self.code_gen_dict["$STREAMDECLARATIONS$"].append(
+            'hls::stream<ap_uint<{}>> in0 ("in0");'.format(self.get_instream_width())
+        )
+        self.code_gen_dict["$STREAMDECLARATIONS$"].append(
+            'hls::stream<ap_uint<{}>> out ("out");'.format(self.get_outstream_width())
+        )
+
+    def docompute(self):
+        node = self.onnx_node
+        self.code_gen_dict["$DOCOMPUTE$"] = [
+            """{}<ConvKernelDim1, IFMChannels1, Input_precision1, IFMDim1,
+                OFMDim1, SIMD1, Stride1> (in0, out, numReps);""".format(
+                node.op_type,
+            )
+        ]
+
+    def dataoutstrm(self):
+        pass
+
+    def save_as_npy(self):
+        self.code_gen_dict["$SAVEASCNPY$"] = []
-- 
GitLab