[core] Add Tensor View (#281)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Fri, 1 Jun 2018 06:54:25 +0000 (15:54 +0900)
committer오형석/동작제어Lab(SR)/Staff Engineer/삼성전자 <hseok82.oh@samsung.com>
Fri, 1 Jun 2018 06:54:25 +0000 (15:54 +0900)
This commit introduces 'nncc::core::ADT::tensor::View' class which
allows users to interpret a memory region as a tensor with a specified
shape and layout.

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

index 4e18147..4a83c0b 100644 (file)
@@ -6,6 +6,7 @@ list(REMOVE_ITEM SOURCES ${TESTS})
 add_nncc_library(nncc_core SHARED ${HEADERS} ${SOURCES})
 set_target_properties(nncc_core PROPERTIES LINKER_LANGUAGE CXX)
 target_include_directories(nncc_core PUBLIC include)
+target_link_libraries(nncc_core PUBLIC nncc_foundation)
 
 add_nncc_test(nncc_core_test ${TESTS})
 nncc_target_link_libraries(nncc_core_test nncc_core)
diff --git a/libs/core/include/nncc/core/ADT/tensor/View.h b/libs/core/include/nncc/core/ADT/tensor/View.h
new file mode 100644 (file)
index 0000000..96ef5ab
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef __NNCC_CORE_ADT_TENSOR_VIEW_H__
+#define __NNCC_CORE_ADT_TENSOR_VIEW_H__
+
+#include "nncc/core/ADT/tensor/Shape.h"
+#include "nncc/core/ADT/tensor/Index.h"
+#include "nncc/core/ADT/tensor/Reader.h"
+#include "nncc/core/ADT/tensor/Accessor.h"
+#include "nncc/core/ADT/tensor/Layout.h"
+
+#include <nncc/foundation/Region.h>
+
+#include <memory>
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace tensor
+{
+
+template <typename T> class View final : public Reader<T>, public Accessor<T>
+{
+public:
+  explicit View(const Shape &shape, std::unique_ptr<Layout> &&layout,
+                std::unique_ptr<nncc::foundation::Region<T>> &&region)
+      : _shape{shape}, _layout{std::move(layout)}, _region{std::move(region)}
+  {
+    // DO NOTHING
+  }
+
+public:
+  T at(const Index &index) const override
+  {
+    return *(_region->base() + _layout->offset(_shape, index));
+  }
+
+public:
+  T &at(const Index &index) override { return *(_region->base() + _layout->offset(_shape, index)); }
+
+public:
+  const Shape &shape(void) const { return _shape; }
+
+private:
+  const Shape _shape;
+  std::unique_ptr<Layout> _layout;
+
+private:
+  std::unique_ptr<nncc::foundation::Region<T>> _region;
+};
+
+template <typename T, typename LayoutImpl>
+View<T> make_view(const Shape &shape, std::unique_ptr<nncc::foundation::Region<T>> &&region)
+{
+  std::unique_ptr<Layout> layout(new LayoutImpl{});
+  return View<T>{shape, std::move(layout), std::move(region)};
+}
+
+} // namespace tensor
+} // namespace ADT
+} // namespace core
+} // namespace nncc
+
+#endif // __NNCC_CORE_ADT_TENSOR_VIEW_H__
diff --git a/libs/core/src/ADT/tensor/View.test.cpp b/libs/core/src/ADT/tensor/View.test.cpp
new file mode 100644 (file)
index 0000000..6b60167
--- /dev/null
@@ -0,0 +1,63 @@
+#include "nncc/core/ADT/tensor/View.h"
+#include "nncc/core/ADT/tensor/LexicalLayout.h"
+
+#include <nncc/foundation/Memory.h>
+#include <nncc/foundation/ExternalRegion.h>
+
+#include <gtest/gtest.h>
+
+using namespace nncc::core::ADT::tensor;
+
+using nncc::foundation::make_unique;
+using nncc::foundation::ExternalRegion;
+
+TEST(ADT_TENSOR_VIEW, ctor)
+{
+  const Shape shape{2, 3};
+
+  int data[2 * 3] = {
+      0,
+  };
+  auto region = make_unique<ExternalRegion<int>>(data, 2 * 3);
+  auto view = make_view<int, LexicalLayout>(shape, std::move(region));
+
+  ASSERT_EQ(view.shape(), shape);
+}
+
+TEST(ADT_TENSOR_VIEW, read)
+{
+  const Shape shape{2, 3};
+
+  int data[2 * 3] = {
+      0,
+  };
+  auto region = make_unique<ExternalRegion<int>>(data, 2 * 3);
+  const auto view = make_view<int, LexicalLayout>(shape, std::move(region));
+
+  LexicalLayout layout{};
+
+  const Index index{1, 2};
+
+  ASSERT_EQ(data[layout.offset(shape, index)], 0);
+  data[layout.offset(shape, index)] = 2;
+  ASSERT_EQ(view.at(index), 2);
+}
+
+TEST(ADT_TENSOR_VIEW, access)
+{
+  const Shape shape{2, 3};
+
+  int data[2 * 3] = {
+      0,
+  };
+  auto region = make_unique<ExternalRegion<int>>(data, 2 * 3);
+  auto view = make_view<int, LexicalLayout>(shape, std::move(region));
+
+  LexicalLayout layout{};
+
+  const Index index{1, 2};
+
+  ASSERT_EQ(data[layout.offset(shape, index)], 0);
+  view.at(index) = 4;
+  ASSERT_EQ(data[layout.offset(shape, index)], 4);
+}