mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-04-16 06:39:37 +08:00
Fix "unary minus operator applied to unsigned type, result still unsigned" on MSVC and other stupid warnings
This commit is contained in:
parent
dcdb0233c1
commit
122befe54c
@ -335,12 +335,9 @@ EIGEN_DEVICE_FUNC inline Packet psub(const Packet& a, const Packet& b) {
|
||||
/** \internal \returns -a (coeff-wise) */
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC inline Packet pnegate(const Packet& a) {
|
||||
return -a;
|
||||
}
|
||||
|
||||
template <>
|
||||
EIGEN_DEVICE_FUNC inline bool pnegate(const bool& a) {
|
||||
return !a;
|
||||
EIGEN_STATIC_ASSERT((!is_same<typename unpacket_traits<Packet>::type, bool>::value),
|
||||
NEGATE IS NOT DEFINED FOR BOOLEAN TYPES)
|
||||
return numext::negate(a);
|
||||
}
|
||||
|
||||
/** \internal \returns conj(a) (coeff-wise) */
|
||||
@ -1117,8 +1114,9 @@ EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog10(const Packet&
|
||||
/** \internal \returns the log10 of \a a (coeff-wise) */
|
||||
template <typename Packet>
|
||||
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog2(const Packet& a) {
|
||||
typedef typename internal::unpacket_traits<Packet>::type Scalar;
|
||||
return pmul(pset1<Packet>(Scalar(EIGEN_LOG2E)), plog(a));
|
||||
using Scalar = typename internal::unpacket_traits<Packet>::type;
|
||||
using RealScalar = typename NumTraits<Scalar>::Real;
|
||||
return pmul(pset1<Packet>(Scalar(RealScalar(EIGEN_LOG2E))), plog(a));
|
||||
}
|
||||
|
||||
/** \internal \returns the square-root of \a a (coeff-wise) */
|
||||
@ -1403,6 +1401,12 @@ EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet, 1>& /*kernel*/) {
|
||||
template <size_t N>
|
||||
struct Selector {
|
||||
bool select[N];
|
||||
template <typename MaskType = int>
|
||||
EIGEN_DEVICE_FUNC inline MaskType mask(size_t begin = 0, size_t end = N) const {
|
||||
MaskType res = 0;
|
||||
for (size_t i = begin; i < end; i++) res |= (static_cast<MaskType>(select[i]) << i);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Packet>
|
||||
|
@ -861,6 +861,25 @@ struct sign_retval {
|
||||
typedef Scalar type;
|
||||
};
|
||||
|
||||
// suppress "unary minus operator applied to unsigned type, result still unsigned" warnings on MSVC
|
||||
// note: `0 - a` is distinct from `-a` when Scalar is a floating point type and `a` is zero
|
||||
|
||||
template <typename Scalar, bool IsInteger = NumTraits<Scalar>::IsInteger>
|
||||
struct negate_impl {
|
||||
static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar run(const Scalar& a) { return -a; }
|
||||
};
|
||||
|
||||
template <typename Scalar>
|
||||
struct negate_impl<Scalar, true> {
|
||||
EIGEN_STATIC_ASSERT((!is_same<Scalar, bool>::value), NEGATE IS NOT DEFINED FOR BOOLEAN TYPES)
|
||||
static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar run(const Scalar& a) { return Scalar(0) - a; }
|
||||
};
|
||||
|
||||
template <typename Scalar>
|
||||
struct negate_retval {
|
||||
typedef Scalar type;
|
||||
};
|
||||
|
||||
template <typename Scalar, bool IsInteger = NumTraits<typename unpacket_traits<Scalar>::type>::IsInteger>
|
||||
struct nearest_integer_impl {
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_floor(const Scalar& x) {
|
||||
@ -1066,6 +1085,11 @@ EIGEN_DEVICE_FUNC inline EIGEN_MATHFUNC_RETVAL(sign, Scalar) sign(const Scalar&
|
||||
return EIGEN_MATHFUNC_IMPL(sign, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template <typename Scalar>
|
||||
EIGEN_DEVICE_FUNC inline EIGEN_MATHFUNC_RETVAL(negate, Scalar) negate(const Scalar& x) {
|
||||
return EIGEN_MATHFUNC_IMPL(negate, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template <typename Scalar>
|
||||
EIGEN_DEVICE_FUNC inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x) {
|
||||
return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
|
||||
|
@ -2147,20 +2147,13 @@ EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet16i, 4>& kernel) {
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet16f pblend(const Selector<16>& ifPacket, const Packet16f& thenPacket,
|
||||
const Packet16f& elsePacket) {
|
||||
__mmask16 m = (ifPacket.select[0]) | (ifPacket.select[1] << 1) | (ifPacket.select[2] << 2) |
|
||||
(ifPacket.select[3] << 3) | (ifPacket.select[4] << 4) | (ifPacket.select[5] << 5) |
|
||||
(ifPacket.select[6] << 6) | (ifPacket.select[7] << 7) | (ifPacket.select[8] << 8) |
|
||||
(ifPacket.select[9] << 9) | (ifPacket.select[10] << 10) | (ifPacket.select[11] << 11) |
|
||||
(ifPacket.select[12] << 12) | (ifPacket.select[13] << 13) | (ifPacket.select[14] << 14) |
|
||||
(ifPacket.select[15] << 15);
|
||||
__mmask16 m = ifPacket.mask<__mmask16>();
|
||||
return _mm512_mask_blend_ps(m, elsePacket, thenPacket);
|
||||
}
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet8d pblend(const Selector<8>& ifPacket, const Packet8d& thenPacket,
|
||||
const Packet8d& elsePacket) {
|
||||
__mmask8 m = (ifPacket.select[0]) | (ifPacket.select[1] << 1) | (ifPacket.select[2] << 2) |
|
||||
(ifPacket.select[3] << 3) | (ifPacket.select[4] << 4) | (ifPacket.select[5] << 5) |
|
||||
(ifPacket.select[6] << 6) | (ifPacket.select[7] << 7);
|
||||
__mmask8 m = ifPacket.mask<__mmask8>();
|
||||
return _mm512_mask_blend_pd(m, elsePacket, thenPacket);
|
||||
}
|
||||
|
||||
|
@ -296,6 +296,7 @@ struct packet_traits<bool> : default_packet_traits {
|
||||
HasMax = 0,
|
||||
HasConj = 0,
|
||||
HasSqrt = 1,
|
||||
HasNegate = 0,
|
||||
HasSign = 0 // Don't try to vectorize psign<bool> = identity.
|
||||
};
|
||||
};
|
||||
@ -601,11 +602,6 @@ EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a) {
|
||||
return psub(pzero(a), a);
|
||||
}
|
||||
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet16b pnegate(const Packet16b& a) {
|
||||
return a;
|
||||
}
|
||||
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet4f pconj(const Packet4f& a) {
|
||||
return a;
|
||||
|
@ -24,7 +24,7 @@ namespace internal {
|
||||
*/
|
||||
template <typename Scalar>
|
||||
struct scalar_opposite_op {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(const Scalar& a) const { return -a; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(const Scalar& a) const { return numext::negate(a); }
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const {
|
||||
return internal::pnegate(a);
|
||||
@ -455,8 +455,9 @@ struct functor_traits<scalar_log10_op<Scalar>> {
|
||||
*/
|
||||
template <typename Scalar>
|
||||
struct scalar_log2_op {
|
||||
using RealScalar = typename NumTraits<Scalar>::Real;
|
||||
EIGEN_DEVICE_FUNC inline const Scalar operator()(const Scalar& a) const {
|
||||
return Scalar(EIGEN_LOG2E) * numext::log(a);
|
||||
return Scalar(RealScalar(EIGEN_LOG2E)) * numext::log(a);
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const {
|
||||
|
@ -614,9 +614,9 @@ void array_generic(const ArrayType& m) {
|
||||
VERIFY(o2.cols() == cols);
|
||||
|
||||
ArrayType2 o3(rows, cols);
|
||||
VERIFY(o3(0) == Scalar(rows) && o3(1) == Scalar(cols));
|
||||
VERIFY(o3(0) == RealScalar(rows) && o3(1) == RealScalar(cols));
|
||||
ArrayType2 o4(static_cast<int>(rows), static_cast<int>(cols));
|
||||
VERIFY(o4(0) == Scalar(rows) && o4(1) == Scalar(cols));
|
||||
VERIFY(o4(0) == RealScalar(rows) && o4(1) == RealScalar(cols));
|
||||
}
|
||||
{
|
||||
TwoDArrayType o1{rows, cols};
|
||||
@ -627,9 +627,9 @@ void array_generic(const ArrayType& m) {
|
||||
VERIFY(o2.cols() == cols);
|
||||
|
||||
ArrayType2 o3{rows, cols};
|
||||
VERIFY(o3(0) == Scalar(rows) && o3(1) == Scalar(cols));
|
||||
VERIFY(o3(0) == RealScalar(rows) && o3(1) == RealScalar(cols));
|
||||
ArrayType2 o4{int(rows), int(cols)};
|
||||
VERIFY(o4(0) == Scalar(rows) && o4(1) == Scalar(cols));
|
||||
VERIFY(o4(0) == RealScalar(rows) && o4(1) == RealScalar(cols));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ void test_conversion() {
|
||||
// Conversion to bool
|
||||
VERIFY_IS_EQUAL(static_cast<bool>(bfloat16(3)), true);
|
||||
VERIFY_IS_EQUAL(static_cast<bool>(bfloat16(0.33333f)), true);
|
||||
VERIFY_IS_EQUAL(bfloat16(-0.0), false);
|
||||
VERIFY_IS_EQUAL(static_cast<bool>(bfloat16(-0.0)), false);
|
||||
VERIFY_IS_EQUAL(static_cast<bool>(bfloat16(0.0)), false);
|
||||
|
||||
// Explicit conversion to float.
|
||||
|
@ -23,6 +23,7 @@ void verify_euler(const Matrix<Scalar, 3, 1>& ea, int i, int j, int k) {
|
||||
typedef AngleAxis<Scalar> AngleAxisx;
|
||||
const Matrix3 m(AngleAxisx(ea[0], Vector3::Unit(i)) * AngleAxisx(ea[1], Vector3::Unit(j)) *
|
||||
AngleAxisx(ea[2], Vector3::Unit(k)));
|
||||
const Scalar kPi = Scalar(EIGEN_PI);
|
||||
|
||||
// Test non-canonical eulerAngles
|
||||
{
|
||||
@ -33,11 +34,11 @@ void verify_euler(const Matrix<Scalar, 3, 1>& ea, int i, int j, int k) {
|
||||
|
||||
// approx_or_less_than does not work for 0
|
||||
VERIFY(0 < eabis[0] || test_isMuchSmallerThan(eabis[0], Scalar(1)));
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(eabis[0], Scalar(EIGEN_PI));
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(-Scalar(EIGEN_PI), eabis[1]);
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(eabis[1], Scalar(EIGEN_PI));
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(-Scalar(EIGEN_PI), eabis[2]);
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(eabis[2], Scalar(EIGEN_PI));
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(eabis[0], kPi);
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(-kPi, eabis[1]);
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(eabis[1], kPi);
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(-kPi, eabis[2]);
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(eabis[2], kPi);
|
||||
}
|
||||
|
||||
// Test canonicalEulerAngles
|
||||
@ -47,20 +48,20 @@ void verify_euler(const Matrix<Scalar, 3, 1>& ea, int i, int j, int k) {
|
||||
AngleAxisx(eabis[2], Vector3::Unit(k)));
|
||||
VERIFY_IS_APPROX(m, mbis);
|
||||
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(-Scalar(EIGEN_PI), eabis[0]);
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(eabis[0], Scalar(EIGEN_PI));
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(-kPi, eabis[0]);
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(eabis[0], kPi);
|
||||
if (i != k) {
|
||||
// Tait-Bryan sequence
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(-Scalar(EIGEN_PI / 2), eabis[1]);
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(eabis[1], Scalar(EIGEN_PI / 2));
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(-Scalar(kPi / 2), eabis[1]);
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(eabis[1], Scalar(kPi / 2));
|
||||
} else {
|
||||
// Proper Euler sequence
|
||||
// approx_or_less_than does not work for 0
|
||||
VERIFY(0 < eabis[1] || test_isMuchSmallerThan(eabis[1], Scalar(1)));
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(eabis[1], Scalar(EIGEN_PI));
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(eabis[1], kPi);
|
||||
}
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(-Scalar(EIGEN_PI), eabis[2]);
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(eabis[2], Scalar(EIGEN_PI));
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(-kPi, eabis[2]);
|
||||
VERIFY_IS_APPROX_OR_LESS_THAN(eabis[2], kPi);
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,7 +101,10 @@ void eulerangles() {
|
||||
typedef Quaternion<Scalar> Quaternionx;
|
||||
typedef AngleAxis<Scalar> AngleAxisx;
|
||||
|
||||
Scalar a = internal::random<Scalar>(-Scalar(EIGEN_PI), Scalar(EIGEN_PI));
|
||||
const Scalar kPi = Scalar(EIGEN_PI);
|
||||
const Scalar smallVal = static_cast<Scalar>(0.001);
|
||||
|
||||
Scalar a = internal::random<Scalar>(-kPi, kPi);
|
||||
Quaternionx q1;
|
||||
q1 = AngleAxisx(a, Vector3::Random().normalized());
|
||||
Matrix3 m;
|
||||
@ -120,65 +124,65 @@ void eulerangles() {
|
||||
check_all_var(ea);
|
||||
|
||||
// Check with random angles in range [-pi:pi]x[-pi:pi]x[-pi:pi].
|
||||
ea = Array3::Random() * Scalar(EIGEN_PI);
|
||||
ea = Array3::Random() * kPi;
|
||||
check_all_var(ea);
|
||||
|
||||
auto test_with_some_zeros = [](const Vector3& eaz) {
|
||||
auto test_with_some_zeros = [=](const Vector3& eaz) {
|
||||
check_all_var(eaz);
|
||||
Vector3 ea_glz = eaz;
|
||||
ea_glz[0] = Scalar(0);
|
||||
check_all_var(ea_glz);
|
||||
ea_glz[0] = internal::random<Scalar>(-0.001, 0.001);
|
||||
ea_glz[0] = internal::random<Scalar>(-smallVal, smallVal);
|
||||
check_all_var(ea_glz);
|
||||
ea_glz[2] = Scalar(0);
|
||||
check_all_var(ea_glz);
|
||||
ea_glz[2] = internal::random<Scalar>(-0.001, 0.001);
|
||||
ea_glz[2] = internal::random<Scalar>(-smallVal, smallVal);
|
||||
check_all_var(ea_glz);
|
||||
};
|
||||
// Check gimbal lock configurations and a bit noisy gimbal locks
|
||||
Vector3 ea_gl = ea;
|
||||
ea_gl[1] = EIGEN_PI / 2;
|
||||
ea_gl[1] = kPi / 2;
|
||||
test_with_some_zeros(ea_gl);
|
||||
ea_gl[1] += internal::random<Scalar>(-0.001, 0.001);
|
||||
ea_gl[1] += internal::random<Scalar>(-smallVal, smallVal);
|
||||
test_with_some_zeros(ea_gl);
|
||||
ea_gl[1] = -EIGEN_PI / 2;
|
||||
ea_gl[1] = -kPi / 2;
|
||||
test_with_some_zeros(ea_gl);
|
||||
ea_gl[1] += internal::random<Scalar>(-0.001, 0.001);
|
||||
ea_gl[1] += internal::random<Scalar>(-smallVal, smallVal);
|
||||
test_with_some_zeros(ea_gl);
|
||||
ea_gl[1] = EIGEN_PI / 2;
|
||||
ea_gl[1] = kPi / 2;
|
||||
ea_gl[2] = ea_gl[0];
|
||||
test_with_some_zeros(ea_gl);
|
||||
ea_gl[1] += internal::random<Scalar>(-0.001, 0.001);
|
||||
ea_gl[1] += internal::random<Scalar>(-smallVal, smallVal);
|
||||
test_with_some_zeros(ea_gl);
|
||||
ea_gl[1] = -EIGEN_PI / 2;
|
||||
ea_gl[1] = -kPi / 2;
|
||||
test_with_some_zeros(ea_gl);
|
||||
ea_gl[1] += internal::random<Scalar>(-0.001, 0.001);
|
||||
ea_gl[1] += internal::random<Scalar>(-smallVal, smallVal);
|
||||
test_with_some_zeros(ea_gl);
|
||||
|
||||
// Similar to above, but with pi instead of pi/2
|
||||
Vector3 ea_pi = ea;
|
||||
ea_pi[1] = EIGEN_PI;
|
||||
ea_pi[1] = kPi;
|
||||
test_with_some_zeros(ea_gl);
|
||||
ea_pi[1] += internal::random<Scalar>(-0.001, 0.001);
|
||||
ea_pi[1] += internal::random<Scalar>(-smallVal, smallVal);
|
||||
test_with_some_zeros(ea_gl);
|
||||
ea_pi[1] = -EIGEN_PI;
|
||||
ea_pi[1] = -kPi;
|
||||
test_with_some_zeros(ea_gl);
|
||||
ea_pi[1] += internal::random<Scalar>(-0.001, 0.001);
|
||||
ea_pi[1] += internal::random<Scalar>(-smallVal, smallVal);
|
||||
test_with_some_zeros(ea_gl);
|
||||
ea_pi[1] = EIGEN_PI;
|
||||
ea_pi[1] = kPi;
|
||||
ea_pi[2] = ea_pi[0];
|
||||
test_with_some_zeros(ea_gl);
|
||||
ea_pi[1] += internal::random<Scalar>(-0.001, 0.001);
|
||||
ea_pi[1] += internal::random<Scalar>(-smallVal, smallVal);
|
||||
test_with_some_zeros(ea_gl);
|
||||
ea_pi[1] = -EIGEN_PI;
|
||||
ea_pi[1] = -kPi;
|
||||
test_with_some_zeros(ea_gl);
|
||||
ea_pi[1] += internal::random<Scalar>(-0.001, 0.001);
|
||||
ea_pi[1] += internal::random<Scalar>(-smallVal, smallVal);
|
||||
test_with_some_zeros(ea_gl);
|
||||
|
||||
ea[2] = ea[0] = internal::random<Scalar>(0, Scalar(EIGEN_PI));
|
||||
ea[2] = ea[0] = internal::random<Scalar>(0, kPi);
|
||||
check_all_var(ea);
|
||||
|
||||
ea[0] = ea[1] = internal::random<Scalar>(0, Scalar(EIGEN_PI));
|
||||
ea[0] = ea[1] = internal::random<Scalar>(0, kPi);
|
||||
check_all_var(ea);
|
||||
|
||||
ea[1] = 0;
|
||||
|
@ -790,6 +790,7 @@ void check_tutorial_examples() {
|
||||
VERIFY_IS_EQUAL(int(slice1.SizeAtCompileTime), 6);
|
||||
VERIFY_IS_EQUAL(int(slice2.SizeAtCompileTime), 6);
|
||||
auto slice3 = A(all, seq(fix<0>, last, fix<2>));
|
||||
TEST_SET_BUT_UNUSED_VARIABLE(slice3)
|
||||
VERIFY_IS_EQUAL(int(slice3.RowsAtCompileTime), kRows);
|
||||
VERIFY_IS_EQUAL(int(slice3.ColsAtCompileTime), (kCols + 1) / 2);
|
||||
}
|
||||
|
@ -9,21 +9,14 @@
|
||||
|
||||
#include "main.h"
|
||||
|
||||
// GCC<=4.8 has spurious shadow warnings, because `ptr` re-appears inside template instantiations
|
||||
// workaround: put these in an anonymous namespace
|
||||
namespace {
|
||||
float* ptr;
|
||||
const float* const_ptr;
|
||||
} // namespace
|
||||
|
||||
template <typename PlainObjectType, bool IsDynamicSize = PlainObjectType::SizeAtCompileTime == Dynamic,
|
||||
bool IsVector = PlainObjectType::IsVectorAtCompileTime>
|
||||
struct mapstaticmethods_impl {};
|
||||
|
||||
template <typename PlainObjectType, bool IsVector>
|
||||
struct mapstaticmethods_impl<PlainObjectType, false, IsVector> {
|
||||
static void run(const PlainObjectType& m) {
|
||||
mapstaticmethods_impl<PlainObjectType, true, IsVector>::run(m);
|
||||
static void run(const PlainObjectType& m, float* ptr, const float* const_ptr) {
|
||||
mapstaticmethods_impl<PlainObjectType, true, IsVector>::run(m, ptr, const_ptr);
|
||||
|
||||
int i = internal::random<int>(2, 5), j = internal::random<int>(2, 5);
|
||||
|
||||
@ -66,7 +59,7 @@ struct mapstaticmethods_impl<PlainObjectType, false, IsVector> {
|
||||
|
||||
template <typename PlainObjectType>
|
||||
struct mapstaticmethods_impl<PlainObjectType, true, false> {
|
||||
static void run(const PlainObjectType& m) {
|
||||
static void run(const PlainObjectType& m, float* ptr, const float* const_ptr) {
|
||||
Index rows = m.rows(), cols = m.cols();
|
||||
|
||||
int i = internal::random<int>(2, 5), j = internal::random<int>(2, 5);
|
||||
@ -110,7 +103,7 @@ struct mapstaticmethods_impl<PlainObjectType, true, false> {
|
||||
|
||||
template <typename PlainObjectType>
|
||||
struct mapstaticmethods_impl<PlainObjectType, true, true> {
|
||||
static void run(const PlainObjectType& v) {
|
||||
static void run(const PlainObjectType& v, float* ptr, const float* const_ptr) {
|
||||
Index size = v.size();
|
||||
|
||||
int i = internal::random<int>(2, 5);
|
||||
@ -133,34 +126,34 @@ struct mapstaticmethods_impl<PlainObjectType, true, true> {
|
||||
};
|
||||
|
||||
template <typename PlainObjectType>
|
||||
void mapstaticmethods(const PlainObjectType& m) {
|
||||
mapstaticmethods_impl<PlainObjectType>::run(m);
|
||||
void mapstaticmethods(const PlainObjectType& m, float* ptr, const float* const_ptr) {
|
||||
mapstaticmethods_impl<PlainObjectType>::run(m, ptr, const_ptr);
|
||||
VERIFY(true); // just to avoid 'unused function' warning
|
||||
}
|
||||
|
||||
EIGEN_DECLARE_TEST(mapstaticmethods) {
|
||||
ptr = internal::aligned_new<float>(1000);
|
||||
float* ptr = internal::aligned_new<float>(1000);
|
||||
for (int i = 0; i < 1000; i++) ptr[i] = float(i);
|
||||
|
||||
const_ptr = ptr;
|
||||
const float* const_ptr = ptr;
|
||||
|
||||
CALL_SUBTEST_1((mapstaticmethods(Matrix<float, 1, 1>())));
|
||||
CALL_SUBTEST_1((mapstaticmethods(Vector2f())));
|
||||
CALL_SUBTEST_2((mapstaticmethods(Vector3f())));
|
||||
CALL_SUBTEST_2((mapstaticmethods(Matrix2f())));
|
||||
CALL_SUBTEST_3((mapstaticmethods(Matrix4f())));
|
||||
CALL_SUBTEST_3((mapstaticmethods(Array4f())));
|
||||
CALL_SUBTEST_4((mapstaticmethods(Array3f())));
|
||||
CALL_SUBTEST_4((mapstaticmethods(Array33f())));
|
||||
CALL_SUBTEST_5((mapstaticmethods(Array44f())));
|
||||
CALL_SUBTEST_5((mapstaticmethods(VectorXf(1))));
|
||||
CALL_SUBTEST_5((mapstaticmethods(VectorXf(8))));
|
||||
CALL_SUBTEST_6((mapstaticmethods(MatrixXf(1, 1))));
|
||||
CALL_SUBTEST_6((mapstaticmethods(MatrixXf(5, 7))));
|
||||
CALL_SUBTEST_7((mapstaticmethods(ArrayXf(1))));
|
||||
CALL_SUBTEST_7((mapstaticmethods(ArrayXf(5))));
|
||||
CALL_SUBTEST_8((mapstaticmethods(ArrayXXf(1, 1))));
|
||||
CALL_SUBTEST_8((mapstaticmethods(ArrayXXf(8, 6))));
|
||||
CALL_SUBTEST_1((mapstaticmethods(Matrix<float, 1, 1>(), ptr, const_ptr)));
|
||||
CALL_SUBTEST_1((mapstaticmethods(Vector2f(), ptr, const_ptr)));
|
||||
CALL_SUBTEST_2((mapstaticmethods(Vector3f(), ptr, const_ptr)));
|
||||
CALL_SUBTEST_2((mapstaticmethods(Matrix2f(), ptr, const_ptr)));
|
||||
CALL_SUBTEST_3((mapstaticmethods(Matrix4f(), ptr, const_ptr)));
|
||||
CALL_SUBTEST_3((mapstaticmethods(Array4f(), ptr, const_ptr)));
|
||||
CALL_SUBTEST_4((mapstaticmethods(Array3f(), ptr, const_ptr)));
|
||||
CALL_SUBTEST_4((mapstaticmethods(Array33f(), ptr, const_ptr)));
|
||||
CALL_SUBTEST_5((mapstaticmethods(Array44f(), ptr, const_ptr)));
|
||||
CALL_SUBTEST_5((mapstaticmethods(VectorXf(1), ptr, const_ptr)));
|
||||
CALL_SUBTEST_5((mapstaticmethods(VectorXf(8), ptr, const_ptr)));
|
||||
CALL_SUBTEST_6((mapstaticmethods(MatrixXf(1, 1), ptr, const_ptr)));
|
||||
CALL_SUBTEST_6((mapstaticmethods(MatrixXf(5, 7), ptr, const_ptr)));
|
||||
CALL_SUBTEST_7((mapstaticmethods(ArrayXf(1), ptr, const_ptr)));
|
||||
CALL_SUBTEST_7((mapstaticmethods(ArrayXf(5), ptr, const_ptr)));
|
||||
CALL_SUBTEST_8((mapstaticmethods(ArrayXXf(1, 1), ptr, const_ptr)));
|
||||
CALL_SUBTEST_8((mapstaticmethods(ArrayXXf(8, 6), ptr, const_ptr)));
|
||||
|
||||
internal::aligned_delete(ptr, 1000);
|
||||
}
|
||||
|
@ -33,27 +33,47 @@ bool test_is_equal_or_nans(const T& actual, const U& expected) {
|
||||
|
||||
#define VERIFY_IS_EQUAL_OR_NANS(a, b) VERIFY(test_is_equal_or_nans(a, b))
|
||||
|
||||
template <typename T>
|
||||
void check_negate() {
|
||||
Index size = 1000;
|
||||
for (Index i = 0; i < size; i++) {
|
||||
T val = i == 0 ? T(0) : internal::random<T>(T(0), NumTraits<T>::highest());
|
||||
T neg_val = numext::negate(val);
|
||||
VERIFY_IS_EQUAL(T(val + neg_val), T(0));
|
||||
VERIFY_IS_EQUAL(numext::negate(neg_val), val);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void check_abs() {
|
||||
typedef typename NumTraits<T>::Real Real;
|
||||
Real zero(0);
|
||||
|
||||
if (NumTraits<T>::IsSigned) VERIFY_IS_EQUAL(numext::abs(-T(1)), T(1));
|
||||
if (NumTraits<T>::IsSigned) VERIFY_IS_EQUAL(numext::abs(numext::negate(T(1))), T(1));
|
||||
VERIFY_IS_EQUAL(numext::abs(T(0)), T(0));
|
||||
VERIFY_IS_EQUAL(numext::abs(T(1)), T(1));
|
||||
|
||||
for (int k = 0; k < 100; ++k) {
|
||||
T x = internal::random<T>();
|
||||
if (!internal::is_same<T, bool>::value) x = x / Real(2);
|
||||
x = x / Real(2);
|
||||
if (NumTraits<T>::IsSigned) {
|
||||
VERIFY_IS_EQUAL(numext::abs(x), numext::abs(-x));
|
||||
VERIFY(numext::abs(-x) >= zero);
|
||||
VERIFY_IS_EQUAL(numext::abs(x), numext::abs(numext::negate(x)));
|
||||
VERIFY(numext::abs(numext::negate(x)) >= zero);
|
||||
}
|
||||
VERIFY(numext::abs(x) >= zero);
|
||||
VERIFY_IS_APPROX(numext::abs2(x), numext::abs2(numext::abs(x)));
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void check_abs<bool>() {
|
||||
for (bool x : {true, false}) {
|
||||
VERIFY_IS_EQUAL(numext::abs(x), x);
|
||||
VERIFY(numext::abs(x) >= false);
|
||||
VERIFY_IS_EQUAL(numext::abs2(x), numext::abs2(numext::abs(x)));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void check_arg() {
|
||||
typedef typename NumTraits<T>::Real Real;
|
||||
@ -236,16 +256,17 @@ struct check_signbit_impl {
|
||||
negative_values = {static_cast<T>(-1), static_cast<T>(NumTraits<T>::lowest())};
|
||||
non_negative_values = {static_cast<T>(0), static_cast<T>(1), static_cast<T>(NumTraits<T>::highest())};
|
||||
} else {
|
||||
// has sign bit
|
||||
const T neg_zero = static_cast<T>(-0.0);
|
||||
const T neg_one = static_cast<T>(-1.0);
|
||||
const T neg_inf = -std::numeric_limits<T>::infinity();
|
||||
const T neg_nan = -std::numeric_limits<T>::quiet_NaN();
|
||||
// does not have sign bit
|
||||
const T pos_zero = static_cast<T>(0.0);
|
||||
const T pos_one = static_cast<T>(1.0);
|
||||
const T pos_inf = std::numeric_limits<T>::infinity();
|
||||
const T pos_nan = std::numeric_limits<T>::quiet_NaN();
|
||||
// has sign bit
|
||||
const T neg_zero = numext::negate(pos_zero);
|
||||
const T neg_one = numext::negate(pos_one);
|
||||
const T neg_inf = numext::negate(pos_inf);
|
||||
const T neg_nan = numext::negate(pos_nan);
|
||||
|
||||
negative_values = {neg_zero, neg_one, neg_inf, neg_nan};
|
||||
non_negative_values = {pos_zero, pos_one, pos_inf, pos_nan};
|
||||
}
|
||||
@ -273,6 +294,22 @@ void check_signbit() {
|
||||
|
||||
EIGEN_DECLARE_TEST(numext) {
|
||||
for (int k = 0; k < g_repeat; ++k) {
|
||||
CALL_SUBTEST(check_negate<signed char>());
|
||||
CALL_SUBTEST(check_negate<unsigned char>());
|
||||
CALL_SUBTEST(check_negate<short>());
|
||||
CALL_SUBTEST(check_negate<unsigned short>());
|
||||
CALL_SUBTEST(check_negate<int>());
|
||||
CALL_SUBTEST(check_negate<unsigned int>());
|
||||
CALL_SUBTEST(check_negate<long>());
|
||||
CALL_SUBTEST(check_negate<unsigned long>());
|
||||
CALL_SUBTEST(check_negate<half>());
|
||||
CALL_SUBTEST(check_negate<bfloat16>());
|
||||
CALL_SUBTEST(check_negate<float>());
|
||||
CALL_SUBTEST(check_negate<double>());
|
||||
CALL_SUBTEST(check_negate<long double>());
|
||||
CALL_SUBTEST(check_negate<std::complex<float> >());
|
||||
CALL_SUBTEST(check_negate<std::complex<double> >());
|
||||
|
||||
CALL_SUBTEST(check_abs<bool>());
|
||||
CALL_SUBTEST(check_abs<signed char>());
|
||||
CALL_SUBTEST(check_abs<unsigned char>());
|
||||
|
@ -34,11 +34,11 @@ inline T REF_MSUB(const T& a, const T& b, const T& c) {
|
||||
}
|
||||
template <typename T>
|
||||
inline T REF_NMADD(const T& a, const T& b, const T& c) {
|
||||
return (-a * b) + c;
|
||||
return c - a * b;
|
||||
}
|
||||
template <typename T>
|
||||
inline T REF_NMSUB(const T& a, const T& b, const T& c) {
|
||||
return (-a * b) - c;
|
||||
return test::negate(a * b + c);
|
||||
}
|
||||
template <typename T>
|
||||
inline T REF_DIV(const T& a, const T& b) {
|
||||
@ -427,6 +427,32 @@ struct eigen_optimization_barrier_test<
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Scalar, typename Packet, bool HasNegate = internal::packet_traits<Scalar>::HasNegate>
|
||||
struct negate_test_impl {
|
||||
static void run_negate(Scalar* data1, Scalar* data2, Scalar* ref, int PacketSize) {
|
||||
CHECK_CWISE1_IF(HasNegate, test::negate, internal::pnegate);
|
||||
}
|
||||
static void run_nmsub(Scalar* data1, Scalar* data2, Scalar* ref, int PacketSize) {
|
||||
CHECK_CWISE3_IF(HasNegate, REF_NMSUB, internal::pnmsub);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Scalar, typename Packet>
|
||||
struct negate_test_impl<Scalar, Packet, false> {
|
||||
static void run_negate(Scalar*, Scalar*, Scalar*, int) {}
|
||||
static void run_nmsub(Scalar*, Scalar*, Scalar*, int) {}
|
||||
};
|
||||
|
||||
template <typename Scalar, typename Packet>
|
||||
void negate_test(Scalar* data1, Scalar* data2, Scalar* ref, int size) {
|
||||
negate_test_impl<Scalar, Packet>::run_negate(data1, data2, ref, size);
|
||||
}
|
||||
|
||||
template <typename Scalar, typename Packet>
|
||||
void nmsub_test(Scalar* data1, Scalar* data2, Scalar* ref, int size) {
|
||||
negate_test_impl<Scalar, Packet>::run_negate(data1, data2, ref, size);
|
||||
}
|
||||
|
||||
template <typename Scalar, typename Packet>
|
||||
void packetmath() {
|
||||
typedef internal::packet_traits<Scalar> PacketTraits;
|
||||
@ -533,7 +559,7 @@ void packetmath() {
|
||||
CHECK_CWISE2_IF(PacketTraits::HasMul, REF_MUL, internal::pmul);
|
||||
CHECK_CWISE2_IF(PacketTraits::HasDiv, REF_DIV, internal::pdiv);
|
||||
|
||||
CHECK_CWISE1_IF(PacketTraits::HasNegate, test::negate, internal::pnegate);
|
||||
negate_test<Scalar, Packet>(data1, data2, ref, PacketSize);
|
||||
CHECK_CWISE1_IF(PacketTraits::HasReciprocal, REF_RECIPROCAL, internal::preciprocal);
|
||||
CHECK_CWISE1(numext::conj, internal::pconj);
|
||||
CHECK_CWISE1_IF(PacketTraits::HasSign, numext::sign, internal::psign);
|
||||
@ -689,7 +715,7 @@ void packetmath() {
|
||||
CHECK_CWISE1_IF(PacketTraits::HasRsqrt, numext::rsqrt, internal::prsqrt);
|
||||
CHECK_CWISE3_IF(true, REF_MADD, internal::pmadd);
|
||||
if (!std::is_same<Scalar, bool>::value && NumTraits<Scalar>::IsSigned) {
|
||||
CHECK_CWISE3_IF(PacketTraits::HasNegate, REF_NMSUB, internal::pnmsub);
|
||||
nmsub_test<Scalar, Packet>(data1, data2, ref, PacketSize);
|
||||
}
|
||||
|
||||
// For pmsub, pnmadd, the values can cancel each other to become near zero,
|
||||
@ -698,11 +724,11 @@ void packetmath() {
|
||||
for (int i = 0; i < PacketSize; ++i) {
|
||||
data1[i] = numext::abs(internal::random<Scalar>());
|
||||
data1[i + PacketSize] = numext::abs(internal::random<Scalar>());
|
||||
data1[i + 2 * PacketSize] = -numext::abs(internal::random<Scalar>());
|
||||
data1[i + 2 * PacketSize] = Scalar(0) - numext::abs(internal::random<Scalar>());
|
||||
}
|
||||
if (!std::is_same<Scalar, bool>::value && NumTraits<Scalar>::IsSigned) {
|
||||
CHECK_CWISE3_IF(true, REF_MSUB, internal::pmsub);
|
||||
CHECK_CWISE3_IF(PacketTraits::HasNegate, REF_NMADD, internal::pnmadd);
|
||||
CHECK_CWISE3_IF(true, REF_NMADD, internal::pnmadd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,11 +22,16 @@ namespace Eigen {
|
||||
|
||||
namespace test {
|
||||
|
||||
template <typename T>
|
||||
template <typename T, std::enable_if_t<NumTraits<T>::IsSigned, bool> = true>
|
||||
T negate(const T& x) {
|
||||
return -x;
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<!NumTraits<T>::IsSigned, bool> = true>
|
||||
T negate(const T& x) {
|
||||
return T(0) - x;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Map<const Array<unsigned char, sizeof(T), 1> > bits(const T& x) {
|
||||
return Map<const Array<unsigned char, sizeof(T), 1> >(reinterpret_cast<const unsigned char*>(&x));
|
||||
|
@ -110,29 +110,29 @@ void sparse_vector(int rows, int cols) {
|
||||
|
||||
// test move
|
||||
{
|
||||
SparseVectorType v3(std::move(v1));
|
||||
VERIFY_IS_APPROX(v3, refV1);
|
||||
v1 = v3;
|
||||
SparseVectorType tmp(std::move(v1));
|
||||
VERIFY_IS_APPROX(tmp, refV1);
|
||||
v1 = tmp;
|
||||
}
|
||||
|
||||
{
|
||||
SparseVectorType v3;
|
||||
v3 = std::move(v1);
|
||||
VERIFY_IS_APPROX(v3, refV1);
|
||||
v1 = v3;
|
||||
SparseVectorType tmp;
|
||||
tmp = std::move(v1);
|
||||
VERIFY_IS_APPROX(tmp, refV1);
|
||||
v1 = tmp;
|
||||
}
|
||||
|
||||
{
|
||||
SparseVectorType v3(std::move(mv1));
|
||||
VERIFY_IS_APPROX(v3, refV1);
|
||||
mv1 = v3;
|
||||
SparseVectorType tmp(std::move(mv1));
|
||||
VERIFY_IS_APPROX(tmp, refV1);
|
||||
mv1 = tmp;
|
||||
}
|
||||
|
||||
{
|
||||
SparseVectorType v3;
|
||||
v3 = std::move(mv1);
|
||||
VERIFY_IS_APPROX(v3, refV1);
|
||||
mv1 = v3;
|
||||
SparseVectorType tmp;
|
||||
tmp = std::move(mv1);
|
||||
VERIFY_IS_APPROX(tmp, refV1);
|
||||
mv1 = tmp;
|
||||
}
|
||||
|
||||
// test conservative resize
|
||||
|
@ -287,6 +287,7 @@ template <typename Scalar, bool Enable = !internal::is_same<
|
||||
typename internal::unpacket_traits<typename internal::packet_traits<Scalar>::type>::half,
|
||||
typename internal::packet_traits<Scalar>::type>::value>
|
||||
struct vectorization_logic_half {
|
||||
using RealScalar = typename NumTraits<Scalar>::Real;
|
||||
typedef internal::packet_traits<Scalar> PacketTraits;
|
||||
typedef typename internal::unpacket_traits<typename internal::packet_traits<Scalar>::type>::half PacketType;
|
||||
static constexpr int PacketSize = internal::unpacket_traits<PacketType>::size;
|
||||
@ -355,10 +356,12 @@ struct vectorization_logic_half {
|
||||
VERIFY(test_assign(Vector1(), Vector1().template segment<MinVSize>(0).derived(),
|
||||
EIGEN_UNALIGNED_VECTORIZE ? InnerVectorizedTraversal : LinearVectorizedTraversal,
|
||||
CompleteUnrolling));
|
||||
VERIFY(test_assign(Vector1(), Scalar(2.1) * Vector1() - Vector1(), InnerVectorizedTraversal, CompleteUnrolling));
|
||||
VERIFY(test_assign(Vector1(), Scalar(RealScalar(2.1)) * Vector1() - Vector1(), InnerVectorizedTraversal,
|
||||
CompleteUnrolling));
|
||||
VERIFY(test_assign(
|
||||
Vector1(),
|
||||
(Scalar(2.1) * Vector1().template segment<MinVSize>(0) - Vector1().template segment<MinVSize>(0)).derived(),
|
||||
(Scalar(RealScalar(2.1)) * Vector1().template segment<MinVSize>(0) - Vector1().template segment<MinVSize>(0))
|
||||
.derived(),
|
||||
EIGEN_UNALIGNED_VECTORIZE ? InnerVectorizedTraversal : LinearVectorizedTraversal, CompleteUnrolling));
|
||||
VERIFY(test_assign(Vector1(), Vector1().cwiseProduct(Vector1()), InnerVectorizedTraversal, CompleteUnrolling));
|
||||
VERIFY(test_assign(Vector1(), Vector1().template cast<Scalar>(), InnerVectorizedTraversal, CompleteUnrolling));
|
||||
|
Loading…
x
Reference in New Issue
Block a user