[newrt] Implement Reshape kernel for CPU (#1950)
author김수진/동작제어Lab(SR)/Engineer/삼성전자 <sjsujin.kim@samsung.com>
Mon, 16 Jul 2018 05:04:31 +0000 (14:04 +0900)
committer박세희/동작제어Lab(SR)/Principal Engineer/삼성전자 <saehie.park@samsung.com>
Mon, 16 Jul 2018 05:04:31 +0000 (14:04 +0900)
* [newrt] Implement Reshape kernel for CPU

This commit implements Reshape kernel for CPU in new_runtime.

Signed-off-by: sjsujinkim <sjsujin.kim@samsung.com>
* Add errer handling in sizeOfData

runtimes/new_runtime/src/internal/cpu/StageGenerator.cc
runtimes/new_runtime/src/internal/kernels/cpufallback/OperationUtils.cc
runtimes/new_runtime/src/internal/kernels/cpufallback/OperationUtils.h
runtimes/new_runtime/src/internal/kernels/cpufallback/ReshapeLayer.cc [new file with mode: 0644]
runtimes/new_runtime/src/internal/kernels/cpufallback/ReshapeLayer.h [new file with mode: 0644]

index b944398..19319f8 100644 (file)
@@ -8,6 +8,7 @@
 #include "internal/kernels/cpufallback/MaxPoolLayer.h"
 #include "internal/kernels/cpufallback/ConcatLayer.h"
 #include "internal/kernels/cpufallback/FullyConnectedLayer.h"
+#include "internal/kernels/cpufallback/ReshapeLayer.h"
 
 #include "logging.h"
 
@@ -421,7 +422,39 @@ Stage StageGenerator::generate(const ::internal::tflite::op::FullyConnected::Nod
 
 Stage StageGenerator::generate(const ::internal::tflite::op::Reshape::Node &node)
 {
-  throw std::runtime_error("NYI");
+  const ::internal::tflite::operand::Index output_index{node.param().output_index};
+  const ::internal::tflite::operand::Index input_index{node.param().input_index};
+
+  struct Param
+  {
+    int output_index;
+    int input_index;
+
+    ::internal::tflite::operand::Shape ofm_shape{1};
+    ::internal::tflite::operand::Shape ifm_shape{1};
+  };
+
+  Param param;
+
+  param.output_index = output_index.asInt();
+  param.input_index = input_index.asInt();
+
+  param.ofm_shape = _ctx.at(output_index).shape();
+  param.ifm_shape = _ctx.at(input_index).shape();
+
+  auto tensors = _tensor_builder;
+
+  return [tensors, param](IExecutionBuilder &builder) {
+    auto output_alloc = tensors->at(::internal::tflite::operand::Index{param.output_index}).get();
+    auto input_alloc = tensors->at(::internal::tflite::operand::Index{param.input_index}).get();
+
+    std::unique_ptr<::internal::kernels::cpu::ReshapeLayer> fn{
+        new ::internal::kernels::cpu::ReshapeLayer};
+
+    fn->configure(input_alloc->buffer(), param.ifm_shape, output_alloc->buffer(), param.ofm_shape);
+
+    builder.append(std::move(fn));
+  };
 }
 
 Stage StageGenerator::generate(const ::internal::tflite::op::Softmax::Node &node)
index 7ca51a9..062f1fd 100644 (file)
@@ -152,6 +152,35 @@ Shape convertShape(const ::internal::tflite::operand::Shape &o)
   return shape;
 }
 
+size_t sizeOfData(OperandType type, const std::vector<uint32_t> &dimensions)
+{
+  size_t size = 4;
+
+  switch (type)
+  {
+    case OperandType::FLOAT32:
+    case OperandType::INT32:
+    case OperandType::UINT32:
+    case OperandType::TENSOR_FLOAT32:
+    case OperandType::TENSOR_INT32:
+      size = 4;
+      break;
+    case OperandType::TENSOR_QUANT8_ASYMM:
+      size = 1;
+      break;
+    default:
+      throw std::runtime_error("Not supported operand type.");
+      break;
+  }
+
+  for (auto d : dimensions)
+  {
+    size *= d;
+  }
+
+  return size;
+}
+
 } // namespace cpu
 } // namespace kernels
 } // namespace internal
index d72d348..6660941 100644 (file)
@@ -83,6 +83,8 @@ void CalculateActivationRangeUint8(int32_t activation, const Shape &outputShape,
 
 Shape convertShape(const ::internal::tflite::operand::Shape &o);
 
+uint32_t sizeOfData(OperandType type, const std::vector<uint32_t> &dimensions);
+
 } // namespace cpu
 } // namespace kernels
 } // namespace internal
diff --git a/runtimes/new_runtime/src/internal/kernels/cpufallback/ReshapeLayer.cc b/runtimes/new_runtime/src/internal/kernels/cpufallback/ReshapeLayer.cc
new file mode 100644 (file)
index 0000000..1027316
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 "ReshapeLayer.h"
+
+#include "tensorflow/contrib/lite/kernels/internal/optimized/optimized_ops.h"
+#include "tensorflow/contrib/lite/kernels/internal/reference/reference_ops.h"
+#include "internal/kernels/cpufallback/OperationUtils.h"
+
+namespace internal
+{
+namespace kernels
+{
+namespace cpu
+{
+
+bool ReshapeLayer::reshapeGeneric()
+{
+  size_t count = sizeOfData(_inputShape.type, _inputShape.dimensions);
+  memcpy(reinterpret_cast<void *>(_outputData), reinterpret_cast<const void *>(_inputData), count);
+  return true;
+}
+
+void ReshapeLayer::configure(uint8_t *inputData, const internal::tflite::operand::Shape &inputShape,
+                             uint8_t *outputData,
+                             const internal::tflite::operand::Shape &outputShape)
+{
+  _inputData = inputData;
+  _inputShape = convertShape(inputShape);
+  _outputData = outputData;
+  _outputShape = convertShape(outputShape);
+}
+
+void ReshapeLayer::run() { reshapeGeneric(); }
+
+} // namespace cpu
+} // namespace kernels
+} // namespace internal
diff --git a/runtimes/new_runtime/src/internal/kernels/cpufallback/ReshapeLayer.h b/runtimes/new_runtime/src/internal/kernels/cpufallback/ReshapeLayer.h
new file mode 100644 (file)
index 0000000..65e24ce
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef __INTERNAL_KERNELS_CPU_RESHAPELAYER_H__
+#define __INTERNAL_KERNELS_CPU_RESHAPELAYER_H__
+
+#include <NeuralNetworks.h>
+
+#include <arm_compute/runtime/IFunction.h>
+
+#include "internal/Model.h"
+#include "internal/kernels/cpufallback/OperationUtils.h"
+
+using namespace internal::kernels::cpu;
+
+namespace internal
+{
+namespace kernels
+{
+namespace cpu
+{
+
+class ReshapeLayer : public ::arm_compute::IFunction
+{
+public:
+  ReshapeLayer() {}
+
+public:
+  bool reshapeGeneric();
+
+  void configure(uint8_t *inputData, const internal::tflite::operand::Shape &inputShape,
+                 uint8_t *outputData, const internal::tflite::operand::Shape &outputShape);
+
+  void run();
+
+private:
+  uint8_t *_inputData;
+  uint8_t *_outputData;
+
+  Shape _inputShape;
+  Shape _outputShape;
+};
+
+} // namespace cpu
+} // namespace kernels
+} // namespace internal
+
+#endif // __INTERNAL_KERNELS_CPU_RESHAPELAYER_H__