mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
merge with default Eigen
This commit is contained in:
@@ -24,7 +24,7 @@ struct gebp_kernel;
|
||||
template<typename Scalar, typename Index, typename DataMapper, int nr, int StorageOrder, bool Conjugate = false, bool PanelMode=false>
|
||||
struct gemm_pack_rhs;
|
||||
|
||||
template<typename Scalar, typename Index, typename DataMapper, int Pack1, int Pack2, int StorageOrder, bool Conjugate = false, bool PanelMode = false>
|
||||
template<typename Scalar, typename Index, typename DataMapper, int Pack1, int Pack2, typename Packet, int StorageOrder, bool Conjugate = false, bool PanelMode = false>
|
||||
struct gemm_pack_lhs;
|
||||
|
||||
template<
|
||||
@@ -156,11 +156,9 @@ class BlasVectorMapper {
|
||||
};
|
||||
|
||||
template<typename Scalar, typename Index, int AlignmentType>
|
||||
class BlasLinearMapper {
|
||||
public:
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
typedef typename packet_traits<Scalar>::half HalfPacket;
|
||||
|
||||
class BlasLinearMapper
|
||||
{
|
||||
public:
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar *data) : m_data(data) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(int i) const {
|
||||
@@ -171,29 +169,25 @@ class BlasLinearMapper {
|
||||
return m_data[i];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i) const {
|
||||
return ploadt<Packet, AlignmentType>(m_data + i);
|
||||
template<typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacket(Index i) const {
|
||||
return ploadt<PacketType, AlignmentType>(m_data + i);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HalfPacket loadHalfPacket(Index i) const {
|
||||
return ploadt<HalfPacket, AlignmentType>(m_data + i);
|
||||
template<typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, const PacketType &p) const {
|
||||
pstoret<Scalar, PacketType, AlignmentType>(m_data + i, p);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, const Packet &p) const {
|
||||
pstoret<Scalar, Packet, AlignmentType>(m_data + i, p);
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
Scalar *m_data;
|
||||
};
|
||||
|
||||
// Lightweight helper class to access matrix coefficients.
|
||||
template<typename Scalar, typename Index, int StorageOrder, int AlignmentType = Unaligned>
|
||||
class blas_data_mapper {
|
||||
public:
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
typedef typename packet_traits<Scalar>::half HalfPacket;
|
||||
|
||||
class blas_data_mapper
|
||||
{
|
||||
public:
|
||||
typedef BlasLinearMapper<Scalar, Index, AlignmentType> LinearMapper;
|
||||
typedef BlasVectorMapper<Scalar, Index> VectorMapper;
|
||||
|
||||
@@ -218,8 +212,9 @@ class blas_data_mapper {
|
||||
return m_data[StorageOrder==RowMajor ? j + i*m_stride : i + j*m_stride];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i, Index j) const {
|
||||
return ploadt<Packet, AlignmentType>(&operator()(i, j));
|
||||
template<typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacket(Index i, Index j) const {
|
||||
return ploadt<PacketType, AlignmentType>(&operator()(i, j));
|
||||
}
|
||||
|
||||
template <typename PacketT, int AlignmentT>
|
||||
@@ -227,10 +222,6 @@ class blas_data_mapper {
|
||||
return ploadt<PacketT, AlignmentT>(&operator()(i, j));
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HalfPacket loadHalfPacket(Index i, Index j) const {
|
||||
return ploadt<HalfPacket, AlignmentType>(&operator()(i, j));
|
||||
}
|
||||
|
||||
template<typename SubPacket>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void scatterPacket(Index i, Index j, const SubPacket &p) const {
|
||||
pscatter<Scalar, SubPacket>(&operator()(i, j), p, m_stride);
|
||||
@@ -251,7 +242,7 @@ class blas_data_mapper {
|
||||
return internal::first_default_aligned(m_data, size);
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
Scalar* EIGEN_RESTRICT m_data;
|
||||
const Index m_stride;
|
||||
};
|
||||
@@ -289,8 +280,8 @@ template<typename XprType> struct blas_traits
|
||||
ExtractType,
|
||||
typename _ExtractType::PlainObject
|
||||
>::type DirectLinearAccessType;
|
||||
static inline ExtractType extract(const XprType& x) { return x; }
|
||||
static inline const Scalar extractScalarFactor(const XprType&) { return Scalar(1); }
|
||||
static inline EIGEN_DEVICE_FUNC ExtractType extract(const XprType& x) { return x; }
|
||||
static inline EIGEN_DEVICE_FUNC const Scalar extractScalarFactor(const XprType&) { return Scalar(1); }
|
||||
};
|
||||
|
||||
// pop conjugate
|
||||
@@ -318,8 +309,8 @@ struct blas_traits<CwiseBinaryOp<scalar_product_op<Scalar>, const CwiseNullaryOp
|
||||
typedef blas_traits<NestedXpr> Base;
|
||||
typedef CwiseBinaryOp<scalar_product_op<Scalar>, const CwiseNullaryOp<scalar_constant_op<Scalar>,Plain>, NestedXpr> XprType;
|
||||
typedef typename Base::ExtractType ExtractType;
|
||||
static inline ExtractType extract(const XprType& x) { return Base::extract(x.rhs()); }
|
||||
static inline Scalar extractScalarFactor(const XprType& x)
|
||||
static inline EIGEN_DEVICE_FUNC ExtractType extract(const XprType& x) { return Base::extract(x.rhs()); }
|
||||
static inline EIGEN_DEVICE_FUNC Scalar extractScalarFactor(const XprType& x)
|
||||
{ return x.lhs().functor().m_other * Base::extractScalarFactor(x.rhs()); }
|
||||
};
|
||||
template<typename Scalar, typename NestedXpr, typename Plain>
|
||||
|
||||
436
Eigen/src/Core/util/ConfigureVectorization.h
Normal file
436
Eigen/src/Core/util/ConfigureVectorization.h
Normal file
@@ -0,0 +1,436 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008-2018 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_CONFIGURE_VECTORIZATION_H
|
||||
#define EIGEN_CONFIGURE_VECTORIZATION_H
|
||||
|
||||
// FIXME: not sure why this is needed, perhaps it is not needed anymore.
|
||||
#ifdef __NVCC__
|
||||
#ifndef EIGEN_DONT_VECTORIZE
|
||||
#define EIGEN_DONT_VECTORIZE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Static and dynamic alignment control
|
||||
//
|
||||
// The main purpose of this section is to define EIGEN_MAX_ALIGN_BYTES and EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
// as the maximal boundary in bytes on which dynamically and statically allocated data may be alignment respectively.
|
||||
// The values of EIGEN_MAX_ALIGN_BYTES and EIGEN_MAX_STATIC_ALIGN_BYTES can be specified by the user. If not,
|
||||
// a default value is automatically computed based on architecture, compiler, and OS.
|
||||
//
|
||||
// This section also defines macros EIGEN_ALIGN_TO_BOUNDARY(N) and the shortcuts EIGEN_ALIGN{8,16,32,_MAX}
|
||||
// to be used to declare statically aligned buffers.
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/* EIGEN_ALIGN_TO_BOUNDARY(n) forces data to be n-byte aligned. This is used to satisfy SIMD requirements.
|
||||
* However, we do that EVEN if vectorization (EIGEN_VECTORIZE) is disabled,
|
||||
* so that vectorization doesn't affect binary compatibility.
|
||||
*
|
||||
* If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link
|
||||
* vectorized and non-vectorized code.
|
||||
*/
|
||||
#if (defined EIGEN_CUDACC)
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __align__(n)
|
||||
#define EIGEN_ALIGNOF(x) __alignof(x)
|
||||
#elif EIGEN_COMP_GNUC || EIGEN_COMP_PGI || EIGEN_COMP_IBM || EIGEN_COMP_ARM
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
|
||||
#define EIGEN_ALIGNOF(x) __alignof(x)
|
||||
#elif EIGEN_COMP_MSVC
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __declspec(align(n))
|
||||
#define EIGEN_ALIGNOF(x) __alignof(x)
|
||||
#elif EIGEN_COMP_SUNCC
|
||||
// FIXME not sure about this one:
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
|
||||
#define EIGEN_ALIGNOF(x) __alignof(x)
|
||||
#else
|
||||
#error Please tell me what is the equivalent of __attribute__((aligned(n))) and __alignof(x) for your compiler
|
||||
#endif
|
||||
|
||||
// If the user explicitly disable vectorization, then we also disable alignment
|
||||
#if defined(EIGEN_DONT_VECTORIZE)
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 0
|
||||
#elif defined(__AVX512F__)
|
||||
// 64 bytes static alignment is preferred only if really required
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 64
|
||||
#elif defined(__AVX__)
|
||||
// 32 bytes static alignment is preferred only if really required
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 32
|
||||
#else
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 16
|
||||
#endif
|
||||
|
||||
|
||||
// EIGEN_MIN_ALIGN_BYTES defines the minimal value for which the notion of explicit alignment makes sense
|
||||
#define EIGEN_MIN_ALIGN_BYTES 16
|
||||
|
||||
// Defined the boundary (in bytes) on which the data needs to be aligned. Note
|
||||
// that unless EIGEN_ALIGN is defined and not equal to 0, the data may not be
|
||||
// aligned at all regardless of the value of this #define.
|
||||
|
||||
#if (defined(EIGEN_DONT_ALIGN_STATICALLY) || defined(EIGEN_DONT_ALIGN)) && defined(EIGEN_MAX_STATIC_ALIGN_BYTES) && EIGEN_MAX_STATIC_ALIGN_BYTES>0
|
||||
#error EIGEN_MAX_STATIC_ALIGN_BYTES and EIGEN_DONT_ALIGN[_STATICALLY] are both defined with EIGEN_MAX_STATIC_ALIGN_BYTES!=0. Use EIGEN_MAX_STATIC_ALIGN_BYTES=0 as a synonym of EIGEN_DONT_ALIGN_STATICALLY.
|
||||
#endif
|
||||
|
||||
// EIGEN_DONT_ALIGN_STATICALLY and EIGEN_DONT_ALIGN are deprecated
|
||||
// They imply EIGEN_MAX_STATIC_ALIGN_BYTES=0
|
||||
#if defined(EIGEN_DONT_ALIGN_STATICALLY) || defined(EIGEN_DONT_ALIGN)
|
||||
#ifdef EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#undef EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#endif
|
||||
#define EIGEN_MAX_STATIC_ALIGN_BYTES 0
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
|
||||
// Try to automatically guess what is the best default value for EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
|
||||
// 16 byte alignment is only useful for vectorization. Since it affects the ABI, we need to enable
|
||||
// 16 byte alignment on all platforms where vectorization might be enabled. In theory we could always
|
||||
// enable alignment, but it can be a cause of problems on some platforms, so we just disable it in
|
||||
// certain common platform (compiler+architecture combinations) to avoid these problems.
|
||||
// Only static alignment is really problematic (relies on nonstandard compiler extensions),
|
||||
// try to keep heap alignment even when we have to disable static alignment.
|
||||
#if EIGEN_COMP_GNUC && !(EIGEN_ARCH_i386_OR_x86_64 || EIGEN_ARCH_ARM_OR_ARM64 || EIGEN_ARCH_PPC || EIGEN_ARCH_IA64 || EIGEN_ARCH_MIPS)
|
||||
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 1
|
||||
#elif EIGEN_ARCH_ARM_OR_ARM64 && EIGEN_COMP_GNUC_STRICT && EIGEN_GNUC_AT_MOST(4, 6)
|
||||
// Old versions of GCC on ARM, at least 4.4, were once seen to have buggy static alignment support.
|
||||
// Not sure which version fixed it, hopefully it doesn't affect 4.7, which is still somewhat in use.
|
||||
// 4.8 and newer seem definitely unaffected.
|
||||
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 1
|
||||
#else
|
||||
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 0
|
||||
#endif
|
||||
|
||||
// static alignment is completely disabled with GCC 3, Sun Studio, and QCC/QNX
|
||||
#if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT \
|
||||
&& !EIGEN_GCC3_OR_OLDER \
|
||||
&& !EIGEN_COMP_SUNCC \
|
||||
&& !EIGEN_OS_QNX
|
||||
#define EIGEN_ARCH_WANTS_STACK_ALIGNMENT 1
|
||||
#else
|
||||
#define EIGEN_ARCH_WANTS_STACK_ALIGNMENT 0
|
||||
#endif
|
||||
|
||||
#if EIGEN_ARCH_WANTS_STACK_ALIGNMENT
|
||||
#define EIGEN_MAX_STATIC_ALIGN_BYTES EIGEN_IDEAL_MAX_ALIGN_BYTES
|
||||
#else
|
||||
#define EIGEN_MAX_STATIC_ALIGN_BYTES 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// If EIGEN_MAX_ALIGN_BYTES is defined, then it is considered as an upper bound for EIGEN_MAX_ALIGN_BYTES
|
||||
#if defined(EIGEN_MAX_ALIGN_BYTES) && EIGEN_MAX_ALIGN_BYTES<EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#undef EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#define EIGEN_MAX_STATIC_ALIGN_BYTES EIGEN_MAX_ALIGN_BYTES
|
||||
#endif
|
||||
|
||||
#if EIGEN_MAX_STATIC_ALIGN_BYTES==0 && !defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
|
||||
#define EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
|
||||
#endif
|
||||
|
||||
// At this stage, EIGEN_MAX_STATIC_ALIGN_BYTES>0 is the true test whether we want to align arrays on the stack or not.
|
||||
// It takes into account both the user choice to explicitly enable/disable alignment (by setting EIGEN_MAX_STATIC_ALIGN_BYTES)
|
||||
// and the architecture config (EIGEN_ARCH_WANTS_STACK_ALIGNMENT).
|
||||
// Henceforth, only EIGEN_MAX_STATIC_ALIGN_BYTES should be used.
|
||||
|
||||
|
||||
// Shortcuts to EIGEN_ALIGN_TO_BOUNDARY
|
||||
#define EIGEN_ALIGN8 EIGEN_ALIGN_TO_BOUNDARY(8)
|
||||
#define EIGEN_ALIGN16 EIGEN_ALIGN_TO_BOUNDARY(16)
|
||||
#define EIGEN_ALIGN32 EIGEN_ALIGN_TO_BOUNDARY(32)
|
||||
#define EIGEN_ALIGN64 EIGEN_ALIGN_TO_BOUNDARY(64)
|
||||
#if EIGEN_MAX_STATIC_ALIGN_BYTES>0
|
||||
#define EIGEN_ALIGN_MAX EIGEN_ALIGN_TO_BOUNDARY(EIGEN_MAX_STATIC_ALIGN_BYTES)
|
||||
#else
|
||||
#define EIGEN_ALIGN_MAX
|
||||
#endif
|
||||
|
||||
|
||||
// Dynamic alignment control
|
||||
|
||||
#if defined(EIGEN_DONT_ALIGN) && defined(EIGEN_MAX_ALIGN_BYTES) && EIGEN_MAX_ALIGN_BYTES>0
|
||||
#error EIGEN_MAX_ALIGN_BYTES and EIGEN_DONT_ALIGN are both defined with EIGEN_MAX_ALIGN_BYTES!=0. Use EIGEN_MAX_ALIGN_BYTES=0 as a synonym of EIGEN_DONT_ALIGN.
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_DONT_ALIGN
|
||||
#ifdef EIGEN_MAX_ALIGN_BYTES
|
||||
#undef EIGEN_MAX_ALIGN_BYTES
|
||||
#endif
|
||||
#define EIGEN_MAX_ALIGN_BYTES 0
|
||||
#elif !defined(EIGEN_MAX_ALIGN_BYTES)
|
||||
#define EIGEN_MAX_ALIGN_BYTES EIGEN_IDEAL_MAX_ALIGN_BYTES
|
||||
#endif
|
||||
|
||||
#if EIGEN_IDEAL_MAX_ALIGN_BYTES > EIGEN_MAX_ALIGN_BYTES
|
||||
#define EIGEN_DEFAULT_ALIGN_BYTES EIGEN_IDEAL_MAX_ALIGN_BYTES
|
||||
#else
|
||||
#define EIGEN_DEFAULT_ALIGN_BYTES EIGEN_MAX_ALIGN_BYTES
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef EIGEN_UNALIGNED_VECTORIZE
|
||||
#define EIGEN_UNALIGNED_VECTORIZE 1
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// if alignment is disabled, then disable vectorization. Note: EIGEN_MAX_ALIGN_BYTES is the proper check, it takes into
|
||||
// account both the user's will (EIGEN_MAX_ALIGN_BYTES,EIGEN_DONT_ALIGN) and our own platform checks
|
||||
#if EIGEN_MAX_ALIGN_BYTES==0
|
||||
#ifndef EIGEN_DONT_VECTORIZE
|
||||
#define EIGEN_DONT_VECTORIZE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// The following (except #include <malloc.h> and _M_IX86_FP ??) can likely be
|
||||
// removed as gcc 4.1 and msvc 2008 are not supported anyways.
|
||||
#if EIGEN_COMP_MSVC
|
||||
#include <malloc.h> // for _aligned_malloc -- need it regardless of whether vectorization is enabled
|
||||
#if (EIGEN_COMP_MSVC >= 1500) // 2008 or later
|
||||
// a user reported that in 64-bit mode, MSVC doesn't care to define _M_IX86_FP.
|
||||
#if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || EIGEN_ARCH_x86_64
|
||||
#define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#if (defined __SSE2__) && ( (!EIGEN_COMP_GNUC) || EIGEN_COMP_ICC || EIGEN_GNUC_AT_LEAST(4,2) )
|
||||
#define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef EIGEN_DONT_VECTORIZE
|
||||
|
||||
#if defined (EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
|
||||
|
||||
// Defines symbols for compile-time detection of which instructions are
|
||||
// used.
|
||||
// EIGEN_VECTORIZE_YY is defined if and only if the instruction set YY is used
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_SSE
|
||||
#define EIGEN_VECTORIZE_SSE2
|
||||
|
||||
// Detect sse3/ssse3/sse4:
|
||||
// gcc and icc defines __SSE3__, ...
|
||||
// there is no way to know about this on msvc. You can define EIGEN_VECTORIZE_SSE* if you
|
||||
// want to force the use of those instructions with msvc.
|
||||
#ifdef __SSE3__
|
||||
#define EIGEN_VECTORIZE_SSE3
|
||||
#endif
|
||||
#ifdef __SSSE3__
|
||||
#define EIGEN_VECTORIZE_SSSE3
|
||||
#endif
|
||||
#ifdef __SSE4_1__
|
||||
#define EIGEN_VECTORIZE_SSE4_1
|
||||
#endif
|
||||
#ifdef __SSE4_2__
|
||||
#define EIGEN_VECTORIZE_SSE4_2
|
||||
#endif
|
||||
#ifdef __AVX__
|
||||
#define EIGEN_VECTORIZE_AVX
|
||||
#define EIGEN_VECTORIZE_SSE3
|
||||
#define EIGEN_VECTORIZE_SSSE3
|
||||
#define EIGEN_VECTORIZE_SSE4_1
|
||||
#define EIGEN_VECTORIZE_SSE4_2
|
||||
#endif
|
||||
#ifdef __AVX2__
|
||||
#define EIGEN_VECTORIZE_AVX2
|
||||
#define EIGEN_VECTORIZE_AVX
|
||||
#define EIGEN_VECTORIZE_SSE3
|
||||
#define EIGEN_VECTORIZE_SSSE3
|
||||
#define EIGEN_VECTORIZE_SSE4_1
|
||||
#define EIGEN_VECTORIZE_SSE4_2
|
||||
#endif
|
||||
#ifdef __FMA__
|
||||
#define EIGEN_VECTORIZE_FMA
|
||||
#endif
|
||||
#if defined(__AVX512F__)
|
||||
#define EIGEN_VECTORIZE_AVX512
|
||||
#define EIGEN_VECTORIZE_AVX2
|
||||
#define EIGEN_VECTORIZE_AVX
|
||||
#define EIGEN_VECTORIZE_FMA
|
||||
#define EIGEN_VECTORIZE_SSE3
|
||||
#define EIGEN_VECTORIZE_SSSE3
|
||||
#define EIGEN_VECTORIZE_SSE4_1
|
||||
#define EIGEN_VECTORIZE_SSE4_2
|
||||
#ifdef __AVX512DQ__
|
||||
#define EIGEN_VECTORIZE_AVX512DQ
|
||||
#endif
|
||||
#ifdef __AVX512ER__
|
||||
#define EIGEN_VECTORIZE_AVX512ER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// include files
|
||||
|
||||
// This extern "C" works around a MINGW-w64 compilation issue
|
||||
// https://sourceforge.net/tracker/index.php?func=detail&aid=3018394&group_id=202880&atid=983354
|
||||
// In essence, intrin.h is included by windows.h and also declares intrinsics (just as emmintrin.h etc. below do).
|
||||
// However, intrin.h uses an extern "C" declaration, and g++ thus complains of duplicate declarations
|
||||
// with conflicting linkage. The linkage for intrinsics doesn't matter, but at that stage the compiler doesn't know;
|
||||
// so, to avoid compile errors when windows.h is included after Eigen/Core, ensure intrinsics are extern "C" here too.
|
||||
// notice that since these are C headers, the extern "C" is theoretically needed anyways.
|
||||
extern "C" {
|
||||
// In theory we should only include immintrin.h and not the other *mmintrin.h header files directly.
|
||||
// Doing so triggers some issues with ICC. However old gcc versions seems to not have this file, thus:
|
||||
#if EIGEN_COMP_ICC >= 1110
|
||||
#include <immintrin.h>
|
||||
#else
|
||||
#include <mmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
#include <xmmintrin.h>
|
||||
#ifdef EIGEN_VECTORIZE_SSE3
|
||||
#include <pmmintrin.h>
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_SSSE3
|
||||
#include <tmmintrin.h>
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_SSE4_1
|
||||
#include <smmintrin.h>
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_SSE4_2
|
||||
#include <nmmintrin.h>
|
||||
#endif
|
||||
#if defined(EIGEN_VECTORIZE_AVX) || defined(EIGEN_VECTORIZE_AVX512)
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
#endif
|
||||
} // end extern "C"
|
||||
|
||||
#elif defined __VSX__
|
||||
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_VSX
|
||||
#include <altivec.h>
|
||||
// We need to #undef all these ugly tokens defined in <altivec.h>
|
||||
// => use __vector instead of vector
|
||||
#undef bool
|
||||
#undef vector
|
||||
#undef pixel
|
||||
|
||||
#elif defined __ALTIVEC__
|
||||
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_ALTIVEC
|
||||
#include <altivec.h>
|
||||
// We need to #undef all these ugly tokens defined in <altivec.h>
|
||||
// => use __vector instead of vector
|
||||
#undef bool
|
||||
#undef vector
|
||||
#undef pixel
|
||||
|
||||
#elif (defined __ARM_NEON) || (defined __ARM_NEON__)
|
||||
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_NEON
|
||||
#include <arm_neon.h>
|
||||
|
||||
#elif (defined __s390x__ && defined __VEC__)
|
||||
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_ZVECTOR
|
||||
#include <vecintrin.h>
|
||||
|
||||
#elif defined __mips_msa
|
||||
|
||||
// Limit MSA optimizations to little-endian CPUs for now.
|
||||
// TODO: Perhaps, eventually support MSA optimizations on big-endian CPUs?
|
||||
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||
#if defined(__LP64__)
|
||||
#define EIGEN_MIPS_64
|
||||
#else
|
||||
#define EIGEN_MIPS_32
|
||||
#endif
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_MSA
|
||||
#include <msa.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__F16C__) && !defined(EIGEN_COMP_CLANG)
|
||||
// We can use the optimized fp16 to float and float to fp16 conversion routines
|
||||
#define EIGEN_HAS_FP16_C
|
||||
#endif
|
||||
|
||||
#if defined EIGEN_CUDACC
|
||||
#define EIGEN_VECTORIZE_GPU
|
||||
#include <vector_types.h>
|
||||
#if EIGEN_CUDACC_VER >= 70500
|
||||
#define EIGEN_HAS_CUDA_FP16
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_HAS_CUDA_FP16)
|
||||
#include <host_defines.h>
|
||||
#include <cuda_fp16.h>
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
|
||||
#define EIGEN_VECTORIZE_GPU
|
||||
#include <hip/hip_vector_types.h>
|
||||
|
||||
#define EIGEN_HAS_HIP_FP16
|
||||
#include <hip/hip_fp16.h>
|
||||
|
||||
#define HIP_PATCH_WITH_NEW_FP16 18215
|
||||
#if (HIP_VERSION_PATCH < HIP_PATCH_WITH_NEW_FP16)
|
||||
#define EIGEN_HAS_OLD_HIP_FP16
|
||||
// Old HIP implementation does not have a explicit typedef for "half2"
|
||||
typedef __half2 half2;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief Namespace containing all symbols from the %Eigen library. */
|
||||
namespace Eigen {
|
||||
|
||||
inline static const char *SimdInstructionSetsInUse(void) {
|
||||
#if defined(EIGEN_VECTORIZE_AVX512)
|
||||
return "AVX512, FMA, AVX2, AVX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
|
||||
#elif defined(EIGEN_VECTORIZE_AVX)
|
||||
return "AVX SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
|
||||
#elif defined(EIGEN_VECTORIZE_SSE4_2)
|
||||
return "SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
|
||||
#elif defined(EIGEN_VECTORIZE_SSE4_1)
|
||||
return "SSE, SSE2, SSE3, SSSE3, SSE4.1";
|
||||
#elif defined(EIGEN_VECTORIZE_SSSE3)
|
||||
return "SSE, SSE2, SSE3, SSSE3";
|
||||
#elif defined(EIGEN_VECTORIZE_SSE3)
|
||||
return "SSE, SSE2, SSE3";
|
||||
#elif defined(EIGEN_VECTORIZE_SSE2)
|
||||
return "SSE, SSE2";
|
||||
#elif defined(EIGEN_VECTORIZE_ALTIVEC)
|
||||
return "AltiVec";
|
||||
#elif defined(EIGEN_VECTORIZE_VSX)
|
||||
return "VSX";
|
||||
#elif defined(EIGEN_VECTORIZE_NEON)
|
||||
return "ARM NEON";
|
||||
#elif defined(EIGEN_VECTORIZE_ZVECTOR)
|
||||
return "S390X ZVECTOR";
|
||||
#elif defined(EIGEN_VECTORIZE_MSA)
|
||||
return "MIPS MSA";
|
||||
#else
|
||||
return "None";
|
||||
#endif
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
|
||||
#endif // EIGEN_CONFIGURE_VECTORIZATION_H
|
||||
@@ -470,6 +470,7 @@ namespace Architecture
|
||||
AltiVec = 0x2,
|
||||
VSX = 0x3,
|
||||
NEON = 0x4,
|
||||
MSA = 0x5,
|
||||
#if defined EIGEN_VECTORIZE_SSE
|
||||
Target = SSE
|
||||
#elif defined EIGEN_VECTORIZE_ALTIVEC
|
||||
@@ -478,6 +479,8 @@ namespace Architecture
|
||||
Target = VSX
|
||||
#elif defined EIGEN_VECTORIZE_NEON
|
||||
Target = NEON
|
||||
#elif defined EIGEN_VECTORIZE_MSA
|
||||
Target = MSA
|
||||
#else
|
||||
Target = Generic
|
||||
#endif
|
||||
|
||||
@@ -45,16 +45,25 @@
|
||||
#pragma clang diagnostic ignored "-Wabsolute-value"
|
||||
#endif
|
||||
|
||||
#elif defined __GNUC__ && __GNUC__>=6
|
||||
#elif defined __GNUC__
|
||||
|
||||
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#pragma GCC diagnostic ignored "-Wignored-attributes"
|
||||
// g++ warns about local variables shadowing member functions, which is too strict
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#if __GNUC__ == 4 && __GNUC_MINOR__ < 8
|
||||
// Until g++-4.7 there are warnings when comparing unsigned int vs 0, even in templated functions:
|
||||
#pragma GCC diagnostic ignored "-Wtype-limits"
|
||||
#endif
|
||||
#if __GNUC__>=6
|
||||
#pragma GCC diagnostic ignored "-Wignored-attributes"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined __NVCC__
|
||||
#pragma diag_suppress boolean_controlling_expr_is_constant
|
||||
// Disable the "statement is unreachable" message
|
||||
#pragma diag_suppress code_is_unreachable
|
||||
// Disable the "dynamic initialization in unreachable code" message
|
||||
@@ -72,6 +81,15 @@
|
||||
#pragma diag_suppress 2671
|
||||
#pragma diag_suppress 2735
|
||||
#pragma diag_suppress 2737
|
||||
#pragma diag_suppress 2739
|
||||
#endif
|
||||
|
||||
#else
|
||||
// warnings already disabled:
|
||||
# ifndef EIGEN_WARNINGS_DISABLED_2
|
||||
# define EIGEN_WARNINGS_DISABLED_2
|
||||
# elif defined(EIGEN_INTERNAL_DEBUGGING)
|
||||
# error "Do not include \"DisableStupidWarnings.h\" recursively more than twice!"
|
||||
# endif
|
||||
|
||||
#endif // not EIGEN_WARNINGS_DISABLED
|
||||
|
||||
@@ -13,13 +13,6 @@
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \namespace Eigen::placeholders
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* Namespace containing symbolic placeholder and identifiers
|
||||
*/
|
||||
namespace placeholders {
|
||||
|
||||
namespace internal {
|
||||
struct symbolic_last_tag {};
|
||||
}
|
||||
@@ -35,36 +28,35 @@ struct symbolic_last_tag {};
|
||||
* A typical usage example would be:
|
||||
* \code
|
||||
* using namespace Eigen;
|
||||
* using Eigen::placeholders::last;
|
||||
* using Eigen::last;
|
||||
* VectorXd v(n);
|
||||
* v(seq(2,last-2)).setOnes();
|
||||
* \endcode
|
||||
*
|
||||
* \sa end
|
||||
*/
|
||||
static const Symbolic::SymbolExpr<internal::symbolic_last_tag> last;
|
||||
static const symbolic::SymbolExpr<internal::symbolic_last_tag> last; // PLEASE use Eigen::last instead of Eigen::placeholders::last
|
||||
|
||||
/** \var end
|
||||
/** \var lastp1
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* Can be used as a parameter to Eigen::seq and Eigen::seqN functions to symbolically reference the last+1 element/row/columns
|
||||
* of the underlying vector or matrix once passed to DenseBase::operator()(const RowIndices&, const ColIndices&).
|
||||
* Can be used as a parameter to Eigen::seq and Eigen::seqN functions to symbolically
|
||||
* reference the last+1 element/row/columns of the underlying vector or matrix once
|
||||
* passed to DenseBase::operator()(const RowIndices&, const ColIndices&).
|
||||
*
|
||||
* This symbolic placeholder support standard arithmetic operation.
|
||||
* It is essentially an alias to last+1
|
||||
* It is essentially an alias to last+fix<1>.
|
||||
*
|
||||
* \sa last
|
||||
*/
|
||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||
static const auto end = last+1;
|
||||
static const auto lastp1 = last+fix<1>;
|
||||
#else
|
||||
// Using a FixedExpr<1> expression is important here to make sure the compiler
|
||||
// can fully optimize the computation starting indices with zero overhead.
|
||||
static const Symbolic::AddExpr<Symbolic::SymbolExpr<internal::symbolic_last_tag>,Symbolic::ValueExpr<Eigen::internal::FixedInt<1> > > end(last+fix<1>());
|
||||
static const symbolic::AddExpr<symbolic::SymbolExpr<internal::symbolic_last_tag>,symbolic::ValueExpr<Eigen::internal::FixedInt<1> > > lastp1(last+fix<1>());
|
||||
#endif
|
||||
|
||||
} // end namespace placeholders
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Replace symbolic last/end "keywords" by their true runtime value
|
||||
@@ -74,9 +66,9 @@ template<int N>
|
||||
FixedInt<N> eval_expr_given_size(FixedInt<N> x, Index /*size*/) { return x; }
|
||||
|
||||
template<typename Derived>
|
||||
Index eval_expr_given_size(const Symbolic::BaseExpr<Derived> &x, Index size)
|
||||
Index eval_expr_given_size(const symbolic::BaseExpr<Derived> &x, Index size)
|
||||
{
|
||||
return x.derived().eval(placeholders::last=size-1);
|
||||
return x.derived().eval(last=size-1);
|
||||
}
|
||||
|
||||
// Extract increment/step at compile time
|
||||
@@ -117,7 +109,7 @@ template<> struct get_compile_time_incr<SingleRange> {
|
||||
enum { value = 1 }; // 1 or 0 ??
|
||||
};
|
||||
|
||||
// Turn a single index into something that looks like an array (i.e., that exposes a .size(), and operatro[](int) methods)
|
||||
// Turn a single index into something that looks like an array (i.e., that exposes a .size(), and operator[](int) methods)
|
||||
template<typename T, int XprSize>
|
||||
struct IndexedViewCompatibleType<T,XprSize,typename internal::enable_if<internal::is_integral<T>::value>::type> {
|
||||
// Here we could simply use Array, but maybe it's less work for the compiler to use
|
||||
@@ -127,13 +119,13 @@ struct IndexedViewCompatibleType<T,XprSize,typename internal::enable_if<internal
|
||||
};
|
||||
|
||||
template<typename T, int XprSize>
|
||||
struct IndexedViewCompatibleType<T, XprSize, typename enable_if<Symbolic::is_symbolic<T>::value>::type> {
|
||||
struct IndexedViewCompatibleType<T, XprSize, typename enable_if<symbolic::is_symbolic<T>::value>::type> {
|
||||
typedef SingleRange type;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
typename enable_if<Symbolic::is_symbolic<T>::value,SingleRange>::type
|
||||
typename enable_if<symbolic::is_symbolic<T>::value,SingleRange>::type
|
||||
makeIndexedViewCompatible(const T& id, Index size, SpecializedType) {
|
||||
return eval_expr_given_size(id,size);
|
||||
}
|
||||
@@ -172,14 +164,21 @@ template<int Size> struct get_compile_time_incr<AllRange<Size> > {
|
||||
} // end namespace internal
|
||||
|
||||
|
||||
namespace placeholders {
|
||||
|
||||
/** \var all
|
||||
* \ingroup Core_Module
|
||||
* Can be used as a parameter to DenseBase::operator()(const RowIndices&, const ColIndices&) to index all rows or columns
|
||||
*/
|
||||
static const Eigen::internal::all_t all;
|
||||
static const Eigen::internal::all_t all; // PLEASE use Eigen::all instead of Eigen::placeholders::all
|
||||
|
||||
|
||||
namespace placeholders {
|
||||
typedef symbolic::SymbolExpr<internal::symbolic_last_tag> last_t;
|
||||
typedef symbolic::AddExpr<symbolic::SymbolExpr<internal::symbolic_last_tag>,symbolic::ValueExpr<Eigen::internal::FixedInt<1> > > end_t;
|
||||
typedef Eigen::internal::all_t all_t;
|
||||
|
||||
EIGEN_DEPRECATED static const all_t all = Eigen::all; // PLEASE use Eigen::all instead of Eigen::placeholders::all
|
||||
EIGEN_DEPRECATED static const last_t last = Eigen::last; // PLEASE use Eigen::last instead of Eigen::placeholders::last
|
||||
EIGEN_DEPRECATED static const end_t end = Eigen::lastp1; // PLEASE use Eigen::lastp1 instead of Eigen::placeholders::end
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -151,9 +151,9 @@ struct get_fixed_value<variable_if_dynamic<T,N>,Default> {
|
||||
static const int value = N;
|
||||
};
|
||||
|
||||
template<typename T> Index get_runtime_value(const T &x) { return x; }
|
||||
template<typename T> EIGEN_DEVICE_FUNC Index get_runtime_value(const T &x) { return x; }
|
||||
#if !EIGEN_HAS_CXX14
|
||||
template<int N> Index get_runtime_value(FixedInt<N> (*)()) { return N; }
|
||||
template<int N> EIGEN_DEVICE_FUNC Index get_runtime_value(FixedInt<N> (*)()) { return N; }
|
||||
#endif
|
||||
|
||||
// Cleanup integer/FixedInt/VariableAndFixedInt/etc types:
|
||||
|
||||
@@ -49,12 +49,17 @@
|
||||
#define EIGEN_USE_LAPACKE
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_USE_MKL_VML)
|
||||
#if defined(EIGEN_USE_MKL_VML) && !defined(EIGEN_USE_MKL)
|
||||
#define EIGEN_USE_MKL
|
||||
#endif
|
||||
|
||||
|
||||
#if defined EIGEN_USE_MKL
|
||||
# include <mkl.h>
|
||||
# if (!defined MKL_DIRECT_CALL) && (!defined EIGEN_MKL_NO_DIRECT_CALL)
|
||||
# define MKL_DIRECT_CALL
|
||||
# define MKL_DIRECT_CALL_JUST_SET
|
||||
# endif
|
||||
# include <mkl.h>
|
||||
/*Check IMKL version for compatibility: < 10.3 is not usable with Eigen*/
|
||||
# ifndef INTEL_MKL_VERSION
|
||||
# undef EIGEN_USE_MKL /* INTEL_MKL_VERSION is not even defined on older versions */
|
||||
@@ -68,6 +73,9 @@
|
||||
# undef EIGEN_USE_MKL_VML
|
||||
# undef EIGEN_USE_LAPACKE_STRICT
|
||||
# undef EIGEN_USE_LAPACKE
|
||||
# ifdef MKL_DIRECT_CALL_JUST_SET
|
||||
# undef MKL_DIRECT_CALL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -108,6 +116,10 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_USE_BLAS) && !defined(EIGEN_USE_MKL)
|
||||
#include "../../misc/blas.h"
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
typedef std::complex<double> dcomplex;
|
||||
@@ -121,8 +133,5 @@ typedef int BlasIndex;
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#if defined(EIGEN_USE_BLAS)
|
||||
#include "../../misc/blas.h"
|
||||
#endif
|
||||
|
||||
#endif // EIGEN_MKL_SUPPORT_H
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef EIGEN_MACROS_H
|
||||
#define EIGEN_MACROS_H
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Eigen version and basic defaults
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
#define EIGEN_WORLD_VERSION 3
|
||||
#define EIGEN_MAJOR_VERSION 3
|
||||
#define EIGEN_MINOR_VERSION 90
|
||||
@@ -19,7 +23,40 @@
|
||||
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
|
||||
EIGEN_MINOR_VERSION>=z))))
|
||||
|
||||
#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
|
||||
#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION Eigen::RowMajor
|
||||
#else
|
||||
#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION Eigen::ColMajor
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_DEFAULT_DENSE_INDEX_TYPE
|
||||
#define EIGEN_DEFAULT_DENSE_INDEX_TYPE std::ptrdiff_t
|
||||
#endif
|
||||
|
||||
// Upperbound on the C++ version to use.
|
||||
// Expected values are 03, 11, 14, 17, etc.
|
||||
// By default, let's use an arbitrarily large C++ version.
|
||||
#ifndef EIGEN_MAX_CPP_VER
|
||||
#define EIGEN_MAX_CPP_VER 99
|
||||
#endif
|
||||
|
||||
/** Allows to disable some optimizations which might affect the accuracy of the result.
|
||||
* Such optimization are enabled by default, and set EIGEN_FAST_MATH to 0 to disable them.
|
||||
* They currently include:
|
||||
* - single precision ArrayBase::sin() and ArrayBase::cos() for SSE and AVX vectorization.
|
||||
*/
|
||||
#ifndef EIGEN_FAST_MATH
|
||||
#define EIGEN_FAST_MATH 1
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_STACK_ALLOCATION_LIMIT
|
||||
// 131072 == 128 KB
|
||||
#define EIGEN_STACK_ALLOCATION_LIMIT 131072
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Compiler identification, EIGEN_COMP_*
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
/// \internal EIGEN_COMP_GNUC set to 1 for all compilers compatible with GCC
|
||||
#ifdef __GNUC__
|
||||
@@ -73,12 +110,17 @@
|
||||
|
||||
// For the record, here is a table summarizing the possible values for EIGEN_COMP_MSVC:
|
||||
// name ver MSC_VER
|
||||
// 2008 9 1500
|
||||
// 2010 10 1600
|
||||
// 2012 11 1700
|
||||
// 2013 12 1800
|
||||
// 2015 14 1900
|
||||
// "15" 15 1900
|
||||
// 2008 9 1500
|
||||
// 2010 10 1600
|
||||
// 2012 11 1700
|
||||
// 2013 12 1800
|
||||
// 2015 14 1900
|
||||
// "15" 15 1900
|
||||
// 2017-14.1 15.0 1910
|
||||
// 2017-14.11 15.3 1911
|
||||
// 2017-14.12 15.5 1912
|
||||
// 2017-14.13 15.6 1913
|
||||
// 2017-14.14 15.7 1914
|
||||
|
||||
/// \internal EIGEN_COMP_MSVC_STRICT set to 1 if the compiler is really Microsoft Visual C++ and not ,e.g., ICC or clang-cl
|
||||
#if EIGEN_COMP_MSVC && !(EIGEN_COMP_ICC || EIGEN_COMP_LLVM || EIGEN_COMP_CLANG)
|
||||
@@ -142,7 +184,11 @@
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Architecture identification, EIGEN_ARCH_*
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64) || defined(__amd64)
|
||||
#define EIGEN_ARCH_x86_64 1
|
||||
@@ -212,7 +258,9 @@
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Operating system identification, EIGEN_OS_*
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
/// \internal EIGEN_OS_UNIX set to 1 if the OS is a unix variant
|
||||
#if defined(__unix__) || defined(__unix)
|
||||
@@ -314,6 +362,108 @@
|
||||
#endif
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Detect GPU compilers and architectures
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
// NVCC is not supported as the target platform for HIPCC
|
||||
// Note that this also makes EIGEN_CUDACC and EIGEN_HIPCC mutually exclusive
|
||||
#if defined(__NVCC__) && defined(__HIPCC__)
|
||||
#error "NVCC as the target platform for HIPCC is currently not supported."
|
||||
#endif
|
||||
|
||||
#if defined(__CUDACC__) && !defined(EIGEN_NO_CUDA)
|
||||
// Means the compiler is either nvcc or clang with CUDA enabled
|
||||
#define EIGEN_CUDACC __CUDACC__
|
||||
#endif
|
||||
|
||||
#if defined(__CUDA_ARCH__) && !defined(EIGEN_NO_CUDA)
|
||||
// Means we are generating code for the device
|
||||
#define EIGEN_CUDA_ARCH __CUDA_ARCH__
|
||||
#endif
|
||||
|
||||
// Starting with CUDA 9 the composite __CUDACC_VER__ is not available.
|
||||
#if defined(__CUDACC_VER_MAJOR__) && (__CUDACC_VER_MAJOR__ >= 9)
|
||||
#define EIGEN_CUDACC_VER ((__CUDACC_VER_MAJOR__ * 10000) + (__CUDACC_VER_MINOR__ * 100))
|
||||
#elif defined(__CUDACC_VER__)
|
||||
#define EIGEN_CUDACC_VER __CUDACC_VER__
|
||||
#else
|
||||
#define EIGEN_CUDACC_VER 0
|
||||
#endif
|
||||
|
||||
#if defined(__HIPCC__) && !defined(EIGEN_NO_HIP)
|
||||
// Means the compiler is HIPCC (analogous to EIGEN_CUDACC, but for HIP)
|
||||
#define EIGEN_HIPCC __HIPCC__
|
||||
|
||||
// We need to include hip_runtime.h here because it pulls in
|
||||
// ++ hip_common.h which contains the define for __HIP_DEVICE_COMPILE__
|
||||
// ++ host_defines.h which contains the defines for the __host__ and __device__ macros
|
||||
#include <hip/hip_runtime.h>
|
||||
|
||||
#if defined(__HIP_DEVICE_COMPILE__)
|
||||
// analogous to EIGEN_CUDA_ARCH, but for HIP
|
||||
#define EIGEN_HIP_DEVICE_COMPILE __HIP_DEVICE_COMPILE__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Unify CUDA/HIPCC
|
||||
|
||||
#if defined(EIGEN_CUDACC) || defined(EIGEN_HIPCC)
|
||||
//
|
||||
// If either EIGEN_CUDACC or EIGEN_HIPCC is defined, then define EIGEN_GPUCC
|
||||
//
|
||||
#define EIGEN_GPUCC
|
||||
//
|
||||
// EIGEN_HIPCC implies the HIP compiler and is used to tweak Eigen code for use in HIP kernels
|
||||
// EIGEN_CUDACC implies the CUDA compiler and is used to tweak Eigen code for use in CUDA kernels
|
||||
//
|
||||
// In most cases the same tweaks are required to the Eigen code to enable in both the HIP and CUDA kernels.
|
||||
// For those cases, the corresponding code should be guarded with
|
||||
// #if defined(EIGEN_GPUCC)
|
||||
// instead of
|
||||
// #if defined(EIGEN_CUDACC) || defined(EIGEN_HIPCC)
|
||||
//
|
||||
// For cases where the tweak is specific to HIP, the code should be guarded with
|
||||
// #if defined(EIGEN_HIPCC)
|
||||
//
|
||||
// For cases where the tweak is specific to CUDA, the code should be guarded with
|
||||
// #if defined(EIGEN_CUDACC)
|
||||
//
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_CUDA_ARCH) || defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
//
|
||||
// If either EIGEN_CUDA_ARCH or EIGEN_HIP_DEVICE_COMPILE is defined, then define EIGEN_GPU_COMPILE_PHASE
|
||||
//
|
||||
#define EIGEN_GPU_COMPILE_PHASE
|
||||
//
|
||||
// GPU compilers (HIPCC, NVCC) typically do two passes over the source code,
|
||||
// + one to compile the source for the "host" (ie CPU)
|
||||
// + another to compile the source for the "device" (ie. GPU)
|
||||
//
|
||||
// Code that needs to enabled only during the either the "host" or "device" compilation phase
|
||||
// needs to be guarded with a macro that indicates the current compilation phase
|
||||
//
|
||||
// EIGEN_HIP_DEVICE_COMPILE implies the device compilation phase in HIP
|
||||
// EIGEN_CUDA_ARCH implies the device compilation phase in CUDA
|
||||
//
|
||||
// In most cases, the "host" / "device" specific code is the same for both HIP and CUDA
|
||||
// For those cases, the code should be guarded with
|
||||
// #if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
// instead of
|
||||
// #if defined(EIGEN_CUDA_ARCH) || defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
//
|
||||
// For cases where the tweak is specific to HIP, the code should be guarded with
|
||||
// #if defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
//
|
||||
// For cases where the tweak is specific to CUDA, the code should be guarded with
|
||||
// #if defined(EIGEN_CUDA_ARCH)
|
||||
//
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Detect Compiler/Architecture/OS specific features
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
#if EIGEN_GNUC_AT_MOST(4,3) && !EIGEN_COMP_CLANG
|
||||
// see bug 89
|
||||
@@ -322,20 +472,6 @@
|
||||
#define EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO 1
|
||||
#endif
|
||||
|
||||
// This macro can be used to prevent from macro expansion, e.g.:
|
||||
// std::max EIGEN_NOT_A_MACRO(a,b)
|
||||
#define EIGEN_NOT_A_MACRO
|
||||
|
||||
#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
|
||||
#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION Eigen::RowMajor
|
||||
#else
|
||||
#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION Eigen::ColMajor
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_DEFAULT_DENSE_INDEX_TYPE
|
||||
#define EIGEN_DEFAULT_DENSE_INDEX_TYPE std::ptrdiff_t
|
||||
#endif
|
||||
|
||||
// Cross compiler wrapper around LLVM's __has_builtin
|
||||
#ifdef __has_builtin
|
||||
# define EIGEN_HAS_BUILTIN(x) __has_builtin(x)
|
||||
@@ -357,13 +493,6 @@
|
||||
#define EIGEN_HAS_STATIC_ARRAY_TEMPLATE 0
|
||||
#endif
|
||||
|
||||
// Upperbound on the C++ version to use.
|
||||
// Expected values are 03, 11, 14, 17, etc.
|
||||
// By default, let's use an arbitrarily large C++ version.
|
||||
#ifndef EIGEN_MAX_CPP_VER
|
||||
#define EIGEN_MAX_CPP_VER 99
|
||||
#endif
|
||||
|
||||
#if EIGEN_MAX_CPP_VER>=11 && (defined(__cplusplus) && (__cplusplus >= 201103L) || EIGEN_COMP_MSVC >= 1900)
|
||||
#define EIGEN_HAS_CXX11 1
|
||||
#else
|
||||
@@ -389,6 +518,8 @@
|
||||
#endif
|
||||
|
||||
// Does the compiler support C99?
|
||||
// Need to include <cmath> to make sure _GLIBCXX_USE_C99 gets defined
|
||||
#include <cmath>
|
||||
#ifndef EIGEN_HAS_C99_MATH
|
||||
#if EIGEN_MAX_CPP_VER>=11 && \
|
||||
((defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)) \
|
||||
@@ -402,18 +533,35 @@
|
||||
#endif
|
||||
|
||||
// Does the compiler support result_of?
|
||||
// It's likely that MSVC 2013 supports result_of but I couldn't not find a good source for that,
|
||||
// so let's be conservative.
|
||||
#ifndef EIGEN_HAS_STD_RESULT_OF
|
||||
#if EIGEN_MAX_CPP_VER>=11 && ((__has_feature(cxx_lambdas) || (defined(__cplusplus) && __cplusplus >= 201103L)))
|
||||
#if EIGEN_MAX_CPP_VER>=11 && \
|
||||
(__has_feature(cxx_lambdas) || (defined(__cplusplus) && __cplusplus >= 201103L) || EIGEN_COMP_MSVC >= 1900)
|
||||
#define EIGEN_HAS_STD_RESULT_OF 1
|
||||
#else
|
||||
#define EIGEN_HAS_STD_RESULT_OF 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Does the compiler support type_traits?
|
||||
// - full support of type traits was added only to GCC 5.1.0.
|
||||
// - 20150626 corresponds to the last release of 4.x libstdc++
|
||||
#ifndef EIGEN_HAS_TYPE_TRAITS
|
||||
#if EIGEN_MAX_CPP_VER>=11 && (EIGEN_HAS_CXX11 || EIGEN_COMP_MSVC >= 1700) \
|
||||
&& ((!EIGEN_COMP_GNUC_STRICT) || EIGEN_GNUC_AT_LEAST(5, 1)) \
|
||||
&& ((!defined(__GLIBCXX__)) || __GLIBCXX__ > 20150626)
|
||||
#define EIGEN_HAS_TYPE_TRAITS 1
|
||||
#define EIGEN_INCLUDE_TYPE_TRAITS
|
||||
#else
|
||||
#define EIGEN_HAS_TYPE_TRAITS 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Does the compiler support variadic templates?
|
||||
#ifndef EIGEN_HAS_VARIADIC_TEMPLATES
|
||||
#if EIGEN_MAX_CPP_VER>=11 && (__cplusplus > 199711L || EIGEN_COMP_MSVC >= 1900) \
|
||||
&& (!defined(__NVCC__) || !EIGEN_ARCH_ARM_OR_ARM64 || (defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000) )
|
||||
&& (!defined(__NVCC__) || !EIGEN_ARCH_ARM_OR_ARM64 || (EIGEN_CUDACC_VER >= 80000) )
|
||||
// ^^ Disable the use of variadic templates when compiling with versions of nvcc older than 8.0 on ARM devices:
|
||||
// this prevents nvcc from crashing when compiling Eigen on Tegra X1
|
||||
#define EIGEN_HAS_VARIADIC_TEMPLATES 1
|
||||
@@ -426,23 +574,22 @@
|
||||
|
||||
// Does the compiler fully support const expressions? (as in c++14)
|
||||
#ifndef EIGEN_HAS_CONSTEXPR
|
||||
#if defined(EIGEN_CUDACC)
|
||||
// Const expressions are supported provided that c++11 is enabled and we're using either clang or nvcc 7.5 or above
|
||||
#if EIGEN_MAX_CPP_VER>=14 && (__cplusplus > 199711L && (EIGEN_COMP_CLANG || EIGEN_CUDACC_VER >= 70500))
|
||||
#define EIGEN_HAS_CONSTEXPR 1
|
||||
#endif
|
||||
#elif EIGEN_MAX_CPP_VER>=14 && (__has_feature(cxx_relaxed_constexpr) || (defined(__cplusplus) && __cplusplus >= 201402L) || \
|
||||
(EIGEN_GNUC_AT_LEAST(4,8) && (__cplusplus > 199711L)) || \
|
||||
(EIGEN_COMP_CLANG >= 306 && (__cplusplus > 199711L)))
|
||||
#define EIGEN_HAS_CONSTEXPR 1
|
||||
#endif
|
||||
|
||||
#if defined(__CUDACC__)
|
||||
// Const expressions are supported provided that c++11 is enabled and we're using either clang or nvcc 7.5 or above
|
||||
#if EIGEN_MAX_CPP_VER>=14 && (__cplusplus > 199711L && defined(__CUDACC_VER__) && (EIGEN_COMP_CLANG || __CUDACC_VER__ >= 70500))
|
||||
#define EIGEN_HAS_CONSTEXPR 1
|
||||
#endif
|
||||
#elif EIGEN_MAX_CPP_VER>=14 && (__has_feature(cxx_relaxed_constexpr) || (defined(__cplusplus) && __cplusplus >= 201402L) || \
|
||||
(EIGEN_GNUC_AT_LEAST(4,8) && (__cplusplus > 199711L)) || \
|
||||
(EIGEN_COMP_CLANG >= 306 && (__cplusplus > 199711L)))
|
||||
#define EIGEN_HAS_CONSTEXPR 1
|
||||
#endif
|
||||
#ifndef EIGEN_HAS_CONSTEXPR
|
||||
#define EIGEN_HAS_CONSTEXPR 0
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_HAS_CONSTEXPR
|
||||
#define EIGEN_HAS_CONSTEXPR 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif // EIGEN_HAS_CONSTEXPR
|
||||
|
||||
// Does the compiler support C++11 math?
|
||||
// Let's be conservative and enable the default C++11 implementation only if we are sure it exists
|
||||
@@ -480,15 +627,42 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Allows to disable some optimizations which might affect the accuracy of the result.
|
||||
* Such optimization are enabled by default, and set EIGEN_FAST_MATH to 0 to disable them.
|
||||
* They currently include:
|
||||
* - single precision ArrayBase::sin() and ArrayBase::cos() for SSE and AVX vectorization.
|
||||
*/
|
||||
#ifndef EIGEN_FAST_MATH
|
||||
#define EIGEN_FAST_MATH 1
|
||||
#ifndef EIGEN_HAS_CXX11_ATOMIC
|
||||
#if EIGEN_MAX_CPP_VER>=11 && \
|
||||
(__has_feature(cxx_atomic) \
|
||||
|| (__cplusplus > 201103L) \
|
||||
|| ((__cplusplus >= 201103L) && (EIGEN_COMP_MSVC==0 || EIGEN_COMP_MSVC >= 1700)))
|
||||
#define EIGEN_HAS_CXX11_ATOMIC 1
|
||||
#else
|
||||
#define EIGEN_HAS_CXX11_ATOMIC 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_CUDACC) && EIGEN_HAS_CONSTEXPR
|
||||
// While available already with c++11, this is useful mostly starting with c++14 and relaxed constexpr rules
|
||||
#if defined(__NVCC__)
|
||||
// nvcc considers constexpr functions as __host__ __device__ with the option --expt-relaxed-constexpr
|
||||
#ifdef __CUDACC_RELAXED_CONSTEXPR__
|
||||
#define EIGEN_CONSTEXPR_ARE_DEVICE_FUNC
|
||||
#endif
|
||||
// See bug 1580: clang/CUDA fails to make the following calls
|
||||
// to constexpr bool std::equal_to::operator() even when
|
||||
// EIGEN_CONSTEXPR_ARE_DEVICE_FUNC is defined in c++14 only.
|
||||
// #elif defined(__clang__) && defined(__CUDA__) && EIGEN_HAS_CONSTEXPR == 1
|
||||
// // clang++ always considers constexpr functions as implicitly __host__ __device__
|
||||
// #define EIGEN_CONSTEXPR_ARE_DEVICE_FUNC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Preprocessor programming helpers
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
// This macro can be used to prevent from macro expansion, e.g.:
|
||||
// std::max EIGEN_NOT_A_MACRO(a,b)
|
||||
#define EIGEN_NOT_A_MACRO
|
||||
|
||||
#define EIGEN_DEBUG_VAR(x) std::cerr << #x << " = " << x << std::endl;
|
||||
|
||||
// concatenate two tokens
|
||||
@@ -504,11 +678,13 @@
|
||||
// EIGEN_STRONG_INLINE is a stronger version of the inline, using __forceinline on MSVC,
|
||||
// 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
|
||||
#define EIGEN_STRONG_INLINE __forceinline
|
||||
#else
|
||||
#define EIGEN_STRONG_INLINE inline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// EIGEN_ALWAYS_INLINE is the stronget, it has the effect of making the function inline and adding every possible
|
||||
// attribute to maximize inlining. This should only be used when really necessary: in particular,
|
||||
@@ -538,12 +714,42 @@
|
||||
#define EIGEN_PERMISSIVE_EXPR
|
||||
#endif
|
||||
|
||||
// GPU stuff
|
||||
|
||||
// Disable some features when compiling with GPU compilers (NVCC/clang-cuda/SYCL/HIPCC)
|
||||
#if defined(EIGEN_CUDACC) || defined(__SYCL_DEVICE_ONLY__) || defined(EIGEN_HIPCC)
|
||||
// Do not try asserts on device code
|
||||
#ifndef EIGEN_NO_DEBUG
|
||||
#define EIGEN_NO_DEBUG
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_INTERNAL_DEBUGGING
|
||||
#undef EIGEN_INTERNAL_DEBUGGING
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_EXCEPTIONS
|
||||
#undef EIGEN_EXCEPTIONS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// All functions callable from CUDA/HIP code must be qualified with __device__
|
||||
#ifdef EIGEN_GPUCC
|
||||
#ifndef EIGEN_DONT_VECTORIZE
|
||||
#define EIGEN_DONT_VECTORIZE
|
||||
#endif
|
||||
|
||||
#define EIGEN_DEVICE_FUNC __host__ __device__
|
||||
#else
|
||||
#define EIGEN_DEVICE_FUNC
|
||||
#endif
|
||||
|
||||
|
||||
// this macro allows to get rid of linking errors about multiply defined functions.
|
||||
// - static is not very good because it prevents definitions from different object files to be merged.
|
||||
// So static causes the resulting linked executable to be bloated with multiple copies of the same function.
|
||||
// - inline is not perfect either as it unwantedly hints the compiler toward inlining the function.
|
||||
#define EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
#define EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS inline
|
||||
#define EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_DEVICE_FUNC
|
||||
#define EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_DEVICE_FUNC inline
|
||||
|
||||
#ifdef NDEBUG
|
||||
# ifndef EIGEN_NO_DEBUG
|
||||
@@ -649,169 +855,6 @@ namespace Eigen {
|
||||
# define EIGEN_CONST_CONDITIONAL(cond) cond
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Static and dynamic alignment control
|
||||
//
|
||||
// The main purpose of this section is to define EIGEN_MAX_ALIGN_BYTES and EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
// as the maximal boundary in bytes on which dynamically and statically allocated data may be alignment respectively.
|
||||
// The values of EIGEN_MAX_ALIGN_BYTES and EIGEN_MAX_STATIC_ALIGN_BYTES can be specified by the user. If not,
|
||||
// a default value is automatically computed based on architecture, compiler, and OS.
|
||||
//
|
||||
// This section also defines macros EIGEN_ALIGN_TO_BOUNDARY(N) and the shortcuts EIGEN_ALIGN{8,16,32,_MAX}
|
||||
// to be used to declare statically aligned buffers.
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/* EIGEN_ALIGN_TO_BOUNDARY(n) forces data to be n-byte aligned. This is used to satisfy SIMD requirements.
|
||||
* However, we do that EVEN if vectorization (EIGEN_VECTORIZE) is disabled,
|
||||
* so that vectorization doesn't affect binary compatibility.
|
||||
*
|
||||
* If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link
|
||||
* vectorized and non-vectorized code.
|
||||
*/
|
||||
#if (defined __CUDACC__)
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __align__(n)
|
||||
#elif EIGEN_COMP_GNUC || EIGEN_COMP_PGI || EIGEN_COMP_IBM || EIGEN_COMP_ARM
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
|
||||
#elif EIGEN_COMP_MSVC
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __declspec(align(n))
|
||||
#elif EIGEN_COMP_SUNCC
|
||||
// FIXME not sure about this one:
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
|
||||
#else
|
||||
#error Please tell me what is the equivalent of __attribute__((aligned(n))) for your compiler
|
||||
#endif
|
||||
|
||||
// If the user explicitly disable vectorization, then we also disable alignment
|
||||
#if defined(EIGEN_DONT_VECTORIZE)
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 0
|
||||
#elif defined(EIGEN_VECTORIZE_AVX512)
|
||||
// 64 bytes static alignmeent is preferred only if really required
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 64
|
||||
#elif defined(__AVX__)
|
||||
// 32 bytes static alignmeent is preferred only if really required
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 32
|
||||
#else
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 16
|
||||
#endif
|
||||
|
||||
|
||||
// EIGEN_MIN_ALIGN_BYTES defines the minimal value for which the notion of explicit alignment makes sense
|
||||
#define EIGEN_MIN_ALIGN_BYTES 16
|
||||
|
||||
// Defined the boundary (in bytes) on which the data needs to be aligned. Note
|
||||
// that unless EIGEN_ALIGN is defined and not equal to 0, the data may not be
|
||||
// aligned at all regardless of the value of this #define.
|
||||
|
||||
#if (defined(EIGEN_DONT_ALIGN_STATICALLY) || defined(EIGEN_DONT_ALIGN)) && defined(EIGEN_MAX_STATIC_ALIGN_BYTES) && EIGEN_MAX_STATIC_ALIGN_BYTES>0
|
||||
#error EIGEN_MAX_STATIC_ALIGN_BYTES and EIGEN_DONT_ALIGN[_STATICALLY] are both defined with EIGEN_MAX_STATIC_ALIGN_BYTES!=0. Use EIGEN_MAX_STATIC_ALIGN_BYTES=0 as a synonym of EIGEN_DONT_ALIGN_STATICALLY.
|
||||
#endif
|
||||
|
||||
// EIGEN_DONT_ALIGN_STATICALLY and EIGEN_DONT_ALIGN are deprectated
|
||||
// They imply EIGEN_MAX_STATIC_ALIGN_BYTES=0
|
||||
#if defined(EIGEN_DONT_ALIGN_STATICALLY) || defined(EIGEN_DONT_ALIGN)
|
||||
#ifdef EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#undef EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#endif
|
||||
#define EIGEN_MAX_STATIC_ALIGN_BYTES 0
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
|
||||
// Try to automatically guess what is the best default value for EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
|
||||
// 16 byte alignment is only useful for vectorization. Since it affects the ABI, we need to enable
|
||||
// 16 byte alignment on all platforms where vectorization might be enabled. In theory we could always
|
||||
// enable alignment, but it can be a cause of problems on some platforms, so we just disable it in
|
||||
// certain common platform (compiler+architecture combinations) to avoid these problems.
|
||||
// Only static alignment is really problematic (relies on nonstandard compiler extensions),
|
||||
// try to keep heap alignment even when we have to disable static alignment.
|
||||
#if EIGEN_COMP_GNUC && !(EIGEN_ARCH_i386_OR_x86_64 || EIGEN_ARCH_ARM_OR_ARM64 || EIGEN_ARCH_PPC || EIGEN_ARCH_IA64)
|
||||
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 1
|
||||
#elif EIGEN_ARCH_ARM_OR_ARM64 && EIGEN_COMP_GNUC_STRICT && EIGEN_GNUC_AT_MOST(4, 6)
|
||||
// Old versions of GCC on ARM, at least 4.4, were once seen to have buggy static alignment support.
|
||||
// Not sure which version fixed it, hopefully it doesn't affect 4.7, which is still somewhat in use.
|
||||
// 4.8 and newer seem definitely unaffected.
|
||||
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 1
|
||||
#else
|
||||
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 0
|
||||
#endif
|
||||
|
||||
// static alignment is completely disabled with GCC 3, Sun Studio, and QCC/QNX
|
||||
#if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT \
|
||||
&& !EIGEN_GCC3_OR_OLDER \
|
||||
&& !EIGEN_COMP_SUNCC \
|
||||
&& !EIGEN_OS_QNX
|
||||
#define EIGEN_ARCH_WANTS_STACK_ALIGNMENT 1
|
||||
#else
|
||||
#define EIGEN_ARCH_WANTS_STACK_ALIGNMENT 0
|
||||
#endif
|
||||
|
||||
#if EIGEN_ARCH_WANTS_STACK_ALIGNMENT
|
||||
#define EIGEN_MAX_STATIC_ALIGN_BYTES EIGEN_IDEAL_MAX_ALIGN_BYTES
|
||||
#else
|
||||
#define EIGEN_MAX_STATIC_ALIGN_BYTES 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// If EIGEN_MAX_ALIGN_BYTES is defined, then it is considered as an upper bound for EIGEN_MAX_ALIGN_BYTES
|
||||
#if defined(EIGEN_MAX_ALIGN_BYTES) && EIGEN_MAX_ALIGN_BYTES<EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#undef EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#define EIGEN_MAX_STATIC_ALIGN_BYTES EIGEN_MAX_ALIGN_BYTES
|
||||
#endif
|
||||
|
||||
#if EIGEN_MAX_STATIC_ALIGN_BYTES==0 && !defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
|
||||
#define EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
|
||||
#endif
|
||||
|
||||
// At this stage, EIGEN_MAX_STATIC_ALIGN_BYTES>0 is the true test whether we want to align arrays on the stack or not.
|
||||
// It takes into account both the user choice to explicitly enable/disable alignment (by settting EIGEN_MAX_STATIC_ALIGN_BYTES)
|
||||
// and the architecture config (EIGEN_ARCH_WANTS_STACK_ALIGNMENT).
|
||||
// Henceforth, only EIGEN_MAX_STATIC_ALIGN_BYTES should be used.
|
||||
|
||||
|
||||
// Shortcuts to EIGEN_ALIGN_TO_BOUNDARY
|
||||
#define EIGEN_ALIGN8 EIGEN_ALIGN_TO_BOUNDARY(8)
|
||||
#define EIGEN_ALIGN16 EIGEN_ALIGN_TO_BOUNDARY(16)
|
||||
#define EIGEN_ALIGN32 EIGEN_ALIGN_TO_BOUNDARY(32)
|
||||
#define EIGEN_ALIGN64 EIGEN_ALIGN_TO_BOUNDARY(64)
|
||||
#if EIGEN_MAX_STATIC_ALIGN_BYTES>0
|
||||
#define EIGEN_ALIGN_MAX EIGEN_ALIGN_TO_BOUNDARY(EIGEN_MAX_STATIC_ALIGN_BYTES)
|
||||
#else
|
||||
#define EIGEN_ALIGN_MAX
|
||||
#endif
|
||||
|
||||
|
||||
// Dynamic alignment control
|
||||
|
||||
#if defined(EIGEN_DONT_ALIGN) && defined(EIGEN_MAX_ALIGN_BYTES) && EIGEN_MAX_ALIGN_BYTES>0
|
||||
#error EIGEN_MAX_ALIGN_BYTES and EIGEN_DONT_ALIGN are both defined with EIGEN_MAX_ALIGN_BYTES!=0. Use EIGEN_MAX_ALIGN_BYTES=0 as a synonym of EIGEN_DONT_ALIGN.
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_DONT_ALIGN
|
||||
#ifdef EIGEN_MAX_ALIGN_BYTES
|
||||
#undef EIGEN_MAX_ALIGN_BYTES
|
||||
#endif
|
||||
#define EIGEN_MAX_ALIGN_BYTES 0
|
||||
#elif !defined(EIGEN_MAX_ALIGN_BYTES)
|
||||
#define EIGEN_MAX_ALIGN_BYTES EIGEN_IDEAL_MAX_ALIGN_BYTES
|
||||
#endif
|
||||
|
||||
#if EIGEN_IDEAL_MAX_ALIGN_BYTES > EIGEN_MAX_ALIGN_BYTES
|
||||
#define EIGEN_DEFAULT_ALIGN_BYTES EIGEN_IDEAL_MAX_ALIGN_BYTES
|
||||
#else
|
||||
#define EIGEN_DEFAULT_ALIGN_BYTES EIGEN_MAX_ALIGN_BYTES
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef EIGEN_UNALIGNED_VECTORIZE
|
||||
#define EIGEN_UNALIGNED_VECTORIZE 1
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifdef EIGEN_DONT_USE_RESTRICT_KEYWORD
|
||||
#define EIGEN_RESTRICT
|
||||
#endif
|
||||
@@ -819,10 +862,6 @@ namespace Eigen {
|
||||
#define EIGEN_RESTRICT __restrict
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_STACK_ALLOCATION_LIMIT
|
||||
// 131072 == 128 KB
|
||||
#define EIGEN_STACK_ALLOCATION_LIMIT 131072
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_DEFAULT_IO_FORMAT
|
||||
#ifdef EIGEN_MAKING_DOCS
|
||||
@@ -837,7 +876,20 @@ namespace Eigen {
|
||||
// just an empty macro !
|
||||
#define EIGEN_EMPTY
|
||||
|
||||
#if EIGEN_COMP_MSVC_STRICT && (EIGEN_COMP_MSVC < 1900 || defined(__CUDACC_VER__)) // for older MSVC versions, as well as 1900 && CUDA 8, using the base operator is sufficient (cf Bugs 1000, 1324)
|
||||
|
||||
// When compiling CUDA/HIP device code with NVCC or HIPCC
|
||||
// pull in math functions from the global namespace.
|
||||
// In host mode, and when device code is compiled with clang,
|
||||
// use the std versions.
|
||||
#if (defined(EIGEN_CUDA_ARCH) && defined(__NVCC__)) || defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
#define EIGEN_USING_STD_MATH(FUNC) using ::FUNC;
|
||||
#else
|
||||
#define EIGEN_USING_STD_MATH(FUNC) using std::FUNC;
|
||||
#endif
|
||||
|
||||
|
||||
#if EIGEN_COMP_MSVC_STRICT && (EIGEN_COMP_MSVC < 1900 || EIGEN_CUDACC_VER>0)
|
||||
// for older MSVC versions, as well as 1900 && CUDA 8, using the base operator is sufficient (cf Bugs 1000, 1324)
|
||||
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
|
||||
using Base::operator =;
|
||||
#elif EIGEN_COMP_CLANG // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)
|
||||
@@ -955,7 +1007,7 @@ namespace Eigen {
|
||||
const typename internal::plain_constant_type<EXPR,SCALAR>::type, const EXPR>
|
||||
|
||||
// Workaround for MSVC 2010 (see ML thread "patch with compile for for MSVC 2010")
|
||||
#if EIGEN_COMP_MSVC_STRICT<=1600
|
||||
#if EIGEN_COMP_MSVC_STRICT && (EIGEN_COMP_MSVC_STRICT<=1600)
|
||||
#define EIGEN_MSVC10_WORKAROUND_BINARYOP_RETURN_TYPE(X) typename internal::enable_if<true,X>::type
|
||||
#else
|
||||
#define EIGEN_MSVC10_WORKAROUND_BINARYOP_RETURN_TYPE(X) X
|
||||
@@ -984,15 +1036,23 @@ namespace Eigen {
|
||||
EIGEN_MAKE_SCALAR_BINARY_OP_ONTHERIGHT(METHOD,OPNAME)
|
||||
|
||||
|
||||
#if (defined(_CPPUNWIND) || defined(__EXCEPTIONS)) && !defined(EIGEN_CUDA_ARCH) && !defined(EIGEN_EXCEPTIONS) && !defined(EIGEN_USE_SYCL) && !defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
#define EIGEN_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef EIGEN_EXCEPTIONS
|
||||
# define EIGEN_THROW_X(X) throw X
|
||||
# define EIGEN_THROW throw
|
||||
# define EIGEN_TRY try
|
||||
# define EIGEN_CATCH(X) catch (X)
|
||||
#else
|
||||
# ifdef __CUDA_ARCH__
|
||||
# if defined(EIGEN_CUDA_ARCH)
|
||||
# define EIGEN_THROW_X(X) asm("trap;")
|
||||
# define EIGEN_THROW asm("trap;")
|
||||
# elif defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
# define EIGEN_THROW_X(X) asm("s_trap 0")
|
||||
# define EIGEN_THROW asm("s_trap 0")
|
||||
# else
|
||||
# define EIGEN_THROW_X(X) std::abort()
|
||||
# define EIGEN_THROW std::abort()
|
||||
@@ -1012,7 +1072,38 @@ namespace Eigen {
|
||||
# define EIGEN_NOEXCEPT
|
||||
# define EIGEN_NOEXCEPT_IF(x)
|
||||
# define EIGEN_NO_THROW throw()
|
||||
# define EIGEN_EXCEPTION_SPEC(X) throw(X)
|
||||
# if EIGEN_COMP_MSVC
|
||||
// MSVC does not support exception specifications (warning C4290),
|
||||
// and they are deprecated in c++11 anyway.
|
||||
# define EIGEN_EXCEPTION_SPEC(X) throw()
|
||||
# else
|
||||
# define EIGEN_EXCEPTION_SPEC(X) throw(X)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if EIGEN_HAS_VARIADIC_TEMPLATES
|
||||
// The all function is used to enable a variadic version of eigen_assert which can take a parameter pack as its input.
|
||||
namespace Eigen {
|
||||
namespace internal {
|
||||
|
||||
inline bool all(){ return true; }
|
||||
|
||||
template<typename T, typename ...Ts>
|
||||
bool all(T t, Ts ... ts){ return t && all(ts...); }
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Wrapping #pragma unroll in a macro since it is required for SYCL
|
||||
#if defined(__SYCL_DEVICE_ONLY__)
|
||||
#if defined(_MSC_VER)
|
||||
#define EIGEN_UNROLL_LOOP __pragma(unroll)
|
||||
#else
|
||||
#define EIGEN_UNROLL_LOOP _Pragma("unroll")
|
||||
#endif
|
||||
#else
|
||||
#define EIGEN_UNROLL_LOOP
|
||||
#endif
|
||||
|
||||
#endif // EIGEN_MACROS_H
|
||||
|
||||
@@ -70,7 +70,20 @@ inline void throw_std_bad_alloc()
|
||||
throw std::bad_alloc();
|
||||
#else
|
||||
std::size_t huge = static_cast<std::size_t>(-1);
|
||||
#if defined(EIGEN_HIPCC)
|
||||
//
|
||||
// calls to "::operator new" are to be treated as opaque function calls (i.e no inlining),
|
||||
// and as a consequence the code in the #else block triggers the hipcc warning :
|
||||
// "no overloaded function has restriction specifiers that are compatible with the ambient context"
|
||||
//
|
||||
// "throw_std_bad_alloc" has the EIGEN_DEVICE_FUNC attribute, so it seems that hipcc expects
|
||||
// the same on "operator new"
|
||||
// Reverting code back to the old version in this #if block for the hipcc compiler
|
||||
//
|
||||
new int[huge];
|
||||
#else
|
||||
::operator new(huge);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -83,11 +96,12 @@ inline void throw_std_bad_alloc()
|
||||
/** \internal Like malloc, but the returned pointer is guaranteed to be 16-byte aligned.
|
||||
* Fast, but wastes 16 additional bytes of memory. Does not throw any exception.
|
||||
*/
|
||||
inline void* handmade_aligned_malloc(std::size_t size)
|
||||
inline void* handmade_aligned_malloc(std::size_t size, std::size_t alignment = EIGEN_DEFAULT_ALIGN_BYTES)
|
||||
{
|
||||
void *original = std::malloc(size+EIGEN_DEFAULT_ALIGN_BYTES);
|
||||
eigen_assert(alignment >= sizeof(void*) && (alignment & -alignment) == alignment && "Alignment must be at least sizeof(void*) and a power of 2");
|
||||
void *original = std::malloc(size+alignment);
|
||||
if (original == 0) return 0;
|
||||
void *aligned = reinterpret_cast<void*>((reinterpret_cast<std::size_t>(original) & ~(std::size_t(EIGEN_DEFAULT_ALIGN_BYTES-1))) + EIGEN_DEFAULT_ALIGN_BYTES);
|
||||
void *aligned = reinterpret_cast<void*>((reinterpret_cast<std::size_t>(original) & ~(std::size_t(alignment-1))) + alignment);
|
||||
*(reinterpret_cast<void**>(aligned) - 1) = original;
|
||||
return aligned;
|
||||
}
|
||||
@@ -156,9 +170,15 @@ EIGEN_DEVICE_FUNC inline void* aligned_malloc(std::size_t size)
|
||||
|
||||
void *result;
|
||||
#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
|
||||
#if defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
result = ::malloc(size);
|
||||
#else
|
||||
result = std::malloc(size);
|
||||
#endif
|
||||
|
||||
#if EIGEN_DEFAULT_ALIGN_BYTES==16
|
||||
eigen_assert((size<16 || (std::size_t(result)%16)==0) && "System's malloc returned an unaligned pointer. Compile with EIGEN_MALLOC_ALREADY_ALIGNED=0 to fallback to handmade alignd memory allocator.");
|
||||
eigen_assert((size<16 || (std::size_t(result)%16)==0) && "System's malloc returned an unaligned pointer. Compile with EIGEN_MALLOC_ALREADY_ALIGNED=0 to fallback to handmade aligned memory allocator.");
|
||||
#endif
|
||||
#else
|
||||
result = handmade_aligned_malloc(size);
|
||||
@@ -174,7 +194,13 @@ EIGEN_DEVICE_FUNC inline void* aligned_malloc(std::size_t size)
|
||||
EIGEN_DEVICE_FUNC inline void aligned_free(void *ptr)
|
||||
{
|
||||
#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
|
||||
#if defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
::free(ptr);
|
||||
#else
|
||||
std::free(ptr);
|
||||
#endif
|
||||
|
||||
#else
|
||||
handmade_aligned_free(ptr);
|
||||
#endif
|
||||
@@ -218,7 +244,12 @@ template<> EIGEN_DEVICE_FUNC inline void* conditional_aligned_malloc<false>(std:
|
||||
{
|
||||
check_that_malloc_is_allowed();
|
||||
|
||||
#if defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
void *result = ::malloc(size);
|
||||
#else
|
||||
void *result = std::malloc(size);
|
||||
#endif
|
||||
|
||||
if(!result && size)
|
||||
throw_std_bad_alloc();
|
||||
return result;
|
||||
@@ -232,7 +263,11 @@ template<bool Align> EIGEN_DEVICE_FUNC inline void conditional_aligned_free(void
|
||||
|
||||
template<> EIGEN_DEVICE_FUNC inline void conditional_aligned_free<false>(void *ptr)
|
||||
{
|
||||
#if defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
::free(ptr);
|
||||
#else
|
||||
std::free(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<bool Align> inline void* conditional_aligned_realloc(void* ptr, std::size_t new_size, std::size_t old_size)
|
||||
@@ -493,7 +528,11 @@ template<typename T> struct smart_copy_helper<T,true> {
|
||||
IntPtr size = IntPtr(end)-IntPtr(start);
|
||||
if(size==0) return;
|
||||
eigen_internal_assert(start!=0 && end!=0 && target!=0);
|
||||
memcpy(target, start, size);
|
||||
#if defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
::memcpy(target, start, size);
|
||||
#else
|
||||
std::memcpy(target, start, size);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@@ -542,7 +581,7 @@ template<typename T> struct smart_memmove_helper<T,false> {
|
||||
|
||||
// you can overwrite Eigen's default behavior regarding alloca by defining EIGEN_ALLOCA
|
||||
// to the appropriate stack allocation function
|
||||
#ifndef EIGEN_ALLOCA
|
||||
#if ! defined EIGEN_ALLOCA && ! defined EIGEN_GPU_COMPILE_PHASE
|
||||
#if EIGEN_OS_LINUX || EIGEN_OS_MAC || (defined alloca)
|
||||
#define EIGEN_ALLOCA alloca
|
||||
#elif EIGEN_COMP_MSVC
|
||||
@@ -550,6 +589,15 @@ template<typename T> struct smart_memmove_helper<T,false> {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// With clang -Oz -mthumb, alloca changes the stack pointer in a way that is
|
||||
// not allowed in Thumb2. -DEIGEN_STACK_ALLOCATION_LIMIT=0 doesn't work because
|
||||
// the compiler still emits bad code because stack allocation checks use "<=".
|
||||
// TODO: Eliminate after https://bugs.llvm.org/show_bug.cgi?id=23772
|
||||
// is fixed.
|
||||
#if defined(__clang__) && defined(__thumb__)
|
||||
#undef EIGEN_ALLOCA
|
||||
#endif
|
||||
|
||||
// This helper class construct the allocated memory, and takes care of destructing and freeing the handled data
|
||||
// at destruction time. In practice this helper class is mainly useful to avoid memory leak in case of exceptions.
|
||||
template<typename T> class aligned_stack_memory_handler : noncopyable
|
||||
@@ -561,12 +609,14 @@ template<typename T> class aligned_stack_memory_handler : noncopyable
|
||||
* In this case, the buffer elements will also be destructed when this handler will be destructed.
|
||||
* Finally, if \a dealloc is true, then the pointer \a ptr is freed.
|
||||
**/
|
||||
EIGEN_DEVICE_FUNC
|
||||
aligned_stack_memory_handler(T* ptr, std::size_t size, bool dealloc)
|
||||
: m_ptr(ptr), m_size(size), m_deallocate(dealloc)
|
||||
{
|
||||
if(NumTraits<T>::RequireInitialization && m_ptr)
|
||||
Eigen::internal::construct_elements_of_array(m_ptr, size);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
~aligned_stack_memory_handler()
|
||||
{
|
||||
if(NumTraits<T>::RequireInitialization && m_ptr)
|
||||
@@ -580,6 +630,60 @@ template<typename T> class aligned_stack_memory_handler : noncopyable
|
||||
bool m_deallocate;
|
||||
};
|
||||
|
||||
#ifdef EIGEN_ALLOCA
|
||||
|
||||
template<typename Xpr, int NbEvaluations,
|
||||
bool MapExternalBuffer = nested_eval<Xpr,NbEvaluations>::Evaluate && Xpr::MaxSizeAtCompileTime==Dynamic
|
||||
>
|
||||
struct local_nested_eval_wrapper
|
||||
{
|
||||
static const bool NeedExternalBuffer = false;
|
||||
typedef typename Xpr::Scalar Scalar;
|
||||
typedef typename nested_eval<Xpr,NbEvaluations>::type ObjectType;
|
||||
ObjectType object;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
local_nested_eval_wrapper(const Xpr& xpr, Scalar* ptr) : object(xpr)
|
||||
{
|
||||
EIGEN_UNUSED_VARIABLE(ptr);
|
||||
eigen_internal_assert(ptr==0);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Xpr, int NbEvaluations>
|
||||
struct local_nested_eval_wrapper<Xpr,NbEvaluations,true>
|
||||
{
|
||||
static const bool NeedExternalBuffer = true;
|
||||
typedef typename Xpr::Scalar Scalar;
|
||||
typedef typename plain_object_eval<Xpr>::type PlainObject;
|
||||
typedef Map<PlainObject,EIGEN_DEFAULT_ALIGN_BYTES> ObjectType;
|
||||
ObjectType object;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
local_nested_eval_wrapper(const Xpr& xpr, Scalar* ptr)
|
||||
: object(ptr==0 ? reinterpret_cast<Scalar*>(Eigen::internal::aligned_malloc(sizeof(Scalar)*xpr.size())) : ptr, xpr.rows(), xpr.cols()),
|
||||
m_deallocate(ptr==0)
|
||||
{
|
||||
if(NumTraits<Scalar>::RequireInitialization && object.data())
|
||||
Eigen::internal::construct_elements_of_array(object.data(), object.size());
|
||||
object = xpr;
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
~local_nested_eval_wrapper()
|
||||
{
|
||||
if(NumTraits<Scalar>::RequireInitialization && object.data())
|
||||
Eigen::internal::destruct_elements_of_array(object.data(), object.size());
|
||||
if(m_deallocate)
|
||||
Eigen::internal::aligned_free(object.data());
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_deallocate;
|
||||
};
|
||||
|
||||
#endif // EIGEN_ALLOCA
|
||||
|
||||
template<typename T> class scoped_array : noncopyable
|
||||
{
|
||||
T* m_ptr;
|
||||
@@ -607,9 +711,11 @@ template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
|
||||
} // end namespace internal
|
||||
|
||||
/** \internal
|
||||
* Declares, allocates and construct an aligned buffer named NAME of SIZE elements of type TYPE on the stack
|
||||
* if SIZE is smaller than EIGEN_STACK_ALLOCATION_LIMIT, and if stack allocation is supported by the platform
|
||||
* (currently, this is Linux and Visual Studio only). Otherwise the memory is allocated on the heap.
|
||||
*
|
||||
* The macro ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) declares, allocates,
|
||||
* and construct an aligned buffer named NAME of SIZE elements of type TYPE on the stack
|
||||
* if the size in bytes is smaller than EIGEN_STACK_ALLOCATION_LIMIT, and if stack allocation is supported by the platform
|
||||
* (currently, this is Linux, OSX and Visual Studio only). Otherwise the memory is allocated on the heap.
|
||||
* The allocated buffer is automatically deleted when exiting the scope of this declaration.
|
||||
* If BUFFER is non null, then the declared variable is simply an alias for BUFFER, and no allocation/deletion occurs.
|
||||
* Here is an example:
|
||||
@@ -620,6 +726,14 @@ template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
|
||||
* }
|
||||
* \endcode
|
||||
* The underlying stack allocation function can controlled with the EIGEN_ALLOCA preprocessor token.
|
||||
*
|
||||
* The macro ei_declare_local_nested_eval(XPR_T,XPR,N,NAME) is analogue to
|
||||
* \code
|
||||
* typename internal::nested_eval<XPRT_T,N>::type NAME(XPR);
|
||||
* \endcode
|
||||
* with the advantage of using aligned stack allocation even if the maximal size of XPR at compile time is unknown.
|
||||
* This is accomplished through alloca if this later is supported and if the required number of bytes
|
||||
* is below EIGEN_STACK_ALLOCATION_LIMIT.
|
||||
*/
|
||||
#ifdef EIGEN_ALLOCA
|
||||
|
||||
@@ -639,6 +753,13 @@ template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
|
||||
: Eigen::internal::aligned_malloc(sizeof(TYPE)*SIZE) ); \
|
||||
Eigen::internal::aligned_stack_memory_handler<TYPE> EIGEN_CAT(NAME,_stack_memory_destructor)((BUFFER)==0 ? NAME : 0,SIZE,sizeof(TYPE)*SIZE>EIGEN_STACK_ALLOCATION_LIMIT)
|
||||
|
||||
|
||||
#define ei_declare_local_nested_eval(XPR_T,XPR,N,NAME) \
|
||||
Eigen::internal::local_nested_eval_wrapper<XPR_T,N> EIGEN_CAT(NAME,_wrapper)(XPR, reinterpret_cast<typename XPR_T::Scalar*>( \
|
||||
( (Eigen::internal::local_nested_eval_wrapper<XPR_T,N>::NeedExternalBuffer) && ((sizeof(typename XPR_T::Scalar)*XPR.size())<=EIGEN_STACK_ALLOCATION_LIMIT) ) \
|
||||
? EIGEN_ALIGNED_ALLOCA( sizeof(typename XPR_T::Scalar)*XPR.size() ) : 0 ) ) ; \
|
||||
typename Eigen::internal::local_nested_eval_wrapper<XPR_T,N>::ObjectType NAME(EIGEN_CAT(NAME,_wrapper).object)
|
||||
|
||||
#else
|
||||
|
||||
#define ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) \
|
||||
@@ -646,6 +767,9 @@ template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
|
||||
TYPE* NAME = (BUFFER)!=0 ? BUFFER : reinterpret_cast<TYPE*>(Eigen::internal::aligned_malloc(sizeof(TYPE)*SIZE)); \
|
||||
Eigen::internal::aligned_stack_memory_handler<TYPE> EIGEN_CAT(NAME,_stack_memory_destructor)((BUFFER)==0 ? NAME : 0,SIZE,true)
|
||||
|
||||
|
||||
#define ei_declare_local_nested_eval(XPR_T,XPR,N,NAME) typename Eigen::internal::nested_eval<XPR_T,N>::type NAME(XPR)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -688,15 +812,27 @@ template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
|
||||
#endif
|
||||
|
||||
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(true)
|
||||
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar,Size) \
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(bool(((Size)!=Eigen::Dynamic) && ((sizeof(Scalar)*(Size))%EIGEN_MAX_ALIGN_BYTES==0)))
|
||||
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar,Size) \
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(bool( \
|
||||
((Size)!=Eigen::Dynamic) && \
|
||||
(((EIGEN_MAX_ALIGN_BYTES>=16) && ((sizeof(Scalar)*(Size))%(EIGEN_MAX_ALIGN_BYTES )==0)) || \
|
||||
((EIGEN_MAX_ALIGN_BYTES>=32) && ((sizeof(Scalar)*(Size))%(EIGEN_MAX_ALIGN_BYTES/2)==0)) || \
|
||||
((EIGEN_MAX_ALIGN_BYTES>=64) && ((sizeof(Scalar)*(Size))%(EIGEN_MAX_ALIGN_BYTES/4)==0)) )))
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/** \class aligned_allocator
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* \brief STL compatible allocator to use with with 16 byte aligned types
|
||||
* \brief STL compatible allocator to use with types requiring a non standrad alignment.
|
||||
*
|
||||
* The memory is aligned as for dynamically aligned matrix/array types such as MatrixXd.
|
||||
* By default, it will thus provide at least 16 bytes alignment and more in following cases:
|
||||
* - 32 bytes alignment if AVX is enabled.
|
||||
* - 64 bytes alignment if AVX512 is enabled.
|
||||
*
|
||||
* This can be controlled using the \c EIGEN_MAX_ALIGN_BYTES macro as documented
|
||||
* \link TopicPreprocessorDirectivesPerformance there \endlink.
|
||||
*
|
||||
* Example:
|
||||
* \code
|
||||
|
||||
@@ -11,9 +11,18 @@
|
||||
#ifndef EIGEN_META_H
|
||||
#define EIGEN_META_H
|
||||
|
||||
#if defined(__CUDA_ARCH__)
|
||||
#include <cfloat>
|
||||
#include <math_constants.h>
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
|
||||
#include <cfloat>
|
||||
|
||||
#if defined(EIGEN_CUDA_ARCH)
|
||||
#include <math_constants.h>
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
#include "Eigen/src/Core/arch/HIP/hcc/math_constants.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if EIGEN_COMP_ICC>=1600 && __cplusplus >= 201103L
|
||||
@@ -98,6 +107,8 @@ template<> struct is_arithmetic<signed long> { enum { value = true }; };
|
||||
template<> struct is_arithmetic<unsigned long> { enum { value = true }; };
|
||||
|
||||
#if EIGEN_HAS_CXX11
|
||||
template<> struct is_arithmetic<signed long long> { enum { value = true }; };
|
||||
template<> struct is_arithmetic<unsigned long long> { enum { value = true }; };
|
||||
using std::is_integral;
|
||||
#else
|
||||
template<typename T> struct is_integral { enum { value = false }; };
|
||||
@@ -111,8 +122,33 @@ template<> struct is_integral<signed int> { enum { value = true }; }
|
||||
template<> struct is_integral<unsigned int> { enum { value = true }; };
|
||||
template<> struct is_integral<signed long> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned long> { enum { value = true }; };
|
||||
#if EIGEN_COMP_MSVC
|
||||
template<> struct is_integral<signed __int64> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned __int64> { enum { value = true }; };
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if EIGEN_HAS_CXX11
|
||||
using std::make_unsigned;
|
||||
#else
|
||||
// TODO: Possibly improve this implementation of make_unsigned.
|
||||
// It is currently used only by
|
||||
// template<typename Scalar> struct random_default_impl<Scalar, false, true>.
|
||||
template<typename> struct make_unsigned;
|
||||
template<> struct make_unsigned<char> { typedef unsigned char type; };
|
||||
template<> struct make_unsigned<signed char> { typedef unsigned char type; };
|
||||
template<> struct make_unsigned<unsigned char> { typedef unsigned char type; };
|
||||
template<> struct make_unsigned<signed short> { typedef unsigned short type; };
|
||||
template<> struct make_unsigned<unsigned short> { typedef unsigned short type; };
|
||||
template<> struct make_unsigned<signed int> { typedef unsigned int type; };
|
||||
template<> struct make_unsigned<unsigned int> { typedef unsigned int type; };
|
||||
template<> struct make_unsigned<signed long> { typedef unsigned long type; };
|
||||
template<> struct make_unsigned<unsigned long> { typedef unsigned long type; };
|
||||
#if EIGEN_COMP_MSVC
|
||||
template<> struct make_unsigned<signed __int64> { typedef unsigned __int64 type; };
|
||||
template<> struct make_unsigned<unsigned __int64> { typedef unsigned __int64 type; };
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template <typename T> struct add_const { typedef const T type; };
|
||||
template <typename T> struct add_const<T&> { typedef T& type; };
|
||||
@@ -139,16 +175,19 @@ private:
|
||||
struct yes {int a[1];};
|
||||
struct no {int a[2];};
|
||||
|
||||
static yes test(const To&, int);
|
||||
template<typename T>
|
||||
static yes test(T, int);
|
||||
|
||||
template<typename T>
|
||||
static no test(any_conversion, ...);
|
||||
|
||||
public:
|
||||
static From ms_from;
|
||||
static typename internal::remove_reference<From>::type* ms_from;
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma warning push
|
||||
#pragma warning ( disable : 2259 )
|
||||
#endif
|
||||
enum { value = sizeof(test(ms_from, 0))==sizeof(yes) };
|
||||
enum { value = sizeof(test<To>(*ms_from, 0))==sizeof(yes) };
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma warning pop
|
||||
#endif
|
||||
@@ -157,8 +196,7 @@ public:
|
||||
template<typename From, typename To>
|
||||
struct is_convertible
|
||||
{
|
||||
enum { value = is_convertible_impl<typename remove_all<From>::type,
|
||||
typename remove_all<To >::type>::value };
|
||||
enum { value = is_convertible_impl<From,To>::value };
|
||||
};
|
||||
|
||||
/** \internal Allows to enable/disable an overload
|
||||
@@ -169,7 +207,7 @@ template<bool Condition, typename T=void> struct enable_if;
|
||||
template<typename T> struct enable_if<true,T>
|
||||
{ typedef T type; };
|
||||
|
||||
#if defined(__CUDA_ARCH__)
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
#if !defined(__FLT_EPSILON__)
|
||||
#define __FLT_EPSILON__ FLT_EPSILON
|
||||
#define __DBL_EPSILON__ DBL_EPSILON
|
||||
@@ -191,13 +229,31 @@ template<> struct numeric_limits<float>
|
||||
EIGEN_DEVICE_FUNC
|
||||
static float epsilon() { return __FLT_EPSILON__; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static float (max)() { return CUDART_MAX_NORMAL_F; }
|
||||
static float (max)() {
|
||||
#if defined(EIGEN_CUDA_ARCH)
|
||||
return CUDART_MAX_NORMAL_F;
|
||||
#else
|
||||
return HIPRT_MAX_NORMAL_F;
|
||||
#endif
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
static float (min)() { return FLT_MIN; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static float infinity() { return CUDART_INF_F; }
|
||||
static float infinity() {
|
||||
#if defined(EIGEN_CUDA_ARCH)
|
||||
return CUDART_INF_F;
|
||||
#else
|
||||
return HIPRT_INF_F;
|
||||
#endif
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
static float quiet_NaN() { return CUDART_NAN_F; }
|
||||
static float quiet_NaN() {
|
||||
#if defined(EIGEN_CUDA_ARCH)
|
||||
return CUDART_NAN_F;
|
||||
#else
|
||||
return HIPRT_NAN_F;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
template<> struct numeric_limits<double>
|
||||
{
|
||||
@@ -208,9 +264,21 @@ template<> struct numeric_limits<double>
|
||||
EIGEN_DEVICE_FUNC
|
||||
static double (min)() { return DBL_MIN; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static double infinity() { return CUDART_INF; }
|
||||
static double infinity() {
|
||||
#if defined(EIGEN_CUDA_ARCH)
|
||||
return CUDART_INF;
|
||||
#else
|
||||
return HIPRT_INF;
|
||||
#endif
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
static double quiet_NaN() { return CUDART_NAN; }
|
||||
static double quiet_NaN() {
|
||||
#if defined(EIGEN_CUDA_ARCH)
|
||||
return CUDART_NAN;
|
||||
#else
|
||||
return HIPRT_NAN;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
template<> struct numeric_limits<int>
|
||||
{
|
||||
@@ -272,7 +340,7 @@ template<> struct numeric_limits<unsigned long long>
|
||||
#endif
|
||||
|
||||
/** \internal
|
||||
* A base class do disable default copy ctor and copy assignement operator.
|
||||
* A base class do disable default copy ctor and copy assignment operator.
|
||||
*/
|
||||
class noncopyable
|
||||
{
|
||||
@@ -433,10 +501,10 @@ struct meta_no { char a[2]; };
|
||||
template <typename T>
|
||||
struct has_ReturnType
|
||||
{
|
||||
template <typename C> static meta_yes testFunctor(typename C::ReturnType const *);
|
||||
template <typename C> static meta_no testFunctor(...);
|
||||
template <typename C> static meta_yes testFunctor(C const *, typename C::ReturnType const * = 0);
|
||||
template <typename C> static meta_no testFunctor(...);
|
||||
|
||||
enum { value = sizeof(testFunctor<T>(0)) == sizeof(meta_yes) };
|
||||
enum { value = sizeof(testFunctor<T>(static_cast<T*>(0))) == sizeof(meta_yes) };
|
||||
};
|
||||
|
||||
template<typename T> const T* return_ptr();
|
||||
@@ -522,14 +590,14 @@ template<typename T, typename U> struct scalar_product_traits
|
||||
} // end namespace internal
|
||||
|
||||
namespace numext {
|
||||
|
||||
#if defined(__CUDA_ARCH__)
|
||||
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
template<typename T> EIGEN_DEVICE_FUNC void swap(T &a, T &b) { T tmp = b; b = a; a = tmp; }
|
||||
#else
|
||||
template<typename T> EIGEN_STRONG_INLINE void swap(T &a, T &b) { std::swap(a,b); }
|
||||
#endif
|
||||
|
||||
#if defined(__CUDA_ARCH__)
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
using internal::device::numeric_limits;
|
||||
#else
|
||||
using std::numeric_limits;
|
||||
@@ -538,11 +606,36 @@ using std::numeric_limits;
|
||||
// Integer division with rounding up.
|
||||
// T is assumed to be an integer type with a>=0, and b>0
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
T div_ceil(const T &a, const T &b)
|
||||
{
|
||||
return (a+b-1) / b;
|
||||
}
|
||||
|
||||
// The aim of the following functions is to bypass -Wfloat-equal warnings
|
||||
// when we really want a strict equality comparison on floating points.
|
||||
template<typename X, typename Y> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||
bool equal_strict(const X& x,const Y& y) { return x == y; }
|
||||
|
||||
#if !defined(EIGEN_GPU_COMPILE_PHASE) || defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC)
|
||||
template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||
bool equal_strict(const float& x,const float& y) { return std::equal_to<float>()(x,y); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||
bool equal_strict(const double& x,const double& y) { return std::equal_to<double>()(x,y); }
|
||||
#endif
|
||||
|
||||
template<typename X, typename Y> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||
bool not_equal_strict(const X& x,const Y& y) { return x != y; }
|
||||
|
||||
#if !defined(EIGEN_GPU_COMPILE_PHASE) || defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC)
|
||||
template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||
bool not_equal_strict(const float& x,const float& y) { return std::not_equal_to<float>()(x,y); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||
bool not_equal_strict(const double& x,const double& y) { return std::not_equal_to<double>()(x,y); }
|
||||
#endif
|
||||
|
||||
} // end namespace numext
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
#ifdef EIGEN_WARNINGS_DISABLED
|
||||
#ifdef EIGEN_WARNINGS_DISABLED_2
|
||||
// "DisableStupidWarnings.h" was included twice recursively: Do not reenable warnings yet!
|
||||
# undef EIGEN_WARNINGS_DISABLED_2
|
||||
|
||||
#elif defined(EIGEN_WARNINGS_DISABLED)
|
||||
#undef EIGEN_WARNINGS_DISABLED
|
||||
|
||||
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||
@@ -8,7 +12,7 @@
|
||||
#pragma warning pop
|
||||
#elif defined __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined __GNUC__ && __GNUC__>=6
|
||||
#elif defined __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EIGEN_STATIC_ASSERT
|
||||
#ifndef EIGEN_NO_STATIC_ASSERT
|
||||
|
||||
#if EIGEN_MAX_CPP_VER>=11 && (__has_feature(cxx_static_assert) || (defined(__cplusplus) && __cplusplus >= 201103L) || (EIGEN_COMP_MSVC >= 1600))
|
||||
@@ -44,64 +45,65 @@
|
||||
struct static_assertion<true>
|
||||
{
|
||||
enum {
|
||||
YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX,
|
||||
YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES,
|
||||
YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES,
|
||||
THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE,
|
||||
THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE,
|
||||
THIS_METHOD_IS_ONLY_FOR_OBJECTS_OF_A_SPECIFIC_SIZE,
|
||||
OUT_OF_RANGE_ACCESS,
|
||||
YOU_MADE_A_PROGRAMMING_MISTAKE,
|
||||
EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT,
|
||||
EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE,
|
||||
YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR,
|
||||
YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR,
|
||||
UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC,
|
||||
THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES,
|
||||
FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED,
|
||||
NUMERIC_TYPE_MUST_BE_REAL,
|
||||
COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED,
|
||||
WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED,
|
||||
THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE,
|
||||
INVALID_MATRIX_PRODUCT,
|
||||
INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS,
|
||||
INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION,
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY,
|
||||
THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES,
|
||||
THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES,
|
||||
INVALID_MATRIX_TEMPLATE_PARAMETERS,
|
||||
INVALID_MATRIXBASE_TEMPLATE_PARAMETERS,
|
||||
BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER,
|
||||
THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX,
|
||||
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE,
|
||||
THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES,
|
||||
YOU_ALREADY_SPECIFIED_THIS_STRIDE,
|
||||
INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION,
|
||||
THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD,
|
||||
PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1,
|
||||
THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS,
|
||||
YOU_CANNOT_MIX_ARRAYS_AND_MATRICES,
|
||||
YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION,
|
||||
THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY,
|
||||
YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT,
|
||||
THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS,
|
||||
THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS,
|
||||
THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL,
|
||||
THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES,
|
||||
YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED,
|
||||
YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED,
|
||||
THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE,
|
||||
THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH,
|
||||
OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG,
|
||||
IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY,
|
||||
STORAGE_LAYOUT_DOES_NOT_MATCH,
|
||||
EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT__INVALID_COST_VALUE,
|
||||
THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS,
|
||||
MATRIX_FREE_CONJUGATE_GRADIENT_IS_COMPATIBLE_WITH_UPPER_UNION_LOWER_MODE_ONLY,
|
||||
THIS_TYPE_IS_NOT_SUPPORTED,
|
||||
STORAGE_KIND_MUST_MATCH,
|
||||
STORAGE_INDEX_MUST_MATCH,
|
||||
CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY
|
||||
YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX=1,
|
||||
YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES=1,
|
||||
YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_OBJECTS_OF_A_SPECIFIC_SIZE=1,
|
||||
OUT_OF_RANGE_ACCESS=1,
|
||||
YOU_MADE_A_PROGRAMMING_MISTAKE=1,
|
||||
EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT=1,
|
||||
EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE=1,
|
||||
YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR=1,
|
||||
YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR=1,
|
||||
UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC=1,
|
||||
THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES=1,
|
||||
FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED=1,
|
||||
NUMERIC_TYPE_MUST_BE_REAL=1,
|
||||
COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED=1,
|
||||
WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE=1,
|
||||
INVALID_MATRIX_PRODUCT=1,
|
||||
INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS=1,
|
||||
INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION=1,
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES=1,
|
||||
INVALID_MATRIX_TEMPLATE_PARAMETERS=1,
|
||||
INVALID_MATRIXBASE_TEMPLATE_PARAMETERS=1,
|
||||
BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX=1,
|
||||
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES=1,
|
||||
YOU_ALREADY_SPECIFIED_THIS_STRIDE=1,
|
||||
INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION=1,
|
||||
THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD=1,
|
||||
PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS=1,
|
||||
YOU_CANNOT_MIX_ARRAYS_AND_MATRICES=1,
|
||||
YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION=1,
|
||||
THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY=1,
|
||||
YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES=1,
|
||||
YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED=1,
|
||||
YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED=1,
|
||||
THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE=1,
|
||||
THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH=1,
|
||||
OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG=1,
|
||||
IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY=1,
|
||||
STORAGE_LAYOUT_DOES_NOT_MATCH=1,
|
||||
EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT__INVALID_COST_VALUE=1,
|
||||
THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS=1,
|
||||
MATRIX_FREE_CONJUGATE_GRADIENT_IS_COMPATIBLE_WITH_UPPER_UNION_LOWER_MODE_ONLY=1,
|
||||
THIS_TYPE_IS_NOT_SUPPORTED=1,
|
||||
STORAGE_KIND_MUST_MATCH=1,
|
||||
STORAGE_INDEX_MUST_MATCH=1,
|
||||
CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY=1,
|
||||
SELFADJOINTVIEW_ACCEPTS_UPPER_AND_LOWER_MODE_ONLY=1
|
||||
};
|
||||
};
|
||||
|
||||
@@ -131,7 +133,7 @@
|
||||
#define EIGEN_STATIC_ASSERT(CONDITION,MSG) eigen_assert((CONDITION) && #MSG);
|
||||
|
||||
#endif // EIGEN_NO_STATIC_ASSERT
|
||||
|
||||
#endif // EIGEN_STATIC_ASSERT
|
||||
|
||||
// static assertion failing if the type \a TYPE is not a vector type
|
||||
#define EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE) \
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \namespace Eigen::Symbolic
|
||||
/** \namespace Eigen::symbolic
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* This namespace defines a set of classes and functions to build and evaluate symbolic expressions of scalar type Index.
|
||||
@@ -20,9 +20,9 @@ namespace Eigen {
|
||||
*
|
||||
* \code
|
||||
* // First step, defines symbols:
|
||||
* struct x_tag {}; static const Symbolic::SymbolExpr<x_tag> x;
|
||||
* struct y_tag {}; static const Symbolic::SymbolExpr<y_tag> y;
|
||||
* struct z_tag {}; static const Symbolic::SymbolExpr<z_tag> z;
|
||||
* struct x_tag {}; static const symbolic::SymbolExpr<x_tag> x;
|
||||
* struct y_tag {}; static const symbolic::SymbolExpr<y_tag> y;
|
||||
* struct z_tag {}; static const symbolic::SymbolExpr<z_tag> z;
|
||||
*
|
||||
* // Defines an expression:
|
||||
* auto expr = (x+3)/y+z;
|
||||
@@ -35,10 +35,10 @@ namespace Eigen {
|
||||
* std::cout << expr98.eval(x=6) << "\n";
|
||||
* \endcode
|
||||
*
|
||||
* It is currently only used internally to define and minipulate the placeholders::last and placeholders::end symbols in Eigen::seq and Eigen::seqN.
|
||||
* It is currently only used internally to define and manipulate the Eigen::last and Eigen::lastp1 symbols in Eigen::seq and Eigen::seqN.
|
||||
*
|
||||
*/
|
||||
namespace Symbolic {
|
||||
namespace symbolic {
|
||||
|
||||
template<typename Tag> class Symbol;
|
||||
template<typename Arg0> class NegateExpr;
|
||||
@@ -187,17 +187,10 @@ public:
|
||||
|
||||
template<typename T>
|
||||
struct is_symbolic {
|
||||
// BaseExpr has no conversion ctor, so we only have to check whether T can be staticaly cast to its base class BaseExpr<T>.
|
||||
// BaseExpr has no conversion ctor, so we only have to check whether T can be statically cast to its base class BaseExpr<T>.
|
||||
enum { value = internal::is_convertible<T,BaseExpr<T> >::value };
|
||||
};
|
||||
|
||||
// Specialization for functions, because is_convertible fails in this case.
|
||||
// Useful in c++98/11 mode when testing is_symbolic<decltype(fix<N>)>
|
||||
template<typename T>
|
||||
struct is_symbolic<T (*)()> {
|
||||
enum { value = false };
|
||||
};
|
||||
|
||||
/** Represents the actual value of a symbol identified by its tag
|
||||
*
|
||||
* It is the return type of SymbolValue::operator=, and most of the time this is only way it is used.
|
||||
@@ -293,7 +286,7 @@ protected:
|
||||
Arg1 m_arg1;
|
||||
};
|
||||
|
||||
} // end namespace Symbolic
|
||||
} // end namespace symbolic
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
|
||||
@@ -34,6 +34,26 @@ inline IndexDest convert_index(const IndexSrc& idx) {
|
||||
return IndexDest(idx);
|
||||
}
|
||||
|
||||
// true if T can be considered as an integral index (i.e., and integral type or enum)
|
||||
template<typename T> struct is_valid_index_type
|
||||
{
|
||||
enum { value =
|
||||
#if EIGEN_HAS_TYPE_TRAITS
|
||||
internal::is_integral<T>::value || std::is_enum<T>::value
|
||||
#elif EIGEN_COMP_MSVC
|
||||
internal::is_integral<T>::value || __is_enum(T)
|
||||
#else
|
||||
// without C++11, we use is_convertible to Index instead of is_integral in order to treat enums as Index.
|
||||
internal::is_convertible<T,Index>::value
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
// true if both types are not valid index types
|
||||
template<typename RowIndices, typename ColIndices>
|
||||
struct valid_indexed_view_overload {
|
||||
enum { value = !(internal::is_valid_index_type<RowIndices>::value && internal::is_valid_index_type<ColIndices>::value) };
|
||||
};
|
||||
|
||||
// promote_scalar_arg is an helper used in operation between an expression and a scalar, like:
|
||||
// expression * scalar
|
||||
@@ -385,7 +405,7 @@ template<typename T> struct plain_matrix_type_row_major
|
||||
typedef Matrix<typename traits<T>::Scalar,
|
||||
Rows,
|
||||
Cols,
|
||||
(MaxCols==1&&MaxRows!=1) ? RowMajor : ColMajor,
|
||||
(MaxCols==1&&MaxRows!=1) ? ColMajor : RowMajor,
|
||||
MaxRows,
|
||||
MaxCols
|
||||
> type;
|
||||
@@ -440,7 +460,7 @@ template<typename T, int n, typename PlainObject = typename plain_object_eval<T>
|
||||
{
|
||||
enum {
|
||||
ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost,
|
||||
CoeffReadCost = evaluator<T>::CoeffReadCost, // NOTE What if an evaluator evaluate itself into a tempory?
|
||||
CoeffReadCost = evaluator<T>::CoeffReadCost, // NOTE What if an evaluator evaluate itself into a temporary?
|
||||
// Then CoeffReadCost will be small (e.g., 1) but we still have to evaluate, especially if n>1.
|
||||
// This situation is already taken care by the EvalBeforeNestingBit flag, which is turned ON
|
||||
// for all evaluator creating a temporary. This flag is then propagated by the parent evaluators.
|
||||
@@ -656,17 +676,32 @@ template<typename T> struct is_diagonal<DiagonalWrapper<T> >
|
||||
template<typename T, int S> struct is_diagonal<DiagonalMatrix<T,S> >
|
||||
{ enum { ret = true }; };
|
||||
|
||||
|
||||
template<typename T> struct is_identity
|
||||
{ enum { value = false }; };
|
||||
|
||||
template<typename T> struct is_identity<CwiseNullaryOp<internal::scalar_identity_op<typename T::Scalar>, T> >
|
||||
{ enum { value = true }; };
|
||||
|
||||
|
||||
template<typename S1, typename S2> struct glue_shapes;
|
||||
template<> struct glue_shapes<DenseShape,TriangularShape> { typedef TriangularShape type; };
|
||||
|
||||
template<typename T1, typename T2>
|
||||
bool is_same_dense(const T1 &mat1, const T2 &mat2, typename enable_if<has_direct_access<T1>::ret&&has_direct_access<T2>::ret, T1>::type * = 0)
|
||||
struct possibly_same_dense {
|
||||
enum { value = has_direct_access<T1>::ret && has_direct_access<T2>::ret && is_same<typename T1::Scalar,typename T2::Scalar>::value };
|
||||
};
|
||||
|
||||
template<typename T1, typename T2>
|
||||
EIGEN_DEVICE_FUNC
|
||||
bool is_same_dense(const T1 &mat1, const T2 &mat2, typename enable_if<possibly_same_dense<T1,T2>::value>::type * = 0)
|
||||
{
|
||||
return (mat1.data()==mat2.data()) && (mat1.innerStride()==mat2.innerStride()) && (mat1.outerStride()==mat2.outerStride());
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
bool is_same_dense(const T1 &, const T2 &, typename enable_if<!(has_direct_access<T1>::ret&&has_direct_access<T2>::ret), T1>::type * = 0)
|
||||
EIGEN_DEVICE_FUNC
|
||||
bool is_same_dense(const T1 &, const T2 &, typename enable_if<!possibly_same_dense<T1,T2>::value>::type * = 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user