Unify NEON and OpenCL implementation of reshape layer (#800)
author김정현/동작제어Lab(SR)/Senior Engineer/삼성전자 <jh0822.kim@samsung.com>
Thu, 19 Apr 2018 03:57:33 +0000 (12:57 +0900)
committer박세희/동작제어Lab(SR)/Principal Engineer/삼성전자 <saehie.park@samsung.com>
Thu, 19 Apr 2018 03:57:33 +0000 (12:57 +0900)
NEON and OpenCL implementations of reshape layer are very similar.
This commit
- extracts common features to `src/Reshape.h`
- implement different parts into `neon/Reshape.cpp` and `cl/Reshape.cpp`.

Signed-off-by: Junghyun Kim <jh0822.kim@samsung.com>
src/kernel/acl/src/Reshape.h [new file with mode: 0644]
src/kernel/acl/src/cl/Reshape.cpp
src/kernel/acl/src/neon/Reshape.cpp

diff --git a/src/kernel/acl/src/Reshape.h b/src/kernel/acl/src/Reshape.h
new file mode 100644 (file)
index 0000000..1d4d5dc
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef __NNFW_KERNEL_ACL_RESHAPE_COMMON_H__
+#define __NNFW_KERNEL_ACL_RESHAPE_COMMON_H__
+#include <OperationsUtils.h>
+#include <arm_compute/core/TensorShape.h>
+#include <arm_compute/core/TensorInfo.h>
+
+// TODO: fix include path in CMakeFiles
+#include "IO_accessor.h"
+#include "shape.h"
+
+namespace nnfw {
+namespace kernel {
+namespace acl {
+
+namespace common {
+
+typedef std::function<void (void)> sync_scheduler_f;
+
+template<class TensorT, class LayerT>
+bool reshapeGeneric(const void* inputData, const android::nn::Shape& inputShape,
+                    void* outputData, const android::nn::Shape& outputShape,
+                    sync_scheduler_f sync_scheduler) {
+
+  auto input_shape = util::fromNNShape(inputShape);
+  auto output_shape = util::fromNNShape(outputShape);
+
+  TensorT input(arm_compute::TensorInfo(input_shape, arm_compute::Format::F32));
+  TensorT output(arm_compute::TensorInfo(output_shape, arm_compute::Format::F32));
+
+  LayerT l;
+
+  l.configure(input.ptr(), output.ptr());
+
+  input.allocate();
+  output.allocate();
+
+  TensorAccess<InputAccessor>(input.ref(), (float*)inputData, inputShape);
+
+  l.run();
+
+  sync_scheduler();
+
+  TensorAccess<OutputAccessor>(output.ref(), (float*)outputData, outputShape);
+
+  return true;
+}
+
+} // namespace common
+
+} // namespace acl
+} // namespace kernel
+} // namespace nnfw
+
+#endif // __NNFW_KERNEL_ACL_RESHAPE_COMMON_H__
index d6a3b87..c51fc20 100644 (file)
@@ -5,38 +5,21 @@
 // TODO: fix include path in CMakeFiles
 #include "../IO_accessor.h"
 #include "../shape.h"
+#include "../CLUniqueTensor.h"
+#include "../Reshape.h"
 
 namespace nnfw {
 namespace kernel {
 namespace acl {
 
-bool reshapeGeneric(const void* inputData, const android::nn::Shape& inputShape,
-                    void* outputData, const android::nn::Shape& outputShape) {
-
-  auto input_shape = util::fromNNShape(inputShape);
-  auto output_shape = util::fromNNShape(outputShape);
-
-  arm_compute::CLTensor input, output;
-
-  input.allocator()->init(arm_compute::TensorInfo(input_shape, arm_compute::Format::F32));
-  output.allocator()->init(arm_compute::TensorInfo(output_shape, arm_compute::Format::F32));
-
-  arm_compute::CLReshapeLayer l;
-
-  l.configure(&input, &output);
-
-  input.allocator()->allocate();
-  output.allocator()->allocate();
-
-  TensorAccess<InputAccessor>(input, (float*)inputData, inputShape);
-
-  l.run();
-
+static void sync_scheduler() {
   arm_compute::CLScheduler::get().sync();
+}
 
-  TensorAccess<OutputAccessor>(output, (float*)outputData, outputShape);
-
-  return true;
+bool reshapeGeneric(const void* inputData, const android::nn::Shape& inputShape,
+                    void* outputData, const android::nn::Shape& outputShape) {
+  return common::reshapeGeneric<CLUniqueTensor, arm_compute::CLReshapeLayer>
+    (inputData, inputShape, outputData, outputShape, sync_scheduler);
 }
 
 } // namespace acl
index 6ac181e..a126fe3 100644 (file)
@@ -5,40 +5,28 @@
 // TODO: fix include path in CMakeFiles
 #include "../IO_accessor.h"
 #include "../shape.h"
+#include "../NEUniqueTensor.h"
+#include "../Reshape.h"
 
 namespace nnfw {
 namespace kernel {
 namespace acl {
+
 namespace neon {
 
+static void sync_scheduler() {
+  arm_compute::CLScheduler::get().sync();
+}
+
 bool reshapeGeneric(const void* inputData, const android::nn::Shape& inputShape,
                     void* outputData, const android::nn::Shape& outputShape) {
-
-  auto input_shape = util::fromNNShape(inputShape);
-  auto output_shape = util::fromNNShape(outputShape);
-
-  arm_compute::Tensor input, output;
-
-  input.allocator()->init(arm_compute::TensorInfo(input_shape, arm_compute::Format::F32));
-  output.allocator()->init(arm_compute::TensorInfo(output_shape, arm_compute::Format::F32));
-
-  arm_compute::NEReshapeLayer l;
-
-  l.configure(&input, &output);
-
-  input.allocator()->allocate();
-  output.allocator()->allocate();
-
-  TensorAccess<InputAccessor>(input, (float*)inputData, inputShape);
-
-  l.run();
-
-  TensorAccess<OutputAccessor>(output, (float*)outputData, outputShape);
-
-  return true;
+  return common::reshapeGeneric<NEUniqueTensor, arm_compute::NEReshapeLayer>
+    (inputData, inputShape, outputData, outputShape, sync_scheduler);
 }
 
 } // namespace neon
+
 } // namespace acl
 } // namespace kernel
 } // namespace nnfw
+