diff options
Diffstat (limited to 'compiler/coco/core/include')
71 files changed, 4615 insertions, 0 deletions
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__ |