diff --git a/include/clad/Differentiator/ArrayRef.h b/include/clad/Differentiator/ArrayRef.h index fac7ab320..f1e56a96c 100644 --- a/include/clad/Differentiator/ArrayRef.h +++ b/include/clad/Differentiator/ArrayRef.h @@ -25,20 +25,26 @@ template class array_ref { array_ref() = default; /// Constructor to store the pointer to and size of an array supplied by the /// user + constexpr CUDA_HOST_DEVICE array_ref(T* arr, std::size_t size) : m_arr(arr), m_size(size) {} /// Constructor for arrays having size equal to 1 or non pointer types to /// store their addresses + constexpr CUDA_HOST_DEVICE array_ref(T* a) : m_arr(a), m_size(1) {} /// Constructor for clad::array types + constexpr CUDA_HOST_DEVICE array_ref(array& a) : m_arr(a.ptr()), m_size(a.size()) {} /// Operator for conversion from array_ref to T*. + constexpr CUDA_HOST_DEVICE operator T*() { return m_arr; } /// Operator for conversion from array_ref to const T*. + constexpr CUDA_HOST_DEVICE operator const T*() const { return m_arr; } template + constexpr CUDA_HOST_DEVICE array_ref& operator=(const array& a) { assert(m_size == a.size()); for (std::size_t i = 0; i < m_size; ++i) @@ -46,17 +52,22 @@ template class array_ref { return *this; } template + constexpr CUDA_HOST_DEVICE array_ref& operator=(const array_ref& a) { m_arr = a.ptr(); m_size = a.size(); return *this; } /// Returns the size of the underlying array + constexpr CUDA_HOST_DEVICE std::size_t size() const { return m_size; } + constexpr CUDA_HOST_DEVICE PUREFUNC T* ptr() const { return m_arr; } + constexpr CUDA_HOST_DEVICE PUREFUNC T*& ptr_ref() { return m_arr; } /// Returns an array_ref to a part of the underlying array starting at /// offset and having the specified size + constexpr CUDA_HOST_DEVICE array_ref slice(std::size_t offset, std::size_t size) { assert((offset >= 0) && (offset + size <= m_size) && "Window is outside array. Please provide an offset and size " @@ -64,11 +75,13 @@ template class array_ref { return array_ref(&m_arr[offset], size); } /// Returns the reference to the underlying array + constexpr CUDA_HOST_DEVICE PUREFUNC T& operator*() { return *m_arr; } // Arithmetic overloads /// Divides the arrays element wise template + constexpr CUDA_HOST_DEVICE array_ref& operator/=(array_ref& Ar) { assert(m_size == Ar.size() && "Size of both the array_refs must be equal " "for carrying out addition assignment"); @@ -78,6 +91,7 @@ template class array_ref { } /// Multiplies the arrays element wise template + constexpr CUDA_HOST_DEVICE array_ref& operator*=(array_ref& Ar) { assert(m_size == Ar.size() && "Size of both the array_refs must be equal " "for carrying out addition assignment"); @@ -87,6 +101,7 @@ template class array_ref { } /// Adds the arrays element wise template + constexpr CUDA_HOST_DEVICE array_ref& operator+=(array_ref& Ar) { assert(m_size == Ar.size() && "Size of both the array_refs must be equal " "for carrying out addition assignment"); @@ -96,6 +111,7 @@ template class array_ref { } /// Subtracts the arrays element wise template + constexpr CUDA_HOST_DEVICE array_ref& operator-=(array_ref& Ar) { assert(m_size == Ar.size() && "Size of both the array_refs must be equal " "for carrying out addition assignment"); @@ -104,28 +120,36 @@ template class array_ref { return *this; } /// Divides the elements of the array_ref by elements of the array - template CUDA_HOST_DEVICE array_ref& operator/=(array& A) { + template + constexpr + CUDA_HOST_DEVICE array_ref& operator/=(array& A) { assert(m_size == A.size() && "Size of arrays must be equal"); for (std::size_t i = 0; i < m_size; i++) m_arr[i] /= A[i]; return *this; } /// Multiplies the elements of the array_ref by elements of the array - template CUDA_HOST_DEVICE array_ref& operator*=(array& A) { + template + constexpr + CUDA_HOST_DEVICE array_ref& operator*=(array& A) { assert(m_size == A.size() && "Size of arrays must be equal"); for (std::size_t i = 0; i < m_size; i++) m_arr[i] *= A[i]; return *this; } /// Adds the elements of the array_ref by elements of the array - template CUDA_HOST_DEVICE array_ref& operator+=(array& A) { + template + constexpr + CUDA_HOST_DEVICE array_ref& operator+=(array& A) { assert(m_size == A.size() && "Size of arrays must be equal"); for (std::size_t i = 0; i < m_size; i++) m_arr[i] += A[i]; return *this; } /// Subtracts the elements of the array_ref by elements of the array - template CUDA_HOST_DEVICE array_ref& operator-=(array& A) { + template + constexpr + CUDA_HOST_DEVICE array_ref& operator-=(array& A) { assert(m_size == A.size() && "Size of arrays must be equal"); for (std::size_t i = 0; i < m_size; i++) m_arr[i] -= A[i]; @@ -134,6 +158,7 @@ template class array_ref { /// Divides the array by a scalar template ::value, int>::type = 0> + constexpr CUDA_HOST_DEVICE array_ref& operator/=(U a) { for (std::size_t i = 0; i < m_size; i++) m_arr[i] /= a; @@ -142,6 +167,7 @@ template class array_ref { /// Multiplies the array by a scalar template ::value, int>::type = 0> + constexpr CUDA_HOST_DEVICE array_ref& operator*=(U a) { for (std::size_t i = 0; i < m_size; i++) m_arr[i] *= a; @@ -150,6 +176,7 @@ template class array_ref { /// Adds the array by a scalar template ::value, int>::type = 0> + constexpr CUDA_HOST_DEVICE array_ref& operator+=(U a) { for (std::size_t i = 0; i < m_size; i++) m_arr[i] += a; @@ -159,6 +186,7 @@ template class array_ref { /// Subtracts the array by a scalar template ::value, int>::type = 0> + constexpr CUDA_HOST_DEVICE array_ref& operator-=(U a) { for (std::size_t i = 0; i < m_size; i++) m_arr[i] -= a; @@ -171,8 +199,8 @@ template class array_ref { /// Multiplies the arrays element wise template -CUDA_HOST_DEVICE - array_expression&, BinaryMul, const array_ref&> +constexpr +CUDA_HOST_DEVICE array_expression&, BinaryMul, const array_ref&> operator*(const array_ref& Ar, const array_ref& Br) { assert(Ar.size() == Br.size() && "Size of both the array_refs must be equal for carrying out " @@ -183,6 +211,7 @@ CUDA_HOST_DEVICE /// Adds the arrays element wise template +constexpr CUDA_HOST_DEVICE array_expression&, BinaryAdd, const array_ref&> operator+(const array_ref& Ar, const array_ref& Br) { @@ -195,6 +224,7 @@ CUDA_HOST_DEVICE /// Subtracts the arrays element wise template +constexpr CUDA_HOST_DEVICE array_expression&, BinarySub, const array_ref&> operator-(const array_ref& Ar, const array_ref& Br) { @@ -208,6 +238,7 @@ CUDA_HOST_DEVICE /// Divides the arrays element wise template +constexpr CUDA_HOST_DEVICE array_expression&, BinaryDiv, const array_ref&> operator/(const array_ref& Ar, const array_ref& Br) { @@ -221,6 +252,7 @@ CUDA_HOST_DEVICE /// Multiplies array_ref by a scalar template ::value, int>::type = 0> +constexpr CUDA_HOST_DEVICE array_expression&, BinaryMul, U> operator*(const array_ref& Ar, U a) { return array_expression&, BinaryMul, U>(Ar, a); @@ -229,6 +261,7 @@ operator*(const array_ref& Ar, U a) { /// Multiplies array_ref by a scalar (reverse order) template ::value, int>::type = 0> +constexpr CUDA_HOST_DEVICE array_expression&, BinaryMul, U> operator*(U a, const array_ref& Ar) { return array_expression&, BinaryMul, U>(Ar, a); @@ -237,6 +270,7 @@ operator*(U a, const array_ref& Ar) { /// Divides array_ref by a scalar template ::value, int>::type = 0> +constexpr CUDA_HOST_DEVICE array_expression&, BinaryDiv, U> operator/(const array_ref& Ar, U a) { return array_expression&, BinaryDiv, U>(Ar, a); @@ -245,6 +279,7 @@ operator/(const array_ref& Ar, U a) { /// Adds array_ref by a scalar template ::value, int>::type = 0> +constexpr CUDA_HOST_DEVICE array_expression&, BinaryAdd, U> operator+(const array_ref& Ar, U a) { return array_expression&, BinaryAdd, U>(Ar, a); @@ -253,6 +288,7 @@ operator+(const array_ref& Ar, U a) { /// Adds array_ref by a scalar (reverse order) template ::value, int>::type = 0> +constexpr CUDA_HOST_DEVICE array_expression&, BinaryAdd, U> operator+(U a, const array_ref& Ar) { return array_expression&, BinaryAdd, U>(Ar, a); @@ -261,6 +297,7 @@ operator+(U a, const array_ref& Ar) { /// Subtracts array_ref by a scalar template ::value, int>::type = 0> +constexpr CUDA_HOST_DEVICE array_expression&, BinarySub, U> operator-(const array_ref& Ar, U a) { return array_expression&, BinarySub, U>(Ar, a); @@ -269,6 +306,7 @@ operator-(const array_ref& Ar, U a) { /// Subtracts array_ref by a scalar (reverse order) template ::value, int>::type = 0> +constexpr CUDA_HOST_DEVICE array_expression&> operator-(U a, const array_ref& Ar) { return array_expression&>(a, Ar); @@ -303,15 +341,21 @@ operator-(U a, const array_ref& Ar) { template ::value || std::is_same::value>::type> + constexpr CUDA_HOST_DEVICE array_ref(T arr, std::size_t size = 1) : m_arr((void*)arr), m_size(size) {} template + constexpr CUDA_HOST_DEVICE array_ref(const array_ref& other) : m_arr(other.ptr()), m_size(other.size()) {} - template CUDA_HOST_DEVICE operator array_ref() { + template + constexpr + CUDA_HOST_DEVICE operator array_ref() { return array_ref((T*)(m_arr), m_size); } + [[nodiscard]] constexpr CUDA_HOST_DEVICE void* ptr() const { return m_arr; } + [[nodiscard]] constexpr CUDA_HOST_DEVICE std::size_t size() const { return m_size; } }; // NOLINTEND(*-pointer-arithmetic)