#include <nncc/core/ADT/tensor/LexicalLayout.h>
-#include <nncc/core/ADT/tensor/View.h>
-
-#include <nncc/foundation/Memory.h>
-#include <nncc/foundation/ExternalRegion.h>
+#include <nncc/core/ADT/tensor/Overlay.h>
#include <caffe/caffe.hpp>
virtual std::string name(uint32_t n) const = 0;
virtual caffe::Blob<DType> *blob(uint32_t n) = 0;
- std::unique_ptr<nncc::foundation::Region<DType>> region(uint32_t n)
+ DType *region(uint32_t n)
{
- auto b = blob(n);
- auto count = b->count();
- auto data = b->mutable_cpu_data();
-
- return nncc::foundation::make_unique<nncc::foundation::ExternalRegion<DType>>(data, count);
+ return blob(n)->mutable_cpu_data();
}
};
void getMutableFloatTensor(uint32_t n, const TensorContext::TypedAccessor<float> &f) override
{
using nncc::core::ADT::tensor::LexicalLayout;
- using nncc::core::ADT::tensor::make_view;
+ using nncc::core::ADT::tensor::make_overlay;
- auto span = _blobs.region(n);
- auto view = make_view<float, LexicalLayout>(shape(n), std::move(span));
+ auto base = _blobs.region(n);
+ auto view = make_overlay<float, LexicalLayout>(shape(n), base);
f(*this, n, view);
}
void getConstFloatTensor(uint32_t n, const TensorContext::TypedReader<float> &f) const override
{
using nncc::core::ADT::tensor::LexicalLayout;
- using nncc::core::ADT::tensor::make_view;
+ using nncc::core::ADT::tensor::make_overlay;
- auto span = _blobs.region(n);
- auto view = make_view<float, LexicalLayout>(shape(n), std::move(span));
+ auto base = _blobs.region(n);
+ auto view = make_overlay<float, LexicalLayout>(shape(n), base);
f(*this, n, view);
}
--- /dev/null
+#ifndef __NNCC_CORE_ADT_TENSOR_BUFFER_H__
+#define __NNCC_CORE_ADT_TENSOR_BUFFER_H__
+
+#include "nncc/core/ADT/tensor/View.h"
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace tensor
+{
+
+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:
+ T *base(void) override { return _buffer.data(); }
+ const T *base(void) const override { 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 tensor
+} // namespace ADT
+} // namespace core
+} // namespace nncc
+
+#endif // __NNCC_CORE_ADT_TENSOR_BUFFER_H__
--- /dev/null
+#ifndef __NNCC_CORE_ADT_TENSOR_OVERLAY_H__
+#define __NNCC_CORE_ADT_TENSOR_OVERLAY_H__
+
+#include "nncc/core/ADT/tensor/View.h"
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace tensor
+{
+
+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:
+ T *base(void) override { return _base; }
+ const T *base(void) const override { 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 tensor
+} // namespace ADT
+} // namespace core
+} // namespace nncc
+
+#endif // __NNCC_CORE_ADT_TENSOR_OVERLAY_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 tensor
{
-template <typename T> class View final : public Reader<T>, public Accessor<T>
+template <typename T> class View : public Reader<T>, public Accessor<T>
{
public:
- explicit View(const Shape &shape, const Layout &layout,
- std::unique_ptr<nncc::foundation::Region<T>> &®ion)
- : _shape{shape}, _layout{std::move(layout)}, _region{std::move(region)}
+ explicit View(const Shape &shape, const Layout &layout)
+ : _shape{shape}, _layout{std::move(layout)}
{
// DO NOTHING
}
public:
- T at(const Index &index) const override
- {
- return *(_region->base() + _layout.offset(_shape, index));
- }
+ virtual ~View() = default;
+
+public:
+ virtual T *base(void) = 0;
+ virtual const T *base(void) const = 0;
public:
- T &at(const Index &index) override { return *(_region->base() + _layout.offset(_shape, index)); }
+ T at(const Index &index) const override { return *(base() + _layout.offset(_shape, index)); }
+
+public:
+ T &at(const Index &index) override { return *(base() + _layout.offset(_shape, index)); }
public:
const Shape &shape(void) const { return _shape; }
private:
const Shape _shape;
const 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>> &®ion)
-{
- return View<T>{shape, LayoutImpl{}, std::move(region)};
-}
-
} // namespace tensor
} // namespace ADT
} // namespace core
--- /dev/null
+#include "nncc/core/ADT/tensor/Buffer.h"
+#include "nncc/core/ADT/tensor/LexicalLayout.h"
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::tensor::Shape;
+using nncc::core::ADT::tensor::Index;
+using nncc::core::ADT::tensor::LexicalLayout;
+using nncc::core::ADT::tensor::Buffer;
+
+using nncc::core::ADT::tensor::make_buffer;
+
+TEST(ADT_TENSOR_BUFFER, ctor)
+{
+ const Shape shape{2, 3};
+ auto buffer = make_buffer<int, LexicalLayout>(shape);
+
+ ASSERT_EQ(buffer.shape(), shape);
+}
+
+TEST(ADT_TENSOR_BUFFER, access)
+{
+ const Shape shape{2, 3};
+ auto buffer = make_buffer<int, LexicalLayout>(shape);
+
+ const Index index{1, 2};
+
+ ASSERT_EQ(buffer.at(index), 0);
+ buffer.at(index) = 4;
+
+ // Casting is introduced to use 'const T &at(...) const' method
+ ASSERT_EQ(static_cast<const Buffer<int> &>(buffer).at(index), 4);
+}
--- /dev/null
+#include "nncc/core/ADT/tensor/Overlay.h"
+#include "nncc/core/ADT/tensor/LexicalLayout.h"
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::tensor::Shape;
+using nncc::core::ADT::tensor::Index;
+using nncc::core::ADT::tensor::LexicalLayout;
+using nncc::core::ADT::tensor::Overlay;
+
+using nncc::core::ADT::tensor::make_overlay;
+
+TEST(ADT_TENSOR_OVERLAY, ctor)
+{
+ const Shape shape{2, 3};
+
+ int data[2 * 3] = {
+ 0,
+ };
+ auto view = make_overlay<int, LexicalLayout>(shape, data);
+
+ ASSERT_EQ(view.shape(), shape);
+}
+
+TEST(ADT_TENSOR_OVERLAY, read)
+{
+ const Shape shape{2, 3};
+
+ int data[2 * 3] = {
+ 0,
+ };
+ const auto view = make_overlay<int, LexicalLayout>(shape, data);
+
+ 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_OVERLAY, access)
+{
+ const Shape shape{2, 3};
+
+ int data[2 * 3] = {
+ 0,
+ };
+ auto view = make_overlay<int, LexicalLayout>(shape, data);
+
+ 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);
+}
+++ /dev/null
-#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);
-}