target_include_directories(enco_core PUBLIC include)
target_link_libraries(enco_core coco_core)
target_link_libraries(enco_core coco_generic)
+target_link_libraries(enco_core morph)
nncc_find_package(GTest QUIET)
--- /dev/null
+#ifndef __ANN_BINDER_H__
+#define __ANN_BINDER_H__
+
+#include "ANN/IR/Module.h"
+
+#include <coco/IR.h>
+
+#include <morph/nnapi.h>
+
+/**
+ * @brief A bridge between ann::Module and coco::Block
+ */
+class ANNBinder
+{
+public:
+ ANNBinder(uint32_t id, coco::Block *block, std::unique_ptr<ann::Module> &&module)
+ : _id{id}, _block{block}, _module{std::move(module)}
+ {
+ // DO NOTHING
+ }
+
+public:
+ uint32_t id(void) const { return _id; }
+
+public:
+ const coco::Block *block(void) const { return _block; }
+ coco::Block *block(void) { return _block; }
+
+public:
+ const ann::Module *module(void) const { return _module.get(); }
+
+private:
+ uint32_t const _id;
+ coco::Block *const _block;
+ std::unique_ptr<ann::Module> _module;
+};
+
+#endif // __ANN_BINDER_H__
--- /dev/null
+#include "ANN/Context.h"
+
+#include <nncc/foundation/Memory.h>
+
+ANNBinder *ANNContext::create(coco::Block *blk)
+{
+ const uint32_t id = _binders.size();
+
+ auto mod = nncc::foundation::make_unique<ann::Module>();
+ auto obj = nncc::foundation::make_unique<ANNBinder>(id, blk, std::move(mod));
+ auto ptr = obj.get();
+
+ _binders.emplace_back(std::move(obj));
+ _map[blk] = ptr;
+
+ return ptr;
+}
--- /dev/null
+#ifndef __ANN_CONTEXT_H__
+#define __ANN_CONTEXT_H__
+
+#include "ANN/Binder.h"
+
+#include <map>
+#include <vector>
+
+#include <memory>
+
+struct ANNContext
+{
+public:
+ ANNBinder *create(coco::Block *blk);
+
+public:
+ uint32_t count(void) const { return _binders.size(); }
+
+public:
+ ANNBinder *nth(uint32_t n) { return _binders.at(n).get(); }
+ const ANNBinder *nth(uint32_t n) const { return _binders.at(n).get(); }
+
+public:
+ ANNBinder *find(const coco::Block *blk) const
+ {
+ auto it = _map.find(blk);
+
+ if (it == _map.end())
+ {
+ return nullptr;
+ }
+
+ return it->second;
+ }
+
+private:
+ std::vector<std::unique_ptr<ANNBinder>> _binders;
+ std::map<const coco::Block *, ANNBinder *> _map;
+};
+
+#endif // __ANN_CONTEXT_H__
--- /dev/null
+#include "Context.h"
+
+#include <set>
+
+#include <gtest/gtest.h>
+
+namespace
+{
+class ANNContextTest : public ::testing::Test
+{
+public:
+ ANNContextTest() { m = coco::Module::create(); }
+
+public:
+ virtual ~ANNContextTest() = default;
+
+protected:
+ std::unique_ptr<coco::Module> m;
+};
+}
+
+TEST_F(ANNContextTest, constructor)
+{
+ ANNContext ann_ctx;
+
+ ASSERT_EQ(ann_ctx.count(), 0);
+}
+
+TEST_F(ANNContextTest, create)
+{
+ ANNContext ann_ctx;
+
+ auto blk = m->entity()->block()->create();
+ auto binder = ann_ctx.create(blk);
+
+ ASSERT_NE(binder, nullptr);
+}
+
+TEST_F(ANNContextTest, create_distinct_id)
+{
+ const uint32_t count = 32;
+
+ ANNContext ann_ctx;
+
+ std::set<uint32_t> ids;
+
+ for (uint32_t n = 0; n < count; ++n)
+ {
+ auto blk = m->entity()->block()->create();
+ auto binder = ann_ctx.create(blk);
+ ids.insert(binder->id());
+ }
+
+ ASSERT_EQ(ids.size(), count);
+}
+
+TEST_F(ANNContextTest, find)
+{
+ ANNContext ann_ctx;
+
+ // CASE: Corresponding binder does not exist
+ {
+ auto blk = m->entity()->block()->create();
+ ASSERT_EQ(ann_ctx.find(blk), nullptr);
+ }
+
+ // CASE: Corresponding binder does exist
+ {
+ auto blk = m->entity()->block()->create();
+ auto binder_created = ann_ctx.create(blk);
+ auto binder_found = ann_ctx.find(blk);
+
+ ASSERT_EQ(binder_created, binder_found);
+ }
+}