From 511a9fab2813b170a6ddde072d79b07fbdbac611 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EA=B9=80=EC=88=98=EC=A7=84/On-Device=20Lab=28SR=29/Enginee?= =?utf8?q?r/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Wed, 13 Mar 2019 16:24:30 +0900 Subject: [PATCH] [neurun] Enable Floor, SpaceToDepth ops (#4686) This commit enables `Floor`, `SpaceToDepth` for `acl_cl`. Signed-off-by: sjsujinkim --- .../nnapi/frontend/wrapper/OperationFactory.cc | 29 ++++++++ .../neurun/src/backend/acl_cl/StageGenerator.cc | 80 ++++++++++++++++++++++ .../neurun/src/backend/acl_cl/StageGenerator.h | 2 + runtimes/neurun/src/compiler/OperationValidator.cc | 30 ++++++++ runtimes/neurun/src/compiler/OperationValidator.h | 1 + runtimes/neurun/src/model/operation/FloorNode.cc | 39 +++++++++++ runtimes/neurun/src/model/operation/FloorNode.h | 51 ++++++++++++++ runtimes/neurun/src/model/operation/Node.Include.h | 2 + runtimes/neurun/src/model/operation/Op.lst | 2 + .../neurun/src/model/operation/SpaceToDepthNode.cc | 40 +++++++++++ .../neurun/src/model/operation/SpaceToDepthNode.h | 63 +++++++++++++++++ tests/nnapi/nnapi_gtest.skip.armv7l-linux.neurun | 2 - .../neurun_frameworktest_list.armv7l.acl_cl.txt | 2 + 13 files changed, 341 insertions(+), 2 deletions(-) create mode 100644 runtimes/neurun/src/model/operation/FloorNode.cc create mode 100644 runtimes/neurun/src/model/operation/FloorNode.h create mode 100644 runtimes/neurun/src/model/operation/SpaceToDepthNode.cc create mode 100644 runtimes/neurun/src/model/operation/SpaceToDepthNode.h diff --git a/runtimes/neurun/frontend/nnapi/frontend/wrapper/OperationFactory.cc b/runtimes/neurun/frontend/nnapi/frontend/wrapper/OperationFactory.cc index 48e8f16..2c4873a 100644 --- a/runtimes/neurun/frontend/nnapi/frontend/wrapper/OperationFactory.cc +++ b/runtimes/neurun/frontend/nnapi/frontend/wrapper/OperationFactory.cc @@ -700,6 +700,35 @@ OperationFactory::OperationFactory() return new operation::ReLU6Node{inputs, outputs}; }; + + _map[ANEURALNETWORKS_FLOOR] = [](const OperationFactory::Param &init_param) { + assert(init_param.input_count == 1 && init_param.output_count == 1); + + operand::IndexSet outputs{init_param.outputs[0]}; + + // Each input should be interpreted as follows: + // 0 -> input Tensor Index + operand::IndexSet inputs{init_param.inputs[0]}; + + return new operation::FloorNode{inputs, outputs}; + }; + + _map[ANEURALNETWORKS_SPACE_TO_DEPTH] = [](const OperationFactory::Param &init_param) { + assert(init_param.input_count == 2 && init_param.output_count == 1); + + operand::IndexSet outputs{init_param.outputs[0]}; + + // Each input should be interpreted as follows: + // + // 0 -> Input Tensor Index + // 1 -> Block size Index + operand::IndexSet inputs{init_param.inputs[0]}; + + operation::SpaceToDepthNode::Param param; + param.block_size_index = operand::Index{init_param.inputs[1]}; + + return new operation::SpaceToDepthNode{inputs, outputs, param}; + }; } neurun::model::operation::Node *OperationFactory::create(ANeuralNetworksOperationType type, diff --git a/runtimes/neurun/src/backend/acl_cl/StageGenerator.cc b/runtimes/neurun/src/backend/acl_cl/StageGenerator.cc index f292299..b07f887 100644 --- a/runtimes/neurun/src/backend/acl_cl/StageGenerator.cc +++ b/runtimes/neurun/src/backend/acl_cl/StageGenerator.cc @@ -1860,6 +1860,86 @@ void StageGenerator::visit(const model::operation::ReLU6Node &node) }); } +void StageGenerator::visit(const model::operation::FloorNode &node) +{ + const auto ofm_index{node.getOutputs().at(0)}; + const auto ifm_index{node.getInputs().at(model::operation::FloorNode::Input::INPUT)}; + + struct Param + { + model::operand::Index ofm_index; + model::operand::Index ifm_index; + }; + + Param param; + + param.ofm_index = ofm_index; + param.ifm_index = ifm_index; + + auto tensors = _tensor_builder; + + returnStage([tensors, param](IExecutionBuilder &builder) { + auto ofm_alloc = tensors->at(param.ofm_index).get(); + auto ifm_alloc = tensors->at(param.ifm_index).get(); + + std::unique_ptr<::arm_compute::IFunction> fn; + + auto l = make_layer<::arm_compute::CLFloor>(); + + l->configure(ifm_alloc->handle(), ofm_alloc->handle()); + + fn = std::move(l); + + auto acl_fn = make_cl_function(std::move(fn)); + + builder.append(std::move(acl_fn)); + }); +} + +void StageGenerator::visit(const model::operation::SpaceToDepthNode &node) +{ + const auto ofm_index{node.getOutputs().at(0)}; + const auto ifm_index{node.getInputs().at(model::operation::SpaceToDepthNode::Input::INPUT)}; + const auto block_size_index{node.param().block_size_index}; + + // Construct operation parameters + struct Param + { + model::operand::Index ofm_index; + model::operand::Index ifm_index; + + int32_t block_size; + }; + + Param param; + + param.ofm_index = ofm_index; + param.ifm_index = ifm_index; + param.block_size = _ctx.at(block_size_index).asScalar(); + + auto tensors = _tensor_builder; + + tensors->dimCorrection(ofm_index, false); + tensors->dimCorrection(ifm_index, false); + + returnStage([tensors, param](IExecutionBuilder &builder) { + auto ofm_alloc = tensors->at(param.ofm_index).get(); + auto ifm_alloc = tensors->at(param.ifm_index).get(); + + std::unique_ptr<::arm_compute::IFunction> fn; + + auto l = make_layer<::arm_compute::CLSpaceToDepth>(); + + l->configure(ifm_alloc->handle(), ofm_alloc->handle(), param.block_size); + + fn = std::move(l); + + auto acl_fn = make_cl_function(std::move(fn)); + + builder.append(std::move(acl_fn)); + }); +} + } // namespace acl_cl } // namespace backend } // namespace neurun diff --git a/runtimes/neurun/src/backend/acl_cl/StageGenerator.h b/runtimes/neurun/src/backend/acl_cl/StageGenerator.h index 0e289a5..c552f1b 100644 --- a/runtimes/neurun/src/backend/acl_cl/StageGenerator.h +++ b/runtimes/neurun/src/backend/acl_cl/StageGenerator.h @@ -65,6 +65,8 @@ public: virtual void visit(const model::operation::ResizeBilinearNode &) override; virtual void visit(const model::operation::ReLU1Node &) override; virtual void visit(const model::operation::ReLU6Node &) override; + virtual void visit(const model::operation::FloorNode &) override; + virtual void visit(const model::operation::SpaceToDepthNode &) override; private: const neurun::model::operand::Set &_ctx; diff --git a/runtimes/neurun/src/compiler/OperationValidator.cc b/runtimes/neurun/src/compiler/OperationValidator.cc index 4af32ce..7e475ec 100644 --- a/runtimes/neurun/src/compiler/OperationValidator.cc +++ b/runtimes/neurun/src/compiler/OperationValidator.cc @@ -194,5 +194,35 @@ void OperationValidator::visit(const model::operation::ReduceMaxNode &node) } } +void OperationValidator::visit(const model::operation::SpaceToDepthNode &node) +{ + const auto ofm_index{node.getOutputs().at(0)}; + const auto ifm_index{node.getInputs().at(model::operation::SpaceToDepthNode::Input::INPUT)}; + const auto block_size_index{node.param().block_size_index}; + + const auto input_batch = _ctx.at(ifm_index).shape().dim(0); + const auto output_batch = _ctx.at(ofm_index).shape().dim(0); + const auto input_depth = _ctx.at(ifm_index).shape().dim(3); + const auto output_depth = _ctx.at(ofm_index).shape().dim(3); + const auto block_size = _ctx.at(block_size_index).asScalar(); + const auto input_height = _ctx.at(ifm_index).shape().dim(1); + const auto input_width = _ctx.at(ifm_index).shape().dim(2); + + UNUSED_RELEASE(input_batch); + UNUSED_RELEASE(output_batch); + UNUSED_RELEASE(input_depth); + UNUSED_RELEASE(output_depth); + UNUSED_RELEASE(block_size); + UNUSED_RELEASE(input_height); + UNUSED_RELEASE(input_width); + + // All assertions as per NNAPI specification. + assert(_ctx.at(ifm_index).shape().rank() == 4); + assert(_ctx.at(ofm_index).shape().rank() == 4); + assert((block_size >= 1) && (input_height % block_size == 0) && (input_width % block_size == 0)); + assert(input_batch == output_batch); + assert(input_depth * block_size * block_size == output_depth); +} + } // namespace compiler } // namespace neurun diff --git a/runtimes/neurun/src/compiler/OperationValidator.h b/runtimes/neurun/src/compiler/OperationValidator.h index 951eea3..8fd82e6 100644 --- a/runtimes/neurun/src/compiler/OperationValidator.h +++ b/runtimes/neurun/src/compiler/OperationValidator.h @@ -47,6 +47,7 @@ public: virtual void visit(const model::operation::ReduceSumNode &node) override; virtual void visit(const model::operation::TransposeNode &node) override; virtual void visit(const model::operation::ReduceMaxNode &node) override; + virtual void visit(const model::operation::SpaceToDepthNode &node) override; private: const neurun::model::operand::Set &_ctx; diff --git a/runtimes/neurun/src/model/operation/FloorNode.cc b/runtimes/neurun/src/model/operation/FloorNode.cc new file mode 100644 index 0000000..ed06102 --- /dev/null +++ b/runtimes/neurun/src/model/operation/FloorNode.cc @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019 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. + */ + +#include "FloorNode.h" + +#include + +#include "NodeVisitor.h" + +namespace neurun +{ +namespace model +{ +namespace operation +{ + +void FloorNode::accept(NodeVisitor &&v) const { v.visit(*this); } + +FloorNode::FloorNode(const operand::IndexSet &inputs, const operand::IndexSet &outputs) + : model::operation::Node{OperandConstraint::createExact(1u), inputs, outputs} +{ +} + +} // namespace operation +} // namespace model +} // namespace neurun diff --git a/runtimes/neurun/src/model/operation/FloorNode.h b/runtimes/neurun/src/model/operation/FloorNode.h new file mode 100644 index 0000000..403ea6a --- /dev/null +++ b/runtimes/neurun/src/model/operation/FloorNode.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019 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. + */ + +#ifndef __NEURUN_MODEL_OPERATION_FLOOR_NODE_H__ +#define __NEURUN_MODEL_OPERATION_FLOOR_NODE_H__ + +#include + +#include "model/operation/Node.h" + +namespace neurun +{ +namespace model +{ +namespace operation +{ + +class FloorNode : public model::operation::Node +{ +public: + enum Input + { + INPUT = 0 + }; + +public: + FloorNode(const operand::IndexSet &inputs, const operand::IndexSet &outputs); + +public: + virtual void accept(NodeVisitor &&) const override; + virtual std::string getName() const override { return "Floor"; } +}; + +} // namespace operation +} // namespace model +} // namespace neurun + +#endif // __NEURUN_MODEL_OPERATION_FLOOR_NODE_H__ diff --git a/runtimes/neurun/src/model/operation/Node.Include.h b/runtimes/neurun/src/model/operation/Node.Include.h index 6104f27..b4aba7f 100644 --- a/runtimes/neurun/src/model/operation/Node.Include.h +++ b/runtimes/neurun/src/model/operation/Node.Include.h @@ -45,3 +45,5 @@ #include "ResizeBilinearNode.h" #include "ReLU1Node.h" #include "ReLU6Node.h" +#include "FloorNode.h" +#include "SpaceToDepthNode.h" diff --git a/runtimes/neurun/src/model/operation/Op.lst b/runtimes/neurun/src/model/operation/Op.lst index ed2d6db..da17e6d 100644 --- a/runtimes/neurun/src/model/operation/Op.lst +++ b/runtimes/neurun/src/model/operation/Op.lst @@ -49,4 +49,6 @@ OP(ReLUNode , true , RELU) OP(ResizeBilinearNode , true , RESIZE_BILINEAR) OP(ReLU1Node , true , RELU1) OP(ReLU6Node , true , RELU6) +OP(FloorNode , true , FLOOR) +OP(SpaceToDepthNode , true , SPACE_TO_DEPTH) OP(PermuteNode , false , NOT_AVAILABLE) diff --git a/runtimes/neurun/src/model/operation/SpaceToDepthNode.cc b/runtimes/neurun/src/model/operation/SpaceToDepthNode.cc new file mode 100644 index 0000000..baef777 --- /dev/null +++ b/runtimes/neurun/src/model/operation/SpaceToDepthNode.cc @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019 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. + */ + +#include "SpaceToDepthNode.h" + +#include + +#include "NodeVisitor.h" + +namespace neurun +{ +namespace model +{ +namespace operation +{ + +void SpaceToDepthNode::accept(NodeVisitor &&v) const { v.visit(*this); } + +SpaceToDepthNode::SpaceToDepthNode(const operand::IndexSet &inputs, + const operand::IndexSet &outputs, const Param ¶m) + : model::operation::Node{OperandConstraint::createExact(1u), inputs, outputs}, _param{param} +{ +} + +} // namespace operation +} // namespace model +} // namespace neurun diff --git a/runtimes/neurun/src/model/operation/SpaceToDepthNode.h b/runtimes/neurun/src/model/operation/SpaceToDepthNode.h new file mode 100644 index 0000000..e7bcd91 --- /dev/null +++ b/runtimes/neurun/src/model/operation/SpaceToDepthNode.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019 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. + */ + +#ifndef __NEURUN_MODEL_OPERATION_SPACE_TO_DEPTH_NODE_H__ +#define __NEURUN_MODEL_OPERATION_SPACE_TO_DEPTH_NODE_H__ + +#include + +#include "model/operation/Node.h" + +namespace neurun +{ +namespace model +{ +namespace operation +{ + +class SpaceToDepthNode : public model::operation::Node +{ +public: + enum Input + { + INPUT = 0 + }; + + struct Param + { + operand::Index block_size_index; + }; + +public: + SpaceToDepthNode(const operand::IndexSet &inputs, const operand::IndexSet &outputs, + const Param ¶m); + +public: + virtual void accept(NodeVisitor &&) const override; + virtual std::string getName() const override { return "SpaceToDepth"; } + +public: + const Param ¶m() const { return _param; } + +private: + Param _param; +}; + +} // namespace operation +} // namespace model +} // namespace neurun + +#endif // __NEURUN_MODEL_OPERATION_SPACE_TO_DEPTH_NODE_H__ diff --git a/tests/nnapi/nnapi_gtest.skip.armv7l-linux.neurun b/tests/nnapi/nnapi_gtest.skip.armv7l-linux.neurun index 9674b2f..0553fc4 100644 --- a/tests/nnapi/nnapi_gtest.skip.armv7l-linux.neurun +++ b/tests/nnapi/nnapi_gtest.skip.armv7l-linux.neurun @@ -18,7 +18,6 @@ GeneratedTests.embedding_lookup GeneratedTests.embedding_lookup_2d_nnfw GeneratedTests.embedding_lookup_4d_nnfw GeneratedTests.equal_ex* -GeneratedTests.floor_ GeneratedTests.hashtable_lookup* GeneratedTests.l2_normalization* GeneratedTests.l2_pool* @@ -37,7 +36,6 @@ GeneratedTests.relu* GeneratedTests.rnn* GeneratedTests.mean* GeneratedTests.pad* -GeneratedTests.space_to_depth* GeneratedTests.sqrt_ex* GeneratedTests.squared_difference_ex* GeneratedTests.svdf* diff --git a/tests/scripts/neurun_frameworktest_list.armv7l.acl_cl.txt b/tests/scripts/neurun_frameworktest_list.armv7l.acl_cl.txt index 2a89033..adaa90e 100644 --- a/tests/scripts/neurun_frameworktest_list.armv7l.acl_cl.txt +++ b/tests/scripts/neurun_frameworktest_list.armv7l.acl_cl.txt @@ -7,6 +7,7 @@ conv_2d depthwise_conv_2d div/broadcast exp +floor fullyconnected/fc1 max_pool_2d MODELS/mobilenet @@ -20,6 +21,7 @@ rsqrt relu6 reshape resize_bilinear +space_to_depth strided_slice sub/broadcast tanh -- 2.7.4