From 03ca1ee718f8c28a8ae1dfe5ad7ab8e930a74e70 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EB=B0=95=EC=A2=85=ED=98=84/=EB=8F=99=EC=9E=91=EC=A0=9C?= =?utf8?q?=EC=96=B4Lab=28SR=29/Senior=20Engineer/=EC=82=BC=EC=84=B1?= =?utf8?q?=EC=A0=84=EC=9E=90?= Date: Mon, 16 Apr 2018 09:14:39 +0900 Subject: [PATCH] [Pure ACL] Record AvgPool2D operation in model (#671) This commit allows pure ACL NN runtime to record AvgPool2D operation in its model. Note that compilation and execution is not supported, yet. Signed-off-by: Jonghyun Park --- .../bindings/pure_arm_compute/src/compilation.cc | 6 ++ .../pure_arm_compute/src/internal/op/AvgPool2D.cc | 65 +++++++++++++++++++++ .../pure_arm_compute/src/internal/op/AvgPool2D.h | 66 ++++++++++++++++++++++ .../pure_arm_compute/src/internal/op/NodeVisitor.h | 2 + .../bindings/pure_arm_compute/src/model.cc | 25 ++++++++ 5 files changed, 164 insertions(+) create mode 100644 tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/op/AvgPool2D.cc create mode 100644 tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/op/AvgPool2D.h diff --git a/tools/nnapi_bindings/bindings/pure_arm_compute/src/compilation.cc b/tools/nnapi_bindings/bindings/pure_arm_compute/src/compilation.cc index 29168e7..8482e32 100644 --- a/tools/nnapi_bindings/bindings/pure_arm_compute/src/compilation.cc +++ b/tools/nnapi_bindings/bindings/pure_arm_compute/src/compilation.cc @@ -213,6 +213,7 @@ public: public: void visit(const ::internal::tflite::op::Conv2D::implicit::Node &node) override; void visit(const ::internal::tflite::op::MaxPool2D::implicit::Node &node) override; + void visit(const ::internal::tflite::op::AvgPool2D::implicit::Node &node) override; private: const ::internal::tflite::operand::Set &_ctx; @@ -432,6 +433,11 @@ void Planner::visit(const ::internal::tflite::op::MaxPool2D::implicit::Node &nod _builder.addStage(stage); } +void Planner::visit(const ::internal::tflite::op::AvgPool2D::implicit::Node &node) +{ + throw std::runtime_error{"Not implemented, yet"}; +} + class AllocationContext final : public IAllocationContext { public: diff --git a/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/op/AvgPool2D.cc b/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/op/AvgPool2D.cc new file mode 100644 index 0000000..a6a7cf4 --- /dev/null +++ b/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/op/AvgPool2D.cc @@ -0,0 +1,65 @@ +#include "internal/op/AvgPool2D.h" +#include "internal/op/NodeVisitor.h" + +#include + +namespace internal +{ +namespace tflite +{ +namespace op +{ +namespace AvgPool2D +{ +namespace implicit +{ + +void Node::accept(NodeVisitor &&v) const { v.visit(*this); } + +} // namespace implicit +} // namespace AvgPool2D +} // namespace op +} // namespace tflite +} // namespace internal + +namespace internal +{ +namespace tflite +{ +namespace op +{ +namespace AvgPool2D +{ +namespace implicit +{ + +Param::Param(uint32_t inputCount, const uint32_t* inputs, + uint32_t outputCount, const uint32_t* outputs) +{ + assert(inputCount == 7 && outputCount == 1); + + ofm_index = outputs[0]; + + // Each input should be interpreted as follows: + // + // 0 -> IFM Tensor Index + // 1 -> Padding Code (ANEURALNETWORKS_PADDING_SAME or ANEURALNETWORKS_PADDING_VALID) Index + // 2 -> Horizontal (over width) Stride Index + // 3 -> Vertial (over height) Stride Index + // 4 -> Filter Width Index + // 5 -> Filter Height Index + // 6 -> FuseCode (activation) Index + ifm_index = inputs[0]; + padding_index = inputs[1]; + hstride_index = inputs[2]; + vstride_index = inputs[3]; + kw_index = inputs[4]; + kh_index = inputs[5]; + activation_index = inputs[6]; +} + +} // namespace implicit +} // namespace AvgPool2D +} // namespace op +} // namespace tflite +} // namespace internal diff --git a/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/op/AvgPool2D.h b/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/op/AvgPool2D.h new file mode 100644 index 0000000..efe4a51 --- /dev/null +++ b/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/op/AvgPool2D.h @@ -0,0 +1,66 @@ +#ifndef __INTERNAL_OP_AVG_POOL_2D_H__ +#define __INTERNAL_OP_AVG_POOL_2D_H__ + +#include "internal/op/Node.h" + +#include + +namespace internal +{ +namespace tflite +{ +namespace op +{ +namespace AvgPool2D +{ +namespace implicit +{ + +struct Param +{ + int32_t ofm_index; + + int32_t ifm_index; + + int32_t kw_index; + int32_t kh_index; + + int32_t hstride_index; + int32_t vstride_index; + + int32_t padding_index; + int32_t activation_index; + + Param() = default; + Param(uint32_t inputCount, const uint32_t* inputs, + uint32_t outputCount, const uint32_t* outputs); +}; + +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 AvgPool2D +} // namespace op +} // namespace tflite +} // namespace internal + +#endif // __INTERNAL_OP_MAX_POOL_2D_H__ diff --git a/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/op/NodeVisitor.h b/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/op/NodeVisitor.h index f5857ff..cd2155b 100644 --- a/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/op/NodeVisitor.h +++ b/tools/nnapi_bindings/bindings/pure_arm_compute/src/internal/op/NodeVisitor.h @@ -3,6 +3,7 @@ #include "internal/op/Conv2D.h" #include "internal/op/MaxPool2D.h" +#include "internal/op/AvgPool2D.h" namespace internal { @@ -17,6 +18,7 @@ struct NodeVisitor virtual void visit(const Conv2D::implicit::Node &) = 0; virtual void visit(const MaxPool2D::implicit::Node &) = 0; + virtual void visit(const AvgPool2D::implicit::Node &) = 0; }; } // namespace op 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 9f2384c..853845e 100644 --- a/tools/nnapi_bindings/bindings/pure_arm_compute/src/model.cc +++ b/tools/nnapi_bindings/bindings/pure_arm_compute/src/model.cc @@ -133,6 +133,31 @@ ANeuralNetworksModel_addOperation(ANeuralNetworksModel* model, break; } + case ANEURALNETWORKS_AVERAGE_POOL_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) + { + using internal::tflite::op::AvgPool2D::implicit::Param; + using internal::tflite::op::AvgPool2D::implicit::Node; + + // Add 'operations' + auto &operations = model->deref().operations(); + + operations.emplace_back(Param{inputCount, inputs, outputCount, outputs}); + } + else + { + throw std::runtime_error{"Explicit padding in AvgPool2D is not supported, yet"}; + } + + break; + } default: throw std::runtime_error{"Not supported operation"}; }; -- 2.7.4