mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-03-25 18:50:40 +08:00
* include Macros.h much earlier: since it takes care of the alignment platform detection, it is needed before we do the vectorization stuff in Eigen/Core !!
* kill EIGEN_DONT_ALIGN_HEAP option (one should use EIGEN_DONT_ALIGN) * rename EIGEN_DONT_ALIGN_STACK to EIGEN_DONT_ALIGN_STATICALLY. hope it's a better name.
This commit is contained in:
parent
61a14539c7
commit
2bd31d3fbc
36
Eigen/Core
36
Eigen/Core
@ -29,6 +29,26 @@
|
||||
// first thing Eigen does: prevent MSVC from committing suicide
|
||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
||||
|
||||
// then include this file where all our macros are defined. It's really important to do it first because
|
||||
// it's where we do all the alignment settings (platform detection and honoring the user's will if he
|
||||
// defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization.
|
||||
#include "src/Core/util/Macros.h"
|
||||
|
||||
// if alignment is disabled, then disable vectorization. Note: EIGEN_ALIGN is the proper check, it takes into
|
||||
// account both the user's will (EIGEN_DONT_ALIGN) and our own platform checks
|
||||
#if !EIGEN_ALIGN
|
||||
#ifndef EIGEN_DONT_VECTORIZE
|
||||
#define EIGEN_DONT_VECTORIZE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// disable vectorization on LLVM: it's not yet ready for that.
|
||||
#ifdef __clang__
|
||||
#ifndef EIGEN_DONT_VECTORIZE
|
||||
#define EIGEN_DONT_VECTORIZE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <malloc.h> // for _aligned_malloc -- need it regardless of whether vectorization is enabled
|
||||
#if (_MSC_VER >= 1500) // 2008 or later
|
||||
@ -40,26 +60,13 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
|
||||
#else
|
||||
#define EIGEN_GNUC_AT_LEAST(x,y) 0
|
||||
#endif
|
||||
|
||||
// Remember that usage of defined() in a #define is undefined by the standard
|
||||
#if (defined __SSE2__) && ( (!defined __GNUC__) || EIGEN_GNUC_AT_LEAST(4,2) )
|
||||
#define EIGEN_SSE2_BUT_NOT_OLD_GCC
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_DONT_ALIGN
|
||||
#define EIGEN_DONT_VECTORIZE
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#define EIGEN_DONT_VECTORIZE
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_DONT_VECTORIZE
|
||||
|
||||
#if defined (EIGEN_SSE2_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
|
||||
|
||||
// Defines symbols for compile-time detection of which instructions are
|
||||
@ -201,7 +208,6 @@ using std::size_t;
|
||||
/** The type used to identify a dense storage. */
|
||||
struct Dense {};
|
||||
|
||||
#include "src/Core/util/Macros.h"
|
||||
#include "src/Core/util/Constants.h"
|
||||
#include "src/Core/util/ForwardDeclarations.h"
|
||||
#include "src/Core/util/Meta.h"
|
||||
|
@ -35,6 +35,17 @@
|
||||
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
|
||||
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
|
||||
EIGEN_MINOR_VERSION>=z))))
|
||||
#ifdef __GNUC__
|
||||
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
|
||||
#else
|
||||
#define EIGEN_GNUC_AT_LEAST(x,y) 0
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ <= 3)
|
||||
#define EIGEN_GCC3_OR_OLDER 1
|
||||
#else
|
||||
#define EIGEN_GCC3_OR_OLDER 0
|
||||
#endif
|
||||
|
||||
// 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
|
||||
@ -49,12 +60,6 @@
|
||||
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 0
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ <= 3)
|
||||
#define EIGEN_GCC3_OR_OLDER 1
|
||||
#else
|
||||
#define EIGEN_GCC3_OR_OLDER 0
|
||||
#endif
|
||||
|
||||
// FIXME vectorization + stack alignment is completely disabled with sun studio
|
||||
#if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT && !EIGEN_GCC3_OR_OLDER && !defined(__SUNPRO_CC)
|
||||
#define EIGEN_ARCH_WANTS_STACK_ALIGNMENT 1
|
||||
@ -63,20 +68,20 @@
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_DONT_ALIGN
|
||||
#ifndef EIGEN_DONT_ALIGN_STACK
|
||||
#define EIGEN_DONT_ALIGN_STACK
|
||||
#endif
|
||||
#ifndef EIGEN_DONT_ALIGN_HEAP
|
||||
#define EIGEN_DONT_ALIGN_HEAP
|
||||
#ifndef EIGEN_DONT_ALIGN_STATICALLY
|
||||
#define EIGEN_DONT_ALIGN_STATICALLY
|
||||
#endif
|
||||
#define EIGEN_ALIGN 0
|
||||
#else
|
||||
#define EIGEN_ALIGN 1
|
||||
#endif
|
||||
|
||||
// EIGEN_ALIGN_STACK 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 disable
|
||||
// alignment (EIGEN_DONT_ALIGN_STACK) and the architecture config (EIGEN_ARCH_WANTS_STACK_ALIGNMENT). Henceforth, only EIGEN_ALIGN_STACK should be used.
|
||||
#if EIGEN_ARCH_WANTS_STACK_ALIGNMENT && !defined(EIGEN_DONT_ALIGN_STACK)
|
||||
#define EIGEN_ALIGN_STACK 1
|
||||
// EIGEN_ALIGN_STATICALLY 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 disable
|
||||
// alignment (EIGEN_DONT_ALIGN_STATICALLY) and the architecture config (EIGEN_ARCH_WANTS_STACK_ALIGNMENT). Henceforth, only EIGEN_ALIGN_STATICALLY should be used.
|
||||
#if EIGEN_ARCH_WANTS_STACK_ALIGNMENT && !defined(EIGEN_DONT_ALIGN_STATICALLY)
|
||||
#define EIGEN_ALIGN_STATICALLY 1
|
||||
#else
|
||||
#define EIGEN_ALIGN_STACK 0
|
||||
#define EIGEN_ALIGN_STATICALLY 0
|
||||
#ifdef EIGEN_VECTORIZE
|
||||
#error "Vectorization enabled, but our platform checks say that we don't do 16 byte stack alignment on this platform. If you added vectorization for another architecture, you also need to edit this platform check."
|
||||
#endif
|
||||
@ -85,12 +90,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_DONT_ALIGN_HEAP
|
||||
#define EIGEN_ALIGN_HEAP 1
|
||||
#else
|
||||
#define EIGEN_ALIGN_HEAP 0
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
|
||||
#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION RowMajor
|
||||
#else
|
||||
@ -204,7 +203,7 @@ using Eigen::ei_cos;
|
||||
* 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 !EIGEN_ALIGN_STACK
|
||||
#if !EIGEN_ALIGN_STATICALLY
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n)
|
||||
#elif (defined __GNUC__) || (defined __PGI)
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
|
||||
|
@ -172,7 +172,7 @@ inline void* ei_aligned_malloc(size_t size)
|
||||
#endif
|
||||
|
||||
void *result;
|
||||
#if !EIGEN_ALIGN_HEAP
|
||||
#if !EIGEN_ALIGN
|
||||
result = std::malloc(size);
|
||||
#elif EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
result = std::malloc(size);
|
||||
@ -196,7 +196,7 @@ inline void* ei_aligned_malloc(size_t size)
|
||||
/** \internal Frees memory allocated with ei_aligned_malloc. */
|
||||
inline void ei_aligned_free(void *ptr)
|
||||
{
|
||||
#if !EIGEN_ALIGN_HEAP
|
||||
#if !EIGEN_ALIGN
|
||||
std::free(ptr);
|
||||
#elif EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
std::free(ptr);
|
||||
@ -221,7 +221,7 @@ inline void* ei_aligned_realloc(void *ptr, size_t new_size, size_t old_size)
|
||||
(void)old_size; // Suppress 'unused variable' warning. Seen in boost tee.
|
||||
|
||||
void *result;
|
||||
#if !EIGEN_ALIGN_HEAP
|
||||
#if !EIGEN_ALIGN
|
||||
result = std::realloc(ptr,new_size);
|
||||
#elif EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
result = std::realloc(ptr,new_size);
|
||||
@ -443,7 +443,7 @@ inline static Integer ei_first_aligned(const Scalar* array, Integer size)
|
||||
*** Implementation of EIGEN_MAKE_ALIGNED_OPERATOR_NEW [_IF] ***
|
||||
*****************************************************************************/
|
||||
|
||||
#if EIGEN_ALIGN_HEAP
|
||||
#if EIGEN_ALIGN
|
||||
#ifdef EIGEN_EXCEPTIONS
|
||||
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
|
||||
void* operator new(size_t size, const std::nothrow_t&) throw() { \
|
||||
|
@ -88,21 +88,38 @@ class ei_compute_matrix_flags
|
||||
enum {
|
||||
row_major_bit = Options&RowMajor ? RowMajorBit : 0,
|
||||
is_dynamic_size_storage = MaxRows==Dynamic || MaxCols==Dynamic,
|
||||
#if EIGEN_ALIGN_STACK
|
||||
#if EIGEN_ALIGN_STATICALLY
|
||||
is_fixed_size_aligned
|
||||
= (!is_dynamic_size_storage) && (((MaxCols*MaxRows) % ei_packet_traits<Scalar>::size) == 0),
|
||||
#else
|
||||
is_fixed_size_aligned = 0,
|
||||
#endif
|
||||
#if EIGEN_ALIGN_HEAP
|
||||
#if EIGEN_ALIGN
|
||||
is_dynamic_size_aligned = is_dynamic_size_storage,
|
||||
#else
|
||||
is_dynamic_size_aligned = 0,
|
||||
#endif
|
||||
|
||||
aligned_bit = (((Options&DontAlign)==0)
|
||||
&& (is_dynamic_size_aligned || is_fixed_size_aligned))
|
||||
? AlignedBit : 0,
|
||||
aligned_bit =
|
||||
(
|
||||
((Options&DontAlign)==0)
|
||||
&& (
|
||||
#if EIGEN_ALIGN_STATICALLY
|
||||
((!is_dynamic_size_storage) && (((MaxCols*MaxRows) % ei_packet_traits<Scalar>::size) == 0))
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
|
||||
||
|
||||
|
||||
#if EIGEN_ALIGN
|
||||
is_dynamic_size_storage
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
|
||||
)
|
||||
) ? AlignedBit : 0,
|
||||
packet_access_bit = ei_packet_traits<Scalar>::size > 1 && aligned_bit ? PacketAccessBit : 0
|
||||
};
|
||||
|
||||
|
@ -107,8 +107,11 @@ However there are a few corner cases where these alignment settings get overridd
|
||||
|
||||
Two possibilities:
|
||||
<ul>
|
||||
<li>Define EIGEN_DONT_ALIGN. That disables all 128-bit alignment code, and in particular everything vectorization-related. But do note that this in particular breaks ABI compatibility with vectorized code.</li>
|
||||
<li>Or define both EIGEN_DONT_VECTORIZE and EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT. This keeps the 128-bit alignment code and thus preserves ABI compatibility.</li>
|
||||
<li>Define EIGEN_DONT_ALIGN_STATICALLY. That disables all 128-bit static alignment code, while keeping 128-bit heap alignment. This has the effect of
|
||||
disabling vectorization for fixed-size objects (like Matrix4d) while keeping vectorization of dynamic-size objects
|
||||
(like MatrixXd). But do note that this breaks ABI compatibility with the default behavior of 128-bit static alignment.</li>
|
||||
<li>Or define both EIGEN_DONT_VECTORIZE and EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT. This keeps the
|
||||
128-bit alignment code and thus preserves ABI compatibility, but completely disables vectorization.</li>
|
||||
</ul>
|
||||
|
||||
For more information, see <a href="http://eigen.tuxfamily.org/index.php?title=FAQ#I_disabled_vectorization.2C_but_I.27m_still_getting_annoyed_about_alignment_issues.21">this FAQ</a>.
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#if EIGEN_ALIGN_HEAP
|
||||
#if EIGEN_ALIGN
|
||||
#define ALIGNMENT 16
|
||||
#else
|
||||
#define ALIGNMENT 1
|
||||
|
@ -78,7 +78,7 @@ void check_unalignedassert_good()
|
||||
delete[] y;
|
||||
}
|
||||
|
||||
#if EIGEN_ALIGN_STACK
|
||||
#if EIGEN_ALIGN_STATICALLY
|
||||
template<typename T>
|
||||
void construct_at_boundary(int boundary)
|
||||
{
|
||||
@ -94,7 +94,7 @@ void construct_at_boundary(int boundary)
|
||||
|
||||
void unalignedassert()
|
||||
{
|
||||
#if EIGEN_ALIGN_STACK
|
||||
#if EIGEN_ALIGN_STATICALLY
|
||||
construct_at_boundary<Vector2f>(4);
|
||||
construct_at_boundary<Vector3f>(4);
|
||||
construct_at_boundary<Vector4f>(16);
|
||||
@ -124,7 +124,7 @@ void unalignedassert()
|
||||
check_unalignedassert_good<TestNew6>();
|
||||
check_unalignedassert_good<Depends<true> >();
|
||||
|
||||
#if EIGEN_ALIGN_STACK
|
||||
#if EIGEN_ALIGN_STATICALLY
|
||||
VERIFY_RAISES_ASSERT(construct_at_boundary<Vector4f>(8));
|
||||
VERIFY_RAISES_ASSERT(construct_at_boundary<Matrix4f>(8));
|
||||
VERIFY_RAISES_ASSERT(construct_at_boundary<Vector2d>(8));
|
||||
|
Loading…
x
Reference in New Issue
Block a user