From: 박종현/동작제어Lab(SR)/Senior Engineer/삼성전자 Date: Mon, 9 Apr 2018 07:19:53 +0000 (+0900) Subject: [Pure ACL NN Runtime] Partailly implement addOperation (#501) X-Git-Tag: 0.1~381 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ac98dd4681939e5c584a8221dbc93de6b5ff53cc;p=platform%2Fcore%2Fml%2Fnnfw.git [Pure ACL NN Runtime] Partailly implement addOperation (#501) This commit implements ANeuralNetworksModel_addOperation partially for Conv2D operation with implicit paddings. Signed-off-by: Jonghyun Park --- diff --git a/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/Model.cc b/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/Model.cc index 580c925..5658f81 100644 --- a/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/Model.cc +++ b/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/Model.cc @@ -20,6 +20,25 @@ namespace internal { namespace tflite { +namespace op +{ +namespace Conv2D +{ +namespace implicit +{ + +void Node::accept(NodeVisitor &&v) const { v.visit(*this); } + +} // namespace implicit +} // namespace Conv2D +} // namespace op +} // namespace tflite +} // namespace internal + +namespace internal +{ +namespace tflite +{ namespace operand { diff --git a/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/Model.h b/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/Model.h index a593d17..6675d7a 100644 --- a/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/Model.h +++ b/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/Model.h @@ -187,6 +187,136 @@ namespace internal { namespace tflite { +namespace op +{ + +struct NodeVisitor; + +struct Node +{ + virtual ~Node() = default; + + virtual void accept(NodeVisitor &&) const = 0; +}; + +} // namespace op +} // namespace tflite +} // namespace internal + +namespace internal +{ +namespace tflite +{ +namespace op +{ +namespace Conv2D +{ +namespace implicit +{ + +struct Param +{ + int32_t ofm_index; + + int32_t ifm_index; + int32_t ker_index; + int32_t bias_index; + + int32_t hstride; + int32_t vstride; + + int32_t padding; + int32_t activation; +}; + +class Node final : public op::Node +{ +public: + Node(const Param ¶m) : _param(param) + { + // DO NOTHING + } + +public: + virtual ~Node() = default; + +public: + const Param ¶m(void) const { return _param; } + +public: + void accept(NodeVisitor &&) const override; + +private: + const Param _param; +}; + +} // namespace implicit +} // namespace Conv2D +} // namespace op +} // namespace tflite +} // namespace internal + +namespace internal +{ +namespace tflite +{ +namespace op +{ + +struct NodeVisitor +{ + virtual ~NodeVisitor() = default; + + virtual void visit(const Conv2D::implicit::Node &) = 0; +}; + +} // namespace op +} // namespace tflite +} // namespace internal + +namespace internal +{ +namespace tflite +{ +namespace op +{ + +class Sequence +{ +public: + Sequence() = default; + +public: + uint32_t size(void) const { return _ops.size(); } + +public: + op::Node &at(uint32_t nth) { return *(_ops.at(nth)); } + const op::Node &at(uint32_t nth) const { return *(_ops.at(nth)); } + +private: + Sequence &emplace_back(std::unique_ptr &&node) + { + _ops.emplace_back(std::move(node)); + return (*this); + } +public: + template Sequence &emplace_back(Args&&... args) + { + emplace_back(std::unique_ptr(new T{std::forward(args)...})); + } + +private: + std::vector> _ops; +}; + +} // namespace op +} // namespace tflite +} // namespace internal + +namespace internal +{ +namespace tflite +{ class Model { @@ -194,8 +324,13 @@ public: operand::Set &operands(void) { return _operands; } const operand::Set &operands(void) const { return _operands; } +public: + op::Sequence &operations(void) { return _operations; } + const op::Sequence &operations(void) const { return _operations; } + private: operand::Set _operands; + op::Sequence _operations; }; } // namespace tflite diff --git a/tools/nnapi_bindings/bindings/pure_arm_compute/src/model.cc b/tools/nnapi_bindings/bindings/pure_arm_compute/src/model.cc index df587e4..1241d6b 100644 --- a/tools/nnapi_bindings/bindings/pure_arm_compute/src/model.cc +++ b/tools/nnapi_bindings/bindings/pure_arm_compute/src/model.cc @@ -1,6 +1,7 @@ #include #include +#include #include "model.h" #include "memory.h" @@ -80,6 +81,52 @@ ANeuralNetworksModel_addOperation(ANeuralNetworksModel* model, uint32_t inputCount, const uint32_t* inputs, uint32_t outputCount, const uint32_t* outputs) { + switch (type) + { + case ANEURALNETWORKS_CONV_2D: + { + // inputCount is either 7 or 9 acccording to NN API specification. + // - Padding is implicit when inputCount is 7 + // - Padding is explicit when inputCount is 9 + assert(inputCount == 7 || inputCount == 9); + assert(outputCount == 1); + + if (inputCount == 7) + { + internal::tflite::op::Conv2D::implicit::Param param; + + param.ofm_index = outputs[0]; + + // Each input should be interpreted as follows: + // + // 0 -> IFM Tensor Index + // 1 -> Kernel Tensor Index + // 2 -> Bias Tensor Index + // 3 -> Padding Code (ANEURALNETWORKS_PADDING_SAME or ANEURALNETWORKS_PADDING_VALID) + // 4 -> Stride (width) + // 5 -> Stride (height) + // 6 -> Activation + param.ifm_index = inputs[0]; + param.ker_index = inputs[1]; + param.bias_index = inputs[2]; + // TODO Set hstride/vstride/padding/activation + + // Add 'operations' + auto &operations = model->deref().operations(); + + operations.emplace_back(param); + } + else + { + throw std::runtime_error{"Explicit padding in Conv2D is not supported, yet"}; + } + + break; + } + default: + throw std::runtime_error{"Not supported operation"}; + }; + return ANEURALNETWORKS_NO_ERROR; }