From: 남궁석/On-Device Lab(SR)/Engineer/삼성전자 Date: Wed, 16 Oct 2019 08:03:58 +0000 (+0900) Subject: [exo] Introduce TFLConcatenation converter (#8221) X-Git-Tag: submit/tizen/20191205.083104~755 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a9f4102d9ef58dadfb67da680b73b1ee360b3b35;p=platform%2Fcore%2Fml%2Fnnfw.git [exo] Introduce TFLConcatenation converter (#8221) This commit will introduce `TFLConcatenation` converter in `exo` Signed-off-by: Seok NamKoong --- diff --git a/compiler/exo/src/Conversion/TensorConcatConverter.cpp b/compiler/exo/src/Conversion/TensorConcatConverter.cpp new file mode 100644 index 0000000..1c36b11 --- /dev/null +++ b/compiler/exo/src/Conversion/TensorConcatConverter.cpp @@ -0,0 +1,66 @@ +/* + * 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 "TensorConcatConverter.h" + +#include "GraphBlock.h" +#include "Check.h" + +#include "Dialect/IR/TFLNodes.h" + +#include + +namespace exo +{ +/** + * @brief Converts loco::TensorConcat to locoex::TFLConcatenate + * + * Before: + * input:0 ----- loco::TensorConcat ------- C + * input:1 ----/ + * + * After: + * input:0 ----- locoex::TFLConcatenate --- C + * input:1 ----/ + * + * input:0 ----- loco::TensorConcat --- + * input:1 ----/ + * + */ +bool TensorConcatConverter::convert(loco::TensorConcat *origin) +{ + assert(loco::shape_get(origin).domain() == loco::Domain::Tensor); + + if (!loco::shape_known(origin)) + { + return false; + } + + auto tfl_concat = origin->graph()->nodes()->create(2); + tfl_concat->values(0, origin->lhs()); + tfl_concat->values(1, origin->rhs()); + tfl_concat->axis(origin->axis()); + tfl_concat->fusedActivationFunction(locoex::FusedActFunc::NONE); + + loco::replace(origin).with(tfl_concat); + + origin->lhs(nullptr); + origin->rhs(nullptr); + + return true; +} + +} // namespace exo diff --git a/compiler/exo/src/Conversion/TensorConcatConverter.h b/compiler/exo/src/Conversion/TensorConcatConverter.h new file mode 100644 index 0000000..6b90f47 --- /dev/null +++ b/compiler/exo/src/Conversion/TensorConcatConverter.h @@ -0,0 +1,41 @@ +/* + * 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 __CONVERSION_TENSORCONCAT_CONVERTER_H__ +#define __CONVERSION_TENSORCONCAT_CONVERTER_H__ + +#include "CanonicalNodeConverter.h" + +#include + +namespace exo +{ + +/** + * @brief Convert loco::TensorConcat to TFLConcatenate + */ +class TensorConcatConverter : public CanonicalNodeConverter +{ +public: + const char *name(void) const final { return "exo::TensorConcatConverter"; } + +public: + bool convert(loco::TensorConcat *origin) final; +}; + +} // namespace exo + +#endif // __CONVERSION_TENSORCONCAT_CONVERTER_H__ diff --git a/compiler/exo/src/Conversions.h b/compiler/exo/src/Conversions.h index 4b3e0ca..1d969e6 100644 --- a/compiler/exo/src/Conversions.h +++ b/compiler/exo/src/Conversions.h @@ -33,7 +33,7 @@ #include "Conversion/ReluConverter.h" // TODO loco::ReLU6 // TODO loco::Tanh -// TODO loco::TensorConcat +#include "Conversion/TensorConcatConverter.h" // TODO loco::TensorBiasAdd #include "Conversion/TensorBroadcastConverter.h" // TODO loco::TensorSoftmax diff --git a/compiler/exo/src/Convert.cpp b/compiler/exo/src/Convert.cpp index c68a1ce..9ce0f9a 100644 --- a/compiler/exo/src/Convert.cpp +++ b/compiler/exo/src/Convert.cpp @@ -91,7 +91,10 @@ void convert_to_TFLNodes(loco::Graph *graph) // TODO loco::ReLU6 // TODO loco::Tanh - // TODO loco::TensorConcat + + if (get()) + phase.emplace_back(stdex::make_unique()); + // TODO loco::TensorBiasAdd if (get()) phase.emplace_back(stdex::make_unique()); diff --git a/compiler/exo/src/Dialect/Service/TFLShapeInferenceRule.cpp b/compiler/exo/src/Dialect/Service/TFLShapeInferenceRule.cpp index b42bc37..e4b986f 100644 --- a/compiler/exo/src/Dialect/Service/TFLShapeInferenceRule.cpp +++ b/compiler/exo/src/Dialect/Service/TFLShapeInferenceRule.cpp @@ -212,7 +212,35 @@ public: return infer_pool_2d_shape(node); } - // TODO TFLConcatenation + loco::NodeShape visit(const locoex::TFLConcatenation *node) final + { + // TODO Support when TFLConcatenation has 0 input + assert(node->numValues() > 0); + + auto axis = node->axis(); + auto first_shape = loco::shape_get(node->values(0)).as(); + + loco::TensorShape output_shape; + + output_shape.rank(first_shape.rank()); + for (uint32_t i = 0; i < output_shape.rank(); ++i) + output_shape.dim(i) = first_shape.dim(i); + + for (uint32_t i = 1; i < node->numValues(); ++i) + { + auto input_shape = loco::shape_get(node->values(i)).as(); + + for (uint32_t j = 0; j < output_shape.rank(); ++j) + { + if (j == axis) + output_shape.dim(j) = output_shape.dim(j).value() + input_shape.dim(j).value(); + else + assert(output_shape.dim(j) == input_shape.dim(j)); + } + } + + return loco::NodeShape{output_shape}; + } loco::NodeShape visit(const locoex::TFLConst *node) final { diff --git a/compiler/exo/src/Dialect/Service/TFLTypeInferenceRule.cpp b/compiler/exo/src/Dialect/Service/TFLTypeInferenceRule.cpp index 31d96be..2c3bf64 100644 --- a/compiler/exo/src/Dialect/Service/TFLTypeInferenceRule.cpp +++ b/compiler/exo/src/Dialect/Service/TFLTypeInferenceRule.cpp @@ -47,7 +47,16 @@ struct TypeInferenceAlgorithm final : public locoex::TFLNodeVisitorvalue()); } - // TODO TFLConcatenation + loco::DataType visit(const locoex::TFLConcatenation *node) final + { + // TODO Support when TFLConcatenation has 0 input + assert(node->numValues() > 0); + + for (uint32_t i = 1; i < node->numValues(); ++i) + assert(loco::dtype_get(node->values(i - 1)) == loco::dtype_get(node->values(i))); + + return loco::dtype_get(node->values(0)); + } loco::DataType visit(const locoex::TFLConst *node) final { return node->dtype(); } diff --git a/compiler/exo/src/Knob.lst b/compiler/exo/src/Knob.lst index 245549e..213c23c 100644 --- a/compiler/exo/src/Knob.lst +++ b/compiler/exo/src/Knob.lst @@ -25,7 +25,7 @@ KNOB_BOOL(ConvertMaxPool2D, true, Convert loco::MaxPool2D to TFLMaxPool2D) KNOB_BOOL(ConvertRelu, true, Convert loco::Relu to TFLRelu) // TODO loco::ReLU6 // TODO loco::Tanh -// TODO loco::TensorConcat +KNOB_BOOL(ConvertTensorConcat, false, Convert loco::TensorConcat to TFLConcatenate) // TODO loco::TensorBiasAdd KNOB_BOOL(ConvertTensorBroadcast, true, Resolve loco::TensorBroadcast) // TODO loco::TensorSoftmax