From 2ceb009736498fd735346c95441785a9ba7adaa9 Mon Sep 17 00:00:00 2001
From: Yaman Umuroglu <maltanar@gmail.com>
Date: Tue, 3 Dec 2019 00:09:53 +0000
Subject: [PATCH] [CustomOp] remove non-batch StreamingMaxPool for now

---
 .../fpgadataflow/streamingmaxpool.py          | 191 ------------------
 src/finn/custom_op/registry.py                |   4 +-
 .../test_layer_streaming_maxpool.py           |  80 --------
 3 files changed, 1 insertion(+), 274 deletions(-)
 delete mode 100644 src/finn/custom_op/fpgadataflow/streamingmaxpool.py
 delete mode 100644 tests/fpgadataflow/test_layer_streaming_maxpool.py

diff --git a/src/finn/custom_op/fpgadataflow/streamingmaxpool.py b/src/finn/custom_op/fpgadataflow/streamingmaxpool.py
deleted file mode 100644
index ee35b476a..000000000
--- a/src/finn/custom_op/fpgadataflow/streamingmaxpool.py
+++ /dev/null
@@ -1,191 +0,0 @@
-import os
-import subprocess
-import tempfile as tmp
-
-import numpy as np
-
-from finn.custom_op.fpgadataflow import HLSCustomOp
-
-
-class StreamingMaxPool(HLSCustomOp):
-    def get_nodeattr_types(self):
-        my_attrs = {
-            "ImgDim": ("i", True, 0),
-            "PoolDim": ("i", True, 0),
-            "NumChannels": ("i", True, 0),
-        }
-        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 execute_node(self, context, graph):
-        node = self.onnx_node
-        # make temporary directory for generated files
-        self.tmp_dir = tmp.mkdtemp(prefix=str(node.op_type) + "_")
-
-        # create empty list for temporary files to enable the option
-        # to delete the files after the execution
-        temp_files = []
-
-        # create a npy file fore each input of the node (in_ind is input index)
-        in_ind = 0
-        for inputs in node.input:
-            np.save(
-                os.path.join(self.tmp_dir, "input_{}.npy".format(in_ind)),
-                context[inputs],
-            )
-            temp_files.append("{}/input_{}.npy".format(self.tmp_dir, in_ind))
-            in_ind += 1
-
-        # code generation
-        self.code_generation()
-
-        # c++ compilation and execution flow
-        temp_files.append("{}/execute_{}.cpp".format(self.tmp_dir, node.op_type))
-        bash_compile = """g++ -o {}/execute_{} {}/execute_{}.cpp
-        /workspace/cnpy/cnpy.cpp -I/workspace/cnpy/
-        -I/workspace/finn-hlslib -I/workspace/vivado-hlslib
-        --std=c++11 -lz""".format(
-            self.tmp_dir, node.op_type, self.tmp_dir, node.op_type
-        )
-        process_compile = subprocess.Popen(bash_compile.split(), stdout=subprocess.PIPE)
-        process_compile.communicate()
-        bash_execute = "{}/execute_{}".format(self.tmp_dir, node.op_type)
-        process_execute = subprocess.Popen(bash_execute.split(), stdout=subprocess.PIPE)
-        process_execute.communicate()
-        temp_files.append("{}/execute_{}".format(self.tmp_dir, node.op_type))
-        temp_files.append("{}/output.npy".format(self.tmp_dir))
-
-        # load output npy file
-        output = np.load("{}/output.npy".format(self.tmp_dir))
-        context[node.output[0]] = output
-        # deleting temporary files
-        # for temp_file in temp_files:
-        #    os.remove(temp_file)
-
-    def global_includes(self):
-        self.code_gen_dict["$GLOBALS$"] = ['#include "maxpool.h"']
-
-    def defines(self):
-        self.code_gen_dict["$DEFINES$"] = [
-            "#define ImgDim {}\n #define PoolDim {}\n #define NumChannels {}".format(
-                self.get_nodeattr("ImgDim"),
-                self.get_nodeattr("PoolDim"),
-                self.get_nodeattr("NumChannels"),
-            )
-        ]
-
-    def read_npy_data(self):
-        node = self.onnx_node
-        # c++ code to read out an npy file
-        # and put it in hls::stream in the correct order
-        self.code_gen_dict["$READNPYDATA$"] = []
-        input_ind = 0
-        input_file_names = []
-        for inputs in node.input:
-            input_file_names.append("{}/input_{}.npy".format(self.tmp_dir, input_ind))
-            input_ind += 1
-
-        input_ind = 0
-        for input_file in input_file_names:
-            self.code_gen_dict["$READNPYDATA$"].append(
-                """cnpy::NpyArray arr = cnpy::npy_load("{}");\n
-                float* loaded_data{} = arr.data<float>();""".format(
-                    input_file, input_ind
-                )
-            )
-            self.code_gen_dict["$READNPYDATA$"].append(
-                """int num_values = 1; \n
-                for(int i = 0; i < arr.shape.size(); i++){\n
-                num_values *= arr.shape[i]; \n }"""
-            )
-            self.code_gen_dict["$READNPYDATA$"].append(
-                "ap_uint<{}> dat;".format(self.get_nodeattr("NumChannels"))
-            )
-            self.code_gen_dict["$READNPYDATA$"].append(
-                "for(int i=0; i < num_values/{}; i++){{".format(
-                    self.get_nodeattr("NumChannels")
-                )
-            )
-            for channel in range(self.get_nodeattr("NumChannels")):
-                self.code_gen_dict["$READNPYDATA$"].append(
-                    "dat.range({},{}) = loaded_data{}[i+((num_values/{})*{})];".format(
-                        channel,
-                        channel,
-                        input_ind,
-                        self.get_nodeattr("NumChannels"),
-                        channel,
-                    )
-                )
-            self.code_gen_dict["$READNPYDATA$"].append("in{} << dat;".format(input_ind))
-            self.code_gen_dict["$READNPYDATA$"].append("}")
-            input_ind += 1
-
-    def strm_decl(self):
-        node = self.onnx_node
-        self.code_gen_dict["$STREAMDECLARATIONS$"] = []
-        input_ind = 0
-        for inputs in node.input:
-            self.code_gen_dict["$STREAMDECLARATIONS$"].append(
-                'hls::stream<ap_uint<{}>> in{} ("in{}");'.format(
-                    self.get_nodeattr("NumChannels"), input_ind, input_ind
-                )
-            )
-            input_ind += 1
-        self.code_gen_dict["$STREAMDECLARATIONS$"].append(
-            'hls::stream<ap_uint<{}>> out ("out");'.format(
-                self.get_nodeattr("NumChannels")
-            )
-        )
-
-    def docompute(self):
-        node = self.onnx_node
-        self.code_gen_dict["$DOCOMPUTE$"] = [
-            "{}<ImgDim, PoolDim, NumChannels>(in0, out);".format(node.op_type)
-        ]
-
-    def dataoutstrm(self):
-        self.code_gen_dict["$DATAOUTSTREAM$"] = [
-            "ap_uint<{}> out_data;\n std::vector<ap_uint<{}>> out_data_vector;".format(
-                self.get_nodeattr("NumChannels"), self.get_nodeattr("NumChannels")
-            )
-        ]
-        self.code_gen_dict["$DATAOUTSTREAM$"].append("while(out.read_nb(out_data)){")
-        self.code_gen_dict["$DATAOUTSTREAM$"].append(
-            "out_data_vector.push_back(out_data);\n}"
-        )
-        self.code_gen_dict["$DATAOUTSTREAM$"].append(
-            "std::vector<float> output_data_vector;"
-        )
-        self.code_gen_dict["$DATAOUTSTREAM$"].append(
-            """for(std::vector<ap_uint<{}>>::iterator it = out_data_vector.begin();
-            it != out_data_vector.end(); ++it){{""".format(
-                self.get_nodeattr("NumChannels")
-            )
-        )
-        self.code_gen_dict["$DATAOUTSTREAM$"].append(
-            "ap_uint<{}> output_data = *it;".format(self.get_nodeattr("NumChannels"))
-        )
-        for channel in range(self.get_nodeattr("NumChannels")):
-            self.code_gen_dict["$DATAOUTSTREAM$"].append(
-                "output_data_vector.push_back(output_data.range({},{}));".format(
-                    channel, channel
-                )
-            )
-        self.code_gen_dict["$DATAOUTSTREAM$"].append("}")
-
-    def save_as_npy(self):
-        self.code_gen_dict["$SAVEASCNPY$"] = [
-            """cnpy::npy_save("{}/output.npy",&output_data_vector[0],
-            {{{},{},{}}},"w");""".format(
-                self.tmp_dir,
-                self.get_nodeattr("NumChannels"),
-                int(self.get_nodeattr("ImgDim") / self.get_nodeattr("PoolDim")),
-                int(self.get_nodeattr("ImgDim") / self.get_nodeattr("PoolDim")),
-            )
-        ]
diff --git a/src/finn/custom_op/registry.py b/src/finn/custom_op/registry.py
index 38e7ef807..4b8f4d649 100644
--- a/src/finn/custom_op/registry.py
+++ b/src/finn/custom_op/registry.py
@@ -1,8 +1,7 @@
 # make sure new CustomOp subclasses are imported here so that they get
 # registered and plug in correctly into the infrastructure
-from finn.custom_op.fpgadataflow.streamingmaxpool import StreamingMaxPool
-from finn.custom_op.fpgadataflow.streamingmaxpool_batch import StreamingMaxPool_Batch
 from finn.custom_op.fpgadataflow.streamingfclayer_batch import StreamingFCLayer_Batch
+from finn.custom_op.fpgadataflow.streamingmaxpool_batch import StreamingMaxPool_Batch
 from finn.custom_op.multithreshold import MultiThreshold
 from finn.custom_op.xnorpopcount import XnorPopcountMatMul
 
@@ -11,6 +10,5 @@ custom_op = {}
 
 custom_op["MultiThreshold"] = MultiThreshold
 custom_op["XnorPopcountMatMul"] = XnorPopcountMatMul
-custom_op["StreamingMaxPool"] = StreamingMaxPool
 custom_op["StreamingMaxPool_Batch"] = StreamingMaxPool_Batch
 custom_op["StreamingFCLayer_Batch"] = StreamingFCLayer_Batch
diff --git a/tests/fpgadataflow/test_layer_streaming_maxpool.py b/tests/fpgadataflow/test_layer_streaming_maxpool.py
deleted file mode 100644
index 4c9806a35..000000000
--- a/tests/fpgadataflow/test_layer_streaming_maxpool.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# import onnx
-import numpy as np
-from onnx import TensorProto, helper
-
-import finn.core.onnx_exec as oxe
-from finn.core.datatype import DataType
-from finn.core.modelwrapper import ModelWrapper
-
-
-def test_layer_streaming_maxpool():
-    inp = helper.make_tensor_value_info("in", TensorProto.FLOAT, [2, 4, 4])
-    outp = helper.make_tensor_value_info("out", TensorProto.FLOAT, [2, 2, 2])
-
-    MaxPool_node = helper.make_node(
-        "StreamingMaxPool",
-        ["in"],
-        ["out"],
-        domain="finn",
-        backend="fpgadataflow",
-        ImgDim=4,
-        PoolDim=2,
-        NumChannels=2,
-    )
-
-    graph = helper.make_graph(
-        nodes=[MaxPool_node], name="max_pool_graph", inputs=[inp], outputs=[outp],
-    )
-    model = helper.make_model(graph, producer_name="finn-hls-onnx-model")
-    model = ModelWrapper(model)
-
-    # set the tensor datatypes (in this case: all to bipolar)
-    for tensor in graph.input:
-        model.set_tensor_datatype(tensor.name, DataType["BIPOLAR"])
-    for tensor in graph.output:
-        model.set_tensor_datatype(tensor.name, DataType["BIPOLAR"])
-
-    # onnx.save(model.model, "max-pool-model.onnx")
-
-    input_tensor = np.asarray(
-        [
-            1,
-            1,
-            1,
-            1,
-            1,
-            1,
-            1,
-            1,
-            0,
-            0,
-            0,
-            0,
-            0,
-            0,
-            0,
-            0,
-            0,
-            0,
-            0,
-            0,
-            0,
-            0,
-            0,
-            0,
-            1,
-            1,
-            1,
-            1,
-            1,
-            1,
-            1,
-            1,
-        ],
-        dtype=np.float32,
-    ).reshape(2, 4, 4)
-    print(input_tensor)
-
-    input_dict = {"in": input_tensor}
-    output_dict = oxe.execute_onnx(model, input_dict)
-    print(output_dict)
-- 
GitLab