From 4480a441f9273be5c08b524bfa9ffd67734da5ce 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/Staff=20Engineer/=EC=82=BC=EC=84=B1?= =?utf8?q?=EC=A0=84=EC=9E=90?= Date: Wed, 28 Nov 2018 12:43:49 +0900 Subject: [PATCH] [enco] Delegate Concat to NN runtime (#2426) With this commit, enco backend delegates ConcatF to NN runtime instead of lowering it as a sequence of Shuffle. Signed-off-by: Jonghyun Park --- contrib/enco/core/src/ANN/IR/Operation.def | 1 + contrib/enco/core/src/Backend.cpp | 4 +-- contrib/enco/core/src/Transforms/Split.cpp | 56 ++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/contrib/enco/core/src/ANN/IR/Operation.def b/contrib/enco/core/src/ANN/IR/Operation.def index 56b2e5c..693377e 100644 --- a/contrib/enco/core/src/ANN/IR/Operation.def +++ b/contrib/enco/core/src/ANN/IR/Operation.def @@ -12,3 +12,4 @@ ANN_OPERATION(AVG_POOL_2D, ANEURALNETWORKS_AVERAGE_POOL_2D) ANN_OPERATION(RELU, ANEURALNETWORKS_RELU) ANN_OPERATION(RELU6, ANEURALNETWORKS_RELU6) ANN_OPERATION(PAD, ANEURALNETWORKS_PAD) +ANN_OPERATION(CONCAT, ANEURALNETWORKS_CONCATENATION) diff --git a/contrib/enco/core/src/Backend.cpp b/contrib/enco/core/src/Backend.cpp index 245f86c..43feb9d 100644 --- a/contrib/enco/core/src/Backend.cpp +++ b/contrib/enco/core/src/Backend.cpp @@ -119,8 +119,8 @@ void BackendImpl::compile(coco::Module *m, coco::Data *d) // Lower Copy as Shuffle lower_copy(code(sess)); - // Lower ConcatF as Shuffle - lower_concat(code(sess)); + // TODO Lower ConcatF that cannot be delegated to NNAPI as Shuffle + // lower_concat(code(sess)); generate_bypass_shuffle(code(sess)); diff --git a/contrib/enco/core/src/Transforms/Split.cpp b/contrib/enco/core/src/Transforms/Split.cpp index 677506d..7be8225 100644 --- a/contrib/enco/core/src/Transforms/Split.cpp +++ b/contrib/enco/core/src/Transforms/Split.cpp @@ -110,6 +110,35 @@ private: coco::FeatureObject *_out; }; +/** + * WARN The current implementation supports concatenation along depth only + */ +class ANNConcatAppender final : public ANNOpAppender +{ +public: + void left(coco::FeatureObject *o) { _left = o; } + void right(coco::FeatureObject *o) { _right = o; } + void out(coco::FeatureObject *o) { _out = o; } + +public: + void append(ANNBinder *binder) const override + { + auto left = binder->addOperand(_left); + auto right = binder->addOperand(_right); + auto axis = binder->addOperand(); + binder->setOperand(axis, 3 /* DEPTH */); + + auto out = binder->addOperand(_out); + + binder->addOperation(ann::Operation::Code::CONCAT, {left, right, axis}, {out}); + } + +private: + coco::FeatureObject *_left; + coco::FeatureObject *_right; + coco::FeatureObject *_out; +}; + class ANNConv2DAppender final : public ANNOpAppender { public: @@ -759,6 +788,33 @@ public: return std::move(app); } } + else if (auto op = eval->op()->asConcatF()) + { + auto left_load = op->left()->asLoad(); + auto right_load = op->right()->asLoad(); + + if (left_load && right_load && (op->axis() == coco::ConcatF::Axis::Depth)) + { + // Let's compile the following code fragment: + // + // %ofm = eval(ConcatF(Depth, Load(%left), Load(%right))) + // + auto left = left_load->object()->asFeature(); + auto right = right_load->object()->asFeature(); + assert(left != nullptr && right != nullptr); + + auto out = eval->out()->asFeature(); + assert(out != nullptr); + + auto app = make_unique(); + + app->left(left); + app->right(right); + app->out(out); + + return std::move(app); + } + } // Return nullptr if a given Eval instruction is incompatible return nullptr; -- 2.7.4