IVGCVSW-6457 Add FLOOR_DIV Support to the TfLiteDelegate

Change-Id: Ia4bf42b1f3f86b947825dff8e538d2d4343effab
Signed-off-by: Jim Flynn <jim.flynn@arm.com>
diff --git a/delegate/src/MultiLayerFacade.hpp b/delegate/src/MultiLayerFacade.hpp
new file mode 100644
index 0000000..fa23980
--- /dev/null
+++ b/delegate/src/MultiLayerFacade.hpp
@@ -0,0 +1,137 @@
+//
+// Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+// NOTE: the MultiLayerFacade class is a utility class which makes a chain
+//       of operators look like a single IConnectableLayer with the first
+//       layer in the chain supplying the input slots and the last supplying
+//       the output slots. It enables us, for example, to simulate a
+//       Tensorflow Lite FloorDiv operator by chaining a Div layer followed
+//       by a Floor layer and pass them as a single unit to the code that
+//       connects up the graph as the delegate proceeds to build up the
+//       Arm NN subgraphs.
+//
+
+#include <common/include/ProfilingGuid.hpp>
+#include <armnn/INetwork.hpp>
+
+namespace armnnDelegate
+{
+
+class MultiLayerFacade : public armnn::IConnectableLayer
+{
+public:
+    MultiLayerFacade() :
+        m_FirstLayer(nullptr), m_LastLayer(nullptr) {}
+
+    MultiLayerFacade(armnn::IConnectableLayer* firstLayer, armnn::IConnectableLayer* lastLayer) :
+        m_FirstLayer(firstLayer), m_LastLayer(lastLayer) {}
+
+    MultiLayerFacade(const MultiLayerFacade& obj) :
+        m_FirstLayer(obj.m_FirstLayer), m_LastLayer(obj.m_LastLayer) {}
+
+    ~MultiLayerFacade() {} // we don't own the pointers
+
+    MultiLayerFacade& operator=(const MultiLayerFacade& obj)
+    {
+        m_FirstLayer = obj.m_FirstLayer;
+        m_LastLayer = obj.m_LastLayer;
+        return *this;
+    }
+
+    void AssignValues(armnn::IConnectableLayer* firstLayer, armnn::IConnectableLayer* lastLayer)
+    {
+        m_FirstLayer = firstLayer;
+        m_LastLayer = lastLayer;
+    }
+
+    virtual const char* GetName() const override
+    {
+        return m_FirstLayer->GetName();
+    }
+
+    virtual unsigned int GetNumInputSlots() const override
+    {
+        return m_FirstLayer->GetNumInputSlots();
+    }
+
+    virtual unsigned int GetNumOutputSlots() const override
+    {
+        return m_LastLayer->GetNumOutputSlots();
+    }
+
+    virtual const armnn::IInputSlot& GetInputSlot(unsigned int index) const override
+    {
+        return m_FirstLayer->GetInputSlot(index);
+    }
+
+    virtual armnn::IInputSlot& GetInputSlot(unsigned int index) override
+    {
+        return m_FirstLayer->GetInputSlot(index);
+    }
+
+    virtual const armnn::IOutputSlot& GetOutputSlot(unsigned int index) const override
+    {
+        return m_LastLayer->GetOutputSlot(index);
+    }
+
+    virtual armnn::IOutputSlot& GetOutputSlot(unsigned int index) override
+    {
+        return m_LastLayer->GetOutputSlot(index);
+    }
+
+    virtual std::vector<armnn::TensorShape> InferOutputShapes(
+        const std::vector<armnn::TensorShape>& inputShapes) const override
+    {
+        // NOTE: do not expect this function to be used. Likely that if it is it might need to be overridden
+        //       for particular sequences of operators.
+        return m_FirstLayer->InferOutputShapes(inputShapes);
+    }
+
+    virtual armnn::LayerGuid GetGuid() const override
+    {
+        return m_FirstLayer->GetGuid();
+    }
+
+    // The Accept function needs to be wrapped in a no warn macro to avoid deprecation warnings from
+    // the deprecated ILayerVisitor which is used in the function.
+    ARMNN_NO_DEPRECATE_WARN_BEGIN
+    ARMNN_DEPRECATED_MSG_REMOVAL_DATE("Accept is deprecated. The ILayerVisitor that works in conjunction with this "
+                                      "Accept function is deprecated. Use IStrategy in combination with "
+                                      "ExecuteStrategy instead, which is an ABI/API stable version of the "
+                                      "visitor pattern.",
+                                      "22.05")
+    virtual void Accept(armnn::ILayerVisitor& visitor) const override
+    {
+        // Do not expect this function to be used so not providing an implementation
+    }
+    ARMNN_NO_DEPRECATE_WARN_END
+
+    virtual void ExecuteStrategy(armnn::IStrategy& strategy) const override
+    {
+        // Do not expect this function to be used so not providing an implementation
+        // if an implementation is required and the chain contains more than two operators
+        // would have to provide a way to record the intermediate layers so they could be
+        // visited... the same applies to the Accept method above and the BackendSelectionHint
+        // below.
+    }
+
+    virtual void BackendSelectionHint(armnn::Optional<armnn::BackendId> backend) override
+    {
+        // Do not expect this function to be used so not providing an implementation
+    }
+
+    virtual armnn::LayerType GetType() const override
+    {
+        return m_FirstLayer->GetType();
+    }
+
+private:
+    armnn::IConnectableLayer* m_FirstLayer;
+    armnn::IConnectableLayer* m_LastLayer;
+};
+
+} // namespace armnnDelegate