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
4 changes: 2 additions & 2 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

<!--
<!--
Short description of change

This should be one or two sentences that describe the overall
Expand All @@ -16,7 +16,7 @@ Additional information about the PR answering following questions:
* More detail if necessary to describe all commits in pull request.
* Why these changes are necessary.
* Potential impact on specific hardware, software or backends.
* New functions and their functionallity.
* New functions and their functionality.
* Can this PR be backported to older versions?
* Future changes not implemented in this PR.
-->
Expand Down
1 change: 1 addition & 0 deletions src/api/unified/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ target_link_libraries(af
cpp_api_interface
spdlog
Threads::Threads
Boost::boost
Comment thread
9prady9 marked this conversation as resolved.
${CMAKE_DL_LIBS}
)

Expand Down
22 changes: 20 additions & 2 deletions src/backend/common/ArrayInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ class ArrayInfo {
, dim_strides(stride)
, is_sparse(false) {
setId(id);
static_assert(std::is_move_assignable<ArrayInfo>::value,
"ArrayInfo is not move assignable");
static_assert(std::is_move_constructible<ArrayInfo>::value,
"ArrayInfo is not move constructible");
static_assert(
offsetof(ArrayInfo, devId) == 0,
"ArrayInfo::devId must be the first member variable of ArrayInfo. \
Expand All @@ -79,10 +83,24 @@ class ArrayInfo {
This is then used in the unified backend to check mismatched arrays.");
}

// Copy constructors are deprecated if there is a
// user-defined destructor in c++11
ArrayInfo() = default;
ArrayInfo(const ArrayInfo& other) = default;
ArrayInfo(ArrayInfo&& other) = default;

ArrayInfo& operator=(ArrayInfo other) noexcept {
Comment thread
9prady9 marked this conversation as resolved.
swap(other);
return *this;
}

void swap(ArrayInfo& other) noexcept {
using std::swap;
swap(devId, other.devId);
swap(type, other.type);
swap(dim_size, other.dim_size);
swap(offset, other.offset);
swap(dim_strides, other.dim_strides);
swap(is_sparse, other.is_sparse);
}

const af_dtype& getType() const { return type; }

Expand Down
8 changes: 8 additions & 0 deletions src/backend/common/half.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,14 @@ class alignas(2) half {
data_(bits)
#endif
{
#ifndef __CUDACC_RTC__
static_assert(std::is_standard_layout<half>::value,
"half must be a standard layout type");
static_assert(std::is_nothrow_move_assignable<half>::value,
"half is not move assignable");
static_assert(std::is_nothrow_move_constructible<half>::value,
"half is not move constructible");
#endif
}

#if defined(__CUDA_ARCH__)
Expand Down
4 changes: 3 additions & 1 deletion src/backend/common/jit/BufferNodeBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ class BufferNodeBase : public common::Node {
bool m_linear_buffer;

public:
BufferNodeBase(af::dtype type) : Node(type, 0, {}) {}
BufferNodeBase(af::dtype type) : Node(type, 0, {}) {
// This class is not movable because of std::once_flag
Comment thread
9prady9 marked this conversation as resolved.
}

bool isBuffer() const final { return true; }

Expand Down
31 changes: 27 additions & 4 deletions src/backend/common/jit/NaryNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ namespace common {

class NaryNode : public Node {
private:
const int m_num_children;
const int m_op;
const std::string m_op_str;
int m_num_children;
int m_op;
std::string m_op_str;

public:
NaryNode(const af::dtype type, const char *op_str, const int num_children,
Expand All @@ -39,7 +39,30 @@ class NaryNode : public Node {
children))
, m_num_children(num_children)
, m_op(op)
, m_op_str(op_str) {}
, m_op_str(op_str) {
static_assert(std::is_nothrow_move_assignable<NaryNode>::value,
"NaryNode is not move assignable");
static_assert(std::is_nothrow_move_constructible<NaryNode>::value,
"NaryNode is not move constructible");
}

NaryNode(NaryNode &&other) = default;

NaryNode(const NaryNode &other) = default;

/// Default copy assignment operator
NaryNode &operator=(const NaryNode &node) = default;

/// Default move assignment operator
NaryNode &operator=(NaryNode &&node) noexcept = default;

void swap(NaryNode &other) noexcept {
using std::swap;
Node::swap(other);
swap(m_num_children, other.m_num_children);
swap(m_op, other.m_op);
swap(m_op_str, other.m_op_str);
}
Comment thread
9prady9 marked this conversation as resolved.

void genKerName(std::stringstream &kerStream,
const common::Node_ids &ids) const final {
Expand Down
34 changes: 21 additions & 13 deletions src/backend/common/jit/Node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

enum class kJITHeuristics {
Expand Down Expand Up @@ -80,30 +81,37 @@ class Node {
static const int kMaxChildren = 3;

protected:
const std::array<Node_ptr, kMaxChildren> m_children;
const af::dtype m_type;
const int m_height;
std::array<Node_ptr, kMaxChildren> m_children;
af::dtype m_type;
int m_height;

template<typename T>
friend class NodeIterator;

void swap(Node &other) noexcept {
using std::swap;
for (int i = 0; i < kMaxChildren; i++) {
swap(m_children[i], other.m_children[i]);
}
swap(m_type, other.m_type);
swap(m_height, other.m_height);
}

public:
Node() = default;
Node(const af::dtype type, const int height,
const std::array<Node_ptr, kMaxChildren> children)
: m_children(children), m_type(type), m_height(height) {}

/// Default copy constructor
Node(Node &node) = default;
: m_children(children), m_type(type), m_height(height) {
static_assert(std::is_nothrow_move_assignable<Node>::value,
"Node is not move assignable");
}

/// Default move constructor
Node(Node &&node) = default;
/// Default copy constructor operator
Node(const Node &node) = default;

/// Default copy assignment operator
Node &operator=(const Node &node) = default;

/// Default move assignment operator
Node &operator=(Node &&node) = default;

int getNodesMap(Node_map_t &node_map, std::vector<Node *> &full_nodes,
std::vector<Node_ids> &full_ids);

Expand Down Expand Up @@ -213,7 +221,7 @@ class Node {
virtual std::string getNameStr() const { return getShortName(m_type); }

/// Default destructor
virtual ~Node() = default;
virtual ~Node() noexcept = default;
};

struct Node_ids {
Expand Down
26 changes: 25 additions & 1 deletion src/backend/common/jit/ScalarNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,31 @@ class ScalarNode : public common::Node {
public:
ScalarNode(T val)
: Node(static_cast<af::dtype>(af::dtype_traits<T>::af_type), 0, {})
, m_val(val) {}
, m_val(val) {
static_assert(std::is_nothrow_move_assignable<ScalarNode>::value,
"ScalarNode is not move assignable");
static_assert(std::is_nothrow_move_constructible<ScalarNode>::value,
"ScalarNode is not move constructible");
}

/// Default move copy constructor
ScalarNode(const ScalarNode& other) = default;

/// Default move constructor
ScalarNode(ScalarNode&& other) = default;

/// Default move/copy assignment operator(Rule of 4)
ScalarNode& operator=(ScalarNode node) noexcept {
swap(node);
return *this;
}

// Swap specilization
void swap(ScalarNode& other) noexcept {
using std::swap;
Node::swap(other);
swap(m_val, other.m_val);
}

void genKerName(std::stringstream& kerStream,
const common::Node_ids& ids) const final {
Expand Down
29 changes: 27 additions & 2 deletions src/backend/common/jit/ShiftNodeBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,37 @@ template<typename BufferNode>
class ShiftNodeBase : public Node {
private:
std::shared_ptr<BufferNode> m_buffer_node;
const std::array<int, 4> m_shifts;
std::array<int, 4> m_shifts;

public:
ShiftNodeBase(const af::dtype type, std::shared_ptr<BufferNode> buffer_node,
const std::array<int, 4> shifts)
: Node(type, 0, {}), m_buffer_node(buffer_node), m_shifts(shifts) {}
: Node(type, 0, {}), m_buffer_node(buffer_node), m_shifts(shifts) {
static_assert(std::is_nothrow_move_assignable<ShiftNodeBase>::value,
"ShiftNode is not move assignable");
static_assert(std::is_nothrow_move_constructible<ShiftNodeBase>::value,
"ShiftNode is not move constructible");
}

/// Default move copy constructor
ShiftNodeBase(const ShiftNodeBase &other) = default;

/// Default move constructor
ShiftNodeBase(ShiftNodeBase &&other) = default;

/// Default move/copy assignment operator(Rule of 4)
ShiftNodeBase &operator=(ShiftNodeBase node) noexcept {
swap(node);
return *this;
}

// Swap specilization
void swap(ShiftNodeBase &other) noexcept {
using std::swap;
Node::swap(other);
swap(m_buffer_node, other.m_buffer_node);
swap(m_shifts, other.m_shifts);
}

bool isLinear(dim_t dims[4]) const final {
UNUSED(dims);
Expand Down
7 changes: 6 additions & 1 deletion src/backend/common/jit/UnaryNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ namespace common {
class UnaryNode : public NaryNode {
public:
UnaryNode(const af::dtype type, const char *op_str, Node_ptr child, int op)
: NaryNode(type, op_str, 1, {{child}}, op, child->getHeight() + 1) {}
: NaryNode(type, op_str, 1, {{child}}, op, child->getHeight() + 1) {
static_assert(std::is_nothrow_move_assignable<UnaryNode>::value,
"UnaryNode is not move assignable");
static_assert(std::is_nothrow_move_constructible<UnaryNode>::value,
"UnaryNode is not move constructible");
}
};
} // namespace common
4 changes: 4 additions & 0 deletions src/backend/cpu/Array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ 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,
"Array<T> is not move assignable");
static_assert(std::is_move_constructible<Array<T>>::value,
"Array<T> is not move constructible");
static_assert(
offsetof(Array<T>, info) == 0,
"Array<T>::info must be the first member variable of Array<T>");
Expand Down
18 changes: 18 additions & 0 deletions src/backend/cpu/Array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,24 @@ class Array {
T *const in_data, bool is_device = false);

public:
Array<T>(const Array<T> &other) = default;
Array<T>(Array<T> &&other) = 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);
}

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
9 changes: 4 additions & 5 deletions src/backend/cuda/Array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,15 @@ Array<T>::Array(const af::dim4 &dims, const T *const in_data, bool is_device,
, node(bufferNodePtr<T>())
, ready(true)
, owner(true) {
#if __cplusplus > 199711L
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,
"Array<T> is not move assignable");
static_assert(std::is_move_constructible<Array<T>>::value,
"Array<T> is not move constructible");
static_assert(
offsetof(Array<T>, info) == 0,
"Array<T>::info must be the first member variable of Array<T>");
#endif
if (!is_device) {
CUDA_CHECK(
cudaMemcpyAsync(data.get(), in_data, dims.elements() * sizeof(T),
Expand Down Expand Up @@ -218,9 +220,6 @@ void evalMultiple(std::vector<Array<T> *> arrays) {
for (Array<T> *array : output_arrays) { array->node = bufferNodePtr<T>(); }
}

template<typename T>
Array<T>::~Array() = default;

template<typename T>
Node_ptr Array<T>::getNode() {
if (node->isBuffer()) {
Expand Down
2 changes: 1 addition & 1 deletion src/backend/cuda/Array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ class Array {

#undef INFO_IS_FUNC

~Array();
~Array() = default;

bool isReady() const { return ready; }
bool isOwner() const { return owner; }
Expand Down
11 changes: 9 additions & 2 deletions src/backend/cuda/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -286,18 +286,25 @@ set_target_properties(af_cuda_static_cuda_library
)

if(UNIX)

check_cxx_compiler_flag("-Wl,--start-group -Werror" group_flags)
if(group_flags)
set(START_GROUP -Wl,--start-group)
set(END_GROUP -Wl,--end-group)
endif()

target_link_libraries(af_cuda_static_cuda_library
PRIVATE
Boost::boost
${CMAKE_DL_LIBS}
${cusolver_lib}
-Wl,--start-group
${START_GROUP}
${CUDA_culibos_LIBRARY} #also a static libary
${CUDA_cublas_static_LIBRARY}
${CUDA_cufft_static_LIBRARY}
${CUDA_cusparse_static_LIBRARY}
${cusolver_static_lib}
-Wl,--end-group
${END_GROUP}
)

if(CUDA_VERSION VERSION_GREATER 9.5)
Expand Down
4 changes: 4 additions & 0 deletions src/backend/opencl/Array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ 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,
"Array<T> is not move assignable");
static_assert(std::is_move_constructible<Array<T>>::value,
"Array<T> is not move constructible");
static_assert(
offsetof(Array<T>, info) == 0,
"Array<T>::info must be the first member variable of Array<T>");
Expand Down
Loading