From 67394d1566086a9c26ab26a0a191e950ed6a7598 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=9C=A4=ED=98=84=EC=8B=9D/=EB=8F=99=EC=9E=91=EC=A0=9C?= =?utf8?q?=EC=96=B4Lab=28SR=29/Principal=20Engineer/=EC=82=BC=EC=84=B1?= =?utf8?q?=EC=A0=84=EC=9E=90?= Date: Thu, 14 Jun 2018 17:22:48 +0900 Subject: [PATCH] [Pure ACL] added Rank 2 input (#1678) This commit intrudocues rank 2 input. Naming (`matrix`) was used to be aligned with `MatrixSink` Tested with tflite file with `Mul` (2d x scalar) and `Gather`. Signed-off-by: Hyun Sik Yoon --- include/util/matrix/Shape.h | 46 +++++++++++++++++++++ runtimes/pure_arm_compute/src/execution.cc | 38 ++++++++++++++--- .../pure_arm_compute/src/internal/MatrixSource.h | 47 ++++++++++++++++++++++ runtimes/pure_arm_compute/src/internal/Model.cc | 10 +++++ runtimes/pure_arm_compute/src/internal/Model.h | 2 + 5 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 include/util/matrix/Shape.h create mode 100644 runtimes/pure_arm_compute/src/internal/MatrixSource.h diff --git a/include/util/matrix/Shape.h b/include/util/matrix/Shape.h new file mode 100644 index 0000000..e2c20b4 --- /dev/null +++ b/include/util/matrix/Shape.h @@ -0,0 +1,46 @@ +/* + * 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. + */ + +// for 2D tensor +#ifndef __NNFW_UTIL_MATRIX_SHAPE_H__ +#define __NNFW_UTIL_MATRIX_SHAPE_H__ + +#include + +namespace nnfw +{ +namespace util +{ +namespace matrix +{ + +struct Shape +{ + int32_t H; // Height + int32_t W; // Width + + Shape() = default; + Shape(int32_t height, int32_t width) : H{height}, W{width} + { + // DO NOTHING + } +}; + +} // namespace feature +} // namespace util +} // namespace nnfw + +#endif // __NNFW_UTIL_MATRIX_SHAPE_H__ diff --git a/runtimes/pure_arm_compute/src/execution.cc b/runtimes/pure_arm_compute/src/execution.cc index 291b43d..12c3ec2 100644 --- a/runtimes/pure_arm_compute/src/execution.cc +++ b/runtimes/pure_arm_compute/src/execution.cc @@ -4,6 +4,7 @@ #include "execution.h" #include "internal/VectorSource.h" +#include "internal/MatrixSource.h" #include "internal/FeatureSource.h" #include "internal/TensorSource.h" #include "internal/nnapi/feature/View.h" @@ -105,6 +106,36 @@ static void asVectorSource(ANeuralNetworksExecution *execution, int32_t type, in } } +static void asMatrixSource(ANeuralNetworksExecution *execution, int32_t type, int32_t index, + const nnfw::util::matrix::Shape &shape, const void *buffer, + size_t length) +{ + switch (type) + { + case ANEURALNETWORKS_FLOAT32: + case ANEURALNETWORKS_TENSOR_FLOAT32: + execution->source>(index, shape, reinterpret_cast(buffer), + length); + break; + case ANEURALNETWORKS_INT32: + case ANEURALNETWORKS_TENSOR_INT32: + execution->source>(index, shape, + reinterpret_cast(buffer), length); + break; + case ANEURALNETWORKS_UINT32: + execution->source>(index, shape, + reinterpret_cast(buffer), length); + break; + case ANEURALNETWORKS_TENSOR_QUANT8_ASYMM: + execution->source>(index, shape, + reinterpret_cast(buffer), length); + break; + default: + throw std::runtime_error("Not supported, yet"); + break; + } +} + static void asTensorSource(ANeuralNetworksExecution *execution, int32_t type, int32_t index, const nnfw::util::tensor::Shape &shape, const void *buffer, size_t length) @@ -317,12 +348,9 @@ int ANeuralNetworksExecution_setInput(ANeuralNetworksExecution *execution, int32 } else if (operands.at(operand_index).shape().rank() == 2) { - // TODO check whether the following assert is needed or not - // assert(operands.at(operand_index).shape().dim(0) == 1); - const auto len = - operands.at(operand_index).shape().dim(0) * operands.at(operand_index).shape().dim(1); + const auto &operand_shape = operands.at(operand_index).shape().asMatrix(); - asVectorSource(execution, input_type, index, len, buffer, length); + asMatrixSource(execution, input_type, index, operand_shape, buffer, length); } else if (operands.at(operand_index).shape().rank() == 3) { diff --git a/runtimes/pure_arm_compute/src/internal/MatrixSource.h b/runtimes/pure_arm_compute/src/internal/MatrixSource.h new file mode 100644 index 0000000..b1fb3c3 --- /dev/null +++ b/runtimes/pure_arm_compute/src/internal/MatrixSource.h @@ -0,0 +1,47 @@ +#ifndef __INTERNAL_MATRIX_SOURCE_H__ +#define __INTERNAL_MATRIX_SOURCE_H__ + +#include +#include +#include + +#include "internal/Source.h" + +template class MatrixSource final : public Source +{ +public: + MatrixSource(const nnfw::util::matrix::Shape &shape, const T *base, const size_t size) + : _shape{shape}, _base{base}, _size{size} + { + // do nothing + } + +public: + void push(::arm_compute::ITensor &tensor) const override + { + using ::arm_compute::Window; + using ::arm_compute::Iterator; + using ::arm_compute::Coordinates; + using ::arm_compute::execute_window_loop; + + Window window; + window.use_tensor_dimensions(tensor.info()->tensor_shape(), ::arm_compute::Window::DimY); + + int32_t width = _shape.W; + + Iterator it(&tensor, window); + execute_window_loop(window, + [&](const ::arm_compute::Coordinates &id) { + const auto height = id.y(); + memcpy(it.ptr(), _base + height * width, width * sizeof(T)); + }, + it); + } + +private: + const nnfw::util::matrix::Shape _shape; + const T *const _base; + const size_t _size; +}; + +#endif // __INTERNAL_MATRIX_SOURCE_H__ diff --git a/runtimes/pure_arm_compute/src/internal/Model.cc b/runtimes/pure_arm_compute/src/internal/Model.cc index a3be331..a063b27 100644 --- a/runtimes/pure_arm_compute/src/internal/Model.cc +++ b/runtimes/pure_arm_compute/src/internal/Model.cc @@ -21,6 +21,16 @@ int32_t Shape::asVector(void) const return dim(0); } +nnfw::util::matrix::Shape Shape::asMatrix(void) const +{ + assert(rank() == 2); + + const auto height = dim(0); + const auto width = dim(1); + + return nnfw::util::matrix::Shape(height, width); +} + nnfw::util::feature::Shape Shape::asFeature(void) const { assert(rank() == 4); diff --git a/runtimes/pure_arm_compute/src/internal/Model.h b/runtimes/pure_arm_compute/src/internal/Model.h index 54c2c53..7357997 100644 --- a/runtimes/pure_arm_compute/src/internal/Model.h +++ b/runtimes/pure_arm_compute/src/internal/Model.h @@ -31,6 +31,7 @@ private: #include #include "util/feature/Shape.h" +#include "util/matrix/Shape.h" #include "util/kernel/Shape.h" #include "util/tensor/Shape.h" @@ -49,6 +50,7 @@ public: public: int32_t asVector(void) const; nnfw::util::feature::Shape asFeature(void) const; + nnfw::util::matrix::Shape asMatrix(void) const; nnfw::util::kernel::Shape asKernel(void) const; nnfw::util::tensor::Shape asTensor(void) const; }; -- 2.7.4