[enco] Introduce ANNBinder and ANNContext (#1109)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Tue, 21 Aug 2018 06:36:36 +0000 (15:36 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Tue, 21 Aug 2018 06:36:36 +0000 (15:36 +0900)
This commit introduces ANNBinder (which bridges coco::Block and
ann::Module) and ANNContext (which serves as a factory/tracker of
ANNContext).

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
contrib/enco/core/CMakeLists.txt
contrib/enco/core/src/ANN/Binder.h [new file with mode: 0644]
contrib/enco/core/src/ANN/Context.cpp [new file with mode: 0644]
contrib/enco/core/src/ANN/Context.h [new file with mode: 0644]
contrib/enco/core/src/ANN/Context.test.cpp [new file with mode: 0644]

index e150c03..8187ed6 100644 (file)
@@ -8,6 +8,7 @@ target_include_directories(enco_core PRIVATE src)
 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)
 
diff --git a/contrib/enco/core/src/ANN/Binder.h b/contrib/enco/core/src/ANN/Binder.h
new file mode 100644 (file)
index 0000000..56d8d92
--- /dev/null
@@ -0,0 +1,38 @@
+#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__
diff --git a/contrib/enco/core/src/ANN/Context.cpp b/contrib/enco/core/src/ANN/Context.cpp
new file mode 100644 (file)
index 0000000..6cbbdd4
--- /dev/null
@@ -0,0 +1,17 @@
+#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;
+}
diff --git a/contrib/enco/core/src/ANN/Context.h b/contrib/enco/core/src/ANN/Context.h
new file mode 100644 (file)
index 0000000..e4491e0
--- /dev/null
@@ -0,0 +1,41 @@
+#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__
diff --git a/contrib/enco/core/src/ANN/Context.test.cpp b/contrib/enco/core/src/ANN/Context.test.cpp
new file mode 100644 (file)
index 0000000..207f41b
--- /dev/null
@@ -0,0 +1,75 @@
+#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);
+  }
+}