mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-06-04 18:54:00 +08:00
* throw bad_alloc if exceptions are enabled, after patch by Kenneth Riddile
* disable vectorization on MSVC 2005, as it doesn't have all the required intrinsics. require 2008.
This commit is contained in:
parent
50105c3ed6
commit
38b83b4157
58
Eigen/Core
58
Eigen/Core
@ -1,30 +1,32 @@
|
|||||||
#ifndef EIGEN_CORE_H
|
#ifndef EIGEN_CORE_H
|
||||||
#define EIGEN_CORE_H
|
#define EIGEN_CORE_H
|
||||||
|
|
||||||
|
// first thing Eigen does: prevent MSVC from committing suicide
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning( disable : 4181 4244 )
|
#pragma warning( disable : 4181 4244 )
|
||||||
|
#if (_MSC_VER >= 1500) // 2008 or later
|
||||||
|
// Remember that usage of defined() in a #define is undefined by the standard
|
||||||
|
#ifdef _M_IX86_FP
|
||||||
|
#if _M_IX86_FP >= 2
|
||||||
|
#define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
|
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
|
||||||
#else
|
#else
|
||||||
#define EIGEN_GNUC_AT_LEAST(x,y) 0
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef EIGEN_DONT_VECTORIZE
|
#ifndef EIGEN_DONT_VECTORIZE
|
||||||
#define EIGEN_HAVE__SSE2__BUT_NOT_OLD_GCC ((defined __SSE2__) && ( (!defined __GNUC__) || EIGEN_GNUC_AT_LEAST(4,2) ))
|
#if defined (EIGEN_SSE2_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
|
||||||
|
|
||||||
// Now check for SSE2 with MSVC. Normally we'd formulate this in 1 line using defined() but this triggers MSVC bugs.
|
|
||||||
#ifdef _M_IX86_FP
|
|
||||||
#if (_M_IX86_FP >= 2)
|
|
||||||
#define EIGEN_HAVE_MSVC_SSE2 1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#ifndef EIGEN_HAVE_MSVC_SSE2
|
|
||||||
#define EIGEN_HAVE_MSVC_SSE2 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (EIGEN_HAVE__SSE2__BUT_NOT_OLD_GCC || EIGEN_HAVE_MSVC_SSE2)
|
|
||||||
#define EIGEN_VECTORIZE
|
#define EIGEN_VECTORIZE
|
||||||
#define EIGEN_VECTORIZE_SSE
|
#define EIGEN_VECTORIZE_SSE
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
@ -35,11 +37,11 @@
|
|||||||
#ifdef __SSSE3__
|
#ifdef __SSSE3__
|
||||||
#include <tmmintrin.h>
|
#include <tmmintrin.h>
|
||||||
#endif
|
#endif
|
||||||
#elif (defined __ALTIVEC__)
|
#elif defined __ALTIVEC__
|
||||||
#define EIGEN_VECTORIZE
|
#define EIGEN_VECTORIZE
|
||||||
#define EIGEN_VECTORIZE_ALTIVEC
|
#define EIGEN_VECTORIZE_ALTIVEC
|
||||||
#include <altivec.h>
|
#include <altivec.h>
|
||||||
// We _need_ to #undef all these ugly tokens defined in <altivec.h>
|
// We need to #undef all these ugly tokens defined in <altivec.h>
|
||||||
// => use __vector instead of vector
|
// => use __vector instead of vector
|
||||||
#undef bool
|
#undef bool
|
||||||
#undef vector
|
#undef vector
|
||||||
@ -56,8 +58,16 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#if(defined(_MSC_VER) && defined(EIGEN_VECTORIZE))
|
#if defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER) && defined(EIGEN_VECTORIZE)
|
||||||
#include <malloc.h> // for _aligned_malloc
|
#include <malloc.h> // for _aligned_malloc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(_CPPUNWIND) || defined(__EXCEPTIONS)) && !defined(EIGEN_NO_EXCEPTIONS)
|
||||||
|
#define EIGEN_EXCEPTIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
|
#include <new>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
@ -85,9 +95,9 @@ namespace Eigen {
|
|||||||
#include "src/Core/GenericPacketMath.h"
|
#include "src/Core/GenericPacketMath.h"
|
||||||
|
|
||||||
#if defined EIGEN_VECTORIZE_SSE
|
#if defined EIGEN_VECTORIZE_SSE
|
||||||
#include "src/Core/arch/SSE/PacketMath.h"
|
#include "src/Core/arch/SSE/PacketMath.h"
|
||||||
#elif defined EIGEN_VECTORIZE_ALTIVEC
|
#elif defined EIGEN_VECTORIZE_ALTIVEC
|
||||||
#include "src/Core/arch/AltiVec/PacketMath.h"
|
#include "src/Core/arch/AltiVec/PacketMath.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
|
#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
|
||||||
@ -97,10 +107,12 @@ namespace Eigen {
|
|||||||
#include "src/Core/Functors.h"
|
#include "src/Core/Functors.h"
|
||||||
#include "src/Core/MatrixBase.h"
|
#include "src/Core/MatrixBase.h"
|
||||||
#include "src/Core/Coeffs.h"
|
#include "src/Core/Coeffs.h"
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874
|
#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874
|
||||||
// at least confirmed with Doxygen 1.5.5 and 1.5.6
|
// at least confirmed with Doxygen 1.5.5 and 1.5.6
|
||||||
#include "src/Core/Assign.h"
|
#include "src/Core/Assign.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "src/Core/MatrixStorage.h"
|
#include "src/Core/MatrixStorage.h"
|
||||||
#include "src/Core/NestByValue.h"
|
#include "src/Core/NestByValue.h"
|
||||||
#include "src/Core/Flagged.h"
|
#include "src/Core/Flagged.h"
|
||||||
|
@ -26,12 +26,10 @@
|
|||||||
#ifndef EIGEN_MEMORY_H
|
#ifndef EIGEN_MEMORY_H
|
||||||
#define EIGEN_MEMORY_H
|
#define EIGEN_MEMORY_H
|
||||||
|
|
||||||
#ifdef EIGEN_VECTORIZE
|
#if defined(EIGEN_VECTORIZE) && !defined(_MSC_VER)
|
||||||
#ifndef _MSC_VER
|
|
||||||
// it seems we cannot assume posix_memalign is defined in the stdlib header
|
// it seems we cannot assume posix_memalign is defined in the stdlib header
|
||||||
extern "C" int posix_memalign (void **, size_t, size_t) throw ();
|
extern "C" int posix_memalign (void **, size_t, size_t) throw ();
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* Static array automatically aligned if the total byte size is a multiple of 16
|
* Static array automatically aligned if the total byte size is a multiple of 16
|
||||||
@ -61,35 +59,47 @@ struct ei_byte_forcing_aligned_malloc
|
|||||||
{
|
{
|
||||||
unsigned char c; // sizeof must be 1.
|
unsigned char c; // sizeof must be 1.
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> struct ei_force_aligned_malloc { enum { ret = 0 }; };
|
template<typename T> struct ei_force_aligned_malloc { enum { ret = 0 }; };
|
||||||
template<> struct ei_force_aligned_malloc<ei_byte_forcing_aligned_malloc> { enum { ret = 1 }; };
|
template<> struct ei_force_aligned_malloc<ei_byte_forcing_aligned_malloc> { enum { ret = 1 }; };
|
||||||
|
|
||||||
/** \internal allocates \a size * sizeof(\a T) bytes with 16 bytes alignment.
|
/** \internal allocates \a size * sizeof(\a T) bytes. If vectorization is enabled and T is such that a packet
|
||||||
* */
|
* containts more than one T, then the returned pointer is guaranteed to have 16 bytes alignment.
|
||||||
|
* On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown.
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T* ei_aligned_malloc(size_t size)
|
inline T* ei_aligned_malloc(size_t size)
|
||||||
{
|
{
|
||||||
|
T* result;
|
||||||
|
|
||||||
#ifdef EIGEN_VECTORIZE
|
#ifdef EIGEN_VECTORIZE
|
||||||
if(ei_packet_traits<T>::size>1 || ei_force_aligned_malloc<T>::ret)
|
if(ei_packet_traits<T>::size>1 || ei_force_aligned_malloc<T>::ret)
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
return static_cast<T*>(_aligned_malloc(size*sizeof(T), 16));
|
result = static_cast<T*>(_aligned_malloc(size*sizeof(T), 16));
|
||||||
#else
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
void* ptr;
|
const int failed = (result == 0);
|
||||||
if(posix_memalign(&ptr, 16, size*sizeof(T))==0)
|
#endif
|
||||||
return static_cast<T*>(ptr);
|
#else // not MSVC
|
||||||
else
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
return 0;
|
const int failed =
|
||||||
|
#endif
|
||||||
|
posix_memalign(reinterpret_cast<void**>(&result), 16, size*sizeof(T));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
|
if(failed)
|
||||||
|
throw std::bad_alloc();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
return new T[size]; // here we really want a new, not a malloc. Justification: if the user uses Eigen on
|
result = new T[size]; // here we really want a new, not a malloc. Justification: if the user uses Eigen on
|
||||||
// some fancy scalar type such as multiple-precision numbers, and this type has a custom operator new,
|
// some fancy scalar type such as multiple-precision numbers, and this type has a custom operator new,
|
||||||
// then we want to honor this operator new! Anyway this type won't have vectorization so the vectorizing path
|
// then we want to honor this operator new! Anyway this type won't have vectorization so the vectorizing path
|
||||||
// is irrelevant here. Yes, we should say somewhere in the docs that if the user uses a custom scalar type then
|
// is irrelevant here. Yes, we should say somewhere in the docs that if the user uses a custom scalar type then
|
||||||
// he can't have both vectorization and a custom operator new on his scalar type.
|
// he can't have both vectorization and a custom operator new on his scalar type.
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal free memory allocated with ei_aligned_malloc */
|
/** \internal free memory allocated with ei_aligned_malloc */
|
||||||
|
@ -47,6 +47,8 @@ namespace Eigen
|
|||||||
#define EI_PP_CAT2(a,b) a ## b
|
#define EI_PP_CAT2(a,b) a ## b
|
||||||
#define EI_PP_CAT(a,b) EI_PP_CAT2(a,b)
|
#define EI_PP_CAT(a,b) EI_PP_CAT2(a,b)
|
||||||
|
|
||||||
|
#define EIGEN_NO_EXCEPTIONS // disabling throwing assertions on bad alloc -- somehow makes the tests crawl
|
||||||
|
|
||||||
#ifndef EIGEN_NO_ASSERTION_CHECKING
|
#ifndef EIGEN_NO_ASSERTION_CHECKING
|
||||||
|
|
||||||
namespace Eigen
|
namespace Eigen
|
||||||
|
Loading…
x
Reference in New Issue
Block a user