[core.ADT] Introduce feature buffer/overlay (#400)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Thu, 28 Jun 2018 01:05:00 +0000 (10:05 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Thu, 28 Jun 2018 01:05:00 +0000 (10:05 +0900)
This commit introduces feature buffer/overlay classes, and related
tests. The design of buffer/overlay is almost similar as that of
kernel/tensor.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
libs/core/include/nncc/core/ADT/feature/Buffer.h [new file with mode: 0644]
libs/core/include/nncc/core/ADT/feature/Overlay.h [new file with mode: 0644]
libs/core/include/nncc/core/ADT/feature/View.h [new file with mode: 0644]
libs/core/src/ADT/feature/Buffer.test.cpp [new file with mode: 0644]
libs/core/src/ADT/feature/Overlay.test.cpp [new file with mode: 0644]

diff --git a/libs/core/include/nncc/core/ADT/feature/Buffer.h b/libs/core/include/nncc/core/ADT/feature/Buffer.h
new file mode 100644 (file)
index 0000000..d7bc05c
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef __NNCC_CORE_ADT_FEATURE_BUFFER_H__
+#define __NNCC_CORE_ADT_FEATURE_BUFFER_H__
+
+#include "nncc/core/ADT/feature/View.h"
+
+#include <vector>
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace feature
+{
+
+template <typename T> class Buffer final : public View<T>
+{
+public:
+  explicit Buffer(const Shape &shape, const Layout &layout) : View<T>{shape, layout}
+  {
+    _buffer.resize(num_elements(shape));
+  }
+
+public:
+  virtual T *base(void) { return _buffer.data(); }
+  virtual const T *base(void) const { return _buffer.data(); }
+
+private:
+  std::vector<T> _buffer;
+};
+
+template <typename T, typename LayoutImpl> Buffer<T> make_buffer(const Shape &shape)
+{
+  return Buffer<T>{shape, LayoutImpl{}};
+}
+
+} // namespace feature
+} // namespace ADT
+} // namespace core
+} // namespace nncc
+
+#endif // __NNCC_CORE_ADT_FEATURE_BUFFER_H__
diff --git a/libs/core/include/nncc/core/ADT/feature/Overlay.h b/libs/core/include/nncc/core/ADT/feature/Overlay.h
new file mode 100644 (file)
index 0000000..ab3dd6c
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef __NNCC_CORE_ADT_FEATURE_OVERLAY_H__
+#define __NNCC_CORE_ADT_FEATURE_OVERLAY_H__
+
+#include "nncc/core/ADT/feature/View.h"
+
+#include <vector>
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace feature
+{
+
+template <typename T> class Overlay final : public View<T>
+{
+public:
+  explicit Overlay(const Shape &shape, const Layout &layout, T *base)
+      : View<T>{shape, layout}, _base{base}
+  {
+    // DO NOTHING
+  }
+
+public:
+  virtual T *base(void) { return _base; }
+  virtual const T *base(void) const { return _base; }
+
+private:
+  T *const _base;
+};
+
+template <typename T, typename LayoutImpl> Overlay<T> make_overlay(const Shape &shape, T *base)
+{
+  return Overlay<T>{shape, LayoutImpl{}, base};
+}
+
+} // namespace feature
+} // namespace ADT
+} // namespace core
+} // namespace nncc
+
+#endif // __NNCC_CORE_ADT_FEATURE_OVERLAY_H__
diff --git a/libs/core/include/nncc/core/ADT/feature/View.h b/libs/core/include/nncc/core/ADT/feature/View.h
new file mode 100644 (file)
index 0000000..cbfac14
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef __NNCC_CORE_ADT_FEATURE_VIEW_H__
+#define __NNCC_CORE_ADT_FEATURE_VIEW_H__
+
+#include "nncc/core/ADT/feature/Shape.h"
+#include "nncc/core/ADT/feature/Reader.h"
+#include "nncc/core/ADT/feature/Accessor.h"
+#include "nncc/core/ADT/feature/Layout.h"
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace feature
+{
+
+template <typename T> class View : public Reader<T>, public Accessor<T>
+{
+public:
+  explicit View(const Shape &shape, const Layout &layout) : _shape{shape}, _layout{layout}
+  {
+    // DO NOTHING
+  }
+
+public:
+  virtual T *base(void) = 0;
+  virtual const T *base(void) const = 0;
+
+public:
+  T at(uint32_t ch, uint32_t row, uint32_t col) const override final
+  {
+    return *(base() + _layout.offset(_shape, ch, row, col));
+  }
+
+public:
+  T &at(uint32_t ch, uint32_t row, uint32_t col) override final
+  {
+    return *(base() + _layout.offset(_shape, ch, row, col));
+  }
+
+public:
+  const Shape &shape(void) const { return _shape; }
+
+private:
+  const Shape _shape;
+  const Layout _layout;
+};
+
+} // namespace feature
+} // namespace ADT
+} // namespace core
+} // namespace nncc
+
+#endif // __NNCC_CORE_ADT_FEATURE_VIEW_H__
diff --git a/libs/core/src/ADT/feature/Buffer.test.cpp b/libs/core/src/ADT/feature/Buffer.test.cpp
new file mode 100644 (file)
index 0000000..bbaba2f
--- /dev/null
@@ -0,0 +1,32 @@
+#include "nncc/core/ADT/feature/Buffer.h"
+#include "nncc/core/ADT/feature/CHWLayout.h"
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::feature::Shape;
+using nncc::core::ADT::feature::CHWLayout;
+using nncc::core::ADT::feature::Buffer;
+
+using nncc::core::ADT::feature::make_buffer;
+
+TEST(ADT_FEATURE_BUFFER, ctor)
+{
+  const Shape shape{4, 6, 3};
+  auto buffer = make_buffer<int, CHWLayout>(shape);
+
+  ASSERT_EQ(buffer.shape().depth(), shape.depth());
+  ASSERT_EQ(buffer.shape().height(), shape.height());
+  ASSERT_EQ(buffer.shape().width(), shape.width());
+}
+
+TEST(ADT_FEATURE_BUFFER, access)
+{
+  const Shape shape{4, 6, 3};
+  auto buffer = make_buffer<int, CHWLayout>(shape);
+
+  ASSERT_EQ(buffer.at(3, 5, 2), 0);
+  buffer.at(3, 5, 2) = 4;
+
+  // Casting is introduced to use 'const T &at(...) const' method
+  ASSERT_EQ(static_cast<const Buffer<int> &>(buffer).at(3, 5, 2), 4);
+}
diff --git a/libs/core/src/ADT/feature/Overlay.test.cpp b/libs/core/src/ADT/feature/Overlay.test.cpp
new file mode 100644 (file)
index 0000000..b7cab68
--- /dev/null
@@ -0,0 +1,56 @@
+#include "nncc/core/ADT/feature/Overlay.h"
+#include "nncc/core/ADT/feature/CHWLayout.h"
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::feature::Shape;
+using nncc::core::ADT::feature::CHWLayout;
+using nncc::core::ADT::feature::Overlay;
+
+using nncc::core::ADT::feature::make_overlay;
+
+TEST(ADT_FEATURE_OVERLAY, ctor)
+{
+  const Shape shape{4, 6, 3};
+
+  int data[4 * 6 * 3] = {
+      0,
+  };
+  auto overlay = make_overlay<int, CHWLayout>(shape, data);
+
+  ASSERT_EQ(overlay.shape().depth(), shape.depth());
+  ASSERT_EQ(overlay.shape().height(), shape.height());
+  ASSERT_EQ(overlay.shape().width(), shape.width());
+}
+
+TEST(ADT_FEATURE_OVERLAY, read)
+{
+  const Shape shape{4, 6, 3};
+
+  int data[4 * 6 * 3] = {
+      0,
+  };
+  const auto overlay = make_overlay<int, CHWLayout>(shape, data);
+
+  CHWLayout layout{};
+
+  ASSERT_EQ(data[layout.offset(shape, 3, 5, 2)], 0);
+  data[layout.offset(shape, 3, 5, 2)] = 2;
+  ASSERT_EQ(overlay.at(3, 5, 2), 2);
+}
+
+TEST(ADT_FEATURE_OVERLAY, access)
+{
+  const Shape shape{4, 6, 3};
+
+  int data[4 * 6 * 3] = {
+      0,
+  };
+  auto overlay = make_overlay<int, CHWLayout>(shape, data);
+
+  CHWLayout layout{};
+
+  ASSERT_EQ(data[layout.offset(shape, 3, 5, 2)], 0);
+  overlay.at(3, 5, 2) = 4;
+  ASSERT_EQ(data[layout.offset(shape, 3, 5, 2)], 4);
+}