diff --git a/src/algebra/TinyMatrix.hpp b/src/algebra/TinyMatrix.hpp index fb0f94ad0b437633da38ea4a258d326d3ec504d9..eda3b5f19c3f7950bda6acce50a3e39b7c9f2cec 100644 --- a/src/algebra/TinyMatrix.hpp +++ b/src/algebra/TinyMatrix.hpp @@ -16,27 +16,25 @@ private: T m_values[N*N]; static_assert((N>0),"TinyMatrix size must be strictly positive"); - KOKKOS_INLINE_FUNCTION - size_t _index(const size_t& i, const size_t& j) const + KOKKOS_FORCEINLINE_FUNCTION + constexpr size_t _index(const size_t& i, const size_t& j) const noexcept { return std::move(i*N+j); } - void _unpackVariadicInput(const T& t) - { - m_values[N*N-1] = t; - } - template <typename... Args> - void _unpackVariadicInput(const T& t, Args&&... args) + KOKKOS_FORCEINLINE_FUNCTION + constexpr void _unpackVariadicInput(const T& t, Args&&... args) noexcept { m_values[N*N-1-sizeof...(args)] = t; - this->_unpackVariadicInput(args...); + if constexpr (sizeof...(args) >0) { + this->_unpackVariadicInput(args...); + } } public: KOKKOS_INLINE_FUNCTION - TinyMatrix operator-() const + constexpr TinyMatrix operator-() const { TinyMatrix opposed; for (size_t i=0; i<N*N; ++i) { @@ -46,17 +44,14 @@ public: } KOKKOS_INLINE_FUNCTION - friend TinyMatrix operator*(const T& t, const TinyMatrix& A) + constexpr friend TinyMatrix operator*(const T& t, const TinyMatrix& A) { - TinyMatrix tA; - for (size_t i=0; i<N*N; ++i) { - tA.m_values[i] = t * A.m_values[i]; - } - return std::move(tA); + TinyMatrix B = A; + return std::move(B *= t); } KOKKOS_INLINE_FUNCTION - TinyMatrix& operator*=(const T& t) + constexpr TinyMatrix& operator*=(const T& t) { for (size_t i=0; i<N*N; ++i) { m_values[i] *= t; @@ -65,7 +60,7 @@ public: } KOKKOS_INLINE_FUNCTION - TinyMatrix operator*(const TinyMatrix& B) const + constexpr TinyMatrix operator*(const TinyMatrix& B) const { const TinyMatrix& A = *this; TinyMatrix AB; @@ -82,7 +77,7 @@ public: } KOKKOS_INLINE_FUNCTION - TinyVector<N,T> operator*(const TinyVector<N,T>& x) const + constexpr TinyVector<N,T> operator*(const TinyVector<N,T>& x) const { const TinyMatrix& A = *this; TinyVector<N,T> Ax; @@ -97,7 +92,7 @@ public: } KOKKOS_INLINE_FUNCTION - friend std::ostream& operator<<(std::ostream& os, const TinyMatrix& A) + constexpr friend std::ostream& operator<<(std::ostream& os, const TinyMatrix& A) { if constexpr(N==1) { os << A(0,0); @@ -117,7 +112,7 @@ public: } KOKKOS_INLINE_FUNCTION - bool operator==(const TinyMatrix& A) const + constexpr bool operator==(const TinyMatrix& A) const { for (size_t i=0; i<N*N; ++i) { if (m_values[i] != A.m_values[i]) return false; @@ -126,13 +121,13 @@ public: } KOKKOS_INLINE_FUNCTION - bool operator!=(const TinyMatrix& A) const + constexpr bool operator!=(const TinyMatrix& A) const { return not this->operator==(A); } KOKKOS_INLINE_FUNCTION - TinyMatrix operator+(const TinyMatrix& A) const + constexpr TinyMatrix operator+(const TinyMatrix& A) const { TinyMatrix sum; for (size_t i=0; i<N*N; ++i) { @@ -142,7 +137,7 @@ public: } KOKKOS_INLINE_FUNCTION - TinyMatrix operator+(TinyMatrix&& A) const + constexpr TinyMatrix operator+(TinyMatrix&& A) const { for (size_t i=0; i<N*N; ++i) { A.m_values[i] += m_values[i]; @@ -151,7 +146,7 @@ public: } KOKKOS_INLINE_FUNCTION - TinyMatrix operator-(const TinyMatrix& A) const + constexpr TinyMatrix operator-(const TinyMatrix& A) const { TinyMatrix difference; for (size_t i=0; i<N*N; ++i) { @@ -161,7 +156,7 @@ public: } KOKKOS_INLINE_FUNCTION - TinyMatrix operator-(TinyMatrix&& A) const + constexpr TinyMatrix operator-(TinyMatrix&& A) const { for (size_t i=0; i<N*N; ++i) { A.m_values[i] = m_values[i]-A.m_values[i]; @@ -170,7 +165,7 @@ public: } KOKKOS_INLINE_FUNCTION - TinyMatrix& operator+=(const TinyMatrix& A) + constexpr TinyMatrix& operator+=(const TinyMatrix& A) { for (size_t i=0; i<N*N; ++i) { m_values[i] += A.m_values[i]; @@ -179,7 +174,7 @@ public: } KOKKOS_INLINE_FUNCTION - TinyMatrix& operator-=(const TinyMatrix& A) + constexpr TinyMatrix& operator-=(const TinyMatrix& A) { for (size_t i=0; i<N*N; ++i) { m_values[i] -= A.m_values[i]; @@ -188,21 +183,21 @@ public: } KOKKOS_INLINE_FUNCTION - T& operator()(const size_t& i, const size_t& j) + constexpr T& operator()(const size_t& i, const size_t& j) noexcept(NO_ASSERT) { Assert((i<N) and (j<N)); return m_values[_index(i,j)]; } KOKKOS_INLINE_FUNCTION - const T& operator()(const size_t& i, const size_t& j) const + constexpr const T& operator()(const size_t& i, const size_t& j) const noexcept(NO_ASSERT) { Assert((i<N) and (j<N)); return m_values[_index(i,j)]; } KOKKOS_INLINE_FUNCTION - TinyMatrix& operator=(const ZeroType& z) + constexpr TinyMatrix& operator=(const ZeroType& z) noexcept { static_assert(std::is_arithmetic<T>(),"Cannot assign 'zero' value for non-arithmetic types"); for (size_t i=0; i<N*N; ++i) { @@ -212,7 +207,7 @@ public: } KOKKOS_INLINE_FUNCTION - TinyMatrix& operator=(const IdentityType& I) + constexpr TinyMatrix& operator=(const IdentityType& I) noexcept { static_assert(std::is_arithmetic<T>(),"Cannot assign 'identity' value for non-arithmetic types"); for (size_t i=0; i<N; ++i) { @@ -224,7 +219,7 @@ public: } KOKKOS_INLINE_FUNCTION - TinyMatrix& operator=(const TinyMatrix& A) + constexpr TinyMatrix& operator=(const TinyMatrix& A) noexcept { for (size_t i=0; i<N*N; ++i) { m_values[i] = A.m_values[i]; @@ -233,21 +228,24 @@ public: } KOKKOS_INLINE_FUNCTION - TinyMatrix& operator=(TinyMatrix&& A) = default; + constexpr TinyMatrix& operator=(TinyMatrix&& A) noexcept = default; template <typename... Args> KOKKOS_INLINE_FUNCTION - TinyMatrix(const T& t, Args&&... args) + constexpr TinyMatrix(const T& t, Args&&... args) noexcept { static_assert(sizeof...(args)==N*N-1, "wrong number of parameters"); this->_unpackVariadicInput(t, args...); } KOKKOS_INLINE_FUNCTION - TinyMatrix()=default; + constexpr TinyMatrix() noexcept + { + ; + } KOKKOS_INLINE_FUNCTION - TinyMatrix(const ZeroType& z) + constexpr TinyMatrix(const ZeroType& z) noexcept { static_assert(std::is_arithmetic<T>(),"Cannot construct from 'zero' value for non-arithmetic types"); for (size_t i=0; i<N*N; ++i) { @@ -256,7 +254,7 @@ public: } KOKKOS_INLINE_FUNCTION - TinyMatrix(const IdentityType& I) + constexpr TinyMatrix(const IdentityType& I) noexcept { static_assert(std::is_arithmetic<T>(),"Cannot construct from 'identity' value for non-arithmetic types"); for (size_t i=0; i<N; ++i) { @@ -267,7 +265,7 @@ public: } KOKKOS_INLINE_FUNCTION - TinyMatrix(const TinyMatrix& A) + constexpr TinyMatrix(const TinyMatrix& A) noexcept { for (size_t i=0; i<N*N; ++i) { m_values[i] = A.m_values[i]; @@ -275,7 +273,7 @@ public: } KOKKOS_INLINE_FUNCTION - TinyMatrix(TinyMatrix&& A) = default; + TinyMatrix(TinyMatrix&& A) noexcept = default; KOKKOS_INLINE_FUNCTION ~TinyMatrix()=default; @@ -283,8 +281,8 @@ public: template <size_t N, typename T> KOKKOS_INLINE_FUNCTION -TinyMatrix<N,T> tensorProduct(const TinyVector<N,T>& x, - const TinyVector<N,T>& y) +constexpr TinyMatrix<N,T> tensorProduct(const TinyVector<N,T>& x, + const TinyVector<N,T>& y) { TinyMatrix<N,T> A; for (size_t i=0; i<N; ++i) { @@ -297,7 +295,7 @@ TinyMatrix<N,T> tensorProduct(const TinyVector<N,T>& x, template <size_t N, typename T> KOKKOS_INLINE_FUNCTION -T det(const TinyMatrix<N,T>& A) +constexpr T det(const TinyMatrix<N,T>& A) { static_assert(std::is_arithmetic<T>::value, "determinent is not defined for non arithmetic types"); static_assert(std::is_floating_point<T>::value, "determinent for arbitrary dimension N is defined for floating point types only"); @@ -341,7 +339,7 @@ T det(const TinyMatrix<N,T>& A) template <typename T> KOKKOS_INLINE_FUNCTION -T det(const TinyMatrix<1,T>& A) +constexpr T det(const TinyMatrix<1,T>& A) { static_assert(std::is_arithmetic<T>::value, "determinent is not defined for non arithmetic types"); return A(0,0); @@ -349,7 +347,7 @@ T det(const TinyMatrix<1,T>& A) template <typename T> KOKKOS_INLINE_FUNCTION -T det(const TinyMatrix<2,T>& A) +constexpr T det(const TinyMatrix<2,T>& A) { static_assert(std::is_arithmetic<T>::value, "determinent is not defined for non arithmetic types"); return A(0,0)*A(1,1)-A(1,0)*A(0,1); @@ -357,7 +355,7 @@ T det(const TinyMatrix<2,T>& A) template <typename T> KOKKOS_INLINE_FUNCTION -T det(const TinyMatrix<3,T>& A) +constexpr T det(const TinyMatrix<3,T>& A) { static_assert(std::is_arithmetic<T>::value, "determinent is not defined for non arithmetic types"); return @@ -368,9 +366,9 @@ T det(const TinyMatrix<3,T>& A) template <size_t N, typename T> KOKKOS_INLINE_FUNCTION -TinyMatrix<N-1,T> getMinor(const TinyMatrix<N,T>& A, - const size_t& I, - const size_t& J) +constexpr TinyMatrix<N-1,T> getMinor(const TinyMatrix<N,T>& A, + const size_t& I, + const size_t& J) { static_assert(N>=2, "minor calculation requires at least 2x2 matrices"); Assert((I<N) and (J<N)); @@ -396,11 +394,11 @@ TinyMatrix<N-1,T> getMinor(const TinyMatrix<N,T>& A, template <size_t N, typename T> KOKKOS_INLINE_FUNCTION -TinyMatrix<N,T> inverse(const TinyMatrix<N,T>& A); +constexpr TinyMatrix<N,T> inverse(const TinyMatrix<N,T>& A); template <typename T> KOKKOS_INLINE_FUNCTION -TinyMatrix<1,T> inverse(const TinyMatrix<1,T>& A) +constexpr TinyMatrix<1,T> inverse(const TinyMatrix<1,T>& A) { static_assert(std::is_arithmetic<T>::value, "inverse is not defined for non arithmetic types"); static_assert(std::is_floating_point<T>::value, "inverse is defined for floating point types only"); @@ -411,9 +409,9 @@ TinyMatrix<1,T> inverse(const TinyMatrix<1,T>& A) template <size_t N, typename T> KOKKOS_INLINE_FUNCTION -T cofactor(const TinyMatrix<N,T>& A, - const size_t& i, - const size_t& j) +constexpr T cofactor(const TinyMatrix<N,T>& A, + const size_t& i, + const size_t& j) { static_assert(std::is_arithmetic<T>::value, "cofactor is not defined for non arithmetic types"); const T sign = ((i+j)%2) ? -1 : 1; @@ -423,7 +421,7 @@ T cofactor(const TinyMatrix<N,T>& A, template <typename T> KOKKOS_INLINE_FUNCTION -TinyMatrix<2,T> inverse(const TinyMatrix<2,T>& A) +constexpr TinyMatrix<2,T> inverse(const TinyMatrix<2,T>& A) { static_assert(std::is_arithmetic<T>::value, "inverse is not defined for non arithmetic types"); static_assert(std::is_floating_point<T>::value, "inverse is defined for floating point types only"); @@ -439,7 +437,7 @@ TinyMatrix<2,T> inverse(const TinyMatrix<2,T>& A) template <typename T> KOKKOS_INLINE_FUNCTION -TinyMatrix<3,T> inverse(const TinyMatrix<3,T>& A) +constexpr TinyMatrix<3,T> inverse(const TinyMatrix<3,T>& A) { static_assert(std::is_arithmetic<T>::value, "inverse is not defined for non arithmetic types"); static_assert(std::is_floating_point<T>::value, "inverse is defined for floating point types only"); diff --git a/src/algebra/TinyVector.hpp b/src/algebra/TinyVector.hpp index 35cdb5d35f219979a406d3de0fe49e73924af7d8..c783bb7968696c120f96ef82014a5443639871d9 100644 --- a/src/algebra/TinyVector.hpp +++ b/src/algebra/TinyVector.hpp @@ -14,21 +14,19 @@ class TinyVector T m_values[N]; static_assert((N>0),"TinyVector size must be strictly positive"); - void _unpackVariadicInput(const T& t) - { - m_values[N-1] = t; - } - template <typename... Args> - void _unpackVariadicInput(const T& t, Args&&... args) + KOKKOS_FORCEINLINE_FUNCTION + constexpr void _unpackVariadicInput(const T& t, Args&&... args) noexcept { m_values[N-1-sizeof...(args)] = t; - this->_unpackVariadicInput(args...); + if constexpr (sizeof...(args) > 0) { + this->_unpackVariadicInput(args...); + } } public: KOKKOS_INLINE_FUNCTION - TinyVector operator-() const + constexpr TinyVector operator-() const { TinyVector opposed; for (size_t i=0; i<N; ++i) { @@ -44,7 +42,7 @@ class TinyVector } KOKKOS_INLINE_FUNCTION - bool operator==(const TinyVector& v) const + constexpr bool operator==(const TinyVector& v) const { for (size_t i=0; i<N; ++i) { if (m_values[i] != v.m_values[i]) return false; @@ -53,13 +51,13 @@ class TinyVector } KOKKOS_INLINE_FUNCTION - bool operator!=(const TinyVector& v) const + constexpr bool operator!=(const TinyVector& v) const { return not this->operator==(v); } KOKKOS_INLINE_FUNCTION - T operator,(const TinyVector& v) const + constexpr T operator,(const TinyVector& v) const { T t = m_values[0]*v.m_values[0]; for (size_t i=1; i<N; ++i) { @@ -69,7 +67,7 @@ class TinyVector } KOKKOS_INLINE_FUNCTION - TinyVector& operator*=(const T& t) + constexpr TinyVector& operator*=(const T& t) { for (size_t i=0; i<N; ++i) { m_values[i] *= t; @@ -78,24 +76,21 @@ class TinyVector } KOKKOS_INLINE_FUNCTION - friend TinyVector operator*(const T& t, const TinyVector& v) + constexpr friend TinyVector operator*(const T& t, const TinyVector& v) { - TinyVector tv; - for (size_t i=0; i<N; ++i) { - tv.m_values[i] = t * v.m_values[i]; - } - return std::move(tv); + TinyVector w = v; + return std::move(w*=t); } KOKKOS_INLINE_FUNCTION - friend TinyVector operator*(const T& t, TinyVector&& v) + constexpr friend TinyVector operator*(const T& t, TinyVector&& v) { v *= t; return std::move(v); } KOKKOS_INLINE_FUNCTION - friend std::ostream& operator<<(std::ostream& os, const TinyVector& v) + constexpr friend std::ostream& operator<<(std::ostream& os, const TinyVector& v) { os << '(' << v.m_values[0]; for (size_t i=1; i<N; ++i) { @@ -106,7 +101,7 @@ class TinyVector } KOKKOS_INLINE_FUNCTION - TinyVector operator+(const TinyVector& v) const + constexpr TinyVector operator+(const TinyVector& v) const { TinyVector sum; for (size_t i=0; i<N; ++i) { @@ -116,7 +111,7 @@ class TinyVector } KOKKOS_INLINE_FUNCTION - TinyVector operator+(TinyVector&& v) const + constexpr TinyVector operator+(TinyVector&& v) const { for (size_t i=0; i<N; ++i) { v.m_values[i] += m_values[i]; @@ -125,7 +120,7 @@ class TinyVector } KOKKOS_INLINE_FUNCTION - TinyVector operator-(const TinyVector& v) const + constexpr TinyVector operator-(const TinyVector& v) const { TinyVector difference; for (size_t i=0; i<N; ++i) { @@ -135,7 +130,7 @@ class TinyVector } KOKKOS_INLINE_FUNCTION - TinyVector operator-(TinyVector&& v) const + constexpr TinyVector operator-(TinyVector&& v) const { for (size_t i=0; i<N; ++i) { v.m_values[i] = m_values[i]-v.m_values[i]; @@ -144,7 +139,7 @@ class TinyVector } KOKKOS_INLINE_FUNCTION - TinyVector& operator+=(const TinyVector& v) + constexpr TinyVector& operator+=(const TinyVector& v) { for (size_t i=0; i<N; ++i) { m_values[i] += v.m_values[i]; @@ -153,7 +148,7 @@ class TinyVector } KOKKOS_INLINE_FUNCTION - TinyVector& operator-=(const TinyVector& v) + constexpr TinyVector& operator-=(const TinyVector& v) { for (size_t i=0; i<N; ++i) { m_values[i] -= v.m_values[i]; @@ -162,21 +157,21 @@ class TinyVector } KOKKOS_INLINE_FUNCTION - T& operator[](const size_t& i) + constexpr T& operator[](const size_t& i) noexcept(NO_ASSERT) { Assert(i<N); return m_values[i]; } KOKKOS_INLINE_FUNCTION - const T& operator[](const size_t& i) const + constexpr const T& operator[](const size_t& i) const noexcept(NO_ASSERT) { Assert(i<N); return m_values[i]; } KOKKOS_INLINE_FUNCTION - TinyVector& operator=(const ZeroType& z) + constexpr TinyVector& operator=(const ZeroType& z) noexcept { static_assert(std::is_arithmetic<T>(),"Cannot assign 'zero' value for non-arithmetic types"); for (size_t i=0; i<N; ++i) { @@ -186,7 +181,7 @@ class TinyVector } KOKKOS_INLINE_FUNCTION - const TinyVector& operator=(const TinyVector& v) + const TinyVector& operator=(const TinyVector& v) noexcept { for (size_t i=0; i<N; ++i) { m_values[i] = v.m_values[i]; @@ -195,24 +190,24 @@ class TinyVector } KOKKOS_INLINE_FUNCTION - TinyVector& operator=(TinyVector&& v) = default; + constexpr TinyVector& operator=(TinyVector&& v) noexcept = default; template <typename... Args> KOKKOS_INLINE_FUNCTION - TinyVector(const T& t, Args&&... args) + constexpr TinyVector(const T& t, Args&&... args) noexcept { static_assert(sizeof...(args)==N-1, "wrong number of parameters"); this->_unpackVariadicInput(t, args...); } KOKKOS_INLINE_FUNCTION - TinyVector() + constexpr TinyVector() noexcept { ; } KOKKOS_INLINE_FUNCTION - TinyVector(const ZeroType& z) + constexpr TinyVector(const ZeroType& z) noexcept { static_assert(std::is_arithmetic<T>(),"Cannot construct from 'zero' value for non-arithmetic types"); for (size_t i=0; i<N; ++i) { @@ -221,7 +216,7 @@ class TinyVector } KOKKOS_INLINE_FUNCTION - TinyVector(const TinyVector& v) + constexpr TinyVector(const TinyVector& v) noexcept { for (size_t i=0; i<N; ++i) { m_values[i] = v.m_values[i]; @@ -229,18 +224,15 @@ class TinyVector } KOKKOS_INLINE_FUNCTION - TinyVector(TinyVector&& v) = default; + constexpr TinyVector(TinyVector&& v) noexcept = default; KOKKOS_INLINE_FUNCTION - ~TinyVector() - { - ; - } + ~TinyVector() noexcept = default; }; template <size_t N, typename T> KOKKOS_INLINE_FUNCTION -T l2Norm(const TinyVector<N,T>& x) +constexpr T l2Norm(const TinyVector<N,T>& x) { static_assert(std::is_arithmetic<T>(),"Cannot compute L2 norm for non-arithmetic types"); static_assert(std::is_floating_point<T>::value, "L2 norm is defined for floating point types only"); @@ -250,7 +242,7 @@ T l2Norm(const TinyVector<N,T>& x) // Cross product is only defined for K^3 vectors template <typename T> KOKKOS_INLINE_FUNCTION -TinyVector<3,T> crossProduct(const TinyVector<3,T>& u, const TinyVector<3,T>& v) +constexpr TinyVector<3,T> crossProduct(const TinyVector<3,T>& u, const TinyVector<3,T>& v) { TinyVector<3,T> cross_product(u[1]*v[2]-u[2]*v[1], u[2]*v[0]-u[0]*v[2], diff --git a/src/utils/PastisAssert.hpp b/src/utils/PastisAssert.hpp index 90cfe15995f4c94460e4da4bc042f3a680496e08..9f5a171ac0b723ee553fb2a71b15e3d2743d6340 100644 --- a/src/utils/PastisAssert.hpp +++ b/src/utils/PastisAssert.hpp @@ -62,4 +62,12 @@ class AssertError #endif // NDEBUG +// stores the current state of Assert macro. This is useful for instance to +// noexcept management of Assert throws +#ifdef NDEBUG +#define NO_ASSERT true +#else // NDEBUG +#define NO_ASSERT false +#endif // NDEBUG + #endif // PASTIS_ASSERT_HPP