Update Eigen to: https://gitlab.com/libeigen/eigen/-/commit/f612df273689a19d25b45ca4f8269463207c4fee
BEGIN_PUBLIC
Update Eigen to: https://gitlab.com/libeigen/eigen/-/commit/f612df273689a19d25b45ca4f8269463207c4fee
END_PUBLIC
PiperOrigin-RevId: 363224885
diff --git a/Eigen/Core b/Eigen/Core
index 1a60dcb..5921e15 100644
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -40,6 +40,13 @@
#pragma GCC optimize ("-fno-ipa-cp-clone")
#endif
+// Prevent ICC from specializing std::complex operators that silently fail
+// on device. This allows us to use our own device-compatible specializations
+// instead.
+#if defined(EIGEN_COMP_ICC) && defined(EIGEN_GPU_COMPILE_PHASE) \
+ && !defined(_OVERRIDE_COMPLEX_SPECIALIZATION_)
+#define _OVERRIDE_COMPLEX_SPECIALIZATION_ 1
+#endif
#include <complex>
// this include file manages BLAS and MKL related macros
diff --git a/Eigen/src/Core/Array.h b/Eigen/src/Core/Array.h
index 64fd02d..9a61665 100644
--- a/Eigen/src/Core/Array.h
+++ b/Eigen/src/Core/Array.h
@@ -157,7 +157,7 @@
EIGEN_DEVICE_FUNC
Array& operator=(Array&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
{
- other.swap(*this);
+ Base::operator=(std::move(other));
return *this;
}
#endif
diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h
index e29733c..7c67ffd 100644
--- a/Eigen/src/Core/MathFunctions.h
+++ b/Eigen/src/Core/MathFunctions.h
@@ -476,31 +476,35 @@
* Implementation of round *
****************************************************************************/
+template<typename Scalar>
+struct round_impl
+{
+ EIGEN_DEVICE_FUNC
+ static inline Scalar run(const Scalar& x)
+ {
+ EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
#if EIGEN_HAS_CXX11_MATH
- template<typename Scalar>
- struct round_impl {
- EIGEN_DEVICE_FUNC
- static inline Scalar run(const Scalar& x)
- {
- EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
- EIGEN_USING_STD(round);
+ EIGEN_USING_STD(round);
+ return Scalar(round(x));
+#elif EIGEN_HAS_C99_MATH
+ if (is_same<Scalar, float>::value) {
+ return Scalar(::roundf(x));
+ } else {
return Scalar(round(x));
}
- };
#else
- template<typename Scalar>
- struct round_impl
- {
- EIGEN_DEVICE_FUNC
- static inline Scalar run(const Scalar& x)
- {
- EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
- EIGEN_USING_STD(floor);
- EIGEN_USING_STD(ceil);
- return (x > Scalar(0)) ? floor(x + Scalar(0.5)) : ceil(x - Scalar(0.5));
+ EIGEN_USING_STD(floor);
+ EIGEN_USING_STD(ceil);
+ // If not enough precision to resolve a decimal at all, return the input.
+ // Otherwise, adding 0.5 can trigger an increment by 1.
+ const Scalar limit = Scalar(1ull << (NumTraits<Scalar>::digits() - 1));
+ if (x >= limit || x <= -limit) {
+ return x;
}
- };
+ return (x > Scalar(0)) ? Scalar(floor(x + Scalar(0.5))) : Scalar(ceil(x - Scalar(0.5)));
#endif
+ }
+};
template<typename Scalar>
struct round_retval
diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h
index fb72382..053003c 100644
--- a/Eigen/src/Core/Matrix.h
+++ b/Eigen/src/Core/Matrix.h
@@ -278,7 +278,7 @@
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Matrix& operator=(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
{
- other.swap(*this);
+ Base::operator=(std::move(other));
return *this;
}
#endif
diff --git a/Eigen/src/Core/PlainObjectBase.h b/Eigen/src/Core/PlainObjectBase.h
index 595a6c1..e53ca1b 100644
--- a/Eigen/src/Core/PlainObjectBase.h
+++ b/Eigen/src/Core/PlainObjectBase.h
@@ -118,16 +118,8 @@
using Base::IsVectorAtCompileTime;
using Base::Flags;
- template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
- friend class Eigen::Map<Derived, Unaligned>;
typedef Eigen::Map<Derived, Unaligned> MapType;
- friend class Eigen::Map<const Derived, Unaligned>;
typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
-#if EIGEN_MAX_ALIGN_BYTES>0
- // for EIGEN_MAX_ALIGN_BYTES==0, AlignedMax==Unaligned, and many compilers generate warnings for friend-ing a class twice.
- friend class Eigen::Map<Derived, AlignedMax>;
- friend class Eigen::Map<const Derived, AlignedMax>;
-#endif
typedef Eigen::Map<Derived, AlignedMax> AlignedMapType;
typedef const Eigen::Map<const Derived, AlignedMax> ConstAlignedMapType;
template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
@@ -508,8 +500,8 @@
EIGEN_DEVICE_FUNC
PlainObjectBase& operator=(PlainObjectBase&& other) EIGEN_NOEXCEPT
{
- using std::swap;
- swap(m_storage, other.m_storage);
+ _check_template_params();
+ m_storage = std::move(other.m_storage);
return *this;
}
#endif
@@ -989,6 +981,17 @@
enum { IsPlainObjectBase = 1 };
#endif
+ public:
+ // These apparently need to be down here for nvcc+icc to prevent duplicate
+ // Map symbol.
+ template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
+ friend class Eigen::Map<Derived, Unaligned>;
+ friend class Eigen::Map<const Derived, Unaligned>;
+#if EIGEN_MAX_ALIGN_BYTES>0
+ // for EIGEN_MAX_ALIGN_BYTES==0, AlignedMax==Unaligned, and many compilers generate warnings for friend-ing a class twice.
+ friend class Eigen::Map<Derived, AlignedMax>;
+ friend class Eigen::Map<const Derived, AlignedMax>;
+#endif
};
namespace internal {
diff --git a/Eigen/src/Core/arch/AltiVec/PacketMath.h b/Eigen/src/Core/arch/AltiVec/PacketMath.h
index 495afac..7c70c07 100755
--- a/Eigen/src/Core/arch/AltiVec/PacketMath.h
+++ b/Eigen/src/Core/arch/AltiVec/PacketMath.h
@@ -188,6 +188,7 @@
HasRound = 1,
HasFloor = 1,
HasCeil = 1,
+ HasRint = 1,
HasNegate = 1,
HasBlend = 1
};
@@ -229,6 +230,7 @@
HasRound = 1,
HasFloor = 1,
HasCeil = 1,
+ HasRint = 1,
HasNegate = 1,
HasBlend = 1
};
@@ -911,18 +913,35 @@
return vec_sel(b, a, reinterpret_cast<Packet4ui>(mask));
}
-template<> EIGEN_STRONG_INLINE Packet4f pround<Packet4f>(const Packet4f& a) {
+template<> EIGEN_STRONG_INLINE Packet4f pround<Packet4f>(const Packet4f& a)
+{
Packet4f t = vec_add(reinterpret_cast<Packet4f>(vec_or(vec_and(reinterpret_cast<Packet4ui>(a), p4ui_SIGN), p4ui_PREV0DOT5)), a);
Packet4f res;
+#ifdef __VSX__
+ __asm__("xvrspiz %x0, %x1\n\t"
+ : "=&wa" (res)
+ : "wa" (t));
+#else
__asm__("vrfiz %0, %1\n\t"
: "=v" (res)
: "v" (t));
+#endif
return res;
}
template<> EIGEN_STRONG_INLINE Packet4f pceil<Packet4f>(const Packet4f& a) { return vec_ceil(a); }
template<> EIGEN_STRONG_INLINE Packet4f pfloor<Packet4f>(const Packet4f& a) { return vec_floor(a); }
+template<> EIGEN_STRONG_INLINE Packet4f print<Packet4f>(const Packet4f& a)
+{
+ Packet4f res;
+
+ __asm__("xvrspic %x0, %x1\n\t"
+ : "=&wa" (res)
+ : "wa" (a));
+
+ return res;
+}
template<typename Packet> EIGEN_STRONG_INLINE Packet ploadu_common(const __UNPACK_TYPE__(Packet)* from)
{
@@ -1366,6 +1385,9 @@
template<> EIGEN_STRONG_INLINE Packet8bf pround<Packet8bf> (const Packet8bf& a){
BF16_TO_F32_UNARY_OP_WRAPPER(pround<Packet4f>, a);
}
+template<> EIGEN_STRONG_INLINE Packet8bf print<Packet8bf> (const Packet8bf& a){
+ BF16_TO_F32_UNARY_OP_WRAPPER(print<Packet4f>, a);
+}
template<> EIGEN_STRONG_INLINE Packet8bf pmadd(const Packet8bf& a, const Packet8bf& b, const Packet8bf& c) {
Packet4f a_even = Bf16ToF32Even(a);
Packet4f a_odd = Bf16ToF32Odd(a);
@@ -2234,6 +2256,8 @@
static Packet2l p2l_ONE = { 1, 1 };
static Packet2l p2l_ZERO = reinterpret_cast<Packet2l>(p4i_ZERO);
+static Packet2ul p2ul_SIGN = { 0x8000000000000000ull, 0x8000000000000000ull };
+static Packet2ul p2ul_PREV0DOT5 = { 0x3FDFFFFFFFFFFFFFull, 0x3FDFFFFFFFFFFFFFull };
static Packet2d p2d_ONE = { 1.0, 1.0 };
static Packet2d p2d_ZERO = reinterpret_cast<Packet2d>(p4f_ZERO);
static Packet2d p2d_MZERO = { -0.0, -0.0 };
@@ -2244,16 +2268,9 @@
static Packet2d p2d_COUNTDOWN = reinterpret_cast<Packet2d>(vec_sld(reinterpret_cast<Packet4f>(p2d_ONE), reinterpret_cast<Packet4f>(p2d_ZERO), 8));
#endif
-template<int index> Packet2d vec_splat_dbl(Packet2d& a);
-
-template<> EIGEN_STRONG_INLINE Packet2d vec_splat_dbl<0>(Packet2d& a)
+template<int index> Packet2d vec_splat_dbl(Packet2d& a)
{
- return reinterpret_cast<Packet2d>(vec_perm(a, a, p16uc_PSET64_HI));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2d vec_splat_dbl<1>(Packet2d& a)
-{
- return reinterpret_cast<Packet2d>(vec_perm(a, a, p16uc_PSET64_LO));
+ return vec_splat(a, index);
}
template<> struct packet_traits<double> : default_packet_traits
@@ -2282,6 +2299,7 @@
HasRound = 1,
HasFloor = 1,
HasCeil = 1,
+ HasRint = 1,
HasNegate = 1,
HasBlend = 1
};
@@ -2408,9 +2426,29 @@
template<> EIGEN_STRONG_INLINE Packet2d pandnot<Packet2d>(const Packet2d& a, const Packet2d& b) { return vec_and(a, vec_nor(b, b)); }
-template<> EIGEN_STRONG_INLINE Packet2d pround<Packet2d>(const Packet2d& a) { return vec_round(a); }
+template<> EIGEN_STRONG_INLINE Packet2d pround<Packet2d>(const Packet2d& a)
+{
+ Packet2d t = vec_add(reinterpret_cast<Packet2d>(vec_or(vec_and(reinterpret_cast<Packet2ul>(a), p2ul_SIGN), p2ul_PREV0DOT5)), a);
+ Packet2d res;
+
+ __asm__("xvrdpiz %x0, %x1\n\t"
+ : "=&wa" (res)
+ : "wa" (t));
+
+ return res;
+}
template<> EIGEN_STRONG_INLINE Packet2d pceil<Packet2d>(const Packet2d& a) { return vec_ceil(a); }
template<> EIGEN_STRONG_INLINE Packet2d pfloor<Packet2d>(const Packet2d& a) { return vec_floor(a); }
+template<> EIGEN_STRONG_INLINE Packet2d print<Packet2d>(const Packet2d& a)
+{
+ Packet2d res;
+
+ __asm__("xvrdpic %x0, %x1\n\t"
+ : "=&wa" (res)
+ : "wa" (a));
+
+ return res;
+}
template<> EIGEN_STRONG_INLINE Packet2d ploadu<Packet2d>(const double* from)
{
diff --git a/Eigen/src/Core/arch/CUDA/Complex.h b/Eigen/src/Core/arch/CUDA/Complex.h
index caf3fe7..b1618e5 100644
--- a/Eigen/src/Core/arch/CUDA/Complex.h
+++ b/Eigen/src/Core/arch/CUDA/Complex.h
@@ -12,9 +12,6 @@
#define EIGEN_COMPLEX_CUDA_H
// clang-format off
-
-#if defined(EIGEN_CUDACC) && defined(EIGEN_GPU_COMPILE_PHASE)
-
// Many std::complex methods such as operator+, operator-, operator* and
// operator/ are not constexpr. Due to this, GCC and older versions of clang do
// not treat them as device functions and thus Eigen functors making use of
@@ -22,6 +19,17 @@
// operators and functors for complex types when building for CUDA to enable
// their use on-device.
+#if defined(EIGEN_CUDACC) && defined(EIGEN_GPU_COMPILE_PHASE)
+
+// ICC already specializes std::complex<float> and std::complex<double>
+// operators, preventing us from making them device functions here.
+// This will lead to silent runtime errors if the operators are used on device.
+//
+// To allow std::complex operator use on device, define _OVERRIDE_COMPLEX_SPECIALIZATION_
+// prior to first inclusion of <complex>. This prevents ICC from adding
+// its own specializations, so our custom ones below can be used instead.
+#if !(defined(EIGEN_COMP_ICC) && defined(_USE_COMPLEX_SPECIALIZATION_))
+
// Import Eigen's internal operator specializations.
#define EIGEN_USING_STD_COMPLEX_OPERATORS \
using Eigen::complex_operator_detail::operator+; \
@@ -244,6 +252,8 @@
} // namespace internal
} // namespace Eigen
-#endif
+#endif // !(EIGEN_COMP_ICC && _USE_COMPLEX_SPECIALIZATION_)
+
+#endif // EIGEN_CUDACC && EIGEN_GPU_COMPILE_PHASE
#endif // EIGEN_COMPLEX_CUDA_H
diff --git a/Eigen/src/Core/arch/Default/Half.h b/Eigen/src/Core/arch/Default/Half.h
index eb3030a..56ff7ce 100644
--- a/Eigen/src/Core/arch/Default/Half.h
+++ b/Eigen/src/Core/arch/Default/Half.h
@@ -465,6 +465,28 @@
return half(static_cast<float>(a) / static_cast<float>(b));
}
+EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator++(half& a) {
+ a += half(1);
+ return a;
+}
+
+EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator--(half& a) {
+ a -= half(1);
+ return a;
+}
+
+EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator++(half& a, int) {
+ half original_value = a;
+ ++a;
+ return original_value;
+}
+
+EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator--(half& a, int) {
+ half original_value = a;
+ --a;
+ return original_value;
+}
+
// Conversion routines, including fallbacks for the host or older CUDA.
// Note that newer Intel CPUs (Haswell or newer) have vectorized versions of
// these in hardware. If we need more performance on older/other CPUs, they are
@@ -707,6 +729,9 @@
return half(::ceilf(float(a)));
#endif
}
+EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half fmod(const half& a, const half& b) {
+ return half(::fmodf(float(a), float(b)));
+}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half (min)(const half& a, const half& b) {
#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530) || \
diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h
index 252d2be..273dffb 100644
--- a/Eigen/src/Core/util/Macros.h
+++ b/Eigen/src/Core/util/Macros.h
@@ -230,7 +230,7 @@
//------------------------------------------------------------------------------------------
-#if defined(__x86_64__) || defined(_M_X64) || defined(__amd64)
+#if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC)) || defined(__amd64)
#define EIGEN_ARCH_x86_64 1
#else
#define EIGEN_ARCH_x86_64 0
@@ -256,7 +256,7 @@
#endif
/// \internal EIGEN_ARCH_ARM64 set to 1 if the architecture is ARM64
-#if defined(__aarch64__)
+#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
#define EIGEN_ARCH_ARM64 1
#else
#define EIGEN_ARCH_ARM64 0
@@ -909,7 +909,7 @@
// but it still doesn't use GCC's always_inline. This is useful in (common) situations where MSVC needs forceinline
// but GCC is still doing fine with just inline.
#ifndef EIGEN_STRONG_INLINE
-#if EIGEN_COMP_MSVC || EIGEN_COMP_ICC
+#if (EIGEN_COMP_MSVC || EIGEN_COMP_ICC) && !defined(EIGEN_GPUCC)
#define EIGEN_STRONG_INLINE __forceinline
#else
#define EIGEN_STRONG_INLINE inline
@@ -1121,7 +1121,10 @@
// Note that this is restricted to plain types - this will not work
// directly for std::complex<T>, Eigen::half, Eigen::bfloat16. For these,
// you will need to apply to the underlying POD type.
- #if EIGEN_ARCH_PPC
+ #if EIGEN_ARCH_PPC && EIGEN_COMP_GNUC_STRICT
+ // This seems to be broken on clang. Packet4f is loaded into a single
+ // register rather than a vector, zeroing out some entries. Integer
+ // types also generate a compile error.
// General, Altivec, VSX.
#define EIGEN_OPTIMIZATION_BARRIER(X) __asm__ ("" : "+r,v,wa" (X));
#elif EIGEN_ARCH_ARM_OR_ARM64
diff --git a/test/half_float.cpp b/test/half_float.cpp
index b2c2219..729de1b 100644
--- a/test/half_float.cpp
+++ b/test/half_float.cpp
@@ -168,6 +168,20 @@
VERIFY_IS_APPROX(float(half(1.0f) / half(3.0f)), 0.33333f);
VERIFY_IS_EQUAL(float(-half(4096.0f)), -4096.0f);
VERIFY_IS_EQUAL(float(-half(-4096.0f)), 4096.0f);
+
+ half x(3);
+ half y = ++x;
+ VERIFY_IS_EQUAL(x, half(4));
+ VERIFY_IS_EQUAL(y, half(4));
+ y = --x;
+ VERIFY_IS_EQUAL(x, half(3));
+ VERIFY_IS_EQUAL(y, half(3));
+ y = x++;
+ VERIFY_IS_EQUAL(x, half(4));
+ VERIFY_IS_EQUAL(y, half(3));
+ y = x--;
+ VERIFY_IS_EQUAL(x, half(3));
+ VERIFY_IS_EQUAL(y, half(4));
}
void test_comparison()
@@ -254,6 +268,11 @@
VERIFY_IS_EQUAL(float(log1p(half(0.0f))), 0.0f);
VERIFY_IS_APPROX(float(numext::log1p(half(10.0f))), 2.3978953f);
VERIFY_IS_APPROX(float(log1p(half(10.0f))), 2.3978953f);
+
+ VERIFY_IS_APPROX(numext::fmod(half(5.3f), half(2.0f)), half(1.3f));
+ VERIFY_IS_APPROX(fmod(half(5.3f), half(2.0f)), half(1.3f));
+ VERIFY_IS_APPROX(numext::fmod(half(-18.5f), half(-4.2f)), half(-1.7f));
+ VERIFY_IS_APPROX(fmod(half(-18.5f), half(-4.2f)), half(-1.7f));
}
void test_trigonometric_functions()
diff --git a/test/main.h b/test/main.h
index cf06173..3e80c9f 100644
--- a/test/main.h
+++ b/test/main.h
@@ -40,6 +40,8 @@
// definitions.
#include <limits>
#include <algorithm>
+// Disable ICC's std::complex operator specializations so we can use our own.
+#define _OVERRIDE_COMPLEX_SPECIALIZATION_ 1
#include <complex>
#include <deque>
#include <queue>
diff --git a/test/rand.cpp b/test/rand.cpp
index dd4e739..984c01f 100644
--- a/test/rand.cpp
+++ b/test/rand.cpp
@@ -51,7 +51,7 @@
Scalar r = check_in_range(x,y);
hist( int((int64(r)-int64(x))/divisor) )++;
}
- VERIFY( (((hist.cast<double>()/double(f))-1.0).abs()<0.025).all() );
+ VERIFY( (((hist.cast<double>()/double(f))-1.0).abs()<0.03).all() );
}
EIGEN_DECLARE_TEST(rand)
diff --git a/test/rvalue_types.cpp b/test/rvalue_types.cpp
index 2eef47d..c20a32f 100644
--- a/test/rvalue_types.cpp
+++ b/test/rvalue_types.cpp
@@ -18,6 +18,36 @@
using internal::UIntPtr;
+// A Scalar that asserts for uninitialized access.
+template<typename T>
+class SafeScalar {
+ public:
+ SafeScalar() : initialized_(false) {}
+ SafeScalar(const SafeScalar& other) {
+ *this = other;
+ }
+ SafeScalar& operator=(const SafeScalar& other) {
+ val_ = T(other);
+ initialized_ = true;
+ return *this;
+ }
+
+ SafeScalar(T val) : val_(val), initialized_(true) {}
+ SafeScalar& operator=(T val) {
+ val_ = val;
+ initialized_ = true;
+ }
+
+ operator T() const {
+ VERIFY(initialized_ && "Uninitialized access.");
+ return val_;
+ }
+
+ private:
+ T val_;
+ bool initialized_;
+};
+
#if EIGEN_HAS_RVALUE_REFERENCES
template <typename MatrixType>
void rvalue_copyassign(const MatrixType& m)
@@ -94,19 +124,24 @@
MatrixType d = m;
VERIFY_IS_EQUAL(d, m);
- // rvalue reference is moved
+ // rvalue reference is moved - copy constructor.
MatrixType e_src(m);
VERIFY_IS_EQUAL(e_src, m);
MatrixType e_dst(std::move(e_src));
- VERIFY_IS_EQUAL(e_src, MatrixType());
VERIFY_IS_EQUAL(e_dst, m);
- // rvalue reference is moved
+ // rvalue reference is moved - copy constructor.
MatrixType f_src(m);
VERIFY_IS_EQUAL(f_src, m);
MatrixType f_dst = std::move(f_src);
- VERIFY_IS_EQUAL(f_src, MatrixType());
VERIFY_IS_EQUAL(f_dst, m);
+
+ // rvalue reference is moved - copy assignment.
+ MatrixType g_src(m);
+ VERIFY_IS_EQUAL(g_src, m);
+ MatrixType g_dst;
+ g_dst = std::move(g_src);
+ VERIFY_IS_EQUAL(g_dst, m);
}
#else
template <typename MatrixType>
@@ -144,6 +179,8 @@
#if EIGEN_HAS_CXX11
CALL_SUBTEST_5(rvalue_move(Eigen::Matrix<MovableScalar<float>,1,3>::Random().eval()));
+ CALL_SUBTEST_5(rvalue_move(Eigen::Matrix<SafeScalar<float>,1,3>::Random().eval()));
+ CALL_SUBTEST_5(rvalue_move(Eigen::Matrix<SafeScalar<float>,Eigen::Dynamic,Eigen::Dynamic>::Random(1,3).eval()));
#endif
}
}
diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp
index f7ad930..9453111 100644
--- a/test/sparse_basic.cpp
+++ b/test/sparse_basic.cpp
@@ -688,7 +688,7 @@
typedef Triplet<Scalar,Index> TripletType;
std::vector<TripletType> triplets;
double nelements = density * rows*cols;
- VERIFY(nelements>=0 && nelements < NumTraits<StorageIndex>::highest());
+ VERIFY(nelements>=0 && nelements < static_cast<double>(NumTraits<StorageIndex>::highest()));
Index ntriplets = Index(nelements);
triplets.reserve(ntriplets);
Scalar sum = Scalar(0);
diff --git a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h
index 200f58b..8cac2bb 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h
@@ -402,14 +402,13 @@
#if EIGEN_HAS_RVALUE_REFERENCES
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Tensor(Self&& other)
- : Tensor()
+ : m_storage(std::move(other.m_storage))
{
- m_storage.swap(other.m_storage);
}
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Tensor& operator=(Self&& other)
{
- m_storage.swap(other.m_storage);
+ m_storage = std::move(other.m_storage);
return *this;
}
#endif
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h b/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h
index 656fd21..5ff0880 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h
@@ -108,6 +108,20 @@
return *this;
}
+#if EIGEN_HAS_RVALUE_REFERENCES
+ EIGEN_DEVICE_FUNC TensorStorage(Self&& other) : TensorStorage()
+ {
+ *this = std::move(other);
+ }
+
+ EIGEN_DEVICE_FUNC Self& operator=(Self&& other)
+ {
+ numext::swap(m_data, other.m_data);
+ numext::swap(m_dimensions, other.m_dimensions);
+ return *this;
+ }
+#endif
+
EIGEN_DEVICE_FUNC ~TensorStorage() { internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, internal::array_prod(m_dimensions)); }
EIGEN_DEVICE_FUNC void swap(Self& other)
{ numext::swap(m_data,other.m_data); numext::swap(m_dimensions,other.m_dimensions); }
diff --git a/unsupported/test/cxx11_tensor_move.cpp b/unsupported/test/cxx11_tensor_move.cpp
index 0ab2b77..a298231 100644
--- a/unsupported/test/cxx11_tensor_move.cpp
+++ b/unsupported/test/cxx11_tensor_move.cpp
@@ -62,14 +62,9 @@
moved_tensor3 = std::move(moved_tensor1);
moved_tensor4 = std::move(moved_tensor2);
- VERIFY_IS_EQUAL(moved_tensor1.size(), 8);
- VERIFY_IS_EQUAL(moved_tensor2.size(), 8);
-
for (int i = 0; i < 8; i++)
{
calc_indices(i, x, y, z);
- VERIFY_IS_EQUAL(moved_tensor1(x,y,z), 0);
- VERIFY_IS_EQUAL(moved_tensor2(x,y,z), 0);
VERIFY_IS_EQUAL(moved_tensor3(x,y,z), i);
VERIFY_IS_EQUAL(moved_tensor4(x,y,z), 2 * i);
}