summaryrefslogtreecommitdiff
path: root/compiler/coco/core
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/coco/core')
-rw-r--r--compiler/coco/core/CMakeLists.txt25
-rw-r--r--compiler/coco/core/include/coco/ADT/DLinkedList.h288
-rw-r--r--compiler/coco/core/include/coco/ADT/PtrList.h54
-rw-r--r--compiler/coco/core/include/coco/ADT/PtrManager.h67
-rw-r--r--compiler/coco/core/include/coco/IR.h34
-rw-r--r--compiler/coco/core/include/coco/IR/Arg.h80
-rw-r--r--compiler/coco/core/include/coco/IR/Bag.h164
-rw-r--r--compiler/coco/core/include/coco/IR/BagManager.h47
-rw-r--r--compiler/coco/core/include/coco/IR/Block.forward.h27
-rw-r--r--compiler/coco/core/include/coco/IR/Block.h78
-rw-r--r--compiler/coco/core/include/coco/IR/BlockIndex.h63
-rw-r--r--compiler/coco/core/include/coco/IR/BlockManager.h47
-rw-r--r--compiler/coco/core/include/coco/IR/Def.forward.h27
-rw-r--r--compiler/coco/core/include/coco/IR/Def.h52
-rw-r--r--compiler/coco/core/include/coco/IR/Dep.forward.h27
-rw-r--r--compiler/coco/core/include/coco/IR/Dep.h59
-rw-r--r--compiler/coco/core/include/coco/IR/DepSet.h31
-rw-r--r--compiler/coco/core/include/coco/IR/ElemID.h51
-rw-r--r--compiler/coco/core/include/coco/IR/Entity.h51
-rw-r--r--compiler/coco/core/include/coco/IR/EntityBuilder.h48
-rw-r--r--compiler/coco/core/include/coco/IR/EntityManager.h67
-rw-r--r--compiler/coco/core/include/coco/IR/FeatureLayout.h54
-rw-r--r--compiler/coco/core/include/coco/IR/FeatureLayouts.h159
-rw-r--r--compiler/coco/core/include/coco/IR/FeatureObject.forward.h27
-rw-r--r--compiler/coco/core/include/coco/IR/FeatureObject.h63
-rw-r--r--compiler/coco/core/include/coco/IR/FeatureShape.h70
-rw-r--r--compiler/coco/core/include/coco/IR/Input.forward.h27
-rw-r--r--compiler/coco/core/include/coco/IR/Input.h44
-rw-r--r--compiler/coco/core/include/coco/IR/InputList.h31
-rw-r--r--compiler/coco/core/include/coco/IR/InputManager.h39
-rw-r--r--compiler/coco/core/include/coco/IR/Instr.forward.h28
-rw-r--r--compiler/coco/core/include/coco/IR/Instr.h161
-rw-r--r--compiler/coco/core/include/coco/IR/Instr.lst9
-rw-r--r--compiler/coco/core/include/coco/IR/InstrIndex.h63
-rw-r--r--compiler/coco/core/include/coco/IR/InstrManager.h66
-rw-r--r--compiler/coco/core/include/coco/IR/Instrs.h175
-rw-r--r--compiler/coco/core/include/coco/IR/KernelLayout.h58
-rw-r--r--compiler/coco/core/include/coco/IR/KernelLayouts.h117
-rw-r--r--compiler/coco/core/include/coco/IR/KernelObject.forward.h27
-rw-r--r--compiler/coco/core/include/coco/IR/KernelObject.h65
-rw-r--r--compiler/coco/core/include/coco/IR/Locatable.h37
-rw-r--r--compiler/coco/core/include/coco/IR/Module.forward.h27
-rw-r--r--compiler/coco/core/include/coco/IR/Module.h67
-rw-r--r--compiler/coco/core/include/coco/IR/Object.forward.h27
-rw-r--r--compiler/coco/core/include/coco/IR/Object.h144
-rw-r--r--compiler/coco/core/include/coco/IR/ObjectManager.h53
-rw-r--r--compiler/coco/core/include/coco/IR/ObjectSet.h31
-rw-r--r--compiler/coco/core/include/coco/IR/Op.forward.h27
-rw-r--r--compiler/coco/core/include/coco/IR/Op.h255
-rw-r--r--compiler/coco/core/include/coco/IR/Op.lst19
-rw-r--r--compiler/coco/core/include/coco/IR/OpManager.h63
-rw-r--r--compiler/coco/core/include/coco/IR/Ops.h412
-rw-r--r--compiler/coco/core/include/coco/IR/Output.forward.h27
-rw-r--r--compiler/coco/core/include/coco/IR/Output.h44
-rw-r--r--compiler/coco/core/include/coco/IR/OutputList.h31
-rw-r--r--compiler/coco/core/include/coco/IR/OutputManager.h39
-rw-r--r--compiler/coco/core/include/coco/IR/Padding2D.h65
-rw-r--r--compiler/coco/core/include/coco/IR/Part.forward.h27
-rw-r--r--compiler/coco/core/include/coco/IR/Part.h53
-rw-r--r--compiler/coco/core/include/coco/IR/Read.forward.h27
-rw-r--r--compiler/coco/core/include/coco/IR/Read.h55
-rw-r--r--compiler/coco/core/include/coco/IR/ReadSet.h31
-rw-r--r--compiler/coco/core/include/coco/IR/Step.forward.h27
-rw-r--r--compiler/coco/core/include/coco/IR/Step.h54
-rw-r--r--compiler/coco/core/include/coco/IR/Stride2D.h54
-rw-r--r--compiler/coco/core/include/coco/IR/Update.forward.h27
-rw-r--r--compiler/coco/core/include/coco/IR/Update.h51
-rw-r--r--compiler/coco/core/include/coco/IR/UpdateSet.h31
-rw-r--r--compiler/coco/core/include/coco/IR/Use.forward.h27
-rw-r--r--compiler/coco/core/include/coco/IR/Use.h52
-rw-r--r--compiler/coco/core/include/coco/IR/UseSet.h31
-rw-r--r--compiler/coco/core/include/coco/IR/Window2D.h55
-rw-r--r--compiler/coco/core/src/ADT/DLinkedList.test.cpp281
-rw-r--r--compiler/coco/core/src/ADT/PtrList.cpp19
-rw-r--r--compiler/coco/core/src/ADT/PtrList.test.cpp47
-rw-r--r--compiler/coco/core/src/ADT/PtrManager.test.cpp99
-rw-r--r--compiler/coco/core/src/IR.test.cpp303
-rw-r--r--compiler/coco/core/src/IR/Arg.cpp78
-rw-r--r--compiler/coco/core/src/IR/Arg.test.cpp100
-rw-r--r--compiler/coco/core/src/IR/AvgPool2D.test.cpp113
-rw-r--r--compiler/coco/core/src/IR/Bag.cpp147
-rw-r--r--compiler/coco/core/src/IR/Bag.test.cpp30
-rw-r--r--compiler/coco/core/src/IR/BagManager.cpp33
-rw-r--r--compiler/coco/core/src/IR/BagManager.test.cpp38
-rw-r--r--compiler/coco/core/src/IR/Block.cpp56
-rw-r--r--compiler/coco/core/src/IR/Block.test.cpp28
-rw-r--r--compiler/coco/core/src/IR/BlockIndex.cpp30
-rw-r--r--compiler/coco/core/src/IR/BlockIndex.test.cpp50
-rw-r--r--compiler/coco/core/src/IR/BlockManager.cpp41
-rw-r--r--compiler/coco/core/src/IR/BlockManager.test.cpp60
-rw-r--r--compiler/coco/core/src/IR/Consumer.mock.h33
-rw-r--r--compiler/coco/core/src/IR/Conv2D.cpp75
-rw-r--r--compiler/coco/core/src/IR/Conv2D.test.cpp154
-rw-r--r--compiler/coco/core/src/IR/Def.cpp43
-rw-r--r--compiler/coco/core/src/IR/Def.test.cpp82
-rw-r--r--compiler/coco/core/src/IR/Dep.cpp53
-rw-r--r--compiler/coco/core/src/IR/Dep.test.cpp73
-rw-r--r--compiler/coco/core/src/IR/ElemID.cpp25
-rw-r--r--compiler/coco/core/src/IR/ElemID.test.cpp62
-rw-r--r--compiler/coco/core/src/IR/EntityManager.cpp20
-rw-r--r--compiler/coco/core/src/IR/Eval.cpp28
-rw-r--r--compiler/coco/core/src/IR/Eval.test.cpp60
-rw-r--r--compiler/coco/core/src/IR/FeatureLayouts.cpp211
-rw-r--r--compiler/coco/core/src/IR/FeatureLayouts.test.cpp66
-rw-r--r--compiler/coco/core/src/IR/FeatureObject.cpp31
-rw-r--r--compiler/coco/core/src/IR/FeatureObject.test.cpp122
-rw-r--r--compiler/coco/core/src/IR/FeatureShape.test.cpp29
-rw-r--r--compiler/coco/core/src/IR/Input.cpp41
-rw-r--r--compiler/coco/core/src/IR/Input.test.cpp79
-rw-r--r--compiler/coco/core/src/IR/InputManager.cpp31
-rw-r--r--compiler/coco/core/src/IR/InputManager.test.cpp29
-rw-r--r--compiler/coco/core/src/IR/Instr.cpp56
-rw-r--r--compiler/coco/core/src/IR/InstrIndex.cpp30
-rw-r--r--compiler/coco/core/src/IR/InstrIndex.test.cpp50
-rw-r--r--compiler/coco/core/src/IR/InstrManager.cpp33
-rw-r--r--compiler/coco/core/src/IR/InstrManager.test.cpp52
-rw-r--r--compiler/coco/core/src/IR/KernelLayouts.cpp155
-rw-r--r--compiler/coco/core/src/IR/KernelLayouts.test.cpp126
-rw-r--r--compiler/coco/core/src/IR/KernelObject.cpp42
-rw-r--r--compiler/coco/core/src/IR/KernelObject.test.cpp78
-rw-r--r--compiler/coco/core/src/IR/Load.cpp53
-rw-r--r--compiler/coco/core/src/IR/MaxPool2D.test.cpp101
-rw-r--r--compiler/coco/core/src/IR/Module.cpp150
-rw-r--r--compiler/coco/core/src/IR/Module.test.cpp196
-rw-r--r--compiler/coco/core/src/IR/Object.cpp116
-rw-r--r--compiler/coco/core/src/IR/Object.test.cpp110
-rw-r--r--compiler/coco/core/src/IR/ObjectManager.cpp52
-rw-r--r--compiler/coco/core/src/IR/ObjectManager.test.cpp57
-rw-r--r--compiler/coco/core/src/IR/Op.cpp153
-rw-r--r--compiler/coco/core/src/IR/OpManager.cpp99
-rw-r--r--compiler/coco/core/src/IR/OpManager.test.cpp120
-rw-r--r--compiler/coco/core/src/IR/Ops.cpp22
-rw-r--r--compiler/coco/core/src/IR/Ops.test.cpp129
-rw-r--r--compiler/coco/core/src/IR/Output.cpp41
-rw-r--r--compiler/coco/core/src/IR/Output.test.cpp83
-rw-r--r--compiler/coco/core/src/IR/OutputManager.cpp31
-rw-r--r--compiler/coco/core/src/IR/OutputManager.test.cpp29
-rw-r--r--compiler/coco/core/src/IR/PadF.test.cpp89
-rw-r--r--compiler/coco/core/src/IR/Padding2D.cpp46
-rw-r--r--compiler/coco/core/src/IR/Padding2D.test.cpp51
-rw-r--r--compiler/coco/core/src/IR/Part.cpp45
-rw-r--r--compiler/coco/core/src/IR/Part.test.cpp70
-rw-r--r--compiler/coco/core/src/IR/Producer.mock.h33
-rw-r--r--compiler/coco/core/src/IR/ReLU.test.cpp85
-rw-r--r--compiler/coco/core/src/IR/ReLU6.test.cpp85
-rw-r--r--compiler/coco/core/src/IR/Read.cpp49
-rw-r--r--compiler/coco/core/src/IR/Read.test.cpp81
-rw-r--r--compiler/coco/core/src/IR/Reader.mock.h33
-rw-r--r--compiler/coco/core/src/IR/Shuffle.cpp41
-rw-r--r--compiler/coco/core/src/IR/Shuffle.test.cpp95
-rw-r--r--compiler/coco/core/src/IR/Sqrt.test.cpp85
-rw-r--r--compiler/coco/core/src/IR/Step.cpp52
-rw-r--r--compiler/coco/core/src/IR/Stride2D.cpp34
-rw-r--r--compiler/coco/core/src/IR/Stride2D.test.cpp45
-rw-r--r--compiler/coco/core/src/IR/Sub.test.cpp87
-rw-r--r--compiler/coco/core/src/IR/Update.cpp49
-rw-r--r--compiler/coco/core/src/IR/Update.test.cpp81
-rw-r--r--compiler/coco/core/src/IR/Updater.mock.h33
-rw-r--r--compiler/coco/core/src/IR/Use.cpp43
-rw-r--r--compiler/coco/core/src/IR/Use.test.cpp86
-rw-r--r--compiler/coco/core/src/IR/Window2D.test.cpp46
161 files changed, 11148 insertions, 0 deletions
diff --git a/compiler/coco/core/CMakeLists.txt b/compiler/coco/core/CMakeLists.txt
new file mode 100644
index 000000000..8c6844733
--- /dev/null
+++ b/compiler/coco/core/CMakeLists.txt
@@ -0,0 +1,25 @@
+file(GLOB_RECURSE SOURCES "src/*.cpp")
+file(GLOB_RECURSE TESTS "src/*.test.cpp")
+list(REMOVE_ITEM SOURCES ${TESTS})
+
+add_library(coco_core SHARED ${SOURCES})
+target_include_directories(coco_core PUBLIC include)
+# NOTE Some coco_core PUBLIC headers include angkor headers
+target_link_libraries(coco_core PUBLIC angkor)
+target_link_libraries(coco_core PRIVATE pepper_assert)
+target_link_libraries(coco_core PRIVATE stdex)
+# Let's apply nncc common compile options
+# NOTE This will enable strict compilation (warnings as error).
+# Please refer to top-level CMakeLists.txt for details
+target_link_libraries(coco_core PRIVATE nncc_common)
+
+if(NOT ENABLE_TEST)
+ return()
+endif(NOT ENABLE_TEST)
+
+# Google Test is required for internal testing
+nnas_find_package(GTest REQUIRED)
+
+GTest_AddTest(coco_core_test ${TESTS})
+target_link_libraries(coco_core_test coco_core)
+target_link_libraries(coco_core_test stdex)
diff --git a/compiler/coco/core/include/coco/ADT/DLinkedList.h b/compiler/coco/core/include/coco/ADT/DLinkedList.h
new file mode 100644
index 000000000..e3c275041
--- /dev/null
+++ b/compiler/coco/core/include/coco/ADT/DLinkedList.h
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_ADT_DLINKED_LIST_H__
+#define __COCO_ADT_DLINKED_LIST_H__
+
+#include <cassert>
+#include <type_traits>
+
+namespace coco
+{
+
+// **CAUTION** Child SHOULD inherit DLinkedList<Child, Parent>::Node
+template <typename Child, typename Parent> struct DLinkedList
+{
+ /// @brief A hook for Child-Join event
+ static void joined(Parent *, Child *);
+ /// @brief A hook for Child-Leave event
+ static void leaving(Parent *, Child *);
+
+ class Head
+ {
+ public:
+ Head(Parent *parent) : _parent{parent}
+ {
+ _head = nullptr;
+ _tail = nullptr;
+ }
+
+ public:
+ Head(const Head &) = delete;
+ Head(Head &&) = delete;
+
+ public:
+ Child *head(void) const { return _head; }
+ Child *tail(void) const { return _tail; }
+
+ public:
+ bool empty(void) const
+ {
+ if (_head == nullptr)
+ {
+ assert(_head == _tail);
+ return true;
+ }
+
+ assert(_head != nullptr);
+ assert(_tail != nullptr);
+ return false;
+ }
+
+ public:
+ void enlist(Child *child)
+ {
+ assert((child->prev() == nullptr) || (child->prev()->parent() == _parent));
+ assert((child->next() == nullptr) || (child->next()->parent() == _parent));
+
+ if (empty())
+ {
+ _head = child;
+ _tail = child;
+ }
+ else
+ {
+ if (child->next() == _head)
+ {
+ // _child is a new head
+ assert(child->prev() == nullptr);
+ _head = child;
+ }
+
+ if (child->prev() == _tail)
+ {
+ // _child is a new tail
+ assert(child->next() == nullptr);
+ _tail = child;
+ }
+ }
+
+ // Update parent-child relation
+ child->parent(_parent);
+
+ // Notify Child-Joining event
+ joined(_parent, child);
+ }
+
+ public:
+ void delist(Child *child)
+ {
+ assert(child->parent() == _parent);
+ assert(!empty());
+
+ // Notify Child-Leaving event
+ leaving(_parent, child);
+
+ if (child == _head)
+ {
+ _head = child->next();
+ }
+
+ if (child == _tail)
+ {
+ _tail = child->prev();
+ }
+
+ // Update parent-child relation
+ child->parent(nullptr);
+ }
+
+ public:
+ void prepend(Child *child)
+ {
+ if (empty())
+ {
+ enlist(child);
+ }
+ else
+ {
+ child->insertBefore(_head);
+ }
+ }
+
+ public:
+ void append(Child *child)
+ {
+ if (empty())
+ {
+ enlist(child);
+ }
+ else
+ {
+ child->insertAfter(_tail);
+ }
+ }
+
+ private:
+ Parent *const _parent;
+
+ private:
+ Child *_head;
+ Child *_tail;
+ };
+
+ // NOTE Client SHOULD implement this static method
+ static Head *head(Parent *);
+
+ class Node
+ {
+ public:
+ friend class Head;
+
+ public:
+ Node()
+ {
+ static_assert(std::is_base_of<Node, Child>::value,
+ "Type `Child` must be subclass of `Node`.");
+
+ _prev = nullptr;
+ _next = nullptr;
+ }
+
+ public:
+ virtual ~Node()
+ {
+ // Each Child should unlink itself on destruction
+ //
+ // NOTE detach invokes "leaving" hook which may access the internal of each Child,
+ // so it is not safe to invoke detach here
+ assert(parent() == nullptr);
+ }
+
+ public:
+ Parent *parent(void) const { return _parent; }
+
+ private:
+ Child *curr(void) { return reinterpret_cast<Child *>(this); }
+ const Child *curr(void) const { return reinterpret_cast<const Child *>(this); }
+
+ public:
+ Child *prev(void) const { return _prev; }
+ Child *next(void) const { return _next; }
+
+ public:
+ void insertBefore(Node *next)
+ {
+ assert(next != nullptr);
+ assert(next->parent() != nullptr);
+ assert(head(next->parent()) != nullptr);
+
+ assert(_prev == nullptr);
+ assert(_next == nullptr);
+
+ // Update the link of the current node
+ _prev = next->prev();
+ _next = next->curr();
+
+ if (auto prev = next->prev())
+ {
+ prev->_next = curr();
+ }
+ next->_prev = curr();
+
+ // Update parent-child relation
+ assert(parent() == nullptr);
+ head(next->parent())->enlist(curr());
+ assert(parent() == next->parent());
+ }
+
+ public:
+ void insertAfter(Node *prev)
+ {
+ assert(prev != nullptr);
+ assert(prev->parent() != nullptr);
+ assert(head(prev->parent()) != nullptr);
+
+ assert(_prev == nullptr);
+ assert(_next == nullptr);
+
+ // Update the link of the current node
+ _prev = prev->curr();
+ _next = prev->next();
+
+ // Update the link of the sibling nodes
+ if (auto next = prev->next())
+ {
+ next->_prev = curr();
+ }
+ prev->_next = curr();
+
+ // Update parent-child relation
+ assert(parent() == nullptr);
+ head(prev->parent())->enlist(curr());
+ assert(parent() == prev->parent());
+ };
+
+ public:
+ void detach(void)
+ {
+ // Update parent-child relation
+ assert(parent() != nullptr);
+ assert(head(parent()) != nullptr);
+ head(parent())->delist(curr());
+ assert(parent() == nullptr);
+
+ // Update the link of sibling nodes
+ if (prev())
+ {
+ prev()->_next = next();
+ }
+
+ if (next())
+ {
+ next()->_prev = prev();
+ }
+
+ // Update the link of the current node
+ _prev = nullptr;
+ _next = nullptr;
+ }
+
+ private:
+ // WARN Do NOT invoke this method outside Head::enlist
+ void parent(Parent *p) { _parent = p; }
+
+ private:
+ // WARN Do NOT modify this field inside Node.
+ Parent *_parent = nullptr;
+ Child *_prev;
+ Child *_next;
+ };
+};
+
+} // namespace coco
+
+#endif // __COCO_ADT_DLINKED_LIST_H__
diff --git a/compiler/coco/core/include/coco/ADT/PtrList.h b/compiler/coco/core/include/coco/ADT/PtrList.h
new file mode 100644
index 000000000..37fead728
--- /dev/null
+++ b/compiler/coco/core/include/coco/ADT/PtrList.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_ADT_PTR_LIST_H__
+#define __COCO_ADT_PTR_LIST_H__
+
+#include <vector>
+
+#include <cstdint>
+
+namespace coco
+{
+
+template <typename T> class PtrList
+{
+public:
+ PtrList() = default;
+
+public:
+ PtrList(const PtrList &) = delete;
+ PtrList(PtrList &&) = delete;
+
+public:
+ virtual ~PtrList() = default;
+
+public:
+ uint32_t size(void) const { return _ptrs.size(); }
+
+public:
+ T *at(uint32_t n) const { return _ptrs.at(n); }
+
+public:
+ void insert(T *ptr) { _ptrs.emplace_back(ptr); }
+
+private:
+ std::vector<T *> _ptrs;
+};
+
+} // namespace coco
+
+#endif // __COCO_ADT_PTR_LIST_H__
diff --git a/compiler/coco/core/include/coco/ADT/PtrManager.h b/compiler/coco/core/include/coco/ADT/PtrManager.h
new file mode 100644
index 000000000..2b254c70a
--- /dev/null
+++ b/compiler/coco/core/include/coco/ADT/PtrManager.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_ADT_PTR_MANAGER_H__
+#define __COCO_ADT_PTR_MANAGER_H__
+
+#include <vector>
+
+#include <memory>
+#include <stdexcept>
+
+namespace coco
+{
+
+template <typename T> class PtrManager
+{
+public:
+ /// @brief Return the number of managed objects
+ uint32_t size(void) const { return _ptrs.size(); }
+
+public:
+ T *at(uint32_t n) const { return _ptrs.at(n).get(); }
+
+protected:
+ template <typename U> U *take(std::unique_ptr<U> &&o)
+ {
+ auto res = o.get();
+ _ptrs.emplace_back(std::move(o));
+ return res;
+ }
+
+protected:
+ std::unique_ptr<T> release(T *ptr)
+ {
+ for (auto it = _ptrs.begin(); it != _ptrs.end(); ++it)
+ {
+ if (it->get() == ptr)
+ {
+ std::unique_ptr<T> res = std::move(*it);
+ _ptrs.erase(it);
+ return res;
+ }
+ }
+
+ throw std::invalid_argument{"ptr"};
+ }
+
+private:
+ std::vector<std::unique_ptr<T>> _ptrs;
+};
+
+} // namespace coco
+
+#endif // __COCO_ADT_PTR_MANAGER_H__
diff --git a/compiler/coco/core/include/coco/IR.h b/compiler/coco/core/include/coco/IR.h
new file mode 100644
index 000000000..aa7ad5727
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_H__
+#define __COCO_IR_H__
+
+#include "coco/IR/Bag.h"
+#include "coco/IR/Object.h"
+#include "coco/IR/FeatureLayouts.h"
+#include "coco/IR/KernelLayouts.h"
+
+#include "coco/IR/Op.h"
+#include "coco/IR/Instr.h"
+#include "coco/IR/Block.h"
+
+#include "coco/IR/Input.h"
+#include "coco/IR/Output.h"
+
+#include "coco/IR/Module.h"
+
+#endif // __COCO_IR_H__
diff --git a/compiler/coco/core/include/coco/IR/Arg.h b/compiler/coco/core/include/coco/IR/Arg.h
new file mode 100644
index 000000000..fc451a231
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Arg.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_ARG_H__
+#define __COCO_IR_ARG_H__
+
+#include "coco/IR/Bag.h"
+#include "coco/IR/ElemID.h"
+
+#include <nncc/core/ADT/tensor/Shape.h>
+#include <nncc/core/ADT/tensor/Index.h>
+#include <nncc/core/ADT/tensor/Layout.h>
+
+#include <string>
+#include <vector>
+
+namespace coco
+{
+
+/**
+ * @brief Base class for NN model arguments (Input/Output)
+ */
+class Arg
+{
+public:
+ explicit Arg(const nncc::core::ADT::tensor::Shape &shape);
+
+public:
+ virtual ~Arg() = default;
+
+public:
+ const nncc::core::ADT::tensor::Shape &shape(void) const { return _shape; }
+
+public:
+ const std::string &name(void) const { return _name; }
+ void name(const std::string &s) { _name = s; }
+
+protected:
+ virtual void onTake(Bag *) { return; }
+ virtual void onRelease(Bag *) { return; }
+
+public:
+ Bag *bag(void) const { return _bag; }
+ void bag(Bag *);
+
+public:
+ ElemID &at(const nncc::core::ADT::tensor::Index &);
+ const ElemID &at(const nncc::core::ADT::tensor::Index &) const;
+
+public:
+ void reorder(const nncc::core::ADT::tensor::Layout &l);
+ template <typename LayoutImpl> void reorder(void) { reorder(LayoutImpl{}); }
+
+private:
+ nncc::core::ADT::tensor::Shape const _shape;
+
+private:
+ std::string _name;
+
+private:
+ Bag *_bag;
+ std::vector<ElemID> _map;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_ARG_H__
diff --git a/compiler/coco/core/include/coco/IR/Bag.h b/compiler/coco/core/include/coco/IR/Bag.h
new file mode 100644
index 000000000..1c86899d7
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Bag.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_BAG_H__
+#define __COCO_IR_BAG_H__
+
+#include "coco/IR/Entity.h"
+#include "coco/IR/ObjectSet.h"
+#include "coco/IR/DepSet.h"
+#include "coco/IR/ReadSet.h"
+#include "coco/IR/UpdateSet.h"
+#include "coco/IR/Input.forward.h"
+#include "coco/IR/Output.forward.h"
+#include "coco/IR/Locatable.h"
+
+#include <set>
+
+#include <memory>
+
+namespace coco
+{
+
+/**
+ * @brief A collection of (abstracted) elements of the same type
+ *
+ * When there are N elements in a bag, we refer to N as the size of this bag, and every
+ * element in a bag has a unique numeric ID whose range is [0, N).
+ *
+ * NOTE 'Bag' is not a container (such as std::vector). 'Bag' just assures that there are
+ * N elements. It does not state about its value.
+ *
+ * NOTE coco IR treats Bag as virtual memory allocation
+ */
+class Bag final : public Entity
+{
+public:
+ struct Updater : public Locatable
+ {
+ virtual ~Updater() = default;
+ };
+
+ using UpdaterSet = std::set<Updater *>;
+
+ struct Reader : public Locatable
+ {
+ virtual ~Reader() = default;
+ };
+
+ using ReaderSet = std::set<Reader *>;
+
+public:
+ friend class Dep;
+ friend class Read;
+ friend class Update;
+ friend class Input;
+ friend class Output;
+
+public:
+ explicit Bag(uint32_t size);
+
+public:
+ ~Bag();
+
+public:
+ uint32_t size(void) const;
+
+public:
+ bool isInput(void) const;
+ bool isOutput(void) const;
+
+public:
+ /// @brief Return the set of Dep links that point to this bag
+ const DepSet *deps(void) const;
+ /// @brief Return the set of Read links that point to this bag
+ const ReadSet *reads(void) const;
+ /// @brief Return the set of Update links that point to this bag
+ const UpdateSet *updates(void) const;
+
+public:
+ /// @brief Return a valid pointer if this bag is marked as an input of the model
+ Input *input(void) const { return _input; }
+ /// @brief Return a valid pointer if this bag is marked as an output of the model
+ Output *output(void) const { return _output; }
+
+public:
+ /**
+ * @brief Replace all the occurence of a bag (except those in Input/Output) with another bag
+ *
+ * NOTE reaplceWith(b) works correctly only when b is neither Input nor Output
+ */
+ void replaceWith(Bag *b);
+
+ /**
+ * @brief Replace all the occurence of a bag in Object with another bag
+ *
+ * NOTE Unlike replaceWith(b), replaceAllDepsWith(b) has no restriction
+ */
+ void replaceAllDepsWith(Bag *);
+
+private:
+ // "mutable_" prefix is deliberately introduced below to avoid resolution issue.
+ //
+ // Let's assume that two "deps" are overloaded in Bag as follows:
+ // class Bag
+ // {
+ // private:
+ // DepSet *deps(void); <-- 1
+ // public:
+ // const DepSet *deps(void) const; <-- 2
+ // };
+ //
+ // C++ compiler tries to invoke method 1 unless a bag itself is const. Thus, any "deps" calls
+ // over non-const bags except those calls from friend classes will introduce build error.
+
+ // WARN Only Dep is allowed to access this method
+ DepSet *mutable_deps(void) { return &_deps; }
+ // WARN Only Read is allowed to access this method
+ ReadSet *mutable_reads(void) { return &_reads; }
+ // WARN Only Update is allowed to access this method
+ UpdateSet *mutable_updates(void) { return &_updates; }
+
+private:
+ // WARN Only Input is allowed to access this method
+ void input(Input *i) { _input = i; }
+ // WARN Only Output is allowed to access this method
+ void output(Output *o) { _output = o; }
+
+private:
+ uint32_t _size;
+
+ /** @brief Links to dependent Object(s) */
+ DepSet _deps;
+ /** @brief Direct reads (not through Object) */
+ ReadSet _reads;
+ /** @brief Direct updates (not through Object) */
+ UpdateSet _updates;
+
+ Input *_input = nullptr;
+ Output *_output = nullptr;
+};
+
+/// @brief Return a set of objects that depends on a given bag
+ObjectSet dependent_objects(const Bag *);
+/// @brief Return a set of readers that reads a given bag
+Bag::ReaderSet readers(const Bag *);
+/// @brief Return a set of updaters that updates a given bag
+Bag::UpdaterSet updaters(const Bag *);
+
+} // namespace coco
+
+#endif // __COCO_IR_BAG_H__
diff --git a/compiler/coco/core/include/coco/IR/BagManager.h b/compiler/coco/core/include/coco/IR/BagManager.h
new file mode 100644
index 000000000..6ba644101
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/BagManager.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_BAG_MANAGER_H__
+#define __COCO_IR_BAG_MANAGER_H__
+
+#include "coco/IR/Bag.h"
+#include "coco/IR/EntityBuilder.h"
+
+#include "coco/ADT/PtrManager.h"
+
+namespace coco
+{
+
+class BagManager final : public PtrManager<Bag>, public EntityBuilder
+{
+public:
+ BagManager(Module *m = nullptr) { module(m); }
+
+public:
+ Bag *create(uint32_t size);
+
+public:
+ /**
+ * @brief Destroy (= deallocate) a Bag entity
+ *
+ * NOTE A Bag SHOULD BE detached from IR before destruction
+ */
+ void destroy(Bag *b);
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_BAG_MANAGER_H__
diff --git a/compiler/coco/core/include/coco/IR/Block.forward.h b/compiler/coco/core/include/coco/IR/Block.forward.h
new file mode 100644
index 000000000..6d1793141
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Block.forward.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_BLOCK_FORWARD_H__
+#define __COCO_IR_BLOCK_FORWARD_H__
+
+namespace coco
+{
+
+class Block;
+
+} // namespace coco
+
+#endif // __COCO_IR_BLOCK_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/Block.h b/compiler/coco/core/include/coco/IR/Block.h
new file mode 100644
index 000000000..1bb3f47c7
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Block.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_BLOCK_H__
+#define __COCO_IR_BLOCK_H__
+
+#include "coco/IR/Module.forward.h"
+#include "coco/IR/Block.forward.h"
+#include "coco/IR/BlockIndex.h"
+#include "coco/IR/Instr.h"
+#include "coco/IR/Entity.h"
+
+#include "coco/ADT/DLinkedList.h"
+
+namespace coco
+{
+
+using BlockList = DLinkedList<Block, Module>::Head;
+
+/**
+ * @brief A unit of (grouped) instructions
+ *
+ * Block allows backend to manage a set of instructions as one unit, which is useful for H/W that
+ * has a restriction on code size
+ */
+class Block final : public DLinkedList<Block, Module>::Node, public Entity
+{
+public:
+ friend void DLinkedList<Block, Module>::joined(Module *, Block *);
+ friend void DLinkedList<Block, Module>::leaving(Module *, Block *);
+
+public:
+ Block() : _instr{this}
+ {
+ // DO NOTHING
+ }
+
+public:
+ Block(const Block &) = delete;
+ Block(Block &&) = delete;
+
+public:
+ ~Block()
+ {
+ if (parent())
+ {
+ detach();
+ }
+ }
+
+public:
+ InstrList *instr(void) { return &_instr; }
+ const InstrList *instr(void) const { return &_instr; }
+
+public:
+ const BlockIndex &index(void) const { return _index; }
+
+private:
+ BlockIndex _index;
+ DLinkedList<Instr, Block>::Head _instr;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_BLOCK_H__
diff --git a/compiler/coco/core/include/coco/IR/BlockIndex.h b/compiler/coco/core/include/coco/IR/BlockIndex.h
new file mode 100644
index 000000000..7deabf488
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/BlockIndex.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_BLOCK_INDEX_H__
+#define __COCO_IR_BLOCK_INDEX_H__
+
+#include <cstdint>
+
+namespace coco
+{
+
+/**
+ * @brief A BlockIndex denotes the index of a block in a block list
+ */
+class BlockIndex final
+{
+private:
+ static const uint32_t undefined = 0xffffffff;
+
+public:
+ BlockIndex() : _value{undefined}
+ {
+ // DO NOTHING
+ }
+
+public:
+ BlockIndex(uint32_t value) { set(value); }
+
+public:
+ bool valid(void) const { return _value != undefined; }
+
+public:
+ uint32_t value(void) const { return _value; }
+
+public:
+ void set(uint32_t value);
+ void reset(void) { _value = undefined; }
+
+private:
+ uint32_t _value;
+};
+
+static inline bool operator<(const BlockIndex &lhs, const BlockIndex &rhs)
+{
+ return lhs.value() < rhs.value();
+}
+
+} // namespace coco
+
+#endif // __COCO_IR_BLOCK_INDEX_H__
diff --git a/compiler/coco/core/include/coco/IR/BlockManager.h b/compiler/coco/core/include/coco/IR/BlockManager.h
new file mode 100644
index 000000000..f81f1f22b
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/BlockManager.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_BLOCK_MANAGER_H__
+#define __COCO_IR_BLOCK_MANAGER_H__
+
+#include "coco/IR/Block.h"
+#include "coco/IR/EntityBuilder.h"
+
+#include "coco/ADT/PtrManager.h"
+
+namespace coco
+{
+
+class BlockManager final : public PtrManager<Block>, public EntityBuilder
+{
+public:
+ BlockManager(Module *m = nullptr) { module(m); }
+
+public:
+ Block *create(void);
+
+public:
+ /**
+ * @brief Free 'Block' object
+ *
+ * NOTE Block SHOULD be detached from any list before it is destructed
+ */
+ void destroy(Block *);
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_BLOCK_MANAGER_H__
diff --git a/compiler/coco/core/include/coco/IR/Def.forward.h b/compiler/coco/core/include/coco/IR/Def.forward.h
new file mode 100644
index 000000000..93878c658
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Def.forward.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_DEF_FORWARD_H__
+#define __COCO_IR_DEF_FORWARD_H__
+
+namespace coco
+{
+
+class Def;
+
+} // namespace coco
+
+#endif // __COCO_IR_DEF_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/Def.h b/compiler/coco/core/include/coco/IR/Def.h
new file mode 100644
index 000000000..d9b1567e5
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Def.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_DEF_H__
+#define __COCO_IR_DEF_H__
+
+#include "coco/IR/Object.h"
+
+namespace coco
+{
+
+class Def final
+{
+public:
+ Def(Object::Producer *producer) : _producer{producer}
+ {
+ // DO NOTHING
+ }
+
+public:
+ ~Def() { value(nullptr); }
+
+public:
+ Object *value(void) const { return _value; }
+
+public:
+ void value(Object *value);
+
+public:
+ Object::Producer *producer(void) const { return _producer; }
+
+private:
+ Object *_value = nullptr;
+ Object::Producer *_producer = nullptr;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_DEF_H__
diff --git a/compiler/coco/core/include/coco/IR/Dep.forward.h b/compiler/coco/core/include/coco/IR/Dep.forward.h
new file mode 100644
index 000000000..596ee3126
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Dep.forward.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_DEP_FORWARD_H__
+#define __COCO_IR_DEP_FORWARD_H__
+
+namespace coco
+{
+
+class Dep;
+
+} // namespace coco
+
+#endif // __COCO_IR_DEP_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/Dep.h b/compiler/coco/core/include/coco/IR/Dep.h
new file mode 100644
index 000000000..645c3befe
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Dep.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_DEP_H__
+#define __COCO_IR_DEP_H__
+
+#include "coco/IR/Bag.h"
+#include "coco/IR/Object.forward.h"
+
+namespace coco
+{
+
+/**
+ * @brief A Dep represents the edge between a Bag and its dependent Object
+ *
+ * WARNING A Dep will update dependent Object set (stored BagInfo) only when
+ * users properly initialize object and link values.
+ */
+class Dep final
+{
+public:
+ Dep() = default;
+
+public:
+ Dep(const Dep &) = delete;
+ Dep(Dep &&) = delete;
+
+public:
+ ~Dep();
+
+public:
+ Bag *bag(void) const { return _bag; }
+ void bag(Bag *);
+
+public:
+ Object *object(void) const { return _object; }
+ void object(Object *object) { _object = object; }
+
+private:
+ Bag *_bag = nullptr;
+ Object *_object = nullptr;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_DEP_H__
diff --git a/compiler/coco/core/include/coco/IR/DepSet.h b/compiler/coco/core/include/coco/IR/DepSet.h
new file mode 100644
index 000000000..c4e2df979
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/DepSet.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_DEP_SET_H__
+#define __COCO_IR_DEP_SET_H__
+
+#include "coco/IR/Dep.forward.h"
+
+#include <set>
+
+namespace coco
+{
+
+using DepSet = std::set<Dep *>;
+
+} // namespace coco
+
+#endif // __COCO_IR_DEP_SET_H__
diff --git a/compiler/coco/core/include/coco/IR/ElemID.h b/compiler/coco/core/include/coco/IR/ElemID.h
new file mode 100644
index 000000000..7065d13eb
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/ElemID.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_ELEM_ID_H__
+#define __COCO_IR_ELEM_ID_H__
+
+#include <cstdint>
+
+namespace coco
+{
+
+class ElemID final
+{
+public:
+ ElemID() : _value{0xffffffff}
+ {
+ // DO NOTHING
+ }
+
+public:
+ explicit ElemID(uint32_t value) : _value{value}
+ {
+ // DO NOTHING
+ }
+
+public:
+ uint32_t value(void) const { return _value; }
+
+private:
+ uint32_t _value;
+};
+
+bool operator==(const ElemID &lhs, const ElemID &rhs);
+bool operator<(const ElemID &lhs, const ElemID &rhs);
+
+} // namespace coco
+
+#endif // __COCO_IR_ELEM_ID_H__
diff --git a/compiler/coco/core/include/coco/IR/Entity.h b/compiler/coco/core/include/coco/IR/Entity.h
new file mode 100644
index 000000000..4bf9df651
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Entity.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_ENTITY_H__
+#define __COCO_IR_ENTITY_H__
+
+#include "coco/IR/Module.forward.h"
+
+namespace coco
+{
+
+/**
+ * @brief A base class for IR entities
+ *
+ * NOTE Each IR entity has a link to a module that it belongs to
+ */
+class Entity
+{
+public:
+ friend class EntityBuilder;
+
+public:
+ virtual ~Entity() = default;
+
+public:
+ Module *module(void) const { return _module; }
+
+private:
+ // WARN Only EntityBuilder is allowed to access this method
+ void module(Module *m) { _module = m; }
+
+private:
+ Module *_module = nullptr;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_ENTITY_H__
diff --git a/compiler/coco/core/include/coco/IR/EntityBuilder.h b/compiler/coco/core/include/coco/IR/EntityBuilder.h
new file mode 100644
index 000000000..161f3f294
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/EntityBuilder.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_ENTITY_BUILDER_H__
+#define __COCO_IR_ENTITY_BUILDER_H__
+
+#include "coco/IR/Entity.h"
+#include "coco/IR/Module.forward.h"
+
+namespace coco
+{
+
+/**
+ * @brief A base class for IR entity builders
+ *
+ * NOTE Only EntityBuilder is allowed to update module field of each Entity
+ */
+class EntityBuilder
+{
+public:
+ virtual ~EntityBuilder() = default;
+
+protected:
+ Module *module(void) const { return _module; }
+
+ void module(Module *m) { _module = m; }
+ void modulize(Entity *entity) const { entity->module(_module); }
+
+private:
+ Module *_module = nullptr;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_ENTITY_BUILDER_H__
diff --git a/compiler/coco/core/include/coco/IR/EntityManager.h b/compiler/coco/core/include/coco/IR/EntityManager.h
new file mode 100644
index 000000000..e76dec7aa
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/EntityManager.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_ENTITY_MANAGER_H__
+#define __COCO_IR_ENTITY_MANAGER_H__
+
+#include "coco/IR/BagManager.h"
+#include "coco/IR/ObjectManager.h"
+
+#include "coco/IR/OpManager.h"
+#include "coco/IR/InstrManager.h"
+#include "coco/IR/BlockManager.h"
+
+#include "coco/IR/InputManager.h"
+#include "coco/IR/OutputManager.h"
+
+namespace coco
+{
+
+/**
+ * @brief Meta (lifetime) manager interface
+ *
+ * EntityManager is referred as meta manager as it is a gateway to other
+ * managers.
+ */
+struct EntityManager
+{
+ virtual ~EntityManager() = default;
+
+ virtual BagManager *bag(void) = 0;
+ virtual const BagManager *bag(void) const = 0;
+
+ virtual ObjectManager *object(void) = 0;
+ virtual const ObjectManager *object(void) const = 0;
+
+ virtual OpManager *op(void) = 0;
+ virtual const OpManager *op(void) const = 0;
+
+ virtual InstrManager *instr(void) = 0;
+ virtual const InstrManager *instr(void) const = 0;
+
+ virtual BlockManager *block(void) = 0;
+ virtual const BlockManager *block(void) const = 0;
+
+ virtual InputManager *input(void) = 0;
+ virtual const InputManager *input(void) const = 0;
+
+ virtual OutputManager *output(void) = 0;
+ virtual const OutputManager *output(void) const = 0;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_ENTITY_MANAGER_H__
diff --git a/compiler/coco/core/include/coco/IR/FeatureLayout.h b/compiler/coco/core/include/coco/IR/FeatureLayout.h
new file mode 100644
index 000000000..63f02c8ba
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/FeatureLayout.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_FEATURE_LAYOUT_H__
+#define __COCO_IR_FEATURE_LAYOUT_H__
+
+#include "coco/IR/ElemID.h"
+#include "coco/IR/FeatureShape.h"
+
+namespace coco
+{
+
+/**
+ * @brief A FeatureLayout connects each feature index to a Bag element
+ *
+ * NOTE FeatureLayout is an immutable interface
+ */
+struct FeatureLayout
+{
+ struct ID
+ {
+ virtual ~ID() = default;
+ };
+
+ virtual ~FeatureLayout() = default;
+
+ virtual const ID *id(void) const = 0;
+
+ virtual const FeatureShape &shape(void) const = 0;
+
+ uint32_t batch(void) const { return shape().batch(); }
+ uint32_t depth(void) const { return shape().depth(); }
+ uint32_t height(void) const { return shape().height(); }
+ uint32_t width(void) const { return shape().width(); }
+
+ virtual ElemID at(uint32_t b, uint32_t ch, uint32_t row, uint32_t col) const = 0;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_FEATURE_LAYOUT_H__
diff --git a/compiler/coco/core/include/coco/IR/FeatureLayouts.h b/compiler/coco/core/include/coco/IR/FeatureLayouts.h
new file mode 100644
index 000000000..23b9c4919
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/FeatureLayouts.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_FEATURE_LAYOUTS_H__
+#define __COCO_IR_FEATURE_LAYOUTS_H__
+
+#include "coco/IR/FeatureLayout.h"
+
+#include <nncc/core/ADT/feature/Layout.h>
+
+#include <vector>
+#include <memory>
+
+namespace coco
+{
+namespace FeatureLayouts
+{
+
+/**
+ * @brief BCHW Feature Layout
+ */
+class BCHW final : public FeatureLayout
+{
+private:
+ BCHW(const FeatureShape &shape) : _shape{shape}
+ {
+ // DO NOTHING
+ }
+
+public:
+ static const FeatureLayout::ID *uid(void);
+ const FeatureLayout::ID *id(void) const override { return uid(); }
+
+ const FeatureShape &shape(void) const override { return _shape; }
+
+ ElemID at(uint32_t b, uint32_t ch, uint32_t row, uint32_t col) const override;
+
+private:
+ FeatureShape _shape;
+
+public:
+ static std::unique_ptr<BCHW> create(const nncc::core::ADT::feature::Shape &shape);
+};
+
+/**
+ * @brief BHWC Feature Layout
+ */
+class BHWC : public coco::FeatureLayout
+{
+private:
+ BHWC(const FeatureShape &shape) : _shape{shape}
+ {
+ // DO NOTHING
+ }
+
+public:
+ static const FeatureLayout::ID *uid(void);
+ const FeatureLayout::ID *id(void) const override { return uid(); }
+
+ const FeatureShape &shape(void) const override { return _shape; }
+
+ coco::ElemID at(uint32_t b, uint32_t ch, uint32_t row, uint32_t col) const override;
+
+private:
+ FeatureShape _shape;
+
+public:
+ static std::unique_ptr<BHWC> create(const nncc::core::ADT::feature::Shape &shape);
+ static std::unique_ptr<BHWC> create(const FeatureShape &shape);
+};
+
+/**
+ * @brief BC (Channel-wise Channel-major) Feature Layout
+ *
+ * 1. A layout is said to be channel-wise if the following holds:
+ *
+ * For each pair of valid feature index I and J,
+ * at(I) == at(J) if batch(I) == batch(J) and channel(I) == channel(J)
+ *
+ * 2. A layout is said to be channel-major if the followings hold:
+ *
+ * For each pair of valid feature index I and J,
+ * at(I) + 1 == at(J) if batch(I) == batch(J) and channel(I) + 1 == channel(J)
+ *
+ * For each pair of valid feature index I and J,
+ * at(I) + 1 == at(J) if batch(I) + 1 == batch(J), channel(I) == depth - 1, and channel(J) == 0
+ */
+class BC : public coco::FeatureLayout
+{
+private:
+ BC(const FeatureShape &shape) : _shape{shape}
+ {
+ // DO NOTHING
+ }
+
+public:
+ static const FeatureLayout::ID *uid(void);
+ const FeatureLayout::ID *id(void) const override { return uid(); }
+
+ const FeatureShape &shape(void) const override { return _shape; }
+
+ coco::ElemID at(uint32_t b, uint32_t ch, uint32_t row, uint32_t col) const override;
+
+private:
+ FeatureShape _shape;
+
+public:
+ static std::unique_ptr<BC> create(const nncc::core::ADT::feature::Shape &shape);
+};
+
+/**
+ * @brief Generic Feature Layout
+ */
+class Generic final : public FeatureLayout
+{
+private:
+ Generic(const FeatureShape &shape);
+
+public:
+ static const FeatureLayout::ID *uid(void);
+ const FeatureLayout::ID *id(void) const override { return uid(); }
+
+ const FeatureShape &shape(void) const override { return _shape; }
+
+ ElemID &at(uint32_t b, uint32_t ch, uint32_t row, uint32_t col);
+ ElemID at(uint32_t b, uint32_t ch, uint32_t row, uint32_t col) const override;
+
+ void reorder(const nncc::core::ADT::feature::Layout &l);
+
+private:
+ uint32_t offset(uint32_t b, uint32_t ch, uint32_t row, uint32_t col) const;
+
+private:
+ FeatureShape _shape;
+
+private:
+ std::vector<ElemID> _content;
+
+public:
+ static std::unique_ptr<Generic> create(const nncc::core::ADT::feature::Shape &shape);
+};
+
+} // namespace FeatureLayouts
+} // namespace coco
+
+#endif // __COCO_IR_FEATURE_LAYOUTS_H__
diff --git a/compiler/coco/core/include/coco/IR/FeatureObject.forward.h b/compiler/coco/core/include/coco/IR/FeatureObject.forward.h
new file mode 100644
index 000000000..41477e853
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/FeatureObject.forward.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_FEATURE_OBJECT_FORWARD_H__
+#define __COCO_IR_FEATURE_OBJECT_FORWARD_H__
+
+namespace coco
+{
+
+class FeatureObject;
+
+} // namespace coco
+
+#endif // __COCO_IR_FEATURE_OBJECT_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/FeatureObject.h b/compiler/coco/core/include/coco/IR/FeatureObject.h
new file mode 100644
index 000000000..f4244d9be
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/FeatureObject.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_FEATURE_OBJECT_H__
+#define __COCO_IR_FEATURE_OBJECT_H__
+
+#include "coco/IR/Object.h"
+#include "coco/IR/FeatureShape.h"
+#include "coco/IR/FeatureLayout.h"
+#include "coco/IR/ElemID.h"
+
+#include <nncc/core/ADT/feature/Layout.h>
+
+#include <vector>
+
+namespace coco
+{
+
+/**
+ * @brief FeatureMap values (used in CNN)
+ */
+class FeatureObject final : public Object
+{
+public:
+ FeatureObject() = default;
+
+public:
+ ~FeatureObject();
+
+public:
+ Object::Kind kind(void) const override { return Object::Kind::Feature; }
+
+public:
+ FeatureObject *asFeature(void) override { return this; }
+ const FeatureObject *asFeature(void) const override { return this; }
+
+public:
+ const FeatureShape &shape(void) const;
+
+public:
+ const FeatureLayout *layout(void) const { return _layout.get(); }
+ void layout(std::unique_ptr<FeatureLayout> &&l) { _layout = std::move(l); }
+
+private:
+ std::unique_ptr<FeatureLayout> _layout;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_FEATURE_OBJECT_H__
diff --git a/compiler/coco/core/include/coco/IR/FeatureShape.h b/compiler/coco/core/include/coco/IR/FeatureShape.h
new file mode 100644
index 000000000..015fc709d
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/FeatureShape.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_FEATURE_SHAPE_H__
+#define __COCO_IR_FEATURE_SHAPE_H__
+
+#include <nncc/core/ADT/feature/Shape.h>
+
+namespace coco
+{
+
+/**
+ * @brief The shape of a feature map
+ *
+ * TODO Implement coco's own FeatureShape without "nncc::core::ADT::feature::Shape"
+ */
+class FeatureShape : public nncc::core::ADT::feature::Shape
+{
+public:
+ FeatureShape(uint32_t depth, uint32_t height, uint32_t width)
+ : Shape{depth, height, width}, _batch{1}
+ {
+ // DO NOTHING
+ }
+
+ FeatureShape(uint32_t batch, uint32_t depth, uint32_t height, uint32_t width)
+ : Shape{depth, height, width}, _batch{batch}
+ {
+ // DO NOTHING
+ }
+
+ FeatureShape(const nncc::core::ADT::feature::Shape &shape) : Shape{shape}, _batch{1}
+ {
+ // DO NOTHING
+ }
+
+public:
+ uint32_t batch(void) const { return _batch; }
+
+private:
+ uint32_t _batch;
+};
+
+static inline bool operator==(const FeatureShape &lhs, const FeatureShape &rhs)
+{
+ return (lhs.batch() == rhs.batch()) && (lhs.depth() == rhs.depth()) &&
+ (lhs.height() == rhs.height()) && (lhs.width() == rhs.width());
+}
+
+static inline bool operator!=(const FeatureShape &lhs, const FeatureShape &rhs)
+{
+ return !(lhs == rhs);
+}
+
+} // namespace coco
+
+#endif // __COCO_IR_FEATURE_SHAPE_H__
diff --git a/compiler/coco/core/include/coco/IR/Input.forward.h b/compiler/coco/core/include/coco/IR/Input.forward.h
new file mode 100644
index 000000000..4b529cddf
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Input.forward.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_INPUT_FORWARD_H__
+#define __COCO_IR_INPUT_FORWARD_H__
+
+namespace coco
+{
+
+class Input;
+
+} // namespace coco
+
+#endif // __COCO_IR_INPUT_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/Input.h b/compiler/coco/core/include/coco/IR/Input.h
new file mode 100644
index 000000000..ef8e88c9d
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Input.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_INPUT_H__
+#define __COCO_IR_INPUT_H__
+
+#include "coco/IR/Arg.h"
+#include "coco/IR/Entity.h"
+
+#include <nncc/core/ADT/tensor/Shape.h>
+#include <nncc/core/ADT/tensor/Index.h>
+
+#include <string>
+#include <vector>
+
+namespace coco
+{
+
+class Input final : public Arg, public Entity
+{
+public:
+ Input(const nncc::core::ADT::tensor::Shape &shape);
+
+private:
+ void onTake(Bag *) override;
+ void onRelease(Bag *) override;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_INPUT_H__
diff --git a/compiler/coco/core/include/coco/IR/InputList.h b/compiler/coco/core/include/coco/IR/InputList.h
new file mode 100644
index 000000000..cd6337a5a
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/InputList.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_INPUT_LIST_H__
+#define __COCO_IR_INPUT_LIST_H__
+
+#include "coco/IR/Input.h"
+
+#include "coco/ADT/PtrList.h"
+
+namespace coco
+{
+
+using InputList = PtrList<Input>;
+
+} // namespace coco
+
+#endif // __COCO_IR_INPUT_LIST_H__
diff --git a/compiler/coco/core/include/coco/IR/InputManager.h b/compiler/coco/core/include/coco/IR/InputManager.h
new file mode 100644
index 000000000..bfbd712b5
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/InputManager.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_INPUT_MANAGER_H__
+#define __COCO_IR_INPUT_MANAGER_H__
+
+#include "coco/IR/Input.h"
+#include "coco/IR/EntityBuilder.h"
+
+#include "coco/ADT/PtrManager.h"
+
+namespace coco
+{
+
+class InputManager final : public PtrManager<Input>, public EntityBuilder
+{
+public:
+ InputManager(Module *m = nullptr) { module(m); }
+
+public:
+ Input *create(const nncc::core::ADT::tensor::Shape &);
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_INPUT_MANAGER_H__
diff --git a/compiler/coco/core/include/coco/IR/Instr.forward.h b/compiler/coco/core/include/coco/IR/Instr.forward.h
new file mode 100644
index 000000000..4043970db
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Instr.forward.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_INSTR_FORWARD_H__
+#define __COCO_IR_INSTR_FORWARD_H__
+
+namespace coco
+{
+
+// WARNING This header should be aligned with Instr.h
+class Instr;
+
+} // namespace coco
+
+#endif // __COCO_IR_INSTR_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/Instr.h b/compiler/coco/core/include/coco/IR/Instr.h
new file mode 100644
index 000000000..fc1cc332d
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Instr.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_INSTR_H__
+#define __COCO_IR_INSTR_H__
+
+#include "coco/IR/Bag.h"
+#include "coco/IR/Block.forward.h"
+#include "coco/IR/Instr.forward.h"
+#include "coco/IR/InstrIndex.h"
+#include "coco/IR/Entity.h"
+
+#include "coco/ADT/DLinkedList.h"
+
+#include <cassert>
+#include <stdexcept>
+
+namespace coco
+{
+
+#define INSTR(Name) class Name;
+#include "coco/IR/Instr.lst"
+#undef INSTR
+
+using InstrList = coco::DLinkedList<Instr, Block>::Head;
+
+/**
+ * @brief Base interface on explicit computation steps in coco IR
+ *
+ * NOTE Input/output is explicit in Instr, but implicit in Op
+ * NOTE Instr is may (not always) be a combination of multiple NN operations
+ *
+ * One may find a set of supported instructions from "Instrs.h"
+ *
+ * >> How to add a new base instruction in coco IR <<
+ *
+ * To introduce a new instruction (whose name is INS),
+ * 1. Append "INSTR(INS)" to "Instr.lst"
+ * 2. Declare class INS which inherits Instr class in "Instrs.h"
+ * NOTE This class SHOULD be default constructible
+ *
+ */
+class Instr : public coco::DLinkedList<Instr, Block>::Node, public Entity
+{
+public:
+ friend void DLinkedList<Instr, Block>::joined(Block *, Instr *);
+ friend void DLinkedList<Instr, Block>::leaving(Block *, Instr *);
+
+public:
+ Instr() = default;
+
+public:
+ Instr(const Instr &) = delete;
+ Instr(Instr &&) = delete;
+
+public:
+ virtual ~Instr()
+ {
+ if (parent())
+ {
+ // NOTE It is safe to invoke detach here (although "Instr" is not a final class)
+ // as "leaving" hook accesses only the internal of "Instr" class
+ detach();
+ }
+ }
+
+public:
+#define INSTR(Name) \
+ virtual Name *as##Name(void) { return nullptr; } \
+ virtual const Name *as##Name(void) const { return nullptr; }
+#include "coco/IR/Instr.lst"
+#undef INSTR
+
+public:
+ /**
+ * @brief Instr visitor interface
+ *
+ * WARN Use this interface only for coco-internal classes
+ * (to minimize changes upon Instr extension)
+ */
+ template <typename T> struct IVisitor
+ {
+ virtual ~IVisitor() = default;
+
+#define INSTR(Name) virtual T visit(const Name *) = 0;
+#include "coco/IR/Instr.lst"
+#undef INSTR
+ };
+
+ template <typename T> struct Visitor : public IVisitor<T>
+ {
+ virtual ~Visitor() = default;
+
+#define INSTR(Name) \
+ T visit(const Name *) override { throw std::runtime_error{"NYI"}; }
+#include "coco/IR/Instr.lst"
+#undef INSTR
+ };
+
+public:
+ template <typename T> T accept(IVisitor<T> *v) const
+ {
+#define INSTR(Name) \
+ if (auto ins = as##Name()) \
+ { \
+ return v->visit(ins); \
+ }
+#include "coco/IR/Instr.lst"
+#undef INSTR
+ throw std::runtime_error{"unreachable"};
+ }
+
+ template <typename T> T accept(IVisitor<T> &v) const { return accept(&v); }
+ template <typename T> T accept(IVisitor<T> &&v) const { return accept(&v); }
+
+public:
+ const InstrIndex &index(void) const { return _index; }
+
+private:
+ InstrIndex _index;
+};
+
+/**
+ * @brief Return true if a given instruction is of T type
+ *
+ * @note "ins" cannot be a null pointer
+ */
+template <typename T> bool isa(const Instr *ins)
+{
+ assert(ins != nullptr);
+ return dynamic_cast<const T *>(ins) != nullptr;
+}
+
+/**
+ * @brief Cast as a derived instruction
+ *
+ * @note "safe_cast<T>(ins)" returns a null pointer if "ins" is not of T type
+ * @note "safe_cast<T>(ins)" returns a null pointer if "ins" is a null pointer
+ */
+template <typename T> T *safe_cast(Instr *ins)
+{
+ // NOTE dynamic_cast<T *>(nullptr) returns nullptr
+ return dynamic_cast<T *>(ins);
+}
+
+} // namespace coco
+
+#endif // __COCO_IR_INSTR_H__
diff --git a/compiler/coco/core/include/coco/IR/Instr.lst b/compiler/coco/core/include/coco/IR/Instr.lst
new file mode 100644
index 000000000..f13a65bf2
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Instr.lst
@@ -0,0 +1,9 @@
+#ifndef INSTR
+#error Define INSTR first
+#endif // INSTR
+
+// INSTR(Name)
+
+INSTR(Eval)
+INSTR(Shuffle)
+INSTR(Copy)
diff --git a/compiler/coco/core/include/coco/IR/InstrIndex.h b/compiler/coco/core/include/coco/IR/InstrIndex.h
new file mode 100644
index 000000000..a61d97cad
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/InstrIndex.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_INSTR_INDEX_H__
+#define __COCO_IR_INSTR_INDEX_H__
+
+#include <cstdint>
+
+namespace coco
+{
+
+/**
+ * @brief A InstrIndex denotes the index of an instruction in an instruction list
+ */
+class InstrIndex final
+{
+private:
+ static const uint32_t undefined = 0xffffffff;
+
+public:
+ InstrIndex() : _value{undefined}
+ {
+ // DO NOTHING
+ }
+
+public:
+ InstrIndex(uint32_t value) { set(value); }
+
+public:
+ bool valid(void) const { return _value != undefined; }
+
+public:
+ uint32_t value(void) const { return _value; }
+
+public:
+ void set(uint32_t value);
+ void reset(void) { _value = undefined; }
+
+private:
+ uint32_t _value;
+};
+
+static inline bool operator<(const InstrIndex &lhs, const InstrIndex &rhs)
+{
+ return lhs.value() < rhs.value();
+}
+
+} // namespace coco
+
+#endif // __COCO_IR_INSTR_INDEX_H__
diff --git a/compiler/coco/core/include/coco/IR/InstrManager.h b/compiler/coco/core/include/coco/IR/InstrManager.h
new file mode 100644
index 000000000..537467ae2
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/InstrManager.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_INSTR_MANAGER_H__
+#define __COCO_IR_INSTR_MANAGER_H__
+
+#include "coco/IR/Instr.h"
+#include "coco/IR/Instrs.h"
+
+#include "coco/IR/Op.forward.h"
+
+#include "coco/IR/Bag.h"
+
+#include "coco/IR/Object.forward.h"
+
+#include "coco/IR/EntityBuilder.h"
+
+#include "coco/ADT/PtrManager.h"
+
+namespace coco
+{
+
+class InstrManager final : public PtrManager<Instr>, public EntityBuilder
+{
+public:
+ InstrManager(Module *m = nullptr) { module(m); }
+
+public:
+ template <typename Ins> Ins *create(void);
+
+public:
+ /**
+ * @brief Destroy (= deallocate) an Instr instance
+ *
+ * NOTE destroy(ins) WILL NOT update ins->parent(). An Instruction SHOULD BE detacted from a
+ * module before destroy call
+ */
+ void destroy(Instr *);
+};
+
+//
+// Every instruction class SHOULD be default constructible
+//
+template <typename Ins> Ins *InstrManager::create(void)
+{
+ auto ins = new Ins;
+ modulize(ins);
+ return take(std::unique_ptr<Ins>(ins));
+}
+
+} // namespace coco
+
+#endif // __COCO_IR_INSTR_MANAGER_H__
diff --git a/compiler/coco/core/include/coco/IR/Instrs.h b/compiler/coco/core/include/coco/IR/Instrs.h
new file mode 100644
index 000000000..9245443e9
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Instrs.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_INSTRS_H__
+#define __COCO_IR_INSTRS_H__
+
+#include "coco/IR/Instr.h"
+
+#include "coco/IR/ElemID.h"
+
+#include "coco/IR/Bag.h"
+#include "coco/IR/Object.h"
+
+#include "coco/IR/Def.h"
+#include "coco/IR/Use.h"
+#include "coco/IR/Read.h"
+#include "coco/IR/Update.h"
+
+#include "coco/IR/Step.h"
+
+#include <map>
+
+namespace coco
+{
+
+/**
+ * @brief Evaluate an Object from a given Op
+ */
+class Eval final : public Instr, public Object::Producer
+{
+public:
+ explicit Eval();
+
+public:
+ Eval *asEval(void) override { return this; }
+ const Eval *asEval(void) const override { return this; }
+
+public:
+ Instr *loc(void) override { return this; }
+
+public:
+ Object *out(void) const { return _out.value(); }
+ void out(Object *obj) { _out.value(obj); }
+
+public:
+ Op *op(void) const { return _step.op(); }
+ void op(Op *op) { _step.op(op); }
+
+private:
+ Def _out;
+ Step _step;
+};
+
+/**
+ * @brief Index-wise element transfer between two objects
+ *
+ * Given two objects "src" and "dst" of the same kind/shape, "copy(src, dst)"
+ * denotes index-wise element transfer.
+ *
+ * For example, the following pseudo-code describes "copy(src, dat)"
+ * when both src and dst are a feature map of the shape B x C x H x W:
+ *
+ * for each valid index b, ch, row, col:
+ * load the "src->at(b, ch, row, col)"-th element from bag(src)
+ * store it as the "dst->at(b, ch, row, col)"-th element of bag(dst)
+ *
+ * In principle, "copy" is unnecessary as it is always possible to rewrite "copy"
+ * as a "shuffle" below. However, "shuffle"-based optimization is too heavy as it
+ * requires much of iterations.
+ */
+class Copy final : public Instr, public Object::Producer, public Object::Consumer
+{
+public:
+ Copy() : _from{this}, _into{this}
+ {
+ // DO NOTHING
+ }
+
+public:
+ Copy *asCopy(void) override { return this; }
+ const Copy *asCopy(void) const override { return this; }
+
+public:
+ Instr *loc(void) override { return this; }
+
+public:
+ Object *from(void) const { return _from.value(); }
+ void from(Object *o) { _from.value(o); }
+
+public:
+ Object *into(void) const { return _into.value(); }
+ void into(Object *o) { _into.value(o); }
+
+private:
+ Use _from;
+ Def _into;
+};
+
+/**
+ * @brief Generic element transfer
+ */
+class Shuffle final : public Instr, public Bag::Reader, public Bag::Updater
+{
+public:
+ Shuffle() : _from{this}, _into{this}
+ {
+ // DO NOTHING
+ }
+
+public:
+ Shuffle *asShuffle(void) override { return this; }
+ const Shuffle *asShuffle(void) const override { return this; }
+
+public:
+ Instr *loc(void) override { return this; }
+
+public:
+ Bag *from(void) const { return _from.bag(); }
+ void from(Bag *bag);
+
+public:
+ Bag *into(void) const { return _into.bag(); }
+ void into(Bag *);
+
+public:
+ /**
+ * @brief Return the number of Element-wise transfers
+ *
+ * NOTE size() SHOULD BE identical to range().size()
+ */
+ uint32_t size(void) const;
+
+ /// @brief Return a set of elements in the destination bag that Shuffle will update
+ std::set<ElemID> range(void) const;
+
+public:
+ /// @brief Return true if a given elem is updated after execution
+ bool defined(const ElemID &dst) const { return _content.find(dst) != _content.end(); }
+
+public:
+ /**
+ * Let M be the return of at(N). This means that N-th element in the destination
+ * bag will be filled with the value of M-th element in the source bag.
+ *
+ * NOTE at(n) may be undefined on partial shuffle
+ */
+ const ElemID &at(const ElemID &dst) const { return _content.at(dst); }
+
+public:
+ void insert(const ElemID &from, const ElemID &into);
+
+private:
+ Read _from;
+ Update _into;
+
+private:
+ std::map<ElemID /* DST */, ElemID /* SRC */> _content;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_INSTRS_H__
diff --git a/compiler/coco/core/include/coco/IR/KernelLayout.h b/compiler/coco/core/include/coco/IR/KernelLayout.h
new file mode 100644
index 000000000..49aaf1a81
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/KernelLayout.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_KERNEL_LAYOUT_H__
+#define __COCO_IR_KERNEL_LAYOUT_H__
+
+#include "coco/IR/ElemID.h"
+
+#include <nncc/core/ADT/kernel/Shape.h>
+
+namespace coco
+{
+
+/**
+ * @brief A KernelLayout connectes each kernel index to an element (in a bag)
+ *
+ * NOTE KernelLayout is an immutable interface
+ */
+struct KernelLayout
+{
+ struct ID
+ {
+ virtual ~ID() = default;
+ };
+
+ virtual ~KernelLayout() = default;
+
+ /**
+ * @brief Return the identifier of each layout
+ *
+ * REQUIRED
+ *
+ * Given l1 and l2 of KernelLayout * type,
+ * typeid(*l1) == typeif(*l2) SHOULD hold if l1->id() == l2->id() holds.
+ */
+ virtual const ID *id(void) const = 0;
+
+ virtual const nncc::core::ADT::kernel::Shape &shape(void) const = 0;
+
+ virtual ElemID at(uint32_t n, uint32_t ch, uint32_t row, uint32_t col) const = 0;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_KERNEL_LAYOUT_H__
diff --git a/compiler/coco/core/include/coco/IR/KernelLayouts.h b/compiler/coco/core/include/coco/IR/KernelLayouts.h
new file mode 100644
index 000000000..0a04cf163
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/KernelLayouts.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_KERNEL_LAYOUTS_H__
+#define __COCO_IR_KERNEL_LAYOUTS_H__
+
+#include "coco/IR/KernelLayout.h"
+
+#include <nncc/core/ADT/kernel/Layout.h>
+
+#include <vector>
+#include <memory>
+
+namespace coco
+{
+namespace KernelLayouts
+{
+
+/**
+ * @brief NCHW Kernel Layout
+ */
+class NCHW final : public KernelLayout
+{
+private:
+ NCHW(const nncc::core::ADT::kernel::Shape &shape) : _shape{shape}
+ {
+ // DO NOTHING
+ }
+
+public:
+ static const KernelLayout::ID *uid(void);
+ const KernelLayout::ID *id(void) const override { return uid(); }
+
+ const nncc::core::ADT::kernel::Shape &shape(void) const override { return _shape; }
+
+ ElemID at(uint32_t n, uint32_t ch, uint32_t row, uint32_t col) const override;
+
+private:
+ nncc::core::ADT::kernel::Shape _shape;
+
+public:
+ static std::unique_ptr<NCHW> create(const nncc::core::ADT::kernel::Shape &shape);
+};
+
+/**
+ * @brief NHWC Kernel Layout
+ */
+class NHWC final : public KernelLayout
+{
+private:
+ NHWC(const nncc::core::ADT::kernel::Shape &shape) : _shape{shape}
+ {
+ // DO NOTHING
+ }
+
+public:
+ static const KernelLayout::ID *uid(void);
+ const KernelLayout::ID *id(void) const override { return uid(); }
+
+ const nncc::core::ADT::kernel::Shape &shape(void) const override { return _shape; }
+
+ ElemID at(uint32_t n, uint32_t ch, uint32_t row, uint32_t col) const override;
+
+private:
+ nncc::core::ADT::kernel::Shape _shape;
+
+public:
+ static std::unique_ptr<NHWC> create(const nncc::core::ADT::kernel::Shape &shape);
+};
+
+/**
+ * @brief Generic Kernel Layout
+ */
+class Generic final : public KernelLayout
+{
+private:
+ Generic(const nncc::core::ADT::kernel::Shape &shape);
+
+public:
+ static const KernelLayout::ID *uid(void);
+ const KernelLayout::ID *id(void) const override { return uid(); }
+
+ const nncc::core::ADT::kernel::Shape &shape(void) const override { return _shape; }
+
+ ElemID &at(uint32_t n, uint32_t ch, uint32_t row, uint32_t col);
+ ElemID at(uint32_t n, uint32_t ch, uint32_t row, uint32_t col) const override;
+
+ void reorder(const nncc::core::ADT::kernel::Layout &l);
+ template <typename LayoutImpl> void reorder(void) { reorder(LayoutImpl{}); }
+
+private:
+ nncc::core::ADT::kernel::Shape _shape;
+
+private:
+ std::vector<ElemID> _content;
+
+public:
+ static std::unique_ptr<Generic> create(const nncc::core::ADT::kernel::Shape &shape);
+};
+
+} // namespace KernelLayouts
+} // namespace coco
+
+#endif // __COCO_IR_KERNEL_LAYOUTS_H__
diff --git a/compiler/coco/core/include/coco/IR/KernelObject.forward.h b/compiler/coco/core/include/coco/IR/KernelObject.forward.h
new file mode 100644
index 000000000..10fbac4ca
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/KernelObject.forward.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_KERNEL_OBJECT_FORWARD_H__
+#define __COCO_IR_KERNEL_OBJECT_FORWARD_H__
+
+namespace coco
+{
+
+class KernelObject;
+
+} // namespace coco
+
+#endif // __COCO_IR_KERNEL_OBJECT_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/KernelObject.h b/compiler/coco/core/include/coco/IR/KernelObject.h
new file mode 100644
index 000000000..2ec0cee0b
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/KernelObject.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_KERNEL_OBJECT_H__
+#define __COCO_IR_KERNEL_OBJECT_H__
+
+#include "coco/IR/Object.h"
+#include "coco/IR/KernelLayout.h"
+#include "coco/IR/ElemID.h"
+
+#include <nncc/core/ADT/kernel/Shape.h>
+#include <nncc/core/ADT/kernel/Layout.h>
+
+namespace coco
+{
+
+/**
+ * @brief Convolution Kernel (in CNN) values
+ */
+class KernelObject final : public Object
+{
+public:
+ KernelObject() = default;
+ explicit KernelObject(const nncc::core::ADT::kernel::Shape &shape);
+
+public:
+ virtual ~KernelObject();
+
+public:
+ Object::Kind kind(void) const override { return Object::Kind::Kernel; }
+
+public:
+ KernelObject *asKernel(void) override { return this; }
+ const KernelObject *asKernel(void) const override { return this; }
+
+public:
+ const nncc::core::ADT::kernel::Shape &shape(void) const;
+
+public:
+ ElemID at(uint32_t n, uint32_t ch, uint32_t row, uint32_t col) const;
+
+public:
+ const KernelLayout *layout(void) const { return _layout.get(); }
+ void layout(std::unique_ptr<KernelLayout> &&l) { _layout = std::move(l); }
+
+private:
+ std::unique_ptr<KernelLayout> _layout;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_KERNEL_OBJECT_H__
diff --git a/compiler/coco/core/include/coco/IR/Locatable.h b/compiler/coco/core/include/coco/IR/Locatable.h
new file mode 100644
index 000000000..b80a4a360
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Locatable.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_LOCATABLE_H__
+#define __COCO_IR_LOCATABLE_H__
+
+#include "coco/IR/Instr.forward.h"
+
+namespace coco
+{
+
+/**
+ * @brief Return the associated instruction if exists.
+ */
+struct Locatable
+{
+ virtual ~Locatable() = default;
+
+ virtual Instr *loc(void) = 0;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_LOCATABLE_H__
diff --git a/compiler/coco/core/include/coco/IR/Module.forward.h b/compiler/coco/core/include/coco/IR/Module.forward.h
new file mode 100644
index 000000000..94f8cc7d2
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Module.forward.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_MODULE_FORWARD_H__
+#define __COCO_IR_MODULE_FORWARD_H__
+
+namespace coco
+{
+
+class Module;
+
+} // namespace coco
+
+#endif // __COCO_IR_MODULE_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/Module.h b/compiler/coco/core/include/coco/IR/Module.h
new file mode 100644
index 000000000..9eb0b248b
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Module.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_MODULE_H__
+#define __COCO_IR_MODULE_H__
+
+#include "coco/IR/EntityManager.h"
+#include "coco/IR/Block.h"
+#include "coco/IR/InputList.h"
+#include "coco/IR/OutputList.h"
+
+#include <memory>
+
+namespace coco
+{
+
+/**
+ * @brief Top-level element of coco IR which represents a neural network
+ */
+class Module
+{
+public:
+ Module() = default;
+
+public:
+ Module(const Module &) = delete;
+ Module(Module &&) = delete;
+
+public:
+ virtual ~Module() = default;
+
+public:
+ virtual EntityManager *entity(void) = 0;
+ virtual const EntityManager *entity(void) const = 0;
+
+public:
+ virtual BlockList *block(void) = 0;
+ virtual const BlockList *block(void) const = 0;
+
+public:
+ virtual InputList *input(void) = 0;
+ virtual const InputList *input(void) const = 0;
+
+public:
+ virtual OutputList *output(void) = 0;
+ virtual const OutputList *output(void) const = 0;
+
+public:
+ static std::unique_ptr<Module> create(void);
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_MODULE_H__
diff --git a/compiler/coco/core/include/coco/IR/Object.forward.h b/compiler/coco/core/include/coco/IR/Object.forward.h
new file mode 100644
index 000000000..d9a6c0422
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Object.forward.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_OBJECT_FORWARD_H__
+#define __COCO_IR_OBJECT_FORWARD_H__
+
+namespace coco
+{
+
+class Object;
+
+} // namespace coco
+
+#endif // __COCO_IR_OBJECT_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/Object.h b/compiler/coco/core/include/coco/IR/Object.h
new file mode 100644
index 000000000..617e8a198
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Object.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_OBJECT_H__
+#define __COCO_IR_OBJECT_H__
+
+#include "coco/IR/Entity.h"
+#include "coco/IR/Bag.h"
+#include "coco/IR/Dep.h"
+#include "coco/IR/Def.forward.h"
+#include "coco/IR/UseSet.h"
+
+#include "coco/IR/FeatureObject.forward.h"
+#include "coco/IR/KernelObject.forward.h"
+
+#include <set>
+
+namespace coco
+{
+
+/**
+ * @brief Base interface on all typed NN values
+ */
+class Object : public Entity
+{
+public:
+ friend class Def;
+ friend class Use;
+
+public:
+ enum class Kind
+ {
+ Unknown,
+ Feature,
+ Kernel,
+ };
+
+public:
+ struct Producer : public Bag::Updater
+ {
+ virtual ~Producer() = default;
+ };
+
+ struct Consumer : public Bag::Reader
+ {
+ virtual ~Consumer() = default;
+ };
+
+ using ConsumerSet = std::set<Consumer *>;
+
+public:
+ Object();
+
+public:
+ virtual ~Object() = default;
+
+public:
+ virtual Kind kind(void) const { return Kind::Unknown; }
+
+public:
+ coco::Bag *bag(void) const { return _dep.bag(); }
+ void bag(coco::Bag *bag) { _dep.bag(bag); }
+
+public:
+ virtual FeatureObject *asFeature(void) { return nullptr; }
+ virtual const FeatureObject *asFeature(void) const { return nullptr; }
+
+ virtual KernelObject *asKernel(void) { return nullptr; }
+ virtual const KernelObject *asKernel(void) const { return nullptr; }
+
+public:
+ Def *def(void) const;
+ const UseSet *uses(void) const;
+
+private:
+ /**
+ * @brief Update the link to a producer
+ *
+ * WARN Only Def class is allowed to access this method
+ */
+ void def(Def *d);
+
+ // NOTE "mutable_" prefix is introduced to avoid resolution issue similarly as in Bag
+ // WARN Only Use class is allowed to access this method
+ UseSet *mutable_uses(void);
+
+private:
+ Dep _dep;
+ Def *_def = nullptr;
+ UseSet _uses;
+};
+
+/**
+ * @brief Check whether a given object is of type T
+ *
+ * The example below shows how to use this "isa<T>" helper:
+ * auto obj = new FeatureObject{};
+ *
+ * if (isa<FeatureObject>())
+ * {
+ * std::cout << "FeatureObject" << std::endl;
+ * }
+ */
+template <typename T> bool isa(const Object *);
+
+/**
+ * @brief Cast a generic object as a specific one
+ *
+ * "cast<T>(o)" accepts only a valid object pointer "o" that "isa<T>(o)" holds
+ * - Then, "cast<T>(o)" always returns a valid object pointer.
+ */
+template <typename T> T *cast(Object *);
+
+/**
+ * @brief Cast a generic object as a specific one
+ *
+ * Unlike "cast<T>", "safe_cast<T>" accepts any object pointer
+ * - "safe_cast<T>(nullptr)" returns "nullptr"
+ * - "safe_cast<T>(o)" returns "nullptr" if "isa<T>(o)" does not hold
+ */
+template <typename T> T *safe_cast(Object *);
+
+/// @brief Return the producer of a given object if it exists
+Object::Producer *producer(const Object *);
+
+/// @brief Return a set of consumers of a given object.
+Object::ConsumerSet consumers(const Object *);
+
+} // namespace coco
+
+#endif // __COCO_IR_OBJECT_H__
diff --git a/compiler/coco/core/include/coco/IR/ObjectManager.h b/compiler/coco/core/include/coco/IR/ObjectManager.h
new file mode 100644
index 000000000..a05b724ce
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/ObjectManager.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_OBJECT_MANAGER_H__
+#define __COCO_IR_OBJECT_MANAGER_H__
+
+#include "coco/IR/Object.h"
+#include "coco/IR/FeatureShape.h"
+#include "coco/IR/FeatureObject.h"
+#include "coco/IR/KernelObject.forward.h"
+#include "coco/IR/EntityBuilder.h"
+
+#include "coco/ADT/PtrManager.h"
+
+#include <nncc/core/ADT/kernel/Shape.h>
+
+namespace coco
+{
+
+class ObjectManager final : public PtrManager<Object>, public EntityBuilder
+{
+public:
+ ObjectManager(Module *m = nullptr) { module(m); }
+
+public:
+ template <typename T> T *create(void);
+
+public:
+ /**
+ * @brief Destroy (= deallocate) an Object entity
+ *
+ * NOTE An Object SHOULD HAVE NO DEF & USES to be destructed
+ * NOTE An Object WILL BE unlinked from its dependent bag (if has) on destruction
+ */
+ void destroy(Object *o);
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_OBJECT_MANAGER_H__
diff --git a/compiler/coco/core/include/coco/IR/ObjectSet.h b/compiler/coco/core/include/coco/IR/ObjectSet.h
new file mode 100644
index 000000000..d97781996
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/ObjectSet.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_OBJECT_SET_H__
+#define __COCO_IR_OBJECT_SET_H__
+
+#include "coco/IR/Object.forward.h"
+
+#include <set>
+
+namespace coco
+{
+
+using ObjectSet = std::set<Object *>;
+
+} // namespace coco
+
+#endif // __COCO_IR_OBJECT_SET_H__
diff --git a/compiler/coco/core/include/coco/IR/Op.forward.h b/compiler/coco/core/include/coco/IR/Op.forward.h
new file mode 100644
index 000000000..9ba3c94e3
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Op.forward.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_OP_FORWARD_H__
+#define __COCO_IR_OP_FORWARD_H__
+
+namespace coco
+{
+
+struct Op;
+
+} // namespace coco
+
+#endif // __COCO_IR_OP_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/Op.h b/compiler/coco/core/include/coco/IR/Op.h
new file mode 100644
index 000000000..090527e2f
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Op.h
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file Op.h
+ * @brief This header file declares "Op" class and several traits related with "Op"
+ */
+#ifndef __COCO_IR_OP_H__
+#define __COCO_IR_OP_H__
+
+#include "coco/IR/Object.forward.h"
+#include "coco/IR/Instr.forward.h"
+#include "coco/IR/Step.forward.h"
+#include "coco/IR/Part.h"
+#include "coco/IR/Entity.h"
+
+#include <set>
+
+#include <stdexcept>
+
+namespace coco
+{
+
+#define OP(Name) class Name;
+#include "coco/IR/Op.lst"
+#undef OP
+
+/**
+ * @brief Base interface on all supported NN operations
+ */
+struct Op : public Entity
+{
+ friend class Step;
+ friend class Part;
+
+ virtual ~Op();
+
+ /**
+ * @brief Return the number of arguments (# of child Ops)
+ */
+ virtual uint32_t arity(void) const = 0;
+
+ /**
+ * @brief Return N-th argument
+ *
+ * @note The behavior of arg(n) is defined only when n < artiy()
+ */
+ virtual Op *arg(uint32_t n) const = 0;
+
+ /**
+ * @brief Return a set of object(s) used during execution
+ *
+ * NOTE There is no 'def' method as Op is not allowed to define a new object
+ */
+ virtual std::set<Object *> uses(void) const = 0;
+
+#define OP(Name) \
+ virtual Name *as##Name(void) { return nullptr; } \
+ virtual const Name *as##Name(void) const { return nullptr; }
+#include "coco/IR/Op.lst"
+#undef OP
+
+ /**
+ * @brief Op visitor interface
+ *
+ * WARN Use this interface only for coco-internal classes
+ * (to minimize changes upon Op extension)
+ */
+ template <typename T> struct IVisitor
+ {
+ virtual ~IVisitor() = default;
+
+#define OP(Name) virtual T visit(const Name *) = 0;
+#include "coco/IR/Op.lst"
+#undef OP
+ };
+
+ template <typename T> struct Visitor : public IVisitor<T>
+ {
+ virtual ~Visitor() = default;
+
+#define OP(Name) \
+ T visit(const Name *) override { throw std::runtime_error{"NYI"}; }
+#include "coco/IR/Op.lst"
+#undef OP
+ };
+
+ template <typename T> T accept(IVisitor<T> *v) const
+ {
+#define OP(Name) \
+ if (auto op = as##Name()) \
+ { \
+ return v->visit(op); \
+ }
+#include "coco/IR/Op.lst"
+#undef OP
+ throw std::runtime_error{"unreachable"};
+ }
+
+ template <typename T> T accept(IVisitor<T> &v) const { return accept(&v); }
+ template <typename T> T accept(IVisitor<T> &&v) const { return accept(&v); }
+
+public:
+ /**
+ * @brief Op mutator interface
+ *
+ * WARN Use this interface only for coco-internal classes
+ * (to minimize changes upon Instr extension)
+ */
+ struct IMutator
+ {
+ virtual ~IMutator() = default;
+
+#define OP(Name) virtual void mutate(Name *) = 0;
+#include "coco/IR/Op.lst"
+#undef OP
+ };
+
+ struct Mutator : public IMutator
+ {
+ virtual ~Mutator() = default;
+
+#define OP(Name) \
+ void mutate(Name *) override { throw std::runtime_error{"NYI"}; }
+#include "coco/IR/Op.lst"
+#undef OP
+ };
+
+ void accept(IMutator *m)
+ {
+#define OP(Name) \
+ if (auto op = as##Name()) \
+ { \
+ return m->mutate(op); \
+ }
+#include "coco/IR/Op.lst"
+#undef OP
+ throw std::runtime_error{"unreachable"};
+ }
+
+ void accept(IMutator &m) { return accept(&m); }
+ void accept(IMutator &&m) { return accept(&m); }
+
+public:
+ Instr *parent(void) const;
+
+ /// @brief Return a pointer to the parent Op
+ Op *up(void) const;
+
+private:
+ /**
+ * @brief A link to Instr from Op
+ *
+ * WARN Update this field only through Step
+ */
+ Step *_step = nullptr;
+
+ /**
+ * @brief A link to a parent Op
+ *
+ * WARN Update this field only through Part
+ * NOTE An "Op" CANNOT have a link to a parent Op if it is linked to an "Instr"
+ */
+ Part *_part = nullptr;
+};
+
+/**
+ * @brief Op with a single argument
+ */
+class UnaryOp : public Op
+{
+public:
+ explicit UnaryOp();
+
+public:
+ UnaryOp(const UnaryOp &) = delete;
+ UnaryOp(UnaryOp &&) = delete;
+
+public:
+ virtual ~UnaryOp() = default;
+
+public:
+ uint32_t arity(void) const final;
+ Op *arg(uint32_t n) const final;
+
+ std::set<Object *> uses(void) const final;
+
+public:
+ Op *arg(void) const { return _arg.child(); }
+ void arg(Op *arg) { _arg.child(arg); }
+
+private:
+ /// @brief Link to Op's argument
+ Part _arg;
+};
+
+/**
+ * @brief Op with two arguments
+ */
+class BinaryOp : public Op
+{
+public:
+ explicit BinaryOp();
+
+public:
+ BinaryOp(const BinaryOp &) = delete;
+ BinaryOp(BinaryOp &&) = delete;
+
+public:
+ virtual ~BinaryOp() = default;
+
+public:
+ uint32_t arity(void) const final;
+ Op *arg(uint32_t n) const final;
+
+ std::set<Object *> uses(void) const final;
+
+public:
+ Op *left(void) const { return _left.child(); }
+ void left(Op *op) { _left.child(op); }
+
+public:
+ Op *right(void) const { return _right.child(); }
+ void right(Op *op) { _right.child(op); }
+
+private:
+ /// @brief Left-hand side (LHS) argument
+ Part _left;
+ /// @brief Right-hand side (RHS) argument
+ Part _right;
+};
+
+/**
+ * @brief Return the root Op from a given Op node
+ *
+ * @note root(op) == op holds for a root op
+ */
+Op *root(Op *);
+
+} // namespace coco
+
+#endif // __COCO_IR_OP_H__
diff --git a/compiler/coco/core/include/coco/IR/Op.lst b/compiler/coco/core/include/coco/IR/Op.lst
new file mode 100644
index 000000000..a3028bde2
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Op.lst
@@ -0,0 +1,19 @@
+#ifndef OP
+#error OP should be defined before including this file
+#endif // OP
+
+// OP(Name)
+
+OP(Load)
+OP(Conv2D)
+OP(MaxPool2D)
+OP(AvgPool2D)
+OP(PadF)
+OP(ReLU)
+OP(ReLU6)
+OP(Add)
+OP(Sqrt)
+OP(Sub)
+OP(Mul)
+OP(Div)
+OP(ConcatF)
diff --git a/compiler/coco/core/include/coco/IR/OpManager.h b/compiler/coco/core/include/coco/IR/OpManager.h
new file mode 100644
index 000000000..2c88867de
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/OpManager.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_OP_MANAGER_H__
+#define __COCO_IR_OP_MANAGER_H__
+
+#include "coco/IR/Op.h"
+#include "coco/IR/Ops.h"
+
+#include "coco/IR/Instr.forward.h"
+
+#include "coco/IR/Object.forward.h"
+
+#include "coco/IR/EntityBuilder.h"
+
+#include "coco/ADT/PtrManager.h"
+
+namespace coco
+{
+
+class OpManager final : public PtrManager<Op>, public EntityBuilder
+{
+public:
+ OpManager(Module *m = nullptr) { module(m); }
+
+public:
+ ~OpManager();
+
+public:
+ template <typename T> T *create(void);
+
+public:
+ /**
+ * @brief Destroy (= deallocate) a Op instance
+ *
+ * NOTE destroy(op) WILL NOT update op->parent(). Client SHOULD detach op before destroy(op) call
+ */
+ void destroy(Op *);
+
+ /**
+ * @brief Destroy a Op tree
+ *
+ * @require op->parent() == nullptr && op->up() == nullptr
+ */
+ void destroy_all(Op *);
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_OP_MANAGER_H__
diff --git a/compiler/coco/core/include/coco/IR/Ops.h b/compiler/coco/core/include/coco/IR/Ops.h
new file mode 100644
index 000000000..01ac92b7f
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Ops.h
@@ -0,0 +1,412 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_OPS_H__
+#define __COCO_IR_OPS_H__
+
+#include "coco/IR/Op.h"
+#include "coco/IR/Object.h"
+#include "coco/IR/KernelObject.h"
+
+#include "coco/IR/Use.h"
+#include "coco/IR/Part.h"
+
+#include "coco/IR/Padding2D.h"
+#include "coco/IR/Stride2D.h"
+#include "coco/IR/Window2D.h"
+
+namespace coco
+{
+
+/**
+ * @brief Load an Object
+ */
+class Load final : public Op, public Object::Consumer
+{
+public:
+ explicit Load();
+
+public:
+ Load(const Load &) = delete;
+ Load(Load &&) = delete;
+
+public:
+ uint32_t arity(void) const final;
+ Op *arg(uint32_t n) const final;
+
+ std::set<Object *> uses(void) const override;
+
+public:
+ Load *asLoad(void) override { return this; }
+ const Load *asLoad(void) const override { return this; }
+
+public:
+ Instr *loc(void) override { return parent(); }
+
+public:
+ void object(Object *o) { _obj.value(o); }
+ Object *object(void) const { return _obj.value(); }
+
+private:
+ Use _obj;
+};
+
+/**
+ * @brief 2D Convolution over 3D Feature Map with 4D kernel
+ *
+ * NOTE IFM and OFM are implicit. Only 4D kernel is explicit in this class
+ * TODO Decide source code layout policy and extract this class if necessary
+ */
+class Conv2D : public Op, public Object::Consumer
+{
+public:
+ explicit Conv2D();
+
+public:
+ uint32_t arity(void) const final;
+ Op *arg(uint32_t n) const final;
+
+ std::set<Object *> uses(void) const override;
+
+public:
+ Conv2D *asConv2D(void) override { return this; }
+ const Conv2D *asConv2D(void) const override { return this; }
+
+public:
+ Instr *loc(void) override { return parent(); }
+
+private:
+ Use _ker;
+
+public:
+ Op *arg(void) const { return _arg.child(); }
+ void arg(Op *arg) { _arg.child(arg); }
+
+public:
+ KernelObject *ker(void) const;
+ void ker(KernelObject *ker);
+
+public:
+ /**
+ * @brief Divide an input and kernel (= convolution filter) into G independent groups
+ *
+ * Given an input of shape(Ic, Ih, Iw), a kernel of shape(Kn, Kc, Kh, Kw), and group G,
+ * Conv2D is identical to G independent convolutions over G inputs of shape(Ic / G, Ih, Iw)
+ * and a kernel of shape(Kn / G, Kc, Kh, Kw) followed by concatenation.
+ *
+ * REQUIRED
+ * - "Ic" SHOULD BE a multiple of "G"
+ * - "Kc" SHOULD BE identical to "Ic /G"
+ *
+ * NOTE Depthwise convolution is a special case of group convolution where Ic == G.
+ */
+ uint32_t group(void) const { return _group; }
+ void group(uint32_t g) { _group = g; }
+
+public:
+ Padding2D *pad(void) { return &_pad; }
+ const Padding2D *pad(void) const { return &_pad; }
+
+public:
+ Stride2D *stride(void) { return &_stride; }
+ const Stride2D *stride(void) const { return &_stride; }
+
+private:
+ uint32_t _group = 1;
+
+ Padding2D _pad;
+ Stride2D _stride;
+
+private:
+ /// @brief Link to an argument of Conv2D operation (= IFM)
+ Part _arg;
+};
+
+/**
+ * @brief 2D Max Pooling
+ */
+class MaxPool2D final : public UnaryOp
+{
+public:
+ explicit MaxPool2D() = default;
+
+public:
+ MaxPool2D(const MaxPool2D &) = delete;
+ MaxPool2D(MaxPool2D &&) = delete;
+
+public:
+ MaxPool2D *asMaxPool2D(void) override { return this; }
+ const MaxPool2D *asMaxPool2D(void) const override { return this; }
+
+public:
+ Window2D *window(void) { return &_window; }
+ const Window2D *window(void) const { return &_window; }
+
+public:
+ Stride2D *stride(void) { return &_stride; }
+ const Stride2D *stride(void) const { return &_stride; }
+
+public:
+ Padding2D *pad(void) { return &_pad; }
+ const Padding2D *pad(void) const { return &_pad; }
+
+private:
+ Window2D _window;
+ Stride2D _stride;
+ Padding2D _pad;
+};
+
+/**
+ * @brief 2D Average Pooling
+ */
+class AvgPool2D final : public UnaryOp
+{
+public:
+ enum class Divisor
+ {
+ Unknown,
+ // Use the number of elements in each receptive field as a divisor
+ Static,
+ // Use the number of valid (non-padding) elements in each receptive field as a divisor
+ PaddingExcluded
+ };
+
+public:
+ explicit AvgPool2D() = default;
+
+public:
+ AvgPool2D(const AvgPool2D &) = delete;
+ AvgPool2D(AvgPool2D &&) = delete;
+
+public:
+ AvgPool2D *asAvgPool2D(void) override { return this; }
+ const AvgPool2D *asAvgPool2D(void) const override { return this; }
+
+public:
+ Divisor divisor(void) const { return _divisor; }
+ void divisor(const Divisor &divisor) { _divisor = divisor; }
+
+public:
+ Window2D *window(void) { return &_window; }
+ const Window2D *window(void) const { return &_window; }
+
+public:
+ Padding2D *pad(void) { return &_pad; }
+ const Padding2D *pad(void) const { return &_pad; }
+
+public:
+ Stride2D *stride(void) { return &_stride; }
+ const Stride2D *stride(void) const { return &_stride; }
+
+private:
+ Divisor _divisor = Divisor::Unknown;
+
+ Window2D _window;
+ Stride2D _stride;
+ Padding2D _pad;
+};
+
+/**
+ * @brief Introduce padding area
+ */
+class PadF final : public UnaryOp
+{
+public:
+ explicit PadF() = default;
+
+public:
+ PadF(const PadF &) = delete;
+ PadF(PadF &&) = delete;
+
+public:
+ PadF *asPadF(void) override { return this; }
+ const PadF *asPadF(void) const override { return this; }
+
+public:
+ Padding2D *pad(void) { return &_pad; }
+ const Padding2D *pad(void) const { return &_pad; }
+
+private:
+ Padding2D _pad;
+};
+
+/**
+ * @brief Apply ReLU over elements
+ */
+class ReLU final : public UnaryOp
+{
+public:
+ explicit ReLU() = default;
+
+public:
+ ReLU(const ReLU &) = delete;
+ ReLU(ReLU &&) = delete;
+
+public:
+ ReLU *asReLU(void) override { return this; }
+ const ReLU *asReLU(void) const override { return this; }
+};
+
+/**
+ * @brief Apply ReLU6 over elements
+ * @note ReLU6 is subject to change
+ */
+class ReLU6 final : public UnaryOp
+{
+public:
+ explicit ReLU6() = default;
+
+public:
+ ReLU6(const ReLU6 &) = delete;
+ ReLU6(ReLU6 &&) = delete;
+
+public:
+ ReLU6 *asReLU6(void) override { return this; }
+ const ReLU6 *asReLU6(void) const override { return this; }
+};
+
+/**
+ * @brief Element-wise addition
+ *
+ * Add(L, R) is valid only when L and R have identical kind/shape/dtype
+ */
+class Add final : public BinaryOp
+{
+public:
+ explicit Add() = default;
+
+public:
+ Add(const Add &) = delete;
+ Add(Add &&) = delete;
+
+public:
+ Add *asAdd(void) override { return this; }
+ const Add *asAdd(void) const override { return this; }
+};
+
+/**
+ * @brief Element-wise subtraction
+ *
+ * Sub(L, R) is valid only when L and R have identical kind/shape/dtype
+ */
+class Sub final : public BinaryOp
+{
+public:
+ explicit Sub() = default;
+
+public:
+ Sub(const Sub &) = delete;
+ Sub(Sub &&) = delete;
+
+public:
+ Sub *asSub(void) override { return this; }
+ const Sub *asSub(void) const override { return this; }
+};
+
+/**
+ * @brief Element-wise multiplication
+ *
+ * Mul(L, R) is valid only when L and R have identical kind/shape/dtype
+ */
+class Mul final : public BinaryOp
+{
+public:
+ explicit Mul() = default;
+
+public:
+ Mul(const Mul &) = delete;
+ Mul(Mul &&) = delete;
+
+public:
+ Mul *asMul(void) override { return this; }
+ const Mul *asMul(void) const override { return this; }
+};
+
+/**
+ * @brief Element-wise division
+ *
+ * Div(L, R) is valid only when L and R have identical kind/shape/dtype
+ */
+class Div final : public BinaryOp
+{
+public:
+ explicit Div() = default;
+
+public:
+ Div(const Div &) = delete;
+ Div(Div &&) = delete;
+
+public:
+ Div *asDiv(void) override { return this; }
+ const Div *asDiv(void) const override { return this; }
+};
+
+/**
+ * @brief Concatenate two feature maps
+ *
+ * ConcatF(L, R) requires
+ */
+class ConcatF final : public BinaryOp
+{
+public:
+ enum class Axis
+ {
+ Unknown = 0,
+ Batch = 1,
+ Depth = 2,
+ Height = 3,
+ Width = 4,
+ };
+
+public:
+ explicit ConcatF() = default;
+
+public:
+ ConcatF(const ConcatF &) = delete;
+ ConcatF(ConcatF &&) = delete;
+
+public:
+ ConcatF *asConcatF(void) override { return this; }
+ const ConcatF *asConcatF(void) const override { return this; }
+
+public:
+ const Axis &axis(void) const { return _axis; }
+ void axis(const Axis &axis) { _axis = axis; }
+
+private:
+ Axis _axis = Axis::Unknown;
+};
+
+/**
+ * @brief Apply Sqrt over elements
+ */
+class Sqrt final : public UnaryOp
+{
+public:
+ explicit Sqrt() = default;
+
+public:
+ Sqrt(const Sqrt &) = delete;
+ Sqrt(Sqrt &&) = delete;
+
+public:
+ Sqrt *asSqrt(void) override { return this; }
+ const Sqrt *asSqrt(void) const override { return this; }
+};
+
+} // namesapce coco
+
+#endif // __COCO_IR_OPS_H__
diff --git a/compiler/coco/core/include/coco/IR/Output.forward.h b/compiler/coco/core/include/coco/IR/Output.forward.h
new file mode 100644
index 000000000..f011400c0
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Output.forward.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_OUTPUT_FORWARD_H__
+#define __COCO_IR_OUTPUT_FORWARD_H__
+
+namespace coco
+{
+
+class Output;
+
+} // namespace coco
+
+#endif // __COCO_IR_OUTPUT_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/Output.h b/compiler/coco/core/include/coco/IR/Output.h
new file mode 100644
index 000000000..3f77c131d
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Output.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_OUTPUT_H__
+#define __COCO_IR_OUTPUT_H__
+
+#include "coco/IR/Arg.h"
+#include "coco/IR/Entity.h"
+
+#include <nncc/core/ADT/tensor/Shape.h>
+#include <nncc/core/ADT/tensor/Index.h>
+
+#include <string>
+#include <vector>
+
+namespace coco
+{
+
+class Output final : public Arg, public Entity
+{
+public:
+ Output(const nncc::core::ADT::tensor::Shape &shape);
+
+private:
+ void onTake(Bag *) override;
+ void onRelease(Bag *) override;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_OUTPUT_H__
diff --git a/compiler/coco/core/include/coco/IR/OutputList.h b/compiler/coco/core/include/coco/IR/OutputList.h
new file mode 100644
index 000000000..0e2abad75
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/OutputList.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_OUTPUT_LIST_H__
+#define __COCO_IR_OUTPUT_LIST_H__
+
+#include "coco/IR/Output.h"
+
+#include "coco/ADT/PtrList.h"
+
+namespace coco
+{
+
+using OutputList = PtrList<Output>;
+
+} // namespace coco
+
+#endif // __COCO_IR_OUTPUT_LIST_H__
diff --git a/compiler/coco/core/include/coco/IR/OutputManager.h b/compiler/coco/core/include/coco/IR/OutputManager.h
new file mode 100644
index 000000000..b40380388
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/OutputManager.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_OUTPUT_MANAGER_H__
+#define __COCO_IR_OUTPUT_MANAGER_H__
+
+#include "coco/IR/Output.h"
+#include "coco/IR/EntityBuilder.h"
+
+#include "coco/ADT/PtrManager.h"
+
+namespace coco
+{
+
+class OutputManager final : public PtrManager<Output>, public EntityBuilder
+{
+public:
+ OutputManager(Module *m = nullptr) { module(m); }
+
+public:
+ Output *create(const nncc::core::ADT::tensor::Shape &);
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_OUTPUT_MANAGER_H__
diff --git a/compiler/coco/core/include/coco/IR/Padding2D.h b/compiler/coco/core/include/coco/IR/Padding2D.h
new file mode 100644
index 000000000..b764656cc
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Padding2D.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_PADDING_2D_H__
+#define __COCO_IR_PADDING_2D_H__
+
+#include <cstdint>
+
+namespace coco
+{
+
+class Padding2D
+{
+public:
+ Padding2D() : _top{0}, _bottom{0}, _left{0}, _right{0}
+ {
+ // DO NOTHING
+ }
+
+public:
+ Padding2D(uint32_t top, uint32_t bottom, uint32_t left, uint32_t right)
+ : _top{top}, _bottom{bottom}, _left{left}, _right{right}
+ {
+ // DO NOTHING
+ }
+
+public:
+ uint32_t top(void) const { return _top; }
+ Padding2D &top(uint32_t value);
+
+public:
+ uint32_t bottom(void) const { return _bottom; }
+ Padding2D &bottom(uint32_t value);
+
+public:
+ uint32_t left(void) const { return _left; }
+ Padding2D &left(uint32_t value);
+
+public:
+ uint32_t right(void) const { return _right; }
+ Padding2D &right(uint32_t value);
+
+private:
+ uint32_t _top;
+ uint32_t _bottom;
+ uint32_t _left;
+ uint32_t _right;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_PADDING_2D_H__
diff --git a/compiler/coco/core/include/coco/IR/Part.forward.h b/compiler/coco/core/include/coco/IR/Part.forward.h
new file mode 100644
index 000000000..642ea56b5
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Part.forward.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_PART_FORWARD_H__
+#define __COCO_IR_PART_FORWARD_H__
+
+namespace coco
+{
+
+class Part;
+
+} // namespace coco
+
+#endif // __COCO_IR_PART_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/Part.h b/compiler/coco/core/include/coco/IR/Part.h
new file mode 100644
index 000000000..72af217cc
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Part.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_PART_H__
+#define __COCO_IR_PART_H__
+
+#include "coco/IR/Op.forward.h"
+
+namespace coco
+{
+
+/**
+ * @brief A Part represents the edge between a child Op and its parent Op
+ */
+class Part final
+{
+public:
+ Part(Op *parent) : _parent{parent}
+ {
+ // DO NOTHING
+ }
+
+public:
+ ~Part() { child(nullptr); }
+
+public:
+ Op *child(void) const { return _child; }
+ void child(Op *c);
+
+public:
+ Op *parent(void) const { return _parent; }
+
+private:
+ Op *_parent = nullptr;
+ Op *_child = nullptr;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_PART_H__
diff --git a/compiler/coco/core/include/coco/IR/Read.forward.h b/compiler/coco/core/include/coco/IR/Read.forward.h
new file mode 100644
index 000000000..7fd99e212
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Read.forward.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_READ_FORWARD_H__
+#define __COCO_IR_READ_FORWARD_H__
+
+namespace coco
+{
+
+class Read;
+
+} // namespace coco
+
+#endif // __COCO_IR_READ_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/Read.h b/compiler/coco/core/include/coco/IR/Read.h
new file mode 100644
index 000000000..9f62d8bf8
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Read.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_READ_H__
+#define __COCO_IR_READ_H__
+
+#include "coco/IR/Bag.h"
+
+namespace coco
+{
+
+/**
+ * @brief A Read represents an edge between a Bag and its Reader
+ */
+class Read final
+{
+public:
+ Read(Bag::Reader *r)
+ {
+ // Initialize link and reader
+ reader(r);
+ }
+
+public:
+ ~Read();
+
+public:
+ Bag *bag(void) const { return _bag; }
+ void bag(Bag *bag);
+
+public:
+ Bag::Reader *reader(void) const { return _reader; }
+ void reader(Bag::Reader *r) { _reader = r; }
+
+private:
+ Bag *_bag = nullptr;
+ Bag::Reader *_reader = nullptr;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_READ_H__
diff --git a/compiler/coco/core/include/coco/IR/ReadSet.h b/compiler/coco/core/include/coco/IR/ReadSet.h
new file mode 100644
index 000000000..c470c4bfd
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/ReadSet.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_READ_SET_H__
+#define __COCO_IR_READ_SET_H__
+
+#include "coco/IR/Read.forward.h"
+
+#include <set>
+
+namespace coco
+{
+
+using ReadSet = std::set<Read *>;
+
+} // namespace coco
+
+#endif // __COCO_IR_READ_SET_H__
diff --git a/compiler/coco/core/include/coco/IR/Step.forward.h b/compiler/coco/core/include/coco/IR/Step.forward.h
new file mode 100644
index 000000000..635069122
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Step.forward.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_STEP_FORWARD_H__
+#define __COCO_IR_STEP_FORWARD_H__
+
+namespace coco
+{
+
+class Step;
+
+} // namespace coco
+
+#endif // __COCO_IR_STEP_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/Step.h b/compiler/coco/core/include/coco/IR/Step.h
new file mode 100644
index 000000000..31dad4389
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Step.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_STEP_H__
+#define __COCO_IR_STEP_H__
+
+#include "coco/IR/Op.forward.h"
+#include "coco/IR/Instr.forward.h"
+
+namespace coco
+{
+
+/**
+ * @brief A Step denotes the edge between Op and Instr
+ */
+class Step final
+{
+public:
+ explicit Step(Instr *instr) : _instr{instr}
+ {
+ // DO NOTHING
+ }
+
+public:
+ ~Step() { op(nullptr); }
+
+public:
+ Op *op(void) const { return _op; }
+ void op(Op *o);
+
+public:
+ Instr *instr(void) const { return _instr; }
+
+private:
+ Op *_op = nullptr;
+ Instr *_instr = nullptr;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_STEP_H__
diff --git a/compiler/coco/core/include/coco/IR/Stride2D.h b/compiler/coco/core/include/coco/IR/Stride2D.h
new file mode 100644
index 000000000..9e69ffa40
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Stride2D.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_STRIDE_2D_H__
+#define __COCO_IR_STRIDE_2D_H__
+
+#include <cstdint>
+
+namespace coco
+{
+
+class Stride2D
+{
+public:
+ Stride2D() : _vertical{1}, _horizontal{1}
+ {
+ // DO NOTHING
+ }
+
+public:
+ Stride2D(uint32_t vertical, uint32_t horizontal) : _vertical{vertical}, _horizontal{horizontal}
+ {
+ // DO NOTHING
+ }
+
+public:
+ uint32_t vertical(void) const { return _vertical; }
+ Stride2D &vertical(uint32_t value);
+
+public:
+ uint32_t horizontal(void) const { return _horizontal; }
+ Stride2D &horizontal(uint32_t value);
+
+private:
+ uint32_t _vertical;
+ uint32_t _horizontal;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_STRIDE_2D_H__
diff --git a/compiler/coco/core/include/coco/IR/Update.forward.h b/compiler/coco/core/include/coco/IR/Update.forward.h
new file mode 100644
index 000000000..059f318c9
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Update.forward.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_UPDATE_FORWARD_H__
+#define __COCO_IR_UPDATE_FORWARD_H__
+
+namespace coco
+{
+
+class Update;
+
+} // namespace coco
+
+#endif // __COCO_IR_UPDATE_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/Update.h b/compiler/coco/core/include/coco/IR/Update.h
new file mode 100644
index 000000000..7cf876d74
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Update.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_UPDATE_H__
+#define __COCO_IR_UPDATE_H__
+
+#include "coco/IR/Bag.h"
+
+namespace coco
+{
+
+/**
+ * @brief A Update represents an edge between a Bag and its Updater
+ */
+class Update final
+{
+public:
+ Update(Bag::Updater *u) { updater(u); }
+
+public:
+ ~Update();
+
+public:
+ Bag *bag(void) const { return _bag; }
+ void bag(Bag *bag);
+
+public:
+ Bag::Updater *updater(void) const { return _updater; }
+ void updater(Bag::Updater *u) { _updater = u; }
+
+private:
+ Bag *_bag = nullptr;
+ Bag::Updater *_updater = nullptr;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_UPDATE_H__
diff --git a/compiler/coco/core/include/coco/IR/UpdateSet.h b/compiler/coco/core/include/coco/IR/UpdateSet.h
new file mode 100644
index 000000000..1e772adf3
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/UpdateSet.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_UPDATE_SET_H__
+#define __COCO_IR_UPDATE_SET_H__
+
+#include "coco/IR/Update.forward.h"
+
+#include <set>
+
+namespace coco
+{
+
+using UpdateSet = std::set<Update *>;
+
+} // namespace coco
+
+#endif // __COCO_IR_UPDATE_SET_H__
diff --git a/compiler/coco/core/include/coco/IR/Use.forward.h b/compiler/coco/core/include/coco/IR/Use.forward.h
new file mode 100644
index 000000000..329430bb3
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Use.forward.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_USE_FORWARD_H__
+#define __COCO_IR_USE_FORWARD_H__
+
+namespace coco
+{
+
+class Use;
+
+} // namespace coco
+
+#endif // __COCO_IR_USE_FORWARD_H__
diff --git a/compiler/coco/core/include/coco/IR/Use.h b/compiler/coco/core/include/coco/IR/Use.h
new file mode 100644
index 000000000..c4c9b98b4
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Use.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_USE_H__
+#define __COCO_IR_USE_H__
+
+#include "coco/IR/Object.h"
+
+namespace coco
+{
+
+class Use final
+{
+public:
+ Use(Object::Consumer *use) : _value{nullptr}, _consumer{use}
+ {
+ // DO NOTHING
+ }
+
+public:
+ ~Use() { value(nullptr); }
+
+public:
+ Object *value(void) const { return _value; }
+
+public:
+ void value(Object *value);
+
+public:
+ Object::Consumer *consumer(void) const { return _consumer; }
+
+private:
+ Object *_value;
+ Object::Consumer *_consumer = nullptr;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_USE_H__
diff --git a/compiler/coco/core/include/coco/IR/UseSet.h b/compiler/coco/core/include/coco/IR/UseSet.h
new file mode 100644
index 000000000..a698a733f
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/UseSet.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_USE_SET_H__
+#define __COCO_IR_USE_SET_H__
+
+#include "coco/IR/Use.forward.h"
+
+#include <set>
+
+namespace coco
+{
+
+using UseSet = std::set<Use *>;
+
+} // namespace coco
+
+#endif // __COCO_IR_USE_SET_H__
diff --git a/compiler/coco/core/include/coco/IR/Window2D.h b/compiler/coco/core/include/coco/IR/Window2D.h
new file mode 100644
index 000000000..a434538f3
--- /dev/null
+++ b/compiler/coco/core/include/coco/IR/Window2D.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_WINDOW_2D_H__
+#define __COCO_IR_WINDOW_2D_H__
+
+#include <cstdint>
+
+namespace coco
+{
+
+class Window2D
+{
+public:
+ Window2D() : _vertical{1}, _horizontal{1}
+ {
+ // DO NOTHING
+ }
+
+public:
+ Window2D(uint32_t vertical, uint32_t horizontal) : _vertical{vertical}, _horizontal{horizontal}
+ {
+ // DO NOTHING
+ }
+
+public:
+ uint32_t height(void) const { return _vertical; }
+ void height(uint32_t value) { _vertical = value; }
+
+public:
+ uint32_t width(void) const { return _horizontal; }
+ void width(uint32_t value) { _horizontal = value; }
+
+private:
+ // TODO Rename these fields as _height and _width, respectively
+ uint32_t _vertical;
+ uint32_t _horizontal;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_WINDOW_2D_H__
diff --git a/compiler/coco/core/src/ADT/DLinkedList.test.cpp b/compiler/coco/core/src/ADT/DLinkedList.test.cpp
new file mode 100644
index 000000000..563a39653
--- /dev/null
+++ b/compiler/coco/core/src/ADT/DLinkedList.test.cpp
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/ADT/DLinkedList.h"
+
+#include <set>
+
+#include <gtest/gtest.h>
+
+namespace
+{
+
+class Parent;
+class Child;
+
+using ChildList = coco::DLinkedList<Child, Parent>::Head;
+
+class Parent
+{
+public:
+ friend void coco::DLinkedList<Child, Parent>::joined(Parent *, Child *);
+ friend void coco::DLinkedList<Child, Parent>::leaving(Parent *, Child *);
+
+public:
+ Parent() : _list{this}, _count{0}
+ {
+ // DO NOTHING
+ }
+
+public:
+ ChildList *children(void) { return &_list; }
+ uint32_t count(void) const { return _count; }
+
+private:
+ ChildList _list;
+ uint32_t _count;
+};
+
+class Child final : public coco::DLinkedList<Child, Parent>::Node
+{
+public:
+ ~Child()
+ {
+ if (parent())
+ {
+ detach();
+ }
+ }
+};
+
+} // namespace
+
+namespace coco
+{
+
+template <> void DLinkedList<Child, Parent>::joined(Parent *p, Child *) { p->_count += 1; }
+template <> void DLinkedList<Child, Parent>::leaving(Parent *p, Child *) { p->_count -= 1; }
+
+template <> ChildList *DLinkedList<Child, Parent>::head(Parent *p) { return p->children(); }
+
+} // namespace coco
+
+namespace
+{
+class DLinkedListTest : public ::testing::Test
+{
+public:
+ virtual ~DLinkedListTest()
+ {
+ // NOTE Child SHOULD BE freed before parent
+ for (auto child : _children)
+ {
+ delete child;
+ }
+
+ for (auto parent : _parents)
+ {
+ delete parent;
+ }
+ }
+
+protected:
+ template <typename T> T *create(void);
+
+ void destroy(Child *);
+
+private:
+ std::set<::Parent *> _parents;
+ std::set<::Child *> _children;
+};
+
+template <>::Parent *DLinkedListTest::create(void)
+{
+ auto parent = new ::Parent;
+ _parents.insert(parent);
+ return parent;
+}
+
+template <>::Child *DLinkedListTest::create(void)
+{
+ auto child = new ::Child;
+ _children.insert(child);
+ return child;
+}
+
+void DLinkedListTest::destroy(Child *child)
+{
+ _children.erase(child);
+ delete child;
+}
+
+} // namespace
+
+TEST_F(DLinkedListTest, append)
+{
+ auto parent = create<::Parent>();
+ auto child = create<::Child>();
+
+ parent->children()->append(child);
+
+ ASSERT_EQ(child->parent(), parent);
+ ASSERT_EQ(child->prev(), nullptr);
+ ASSERT_EQ(child->next(), nullptr);
+
+ ASSERT_EQ(parent->children()->head(), child);
+ ASSERT_EQ(parent->children()->tail(), child);
+ ASSERT_EQ(parent->count(), 1);
+}
+
+TEST_F(DLinkedListTest, insert_two_elements)
+{
+ auto parent = create<::Parent>();
+
+ ASSERT_EQ(parent->children()->head(), nullptr);
+ ASSERT_EQ(parent->children()->tail(), nullptr);
+
+ auto child_1 = create<::Child>();
+
+ ASSERT_EQ(child_1->parent(), nullptr);
+ ASSERT_EQ(child_1->prev(), nullptr);
+ ASSERT_EQ(child_1->next(), nullptr);
+
+ parent->children()->append(child_1);
+
+ ASSERT_EQ(child_1->parent(), parent);
+ ASSERT_EQ(child_1->prev(), nullptr);
+ ASSERT_EQ(child_1->next(), nullptr);
+
+ ASSERT_EQ(parent->children()->head(), child_1);
+ ASSERT_EQ(parent->children()->tail(), child_1);
+
+ auto child_2 = create<::Child>();
+
+ ASSERT_EQ(child_2->parent(), nullptr);
+ ASSERT_EQ(child_2->prev(), nullptr);
+ ASSERT_EQ(child_2->next(), nullptr);
+
+ child_2->insertAfter(child_1);
+
+ ASSERT_EQ(child_2->parent(), parent);
+ ASSERT_EQ(child_2->prev(), child_1);
+ ASSERT_EQ(child_2->next(), nullptr);
+
+ ASSERT_EQ(child_1->parent(), parent);
+ ASSERT_EQ(child_1->prev(), nullptr);
+ ASSERT_EQ(child_1->next(), child_2);
+
+ ASSERT_EQ(parent->children()->head(), child_1);
+ ASSERT_EQ(parent->children()->tail(), child_2);
+}
+
+TEST_F(DLinkedListTest, insertBefore)
+{
+ auto parent = create<::Parent>();
+
+ auto child_1 = create<::Child>();
+ auto child_2 = create<::Child>();
+
+ parent->children()->append(child_1);
+ child_2->insertBefore(child_1);
+
+ ASSERT_EQ(child_2->parent(), parent);
+ ASSERT_EQ(child_2->prev(), nullptr);
+ ASSERT_EQ(child_2->next(), child_1);
+
+ ASSERT_EQ(child_1->parent(), parent);
+ ASSERT_EQ(child_1->prev(), child_2);
+ ASSERT_EQ(child_1->next(), nullptr);
+
+ ASSERT_EQ(parent->children()->head(), child_2);
+ ASSERT_EQ(parent->children()->tail(), child_1);
+}
+
+TEST_F(DLinkedListTest, prepend_after_append)
+{
+ auto parent = create<::Parent>();
+
+ auto child_1 = create<::Child>();
+ auto child_2 = create<::Child>();
+
+ parent->children()->append(child_1);
+ parent->children()->prepend(child_2);
+
+ ASSERT_EQ(child_2->next(), child_1);
+
+ ASSERT_EQ(child_1->parent(), parent);
+ ASSERT_EQ(child_1->prev(), child_2);
+ ASSERT_EQ(child_1->next(), nullptr);
+
+ ASSERT_EQ(parent->children()->head(), child_2);
+ ASSERT_EQ(parent->children()->tail(), child_1);
+}
+
+TEST_F(DLinkedListTest, detach)
+{
+ auto parent = create<::Parent>();
+
+ auto child_1 = create<::Child>();
+ auto child_2 = create<::Child>();
+
+ parent->children()->append(child_1);
+ parent->children()->append(child_2);
+
+ child_1->detach();
+
+ ASSERT_EQ(child_1->parent(), nullptr);
+ ASSERT_EQ(child_1->prev(), nullptr);
+ ASSERT_EQ(child_1->next(), nullptr);
+
+ ASSERT_EQ(child_2->parent(), parent);
+ ASSERT_EQ(child_2->prev(), nullptr);
+
+ ASSERT_EQ(parent->children()->head(), child_2);
+ ASSERT_EQ(parent->children()->tail(), child_2);
+
+ child_2->detach();
+
+ ASSERT_EQ(child_2->parent(), nullptr);
+ ASSERT_EQ(child_2->prev(), nullptr);
+ ASSERT_EQ(child_2->next(), nullptr);
+
+ ASSERT_TRUE(parent->children()->empty());
+ ASSERT_EQ(parent->children()->head(), nullptr);
+ ASSERT_EQ(parent->children()->tail(), nullptr);
+}
+
+TEST_F(DLinkedListTest, node_destructor)
+{
+ auto parent = create<::Parent>();
+
+ auto child_1 = create<::Child>();
+ auto child_2 = create<::Child>();
+
+ parent->children()->append(child_1);
+ parent->children()->append(child_2);
+
+ destroy(child_2);
+
+ ASSERT_EQ(parent->children()->head(), child_1);
+ ASSERT_EQ(parent->children()->tail(), child_1);
+ ASSERT_EQ(child_1->next(), nullptr);
+ ASSERT_EQ(child_1->prev(), nullptr);
+
+ destroy(child_1);
+
+ ASSERT_EQ(parent->children()->head(), nullptr);
+ ASSERT_EQ(parent->children()->tail(), nullptr);
+}
diff --git a/compiler/coco/core/src/ADT/PtrList.cpp b/compiler/coco/core/src/ADT/PtrList.cpp
new file mode 100644
index 000000000..ea2beb06b
--- /dev/null
+++ b/compiler/coco/core/src/ADT/PtrList.cpp
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/ADT/PtrList.h"
+
+// NOTE Do NOT delete this file; this file checks the completeness of 'PtrList.h'
diff --git a/compiler/coco/core/src/ADT/PtrList.test.cpp b/compiler/coco/core/src/ADT/PtrList.test.cpp
new file mode 100644
index 000000000..dcbad8b90
--- /dev/null
+++ b/compiler/coco/core/src/ADT/PtrList.test.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/ADT/PtrList.h"
+
+#include <memory>
+
+#include <gtest/gtest.h>
+
+namespace
+{
+struct Object
+{
+};
+}
+
+TEST(ADT_PTR_LIST, ctor)
+{
+ coco::PtrList<Object> l;
+
+ ASSERT_EQ(l.size(), 0);
+}
+
+TEST(ADT_PTR_LIST, insert)
+{
+ coco::PtrList<Object> l;
+
+ std::unique_ptr<Object> ptr{new Object};
+
+ l.insert(ptr.get());
+
+ ASSERT_EQ(l.size(), 1);
+ ASSERT_EQ(l.at(0), ptr.get());
+}
diff --git a/compiler/coco/core/src/ADT/PtrManager.test.cpp b/compiler/coco/core/src/ADT/PtrManager.test.cpp
new file mode 100644
index 000000000..bb9056f29
--- /dev/null
+++ b/compiler/coco/core/src/ADT/PtrManager.test.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/ADT/PtrManager.h"
+
+#include <memory>
+
+#include <gtest/gtest.h>
+
+namespace
+{
+struct Count
+{
+ uint32_t allocated;
+ uint32_t freed;
+
+ Count() : allocated{0}, freed{0}
+ {
+ // DO NOTHING
+ }
+};
+
+class Object
+{
+public:
+ Object(Count *count, uint32_t value) : _count{count}, _value{value} { _count->allocated += 1; }
+
+public:
+ ~Object() { _count->freed += 1; }
+
+public:
+ uint32_t value(void) const { return _value; }
+
+private:
+ Count *const _count;
+
+private:
+ uint32_t _value;
+};
+
+struct ObjectManager final : public coco::PtrManager<Object>
+{
+ Object *alloc(Count *count, uint32_t value)
+ {
+ std::unique_ptr<Object> o{new Object{count, value}};
+ return take(std::move(o));
+ }
+
+ void free(Object *o) { release(o); }
+};
+}
+
+TEST(ADT_PTR_MANAGER, usecase)
+{
+ Count c;
+
+ ASSERT_EQ(c.allocated, 0);
+ ASSERT_EQ(c.freed, 0);
+
+ {
+ ::ObjectManager mgr;
+
+ auto obj_1 = mgr.alloc(&c, 3);
+ auto obj_2 = mgr.alloc(&c, 4);
+
+ EXPECT_EQ(c.allocated, 2);
+ ASSERT_EQ(c.freed, 0);
+
+ EXPECT_EQ(mgr.size(), 2);
+ EXPECT_EQ(mgr.at(0), obj_1);
+ EXPECT_EQ(mgr.at(1), obj_2);
+
+ // Let's delete obj_1
+ mgr.free(obj_1);
+
+ EXPECT_EQ(c.allocated, 2);
+ ASSERT_EQ(c.freed, 1);
+
+ EXPECT_EQ(mgr.size(), 1);
+ EXPECT_EQ(mgr.at(0), obj_2);
+ }
+
+ // PtrManger SHOULD destruct all of the allocated object when it is destructed.
+ ASSERT_EQ(c.allocated, 2);
+ ASSERT_EQ(c.freed, 2);
+}
diff --git a/compiler/coco/core/src/IR.test.cpp b/compiler/coco/core/src/IR.test.cpp
new file mode 100644
index 000000000..3f8c0ad34
--- /dev/null
+++ b/compiler/coco/core/src/IR.test.cpp
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR.h"
+
+#include <nncc/core/ADT/tensor/Shape.h>
+#include <nncc/core/ADT/tensor/IndexEnumerator.h>
+#include <nncc/core/ADT/tensor/LexicalLayout.h>
+
+#include <nncc/core/ADT/feature/CHWLayout.h>
+
+#include <nncc/core/ADT/kernel/NCHWLayout.h>
+
+#include <gtest/gtest.h>
+
+#include <set>
+#include <map>
+#include <string>
+
+using nncc::core::ADT::feature::num_elements;
+
+using nncc::core::ADT::kernel::num_elements;
+
+using nncc::core::ADT::tensor::LexicalLayout;
+using nncc::core::ADT::tensor::IndexEnumerator;
+using nncc::core::ADT::tensor::num_elements;
+
+//
+// 'caffe_conv' test demonstrates how to translate the following Caffe network into coco IR:
+//
+// layer {
+// name: "data"
+// type: "Input"
+// top: "data"
+// input_param: { shape: { dim: 1 dim: 1 dim: 3 dim: 3 } }
+// }
+//
+// layer {
+// name: "conv"
+// type: "Convolution"
+// bottom: "data"
+// top: "conv"
+// blobs {
+// ...
+// shape { dim: 1 dim: 1 dim: 3 dim: 3 }
+// }
+// convolution_param {
+// bias_term: false
+// num_output: 1
+// kernel_size: 3
+// }
+// }
+//
+TEST(IR, caffe_conv)
+{
+ // For inter-layer communication
+ std::map<std::string, coco::Bag *> bags;
+ std::map<std::string, nncc::core::ADT::tensor::Shape> shapes;
+
+ std::set<std::string> top_blobs;
+
+ // Create a module and block
+ auto m = coco::Module::create();
+ auto blk = m->entity()->block()->create();
+
+ // Next, append the block to the module
+ m->block()->append(blk);
+
+ // Now, the block belongs to the module (and has no sibling)
+ ASSERT_EQ(blk->parent(), m.get());
+ ASSERT_EQ(blk->next(), nullptr);
+ ASSERT_EQ(blk->prev(), nullptr);
+
+ // The head and tail points to the appended block
+ ASSERT_EQ(m->block()->head(), blk);
+ ASSERT_EQ(m->block()->tail(), blk);
+
+ // Let's translate the first 'Input' layer
+ {
+ using nncc::core::ADT::tensor::Shape;
+
+ const Shape shape{1, 1, 3, 3};
+
+ auto bag = m->entity()->bag()->create(num_elements(shape));
+ auto input = m->entity()->input()->create(shape);
+
+ input->bag(bag);
+ input->name("data");
+
+ // Caffe uses lexical layout for tensors
+ for (IndexEnumerator e{shape}; e.valid(); e.advance())
+ {
+ const static LexicalLayout l{};
+ const auto offset = static_cast<uint32_t>(l.offset(shape, e.current()));
+
+ input->at(e.current()) = coco::ElemID{offset};
+ }
+
+ m->input()->insert(input);
+
+ bags["data"] = bag;
+ shapes["data"] = shape;
+
+ top_blobs = {"data"};
+ }
+
+ // Next, translate 'Convolution' layer
+ {
+ using nncc::core::ADT::feature::CHWLayout;
+ using nncc::core::ADT::kernel::NCHWLayout;
+
+ const nncc::core::ADT::feature::Shape ifm_shape{1, 3, 3};
+ auto ifm_bag = bags["data"];
+ auto ifm_obj = m->entity()->object()->create<coco::FeatureObject>();
+ auto ifm_layout = coco::FeatureLayouts::BCHW::create(ifm_shape);
+
+ ifm_obj->bag(ifm_bag);
+ ifm_obj->layout(std::move(ifm_layout));
+
+ const nncc::core::ADT::kernel::Shape ker_shape{1, 1, 3, 3};
+ auto ker_bag = m->entity()->bag()->create(num_elements(ker_shape));
+ auto ker_layout = coco::KernelLayouts::Generic::create(ker_shape);
+
+ ker_layout->reorder<NCHWLayout>();
+
+ auto ker_obj = m->entity()->object()->create<coco::KernelObject>();
+
+ ker_obj->bag(ker_bag);
+ ker_obj->layout(std::move(ker_layout));
+
+ const nncc::core::ADT::feature::Shape ofm_shape{1, 1, 1};
+ auto ofm_bag = m->entity()->bag()->create(1 * 1 * 1);
+ auto ofm_obj = m->entity()->object()->create<coco::FeatureObject>();
+ auto ofm_layout = coco::FeatureLayouts::BCHW::create(ifm_shape);
+
+ ofm_obj->bag(ofm_bag);
+ ofm_obj->layout(std::move(ofm_layout));
+
+ // Create Load operation
+ auto load = m->entity()->op()->create<coco::Load>();
+
+ load->object(ifm_obj);
+
+ // Create Conv2D operation
+ //
+ // NOTE Conv2D op in coco IR does not perform BiasAdd
+ auto op = m->entity()->op()->create<coco::Conv2D>();
+
+ op->ker(ker_obj);
+
+ // Create UnitF instruction with Conv2D operation
+ auto ins = m->entity()->instr()->create<coco::Eval>();
+
+ ins->out(ofm_obj);
+ ins->op(op);
+
+ // Append the instruction (to the block)
+ blk->instr()->append(ins);
+
+ bags["conv"] = ofm_bag;
+ shapes["conv"] = nncc::core::ADT::tensor::Shape{1, 1, 1, 1};
+
+ top_blobs = {"conv"};
+ }
+
+ // Finalize
+ for (const auto &top_blob : top_blobs)
+ {
+ const auto &shape = shapes[top_blob];
+
+ auto output = m->entity()->output()->create(shape);
+
+ output->bag(bags[top_blob]);
+ output->name(top_blob);
+
+ for (IndexEnumerator e{shape}; e.valid(); e.advance())
+ {
+ const static LexicalLayout l{};
+ const auto offset = static_cast<uint32_t>(l.offset(shape, e.current()));
+
+ output->at(e.current()) = coco::ElemID{offset};
+ }
+
+ m->output()->insert(output);
+ }
+
+ // Let's validate the constructed IR
+ {
+ // There is one input whose name is 'data'
+ ASSERT_EQ(m->input()->size(), 1);
+ ASSERT_EQ(m->input()->at(0)->name(), "data");
+
+ // There is one output whose name is 'conv'
+ ASSERT_EQ(m->output()->size(), 1);
+ ASSERT_EQ(m->output()->at(0)->name(), "conv");
+
+ ASSERT_FALSE(m->block()->empty());
+
+ // There is one block in the module
+ auto blk = m->block()->head();
+
+ ASSERT_EQ(blk->next(), nullptr);
+ ASSERT_FALSE(blk->instr()->empty());
+
+ // There is one instruction in the block
+ auto ins = blk->instr()->head();
+
+ ASSERT_EQ(ins->next(), nullptr);
+
+ // That instruction is 'Eval'
+ // TODO Rename 'unit'
+ auto unit = ins->asEval();
+
+ ASSERT_NE(unit, nullptr);
+
+// TODO Rewrite below test
+#if 0
+ // Input #0 points to IFM
+ ASSERT_NE(unit->ifm(), nullptr);
+ ASSERT_EQ(unit->ifm()->bag(), m->input()->at(0)->bag());
+#endif
+
+ // Output #0 points to OFM
+ ASSERT_NE(unit->out(), nullptr);
+ ASSERT_EQ(unit->out()->bag(), m->output()->at(0)->bag());
+
+ // The actual operation is Conv2D
+ auto conv = unit->op()->asConv2D();
+
+ ASSERT_NE(conv, nullptr);
+
+ // Let's check Kernel Object
+ ASSERT_NE(conv->ker(), nullptr);
+// TODO Rewrite below test
+#if 0
+ ASSERT_NE(conv->ker()->bag(), unit->ifm()->bag());
+ ASSERT_NE(conv->ker()->bag(), unit->ofm()->bag());
+#endif
+
+// One may find the correspondence among Input, Output, and Objects through ElemID
+// TODO Rewrite below test
+#if 0
+ {
+ auto input_0 = m->input()->at(0);
+ auto ifm = unit->ifm();
+
+ nncc::core::ADT::tensor::Index input_index{0, 0, 2, 2};
+
+ // Here we can check that Input(0, 0, 2, 2) corresponds to IFM(0, 2, 2)
+ ASSERT_EQ(input_0->at(input_index).value(), ifm->at(0, 2, 2).value());
+ }
+#endif
+ }
+}
+
+//
+// This test demonstrates how to use 'replaceWith' method
+//
+TEST(IR, bag_replaceWith)
+{
+ auto m = coco::Module::create();
+
+ auto bag_1 = m->entity()->bag()->create(1);
+ auto bag_2 = m->entity()->bag()->create(1);
+
+ auto obj = m->entity()->object()->create<coco::FeatureObject>();
+ obj->bag(bag_1);
+
+ auto shuffle_1 = m->entity()->instr()->create<coco::Shuffle>();
+ shuffle_1->into(bag_1);
+
+ auto shuffle_2 = m->entity()->instr()->create<coco::Shuffle>();
+ shuffle_2->from(bag_1);
+
+ ASSERT_EQ(obj->bag(), bag_1);
+ ASSERT_EQ(shuffle_1->into(), bag_1);
+ ASSERT_EQ(shuffle_2->from(), bag_1);
+
+ bag_1->replaceAllDepsWith(bag_2);
+
+ ASSERT_EQ(obj->bag(), bag_2);
+ ASSERT_EQ(shuffle_1->into(), bag_1);
+ ASSERT_EQ(shuffle_2->from(), bag_1);
+
+ bag_1->replaceWith(bag_2);
+
+ ASSERT_EQ(obj->bag(), bag_2);
+ ASSERT_EQ(shuffle_1->into(), bag_2);
+ ASSERT_EQ(shuffle_2->from(), bag_2);
+}
diff --git a/compiler/coco/core/src/IR/Arg.cpp b/compiler/coco/core/src/IR/Arg.cpp
new file mode 100644
index 000000000..b6f9c4777
--- /dev/null
+++ b/compiler/coco/core/src/IR/Arg.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Arg.h"
+
+#include <nncc/core/ADT/tensor/LexicalLayout.h>
+#include <nncc/core/ADT/tensor/IndexEnumerator.h>
+
+#include <cassert>
+
+namespace
+{
+
+const nncc::core::ADT::tensor::LexicalLayout l;
+
+} // namespace
+
+namespace coco
+{
+
+Arg::Arg(const nncc::core::ADT::tensor::Shape &shape) : _shape{shape}, _bag{nullptr}
+{
+ _map.resize(nncc::core::ADT::tensor::num_elements(shape));
+}
+
+void Arg::bag(Bag *bag)
+{
+ if (_bag != nullptr)
+ {
+ onRelease(_bag);
+ _bag = nullptr;
+ }
+
+ assert(_bag == nullptr);
+
+ if (bag != nullptr)
+ {
+ _bag = bag;
+ onTake(_bag);
+ }
+}
+
+ElemID &Arg::at(const nncc::core::ADT::tensor::Index &index)
+{
+ return _map.at(l.offset(_shape, index));
+}
+
+const ElemID &Arg::at(const nncc::core::ADT::tensor::Index &index) const
+{
+ return _map.at(l.offset(_shape, index));
+}
+
+void Arg::reorder(const nncc::core::ADT::tensor::Layout &l)
+{
+ using nncc::core::ADT::tensor::IndexEnumerator;
+
+ for (IndexEnumerator e{shape()}; e.valid(); e.advance())
+ {
+ const auto offset = static_cast<uint32_t>(l.offset(shape(), e.current()));
+
+ at(e.current()) = coco::ElemID{offset};
+ }
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Arg.test.cpp b/compiler/coco/core/src/IR/Arg.test.cpp
new file mode 100644
index 000000000..391e05901
--- /dev/null
+++ b/compiler/coco/core/src/IR/Arg.test.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Arg.h"
+
+#include <nncc/core/ADT/tensor/IndexEnumerator.h>
+#include <nncc/core/ADT/tensor/LexicalLayout.h>
+
+#include <memory>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::tensor::Shape;
+using nncc::core::ADT::tensor::Index;
+using nncc::core::ADT::tensor::IndexEnumerator;
+using nncc::core::ADT::tensor::LexicalLayout;
+
+namespace
+{
+class ArgTest : public ::testing::Test
+{
+protected:
+ coco::Arg *allocate(const Shape &shape)
+ {
+ auto arg = new coco::Arg{shape};
+ _allocated.emplace_back(arg);
+ return arg;
+ }
+
+private:
+ std::vector<std::unique_ptr<coco::Arg>> _allocated;
+};
+} // namespace
+
+TEST_F(ArgTest, constructor)
+{
+ const Shape shape{1, 3, 3, 1};
+
+ auto arg = allocate(shape);
+
+ ASSERT_EQ(arg->shape(), shape);
+ ASSERT_TRUE(arg->name().empty());
+ ASSERT_EQ(arg->bag(), nullptr);
+}
+
+TEST_F(ArgTest, name_update)
+{
+ const Shape shape{1, 3, 3, 1};
+
+ auto arg = allocate(shape);
+
+ arg->name("data");
+ ASSERT_EQ(arg->name(), "data");
+}
+
+TEST_F(ArgTest, at)
+{
+ const Shape shape{1, 3, 3, 1};
+
+ auto arg = allocate(shape);
+
+ coco::Arg *mutable_ptr = arg;
+ const coco::Arg *immutable_ptr = arg;
+
+ for (IndexEnumerator e{shape}; e.valid(); e.advance())
+ {
+ mutable_ptr->at(e.current()) = coco::ElemID{16};
+ }
+
+ for (IndexEnumerator e{shape}; e.valid(); e.advance())
+ {
+ ASSERT_EQ(immutable_ptr->at(e.current()).value(), 16);
+ }
+}
+
+TEST_F(ArgTest, reorder)
+{
+ const Shape shape{2, 2, 2, 2};
+
+ auto arg = allocate(shape);
+
+ arg->reorder<LexicalLayout>();
+
+ ASSERT_EQ(arg->at(Index{0, 0, 0, 0}).value(), 0);
+ ASSERT_EQ(arg->at(Index{0, 0, 0, 1}).value(), 1);
+}
diff --git a/compiler/coco/core/src/IR/AvgPool2D.test.cpp b/compiler/coco/core/src/IR/AvgPool2D.test.cpp
new file mode 100644
index 000000000..d62bc9b7d
--- /dev/null
+++ b/compiler/coco/core/src/IR/AvgPool2D.test.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Ops.h"
+
+#include <memory>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+namespace
+{
+struct IsAvgPool2D : public coco::Op::Visitor<bool>
+{
+ bool visit(const coco::AvgPool2D *) override { return true; }
+};
+
+class AvgPool2DTest : public ::testing::Test
+{
+public:
+ AvgPool2DTest()
+ {
+ // DO NOTHING
+ }
+
+protected:
+ coco::AvgPool2D *allocate(void)
+ {
+ auto op = new coco::AvgPool2D;
+ _allocated.emplace_back(op);
+ return op;
+ }
+
+private:
+ std::vector<std::unique_ptr<coco::AvgPool2D>> _allocated;
+};
+} // namespace
+
+TEST_F(AvgPool2DTest, initialization)
+{
+ auto op = allocate();
+
+ coco::AvgPool2D *mutable_ptr = op;
+ const coco::AvgPool2D *immutable_ptr = op;
+
+ // uses() should be empty on construction
+ ASSERT_EQ(op->uses().size(), 0);
+ // parent() should be nullptr on construction
+ ASSERT_EQ(op->parent(), nullptr);
+
+ // arg() should be nullptr on construction
+ ASSERT_EQ(immutable_ptr->arg(), nullptr);
+
+ // divisor() SHOULD be unknow on construction
+ ASSERT_EQ(immutable_ptr->divisor(), coco::AvgPool2D::Divisor::Unknown);
+
+ // window() SHOULD return a valid pointer
+ ASSERT_NE(mutable_ptr->window(), nullptr);
+ ASSERT_EQ(mutable_ptr->window(), immutable_ptr->window());
+
+ // pad() SHOULD return a valid pointer
+ ASSERT_NE(mutable_ptr->pad(), nullptr);
+ ASSERT_EQ(mutable_ptr->pad(), immutable_ptr->pad());
+
+ // stride() SHOULD return a valid pointer
+ ASSERT_NE(mutable_ptr->stride(), nullptr);
+ ASSERT_EQ(mutable_ptr->stride(), immutable_ptr->stride());
+}
+
+TEST_F(AvgPool2DTest, asAvgPool2D)
+{
+ auto op = allocate();
+
+ coco::Op *mutable_base = op;
+ const coco::Op *immutable_base = op;
+
+ ASSERT_EQ(mutable_base->asAvgPool2D(), op);
+ ASSERT_EQ(mutable_base->asAvgPool2D(), immutable_base->asAvgPool2D());
+}
+
+TEST_F(AvgPool2DTest, accept)
+{
+ // Test 'AvgPool2D' class
+ auto op = allocate();
+
+ coco::AvgPool2D *mutable_ptr = op;
+ const coco::AvgPool2D *immutable_ptr = op;
+
+ ASSERT_TRUE(mutable_ptr->accept(IsAvgPool2D{}));
+ ASSERT_TRUE(immutable_ptr->accept(IsAvgPool2D{}));
+}
+
+TEST_F(AvgPool2DTest, disivor)
+{
+ auto op = allocate();
+
+ op->divisor(coco::AvgPool2D::Divisor::Static);
+
+ ASSERT_EQ(op->divisor(), coco::AvgPool2D::Divisor::Static);
+}
diff --git a/compiler/coco/core/src/IR/Bag.cpp b/compiler/coco/core/src/IR/Bag.cpp
new file mode 100644
index 000000000..7dce48587
--- /dev/null
+++ b/compiler/coco/core/src/IR/Bag.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Bag.h"
+
+#include "coco/IR/Object.h"
+#include "coco/IR/Read.h"
+#include "coco/IR/Update.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+Bag::Bag(uint32_t size) : _size{size}
+{
+ // DO NOTHING
+}
+
+Bag::~Bag()
+{
+ // All the references over a bag SHOULD be dropped before its destruction
+ assert(deps()->size() == 0);
+ assert(reads()->size() == 0);
+ assert(updates()->size() == 0);
+}
+
+uint32_t Bag::size(void) const { return _size; }
+
+bool Bag::isInput(void) const { return _input != nullptr; }
+bool Bag::isOutput(void) const { return _output != nullptr; }
+
+const DepSet *Bag::deps(void) const { return &_deps; }
+const ReadSet *Bag::reads(void) const { return &_reads; }
+const UpdateSet *Bag::updates(void) const { return &_updates; }
+
+void Bag::replaceWith(Bag *b)
+{
+ assert(!isInput() && !isOutput());
+
+ replaceAllDepsWith(b);
+ // Replace all the occurence inside Read
+ while (!(reads()->empty()))
+ {
+ auto read = *(reads()->begin());
+ assert(read->bag() == this);
+ read->bag(b);
+ }
+
+ // Replace all the occurence insider Update
+ while (!(updates()->empty()))
+ {
+ auto update = *(updates()->begin());
+ assert(update->bag() == this);
+ update->bag(b);
+ }
+
+ assert(deps()->empty());
+ assert(reads()->empty());
+ assert(updates()->empty());
+}
+
+void Bag::replaceAllDepsWith(Bag *b)
+{
+ // Replace all the occurence inside Dep
+ while (!(deps()->empty()))
+ {
+ auto dep = *(deps()->begin());
+ assert(dep->bag() == this);
+ dep->bag(b);
+ }
+}
+
+ObjectSet dependent_objects(const Bag *b)
+{
+ ObjectSet res;
+
+ for (const auto &dep : *(b->deps()))
+ {
+ if (auto obj = dep->object())
+ {
+ res.insert(obj);
+ }
+ }
+
+ return res;
+}
+
+Bag::ReaderSet readers(const Bag *b)
+{
+ Bag::ReaderSet res;
+
+ for (auto obj : dependent_objects(b))
+ {
+ for (auto consumer : consumers(obj))
+ {
+ // NOTE Object::Consumer inherits Bag::Reader
+ res.insert(consumer);
+ }
+ }
+
+ for (auto read : *b->reads())
+ {
+ auto reader = read->reader();
+ assert(reader != nullptr);
+ res.insert(reader);
+ }
+
+ return res;
+}
+
+Bag::UpdaterSet updaters(const Bag *b)
+{
+ Bag::UpdaterSet res;
+
+ for (auto obj : dependent_objects(b))
+ {
+ if (auto p = producer(obj))
+ {
+ res.insert(p);
+ }
+ }
+
+ for (auto update : *b->updates())
+ {
+ auto updater = update->updater();
+ assert(updater != nullptr);
+ res.insert(updater);
+ }
+
+ return res;
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Bag.test.cpp b/compiler/coco/core/src/IR/Bag.test.cpp
new file mode 100644
index 000000000..9995e81ef
--- /dev/null
+++ b/compiler/coco/core/src/IR/Bag.test.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Bag.h"
+
+#include <gtest/gtest.h>
+
+TEST(IR_BAG, ctor_should_set_size)
+{
+ coco::Bag b{3};
+
+ ASSERT_EQ(b.size(), 3);
+
+ // Bag has no read/updates at the beginning
+ EXPECT_EQ(b.reads()->size(), 0);
+ EXPECT_EQ(b.updates()->size(), 0);
+}
diff --git a/compiler/coco/core/src/IR/BagManager.cpp b/compiler/coco/core/src/IR/BagManager.cpp
new file mode 100644
index 000000000..10fe69d57
--- /dev/null
+++ b/compiler/coco/core/src/IR/BagManager.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/BagManager.h"
+
+#include <stdex/Memory.h>
+
+namespace coco
+{
+
+Bag *BagManager::create(uint32_t size)
+{
+ auto bag = stdex::make_unique<Bag>(size);
+ modulize(bag.get());
+ return take(std::move(bag));
+}
+
+void BagManager::destroy(Bag *b) { release(b); }
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/BagManager.test.cpp b/compiler/coco/core/src/IR/BagManager.test.cpp
new file mode 100644
index 000000000..bf135a951
--- /dev/null
+++ b/compiler/coco/core/src/IR/BagManager.test.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/BagManager.h"
+
+#include <gtest/gtest.h>
+
+TEST(IR_BAG_MANAGER, create)
+{
+ coco::BagManager mgr;
+
+ auto bag = mgr.create(3);
+
+ ASSERT_EQ(bag->size(), 3);
+}
+
+TEST(IR_BAG_MANAGER, destruct)
+{
+ coco::BagManager mgr;
+
+ auto b = mgr.create(3);
+ mgr.destroy(b);
+
+ ASSERT_EQ(mgr.size(), 0);
+}
diff --git a/compiler/coco/core/src/IR/Block.cpp b/compiler/coco/core/src/IR/Block.cpp
new file mode 100644
index 000000000..14c026039
--- /dev/null
+++ b/compiler/coco/core/src/IR/Block.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Block.h"
+#include "coco/IR/Module.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+template <> void DLinkedList<Block, Module>::joined(Module *, Block *curr_blk)
+{
+ assert(!curr_blk->index().valid());
+ uint32_t value = 0;
+
+ if (auto prev_blk = curr_blk->prev())
+ {
+ value = prev_blk->index().value() + 1;
+ }
+
+ for (auto blk = curr_blk; blk; blk = blk->next())
+ {
+ blk->_index.set(value++);
+ }
+}
+
+template <> void DLinkedList<Block, Module>::leaving(Module *, Block *curr_blk)
+{
+ assert(curr_blk->index().valid());
+ uint32_t value = curr_blk->index().value();
+
+ for (auto blk = curr_blk->next(); blk; blk = blk->next())
+ {
+ blk->_index.set(value++);
+ }
+
+ curr_blk->_index.reset();
+}
+
+template <> BlockList *DLinkedList<Block, Module>::head(Module *m) { return m->block(); }
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Block.test.cpp b/compiler/coco/core/src/IR/Block.test.cpp
new file mode 100644
index 000000000..c2acc89f7
--- /dev/null
+++ b/compiler/coco/core/src/IR/Block.test.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Block.h"
+
+#include <gtest/gtest.h>
+
+TEST(IR_BLOCK, default_block_has_empty_instr_list)
+{
+ coco::Block blk;
+
+ ASSERT_TRUE(blk.instr()->empty());
+ ASSERT_EQ(blk.instr()->head(), nullptr);
+ ASSERT_EQ(blk.instr()->tail(), nullptr);
+}
diff --git a/compiler/coco/core/src/IR/BlockIndex.cpp b/compiler/coco/core/src/IR/BlockIndex.cpp
new file mode 100644
index 000000000..8cb56724c
--- /dev/null
+++ b/compiler/coco/core/src/IR/BlockIndex.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/BlockIndex.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+void BlockIndex::set(uint32_t value)
+{
+ assert(value != undefined);
+ _value = value;
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/BlockIndex.test.cpp b/compiler/coco/core/src/IR/BlockIndex.test.cpp
new file mode 100644
index 000000000..68afb889e
--- /dev/null
+++ b/compiler/coco/core/src/IR/BlockIndex.test.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/BlockIndex.h"
+
+#include <gtest/gtest.h>
+
+namespace
+{
+
+class BlockIndexTest : public ::testing::Test
+{
+};
+
+} // namespace
+
+TEST_F(BlockIndexTest, default_constructor)
+{
+ coco::BlockIndex blk_ind;
+
+ ASSERT_FALSE(blk_ind.valid());
+}
+
+TEST_F(BlockIndexTest, explicit_constructor)
+{
+ coco::BlockIndex blk_ind{3};
+
+ ASSERT_TRUE(blk_ind.valid());
+ ASSERT_EQ(blk_ind.value(), 3);
+}
+
+TEST_F(BlockIndexTest, operator_lt)
+{
+ // Valid index is always less than undefined one.
+ ASSERT_TRUE(coco::BlockIndex(3) < coco::BlockIndex());
+ ASSERT_TRUE(coco::BlockIndex(3) < coco::BlockIndex(4));
+}
diff --git a/compiler/coco/core/src/IR/BlockManager.cpp b/compiler/coco/core/src/IR/BlockManager.cpp
new file mode 100644
index 000000000..5e3b88173
--- /dev/null
+++ b/compiler/coco/core/src/IR/BlockManager.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/BlockManager.h"
+
+#include <stdex/Memory.h>
+
+#include <cassert>
+
+namespace coco
+{
+
+Block *BlockManager::create(void)
+{
+ auto blk = stdex::make_unique<Block>();
+ modulize(blk.get());
+ return take(std::move(blk));
+}
+
+void BlockManager::destroy(Block *blk)
+{
+ assert(blk->parent() == nullptr);
+ assert(blk->prev() == nullptr);
+ assert(blk->next() == nullptr);
+ release(blk);
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/BlockManager.test.cpp b/compiler/coco/core/src/IR/BlockManager.test.cpp
new file mode 100644
index 000000000..94f69b773
--- /dev/null
+++ b/compiler/coco/core/src/IR/BlockManager.test.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/BlockManager.h"
+
+#include <memory>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+namespace
+{
+class BlockManagerTest : public ::testing::Test
+{
+public:
+ // Create a coco::BlockManager for testing
+ coco::BlockManager *allocate(void)
+ {
+ auto p = new coco::BlockManager;
+ _allocated.emplace_back(p);
+ return p;
+ }
+
+private:
+ std::vector<std::unique_ptr<coco::BlockManager>> _allocated;
+};
+} // namespace
+
+TEST_F(BlockManagerTest, create)
+{
+ auto mgr = allocate();
+ auto blk = mgr->create();
+
+ ASSERT_NE(blk, nullptr);
+}
+
+TEST_F(BlockManagerTest, destroy)
+{
+ auto mgr = allocate();
+ auto blk_1 = mgr->create();
+ auto blk_2 = mgr->create();
+
+ mgr->destroy(blk_1);
+
+ ASSERT_EQ(mgr->size(), 1);
+ ASSERT_EQ(mgr->at(0), blk_2);
+}
diff --git a/compiler/coco/core/src/IR/Consumer.mock.h b/compiler/coco/core/src/IR/Consumer.mock.h
new file mode 100644
index 000000000..7d7cc492a
--- /dev/null
+++ b/compiler/coco/core/src/IR/Consumer.mock.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_CONSUMER_MOCK_H__
+#define __COCO_IR_CONSUMER_MOCK_H__
+
+#include "coco/IR/Object.h"
+
+namespace
+{
+namespace mock
+{
+struct Consumer final : public coco::Object::Consumer
+{
+ coco::Instr *loc(void) override { return nullptr; }
+};
+} // namespace mock
+} // namespace
+
+#endif // __COCO_IR_CONSUMER_MOCK_H__
diff --git a/compiler/coco/core/src/IR/Conv2D.cpp b/compiler/coco/core/src/IR/Conv2D.cpp
new file mode 100644
index 000000000..19395a158
--- /dev/null
+++ b/compiler/coco/core/src/IR/Conv2D.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Ops.h"
+
+#include <pepper/assert.h>
+
+namespace coco
+{
+
+Conv2D::Conv2D() : _ker{this}, _arg{this}
+{
+ // DO NOTHING
+}
+
+uint32_t Conv2D::arity(void) const
+{
+ // Conv2D has one argument (IFM)
+ // NOTE This design is subject to change
+ return 1;
+}
+
+Op *Conv2D::arg(DBGARG(uint32_t, n)) const
+{
+ assert(n < arity());
+ return arg();
+}
+
+std::set<Object *> Conv2D::uses(void) const
+{
+ std::set<Object *> res;
+
+ if (ker())
+ {
+ res.insert(ker());
+ }
+
+ if (auto ifm = arg())
+ {
+ for (auto obj : ifm->uses())
+ {
+ res.insert(obj);
+ }
+ }
+
+ return res;
+}
+
+void Conv2D::ker(KernelObject *ker) { _ker.value(ker); }
+
+KernelObject *Conv2D::ker(void) const
+{
+ if (auto obj = _ker.value())
+ {
+ assert(obj->asKernel() != nullptr);
+ return obj->asKernel();
+ }
+
+ return nullptr;
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Conv2D.test.cpp b/compiler/coco/core/src/IR/Conv2D.test.cpp
new file mode 100644
index 000000000..df0a2470b
--- /dev/null
+++ b/compiler/coco/core/src/IR/Conv2D.test.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Ops.h"
+#include "coco/IR/ObjectManager.h"
+
+#include <vector>
+#include <memory>
+
+#include <stdex/Memory.h>
+
+#include <gtest/gtest.h>
+
+using stdex::make_unique;
+
+namespace
+{
+class Conv2DTest : public ::testing::Test
+{
+public:
+ Conv2DTest()
+ {
+ // DO NOTHING
+ }
+
+protected:
+ coco::Conv2D *allocate(void)
+ {
+ auto op = new coco::Conv2D;
+ _allocated.emplace_back(op);
+ return op;
+ }
+
+protected:
+ coco::ObjectManager obj_mgr;
+
+private:
+ std::vector<std::unique_ptr<coco::Conv2D>> _allocated;
+};
+} // namespace
+
+TEST_F(Conv2DTest, ctor)
+{
+ auto op = allocate();
+
+ // arg() should be initialized as nullptr on construction
+ ASSERT_EQ(op->arg(), nullptr);
+ // ker() should be initialized as nullptr on construction
+ ASSERT_EQ(op->ker(), nullptr);
+
+ // uses() should be empty on construction
+ ASSERT_EQ(op->uses().size(), 0);
+ // parent() should be nullptr on construction
+ ASSERT_EQ(op->parent(), nullptr);
+
+ ASSERT_EQ(op->group(), 1);
+
+ ASSERT_NE(op->pad(), nullptr);
+ ASSERT_EQ(op->pad()->top(), 0);
+ ASSERT_EQ(op->pad()->bottom(), 0);
+ ASSERT_EQ(op->pad()->left(), 0);
+ ASSERT_EQ(op->pad()->right(), 0);
+
+ ASSERT_NE(op->stride(), nullptr);
+ ASSERT_EQ(op->stride()->vertical(), 1);
+ ASSERT_EQ(op->stride()->horizontal(), 1);
+}
+
+TEST_F(Conv2DTest, asConv2D)
+{
+ auto op = allocate();
+
+ coco::Op *mutable_base = op;
+ const coco::Op *immutable_base = op;
+
+ ASSERT_EQ(mutable_base->asConv2D(), op);
+ ASSERT_EQ(mutable_base->asConv2D(), immutable_base->asConv2D());
+}
+
+namespace
+{
+struct IsConv2D : public coco::Op::Visitor<bool>
+{
+ bool visit(const coco::Conv2D *) override { return true; }
+};
+} // namespace
+
+TEST_F(Conv2DTest, ker_update)
+{
+ // Prepare a kernel object for testing
+ auto obj = obj_mgr.create<coco::KernelObject>();
+
+ // Test 'Conv2D' class
+ auto op = allocate();
+
+ op->ker(obj);
+ ASSERT_EQ(op->ker(), obj);
+
+ // Op now uses 'obj'
+ {
+ auto uses = op->uses();
+
+ ASSERT_NE(uses.find(obj), uses.end());
+ }
+
+ // ker method should enlist op itself as a consumer of a given kernel object
+ {
+ auto consumers = coco::consumers(obj);
+
+ ASSERT_EQ(consumers.size(), 1);
+ ASSERT_NE(consumers.find(op), consumers.end());
+ }
+}
+
+TEST_F(Conv2DTest, accept)
+{
+ // Test 'Conv2D' class
+ auto op = allocate();
+
+ coco::Conv2D *mutable_ptr = op;
+ const coco::Conv2D *immutable_ptr = op;
+
+ ASSERT_TRUE(mutable_ptr->accept(IsConv2D{}));
+ ASSERT_TRUE(immutable_ptr->accept(IsConv2D{}));
+}
+
+TEST_F(Conv2DTest, destructor)
+{
+ // Prepare a kernel object for testing
+ auto obj = obj_mgr.create<coco::KernelObject>();
+
+ // Create 'Conv2D' op
+ auto op = make_unique<coco::Conv2D>();
+
+ op->ker(obj);
+
+ // Destroy 'Conv2D' op
+ op.reset();
+
+ ASSERT_EQ(obj->uses()->size(), 0);
+}
diff --git a/compiler/coco/core/src/IR/Def.cpp b/compiler/coco/core/src/IR/Def.cpp
new file mode 100644
index 000000000..1546b6693
--- /dev/null
+++ b/compiler/coco/core/src/IR/Def.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Def.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+void Def::value(Object *value)
+{
+ if (_value)
+ {
+ _value->def(nullptr);
+ _value = nullptr;
+ }
+
+ assert(_value == nullptr);
+
+ if (value)
+ {
+ _value = value;
+ _value->def(this);
+ }
+
+ assert(_value == value);
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Def.test.cpp b/compiler/coco/core/src/IR/Def.test.cpp
new file mode 100644
index 000000000..98455c09e
--- /dev/null
+++ b/compiler/coco/core/src/IR/Def.test.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Def.h"
+#include "coco/IR/ObjectManager.h"
+
+#include "coco/IR/FeatureObject.h"
+
+#include <stdex/Memory.h>
+
+#include "Producer.mock.h"
+
+#include <gtest/gtest.h>
+
+using stdex::make_unique;
+
+namespace
+{
+class DefTest : public ::testing::Test
+{
+protected:
+ coco::ObjectManager obj_mgr;
+};
+} // namespace
+
+TEST_F(DefTest, constructor)
+{
+ auto o = obj_mgr.create<coco::FeatureObject>();
+
+ ::mock::Producer producer;
+ coco::Def def{&producer};
+
+ ASSERT_EQ(def.value(), nullptr);
+}
+
+TEST_F(DefTest, value)
+{
+ auto o = obj_mgr.create<coco::FeatureObject>();
+
+ ::mock::Producer producer;
+ coco::Def def{&producer};
+
+ def.value(o);
+
+ ASSERT_EQ(def.value(), o);
+
+ ASSERT_EQ(o->def(), &def);
+
+ def.value(nullptr);
+
+ ASSERT_EQ(o->def(), nullptr);
+}
+
+TEST_F(DefTest, unlink_on_destruction)
+{
+ auto o = obj_mgr.create<coco::FeatureObject>();
+
+ ::mock::Producer producer;
+ auto def = make_unique<coco::Def>(&producer);
+
+ def->value(o);
+ ASSERT_EQ(o->def(), def.get());
+
+ // Let's destruct the allocated slot
+ def.reset(nullptr);
+
+ // The def of Object SHOULD BE updated
+ ASSERT_EQ(o->def(), nullptr);
+}
diff --git a/compiler/coco/core/src/IR/Dep.cpp b/compiler/coco/core/src/IR/Dep.cpp
new file mode 100644
index 000000000..6a5d3cafb
--- /dev/null
+++ b/compiler/coco/core/src/IR/Dep.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Dep.h"
+#include "coco/IR/Object.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+Dep::~Dep() { bag(nullptr); }
+
+void Dep::bag(Bag *bag)
+{
+ if (_bag != nullptr)
+ {
+ // Remove bag <-> dep link
+ assert(_bag->deps()->find(this) != _bag->deps()->end());
+ _bag->mutable_deps()->erase(this);
+
+ // Reset _bag
+ _bag = nullptr;
+ }
+
+ assert(_bag == nullptr);
+
+ if (bag != nullptr)
+ {
+ // Set _bag
+ _bag = bag;
+
+ // Create bag <-> dep link
+ _bag->mutable_deps()->insert(this);
+ }
+
+ assert(_bag == bag);
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Dep.test.cpp b/compiler/coco/core/src/IR/Dep.test.cpp
new file mode 100644
index 000000000..e2104a8af
--- /dev/null
+++ b/compiler/coco/core/src/IR/Dep.test.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Dep.h"
+
+#include "coco/IR/BagManager.h"
+
+#include "coco/IR/ObjectManager.h"
+#include "coco/IR/FeatureObject.h"
+
+#include <gtest/gtest.h>
+
+using namespace nncc::core::ADT;
+
+namespace
+{
+class DepTest : public ::testing::Test
+{
+protected:
+ coco::BagManager bag_mgr;
+ coco::ObjectManager obj_mgr;
+};
+} // namespace
+
+TEST_F(DepTest, default_constructor)
+{
+ coco::Dep dep;
+
+ ASSERT_EQ(dep.bag(), nullptr);
+ ASSERT_EQ(dep.object(), nullptr);
+}
+
+TEST_F(DepTest, bag_update)
+{
+ auto bag = bag_mgr.create(3);
+
+ coco::Dep dep;
+
+ // NOTE b->object() is not updated here
+ dep.bag(bag);
+
+ ASSERT_EQ(dep.bag(), bag);
+}
+
+TEST_F(DepTest, bag_update_with_link_and_object)
+{
+ auto bag = bag_mgr.create(3);
+ auto obj = obj_mgr.create<coco::FeatureObject>();
+
+ coco::Dep dep;
+
+ dep.object(obj);
+
+ dep.bag(bag);
+
+ auto deps = coco::dependent_objects(bag);
+
+ ASSERT_EQ(deps.size(), 1);
+ ASSERT_NE(deps.count(obj), 0);
+}
diff --git a/compiler/coco/core/src/IR/ElemID.cpp b/compiler/coco/core/src/IR/ElemID.cpp
new file mode 100644
index 000000000..145bb986a
--- /dev/null
+++ b/compiler/coco/core/src/IR/ElemID.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/ElemID.h"
+
+namespace coco
+{
+
+bool operator==(const ElemID &lhs, const ElemID &rhs) { return lhs.value() == rhs.value(); }
+bool operator<(const ElemID &lhs, const ElemID &rhs) { return lhs.value() < rhs.value(); }
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/ElemID.test.cpp b/compiler/coco/core/src/IR/ElemID.test.cpp
new file mode 100644
index 000000000..dff2fa27c
--- /dev/null
+++ b/compiler/coco/core/src/IR/ElemID.test.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/ElemID.h"
+
+#include <vector>
+
+#include <gtest/gtest.h>
+
+TEST(IR_ELEM_ID, constructor)
+{
+ coco::ElemID id{128};
+
+ ASSERT_EQ(id.value(), 128);
+}
+
+TEST(IR_ELEM_ID, copy)
+{
+ coco::ElemID src{16};
+ coco::ElemID dst{32};
+
+ dst = src;
+
+ ASSERT_EQ(dst.value(), 16);
+}
+
+TEST(IR_ELEM_ID, std_vector_compatible)
+{
+ // ElemID SHOULD be compatible with standard container (including std::vector)
+ std::vector<coco::ElemID> vec;
+
+ vec.resize(16);
+ vec.clear();
+ vec.emplace_back(coco::ElemID{128});
+
+ ASSERT_EQ(vec.at(0).value(), 128);
+}
+
+TEST(IR_ELEM_ID, operator_eq)
+{
+ ASSERT_TRUE(coco::ElemID{16} == coco::ElemID{16});
+ ASSERT_FALSE(coco::ElemID{16} == coco::ElemID{17});
+}
+
+TEST(IR_ELEM_ID, operator_lt)
+{
+ ASSERT_FALSE(coco::ElemID{16} < coco::ElemID{16});
+ ASSERT_TRUE(coco::ElemID{16} < coco::ElemID{17});
+}
diff --git a/compiler/coco/core/src/IR/EntityManager.cpp b/compiler/coco/core/src/IR/EntityManager.cpp
new file mode 100644
index 000000000..f6f2cb382
--- /dev/null
+++ b/compiler/coco/core/src/IR/EntityManager.cpp
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/EntityManager.h"
+
+// NOTE Do NOT delete this file; this file enforces compiler to check whether 'EntityManager.h' is
+// complete.
diff --git a/compiler/coco/core/src/IR/Eval.cpp b/compiler/coco/core/src/IR/Eval.cpp
new file mode 100644
index 000000000..dcf579049
--- /dev/null
+++ b/compiler/coco/core/src/IR/Eval.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Instrs.h"
+#include "coco/IR/Op.h"
+
+namespace coco
+{
+
+Eval::Eval() : _out{this}, _step{this}
+{
+ // DO NOTHING
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Eval.test.cpp b/compiler/coco/core/src/IR/Eval.test.cpp
new file mode 100644
index 000000000..6469f6763
--- /dev/null
+++ b/compiler/coco/core/src/IR/Eval.test.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Instrs.h"
+#include "coco/IR/ObjectManager.h"
+#include "coco/IR/OpManager.h"
+
+#include <gtest/gtest.h>
+
+namespace
+{
+class EvalTest : public ::testing::Test
+{
+public:
+ virtual ~EvalTest() = default;
+
+protected:
+ coco::Eval *allocate(void)
+ {
+ auto ins = new coco::Eval{};
+ _allocated.emplace_back(ins);
+ return ins;
+ }
+
+private:
+ std::vector<std::unique_ptr<coco::Instr>> _allocated;
+};
+} // namespace
+
+TEST_F(EvalTest, constructor)
+{
+ auto ins = allocate();
+
+ ASSERT_EQ(ins->out(), nullptr);
+ ASSERT_EQ(ins->op(), nullptr);
+}
+
+TEST_F(EvalTest, asEval)
+{
+ auto ins = allocate();
+
+ coco::Instr *mutable_ptr = ins;
+ const coco::Instr *immutable_ptr = ins;
+
+ ASSERT_NE(mutable_ptr->asEval(), nullptr);
+ ASSERT_EQ(mutable_ptr->asEval(), immutable_ptr->asEval());
+}
diff --git a/compiler/coco/core/src/IR/FeatureLayouts.cpp b/compiler/coco/core/src/IR/FeatureLayouts.cpp
new file mode 100644
index 000000000..98423e01f
--- /dev/null
+++ b/compiler/coco/core/src/IR/FeatureLayouts.cpp
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/FeatureLayouts.h"
+
+#include <nncc/core/ADT/feature/CHWLayout.h>
+#include <nncc/core/ADT/feature/HWCLayout.h>
+
+#include <cassert>
+
+using namespace nncc::core::ADT::feature;
+
+//
+// BCHW Layout
+//
+namespace coco
+{
+namespace FeatureLayouts
+{
+
+const FeatureLayout::ID *BCHW::uid(void)
+{
+ struct LayoutID final : public FeatureLayout::ID
+ {
+ };
+ static LayoutID id;
+ return &id;
+}
+
+ElemID BCHW::at(uint32_t b, uint32_t ch, uint32_t row, uint32_t col) const
+{
+ static CHWLayout l;
+
+ uint32_t offset = 0;
+ offset += b * num_elements(_shape);
+ offset += l.offset(_shape, ch, row, col);
+ return ElemID{offset};
+}
+
+std::unique_ptr<BCHW> BCHW::create(const nncc::core::ADT::feature::Shape &shape)
+{
+ // NOTE It is impossible to use make_unique here as the constructor is private
+ return std::unique_ptr<BCHW>{new BCHW{FeatureShape{shape}}};
+}
+
+} // namespace FeatureLayouts
+} // namespace coco
+
+//
+// BHWC Layout
+//
+namespace coco
+{
+namespace FeatureLayouts
+{
+
+const FeatureLayout::ID *BHWC::uid(void)
+{
+ struct LayoutID final : public FeatureLayout::ID
+ {
+ };
+ static LayoutID id;
+ return &id;
+}
+
+ElemID BHWC::at(uint32_t b, uint32_t ch, uint32_t row, uint32_t col) const
+{
+ static HWCLayout l;
+
+ uint32_t offset = 0;
+ offset += b * num_elements(_shape);
+ offset += l.offset(_shape, ch, row, col);
+
+ return ElemID{offset};
+}
+
+std::unique_ptr<BHWC> BHWC::create(const nncc::core::ADT::feature::Shape &shape)
+{
+ // NOTE It is impossible to use make_unique here as the constructor is private
+ return std::unique_ptr<BHWC>{new BHWC{FeatureShape{shape}}};
+}
+
+std::unique_ptr<BHWC> BHWC::create(const FeatureShape &shape)
+{
+ // NOTE It is impossible to use make_unique here as the constructor is private
+ return std::unique_ptr<BHWC>{new BHWC{shape}};
+}
+
+} // namespace FeatureLayouts
+} // namespace coco
+
+//
+// BC: Channel-major Channel-wise Layout
+//
+namespace coco
+{
+namespace FeatureLayouts
+{
+
+const FeatureLayout::ID *BC::uid(void)
+{
+ struct LayoutID final : public FeatureLayout::ID
+ {
+ };
+ static LayoutID id;
+ return &id;
+}
+
+// NOTE BC layout ignores row/col as its name suggests
+ElemID BC::at(uint32_t b, uint32_t ch, uint32_t /*row*/, uint32_t /*col*/) const
+{
+ assert(b < shape().batch());
+
+ uint32_t offset = 0;
+
+ offset += b * _shape.depth();
+ offset += ch;
+
+ return ElemID{offset};
+}
+
+std::unique_ptr<BC> BC::create(const nncc::core::ADT::feature::Shape &shape)
+{
+ // NOTE It is impossible to use make_unique here as the constructor is private
+ return std::unique_ptr<BC>{new BC{FeatureShape{shape}}};
+}
+
+} // namespace FeatureLayouts
+} // namespace coco
+
+//
+// Generic Layout
+//
+namespace coco
+{
+namespace FeatureLayouts
+{
+
+Generic::Generic(const FeatureShape &shape) : _shape{shape}
+{
+ _content.resize(_shape.batch() * num_elements(_shape));
+}
+
+const FeatureLayout::ID *Generic::uid(void)
+{
+ struct LayoutID final : public FeatureLayout::ID
+ {
+ };
+ static LayoutID id;
+ return &id;
+}
+
+uint32_t Generic::offset(uint32_t b, uint32_t ch, uint32_t row, uint32_t col) const
+{
+ static nncc::core::ADT::feature::CHWLayout l{};
+
+ uint32_t res = 0;
+
+ res += b * num_elements(_shape);
+ res += l.offset(shape(), ch, row, col);
+
+ return res;
+}
+
+ElemID &Generic::at(uint32_t b, uint32_t ch, uint32_t row, uint32_t col)
+{
+ return _content.at(offset(b, ch, row, col));
+}
+
+ElemID Generic::at(uint32_t b, uint32_t ch, uint32_t row, uint32_t col) const
+{
+ return _content.at(offset(b, ch, row, col));
+}
+
+void Generic::reorder(const nncc::core::ADT::feature::Layout &l)
+{
+ assert(shape().batch() == 1);
+
+ for (uint32_t ch = 0; ch < shape().depth(); ++ch)
+ {
+ for (uint32_t row = 0; row < shape().height(); ++row)
+ {
+ for (uint32_t col = 0; col < shape().width(); ++col)
+ {
+ at(0, ch, row, col) = ElemID{l.offset(shape(), ch, row, col)};
+ }
+ }
+ }
+}
+
+std::unique_ptr<Generic> Generic::create(const nncc::core::ADT::feature::Shape &shape)
+{
+ // NOTE It is impossible to use make_unique here as the constructor is private
+ return std::unique_ptr<Generic>{new Generic{shape}};
+}
+
+} // namespace FeatureLayouts
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/FeatureLayouts.test.cpp b/compiler/coco/core/src/IR/FeatureLayouts.test.cpp
new file mode 100644
index 000000000..9f9772dd8
--- /dev/null
+++ b/compiler/coco/core/src/IR/FeatureLayouts.test.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/FeatureLayouts.h"
+
+#include <gtest/gtest.h>
+
+using namespace nncc::core::ADT;
+
+TEST(FeatureLayoutsTest, BC)
+{
+ // NOTE The current implementation uses a hard-coded "batch" value
+ const uint32_t B = 1;
+ const uint32_t C = 3;
+ const uint32_t H = 4;
+ const uint32_t W = 5;
+
+ auto l = coco::FeatureLayouts::BC::create(feature::Shape{C, H, W});
+
+ ASSERT_EQ(l->batch(), B);
+ ASSERT_EQ(l->depth(), C);
+ ASSERT_EQ(l->height(), H);
+ ASSERT_EQ(l->width(), W);
+
+ // Check whether BC layout is actually channel-wise
+ for (uint32_t b = 0; b < B; ++b)
+ {
+ for (uint32_t ch = 0; ch < C; ++ch)
+ {
+ for (uint32_t row = 0; row < H; ++row)
+ {
+ for (uint32_t col = 0; col < W; ++col)
+ {
+ ASSERT_EQ(l->at(b, ch, 0, 0), l->at(b, ch, row, col));
+ }
+ }
+ }
+ }
+
+ // Check whether BC layout is actually channel-major
+ for (uint32_t b = 0; b < B; ++b)
+ {
+ for (uint32_t ch = 1; ch < C; ++ch)
+ {
+ ASSERT_EQ(l->at(b, ch - 1, 0, 0).value() + 1, l->at(b, ch, 0, 0).value());
+ }
+ }
+
+ for (uint32_t b = 1; b < B; ++b)
+ {
+ ASSERT_EQ(l->at(b - 1, C - 1, 0, 0).value() + 1, l->at(b, 0, 0, 0).value());
+ }
+}
diff --git a/compiler/coco/core/src/IR/FeatureObject.cpp b/compiler/coco/core/src/IR/FeatureObject.cpp
new file mode 100644
index 000000000..46de98874
--- /dev/null
+++ b/compiler/coco/core/src/IR/FeatureObject.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/FeatureObject.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+FeatureObject::~FeatureObject()
+{
+ // DO NOTHING
+}
+
+const FeatureShape &FeatureObject::shape(void) const { return _layout->shape(); }
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/FeatureObject.test.cpp b/compiler/coco/core/src/IR/FeatureObject.test.cpp
new file mode 100644
index 000000000..23188f866
--- /dev/null
+++ b/compiler/coco/core/src/IR/FeatureObject.test.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/FeatureObject.h"
+#include "coco/IR/FeatureLayouts.h"
+
+#include <vector>
+#include <memory>
+
+#include <gtest/gtest.h>
+
+using namespace nncc::core::ADT;
+
+namespace
+{
+class FeatureObjectTest : public ::testing::Test
+{
+protected:
+ coco::FeatureObject *allocate()
+ {
+ auto o = new coco::FeatureObject{};
+ _allocated.emplace_back(o);
+ return o;
+ }
+
+ // TODO Deprecate this method
+ coco::FeatureObject *allocate(const coco::FeatureShape &shape)
+ {
+ auto o = new coco::FeatureObject{};
+ o->layout(coco::FeatureLayouts::Generic::create(shape));
+ _allocated.emplace_back(o);
+ return o;
+ }
+
+private:
+ std::vector<std::unique_ptr<coco::FeatureObject>> _allocated;
+};
+} // namespace
+
+TEST_F(FeatureObjectTest, ctor)
+{
+ const coco::FeatureShape shape{1, 3, 3};
+
+ auto o = allocate(shape);
+
+ ASSERT_EQ(o->shape(), shape);
+ ASSERT_EQ(o->kind(), coco::Object::Kind::Feature);
+}
+
+// TODO Reimplement this test as a test for GenericFeatureLayout
+#if 0
+TEST_F(FeatureObjectTest, at)
+{
+ const uint32_t C = 1;
+ const uint32_t H = 3;
+ const uint32_t W = 3;
+
+ const coco::FeatureShape shape{C, H, W};
+
+ auto o = allocate(shape);
+
+ coco::FeatureObject *mutable_ptr = o;
+ const coco::FeatureObject *immutable_ptr = o;
+
+ for (uint32_t ch = 0; ch < C; ++ch)
+ {
+ for (uint32_t row = 0; row < H; ++row)
+ {
+ for (uint32_t col = 0; col < W; ++col)
+ {
+ mutable_ptr->at(ch, row, col) = coco::ElemID{16};
+ }
+ }
+ }
+
+ for (uint32_t ch = 0; ch < C; ++ch)
+ {
+ for (uint32_t row = 0; row < H; ++row)
+ {
+ for (uint32_t col = 0; col < W; ++col)
+ {
+ ASSERT_EQ(immutable_ptr->at(ch, row, col).value(), 16);
+ }
+ }
+ }
+}
+#endif
+
+TEST_F(FeatureObjectTest, asFeature)
+{
+ const coco::FeatureShape shape{1, 3, 3};
+
+ auto o = allocate(shape);
+
+ coco::Object *mutable_object = o;
+ const coco::Object *immutable_object = o;
+
+ ASSERT_NE(mutable_object->asFeature(), nullptr);
+ ASSERT_EQ(mutable_object->asFeature(), immutable_object->asFeature());
+}
+
+TEST_F(FeatureObjectTest, casting_helpers)
+{
+ auto obj = allocate();
+
+ ASSERT_TRUE(coco::isa<coco::FeatureObject>(obj));
+ ASSERT_EQ(coco::cast<coco::FeatureObject>(obj), obj);
+ ASSERT_EQ(coco::safe_cast<coco::FeatureObject>(obj), obj);
+}
diff --git a/compiler/coco/core/src/IR/FeatureShape.test.cpp b/compiler/coco/core/src/IR/FeatureShape.test.cpp
new file mode 100644
index 000000000..ceeab02b7
--- /dev/null
+++ b/compiler/coco/core/src/IR/FeatureShape.test.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/FeatureShape.h"
+
+#include <gtest/gtest.h>
+
+TEST(FeatureShapeTest, constructor_with_4_arguments)
+{
+ const coco::FeatureShape shape{1, 2, 3, 4};
+
+ ASSERT_EQ(shape.batch(), 1);
+ ASSERT_EQ(shape.depth(), 2);
+ ASSERT_EQ(shape.height(), 3);
+ ASSERT_EQ(shape.width(), 4);
+}
diff --git a/compiler/coco/core/src/IR/Input.cpp b/compiler/coco/core/src/IR/Input.cpp
new file mode 100644
index 000000000..4385ac26c
--- /dev/null
+++ b/compiler/coco/core/src/IR/Input.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Input.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+Input::Input(const nncc::core::ADT::tensor::Shape &shape) : Arg{shape}
+{
+ // DO NOT?HING
+}
+
+void Input::onTake(Bag *bag)
+{
+ assert(bag->input() == nullptr);
+ bag->input(this);
+}
+
+void Input::onRelease(Bag *bag)
+{
+ assert(bag->input() == this);
+ bag->input(nullptr);
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Input.test.cpp b/compiler/coco/core/src/IR/Input.test.cpp
new file mode 100644
index 000000000..7cc1731cc
--- /dev/null
+++ b/compiler/coco/core/src/IR/Input.test.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Input.h"
+#include "coco/IR/BagManager.h"
+
+#include <nncc/core/ADT/tensor/IndexEnumerator.h>
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::tensor::Shape;
+using nncc::core::ADT::tensor::IndexEnumerator;
+
+TEST(IR_INPUT, ctor_should_set_shape)
+{
+ const nncc::core::ADT::tensor::Shape shape{1, 3, 3, 1};
+ coco::Input input{shape};
+
+ ASSERT_EQ(input.shape(), shape);
+ ASSERT_TRUE(input.name().empty());
+}
+
+TEST(IR_INPUT, bag_update)
+{
+ // Create a bag
+ coco::BagManager bag_mgr;
+
+ auto bag = bag_mgr.create(9);
+
+ const nncc::core::ADT::tensor::Shape shape{1, 3, 3, 1};
+ coco::Input input{shape};
+
+ input.bag(bag);
+ ASSERT_EQ(input.bag(), bag);
+
+ // bag(...) method SHOULD update 'bag' type
+ ASSERT_TRUE(bag->isInput());
+}
+
+TEST(IR_INPUT, name_update)
+{
+ const nncc::core::ADT::tensor::Shape shape{1, 3, 3, 1};
+ coco::Input input{shape};
+
+ input.name("data");
+ ASSERT_EQ(input.name(), "data");
+}
+
+TEST(IR_INPUT, at)
+{
+ const Shape shape{1, 3, 3, 1};
+ coco::Input input{shape};
+
+ coco::Input *mutable_ptr = &input;
+ const coco::Input *immutable_ptr = &input;
+
+ for (IndexEnumerator e{shape}; e.valid(); e.advance())
+ {
+ mutable_ptr->at(e.current()) = coco::ElemID{16};
+ }
+
+ for (IndexEnumerator e{shape}; e.valid(); e.advance())
+ {
+ ASSERT_EQ(immutable_ptr->at(e.current()).value(), 16);
+ }
+}
diff --git a/compiler/coco/core/src/IR/InputManager.cpp b/compiler/coco/core/src/IR/InputManager.cpp
new file mode 100644
index 000000000..6d5b9470b
--- /dev/null
+++ b/compiler/coco/core/src/IR/InputManager.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/InputManager.h"
+
+#include <stdex/Memory.h>
+
+namespace coco
+{
+
+Input *InputManager::create(const nncc::core::ADT::tensor::Shape &shape)
+{
+ auto input = stdex::make_unique<Input>(shape);
+ modulize(input.get());
+ return take(std::move(input));
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/InputManager.test.cpp b/compiler/coco/core/src/IR/InputManager.test.cpp
new file mode 100644
index 000000000..be43113b4
--- /dev/null
+++ b/compiler/coco/core/src/IR/InputManager.test.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/InputManager.h"
+
+#include <gtest/gtest.h>
+
+TEST(IR_INPUT_MANAGER, make)
+{
+ coco::InputManager mgr;
+
+ const nncc::core::ADT::tensor::Shape shape{1, 3, 3, 1};
+ auto input = mgr.create(shape);
+
+ ASSERT_EQ(input->shape(), shape);
+}
diff --git a/compiler/coco/core/src/IR/Instr.cpp b/compiler/coco/core/src/IR/Instr.cpp
new file mode 100644
index 000000000..9f000ba1c
--- /dev/null
+++ b/compiler/coco/core/src/IR/Instr.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Instr.h"
+#include "coco/IR/Block.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+template <> void DLinkedList<Instr, Block>::joined(Block *, Instr *curr_ins)
+{
+ assert(!curr_ins->index().valid());
+ uint32_t value = 0;
+
+ if (auto prev_ins = curr_ins->prev())
+ {
+ value = prev_ins->index().value() + 1;
+ }
+
+ for (auto ins = curr_ins; ins; ins = ins->next())
+ {
+ ins->_index.set(value++);
+ }
+}
+
+template <> void DLinkedList<Instr, Block>::leaving(Block *, Instr *curr_ins)
+{
+ assert(curr_ins->index().valid());
+ uint32_t value = curr_ins->index().value();
+
+ for (auto ins = curr_ins->next(); ins; ins = ins->next())
+ {
+ ins->_index.set(value++);
+ }
+
+ curr_ins->_index.reset();
+}
+
+template <> InstrList *DLinkedList<Instr, Block>::head(Block *b) { return b->instr(); }
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/InstrIndex.cpp b/compiler/coco/core/src/IR/InstrIndex.cpp
new file mode 100644
index 000000000..c447cfc42
--- /dev/null
+++ b/compiler/coco/core/src/IR/InstrIndex.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/InstrIndex.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+void InstrIndex::set(uint32_t value)
+{
+ assert(value != undefined);
+ _value = value;
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/InstrIndex.test.cpp b/compiler/coco/core/src/IR/InstrIndex.test.cpp
new file mode 100644
index 000000000..40f5d49de
--- /dev/null
+++ b/compiler/coco/core/src/IR/InstrIndex.test.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/InstrIndex.h"
+
+#include <gtest/gtest.h>
+
+namespace
+{
+
+class InstrIndexTest : public ::testing::Test
+{
+};
+
+} // namespace
+
+TEST_F(InstrIndexTest, default_constructor)
+{
+ coco::InstrIndex ins_ind;
+
+ ASSERT_FALSE(ins_ind.valid());
+}
+
+TEST_F(InstrIndexTest, explicit_constructor)
+{
+ coco::InstrIndex ins_ind{3};
+
+ ASSERT_TRUE(ins_ind.valid());
+ ASSERT_EQ(ins_ind.value(), 3);
+}
+
+TEST_F(InstrIndexTest, operator_lt)
+{
+ // Valid index is always less than undefined one.
+ ASSERT_TRUE(coco::InstrIndex(3) < coco::InstrIndex());
+ ASSERT_TRUE(coco::InstrIndex(3) < coco::InstrIndex(4));
+}
diff --git a/compiler/coco/core/src/IR/InstrManager.cpp b/compiler/coco/core/src/IR/InstrManager.cpp
new file mode 100644
index 000000000..32f1cbf28
--- /dev/null
+++ b/compiler/coco/core/src/IR/InstrManager.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/InstrManager.h"
+
+#include "coco/IR/Op.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+void InstrManager::destroy(Instr *ins)
+{
+ // ins SHOULD BE detached from any block before destroy call
+ assert(ins->parent() == nullptr);
+ release(ins);
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/InstrManager.test.cpp b/compiler/coco/core/src/IR/InstrManager.test.cpp
new file mode 100644
index 000000000..23d9f8e86
--- /dev/null
+++ b/compiler/coco/core/src/IR/InstrManager.test.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/InstrManager.h"
+#include "coco/IR/Op.h"
+
+#include <gtest/gtest.h>
+
+namespace
+{
+
+// Dummy custom instruction for testing
+struct CustomInstr final : public coco::Instr
+{
+};
+
+class InstrManagerTest : public ::testing::Test
+{
+public:
+ virtual ~InstrManagerTest() = default;
+
+protected:
+ coco::InstrManager mgr;
+};
+} // namespace
+
+TEST_F(InstrManagerTest, create_Shuffle)
+{
+ auto ins = mgr.create<coco::Shuffle>();
+ ASSERT_NE(ins, nullptr);
+ mgr.destroy(ins);
+}
+
+TEST_F(InstrManagerTest, create_Custom)
+{
+ auto ins = mgr.create<CustomInstr>();
+ ASSERT_NE(ins, nullptr);
+ mgr.destroy(ins);
+}
diff --git a/compiler/coco/core/src/IR/KernelLayouts.cpp b/compiler/coco/core/src/IR/KernelLayouts.cpp
new file mode 100644
index 000000000..6e9a1575a
--- /dev/null
+++ b/compiler/coco/core/src/IR/KernelLayouts.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/KernelLayouts.h"
+
+#include <nncc/core/ADT/kernel/NCHWLayout.h>
+#include <nncc/core/ADT/kernel/NHWCLayout.h>
+
+#include <cassert>
+
+using namespace nncc::core::ADT::kernel;
+
+using nncc::core::ADT::kernel::num_elements;
+using nncc::core::ADT::kernel::Shape;
+
+//
+// NCHW Layout
+//
+namespace coco
+{
+namespace KernelLayouts
+{
+
+const KernelLayout::ID *NCHW::uid(void)
+{
+ struct LayoutID final : public KernelLayout::ID
+ {
+ };
+ static LayoutID id;
+ return &id;
+}
+
+ElemID NCHW::at(uint32_t n, uint32_t ch, uint32_t row, uint32_t col) const
+{
+ static NCHWLayout l;
+ return ElemID{l.offset(_shape, n, ch, row, col)};
+}
+
+std::unique_ptr<NCHW> NCHW::create(const nncc::core::ADT::kernel::Shape &shape)
+{
+ // NOTE It is impossible to use make_unique here as the constructor is private
+ return std::unique_ptr<NCHW>{new NCHW{shape}};
+}
+
+} // namespace KernelLayouts
+} // namespace coco
+
+//
+// NHWC Layout
+//
+namespace coco
+{
+namespace KernelLayouts
+{
+
+const KernelLayout::ID *NHWC::uid(void)
+{
+ struct LayoutID final : public KernelLayout::ID
+ {
+ };
+ static LayoutID id;
+ return &id;
+}
+
+ElemID NHWC::at(uint32_t n, uint32_t ch, uint32_t row, uint32_t col) const
+{
+ static NHWCLayout l;
+ return ElemID{l.offset(_shape, n, ch, row, col)};
+}
+
+std::unique_ptr<NHWC> NHWC::create(const nncc::core::ADT::kernel::Shape &shape)
+{
+ // NOTE It is impossible to use make_unique here as the constructor is private
+ return std::unique_ptr<NHWC>{new NHWC{shape}};
+}
+
+} // namespace KernelLayouts
+} // namespace coco
+
+//
+// Generic Layout
+//
+namespace
+{
+
+nncc::core::ADT::kernel::NCHWLayout l;
+
+} // namespace
+
+namespace coco
+{
+namespace KernelLayouts
+{
+
+Generic::Generic(const nncc::core::ADT::kernel::Shape &shape) : _shape{shape}
+{
+ _content.resize(num_elements(_shape));
+}
+
+const KernelLayout::ID *Generic::uid(void)
+{
+ struct LayoutID final : public KernelLayout::ID
+ {
+ };
+ static LayoutID id;
+ return &id;
+}
+
+ElemID &Generic::at(uint32_t n, uint32_t ch, uint32_t row, uint32_t col)
+{
+ return _content.at(l.offset(_shape, n, ch, row, col));
+}
+
+ElemID Generic::at(uint32_t n, uint32_t ch, uint32_t row, uint32_t col) const
+{
+ return _content.at(l.offset(_shape, n, ch, row, col));
+}
+
+void Generic::reorder(const nncc::core::ADT::kernel::Layout &l)
+{
+ for (uint32_t n = 0; n < shape().count(); ++n)
+ {
+ for (uint32_t ch = 0; ch < shape().depth(); ++ch)
+ {
+ for (uint32_t row = 0; row < shape().height(); ++row)
+ {
+ for (uint32_t col = 0; col < shape().width(); ++col)
+ {
+ at(n, ch, row, col) = ElemID{l.offset(shape(), n, ch, row, col)};
+ }
+ }
+ }
+ }
+}
+
+std::unique_ptr<Generic> Generic::create(const Shape &shape)
+{
+ return std::unique_ptr<Generic>{new Generic{shape}};
+}
+
+} // namespace KernelLayouts
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/KernelLayouts.test.cpp b/compiler/coco/core/src/IR/KernelLayouts.test.cpp
new file mode 100644
index 000000000..df13cb051
--- /dev/null
+++ b/compiler/coco/core/src/IR/KernelLayouts.test.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/KernelLayouts.h"
+
+#include <nncc/core/ADT/kernel/NCHWLayout.h>
+#include <nncc/core/ADT/kernel/NHWCLayout.h>
+
+#include <gtest/gtest.h>
+
+using namespace nncc::core::ADT;
+
+TEST(KernelLayoutsTest, NCHW_increment)
+{
+ const uint32_t N = 2;
+ const uint32_t C = 3;
+ const uint32_t H = 4;
+ const uint32_t W = 4;
+
+ auto l = coco::KernelLayouts::NCHW::create(kernel::Shape{N, C, H, W});
+
+ // check NCHW order
+ ASSERT_EQ(l->at(0, 0, 0, 1).value(), l->at(0, 0, 0, 0).value() + 1);
+ ASSERT_EQ(l->at(0, 0, 1, 0).value(), l->at(0, 0, 0, 0).value() + W);
+ ASSERT_EQ(l->at(0, 1, 0, 0).value(), l->at(0, 0, 0, 0).value() + H * W);
+ ASSERT_EQ(l->at(1, 0, 0, 0).value(), l->at(0, 0, 0, 0).value() + C * H * W);
+}
+
+TEST(KernelLayoutsTest, NHWC_increment)
+{
+ const uint32_t N = 2;
+ const uint32_t C = 3;
+ const uint32_t H = 4;
+ const uint32_t W = 4;
+
+ auto l = coco::KernelLayouts::NHWC::create(kernel::Shape{N, C, H, W});
+
+ // check NHWC order
+ ASSERT_EQ(l->at(0, 1, 0, 0).value(), l->at(0, 0, 0, 0).value() + 1);
+ ASSERT_EQ(l->at(0, 0, 0, 1).value(), l->at(0, 0, 0, 0).value() + C);
+ ASSERT_EQ(l->at(0, 0, 1, 0).value(), l->at(0, 0, 0, 0).value() + W * C);
+ ASSERT_EQ(l->at(1, 0, 0, 0).value(), l->at(0, 0, 0, 0).value() + H * W * C);
+}
+
+TEST(KernelLayoutsTest, Generic_increment)
+{
+ const uint32_t N = 2;
+ const uint32_t C = 3;
+ const uint32_t H = 4;
+ const uint32_t W = 4;
+
+ auto nchw = coco::KernelLayouts::Generic::create(kernel::Shape{N, C, H, W});
+ auto nhwc = coco::KernelLayouts::Generic::create(kernel::Shape{N, C, H, W});
+
+ // reorder
+ nchw->reorder(kernel::NCHWLayout());
+ nhwc->reorder(kernel::NHWCLayout());
+
+ // check NCHW order
+ ASSERT_EQ(nchw->at(0, 0, 0, 1).value(), nchw->at(0, 0, 0, 0).value() + 1);
+ ASSERT_EQ(nchw->at(0, 0, 1, 0).value(), nchw->at(0, 0, 0, 0).value() + W);
+ ASSERT_EQ(nchw->at(0, 1, 0, 0).value(), nchw->at(0, 0, 0, 0).value() + H * W);
+ ASSERT_EQ(nchw->at(1, 0, 0, 0).value(), nchw->at(0, 0, 0, 0).value() + C * H * W);
+
+ // check NHWC order
+ ASSERT_EQ(nhwc->at(0, 1, 0, 0).value(), nhwc->at(0, 0, 0, 0).value() + 1);
+ ASSERT_EQ(nhwc->at(0, 0, 0, 1).value(), nhwc->at(0, 0, 0, 0).value() + C);
+ ASSERT_EQ(nhwc->at(0, 0, 1, 0).value(), nhwc->at(0, 0, 0, 0).value() + W * C);
+ ASSERT_EQ(nhwc->at(1, 0, 0, 0).value(), nhwc->at(0, 0, 0, 0).value() + H * W * C);
+}
+
+TEST(KernelLayoutsTest, Generic_at)
+{
+ const uint32_t N = 2;
+ const uint32_t C = 3;
+ const uint32_t H = 4;
+ const uint32_t W = 4;
+
+ auto l = coco::KernelLayouts::Generic::create(kernel::Shape{N, C, H, W});
+
+ ASSERT_NE(l.get(), nullptr);
+
+ coco::KernelLayouts::Generic *mutable_ptr = l.get();
+ const coco::KernelLayouts::Generic *immutable_ptr = l.get();
+
+ for (uint32_t n = 0; n < N; ++n)
+ {
+ for (uint32_t ch = 0; ch < C; ++ch)
+ {
+ for (uint32_t row = 0; row < H; ++row)
+ {
+ for (uint32_t col = 0; col < W; ++col)
+ {
+ mutable_ptr->at(n, ch, row, col) = coco::ElemID{16};
+ }
+ }
+ }
+ }
+
+ for (uint32_t n = 0; n < N; ++n)
+ {
+ for (uint32_t ch = 0; ch < C; ++ch)
+ {
+ for (uint32_t row = 0; row < H; ++row)
+ {
+ for (uint32_t col = 0; col < W; ++col)
+ {
+ ASSERT_EQ(immutable_ptr->at(n, ch, row, col).value(), 16);
+ }
+ }
+ }
+ }
+}
diff --git a/compiler/coco/core/src/IR/KernelObject.cpp b/compiler/coco/core/src/IR/KernelObject.cpp
new file mode 100644
index 000000000..79c298b43
--- /dev/null
+++ b/compiler/coco/core/src/IR/KernelObject.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/KernelObject.h"
+#include "coco/IR/KernelLayouts.h"
+
+#include <nncc/core/ADT/kernel/NCHWLayout.h>
+
+namespace coco
+{
+
+KernelObject::KernelObject(const nncc::core::ADT::kernel::Shape &shape)
+{
+ _layout = KernelLayouts::Generic::create(shape);
+}
+
+KernelObject::~KernelObject()
+{
+ // DO NOTHING
+}
+
+const nncc::core::ADT::kernel::Shape &KernelObject::shape(void) const { return _layout->shape(); }
+
+ElemID KernelObject::at(uint32_t n, uint32_t ch, uint32_t row, uint32_t col) const
+{
+ return _layout->at(n, ch, row, col);
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/KernelObject.test.cpp b/compiler/coco/core/src/IR/KernelObject.test.cpp
new file mode 100644
index 000000000..f227764ca
--- /dev/null
+++ b/compiler/coco/core/src/IR/KernelObject.test.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/KernelObject.h"
+
+#include <vector>
+#include <memory>
+
+#include <gtest/gtest.h>
+
+using namespace nncc::core::ADT;
+
+namespace
+{
+class KernelObjectTest : public ::testing::Test
+{
+protected:
+ coco::KernelObject *allocate()
+ {
+ auto o = new coco::KernelObject{};
+ _allocated.emplace_back(o);
+ return o;
+ }
+
+ coco::KernelObject *allocate(const kernel::Shape &shape)
+ {
+ auto o = new coco::KernelObject{shape};
+ _allocated.emplace_back(o);
+ return o;
+ }
+
+private:
+ std::vector<std::unique_ptr<coco::KernelObject>> _allocated;
+};
+} // namespace
+
+TEST_F(KernelObjectTest, constructor)
+{
+ const nncc::core::ADT::kernel::Shape shape{1, 1, 3, 3};
+ auto o = allocate(shape);
+
+ ASSERT_EQ(o->shape(), shape);
+ ASSERT_EQ(o->kind(), coco::Object::Kind::Kernel);
+}
+
+TEST_F(KernelObjectTest, asKernel)
+{
+ const nncc::core::ADT::kernel::Shape shape{1, 1, 3, 3};
+ auto o = allocate(shape);
+
+ coco::Object *mutable_object = o;
+ const coco::Object *immutable_object = o;
+
+ ASSERT_NE(mutable_object->asKernel(), nullptr);
+ ASSERT_EQ(mutable_object->asKernel(), immutable_object->asKernel());
+}
+
+TEST_F(KernelObjectTest, casting_helpers)
+{
+ auto obj = allocate();
+
+ ASSERT_TRUE(coco::isa<coco::KernelObject>(obj));
+ ASSERT_EQ(coco::cast<coco::KernelObject>(obj), obj);
+ ASSERT_EQ(coco::safe_cast<coco::KernelObject>(obj), obj);
+}
diff --git a/compiler/coco/core/src/IR/Load.cpp b/compiler/coco/core/src/IR/Load.cpp
new file mode 100644
index 000000000..4985e9254
--- /dev/null
+++ b/compiler/coco/core/src/IR/Load.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Ops.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+Load::Load() : _obj{this}
+{
+ // DO NOTHING
+}
+
+uint32_t Load::arity(void) const
+{
+ // Load has no child Op
+ return 0;
+}
+
+Op *Load::arg(uint32_t) const
+{
+ assert(!"Load has no argument");
+ return nullptr;
+}
+
+std::set<Object *> Load::uses(void) const
+{
+ std::set<Object *> res;
+
+ if (auto obj = object())
+ {
+ res.insert(obj);
+ }
+
+ return res;
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/MaxPool2D.test.cpp b/compiler/coco/core/src/IR/MaxPool2D.test.cpp
new file mode 100644
index 000000000..864edddb3
--- /dev/null
+++ b/compiler/coco/core/src/IR/MaxPool2D.test.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Ops.h"
+
+#include <memory>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+namespace
+{
+struct IsMaxPool2D : public coco::Op::Visitor<bool>
+{
+ bool visit(const coco::MaxPool2D *) override { return true; }
+};
+
+class MaxPool2DTest : public ::testing::Test
+{
+public:
+ MaxPool2DTest()
+ {
+ // DO NOTHING
+ }
+
+protected:
+ coco::MaxPool2D *allocate(void)
+ {
+ auto op = new coco::MaxPool2D;
+ _allocated.emplace_back(op);
+ return op;
+ }
+
+private:
+ std::vector<std::unique_ptr<coco::MaxPool2D>> _allocated;
+};
+} // namespace
+
+TEST_F(MaxPool2DTest, initialization)
+{
+ auto op = allocate();
+
+ coco::MaxPool2D *mutable_ptr = op;
+ const coco::MaxPool2D *immutable_ptr = op;
+
+ // uses() should be empty on construction
+ ASSERT_EQ(op->uses().size(), 0);
+ // parent() should be nullptr on construction
+ ASSERT_EQ(op->parent(), nullptr);
+
+ // arg() should be nullptr on construction
+ ASSERT_EQ(immutable_ptr->arg(), nullptr);
+
+ // window() SHOULD return a valid pointer
+ ASSERT_NE(mutable_ptr->window(), nullptr);
+ ASSERT_EQ(mutable_ptr->window(), immutable_ptr->window());
+
+ // stride() SHOULD return a valid pointer
+ ASSERT_NE(mutable_ptr->stride(), nullptr);
+ ASSERT_EQ(mutable_ptr->stride(), immutable_ptr->stride());
+
+ // pad() SHOULD return a valid pointer
+ ASSERT_NE(mutable_ptr->pad(), nullptr);
+ ASSERT_EQ(mutable_ptr->pad(), immutable_ptr->pad());
+}
+
+TEST_F(MaxPool2DTest, asMaxPool2D)
+{
+ auto op = allocate();
+
+ coco::Op *mutable_base = op;
+ const coco::Op *immutable_base = op;
+
+ ASSERT_EQ(mutable_base->asMaxPool2D(), op);
+ ASSERT_EQ(mutable_base->asMaxPool2D(), immutable_base->asMaxPool2D());
+}
+
+TEST_F(MaxPool2DTest, accept)
+{
+ // Test 'MaxPool2D' class
+ auto op = allocate();
+
+ coco::MaxPool2D *mutable_ptr = op;
+ const coco::MaxPool2D *immutable_ptr = op;
+
+ ASSERT_TRUE(mutable_ptr->accept(IsMaxPool2D{}));
+ ASSERT_TRUE(immutable_ptr->accept(IsMaxPool2D{}));
+}
diff --git a/compiler/coco/core/src/IR/Module.cpp b/compiler/coco/core/src/IR/Module.cpp
new file mode 100644
index 000000000..0b65ceedc
--- /dev/null
+++ b/compiler/coco/core/src/IR/Module.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Module.h"
+
+#include <stdex/Memory.h>
+
+using stdex::make_unique;
+
+namespace
+{
+
+struct EntityManagerImpl final : public coco::EntityManager
+{
+public:
+ std::unique_ptr<coco::BagManager> _bag;
+
+public:
+ coco::BagManager *bag(void) override { return _bag.get(); }
+ const coco::BagManager *bag(void) const override { return _bag.get(); }
+
+public:
+ std::unique_ptr<coco::ObjectManager> _object;
+
+public:
+ coco::ObjectManager *object(void) override { return _object.get(); }
+ const coco::ObjectManager *object(void) const override { return _object.get(); }
+
+public:
+ std::unique_ptr<coco::OpManager> _op;
+
+public:
+ coco::OpManager *op(void) override { return _op.get(); }
+ const coco::OpManager *op(void) const override { return _op.get(); }
+
+public:
+ coco::InstrManager *instr(void) override { return _instr.get(); }
+ const coco::InstrManager *instr(void) const override { return _instr.get(); }
+
+public:
+ coco::BlockManager *block(void) override { return _block.get(); }
+ const coco::BlockManager *block(void) const override { return _block.get(); }
+
+public:
+ std::unique_ptr<coco::InputManager> _input;
+
+public:
+ coco::InputManager *input(void) override { return _input.get(); }
+ const coco::InputManager *input(void) const override { return _input.get(); }
+
+public:
+ std::unique_ptr<coco::OutputManager> _output;
+
+public:
+ coco::OutputManager *output(void) override { return _output.get(); }
+ const coco::OutputManager *output(void) const override { return _output.get(); }
+
+public:
+ // WARN Do NOT change the order of these fields: _block -> _instr
+ //
+ // Note that each instruction may have a reference to a block, and
+ // the destructor of Instr accesses this 'block' reference.
+ //
+ // Thus, Instr entities SHOULD BE destructed before Block entities are destructed.
+ std::unique_ptr<coco::BlockManager> _block;
+ std::unique_ptr<coco::InstrManager> _instr;
+};
+
+} // namespace
+
+namespace
+{
+
+class ModuleImpl final : public coco::Module
+{
+public:
+ coco::EntityManager *entity(void) override { return _entity.get(); }
+ const coco::EntityManager *entity(void) const override { return _entity.get(); }
+
+public:
+ std::unique_ptr<coco::BlockList> _block;
+
+public:
+ coco::BlockList *block(void) override { return _block.get(); }
+ const coco::BlockList *block(void) const override { return _block.get(); }
+
+public:
+ std::unique_ptr<coco::InputList> _input;
+
+public:
+ coco::InputList *input(void) override { return _input.get(); }
+ const coco::InputList *input(void) const override { return _input.get(); }
+
+public:
+ std::unique_ptr<coco::OutputList> _output;
+
+public:
+ coco::OutputList *output(void) override { return _output.get(); }
+ const coco::OutputList *output(void) const override { return _output.get(); }
+
+public:
+ // WARN _entity SHOULD BE declared after _block in order to allow each Block(s) to detach itself.
+ //
+ // If not, Block is destructed after its corresponding BlockList is destructed, which results
+ // in invalid memory access during the update on BlockList (inside Block's destructor).
+ std::unique_ptr<coco::EntityManager> _entity;
+};
+
+} // namespace
+
+namespace coco
+{
+
+std::unique_ptr<Module> Module::create(void)
+{
+ auto m = make_unique<::ModuleImpl>();
+
+ auto mgr = make_unique<::EntityManagerImpl>();
+ {
+ mgr->_bag = make_unique<coco::BagManager>(m.get());
+ mgr->_object = make_unique<coco::ObjectManager>(m.get());
+ mgr->_op = make_unique<coco::OpManager>(m.get());
+ mgr->_instr = make_unique<coco::InstrManager>(m.get());
+ mgr->_block = make_unique<coco::BlockManager>(m.get());
+ mgr->_input = make_unique<coco::InputManager>(m.get());
+ mgr->_output = make_unique<coco::OutputManager>(m.get());
+ }
+ m->_entity = std::move(mgr);
+
+ m->_block = make_unique<coco::BlockList>(m.get());
+ m->_input = make_unique<coco::InputList>();
+ m->_output = make_unique<coco::OutputList>();
+
+ return std::move(m);
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Module.test.cpp b/compiler/coco/core/src/IR/Module.test.cpp
new file mode 100644
index 000000000..b55ceacb8
--- /dev/null
+++ b/compiler/coco/core/src/IR/Module.test.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Module.h"
+
+#include <gtest/gtest.h>
+
+TEST(IR_MODULE, create)
+{
+ auto m = coco::Module::create();
+
+ ASSERT_NE(m.get(), nullptr);
+
+ coco::Module *mutable_m = m.get();
+ const coco::Module *immutable_m = m.get();
+
+ ASSERT_NE(mutable_m->entity(), nullptr);
+ ASSERT_NE(immutable_m->entity(), nullptr);
+
+ ASSERT_NE(mutable_m->entity()->bag(), nullptr);
+ ASSERT_EQ(immutable_m->entity()->bag(), mutable_m->entity()->bag());
+
+ ASSERT_NE(mutable_m->entity()->object(), nullptr);
+ ASSERT_EQ(immutable_m->entity()->object(), mutable_m->entity()->object());
+
+ ASSERT_NE(mutable_m->entity()->op(), nullptr);
+ ASSERT_EQ(immutable_m->entity()->op(), mutable_m->entity()->op());
+
+ ASSERT_NE(mutable_m->entity()->instr(), nullptr);
+ ASSERT_EQ(immutable_m->entity()->instr(), mutable_m->entity()->instr());
+
+ ASSERT_NE(mutable_m->entity()->block(), nullptr);
+ ASSERT_EQ(immutable_m->entity()->block(), mutable_m->entity()->block());
+
+ ASSERT_NE(mutable_m->entity()->input(), nullptr);
+ ASSERT_EQ(immutable_m->entity()->input(), mutable_m->entity()->input());
+
+ ASSERT_NE(mutable_m->entity()->output(), nullptr);
+ ASSERT_EQ(immutable_m->entity()->output(), mutable_m->entity()->output());
+
+ ASSERT_NE(mutable_m->block(), nullptr);
+ ASSERT_EQ(immutable_m->block(), mutable_m->block());
+
+ ASSERT_NE(mutable_m->input(), nullptr);
+ ASSERT_EQ(immutable_m->input(), mutable_m->input());
+
+ ASSERT_NE(mutable_m->output(), nullptr);
+ ASSERT_EQ(immutable_m->output(), mutable_m->output());
+}
+
+TEST(IR_MODULE, append_two_blocks)
+{
+ auto m = coco::Module::create();
+
+ auto blk_1 = m->entity()->block()->create();
+ m->block()->append(blk_1);
+
+ auto blk_2 = m->entity()->block()->create();
+ m->block()->append(blk_2);
+
+ ASSERT_EQ(m->block()->head(), blk_1);
+ ASSERT_EQ(m->block()->tail(), blk_2);
+
+ ASSERT_EQ(blk_1->prev(), nullptr);
+ ASSERT_EQ(blk_1->next(), blk_2);
+
+ ASSERT_EQ(blk_2->prev(), blk_1);
+ ASSERT_EQ(blk_2->next(), nullptr);
+
+ ASSERT_EQ(blk_1->index().value(), 0);
+ ASSERT_EQ(blk_2->index().value(), 1);
+}
+
+TEST(IR_MODULE, append_two_instrs)
+{
+ auto m = coco::Module::create();
+
+ auto blk = m->entity()->block()->create();
+ auto ins_1 = m->entity()->instr()->create<coco::Eval>();
+ auto ins_2 = m->entity()->instr()->create<coco::Eval>();
+
+ blk->instr()->append(ins_1);
+ blk->instr()->append(ins_2);
+
+ ASSERT_EQ(blk->instr()->head(), ins_1);
+ ASSERT_EQ(blk->instr()->tail(), ins_2);
+
+ ASSERT_EQ(ins_1->parent(), blk);
+ ASSERT_EQ(ins_1->prev(), nullptr);
+ ASSERT_EQ(ins_1->next(), ins_2);
+
+ ASSERT_EQ(ins_2->parent(), blk);
+ ASSERT_EQ(ins_2->prev(), ins_1);
+ ASSERT_EQ(ins_2->next(), nullptr);
+
+ ASSERT_EQ(ins_1->index().value(), 0);
+ ASSERT_EQ(ins_2->index().value(), 1);
+}
+
+TEST(IR_MODULE, iterate_constant_block)
+{
+ auto m = coco::Module::create();
+ auto blk = m->entity()->block()->create();
+ auto ins_1 = m->entity()->instr()->create<coco::Eval>();
+ auto ins_2 = m->entity()->instr()->create<coco::Eval>();
+
+ blk->instr()->append(ins_1);
+ blk->instr()->append(ins_2);
+
+ const coco::Block *immutable_blk = blk;
+
+ ASSERT_EQ(immutable_blk->instr()->head(), ins_1);
+ ASSERT_EQ(immutable_blk->instr()->head()->next(), ins_2);
+}
+
+TEST(IR_MODULE, input_as_output)
+{
+ // Some NN frameworks allows users to use a network input as its output.
+ //
+ // For example, let us consider the following Caffe network
+ //
+ // name: "example"
+ // layer {
+ // name: "l"
+ // type: "Input"
+ // top: "data"
+ // input_param { shape: { dim: 1 dim: 1 dim: 3 dim: 3 } }
+ // }
+ //
+ // "data" blob is the input of this network, and it is also the output of this network.
+ const nncc::core::ADT::tensor::Shape shape{1, 1, 3, 3};
+
+ auto m = coco::Module::create();
+ auto bag = m->entity()->bag()->create(9);
+
+ auto input = m->entity()->input()->create(shape);
+ auto output = m->entity()->output()->create(shape);
+
+ input->name("data");
+ input->bag(bag);
+
+ output->name("data");
+ output->bag(bag);
+
+ ASSERT_TRUE(bag->isInput());
+ ASSERT_TRUE(bag->isOutput());
+
+ output->bag(nullptr);
+
+ ASSERT_TRUE(bag->isInput());
+ ASSERT_FALSE(bag->isOutput());
+}
+
+/**
+ * This test ensures that IR entities allocated via EntityManager have a correct module link
+ */
+TEST(IR_Module, create_entites)
+{
+ using namespace coco;
+ using namespace nncc::core::ADT;
+
+ auto m = Module::create();
+ auto entity = m->entity();
+
+ ASSERT_EQ(entity->bag()->create(1)->module(), m.get());
+ ASSERT_EQ(entity->object()->create<coco::FeatureObject>()->module(), m.get());
+ ASSERT_EQ(entity->object()->create<coco::KernelObject>()->module(), m.get());
+#define OP(Name) ASSERT_EQ(entity->op()->create<Name>()->module(), m.get());
+#include "coco/IR/Op.lst"
+#undef OP
+#define INSTR(Name) \
+ { \
+ auto ins = entity->instr()->create<Name>(); \
+ ASSERT_EQ(ins->module(), m.get()); \
+ ASSERT_TRUE(coco::isa<Name>(ins)); \
+ ASSERT_NE(coco::safe_cast<Name>(ins), nullptr); \
+ }
+#include "coco/IR/Instr.lst"
+#undef INSTR
+ ASSERT_EQ(entity->block()->create()->module(), m.get());
+ ASSERT_EQ(entity->input()->create(tensor::Shape{1})->module(), m.get());
+ ASSERT_EQ(entity->output()->create(tensor::Shape{1})->module(), m.get());
+}
diff --git a/compiler/coco/core/src/IR/Object.cpp b/compiler/coco/core/src/IR/Object.cpp
new file mode 100644
index 000000000..6a51a61a3
--- /dev/null
+++ b/compiler/coco/core/src/IR/Object.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Object.h"
+#include "coco/IR/Def.h"
+#include "coco/IR/Use.h"
+
+#include <cassert>
+#include <stdexcept>
+
+namespace coco
+{
+
+Object::Object()
+{
+ // Register self to Dep
+ _dep.object(this);
+}
+
+Def *Object::def(void) const { return _def; }
+
+void Object::def(Def *d)
+{
+ // This assert enforces users to explicitly reset def before update.
+ //
+ // Let's consider an object o with def d0.
+ //
+ // The following code is allowed:
+ // o->def(nullptr);
+ // o->def(d1);
+ //
+ // However, the following code is not allowed:
+ // o->def(d1);
+ //
+ assert((_def == nullptr) || (d == nullptr));
+ _def = d;
+}
+
+const UseSet *Object::uses(void) const { return &_uses; }
+UseSet *Object::mutable_uses(void) { return &_uses; }
+
+Object::Producer *producer(const Object *obj)
+{
+ if (auto d = obj->def())
+ {
+ return d->producer();
+ }
+
+ return nullptr;
+}
+
+Object::ConsumerSet consumers(const Object *obj)
+{
+ Object::ConsumerSet res;
+
+ for (const auto &use : *(obj->uses()))
+ {
+ if (auto consumer = use->consumer())
+ {
+ res.insert(consumer);
+ }
+ }
+
+ return res;
+}
+
+/**
+ * Casting Helpers
+ *
+ * TODO Use Macro to reduce code duplication
+ */
+template <> bool isa<FeatureObject>(const Object *o) { return o->asFeature() != nullptr; }
+template <> bool isa<KernelObject>(const Object *o) { return o->asKernel() != nullptr; }
+
+template <> FeatureObject *cast(Object *o)
+{
+ assert(o != nullptr);
+ auto res = o->asFeature();
+ assert(res != nullptr);
+ return res;
+}
+
+template <> KernelObject *cast(Object *o)
+{
+ assert(o != nullptr);
+ auto res = o->asKernel();
+ assert(res != nullptr);
+ return res;
+}
+
+template <> FeatureObject *safe_cast(Object *o)
+{
+ // NOTE o may be nullptr
+ return (o == nullptr) ? nullptr : o->asFeature();
+}
+
+template <> KernelObject *safe_cast(Object *o)
+{
+ // NOTE o may be nullptr
+ return (o == nullptr) ? nullptr : o->asKernel();
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Object.test.cpp b/compiler/coco/core/src/IR/Object.test.cpp
new file mode 100644
index 000000000..2a2e4db23
--- /dev/null
+++ b/compiler/coco/core/src/IR/Object.test.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Object.h"
+#include "coco/IR/BagManager.h"
+
+#include <vector>
+
+#include <gtest/gtest.h>
+
+namespace
+{
+class ObjectTest : public ::testing::Test
+{
+protected:
+ coco::BagManager bag_mgr;
+};
+} // namespace
+
+namespace
+{
+namespace mock
+{
+struct Object : public coco::Object
+{
+public:
+ virtual ~Object() = default;
+};
+} // namespace mock
+} // namespace
+
+TEST_F(ObjectTest, ctor)
+{
+ ::mock::Object obj;
+
+ // Newly created object should not have a backing bag
+ ASSERT_EQ(obj.bag(), nullptr);
+
+ // Newly created object should not have def and uses
+ ASSERT_EQ(obj.def(), nullptr);
+ ASSERT_TRUE(obj.uses()->empty());
+}
+
+TEST_F(ObjectTest, bag_update)
+{
+ // Prepare bag
+ auto bag = bag_mgr.create(1);
+
+ // Test 'Object' class through a mock-up object
+ ::mock::Object obj;
+
+ obj.bag(bag);
+
+ // 'bag(Bag *)' should affect the return of 'bag(void)'
+ ASSERT_EQ(obj.bag(), bag);
+
+ // User SHOULD be able to access dependent objects through 'bag'
+ {
+ auto deps = coco::dependent_objects(bag);
+ ASSERT_EQ(deps.size(), 1);
+ ASSERT_EQ(deps.count(&obj), 1);
+ }
+
+ // Unlink Object-Bag relation
+ obj.bag(nullptr);
+
+ ASSERT_EQ(obj.bag(), nullptr);
+
+ {
+ auto deps = coco::dependent_objects(bag);
+ ASSERT_EQ(deps.size(), 0);
+ }
+}
+
+TEST_F(ObjectTest, destructor)
+{
+ auto bag = bag_mgr.create(1);
+
+ // Destruct Object after proper initialization
+ {
+ ::mock::Object obj;
+
+ obj.bag(bag);
+ }
+
+ // Object SHOULD be unlinked from Bag on destruction
+ {
+ auto deps = coco::dependent_objects(bag);
+ ASSERT_EQ(deps.size(), 0);
+ }
+}
+
+TEST_F(ObjectTest, safe_cast)
+{
+ ASSERT_EQ(coco::safe_cast<coco::FeatureObject>(nullptr), nullptr);
+ ASSERT_EQ(coco::safe_cast<coco::KernelObject>(nullptr), nullptr);
+}
diff --git a/compiler/coco/core/src/IR/ObjectManager.cpp b/compiler/coco/core/src/IR/ObjectManager.cpp
new file mode 100644
index 000000000..1b7215a04
--- /dev/null
+++ b/compiler/coco/core/src/IR/ObjectManager.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/ObjectManager.h"
+
+#include "coco/IR/FeatureObject.h"
+#include "coco/IR/KernelObject.h"
+
+#include <stdex/Memory.h>
+
+#include <cassert>
+
+using stdex::make_unique;
+
+namespace coco
+{
+
+template <> FeatureObject *ObjectManager::create(void)
+{
+ auto feature = make_unique<FeatureObject>();
+ modulize(feature.get());
+ return take(std::move(feature));
+}
+
+template <> KernelObject *ObjectManager::create(void)
+{
+ auto kernel = make_unique<KernelObject>();
+ modulize(kernel.get());
+ return take(std::move(kernel));
+}
+
+void ObjectManager::destroy(Object *o)
+{
+ assert(o->def() == nullptr);
+ assert(o->uses()->size() == 0);
+ release(o);
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/ObjectManager.test.cpp b/compiler/coco/core/src/IR/ObjectManager.test.cpp
new file mode 100644
index 000000000..781775f25
--- /dev/null
+++ b/compiler/coco/core/src/IR/ObjectManager.test.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/ObjectManager.h"
+#include "coco/IR/BagManager.h"
+
+#include "coco/IR/FeatureObject.h"
+#include "coco/IR/KernelObject.h"
+
+#include <gtest/gtest.h>
+
+TEST(IR_OBJECT_MANAGER, create_feature_with_template)
+{
+ coco::ObjectManager mgr;
+
+ auto feature = mgr.create<coco::FeatureObject>();
+
+ ASSERT_EQ(feature->layout(), nullptr);
+}
+
+TEST(IR_OBJECT_MANAGER, create_kernel_with_template)
+{
+ coco::ObjectManager mgr;
+
+ auto kernel = mgr.create<coco::KernelObject>();
+
+ ASSERT_EQ(kernel->layout(), nullptr);
+}
+
+TEST(IR_OBJECT_MANAGER, destroy)
+{
+ coco::BagManager bag_mgr;
+ coco::ObjectManager obj_mgr;
+
+ auto bag = bag_mgr.create(3);
+ auto feature = obj_mgr.create<coco::FeatureObject>();
+
+ feature->bag(bag);
+
+ obj_mgr.destroy(feature);
+
+ // Object SHOULD BE unlinked from its dependent bag on destruction
+ ASSERT_EQ(bag->deps()->size(), 0);
+}
diff --git a/compiler/coco/core/src/IR/Op.cpp b/compiler/coco/core/src/IR/Op.cpp
new file mode 100644
index 000000000..d3808a9d6
--- /dev/null
+++ b/compiler/coco/core/src/IR/Op.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Op.h"
+#include "coco/IR/Step.h"
+#include "coco/IR/Part.h"
+
+#include <pepper/assert.h>
+
+namespace coco
+{
+Op::~Op()
+{
+ // NOTE Op SHOULD NOT be referred by an instruction to be destructed
+ assert(_step == nullptr);
+}
+
+Instr *Op::parent(void) const
+{
+ // Get the parent instruction specified by _step for root nodes
+ if (_step)
+ {
+ // Op SHOULD BE a root node
+ assert(_part == nullptr);
+ assert(_step->instr() != nullptr);
+ return _step->instr();
+ }
+
+ // Get the parent instruction of its parent Op for non-root nodes
+ if (_part)
+ {
+ assert(_part->parent() != nullptr);
+ return _part->parent()->parent();
+ }
+
+ return nullptr;
+}
+
+Op *Op::up(void) const
+{
+ if (_part)
+ {
+ assert(_part->parent() != nullptr);
+ return _part->parent();
+ }
+ return nullptr;
+}
+
+//
+// UnaryOP trait
+//
+UnaryOp::UnaryOp() : _arg{this}
+{
+ // DO NOTHING
+}
+
+uint32_t UnaryOp::arity(void) const
+{
+ // There is only one argument
+ return 1;
+}
+
+Op *UnaryOp::arg(DBGARG(uint32_t, n)) const
+{
+ assert(n < 1);
+ return arg();
+}
+
+std::set<Object *> UnaryOp::uses(void) const
+{
+ std::set<Object *> res;
+
+ if (auto ifm = arg())
+ {
+ for (auto obj : ifm->uses())
+ {
+ res.insert(obj);
+ }
+ }
+
+ return res;
+}
+
+//
+// BinaryOp trait
+//
+BinaryOp::BinaryOp() : _left{this}, _right{this}
+{
+ // DO NOTHING
+}
+
+uint32_t BinaryOp::arity(void) const
+{
+ // There are two arguments
+ return 2;
+}
+
+Op *BinaryOp::arg(uint32_t n) const
+{
+ assert(n < arity());
+
+ return (n == 0) ? left() : right();
+}
+
+std::set<Object *> BinaryOp::uses(void) const
+{
+ std::set<Object *> res;
+
+ if (auto l = left())
+ {
+ for (auto obj : l->uses())
+ {
+ res.insert(obj);
+ }
+ }
+
+ if (auto r = right())
+ {
+ for (auto obj : r->uses())
+ {
+ res.insert(obj);
+ }
+ }
+
+ return res;
+}
+
+//
+// Additional Helpers
+//
+Op *root(Op *cur)
+{
+ while (cur->up())
+ {
+ cur = cur->up();
+ }
+ return cur;
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/OpManager.cpp b/compiler/coco/core/src/IR/OpManager.cpp
new file mode 100644
index 000000000..c87b704fe
--- /dev/null
+++ b/compiler/coco/core/src/IR/OpManager.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/OpManager.h"
+
+#include <stdex/Memory.h>
+
+#include <cassert>
+#include <queue>
+#include <set>
+
+using stdex::make_unique;
+
+namespace coco
+{
+
+OpManager::~OpManager()
+{
+ std::set<coco::Op *> roots;
+
+ for (uint32_t n = 0; n < size(); ++n)
+ {
+ auto op = at(n);
+
+ if (op->up() != nullptr)
+ {
+ continue;
+ }
+
+ roots.insert(op);
+ }
+
+ for (const auto &op : roots)
+ {
+ destroy_all(op);
+ }
+}
+
+//
+// Each Op class SHOULD be default constructible
+//
+#define OP(Name) \
+ template <> Name *OpManager::create<Name>(void) \
+ { \
+ auto op = make_unique<Name>(); \
+ modulize(op.get()); \
+ return take(std::move(op)); \
+ }
+#include "coco/IR/Op.lst"
+#undef OP
+
+void OpManager::destroy(Op *op)
+{
+ assert(op->parent() == nullptr);
+ release(op);
+}
+
+void OpManager::destroy_all(Op *op)
+{
+ assert(op->parent() == nullptr);
+ assert(op->up() == nullptr);
+
+ std::queue<coco::Op *> q;
+
+ q.emplace(op);
+
+ while (q.size() > 0)
+ {
+ auto cur = q.front();
+ q.pop();
+
+ // Insert child op nodes
+ for (uint32_t n = 0; n < cur->arity(); ++n)
+ {
+ if (auto child = cur->arg(n))
+ {
+ q.emplace(child);
+ }
+ }
+
+ // Destroy the current op node
+ destroy(cur);
+ }
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/OpManager.test.cpp b/compiler/coco/core/src/IR/OpManager.test.cpp
new file mode 100644
index 000000000..9d463b3e4
--- /dev/null
+++ b/compiler/coco/core/src/IR/OpManager.test.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/OpManager.h"
+
+#include <gtest/gtest.h>
+
+namespace
+{
+
+class OpManagerTest : public ::testing::Test
+{
+protected:
+ coco::OpManager mgr;
+};
+
+} // namespace
+
+TEST(IR_OP_MANAGER, create_Conv2D)
+{
+ coco::OpManager mgr;
+
+ auto obj = mgr.create<coco::Conv2D>();
+
+ ASSERT_NE(obj, nullptr);
+}
+
+TEST(IR_OP_MANAGER, create_AvgPool2D)
+{
+ coco::OpManager mgr;
+
+ auto obj = mgr.create<coco::AvgPool2D>();
+
+ ASSERT_NE(obj, nullptr);
+}
+
+TEST_F(OpManagerTest, ReLU)
+{
+ auto obj = mgr.create<coco::ReLU>();
+
+ ASSERT_NE(obj, nullptr);
+}
+
+TEST_F(OpManagerTest, ReLU6)
+{
+ auto obj = mgr.create<coco::ReLU6>();
+
+ ASSERT_NE(obj, nullptr);
+}
+
+TEST_F(OpManagerTest, Sqrt)
+{
+ auto obj = mgr.create<coco::Sqrt>();
+
+ ASSERT_NE(obj, nullptr);
+}
+
+TEST_F(OpManagerTest, Sub)
+{
+ auto obj = mgr.create<coco::Sub>();
+
+ ASSERT_NE(obj, nullptr);
+}
+
+TEST_F(OpManagerTest, Div)
+{
+ auto obj = mgr.create<coco::Div>();
+
+ ASSERT_NE(obj, nullptr);
+}
+
+TEST_F(OpManagerTest, PadF)
+{
+ auto op = mgr.create<coco::PadF>();
+ ASSERT_NE(op, nullptr);
+ mgr.destroy(op);
+}
+
+TEST_F(OpManagerTest, destroy)
+{
+ auto op = mgr.create<coco::Conv2D>();
+ mgr.destroy(op);
+ ASSERT_EQ(mgr.size(), 0);
+}
+
+TEST_F(OpManagerTest, destroy_all)
+{
+ // Create a Op tree
+ auto load_op = mgr.create<coco::Load>();
+ auto conv_op = mgr.create<coco::Conv2D>();
+
+ conv_op->arg(load_op);
+
+ mgr.destroy_all(conv_op);
+
+ ASSERT_EQ(mgr.size(), 0);
+}
+
+TEST_F(OpManagerTest, destroy_all_partial_tree)
+{
+ // Create a (partial) Op tree
+ auto conv_op = mgr.create<coco::Conv2D>();
+
+ mgr.destroy_all(conv_op);
+
+ ASSERT_EQ(mgr.size(), 0);
+}
diff --git a/compiler/coco/core/src/IR/Ops.cpp b/compiler/coco/core/src/IR/Ops.cpp
new file mode 100644
index 000000000..1c1ef5d28
--- /dev/null
+++ b/compiler/coco/core/src/IR/Ops.cpp
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Ops.h"
+
+namespace coco
+{
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Ops.test.cpp b/compiler/coco/core/src/IR/Ops.test.cpp
new file mode 100644
index 000000000..ae979b2bf
--- /dev/null
+++ b/compiler/coco/core/src/IR/Ops.test.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Ops.h"
+#include "coco/IR/ObjectManager.h"
+#include "coco/IR/OpManager.h"
+
+#include <vector>
+#include <memory>
+
+#include <stdex/Memory.h>
+
+#include <gtest/gtest.h>
+
+using stdex::make_unique;
+
+/**
+ * Section: Add Op
+ */
+namespace
+{
+
+class AddTest : public ::testing::Test
+{
+public:
+ AddTest()
+ {
+ // DO NOTHING
+ }
+
+protected:
+ coco::Add *allocate(void)
+ {
+ auto op = new coco::Add;
+ _allocated.emplace_back(op);
+ return op;
+ }
+
+protected:
+ coco::ObjectManager obj_mgr;
+
+private:
+ std::vector<std::unique_ptr<coco::Op>> _allocated;
+};
+
+} // namespace
+
+TEST_F(AddTest, constructor)
+{
+ auto op = allocate();
+
+ ASSERT_EQ(op->left(), nullptr);
+ ASSERT_EQ(op->right(), nullptr);
+}
+
+/**
+ * Section: Mul Op
+ */
+TEST(MulTest, constructor)
+{
+ auto op = make_unique<coco::Mul>();
+
+ ASSERT_EQ(op->left(), nullptr);
+ ASSERT_EQ(op->right(), nullptr);
+}
+
+/**
+ * Section: Div Op
+ */
+TEST(DivTest, constructor)
+{
+ auto op = make_unique<coco::Div>();
+
+ ASSERT_EQ(op->left(), nullptr);
+ ASSERT_EQ(op->right(), nullptr);
+}
+
+/**
+ * Section: Op Helpers
+ */
+namespace
+{
+
+class OpHelperTest : public ::testing::Test
+{
+public:
+ OpHelperTest()
+ {
+ // DO NOTHING
+ }
+
+protected:
+ template <typename Op> Op *allocate(void) { return op_mgr.create<Op>(); }
+
+protected:
+ coco::ObjectManager obj_mgr;
+
+private:
+ coco::OpManager op_mgr;
+};
+
+} // namespace
+
+TEST_F(OpHelperTest, root)
+{
+ auto load = allocate<coco::Load>();
+
+ ASSERT_EQ(root(load), load);
+
+ auto avgpool = allocate<coco::AvgPool2D>();
+
+ avgpool->arg(load);
+
+ ASSERT_EQ(root(load), avgpool);
+ ASSERT_EQ(root(avgpool), avgpool);
+}
diff --git a/compiler/coco/core/src/IR/Output.cpp b/compiler/coco/core/src/IR/Output.cpp
new file mode 100644
index 000000000..7b6d1870b
--- /dev/null
+++ b/compiler/coco/core/src/IR/Output.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Output.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+Output::Output(const nncc::core::ADT::tensor::Shape &shape) : Arg{shape}
+{
+ // DO NOTHING
+}
+
+void Output::onTake(Bag *bag)
+{
+ assert(bag->output() == nullptr);
+ bag->output(this);
+}
+
+void Output::onRelease(Bag *bag)
+{
+ assert(bag->output() == this);
+ bag->output(nullptr);
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Output.test.cpp b/compiler/coco/core/src/IR/Output.test.cpp
new file mode 100644
index 000000000..715a83875
--- /dev/null
+++ b/compiler/coco/core/src/IR/Output.test.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Output.h"
+#include "coco/IR/BagManager.h"
+
+#include <nncc/core/ADT/tensor/IndexEnumerator.h>
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::tensor::Shape;
+using nncc::core::ADT::tensor::IndexEnumerator;
+
+TEST(IR_OUTPUT, ctor_should_set_shape)
+{
+ const nncc::core::ADT::tensor::Shape shape{1, 3, 3, 1};
+ coco::Output output{shape};
+
+ ASSERT_EQ(output.shape(), shape);
+}
+
+TEST(IR_OUTPUT, bag_update)
+{
+ // Create a bag for test
+ coco::BagManager bag_mgr;
+
+ auto bag = bag_mgr.create(9);
+
+ const nncc::core::ADT::tensor::Shape shape{1, 3, 3, 1};
+ coco::Output output{shape};
+
+ output.bag(bag);
+ ASSERT_EQ(output.bag(), bag);
+
+ // bag(...) method SHOULD update 'bag' type
+ ASSERT_TRUE(bag->isOutput());
+
+ output.bag(nullptr);
+
+ // bag(nullptr) SHOULD revert 'bag' type
+ ASSERT_FALSE(bag->isOutput());
+}
+
+TEST(IR_OUTPUT, name_update)
+{
+ const nncc::core::ADT::tensor::Shape shape{1, 3, 3, 1};
+ coco::Output output{shape};
+
+ output.name("softmax");
+ ASSERT_EQ(output.name(), "softmax");
+}
+
+TEST(IR_OUTPUT, at)
+{
+ const Shape shape{1, 3, 3, 1};
+ coco::Output input{shape};
+
+ coco::Output *mutable_ptr = &input;
+ const coco::Output *immutable_ptr = &input;
+
+ for (IndexEnumerator e{shape}; e.valid(); e.advance())
+ {
+ mutable_ptr->at(e.current()) = coco::ElemID{16};
+ }
+
+ for (IndexEnumerator e{shape}; e.valid(); e.advance())
+ {
+ ASSERT_EQ(immutable_ptr->at(e.current()).value(), 16);
+ }
+}
diff --git a/compiler/coco/core/src/IR/OutputManager.cpp b/compiler/coco/core/src/IR/OutputManager.cpp
new file mode 100644
index 000000000..86b9580ac
--- /dev/null
+++ b/compiler/coco/core/src/IR/OutputManager.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/OutputManager.h"
+
+#include <stdex/Memory.h>
+
+namespace coco
+{
+
+Output *OutputManager::create(const nncc::core::ADT::tensor::Shape &shape)
+{
+ auto output = stdex::make_unique<Output>(shape);
+ modulize(output.get());
+ return take(std::move(output));
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/OutputManager.test.cpp b/compiler/coco/core/src/IR/OutputManager.test.cpp
new file mode 100644
index 000000000..80b38b42c
--- /dev/null
+++ b/compiler/coco/core/src/IR/OutputManager.test.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/OutputManager.h"
+
+#include <gtest/gtest.h>
+
+TEST(IR_OUTPUT_MANAGER, make)
+{
+ coco::OutputManager mgr;
+
+ const nncc::core::ADT::tensor::Shape shape{1, 3, 3, 1};
+ auto output = mgr.create(shape);
+
+ ASSERT_EQ(output->shape(), shape);
+}
diff --git a/compiler/coco/core/src/IR/PadF.test.cpp b/compiler/coco/core/src/IR/PadF.test.cpp
new file mode 100644
index 000000000..b443d86fb
--- /dev/null
+++ b/compiler/coco/core/src/IR/PadF.test.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Ops.h"
+
+#include <memory>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+namespace
+{
+struct IsPadF : public coco::Op::Visitor<bool>
+{
+ bool visit(const coco::PadF *) override { return true; }
+};
+
+class PadFTest : public ::testing::Test
+{
+public:
+ PadFTest()
+ {
+ // DO NOTHING
+ }
+
+protected:
+ coco::PadF *allocate(void)
+ {
+ auto op = new coco::PadF;
+ _allocated.emplace_back(op);
+ return op;
+ }
+
+private:
+ std::vector<std::unique_ptr<coco::PadF>> _allocated;
+};
+} // namespace
+
+TEST_F(PadFTest, initialization)
+{
+ auto op = allocate();
+
+ // uses() should be empty on construction
+ ASSERT_EQ(op->uses().size(), 0);
+ // parent() should be nullptr on construction
+ ASSERT_EQ(op->parent(), nullptr);
+
+ // arg() should be nullptr on construction
+ ASSERT_EQ(op->arg(), nullptr);
+
+ // pad() should be a valid
+ ASSERT_NE(op->pad(), nullptr);
+}
+
+TEST_F(PadFTest, asPadF)
+{
+ auto op = allocate();
+
+ coco::Op *mutable_base = op;
+ const coco::Op *immutable_base = op;
+
+ ASSERT_EQ(mutable_base->asPadF(), op);
+ ASSERT_EQ(mutable_base->asPadF(), immutable_base->asPadF());
+}
+
+TEST_F(PadFTest, accept)
+{
+ // Test 'PadF' class
+ auto op = allocate();
+
+ coco::PadF *mutable_ptr = op;
+ const coco::PadF *immutable_ptr = op;
+
+ ASSERT_TRUE(mutable_ptr->accept(IsPadF{}));
+ ASSERT_TRUE(immutable_ptr->accept(IsPadF{}));
+}
diff --git a/compiler/coco/core/src/IR/Padding2D.cpp b/compiler/coco/core/src/IR/Padding2D.cpp
new file mode 100644
index 000000000..8cdc42638
--- /dev/null
+++ b/compiler/coco/core/src/IR/Padding2D.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Padding2D.h"
+
+namespace coco
+{
+
+Padding2D &Padding2D::top(uint32_t value)
+{
+ _top = value;
+ return (*this);
+}
+
+Padding2D &Padding2D::bottom(uint32_t value)
+{
+ _bottom = value;
+ return (*this);
+}
+
+Padding2D &Padding2D::left(uint32_t value)
+{
+ _left = value;
+ return (*this);
+}
+
+Padding2D &Padding2D::right(uint32_t value)
+{
+ _right = value;
+ return (*this);
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Padding2D.test.cpp b/compiler/coco/core/src/IR/Padding2D.test.cpp
new file mode 100644
index 000000000..292ce7d17
--- /dev/null
+++ b/compiler/coco/core/src/IR/Padding2D.test.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Padding2D.h"
+
+#include <gtest/gtest.h>
+
+TEST(IR_PADDING, default_constructor)
+{
+ coco::Padding2D pad;
+
+ ASSERT_EQ(pad.top(), 0);
+ ASSERT_EQ(pad.bottom(), 0);
+ ASSERT_EQ(pad.left(), 0);
+ ASSERT_EQ(pad.right(), 0);
+}
+
+TEST(IR_PADDING, explicit_constructor_4)
+{
+ coco::Padding2D pad{1, 2, 3, 4};
+
+ ASSERT_EQ(pad.top(), 1);
+ ASSERT_EQ(pad.bottom(), 2);
+ ASSERT_EQ(pad.left(), 3);
+ ASSERT_EQ(pad.right(), 4);
+}
+
+TEST(IR_PADDING, update)
+{
+ coco::Padding2D pad;
+
+ pad.top(1).bottom(2).left(3).right(4);
+
+ ASSERT_EQ(pad.top(), 1);
+ ASSERT_EQ(pad.bottom(), 2);
+ ASSERT_EQ(pad.left(), 3);
+ ASSERT_EQ(pad.right(), 4);
+}
diff --git a/compiler/coco/core/src/IR/Part.cpp b/compiler/coco/core/src/IR/Part.cpp
new file mode 100644
index 000000000..bf68c1feb
--- /dev/null
+++ b/compiler/coco/core/src/IR/Part.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Part.h"
+#include "coco/IR/Op.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+void Part::child(Op *c)
+{
+ if (_child != nullptr)
+ {
+ assert(_child->_part == this);
+ _child->_part = nullptr;
+ _child = nullptr;
+ }
+
+ assert(_child == nullptr);
+
+ if (c != nullptr)
+ {
+ assert(c->_part == nullptr);
+ assert(c->_step == nullptr);
+ _child = c;
+ _child->_part = this;
+ }
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Part.test.cpp b/compiler/coco/core/src/IR/Part.test.cpp
new file mode 100644
index 000000000..87e0e1516
--- /dev/null
+++ b/compiler/coco/core/src/IR/Part.test.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Part.h"
+#include "coco/IR/Op.h"
+
+#include <stdex/Memory.h>
+
+#include <gtest/gtest.h>
+
+using stdex::make_unique;
+
+namespace
+{
+namespace mock
+{
+
+// TODO Inherit UnaryOp instead of Op
+struct Op final : public coco::Op
+{
+public:
+ Op() : _arg{this}
+ {
+ // DO NOTHING
+ }
+
+public:
+ uint32_t arity(void) const final { return 1; }
+ coco::Op *arg(uint32_t n) const final { return arg(); }
+
+ std::set<coco::Object *> uses() const override { throw std::runtime_error{"Not supported"}; }
+
+public:
+ ::coco::Op *arg(void) const { return _arg.child(); }
+ void arg(::coco::Op *child) { _arg.child(child); }
+
+private:
+ coco::Part _arg;
+};
+
+} // namespace mock
+} // namespace
+
+TEST(PartTest, destructor)
+{
+ auto parent = make_unique<::mock::Op>();
+ auto child = make_unique<::mock::Op>();
+
+ parent->arg(child.get());
+ ASSERT_EQ(parent->arg(), child.get());
+ ASSERT_EQ(child->up(), parent.get());
+
+ parent.reset();
+
+ // NOTE parent SHOULD unlink itself from child on destruction
+ ASSERT_EQ(child->up(), nullptr);
+}
diff --git a/compiler/coco/core/src/IR/Producer.mock.h b/compiler/coco/core/src/IR/Producer.mock.h
new file mode 100644
index 000000000..ffc343ee8
--- /dev/null
+++ b/compiler/coco/core/src/IR/Producer.mock.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_PRODUCER_MOCK_H__
+#define __COCO_IR_PRODUCER_MOCK_H__
+
+#include "coco/IR/Object.h"
+
+namespace
+{
+namespace mock
+{
+struct Producer final : public coco::Object::Producer
+{
+ coco::Instr *loc(void) override { return nullptr; }
+};
+} // namespace mock
+} // namespace
+
+#endif // __COCO_IR_PRODUCER_MOCK_H__
diff --git a/compiler/coco/core/src/IR/ReLU.test.cpp b/compiler/coco/core/src/IR/ReLU.test.cpp
new file mode 100644
index 000000000..22ef1730e
--- /dev/null
+++ b/compiler/coco/core/src/IR/ReLU.test.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Ops.h"
+
+#include <memory>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+namespace
+{
+struct IsReLU : public coco::Op::Visitor<bool>
+{
+ bool visit(const coco::ReLU *) override { return true; }
+};
+
+class ReLUTest : public ::testing::Test
+{
+public:
+ ReLUTest()
+ {
+ // DO NOTHING
+ }
+
+protected:
+ coco::ReLU *allocate(void)
+ {
+ auto op = new coco::ReLU;
+ _allocated.emplace_back(op);
+ return op;
+ }
+
+private:
+ std::vector<std::unique_ptr<coco::ReLU>> _allocated;
+};
+} // namespace
+
+TEST_F(ReLUTest, initialization)
+{
+ auto op = allocate();
+
+ // uses() should be empty on construction
+ ASSERT_EQ(op->uses().size(), 0);
+ // parent() should be nullptr on construction
+ ASSERT_EQ(op->parent(), nullptr);
+
+ ASSERT_EQ(op->arg(), nullptr);
+}
+
+TEST_F(ReLUTest, asReLU)
+{
+ auto op = allocate();
+
+ coco::Op *mutable_base = op;
+ const coco::Op *immutable_base = op;
+
+ ASSERT_EQ(mutable_base->asReLU(), op);
+ ASSERT_EQ(mutable_base->asReLU(), immutable_base->asReLU());
+}
+
+TEST_F(ReLUTest, accept)
+{
+ // Test 'ReLU' class
+ auto op = allocate();
+
+ coco::ReLU *mutable_ptr = op;
+ const coco::ReLU *immutable_ptr = op;
+
+ ASSERT_TRUE(mutable_ptr->accept(IsReLU{}));
+ ASSERT_TRUE(immutable_ptr->accept(IsReLU{}));
+}
diff --git a/compiler/coco/core/src/IR/ReLU6.test.cpp b/compiler/coco/core/src/IR/ReLU6.test.cpp
new file mode 100644
index 000000000..dd148254f
--- /dev/null
+++ b/compiler/coco/core/src/IR/ReLU6.test.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Ops.h"
+
+#include <memory>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+namespace
+{
+struct IsReLU6 : public coco::Op::Visitor<bool>
+{
+ bool visit(const coco::ReLU6 *) override { return true; }
+};
+
+class ReLU6Test : public ::testing::Test
+{
+public:
+ ReLU6Test()
+ {
+ // DO NOTHING
+ }
+
+protected:
+ coco::ReLU6 *allocate(void)
+ {
+ auto op = new coco::ReLU6;
+ _allocated.emplace_back(op);
+ return op;
+ }
+
+private:
+ std::vector<std::unique_ptr<coco::ReLU6>> _allocated;
+};
+} // namespace
+
+TEST_F(ReLU6Test, initialization)
+{
+ auto op = allocate();
+
+ // uses() should be empty on construction
+ ASSERT_EQ(op->uses().size(), 0);
+ // parent() should be nullptr on construction
+ ASSERT_EQ(op->parent(), nullptr);
+
+ ASSERT_EQ(op->arg(), nullptr);
+}
+
+TEST_F(ReLU6Test, asReLU6)
+{
+ auto op = allocate();
+
+ coco::Op *mutable_base = op;
+ const coco::Op *immutable_base = op;
+
+ ASSERT_EQ(mutable_base->asReLU6(), op);
+ ASSERT_EQ(mutable_base->asReLU6(), immutable_base->asReLU6());
+}
+
+TEST_F(ReLU6Test, accept)
+{
+ // Test 'ReLU6' class
+ auto op = allocate();
+
+ coco::ReLU6 *mutable_ptr = op;
+ const coco::ReLU6 *immutable_ptr = op;
+
+ ASSERT_TRUE(mutable_ptr->accept(IsReLU6{}));
+ ASSERT_TRUE(immutable_ptr->accept(IsReLU6{}));
+}
diff --git a/compiler/coco/core/src/IR/Read.cpp b/compiler/coco/core/src/IR/Read.cpp
new file mode 100644
index 000000000..ea01cce1d
--- /dev/null
+++ b/compiler/coco/core/src/IR/Read.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Read.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+Read::~Read()
+{
+ // Unlink self from Bag if there is a linked bag
+ bag(nullptr);
+}
+
+void Read::bag(Bag *bag)
+{
+ if (_bag)
+ {
+ _bag->mutable_reads()->erase(this);
+ _bag = nullptr;
+ }
+
+ assert(_bag == nullptr);
+
+ if (bag)
+ {
+ _bag = bag;
+ _bag->mutable_reads()->insert(this);
+ }
+
+ assert(_bag == bag);
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Read.test.cpp b/compiler/coco/core/src/IR/Read.test.cpp
new file mode 100644
index 000000000..7c36820a6
--- /dev/null
+++ b/compiler/coco/core/src/IR/Read.test.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Read.h"
+#include "coco/IR/BagManager.h"
+
+#include "Reader.mock.h"
+
+#include <gtest/gtest.h>
+
+namespace
+{
+class ReadTest : public ::testing::Test
+{
+protected:
+ coco::BagManager bag_mgr;
+};
+} // namespace
+
+TEST_F(ReadTest, constructor)
+{
+ // TODO Rename 'read' as 'reader'
+ ::mock::Reader read;
+
+ // TODO Rename 'slot'
+ coco::Read slot{&read};
+
+ ASSERT_EQ(slot.bag(), nullptr);
+}
+
+TEST_F(ReadTest, value)
+{
+ // TODO Rename 'read' as 'reader'
+ ::mock::Reader read;
+
+ // TODO Rename 'slot'
+ coco::Read slot{&read};
+
+ auto bag = bag_mgr.create(16);
+
+ slot.bag(bag);
+
+ ASSERT_EQ(slot.bag(), bag);
+
+ ASSERT_EQ(bag->reads()->size(), 1);
+ ASSERT_NE(bag->reads()->find(&slot), bag->reads()->end());
+
+ slot.bag(nullptr);
+
+ ASSERT_EQ(slot.bag(), nullptr);
+
+ ASSERT_EQ(bag->reads()->size(), 0);
+}
+
+TEST_F(ReadTest, unlink_on_destruction)
+{
+ // TODO Rename 'read' as 'reader'
+ ::mock::Reader reader;
+
+ auto bag = bag_mgr.create(1);
+
+ {
+ coco::Read read{&reader};
+ read.bag(bag);
+ }
+
+ ASSERT_EQ(bag->reads()->size(), 0);
+}
diff --git a/compiler/coco/core/src/IR/Reader.mock.h b/compiler/coco/core/src/IR/Reader.mock.h
new file mode 100644
index 000000000..0965abfeb
--- /dev/null
+++ b/compiler/coco/core/src/IR/Reader.mock.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_READER_MOCK_H__
+#define __COCO_IR_READER_MOCK_H__
+
+#include "coco/IR/Bag.h"
+
+namespace
+{
+namespace mock
+{
+struct Reader final : public coco::Bag::Reader
+{
+ coco::Instr *loc(void) override { return nullptr; }
+};
+} // namespace mock
+} // namespace
+
+#endif // __COCO_IR_READER_MOCK_H__
diff --git a/compiler/coco/core/src/IR/Shuffle.cpp b/compiler/coco/core/src/IR/Shuffle.cpp
new file mode 100644
index 000000000..f8007dd1b
--- /dev/null
+++ b/compiler/coco/core/src/IR/Shuffle.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Instrs.h"
+
+namespace coco
+{
+
+uint32_t Shuffle::size(void) const { return _content.size(); }
+
+std::set<ElemID> Shuffle::range(void) const
+{
+ std::set<ElemID> res;
+
+ for (auto it = _content.begin(); it != _content.end(); ++it)
+ {
+ res.insert(it->first);
+ }
+
+ return res;
+}
+
+void Shuffle::insert(const ElemID &from, const ElemID &into) { _content[into] = from; }
+
+void Shuffle::from(Bag *b) { _from.bag(b); }
+void Shuffle::into(Bag *b) { _into.bag(b); }
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Shuffle.test.cpp b/compiler/coco/core/src/IR/Shuffle.test.cpp
new file mode 100644
index 000000000..f564c08c3
--- /dev/null
+++ b/compiler/coco/core/src/IR/Shuffle.test.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Instrs.h"
+#include "coco/IR/ObjectManager.h"
+#include "coco/IR/OpManager.h"
+
+#include <gtest/gtest.h>
+
+namespace
+{
+class ShuffleTest : public ::testing::Test
+{
+public:
+ virtual ~ShuffleTest() = default;
+
+protected:
+ coco::Shuffle *allocate(void)
+ {
+ auto ins = new coco::Shuffle;
+ _allocated.emplace_back(ins);
+ return ins;
+ }
+
+private:
+ std::vector<std::unique_ptr<coco::Instr>> _allocated;
+};
+} // namespace
+
+TEST_F(ShuffleTest, constructor)
+{
+ auto ins = allocate();
+
+ ASSERT_EQ(ins->from(), nullptr);
+ ASSERT_EQ(ins->into(), nullptr);
+}
+
+TEST_F(ShuffleTest, asShuffle)
+{
+ auto ins = allocate();
+
+ coco::Instr *mutable_ptr = ins;
+ const coco::Instr *immutable_ptr = ins;
+
+ ASSERT_NE(mutable_ptr->asShuffle(), nullptr);
+ ASSERT_EQ(mutable_ptr->asShuffle(), immutable_ptr->asShuffle());
+}
+
+TEST_F(ShuffleTest, size)
+{
+ auto shuffle = allocate();
+
+ shuffle->insert(coco::ElemID{3}, coco::ElemID{2});
+ shuffle->insert(coco::ElemID{3}, coco::ElemID{5});
+
+ ASSERT_EQ(shuffle->size(), 2);
+ ASSERT_EQ(shuffle->range().size(), shuffle->size());
+}
+
+TEST_F(ShuffleTest, range)
+{
+ auto shuffle = allocate();
+
+ shuffle->insert(coco::ElemID{3}, coco::ElemID{2});
+ shuffle->insert(coco::ElemID{3}, coco::ElemID{5});
+
+ auto range = shuffle->range();
+
+ EXPECT_EQ(range.size(), 2);
+ EXPECT_NE(range.count(coco::ElemID{2}), 0);
+ EXPECT_NE(range.count(coco::ElemID{5}), 0);
+}
+
+TEST_F(ShuffleTest, defined)
+{
+ auto shuffle = allocate();
+
+ shuffle->insert(coco::ElemID{3}, coco::ElemID{2});
+
+ EXPECT_TRUE(shuffle->defined(coco::ElemID{2}));
+ EXPECT_FALSE(shuffle->defined(coco::ElemID{3}));
+}
diff --git a/compiler/coco/core/src/IR/Sqrt.test.cpp b/compiler/coco/core/src/IR/Sqrt.test.cpp
new file mode 100644
index 000000000..cf9b232ea
--- /dev/null
+++ b/compiler/coco/core/src/IR/Sqrt.test.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Ops.h"
+
+#include <memory>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+namespace
+{
+struct IsSqrt : public coco::Op::Visitor<bool>
+{
+ bool visit(const coco::Sqrt *) override { return true; }
+};
+
+class SqrtTest : public ::testing::Test
+{
+public:
+ SqrtTest()
+ {
+ // DO NOTHING
+ }
+
+protected:
+ coco::Sqrt *allocate(void)
+ {
+ auto op = new coco::Sqrt;
+ _allocated.emplace_back(op);
+ return op;
+ }
+
+private:
+ std::vector<std::unique_ptr<coco::Sqrt>> _allocated;
+};
+} // namespace
+
+TEST_F(SqrtTest, initialization)
+{
+ auto op = allocate();
+
+ // uses() should be empty on construction
+ ASSERT_EQ(op->uses().size(), 0);
+ // parent() should be nullptr on construction
+ ASSERT_EQ(op->parent(), nullptr);
+
+ ASSERT_EQ(op->arg(), nullptr);
+}
+
+TEST_F(SqrtTest, asSqrt)
+{
+ auto op = allocate();
+
+ coco::Op *mutable_base = op;
+ const coco::Op *immutable_base = op;
+
+ ASSERT_EQ(mutable_base->asSqrt(), op);
+ ASSERT_EQ(mutable_base->asSqrt(), immutable_base->asSqrt());
+}
+
+TEST_F(SqrtTest, accept)
+{
+ // Test 'Sqrt' class
+ auto op = allocate();
+
+ coco::Sqrt *mutable_ptr = op;
+ const coco::Sqrt *immutable_ptr = op;
+
+ ASSERT_TRUE(mutable_ptr->accept(IsSqrt{}));
+ ASSERT_TRUE(immutable_ptr->accept(IsSqrt{}));
+}
diff --git a/compiler/coco/core/src/IR/Step.cpp b/compiler/coco/core/src/IR/Step.cpp
new file mode 100644
index 000000000..04400d46b
--- /dev/null
+++ b/compiler/coco/core/src/IR/Step.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Step.h"
+#include "coco/IR/Op.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+void Step::op(Op *o)
+{
+ if (_op != nullptr)
+ {
+ // Unlink step from _op
+ assert(_op->_step == this);
+ _op->_step = nullptr;
+
+ // Reset _op
+ _op = nullptr;
+ }
+
+ assert(_op == nullptr);
+
+ if (o)
+ {
+ // Update _op
+ _op = o;
+
+ // Link step to _op
+ assert(_op->_step == nullptr);
+ _op->_step = this;
+ }
+
+ assert(_op == o);
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Stride2D.cpp b/compiler/coco/core/src/IR/Stride2D.cpp
new file mode 100644
index 000000000..a034876ef
--- /dev/null
+++ b/compiler/coco/core/src/IR/Stride2D.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Stride2D.h"
+
+namespace coco
+{
+
+Stride2D &Stride2D::vertical(uint32_t value)
+{
+ _vertical = value;
+ return (*this);
+}
+
+Stride2D &Stride2D::horizontal(uint32_t value)
+{
+ _horizontal = value;
+ return (*this);
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Stride2D.test.cpp b/compiler/coco/core/src/IR/Stride2D.test.cpp
new file mode 100644
index 000000000..43d159ee0
--- /dev/null
+++ b/compiler/coco/core/src/IR/Stride2D.test.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Stride2D.h"
+
+#include <gtest/gtest.h>
+
+TEST(IR_STRIDE_2D, default_constructor)
+{
+ coco::Stride2D stride;
+
+ ASSERT_EQ(stride.vertical(), 1);
+ ASSERT_EQ(stride.horizontal(), 1);
+}
+
+TEST(IR_STRIDE_2D, explicit_constructor_4)
+{
+ coco::Stride2D stride{2, 3};
+
+ ASSERT_EQ(stride.vertical(), 2);
+ ASSERT_EQ(stride.horizontal(), 3);
+}
+
+TEST(IR_STRIDE_2D, update)
+{
+ coco::Stride2D stride;
+
+ stride.vertical(2).horizontal(3);
+
+ ASSERT_EQ(stride.vertical(), 2);
+ ASSERT_EQ(stride.horizontal(), 3);
+}
diff --git a/compiler/coco/core/src/IR/Sub.test.cpp b/compiler/coco/core/src/IR/Sub.test.cpp
new file mode 100644
index 000000000..6c8b9ba54
--- /dev/null
+++ b/compiler/coco/core/src/IR/Sub.test.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Ops.h"
+
+#include <memory>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+namespace
+{
+struct IsSub : public coco::Op::Visitor<bool>
+{
+ bool visit(const coco::Sub *) override { return true; }
+};
+
+class SubTest : public ::testing::Test
+{
+public:
+ SubTest()
+ {
+ // DO NOTHING
+ }
+
+protected:
+ coco::Sub *allocate(void)
+ {
+ auto op = new coco::Sub;
+ _allocated.emplace_back(op);
+ return op;
+ }
+
+private:
+ std::vector<std::unique_ptr<coco::Sub>> _allocated;
+};
+} // namespace
+
+TEST_F(SubTest, initialization)
+{
+ auto op = allocate();
+
+ // arguments should be empty on construction
+ ASSERT_EQ(op->left(), nullptr);
+ ASSERT_EQ(op->right(), nullptr);
+
+ // uses() should be empty on construction
+ ASSERT_EQ(op->uses().size(), 0);
+ // parent() should be nullptr on construction
+ ASSERT_EQ(op->parent(), nullptr);
+}
+
+TEST_F(SubTest, asSub)
+{
+ auto op = allocate();
+
+ coco::Op *mutable_base = op;
+ const coco::Op *immutable_base = op;
+
+ ASSERT_EQ(mutable_base->asSub(), op);
+ ASSERT_EQ(mutable_base->asSub(), immutable_base->asSub());
+}
+
+TEST_F(SubTest, accept)
+{
+ // Test 'Sub' class
+ auto op = allocate();
+
+ coco::Sub *mutable_ptr = op;
+ const coco::Sub *immutable_ptr = op;
+
+ ASSERT_TRUE(mutable_ptr->accept(IsSub{}));
+ ASSERT_TRUE(immutable_ptr->accept(IsSub{}));
+}
diff --git a/compiler/coco/core/src/IR/Update.cpp b/compiler/coco/core/src/IR/Update.cpp
new file mode 100644
index 000000000..8e81c85cf
--- /dev/null
+++ b/compiler/coco/core/src/IR/Update.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Update.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+Update::~Update()
+{
+ // Unlink self from a linked bag if it exists
+ bag(nullptr);
+}
+
+void Update::bag(Bag *bag)
+{
+ if (_bag)
+ {
+ _bag->mutable_updates()->erase(this);
+ _bag = nullptr;
+ }
+
+ assert(_bag == nullptr);
+
+ if (bag)
+ {
+ _bag = bag;
+ _bag->mutable_updates()->insert(this);
+ }
+
+ assert(_bag == bag);
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Update.test.cpp b/compiler/coco/core/src/IR/Update.test.cpp
new file mode 100644
index 000000000..0bd355998
--- /dev/null
+++ b/compiler/coco/core/src/IR/Update.test.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Update.h"
+#include "coco/IR/BagManager.h"
+
+#include "Updater.mock.h"
+
+#include <gtest/gtest.h>
+
+namespace
+{
+class UpdateTest : public ::testing::Test
+{
+protected:
+ coco::BagManager bag_mgr;
+};
+} // namespace
+
+TEST_F(UpdateTest, constructor)
+{
+ // TODO Rename 'update'
+ ::mock::Updater update;
+
+ // TODO Rename 'slot'
+ coco::Update slot{&update};
+
+ ASSERT_EQ(slot.bag(), nullptr);
+}
+
+TEST_F(UpdateTest, value)
+{
+ // TODO Rename 'update'
+ ::mock::Updater update;
+
+ // TODO Rename 'slot'
+ coco::Update slot{&update};
+
+ auto bag = bag_mgr.create(16);
+
+ slot.bag(bag);
+
+ ASSERT_EQ(slot.bag(), bag);
+
+ ASSERT_EQ(bag->updates()->size(), 1);
+ ASSERT_NE(bag->updates()->find(&slot), bag->updates()->end());
+
+ slot.bag(nullptr);
+
+ ASSERT_EQ(slot.bag(), nullptr);
+
+ ASSERT_EQ(bag->updates()->size(), 0);
+}
+
+TEST_F(UpdateTest, unlink_on_destruction)
+{
+ ::mock::Updater updater;
+
+ auto bag = bag_mgr.create(1);
+
+ {
+ coco::Update update{&updater};
+ update.bag(bag);
+ ASSERT_EQ(bag->updates()->size(), 1);
+ }
+
+ ASSERT_EQ(bag->updates()->size(), 0);
+}
diff --git a/compiler/coco/core/src/IR/Updater.mock.h b/compiler/coco/core/src/IR/Updater.mock.h
new file mode 100644
index 000000000..6441cdd02
--- /dev/null
+++ b/compiler/coco/core/src/IR/Updater.mock.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __COCO_IR_UPDATER_MOCK_H__
+#define __COCO_IR_UPDATER_MOCK_H__
+
+#include "coco/IR/Bag.h"
+
+namespace
+{
+namespace mock
+{
+struct Updater final : public coco::Bag::Updater
+{
+ coco::Instr *loc(void) override { return nullptr; }
+};
+} // namespace mock
+} // namespace
+
+#endif // __COCO_IR_UPDATER_MOCK_H__
diff --git a/compiler/coco/core/src/IR/Use.cpp b/compiler/coco/core/src/IR/Use.cpp
new file mode 100644
index 000000000..cd9b68105
--- /dev/null
+++ b/compiler/coco/core/src/IR/Use.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Use.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+void Use::value(Object *value)
+{
+ if (_value)
+ {
+ _value->mutable_uses()->erase(this);
+ _value = nullptr;
+ }
+
+ assert(_value == nullptr);
+
+ if (value)
+ {
+ _value = value;
+ _value->mutable_uses()->insert(this);
+ }
+
+ assert(_value == value);
+}
+
+} // namespace coco
diff --git a/compiler/coco/core/src/IR/Use.test.cpp b/compiler/coco/core/src/IR/Use.test.cpp
new file mode 100644
index 000000000..3191e9852
--- /dev/null
+++ b/compiler/coco/core/src/IR/Use.test.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Use.h"
+#include "coco/IR/ObjectManager.h"
+
+#include "coco/IR/FeatureObject.h"
+
+#include "Consumer.mock.h"
+
+#include <stdex/Memory.h>
+
+#include <gtest/gtest.h>
+
+using stdex::make_unique;
+
+namespace
+{
+class UseTest : public ::testing::Test
+{
+protected:
+ coco::ObjectManager obj_mgr;
+};
+} // namespace
+
+TEST_F(UseTest, constructor)
+{
+ auto o = obj_mgr.create<coco::FeatureObject>();
+
+ // TODO Rename 'use'
+ ::mock::Consumer use;
+
+ coco::Use slot{&use};
+
+ ASSERT_EQ(slot.value(), nullptr);
+}
+
+TEST_F(UseTest, value)
+{
+ auto o = obj_mgr.create<coco::FeatureObject>();
+
+ // TODO Rename 'use'
+ ::mock::Consumer use;
+
+ coco::Use slot{&use};
+
+ slot.value(o);
+
+ ASSERT_EQ(slot.value(), o);
+
+ ASSERT_EQ(o->uses()->size(), 1);
+ ASSERT_NE(o->uses()->find(&slot), o->uses()->end());
+
+ slot.value(nullptr);
+
+ ASSERT_EQ(slot.value(), nullptr);
+
+ ASSERT_EQ(o->uses()->size(), 0);
+}
+
+TEST_F(UseTest, destructor)
+{
+ ::mock::Consumer consumer;
+
+ auto o = obj_mgr.create<coco::FeatureObject>();
+ auto use = make_unique<coco::Use>(&consumer);
+
+ use->value(o);
+ use.reset();
+
+ // ~Use SHOULD unlink itself from linked Object (if exists)
+ ASSERT_EQ(o->uses()->size(), 0);
+}
diff --git a/compiler/coco/core/src/IR/Window2D.test.cpp b/compiler/coco/core/src/IR/Window2D.test.cpp
new file mode 100644
index 000000000..c0e919237
--- /dev/null
+++ b/compiler/coco/core/src/IR/Window2D.test.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/Window2D.h"
+
+#include <gtest/gtest.h>
+
+TEST(IR_WINDOW_2D, default_constructor)
+{
+ coco::Window2D window;
+
+ ASSERT_EQ(window.height(), 1);
+ ASSERT_EQ(window.width(), 1);
+}
+
+TEST(IR_WINDOW_2D, explicit_constructor_4)
+{
+ coco::Window2D window{2, 3};
+
+ ASSERT_EQ(window.height(), 2);
+ ASSERT_EQ(window.width(), 3);
+}
+
+TEST(IR_WINDOW_2D, update)
+{
+ coco::Window2D window;
+
+ window.height(2);
+ window.width(3);
+
+ ASSERT_EQ(window.height(), 2);
+ ASSERT_EQ(window.width(), 3);
+}