[nnc backend] Add FullyConnected(matmul) operation implementation (#538)
authorVladimir Plazun/AI Tools Lab /SRR/Engineer/삼성전자 <v.plazun@partner.samsung.com>
Mon, 9 Jul 2018 14:46:57 +0000 (17:46 +0300)
committerSergey Vostokov/AI Tools Lab /SRR/Staff Engineer/삼성전자 <s.vostokov@samsung.com>
Mon, 9 Jul 2018 14:46:57 +0000 (23:46 +0900)
Add FullyConnected(matmul) operation implementation

Used by model IR interpreter

Signed-off-by: Vladimir Plazun <v.plazun@partner.samsung.com>
contrib/nnc/libs/backend/interpreter/core/include/interpreter/ops/FullyConnected.h [new file with mode: 0644]
contrib/nnc/libs/backend/interpreter/core/src/ops/FullyConnected.cpp [new file with mode: 0644]

diff --git a/contrib/nnc/libs/backend/interpreter/core/include/interpreter/ops/FullyConnected.h b/contrib/nnc/libs/backend/interpreter/core/include/interpreter/ops/FullyConnected.h
new file mode 100644 (file)
index 0000000..dda586c
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef _NNC_CORE_BACKEND_INTERPRETER_FULLYCONNECTED_
+#define _NNC_CORE_BACKEND_INTERPRETER_FULLYCONNECTED_
+
+#include "nnc/core/linalg/ShapeRange.h"
+#include "nnc/core/IR/model/operations/fully_connected_op.h"
+#include "interpreter/ops/OperationImpl.h"
+
+namespace nncc
+{
+namespace contrib
+{
+namespace backend
+{
+namespace interpreter
+{
+namespace impl
+{
+
+using nncc::contrib::core::IR::model::ops::FullyConnectedOp;
+
+template<typename T>
+class FullyConnected : public OperationImpl<T>
+{
+public:
+  FullyConnected(const TensorVariant &_input, const FullyConnectedOp &_op) : _op(_op), _input(_input) {}
+
+  std::vector<TensorVariant> operator()() override
+  {
+    TensorVariant res = OperationImpl<T>::allocate_tensor(_op.getOutputShape(0));
+    Tensor<T> accessor(res);
+
+    ShapeRange outRange(res.getShape());
+
+    Tensor<T> weights(_op.getWeights());
+    const Shape &wShape = weights.getShape();
+    uint32_t wRank = wShape.rank();
+
+    const Shape &inShape = _input.getShape();
+    uint32_t inRank = inShape.rank();
+
+    assert(wShape.dim(wRank - 2) == inShape.dim(inRank - 1));
+
+    const uint32_t len = wShape.dim(wRank - 2);
+
+    uint32_t row;
+    uint32_t col;
+    for (auto &outIdx : outRange)
+    {
+      Index tIdx = outIdx;
+      T& outputElement = accessor.at(outIdx);
+      col = tIdx.at(wRank - 1);
+      row = tIdx.at(wRank - 2);
+      for (uint32_t i = 0u; i < len; ++i)
+      {
+        tIdx.at(wRank - 1) = i;
+        const T& w = weights.at(tIdx);
+        tIdx.at(wRank - 1) = col;
+        tIdx.at(wRank - 2) = i;
+        const T& in = _input.at(tIdx);
+        tIdx.at(wRank - 2) = row;
+        outputElement += w * in;
+      }
+    }
+
+    return {res};
+  }
+
+private:
+  const FullyConnectedOp &_op;
+  const Tensor<T> _input;
+};
+
+} // namespace impl
+} // namespace interpreter
+} // namespace backend
+} // namespace contrib
+} // namespace nncc
+
+#endif //_NNC_CORE_BACKEND_INTERPRETER_FULLYCONNECTED_
diff --git a/contrib/nnc/libs/backend/interpreter/core/src/ops/FullyConnected.cpp b/contrib/nnc/libs/backend/interpreter/core/src/ops/FullyConnected.cpp
new file mode 100644 (file)
index 0000000..4833ff1
--- /dev/null
@@ -0,0 +1,3 @@
+#include "interpreter/ops/FullyConnected.h"
+//Do not remove
+//Used to force compile FullyConnected.h