Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 29 additions & 13 deletions include/af/dim4.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,29 @@ class AFAPI dim4
/// \param[in] other The dim4 that will be copied
dim4(const dim4& other);

#if AF_API_VERSION >= 38
#if AF_COMPILER_CXX_RVALUE_REFERENCES
/// Default move constructor
///
/// \param[in] other The dim4 that will be moved
dim4(dim4 &&other) AF_NOEXCEPT = default;

/// Default move assignment operator
///
/// \param[in] other The dim4 that will be moved
dim4 &operator=(dim4 other) AF_NOEXCEPT;
#endif
#endif

/// Constructs a dim4 object from a C array of dim_t objects
///
/// Creates a new dim4 from a C array. If the C array is less than 4, all values
/// past \p ndims will be assigned the value 1.
/// Creates a new dim4 from a C array. If the C array is less than 4, all
/// values past \p ndims will be assigned the value 1.
///
/// \param[in] ndims The number of elements in the C array. Must be less than 4
/// \param[in] ndims The number of elements in the C array. Must be less
/// than 4
/// \param[in] dims The values to assign to each element of dim4
dim4(const unsigned ndims, const dim_t * const dims);
dim4(const unsigned ndims, const dim_t *const dims);

/// Returns the number of elements represented by this dim4
dim_t elements();
Expand All @@ -62,32 +77,33 @@ class AFAPI dim4
dim_t ndims() const;

/// Returns true if the two dim4 represent the same shape
bool operator==(const dim4& other) const;
bool operator==(const dim4 &other) const;

/// Returns true if two dim4s store different values
bool operator!=(const dim4& other) const;
bool operator!=(const dim4 &other) const;

/// Element-wise multiplication of the dim4 objects
dim4& operator*=(const dim4& other);
dim4 &operator*=(const dim4 &other);

/// Element-wise addition of the dim4 objects
dim4& operator+=(const dim4& other);
dim4 &operator+=(const dim4 &other);

/// Element-wise subtraction of the dim4 objects
dim4& operator-=(const dim4& other);
dim4 &operator-=(const dim4 &other);

/// Returns the reference to the element at a give index. (Must be less than 4)
dim_t& operator[](const unsigned dim);
/// Returns the reference to the element at a give index. (Must be less than
/// 4)
dim_t &operator[](const unsigned dim);

/// Returns the reference to the element at a give index. (Must be less than
/// 4)
const dim_t& operator[](const unsigned dim) const;
const dim_t &operator[](const unsigned dim) const;

/// Returns the underlying pointer to the dim4 object
dim_t *get() { return dims; }

/// Returns the underlying pointer to the dim4 object
const dim_t* get() const { return dims; }
const dim_t *get() const { return dims; }
};

/// Performs an element-wise addition of two dim4 objects
Expand Down
4 changes: 4 additions & 0 deletions src/backend/common/ArrayInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ class ArrayInfo {
"ArrayInfo::devId must be the first member variable of ArrayInfo. \
devId is used to encode the backend into the integer. \
This is then used in the unified backend to check mismatched arrays.");
static_assert(std::is_nothrow_move_assignable<ArrayInfo>::value,
"ArrayInfo is not nothrow move assignable");
static_assert(std::is_nothrow_move_constructible<ArrayInfo>::value,
"ArrayInfo is not nothrow move constructible");
}

ArrayInfo() = default;
Expand Down
8 changes: 8 additions & 0 deletions src/backend/common/SparseArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ SparseArrayBase::SparseArrayBase(const af::dim4 &_dims, dim_t _nNZ,
static_assert(offsetof(SparseArrayBase, info) == 0,
"SparseArrayBase::info must be the first member variable of "
"SparseArrayBase.");
static_assert(std::is_nothrow_move_assignable<SparseArrayBase>::value,
"SparseArrayBase is not move assignable");
static_assert(std::is_nothrow_move_constructible<SparseArrayBase>::value,
"SparseArrayBase is not move constructible");
}

SparseArrayBase::SparseArrayBase(const af::dim4 &_dims, dim_t _nNZ,
Expand Down Expand Up @@ -176,6 +180,10 @@ SparseArray<T>::SparseArray(const dim4 &_dims, dim_t _nNZ, af::storage _storage)
, values(createValueArray<T>(dim4(_nNZ), scalar<T>(0))) {
static_assert(std::is_standard_layout<SparseArray<T>>::value,
"SparseArray<T> must be a standard layout type");
static_assert(std::is_nothrow_move_assignable<SparseArray<T>>::value,
"SparseArray<T> is not move assignable");
static_assert(std::is_nothrow_move_constructible<SparseArray<T>>::value,
"SparseArray<T> is not move constructible");
static_assert(offsetof(SparseArray<T>, base) == 0,
"SparseArray<T>::base must be the first member variable of "
"SparseArray<T>");
Expand Down
13 changes: 13 additions & 0 deletions src/backend/common/SparseArray.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class SparseArrayBase {
detail::Array<int> colIdx; ///< Linear array containing col indices

public:
SparseArrayBase(SparseArrayBase &&other) noexcept = default;
SparseArrayBase(const af::dim4 &_dims, dim_t _nNZ, af::storage _storage,
af_dtype _type);

Expand All @@ -51,6 +52,11 @@ class SparseArrayBase {
const af::storage _storage, af_dtype _type,
bool _copy = false);

SparseArrayBase &operator=(SparseArrayBase other) noexcept {
std::swap(*this, other);
return *this;
}

/// A copy constructor for SparseArray
///
/// This constructor copies the \p in SparseArray and creates a new object
Expand Down Expand Up @@ -151,8 +157,15 @@ class SparseArray {
SparseArray(const SparseArray<T> &other, bool deep_copy);

public:
SparseArray(const SparseArray<T> &other) = default;
SparseArray(SparseArray<T> &&other) noexcept = default;

~SparseArray() noexcept = default;

SparseArray<T> &operator=(SparseArray<T> other) noexcept {
std::swap(*this, other);
return *this;
}
// Functions that call ArrayInfo object's functions
#define INSTANTIATE_INFO(return_type, func) \
return_type func() const { return base.func(); }
Expand Down
5 changes: 5 additions & 0 deletions src/backend/common/dim4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ dim4::dim4(const unsigned ndims_, const dim_t* const dims_) : dims{} {
for (unsigned i = 0; i < 4; i++) { dims[i] = ndims_ > i ? dims_[i] : 1; }
}

dim4& dim4::operator=(dim4 other) noexcept {
std::swap(dims, other.dims);
return *this;
}

dim_t dim4::elements() const { return dims[0] * dims[1] * dims[2] * dims[3]; }

dim_t dim4::elements() { return static_cast<const dim4&>(*this).elements(); }
Expand Down
4 changes: 2 additions & 2 deletions src/backend/cpu/Array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ Array<T>::Array(const dim4 &dims, T *const in_data, bool is_device,
, owner(true) {
static_assert(is_standard_layout<Array<T>>::value,
"Array<T> must be a standard layout type");
static_assert(std::is_move_assignable<Array<T>>::value,
static_assert(std::is_nothrow_move_assignable<Array<T>>::value,
"Array<T> is not move assignable");
static_assert(std::is_move_constructible<Array<T>>::value,
static_assert(std::is_nothrow_move_constructible<Array<T>>::value,
"Array<T> is not move constructible");
static_assert(
offsetof(Array<T>, info) == 0,
Expand Down
4 changes: 2 additions & 2 deletions src/backend/cuda/Array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ Array<T>::Array(const af::dim4 &dims, const T *const in_data, bool is_device,
, owner(true) {
static_assert(std::is_standard_layout<Array<T>>::value,
"Array<T> must be a standard layout type");
static_assert(std::is_move_assignable<Array<T>>::value,
static_assert(std::is_nothrow_move_assignable<Array<T>>::value,
"Array<T> is not move assignable");
static_assert(std::is_move_constructible<Array<T>>::value,
static_assert(std::is_nothrow_move_constructible<Array<T>>::value,
"Array<T> is not move constructible");
static_assert(
offsetof(Array<T>, info) == 0,
Expand Down
19 changes: 19 additions & 0 deletions src/backend/cuda/Array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,25 @@ class Array {
Array(const af::dim4 &dims, common::Node_ptr n);

public:
Array(const Array<T> &other) = default;

Array(Array<T> &&other) noexcept = default;

Array<T> &operator=(Array<T> other) noexcept {
swap(other);
return *this;
}

void swap(Array<T> &other) noexcept {
using std::swap;
swap(info, other.info);
swap(data, other.data);
swap(data_dims, other.data_dims);
swap(node, other.node);
swap(ready, other.ready);
swap(owner, other.owner);
}

Array(const af::dim4 &dims, const af::dim4 &strides, dim_t offset,
const T *const in_data, bool is_device = false);

Expand Down
4 changes: 2 additions & 2 deletions src/backend/opencl/Array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ Array<T>::Array(const dim4 &dims, const T *const in_data)
, owner(true) {
static_assert(is_standard_layout<Array<T>>::value,
"Array<T> must be a standard layout type");
static_assert(std::is_move_assignable<Array<T>>::value,
static_assert(std::is_nothrow_move_assignable<Array<T>>::value,
"Array<T> is not move assignable");
static_assert(std::is_move_constructible<Array<T>>::value,
static_assert(std::is_nothrow_move_constructible<Array<T>>::value,
"Array<T> is not move constructible");
static_assert(
offsetof(Array<T>, info) == 0,
Expand Down
20 changes: 19 additions & 1 deletion src/backend/opencl/Array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,27 @@ class Array {
explicit Array(const af::dim4 &dims, cl_mem mem, size_t offset, bool copy);

public:
Array(const Array<T> &other) = default;

Array(Array<T> &&other) noexcept = default;

Array<T> &operator=(Array<T> other) noexcept {
swap(other);
return *this;
}

void swap(Array<T> &other) noexcept {
using std::swap;
swap(info, other.info);
swap(data, other.data);
swap(data_dims, other.data_dims);
swap(node, other.node);
swap(ready, other.ready);
swap(owner, other.owner);
}

Array(const af::dim4 &dims, const af::dim4 &strides, dim_t offset,
const T *const in_data, bool is_device = false);

void resetInfo(const af::dim4 &dims) { info.resetInfo(dims); }
void resetDims(const af::dim4 &dims) { info.resetDims(dims); }
void modDims(const af::dim4 &newDims) { info.modDims(newDims); }
Expand Down