diff options
Diffstat (limited to 'compiler/luci/service/src')
265 files changed, 9639 insertions, 1499 deletions
diff --git a/compiler/luci/service/src/CircleCloneNode.h b/compiler/luci/service/src/CircleCloneNode.h new file mode 100644 index 000000000..02c7cd256 --- /dev/null +++ b/compiler/luci/service/src/CircleCloneNode.h @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2021 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 __CIRCLE_CLONE_NODE_H__ +#define __CIRCLE_CLONE_NODE_H__ + +#include <luci/IR/CircleNodes.h> + +#include <luci/IR/CircleNodeVisitor.h> + +namespace luci +{ + +class CloneNode final : public luci::CircleNodeVisitor<luci::CircleNode *> +{ +public: + CloneNode(loco::Graph *graph) : _graph(graph){}; + +public: + luci::CircleNode *visit(const luci::CircleAbs *) final; + luci::CircleNode *visit(const luci::CircleAdd *) final; + luci::CircleNode *visit(const luci::CircleAddN *) final; + luci::CircleNode *visit(const luci::CircleArgMax *) final; + luci::CircleNode *visit(const luci::CircleArgMin *) final; + luci::CircleNode *visit(const luci::CircleAveragePool2D *) final; + luci::CircleNode *visit(const luci::CircleBatchMatMul *) final; + luci::CircleNode *visit(const luci::CircleBatchToSpaceND *) final; + luci::CircleNode *visit(const luci::CircleCast *) final; + luci::CircleNode *visit(const luci::CircleCeil *) final; + luci::CircleNode *visit(const luci::CircleConcatenation *) final; + luci::CircleNode *visit(const luci::CircleConst *) final; + luci::CircleNode *visit(const luci::CircleConv2D *) final; + luci::CircleNode *visit(const luci::CircleCos *) final; + luci::CircleNode *visit(const luci::CircleCustom *) final; + luci::CircleNode *visit(const luci::CircleDepthToSpace *) final; + luci::CircleNode *visit(const luci::CircleDepthwiseConv2D *) final; + luci::CircleNode *visit(const luci::CircleDequantize *) final; + luci::CircleNode *visit(const luci::CircleDiv *) final; + luci::CircleNode *visit(const luci::CircleElu *) final; + luci::CircleNode *visit(const luci::CircleEqual *) final; + luci::CircleNode *visit(const luci::CircleExp *) final; + luci::CircleNode *visit(const luci::CircleExpandDims *) final; + luci::CircleNode *visit(const luci::CircleFakeQuant *) final; + luci::CircleNode *visit(const luci::CircleFill *) final; + luci::CircleNode *visit(const luci::CircleFloor *) final; + luci::CircleNode *visit(const luci::CircleFloorDiv *) final; + luci::CircleNode *visit(const luci::CircleFloorMod *) final; + luci::CircleNode *visit(const luci::CircleFullyConnected *) final; + luci::CircleNode *visit(const luci::CircleGather *) final; + luci::CircleNode *visit(const luci::CircleGatherNd *) final; + luci::CircleNode *visit(const luci::CircleGreater *) final; + luci::CircleNode *visit(const luci::CircleGreaterEqual *) final; + // luci::CircleNode *visit(const luci::CircleIf *) final; + luci::CircleNode *visit(const luci::CircleL2Normalize *) final; + luci::CircleNode *visit(const luci::CircleL2Pool2D *) final; + luci::CircleNode *visit(const luci::CircleLeakyRelu *) final; + luci::CircleNode *visit(const luci::CircleLess *) final; + luci::CircleNode *visit(const luci::CircleLessEqual *) final; + luci::CircleNode *visit(const luci::CircleLocalResponseNormalization *) final; + luci::CircleNode *visit(const luci::CircleLog *) final; + luci::CircleNode *visit(const luci::CircleLogicalAnd *) final; + luci::CircleNode *visit(const luci::CircleLogicalNot *) final; + luci::CircleNode *visit(const luci::CircleLogicalOr *) final; + luci::CircleNode *visit(const luci::CircleLogistic *) final; + luci::CircleNode *visit(const luci::CircleLogSoftmax *) final; + luci::CircleNode *visit(const luci::CircleMatrixDiag *) final; + luci::CircleNode *visit(const luci::CircleMatrixSetDiag *) final; + luci::CircleNode *visit(const luci::CircleMaximum *) final; + luci::CircleNode *visit(const luci::CircleMaxPool2D *) final; + luci::CircleNode *visit(const luci::CircleMean *) final; + luci::CircleNode *visit(const luci::CircleMinimum *) final; + luci::CircleNode *visit(const luci::CircleMirrorPad *) final; + luci::CircleNode *visit(const luci::CircleMul *) final; + luci::CircleNode *visit(const luci::CircleNeg *) final; + luci::CircleNode *visit(const luci::CircleNonMaxSuppressionV4 *) final; + luci::CircleNode *visit(const luci::CircleNonMaxSuppressionV5 *) final; + luci::CircleNode *visit(const luci::CircleNotEqual *) final; + luci::CircleNode *visit(const luci::CircleOneHot *) final; + luci::CircleNode *visit(const luci::CirclePack *) final; + luci::CircleNode *visit(const luci::CirclePad *) final; + luci::CircleNode *visit(const luci::CirclePadV2 *) final; + luci::CircleNode *visit(const luci::CirclePow *) final; + luci::CircleNode *visit(const luci::CirclePRelu *) final; + luci::CircleNode *visit(const luci::CircleRange *) final; + luci::CircleNode *visit(const luci::CircleRank *) final; + luci::CircleNode *visit(const luci::CircleReduceAny *) final; + luci::CircleNode *visit(const luci::CircleReduceMax *) final; + luci::CircleNode *visit(const luci::CircleReduceMin *) final; + luci::CircleNode *visit(const luci::CircleReduceProd *) final; + luci::CircleNode *visit(const luci::CircleRelu *) final; + luci::CircleNode *visit(const luci::CircleRelu6 *) final; + luci::CircleNode *visit(const luci::CircleReluN1To1 *) final; + luci::CircleNode *visit(const luci::CircleReshape *) final; + luci::CircleNode *visit(const luci::CircleResizeBilinear *) final; + luci::CircleNode *visit(const luci::CircleResizeNearestNeighbor *) final; + luci::CircleNode *visit(const luci::CircleReverseSequence *) final; + luci::CircleNode *visit(const luci::CircleReverseV2 *) final; + luci::CircleNode *visit(const luci::CircleRound *) final; + luci::CircleNode *visit(const luci::CircleRsqrt *) final; + luci::CircleNode *visit(const luci::CircleScatterNd *) final; + luci::CircleNode *visit(const luci::CircleSegmentSum *) final; + luci::CircleNode *visit(const luci::CircleSelect *) final; + luci::CircleNode *visit(const luci::CircleSelectV2 *) final; + luci::CircleNode *visit(const luci::CircleShape *) final; + luci::CircleNode *visit(const luci::CircleSin *) final; + luci::CircleNode *visit(const luci::CircleSlice *) final; + luci::CircleNode *visit(const luci::CircleSoftmax *) final; + luci::CircleNode *visit(const luci::CircleSpaceToBatchND *) final; + luci::CircleNode *visit(const luci::CircleSpaceToDepth *) final; + luci::CircleNode *visit(const luci::CircleSparseToDense *) final; + luci::CircleNode *visit(const luci::CircleSplit *) final; + luci::CircleNode *visit(const luci::CircleSplitV *) final; + luci::CircleNode *visit(const luci::CircleSqrt *) final; + luci::CircleNode *visit(const luci::CircleSquare *) final; + luci::CircleNode *visit(const luci::CircleSquaredDifference *) final; + luci::CircleNode *visit(const luci::CircleSqueeze *) final; + luci::CircleNode *visit(const luci::CircleStridedSlice *) final; + luci::CircleNode *visit(const luci::CircleSub *) final; + luci::CircleNode *visit(const luci::CircleSum *) final; + luci::CircleNode *visit(const luci::CircleTanh *) final; + luci::CircleNode *visit(const luci::CircleTile *) final; + luci::CircleNode *visit(const luci::CircleTopKV2 *) final; + luci::CircleNode *visit(const luci::CircleTranspose *) final; + luci::CircleNode *visit(const luci::CircleTransposeConv *) final; + luci::CircleNode *visit(const luci::CircleUnidirectionalSequenceLSTM *) final; + luci::CircleNode *visit(const luci::CircleUnique *) final; + luci::CircleNode *visit(const luci::CircleUnpack *) final; + luci::CircleNode *visit(const luci::CircleWhere *) final; + // luci::CircleNode *visit(const luci::CircleWhile *) final; + luci::CircleNode *visit(const luci::CircleZerosLike *) final; + + // Circle Only + luci::CircleNode *visit(const luci::CircleBCQFullyConnected *) final; + luci::CircleNode *visit(const luci::CircleBCQGather *) final; + luci::CircleNode *visit(const luci::CircleInstanceNorm *) final; + + // Virtual + luci::CircleNode *visit(const luci::CircleCustomOut *) final; + // luci::CircleNode *visit(const luci::CircleIfOut *) final; + // luci::CircleNode *visit(const luci::CircleInput *) final; + luci::CircleNode *visit(const luci::CircleNonMaxSuppressionV4Out *) final; + luci::CircleNode *visit(const luci::CircleNonMaxSuppressionV5Out *) final; + // luci::CircleNode *visit(const luci::CircleOutput *) final; + luci::CircleNode *visit(const luci::CircleOutputDummy *) final; + luci::CircleNode *visit(const luci::CircleOutputExclude *) final; + luci::CircleNode *visit(const luci::CircleSplitOut *) final; + luci::CircleNode *visit(const luci::CircleSplitVOut *) final; + luci::CircleNode *visit(const luci::CircleTopKV2Out *) final; + luci::CircleNode *visit(const luci::CircleUniqueOut *) final; + luci::CircleNode *visit(const luci::CircleUnpackOut *) final; + // luci::CircleNode *visit(const luci::CircleWhileOut *) final; + + // NOTE CircleNodeVisitor will throw if not supported here + +protected: + loco::Graph *_graph = nullptr; +}; + +} // namespace luci + +#endif // __CIRCLE_CLONE_NODE_H__ diff --git a/compiler/luci/service/src/CircleNodeClone.cpp b/compiler/luci/service/src/CircleNodeClone.cpp new file mode 100644 index 000000000..d2033dd0c --- /dev/null +++ b/compiler/luci/service/src/CircleNodeClone.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include "CircleCloneNode.h" + +#include <oops/UserExn.h> + +#include <cassert> + +namespace luci +{ + +/** + * @note Attributes of specific node type like keep_dims() of CircleSum are + * not copied. + */ +void copy_common_attributes(const luci::CircleNode *src, luci::CircleNode *dst) +{ + assert(src != nullptr); + assert(dst != nullptr); + + dst->name(src->name()); + dst->dtype(src->dtype()); + + dst->rank(src->rank()); + for (uint32_t i = 0; i < src->rank(); i++) + { + dst->dim(i) = src->dim(i); + } + dst->shape_status(src->shape_status()); + + // quantparam + const auto *quantparam = src->quantparam(); + if (quantparam != nullptr) + { + auto qparam = std::make_unique<luci::CircleQuantParam>(); + qparam->scale = quantparam->scale; + qparam->zerop = quantparam->zerop; + qparam->min = quantparam->min; + qparam->max = quantparam->max; + qparam->quantized_dimension = quantparam->quantized_dimension; + + dst->quantparam(std::move(qparam)); + } + + // sparsity + const auto *sparsity = src->sparsityparam(); + if (sparsity != nullptr) + { + auto sparam = std::make_unique<luci::SparsityParam>(); + sparam->traversal_order = sparsity->traversal_order; + sparam->block_map = sparsity->block_map; + sparam->dim_metadata = sparsity->dim_metadata; + + dst->sparsityparam(std::move(sparam)); + } + + // op version + dst->op_version(src->op_version()); +} + +/** + * @note Each visit implementation must copy node specific attributes. + */ +luci::CircleNode *clone_node(const luci::CircleNode *node, loco::Graph *graph) +{ + if (node == nullptr || graph == nullptr) + return nullptr; + + CloneNode cn(graph); + auto cloned = node->accept(&cn); + if (cloned != nullptr) + copy_common_attributes(node, cloned); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/CircleNodeClone.test.cpp b/compiler/luci/service/src/CircleNodeClone.test.cpp new file mode 100644 index 000000000..5908eeb82 --- /dev/null +++ b/compiler/luci/service/src/CircleNodeClone.test.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +// NOTE any node will do for testing +#include <luci/IR/Nodes/CircleAdd.h> + +#include <gtest/gtest.h> + +namespace +{ + +luci::CircleAdd *build_simple_add_graph(loco::Graph *g) +{ + auto node = g->nodes()->create<luci::CircleAdd>(); + + node->name("name"); + node->dtype(loco::DataType::FLOAT32); + node->rank(1); + node->dim(0).set(3); + node->shape_status(luci::ShapeStatus::VALID); + node->fusedActivationFunction(luci::FusedActFunc::NONE); + + auto qparam = std::make_unique<luci::CircleQuantParam>(); + qparam->scale = {1.0}; + qparam->zerop = {0}; + qparam->min = {0.0}; + qparam->max = {1.0}; + qparam->quantized_dimension = 0; + node->quantparam(std::move(qparam)); + + auto sparam = std::make_unique<luci::SparsityParam>(); + sparam->traversal_order = {0}; + sparam->block_map = {0}; + sparam->dim_metadata = {luci::DimMetaData(luci::DimensionType::DENSE, 1)}; + node->sparsityparam(std::move(sparam)); + + node->op_version(2); + + return node; +} + +} // namespace + +TEST(CircleNodeCloneTest, copy_attribites) +{ + auto g = loco::make_graph(); + auto node = build_simple_add_graph(g.get()); + + auto copy = g->nodes()->create<luci::CircleAdd>(); + luci::copy_common_attributes(node, copy); + + ASSERT_EQ(node->name(), copy->name()); + ASSERT_EQ(node->dtype(), copy->dtype()); + ASSERT_EQ(node->rank(), copy->rank()); + ASSERT_EQ(node->shape_status(), copy->shape_status()); + + const auto *qparam_node = node->quantparam(); + const auto *qparam_copy = copy->quantparam(); + ASSERT_EQ(qparam_node->scale, qparam_copy->scale); + + const auto *sparsity_node = node->sparsityparam(); + const auto *sparsity_copy = copy->sparsityparam(); + ASSERT_EQ(sparsity_node->traversal_order, sparsity_copy->traversal_order); + + ASSERT_EQ(node->op_version(), copy->op_version()); +} + +TEST(CircleNodeCloneTest, clone_add_node) +{ + auto g = loco::make_graph(); + auto node = build_simple_add_graph(g.get()); + + auto cg = loco::make_graph(); + auto clone = clone_node(node, cg.get()); + + ASSERT_NE(nullptr, clone); + ASSERT_EQ(cg.get(), clone->graph()); + ASSERT_EQ(node->name(), clone->name()); + ASSERT_EQ(node->dtype(), clone->dtype()); + ASSERT_EQ(node->rank(), clone->rank()); + ASSERT_EQ(node->shape_status(), clone->shape_status()); +} + +TEST(CircleNodeCloneTest, clone_node_NEG) +{ + auto g = loco::make_graph(); + auto node = build_simple_add_graph(g.get()); + + auto cg = loco::make_graph(); + auto clone = luci::clone_node(nullptr, cg.get()); + ASSERT_EQ(nullptr, clone); + auto clone2 = luci::clone_node(node, nullptr); + ASSERT_EQ(nullptr, clone2); +} diff --git a/compiler/luci/service/src/CircleShapeInference.cpp b/compiler/luci/service/src/CircleShapeInference.cpp index db8ffd8ad..73472069b 100644 --- a/compiler/luci/service/src/CircleShapeInference.cpp +++ b/compiler/luci/service/src/CircleShapeInference.cpp @@ -15,27 +15,16 @@ */ #include "luci/Service/CircleShapeInference.h" -#include "luci/Service/ShapeDescription.h" + +#include "CircleShapeInferenceHelper.h" #include <loco.h> -#include <loco/Service/ShapeInference.h> #include <luci/Log.h> #include <cassert> #include <iostream> -namespace luci -{ - -ShapeDescription ShapeInference::get(loco::Node *node) -{ - assert(loco::shape_known(node)); - return to_shape_description(loco::shape_get(node)); -} - -} // namespace luci - namespace { @@ -46,7 +35,11 @@ std::ostream &operator<<(std::ostream &os, const loco::TensorShape &tensor_shape { if (r) os << ","; - os << tensor_shape.dim(r).value(); + + if (tensor_shape.dim(r).known()) + os << tensor_shape.dim(r).value(); + else + os << "?"; } os << "]"; return os; @@ -90,5 +83,5 @@ bool Rule::infer(const luci::CircleNode *circle_node, loco::TensorShape &shape) return true; } -} // namespace ssinf +} // namespace sinf } // namespace luci diff --git a/compiler/luci/service/src/CircleShapeInferenceHelper.cpp b/compiler/luci/service/src/CircleShapeInferenceHelper.cpp index f7eb6c3ec..2009aa59f 100644 --- a/compiler/luci/service/src/CircleShapeInferenceHelper.cpp +++ b/compiler/luci/service/src/CircleShapeInferenceHelper.cpp @@ -14,7 +14,24 @@ * limitations under the License. */ -#include "luci/Service/CircleShapeInferenceHelper.h" +#include "CircleShapeInferenceHelper.h" + +namespace luci +{ + +loco::NodeShape shape_get(const loco::Node *node) +{ + assert(luci::shape_known(node)); + return loco::NodeShape{sinf::circle_shape(loco::must_cast<const luci::CircleNode *>(node))}; +} + +bool shape_known(const loco::Node *node) +{ + return loco::must_cast<const luci::CircleNode *>(node)->shape_status() != + luci::ShapeStatus::UNDEFINED; +} + +} // namespace luci namespace luci { @@ -26,7 +43,7 @@ loco::TensorShape circle_shape(const luci::CircleNode *node) loco::TensorShape shape; shape.rank(node->rank()); for (uint32_t r = 0; r < node->rank(); ++r) - shape.dim(r) = loco::Dimension(node->dim(r).value()); + shape.dim(r) = node->dim(r); return shape; } diff --git a/compiler/luci/service/src/CircleShapeInferenceHelper.h b/compiler/luci/service/src/CircleShapeInferenceHelper.h new file mode 100644 index 000000000..7c7ea496c --- /dev/null +++ b/compiler/luci/service/src/CircleShapeInferenceHelper.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020 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 __LUCI_CIRCLE_SHAPE_INFERENCE_HELPER_H__ +#define __LUCI_CIRCLE_SHAPE_INFERENCE_HELPER_H__ + +#include <loco/IR/NodeShape.h> +#include <loco/IR/TensorShape.h> + +#include <luci/IR/CircleNodes.h> + +namespace luci +{ + +// NOTE Functions in this namespace will be removed after new inference +// algorithms are fully implemented. + +// This function is temporary function for deprecating loco::shape_get +loco::NodeShape shape_get(const loco::Node *node); + +// This function is temporary function for deprecating loco::shape_known +bool shape_known(const loco::Node *node); + +} // namespace luci + +namespace luci +{ +namespace sinf // Namespace for Shape Inference +{ + +// Return shape of circle node as loco::TensorShape +loco::TensorShape circle_shape(const luci::CircleNode *node); + +} // namespace sinf +} // namespace luci + +#endif // __LUCI_CIRCLE_SHAPE_INFERENCE_HELPER_H__ diff --git a/compiler/luci/service/src/CircleShapeInferenceRule.cpp b/compiler/luci/service/src/CircleShapeInferenceRule.cpp index 38ff619ab..c6d8232c3 100644 --- a/compiler/luci/service/src/CircleShapeInferenceRule.cpp +++ b/compiler/luci/service/src/CircleShapeInferenceRule.cpp @@ -17,6 +17,7 @@ #include "luci/Service/CircleShapeInferenceRule.h" #include "Check.h" +#include "CircleShapeInferenceHelper.h" #include "ShapeInfer_StridedSlice.h" #include <luci/IR/CircleNodes.h> @@ -41,7 +42,11 @@ std::ostream &operator<<(std::ostream &os, const loco::TensorShape &tensor_shape { if (r) os << ","; - os << tensor_shape.dim(r).value(); + + if (tensor_shape.dim(r).known()) + os << tensor_shape.dim(r).value(); + else + os << "?"; } os << "]"; return os; @@ -52,7 +57,15 @@ loco::TensorShape own_shape(const luci::CircleNode *node) loco::TensorShape shape; shape.rank(node->rank()); for (uint32_t r = 0; r < node->rank(); ++r) - shape.dim(r) = loco::Dimension(node->dim(r).value()); + { + // Shape inference rules in this file did not consider unknown dimension. + // If some node has unknown dimension, 0 is inserted and wrong shape + // inference was done as a result. + // To fix this, new shape inference algorithm is being implemented. + // Until new inference algorithm is fully implemented, unknown dimension + // would be represented as 1 along with TFLite expression. + shape.dim(r) = node->dim(r).known() ? node->dim(r).value() : 1; + } return shape; } @@ -135,10 +148,8 @@ loco::TensorShape expand_dimension(const loco::TensorShape &x, const loco::Tenso output_shape.rank(rank); for (uint32_t axis = 0; axis < rank; ++axis) { - assert(x.dim(axis).known() && y.dim(axis).known()); - - auto x_dim = x.dim(axis).value(); - auto y_dim = y.dim(axis).value(); + auto x_dim = x.dim(axis).known() ? x.dim(axis).value() : 1; + auto y_dim = y.dim(axis).known() ? y.dim(axis).value() : 1; // each dimension of x and y should be same or one must be 1 if different if (!((x_dim == y_dim) || (x_dim == 1 || y_dim == 1))) @@ -177,23 +188,29 @@ template <loco::DataType T> std::vector<int64_t> vector_from_constant(luci::Circ template <class CIRCLENODE> loco::NodeShape broadcast_xy(const CIRCLENODE *node) { - auto x_shape = loco::shape_get(node->x()).template as<loco::TensorShape>(); - auto y_shape = loco::shape_get(node->y()).template as<loco::TensorShape>(); + auto x_shape = luci::shape_get(node->x()).template as<loco::TensorShape>(); + auto y_shape = luci::shape_get(node->y()).template as<loco::TensorShape>(); auto output_shape = broadcast_shape(x_shape, y_shape); return loco::NodeShape{output_shape}; } +template <class CIRCLENODE> loco::NodeShape use_inputs(const CIRCLENODE *node) +{ + auto inputs_shape = luci::shape_get(node->inputs()).template as<loco::TensorShape>(); + return loco::NodeShape{inputs_shape}; +} + template <class CIRCLENODE> loco::NodeShape use_x(const CIRCLENODE *node) { - auto x_shape = loco::shape_get(node->x()).template as<loco::TensorShape>(); + auto x_shape = luci::shape_get(node->x()).template as<loco::TensorShape>(); return loco::NodeShape{x_shape}; } template <class CIRCLENODE> loco::NodeShape use_logits(const CIRCLENODE *node) { - auto shape = loco::shape_get(node->logits()).template as<loco::TensorShape>(); + auto shape = luci::shape_get(node->logits()).template as<loco::TensorShape>(); return loco::NodeShape{shape}; } @@ -202,7 +219,7 @@ loco::NodeShape use_paddings(const CIRCLENODE *node, const luci::CircleConst *pa { const loco::DataType S32 = loco::DataType::S32; - auto input_shape = loco::shape_get(node->input()).template as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).template as<loco::TensorShape>(); // TODO support other data type LUCI_ASSERT(paddings->dtype() == S32, "Only support int 32 for now"); @@ -232,11 +249,11 @@ loco::NodeShape use_paddings(const CIRCLENODE *node, const luci::CircleConst *pa loco::NodeShape infer_add_n(const luci::CircleAddN *node) { - auto shape = loco::shape_get(node->inputs(0)).as<loco::TensorShape>(); + auto shape = luci::shape_get(node->inputs(0)).as<loco::TensorShape>(); for (uint32_t idx = 1; idx < node->arity(); ++idx) { - auto shape_idx = loco::shape_get(node->inputs(idx)).as<loco::TensorShape>(); + auto shape_idx = luci::shape_get(node->inputs(idx)).as<loco::TensorShape>(); if (!(shape == shape_idx)) { INTERNAL_EXN_V("ADD_N shape not same as the first input: ", idx); @@ -247,8 +264,8 @@ loco::NodeShape infer_add_n(const luci::CircleAddN *node) loco::NodeShape infer_arg_max(const luci::CircleArgMax *node) { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); - auto dimension_shape = loco::shape_get(node->dimension()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); + auto dimension_shape = luci::shape_get(node->dimension()).as<loco::TensorShape>(); int64_t select_axis = 0; { @@ -286,8 +303,8 @@ loco::NodeShape infer_arg_max(const luci::CircleArgMax *node) loco::NodeShape infer_arg_min(const luci::CircleArgMin *node) { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); - auto dimension_shape = loco::shape_get(node->dimension()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); + auto dimension_shape = luci::shape_get(node->dimension()).as<loco::TensorShape>(); int64_t select_axis = 0; { @@ -326,9 +343,7 @@ loco::NodeShape infer_arg_min(const luci::CircleArgMin *node) // Call this for CircleAvgPool2D and CircleMaxPool2D only template <class Pool2DType> loco::NodeShape infer_pool_2d_shape(const Pool2DType *node) { - LUCI_ASSERT(loco::shape_known(node->value()), "Shape must be known"); - - auto ifm_shape = loco::shape_get(node->value()).template as<loco::TensorShape>(); + auto ifm_shape = luci::shape_get(node->value()).template as<loco::TensorShape>(); assert(ifm_shape.rank() == 4); uint32_t input_height = ifm_shape.dim(1).value(); @@ -372,7 +387,7 @@ loco::NodeShape infer_batch_to_space_nd(const luci::CircleBatchToSpaceND *node) { const loco::DataType S32 = loco::DataType::S32; - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); // Support only input rank is 3 and 4 assert(input_shape.rank() == 3 || input_shape.rank() == 4); @@ -384,8 +399,8 @@ loco::NodeShape infer_batch_to_space_nd(const luci::CircleBatchToSpaceND *node) auto const_crops = loco::must_cast<luci::CircleConst *>(node->crops()); LUCI_ASSERT(const_crops->dtype() == loco::DataType::S32, "Only support int32 crops"); - auto const_block_shape_shape = loco::shape_get(const_block_shape).as<loco::TensorShape>(); - auto const_crops_shape = loco::shape_get(const_crops).as<loco::TensorShape>(); + auto const_block_shape_shape = luci::shape_get(const_block_shape).as<loco::TensorShape>(); + auto const_crops_shape = luci::shape_get(const_crops).as<loco::TensorShape>(); assert(const_block_shape_shape.rank() == 1); assert(const_crops_shape.rank() == 2); @@ -423,8 +438,8 @@ struct OutputSize template <class Conv2DType> OutputSize infer_conv2d_type(const Conv2DType *node) { - auto ifm_shape = loco::shape_get(node->input()).template as<loco::TensorShape>(); - auto ker_shape = loco::shape_get(node->filter()).template as<loco::TensorShape>(); + auto ifm_shape = luci::shape_get(node->input()).template as<loco::TensorShape>(); + auto ker_shape = luci::shape_get(node->filter()).template as<loco::TensorShape>(); assert(ifm_shape.rank() == 4); assert(ker_shape.rank() == 4); @@ -496,7 +511,7 @@ loco::NodeShape infer_batchmatmul_shape(const loco::TensorShape &x_shape, loco::Dimension y_lhs = adj_y ? y_shape.dim(y_rank - 1) : y_shape.dim(y_rank - 2); loco::Dimension y_rhs = adj_y ? y_shape.dim(y_rank - 2) : y_shape.dim(y_rank - 1); - if (not(x_rhs == y_lhs)) + if (x_rhs.known() && y_lhs.known() && not(x_rhs == y_lhs)) INTERNAL_EXN("x_rhs and y_lhs should be same"); uint32_t out_rank = output_shape.rank(); @@ -511,7 +526,7 @@ loco::NodeShape infer_concatenation(const luci::CircleConcatenation *node) // TODO Support when CircleConcatenation has 0 input assert(node->numValues() > 0); - auto first_shape = loco::shape_get(node->values(0)).as<loco::TensorShape>(); + auto first_shape = luci::shape_get(node->values(0)).as<loco::TensorShape>(); auto axis = node->axis(); if (axis < 0) axis += first_shape.rank(); @@ -527,14 +542,20 @@ loco::NodeShape infer_concatenation(const luci::CircleConcatenation *node) for (uint32_t i = 1; i < node->numValues(); ++i) { - auto input_shape = loco::shape_get(node->values(i)).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->values(i)).as<loco::TensorShape>(); for (uint32_t j = 0; j < output_shape.rank(); ++j) { if (j == static_cast<uint32_t>(axis)) + { + // If dimension is unknown, value() will return 0. + // This is wrong but until new inference algorithm is implemented, + // this code will not be modified to keep compatibility. output_shape.dim(j) = output_shape.dim(j).value() + input_shape.dim(j).value(); + } else - assert(output_shape.dim(j) == input_shape.dim(j)); + assert(!output_shape.dim(j).known() || !input_shape.dim(j).known() || + output_shape.dim(j) == input_shape.dim(j)); } } @@ -545,8 +566,8 @@ loco::NodeShape infer_conv2d(const luci::CircleConv2D *node) { LOGGER(l); - auto ifm_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); // in NHWC - auto ker_shape = loco::shape_get(node->filter()).as<loco::TensorShape>(); // in OHWI + auto ifm_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); // in NHWC + auto ker_shape = luci::shape_get(node->filter()).as<loco::TensorShape>(); // in OHWI INFO(l) << "[luci] CircleConv2D ShapeInf ifm(" << ifm_shape.rank() << ") ker(" << ker_shape.rank() << ")" << std::endl; @@ -569,7 +590,7 @@ loco::NodeShape infer_conv2d(const luci::CircleConv2D *node) loco::NodeShape infer_depth_to_space(const luci::CircleDepthToSpace *node) { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); LUCI_ASSERT(input_shape.rank() == 4, "Only input rank 4 is supported"); // Only data format NHWC is supported @@ -601,12 +622,13 @@ loco::NodeShape infer_depth_to_space(const luci::CircleDepthToSpace *node) loco::NodeShape infer_depthwise_conv2d(const luci::CircleDepthwiseConv2D *node) { - auto ifm_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); // in NHWC - auto ker_shape = loco::shape_get(node->filter()).as<loco::TensorShape>(); // in 1 H W CM + auto ifm_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); // in NHWC + auto ker_shape = luci::shape_get(node->filter()).as<loco::TensorShape>(); // in 1 H W CM assert(ifm_shape.rank() == 4); assert(ker_shape.rank() == 4); assert(ker_shape.dim(0).value() == 1); + assert(ifm_shape.dim(3).value() * node->depthMultiplier() == ker_shape.dim(3).value()); auto os = infer_conv2d_type(node); @@ -623,7 +645,7 @@ loco::NodeShape infer_depthwise_conv2d(const luci::CircleDepthwiseConv2D *node) loco::NodeShape infer_expand_dims(const luci::CircleExpandDims *node) { const loco::DataType S32 = loco::DataType::S32; - auto x_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto x_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); if (x_shape.rank() == 0) { // This maybe for unknown shape. We use shape from the node itself. @@ -637,7 +659,7 @@ loco::NodeShape infer_expand_dims(const luci::CircleExpandDims *node) } int32_t axis = const_axis->at<S32>(0); LUCI_ASSERT((axis <= static_cast<int32_t>(x_shape.rank())) && - (axis >= -1 - static_cast<int32_t>(x_shape.rank())), + (axis >= -1 - static_cast<int32_t>(x_shape.rank())), "Axis has to be between [-(D+1), D], where D is rank of input."); size_t positive_axis = axis < 0 ? x_shape.rank() + axis + 1 : axis; loco::TensorShape output_shape; @@ -684,8 +706,8 @@ loco::NodeShape infer_fill(const luci::CircleFill *node) loco::NodeShape infer_fully_connected(const luci::CircleFullyConnected *node) { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); - auto weights_shape = loco::shape_get(node->weights()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); + auto weights_shape = luci::shape_get(node->weights()).as<loco::TensorShape>(); // Checking shape capability for fully connected layer // Input: a tensor of at least rank 2 [D1, D2, ... Dn] @@ -715,8 +737,8 @@ loco::NodeShape infer_gather(const luci::CircleGather *node) { loco::TensorShape output_shape; - const auto input_shape = loco::shape_get(node->params()).as<loco::TensorShape>(); - const auto positions_shape = loco::shape_get(node->indices()).as<loco::TensorShape>(); + const auto input_shape = luci::shape_get(node->params()).as<loco::TensorShape>(); + const auto positions_shape = luci::shape_get(node->indices()).as<loco::TensorShape>(); int32_t axis = node->axis(); // If CircleGather input has a dynamic shape, it can't inference this shape. So, it returns the @@ -743,8 +765,8 @@ loco::NodeShape infer_gather_nd(const luci::CircleGatherNd *node) { loco::TensorShape output_shape; - const auto params_shape = loco::shape_get(node->params()).as<loco::TensorShape>(); - const auto indices_shape = loco::shape_get(node->indices()).as<loco::TensorShape>(); + const auto params_shape = luci::shape_get(node->params()).as<loco::TensorShape>(); + const auto indices_shape = luci::shape_get(node->indices()).as<loco::TensorShape>(); const auto params_rank = params_shape.rank(); const auto indices_rank = indices_shape.rank(); @@ -791,7 +813,7 @@ loco::NodeShape infer_matrix_diag(const luci::CircleMatrixDiag *node) { loco::TensorShape output_shape; - auto diagonal_shape = loco::shape_get(node->diagonal()).as<loco::TensorShape>(); + auto diagonal_shape = luci::shape_get(node->diagonal()).as<loco::TensorShape>(); auto rank = diagonal_shape.rank(); output_shape.rank(rank + 1); @@ -808,8 +830,8 @@ loco::NodeShape infer_matrix_diag(const luci::CircleMatrixDiag *node) loco::NodeShape infer_matrix_set_diag(const luci::CircleMatrixSetDiag *node) { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); - auto diagonal_shape = loco::shape_get(node->diagonal()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); + auto diagonal_shape = luci::shape_get(node->diagonal()).as<loco::TensorShape>(); auto rank = diagonal_shape.rank(); @@ -831,7 +853,7 @@ loco::TensorShape infer_reducer(const loco::Node *input, const loco::Node *indic { const loco::DataType S32 = loco::DataType::S32; - auto input_shape = loco::shape_get(input).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(input).as<loco::TensorShape>(); auto reduction_indices = loco::must_cast<const luci::CircleConst *>(indices); { // Exceptions @@ -892,7 +914,7 @@ loco::NodeShape infer_mirror_pad(const luci::CircleMirrorPad *node) loco::NodeShape infer_one_hot(const luci::CircleOneHot *node) { const loco::DataType S32 = loco::DataType::S32; - auto indices_shape = loco::shape_get(node->indices()).as<loco::TensorShape>(); + auto indices_shape = luci::shape_get(node->indices()).as<loco::TensorShape>(); // Only support OneHot node's depth() is CircleConst with type S32 // TODO support depth with other types auto depth = loco::must_cast<luci::CircleConst *>(node->depth()); @@ -925,11 +947,11 @@ loco::NodeShape infer_pack(const luci::CirclePack *node) { LUCI_ASSERT(node->values_count() > 0, "Only support one or more inputs"); - auto first_shape = loco::shape_get(node->values(0)).as<loco::TensorShape>(); + auto first_shape = luci::shape_get(node->values(0)).as<loco::TensorShape>(); // Make sure all inputs have the same shape. for (uint32_t i = 1; i < node->values_count(); ++i) { - auto in_shape = loco::shape_get(node->values(i)).as<loco::TensorShape>(); + auto in_shape = luci::shape_get(node->values(i)).as<loco::TensorShape>(); LUCI_ASSERT(loco::NodeShape{first_shape} == loco::NodeShape{in_shape}, "All inputs must have the same shape"); } @@ -985,8 +1007,8 @@ loco::NodeShape infer_pad_v2(const luci::CirclePadV2 *node) loco::NodeShape infer_p_relu(const luci::CirclePRelu *node) { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); - auto alpha_shape = loco::shape_get(node->alpha()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); + auto alpha_shape = luci::shape_get(node->alpha()).as<loco::TensorShape>(); auto output_shape = broadcast_shape(input_shape, alpha_shape); @@ -1087,10 +1109,12 @@ loco::NodeShape infer_reshape(const luci::CircleReshape *node) loco::TensorShape output_shape = shape_by_input; // One of the dimensions can have special value -1, meaning its actual value should be inferred. - const auto input_shape = loco::shape_get(node->tensor()).as<loco::TensorShape>(); - const uint32_t input_element_count = loco::element_count(&input_shape); + const auto input_shape = luci::shape_get(node->tensor()).as<loco::TensorShape>(); + uint32_t input_element_count = 1; uint32_t output_element_count = 1; uint32_t unknown_dim_index = UINT32_MAX; + for (uint32_t i = 0; i < input_shape.rank(); ++i) + input_element_count *= (input_shape.dim(i).known() ? input_shape.dim(i).value() : 1); for (uint32_t dim_index = 0; dim_index < output_shape.rank(); ++dim_index) { const uint32_t dim_value = output_shape.dim(dim_index).value(); @@ -1114,7 +1138,7 @@ loco::NodeShape infer_reshape(const luci::CircleReshape *node) loco::NodeShape infer_resize_bilinear(const luci::CircleResizeBilinear *node) { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); if (input_shape.rank() != 4) INTERNAL_EXN("Expected ResizeBilinear input to have rank 4"); @@ -1142,7 +1166,7 @@ loco::NodeShape infer_resize_bilinear(const luci::CircleResizeBilinear *node) loco::NodeShape infer_resize_nearest_neighbor(const luci::CircleResizeNearestNeighbor *node) { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); if (input_shape.rank() != 4) INTERNAL_EXN("Expected ResizeNearesNeighbor input to have rank 4"); @@ -1195,8 +1219,8 @@ loco::NodeShape infer_scatter_nd(const luci::CircleScatterNd *node) loco::NodeShape infer_segment_sum(const luci::CircleSegmentSum *node) { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); - auto segment_shape = loco::shape_get(node->segment_ids()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); + auto segment_shape = luci::shape_get(node->segment_ids()).as<loco::TensorShape>(); LUCI_ASSERT(segment_shape.rank() == 1, "segment_ids must be 1-D tensor"); LUCI_ASSERT(segment_shape.dim(0).value() == input_shape.dim(0).value(), @@ -1226,11 +1250,11 @@ loco::NodeShape infer_segment_sum(const luci::CircleSegmentSum *node) loco::NodeShape infer_select(const luci::CircleSelect *node) { - auto t_shape = loco::shape_get(node->t()).as<loco::TensorShape>(); - assert(t_shape == loco::shape_get(node->e()).as<loco::TensorShape>()); + auto t_shape = luci::shape_get(node->t()).as<loco::TensorShape>(); + assert(t_shape == luci::shape_get(node->e()).as<loco::TensorShape>()); // condition shape validation - auto c_shape = loco::shape_get(node->condition()).as<loco::TensorShape>(); + auto c_shape = luci::shape_get(node->condition()).as<loco::TensorShape>(); if (c_shape.rank() != t_shape.rank()) { if (c_shape.rank() != 0 && c_shape.rank() != 1) @@ -1248,9 +1272,9 @@ loco::NodeShape infer_select(const luci::CircleSelect *node) loco::NodeShape infer_select_v2(const luci::CircleSelectV2 *node) { - auto c_shape = loco::shape_get(node->condition()).as<loco::TensorShape>(); - auto t_shape = loco::shape_get(node->t()).as<loco::TensorShape>(); - auto e_shape = loco::shape_get(node->e()).as<loco::TensorShape>(); + auto c_shape = luci::shape_get(node->condition()).as<loco::TensorShape>(); + auto t_shape = luci::shape_get(node->t()).as<loco::TensorShape>(); + auto e_shape = luci::shape_get(node->e()).as<loco::TensorShape>(); // validate ability to broadcast shapes to each other auto b_shape = broadcast_shape(broadcast_shape(c_shape, t_shape), e_shape); @@ -1259,7 +1283,7 @@ loco::NodeShape infer_select_v2(const luci::CircleSelectV2 *node) loco::NodeShape infer_shape(const luci::CircleShape *node) { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); loco::TensorShape output_shape; @@ -1274,7 +1298,7 @@ loco::NodeShape infer_slice(const luci::CircleSlice *node) const loco::DataType S32 = loco::DataType::S32; const loco::DataType S64 = loco::DataType::S64; - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); auto const_begin = loco::must_cast<luci::CircleConst *>(node->begin()); auto const_size = loco::must_cast<luci::CircleConst *>(node->size()); @@ -1318,7 +1342,7 @@ loco::NodeShape infer_space_to_batch_nd(const luci::CircleSpaceToBatchND *node) { const loco::DataType S32 = loco::DataType::S32; - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); // Support only input rank is 3 and 4 assert(input_shape.rank() == 3 || input_shape.rank() == 4); @@ -1330,8 +1354,8 @@ loco::NodeShape infer_space_to_batch_nd(const luci::CircleSpaceToBatchND *node) auto const_paddings = loco::must_cast<luci::CircleConst *>(node->paddings()); LUCI_ASSERT(const_paddings->dtype() == S32, "Only support int32 paddings"); - auto const_block_shape_shape = loco::shape_get(const_block_shape).as<loco::TensorShape>(); - auto const_paddings_shape = loco::shape_get(const_paddings).as<loco::TensorShape>(); + auto const_block_shape_shape = luci::shape_get(const_block_shape).as<loco::TensorShape>(); + auto const_paddings_shape = luci::shape_get(const_paddings).as<loco::TensorShape>(); assert(const_block_shape_shape.rank() == 1); assert(const_paddings_shape.rank() == 2); @@ -1374,7 +1398,7 @@ loco::NodeShape infer_space_to_batch_nd(const luci::CircleSpaceToBatchND *node) loco::NodeShape infer_space_to_depth(const luci::CircleSpaceToDepth *node) { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); LUCI_ASSERT(input_shape.rank() == 4, "Only input rank 4 is supported"); // Only data format NHWC is supported @@ -1412,19 +1436,33 @@ loco::NodeShape infer_sparse_to_dense(const luci::CircleSparseToDense *node) auto output_shape_node = dynamic_cast<luci::CircleConst *>(node->output_shape()); if (output_shape_node != nullptr) { - // Only support node with S32 - LUCI_ASSERT(output_shape_node->dtype() == loco::DataType::S32, - "Only support int32 CircleConst"); + const auto output_shape_type = output_shape_node->dtype(); if (output_shape_node->rank() != 1) INTERNAL_EXN_V("Only support rank 1 CircleConst", oops::to_uint32(output_shape_node->rank())); - shape.rank(output_shape_node->size<loco::DataType::S32>()); + if (output_shape_type == loco::DataType::S32) + { + shape.rank(output_shape_node->size<loco::DataType::S32>()); - for (uint32_t axis = 0; axis < shape.rank(); ++axis) + for (uint32_t axis = 0; axis < shape.rank(); ++axis) + { + shape.dim(axis) = output_shape_node->at<loco::DataType::S32>(axis); + } + } + else if (output_shape_type == loco::DataType::S64) { - shape.dim(axis) = output_shape_node->at<loco::DataType::S32>(axis); + shape.rank(output_shape_node->size<loco::DataType::S64>()); + + for (uint32_t axis = 0; axis < shape.rank(); ++axis) + { + shape.dim(axis) = output_shape_node->at<loco::DataType::S64>(axis); + } + } + else + { + INTERNAL_EXN("Output shape of SparseToDense must be either int32 or int64"); } } else @@ -1453,7 +1491,7 @@ loco::NodeShape infer_strided_slice(const luci::CircleStridedSlice *node) loco::NodeShape infer_squeeze(const luci::CircleSqueeze *node) { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); // TODO input shape may be unknown before runtime std::vector<bool> do_squeeze(input_shape.rank(), false); @@ -1508,7 +1546,7 @@ loco::NodeShape infer_tile(const luci::CircleTile *node) { const loco::DataType S32 = loco::DataType::S32; - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); auto multiples = loco::must_cast<luci::CircleConst *>(node->multiples()); // TODO support non-const case @@ -1534,7 +1572,7 @@ loco::NodeShape infer_tile(const luci::CircleTile *node) loco::NodeShape infer_transpose(const luci::CircleTranspose *node) { - auto input_shape = loco::shape_get(node->a()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->a()).as<loco::TensorShape>(); auto perm_node = loco::must_cast<luci::CircleConst *>(node->perm()); @@ -1576,7 +1614,7 @@ loco::NodeShape infer_unpack(const luci::CircleUnpack *node) // CircleUnpack provides list(array) of Tensors which has one less dimension of the input // We'll set shape of CircleUnpack to shape of actual outputs // TODO fix this if any problem rises - auto value_shape = loco::shape_get(node->value()).as<loco::TensorShape>(); + auto value_shape = luci::shape_get(node->value()).as<loco::TensorShape>(); auto axis = node->axis(); auto num = node->num(); @@ -1610,9 +1648,9 @@ loco::NodeShape infer_unpack(const luci::CircleUnpack *node) loco::NodeShape infer_unidirectionalsequencelstm(const luci::CircleUnidirectionalSequenceLSTM *node) { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); auto recurrent_to_output_weights = - loco::shape_get(node->recurrent_to_output_weights()).as<loco::TensorShape>(); + luci::shape_get(node->recurrent_to_output_weights()).as<loco::TensorShape>(); auto rank = input_shape.rank(); loco::TensorShape output_shape; output_shape.rank(rank); @@ -1626,7 +1664,7 @@ loco::NodeShape infer_unidirectionalsequencelstm(const luci::CircleUnidirectiona loco::NodeShape infer_unique(const luci::CircleUnique *node) { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); assert(input_shape.rank() == 1); @@ -1641,7 +1679,7 @@ loco::NodeShape infer_bcq_fully_connected(const luci::CircleBCQFullyConnected *n { loco::TensorShape out_shape; - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); auto weights_clusters = loco::must_cast<luci::CircleConst *>(node->weights_clusters()); LUCI_ASSERT(input_shape.rank() == 2, "Input rank of BCQFullyConnected should be 2"); @@ -1664,8 +1702,8 @@ loco::NodeShape infer_bcq_gather(const luci::CircleBCQGather *node) loco::TensorShape input_shape; loco::TensorShape output_shape; - const auto input_binary_shape = loco::shape_get(node->input_binary()).as<loco::TensorShape>(); - const auto indices_shape = loco::shape_get(node->indices()).as<loco::TensorShape>(); + const auto input_binary_shape = luci::shape_get(node->input_binary()).as<loco::TensorShape>(); + const auto indices_shape = luci::shape_get(node->indices()).as<loco::TensorShape>(); auto axis = node->axis(); auto input_clusters = loco::must_cast<luci::CircleConst *>(node->input_clusters()); @@ -1712,46 +1750,6 @@ loco::NodeShape infer_output(const luci::CircleOutput *node) return loco::NodeShape{*output_shape}; } -loco::NodeShape infer_if_out(const luci::CircleIfOut *node) -{ - /** - * @note IF operator type and shape are that of the "then" and "else" - * Graph Outputs. - */ - auto circle_if = dynamic_cast<const luci::CircleIf *>(node->input()); - if (circle_if == nullptr) - { - INTERNAL_EXN("CircleIf IR is not configured correctly"); - } - - auto index = node->index(); - auto then_graph = circle_if->then_graph(); - auto else_graph = circle_if->else_graph(); - assert(then_graph != nullptr); - assert(else_graph != nullptr); - - // shape and type are assumed to be same - // these are checked at post_import_graph() in Import - auto then_outputs = loco::output_nodes(then_graph); - auto else_outputs = loco::output_nodes(else_graph); - assert(then_outputs.size() == else_outputs.size()); - assert(index < static_cast<int32_t>(then_outputs.size())); - - auto then_out = loco::must_cast<luci::CircleOutput *>(then_outputs.at(index)); - auto else_out = loco::must_cast<luci::CircleOutput *>(else_outputs.at(index)); - - auto then_graph_outputs = then_graph->outputs(); // loco::GraphOutput items - auto else_graph_outputs = else_graph->outputs(); - assert(then_graph_outputs->size() == else_graph_outputs->size()); - - auto then_graph_output = then_graph_outputs->at(then_out->index()); - auto else_graph_output = else_graph_outputs->at(else_out->index()); - (void)else_graph_output; // make compiler happy for unused variable warnings - assert(*then_graph_output->shape() == *else_graph_output->shape()); - - return loco::NodeShape{*then_graph_output->shape()}; -} - loco::NodeShape infer_non_max_suppression_v4_out(const luci::CircleNonMaxSuppressionV4Out *node) { const loco::DataType S32 = loco::DataType::S32; @@ -1818,7 +1816,7 @@ loco::NodeShape infer_split_out(const luci::CircleSplitOut *node) loco::NodeShape unknown; - auto split_shape = loco::shape_get(split).as<loco::TensorShape>(); + auto split_shape = luci::shape_get(split).as<loco::TensorShape>(); auto split_dim = dynamic_cast<const luci::CircleConst *>(split->split_dim()); if (split_dim == nullptr) @@ -1852,7 +1850,7 @@ loco::NodeShape infer_split_v_out(const luci::CircleSplitVOut *node) loco::NodeShape unknown; - auto split_shape = loco::shape_get(split).as<loco::TensorShape>(); + auto split_shape = luci::shape_get(split).as<loco::TensorShape>(); auto size_splits = dynamic_cast<const luci::CircleConst *>(split->size_splits()); if (size_splits == nullptr) @@ -1913,7 +1911,7 @@ loco::NodeShape infer_top_k_v2_out(const luci::CircleTopKV2Out *node) INTERNAL_EXN("CircleSplit IR is not configured correctly"); // shape of topkv2 is same as topkv2->input() - auto input_shape = loco::shape_get(topkv2).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(topkv2).as<loco::TensorShape>(); auto node_k = loco::must_cast<const luci::CircleConst *>(topkv2->k()); LUCI_ASSERT(node_k->dtype() == S32, "Only support Int32"); @@ -1940,7 +1938,7 @@ loco::NodeShape infer_unique_out(const luci::CircleUniqueOut *node) } assert(node->index() == 1); auto unique = loco::must_cast<luci::CircleUnique *>(node->input()); - auto unique_shape = loco::shape_get(unique->input()).as<loco::TensorShape>(); + auto unique_shape = luci::shape_get(unique->input()).as<loco::TensorShape>(); assert(unique_shape.rank() == 1); @@ -1958,7 +1956,7 @@ loco::NodeShape infer_unpack_out(const luci::CircleUnpackOut *node) INTERNAL_EXN("CircleUnpack IR is not configured correctly"); } - auto unpack_shape = loco::shape_get(unpack).as<loco::TensorShape>(); + auto unpack_shape = luci::shape_get(unpack).as<loco::TensorShape>(); return loco::NodeShape{unpack_shape}; } @@ -2025,8 +2023,8 @@ public: loco::NodeShape visit(const luci::CircleBatchMatMul *node) final { - auto x_shape = loco::shape_get(node->x()).as<loco::TensorShape>(); - auto y_shape = loco::shape_get(node->y()).as<loco::TensorShape>(); + auto x_shape = luci::shape_get(node->x()).as<loco::TensorShape>(); + auto y_shape = luci::shape_get(node->y()).as<loco::TensorShape>(); return infer_batchmatmul_shape(x_shape, y_shape, node->adj_x(), node->adj_y()); } @@ -2065,7 +2063,7 @@ public: loco::NodeShape visit(const luci::CircleDequantize *node) final { - const auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + const auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); return loco::NodeShape{input_shape}; } @@ -2073,7 +2071,7 @@ public: loco::NodeShape visit(const luci::CircleElu *node) final { - auto input_shape = loco::shape_get(node->features()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->features()).as<loco::TensorShape>(); return loco::NodeShape{input_shape}; } @@ -2087,6 +2085,8 @@ public: return infer_expand_dims(node); } + loco::NodeShape visit(const luci::CircleFakeQuant *node) final { return use_inputs(node); } + loco::NodeShape visit(const luci::CircleFill *node) final { return infer_fill(node); } loco::NodeShape visit(const luci::CircleFloor *node) final { return use_x(node); } @@ -2112,7 +2112,7 @@ public: { // Shape of CircleIf is not used. Just use input 0 assert(node->input_count() > 0); - const auto input_shape = loco::shape_get(node->input(0)).as<loco::TensorShape>(); + const auto input_shape = luci::shape_get(node->input(0)).as<loco::TensorShape>(); return loco::NodeShape{input_shape}; } @@ -2125,7 +2125,7 @@ public: loco::NodeShape visit(const luci::CircleLeakyRelu *node) final { - const auto input_shape = loco::shape_get(node->features()).as<loco::TensorShape>(); + const auto input_shape = luci::shape_get(node->features()).as<loco::TensorShape>(); return loco::NodeShape{input_shape}; } @@ -2135,7 +2135,7 @@ public: loco::NodeShape visit(const luci::CircleLocalResponseNormalization *node) final { - const auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + const auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); return loco::NodeShape{input_shape}; } @@ -2184,13 +2184,13 @@ public: loco::NodeShape visit(const luci::CircleNonMaxSuppressionV4 *node) final { - const auto boxes_shape = loco::shape_get(node->boxes()).as<loco::TensorShape>(); + const auto boxes_shape = luci::shape_get(node->boxes()).as<loco::TensorShape>(); return loco::NodeShape{boxes_shape}; } loco::NodeShape visit(const luci::CircleNonMaxSuppressionV5 *node) final { - const auto boxes_shape = loco::shape_get(node->boxes()).as<loco::TensorShape>(); + const auto boxes_shape = luci::shape_get(node->boxes()).as<loco::TensorShape>(); return loco::NodeShape{boxes_shape}; } @@ -2244,21 +2244,21 @@ public: loco::NodeShape visit(const luci::CircleRelu *node) final { - auto input_shape = loco::shape_get(node->features()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->features()).as<loco::TensorShape>(); return loco::NodeShape{input_shape}; } loco::NodeShape visit(const luci::CircleRelu6 *node) final { - auto input_shape = loco::shape_get(node->features()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->features()).as<loco::TensorShape>(); return loco::NodeShape{input_shape}; } loco::NodeShape visit(const luci::CircleReluN1To1 *node) final { - auto input_shape = loco::shape_get(node->features()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->features()).as<loco::TensorShape>(); return loco::NodeShape{input_shape}; } @@ -2284,7 +2284,7 @@ public: loco::NodeShape visit(const luci::CircleReverseSequence *node) final { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); return loco::NodeShape{input_shape}; } @@ -2293,9 +2293,9 @@ public: loco::NodeShape visit(const luci::CircleReverseV2 *node) final { - auto input_shape = loco::shape_get(node->tensor()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->tensor()).as<loco::TensorShape>(); - LUCI_ASSERT(loco::shape_get(node->axis()).as<loco::TensorShape>().rank() == 1, + LUCI_ASSERT(luci::shape_get(node->axis()).as<loco::TensorShape>().rank() == 1, "Tensor must be 1-D"); return loco::NodeShape{input_shape}; @@ -2340,14 +2340,14 @@ public: loco::NodeShape visit(const luci::CircleSplit *node) final { // We'll set Split output as same as input so that SplitOut can handle it's own shape - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); return loco::NodeShape{input_shape}; } loco::NodeShape visit(const luci::CircleSplitV *node) final { // We'll set SplitV output as same as input so that SplitOut can handle it's own shape - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); return loco::NodeShape{input_shape}; } @@ -2382,7 +2382,7 @@ public: loco::NodeShape visit(const luci::CircleTopKV2 *node) final { // set shape of this node as same as input - const auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + const auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); return loco::NodeShape{input_shape}; } @@ -2408,13 +2408,13 @@ public: { // Shape of CircleWhile is not used. Just use input 0 assert(node->arity() > 0); - const auto input_shape = loco::shape_get(node->input(0)).as<loco::TensorShape>(); + const auto input_shape = luci::shape_get(node->input(0)).as<loco::TensorShape>(); return loco::NodeShape{input_shape}; } loco::NodeShape visit(const luci::CircleZerosLike *node) final { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); return loco::NodeShape{input_shape}; } @@ -2429,7 +2429,7 @@ public: loco::NodeShape visit(const luci::CircleInstanceNorm *node) final { - auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>(); + auto input_shape = luci::shape_get(node->input()).as<loco::TensorShape>(); return loco::NodeShape{input_shape}; } @@ -2445,8 +2445,6 @@ public: loco::NodeShape visit(const luci::CircleCustomOut *node) final { return use_own(node); } - loco::NodeShape visit(const luci::CircleIfOut *node) final { return infer_if_out(node); } - loco::NodeShape visit(const luci::CircleNonMaxSuppressionV4Out *node) final { return infer_non_max_suppression_v4_out(node); diff --git a/compiler/luci/service/src/CircleShapeInferenceRule.test.cpp b/compiler/luci/service/src/CircleShapeInferenceRule.test.cpp deleted file mode 100644 index ac27db3bd..000000000 --- a/compiler/luci/service/src/CircleShapeInferenceRule.test.cpp +++ /dev/null @@ -1,626 +0,0 @@ -/* - * Copyright (c) 2020 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 "TestGraph.h" -#include "luci/Service/CircleShapeInferenceRule.h" - -#include <luci/IR/CircleNodes.h> -#include <luci/IR/CircleDialect.h> - -#include <loco.h> -#include <loco/IR/CanonicalDialect.h> -#include <loco/Service/ShapeInference.h> -#include <loco/Service/CanonicalShapeInferenceRule.h> -#include <loco/Service/MultiDialectShapeInferenceRule.h> - -#include <oops/InternalExn.h> - -#include <gtest/gtest.h> - -#include <memory> - -namespace -{ - -bool shape_pass(loco::Graph *g) -{ - loco::CanonicalShapeInferenceRule canonical_rule; - luci::CircleShapeInferenceRule circle_rule; - loco::MultiDialectShapeInferenceRule rules; - - rules.bind(loco::CanonicalDialect::get(), &canonical_rule) - .bind(luci::CircleDialect::get(), &circle_rule); - - return loco::apply(&rules).to(g); -} - -} // namespace - -TEST(CircleShapeInferenceRuleTest, minimal_with_CircleRelu) -{ - // Create a simple network - luci::test::TestGraph graph; - auto relu_node = graph.append<luci::CircleRelu>(graph.input_node); - graph.complete(relu_node); - - // set shape - { - graph.input_node->rank(2); - graph.input_node->dim(0) = 3; - graph.input_node->dim(1) = 4; - - graph.output_node->rank(2); - graph.output_node->dim(0) = 3; - graph.output_node->dim(1) = 4; - - luci::test::graph_input_shape(graph.input_node); - luci::test::graph_output_shape(graph.output_node); - } - - // pre-check - ASSERT_FALSE(loco::shape_known(relu_node)); - - // shape inference - while (shape_pass(graph.graph()) == true) - ; - - // Verify - { - ASSERT_TRUE(loco::shape_known(relu_node)); - ASSERT_EQ(loco::Domain::Tensor, loco::shape_get(relu_node).domain()); - - auto shape = loco::shape_get(relu_node).as<loco::TensorShape>(); - ASSERT_EQ(2, shape.rank()); - ASSERT_EQ(3, shape.dim(0)); - ASSERT_EQ(4, shape.dim(1)); - } -} - -// based on the case shown in -// https://www.corvil.com/kb/what-is-the-difference-between-same-and-valid-padding-in-tf-nn-max-pool-of-tensorflow -TEST(CircleShapeInferenceRuleTest, avgpool2d_valid) -{ - luci::test::TestGraph graph; - auto avg_node = graph.append<luci::CircleAveragePool2D>(graph.input_node); - graph.complete(); - - auto input_node = graph.input_node; - { - input_node->shape({1, 4, 3, 1}); - luci::test::graph_input_shape(input_node); - } - auto output_node = graph.output_node; - { - output_node->shape({1, 2, 1, 1}); - luci::test::graph_output_shape(output_node); - } - // setting CircleAveragePool2D - { - avg_node->filter()->h(2); - avg_node->filter()->w(2); - avg_node->stride()->h(2); - avg_node->stride()->w(2); - avg_node->fusedActivationFunction(luci::FusedActFunc::NONE); - avg_node->padding(luci::Padding::VALID); - } - ASSERT_FALSE(loco::shape_known(avg_node)); - - // shape inference - while (shape_pass(graph.graph()) == true) - ; - - // Verify - { - ASSERT_TRUE(loco::shape_known(avg_node)); - ASSERT_EQ(loco::Domain::Tensor, loco::shape_get(avg_node).domain()); - - auto shape = loco::shape_get(avg_node).as<loco::TensorShape>(); - ASSERT_EQ(4, shape.rank()); - ASSERT_EQ(1, shape.dim(0).value()); - ASSERT_EQ(2, shape.dim(1).value()); - ASSERT_EQ(1, shape.dim(2).value()); - ASSERT_EQ(1, shape.dim(3).value()); - } -} - -TEST(CircleShapeInferenceRuleTest, avgpool2d_same) -{ - luci::test::TestGraph graph; - auto avg_node = graph.append<luci::CircleAveragePool2D>(graph.input_node); - graph.complete(); - - auto input_node = graph.input_node; - { - input_node->shape({1, 4, 3, 1}); - luci::test::graph_input_shape(input_node); - } - auto output_node = graph.output_node; - { - output_node->shape({1, 2, 2, 1}); - luci::test::graph_output_shape(output_node); - } - - // setting CircleAveragePool2D - { - avg_node->filter()->h(2); - avg_node->filter()->w(2); - avg_node->stride()->h(2); - avg_node->stride()->w(2); - avg_node->fusedActivationFunction(luci::FusedActFunc::NONE); - avg_node->padding(luci::Padding::SAME); - } - - ASSERT_FALSE(loco::shape_known(avg_node)); - - // shape inference - while (shape_pass(graph.graph()) == true) - ; - - // Verify - { - ASSERT_TRUE(loco::shape_known(avg_node)); - ASSERT_EQ(loco::Domain::Tensor, loco::shape_get(avg_node).domain()); - - auto shape = loco::shape_get(avg_node).as<loco::TensorShape>(); - ASSERT_EQ(4, shape.rank()); - ASSERT_EQ(1, shape.dim(0).value()); - ASSERT_EQ(2, shape.dim(1).value()); - ASSERT_EQ(2, shape.dim(2).value()); - ASSERT_EQ(1, shape.dim(3).value()); - } -} - -/** - * @note Function to test: Shape inference of two different input shapes - * - * Rank expansion to higher input side - * x(2,1,5) + y(3,5) --> x(2,1,5) + y(1,3,5) - * Do output shape inference like numpy - * x(2,1,5) + y(1,3,5) --> output(2,3,5) - * For each axis, dim value should be same OR one of them should be 1 - */ -TEST(CircleShapeInferenceRuleTest, TFAdd_shapeinf_different) -{ - auto g = loco::make_graph(); - - auto x_node = g->nodes()->create<luci::CircleInput>(); - { - x_node->rank(3); - x_node->dim(0) = 2; - x_node->dim(1) = 1; - x_node->dim(2) = 5; - } - auto y_node = g->nodes()->create<luci::CircleInput>(); - { - y_node->rank(2); - y_node->dim(0) = 3; - y_node->dim(1) = 5; - } - auto add_node = g->nodes()->create<luci::CircleAdd>(); - { - add_node->x(x_node); - add_node->y(y_node); - } - auto output_node = g->nodes()->create<luci::CircleOutput>(); - { - output_node->from(add_node); - } - - auto x_input = g->inputs()->create(); - { - x_input->name("x"); - luci::link(x_input, x_node); - } - auto y_input = g->inputs()->create(); - { - y_input->name("y"); - luci::link(y_input, y_node); - } - auto output = g->outputs()->create(); - { - output->name("output"); - luci::link(output, output_node); - } - - luci::test::graph_input_shape(x_node); - luci::test::graph_input_shape(y_node); - luci::test::graph_output_shape(output_node); - - // pre-check - ASSERT_FALSE(loco::shape_known(add_node)); - - // shape inference - while (shape_pass(g.get()) == true) - ; - - // Verify - { - ASSERT_TRUE(loco::shape_known(add_node)); - ASSERT_EQ(loco::Domain::Tensor, loco::shape_get(add_node).domain()); - - auto shape = loco::shape_get(add_node).as<loco::TensorShape>(); - ASSERT_EQ(3, shape.rank()); - ASSERT_EQ(2, shape.dim(0)); - ASSERT_EQ(3, shape.dim(1)); - ASSERT_EQ(5, shape.dim(2)); - } -} - -TEST(CircleShapeInferenceRuleTest, CircleTranspose_simple) -{ - luci::test::ExampleGraph<luci::test::ExampleGraphType::CircleTranspose> g; - - g.input_node->rank(3); - g.input_node->dim(0) = 3; - g.input_node->dim(1) = 8; - g.input_node->dim(2) = 1; - - g.const_perm->dtype(loco::DataType::S32); - g.const_perm->rank(1); - g.const_perm->dim(0) = 3; - g.const_perm->size<loco::DataType::S32>(3); - g.const_perm->at<loco::DataType::S32>(0) = 1; - g.const_perm->at<loco::DataType::S32>(1) = 2; - g.const_perm->at<loco::DataType::S32>(2) = 0; - - luci::test::graph_input_shape(g.input_node); - luci::test::graph_output_shape(g.output_node); - - // pre-check - ASSERT_FALSE(loco::shape_known(g.transpose_node)); - - // shape inference - while (shape_pass(g.graph()) == true) - ; - - // Verify - { - ASSERT_TRUE(loco::shape_known(g.transpose_node)); - - auto shape = loco::shape_get(g.transpose_node).as<loco::TensorShape>(); - ASSERT_EQ(3, shape.rank()); - ASSERT_EQ(8, shape.dim(0)); - ASSERT_EQ(1, shape.dim(1)); - ASSERT_EQ(3, shape.dim(2)); - } -} - -TEST(CircleShapeInferenceRuleTest, CircleSqueeze) -{ - luci::test::TestGraph graph; - auto squeeze_node = graph.append<luci::CircleSqueeze>(graph.input_node); - graph.complete(); - - auto input_node = graph.input_node; - { - input_node->shape({1, 4, 3, 1}); - } - auto output_node = graph.output_node; - { - output_node->shape({4, 3, 1}); - } - - luci::test::graph_input_shape(input_node); - luci::test::graph_output_shape(output_node); - - squeeze_node->squeeze_dims({0}); - - // pre-check - ASSERT_FALSE(loco::shape_known(squeeze_node)); - - // shape inference - while (shape_pass(graph.graph()) == true) - ; - - // Verify - { - ASSERT_TRUE(loco::shape_known(squeeze_node)); - - auto shape = loco::shape_get(squeeze_node).as<loco::TensorShape>(); - ASSERT_EQ(3, shape.rank()); - ASSERT_EQ(4, shape.dim(0)); - ASSERT_EQ(3, shape.dim(1)); - ASSERT_EQ(1, shape.dim(2)); - } -} - -TEST(CircleShapeInferenceRuleTest, CircleExpandDims) -{ - luci::test::TestGraph graph; - auto axis = graph.append<luci::CircleConst>(); - axis->dtype(loco::DataType::S32); - axis->rank(0); - axis->size<loco::DataType::S32>(1); - axis->at<loco::DataType::S32>(0) = 1; - - auto expand_dims = graph.append<luci::CircleExpandDims>(graph.input_node, axis); - graph.complete(); - - auto input_node = graph.input_node; - { - input_node->shape({4, 3}); - } - - auto output_node = graph.output_node; - { - output_node->from(expand_dims); - } - - luci::test::graph_input_shape(input_node); - luci::test::graph_output_shape(output_node); - - // shape inference - while (shape_pass(graph.graph())) - ; - - // validation - { - ASSERT_TRUE(loco::shape_known(expand_dims)); - - auto shape = loco::shape_get(expand_dims).as<loco::TensorShape>(); - - ASSERT_EQ(3, shape.rank()); - ASSERT_EQ(4, shape.dim(0)); - ASSERT_EQ(1, shape.dim(1)); - ASSERT_EQ(3, shape.dim(2)); - } -} - -TEST(CircleShapeInferenceRuleTest, CircleSqueezeAll) -{ - luci::test::TestGraph graph; - auto squeeze_node = graph.append<luci::CircleSqueeze>(graph.input_node); - graph.complete(); - - auto input_node = graph.input_node; - { - input_node->shape({1, 4, 3, 1}); - } - auto output_node = graph.output_node; - { - input_node->shape({4, 3}); - } - - luci::test::graph_input_shape(input_node); - luci::test::graph_output_shape(output_node); - - squeeze_node->squeeze_dims({}); - - // pre-check - ASSERT_FALSE(loco::shape_known(squeeze_node)); - - // shape inference - while (shape_pass(graph.graph()) == true) - ; - - // Verify - { - ASSERT_TRUE(loco::shape_known(squeeze_node)); - - auto shape = loco::shape_get(squeeze_node).as<loco::TensorShape>(); - ASSERT_EQ(2, shape.rank()); - ASSERT_EQ(4, shape.dim(0)); - ASSERT_EQ(3, shape.dim(1)); - } -} - -TEST(CircleShapeInferenceRuleTest, CircleGatherNd_simple) -{ - luci::test::TestGraph graph; - auto indices_const = graph.append<luci::CircleConst>(); - auto gather_nd_node = graph.append<luci::CircleGatherNd>(graph.input_node, indices_const); - graph.complete(); - - { - auto input_node = graph.input_node; - input_node->shape({1, 4, 4, 3}); - luci::test::graph_input_shape(input_node); - } - { - auto output_node = graph.output_node; - output_node->shape({1, 2, 2, 3}); - luci::test::graph_output_shape(output_node); - } - - { - indices_const->shape({1, 2, 3}); - } - - // pre-check - ASSERT_FALSE(loco::shape_known(gather_nd_node)); - - // shape inference - while (shape_pass(graph.graph()) == true) - ; - - // Verify - { - ASSERT_TRUE(loco::shape_known(gather_nd_node)); - - auto shape = loco::shape_get(gather_nd_node).as<loco::TensorShape>(); - ASSERT_EQ(3, shape.rank()); - ASSERT_EQ(1, shape.dim(0)); - ASSERT_EQ(2, shape.dim(1)); - ASSERT_EQ(3, shape.dim(2)); - } -} - -TEST(CircleShapeInferenceRuleTest, CircleGatherNd_slices) -{ - luci::test::TestGraph graph; - auto indices_const = graph.append<luci::CircleConst>(); - auto gather_nd_node = graph.append<luci::CircleGatherNd>(graph.input_node, indices_const); - graph.complete(); - - { - auto input_node = graph.input_node; - input_node->shape({1, 4, 4, 3}); - luci::test::graph_input_shape(input_node); - } - { - auto output_node = graph.output_node; - output_node->shape({1, 2, 4, 4, 3}); - luci::test::graph_output_shape(output_node); - } - - { - indices_const->shape({1, 2, 1}); - } - - // pre-check - ASSERT_FALSE(loco::shape_known(gather_nd_node)); - - // shape inference - while (shape_pass(graph.graph()) == true) - ; - - // Verify - { - ASSERT_TRUE(loco::shape_known(gather_nd_node)); - - auto shape = loco::shape_get(gather_nd_node).as<loco::TensorShape>(); - ASSERT_EQ(5, shape.rank()); - ASSERT_EQ(1, shape.dim(0)); - ASSERT_EQ(2, shape.dim(1)); - ASSERT_EQ(4, shape.dim(2)); - ASSERT_EQ(4, shape.dim(3)); - ASSERT_EQ(3, shape.dim(4)); - } -} - -TEST(CircleShapeInferenceRuleTest, CircleGatherNd_NEG) -{ - luci::test::TestGraph graph; - auto indices_const = graph.append<luci::CircleConst>(); - auto gather_nd_node = graph.append<luci::CircleGatherNd>(graph.input_node, indices_const); - graph.complete(); - - { - auto input_node = graph.input_node; - input_node->shape({1, 4, 4, 3}); - luci::test::graph_input_shape(input_node); - } - { - // Does not matter, because test should fail anyway - auto output_node = graph.output_node; - output_node->shape({0, 0, 0}); - luci::test::graph_output_shape(output_node); - } - - { - indices_const->shape({1, 2, 5}); - } - - // pre-check - ASSERT_FALSE(loco::shape_known(gather_nd_node)); - - // had to pack into lambda to check throw - auto lambda = [&]() { - // shape inference - while (shape_pass(graph.graph()) == true) - ; - }; - - ASSERT_THROW(lambda(), oops::InternalExn); -} - -TEST(CircleShapeInferenceRuleTest, CircleResizeNearestNeighbor) -{ - luci::test::TestGraph graph; - auto size_const = graph.append<luci::CircleConst>(); - size_const->dtype(loco::DataType::S32); - size_const->rank(1); - size_const->dim(0) = 2; - size_const->size<loco::DataType::S32>(2); - size_const->at<loco::DataType::S32>(0) = 16; - size_const->at<loco::DataType::S32>(1) = 16; - auto resize_node = graph.append<luci::CircleResizeNearestNeighbor>(graph.input_node, size_const); - graph.complete(); - - { - auto input_node = graph.input_node; - input_node->shape({1, 4, 4, 3}); - luci::test::graph_input_shape(input_node); - } - { - auto output_node = graph.output_node; - output_node->from(resize_node); - luci::test::graph_output_shape(output_node); - } - - // pre-check - ASSERT_FALSE(loco::shape_known(resize_node)); - - // shape inference - while (shape_pass(graph.graph()) == true) - ; - - // Verify - { - ASSERT_TRUE(loco::shape_known(resize_node)); - - auto shape = loco::shape_get(resize_node).as<loco::TensorShape>(); - ASSERT_EQ(4, shape.rank()); - ASSERT_EQ(1, shape.dim(0)); - ASSERT_EQ(16, shape.dim(1)); - ASSERT_EQ(16, shape.dim(2)); - ASSERT_EQ(3, shape.dim(3)); - } -} - -TEST(CircleShapeInferenceRuleTest, CircleResizeBilinear) -{ - luci::test::TestGraph graph; - auto size_const = graph.append<luci::CircleConst>(); - size_const->dtype(loco::DataType::S32); - size_const->rank(1); - size_const->dim(0) = 2; - size_const->size<loco::DataType::S32>(2); - size_const->at<loco::DataType::S32>(0) = 16; - size_const->at<loco::DataType::S32>(1) = 16; - auto resize_node = graph.append<luci::CircleResizeBilinear>(graph.input_node, size_const); - graph.complete(); - - { - auto input_node = graph.input_node; - input_node->shape({1, 4, 4, 3}); - luci::test::graph_input_shape(input_node); - } - { - auto output_node = graph.output_node; - output_node->from(resize_node); - luci::test::graph_output_shape(output_node); - } - - // pre-check - ASSERT_FALSE(loco::shape_known(resize_node)); - - // shape inference - while (shape_pass(graph.graph()) == true) - ; - - // Verify - { - ASSERT_TRUE(loco::shape_known(resize_node)); - - auto shape = loco::shape_get(resize_node).as<loco::TensorShape>(); - ASSERT_EQ(4, shape.rank()); - ASSERT_EQ(1, shape.dim(0)); - ASSERT_EQ(16, shape.dim(1)); - ASSERT_EQ(16, shape.dim(2)); - ASSERT_EQ(3, shape.dim(3)); - } -} diff --git a/compiler/luci/service/src/CircleShapeSignatureInference.cpp b/compiler/luci/service/src/CircleShapeSignatureInference.cpp deleted file mode 100644 index 1ccaa19d5..000000000 --- a/compiler/luci/service/src/CircleShapeSignatureInference.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2020 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 "luci/Service/CircleShapeSignatureInference.h" - -#include <luci/Log.h> - -namespace -{ - -std::ostream &operator<<(std::ostream &os, const luci::ShapeSignature &shape_signature) -{ - os << "["; - for (uint32_t r = 0; r < shape_signature.rank(); ++r) - { - if (r) - os << ","; - os << shape_signature.dim(r); - } - os << "]"; - return os; -} - -} // namespace - -namespace luci -{ - -namespace ssinf -{ - -bool Rule::infer(const luci::CircleNode *circle_node, ShapeSignature &shape_signature) const -{ - LOGGER(l); - - // There is nothing to check before ShapeSignatureInference. - - Algorithm alg; - - shape_signature = circle_node->accept(&alg); - - VERBOSE(l, 1) << "[luci] Shape Signature( " << circle_node->name() << " )"; - VERBOSE(l, 1) << " before: " << circle_node->shape_signature(); - VERBOSE(l, 1) << " after: " << shape_signature; - - return true; -} - -} // namespace ssinf - -} // namespace luci diff --git a/compiler/luci/service/src/CircleShapeSignatureInferenceHelper.cpp b/compiler/luci/service/src/CircleShapeSignatureInferenceHelper.cpp deleted file mode 100644 index d7d1a24e8..000000000 --- a/compiler/luci/service/src/CircleShapeSignatureInferenceHelper.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2020 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 "luci/Service/CircleShapeSignatureInferenceHelper.h" - -#include <loco.h> - -#include <luci/Log.h> - -#include <oops/InternalExn.h> - -namespace luci -{ - -namespace ssinf -{ - -luci::ShapeSignature legalized_signature(const luci::ShapeSignature &signature) -{ - // If shape signature has at least one -1, it is not static. - for (uint32_t i = 0; i < signature.rank(); ++i) - if (signature.dim(i) == -1) - return signature; - - // If all dimensions are static, return empty shape signature. - return luci::ShapeSignature(); -} - -ShapeSignature reduced_signature(const loco::Node *node, const loco::Node *indices, bool keep_dims) -{ - LOGGER(l); - - ShapeSignature input_signature; - ShapeSignature output_signature; - - auto circle_node = loco::must_cast<const luci::CircleNode *>(node); - if (circle_node->shape_signature().rank() > 0) - input_signature = circle_node->shape_signature(); - else - { - input_signature.rank(circle_node->rank()); - for (uint32_t i = 0; i < circle_node->rank(); ++i) - input_signature.dim(i) = circle_node->dim(i).value(); - } - - // If input rank is 0, it means that one of following case is occurred. - // - Input is scalar : result is always scalar - // - Input shape signature is not inferenced : cannot infer output shape signauture - // Therefore, when input signature rank is 0, always return empty signature. - if (input_signature.rank() == 0) - return output_signature; - - // When reduction_indices is not constant - auto reduction_indices = dynamic_cast<const luci::CircleConst *>(indices); - if (reduction_indices == nullptr) - { - if (keep_dims) - { - // If keep_dims is true, rank is not changed. - output_signature.rank(input_signature.rank()); - for (uint32_t i = 0; i < output_signature.rank(); ++i) - output_signature.dim(i) = -1; - } - else - { - // There is no way to inference for this case. - // Do nothing to return empty signature. - INFO(l) << "[CircleShapeSignatureInferenceHelper] " << circle_node->name() << std::endl; - INFO(l) << " reduced_signature : cannot infer because of non-constant node" << std::endl; - } - - return output_signature; - } - - std::vector<int32_t> reduction_values; - if (reduction_indices->dtype() == loco::DataType::S32) - { - auto reduction_size = reduction_indices->size<loco::DataType::S32>(); - for (uint32_t i = 0; i < reduction_size; ++i) - { - int32_t axis = reduction_indices->at<loco::DataType::S32>(i); - if (axis < 0) - axis += input_signature.rank(); - - if (!(0 <= axis && axis < static_cast<int32_t>(input_signature.rank()))) - INTERNAL_EXN_V("Invalid reduction axis for REDUCER", oops::to_uint32(axis)); - - reduction_values.push_back(axis); - } - } - else if (reduction_indices->dtype() == loco::DataType::S64) - { - auto reduction_size = reduction_indices->size<loco::DataType::S64>(); - for (uint32_t i = 0; i < reduction_size; ++i) - { - int32_t axis = static_cast<int32_t>(reduction_indices->at<loco::DataType::S64>(i)); - if (axis < 0) - axis += input_signature.rank(); - - if (!(0 <= axis && axis < static_cast<int32_t>(input_signature.rank()))) - INTERNAL_EXN_V("Invalid reduction axis for REDUCER", oops::to_uint32(axis)); - - reduction_values.push_back(axis); - } - } - else - { - INTERNAL_EXN("Wrong reduction axis type, Only INT32, INT64 supported."); - } - - if (keep_dims) - { - output_signature.rank(input_signature.rank()); - for (uint32_t i = 0; i < input_signature.rank(); ++i) - output_signature.dim(i) = input_signature.dim(i); - for (uint32_t i = 0; i < reduction_values.size(); ++i) - output_signature.dim(reduction_values.at(i)) = 1; - } - else - { - std::vector<bool> check_reduce(input_signature.rank(), false); - for (uint32_t i = 0; i < reduction_values.size(); ++i) - check_reduce.at(reduction_values.at(i)) = true; - - uint32_t reduce_cnt = 0; - for (uint32_t i = 0; i < check_reduce.size(); ++i) - if (check_reduce.at(i)) - ++reduce_cnt; - - output_signature.rank(input_signature.rank() - reduce_cnt); - for (uint32_t i = 0, j = 0; i < check_reduce.size(); ++i) - if (check_reduce.at(i) == false) - output_signature.dim(j++) = input_signature.dim(i); - } - - return output_signature; -} - -ShapeSignature input_arg_signature(const luci::CircleNode *node, uint32_t index) -{ - auto circle_input = loco::must_cast<luci::CircleNode *>(node->arg(index)); - return circle_input->shape_signature(); -} - -} // namespace ssinf - -} // namespace luci diff --git a/compiler/luci/service/src/CircleTypeInference.cpp b/compiler/luci/service/src/CircleTypeInference.cpp index b4755b51a..db9a37cb0 100644 --- a/compiler/luci/service/src/CircleTypeInference.cpp +++ b/compiler/luci/service/src/CircleTypeInference.cpp @@ -15,72 +15,23 @@ */ #include "luci/Service/CircleTypeInference.h" +#include "CircleTypeInferenceHelper.h" #include <luci/Log.h> #include <loco.h> -#include <loco/Service/TypeInference.h> - -#include <mio/circle/schema_generated.h> -#include <oops/InternalExn.h> #include <type_traits> namespace { -circle::TensorType translateLocoTypeToCircle(loco::DataType dtype) -{ - switch (dtype) - { - case loco::DataType::U8: - return circle::TensorType_UINT8; - // case loco::DataType::U16: unsupported - // case loco::DataType::U32: unsupported - // case loco::DataType::U64: unsupported - case loco::DataType::S8: - return circle::TensorType_INT8; - case loco::DataType::S16: - return circle::TensorType_INT16; - case loco::DataType::S32: - return circle::TensorType_INT32; - case loco::DataType::S64: - return circle::TensorType_INT64; - case loco::DataType::FLOAT16: - return circle::TensorType_FLOAT16; - case loco::DataType::FLOAT32: - return circle::TensorType_FLOAT32; - // case loco::DataType::FLOAT64: unsupported - case loco::DataType::BOOL: - return circle::TensorType_BOOL; - default: - break; - } - - INTERNAL_EXN_V("Invalid loco dtype", oops::to_uint32(dtype)); -} - -} // namespace - -namespace luci -{ - -circle::TensorType TypeInference::get(loco::Node *node) -{ - assert(loco::dtype_known(node)); - return translateLocoTypeToCircle(loco::dtype_get(node)); -} - -} // namespace luci - -namespace -{ - bool inputs_dtype_ready(const luci::CircleNode *node) { for (uint32_t arity = 0; arity < node->arity(); ++arity) { - if (node->dtype() == loco::DataType::Unknown) + auto input_node = loco::must_cast<luci::CircleNode *>(node->arg(arity)); + if (input_node->dtype() == loco::DataType::Unknown) return false; } diff --git a/compiler/luci/service/src/CircleTypeInferenceHelper.cpp b/compiler/luci/service/src/CircleTypeInferenceHelper.cpp index 75cd9f7b2..06edd70f2 100644 --- a/compiler/luci/service/src/CircleTypeInferenceHelper.cpp +++ b/compiler/luci/service/src/CircleTypeInferenceHelper.cpp @@ -14,7 +14,23 @@ * limitations under the License. */ -#include "luci/Service/CircleTypeInferenceHelper.h" +#include "CircleTypeInferenceHelper.h" + +namespace luci +{ + +loco::DataType dtype_get(const loco::Node *node) +{ + assert(luci::dtype_known(node)); + return loco::must_cast<const luci::CircleNode *>(node)->dtype(); +} + +bool dtype_known(const loco::Node *node) +{ + return loco::must_cast<const luci::CircleNode *>(node)->dtype() != loco::DataType::Unknown; +} + +} // namespace luci namespace luci { diff --git a/compiler/luci/service/src/CircleTypeInferenceHelper.h b/compiler/luci/service/src/CircleTypeInferenceHelper.h new file mode 100644 index 000000000..751340cc7 --- /dev/null +++ b/compiler/luci/service/src/CircleTypeInferenceHelper.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020 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 __LUCI_CIRCLE_TYPE_INFERENCE_HELPER_H__ +#define __LUCI_CIRCLE_TYPE_INFERENCE_HELPER_H__ + +#include <luci/IR/CircleNodes.h> + +#include <loco/IR/DataType.h> + +namespace luci +{ + +// NOTE Functions in this namespace will be removed after new inference +// algorithms are fully implemented. + +// This function is temporary function for deprecating loco::dtype_get +loco::DataType dtype_get(const loco::Node *node); + +// This function is temporary function for deprecating loco::dtype_known +bool dtype_known(const loco::Node *node); + +} // namespace luci + +namespace luci +{ +namespace tinf // Namespace for Type Inference +{ + +// Helper function will be added + +} // namespace tinf +} // namespace luci + +#endif // __LUCI_CIRCLE_TYPE_INFERENCE_HELPER_H__ diff --git a/compiler/luci/service/src/CircleTypeInferenceRule.cpp b/compiler/luci/service/src/CircleTypeInferenceRule.cpp index f738ab5a8..0b8d2af9e 100644 --- a/compiler/luci/service/src/CircleTypeInferenceRule.cpp +++ b/compiler/luci/service/src/CircleTypeInferenceRule.cpp @@ -15,6 +15,7 @@ */ #include "luci/Service/CircleTypeInferenceRule.h" +#include "CircleTypeInferenceHelper.h" #include <luci/IR/CircleDialect.h> #include <luci/IR/CircleNodeVisitor.h> @@ -29,24 +30,24 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT { // TODO Given a tensor x of complex numbers, Abs operation returns a tensor of type float32 or // float64. - loco::DataType visit(const luci::CircleAbs *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleAbs *node) final { return luci::dtype_get(node->x()); } - loco::DataType visit(const luci::CircleAdd *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleAdd *node) final { return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleAddN *node) final { - auto dtype = loco::dtype_get(node->inputs(0)); + auto dtype = luci::dtype_get(node->inputs(0)); for (uint32_t idx = 1; idx < node->arity(); ++idx) { - auto dtype_idx = loco::dtype_get(node->inputs(idx)); + auto dtype_idx = luci::dtype_get(node->inputs(idx)); if (dtype != dtype_idx) { INTERNAL_EXN_V("ADD_N dtype not same as the first input: ", idx); } } - return loco::dtype_get(node->inputs(0)); + return luci::dtype_get(node->inputs(0)); } loco::DataType visit(const luci::CircleArgMax *node) final { return node->output_type(); } @@ -55,22 +56,22 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT loco::DataType visit(const luci::CircleAveragePool2D *node) final { - return loco::dtype_get(node->value()); + return luci::dtype_get(node->value()); } loco::DataType visit(const luci::CircleBatchMatMul *node) final { - return loco::dtype_get(node->x()); + return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleBatchToSpaceND *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleCast *node) final { return node->dtype(); } - loco::DataType visit(const luci::CircleCeil *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleCeil *node) final { return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleConcatenation *node) final { @@ -78,87 +79,92 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT 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))); + assert(luci::dtype_get(node->values(i - 1)) == luci::dtype_get(node->values(i))); - return loco::dtype_get(node->values(0)); + return luci::dtype_get(node->values(0)); } loco::DataType visit(const luci::CircleConst *node) final { return node->dtype(); } loco::DataType visit(const luci::CircleConv2D *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } - loco::DataType visit(const luci::CircleCos *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleCos *node) final { return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleCustom *node) final { if (node->custom_code() == "BatchMatMulV2") { - return loco::dtype_get(node->inputs(0)); + return luci::dtype_get(node->inputs(0)); } return node->dtype(); } loco::DataType visit(const luci::CircleDepthToSpace *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleDepthwiseConv2D *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleDequantize *) final { return loco::DataType::FLOAT32; } - loco::DataType visit(const luci::CircleDiv *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleDiv *node) final { return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleElu *node) final { - return loco::dtype_get(node->features()); + return luci::dtype_get(node->features()); } loco::DataType visit(const luci::CircleEqual *) final { return loco::DataType::BOOL; } - loco::DataType visit(const luci::CircleExp *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleExp *node) final { return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleExpandDims *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); + } + + loco::DataType visit(const luci::CircleFakeQuant *node) final + { + return luci::dtype_get(node->inputs()); } loco::DataType visit(const luci::CircleFill *node) final { - return loco::dtype_get(node->value()); + return luci::dtype_get(node->value()); } - loco::DataType visit(const luci::CircleFloor *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleFloor *node) final { return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleFloorDiv *node) final { - return loco::dtype_get(node->x()); + return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleFloorMod *node) final { - return loco::dtype_get(node->x()); + return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleFullyConnected *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleGather *node) final { - return loco::dtype_get(node->params()); + return luci::dtype_get(node->params()); } loco::DataType visit(const luci::CircleGatherNd *node) final { - return loco::dtype_get(node->params()); + return luci::dtype_get(node->params()); } loco::DataType visit(const luci::CircleGreater *) final { return loco::DataType::BOOL; } @@ -169,22 +175,22 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT { // Type of If is not used. Just use input 0 assert(node->input_count() > 0); - return loco::dtype_get(node->input(0)); + return luci::dtype_get(node->input(0)); } loco::DataType visit(const luci::CircleL2Normalize *node) final { - return loco::dtype_get(node->x()); + return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleL2Pool2D *node) final { - return loco::dtype_get(node->value()); + return luci::dtype_get(node->value()); } loco::DataType visit(const luci::CircleLeakyRelu *node) final { - return loco::dtype_get(node->features()); + return luci::dtype_get(node->features()); } loco::DataType visit(const luci::CircleLess *) final { return loco::DataType::BOOL; } @@ -193,75 +199,75 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT loco::DataType visit(const luci::CircleLocalResponseNormalization *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } - loco::DataType visit(const luci::CircleLog *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleLog *node) final { return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleLogicalAnd *node) final { - return loco::dtype_get(node->x()); + return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleLogicalNot *node) final { - return loco::dtype_get(node->x()); + return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleLogicalOr *node) final { - return loco::dtype_get(node->x()); + return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleLogistic *node) final { - return loco::dtype_get(node->x()); + return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleLogSoftmax *node) final { - return loco::dtype_get(node->logits()); + return luci::dtype_get(node->logits()); } loco::DataType visit(const luci::CircleMatrixDiag *node) final { - return loco::dtype_get(node->diagonal()); + return luci::dtype_get(node->diagonal()); } loco::DataType visit(const luci::CircleMatrixSetDiag *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } - loco::DataType visit(const luci::CircleMaximum *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleMaximum *node) final { return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleMaxPool2D *node) final { - return loco::dtype_get(node->value()); + return luci::dtype_get(node->value()); } loco::DataType visit(const luci::CircleMean *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } - loco::DataType visit(const luci::CircleMinimum *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleMinimum *node) final { return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleMirrorPad *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } - loco::DataType visit(const luci::CircleNeg *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleNeg *node) final { return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleNonMaxSuppressionV4 *node) final { - return loco::dtype_get(node->boxes()); + return luci::dtype_get(node->boxes()); } loco::DataType visit(const luci::CircleNonMaxSuppressionV5 *node) final { - return loco::dtype_get(node->boxes()); + return luci::dtype_get(node->boxes()); } loco::DataType visit(const luci::CircleNotEqual *) final { return loco::DataType::BOOL; } @@ -271,25 +277,25 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT // Only support CirclePack with one or more inputs assert(node->values_count() > 0); - auto first_value_type = loco::dtype_get(node->values(0)); + auto first_value_type = luci::dtype_get(node->values(0)); for (uint32_t i = 1; i < node->values_count(); ++i) - assert(first_value_type == loco::dtype_get(node->values(i))); + assert(first_value_type == luci::dtype_get(node->values(i))); return first_value_type; } - loco::DataType visit(const luci::CirclePad *node) final { return loco::dtype_get(node->input()); } + loco::DataType visit(const luci::CirclePad *node) final { return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CirclePadV2 *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CirclePow *node) final { // TODO make sure types cannot differ - auto x_type = loco::dtype_get(node->x()); - auto y_type = loco::dtype_get(node->y()); + auto x_type = luci::dtype_get(node->x()); + auto y_type = luci::dtype_get(node->y()); if (x_type != y_type) INTERNAL_EXN("Different datatype for x and y are not supported"); @@ -299,8 +305,8 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT loco::DataType visit(const luci::CirclePRelu *node) final { - auto input_type = loco::dtype_get(node->input()); - auto alpha_type = loco::dtype_get(node->alpha()); + auto input_type = luci::dtype_get(node->input()); + auto alpha_type = luci::dtype_get(node->alpha()); if (input_type != alpha_type) INTERNAL_EXN("Different datatype for input and alpha are not supported"); @@ -310,201 +316,201 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT loco::DataType visit(const luci::CircleRange *node) final { - return loco::dtype_get(node->start()); + return luci::dtype_get(node->start()); } loco::DataType visit(const luci::CircleRank *) final { return loco::DataType::S32; } - loco::DataType visit(const luci::CircleMul *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleMul *node) final { return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleOneHot *node) final { - return loco::dtype_get(node->on_value()); + return luci::dtype_get(node->on_value()); } loco::DataType visit(const luci::CircleReduceAny *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleReduceMax *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleReduceMin *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleReduceProd *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleRelu *node) final { - return loco::dtype_get(node->features()); + return luci::dtype_get(node->features()); } loco::DataType visit(const luci::CircleRelu6 *node) final { - return loco::dtype_get(node->features()); + return luci::dtype_get(node->features()); } loco::DataType visit(const luci::CircleReluN1To1 *node) final { - return loco::dtype_get(node->features()); + return luci::dtype_get(node->features()); } loco::DataType visit(const luci::CircleReshape *node) final { - return loco::dtype_get(node->tensor()); + return luci::dtype_get(node->tensor()); } loco::DataType visit(const luci::CircleResizeBilinear *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleResizeNearestNeighbor *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleReverseSequence *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleReverseV2 *node) final { - return loco::dtype_get(node->tensor()); + return luci::dtype_get(node->tensor()); } - loco::DataType visit(const luci::CircleRound *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleRound *node) final { return luci::dtype_get(node->x()); } - loco::DataType visit(const luci::CircleRsqrt *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleRsqrt *node) final { return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleScatterNd *node) final { - return loco::dtype_get(node->updates()); + return luci::dtype_get(node->updates()); } loco::DataType visit(const luci::CircleSegmentSum *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleSelect *node) final { - assert(loco::dtype_get(node->t()) == loco::dtype_get(node->e())); - return loco::dtype_get(node->t()); + assert(luci::dtype_get(node->t()) == luci::dtype_get(node->e())); + return luci::dtype_get(node->t()); } loco::DataType visit(const luci::CircleSelectV2 *node) final { - assert(loco::dtype_get(node->t()) == loco::dtype_get(node->e())); - return loco::dtype_get(node->t()); + assert(luci::dtype_get(node->t()) == luci::dtype_get(node->e())); + return luci::dtype_get(node->t()); } loco::DataType visit(const luci::CircleShape *node) final { return node->out_type(); } - loco::DataType visit(const luci::CircleSin *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleSin *node) final { return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleSlice *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleSoftmax *node) final { - return loco::dtype_get(node->logits()); + return luci::dtype_get(node->logits()); } loco::DataType visit(const luci::CircleSpaceToBatchND *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleSpaceToDepth *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleSparseToDense *node) final { - return loco::dtype_get(node->values()); + return luci::dtype_get(node->values()); } loco::DataType visit(const luci::CircleSplit *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleSplitV *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } - loco::DataType visit(const luci::CircleSqrt *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleSqrt *node) final { return luci::dtype_get(node->x()); } - loco::DataType visit(const luci::CircleSquare *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleSquare *node) final { return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleSquaredDifference *node) final { - return loco::dtype_get(node->x()); + return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleSqueeze *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleStridedSlice *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } - loco::DataType visit(const luci::CircleSub *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleSub *node) final { return luci::dtype_get(node->x()); } - loco::DataType visit(const luci::CircleSum *node) final { return loco::dtype_get(node->input()); } + loco::DataType visit(const luci::CircleSum *node) final { return luci::dtype_get(node->input()); } - loco::DataType visit(const luci::CircleTanh *node) final { return loco::dtype_get(node->x()); } + loco::DataType visit(const luci::CircleTanh *node) final { return luci::dtype_get(node->x()); } loco::DataType visit(const luci::CircleTile *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleTopKV2 *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleTranspose *node) final { - return loco::dtype_get(node->a()); + return luci::dtype_get(node->a()); } loco::DataType visit(const luci::CircleTransposeConv *node) final { - return loco::dtype_get(node->outBackprop()); + return luci::dtype_get(node->outBackprop()); } loco::DataType visit(const luci::CircleUnidirectionalSequenceLSTM *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleUnique *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleUnpack *node) final { - return loco::dtype_get(node->value()); + return luci::dtype_get(node->value()); } loco::DataType visit(const luci::CircleWhere *) final { return loco::DataType::S64; } @@ -513,12 +519,12 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT { // Type of While is not used. Just use input 0 assert(node->input_count() > 0); - return loco::dtype_get(node->input(0)); + return luci::dtype_get(node->input(0)); } loco::DataType visit(const luci::CircleZerosLike *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } // Circle Only @@ -531,7 +537,7 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT loco::DataType visit(const luci::CircleInstanceNorm *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } // Virtual @@ -548,7 +554,7 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT { // We don't care for the type if from() is CircleOutputDummy or CircleOutputExclude // from() type should match that of CircleOutput - assert(output_dtype == loco::dtype_get(node->from())); + assert(output_dtype == luci::dtype_get(node->from())); } return output_dtype; } @@ -559,46 +565,6 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT loco::DataType visit(const luci::CircleCustomOut *node) final { return node->dtype(); } - loco::DataType visit(const luci::CircleIfOut *node) final - { - /** - * @note IF operator type and shape are that of the "then" and "else" - * Graph Outputs. - */ - auto circle_if = dynamic_cast<const luci::CircleIf *>(node->input()); - if (circle_if == nullptr) - { - INTERNAL_EXN("CircleIf IR is not configured correctly"); - } - - auto index = node->index(); - auto then_graph = circle_if->then_graph(); - auto else_graph = circle_if->else_graph(); - assert(then_graph != nullptr); - assert(else_graph != nullptr); - - // shape and type are assumed to be same - // these are checked at post_import_graph() in Import - auto then_outputs = loco::output_nodes(then_graph); - auto else_outputs = loco::output_nodes(else_graph); - assert(then_outputs.size() == else_outputs.size()); - assert(index < static_cast<int32_t>(then_outputs.size())); - - auto then_out = loco::must_cast<luci::CircleOutput *>(then_outputs.at(index)); - auto else_out = loco::must_cast<luci::CircleOutput *>(else_outputs.at(index)); - - auto then_graph_outputs = then_graph->outputs(); // loco::GraphOutput items - auto else_graph_outputs = else_graph->outputs(); - assert(then_graph_outputs->size() == else_graph_outputs->size()); - - auto then_graph_output = then_graph_outputs->at(then_out->index()); - auto else_graph_output = else_graph_outputs->at(else_out->index()); - (void)else_graph_output; // make compiler happy for unused variable warnings - assert(then_graph_output->dtype() == else_graph_output->dtype()); - - return then_graph_output->dtype(); - } - loco::DataType visit(const luci::CircleNonMaxSuppressionV4Out *node) final { (void)node; @@ -619,19 +585,19 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT loco::DataType visit(const luci::CircleSplitOut *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleSplitVOut *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleTopKV2Out *node) final { // First output is same as input if (node->index() == 0) - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); // Second outout is always S32 assert(node->index() == 1); return loco::DataType::S32; @@ -641,7 +607,7 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT { if (node->index() == 0) { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } assert(node->index() == 1); auto unique = loco::must_cast<luci::CircleUnique *>(node->input()); @@ -650,7 +616,7 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT loco::DataType visit(const luci::CircleUnpackOut *node) final { - return loco::dtype_get(node->input()); + return luci::dtype_get(node->input()); } loco::DataType visit(const luci::CircleWhileOut *node) final diff --git a/compiler/luci/service/src/CircleTypeInferenceRule.test.cpp b/compiler/luci/service/src/CircleTypeInferenceRule.test.cpp deleted file mode 100644 index 711a489af..000000000 --- a/compiler/luci/service/src/CircleTypeInferenceRule.test.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2020 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 "TestGraph.h" -#include <luci/Service/CircleTypeInferenceRule.h> - -#include <luci/IR/CircleNodes.h> -#include <luci/IR/CircleDialect.h> - -#include <loco.h> -#include <loco/IR/CanonicalDialect.h> -#include <loco/Service/TypeInference.h> - -#include <gtest/gtest.h> - -#include <memory> - -TEST(CircleTypeInferenceRuleTest, minimal_with_CircleRelu) -{ - // Create a simple network - luci::test::TestGraph graph; - auto relu_node = graph.append<luci::CircleRelu>(graph.input_node); - graph.complete(relu_node); - - // set dtype for nodes; like setting them in import - graph.input_node->dtype(loco::DataType::S32); - relu_node->dtype(loco::DataType::S32); - graph.output_node->dtype(loco::DataType::S32); - - luci::test::graph_input_dtype(graph.input_node); - luci::test::graph_output_dtype(graph.output_node); - - // pre-check - ASSERT_FALSE(loco::dtype_known(relu_node)); - - // type inference - luci::CircleTypeInferenceRule circle_rule; - loco::CanonicalTypeInferenceRule canon_rule; - loco::MultiDialectTypeInferenceRule rules; - - rules.bind(loco::CanonicalDialect::get(), &canon_rule); - rules.bind(luci::CircleDialect::get(), &circle_rule); - - loco::apply(&rules).to(graph.g.get()); - - // Verify - ASSERT_TRUE(loco::dtype_known(relu_node)); - auto type = loco::dtype_get(relu_node); - ASSERT_EQ(loco::DataType::S32, type); -} diff --git a/compiler/luci/service/src/Nodes/CircleInput.cpp b/compiler/luci/service/src/Nodes/CircleAbs.cpp index 24eab7bd6..132760957 100644 --- a/compiler/luci/service/src/Nodes/CircleInput.cpp +++ b/compiler/luci/service/src/Nodes/CircleAbs.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2021 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 + * 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, @@ -14,14 +14,14 @@ * limitations under the License. */ -#include <luci/Service/CircleShapeSignatureInference.h> +#include "CircleCloneNode.h" namespace luci { -ShapeSignature ssinf::Algorithm::visit(const luci::CircleInput *node) +luci::CircleNode *CloneNode::visit(const luci::CircleAbs *) { - return node->shape_signature(); + return _graph->nodes()->create<luci::CircleAbs>(); } } // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleAbs.test.cpp b/compiler/luci/service/src/Nodes/CircleAbs.test.cpp new file mode 100644 index 000000000..885b395b8 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleAbs.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Abs) +{ + auto g = loco::make_graph(); + auto node_abs = g->nodes()->create<luci::CircleAbs>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_abs, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_abs = dynamic_cast<luci::CircleAbs *>(cloned); + ASSERT_NE(nullptr, cloned_abs); +} diff --git a/compiler/luci/service/src/Nodes/CircleAdd.cpp b/compiler/luci/service/src/Nodes/CircleAdd.cpp new file mode 100644 index 000000000..08634320e --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleAdd.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleAdd *node) +{ + if (node->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleAdd>(); + if (cloned != nullptr) + cloned->fusedActivationFunction(node->fusedActivationFunction()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleAdd.test.cpp b/compiler/luci/service/src/Nodes/CircleAdd.test.cpp new file mode 100644 index 000000000..41a818b0a --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleAdd.test.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <luci/IR/CircleNodes.h> +#include <luci/Service/CircleShapeInference.h> + +#include <loco/IR/TensorShape.h> + +#include <gtest/gtest.h> + +/** + * @note Function to test: Shape inference of two different input shapes + * + * Rank expansion to higher input side + * x(2,1,5) + y(3,5) --> x(2,1,5) + y(1,3,5) + * Do output shape inference like numpy + * x(2,1,5) + y(1,3,5) --> output(2,3,5) + * For each axis, dim value should be same OR one of them should be 1 + */ +TEST(ShapeRuleTest, different_input_shapes_add) +{ + luci::CircleInput input1; + luci::CircleInput input2; + luci::CircleAdd add; + + input1.shape({2, 1, 5}); + input1.shape_status(luci::ShapeStatus::VALID); + input2.shape({3, 5}); + input2.shape_status(luci::ShapeStatus::VALID); + + add.x(&input1); + add.y(&input2); + + loco::TensorShape shape; + luci::sinf::Rule shape_inf_rule; + + ASSERT_TRUE(shape_inf_rule.infer(&add, shape)); + ASSERT_EQ(3, shape.rank()); + ASSERT_EQ(2, shape.dim(0).value()); + ASSERT_EQ(3, shape.dim(1).value()); + ASSERT_EQ(5, shape.dim(2).value()); +} + +TEST(CloneNodeTest, clone_Add) +{ + auto g = loco::make_graph(); + auto node_add = g->nodes()->create<luci::CircleAdd>(); + node_add->fusedActivationFunction(luci::FusedActFunc::RELU); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_add, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_add = dynamic_cast<luci::CircleAdd *>(cloned); + ASSERT_NE(nullptr, cloned_add); + ASSERT_EQ(node_add->fusedActivationFunction(), cloned_add->fusedActivationFunction()); +} + +TEST(CloneNodeTest, clone_Add_NEG) +{ + auto g = loco::make_graph(); + auto node_add = g->nodes()->create<luci::CircleAdd>(); + node_add->fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_add, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleAddN.cpp b/compiler/luci/service/src/Nodes/CircleAddN.cpp new file mode 100644 index 000000000..e536e54bb --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleAddN.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleAddN *node) +{ + auto arity = node->arity(); + return _graph->nodes()->create<luci::CircleAddN>(arity); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleAddN.test.cpp b/compiler/luci/service/src/Nodes/CircleAddN.test.cpp new file mode 100644 index 000000000..5d5b82247 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleAddN.test.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_AddN) +{ + auto g = loco::make_graph(); + auto node_addn = g->nodes()->create<luci::CircleAddN>(3); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_addn, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_addn = dynamic_cast<luci::CircleAddN *>(cloned); + ASSERT_NE(nullptr, cloned_addn); + ASSERT_EQ(node_addn->arity(), cloned_addn->arity()); +} diff --git a/compiler/luci/service/src/Nodes/CircleArgMax.cpp b/compiler/luci/service/src/Nodes/CircleArgMax.cpp new file mode 100644 index 000000000..1b3bafa86 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleArgMax.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleArgMax *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleArgMax>(); + if (cloned != nullptr) + cloned->output_type(node->output_type()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleArgMax.test.cpp b/compiler/luci/service/src/Nodes/CircleArgMax.test.cpp new file mode 100644 index 000000000..bb7588403 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleArgMax.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_ArgMax) +{ + auto g = loco::make_graph(); + auto node_argmax = g->nodes()->create<luci::CircleArgMax>(); + node_argmax->output_type(loco::DataType::FLOAT32); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_argmax, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_argmax = dynamic_cast<luci::CircleArgMax *>(cloned); + ASSERT_NE(nullptr, cloned_argmax); + ASSERT_EQ(node_argmax->output_type(), cloned_argmax->output_type()); +} diff --git a/compiler/luci/service/src/Nodes/CircleArgMin.cpp b/compiler/luci/service/src/Nodes/CircleArgMin.cpp new file mode 100644 index 000000000..fa54f7b76 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleArgMin.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleArgMin *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleArgMin>(); + if (cloned != nullptr) + cloned->output_type(node->output_type()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleArgMin.test.cpp b/compiler/luci/service/src/Nodes/CircleArgMin.test.cpp new file mode 100644 index 000000000..ca57946f9 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleArgMin.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_ArgMin) +{ + auto g = loco::make_graph(); + auto node_argmin = g->nodes()->create<luci::CircleArgMin>(); + node_argmin->output_type(loco::DataType::FLOAT32); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_argmin, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_argmin = dynamic_cast<luci::CircleArgMin *>(cloned); + ASSERT_NE(nullptr, cloned_argmin); + ASSERT_EQ(node_argmin->output_type(), cloned_argmin->output_type()); +} diff --git a/compiler/luci/service/src/Nodes/CircleAveragePool2D.cpp b/compiler/luci/service/src/Nodes/CircleAveragePool2D.cpp new file mode 100644 index 000000000..4d2791833 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleAveragePool2D.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleAveragePool2D *node) +{ + if (node->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return nullptr; + if (node->padding() == luci::Padding::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleAveragePool2D>(); + if (cloned != nullptr) + { + cloned->fusedActivationFunction(node->fusedActivationFunction()); + cloned->padding(node->padding()); + cloned->filter()->h(node->filter()->h()); + cloned->filter()->w(node->filter()->w()); + cloned->stride()->h(node->stride()->h()); + cloned->stride()->w(node->stride()->w()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleAveragePool2D.test.cpp b/compiler/luci/service/src/Nodes/CircleAveragePool2D.test.cpp new file mode 100644 index 000000000..d048d1426 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleAveragePool2D.test.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <luci/IR/CircleNodes.h> +#include <luci/Service/CircleShapeInference.h> + +#include <loco/IR/TensorShape.h> + +#include <gtest/gtest.h> + +TEST(ShapeRuleTest, simple_valid_pad_avgpool2d) +{ + luci::CircleInput input; + luci::CircleAveragePool2D avgpool_2d; + + input.shape({1, 4, 3, 1}); + input.shape_status(luci::ShapeStatus::VALID); + + avgpool_2d.value(&input); + avgpool_2d.filter()->h(2); + avgpool_2d.filter()->w(2); + avgpool_2d.stride()->h(2); + avgpool_2d.stride()->w(2); + avgpool_2d.fusedActivationFunction(luci::FusedActFunc::NONE); + avgpool_2d.padding(luci::Padding::VALID); + + loco::TensorShape shape; + luci::sinf::Rule shape_inf_rule; + + ASSERT_TRUE(shape_inf_rule.infer(&avgpool_2d, shape)); + ASSERT_EQ(4, shape.rank()); + ASSERT_EQ(1, shape.dim(0).value()); + ASSERT_EQ(2, shape.dim(1).value()); + ASSERT_EQ(1, shape.dim(2).value()); + ASSERT_EQ(1, shape.dim(3).value()); +} + +TEST(ShapeRuleTest, simple_same_pad_avgpool2d) +{ + luci::CircleInput input; + luci::CircleAveragePool2D avgpool_2d; + + input.shape({1, 4, 3, 1}); + input.shape_status(luci::ShapeStatus::VALID); + + avgpool_2d.value(&input); + avgpool_2d.filter()->h(2); + avgpool_2d.filter()->w(2); + avgpool_2d.stride()->h(2); + avgpool_2d.stride()->w(2); + avgpool_2d.fusedActivationFunction(luci::FusedActFunc::NONE); + avgpool_2d.padding(luci::Padding::SAME); + + loco::TensorShape shape; + luci::sinf::Rule shape_inf_rule; + + ASSERT_TRUE(shape_inf_rule.infer(&avgpool_2d, shape)); + ASSERT_EQ(4, shape.rank()); + ASSERT_EQ(1, shape.dim(0).value()); + ASSERT_EQ(2, shape.dim(1).value()); + ASSERT_EQ(2, shape.dim(2).value()); + ASSERT_EQ(1, shape.dim(3).value()); +} + +TEST(CloneNodeTest, clone_AveragePool2D) +{ + auto g = loco::make_graph(); + auto node_avgpool2d = g->nodes()->create<luci::CircleAveragePool2D>(); + node_avgpool2d->fusedActivationFunction(luci::FusedActFunc::RELU); + node_avgpool2d->padding(luci::Padding::SAME); + node_avgpool2d->filter()->h(1); + node_avgpool2d->filter()->w(2); + node_avgpool2d->stride()->h(3); + node_avgpool2d->stride()->w(4); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_avgpool2d, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_avgpool2d = dynamic_cast<luci::CircleAveragePool2D *>(cloned); + ASSERT_NE(nullptr, cloned_avgpool2d); + ASSERT_EQ(node_avgpool2d->fusedActivationFunction(), cloned_avgpool2d->fusedActivationFunction()); + ASSERT_EQ(node_avgpool2d->padding(), cloned_avgpool2d->padding()); + ASSERT_EQ(node_avgpool2d->filter()->h(), cloned_avgpool2d->filter()->h()); + ASSERT_EQ(node_avgpool2d->filter()->w(), cloned_avgpool2d->filter()->w()); + ASSERT_EQ(node_avgpool2d->stride()->h(), cloned_avgpool2d->stride()->h()); + ASSERT_EQ(node_avgpool2d->stride()->w(), cloned_avgpool2d->stride()->w()); +} + +TEST(CloneNodeTest, clone_AveragePool2D_fusedact_NEG) +{ + auto g = loco::make_graph(); + auto node_avgpool2d = g->nodes()->create<luci::CircleAveragePool2D>(); + node_avgpool2d->fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + node_avgpool2d->padding(luci::Padding::SAME); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_avgpool2d, gc.get()); + ASSERT_EQ(nullptr, cloned); +} + +TEST(CloneNodeTest, clone_AveragePool2D_padding_NEG) +{ + auto g = loco::make_graph(); + auto node_avgpool2d = g->nodes()->create<luci::CircleAveragePool2D>(); + node_avgpool2d->fusedActivationFunction(luci::FusedActFunc::RELU); + node_avgpool2d->padding(luci::Padding::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_avgpool2d, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleBCQFullyConnected.cpp b/compiler/luci/service/src/Nodes/CircleBCQFullyConnected.cpp new file mode 100644 index 000000000..3edc06ab8 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleBCQFullyConnected.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleBCQFullyConnected *node) +{ + if (node->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleBCQFullyConnected>(); + if (cloned != nullptr) + { + cloned->fusedActivationFunction(node->fusedActivationFunction()); + cloned->weights_hidden_size(node->weights_hidden_size()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleBCQFullyConnected.test.cpp b/compiler/luci/service/src/Nodes/CircleBCQFullyConnected.test.cpp new file mode 100644 index 000000000..90c192e07 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleBCQFullyConnected.test.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_BCQFullyConnected) +{ + auto g = loco::make_graph(); + auto node_fc = g->nodes()->create<luci::CircleBCQFullyConnected>(); + node_fc->fusedActivationFunction(luci::FusedActFunc::RELU); + node_fc->weights_hidden_size(3); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_fc, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_fc = dynamic_cast<luci::CircleBCQFullyConnected *>(cloned); + ASSERT_NE(nullptr, cloned_fc); + ASSERT_EQ(node_fc->fusedActivationFunction(), cloned_fc->fusedActivationFunction()); + ASSERT_EQ(node_fc->weights_hidden_size(), cloned_fc->weights_hidden_size()); +} + +TEST(CloneNodeTest, clone_BCQFullyConnected_fusedact_NEG) +{ + auto g = loco::make_graph(); + auto node_fc = g->nodes()->create<luci::CircleBCQFullyConnected>(); + node_fc->fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_fc, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleBCQGather.cpp b/compiler/luci/service/src/Nodes/CircleBCQGather.cpp new file mode 100644 index 000000000..35b6be744 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleBCQGather.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleBCQGather *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleBCQGather>(); + if (cloned != nullptr) + { + cloned->axis(node->axis()); + cloned->input_hidden_size(node->input_hidden_size()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleBCQGather.test.cpp b/compiler/luci/service/src/Nodes/CircleBCQGather.test.cpp new file mode 100644 index 000000000..a3f9e8850 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleBCQGather.test.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_BCQGather) +{ + auto g = loco::make_graph(); + auto node_gat = g->nodes()->create<luci::CircleBCQGather>(); + node_gat->axis(3); + node_gat->input_hidden_size(5); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_gat, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_gat = dynamic_cast<luci::CircleBCQGather *>(cloned); + ASSERT_NE(nullptr, cloned_gat); + ASSERT_EQ(node_gat->axis(), cloned_gat->axis()); + ASSERT_EQ(node_gat->input_hidden_size(), cloned_gat->input_hidden_size()); +} diff --git a/compiler/luci/service/src/Nodes/CircleBatchMatMul.cpp b/compiler/luci/service/src/Nodes/CircleBatchMatMul.cpp new file mode 100644 index 000000000..c7a8bbd52 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleBatchMatMul.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleBatchMatMul *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleBatchMatMul>(); + if (cloned != nullptr) + { + cloned->adj_x(node->adj_x()); + cloned->adj_y(node->adj_y()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleBatchMatMul.test.cpp b/compiler/luci/service/src/Nodes/CircleBatchMatMul.test.cpp new file mode 100644 index 000000000..e013feae8 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleBatchMatMul.test.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_BatchMatMul) +{ + auto g = loco::make_graph(); + auto node_bmm = g->nodes()->create<luci::CircleBatchMatMul>(); + node_bmm->adj_x(true); + node_bmm->adj_y(true); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_bmm, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_bmm = dynamic_cast<luci::CircleBatchMatMul *>(cloned); + ASSERT_NE(nullptr, cloned_bmm); + ASSERT_EQ(node_bmm->adj_x(), cloned_bmm->adj_x()); + ASSERT_EQ(node_bmm->adj_y(), cloned_bmm->adj_y()); +} diff --git a/compiler/luci/service/src/Nodes/CircleOutput.cpp b/compiler/luci/service/src/Nodes/CircleBatchToSpaceND.cpp index d4c8da2d8..70aa05f72 100644 --- a/compiler/luci/service/src/Nodes/CircleOutput.cpp +++ b/compiler/luci/service/src/Nodes/CircleBatchToSpaceND.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2021 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 + * 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, @@ -14,14 +14,14 @@ * limitations under the License. */ -#include <luci/Service/CircleShapeSignatureInference.h> +#include "CircleCloneNode.h" namespace luci { -ShapeSignature ssinf::Algorithm::visit(const luci::CircleOutput *node) +luci::CircleNode *CloneNode::visit(const luci::CircleBatchToSpaceND *) { - return input_arg_signature(node, 0); + return _graph->nodes()->create<luci::CircleBatchToSpaceND>(); } } // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleBatchToSpaceND.test.cpp b/compiler/luci/service/src/Nodes/CircleBatchToSpaceND.test.cpp new file mode 100644 index 000000000..a45039fc7 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleBatchToSpaceND.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_BatchToSpaceND) +{ + auto g = loco::make_graph(); + auto node_b2s = g->nodes()->create<luci::CircleBatchToSpaceND>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_b2s, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_b2s = dynamic_cast<luci::CircleBatchToSpaceND *>(cloned); + ASSERT_NE(nullptr, cloned_b2s); +} diff --git a/compiler/luci/service/src/Nodes/CircleCast.cpp b/compiler/luci/service/src/Nodes/CircleCast.cpp new file mode 100644 index 000000000..75f15f9de --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleCast.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleCast *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleCast>(); + if (cloned != nullptr) + { + cloned->in_data_type(node->in_data_type()); + cloned->out_data_type(node->out_data_type()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleCast.test.cpp b/compiler/luci/service/src/Nodes/CircleCast.test.cpp new file mode 100644 index 000000000..1c4bacb73 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleCast.test.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Cast) +{ + auto g = loco::make_graph(); + auto node_cast = g->nodes()->create<luci::CircleCast>(); + node_cast->in_data_type(loco::DataType::U16); + node_cast->out_data_type(loco::DataType::S32); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_cast, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_cast = dynamic_cast<luci::CircleCast *>(cloned); + ASSERT_NE(nullptr, cloned_cast); + ASSERT_EQ(node_cast->in_data_type(), cloned_cast->in_data_type()); + ASSERT_EQ(node_cast->out_data_type(), cloned_cast->out_data_type()); +} diff --git a/compiler/luci/service/src/Nodes/CircleCeil.cpp b/compiler/luci/service/src/Nodes/CircleCeil.cpp new file mode 100644 index 000000000..92d039a7d --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleCeil.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleCeil *) +{ + return _graph->nodes()->create<luci::CircleCeil>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleCeil.test.cpp b/compiler/luci/service/src/Nodes/CircleCeil.test.cpp new file mode 100644 index 000000000..b182127d9 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleCeil.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Ceil) +{ + auto g = loco::make_graph(); + auto node_ceil = g->nodes()->create<luci::CircleCeil>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_ceil, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_ceil = dynamic_cast<luci::CircleCeil *>(cloned); + ASSERT_NE(nullptr, cloned_ceil); +} diff --git a/compiler/luci/service/src/Nodes/CircleConcatenation.cpp b/compiler/luci/service/src/Nodes/CircleConcatenation.cpp new file mode 100644 index 000000000..75d6a53e6 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleConcatenation.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleConcatenation *node) +{ + if (node->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleConcatenation>(node->numValues()); + if (cloned != nullptr) + { + cloned->fusedActivationFunction(node->fusedActivationFunction()); + cloned->axis(node->axis()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleConcatenation.test.cpp b/compiler/luci/service/src/Nodes/CircleConcatenation.test.cpp new file mode 100644 index 000000000..270068cf0 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleConcatenation.test.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Concatenation) +{ + auto g = loco::make_graph(); + auto node_concat = g->nodes()->create<luci::CircleConcatenation>(3); + node_concat->fusedActivationFunction(luci::FusedActFunc::RELU); + node_concat->axis(7); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_concat, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_concat = dynamic_cast<luci::CircleConcatenation *>(cloned); + ASSERT_NE(nullptr, cloned_concat); + ASSERT_EQ(node_concat->numValues(), cloned_concat->numValues()); + ASSERT_EQ(node_concat->fusedActivationFunction(), cloned_concat->fusedActivationFunction()); + ASSERT_EQ(node_concat->axis(), cloned_concat->axis()); +} + +TEST(CloneNodeTest, clone_Concatenation_NEG) +{ + auto g = loco::make_graph(); + auto node_concat = g->nodes()->create<luci::CircleConcatenation>(3); + node_concat->fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_concat, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleConst.cpp b/compiler/luci/service/src/Nodes/CircleConst.cpp new file mode 100644 index 000000000..0306ef4eb --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleConst.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +#include "luci/Service/CircleNodeClone.h" + +#include <luci/IR/Nodes/CircleConst.h> + +#include <loco.h> +#include <loco/IR/Graph.h> + +#include <oops/UserExn.h> + +#include <cassert> + +namespace +{ + +template <loco::DataType T> +void copy_values(const luci::CircleConst *node, luci::CircleConst *cloned) +{ + assert(T == node->dtype()); + assert(T == cloned->dtype()); + + const auto size = node->size<T>(); + cloned->size<T>(size); + for (uint32_t i = 0; i < size; i++) + cloned->at<T>(i) = node->at<T>(i); +} + +luci::CircleConst *clone_circleconst(const luci::CircleConst *node, loco::Graph *graph) +{ + auto cloned = graph->nodes()->create<luci::CircleConst>(); + + if (cloned != nullptr) + { + // dtype/shape + cloned->dtype(node->dtype()); + cloned->rank(node->rank()); + + // values + switch (node->dtype()) + { + case loco::DataType::FLOAT32: + copy_values<loco::DataType::FLOAT32>(node, cloned); + break; + + case loco::DataType::U8: + copy_values<loco::DataType::U8>(node, cloned); + break; + + case loco::DataType::S8: + copy_values<loco::DataType::S8>(node, cloned); + break; + + case loco::DataType::S16: + copy_values<loco::DataType::S16>(node, cloned); + break; + + case loco::DataType::S32: + copy_values<loco::DataType::S32>(node, cloned); + break; + + case loco::DataType::S64: + copy_values<loco::DataType::S64>(node, cloned); + break; + + case loco::DataType::BOOL: + copy_values<loco::DataType::BOOL>(node, cloned); + break; + + default: + throw oops::UserExn("Unsupported tensor dtype"); + } + } + + return cloned; +} + +} // namespace + +namespace luci +{ + +luci::CircleConst *clone(luci::CircleConst *node) +{ + auto *cloned = clone_circleconst(node, node->graph()); + + copy_common_attributes(node, cloned); + + return cloned; +} + +} // namespace luci + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleConst *node) +{ + return clone_circleconst(node, _graph); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleConst.test.cpp b/compiler/luci/service/src/Nodes/CircleConst.test.cpp new file mode 100644 index 000000000..5d94798f4 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleConst.test.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2021 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 "luci/Service/Nodes/CircleConst.h" +#include "luci/Service/CircleNodeClone.h" + +#include <loco.h> +#include <loco/IR/Graph.h> + +#include <gtest/gtest.h> + +namespace +{ + +luci::CircleConst *new_const_s32(loco::Graph *g) +{ + // prepare source CircleConst + auto circle_const = g->nodes()->create<luci::CircleConst>(); + + const auto size = 2; + + circle_const->dtype(loco::DataType::S32); + circle_const->rank(1); + circle_const->dim(0).set(size); + circle_const->shape_status(luci::ShapeStatus::VALID); + + circle_const->size<loco::DataType::S32>(size); + for (uint32_t i = 0; i < size; i++) + circle_const->at<loco::DataType::S32>(i) = i; + + // quantparam + auto quantparam = std::make_unique<luci::CircleQuantParam>(); + quantparam->scale = {1.0}; + quantparam->zerop = {0}; + quantparam->min = {-127.0}; + quantparam->max = {127.0}; + quantparam->quantized_dimension = 1; + circle_const->quantparam(std::move(quantparam)); + + // sparsityparam + auto sparam = std::make_unique<luci::SparsityParam>(); + sparam->traversal_order = {1}; + sparam->block_map = {1}; + sparam->dim_metadata = {}; + circle_const->sparsityparam(std::move(sparam)); + + return circle_const; +} + +template <loco::DataType DT> luci::CircleConst *new_empty_const(loco::Graph *g) +{ + auto circle_const = g->nodes()->create<luci::CircleConst>(); + + const auto size = 0; + + circle_const->dtype(DT); + circle_const->rank(1); + circle_const->dim(0).set(size); + circle_const->shape_status(luci::ShapeStatus::VALID); + circle_const->size<DT>(size); + + return circle_const; +} + +} // namespace + +TEST(CircleConstTest, clone) +{ + auto g = loco::make_graph(); + + // prepare source CircleConst + auto circle_const = new_const_s32(g.get()); + + // make a clone + auto const_cloned = luci::clone(circle_const); + + // check attributes + ASSERT_EQ(loco::DataType::S32, const_cloned->dtype()); + ASSERT_EQ(1, const_cloned->rank()); + ASSERT_EQ(2, const_cloned->dim(0).value()); + ASSERT_EQ(2, const_cloned->size<loco::DataType::S32>()); + ASSERT_EQ(0, const_cloned->at<loco::DataType::S32>(0)); + ASSERT_EQ(1, const_cloned->at<loco::DataType::S32>(1)); + ASSERT_NE(nullptr, const_cloned->quantparam()); + ASSERT_NE(nullptr, const_cloned->sparsityparam()); +} + +TEST(CircleConstTest, clone_U8) +{ + auto g = loco::make_graph(); + + // prepare source CircleConst + auto circle_const = new_empty_const<loco::DataType::U8>(g.get()); + + // make a clone + auto const_cloned = luci::clone(circle_const); + + // check attributes + ASSERT_EQ(loco::DataType::U8, const_cloned->dtype()); +} + +TEST(CircleConstTest, clone_S8) +{ + auto g = loco::make_graph(); + + // prepare source CircleConst + auto circle_const = new_empty_const<loco::DataType::S8>(g.get()); + + // make a clone + auto const_cloned = luci::clone(circle_const); + + // check attributes + ASSERT_EQ(loco::DataType::S8, const_cloned->dtype()); +} + +TEST(CircleConstTest, clone_S64) +{ + auto g = loco::make_graph(); + + // prepare source CircleConst + auto circle_const = new_empty_const<loco::DataType::S64>(g.get()); + + // make a clone + auto const_cloned = luci::clone(circle_const); + + // check attributes + ASSERT_EQ(loco::DataType::S64, const_cloned->dtype()); +} + +TEST(CircleConstTest, clone_BOOL) +{ + auto g = loco::make_graph(); + + // prepare source CircleConst + auto circle_const = new_empty_const<loco::DataType::BOOL>(g.get()); + + // make a clone + auto const_cloned = luci::clone(circle_const); + + // check attributes + ASSERT_EQ(loco::DataType::BOOL, const_cloned->dtype()); +} + +TEST(CloneNodeTest, clone_Const) +{ + auto g = loco::make_graph(); + auto node_const = new_const_s32(g.get()); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_const, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_const = dynamic_cast<luci::CircleConst *>(cloned); + ASSERT_NE(nullptr, cloned_const); + ASSERT_EQ(loco::DataType::S32, cloned_const->dtype()); + ASSERT_EQ(1, cloned_const->rank()); + ASSERT_EQ(2, cloned_const->dim(0).value()); + ASSERT_EQ(2, cloned_const->size<loco::DataType::S32>()); + ASSERT_EQ(0, cloned_const->at<loco::DataType::S32>(0)); + ASSERT_EQ(1, cloned_const->at<loco::DataType::S32>(1)); + ASSERT_NE(nullptr, cloned_const->quantparam()); + ASSERT_NE(nullptr, cloned_const->sparsityparam()); +} diff --git a/compiler/luci/service/src/Nodes/CircleConv2D.cpp b/compiler/luci/service/src/Nodes/CircleConv2D.cpp new file mode 100644 index 000000000..08cd87ef7 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleConv2D.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleConv2D *node) +{ + if (node->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return nullptr; + if (node->padding() == luci::Padding::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleConv2D>(); + if (cloned != nullptr) + { + cloned->fusedActivationFunction(node->fusedActivationFunction()); + cloned->padding(node->padding()); + cloned->stride()->h(node->stride()->h()); + cloned->stride()->w(node->stride()->w()); + cloned->dilation()->h(node->dilation()->h()); + cloned->dilation()->w(node->dilation()->w()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleConv2D.test.cpp b/compiler/luci/service/src/Nodes/CircleConv2D.test.cpp new file mode 100644 index 000000000..c265d6cd1 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleConv2D.test.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Conv2D) +{ + auto g = loco::make_graph(); + auto node_conv2d = g->nodes()->create<luci::CircleConv2D>(); + node_conv2d->fusedActivationFunction(luci::FusedActFunc::RELU); + node_conv2d->padding(luci::Padding::SAME); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_conv2d, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_conv2d = dynamic_cast<luci::CircleConv2D *>(cloned); + ASSERT_NE(nullptr, cloned_conv2d); + ASSERT_EQ(node_conv2d->fusedActivationFunction(), cloned_conv2d->fusedActivationFunction()); + ASSERT_EQ(node_conv2d->padding(), cloned_conv2d->padding()); +} + +TEST(CloneNodeTest, clone_Conv2D_fusedact_NEG) +{ + auto g = loco::make_graph(); + auto node_conv2d = g->nodes()->create<luci::CircleConv2D>(); + node_conv2d->fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + node_conv2d->padding(luci::Padding::SAME); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_conv2d, gc.get()); + ASSERT_EQ(nullptr, cloned); +} + +TEST(CloneNodeTest, clone_Conv2D_padding_NEG) +{ + auto g = loco::make_graph(); + auto node_conv2d = g->nodes()->create<luci::CircleConv2D>(); + node_conv2d->fusedActivationFunction(luci::FusedActFunc::RELU); + node_conv2d->padding(luci::Padding::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_conv2d, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleCos.cpp b/compiler/luci/service/src/Nodes/CircleCos.cpp new file mode 100644 index 000000000..c46e3741b --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleCos.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleCos *) +{ + return _graph->nodes()->create<luci::CircleCos>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleCos.test.cpp b/compiler/luci/service/src/Nodes/CircleCos.test.cpp new file mode 100644 index 000000000..a25943b98 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleCos.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Cos) +{ + auto g = loco::make_graph(); + auto node_cos = g->nodes()->create<luci::CircleCos>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_cos, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_cos = dynamic_cast<luci::CircleCos *>(cloned); + ASSERT_NE(nullptr, cloned_cos); +} diff --git a/compiler/luci/service/src/Nodes/CircleCustom.cpp b/compiler/luci/service/src/Nodes/CircleCustom.cpp new file mode 100644 index 000000000..a9764c373 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleCustom.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleCustom *node) +{ + uint32_t num_in = node->numInputs(); + uint32_t num_out = node->numOutputs(); + auto *cloned = _graph->nodes()->create<luci::CircleCustom>(num_in, num_out); + if (cloned != nullptr) + { + cloned->custom_options(node->custom_options()); + cloned->custom_code(node->custom_code()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleCustom.test.cpp b/compiler/luci/service/src/Nodes/CircleCustom.test.cpp new file mode 100644 index 000000000..6fee68e71 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleCustom.test.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +#include <string> +#include <vector> + +TEST(CloneNodeTest, clone_Custom) +{ + auto g = loco::make_graph(); + auto node_custom = g->nodes()->create<luci::CircleCustom>(2, 3); + std::vector<uint8_t> options({0x55, 0x56, 0x57}); + std::string code = "hello"; + node_custom->custom_options(options); + node_custom->custom_code(code); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_custom, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_custom = dynamic_cast<luci::CircleCustom *>(cloned); + ASSERT_NE(nullptr, cloned_custom); + auto cloned_options = cloned_custom->custom_options(); + ASSERT_EQ(options.size(), cloned_options.size()); + auto size = options.size(); + for (size_t s = 0; s < size; ++s) + ASSERT_EQ(options.at(s), cloned_options.at(s)); + ASSERT_TRUE(node_custom->custom_code() == cloned_custom->custom_code()); +} diff --git a/compiler/luci/service/src/Nodes/CircleCustomOut.cpp b/compiler/luci/service/src/Nodes/CircleCustomOut.cpp new file mode 100644 index 000000000..84577f529 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleCustomOut.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleCustomOut *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleCustomOut>(); + if (cloned != nullptr) + cloned->index(node->index()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleCustomOut.test.cpp b/compiler/luci/service/src/Nodes/CircleCustomOut.test.cpp new file mode 100644 index 000000000..15121bab6 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleCustomOut.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_CustomOut) +{ + auto g = loco::make_graph(); + auto node_cout = g->nodes()->create<luci::CircleCustomOut>(); + node_cout->index(1); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_cout, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_cout = dynamic_cast<luci::CircleCustomOut *>(cloned); + ASSERT_NE(nullptr, cloned_cout); + ASSERT_EQ(node_cout->index(), cloned_cout->index()); +} diff --git a/compiler/luci/service/src/Nodes/CircleDepthToSpace.cpp b/compiler/luci/service/src/Nodes/CircleDepthToSpace.cpp new file mode 100644 index 000000000..7e0bc7d74 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleDepthToSpace.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleDepthToSpace *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleDepthToSpace>(); + if (cloned != nullptr) + cloned->block_size(node->block_size()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleDepthToSpace.test.cpp b/compiler/luci/service/src/Nodes/CircleDepthToSpace.test.cpp new file mode 100644 index 000000000..192b10b90 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleDepthToSpace.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_DepthToSpace) +{ + auto g = loco::make_graph(); + auto node_d2s = g->nodes()->create<luci::CircleDepthToSpace>(); + node_d2s->block_size(32); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_d2s, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_d2s = dynamic_cast<luci::CircleDepthToSpace *>(cloned); + ASSERT_NE(nullptr, cloned_d2s); + ASSERT_EQ(node_d2s->block_size(), cloned_d2s->block_size()); +} diff --git a/compiler/luci/service/src/Nodes/CircleDepthwiseConv2D.cpp b/compiler/luci/service/src/Nodes/CircleDepthwiseConv2D.cpp new file mode 100644 index 000000000..8e0b23d94 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleDepthwiseConv2D.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleDepthwiseConv2D *node) +{ + if (node->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return nullptr; + if (node->padding() == luci::Padding::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleDepthwiseConv2D>(); + if (cloned != nullptr) + { + cloned->fusedActivationFunction(node->fusedActivationFunction()); + cloned->padding(node->padding()); + cloned->stride()->h(node->stride()->h()); + cloned->stride()->w(node->stride()->w()); + cloned->depthMultiplier(node->depthMultiplier()); + cloned->dilation()->h(node->dilation()->h()); + cloned->dilation()->w(node->dilation()->w()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleDepthwiseConv2D.test.cpp b/compiler/luci/service/src/Nodes/CircleDepthwiseConv2D.test.cpp new file mode 100644 index 000000000..8657464bc --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleDepthwiseConv2D.test.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_DepthwiseConv2D) +{ + auto g = loco::make_graph(); + auto node_dwconv2d = g->nodes()->create<luci::CircleDepthwiseConv2D>(); + node_dwconv2d->fusedActivationFunction(luci::FusedActFunc::RELU); + node_dwconv2d->padding(luci::Padding::SAME); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_dwconv2d, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_dwconv2d = dynamic_cast<luci::CircleDepthwiseConv2D *>(cloned); + ASSERT_NE(nullptr, cloned_dwconv2d); + ASSERT_EQ(node_dwconv2d->fusedActivationFunction(), cloned_dwconv2d->fusedActivationFunction()); + ASSERT_EQ(node_dwconv2d->padding(), cloned_dwconv2d->padding()); +} + +TEST(CloneNodeTest, clone_DepthwiseConv2D_fusedact_NEG) +{ + auto g = loco::make_graph(); + auto node_dwconv2d = g->nodes()->create<luci::CircleDepthwiseConv2D>(); + node_dwconv2d->fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + node_dwconv2d->padding(luci::Padding::SAME); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_dwconv2d, gc.get()); + ASSERT_EQ(nullptr, cloned); +} + +TEST(CloneNodeTest, clone_DepthwiseConv2D_padding_NEG) +{ + auto g = loco::make_graph(); + auto node_dwconv2d = g->nodes()->create<luci::CircleDepthwiseConv2D>(); + node_dwconv2d->fusedActivationFunction(luci::FusedActFunc::RELU); + node_dwconv2d->padding(luci::Padding::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_dwconv2d, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleDequantize.cpp b/compiler/luci/service/src/Nodes/CircleDequantize.cpp new file mode 100644 index 000000000..79983e4d3 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleDequantize.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleDequantize *) +{ + return _graph->nodes()->create<luci::CircleDequantize>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleDequantize.test.cpp b/compiler/luci/service/src/Nodes/CircleDequantize.test.cpp new file mode 100644 index 000000000..e1c563acf --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleDequantize.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Dequantize) +{ + auto g = loco::make_graph(); + auto node_dq = g->nodes()->create<luci::CircleDequantize>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_dq, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_dq = dynamic_cast<luci::CircleDequantize *>(cloned); + ASSERT_NE(nullptr, cloned_dq); +} diff --git a/compiler/luci/service/src/Nodes/CircleDiv.cpp b/compiler/luci/service/src/Nodes/CircleDiv.cpp new file mode 100644 index 000000000..7c48d8b76 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleDiv.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleDiv *node) +{ + if (node->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleDiv>(); + if (cloned != nullptr) + cloned->fusedActivationFunction(node->fusedActivationFunction()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleDiv.test.cpp b/compiler/luci/service/src/Nodes/CircleDiv.test.cpp new file mode 100644 index 000000000..5182ac908 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleDiv.test.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Div) +{ + auto g = loco::make_graph(); + auto node_div = g->nodes()->create<luci::CircleDiv>(); + node_div->fusedActivationFunction(luci::FusedActFunc::RELU); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_div, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_div = dynamic_cast<luci::CircleDiv *>(cloned); + ASSERT_NE(nullptr, cloned_div); + ASSERT_EQ(node_div->fusedActivationFunction(), cloned_div->fusedActivationFunction()); +} + +TEST(CloneNodeTest, clone_Div_NEG) +{ + auto g = loco::make_graph(); + auto node_div = g->nodes()->create<luci::CircleDiv>(); + node_div->fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_div, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleElu.cpp b/compiler/luci/service/src/Nodes/CircleElu.cpp new file mode 100644 index 000000000..e2df30285 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleElu.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleElu *) +{ + return _graph->nodes()->create<luci::CircleElu>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleElu.test.cpp b/compiler/luci/service/src/Nodes/CircleElu.test.cpp new file mode 100644 index 000000000..e75b3bcb1 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleElu.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Elu) +{ + auto g = loco::make_graph(); + auto node_elu = g->nodes()->create<luci::CircleElu>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_elu, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_elu = dynamic_cast<luci::CircleElu *>(cloned); + ASSERT_NE(nullptr, cloned_elu); +} diff --git a/compiler/luci/service/src/Nodes/CircleEqual.cpp b/compiler/luci/service/src/Nodes/CircleEqual.cpp new file mode 100644 index 000000000..5dd382d0b --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleEqual.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleEqual *) +{ + return _graph->nodes()->create<luci::CircleEqual>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleEqual.test.cpp b/compiler/luci/service/src/Nodes/CircleEqual.test.cpp new file mode 100644 index 000000000..99a5535fc --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleEqual.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Equal) +{ + auto g = loco::make_graph(); + auto node_eq = g->nodes()->create<luci::CircleEqual>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_eq, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_eq = dynamic_cast<luci::CircleEqual *>(cloned); + ASSERT_NE(nullptr, cloned_eq); +} diff --git a/compiler/luci/service/src/Nodes/CircleExp.cpp b/compiler/luci/service/src/Nodes/CircleExp.cpp new file mode 100644 index 000000000..3d4918320 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleExp.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleExp *) +{ + return _graph->nodes()->create<luci::CircleExp>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleExp.test.cpp b/compiler/luci/service/src/Nodes/CircleExp.test.cpp new file mode 100644 index 000000000..ff2bb65db --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleExp.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Exp) +{ + auto g = loco::make_graph(); + auto node_exp = g->nodes()->create<luci::CircleExp>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_exp, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_exp = dynamic_cast<luci::CircleExp *>(cloned); + ASSERT_NE(nullptr, cloned_exp); +} diff --git a/compiler/luci/service/src/Nodes/CircleExpandDims.cpp b/compiler/luci/service/src/Nodes/CircleExpandDims.cpp new file mode 100644 index 000000000..4dd1cec86 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleExpandDims.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleExpandDims *) +{ + return _graph->nodes()->create<luci::CircleExpandDims>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleExpandDims.test.cpp b/compiler/luci/service/src/Nodes/CircleExpandDims.test.cpp new file mode 100644 index 000000000..e3481bccd --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleExpandDims.test.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <luci/IR/CircleNodes.h> +#include <luci/Service/CircleShapeInference.h> + +#include <loco/IR/TensorShape.h> + +#include <gtest/gtest.h> + +TEST(ShapeRuleTest, simple_expand_dims) +{ + luci::CircleInput input; + luci::CircleConst axis; + luci::CircleExpandDims expand_dims; + + input.shape({4, 3}); + input.shape_status(luci::ShapeStatus::VALID); + + axis.dtype(loco::DataType::S32); + axis.rank(0); + axis.size<loco::DataType::S32>(1); + axis.at<loco::DataType::S32>(0) = 1; + axis.shape_status(luci::ShapeStatus::VALID); + + expand_dims.input(&input); + expand_dims.axis(&axis); + + loco::TensorShape shape; + luci::sinf::Rule shape_inf_rule; + + ASSERT_TRUE(shape_inf_rule.infer(&expand_dims, shape)); + ASSERT_EQ(3, shape.rank()); + ASSERT_EQ(4, shape.dim(0).value()); + ASSERT_EQ(1, shape.dim(1).value()); + ASSERT_EQ(3, shape.dim(2).value()); +} + +TEST(CloneNodeTest, clone_ExpandDims) +{ + auto g = loco::make_graph(); + auto node_ed = g->nodes()->create<luci::CircleExpandDims>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_ed, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_ed = dynamic_cast<luci::CircleExpandDims *>(cloned); + ASSERT_NE(nullptr, cloned_ed); +} diff --git a/compiler/luci/service/src/Nodes/CircleFakeQuant.cpp b/compiler/luci/service/src/Nodes/CircleFakeQuant.cpp new file mode 100644 index 000000000..7abaca685 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleFakeQuant.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleFakeQuant *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleFakeQuant>(); + if (cloned != nullptr) + { + cloned->min(node->min()); + cloned->max(node->max()); + cloned->num_bits(node->num_bits()); + cloned->narrow_range(node->narrow_range()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleFakeQuant.test.cpp b/compiler/luci/service/src/Nodes/CircleFakeQuant.test.cpp new file mode 100644 index 000000000..2c4e3b836 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleFakeQuant.test.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_FakeQuant) +{ + auto g = loco::make_graph(); + auto node_fq = g->nodes()->create<luci::CircleFakeQuant>(); + node_fq->min(1.0f); + node_fq->max(2.0f); + node_fq->num_bits(8); + node_fq->narrow_range(true); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_fq, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_fq = dynamic_cast<luci::CircleFakeQuant *>(cloned); + ASSERT_NE(nullptr, cloned_fq); + ASSERT_EQ(node_fq->min(), cloned_fq->min()); + ASSERT_EQ(node_fq->max(), cloned_fq->max()); + ASSERT_EQ(node_fq->num_bits(), cloned_fq->num_bits()); + ASSERT_EQ(node_fq->narrow_range(), cloned_fq->narrow_range()); +} diff --git a/compiler/luci/service/src/Nodes/CircleFill.cpp b/compiler/luci/service/src/Nodes/CircleFill.cpp new file mode 100644 index 000000000..d9b74c63a --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleFill.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleFill *) +{ + return _graph->nodes()->create<luci::CircleFill>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleFill.test.cpp b/compiler/luci/service/src/Nodes/CircleFill.test.cpp new file mode 100644 index 000000000..56c807585 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleFill.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Fill) +{ + auto g = loco::make_graph(); + auto node_fill = g->nodes()->create<luci::CircleFill>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_fill, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_fill = dynamic_cast<luci::CircleFill *>(cloned); + ASSERT_NE(nullptr, cloned_fill); +} diff --git a/compiler/luci/service/src/Nodes/CircleFloor.cpp b/compiler/luci/service/src/Nodes/CircleFloor.cpp new file mode 100644 index 000000000..532808bc8 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleFloor.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleFloor *) +{ + return _graph->nodes()->create<luci::CircleFloor>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleFloor.test.cpp b/compiler/luci/service/src/Nodes/CircleFloor.test.cpp new file mode 100644 index 000000000..3d53fd2c3 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleFloor.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Floor) +{ + auto g = loco::make_graph(); + auto node_floor = g->nodes()->create<luci::CircleFloor>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_floor, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_floor = dynamic_cast<luci::CircleFloor *>(cloned); + ASSERT_NE(nullptr, cloned_floor); +} diff --git a/compiler/luci/service/src/Nodes/CircleFloorDiv.cpp b/compiler/luci/service/src/Nodes/CircleFloorDiv.cpp new file mode 100644 index 000000000..65be3e868 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleFloorDiv.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleFloorDiv *) +{ + return _graph->nodes()->create<luci::CircleFloorDiv>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleFloorDiv.test.cpp b/compiler/luci/service/src/Nodes/CircleFloorDiv.test.cpp new file mode 100644 index 000000000..6365ccd3b --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleFloorDiv.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_FloorDiv) +{ + auto g = loco::make_graph(); + auto node_floordiv = g->nodes()->create<luci::CircleFloorDiv>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_floordiv, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_floordiv = dynamic_cast<luci::CircleFloorDiv *>(cloned); + ASSERT_NE(nullptr, cloned_floordiv); +} diff --git a/compiler/luci/service/src/Nodes/CircleFloorMod.cpp b/compiler/luci/service/src/Nodes/CircleFloorMod.cpp new file mode 100644 index 000000000..00e6a0499 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleFloorMod.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleFloorMod *) +{ + return _graph->nodes()->create<luci::CircleFloorMod>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleFloorMod.test.cpp b/compiler/luci/service/src/Nodes/CircleFloorMod.test.cpp new file mode 100644 index 000000000..ce91d5881 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleFloorMod.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_FloorMod) +{ + auto g = loco::make_graph(); + auto node_floormod = g->nodes()->create<luci::CircleFloorMod>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_floormod, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_floormod = dynamic_cast<luci::CircleFloorMod *>(cloned); + ASSERT_NE(nullptr, cloned_floormod); +} diff --git a/compiler/luci/service/src/Nodes/CircleFullyConnected.cpp b/compiler/luci/service/src/Nodes/CircleFullyConnected.cpp new file mode 100644 index 000000000..8acb35cbf --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleFullyConnected.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleFullyConnected *node) +{ + if (node->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return nullptr; + if (node->weights_format() == luci::CircleFullyConnected::WeightsFormat::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleFullyConnected>(); + if (cloned != nullptr) + { + cloned->fusedActivationFunction(node->fusedActivationFunction()); + cloned->weights_format(node->weights_format()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleFullyConnected.test.cpp b/compiler/luci/service/src/Nodes/CircleFullyConnected.test.cpp new file mode 100644 index 000000000..965b59130 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleFullyConnected.test.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_FullyConnected) +{ + auto g = loco::make_graph(); + auto node_fc = g->nodes()->create<luci::CircleFullyConnected>(); + node_fc->fusedActivationFunction(luci::FusedActFunc::RELU); + node_fc->weights_format(luci::CircleFullyConnected::WeightsFormat::DEFAULT); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_fc, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_fc = dynamic_cast<luci::CircleFullyConnected *>(cloned); + ASSERT_NE(nullptr, cloned_fc); + ASSERT_EQ(node_fc->fusedActivationFunction(), cloned_fc->fusedActivationFunction()); + ASSERT_EQ(node_fc->weights_format(), cloned_fc->weights_format()); +} + +TEST(CloneNodeTest, clone_FullyConnected_fusedact_NEG) +{ + auto g = loco::make_graph(); + auto node_fc = g->nodes()->create<luci::CircleFullyConnected>(); + node_fc->fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + node_fc->weights_format(luci::CircleFullyConnected::WeightsFormat::DEFAULT); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_fc, gc.get()); + ASSERT_EQ(nullptr, cloned); +} + +TEST(CloneNodeTest, clone_FullyConnected_wf_NEG) +{ + auto g = loco::make_graph(); + auto node_fc = g->nodes()->create<luci::CircleFullyConnected>(); + node_fc->fusedActivationFunction(luci::FusedActFunc::RELU); + node_fc->weights_format(luci::CircleFullyConnected::WeightsFormat::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_fc, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleGather.cpp b/compiler/luci/service/src/Nodes/CircleGather.cpp new file mode 100644 index 000000000..072bdeabc --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleGather.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleGather *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleGather>(); + if (cloned != nullptr) + cloned->axis(node->axis()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleGather.test.cpp b/compiler/luci/service/src/Nodes/CircleGather.test.cpp new file mode 100644 index 000000000..f48dbdb67 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleGather.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Gather) +{ + auto g = loco::make_graph(); + auto node_gat = g->nodes()->create<luci::CircleGather>(); + node_gat->axis(3); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_gat, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_gat = dynamic_cast<luci::CircleGather *>(cloned); + ASSERT_NE(nullptr, cloned_gat); + ASSERT_EQ(node_gat->axis(), cloned_gat->axis()); +} diff --git a/compiler/luci/service/src/Nodes/CircleGatherNd.cpp b/compiler/luci/service/src/Nodes/CircleGatherNd.cpp new file mode 100644 index 000000000..df7ae6e79 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleGatherNd.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleGatherNd *) +{ + return _graph->nodes()->create<luci::CircleGatherNd>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleGatherNd.test.cpp b/compiler/luci/service/src/Nodes/CircleGatherNd.test.cpp new file mode 100644 index 000000000..3a705710c --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleGatherNd.test.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <luci/IR/CircleNodes.h> +#include <luci/Service/CircleShapeInference.h> + +#include <loco/IR/TensorShape.h> + +#include <oops/InternalExn.h> + +#include <gtest/gtest.h> + +TEST(ShapeRuleTest, gather_nd_simple) +{ + luci::CircleInput input; + luci::CircleConst indices_const; + luci::CircleGatherNd gather_nd; + + input.shape({1, 4, 4, 3}); + indices_const.shape({1, 2, 3}); + + input.shape_status(luci::ShapeStatus::VALID); + indices_const.shape_status(luci::ShapeStatus::VALID); + + gather_nd.params(&input); + gather_nd.indices(&indices_const); + + loco::TensorShape shape; + luci::sinf::Rule shape_inf_rule; + + ASSERT_TRUE(shape_inf_rule.infer(&gather_nd, shape)); + ASSERT_EQ(3, shape.rank()); + ASSERT_EQ(1, shape.dim(0).value()); + ASSERT_EQ(2, shape.dim(1).value()); + ASSERT_EQ(3, shape.dim(2).value()); +} + +TEST(ShapeRuleTest, gather_nd_slices) +{ + luci::CircleInput input; + luci::CircleConst indices_const; + luci::CircleGatherNd gather_nd; + + input.shape({1, 4, 4, 3}); + indices_const.shape({1, 2, 1}); + + input.shape_status(luci::ShapeStatus::VALID); + indices_const.shape_status(luci::ShapeStatus::VALID); + + gather_nd.params(&input); + gather_nd.indices(&indices_const); + + loco::TensorShape shape; + luci::sinf::Rule shape_inf_rule; + + ASSERT_TRUE(shape_inf_rule.infer(&gather_nd, shape)); + ASSERT_EQ(5, shape.rank()); + ASSERT_EQ(1, shape.dim(0).value()); + ASSERT_EQ(2, shape.dim(1).value()); + ASSERT_EQ(4, shape.dim(2).value()); + ASSERT_EQ(4, shape.dim(3).value()); + ASSERT_EQ(3, shape.dim(4).value()); +} + +TEST(ShapeRuleTest, gather_nd_NEG) +{ + luci::CircleInput input; + luci::CircleConst indices_const; + luci::CircleGatherNd gather_nd; + + input.shape({1, 4, 4, 3}); + indices_const.shape({1, 2, 5}); + + input.shape_status(luci::ShapeStatus::VALID); + indices_const.shape_status(luci::ShapeStatus::VALID); + + gather_nd.params(&input); + gather_nd.indices(&indices_const); + + loco::TensorShape shape; + luci::sinf::Rule shape_inf_rule; + + ASSERT_THROW(shape_inf_rule.infer(&gather_nd, shape), oops::InternalExn); +} + +TEST(CloneNodeTest, clone_GatherNd) +{ + auto g = loco::make_graph(); + auto node_gtnd = g->nodes()->create<luci::CircleGatherNd>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_gtnd, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_gtnd = dynamic_cast<luci::CircleGatherNd *>(cloned); + ASSERT_NE(nullptr, cloned_gtnd); +} diff --git a/compiler/luci/service/src/Nodes/CircleGreater.cpp b/compiler/luci/service/src/Nodes/CircleGreater.cpp new file mode 100644 index 000000000..366d955bf --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleGreater.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleGreater *) +{ + return _graph->nodes()->create<luci::CircleGreater>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleGreater.test.cpp b/compiler/luci/service/src/Nodes/CircleGreater.test.cpp new file mode 100644 index 000000000..6d2df61f0 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleGreater.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Greater) +{ + auto g = loco::make_graph(); + auto node_gt = g->nodes()->create<luci::CircleGreater>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_gt, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_gt = dynamic_cast<luci::CircleGreater *>(cloned); + ASSERT_NE(nullptr, cloned_gt); +} diff --git a/compiler/luci/service/src/Nodes/CircleGreaterEqual.cpp b/compiler/luci/service/src/Nodes/CircleGreaterEqual.cpp new file mode 100644 index 000000000..9705bbe1e --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleGreaterEqual.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleGreaterEqual *) +{ + return _graph->nodes()->create<luci::CircleGreaterEqual>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleGreaterEqual.test.cpp b/compiler/luci/service/src/Nodes/CircleGreaterEqual.test.cpp new file mode 100644 index 000000000..10387df3a --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleGreaterEqual.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_GreaterEqual) +{ + auto g = loco::make_graph(); + auto node_ge = g->nodes()->create<luci::CircleGreaterEqual>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_ge, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_ge = dynamic_cast<luci::CircleGreaterEqual *>(cloned); + ASSERT_NE(nullptr, cloned_ge); +} diff --git a/compiler/luci/service/src/Nodes/CircleIfOut.cpp b/compiler/luci/service/src/Nodes/CircleIfOut.cpp new file mode 100644 index 000000000..31ad7203f --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleIfOut.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2021 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 <luci/Service/CircleShapeInference.h> +#include <luci/Service/CircleTypeInference.h> + +namespace +{ + +struct CircleIfOutGraphs +{ + loco::GraphOutput *then_graph_output; + loco::GraphOutput *else_graph_output; +}; + +} // namespace + +namespace +{ + +CircleIfOutGraphs get_out_graphs(const luci::CircleIfOut *node) +{ + CircleIfOutGraphs ret_out; + + /** + * @note IF operator type and shape are that of the "then" and "else" + * Graph Outputs. + */ + auto circle_if = loco::must_cast<const luci::CircleIf *>(node->input()); + + auto index = node->index(); + auto then_graph = circle_if->then_graph(); + auto else_graph = circle_if->else_graph(); + assert(then_graph != nullptr); + assert(else_graph != nullptr); + + // shape and type are assumed to be same + // these are checked at post_import_graph() in Import + auto then_outputs = loco::output_nodes(then_graph); + auto else_outputs = loco::output_nodes(else_graph); + assert(then_outputs.size() == else_outputs.size()); + assert(index < static_cast<int32_t>(then_outputs.size())); + + auto then_out = loco::must_cast<luci::CircleOutput *>(then_outputs.at(index)); + auto else_out = loco::must_cast<luci::CircleOutput *>(else_outputs.at(index)); + + auto then_graph_outputs = then_graph->outputs(); // loco::GraphOutput items + auto else_graph_outputs = else_graph->outputs(); + assert(then_graph_outputs->size() == else_graph_outputs->size()); + + ret_out.then_graph_output = then_graph_outputs->at(then_out->index()); + ret_out.else_graph_output = else_graph_outputs->at(else_out->index()); + + return ret_out; +} + +} // namespace + +namespace luci +{ + +loco::TensorShape sinf::Algorithm::visit(const luci::CircleIfOut *node) +{ + auto graphs = get_out_graphs(node); + assert(*graphs.then_graph_output->shape() == *graphs.else_graph_output->shape()); + return *graphs.then_graph_output->shape(); +} + +loco::DataType tinf::Algorithm::visit(const luci::CircleIfOut *node) +{ + auto graphs = get_out_graphs(node); + assert(graphs.then_graph_output->dtype() == graphs.else_graph_output->dtype()); + return graphs.then_graph_output->dtype(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleInstanceNorm.cpp b/compiler/luci/service/src/Nodes/CircleInstanceNorm.cpp new file mode 100644 index 000000000..d9e49d8ed --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleInstanceNorm.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleInstanceNorm *node) +{ + if (node->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleInstanceNorm>(); + if (cloned != nullptr) + { + cloned->fusedActivationFunction(node->fusedActivationFunction()); + cloned->epsilon(node->epsilon()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleInstanceNorm.test.cpp b/compiler/luci/service/src/Nodes/CircleInstanceNorm.test.cpp new file mode 100644 index 000000000..bae92b1ae --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleInstanceNorm.test.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_InstanceNorm) +{ + auto g = loco::make_graph(); + auto node_fc = g->nodes()->create<luci::CircleInstanceNorm>(); + node_fc->fusedActivationFunction(luci::FusedActFunc::RELU); + node_fc->epsilon(3); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_fc, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_fc = dynamic_cast<luci::CircleInstanceNorm *>(cloned); + ASSERT_NE(nullptr, cloned_fc); + ASSERT_EQ(node_fc->fusedActivationFunction(), cloned_fc->fusedActivationFunction()); + ASSERT_EQ(node_fc->epsilon(), cloned_fc->epsilon()); +} + +TEST(CloneNodeTest, clone_InstanceNorm_fusedact_NEG) +{ + auto g = loco::make_graph(); + auto node_fc = g->nodes()->create<luci::CircleInstanceNorm>(); + node_fc->fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_fc, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleL2Normalize.cpp b/compiler/luci/service/src/Nodes/CircleL2Normalize.cpp new file mode 100644 index 000000000..afa2a6acb --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleL2Normalize.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleL2Normalize *node) +{ + if (node->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleL2Normalize>(); + if (cloned != nullptr) + cloned->fusedActivationFunction(node->fusedActivationFunction()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleL2Normalize.test.cpp b/compiler/luci/service/src/Nodes/CircleL2Normalize.test.cpp new file mode 100644 index 000000000..0f148797e --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleL2Normalize.test.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_L2Normalize) +{ + auto g = loco::make_graph(); + auto node_l2n = g->nodes()->create<luci::CircleL2Normalize>(); + node_l2n->fusedActivationFunction(luci::FusedActFunc::RELU); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_l2n, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_l2n = dynamic_cast<luci::CircleL2Normalize *>(cloned); + ASSERT_NE(nullptr, cloned_l2n); + ASSERT_EQ(node_l2n->fusedActivationFunction(), cloned_l2n->fusedActivationFunction()); +} + +TEST(CloneNodeTest, clone_L2Normalize_NEG) +{ + auto g = loco::make_graph(); + auto node_l2n = g->nodes()->create<luci::CircleL2Normalize>(); + node_l2n->fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_l2n, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleL2Pool2D.cpp b/compiler/luci/service/src/Nodes/CircleL2Pool2D.cpp new file mode 100644 index 000000000..2d876c5bc --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleL2Pool2D.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleL2Pool2D *node) +{ + if (node->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return nullptr; + if (node->padding() == luci::Padding::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleL2Pool2D>(); + if (cloned != nullptr) + { + cloned->fusedActivationFunction(node->fusedActivationFunction()); + cloned->padding(node->padding()); + cloned->filter()->h(node->filter()->h()); + cloned->filter()->w(node->filter()->w()); + cloned->stride()->h(node->stride()->h()); + cloned->stride()->w(node->stride()->w()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleL2Pool2D.test.cpp b/compiler/luci/service/src/Nodes/CircleL2Pool2D.test.cpp new file mode 100644 index 000000000..37344fd9a --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleL2Pool2D.test.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_L2Pool2D) +{ + auto g = loco::make_graph(); + auto node_l2n = g->nodes()->create<luci::CircleL2Pool2D>(); + node_l2n->fusedActivationFunction(luci::FusedActFunc::RELU); + node_l2n->padding(luci::Padding::SAME); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_l2n, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_l2n = dynamic_cast<luci::CircleL2Pool2D *>(cloned); + ASSERT_NE(nullptr, cloned_l2n); + ASSERT_EQ(node_l2n->fusedActivationFunction(), cloned_l2n->fusedActivationFunction()); + ASSERT_EQ(node_l2n->padding(), cloned_l2n->padding()); +} + +TEST(CloneNodeTest, clone_L2Normalize_fusedact_NEG) +{ + auto g = loco::make_graph(); + auto node_l2n = g->nodes()->create<luci::CircleL2Pool2D>(); + node_l2n->fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + node_l2n->padding(luci::Padding::SAME); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_l2n, gc.get()); + ASSERT_EQ(nullptr, cloned); +} + +TEST(CloneNodeTest, clone_L2Normalize_padding_NEG) +{ + auto g = loco::make_graph(); + auto node_l2n = g->nodes()->create<luci::CircleL2Pool2D>(); + node_l2n->fusedActivationFunction(luci::FusedActFunc::RELU); + node_l2n->padding(luci::Padding::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_l2n, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleLeakyRelu.cpp b/compiler/luci/service/src/Nodes/CircleLeakyRelu.cpp new file mode 100644 index 000000000..91030618c --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLeakyRelu.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleLeakyRelu *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleLeakyRelu>(); + if (cloned != nullptr) + cloned->alpha(node->alpha()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleLeakyRelu.test.cpp b/compiler/luci/service/src/Nodes/CircleLeakyRelu.test.cpp new file mode 100644 index 000000000..17fc1442a --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLeakyRelu.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_LeakyRelu) +{ + auto g = loco::make_graph(); + auto node_lr = g->nodes()->create<luci::CircleLeakyRelu>(); + node_lr->alpha(1.2f); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_lr, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_lr = dynamic_cast<luci::CircleLeakyRelu *>(cloned); + ASSERT_NE(nullptr, cloned_lr); + ASSERT_EQ(node_lr->alpha(), cloned_lr->alpha()); +} diff --git a/compiler/luci/service/src/Nodes/CircleLess.cpp b/compiler/luci/service/src/Nodes/CircleLess.cpp new file mode 100644 index 000000000..33b70b735 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLess.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleLess *) +{ + return _graph->nodes()->create<luci::CircleLess>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleLess.test.cpp b/compiler/luci/service/src/Nodes/CircleLess.test.cpp new file mode 100644 index 000000000..43248948d --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLess.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Less) +{ + auto g = loco::make_graph(); + auto node_less = g->nodes()->create<luci::CircleLess>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_less, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_less = dynamic_cast<luci::CircleLess *>(cloned); + ASSERT_NE(nullptr, cloned_less); +} diff --git a/compiler/luci/service/src/Nodes/CircleLessEqual.cpp b/compiler/luci/service/src/Nodes/CircleLessEqual.cpp new file mode 100644 index 000000000..22491365a --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLessEqual.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleLessEqual *) +{ + return _graph->nodes()->create<luci::CircleLessEqual>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleLessEqual.test.cpp b/compiler/luci/service/src/Nodes/CircleLessEqual.test.cpp new file mode 100644 index 000000000..0a87daf5d --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLessEqual.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_LessEqual) +{ + auto g = loco::make_graph(); + auto node_le = g->nodes()->create<luci::CircleLessEqual>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_le, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_le = dynamic_cast<luci::CircleLessEqual *>(cloned); + ASSERT_NE(nullptr, cloned_le); +} diff --git a/compiler/luci/service/src/Nodes/CircleLocalResponseNormalization.cpp b/compiler/luci/service/src/Nodes/CircleLocalResponseNormalization.cpp new file mode 100644 index 000000000..bf69b5ef5 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLocalResponseNormalization.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleLocalResponseNormalization *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleLocalResponseNormalization>(); + if (cloned != nullptr) + { + cloned->radius(node->radius()); + cloned->bias(node->bias()); + cloned->alpha(node->alpha()); + cloned->beta(node->beta()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleLocalResponseNormalization.test.cpp b/compiler/luci/service/src/Nodes/CircleLocalResponseNormalization.test.cpp new file mode 100644 index 000000000..262b119bb --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLocalResponseNormalization.test.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_LocalResponseNormalization) +{ + auto g = loco::make_graph(); + auto node_lrn = g->nodes()->create<luci::CircleLocalResponseNormalization>(); + node_lrn->radius(32); + node_lrn->bias(1.2f); + node_lrn->alpha(3.4f); + node_lrn->beta(5.7f); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_lrn, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_lrn = dynamic_cast<luci::CircleLocalResponseNormalization *>(cloned); + ASSERT_NE(nullptr, cloned_lrn); + ASSERT_EQ(node_lrn->radius(), cloned_lrn->radius()); + ASSERT_EQ(node_lrn->bias(), cloned_lrn->bias()); + ASSERT_EQ(node_lrn->alpha(), cloned_lrn->alpha()); + ASSERT_EQ(node_lrn->beta(), cloned_lrn->beta()); +} diff --git a/compiler/luci/service/src/Nodes/CircleLog.cpp b/compiler/luci/service/src/Nodes/CircleLog.cpp new file mode 100644 index 000000000..5788f129f --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLog.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleLog *) +{ + return _graph->nodes()->create<luci::CircleLog>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleLog.test.cpp b/compiler/luci/service/src/Nodes/CircleLog.test.cpp new file mode 100644 index 000000000..d1ee1428e --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLog.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Log) +{ + auto g = loco::make_graph(); + auto node_log = g->nodes()->create<luci::CircleLog>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_log, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_log = dynamic_cast<luci::CircleLog *>(cloned); + ASSERT_NE(nullptr, cloned_log); +} diff --git a/compiler/luci/service/src/Nodes/CircleLogSoftmax.cpp b/compiler/luci/service/src/Nodes/CircleLogSoftmax.cpp new file mode 100644 index 000000000..352160aff --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLogSoftmax.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleLogSoftmax *) +{ + return _graph->nodes()->create<luci::CircleLogSoftmax>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleLogSoftmax.test.cpp b/compiler/luci/service/src/Nodes/CircleLogSoftmax.test.cpp new file mode 100644 index 000000000..feebb79cb --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLogSoftmax.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_LogSoftmax) +{ + auto g = loco::make_graph(); + auto node_logs = g->nodes()->create<luci::CircleLogSoftmax>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_logs, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_logs = dynamic_cast<luci::CircleLogSoftmax *>(cloned); + ASSERT_NE(nullptr, cloned_logs); +} diff --git a/compiler/luci/service/src/Nodes/CircleLogicalAnd.cpp b/compiler/luci/service/src/Nodes/CircleLogicalAnd.cpp new file mode 100644 index 000000000..5df62b951 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLogicalAnd.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleLogicalAnd *) +{ + return _graph->nodes()->create<luci::CircleLogicalAnd>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleLogicalAnd.test.cpp b/compiler/luci/service/src/Nodes/CircleLogicalAnd.test.cpp new file mode 100644 index 000000000..aa811edfa --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLogicalAnd.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_LogicalAnd) +{ + auto g = loco::make_graph(); + auto node_logand = g->nodes()->create<luci::CircleLogicalAnd>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_logand, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_logand = dynamic_cast<luci::CircleLogicalAnd *>(cloned); + ASSERT_NE(nullptr, cloned_logand); +} diff --git a/compiler/luci/service/src/Nodes/CircleLogicalNot.cpp b/compiler/luci/service/src/Nodes/CircleLogicalNot.cpp new file mode 100644 index 000000000..ac982829d --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLogicalNot.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleLogicalNot *) +{ + return _graph->nodes()->create<luci::CircleLogicalNot>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleLogicalNot.test.cpp b/compiler/luci/service/src/Nodes/CircleLogicalNot.test.cpp new file mode 100644 index 000000000..9e55be944 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLogicalNot.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_LogicalNot) +{ + auto g = loco::make_graph(); + auto node_lognot = g->nodes()->create<luci::CircleLogicalNot>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_lognot, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_lognot = dynamic_cast<luci::CircleLogicalNot *>(cloned); + ASSERT_NE(nullptr, cloned_lognot); +} diff --git a/compiler/luci/service/src/Nodes/CircleLogicalOr.cpp b/compiler/luci/service/src/Nodes/CircleLogicalOr.cpp new file mode 100644 index 000000000..1201d6f34 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLogicalOr.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleLogicalOr *) +{ + return _graph->nodes()->create<luci::CircleLogicalOr>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleLogicalOr.test.cpp b/compiler/luci/service/src/Nodes/CircleLogicalOr.test.cpp new file mode 100644 index 000000000..19b706dcd --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLogicalOr.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_LogicalOr) +{ + auto g = loco::make_graph(); + auto node_logor = g->nodes()->create<luci::CircleLogicalOr>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_logor, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_logor = dynamic_cast<luci::CircleLogicalOr *>(cloned); + ASSERT_NE(nullptr, cloned_logor); +} diff --git a/compiler/luci/service/src/Nodes/CircleLogistic.cpp b/compiler/luci/service/src/Nodes/CircleLogistic.cpp new file mode 100644 index 000000000..b21b187e9 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLogistic.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleLogistic *) +{ + return _graph->nodes()->create<luci::CircleLogistic>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleLogistic.test.cpp b/compiler/luci/service/src/Nodes/CircleLogistic.test.cpp new file mode 100644 index 000000000..05dbe46e4 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleLogistic.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Logistic) +{ + auto g = loco::make_graph(); + auto node_log = g->nodes()->create<luci::CircleLogistic>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_log, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_log = dynamic_cast<luci::CircleLogistic *>(cloned); + ASSERT_NE(nullptr, cloned_log); +} diff --git a/compiler/luci/service/src/Nodes/CircleMatrixDiag.cpp b/compiler/luci/service/src/Nodes/CircleMatrixDiag.cpp new file mode 100644 index 000000000..2bffa07b1 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleMatrixDiag.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleMatrixDiag *) +{ + return _graph->nodes()->create<luci::CircleMatrixDiag>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleMatrixDiag.test.cpp b/compiler/luci/service/src/Nodes/CircleMatrixDiag.test.cpp new file mode 100644 index 000000000..c08c4cb94 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleMatrixDiag.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_MatrixDiag) +{ + auto g = loco::make_graph(); + auto node_md = g->nodes()->create<luci::CircleMatrixDiag>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_md, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_md = dynamic_cast<luci::CircleMatrixDiag *>(cloned); + ASSERT_NE(nullptr, cloned_md); +} diff --git a/compiler/luci/service/src/Nodes/CircleMatrixSetDiag.cpp b/compiler/luci/service/src/Nodes/CircleMatrixSetDiag.cpp new file mode 100644 index 000000000..5ea2a5339 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleMatrixSetDiag.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleMatrixSetDiag *) +{ + return _graph->nodes()->create<luci::CircleMatrixSetDiag>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleMatrixSetDiag.test.cpp b/compiler/luci/service/src/Nodes/CircleMatrixSetDiag.test.cpp new file mode 100644 index 000000000..5ea77ba75 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleMatrixSetDiag.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_MatrixSetDiag) +{ + auto g = loco::make_graph(); + auto node_msd = g->nodes()->create<luci::CircleMatrixSetDiag>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_msd, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_msd = dynamic_cast<luci::CircleMatrixSetDiag *>(cloned); + ASSERT_NE(nullptr, cloned_msd); +} diff --git a/compiler/luci/service/src/Nodes/CircleMaxPool2D.cpp b/compiler/luci/service/src/Nodes/CircleMaxPool2D.cpp new file mode 100644 index 000000000..b21610c7f --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleMaxPool2D.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleMaxPool2D *node) +{ + if (node->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return nullptr; + if (node->padding() == luci::Padding::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleMaxPool2D>(); + if (cloned != nullptr) + { + cloned->fusedActivationFunction(node->fusedActivationFunction()); + cloned->padding(node->padding()); + cloned->filter()->h(node->filter()->h()); + cloned->filter()->w(node->filter()->w()); + cloned->stride()->h(node->stride()->h()); + cloned->stride()->w(node->stride()->w()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleMaxPool2D.test.cpp b/compiler/luci/service/src/Nodes/CircleMaxPool2D.test.cpp new file mode 100644 index 000000000..415cf7c44 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleMaxPool2D.test.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_MaxPool2D) +{ + auto g = loco::make_graph(); + auto node_mp = g->nodes()->create<luci::CircleMaxPool2D>(); + node_mp->fusedActivationFunction(luci::FusedActFunc::RELU); + node_mp->padding(luci::Padding::SAME); + node_mp->filter()->h(1); + node_mp->filter()->w(2); + node_mp->stride()->h(3); + node_mp->stride()->w(4); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_mp, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_mp = dynamic_cast<luci::CircleMaxPool2D *>(cloned); + ASSERT_NE(nullptr, cloned_mp); + ASSERT_EQ(node_mp->fusedActivationFunction(), cloned_mp->fusedActivationFunction()); + ASSERT_EQ(node_mp->padding(), cloned_mp->padding()); + ASSERT_EQ(node_mp->filter()->h(), cloned_mp->filter()->h()); + ASSERT_EQ(node_mp->filter()->w(), cloned_mp->filter()->w()); + ASSERT_EQ(node_mp->stride()->h(), cloned_mp->stride()->h()); + ASSERT_EQ(node_mp->stride()->w(), cloned_mp->stride()->w()); +} + +TEST(CloneNodeTest, clone_MaxPool2D_fusedact_NEG) +{ + auto g = loco::make_graph(); + auto node_mp = g->nodes()->create<luci::CircleMaxPool2D>(); + node_mp->fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + node_mp->padding(luci::Padding::SAME); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_mp, gc.get()); + ASSERT_EQ(nullptr, cloned); +} + +TEST(CloneNodeTest, clone_MaxPool2D_padding_NEG) +{ + auto g = loco::make_graph(); + auto node_mp = g->nodes()->create<luci::CircleMaxPool2D>(); + node_mp->fusedActivationFunction(luci::FusedActFunc::RELU); + node_mp->padding(luci::Padding::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_mp, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleMaximum.cpp b/compiler/luci/service/src/Nodes/CircleMaximum.cpp new file mode 100644 index 000000000..545f4ca21 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleMaximum.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleMaximum *) +{ + return _graph->nodes()->create<luci::CircleMaximum>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleMaximum.test.cpp b/compiler/luci/service/src/Nodes/CircleMaximum.test.cpp new file mode 100644 index 000000000..6f1ada060 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleMaximum.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Maximum) +{ + auto g = loco::make_graph(); + auto node_max = g->nodes()->create<luci::CircleMaximum>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_max, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_max = dynamic_cast<luci::CircleMaximum *>(cloned); + ASSERT_NE(nullptr, cloned_max); +} diff --git a/compiler/luci/service/src/Nodes/CircleMean.cpp b/compiler/luci/service/src/Nodes/CircleMean.cpp index a78713698..95bc54532 100644 --- a/compiler/luci/service/src/Nodes/CircleMean.cpp +++ b/compiler/luci/service/src/Nodes/CircleMean.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2021 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 + * 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, @@ -14,15 +14,17 @@ * limitations under the License. */ -#include <luci/Service/CircleShapeSignatureInference.h> +#include "CircleCloneNode.h" namespace luci { -ShapeSignature ssinf::Algorithm::visit(const luci::CircleMean *node) +luci::CircleNode *CloneNode::visit(const luci::CircleMean *node) { - return legalized_signature( - reduced_signature(node->input(), node->reduction_indices(), node->keep_dims())); + auto *cloned = _graph->nodes()->create<luci::CircleMean>(); + if (cloned != nullptr) + cloned->keep_dims(node->keep_dims()); + return cloned; } } // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleMean.test.cpp b/compiler/luci/service/src/Nodes/CircleMean.test.cpp new file mode 100644 index 000000000..aa1b88f13 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleMean.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Mean) +{ + auto g = loco::make_graph(); + auto node_mean = g->nodes()->create<luci::CircleMean>(); + node_mean->keep_dims(true); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_mean, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_mean = dynamic_cast<luci::CircleMean *>(cloned); + ASSERT_NE(nullptr, cloned_mean); + ASSERT_EQ(node_mean->keep_dims(), cloned_mean->keep_dims()); +} diff --git a/compiler/luci/service/src/Nodes/CircleMinimum.cpp b/compiler/luci/service/src/Nodes/CircleMinimum.cpp new file mode 100644 index 000000000..2c2755c55 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleMinimum.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleMinimum *) +{ + return _graph->nodes()->create<luci::CircleMinimum>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleMinimum.test.cpp b/compiler/luci/service/src/Nodes/CircleMinimum.test.cpp new file mode 100644 index 000000000..0a54be71c --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleMinimum.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Minimum) +{ + auto g = loco::make_graph(); + auto node_min = g->nodes()->create<luci::CircleMinimum>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_min, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_min = dynamic_cast<luci::CircleMinimum *>(cloned); + ASSERT_NE(nullptr, cloned_min); +} diff --git a/compiler/luci/service/src/Nodes/CircleMirrorPad.cpp b/compiler/luci/service/src/Nodes/CircleMirrorPad.cpp new file mode 100644 index 000000000..919221a0b --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleMirrorPad.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleMirrorPad *node) +{ + if (node->mode() == luci::MirrorPadMode::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleMirrorPad>(); + if (cloned != nullptr) + cloned->mode(node->mode()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleMirrorPad.test.cpp b/compiler/luci/service/src/Nodes/CircleMirrorPad.test.cpp new file mode 100644 index 000000000..911cf6d3b --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleMirrorPad.test.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_MirrorPad) +{ + auto g = loco::make_graph(); + auto node_mp = g->nodes()->create<luci::CircleMirrorPad>(); + node_mp->mode(luci::MirrorPadMode::REFLECT); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_mp, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_mp = dynamic_cast<luci::CircleMirrorPad *>(cloned); + ASSERT_NE(nullptr, cloned_mp); + ASSERT_EQ(node_mp->mode(), cloned_mp->mode()); +} + +TEST(CloneNodeTest, clone_MirrorPad_mode_NEG) +{ + auto g = loco::make_graph(); + auto node_mp = g->nodes()->create<luci::CircleMirrorPad>(); + node_mp->mode(luci::MirrorPadMode::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_mp, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleMul.cpp b/compiler/luci/service/src/Nodes/CircleMul.cpp new file mode 100644 index 000000000..096aed196 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleMul.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleMul *node) +{ + if (node->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleMul>(); + if (cloned != nullptr) + cloned->fusedActivationFunction(node->fusedActivationFunction()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleMul.test.cpp b/compiler/luci/service/src/Nodes/CircleMul.test.cpp new file mode 100644 index 000000000..dc5565f11 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleMul.test.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Mul) +{ + auto g = loco::make_graph(); + auto node_mul = g->nodes()->create<luci::CircleMul>(); + node_mul->fusedActivationFunction(luci::FusedActFunc::RELU); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_mul, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_mul = dynamic_cast<luci::CircleMul *>(cloned); + ASSERT_NE(nullptr, cloned_mul); + ASSERT_EQ(node_mul->fusedActivationFunction(), cloned_mul->fusedActivationFunction()); +} + +TEST(CloneNodeTest, clone_Mul_NEG) +{ + auto g = loco::make_graph(); + auto node_mul = g->nodes()->create<luci::CircleMul>(); + node_mul->fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_mul, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleNeg.cpp b/compiler/luci/service/src/Nodes/CircleNeg.cpp new file mode 100644 index 000000000..312189e77 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleNeg.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleNeg *) +{ + return _graph->nodes()->create<luci::CircleNeg>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleNeg.test.cpp b/compiler/luci/service/src/Nodes/CircleNeg.test.cpp new file mode 100644 index 000000000..8c2880324 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleNeg.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Neg) +{ + auto g = loco::make_graph(); + auto node_neg = g->nodes()->create<luci::CircleNeg>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_neg, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_neg = dynamic_cast<luci::CircleNeg *>(cloned); + ASSERT_NE(nullptr, cloned_neg); +} diff --git a/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV4.cpp b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV4.cpp new file mode 100644 index 000000000..4757e8314 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV4.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleNonMaxSuppressionV4 *) +{ + return _graph->nodes()->create<luci::CircleNonMaxSuppressionV4>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV4.test.cpp b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV4.test.cpp new file mode 100644 index 000000000..34f5b0325 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV4.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_NonMaxSuppressionV4) +{ + auto g = loco::make_graph(); + auto node_nms = g->nodes()->create<luci::CircleNonMaxSuppressionV4>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_nms, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_nms = dynamic_cast<luci::CircleNonMaxSuppressionV4 *>(cloned); + ASSERT_NE(nullptr, cloned_nms); +} diff --git a/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV4Out.cpp b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV4Out.cpp new file mode 100644 index 000000000..2a12f2a45 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV4Out.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleNonMaxSuppressionV4Out *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleNonMaxSuppressionV4Out>(); + if (cloned != nullptr) + cloned->index(node->index()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV4Out.test.cpp b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV4Out.test.cpp new file mode 100644 index 000000000..ed9e0e019 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV4Out.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_NonMaxSuppressionV4Out) +{ + auto g = loco::make_graph(); + auto node_nout = g->nodes()->create<luci::CircleNonMaxSuppressionV4Out>(); + node_nout->index(1); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_nout, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_nout = dynamic_cast<luci::CircleNonMaxSuppressionV4Out *>(cloned); + ASSERT_NE(nullptr, cloned_nout); + ASSERT_EQ(node_nout->index(), cloned_nout->index()); +} diff --git a/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV5.cpp b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV5.cpp new file mode 100644 index 000000000..34d128072 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV5.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleNonMaxSuppressionV5 *) +{ + return _graph->nodes()->create<luci::CircleNonMaxSuppressionV5>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV5.test.cpp b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV5.test.cpp new file mode 100644 index 000000000..faaee969e --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV5.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_NonMaxSuppressionV5) +{ + auto g = loco::make_graph(); + auto node_nms = g->nodes()->create<luci::CircleNonMaxSuppressionV5>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_nms, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_nms = dynamic_cast<luci::CircleNonMaxSuppressionV5 *>(cloned); + ASSERT_NE(nullptr, cloned_nms); +} diff --git a/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV5Out.cpp b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV5Out.cpp new file mode 100644 index 000000000..e1d7875e7 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV5Out.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleNonMaxSuppressionV5Out *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleNonMaxSuppressionV5Out>(); + if (cloned != nullptr) + cloned->index(node->index()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV5Out.test.cpp b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV5Out.test.cpp new file mode 100644 index 000000000..ef0f766b9 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleNonMaxSuppressionV5Out.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_NonMaxSuppressionV5Out) +{ + auto g = loco::make_graph(); + auto node_nout = g->nodes()->create<luci::CircleNonMaxSuppressionV5Out>(); + node_nout->index(1); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_nout, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_nout = dynamic_cast<luci::CircleNonMaxSuppressionV5Out *>(cloned); + ASSERT_NE(nullptr, cloned_nout); + ASSERT_EQ(node_nout->index(), cloned_nout->index()); +} diff --git a/compiler/luci/service/src/Nodes/CircleNotEqual.cpp b/compiler/luci/service/src/Nodes/CircleNotEqual.cpp new file mode 100644 index 000000000..4cb5320e8 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleNotEqual.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleNotEqual *) +{ + return _graph->nodes()->create<luci::CircleNotEqual>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleNotEqual.test.cpp b/compiler/luci/service/src/Nodes/CircleNotEqual.test.cpp new file mode 100644 index 000000000..20f7dbc4b --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleNotEqual.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_NotEqual) +{ + auto g = loco::make_graph(); + auto node_ne = g->nodes()->create<luci::CircleNotEqual>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_ne, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_ne = dynamic_cast<luci::CircleNotEqual *>(cloned); + ASSERT_NE(nullptr, cloned_ne); +} diff --git a/compiler/luci/service/src/Nodes/CircleOneHot.cpp b/compiler/luci/service/src/Nodes/CircleOneHot.cpp new file mode 100644 index 000000000..a33c8ff26 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleOneHot.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleOneHot *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleOneHot>(); + if (cloned != nullptr) + cloned->axis(node->axis()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleOneHot.test.cpp b/compiler/luci/service/src/Nodes/CircleOneHot.test.cpp new file mode 100644 index 000000000..dea927d1b --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleOneHot.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_OneHot) +{ + auto g = loco::make_graph(); + auto node_oh = g->nodes()->create<luci::CircleOneHot>(); + node_oh->axis(3); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_oh, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_oh = dynamic_cast<luci::CircleOneHot *>(cloned); + ASSERT_NE(nullptr, cloned_oh); + ASSERT_EQ(node_oh->axis(), cloned_oh->axis()); +} diff --git a/compiler/luci/service/src/Nodes/CircleOutputDummy.cpp b/compiler/luci/service/src/Nodes/CircleOutputDummy.cpp index e0f13c439..ce94dff94 100644 --- a/compiler/luci/service/src/Nodes/CircleOutputDummy.cpp +++ b/compiler/luci/service/src/Nodes/CircleOutputDummy.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2021 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 + * 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, @@ -14,11 +14,14 @@ * limitations under the License. */ -#include <luci/Service/CircleShapeSignatureInference.h> +#include "CircleCloneNode.h" namespace luci { -ShapeSignature ssinf::Algorithm::visit(const luci::CircleOutputDummy *) { return ShapeSignature(); } +luci::CircleNode *CloneNode::visit(const luci::CircleOutputDummy *) +{ + return _graph->nodes()->create<luci::CircleOutputDummy>(); +} } // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleOutputDummy.test.cpp b/compiler/luci/service/src/Nodes/CircleOutputDummy.test.cpp new file mode 100644 index 000000000..6170c7c41 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleOutputDummy.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_OutputDummy) +{ + auto g = loco::make_graph(); + auto node_dummy = g->nodes()->create<luci::CircleOutputDummy>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_dummy, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_dummy = dynamic_cast<luci::CircleOutputDummy *>(cloned); + ASSERT_NE(nullptr, cloned_dummy); +} diff --git a/compiler/luci/service/src/Nodes/CircleOutputExclude.cpp b/compiler/luci/service/src/Nodes/CircleOutputExclude.cpp index 75bbbb3c0..1b0f919c3 100644 --- a/compiler/luci/service/src/Nodes/CircleOutputExclude.cpp +++ b/compiler/luci/service/src/Nodes/CircleOutputExclude.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2021 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 + * 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, @@ -14,14 +14,14 @@ * limitations under the License. */ -#include <luci/Service/CircleShapeSignatureInference.h> +#include "CircleCloneNode.h" namespace luci { -ShapeSignature ssinf::Algorithm::visit(const luci::CircleOutputExclude *) +luci::CircleNode *CloneNode::visit(const luci::CircleOutputExclude *) { - return ShapeSignature(); + return _graph->nodes()->create<luci::CircleOutputExclude>(); } } // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleOutputExclude.test.cpp b/compiler/luci/service/src/Nodes/CircleOutputExclude.test.cpp new file mode 100644 index 000000000..120ffe86b --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleOutputExclude.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_OutputExclude) +{ + auto g = loco::make_graph(); + auto node_outex = g->nodes()->create<luci::CircleOutputExclude>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_outex, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_outex = dynamic_cast<luci::CircleOutputExclude *>(cloned); + ASSERT_NE(nullptr, cloned_outex); +} diff --git a/compiler/luci/service/src/Nodes/CirclePRelu.cpp b/compiler/luci/service/src/Nodes/CirclePRelu.cpp new file mode 100644 index 000000000..8a34e507e --- /dev/null +++ b/compiler/luci/service/src/Nodes/CirclePRelu.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CirclePRelu *) +{ + return _graph->nodes()->create<luci::CirclePRelu>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CirclePRelu.test.cpp b/compiler/luci/service/src/Nodes/CirclePRelu.test.cpp new file mode 100644 index 000000000..1150e3fa4 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CirclePRelu.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_PRelu) +{ + auto g = loco::make_graph(); + auto node_pr = g->nodes()->create<luci::CirclePRelu>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_pr, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_pr = dynamic_cast<luci::CirclePRelu *>(cloned); + ASSERT_NE(nullptr, cloned_pr); +} diff --git a/compiler/luci/service/src/Nodes/CirclePack.cpp b/compiler/luci/service/src/Nodes/CirclePack.cpp new file mode 100644 index 000000000..a3cee0bfd --- /dev/null +++ b/compiler/luci/service/src/Nodes/CirclePack.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CirclePack *node) +{ + auto *cloned = _graph->nodes()->create<luci::CirclePack>(node->values_count()); + if (cloned != nullptr) + cloned->axis(node->axis()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CirclePack.test.cpp b/compiler/luci/service/src/Nodes/CirclePack.test.cpp new file mode 100644 index 000000000..b808956dc --- /dev/null +++ b/compiler/luci/service/src/Nodes/CirclePack.test.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Pack) +{ + auto g = loco::make_graph(); + auto node_pack = g->nodes()->create<luci::CirclePack>(3); + node_pack->axis(7); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_pack, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_pack = dynamic_cast<luci::CirclePack *>(cloned); + ASSERT_NE(nullptr, cloned_pack); + ASSERT_EQ(node_pack->values_count(), cloned_pack->values_count()); + ASSERT_EQ(node_pack->axis(), cloned_pack->axis()); +} diff --git a/compiler/luci/service/src/Nodes/CirclePad.cpp b/compiler/luci/service/src/Nodes/CirclePad.cpp new file mode 100644 index 000000000..425bdce4d --- /dev/null +++ b/compiler/luci/service/src/Nodes/CirclePad.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CirclePad *) +{ + return _graph->nodes()->create<luci::CirclePad>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CirclePad.test.cpp b/compiler/luci/service/src/Nodes/CirclePad.test.cpp new file mode 100644 index 000000000..1d5f8375e --- /dev/null +++ b/compiler/luci/service/src/Nodes/CirclePad.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Pad) +{ + auto g = loco::make_graph(); + auto node_pad = g->nodes()->create<luci::CirclePad>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_pad, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_pad = dynamic_cast<luci::CirclePad *>(cloned); + ASSERT_NE(nullptr, cloned_pad); +} diff --git a/compiler/luci/service/src/Nodes/CirclePadV2.cpp b/compiler/luci/service/src/Nodes/CirclePadV2.cpp new file mode 100644 index 000000000..0e93869b6 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CirclePadV2.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CirclePadV2 *) +{ + return _graph->nodes()->create<luci::CirclePadV2>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CirclePadV2.test.cpp b/compiler/luci/service/src/Nodes/CirclePadV2.test.cpp new file mode 100644 index 000000000..d011f69f8 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CirclePadV2.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_PadV2) +{ + auto g = loco::make_graph(); + auto node_pad = g->nodes()->create<luci::CirclePadV2>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_pad, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_pad = dynamic_cast<luci::CirclePadV2 *>(cloned); + ASSERT_NE(nullptr, cloned_pad); +} diff --git a/compiler/luci/service/src/Nodes/CirclePow.cpp b/compiler/luci/service/src/Nodes/CirclePow.cpp new file mode 100644 index 000000000..bf9388913 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CirclePow.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CirclePow *) +{ + return _graph->nodes()->create<luci::CirclePow>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CirclePow.test.cpp b/compiler/luci/service/src/Nodes/CirclePow.test.cpp new file mode 100644 index 000000000..946298932 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CirclePow.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Pow) +{ + auto g = loco::make_graph(); + auto node_pow = g->nodes()->create<luci::CirclePow>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_pow, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_pow = dynamic_cast<luci::CirclePow *>(cloned); + ASSERT_NE(nullptr, cloned_pow); +} diff --git a/compiler/luci/service/src/Nodes/CircleRange.cpp b/compiler/luci/service/src/Nodes/CircleRange.cpp new file mode 100644 index 000000000..9c6f7b494 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleRange.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleRange *) +{ + return _graph->nodes()->create<luci::CircleRange>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleRange.test.cpp b/compiler/luci/service/src/Nodes/CircleRange.test.cpp new file mode 100644 index 000000000..b2fb29617 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleRange.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Range) +{ + auto g = loco::make_graph(); + auto node_range = g->nodes()->create<luci::CircleRange>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_range, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_range = dynamic_cast<luci::CircleRange *>(cloned); + ASSERT_NE(nullptr, cloned_range); +} diff --git a/compiler/luci/service/src/Nodes/CircleRank.cpp b/compiler/luci/service/src/Nodes/CircleRank.cpp new file mode 100644 index 000000000..db8171c51 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleRank.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleRank *) +{ + return _graph->nodes()->create<luci::CircleRank>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleRank.test.cpp b/compiler/luci/service/src/Nodes/CircleRank.test.cpp new file mode 100644 index 000000000..0e81fb254 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleRank.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Rank) +{ + auto g = loco::make_graph(); + auto node_rank = g->nodes()->create<luci::CircleRank>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_rank, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_rank = dynamic_cast<luci::CircleRank *>(cloned); + ASSERT_NE(nullptr, cloned_rank); +} diff --git a/compiler/luci/service/src/Nodes/CircleReduceAny.cpp b/compiler/luci/service/src/Nodes/CircleReduceAny.cpp index 27da81466..3ab0b3b59 100644 --- a/compiler/luci/service/src/Nodes/CircleReduceAny.cpp +++ b/compiler/luci/service/src/Nodes/CircleReduceAny.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2021 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 + * 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, @@ -14,15 +14,17 @@ * limitations under the License. */ -#include <luci/Service/CircleShapeSignatureInference.h> +#include "CircleCloneNode.h" namespace luci { -ShapeSignature ssinf::Algorithm::visit(const luci::CircleReduceAny *node) +luci::CircleNode *CloneNode::visit(const luci::CircleReduceAny *node) { - return legalized_signature( - reduced_signature(node->input(), node->reduction_indices(), node->keep_dims())); + auto *cloned = _graph->nodes()->create<luci::CircleReduceAny>(); + if (cloned != nullptr) + cloned->keep_dims(node->keep_dims()); + return cloned; } } // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleReduceAny.test.cpp b/compiler/luci/service/src/Nodes/CircleReduceAny.test.cpp new file mode 100644 index 000000000..904b5a139 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleReduceAny.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_ReduceAny) +{ + auto g = loco::make_graph(); + auto node_ra = g->nodes()->create<luci::CircleReduceAny>(); + node_ra->keep_dims(true); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_ra, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_ra = dynamic_cast<luci::CircleReduceAny *>(cloned); + ASSERT_NE(nullptr, cloned_ra); + ASSERT_EQ(node_ra->keep_dims(), cloned_ra->keep_dims()); +} diff --git a/compiler/luci/service/src/Nodes/CircleReduceMax.cpp b/compiler/luci/service/src/Nodes/CircleReduceMax.cpp index 48d9cb970..c026905ca 100644 --- a/compiler/luci/service/src/Nodes/CircleReduceMax.cpp +++ b/compiler/luci/service/src/Nodes/CircleReduceMax.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2021 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 + * 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, @@ -14,15 +14,17 @@ * limitations under the License. */ -#include <luci/Service/CircleShapeSignatureInference.h> +#include "CircleCloneNode.h" namespace luci { -ShapeSignature ssinf::Algorithm::visit(const luci::CircleReduceMax *node) +luci::CircleNode *CloneNode::visit(const luci::CircleReduceMax *node) { - return legalized_signature( - reduced_signature(node->input(), node->reduction_indices(), node->keep_dims())); + auto *cloned = _graph->nodes()->create<luci::CircleReduceMax>(); + if (cloned != nullptr) + cloned->keep_dims(node->keep_dims()); + return cloned; } } // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleReduceMax.test.cpp b/compiler/luci/service/src/Nodes/CircleReduceMax.test.cpp new file mode 100644 index 000000000..b3f3c881e --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleReduceMax.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_ReduceMax) +{ + auto g = loco::make_graph(); + auto node_rmax = g->nodes()->create<luci::CircleReduceMax>(); + node_rmax->keep_dims(true); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_rmax, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_rmax = dynamic_cast<luci::CircleReduceMax *>(cloned); + ASSERT_NE(nullptr, cloned_rmax); + ASSERT_EQ(node_rmax->keep_dims(), cloned_rmax->keep_dims()); +} diff --git a/compiler/luci/service/src/Nodes/CircleReduceMin.cpp b/compiler/luci/service/src/Nodes/CircleReduceMin.cpp index 9a9997118..3dfa19680 100644 --- a/compiler/luci/service/src/Nodes/CircleReduceMin.cpp +++ b/compiler/luci/service/src/Nodes/CircleReduceMin.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2021 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 + * 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, @@ -14,15 +14,17 @@ * limitations under the License. */ -#include <luci/Service/CircleShapeSignatureInference.h> +#include "CircleCloneNode.h" namespace luci { -ShapeSignature ssinf::Algorithm::visit(const luci::CircleReduceMin *node) +luci::CircleNode *CloneNode::visit(const luci::CircleReduceMin *node) { - return legalized_signature( - reduced_signature(node->input(), node->reduction_indices(), node->keep_dims())); + auto *cloned = _graph->nodes()->create<luci::CircleReduceMin>(); + if (cloned != nullptr) + cloned->keep_dims(node->keep_dims()); + return cloned; } } // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleReduceMin.test.cpp b/compiler/luci/service/src/Nodes/CircleReduceMin.test.cpp new file mode 100644 index 000000000..b3faa68da --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleReduceMin.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_ReduceMin) +{ + auto g = loco::make_graph(); + auto node_rmin = g->nodes()->create<luci::CircleReduceMin>(); + node_rmin->keep_dims(true); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_rmin, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_rmin = dynamic_cast<luci::CircleReduceMin *>(cloned); + ASSERT_NE(nullptr, cloned_rmin); + ASSERT_EQ(node_rmin->keep_dims(), cloned_rmin->keep_dims()); +} diff --git a/compiler/luci/service/src/Nodes/CircleReduceProd.cpp b/compiler/luci/service/src/Nodes/CircleReduceProd.cpp index a9d381a74..418a8ce32 100644 --- a/compiler/luci/service/src/Nodes/CircleReduceProd.cpp +++ b/compiler/luci/service/src/Nodes/CircleReduceProd.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2021 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 + * 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, @@ -14,15 +14,17 @@ * limitations under the License. */ -#include <luci/Service/CircleShapeSignatureInference.h> +#include "CircleCloneNode.h" namespace luci { -ShapeSignature ssinf::Algorithm::visit(const luci::CircleReduceProd *node) +luci::CircleNode *CloneNode::visit(const luci::CircleReduceProd *node) { - return legalized_signature( - reduced_signature(node->input(), node->reduction_indices(), node->keep_dims())); + auto *cloned = _graph->nodes()->create<luci::CircleReduceProd>(); + if (cloned != nullptr) + cloned->keep_dims(node->keep_dims()); + return cloned; } } // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleReduceProd.test.cpp b/compiler/luci/service/src/Nodes/CircleReduceProd.test.cpp new file mode 100644 index 000000000..8caf8e91f --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleReduceProd.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_ReduceProd) +{ + auto g = loco::make_graph(); + auto node_rp = g->nodes()->create<luci::CircleReduceProd>(); + node_rp->keep_dims(true); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_rp, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_rp = dynamic_cast<luci::CircleReduceProd *>(cloned); + ASSERT_NE(nullptr, cloned_rp); + ASSERT_EQ(node_rp->keep_dims(), cloned_rp->keep_dims()); +} diff --git a/compiler/luci/service/src/Nodes/CircleRelu.cpp b/compiler/luci/service/src/Nodes/CircleRelu.cpp index a7a7f6f0a..7447eea0c 100644 --- a/compiler/luci/service/src/Nodes/CircleRelu.cpp +++ b/compiler/luci/service/src/Nodes/CircleRelu.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2021 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 + * 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, @@ -14,14 +14,14 @@ * limitations under the License. */ -#include <luci/Service/CircleShapeSignatureInference.h> +#include "CircleCloneNode.h" namespace luci { -ShapeSignature ssinf::Algorithm::visit(const luci::CircleRelu *node) +luci::CircleNode *CloneNode::visit(const luci::CircleRelu *) { - return input_arg_signature(node, 0); + return _graph->nodes()->create<luci::CircleRelu>(); } } // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleRelu.test.cpp b/compiler/luci/service/src/Nodes/CircleRelu.test.cpp new file mode 100644 index 000000000..6154376ba --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleRelu.test.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <luci/IR/CircleNodes.h> +#include <luci/Service/CircleShapeInference.h> +#include <luci/Service/CircleTypeInference.h> + +#include <loco/IR/TensorShape.h> + +#include <gtest/gtest.h> + +TEST(ShapeRuleTest, simple_relu) +{ + luci::CircleInput input; + luci::CircleRelu relu; + + input.shape({3, 4}); + input.shape_status(luci::ShapeStatus::VALID); + + relu.features(&input); + + loco::TensorShape shape; + luci::sinf::Rule shape_inf_rule; + + ASSERT_TRUE(shape_inf_rule.infer(&relu, shape)); + ASSERT_EQ(2, shape.rank()); + ASSERT_EQ(3, shape.dim(0).value()); + ASSERT_EQ(4, shape.dim(1).value()); +} + +TEST(DataTypeRuleTest, simple_relu) +{ + luci::CircleInput input; + luci::CircleRelu relu; + + input.dtype(loco::DataType::S32); + + relu.features(&input); + + loco::DataType dtype; + luci::tinf::Rule type_inf_rule; + + ASSERT_TRUE(type_inf_rule.infer(&relu, dtype)); + ASSERT_EQ(loco::DataType::S32, dtype); +} + +TEST(CloneNodeTest, clone_Relu) +{ + auto g = loco::make_graph(); + auto node_relu = g->nodes()->create<luci::CircleRelu>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_relu, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_relu = dynamic_cast<luci::CircleRelu *>(cloned); + ASSERT_NE(nullptr, cloned_relu); +} diff --git a/compiler/luci/service/src/Nodes/CircleRelu6.cpp b/compiler/luci/service/src/Nodes/CircleRelu6.cpp index 92a596d08..7b98311ed 100644 --- a/compiler/luci/service/src/Nodes/CircleRelu6.cpp +++ b/compiler/luci/service/src/Nodes/CircleRelu6.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2021 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 + * 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, @@ -14,14 +14,14 @@ * limitations under the License. */ -#include <luci/Service/CircleShapeSignatureInference.h> +#include "CircleCloneNode.h" namespace luci { -ShapeSignature ssinf::Algorithm::visit(const luci::CircleRelu6 *node) +luci::CircleNode *CloneNode::visit(const luci::CircleRelu6 *) { - return input_arg_signature(node, 0); + return _graph->nodes()->create<luci::CircleRelu6>(); } } // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleRelu6.test.cpp b/compiler/luci/service/src/Nodes/CircleRelu6.test.cpp new file mode 100644 index 000000000..213dbcb09 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleRelu6.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <loco/IR/TensorShape.h> + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Relu6) +{ + auto g = loco::make_graph(); + auto node_relu6 = g->nodes()->create<luci::CircleRelu6>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_relu6, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_relu6 = dynamic_cast<luci::CircleRelu6 *>(cloned); + ASSERT_NE(nullptr, cloned_relu6); +} diff --git a/compiler/luci/service/src/Nodes/CircleReluN1To1.cpp b/compiler/luci/service/src/Nodes/CircleReluN1To1.cpp index 1e8d9971d..4efedb9fc 100644 --- a/compiler/luci/service/src/Nodes/CircleReluN1To1.cpp +++ b/compiler/luci/service/src/Nodes/CircleReluN1To1.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2021 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 + * 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, @@ -14,14 +14,14 @@ * limitations under the License. */ -#include <luci/Service/CircleShapeSignatureInference.h> +#include "CircleCloneNode.h" namespace luci { -ShapeSignature ssinf::Algorithm::visit(const luci::CircleReluN1To1 *node) +luci::CircleNode *CloneNode::visit(const luci::CircleReluN1To1 *) { - return input_arg_signature(node, 0); + return _graph->nodes()->create<luci::CircleReluN1To1>(); } } // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleReluN1To1.test.cpp b/compiler/luci/service/src/Nodes/CircleReluN1To1.test.cpp new file mode 100644 index 000000000..b828e795c --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleReluN1To1.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <loco/IR/TensorShape.h> + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_ReluN1To1) +{ + auto g = loco::make_graph(); + auto node_relun1 = g->nodes()->create<luci::CircleReluN1To1>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_relun1, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_relun1 = dynamic_cast<luci::CircleReluN1To1 *>(cloned); + ASSERT_NE(nullptr, cloned_relun1); +} diff --git a/compiler/luci/service/src/Nodes/CircleReshape.cpp b/compiler/luci/service/src/Nodes/CircleReshape.cpp new file mode 100644 index 000000000..07a81b306 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleReshape.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleReshape *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleReshape>(); + if (cloned != nullptr) + { + uint32_t rank = node->newShape()->rank(); + cloned->newShape()->rank(rank); + for (uint32_t r = 0; r < rank; ++r) + { + cloned->newShape()->dim(r) = node->newShape()->dim(r); + } + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleReshape.test.cpp b/compiler/luci/service/src/Nodes/CircleReshape.test.cpp new file mode 100644 index 000000000..ca92b717d --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleReshape.test.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Reshape) +{ + auto g = loco::make_graph(); + auto node_reshape = g->nodes()->create<luci::CircleReshape>(); + node_reshape->newShape()->rank(2); + node_reshape->newShape()->dim(0) = 3; + node_reshape->newShape()->dim(1) = 4; + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_reshape, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_reshape = dynamic_cast<luci::CircleReshape *>(cloned); + ASSERT_NE(nullptr, cloned_reshape); + ASSERT_EQ(node_reshape->newShape()->rank(), cloned_reshape->newShape()->rank()); + ASSERT_EQ(node_reshape->newShape()->dim(0), cloned_reshape->newShape()->dim(0)); + ASSERT_EQ(node_reshape->newShape()->dim(1), cloned_reshape->newShape()->dim(1)); +} diff --git a/compiler/luci/service/src/Nodes/CircleResizeBilinear.cpp b/compiler/luci/service/src/Nodes/CircleResizeBilinear.cpp new file mode 100644 index 000000000..55d21af45 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleResizeBilinear.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleResizeBilinear *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleResizeBilinear>(); + if (cloned != nullptr) + { + cloned->align_corners(node->align_corners()); + cloned->half_pixel_centers(node->half_pixel_centers()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleResizeBilinear.test.cpp b/compiler/luci/service/src/Nodes/CircleResizeBilinear.test.cpp new file mode 100644 index 000000000..bff71261d --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleResizeBilinear.test.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <luci/IR/CircleNodes.h> +#include <luci/Service/CircleShapeInference.h> + +#include <loco/IR/TensorShape.h> + +#include <gtest/gtest.h> + +TEST(ShapeRuleTest, resize_bilinear_simple) +{ + luci::CircleInput input; + luci::CircleConst rb_size; + luci::CircleResizeBilinear rb; + + input.shape({1, 4, 4, 3}); + input.shape_status(luci::ShapeStatus::VALID); + + rb_size.dtype(loco::DataType::S32); + rb_size.rank(1); + rb_size.dim(0).set(2); + rb_size.size<loco::DataType::S32>(2); + rb_size.at<loco::DataType::S32>(0) = 16; + rb_size.at<loco::DataType::S32>(1) = 16; + rb_size.shape_status(luci::ShapeStatus::VALID); + + rb.input(&input); + rb.size(&rb_size); + + loco::TensorShape shape; + luci::sinf::Rule shape_inf_rule; + + ASSERT_TRUE(shape_inf_rule.infer(&rb, shape)); + ASSERT_EQ(4, shape.rank()); + ASSERT_EQ(1, shape.dim(0).value()); + ASSERT_EQ(16, shape.dim(1).value()); + ASSERT_EQ(16, shape.dim(2).value()); + ASSERT_EQ(3, shape.dim(3).value()); +} + +TEST(CloneNodeTest, clone_ResizeBilinear) +{ + auto g = loco::make_graph(); + auto node_rb = g->nodes()->create<luci::CircleResizeBilinear>(); + node_rb->align_corners(true); + node_rb->half_pixel_centers(true); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_rb, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_rb = dynamic_cast<luci::CircleResizeBilinear *>(cloned); + ASSERT_NE(nullptr, cloned_rb); + ASSERT_EQ(node_rb->align_corners(), cloned_rb->align_corners()); + ASSERT_EQ(node_rb->half_pixel_centers(), cloned_rb->half_pixel_centers()); +} diff --git a/compiler/luci/service/src/Nodes/CircleResizeNearestNeighbor.cpp b/compiler/luci/service/src/Nodes/CircleResizeNearestNeighbor.cpp new file mode 100644 index 000000000..5727786a7 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleResizeNearestNeighbor.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleResizeNearestNeighbor *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleResizeNearestNeighbor>(); + if (cloned != nullptr) + cloned->align_corners(node->align_corners()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleResizeNearestNeighbor.test.cpp b/compiler/luci/service/src/Nodes/CircleResizeNearestNeighbor.test.cpp new file mode 100644 index 000000000..a1d781c65 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleResizeNearestNeighbor.test.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <luci/IR/CircleNodes.h> +#include <luci/Service/CircleShapeInference.h> + +#include <loco/IR/TensorShape.h> + +#include <gtest/gtest.h> + +TEST(ShapeRuleTest, resize_nearest_neighbor_simple) +{ + luci::CircleInput input; + luci::CircleConst rnn_size; + luci::CircleResizeNearestNeighbor rnn; + + input.shape({1, 4, 4, 3}); + input.shape_status(luci::ShapeStatus::VALID); + + rnn_size.dtype(loco::DataType::S32); + rnn_size.rank(1); + rnn_size.dim(0).set(2); + rnn_size.size<loco::DataType::S32>(2); + rnn_size.at<loco::DataType::S32>(0) = 16; + rnn_size.at<loco::DataType::S32>(1) = 16; + rnn_size.shape_status(luci::ShapeStatus::VALID); + + rnn.input(&input); + rnn.size(&rnn_size); + + loco::TensorShape shape; + luci::sinf::Rule shape_inf_rule; + + ASSERT_TRUE(shape_inf_rule.infer(&rnn, shape)); + ASSERT_EQ(4, shape.rank()); + ASSERT_EQ(1, shape.dim(0).value()); + ASSERT_EQ(16, shape.dim(1).value()); + ASSERT_EQ(16, shape.dim(2).value()); + ASSERT_EQ(3, shape.dim(3).value()); +} + +TEST(CloneNodeTest, clone_ResizeNearestNeighbor) +{ + auto g = loco::make_graph(); + auto node_rnn = g->nodes()->create<luci::CircleResizeNearestNeighbor>(); + node_rnn->align_corners(true); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_rnn, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_rnn = dynamic_cast<luci::CircleResizeNearestNeighbor *>(cloned); + ASSERT_NE(nullptr, cloned_rnn); + ASSERT_EQ(node_rnn->align_corners(), cloned_rnn->align_corners()); +} diff --git a/compiler/luci/service/src/Nodes/CircleReverseSequence.cpp b/compiler/luci/service/src/Nodes/CircleReverseSequence.cpp new file mode 100644 index 000000000..6e6919b0c --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleReverseSequence.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleReverseSequence *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleReverseSequence>(); + if (cloned != nullptr) + { + cloned->seq_axis(node->seq_axis()); + cloned->batch_axis(node->batch_axis()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleReverseSequence.test.cpp b/compiler/luci/service/src/Nodes/CircleReverseSequence.test.cpp new file mode 100644 index 000000000..a7a8e3949 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleReverseSequence.test.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_ReverseSequence) +{ + auto g = loco::make_graph(); + auto node_rs = g->nodes()->create<luci::CircleReverseSequence>(); + node_rs->seq_axis(1); + node_rs->batch_axis(2); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_rs, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_rs = dynamic_cast<luci::CircleReverseSequence *>(cloned); + ASSERT_NE(nullptr, cloned_rs); + ASSERT_EQ(node_rs->seq_axis(), cloned_rs->seq_axis()); + ASSERT_EQ(node_rs->batch_axis(), cloned_rs->batch_axis()); +} diff --git a/compiler/luci/service/src/Nodes/CircleReverseV2.cpp b/compiler/luci/service/src/Nodes/CircleReverseV2.cpp new file mode 100644 index 000000000..e8fee6c3e --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleReverseV2.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleReverseV2 *) +{ + return _graph->nodes()->create<luci::CircleReverseV2>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleReverseV2.test.cpp b/compiler/luci/service/src/Nodes/CircleReverseV2.test.cpp new file mode 100644 index 000000000..0e5ff933c --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleReverseV2.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_ReverseV2) +{ + auto g = loco::make_graph(); + auto node_rev = g->nodes()->create<luci::CircleReverseV2>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_rev, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_rev = dynamic_cast<luci::CircleReverseV2 *>(cloned); + ASSERT_NE(nullptr, cloned_rev); +} diff --git a/compiler/luci/service/src/Nodes/CircleRound.cpp b/compiler/luci/service/src/Nodes/CircleRound.cpp new file mode 100644 index 000000000..2c23f2df6 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleRound.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleRound *) +{ + return _graph->nodes()->create<luci::CircleRound>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleRound.test.cpp b/compiler/luci/service/src/Nodes/CircleRound.test.cpp new file mode 100644 index 000000000..2c2c3a9d0 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleRound.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Round) +{ + auto g = loco::make_graph(); + auto node_rnd = g->nodes()->create<luci::CircleRound>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_rnd, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_rnd = dynamic_cast<luci::CircleRound *>(cloned); + ASSERT_NE(nullptr, cloned_rnd); +} diff --git a/compiler/luci/service/src/Nodes/CircleRsqrt.cpp b/compiler/luci/service/src/Nodes/CircleRsqrt.cpp new file mode 100644 index 000000000..aca702fe1 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleRsqrt.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleRsqrt *) +{ + return _graph->nodes()->create<luci::CircleRsqrt>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleRsqrt.test.cpp b/compiler/luci/service/src/Nodes/CircleRsqrt.test.cpp new file mode 100644 index 000000000..3e4ced562 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleRsqrt.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Rsqrt) +{ + auto g = loco::make_graph(); + auto node_rsqrt = g->nodes()->create<luci::CircleRsqrt>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_rsqrt, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_rsqrt = dynamic_cast<luci::CircleRsqrt *>(cloned); + ASSERT_NE(nullptr, cloned_rsqrt); +} diff --git a/compiler/luci/service/src/Nodes/CircleScatterNd.cpp b/compiler/luci/service/src/Nodes/CircleScatterNd.cpp new file mode 100644 index 000000000..6c477a598 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleScatterNd.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleScatterNd *) +{ + return _graph->nodes()->create<luci::CircleScatterNd>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleScatterNd.test.cpp b/compiler/luci/service/src/Nodes/CircleScatterNd.test.cpp new file mode 100644 index 000000000..ce63603cc --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleScatterNd.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_ScatterNd) +{ + auto g = loco::make_graph(); + auto node_snd = g->nodes()->create<luci::CircleScatterNd>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_snd, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_snd = dynamic_cast<luci::CircleScatterNd *>(cloned); + ASSERT_NE(nullptr, cloned_snd); +} diff --git a/compiler/luci/service/src/Nodes/CircleSegmentSum.cpp b/compiler/luci/service/src/Nodes/CircleSegmentSum.cpp new file mode 100644 index 000000000..aa4001f57 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSegmentSum.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSegmentSum *) +{ + return _graph->nodes()->create<luci::CircleSegmentSum>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSegmentSum.test.cpp b/compiler/luci/service/src/Nodes/CircleSegmentSum.test.cpp new file mode 100644 index 000000000..ff17b0745 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSegmentSum.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_SegmentSum) +{ + auto g = loco::make_graph(); + auto node_ss = g->nodes()->create<luci::CircleSegmentSum>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_ss, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_ss = dynamic_cast<luci::CircleSegmentSum *>(cloned); + ASSERT_NE(nullptr, cloned_ss); +} diff --git a/compiler/luci/service/src/Nodes/CircleSelect.cpp b/compiler/luci/service/src/Nodes/CircleSelect.cpp new file mode 100644 index 000000000..71b31d33f --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSelect.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSelect *) +{ + return _graph->nodes()->create<luci::CircleSelect>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSelect.test.cpp b/compiler/luci/service/src/Nodes/CircleSelect.test.cpp new file mode 100644 index 000000000..e8d631618 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSelect.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Select) +{ + auto g = loco::make_graph(); + auto node_sel = g->nodes()->create<luci::CircleSelect>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_sel, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_sel = dynamic_cast<luci::CircleSelect *>(cloned); + ASSERT_NE(nullptr, cloned_sel); +} diff --git a/compiler/luci/service/src/Nodes/CircleSelectV2.cpp b/compiler/luci/service/src/Nodes/CircleSelectV2.cpp new file mode 100644 index 000000000..07af40c40 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSelectV2.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSelectV2 *) +{ + return _graph->nodes()->create<luci::CircleSelectV2>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSelectV2.test.cpp b/compiler/luci/service/src/Nodes/CircleSelectV2.test.cpp new file mode 100644 index 000000000..253dba555 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSelectV2.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_SelectV2) +{ + auto g = loco::make_graph(); + auto node_sel = g->nodes()->create<luci::CircleSelectV2>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_sel, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_sel = dynamic_cast<luci::CircleSelectV2 *>(cloned); + ASSERT_NE(nullptr, cloned_sel); +} diff --git a/compiler/luci/service/src/Nodes/CircleShape.cpp b/compiler/luci/service/src/Nodes/CircleShape.cpp new file mode 100644 index 000000000..e5b5fa28f --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleShape.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleShape *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleShape>(); + if (cloned != nullptr) + cloned->out_type(node->out_type()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleShape.test.cpp b/compiler/luci/service/src/Nodes/CircleShape.test.cpp new file mode 100644 index 000000000..ec057bd05 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleShape.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Shape) +{ + auto g = loco::make_graph(); + auto node_shape = g->nodes()->create<luci::CircleShape>(); + node_shape->out_type(loco::DataType::S32); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_shape, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_shape = dynamic_cast<luci::CircleShape *>(cloned); + ASSERT_NE(nullptr, cloned_shape); + ASSERT_EQ(node_shape->out_type(), cloned_shape->out_type()); +} diff --git a/compiler/luci/service/src/Nodes/CircleSin.cpp b/compiler/luci/service/src/Nodes/CircleSin.cpp new file mode 100644 index 000000000..46a07d21d --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSin.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSin *) +{ + return _graph->nodes()->create<luci::CircleSin>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSin.test.cpp b/compiler/luci/service/src/Nodes/CircleSin.test.cpp new file mode 100644 index 000000000..b072e7e2c --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSin.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Sin) +{ + auto g = loco::make_graph(); + auto node_sin = g->nodes()->create<luci::CircleSin>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_sin, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_sin = dynamic_cast<luci::CircleSin *>(cloned); + ASSERT_NE(nullptr, cloned_sin); +} diff --git a/compiler/luci/service/src/Nodes/CircleSlice.cpp b/compiler/luci/service/src/Nodes/CircleSlice.cpp new file mode 100644 index 000000000..6b2f4a591 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSlice.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSlice *) +{ + return _graph->nodes()->create<luci::CircleSlice>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSlice.test.cpp b/compiler/luci/service/src/Nodes/CircleSlice.test.cpp new file mode 100644 index 000000000..48ec20304 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSlice.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Slice) +{ + auto g = loco::make_graph(); + auto node_slice = g->nodes()->create<luci::CircleSlice>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_slice, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_slice = dynamic_cast<luci::CircleSlice *>(cloned); + ASSERT_NE(nullptr, cloned_slice); +} diff --git a/compiler/luci/service/src/Nodes/CircleSoftmax.cpp b/compiler/luci/service/src/Nodes/CircleSoftmax.cpp new file mode 100644 index 000000000..359d1000c --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSoftmax.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSoftmax *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleSoftmax>(); + if (cloned != nullptr) + cloned->beta(node->beta()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSoftmax.test.cpp b/compiler/luci/service/src/Nodes/CircleSoftmax.test.cpp new file mode 100644 index 000000000..c80b44d69 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSoftmax.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Softmax) +{ + auto g = loco::make_graph(); + auto node_sm = g->nodes()->create<luci::CircleSoftmax>(); + node_sm->beta(2.3f); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_sm, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_sm = dynamic_cast<luci::CircleSoftmax *>(cloned); + ASSERT_NE(nullptr, cloned_sm); + ASSERT_EQ(node_sm->beta(), cloned_sm->beta()); +} diff --git a/compiler/luci/service/src/Nodes/CircleSpaceToBatchND.cpp b/compiler/luci/service/src/Nodes/CircleSpaceToBatchND.cpp new file mode 100644 index 000000000..feb4f3e37 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSpaceToBatchND.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSpaceToBatchND *) +{ + return _graph->nodes()->create<luci::CircleSpaceToBatchND>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSpaceToBatchND.test.cpp b/compiler/luci/service/src/Nodes/CircleSpaceToBatchND.test.cpp new file mode 100644 index 000000000..eb743795d --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSpaceToBatchND.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_SpaceToBatchND) +{ + auto g = loco::make_graph(); + auto node_s2bnd = g->nodes()->create<luci::CircleSpaceToBatchND>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_s2bnd, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_s2bnd = dynamic_cast<luci::CircleSpaceToBatchND *>(cloned); + ASSERT_NE(nullptr, cloned_s2bnd); +} diff --git a/compiler/luci/service/src/Nodes/CircleSpaceToDepth.cpp b/compiler/luci/service/src/Nodes/CircleSpaceToDepth.cpp new file mode 100644 index 000000000..3a82f5c7a --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSpaceToDepth.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSpaceToDepth *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleSpaceToDepth>(); + if (cloned != nullptr) + cloned->block_size(node->block_size()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSpaceToDepth.test.cpp b/compiler/luci/service/src/Nodes/CircleSpaceToDepth.test.cpp new file mode 100644 index 000000000..fb544e6d7 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSpaceToDepth.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_SpaceToDepth) +{ + auto g = loco::make_graph(); + auto node_s2d = g->nodes()->create<luci::CircleSpaceToDepth>(); + node_s2d->block_size(32); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_s2d, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_s2d = dynamic_cast<luci::CircleSpaceToDepth *>(cloned); + ASSERT_NE(nullptr, cloned_s2d); + ASSERT_EQ(node_s2d->block_size(), cloned_s2d->block_size()); +} diff --git a/compiler/luci/service/src/Nodes/CircleSparseToDense.cpp b/compiler/luci/service/src/Nodes/CircleSparseToDense.cpp new file mode 100644 index 000000000..3dba1a542 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSparseToDense.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSparseToDense *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleSparseToDense>(); + if (cloned != nullptr) + cloned->validate_indices(node->validate_indices()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSparseToDense.test.cpp b/compiler/luci/service/src/Nodes/CircleSparseToDense.test.cpp new file mode 100644 index 000000000..177a469cd --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSparseToDense.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_SparseToDense) +{ + auto g = loco::make_graph(); + auto node_s2d = g->nodes()->create<luci::CircleSparseToDense>(); + node_s2d->validate_indices(true); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_s2d, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_s2d = dynamic_cast<luci::CircleSparseToDense *>(cloned); + ASSERT_NE(nullptr, cloned_s2d); + ASSERT_EQ(node_s2d->validate_indices(), cloned_s2d->validate_indices()); +} diff --git a/compiler/luci/service/src/Nodes/CircleSplit.cpp b/compiler/luci/service/src/Nodes/CircleSplit.cpp new file mode 100644 index 000000000..e68a24a1f --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSplit.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSplit *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleSplit>(); + if (cloned != nullptr) + cloned->num_split(node->num_split()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSplit.test.cpp b/compiler/luci/service/src/Nodes/CircleSplit.test.cpp new file mode 100644 index 000000000..9ee26b425 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSplit.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Split) +{ + auto g = loco::make_graph(); + auto node_split = g->nodes()->create<luci::CircleSplit>(); + node_split->num_split(5); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_split, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_split = dynamic_cast<luci::CircleSplit *>(cloned); + ASSERT_NE(nullptr, cloned_split); + ASSERT_EQ(node_split->num_split(), cloned_split->num_split()); +} diff --git a/compiler/luci/service/src/Nodes/CircleSplitOut.cpp b/compiler/luci/service/src/Nodes/CircleSplitOut.cpp new file mode 100644 index 000000000..024598892 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSplitOut.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSplitOut *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleSplitOut>(); + if (cloned != nullptr) + cloned->index(node->index()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSplitOut.test.cpp b/compiler/luci/service/src/Nodes/CircleSplitOut.test.cpp new file mode 100644 index 000000000..deec08804 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSplitOut.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_SplitOut) +{ + auto g = loco::make_graph(); + auto node_sout = g->nodes()->create<luci::CircleSplitOut>(); + node_sout->index(1); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_sout, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_sout = dynamic_cast<luci::CircleSplitOut *>(cloned); + ASSERT_NE(nullptr, cloned_sout); + ASSERT_EQ(node_sout->index(), cloned_sout->index()); +} diff --git a/compiler/luci/service/src/Nodes/CircleSplitV.cpp b/compiler/luci/service/src/Nodes/CircleSplitV.cpp new file mode 100644 index 000000000..de6c6cce6 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSplitV.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSplitV *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleSplitV>(); + if (cloned != nullptr) + cloned->num_split(node->num_split()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSplitV.test.cpp b/compiler/luci/service/src/Nodes/CircleSplitV.test.cpp new file mode 100644 index 000000000..d109a64aa --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSplitV.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_SplitV) +{ + auto g = loco::make_graph(); + auto node_split = g->nodes()->create<luci::CircleSplitV>(); + node_split->num_split(5); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_split, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_split = dynamic_cast<luci::CircleSplitV *>(cloned); + ASSERT_NE(nullptr, cloned_split); + ASSERT_EQ(node_split->num_split(), cloned_split->num_split()); +} diff --git a/compiler/luci/service/src/Nodes/CircleSplitVOut.cpp b/compiler/luci/service/src/Nodes/CircleSplitVOut.cpp new file mode 100644 index 000000000..f40eb0a47 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSplitVOut.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSplitVOut *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleSplitVOut>(); + if (cloned != nullptr) + cloned->index(node->index()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSplitVOut.test.cpp b/compiler/luci/service/src/Nodes/CircleSplitVOut.test.cpp new file mode 100644 index 000000000..ab5e9d6be --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSplitVOut.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_SplitVOut) +{ + auto g = loco::make_graph(); + auto node_sout = g->nodes()->create<luci::CircleSplitVOut>(); + node_sout->index(1); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_sout, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_sout = dynamic_cast<luci::CircleSplitVOut *>(cloned); + ASSERT_NE(nullptr, cloned_sout); + ASSERT_EQ(node_sout->index(), cloned_sout->index()); +} diff --git a/compiler/luci/service/src/Nodes/CircleSqrt.cpp b/compiler/luci/service/src/Nodes/CircleSqrt.cpp new file mode 100644 index 000000000..a3e63684b --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSqrt.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSqrt *) +{ + return _graph->nodes()->create<luci::CircleSqrt>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSqrt.test.cpp b/compiler/luci/service/src/Nodes/CircleSqrt.test.cpp new file mode 100644 index 000000000..dbef839d6 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSqrt.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Sqrt) +{ + auto g = loco::make_graph(); + auto node_sqrt = g->nodes()->create<luci::CircleSqrt>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_sqrt, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_sqrt = dynamic_cast<luci::CircleSqrt *>(cloned); + ASSERT_NE(nullptr, cloned_sqrt); +} diff --git a/compiler/luci/service/src/Nodes/CircleSquare.cpp b/compiler/luci/service/src/Nodes/CircleSquare.cpp new file mode 100644 index 000000000..88bbed76c --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSquare.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSquare *) +{ + return _graph->nodes()->create<luci::CircleSquare>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSquare.test.cpp b/compiler/luci/service/src/Nodes/CircleSquare.test.cpp new file mode 100644 index 000000000..67ac21210 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSquare.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Square) +{ + auto g = loco::make_graph(); + auto node_squ = g->nodes()->create<luci::CircleSquare>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_squ, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_squ = dynamic_cast<luci::CircleSquare *>(cloned); + ASSERT_NE(nullptr, cloned_squ); +} diff --git a/compiler/luci/service/src/Nodes/CircleSquaredDifference.cpp b/compiler/luci/service/src/Nodes/CircleSquaredDifference.cpp new file mode 100644 index 000000000..6becdf1c9 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSquaredDifference.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSquaredDifference *) +{ + return _graph->nodes()->create<luci::CircleSquaredDifference>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSquaredDifference.test.cpp b/compiler/luci/service/src/Nodes/CircleSquaredDifference.test.cpp new file mode 100644 index 000000000..26099612b --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSquaredDifference.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_SquaredDifference) +{ + auto g = loco::make_graph(); + auto node_sd = g->nodes()->create<luci::CircleSquaredDifference>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_sd, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_sd = dynamic_cast<luci::CircleSquaredDifference *>(cloned); + ASSERT_NE(nullptr, cloned_sd); +} diff --git a/compiler/luci/service/src/Nodes/CircleSqueeze.cpp b/compiler/luci/service/src/Nodes/CircleSqueeze.cpp new file mode 100644 index 000000000..02ba5020c --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSqueeze.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSqueeze *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleSqueeze>(); + if (cloned != nullptr) + cloned->squeeze_dims(node->squeeze_dims()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSqueeze.test.cpp b/compiler/luci/service/src/Nodes/CircleSqueeze.test.cpp new file mode 100644 index 000000000..bc73eafa7 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSqueeze.test.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <luci/IR/CircleNodes.h> +#include <luci/Service/CircleShapeInference.h> + +#include <loco/IR/TensorShape.h> + +#include <gtest/gtest.h> + +TEST(ShapeRuleTest, squeeze_simple) +{ + luci::CircleInput input; + luci::CircleSqueeze squeeze; + + input.shape({1, 4, 3, 1}); + input.shape_status(luci::ShapeStatus::VALID); + + squeeze.input(&input); + squeeze.squeeze_dims({0}); + + loco::TensorShape shape; + luci::sinf::Rule shape_inf_rule; + + ASSERT_TRUE(shape_inf_rule.infer(&squeeze, shape)); + ASSERT_EQ(3, shape.rank()); + ASSERT_EQ(4, shape.dim(0).value()); + ASSERT_EQ(3, shape.dim(1).value()); + ASSERT_EQ(1, shape.dim(2).value()); +} + +TEST(ShapeRuleTest, squeeze_all) +{ + luci::CircleInput input; + luci::CircleSqueeze squeeze; + + input.shape({1, 4, 3, 1}); + input.shape_status(luci::ShapeStatus::VALID); + + squeeze.input(&input); + squeeze.squeeze_dims({}); + + loco::TensorShape shape; + luci::sinf::Rule shape_inf_rule; + + ASSERT_TRUE(shape_inf_rule.infer(&squeeze, shape)); + ASSERT_EQ(2, shape.rank()); + ASSERT_EQ(4, shape.dim(0).value()); + ASSERT_EQ(3, shape.dim(1).value()); +} + +TEST(CloneNodeTest, clone_Squeeze) +{ + auto g = loco::make_graph(); + auto node_squ = g->nodes()->create<luci::CircleSqueeze>(); + node_squ->squeeze_dims({2, 3}); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_squ, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_squ = dynamic_cast<luci::CircleSqueeze *>(cloned); + ASSERT_NE(nullptr, cloned_squ); + ASSERT_EQ(node_squ->squeeze_dims().size(), cloned_squ->squeeze_dims().size()); + for (size_t s = 0; s < node_squ->squeeze_dims().size(); ++s) + ASSERT_EQ(node_squ->squeeze_dims().at(s), cloned_squ->squeeze_dims().at(s)); +} diff --git a/compiler/luci/service/src/Nodes/CircleStridedSlice.cpp b/compiler/luci/service/src/Nodes/CircleStridedSlice.cpp new file mode 100644 index 000000000..c4d199316 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleStridedSlice.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleStridedSlice *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleStridedSlice>(); + if (cloned != nullptr) + { + cloned->begin_mask(node->begin_mask()); + cloned->end_mask(node->end_mask()); + cloned->ellipsis_mask(node->ellipsis_mask()); + cloned->new_axis_mask(node->new_axis_mask()); + cloned->shrink_axis_mask(node->shrink_axis_mask()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleStridedSlice.test.cpp b/compiler/luci/service/src/Nodes/CircleStridedSlice.test.cpp new file mode 100644 index 000000000..d633f3022 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleStridedSlice.test.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_StridedSlice) +{ + auto g = loco::make_graph(); + auto node_ss = g->nodes()->create<luci::CircleStridedSlice>(); + node_ss->begin_mask(1); + node_ss->end_mask(2); + node_ss->ellipsis_mask(3); + node_ss->new_axis_mask(4); + node_ss->shrink_axis_mask(5); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_ss, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_ss = dynamic_cast<luci::CircleStridedSlice *>(cloned); + ASSERT_NE(nullptr, cloned_ss); + ASSERT_EQ(node_ss->begin_mask(), cloned_ss->begin_mask()); + ASSERT_EQ(node_ss->end_mask(), cloned_ss->end_mask()); + ASSERT_EQ(node_ss->ellipsis_mask(), cloned_ss->ellipsis_mask()); + ASSERT_EQ(node_ss->new_axis_mask(), cloned_ss->new_axis_mask()); + ASSERT_EQ(node_ss->shrink_axis_mask(), cloned_ss->shrink_axis_mask()); +} diff --git a/compiler/luci/service/src/Nodes/CircleSub.cpp b/compiler/luci/service/src/Nodes/CircleSub.cpp new file mode 100644 index 000000000..fb4bab19a --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSub.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleSub *node) +{ + if (node->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleSub>(); + if (cloned != nullptr) + cloned->fusedActivationFunction(node->fusedActivationFunction()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSub.test.cpp b/compiler/luci/service/src/Nodes/CircleSub.test.cpp new file mode 100644 index 000000000..e6bd7b8ff --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSub.test.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Sub) +{ + auto g = loco::make_graph(); + auto node_sub = g->nodes()->create<luci::CircleSub>(); + node_sub->fusedActivationFunction(luci::FusedActFunc::RELU); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_sub, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_sub = dynamic_cast<luci::CircleSub *>(cloned); + ASSERT_NE(nullptr, cloned_sub); + ASSERT_EQ(node_sub->fusedActivationFunction(), cloned_sub->fusedActivationFunction()); +} + +TEST(CloneNodeTest, clone_Sub_NEG) +{ + auto g = loco::make_graph(); + auto node_sub = g->nodes()->create<luci::CircleSub>(); + node_sub->fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_sub, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleSum.cpp b/compiler/luci/service/src/Nodes/CircleSum.cpp index 9ef90e8e0..29e6ee5f1 100644 --- a/compiler/luci/service/src/Nodes/CircleSum.cpp +++ b/compiler/luci/service/src/Nodes/CircleSum.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2021 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 + * 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, @@ -14,15 +14,17 @@ * limitations under the License. */ -#include <luci/Service/CircleShapeSignatureInference.h> +#include "CircleCloneNode.h" namespace luci { -ShapeSignature ssinf::Algorithm::visit(const luci::CircleSum *node) +luci::CircleNode *CloneNode::visit(const luci::CircleSum *node) { - return legalized_signature( - reduced_signature(node->input(), node->reduction_indices(), node->keep_dims())); + auto *cloned = _graph->nodes()->create<luci::CircleSum>(); + if (cloned != nullptr) + cloned->keep_dims(node->keep_dims()); + return cloned; } } // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleSum.test.cpp b/compiler/luci/service/src/Nodes/CircleSum.test.cpp new file mode 100644 index 000000000..aa1b0d128 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleSum.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Sum) +{ + auto g = loco::make_graph(); + auto node_sum = g->nodes()->create<luci::CircleSum>(); + node_sum->keep_dims(true); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_sum, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_sum = dynamic_cast<luci::CircleSum *>(cloned); + ASSERT_NE(nullptr, cloned_sum); + ASSERT_EQ(node_sum->keep_dims(), cloned_sum->keep_dims()); +} diff --git a/compiler/luci/service/src/Nodes/CircleTanh.cpp b/compiler/luci/service/src/Nodes/CircleTanh.cpp new file mode 100644 index 000000000..9cb35932f --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleTanh.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleTanh *) +{ + return _graph->nodes()->create<luci::CircleTanh>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleTanh.test.cpp b/compiler/luci/service/src/Nodes/CircleTanh.test.cpp new file mode 100644 index 000000000..0215b42ca --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleTanh.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Tanh) +{ + auto g = loco::make_graph(); + auto node_tanh = g->nodes()->create<luci::CircleTanh>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_tanh, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_tanh = dynamic_cast<luci::CircleTanh *>(cloned); + ASSERT_NE(nullptr, cloned_tanh); +} diff --git a/compiler/luci/service/src/Nodes/CircleTile.cpp b/compiler/luci/service/src/Nodes/CircleTile.cpp new file mode 100644 index 000000000..21c32e021 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleTile.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleTile *) +{ + return _graph->nodes()->create<luci::CircleTile>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleTile.test.cpp b/compiler/luci/service/src/Nodes/CircleTile.test.cpp new file mode 100644 index 000000000..089c86ccb --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleTile.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Tile) +{ + auto g = loco::make_graph(); + auto node_tile = g->nodes()->create<luci::CircleTile>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_tile, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_tile = dynamic_cast<luci::CircleTile *>(cloned); + ASSERT_NE(nullptr, cloned_tile); +} diff --git a/compiler/luci/service/src/Nodes/CircleTopKV2.cpp b/compiler/luci/service/src/Nodes/CircleTopKV2.cpp new file mode 100644 index 000000000..e940c03dd --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleTopKV2.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleTopKV2 *) +{ + return _graph->nodes()->create<luci::CircleTopKV2>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleTopKV2.test.cpp b/compiler/luci/service/src/Nodes/CircleTopKV2.test.cpp new file mode 100644 index 000000000..7f68a408d --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleTopKV2.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_TopKV2) +{ + auto g = loco::make_graph(); + auto node_top = g->nodes()->create<luci::CircleTopKV2>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_top, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_top = dynamic_cast<luci::CircleTopKV2 *>(cloned); + ASSERT_NE(nullptr, cloned_top); +} diff --git a/compiler/luci/service/src/Nodes/CircleTopKV2Out.cpp b/compiler/luci/service/src/Nodes/CircleTopKV2Out.cpp new file mode 100644 index 000000000..5c13f2be1 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleTopKV2Out.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleTopKV2Out *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleTopKV2Out>(); + if (cloned != nullptr) + cloned->index(node->index()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleTopKV2Out.test.cpp b/compiler/luci/service/src/Nodes/CircleTopKV2Out.test.cpp new file mode 100644 index 000000000..cfba61f10 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleTopKV2Out.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_TopKV2Out) +{ + auto g = loco::make_graph(); + auto node_tout = g->nodes()->create<luci::CircleTopKV2Out>(); + node_tout->index(1); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_tout, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_tout = dynamic_cast<luci::CircleTopKV2Out *>(cloned); + ASSERT_NE(nullptr, cloned_tout); + ASSERT_EQ(node_tout->index(), cloned_tout->index()); +} diff --git a/compiler/luci/service/src/Nodes/CircleTranspose.cpp b/compiler/luci/service/src/Nodes/CircleTranspose.cpp new file mode 100644 index 000000000..81db55269 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleTranspose.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleTranspose *) +{ + return _graph->nodes()->create<luci::CircleTranspose>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleTranspose.test.cpp b/compiler/luci/service/src/Nodes/CircleTranspose.test.cpp new file mode 100644 index 000000000..9447d1a5b --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleTranspose.test.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <luci/IR/CircleNodes.h> +#include <luci/Service/CircleShapeInference.h> + +#include <loco/IR/TensorShape.h> + +#include <gtest/gtest.h> + +TEST(ShapeRuleTest, transpose_simple) +{ + luci::CircleInput input; + luci::CircleConst perm; + luci::CircleTranspose transpose; + + input.shape({3, 8, 1}); + input.shape_status(luci::ShapeStatus::VALID); + + perm.dtype(loco::DataType::S32); + perm.rank(1); + perm.dim(0).set(3); + perm.size<loco::DataType::S32>(3); + perm.at<loco::DataType::S32>(0) = 1; + perm.at<loco::DataType::S32>(1) = 2; + perm.at<loco::DataType::S32>(2) = 0; + perm.shape_status(luci::ShapeStatus::VALID); + + transpose.a(&input); + transpose.perm(&perm); + + loco::TensorShape shape; + luci::sinf::Rule shape_inf_rule; + + ASSERT_TRUE(shape_inf_rule.infer(&transpose, shape)); + ASSERT_EQ(3, shape.rank()); + ASSERT_EQ(8, shape.dim(0).value()); + ASSERT_EQ(1, shape.dim(1).value()); + ASSERT_EQ(3, shape.dim(2).value()); +} + +TEST(CloneNodeTest, clone_Transpose) +{ + auto g = loco::make_graph(); + auto node_tr = g->nodes()->create<luci::CircleTranspose>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_tr, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_tr = dynamic_cast<luci::CircleTranspose *>(cloned); + ASSERT_NE(nullptr, cloned_tr); +} diff --git a/compiler/luci/service/src/Nodes/CircleTransposeConv.cpp b/compiler/luci/service/src/Nodes/CircleTransposeConv.cpp new file mode 100644 index 000000000..1fe41bdb2 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleTransposeConv.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleTransposeConv *node) +{ + if (node->padding() == luci::Padding::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleTransposeConv>(); + if (cloned != nullptr) + { + cloned->padding(node->padding()); + cloned->stride()->h(node->stride()->h()); + cloned->stride()->w(node->stride()->w()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleTransposeConv.test.cpp b/compiler/luci/service/src/Nodes/CircleTransposeConv.test.cpp new file mode 100644 index 000000000..29a656c03 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleTransposeConv.test.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_TransposeConv) +{ + auto g = loco::make_graph(); + auto node_trconv = g->nodes()->create<luci::CircleTransposeConv>(); + node_trconv->padding(luci::Padding::SAME); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_trconv, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_trconv = dynamic_cast<luci::CircleTransposeConv *>(cloned); + ASSERT_NE(nullptr, cloned_trconv); + ASSERT_EQ(node_trconv->padding(), cloned_trconv->padding()); +} + +TEST(CloneNodeTest, clone_TransposeConv_padding_NEG) +{ + auto g = loco::make_graph(); + auto node_trconv = g->nodes()->create<luci::CircleTransposeConv>(); + node_trconv->padding(luci::Padding::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_trconv, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleUnidirectionalSequenceLSTM.cpp b/compiler/luci/service/src/Nodes/CircleUnidirectionalSequenceLSTM.cpp new file mode 100644 index 000000000..12205f3b0 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleUnidirectionalSequenceLSTM.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleUnidirectionalSequenceLSTM *node) +{ + if (node->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return nullptr; + + auto *cloned = _graph->nodes()->create<luci::CircleUnidirectionalSequenceLSTM>(); + if (cloned != nullptr) + { + cloned->fusedActivationFunction(node->fusedActivationFunction()); + cloned->cell_clip(node->cell_clip()); + cloned->proj_clip(node->proj_clip()); + cloned->time_major(node->time_major()); + cloned->asymmetric_quantize_inputs(node->asymmetric_quantize_inputs()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleUnidirectionalSequenceLSTM.test.cpp b/compiler/luci/service/src/Nodes/CircleUnidirectionalSequenceLSTM.test.cpp new file mode 100644 index 000000000..c3816ab27 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleUnidirectionalSequenceLSTM.test.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_UnidirectionalSequenceLSTM) +{ + auto g = loco::make_graph(); + auto node_uslstm = g->nodes()->create<luci::CircleUnidirectionalSequenceLSTM>(); + node_uslstm->fusedActivationFunction(luci::FusedActFunc::RELU); + node_uslstm->cell_clip(1.1f); + node_uslstm->proj_clip(2.2f); + node_uslstm->time_major(true); + node_uslstm->asymmetric_quantize_inputs(true); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_uslstm, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_uslstm = dynamic_cast<luci::CircleUnidirectionalSequenceLSTM *>(cloned); + ASSERT_NE(nullptr, cloned_uslstm); + ASSERT_EQ(node_uslstm->fusedActivationFunction(), cloned_uslstm->fusedActivationFunction()); + ASSERT_EQ(node_uslstm->cell_clip(), cloned_uslstm->cell_clip()); + ASSERT_EQ(node_uslstm->proj_clip(), cloned_uslstm->proj_clip()); + ASSERT_EQ(node_uslstm->time_major(), cloned_uslstm->time_major()); + ASSERT_EQ(node_uslstm->asymmetric_quantize_inputs(), cloned_uslstm->asymmetric_quantize_inputs()); +} + +TEST(CloneNodeTest, clone_UnidirectionalSequenceLSTM_NEG) +{ + auto g = loco::make_graph(); + auto node_uslstm = g->nodes()->create<luci::CircleUnidirectionalSequenceLSTM>(); + node_uslstm->fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_uslstm, gc.get()); + ASSERT_EQ(nullptr, cloned); +} diff --git a/compiler/luci/service/src/Nodes/CircleUnique.cpp b/compiler/luci/service/src/Nodes/CircleUnique.cpp new file mode 100644 index 000000000..bde2ea0dc --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleUnique.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleUnique *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleUnique>(); + if (cloned != nullptr) + cloned->idx_out_type(node->idx_out_type()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleUnique.test.cpp b/compiler/luci/service/src/Nodes/CircleUnique.test.cpp new file mode 100644 index 000000000..a8ff9eade --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleUnique.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Unique) +{ + auto g = loco::make_graph(); + auto node_uniq = g->nodes()->create<luci::CircleUnique>(); + node_uniq->idx_out_type(loco::DataType::S32); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_uniq, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_uniq = dynamic_cast<luci::CircleUnique *>(cloned); + ASSERT_NE(nullptr, cloned_uniq); + ASSERT_EQ(node_uniq->idx_out_type(), cloned_uniq->idx_out_type()); +} diff --git a/compiler/luci/service/src/Nodes/CircleUniqueOut.cpp b/compiler/luci/service/src/Nodes/CircleUniqueOut.cpp new file mode 100644 index 000000000..30093f9db --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleUniqueOut.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleUniqueOut *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleUniqueOut>(); + if (cloned != nullptr) + cloned->index(node->index()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleUniqueOut.test.cpp b/compiler/luci/service/src/Nodes/CircleUniqueOut.test.cpp new file mode 100644 index 000000000..780ad4b78 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleUniqueOut.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_UniqueOut) +{ + auto g = loco::make_graph(); + auto node_uout = g->nodes()->create<luci::CircleUniqueOut>(); + node_uout->index(1); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_uout, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_uout = dynamic_cast<luci::CircleUniqueOut *>(cloned); + ASSERT_NE(nullptr, cloned_uout); + ASSERT_EQ(node_uout->index(), cloned_uout->index()); +} diff --git a/compiler/luci/service/src/Nodes/CircleUnpack.cpp b/compiler/luci/service/src/Nodes/CircleUnpack.cpp new file mode 100644 index 000000000..f9d61c426 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleUnpack.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleUnpack *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleUnpack>(); + if (cloned != nullptr) + { + cloned->num(node->num()); + cloned->axis(node->axis()); + } + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleUnpack.test.cpp b/compiler/luci/service/src/Nodes/CircleUnpack.test.cpp new file mode 100644 index 000000000..6559a9276 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleUnpack.test.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Unpack) +{ + auto g = loco::make_graph(); + auto node_unp = g->nodes()->create<luci::CircleUnpack>(); + node_unp->num(1); + node_unp->axis(2); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_unp, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_unp = dynamic_cast<luci::CircleUnpack *>(cloned); + ASSERT_NE(nullptr, cloned_unp); + ASSERT_EQ(node_unp->num(), cloned_unp->num()); + ASSERT_EQ(node_unp->axis(), cloned_unp->axis()); +} diff --git a/compiler/luci/service/src/Nodes/CircleUnpackOut.cpp b/compiler/luci/service/src/Nodes/CircleUnpackOut.cpp new file mode 100644 index 000000000..342d5daca --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleUnpackOut.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleUnpackOut *node) +{ + auto *cloned = _graph->nodes()->create<luci::CircleUnpackOut>(); + if (cloned != nullptr) + cloned->index(node->index()); + return cloned; +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleUnpackOut.test.cpp b/compiler/luci/service/src/Nodes/CircleUnpackOut.test.cpp new file mode 100644 index 000000000..ec9bb974e --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleUnpackOut.test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_UnpackOut) +{ + auto g = loco::make_graph(); + auto node_uout = g->nodes()->create<luci::CircleUnpackOut>(); + node_uout->index(1); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_uout, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_uout = dynamic_cast<luci::CircleUnpackOut *>(cloned); + ASSERT_NE(nullptr, cloned_uout); + ASSERT_EQ(node_uout->index(), cloned_uout->index()); +} diff --git a/compiler/luci/service/src/Nodes/CircleWhere.cpp b/compiler/luci/service/src/Nodes/CircleWhere.cpp new file mode 100644 index 000000000..73f4b64ac --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleWhere.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleWhere *) +{ + return _graph->nodes()->create<luci::CircleWhere>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleWhere.test.cpp b/compiler/luci/service/src/Nodes/CircleWhere.test.cpp new file mode 100644 index 000000000..352719d85 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleWhere.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_Where) +{ + auto g = loco::make_graph(); + auto node_wh = g->nodes()->create<luci::CircleWhere>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_wh, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_wh = dynamic_cast<luci::CircleWhere *>(cloned); + ASSERT_NE(nullptr, cloned_wh); +} diff --git a/compiler/luci/service/src/Nodes/CircleZerosLike.cpp b/compiler/luci/service/src/Nodes/CircleZerosLike.cpp new file mode 100644 index 000000000..2ee455857 --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleZerosLike.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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 "CircleCloneNode.h" + +namespace luci +{ + +luci::CircleNode *CloneNode::visit(const luci::CircleZerosLike *) +{ + return _graph->nodes()->create<luci::CircleZerosLike>(); +} + +} // namespace luci diff --git a/compiler/luci/service/src/Nodes/CircleZerosLike.test.cpp b/compiler/luci/service/src/Nodes/CircleZerosLike.test.cpp new file mode 100644 index 000000000..6e0a4b3be --- /dev/null +++ b/compiler/luci/service/src/Nodes/CircleZerosLike.test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "luci/Service/CircleNodeClone.h" + +#include <gtest/gtest.h> + +TEST(CloneNodeTest, clone_ZerosLike) +{ + auto g = loco::make_graph(); + auto node_zl = g->nodes()->create<luci::CircleZerosLike>(); + + auto gc = loco::make_graph(); + auto cloned = luci::clone_node(node_zl, gc.get()); + ASSERT_NE(nullptr, cloned); + ASSERT_EQ(gc.get(), cloned->graph()); + + auto cloned_zl = dynamic_cast<luci::CircleZerosLike *>(cloned); + ASSERT_NE(nullptr, cloned_zl); +} diff --git a/compiler/luci/service/src/ShapeDescription.cpp b/compiler/luci/service/src/ShapeDescription.cpp index 01a638f8f..adfb7e342 100644 --- a/compiler/luci/service/src/ShapeDescription.cpp +++ b/compiler/luci/service/src/ShapeDescription.cpp @@ -31,7 +31,7 @@ ShapeDescription to_shape_description(const luci::CircleNode *circle_node) res._dims.resize(circle_node->rank()); for (uint32_t i = 0; i < circle_node->rank(); ++i) - res._dims.at(i) = circle_node->dim(i).value(); + res._dims.at(i) = circle_node->dim(i).known() ? circle_node->dim(i).value() : -1; return res; } @@ -53,95 +53,12 @@ ShapeDescription to_shape_description(const loco::TensorShape &shape) return res; } -ShapeDescription to_shape_description(const loco::FeatureShape &shape) -{ - ShapeDescription res; - - res._rank_known = true; - - // T/F Lite encodes a feature map as a NHWC tensor - res._dims.resize(4); - res._dims.at(0) = shape.count().value(); - res._dims.at(1) = shape.height().value(); - res._dims.at(2) = shape.width().value(); - res._dims.at(3) = shape.depth().value(); - - return res; -} - -ShapeDescription to_shape_description(const loco::FilterShape &shape) -{ - ShapeDescription res; - - res._rank_known = true; - - // T/F Lite encodes a convolution filter as a NHWC tensor - res._dims.resize(4); - res._dims.at(0) = shape.count().value(); - res._dims.at(1) = shape.height().value(); - res._dims.at(2) = shape.width().value(); - res._dims.at(3) = shape.depth().value(); - - return res; -} - -ShapeDescription to_shape_description(const loco::DepthwiseFilterShape &shape) -{ - ShapeDescription res; - - res._rank_known = true; - - // T/F Lite encodes a depthwise convolution filter as a [1, H, W, C*M] tensor - res._dims.resize(4); - res._dims.at(0) = 1; - res._dims.at(1) = shape.height().value(); - res._dims.at(2) = shape.width().value(); - res._dims.at(3) = shape.depth().value() * shape.multiplier().value(); - - return res; -} - -ShapeDescription to_shape_description(const loco::BiasShape &shape) -{ - ShapeDescription res; - - res._rank_known = true; - - res._dims.resize(1); - res._dims.at(0) = shape.length().value(); - - return res; -} - -ShapeDescription to_shape_description(const loco::MatrixShape &shape) -{ - ShapeDescription res; - - res._rank_known = true; - - res._dims.resize(2); - res._dims.at(0) = shape.height().value(); - res._dims.at(1) = shape.width().value(); - - return res; -} - ShapeDescription to_shape_description(const loco::NodeShape &shape) { switch (shape.domain()) { case loco::Domain::Tensor: return to_shape_description(shape.as<loco::TensorShape>()); - case loco::Domain::Feature: - return to_shape_description(shape.as<loco::FeatureShape>()); - case loco::Domain::Filter: - return to_shape_description(shape.as<loco::FilterShape>()); - case loco::Domain::DepthwiseFilter: - return to_shape_description(shape.as<loco::DepthwiseFilterShape>()); - case loco::Domain::Bias: - return to_shape_description(shape.as<loco::BiasShape>()); - case loco::Domain::Matrix: - return to_shape_description(shape.as<loco::MatrixShape>()); default: break; } diff --git a/compiler/luci/service/src/ShapeDescription.test.cpp b/compiler/luci/service/src/ShapeDescription.test.cpp new file mode 100644 index 000000000..6e53aac75 --- /dev/null +++ b/compiler/luci/service/src/ShapeDescription.test.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 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 "luci/Service/ShapeDescription.h" + +#include <luci/IR/CircleNode.h> +#include <luci/IR/Nodes/CircleConst.h> + +#include <gtest/gtest.h> + +TEST(ShapeDescriptionTest, CircleNode) +{ + // Use CircleConst as CircleNode + luci::CircleConst circle_const; + circle_const.shape({1, 2, 3, 4}); + + auto sd = luci::to_shape_description(&circle_const); + + ASSERT_EQ(4, sd._dims.size()); + ASSERT_EQ(1, sd._dims.at(0)); + ASSERT_TRUE(sd._rank_known); +} + +TEST(ShapeDescriptionTest, TensorShape) +{ + loco::TensorShape tensor_shape{1, 2, 3, 4}; + loco::NodeShape node_shape(tensor_shape); + + auto sd = luci::to_shape_description(node_shape); + + ASSERT_EQ(4, sd._dims.size()); + ASSERT_EQ(1, sd._dims.at(0)); + ASSERT_TRUE(sd._rank_known); +} + +TEST(ShapeDescriptionTest, BiasShape_NEG) +{ + loco::BiasShape bias_shape; + bias_shape.length() = 1; + loco::NodeShape node_shape(bias_shape); + + EXPECT_THROW(luci::to_shape_description(node_shape), std::exception); +} diff --git a/compiler/luci/service/src/ShapeInfer_StridedSlice.cpp b/compiler/luci/service/src/ShapeInfer_StridedSlice.cpp index 341201148..c5864f938 100644 --- a/compiler/luci/service/src/ShapeInfer_StridedSlice.cpp +++ b/compiler/luci/service/src/ShapeInfer_StridedSlice.cpp @@ -17,12 +17,12 @@ #include "ShapeInfer_StridedSlice.h" #include "Check.h" +#include "CircleShapeInferenceHelper.h" #include <luci/IR/CircleNode.h> #include <loco/IR/DataType.h> #include <loco/IR/NodeShape.h> #include <oops/InternalExn.h> -#include <loco/Service/ShapeInference.h> #include <cmath> #include <cstdint> @@ -245,7 +245,7 @@ loco::TensorShape infer_output_shape(const CircleStridedSlice *node) assert(node->new_axis_mask() == 0); auto op_params = BuildStridedSliceParams(node); - loco::TensorShape input_shape = loco::shape_get(input_node).as<loco::TensorShape>(); + loco::TensorShape input_shape = luci::shape_get(input_node).as<loco::TensorShape>(); uint32_t num_input_axes = input_shape.rank(); assert(begin_node->size<S32>() <= num_input_axes); diff --git a/compiler/luci/service/src/Validate.cpp b/compiler/luci/service/src/Validate.cpp index 3f732b6fe..7ed14c356 100644 --- a/compiler/luci/service/src/Validate.cpp +++ b/compiler/luci/service/src/Validate.cpp @@ -20,10 +20,9 @@ #include <luci/Log.h> #include <loco/IR/NodeShape.h> -#include <loco/Service/ShapeInference.h> -#include <loco/Service/TypeInference.h> #include <cassert> +#include <unordered_map> #include <vector> namespace @@ -36,7 +35,11 @@ std::ostream &operator<<(std::ostream &os, const loco::TensorShape &tensor_shape { if (r) os << ","; - os << tensor_shape.dim(r).value(); + + if (tensor_shape.dim(r).known()) + os << tensor_shape.dim(r).value(); + else + os << "?"; } os << "]"; return os; @@ -49,7 +52,11 @@ std::ostream &operator<<(std::ostream &os, const luci::CircleNode *circle_node) { if (r) os << ","; - os << circle_node->dim(r).value(); + + if (circle_node->dim(r).known()) + os << circle_node->dim(r).value(); + else + os << "?"; } os << "]"; return os; @@ -99,10 +106,24 @@ bool validate_shape_dtype(loco::Graph *g) auto go_tensor_shape = graph_out->shape(); assert(go_tensor_shape); + // NOTE Even if shape of graph output is [] (which means "shape inference was impossible") + // but shape of CircleNode is not, it can be valid case because shape inference + // algorithm of CircleNode may be upgraded than before. The opposite is possible either. + // If such cases are appeared, following validation code should be fixed. bool is_shape_valid = (circle_node->rank() == go_tensor_shape->rank()); for (uint32_t i = 0; is_shape_valid && i < circle_node->rank(); ++i) - if (circle_node->dim(i).value() != go_tensor_shape->dim(i).value()) + { + if (!circle_node->dim(i).known() || !go_tensor_shape->dim(i).known()) + { + // If at least one of two dimensions is unknown, + // the unknown dimension can accept any value. + INFO(l) << "Unknown dimension is matched with known dimension" << std::endl; + } + else if (circle_node->dim(i).value() != go_tensor_shape->dim(i).value()) + { is_shape_valid = false; + } + } if (is_shape_valid == false) { @@ -124,72 +145,62 @@ bool validate_shape_dtype(loco::Graph *g) return true; } -bool validate_shape_signature(loco::Graph *g) -{ - LOGGER(l); - - for (auto node : loco::postorder_traversal(loco::output_nodes(g))) - { - auto circle_node = loco::must_cast<luci::CircleNode *>(node); - const auto shape_signature = circle_node->shape_signature(); +} // namespace - if (shape_signature.rank() == 0) - continue; +namespace luci +{ - // Rank of shape and shape signature should be same - if (circle_node->rank() != shape_signature.rank()) - { - INFO(l) << "[luci] Rank of shape signature for " << circle_node->name() << " do not match" - << std::endl; - return false; - } +bool validate(loco::Graph *g) +{ + if (!loco::valid(g)) + return false; - bool has_unknown = false; + if (!validate_shape_dtype(g)) + return false; - // If shape siganture is not -1, dimension value should be same - for (uint32_t d = 0; d < shape_signature.rank(); ++d) - { - if (shape_signature.dim(d) != -1 && - shape_signature.dim(d) != (int32_t)(circle_node->dim(d).value())) - { - INFO(l) << "[luci] Dimension " << d << "of shape signature for " << circle_node->name() - << " do not match" << std::endl; - return false; - } + // TODO add more validation - if (shape_signature.dim(d) == -1) - has_unknown = true; - } + return true; +} - // Shape signature should have at least one -1 value. - if (!has_unknown) - { - INFO(l) << "[luci] Shape signature in " << circle_node->name() - << " do not have unknown dimension" << std::endl; +bool validate_name(loco::Graph *g) +{ + auto nodes = g->nodes(); + for (uint32_t n = 0; n < nodes->size(); ++n) + { + auto node = loco::must_cast<luci::CircleNode *>(nodes->at(n)); + auto name = node->name(); + if (name.empty()) return false; - } } return true; } -} // namespace - -namespace luci +bool validate_unique_name(luci::Module *m) { + std::unordered_map<std::string, bool> names_col; -bool validate(loco::Graph *g) -{ - if (!loco::valid(g)) - return false; - - if (!validate_shape_dtype(g)) - return false; - - if (!validate_shape_signature(g)) - return false; + for (size_t g = 0; g < m->size(); ++g) + { + auto graph = m->graph(g); + auto nodes = graph->nodes(); + for (uint32_t n = 0; n < nodes->size(); ++n) + { + auto node = loco::must_cast<luci::CircleNode *>(nodes->at(n)); + // skip CircleOutput as it may have same name with from() node + auto output = dynamic_cast<luci::CircleOutput *>(node); + if (output != nullptr) + continue; + + auto name = node->name(); + auto it = names_col.find(name); + if (it != names_col.end()) + return false; - // TODO add more validation + names_col[name] = true; + } + } return true; } diff --git a/compiler/luci/service/src/Validate.test.cpp b/compiler/luci/service/src/Validate.test.cpp new file mode 100644 index 000000000..8ce6d895b --- /dev/null +++ b/compiler/luci/service/src/Validate.test.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2021 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 "luci/Service/Validate.h" + +#include <luci/test/TestIOGraph.h> + +#include <luci/IR/Nodes/CircleAdd.h> +#include <luci/IR/Nodes/CircleSqrt.h> + +#include <gtest/gtest.h> + +namespace +{ + +using namespace luci::test; + +class SqrtGraphlet +{ +public: + SqrtGraphlet() = default; + +public: + void init(loco::Graph *g, const ShapeU32 input_shape) + { + _sqrt = g->nodes()->create<luci::CircleSqrt>(); + _sqrt->dtype(loco::DataType::S32); + _sqrt->name("sqrt"); + } + +protected: + luci::CircleSqrt *_sqrt = nullptr; +}; + +class SqrtGraph : public TestIOGraph, public SqrtGraphlet +{ +public: + SqrtGraph() = default; + +public: + void init(const ShapeU32 shape) + { + TestIOGraph::init(shape, shape); + SqrtGraphlet::init(g(), shape); + + _sqrt->x(input()); + + output()->from(_sqrt); + + // set output name to _sqrt: CircleOutput may have duplicate name + output()->name(_sqrt->name()); + } +}; + +class Sqrt2xGraphlet +{ +public: + Sqrt2xGraphlet() = default; + +public: + void init(loco::Graph *g, const ShapeU32 input_shape) + { + _sqrt1 = g->nodes()->create<luci::CircleSqrt>(); + _sqrt1->dtype(loco::DataType::S32); + _sqrt1->name("sqrt"); + + _sqrt2 = g->nodes()->create<luci::CircleSqrt>(); + _sqrt2->dtype(loco::DataType::S32); + _sqrt2->name("sqrt"); + } + +protected: + luci::CircleSqrt *_sqrt1 = nullptr; + luci::CircleSqrt *_sqrt2 = nullptr; +}; + +class Sqrt2xGraph : public TestIOGraph, public Sqrt2xGraphlet +{ +public: + Sqrt2xGraph() = default; + +public: + void init(const ShapeU32 shape) + { + TestIOGraph::init(shape, shape); + Sqrt2xGraphlet::init(g(), shape); + + _sqrt1->x(input()); + + _sqrt2->x(_sqrt1); + + output()->from(_sqrt2); + } +}; + +} // namespace + +TEST(ValidateTest, non_empty_name) +{ + SqrtGraph g; + g.init({3, 3}); + + ASSERT_TRUE(luci::validate_name(g.g())); +} + +TEST(ValidateTest, unique_name) +{ + luci::Module module; + + SqrtGraph g; + g.init({3, 3}); + g.transfer_to(&module); + + ASSERT_TRUE(luci::validate_unique_name(&module)); +} + +TEST(ValidateTest, unique_name_NEG) +{ + luci::Module module; + + Sqrt2xGraph g; + g.init({3, 3}); + g.transfer_to(&module); + + ASSERT_FALSE(luci::validate_unique_name(&module)); +} |