[neurun] Introduce tensor conversion Nodes (#2064)
author김수진/동작제어Lab(SR)/Engineer/삼성전자 <sjsujin.kim@samsung.com>
Thu, 26 Jul 2018 02:04:36 +0000 (11:04 +0900)
committer이춘석/동작제어Lab(SR)/Staff Engineer/삼성전자 <chunseok.lee@samsung.com>
Thu, 26 Jul 2018 02:04:36 +0000 (11:04 +0900)
* [neurun] Introduce tensor conversion Nodes

Related : #1974

This commit introduces tensor conversion Nodes.

- FromCommon : "common order shape" -> " specific shape of next op".
- ToCommon : "specific shape of prev op" -> "common shape".

The name of 'Common' would be changed to another.

It's part PR of #2056(https://github.sec.samsung.net/STAR/nnfw/pull/2056#issuecomment-128722)

Signed-off-by: sjsujinkim <sjsujin.kim@samsung.com>
* Remove unnecessary op list

* Seperate ACL/CPU converter Nodes

runtimes/neurun/src/backend/acl_cl/StageGenerator.cc
runtimes/neurun/src/backend/acl_cl/StageGenerator.h
runtimes/neurun/src/backend/cpu/StageGenerator.cc
runtimes/neurun/src/backend/cpu/StageGenerator.h
runtimes/neurun/src/compilation.cc
runtimes/neurun/src/internal/IStageGenerator.h
runtimes/neurun/src/internal/op/NodeVisitor.h
runtimes/neurun/src/internal/op/TensorConvert_Acl.cc [new file with mode: 0644]
runtimes/neurun/src/internal/op/TensorConvert_Acl.h [new file with mode: 0644]
runtimes/neurun/src/internal/op/TensorConvert_Cpu.cc [new file with mode: 0644]
runtimes/neurun/src/internal/op/TensorConvert_Cpu.h [new file with mode: 0644]

index 5de30f7..a484c4f 100644 (file)
@@ -504,5 +504,27 @@ Stage StageGenerator::generate(const ::internal::tflite::op::Softmax::Node &node
   };
 }
 
+Stage StageGenerator::generate(
+    const ::internal::tflite::op::TensorConvert::CpuFromCommon::Node &node)
+{
+  throw std::runtime_error("Wrong Approach");
+}
+
+Stage StageGenerator::generate(const ::internal::tflite::op::TensorConvert::CpuToCommon::Node &node)
+{
+  throw std::runtime_error("Wrong Approach");
+}
+
+Stage StageGenerator::generate(
+    const ::internal::tflite::op::TensorConvert::AclFromCommon::Node &node)
+{
+  throw std::runtime_error("NYI - StageGenerator::generate(TensorConvert::AclFromCommon)");
+}
+
+Stage StageGenerator::generate(const ::internal::tflite::op::TensorConvert::AclToCommon::Node &node)
+{
+  throw std::runtime_error("NYI - StageGenerator::generate(TensorConvert::AclToCommon)");
+}
+
 } // namespace arm_compute
 } // namespace internal
index 3f687f5..5480012 100644 (file)
@@ -26,6 +26,14 @@ public:
   virtual Stage generate(const ::internal::tflite::op::FullyConnected::Node &node) override;
   virtual Stage generate(const ::internal::tflite::op::Reshape::Node &node) override;
   virtual Stage generate(const ::internal::tflite::op::Softmax::Node &node) override;
+  virtual Stage
+  generate(const ::internal::tflite::op::TensorConvert::CpuFromCommon::Node &node) override;
+  virtual Stage
+  generate(const ::internal::tflite::op::TensorConvert::CpuToCommon::Node &node) override;
+  virtual Stage
+  generate(const ::internal::tflite::op::TensorConvert::AclFromCommon::Node &node) override;
+  virtual Stage
+  generate(const ::internal::tflite::op::TensorConvert::AclToCommon::Node &node) override;
 
 private:
   const ::internal::tflite::operand::Set &_ctx;
index d05d2a8..1b0c270 100644 (file)
@@ -503,5 +503,27 @@ Stage StageGenerator::generate(const ::internal::tflite::op::Softmax::Node &node
   };
 }
 
+Stage StageGenerator::generate(
+    const ::internal::tflite::op::TensorConvert::CpuFromCommon::Node &node)
+{
+  throw std::runtime_error("NYI - StageGenerator::generate(TensorConvert::CpuFromCommon)");
+}
+
+Stage StageGenerator::generate(const ::internal::tflite::op::TensorConvert::CpuToCommon::Node &node)
+{
+  throw std::runtime_error("NYI - StageGenerator::generate(TensorConvert::CpuToCommon)");
+}
+
+Stage StageGenerator::generate(
+    const ::internal::tflite::op::TensorConvert::AclFromCommon::Node &node)
+{
+  throw std::runtime_error("Wrong Approach");
+}
+
+Stage StageGenerator::generate(const ::internal::tflite::op::TensorConvert::AclToCommon::Node &node)
+{
+  throw std::runtime_error("Wrong Approach");
+}
+
 } // namespace stage
 } // namespace internal
index 1a6c38e..9c41759 100644 (file)
@@ -27,6 +27,14 @@ public:
   virtual Stage generate(const ::internal::tflite::op::FullyConnected::Node &node) override;
   virtual Stage generate(const ::internal::tflite::op::Reshape::Node &node) override;
   virtual Stage generate(const ::internal::tflite::op::Softmax::Node &node) override;
+  virtual Stage
+  generate(const ::internal::tflite::op::TensorConvert::CpuFromCommon::Node &node) override;
+  virtual Stage
+  generate(const ::internal::tflite::op::TensorConvert::CpuToCommon::Node &node) override;
+  virtual Stage
+  generate(const ::internal::tflite::op::TensorConvert::AclFromCommon::Node &node) override;
+  virtual Stage
+  generate(const ::internal::tflite::op::TensorConvert::AclToCommon::Node &node) override;
 
 private:
   const ::internal::tflite::operand::Set &_ctx;
index 076448f..7f652a6 100644 (file)
@@ -87,6 +87,16 @@ public:
 
 #include "internal/op/Op.lst"
 #undef OP
+
+    // TODO : It's just workaround. It's logic should be changed.
+    _gen_map[typeid(::internal::tflite::op::TensorConvert::CpuFromCommon::Node)] =
+        backend_manager.get("cpu");
+    _gen_map[typeid(::internal::tflite::op::TensorConvert::CpuToCommon::Node)] =
+        backend_manager.get("cpu");
+    _gen_map[typeid(::internal::tflite::op::TensorConvert::AclFromCommon::Node)] =
+        backend_manager.get("acl_cl");
+    _gen_map[typeid(::internal::tflite::op::TensorConvert::AclToCommon::Node)] =
+        backend_manager.get("acl_cl");
   }
 
   std::shared_ptr<::internal::IInitializerGenerator>
@@ -149,6 +159,10 @@ public:
   void visit(const ::internal::tflite::op::FullyConnected::Node &node) override;
   void visit(const ::internal::tflite::op::Reshape::Node &node) override;
   void visit(const ::internal::tflite::op::Softmax::Node &node) override;
+  void visit(const ::internal::tflite::op::TensorConvert::CpuFromCommon::Node &node) override;
+  void visit(const ::internal::tflite::op::TensorConvert::CpuToCommon::Node &node) override;
+  void visit(const ::internal::tflite::op::TensorConvert::AclFromCommon::Node &node) override;
+  void visit(const ::internal::tflite::op::TensorConvert::AclToCommon::Node &node) override;
 
 private:
   const ::internal::tflite::operand::Set &_ctx;
@@ -347,6 +361,26 @@ void Planner::visit(const ::internal::tflite::op::Softmax::Node &node)
   _builder.addStage(stage_gen->generate(node));
 }
 
+void Planner::visit(const ::internal::tflite::op::TensorConvert::CpuFromCommon::Node &node)
+{
+  throw std::runtime_error("NYI - Planner::visit(TensorConvert::CpuFromCommon");
+}
+
+void Planner::visit(const ::internal::tflite::op::TensorConvert::CpuToCommon::Node &node)
+{
+  throw std::runtime_error("NYI - Planner::visit(TensorConvert::CpuToCommon");
+}
+
+void Planner::visit(const ::internal::tflite::op::TensorConvert::AclFromCommon::Node &node)
+{
+  throw std::runtime_error("NYI - Planner::visit(TensorConvert::FromCommon");
+}
+
+void Planner::visit(const ::internal::tflite::op::TensorConvert::AclToCommon::Node &node)
+{
+  throw std::runtime_error("NYI - Planner::visit(TensorConvert::AclToCommon");
+}
+
 class TensorMarker : public ::internal::tflite::op::NodeVisitor
 {
 public:
@@ -363,6 +397,10 @@ public:
   void visit(const ::internal::tflite::op::FullyConnected::Node &node) override;
   void visit(const ::internal::tflite::op::Reshape::Node &node) override;
   void visit(const ::internal::tflite::op::Softmax::Node &node) override;
+  void visit(const ::internal::tflite::op::TensorConvert::CpuFromCommon::Node &node) override;
+  void visit(const ::internal::tflite::op::TensorConvert::CpuToCommon::Node &node) override;
+  void visit(const ::internal::tflite::op::TensorConvert::AclFromCommon::Node &node) override;
+  void visit(const ::internal::tflite::op::TensorConvert::AclToCommon::Node &node) override;
 
 private:
   void mark(int32_t ind) { _tensor_builder.mark(::internal::tflite::operand::Index{ind}); }
@@ -427,6 +465,26 @@ void TensorMarker::visit(const ::internal::tflite::op::Softmax::Node &node)
   mark(param.input_index);
 }
 
+void TensorMarker::visit(const ::internal::tflite::op::TensorConvert::CpuFromCommon::Node &node)
+{
+  // DO NOTHING
+}
+
+void TensorMarker::visit(const ::internal::tflite::op::TensorConvert::CpuToCommon::Node &node)
+{
+  // DO NOTHING
+}
+
+void TensorMarker::visit(const ::internal::tflite::op::TensorConvert::AclFromCommon::Node &node)
+{
+  // DO NOTHING
+}
+
+void TensorMarker::visit(const ::internal::tflite::op::TensorConvert::AclToCommon::Node &node)
+{
+  // DO NOTHING
+}
+
 class ExecutionBuilder final : public IExecutionBuilder
 {
 public:
index 9932e46..9341d2f 100644 (file)
@@ -40,6 +40,12 @@ struct IStageGenerator
   virtual Stage generate(const ::internal::tflite::op::FullyConnected::Node &node) = 0;
   virtual Stage generate(const ::internal::tflite::op::Reshape::Node &node) = 0;
   virtual Stage generate(const ::internal::tflite::op::Softmax::Node &node) = 0;
+  virtual Stage
+  generate(const ::internal::tflite::op::TensorConvert::CpuFromCommon::Node &node) = 0;
+  virtual Stage generate(const ::internal::tflite::op::TensorConvert::CpuToCommon::Node &node) = 0;
+  virtual Stage
+  generate(const ::internal::tflite::op::TensorConvert::AclFromCommon::Node &node) = 0;
+  virtual Stage generate(const ::internal::tflite::op::TensorConvert::AclToCommon::Node &node) = 0;
 };
 
 } // namespace internal
index e44467e..c837f58 100644 (file)
@@ -8,6 +8,8 @@
 #include "internal/op/Reshape.h"
 #include "internal/op/FullyConnected.h"
 #include "internal/op/Softmax.h"
+#include "internal/op/TensorConvert_Cpu.h"
+#include "internal/op/TensorConvert_Acl.h"
 
 namespace internal
 {
@@ -27,6 +29,10 @@ struct NodeVisitor
   virtual void visit(const Reshape::Node &) = 0;
   virtual void visit(const FullyConnected::Node &) = 0;
   virtual void visit(const Softmax::Node &) = 0;
+  virtual void visit(const TensorConvert::CpuFromCommon::Node &) = 0;
+  virtual void visit(const TensorConvert::CpuToCommon::Node &) = 0;
+  virtual void visit(const TensorConvert::AclFromCommon::Node &) = 0;
+  virtual void visit(const TensorConvert::AclToCommon::Node &) = 0;
 };
 
 } // namespace op
diff --git a/runtimes/neurun/src/internal/op/TensorConvert_Acl.cc b/runtimes/neurun/src/internal/op/TensorConvert_Acl.cc
new file mode 100644 (file)
index 0000000..9d16f33
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "internal/op/TensorConvert_Acl.h"
+#include "internal/op/NodeVisitor.h"
+
+#include <cassert>
+
+namespace internal
+{
+namespace tflite
+{
+namespace op
+{
+namespace TensorConvert
+{
+namespace AclFromCommon
+{
+
+void Node::accept(NodeVisitor &&v) const { v.visit(*this); }
+
+} // namespace AclFromCommon
+} // namespace TensorConvert
+} // namespace op
+} // namespace tflite
+} // namespace internal
+
+namespace internal
+{
+namespace tflite
+{
+namespace op
+{
+namespace TensorConvert
+{
+namespace AclFromCommon
+{
+
+Param::Param(uint32_t inputIndex) { ifm_index = inputIndex; }
+
+} // namespace AclFromCommon
+} // namespace TensorConvert
+} // namespace op
+} // namespace tflite
+} // namespace internal
+
+namespace internal
+{
+namespace tflite
+{
+namespace op
+{
+namespace TensorConvert
+{
+namespace AclToCommon
+{
+
+void Node::accept(NodeVisitor &&v) const { v.visit(*this); }
+
+} // namespace AclToCommon
+} // namespace TensorConvert
+} // namespace op
+} // namespace tflite
+} // namespace internal
+
+namespace internal
+{
+namespace tflite
+{
+namespace op
+{
+namespace TensorConvert
+{
+namespace AclToCommon
+{
+
+Param::Param(uint32_t outputIndex) { ofm_index = outputIndex; }
+
+} // namespace AclToCommon
+} // namespace TensorConvert
+} // namespace op
+} // namespace tflite
+} // namespace internal
diff --git a/runtimes/neurun/src/internal/op/TensorConvert_Acl.h b/runtimes/neurun/src/internal/op/TensorConvert_Acl.h
new file mode 100644 (file)
index 0000000..303f71c
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __INTERNAL_OP_TENSOR_CONVERT_ACL_H__
+#define __INTERNAL_OP_TENSOR_CONVERT_ACL_H__
+
+#include "internal/op/Node.h"
+
+#include <cstdint>
+
+namespace internal
+{
+namespace tflite
+{
+namespace op
+{
+namespace TensorConvert
+{
+namespace AclFromCommon
+{
+
+struct Param
+{
+  int32_t ifm_index;
+
+  Param() = default;
+  Param(uint32_t inputIndex);
+};
+
+class Node final : public op::Node
+{
+public:
+  Node(const Param &param) : _param(param)
+  {
+    // DO NOTHING
+  }
+
+public:
+  virtual ~Node() = default;
+
+public:
+  const Param &param(void) const { return _param; }
+
+public:
+  void accept(NodeVisitor &&) const override;
+
+private:
+  const Param _param;
+};
+
+} // namespace AclFromCommon
+} // namespace TensorConvert
+} // namespace op
+} // namespace tflite
+} // namespace internal
+
+namespace internal
+{
+namespace tflite
+{
+namespace op
+{
+namespace TensorConvert
+{
+namespace AclToCommon
+{
+
+struct Param
+{
+  int32_t ofm_index;
+
+  Param() = default;
+  Param(uint32_t outputIndex);
+};
+
+class Node final : public op::Node
+{
+public:
+  Node(const Param &param) : _param(param)
+  {
+    // DO NOTHING
+  }
+
+public:
+  virtual ~Node() = default;
+
+public:
+  const Param &param(void) const { return _param; }
+
+public:
+  void accept(NodeVisitor &&) const override;
+
+private:
+  const Param _param;
+};
+
+} // namespace AclToCommon
+} // namespace TensorConvert
+} // namespace op
+} // namespace tflite
+} // namespace internal
+
+#endif // __INTERNAL_OP_TENSOR_CONVERT_ACL_H__
diff --git a/runtimes/neurun/src/internal/op/TensorConvert_Cpu.cc b/runtimes/neurun/src/internal/op/TensorConvert_Cpu.cc
new file mode 100644 (file)
index 0000000..1563480
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "internal/op/TensorConvert_Cpu.h"
+#include "internal/op/NodeVisitor.h"
+
+#include <cassert>
+
+namespace internal
+{
+namespace tflite
+{
+namespace op
+{
+namespace TensorConvert
+{
+namespace CpuFromCommon
+{
+
+void Node::accept(NodeVisitor &&v) const { v.visit(*this); }
+
+} // namespace CpuFromCommon
+} // namespace TensorConvert
+} // namespace op
+} // namespace tflite
+} // namespace internal
+
+namespace internal
+{
+namespace tflite
+{
+namespace op
+{
+namespace TensorConvert
+{
+namespace CpuFromCommon
+{
+
+Param::Param(uint32_t inputIndex) { ifm_index = inputIndex; }
+
+} // namespace FromCommon
+} // namespace TensorConvert
+} // namespace op
+} // namespace tflite
+} // namespace internal
+
+namespace internal
+{
+namespace tflite
+{
+namespace op
+{
+namespace TensorConvert
+{
+namespace CpuToCommon
+{
+
+void Node::accept(NodeVisitor &&v) const { v.visit(*this); }
+
+} // namespace CpuToCommon
+} // namespace TensorConvert
+} // namespace op
+} // namespace tflite
+} // namespace internal
+
+namespace internal
+{
+namespace tflite
+{
+namespace op
+{
+namespace TensorConvert
+{
+namespace CpuToCommon
+{
+
+Param::Param(uint32_t outputIndex) { ofm_index = outputIndex; }
+
+} // namespace CpuToCommon
+} // namespace TensorConvert
+} // namespace op
+} // namespace tflite
+} // namespace internal
diff --git a/runtimes/neurun/src/internal/op/TensorConvert_Cpu.h b/runtimes/neurun/src/internal/op/TensorConvert_Cpu.h
new file mode 100644 (file)
index 0000000..e6dd7d6
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __INTERNAL_OP_TENSOR_CONVERT_CPU_H__
+#define __INTERNAL_OP_TENSOR_CONVERT_CPU_H__
+
+#include "internal/op/Node.h"
+
+#include <cstdint>
+
+namespace internal
+{
+namespace tflite
+{
+namespace op
+{
+namespace TensorConvert
+{
+namespace CpuFromCommon
+{
+
+struct Param
+{
+  int32_t ifm_index;
+
+  Param() = default;
+  Param(uint32_t inputIndex);
+};
+
+class Node final : public op::Node
+{
+public:
+  Node(const Param &param) : _param(param)
+  {
+    // DO NOTHING
+  }
+
+public:
+  virtual ~Node() = default;
+
+public:
+  const Param &param(void) const { return _param; }
+
+public:
+  void accept(NodeVisitor &&) const override;
+
+private:
+  const Param _param;
+};
+
+} // namespace CpuFromCommon
+} // namespace TensorConvert
+} // namespace op
+} // namespace tflite
+} // namespace internal
+
+namespace internal
+{
+namespace tflite
+{
+namespace op
+{
+namespace TensorConvert
+{
+namespace CpuToCommon
+{
+
+struct Param
+{
+  int32_t ofm_index;
+
+  Param() = default;
+  Param(uint32_t outputIndex);
+};
+
+class Node final : public op::Node
+{
+public:
+  Node(const Param &param) : _param(param)
+  {
+    // DO NOTHING
+  }
+
+public:
+  virtual ~Node() = default;
+
+public:
+  const Param &param(void) const { return _param; }
+
+public:
+  void accept(NodeVisitor &&) const override;
+
+private:
+  const Param _param;
+};
+
+} // namespace CpuToCommon
+} // namespace TensorConvert
+} // namespace op
+} // namespace tflite
+} // namespace internal
+
+#endif // __INTERNAL_OP_TENSOR_CONVERT_CPU_H__