diff options
Diffstat (limited to 'compiler/luci/import')
68 files changed, 3709 insertions, 0 deletions
diff --git a/compiler/luci/import/CMakeLists.txt b/compiler/luci/import/CMakeLists.txt new file mode 100644 index 000000000..bc9a9152a --- /dev/null +++ b/compiler/luci/import/CMakeLists.txt @@ -0,0 +1,26 @@ +file(GLOB_RECURSE SOURCES "src/*.cpp") +file(GLOB_RECURSE TESTS "src/*.test.cpp") +list(REMOVE_ITEM SOURCES ${TESTS}) + +add_library(luci_import SHARED ${SOURCES}) +target_include_directories(luci_import PRIVATE src) +target_include_directories(luci_import PUBLIC include) +target_link_libraries(luci_import PUBLIC luci_lang) +target_link_libraries(luci_import PUBLIC mio_circle) +target_link_libraries(luci_import PRIVATE luci_log) +target_link_libraries(luci_import PRIVATE luci_logex) +target_link_libraries(luci_import PRIVATE nncc_common) +target_link_libraries(luci_import PRIVATE locop) +target_link_libraries(luci_import PRIVATE oops) +install(TARGETS luci_import DESTINATION lib) + +if(NOT ENABLE_TEST) + return() +endif(NOT ENABLE_TEST) + +nnas_find_package(GTest REQUIRED) + +GTest_AddTest(luci_import_test ${TESTS}) +target_include_directories(luci_import_test PRIVATE src) +target_link_libraries(luci_import_test luci_import) +target_link_libraries(luci_import_test oops) diff --git a/compiler/luci/import/README.md b/compiler/luci/import/README.md new file mode 100644 index 000000000..4ae81ff67 --- /dev/null +++ b/compiler/luci/import/README.md @@ -0,0 +1,3 @@ +# luci-import + +_luci-import_ provides importing Circle model file to _loco_ graph of _luci_ Circle Dialect IR diff --git a/compiler/luci/import/include/luci/Import/CircleReader.h b/compiler/luci/import/include/luci/Import/CircleReader.h new file mode 100644 index 000000000..fcbe09ceb --- /dev/null +++ b/compiler/luci/import/include/luci/Import/CircleReader.h @@ -0,0 +1,87 @@ +/* + * 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_IMPORT_GRAPHREADER_H__ +#define __LUCI_IMPORT_GRAPHREADER_H__ + +#include <mio/circle/schema_generated.h> + +#include <luci/IR/AttrFusedActFunc.h> +#include <luci/IR/AttrPadding.h> +#include <luci/IR/CircleQuantParam.h> + +#include <loco.h> + +#include <map> +#include <memory> +#include <string> +#include <vector> + +namespace luci +{ + +bool is_valid(const circle::OperatorCodeT &opcode); +bool is_custom(const circle::OperatorCodeT &opcode); +std::string opcode_name(const circle::OperatorCodeT &opcode); +const char *tensor_name(const circle::TensorT &tensor); +const circle::QuantizationParametersT *tensor_quantization(const circle::TensorT &tensor); + +loco::DataType luci_datatype(circle::TensorType type); +FusedActFunc luci_actfunc(const circle::ActivationFunctionType type); +Padding luci_padding(const circle::Padding padding); +std::unique_ptr<CircleQuantParam> +luci_quantparam(const circle::QuantizationParametersT *quantization); + +/** + * @brief Loads Circle file and provides helpers to access attributes + */ +class CircleReader +{ +private: + using CircleBuffers_t = std::vector<std::unique_ptr<circle::BufferT>>; + using CircleTensors_t = std::vector<std::unique_ptr<circle::TensorT>>; + using CircleOperators_t = std::vector<std::unique_ptr<circle::OperatorT>>; + using CircleOperatorCodes_t = std::vector<std::unique_ptr<circle::OperatorCodeT>>; + +public: + CircleReader() = default; + +public: + const CircleOperatorCodes_t &opcodes() const { return _model->operator_codes; } + const CircleBuffers_t &buffers() const { return _model->buffers; } + const CircleTensors_t &tensors() const { return _current_subgraph->tensors; } + const CircleOperators_t &operators() const { return _current_subgraph->operators; } + const std::vector<int32_t> &inputs() const { return _current_subgraph->inputs; } + const std::vector<int32_t> &outputs() const { return _current_subgraph->outputs; } + const std::string &name() const { return _current_subgraph->name; } + + uint32_t num_subgraph() const { return _model->subgraphs.size(); } + + circle::BuiltinOperator builtin_code(const circle::OperatorT &op) const; + std::string opcode_name(const circle::OperatorT &op) const; + +public: + bool parse(const circle::Model *model); + bool select_subgraph(uint32_t subgraph); + +private: + std::unique_ptr<const circle::ModelT> _model; + const circle::SubGraphT *_current_subgraph{nullptr}; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_GRAPHREADER_H__ diff --git a/compiler/luci/import/include/luci/Import/GraphBuilder.h b/compiler/luci/import/include/luci/Import/GraphBuilder.h new file mode 100644 index 000000000..61f673fb6 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/GraphBuilder.h @@ -0,0 +1,56 @@ +/* + * 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_IMPORT_GRAPH_BUILDER_H__ +#define __LUCI_IMPORT_GRAPH_BUILDER_H__ + +#include "GraphBuilderContext.h" + +#include <mio/circle/schema_generated.h> + +namespace luci +{ + +/** + * @brief Interface of convert circle:: NodeDef to loco::Node (e.g., Conv2DGraphBuilder) + */ +class GraphBuilder +{ +public: + struct ValidateArgs + { + ValidateArgs(const circle::OperatorT &o, const CircleReader &r) : op(o), reader(r) {} + + const circle::OperatorT &op; + const CircleReader &reader; + }; + +public: + virtual ~GraphBuilder() = default; + + virtual bool validate(const ValidateArgs &) const = 0; + + void build(const circle::OperatorT &op, GraphBuilderContext *context) const; + +private: + virtual CircleNode *build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const = 0; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_GRAPH_BUILDER_H__ diff --git a/compiler/luci/import/include/luci/Import/GraphBuilderContext.h b/compiler/luci/import/include/luci/Import/GraphBuilderContext.h new file mode 100644 index 000000000..8d464181d --- /dev/null +++ b/compiler/luci/import/include/luci/Import/GraphBuilderContext.h @@ -0,0 +1,79 @@ +/* + * 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_IMPORT_GRAPH_BUILDER_CONTEXT_H__ +#define __LUCI_IMPORT_GRAPH_BUILDER_CONTEXT_H__ + +#include "CircleReader.h" + +#include <luci/IR/CircleNode.h> + +#include <loco.h> + +#include <map> + +namespace luci +{ + +using TensorIndex = int32_t; + +/* + * @brief Tensor Index to CircleNode + * To find CircleNode from TensorIndex + */ +class IndexNodeFinder +{ +public: + void enroll(TensorIndex idx, CircleNode *node); + + CircleNode *node(TensorIndex idx) const; + +private: + using MapIndexNode_t = std::map<TensorIndex, CircleNode *>; + + MapIndexNode_t _table; +}; + +/** + * @brief Class to store context to build loco graph IR from TensorFlow + */ +class GraphBuilderContext +{ +public: + GraphBuilderContext(loco::Graph *g, CircleReader *reader, IndexNodeFinder *nodefinder) + : _g(g), _reader(reader), _indexnodefinder(nodefinder) + { + // DO NOTHING + } + + GraphBuilderContext(const GraphBuilderContext &) = delete; + GraphBuilderContext(GraphBuilderContext &&) = delete; + +public: + loco::Graph *graph() { return _g; } + CircleReader *reader() { return _reader; } + + IndexNodeFinder *nodefinder() { return _indexnodefinder; } + +private: + loco::Graph *_g; + CircleReader *_reader; + IndexNodeFinder *_indexnodefinder; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_GRAPH_BUILDER_CONTEXT_H__ diff --git a/compiler/luci/import/include/luci/Import/GraphBuilderRegistry.h b/compiler/luci/import/include/luci/Import/GraphBuilderRegistry.h new file mode 100644 index 000000000..99054e7b6 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/GraphBuilderRegistry.h @@ -0,0 +1,85 @@ +/* + * 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_IMPORT_GRAPH_BUILDER_REGISTRY_H__ +#define __LUCI_IMPORT_GRAPH_BUILDER_REGISTRY_H__ + +#include "GraphBuilder.h" + +#include <map> + +namespace luci +{ + +struct GraphBuilderSource +{ + virtual ~GraphBuilderSource() = default; + + /** + * @brief Returns registered GraphBuilder pointer for operator (nullptr if not present) + */ + virtual const GraphBuilder *lookup(const circle::BuiltinOperator &op) const = 0; +}; + +/** + * @brief Class to return graph builder for TF nodes + */ +class GraphBuilderRegistry final : public GraphBuilderSource +{ +public: + GraphBuilderRegistry(); + +public: + GraphBuilderRegistry(const GraphBuilderSource *parent) : _parent{parent} + { + // DO NOTHING + } + +public: + /** + * @brief Returns registered GraphBuilder pointer for operator or + * nullptr if not registered + */ + const GraphBuilder *lookup(const circle::BuiltinOperator &op) const final + { + if (_builder_map.find(op) == _builder_map.end()) + return (_parent == nullptr) ? nullptr : _parent->lookup(op); + + return _builder_map.at(op).get(); + } + + static GraphBuilderRegistry &get() + { + static GraphBuilderRegistry me; + return me; + } + +public: + void add(const circle::BuiltinOperator op, std::unique_ptr<GraphBuilder> &&builder) + { + _builder_map[op] = std::move(builder); + } + +private: + const GraphBuilderSource *_parent = nullptr; + +private: + std::map<const circle::BuiltinOperator, std::unique_ptr<GraphBuilder>> _builder_map; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_GRAPH_BUILDER_REGISTRY_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes.h b/compiler/luci/import/include/luci/Import/Nodes.h new file mode 100644 index 000000000..381d02b97 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes.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_IMPORT_NODES_H__ +#define __LUCI_IMPORT_NODES_H__ + +#include "Nodes/CircleAbs.h" +#include "Nodes/CircleAdd.h" +#include "Nodes/CircleArgMax.h" +#include "Nodes/CircleAveragePool2D.h" +#include "Nodes/CircleBatchToSpaceND.h" +#include "Nodes/CircleConcatenation.h" +#include "Nodes/CircleConst.h" +#include "Nodes/CircleConv2D.h" +#include "Nodes/CircleCos.h" +#include "Nodes/CircleDepthwiseConv2D.h" +#include "Nodes/CircleDiv.h" +#include "Nodes/CircleEqual.h" +#include "Nodes/CircleExp.h" +#include "Nodes/CircleFullyConnected.h" +#include "Nodes/CircleLogicalNot.h" +#include "Nodes/CircleLogicalOr.h" +#include "Nodes/CircleMaxPool2D.h" +#include "Nodes/CircleMean.h" +#include "Nodes/CircleMul.h" +#include "Nodes/CirclePack.h" +#include "Nodes/CirclePad.h" +#include "Nodes/CircleRelu.h" +#include "Nodes/CircleReshape.h" +#include "Nodes/CircleRsqrt.h" +#include "Nodes/CircleSoftmax.h" +#include "Nodes/CircleSub.h" +#include "Nodes/CircleTranspose.h" + +#endif // __LUCI_IMPORT_NODES_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleAbs.h b/compiler/luci/import/include/luci/Import/Nodes/CircleAbs.h new file mode 100644 index 000000000..e0cec26d9 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleAbs.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_ABS_H__ +#define __LUCI_IMPORT_OP_CIRCLE_ABS_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleAbsGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_ABS_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleAdd.h b/compiler/luci/import/include/luci/Import/Nodes/CircleAdd.h new file mode 100644 index 000000000..d852ee8b3 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleAdd.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_ADD_H__ +#define __LUCI_IMPORT_OP_CIRCLE_ADD_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleAddGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_ADD_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleArgMax.h b/compiler/luci/import/include/luci/Import/Nodes/CircleArgMax.h new file mode 100644 index 000000000..dae4691dc --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleArgMax.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_ARGMAX_H__ +#define __LUCI_IMPORT_OP_CIRCLE_ARGMAX_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleArgMaxGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_ARGMAX_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleAveragePool2D.h b/compiler/luci/import/include/luci/Import/Nodes/CircleAveragePool2D.h new file mode 100644 index 000000000..07f6565bc --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleAveragePool2D.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_AVERAGEPOOL2D_H__ +#define __LUCI_IMPORT_OP_CIRCLE_AVERAGEPOOL2D_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleAveragePool2DGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_AVERAGEPOOL2D_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleBatchToSpaceND.h b/compiler/luci/import/include/luci/Import/Nodes/CircleBatchToSpaceND.h new file mode 100644 index 000000000..4168d248e --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleBatchToSpaceND.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_BATCHTOSPACEND_H__ +#define __LUCI_IMPORT_OP_CIRCLE_BATCHTOSPACEND_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleBatchToSpaceNDGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_BATCHTOSPACEND_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleConcatenation.h b/compiler/luci/import/include/luci/Import/Nodes/CircleConcatenation.h new file mode 100644 index 000000000..9b4c9ffd1 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleConcatenation.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_CONCATENATION_H__ +#define __LUCI_IMPORT_OP_CIRCLE_CONCATENATION_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleConcatenationGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_CONCATENATION_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleConst.h b/compiler/luci/import/include/luci/Import/Nodes/CircleConst.h new file mode 100644 index 000000000..7d4f10a59 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleConst.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_CONST_H__ +#define __LUCI_IMPORT_OP_CIRCLE_CONST_H__ + +#include "luci/Import/GraphBuilderContext.h" + +#include <luci/IR/Nodes/CircleConst.h> + +/* + * @note Circle does not have Const operator. + * Methods here provide helper that creates CircleConst from + * Tensor and Buffer in circle flatbuffer file. + */ + +namespace luci +{ + +CircleConst *create_circleconst(GraphBuilderContext *context, int32_t tensor_index); + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_CONST_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleConv2D.h b/compiler/luci/import/include/luci/Import/Nodes/CircleConv2D.h new file mode 100644 index 000000000..4529a4f11 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleConv2D.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_CONV_2D_H__ +#define __LUCI_IMPORT_OP_CIRCLE_CONV_2D_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleConv2DGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_CONV_2D_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleCos.h b/compiler/luci/import/include/luci/Import/Nodes/CircleCos.h new file mode 100644 index 000000000..fb472977e --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleCos.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_COS_H__ +#define __LUCI_IMPORT_OP_CIRCLE_COS_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleCosGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_COS_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleDepthwiseConv2D.h b/compiler/luci/import/include/luci/Import/Nodes/CircleDepthwiseConv2D.h new file mode 100644 index 000000000..1953cb76c --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleDepthwiseConv2D.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_DEPTHWISECONV_2D_H__ +#define __LUCI_IMPORT_OP_CIRCLE_DEPTHWISECONV_2D_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleDepthwiseConv2DGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_DEPTHWISECONV_2D_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleDiv.h b/compiler/luci/import/include/luci/Import/Nodes/CircleDiv.h new file mode 100644 index 000000000..6a38118fe --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleDiv.h @@ -0,0 +1,36 @@ +/* + * 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_IMPORT_OP_CIRCLE_DIV_H__ +#define __LUCI_IMPORT_OP_CIRCLE_DIV_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleDivGraphBuilder : public GraphBuilder +{ + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const override; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_DIV_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleEqual.h b/compiler/luci/import/include/luci/Import/Nodes/CircleEqual.h new file mode 100644 index 000000000..a98adcd08 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleEqual.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_EQUAL_H__ +#define __LUCI_IMPORT_OP_CIRCLE_EQUAL_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleEqualGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_EQUAL_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleExp.h b/compiler/luci/import/include/luci/Import/Nodes/CircleExp.h new file mode 100644 index 000000000..521809fe4 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleExp.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_EXP_H__ +#define __LUCI_IMPORT_OP_CIRCLE_EXP_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleExpGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_EXP_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleFullyConnected.h b/compiler/luci/import/include/luci/Import/Nodes/CircleFullyConnected.h new file mode 100644 index 000000000..b7798c688 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleFullyConnected.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_FULLYCONNECTED_H__ +#define __LUCI_IMPORT_OP_CIRCLE_FULLYCONNECTED_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleFullyConnectedGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_FULLYCONNECTED_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleLogicalNot.h b/compiler/luci/import/include/luci/Import/Nodes/CircleLogicalNot.h new file mode 100644 index 000000000..ec890ecf7 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleLogicalNot.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_LOGICALNOT_H__ +#define __LUCI_IMPORT_OP_CIRCLE_LOGICALNOT_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleLogicalNotGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_LOGICALNOT_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleLogicalOr.h b/compiler/luci/import/include/luci/Import/Nodes/CircleLogicalOr.h new file mode 100644 index 000000000..9fb0086c1 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleLogicalOr.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_LOGICALOR_H__ +#define __LUCI_IMPORT_OP_CIRCLE_LOGICALOR_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleLogicalOrGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_LOGICALOR_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleMaxPool2D.h b/compiler/luci/import/include/luci/Import/Nodes/CircleMaxPool2D.h new file mode 100644 index 000000000..bcd2acb30 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleMaxPool2D.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_MAXPOOL2D_H__ +#define __LUCI_IMPORT_OP_CIRCLE_MAXPOOL2D_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleMaxPool2DGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_MAXPOOL2D_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleMean.h b/compiler/luci/import/include/luci/Import/Nodes/CircleMean.h new file mode 100644 index 000000000..a7919a57c --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleMean.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_MEAN_H__ +#define __LUCI_IMPORT_OP_CIRCLE_MEAN_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleMeanGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_MEAN_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleMul.h b/compiler/luci/import/include/luci/Import/Nodes/CircleMul.h new file mode 100644 index 000000000..13027a155 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleMul.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_MUL_H__ +#define __LUCI_IMPORT_OP_CIRCLE_MUL_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleMulGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const override; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_MUL_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CirclePack.h b/compiler/luci/import/include/luci/Import/Nodes/CirclePack.h new file mode 100644 index 000000000..8e4b71995 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CirclePack.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_PACK_H__ +#define __LUCI_IMPORT_OP_CIRCLE_PACK_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CirclePackGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const override; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_PACK_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CirclePad.h b/compiler/luci/import/include/luci/Import/Nodes/CirclePad.h new file mode 100644 index 000000000..e333ee912 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CirclePad.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_PAD_H__ +#define __LUCI_IMPORT_OP_CIRCLE_PAD_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CirclePadGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_PAD_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleRelu.h b/compiler/luci/import/include/luci/Import/Nodes/CircleRelu.h new file mode 100644 index 000000000..deb913243 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleRelu.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_RELU_H__ +#define __LUCI_IMPORT_OP_CIRCLE_RELU_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleReluGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_RELU_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleReshape.h b/compiler/luci/import/include/luci/Import/Nodes/CircleReshape.h new file mode 100644 index 000000000..eb4fb13ba --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleReshape.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_RESHAPE_H__ +#define __LUCI_IMPORT_OP_CIRCLE_RESHAPE_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleReshapeGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_RESHAPE_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleRsqrt.h b/compiler/luci/import/include/luci/Import/Nodes/CircleRsqrt.h new file mode 100644 index 000000000..90d568f1f --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleRsqrt.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_RSQRT_H__ +#define __LUCI_IMPORT_OP_CIRCLE_RSQRT_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleRsqrtGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_RSQRT_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleSoftmax.h b/compiler/luci/import/include/luci/Import/Nodes/CircleSoftmax.h new file mode 100644 index 000000000..b93846d67 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleSoftmax.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_SOFTMAX_H__ +#define __LUCI_IMPORT_OP_CIRCLE_SOFTMAX_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleSoftmaxGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_SOFTMAX_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleSub.h b/compiler/luci/import/include/luci/Import/Nodes/CircleSub.h new file mode 100644 index 000000000..315d1c2f9 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleSub.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_SUB_H__ +#define __LUCI_IMPORT_OP_CIRCLE_SUB_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleSubGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const final; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_SUB_H__ diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleTranspose.h b/compiler/luci/import/include/luci/Import/Nodes/CircleTranspose.h new file mode 100644 index 000000000..ac0f1fb41 --- /dev/null +++ b/compiler/luci/import/include/luci/Import/Nodes/CircleTranspose.h @@ -0,0 +1,37 @@ +/* + * 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_IMPORT_OP_CIRCLE_TRANSPOSE_H__ +#define __LUCI_IMPORT_OP_CIRCLE_TRANSPOSE_H__ + +#include "luci/Import/GraphBuilder.h" + +namespace luci +{ + +class CircleTransposeGraphBuilder : public GraphBuilder +{ +public: + bool validate(const ValidateArgs &args) const final; + +private: + CircleNode *build_node(const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const override; +}; + +} // namespace luci + +#endif // __LUCI_IMPORT_OP_CIRCLE_TRANSPOSE_H__ diff --git a/compiler/luci/import/include/luci/Importer.h b/compiler/luci/import/include/luci/Importer.h new file mode 100644 index 000000000..246df9f27 --- /dev/null +++ b/compiler/luci/import/include/luci/Importer.h @@ -0,0 +1,54 @@ +/* + * 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_IMPORTER_H__ +#define __LUCI_IMPORTER_H__ + +#include "luci/Import/GraphBuilderRegistry.h" + +#include "luci/IR/Module.h" + +#include <loco.h> + +#include <mio/circle/schema_generated.h> + +#include <memory> + +namespace luci +{ + +class Importer final +{ +public: + Importer(); + +public: + explicit Importer(const GraphBuilderSource *source) : _source{source} + { + // DO NOTHING + } + +public: + std::unique_ptr<loco::Graph> import(const circle::Model *model) const; + std::unique_ptr<Module> importModule(const circle::Model *model) const; + +private: + const GraphBuilderSource *_source = nullptr; +}; + +} // namespace luci + +#endif // __MOCO_IMPORTER_H__ diff --git a/compiler/luci/import/src/CircleReader.cpp b/compiler/luci/import/src/CircleReader.cpp new file mode 100644 index 000000000..ead0093b8 --- /dev/null +++ b/compiler/luci/import/src/CircleReader.cpp @@ -0,0 +1,211 @@ +/* + * 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/Import/CircleReader.h" + +#include <memory> +#include <sstream> +#include <string> + +namespace luci +{ + +bool is_valid(const circle::OperatorCodeT &opcode) +{ + circle::BuiltinOperator code = opcode.builtin_code; + return (circle::BuiltinOperator_MIN <= code && code <= circle::BuiltinOperator_MAX); +} + +bool is_custom(const circle::OperatorCodeT &opcode) +{ + circle::BuiltinOperator code = opcode.builtin_code; + return (code == circle::BuiltinOperator_CUSTOM); +} + +std::string opcode_name(const circle::OperatorCodeT &opcode) +{ + if (!is_valid(opcode)) + { + std::ostringstream oss; + oss << "(invalid)"; + return oss.str(); + } + + if (is_custom(opcode)) + { + if (opcode.custom_code.empty()) + return "(invalid custom)"; + + return opcode.custom_code; + } + + circle::BuiltinOperator code = opcode.builtin_code; + return circle::EnumNameBuiltinOperator(code); +} + +const char *tensor_name(const circle::TensorT &tensor) +{ + static const char *kEmptyTensorName = "(noname)"; + + if (!tensor.name.empty()) + return tensor.name.c_str(); + + return kEmptyTensorName; +} + +const circle::QuantizationParametersT *tensor_quantization(const circle::TensorT &tensor) +{ + return tensor.quantization.get(); +} + +loco::DataType luci_datatype(const circle::TensorType type) +{ + switch (type) + { + case circle::TensorType_FLOAT32: + return loco::DataType::FLOAT32; + case circle::TensorType_FLOAT16: + return loco::DataType::FLOAT16; + case circle::TensorType_INT32: + return loco::DataType::S32; + case circle::TensorType_UINT8: + return loco::DataType::U8; + case circle::TensorType_INT64: + return loco::DataType::S64; + case circle::TensorType_STRING: + break; + case circle::TensorType_BOOL: + return loco::DataType::BOOL; + case circle::TensorType_INT16: + return loco::DataType::S16; + case circle::TensorType_COMPLEX64: + break; + case circle::TensorType_INT8: + return loco::DataType::S8; + default: + break; + } + assert(false); + return loco::DataType::Unknown; +} + +FusedActFunc luci_actfunc(const circle::ActivationFunctionType type) +{ + switch (type) + { + case circle::ActivationFunctionType::ActivationFunctionType_NONE: + return luci::FusedActFunc::NONE; + case circle::ActivationFunctionType::ActivationFunctionType_RELU: + return luci::FusedActFunc::RELU; + case circle::ActivationFunctionType::ActivationFunctionType_RELU_N1_TO_1: + return luci::FusedActFunc::RELU_N1_TO_1; + case circle::ActivationFunctionType::ActivationFunctionType_RELU6: + return luci::FusedActFunc::RELU6; + case circle::ActivationFunctionType::ActivationFunctionType_TANH: + break; + default: + break; + } + assert(false); + return luci::FusedActFunc::UNDEFINED; +} + +Padding luci_padding(const circle::Padding padding) +{ + switch (padding) + { + case circle::Padding::Padding_SAME: + return Padding::SAME; + case circle::Padding::Padding_VALID: + return Padding::VALID; + } + assert(false); + return Padding::UNDEFINED; +} + +std::unique_ptr<CircleQuantParam> +luci_quantparam(const circle::QuantizationParametersT *quantization) +{ + const auto &min = quantization->min; + const auto &max = quantization->max; + const auto &scale = quantization->scale; + const auto &zero_point = quantization->zero_point; + + if ((!min.empty() && !max.empty()) || (!scale.empty() && !zero_point.empty())) + { + auto quantparam = std::make_unique<CircleQuantParam>(); + + quantparam->min = min; + quantparam->max = max; + quantparam->scale = scale; + quantparam->zerop = zero_point; + + return quantparam; + } + + return nullptr; +} + +circle::BuiltinOperator CircleReader::builtin_code(const circle::OperatorT &op) const +{ + const auto &op_codes = opcodes(); + uint32_t index = op.opcode_index; + assert(index < op_codes.size()); + const circle::OperatorCodeT &opcode = *op_codes[index]; + + return opcode.builtin_code; +} + +std::string CircleReader::opcode_name(const circle::OperatorT &op) const +{ + const auto &op_codes = opcodes(); + uint32_t index = op.opcode_index; + assert(index < op_codes.size()); + const circle::OperatorCodeT &opcode = *op_codes[index]; + + if (!is_valid(opcode)) + { + std::ostringstream oss; + oss << "(invalid: " << index << ")"; + return oss.str(); + } + + return ::luci::opcode_name(opcode); +} + +bool CircleReader::parse(const circle::Model *model) +{ + assert(model != nullptr); + + _model.reset(model->UnPack()); + + return true; +} + +bool CircleReader::select_subgraph(uint32_t sgindex) +{ + if (_model->subgraphs.size() <= sgindex) + { + assert(false); + return false; + } + + _current_subgraph = _model->subgraphs[sgindex].get(); + + return true; +} + +} // namespace luci diff --git a/compiler/luci/import/src/GraphBuilder.cpp b/compiler/luci/import/src/GraphBuilder.cpp new file mode 100644 index 000000000..e0ec9ded5 --- /dev/null +++ b/compiler/luci/import/src/GraphBuilder.cpp @@ -0,0 +1,61 @@ +/* + * 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/Import/GraphBuilder.h" + +namespace luci +{ + +void GraphBuilder::build(const circle::OperatorT &op, GraphBuilderContext *context) const +{ + assert(context != nullptr); + + const std::vector<int32_t> &inputs = op.inputs; + const std::vector<int32_t> &outputs = op.outputs; + const auto &tensors = context->reader()->tensors(); + + std::vector<CircleNode *> input_nodes; + for (const int32_t input_tensor_index : inputs) + { + input_nodes.push_back(context->nodefinder()->node(input_tensor_index)); + } + + CircleNode *node = build_node(op, input_nodes, context->graph()); + + // Set up node parameters. + assert(outputs.size() == 1); + { + const circle::TensorT &output_tensor = *tensors[outputs[0]]; + + node->name(tensor_name(output_tensor)); + + auto quantization = tensor_quantization(output_tensor); + if (quantization) + { + auto quantparam = luci_quantparam(quantization); + if (quantparam) + node->quantparam(std::move(quantparam)); + } + } + + // Register node's only output. + assert(outputs.size() == 1); + { + context->nodefinder()->enroll(outputs[0], node); + } +} + +} // namespace luci diff --git a/compiler/luci/import/src/GraphBuilderContext.cpp b/compiler/luci/import/src/GraphBuilderContext.cpp new file mode 100644 index 000000000..a5162ce83 --- /dev/null +++ b/compiler/luci/import/src/GraphBuilderContext.cpp @@ -0,0 +1,47 @@ +/* + * 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/Import/GraphBuilderContext.h" + +#include <luci/Log.h> + +#include <oops/UserExn.h> + +namespace luci +{ + +void IndexNodeFinder::enroll(TensorIndex idx, CircleNode *node) +{ + if (_table.find(idx) != _table.end()) + { + LOGGER(l); + INFO(l) << "[luci] NodeFinder SKIP (" << idx << ") " << node << std::endl; + return; + } + + _table[idx] = node; +} + +CircleNode *IndexNodeFinder::node(TensorIndex idx) const +{ + MapIndexNode_t::const_iterator iter = _table.find(idx); + + assert(iter != _table.end() && iter->second != nullptr); + + return iter->second; +} + +} // namespace luci diff --git a/compiler/luci/import/src/GraphBuilderRegistry.cpp b/compiler/luci/import/src/GraphBuilderRegistry.cpp new file mode 100644 index 000000000..929b71a7d --- /dev/null +++ b/compiler/luci/import/src/GraphBuilderRegistry.cpp @@ -0,0 +1,163 @@ +/* + * 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/Import/GraphBuilderRegistry.h" + +#include "luci/Import/Nodes.h" + +#include <memory> + +namespace luci +{ + +GraphBuilderRegistry::GraphBuilderRegistry() +{ +#define CIRCLE_NODE(OPCODE, CLASS) add(circle::BuiltinOperator_##OPCODE, std::make_unique<CLASS>()); + + CIRCLE_NODE(ABS, CircleAbsGraphBuilder); // 101 + CIRCLE_NODE(ADD, CircleAddGraphBuilder); // 0 + CIRCLE_NODE(ARG_MAX, CircleArgMaxGraphBuilder); // 56 + CIRCLE_NODE(AVERAGE_POOL_2D, CircleAveragePool2DGraphBuilder); // 1 + CIRCLE_NODE(BATCH_TO_SPACE_ND, CircleBatchToSpaceNDGraphBuilder); // 37 + CIRCLE_NODE(CONCATENATION, CircleConcatenationGraphBuilder); // 2 + CIRCLE_NODE(CONV_2D, CircleConv2DGraphBuilder); // 3 + CIRCLE_NODE(COS, CircleCosGraphBuilder); // 108 + CIRCLE_NODE(DEPTHWISE_CONV_2D, CircleDepthwiseConv2DGraphBuilder); // 4 + CIRCLE_NODE(DIV, CircleDivGraphBuilder); // 42 + CIRCLE_NODE(EQUAL, CircleEqualGraphBuilder); // 71 + CIRCLE_NODE(EXP, CircleExpGraphBuilder); // 47 + CIRCLE_NODE(FULLY_CONNECTED, CircleFullyConnectedGraphBuilder); // 9 + CIRCLE_NODE(LOGICAL_NOT, CircleLogicalNotGraphBuilder); // 87 + CIRCLE_NODE(LOGICAL_OR, CircleLogicalOrGraphBuilder); // 84 + CIRCLE_NODE(MAX_POOL_2D, CircleMaxPool2DGraphBuilder); // 17 + CIRCLE_NODE(MEAN, CircleMeanGraphBuilder); // 40 + CIRCLE_NODE(MUL, CircleMulGraphBuilder); // 18 + CIRCLE_NODE(PACK, CirclePackGraphBuilder); // 83 + CIRCLE_NODE(PAD, CirclePadGraphBuilder); // 34 + CIRCLE_NODE(RELU, CircleReluGraphBuilder); // 19 + CIRCLE_NODE(RESHAPE, CircleReshapeGraphBuilder); // 22 + CIRCLE_NODE(RSQRT, CircleRsqrtGraphBuilder); // 76 + CIRCLE_NODE(SOFTMAX, CircleSoftmaxGraphBuilder); // 25 + CIRCLE_NODE(SUB, CircleSubGraphBuilder); // 41 + CIRCLE_NODE(TRANSPOSE, CircleTransposeGraphBuilder); // 39 + +#undef CIRCLE_NODE + + // BuiltinOperator_DEQUANTIZE = 6, + // BuiltinOperator_EMBEDDING_LOOKUP = 7, + // BuiltinOperator_FLOOR = 8, + // BuiltinOperator_HASHTABLE_LOOKUP = 10, + // BuiltinOperator_L2_NORMALIZATION = 11, + // BuiltinOperator_L2_POOL_2D = 12, + // BuiltinOperator_LOCAL_RESPONSE_NORMALIZATION = 13, + // BuiltinOperator_LOGISTIC = 14, + // BuiltinOperator_LSH_PROJECTION = 15, + // BuiltinOperator_LSTM = 16, + // BuiltinOperator_RELU_N1_TO_1 = 20, + // BuiltinOperator_RELU6 = 21, + // BuiltinOperator_RESIZE_BILINEAR = 23, + // BuiltinOperator_RNN = 24, + // BuiltinOperator_SPACE_TO_DEPTH = 26, + // BuiltinOperator_SVDF = 27, + // BuiltinOperator_TANH = 28, + // BuiltinOperator_CONCAT_EMBEDDINGS = 29, + // BuiltinOperator_SKIP_GRAM = 30, + // BuiltinOperator_CALL = 31, + // BuiltinOperator_CUSTOM = 32, + // BuiltinOperator_EMBEDDING_LOOKUP_SPARSE = 33, + // BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_RNN = 35, + // BuiltinOperator_GATHER = 36, + // BuiltinOperator_SPACE_TO_BATCH_ND = 38, + // BuiltinOperator_SQUEEZE = 43, + // BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_LSTM = 44, + // BuiltinOperator_STRIDED_SLICE = 45, + // BuiltinOperator_BIDIRECTIONAL_SEQUENCE_RNN = 46, + // BuiltinOperator_TOPK_V2 = 48, + // BuiltinOperator_SPLIT = 49, + // BuiltinOperator_LOG_SOFTMAX = 50, + // BuiltinOperator_DELEGATE = 51, + // BuiltinOperator_BIDIRECTIONAL_SEQUENCE_LSTM = 52, + // BuiltinOperator_CAST = 53, + // BuiltinOperator_PRELU = 54, + // BuiltinOperator_MAXIMUM = 55, + // BuiltinOperator_ARG_MAX = 56, + // BuiltinOperator_MINIMUM = 57, + // BuiltinOperator_LESS = 58, + // BuiltinOperator_NEG = 59, + // BuiltinOperator_PADV2 = 60, + // BuiltinOperator_GREATER = 61, + // BuiltinOperator_GREATER_EQUAL = 62, + // BuiltinOperator_LESS_EQUAL = 63, + // BuiltinOperator_SELECT = 64, + // BuiltinOperator_SLICE = 65, + // BuiltinOperator_SIN = 66, + // BuiltinOperator_TRANSPOSE_CONV = 67, + // BuiltinOperator_SPARSE_TO_DENSE = 68, + // BuiltinOperator_TILE = 69, + // BuiltinOperator_EXPAND_DIMS = 70, + // BuiltinOperator_NOT_EQUAL = 72, + // BuiltinOperator_LOG = 73, + // BuiltinOperator_SUM = 74, + // BuiltinOperator_SQRT = 75, + // BuiltinOperator_SHAPE = 77, + // BuiltinOperator_POW = 78, + // BuiltinOperator_ARG_MIN = 79, + // BuiltinOperator_FAKE_QUANT = 80, + // BuiltinOperator_REDUCE_PROD = 81, + // BuiltinOperator_REDUCE_MAX = 82, + // BuiltinOperator_ONE_HOT = 85, + // BuiltinOperator_LOGICAL_AND = 86, + // BuiltinOperator_UNPACK = 88, + // BuiltinOperator_REDUCE_MIN = 89, + // BuiltinOperator_FLOOR_DIV = 90, + // BuiltinOperator_REDUCE_ANY = 91, + // BuiltinOperator_SQUARE = 92, + // BuiltinOperator_ZEROS_LIKE = 93, + // BuiltinOperator_FILL = 94, + // BuiltinOperator_FLOOR_MOD = 95, + // BuiltinOperator_RANGE = 96, + // BuiltinOperator_RESIZE_NEAREST_NEIGHBOR = 97, + // BuiltinOperator_LEAKY_RELU = 98, + // BuiltinOperator_SQUARED_DIFFERENCE = 99, + // BuiltinOperator_MIRROR_PAD = 100, + // BuiltinOperator_SPLIT_V = 102, + // BuiltinOperator_UNIQUE = 103, + // BuiltinOperator_CEIL = 104, + // BuiltinOperator_REVERSE_V2 = 105, + // BuiltinOperator_ADD_N = 106, + // BuiltinOperator_GATHER_ND = 107, + // BuiltinOperator_WHERE = 109, + // BuiltinOperator_RANK = 110, + // BuiltinOperator_ELU = 111, + // BuiltinOperator_REVERSE_SEQUENCE = 112, + // BuiltinOperator_MATRIX_DIAG = 113, + // BuiltinOperator_QUANTIZE = 114, + // BuiltinOperator_MATRIX_SET_DIAG = 115, + // BuiltinOperator_ROUND = 116, + // BuiltinOperator_HARD_SWISH = 117, + // BuiltinOperator_IF = 118, + // BuiltinOperator_WHILE = 119, + // BuiltinOperator_NON_MAX_SUPPRESSION_V4 = 120, + // BuiltinOperator_NON_MAX_SUPPRESSION_V5 = 121, + // BuiltinOperator_SCATTER_ND = 122, + // BuiltinOperator_SELECT_V2 = 123, + // BuiltinOperator_DENSIFY = 124, + // BuiltinOperator_SEGMENT_SUM = 125, + // BuiltinOperator_BATCH_MATMUL = 126, + // BuiltinOperator_INSTANCE_NORM = 254, +} + +} // namespace luci diff --git a/compiler/luci/import/src/Importer.cpp b/compiler/luci/import/src/Importer.cpp new file mode 100644 index 000000000..964c47633 --- /dev/null +++ b/compiler/luci/import/src/Importer.cpp @@ -0,0 +1,253 @@ +/* + * 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/Importer.h" + +#include "luci/Import/GraphBuilder.h" +#include "luci/Import/GraphBuilderContext.h" +#include "luci/Import/GraphBuilderRegistry.h" +#include "luci/Import/CircleReader.h" +#include "luci/Import/Nodes/CircleConst.h" + +#include <luci/IR/Module.h> +#include <luci/IR/CircleNodes.h> +#include <luci/Log.h> +#include <luci/LogHelper.h> + +#include <oops/UserExn.h> + +#include <memory> + +namespace +{ + +void convert_graph(const luci::GraphBuilderSource &source, luci::CircleReader &reader, + loco::Graph *graph) +{ + LOGGER(l); + + auto nodefinder = std::make_unique<luci::IndexNodeFinder>(); + + luci::GraphBuilderContext gb_context(graph, &reader, nodefinder.get()); + + const auto &operators = reader.operators(); + const auto &tensors = reader.tensors(); + + // graph inputs; there are no input nodes in TFlite but just Tensors + // creating virtual input nodes will make possible to connect nodes that uses them + // all attributes of tensor should be copied to CircleInput node + for (const auto input : reader.inputs()) + { + auto input_node = graph->nodes()->create<luci::CircleInput>(); + assert(input_node != nullptr); + const circle::TensorT &tensor = *tensors[input]; + + auto tname = luci::tensor_name(tensor); + input_node->name(tname); + auto quantization = luci::tensor_quantization(tensor); + if (quantization) + { + auto quantparam = luci::luci_quantparam(quantization); + if (quantparam.get()) + input_node->quantparam(std::move(quantparam)); + } + + INFO(l) << "[luci] NodeFinder INPUT(" << input << ") = " << input_node << std::endl; + nodefinder->enroll(input, input_node); + + // Shape of Input + const std::vector<int32_t> &input_dims = tensor.shape; // in NHWC + input_node->rank(input_dims.size()); + for (uint32_t r = 0; r < input_dims.size(); ++r) + input_node->dim(r) = loco::Dimension(input_dims[r]); + + // Data type of Input + auto dtype = luci::luci_datatype(tensor.type); + input_node->dtype(dtype); + + // Name + auto graph_input = graph->inputs()->create(); + graph_input->name(tname); + + // Set GraphInputOutputIndex for graph + input_node->index(graph_input->index()); + + // Data type + graph_input->dtype(dtype); + } + + // Create CircleConst nodes for constant tensors. + const auto &buffers = reader.buffers(); + for (uint32_t i = 0; i < tensors.size(); ++i) + { + const circle::TensorT &tensor = *tensors[i]; + const std::vector<uint8_t> &buffer = buffers[tensor.buffer]->data; + if (!buffer.empty()) + { + luci::CircleConst *const_node = luci::create_circleconst(&gb_context, i); + nodefinder->enroll(i, const_node); + } + } + + // Import the operators. + // Note that operators in model are stored in execution order. This means that when importing + // an operator, its input operators have already been imported. We exploit this fact to set up + // node's inputs right after creating the node. + for (uint32_t i = 0; i < operators.size(); ++i) + { + const circle::OperatorT &op = *operators[i]; + circle::BuiltinOperator builtincode = reader.builtin_code(op); + + if (const auto *builder = source.lookup(builtincode)) + { + luci::GraphBuilder::ValidateArgs args(op, reader); + if (!builder->validate(args)) + { + throw oops::UserExn("Invalid operator", reader.opcode_name(op)); + } + + builder->build(op, &gb_context); + } + else + { + throw oops::UserExn("Not supported", reader.opcode_name(op)); + } + } + + // graph outputs + for (auto output : reader.outputs()) + { + auto output_node = graph->nodes()->create<luci::CircleOutput>(); + assert(output_node != nullptr); + output_node->from(nodefinder->node(output)); + + INFO(l) << "[luci] NodeFinder OUTPUT(" << output << ") = " << output_node << std::endl; + + // set the graph output name and node object + const circle::TensorT &tensor = *tensors[output]; + auto graph_output = graph->outputs()->create(); + std::string tname = luci::tensor_name(tensor); + graph_output->name("output_" + tname); + + // Set GraphInputOutputIndex for graph + output_node->index(graph_output->index()); + + // Shape of Output + auto output_shape = std::make_unique<loco::TensorShape>(); + const std::vector<int32_t> &output_dims = tensor.shape; // in NHWC + output_shape->rank(output_dims.size()); + for (uint32_t r = 0; r < output_dims.size(); ++r) + output_shape->dim(r) = loco::Dimension(output_dims[r]); + graph_output->shape(std::move(output_shape)); + + // Data type + auto dtype = luci::luci_datatype(tensor.type); + graph_output->dtype(dtype); + } +} + +class ValidateCollector final : public loco::ErrorListener +{ +public: + void notify(const loco::ErrorDetail<loco::ErrorCategory::MissingArgument> &d) override + { + LOGGER(l); + INFO(l) << "[luci] GraphValidate error " << d.node() << "(" << d.index() << ")" << std::endl; + } +}; + +} // namespace + +namespace luci +{ + +Importer::Importer() +{ + // DO NOTHING +} + +std::unique_ptr<loco::Graph> Importer::import(const circle::Model *model) const +{ + auto graph = loco::make_graph(); + + const GraphBuilderSource *source_ptr = &GraphBuilderRegistry::get(); + + if (_source != nullptr) + { + // Use user-defined GraphBuilderSource + source_ptr = _source; + } + + CircleReader reader; + if (!reader.parse(model)) + return nullptr; + + // TODO support multiple subgraph when Circle supports + assert(reader.num_subgraph() == 1); + if (!reader.select_subgraph(0)) + return nullptr; + + // Convert circle::Model to loco::Graph + convert_graph(*source_ptr, reader, graph.get()); + + LOGGER(l); + INFO(l) << fmt(graph.get()); + + assert(loco::valid(graph.get(), std::make_unique<ValidateCollector>())); + + return std::move(graph); +} + +std::unique_ptr<Module> Importer::importModule(const circle::Model *model) const +{ + auto module = make_module(); + + const GraphBuilderSource *source_ptr = &GraphBuilderRegistry::get(); + + if (_source != nullptr) + { + // Use user-defined GraphBuilderSource + source_ptr = _source; + } + + CircleReader reader; + if (!reader.parse(model)) + return nullptr; + + for (uint32_t g = 0; g < reader.num_subgraph(); ++g) + { + auto graph = loco::make_graph(); + + if (!reader.select_subgraph(g)) + return nullptr; + + graph->name(reader.name()); + + // Convert circle::Model to loco::Graph + convert_graph(*source_ptr, reader, graph.get()); + + LOGGER(l); + INFO(l) << fmt(graph.get()); + + assert(loco::valid(graph.get(), std::make_unique<ValidateCollector>())); + + module->add(std::move(graph)); + } + + return std::move(module); +} + +} // namespace luci diff --git a/compiler/luci/import/src/Importer.test.cpp b/compiler/luci/import/src/Importer.test.cpp new file mode 100644 index 000000000..4426e15fd --- /dev/null +++ b/compiler/luci/import/src/Importer.test.cpp @@ -0,0 +1,23 @@ +/* + * 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/Importer.h" + +#include <loco.h> + +#include <gtest/gtest.h> + +TEST(TensorFlowLiteImport, Dummy) { luci::Importer import; } diff --git a/compiler/luci/import/src/Nodes/CircleAbs.cpp b/compiler/luci/import/src/Nodes/CircleAbs.cpp new file mode 100644 index 000000000..9054986bd --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleAbs.cpp @@ -0,0 +1,44 @@ +/* + * 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/Import/Nodes/CircleAbs.h" + +#include <luci/IR/Nodes/CircleAbs.h> + +#include <loco.h> + +namespace luci +{ +bool CircleAbsGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 1) + return false; + + // TODO Support type check + return true; +} + +CircleNode *CircleAbsGraphBuilder::build_node(const circle::OperatorT &, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleAbs>(); + node->x(inputs[0]); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleAdd.cpp b/compiler/luci/import/src/Nodes/CircleAdd.cpp new file mode 100644 index 000000000..3b1bb734f --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleAdd.cpp @@ -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. + */ + +#include "luci/Import/Nodes/CircleAdd.h" + +#include <luci/IR/Nodes/CircleAdd.h> + +#include <loco.h> + +namespace luci +{ + +bool CircleAddGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 2) + return false; + + return true; +} + +CircleNode *CircleAddGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleAdd>(); + node->x(inputs[0]); + node->y(inputs[1]); + + const auto *options = op.builtin_options.AsAddOptions(); + node->fusedActivationFunction(luci_actfunc(options->fused_activation_function)); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleArgMax.cpp b/compiler/luci/import/src/Nodes/CircleArgMax.cpp new file mode 100644 index 000000000..2679827e2 --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleArgMax.cpp @@ -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. + */ + +#include "luci/Import/Nodes/CircleArgMax.h" + +#include <luci/IR/Nodes/CircleArgMax.h> + +#include <loco.h> + +namespace luci +{ + +bool CircleArgMaxGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 2) + return false; + + return true; +} + +CircleNode *CircleArgMaxGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleArgMax>(); + node->input(inputs[0]); + node->dimension(inputs[1]); + + const auto *options = op.builtin_options.AsArgMaxOptions(); + node->output_type(luci_datatype(options->output_type)); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleAveragePool2D.cpp b/compiler/luci/import/src/Nodes/CircleAveragePool2D.cpp new file mode 100644 index 000000000..cfc3cf126 --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleAveragePool2D.cpp @@ -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. + */ + +#include "luci/Import/Nodes/CircleAveragePool2D.h" + +#include <luci/IR/Nodes/CircleAveragePool2D.h> + +namespace luci +{ + +bool CircleAveragePool2DGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 1) + return false; + + return true; +} + +CircleNode *CircleAveragePool2DGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleAveragePool2D>(); + node->value(inputs[0]); + + const auto *options = op.builtin_options.AsPool2DOptions(); + node->padding(luci_padding(options->padding)); + node->stride()->w(options->stride_w); + node->stride()->h(options->stride_h); + node->filter()->w(options->filter_width); + node->filter()->h(options->filter_height); + node->fusedActivationFunction(luci_actfunc(options->fused_activation_function)); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleBatchToSpaceND.cpp b/compiler/luci/import/src/Nodes/CircleBatchToSpaceND.cpp new file mode 100644 index 000000000..4bbfadf64 --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleBatchToSpaceND.cpp @@ -0,0 +1,80 @@ +/* + * 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/Import/Nodes/CircleBatchToSpaceND.h" + +#include <luci/IR/Nodes/CircleBatchToSpaceND.h> + +#include <loco.h> + +#include <cassert> + +namespace luci +{ + +bool CircleBatchToSpaceNDGraphBuilder::validate(const ValidateArgs &args) const +{ + const auto &inputs = args.op.inputs; + if (inputs.size() != 3) + return false; + + // input 1 and 2 should have INT32/INT64 type + const auto &tensors = args.reader.tensors(); + const auto &tensor_1 = tensors.at(inputs[1]); + switch (tensor_1->type) + { + case circle::TensorType_INT32: + case circle::TensorType_INT64: + break; + default: + return false; + } + const auto &tensor_2 = tensors.at(inputs[2]); + switch (tensor_2->type) + { + case circle::TensorType_INT32: + case circle::TensorType_INT64: + break; + default: + return false; + } + + // Only support input shape dimension 3 and 4 only + const auto &tensor_0 = tensors.at(inputs[0]); + const auto t_0_s = tensor_0->shape.size(); + if (t_0_s != 3 && t_0_s != 4) + return false; + + // TODO check input shape + + return true; +} + +CircleNode *CircleBatchToSpaceNDGraphBuilder::build_node(const circle::OperatorT &, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleBatchToSpaceND>(); + node->input(inputs[0]); + node->block_shape(inputs[1]); + node->crops(inputs[2]); + + // No options for BatchToSpaceND + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleConcatenation.cpp b/compiler/luci/import/src/Nodes/CircleConcatenation.cpp new file mode 100644 index 000000000..7fc616aa0 --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleConcatenation.cpp @@ -0,0 +1,52 @@ +/* + * 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/Import/Nodes/CircleConcatenation.h" + +#include <luci/IR/Nodes/CircleConcatenation.h> + +namespace luci +{ + +bool CircleConcatenationGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() < 1) + return false; + + if (args.op.outputs.size() != 1) + return false; + + return true; +} + +CircleNode *CircleConcatenationGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleConcatenation>(inputs.size()); + for (uint32_t i = 0; i < inputs.size(); ++i) + { + node->values(i, inputs[i]); + } + + const auto *options = op.builtin_options.AsConcatenationOptions(); + node->axis(options->axis); + node->fusedActivationFunction(luci_actfunc(options->fused_activation_function)); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleConst.cpp b/compiler/luci/import/src/Nodes/CircleConst.cpp new file mode 100644 index 000000000..1d798983b --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleConst.cpp @@ -0,0 +1,110 @@ +/* + * 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/Import/Nodes/CircleConst.h" + +#include <luci/IR/Nodes/CircleConst.h> +#include <luci/Log.h> + +#include <loco.h> +#include <oops/UserExn.h> + +#include <cassert> + +namespace luci +{ + +template <loco::DataType DT> +static void copy_data(const std::vector<uint8_t> &raw_data, uint32_t num_elements, + CircleConst *const_node) +{ + using T = typename loco::DataTypeImpl<DT>::Type; + + assert(raw_data.size() == num_elements * sizeof(T)); + const auto *data = reinterpret_cast<const T *>(raw_data.data()); + + const_node->size<DT>(num_elements); + for (uint32_t i = 0; i < num_elements; ++i) + { + const_node->at<DT>(i) = data[i]; + } +} + +// +// circleconst_from_tensor() ? +// +CircleConst *create_circleconst(GraphBuilderContext *context, int32_t tensor_index) +{ + LOGGER(l); + + auto graph = context->graph(); + auto reader = context->reader(); + const auto &tensors = reader->tensors(); + + // (1) create CircleConst + auto const_node = graph->nodes()->create<CircleConst>(); + const circle::TensorT &const_tensor = *tensors[tensor_index]; + const_node->name(tensor_name(const_tensor)); + auto quantization = luci::tensor_quantization(const_tensor); + if (quantization) + { + auto quantparam = luci::luci_quantparam(quantization); + if (quantparam.get()) + const_node->quantparam(std::move(quantparam)); + } + + INFO(l) << "[luci] NodeFinder const_node(" << tensor_index << ") -> " << const_node << std::endl; + + // (2) set data_type to CircleConst + const_node->dtype(luci_datatype(const_tensor.type)); + + // (3) set shape to CicleConst + std::vector<int32_t> const_dims = const_tensor.shape; // in NHWC + const_node->rank(const_dims.size()); + uint32_t num_elements = 1; + for (uint32_t r = 0; r < const_dims.size(); ++r) + { + const_node->dim(r) = loco::Dimension(const_dims[r]); + num_elements = num_elements * const_dims[r]; + } + + // (4) constant values from circle buffer + const std::vector<uint8_t> &buffer = reader->buffers()[const_tensor.buffer]->data; + if (buffer.empty()) + throw oops::UserExn("Empty buffer"); + + switch (luci_datatype(const_tensor.type)) + { + case loco::DataType::FLOAT32: + copy_data<loco::DataType::FLOAT32>(buffer, num_elements, const_node); + break; + + case loco::DataType::U8: + copy_data<loco::DataType::U8>(buffer, num_elements, const_node); + break; + + case loco::DataType::S32: + copy_data<loco::DataType::S32>(buffer, num_elements, const_node); + break; + + default: + throw oops::UserExn("Unsupported tensor type", circle::EnumNameTensorType(const_tensor.type)); + } + + return const_node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleConv2D.cpp b/compiler/luci/import/src/Nodes/CircleConv2D.cpp new file mode 100644 index 000000000..ec9dce0d2 --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleConv2D.cpp @@ -0,0 +1,58 @@ +/* + * 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/Import/Nodes/CircleConv2D.h" + +#include <luci/IR/Nodes/CircleConv2D.h> + +#include <loco.h> + +#include <cassert> + +namespace luci +{ + +bool CircleConv2DGraphBuilder::validate(const ValidateArgs &args) const +{ + // Circle Conv2D may not have a bias but we won't support this + if (args.op.inputs.size() != 3) + return false; + + return true; +} + +CircleNode *CircleConv2DGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleConv2D>(); + node->input(inputs[0]); + node->filter(inputs[1]); + // For now, bias is required (checked in `verify` method). + assert(inputs.size() == 3); + node->bias(inputs[2]); + + const auto *options = op.builtin_options.AsConv2DOptions(); + node->padding(luci_padding(options->padding)); + node->stride()->w(options->stride_w); + node->stride()->h(options->stride_h); + node->fusedActivationFunction(luci_actfunc(options->fused_activation_function)); + // FIXME Check dilation_w_factor, dilation_h_factor. + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleCos.cpp b/compiler/luci/import/src/Nodes/CircleCos.cpp new file mode 100644 index 000000000..5f61cc7f6 --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleCos.cpp @@ -0,0 +1,46 @@ +/* + * 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/Import/Nodes/CircleCos.h" + +#include <luci/IR/Nodes/CircleCos.h> + +#include <loco.h> + +namespace luci +{ + +bool CircleCosGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 1) + return false; + + return true; +} + +CircleNode *CircleCosGraphBuilder::build_node(const circle::OperatorT &, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleCos>(); + node->x(inputs[0]); + + // No options for Cos + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleDepthwiseConv2D.cpp b/compiler/luci/import/src/Nodes/CircleDepthwiseConv2D.cpp new file mode 100644 index 000000000..c6d3b1f1e --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleDepthwiseConv2D.cpp @@ -0,0 +1,60 @@ +/* + * 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/Import/Nodes/CircleDepthwiseConv2D.h" + +#include <luci/IR/Nodes/CircleDepthwiseConv2D.h> + +#include <oops/UserExn.h> + +namespace luci +{ + +bool CircleDepthwiseConv2DGraphBuilder::validate(const ValidateArgs &args) const +{ + // Circle DepthwiseConv2D may not have a bias but we won't support this + if (args.op.inputs.size() != 3 && args.op.inputs.size() != 2) + return false; + + if (args.op.outputs.size() != 1) + return false; + + return true; +} + +CircleNode *CircleDepthwiseConv2DGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleDepthwiseConv2D>(); + node->input(inputs[0]); + node->filter(inputs[1]); + if (inputs.size() != 3) + throw oops::UserExn("DepthwiseConv2d without bias is unsupported"); + node->bias(inputs[2]); + + const auto *options = op.builtin_options.AsDepthwiseConv2DOptions(); + node->padding(luci_padding(options->padding)); + node->stride()->w(options->stride_w); + node->stride()->h(options->stride_h); + node->depthMultiplier(options->depth_multiplier); + node->fusedActivationFunction(luci_actfunc(options->fused_activation_function)); + // FIXME Check dilation_w_factor, dilation_h_factor. + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleDiv.cpp b/compiler/luci/import/src/Nodes/CircleDiv.cpp new file mode 100644 index 000000000..d09cfb815 --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleDiv.cpp @@ -0,0 +1,49 @@ +/* + * 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/Import/Nodes/CircleDiv.h" + +#include <luci/IR/Nodes/CircleDiv.h> + +namespace luci +{ + +bool CircleDivGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 2) + return false; + + if (args.op.outputs.size() != 1) + return false; + + return true; +} + +CircleNode *CircleDivGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto node = graph->nodes()->create<CircleDiv>(); + node->x(inputs[0]); + node->y(inputs[1]); + + const auto *options = op.builtin_options.AsDivOptions(); + node->fusedActivationFunction(luci_actfunc(options->fused_activation_function)); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleEqual.cpp b/compiler/luci/import/src/Nodes/CircleEqual.cpp new file mode 100644 index 000000000..a53f6e94b --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleEqual.cpp @@ -0,0 +1,51 @@ +/* + * 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/Import/Nodes/CircleEqual.h" + +#include <luci/IR/Nodes/CircleEqual.h> + +#include <loco.h> + +namespace luci +{ + +bool CircleEqualGraphBuilder::validate(const ValidateArgs &args) const +{ + const auto &inputs = args.op.inputs; + + if (inputs.size() != 2) + { + return false; + } + + const auto &tensors = args.reader.tensors(); + + return tensors[inputs[0]]->type == tensors[inputs[1]]->type; +} + +CircleNode *CircleEqualGraphBuilder::build_node(const circle::OperatorT &, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleEqual>(); + node->x(inputs[0]); + node->y(inputs[1]); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleExp.cpp b/compiler/luci/import/src/Nodes/CircleExp.cpp new file mode 100644 index 000000000..44fc93d09 --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleExp.cpp @@ -0,0 +1,59 @@ +/* + * 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/Import/Nodes/CircleExp.h" + +#include <luci/IR/Nodes/CircleAbs.h> + +#include <loco.h> + +namespace luci +{ + +bool CircleExpGraphBuilder::validate(const ValidateArgs &args) const +{ + const auto &inputs = args.op.inputs; + if (inputs.size() != 1) + return false; + + // input type check + const auto &tensors = args.reader.tensors(); + const auto &tensor = tensors.at(inputs[0]); + switch (tensor->type) + { + case circle::TensorType_FLOAT16: + case circle::TensorType_FLOAT32: + case circle::TensorType_FLOAT64: + break; + // TODO support TensorType_COMPLEX64, complex128, bfloat16 + default: + return false; + } + + return true; +} + +CircleNode *CircleExpGraphBuilder::build_node(const circle::OperatorT &, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleAbs>(); + node->x(inputs[0]); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleFullyConnected.cpp b/compiler/luci/import/src/Nodes/CircleFullyConnected.cpp new file mode 100644 index 000000000..8f74fe9ce --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleFullyConnected.cpp @@ -0,0 +1,56 @@ +/* + * 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/Import/Nodes/CircleFullyConnected.h" + +#include <luci/IR/Nodes/CircleFullyConnected.h> + +#include <loco.h> +#include <oops/UserExn.h> + +namespace luci +{ + +bool CircleFullyConnectedGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 3) + return false; + + return true; +} + +CircleNode *CircleFullyConnectedGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleFullyConnected>(); + node->input(inputs[0]); + node->weights(inputs[1]); + node->bias(inputs[2]); + + const auto *options = op.builtin_options.AsFullyConnectedOptions(); + node->fusedActivationFunction(luci_actfunc(options->fused_activation_function)); + if (options->weights_format != circle::FullyConnectedOptionsWeightsFormat_DEFAULT) + { + throw oops::UserExn( + "Unsupported weights format", + circle::EnumNameFullyConnectedOptionsWeightsFormat(options->weights_format)); + } + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleLogicalNot.cpp b/compiler/luci/import/src/Nodes/CircleLogicalNot.cpp new file mode 100644 index 000000000..b1ed3ea37 --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleLogicalNot.cpp @@ -0,0 +1,51 @@ +/* + * 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/Import/Nodes/CircleLogicalNot.h" + +#include <luci/IR/Nodes/CircleLogicalNot.h> + +#include <loco.h> + +namespace luci +{ + +bool CircleLogicalNotGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 1) + return false; + + // Only BOOL type is allowed for the input + const auto &inputs = args.op.inputs; + const auto &tensors = args.reader.tensors(); + const auto &tensor = tensors.at(inputs[0]); + if (tensor->type != circle::TensorType::TensorType_BOOL) + return false; + + return true; +} + +CircleNode *CircleLogicalNotGraphBuilder::build_node(const circle::OperatorT &, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleLogicalNot>(); + node->x(inputs[0]); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleLogicalOr.cpp b/compiler/luci/import/src/Nodes/CircleLogicalOr.cpp new file mode 100644 index 000000000..00eb9c5df --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleLogicalOr.cpp @@ -0,0 +1,55 @@ +/* + * 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/Import/Nodes/CircleLogicalOr.h" + +#include <luci/IR/Nodes/CircleLogicalOr.h> + +#include <loco.h> + +namespace luci +{ + +bool CircleLogicalOrGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 2) + return false; + + // Only BOOL type is allowed for inputs + const auto &inputs = args.op.inputs; + const auto &tensors = args.reader.tensors(); + for (auto input : inputs) + { + const auto &tensor = tensors.at(input); + if (tensor->type != circle::TensorType::TensorType_BOOL) + return false; + } + + return true; +} + +CircleNode *CircleLogicalOrGraphBuilder::build_node(const circle::OperatorT &, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleLogicalOr>(); + node->x(inputs[0]); + node->y(inputs[1]); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleMaxPool2D.cpp b/compiler/luci/import/src/Nodes/CircleMaxPool2D.cpp new file mode 100644 index 000000000..1798819cf --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleMaxPool2D.cpp @@ -0,0 +1,52 @@ +/* + * 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/Import/Nodes/CircleMaxPool2D.h" + +#include <luci/IR/Nodes/CircleMaxPool2D.h> + +#include <loco.h> + +namespace luci +{ + +bool CircleMaxPool2DGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 1) + return false; + + return true; +} + +CircleNode *CircleMaxPool2DGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleMaxPool2D>(); + node->value(inputs[0]); + + const auto *options = op.builtin_options.AsPool2DOptions(); + node->padding(luci_padding(options->padding)); + node->stride()->w(options->stride_w); + node->stride()->h(options->stride_h); + node->filter()->w(options->filter_width); + node->filter()->h(options->filter_height); + node->fusedActivationFunction(luci_actfunc(options->fused_activation_function)); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleMean.cpp b/compiler/luci/import/src/Nodes/CircleMean.cpp new file mode 100644 index 000000000..8261c7b38 --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleMean.cpp @@ -0,0 +1,46 @@ +/* + * 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/Import/Nodes/CircleMean.h" + +#include <luci/IR/Nodes/CircleMean.h> + +namespace luci +{ + +bool CircleMeanGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 2) + return false; + + return true; +} + +CircleNode *CircleMeanGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleMean>(); + node->input(inputs[0]); + node->reduction_indices(inputs[1]); + + const auto *options = op.builtin_options.AsReducerOptions(); + node->keep_dims(options->keep_dims); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleMul.cpp b/compiler/luci/import/src/Nodes/CircleMul.cpp new file mode 100644 index 000000000..d4412b96b --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleMul.cpp @@ -0,0 +1,49 @@ +/* + * 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/Import/Nodes/CircleMul.h" + +#include <luci/IR/Nodes/CircleMul.h> + +namespace luci +{ + +bool CircleMulGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 2) + return false; + + if (args.op.outputs.size() != 1) + return false; + + return true; +} + +CircleNode *CircleMulGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleMul>(); + node->x(inputs[0]); + node->y(inputs[1]); + + const auto *options = op.builtin_options.AsMulOptions(); + node->fusedActivationFunction(luci_actfunc(options->fused_activation_function)); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CirclePack.cpp b/compiler/luci/import/src/Nodes/CirclePack.cpp new file mode 100644 index 000000000..6ba6fae11 --- /dev/null +++ b/compiler/luci/import/src/Nodes/CirclePack.cpp @@ -0,0 +1,61 @@ +/* + * 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/Import/Nodes/CirclePack.h" + +#include <luci/IR/Nodes/CirclePack.h> + +#include <loco.h> +#include <oops/UserExn.h> + +namespace luci +{ + +bool CirclePackGraphBuilder::validate(const ValidateArgs &args) const +{ + const auto &inputs = args.op.inputs; + const auto &outputs = args.op.outputs; + const auto *options = args.op.builtin_options.AsPackOptions(); + + if (options->values_count < 1) + return false; + + if (inputs.size() != static_cast<uint32_t>(options->values_count)) + return false; + + if (outputs.size() != 1) + return false; + + return true; +} + +CircleNode *CirclePackGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CirclePack>(inputs.size()); + for (uint32_t i = 0; i < inputs.size(); ++i) + { + node->values(i, inputs[i]); + } + + const auto *options = op.builtin_options.AsPackOptions(); + node->axis(options->axis); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CirclePad.cpp b/compiler/luci/import/src/Nodes/CirclePad.cpp new file mode 100644 index 000000000..6abcf2d6c --- /dev/null +++ b/compiler/luci/import/src/Nodes/CirclePad.cpp @@ -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. + */ + +#include "luci/Import/Nodes/CirclePad.h" + +#include <luci/IR/Nodes/CirclePad.h> + +#include <loco.h> + +namespace luci +{ + +bool CirclePadGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 2) + return false; + + // TODO do attribute checks + + return true; +} + +CircleNode *CirclePadGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CirclePad>(); + node->input(inputs[0]); + node->paddings(inputs[1]); + + const auto *options = op.builtin_options.AsPadOptions(); + (void)options; // There are no options. + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleRelu.cpp b/compiler/luci/import/src/Nodes/CircleRelu.cpp new file mode 100644 index 000000000..056268a5b --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleRelu.cpp @@ -0,0 +1,47 @@ +/* + * 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/Import/Nodes/CircleRelu.h" + +#include <luci/IR/Nodes/CircleRelu.h> + +#include <loco.h> + +namespace luci +{ + +bool CircleReluGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 1) + return false; + + if (args.op.outputs.size() != 1) + return false; + + return true; +} + +CircleNode *CircleReluGraphBuilder::build_node(const circle::OperatorT &, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleRelu>(); + node->features(inputs[0]); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleReshape.cpp b/compiler/luci/import/src/Nodes/CircleReshape.cpp new file mode 100644 index 000000000..c83f143a6 --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleReshape.cpp @@ -0,0 +1,82 @@ +/* + * 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/Import/Nodes/CircleReshape.h" + +#include <luci/IR/Nodes/CircleConst.h> +#include <luci/IR/Nodes/CircleReshape.h> + +namespace luci +{ + +bool CircleReshapeGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 1 && args.op.inputs.size() != 2) + return false; + + if (args.op.outputs.size() != 1) + return false; + + return true; +} + +static void setup_shape_attribute(const std::vector<int32_t> &shape, CircleReshape *node) +{ + node->newShape()->rank(shape.size()); + for (uint32_t i = 0; i < shape.size(); ++i) + { + node->newShape()->dim(i) = shape[i]; + } +} + +static CircleNode *create_shape_node(const std::vector<int32_t> &shape, loco::Graph *graph) +{ + auto *shape_node = graph->nodes()->create<luci::CircleConst>(); + shape_node->dtype(loco::DataType::S32); + shape_node->rank(1); + shape_node->dim(0) = shape.size(); + shape_node->size<loco::DataType::S32>(shape.size()); + for (uint32_t i = 0; i < shape.size(); ++i) + { + shape_node->at<loco::DataType::S32>(i) = shape[i]; + } + return shape_node; +} + +CircleNode *CircleReshapeGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + // If the second input is not provided, generate it based on the value of the attribute. + // TODO Presence of the second input is the current requirement of the IR. + auto *shape_node = (inputs.size() == 2) ? inputs[1] : nullptr; + if (shape_node == nullptr) + { + const auto *options = op.builtin_options.AsReshapeOptions(); + shape_node = create_shape_node(options->new_shape, graph); + } + + auto *node = graph->nodes()->create<CircleReshape>(); + node->tensor(inputs[0]); + node->shape(shape_node); + + const auto *options = op.builtin_options.AsReshapeOptions(); + setup_shape_attribute(options->new_shape, node); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleRsqrt.cpp b/compiler/luci/import/src/Nodes/CircleRsqrt.cpp new file mode 100644 index 000000000..b5de0b575 --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleRsqrt.cpp @@ -0,0 +1,60 @@ +/* + * 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/Import/Nodes/CircleRsqrt.h" + +#include <luci/IR/Nodes/CircleRsqrt.h> + +#include <loco.h> + +namespace luci +{ + +bool CircleRsqrtGraphBuilder::validate(const ValidateArgs &args) const +{ + const auto &inputs = args.op.inputs; + if (inputs.size() != 1) + return false; + + // Must be one of the following types + // bfloat16, half (float16), float32, float64, complex64, complex128 + // Currently, circle supports float16, float32, complex64 + const auto &tensors = args.reader.tensors(); + const auto &tensor = tensors.at(inputs[0]); + switch (tensor->type) + { + case circle::TensorType_FLOAT16: + case circle::TensorType_FLOAT32: + case circle::TensorType_COMPLEX64: + break; + default: + return false; + } + + return true; +} + +CircleNode *CircleRsqrtGraphBuilder::build_node(const circle::OperatorT &, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleRsqrt>(); + node->x(inputs[0]); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleSoftmax.cpp b/compiler/luci/import/src/Nodes/CircleSoftmax.cpp new file mode 100644 index 000000000..0d316e18c --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleSoftmax.cpp @@ -0,0 +1,49 @@ +/* + * 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/Import/Nodes/CircleSoftmax.h" + +#include <luci/IR/Nodes/CircleSoftmax.h> + +#include <loco.h> + +namespace luci +{ + +bool CircleSoftmaxGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 1) + return false; + + // TODO do attribute checks + + return true; +} + +CircleNode *CircleSoftmaxGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleSoftmax>(); + node->logits(inputs[0]); + + const auto *options = op.builtin_options.AsSoftmaxOptions(); + node->beta(options->beta); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleSub.cpp b/compiler/luci/import/src/Nodes/CircleSub.cpp new file mode 100644 index 000000000..968e9f51f --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleSub.cpp @@ -0,0 +1,51 @@ +/* + * 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/Import/Nodes/CircleSub.h" + +#include <luci/IR/Nodes/CircleSub.h> + +#include <loco.h> + +namespace luci +{ + +bool CircleSubGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 2) + return false; + + if (args.op.outputs.size() != 1) + return false; + + return true; +} + +CircleNode *CircleSubGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleSub>(); + node->x(inputs[0]); + node->y(inputs[1]); + + const auto *options = op.builtin_options.AsSubOptions(); + node->fusedActivationFunction(luci_actfunc(options->fused_activation_function)); + + return node; +} + +} // namespace luci diff --git a/compiler/luci/import/src/Nodes/CircleTranspose.cpp b/compiler/luci/import/src/Nodes/CircleTranspose.cpp new file mode 100644 index 000000000..8622c8b80 --- /dev/null +++ b/compiler/luci/import/src/Nodes/CircleTranspose.cpp @@ -0,0 +1,51 @@ +/* + * 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/Import/Nodes/CircleTranspose.h" + +#include <luci/IR/Nodes/CircleTranspose.h> + +#include <loco.h> + +namespace luci +{ + +bool CircleTransposeGraphBuilder::validate(const ValidateArgs &args) const +{ + if (args.op.inputs.size() != 2) + return false; + + if (args.op.outputs.size() != 1) + return false; + + return true; +} + +CircleNode *CircleTransposeGraphBuilder::build_node(const circle::OperatorT &op, + const std::vector<CircleNode *> &inputs, + loco::Graph *graph) const +{ + auto *node = graph->nodes()->create<CircleTranspose>(); + node->a(inputs[0]); + node->perm(inputs[1]); + + const auto *options = op.builtin_options.AsTransposeOptions(); + (void)options; + + return node; +} + +} // namespace luci |