From aa075081e628b05d7499c8c49a4cdf1183e7b202 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EB=B0=95=EC=A2=85=ED=98=84/=EB=8F=99=EC=9E=91=EC=A0=9C?= =?utf8?q?=EC=96=B4Lab=28SR=29/Staff=20Engineer/=EC=82=BC=EC=84=B1?= =?utf8?q?=EC=A0=84=EC=9E=90?= Date: Thu, 28 Jun 2018 10:05:00 +0900 Subject: [PATCH] [core.ADT] Introduce feature buffer/overlay (#400) 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 --- libs/core/include/nncc/core/ADT/feature/Buffer.h | 43 +++++++++++++++++ libs/core/include/nncc/core/ADT/feature/Overlay.h | 44 ++++++++++++++++++ libs/core/include/nncc/core/ADT/feature/View.h | 55 ++++++++++++++++++++++ libs/core/src/ADT/feature/Buffer.test.cpp | 32 +++++++++++++ libs/core/src/ADT/feature/Overlay.test.cpp | 56 +++++++++++++++++++++++ 5 files changed, 230 insertions(+) create mode 100644 libs/core/include/nncc/core/ADT/feature/Buffer.h create mode 100644 libs/core/include/nncc/core/ADT/feature/Overlay.h create mode 100644 libs/core/include/nncc/core/ADT/feature/View.h create mode 100644 libs/core/src/ADT/feature/Buffer.test.cpp create mode 100644 libs/core/src/ADT/feature/Overlay.test.cpp 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 index 0000000..d7bc05c --- /dev/null +++ b/libs/core/include/nncc/core/ADT/feature/Buffer.h @@ -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 + +namespace nncc +{ +namespace core +{ +namespace ADT +{ +namespace feature +{ + +template class Buffer final : public View +{ +public: + explicit Buffer(const Shape &shape, const Layout &layout) : View{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 _buffer; +}; + +template Buffer make_buffer(const Shape &shape) +{ + return Buffer{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 index 0000000..ab3dd6c --- /dev/null +++ b/libs/core/include/nncc/core/ADT/feature/Overlay.h @@ -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 + +namespace nncc +{ +namespace core +{ +namespace ADT +{ +namespace feature +{ + +template class Overlay final : public View +{ +public: + explicit Overlay(const Shape &shape, const Layout &layout, T *base) + : View{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 Overlay make_overlay(const Shape &shape, T *base) +{ + return Overlay{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 index 0000000..cbfac14 --- /dev/null +++ b/libs/core/include/nncc/core/ADT/feature/View.h @@ -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 class View : public Reader, public Accessor +{ +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 index 0000000..bbaba2f --- /dev/null +++ b/libs/core/src/ADT/feature/Buffer.test.cpp @@ -0,0 +1,32 @@ +#include "nncc/core/ADT/feature/Buffer.h" +#include "nncc/core/ADT/feature/CHWLayout.h" + +#include + +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(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(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 &>(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 index 0000000..b7cab68 --- /dev/null +++ b/libs/core/src/ADT/feature/Overlay.test.cpp @@ -0,0 +1,56 @@ +#include "nncc/core/ADT/feature/Overlay.h" +#include "nncc/core/ADT/feature/CHWLayout.h" + +#include + +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(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(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(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); +} -- 2.7.4