summaryrefslogtreecommitdiff
path: root/compiler/luci/import
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/luci/import')
-rw-r--r--compiler/luci/import/CMakeLists.txt26
-rw-r--r--compiler/luci/import/README.md3
-rw-r--r--compiler/luci/import/include/luci/Import/CircleReader.h87
-rw-r--r--compiler/luci/import/include/luci/Import/GraphBuilder.h56
-rw-r--r--compiler/luci/import/include/luci/Import/GraphBuilderContext.h79
-rw-r--r--compiler/luci/import/include/luci/Import/GraphBuilderRegistry.h85
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes.h48
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleAbs.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleAdd.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleArgMax.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleAveragePool2D.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleBatchToSpaceND.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleConcatenation.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleConst.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleConv2D.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleCos.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleDepthwiseConv2D.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleDiv.h36
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleEqual.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleExp.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleFullyConnected.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleLogicalNot.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleLogicalOr.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleMaxPool2D.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleMean.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleMul.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CirclePack.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CirclePad.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleRelu.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleReshape.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleRsqrt.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleSoftmax.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleSub.h37
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleTranspose.h37
-rw-r--r--compiler/luci/import/include/luci/Importer.h54
-rw-r--r--compiler/luci/import/src/CircleReader.cpp211
-rw-r--r--compiler/luci/import/src/GraphBuilder.cpp61
-rw-r--r--compiler/luci/import/src/GraphBuilderContext.cpp47
-rw-r--r--compiler/luci/import/src/GraphBuilderRegistry.cpp163
-rw-r--r--compiler/luci/import/src/Importer.cpp253
-rw-r--r--compiler/luci/import/src/Importer.test.cpp23
-rw-r--r--compiler/luci/import/src/Nodes/CircleAbs.cpp44
-rw-r--r--compiler/luci/import/src/Nodes/CircleAdd.cpp48
-rw-r--r--compiler/luci/import/src/Nodes/CircleArgMax.cpp48
-rw-r--r--compiler/luci/import/src/Nodes/CircleAveragePool2D.cpp50
-rw-r--r--compiler/luci/import/src/Nodes/CircleBatchToSpaceND.cpp80
-rw-r--r--compiler/luci/import/src/Nodes/CircleConcatenation.cpp52
-rw-r--r--compiler/luci/import/src/Nodes/CircleConst.cpp110
-rw-r--r--compiler/luci/import/src/Nodes/CircleConv2D.cpp58
-rw-r--r--compiler/luci/import/src/Nodes/CircleCos.cpp46
-rw-r--r--compiler/luci/import/src/Nodes/CircleDepthwiseConv2D.cpp60
-rw-r--r--compiler/luci/import/src/Nodes/CircleDiv.cpp49
-rw-r--r--compiler/luci/import/src/Nodes/CircleEqual.cpp51
-rw-r--r--compiler/luci/import/src/Nodes/CircleExp.cpp59
-rw-r--r--compiler/luci/import/src/Nodes/CircleFullyConnected.cpp56
-rw-r--r--compiler/luci/import/src/Nodes/CircleLogicalNot.cpp51
-rw-r--r--compiler/luci/import/src/Nodes/CircleLogicalOr.cpp55
-rw-r--r--compiler/luci/import/src/Nodes/CircleMaxPool2D.cpp52
-rw-r--r--compiler/luci/import/src/Nodes/CircleMean.cpp46
-rw-r--r--compiler/luci/import/src/Nodes/CircleMul.cpp49
-rw-r--r--compiler/luci/import/src/Nodes/CirclePack.cpp61
-rw-r--r--compiler/luci/import/src/Nodes/CirclePad.cpp50
-rw-r--r--compiler/luci/import/src/Nodes/CircleRelu.cpp47
-rw-r--r--compiler/luci/import/src/Nodes/CircleReshape.cpp82
-rw-r--r--compiler/luci/import/src/Nodes/CircleRsqrt.cpp60
-rw-r--r--compiler/luci/import/src/Nodes/CircleSoftmax.cpp49
-rw-r--r--compiler/luci/import/src/Nodes/CircleSub.cpp51
-rw-r--r--compiler/luci/import/src/Nodes/CircleTranspose.cpp51
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