Skip to content
Snippets Groups Projects
Unverified Commit cfc5647d authored by zhanghb97's avatar zhanghb97 Committed by GitHub
Browse files

[Utils][Container] Add copy and move constructors and assignment operators. (#11)

parent 298b0fb7
No related branches found
No related tags found
No related merge requests found
......@@ -46,6 +46,14 @@ public:
// Constructor from a vector of png images.
// Assume that all the images have the same shape.
MemRef(const std::vector<PNGImage> &imgs, intptr_t sizes[N]);
// Copy constructor.
MemRef(const MemRef<T, N> &other);
// Copy assignment operator.
MemRef<T, N> &operator=(const MemRef<T, N> &other);
// Move constructor.
MemRef(MemRef<T, N> &&other) noexcept;
// Move assignment operator.
MemRef<T, N> &operator=(MemRef<T, N> &&other) noexcept;
// Desctrutor.
~MemRef();
// Permute the dimensions.
......
......@@ -187,6 +187,63 @@ MemRef<T, N>::MemRef(const std::vector<PNGImage> &imgs, intptr_t sizes[N]) {
allocated = data;
}
template <typename T, std::size_t N>
MemRef<T, N>::MemRef(const MemRef<T, N> &other)
: offset(other.offset), size(other.size) {
for (size_t i = 0; i < N; i++) {
this->sizes[i] = other.sizes[i];
}
setStrides();
T *ptr = new T[size];
for (size_t i = 0; i < size; i++) {
ptr[i] = other.aligned[i];
}
aligned = ptr;
allocated = ptr;
}
template <typename T, std::size_t N>
MemRef<T, N> &MemRef<T, N>::operator=(const MemRef<T, N> &other) {
if (this != &other) {
this->offset = other.offset;
this->size = other.size;
for (size_t i = 0; i < N; i++) {
this->sizes[i] = other.sizes[i];
}
setStrides();
T *ptr = new T[size];
for (size_t i = 0; i < size; i++) {
ptr[i] = other.aligned[i];
}
aligned = ptr;
allocated = ptr;
}
return *this;
}
template <typename T, std::size_t N>
MemRef<T, N>::MemRef(MemRef<T, N> &&other) noexcept
: allocated(other.allocated), aligned(other.aligned), offset(other.offset),
size(other.size) {
std::swap(this->sizes, other.sizes);
std::swap(this->strides, other.strides);
other.allocated = other.aligned = nullptr;
}
template <typename T, std::size_t N>
MemRef<T, N> &MemRef<T, N>::operator=(MemRef<T, N> &&other) noexcept {
if (this != &other) {
std::swap(strides, other.strides);
std::swap(offset, other.offset);
std::swap(sizes, other.sizes);
std::swap(size, other.size);
std::swap(allocated, other.allocated);
std::swap(aligned, other.aligned);
other.allocated = other.aligned = nullptr;
}
return *this;
}
template <typename T, std::size_t N> MemRef<T, N>::~MemRef() {
delete[] allocated;
}
......
......@@ -195,6 +195,89 @@ TEST_F(MemRefTest, TransposeNCHWToNHWC) {
ASSERT_ARRAY_EQ(transposed.getData(), true_data, n_data);
}
// Copy constructor.
TEST_F(MemRefTest, CopyConstructor2DMemref) {
MemRef<float, 2> copyTemp = m2;
MemRef<float, 2> copy(copyTemp);
// Sizes.
intptr_t true_sizes[] = {2, 3};
size_t n_sizes = sizeof(true_sizes) / sizeof(intptr_t);
ASSERT_EQ(copy.getRank(), n_sizes);
ASSERT_ARRAY_EQ(copy.getSizes(), true_sizes, n_sizes);
// Strides.
intptr_t true_strides[] = {3, 1};
size_t n_strides = sizeof(true_strides) / sizeof(intptr_t);
ASSERT_EQ(copy.getRank(), n_strides);
ASSERT_ARRAY_EQ(copy.getStrides(), true_strides, n_strides);
// Data.
float true_data[] = {0., 1., 2., 3., 4., 5.};
size_t n_data = sizeof(true_data) / sizeof(float);
ASSERT_EQ(copy.getSize(), n_data);
ASSERT_ARRAY_EQ(copy.getData(), true_data, n_data);
}
// Copy assignment operator.
TEST_F(MemRefTest, CopyAssignment2DMemref) {
MemRef<float, 2> copy = MemRef<float, 2>({1, 1});
copy = m2;
// Sizes.
intptr_t true_sizes[] = {2, 3};
size_t n_sizes = sizeof(true_sizes) / sizeof(intptr_t);
ASSERT_EQ(copy.getRank(), n_sizes);
ASSERT_ARRAY_EQ(copy.getSizes(), true_sizes, n_sizes);
// Strides.
intptr_t true_strides[] = {3, 1};
size_t n_strides = sizeof(true_strides) / sizeof(intptr_t);
ASSERT_EQ(copy.getRank(), n_strides);
ASSERT_ARRAY_EQ(copy.getStrides(), true_strides, n_strides);
// Data.
float true_data[] = {0., 1., 2., 3., 4., 5.};
size_t n_data = sizeof(true_data) / sizeof(float);
ASSERT_EQ(copy.getSize(), n_data);
ASSERT_ARRAY_EQ(copy.getData(), true_data, n_data);
}
// Move constructor.
TEST_F(MemRefTest, MoveConstructor2DMemref) {
MemRef<float, 2> move = std::move(m2.transpose());
// Sizes.
intptr_t true_sizes[] = {3, 2};
size_t n_sizes = sizeof(true_sizes) / sizeof(intptr_t);
ASSERT_EQ(move.getRank(), n_sizes);
ASSERT_ARRAY_EQ(move.getSizes(), true_sizes, n_sizes);
// Strides.
intptr_t true_strides[] = {2, 1};
size_t n_strides = sizeof(true_strides) / sizeof(intptr_t);
ASSERT_EQ(move.getRank(), n_strides);
ASSERT_ARRAY_EQ(move.getStrides(), true_strides, n_strides);
// Data.
float true_data[] = {0., 3., 1., 4., 2., 5.};
size_t n_data = sizeof(true_data) / sizeof(float);
ASSERT_EQ(move.getSize(), n_data);
ASSERT_ARRAY_EQ(move.getData(), true_data, n_data);
}
// Move assignment operator.
TEST_F(MemRefTest, MoveAssignment2DMemref) {
MemRef<float, 2> move = MemRef<float, 2>({1, 1});
move = std::move(m2.transpose());
// Sizes.
intptr_t true_sizes[] = {3, 2};
size_t n_sizes = sizeof(true_sizes) / sizeof(intptr_t);
ASSERT_EQ(move.getRank(), n_sizes);
ASSERT_ARRAY_EQ(move.getSizes(), true_sizes, n_sizes);
// Strides.
intptr_t true_strides[] = {2, 1};
size_t n_strides = sizeof(true_strides) / sizeof(intptr_t);
ASSERT_EQ(move.getRank(), n_strides);
ASSERT_ARRAY_EQ(move.getStrides(), true_strides, n_strides);
// Data.
float true_data[] = {0., 3., 1., 4., 2., 5.};
size_t n_data = sizeof(true_data) / sizeof(float);
ASSERT_EQ(move.getSize(), n_data);
ASSERT_ARRAY_EQ(move.getData(), true_data, n_data);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment