diff --git a/Eigen/Core b/Eigen/Core index 404eb89de..9f1210558 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -1,6 +1,14 @@ #ifndef EIGEN_CORE_H #define EIGEN_CORE_H +#ifdef __SSE2__ +#define EIGEN_VECTORIZE +#define EIGEN_VECTORIZE_SSE +#warning "enabling vectorization" +#include +#include +#endif + #include #include #include @@ -9,8 +17,11 @@ namespace Eigen { -#include "src/Core/util/Util.h" +#include "src/Core/util/Macros.h" +#include "src/Core/util/Constants.h" #include "src/Core/util/ForwardDeclarations.h" +#include "src/Core/util/Meta.h" + #include "src/Core/NumTraits.h" #include "src/Core/MathFunctions.h" #include "src/Core/PacketMath.h" diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 62953eded..5c2350d6c 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -191,7 +191,7 @@ template class MatrixBase /** Overloaded for optimal product evaluation */ template - Derived& lazyAssign(const Product& product); + Derived& lazyAssign(const Product& product); CommaInitializer operator<< (const Scalar& s); diff --git a/Eigen/src/Core/PacketMath.h b/Eigen/src/Core/PacketMath.h index aab123533..3697f262e 100644 --- a/Eigen/src/Core/PacketMath.h +++ b/Eigen/src/Core/PacketMath.h @@ -25,7 +25,7 @@ #ifndef EIGEN_PACKET_MATH_H #define EIGEN_PACKET_MATH_H -#ifdef EIGEN_INTEL_PLATFORM +#ifdef EIGEN_VECTORIZE_SSE template<> struct ei_packet_traits { typedef __m128 type; enum {size=4}; }; template<> struct ei_packet_traits { typedef __m128d type; enum {size=2}; }; diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index 9e7127720..5d39f0c2b 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -109,7 +109,7 @@ struct ei_packet_product_unroller struct ei_product_eval_mode { enum{ value = Lhs::MaxRowsAtCompileTime >= 8 && Rhs::MaxColsAtCompileTime >= 8 - ? CacheOptimal : UnrolledDotProduct }; + ? CacheOptimalProduct : NormalProduct }; }; template @@ -133,7 +133,7 @@ struct ei_traits > ? (unsigned int)(LhsFlags | RhsFlags) : (unsigned int)(LhsFlags | RhsFlags) & ~LargeBit ) | EvalBeforeAssigningBit - | (ei_product_eval_mode::value == (int)CacheOptimal ? EvalBeforeNestingBit : 0)) + | (ei_product_eval_mode::value == (int)CacheOptimalProduct ? EvalBeforeNestingBit : 0)) & (~(RowMajorBit | VectorizableBit)) | (((!(Lhs::Flags & RowMajorBit)) && (Lhs::Flags & VectorizableBit)) ? VectorizableBit : ((Rhs::Flags & RowMajorBit && (Rhs::Flags & VectorizableBit)) ? (RowMajorBit | VectorizableBit) @@ -257,7 +257,7 @@ MatrixBase::operator*=(const MatrixBase &other) template template -Derived& MatrixBase::lazyAssign(const Product& product) +Derived& MatrixBase::lazyAssign(const Product& product) { product._cacheOptimalEval(*this); return derived(); diff --git a/Eigen/src/Core/util/CMakeLists.txt b/Eigen/src/Core/util/CMakeLists.txt index 9ab9fc8b0..eb7b2b6eb 100644 --- a/Eigen/src/Core/util/CMakeLists.txt +++ b/Eigen/src/Core/util/CMakeLists.txt @@ -1,6 +1,6 @@ FILE(GLOB Eigen_Core_util_SRCS "*.h") INSTALL(FILES - ${Eigen_Core_SRCS} + ${Eigen_Core_util_SRCS} DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Core/util ) diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h new file mode 100644 index 000000000..c71b12334 --- /dev/null +++ b/Eigen/src/Core/util/Constants.h @@ -0,0 +1,47 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see . + +#ifndef EIGEN_CONSTANTS_H +#define EIGEN_CONSTANTS_H + +const int Dynamic = 10000; + +// matrix/expression flags +const unsigned int RowMajorBit = 0x1; +const unsigned int EvalBeforeNestingBit = 0x2; +const unsigned int EvalBeforeAssigningBit = 0x4; +const unsigned int LargeBit = 0x8; +#ifdef EIGEN_VECTORIZE +const unsigned int VectorizableBit = 0x10; +#else +const unsigned int VectorizableBit = 0x0; +#endif + +enum { ConditionalJumpCost = 5 }; +enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight }; +enum DirectionType { Vertical, Horizontal }; +enum ProductEvaluationMode { NormalProduct, CacheOptimalProduct }; + +#endif // EIGEN_CONSTANTS_H diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index a7f269cb4..6167f13bd 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -70,56 +70,4 @@ template struct ei_scalar_quotient1_op; template struct ei_scalar_min_op; template struct ei_scalar_max_op; -template struct ei_eval -{ - typedef Matrix::Scalar, - ei_traits::RowsAtCompileTime, - ei_traits::ColsAtCompileTime, - ei_traits::Flags & ~(EvalBeforeNestingBit | EvalBeforeAssigningBit), - ei_traits::MaxRowsAtCompileTime, - ei_traits::MaxColsAtCompileTime> type; -}; - -template struct ei_unref { typedef T type; }; -template struct ei_unref { typedef T type; }; - -template struct ei_is_temporary -{ - enum { ret = 0 }; -}; - -template struct ei_is_temporary > -{ - enum { ret = 1 }; -}; - -template struct ei_nested -{ - typedef typename ei_meta_if< - ei_is_temporary::ret, - T, - typename ei_meta_if< - ei_traits::Flags & EvalBeforeNestingBit - || (n+1) * NumTraits::Scalar>::ReadCost < (n-1) * T::CoeffReadCost, - typename ei_eval::type, - const T& - >::ret - >::ret type; -}; - -template struct ei_functor_traits -{ - enum - { - Cost = 10, - IsVectorizable = false - }; -}; - -template struct ei_packet_traits -{ - typedef T type; - enum {size=1}; -}; - #endif // EIGEN_FORWARDDECLARATIONS_H diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h new file mode 100644 index 000000000..84a2a0eef --- /dev/null +++ b/Eigen/src/Core/util/Macros.h @@ -0,0 +1,138 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see . + +#ifndef EIGEN_MACROS_H +#define EIGEN_MACROS_H + +#undef minor + +#ifdef EIGEN_DONT_USE_UNROLLED_LOOPS +#define EIGEN_UNROLLING_LIMIT 0 +#endif + +/** Defines the maximal loop size to enable meta unrolling of loops */ +#ifndef EIGEN_UNROLLING_LIMIT +#define EIGEN_UNROLLING_LIMIT 400 +#endif + +#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR +#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER RowMajorBit +#else +#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER 0 +#endif + +#define USING_PART_OF_NAMESPACE_EIGEN \ +EIGEN_USING_MATRIX_TYPEDEFS \ +using Eigen::Matrix; \ +using Eigen::MatrixBase; + +#ifdef NDEBUG +#define EIGEN_NO_DEBUG +#endif + +#ifndef ei_assert +#ifdef EIGEN_NO_DEBUG +#define ei_assert(x) +#else +#define ei_assert(x) assert(x) +#endif +#endif + +#ifdef EIGEN_INTERNAL_DEBUGGING +#define ei_internal_assert(x) ei_assert(x); +#else +#define ei_internal_assert(x) +#endif + +#ifdef EIGEN_NO_DEBUG +#define EIGEN_ONLY_USED_FOR_DEBUG(x) (void)x +#else +#define EIGEN_ONLY_USED_FOR_DEBUG(x) +#endif + +// FIXME with the always_inline attribute, +// gcc 3.4.x reports the following compilation error: +// Eval.h:91: sorry, unimplemented: inlining failed in call to 'const Eigen::Eval Eigen::MatrixBase::eval() const' +// : function body not available +#if (defined __GNUC__) && (__GNUC__!=3) +#define EIGEN_ALWAYS_INLINE __attribute__((always_inline)) +#else +#define EIGEN_ALWAYS_INLINE +#endif + +#if (defined __GNUC__) +#define EIGEN_ALIGN_128 __attribute__ ((aligned(16))) +#else +#define EIGEN_ALIGN_128 +#endif + +#define EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, Op) \ +template \ +Derived& operator Op(const MatrixBase& other) \ +{ \ + return Eigen::MatrixBase::operator Op(other); \ +} \ +Derived& operator Op(const Derived& other) \ +{ \ + return Eigen::MatrixBase::operator Op(other); \ +} + +#define EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, Op) \ +template \ +Derived& operator Op(const Other& scalar) \ +{ \ + return Eigen::MatrixBase::operator Op(scalar); \ +} + +#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \ +EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, =) \ +EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, +=) \ +EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, -=) \ +EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, *=) \ +EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=) + +#define _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, BaseClass) \ +typedef BaseClass Base; \ +typedef typename Eigen::ei_traits::Scalar Scalar; \ +typedef typename Base::PacketScalar PacketScalar; \ +typedef typename Eigen::ei_nested::type Nested; \ +typedef typename Eigen::ei_eval::type Eval; \ +enum { RowsAtCompileTime = Base::RowsAtCompileTime, \ + ColsAtCompileTime = Base::ColsAtCompileTime, \ + MaxRowsAtCompileTime = Base::MaxRowsAtCompileTime, \ + MaxColsAtCompileTime = Base::MaxColsAtCompileTime, \ + SizeAtCompileTime = Base::SizeAtCompileTime, \ + MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \ + IsVectorAtCompileTime = Base::IsVectorAtCompileTime, \ + Flags = Base::Flags, \ + CoeffReadCost = Base::CoeffReadCost }; + +#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \ +_EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::MatrixBase) \ +friend class Eigen::MatrixBase; + +#define EIGEN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b) + +#endif // EIGEN_MACROS_H diff --git a/Eigen/src/Core/util/Util.h b/Eigen/src/Core/util/Meta.h similarity index 56% rename from Eigen/src/Core/util/Util.h rename to Eigen/src/Core/util/Meta.h index de45927ce..faf177473 100644 --- a/Eigen/src/Core/util/Util.h +++ b/Eigen/src/Core/util/Meta.h @@ -23,148 +23,8 @@ // License and a copy of the GNU General Public License along with // Eigen. If not, see . -#ifndef EIGEN_UTIL_H -#define EIGEN_UTIL_H - -#ifdef EIGEN_VECTORIZE -#ifdef EIGEN_INTEL_PLATFORM -#include -#include -#else -#undef EIGEN_VECTORIZE -#endif -#endif - -#ifdef EIGEN_DONT_USE_UNROLLED_LOOPS -#define EIGEN_UNROLLING_LIMIT 0 -#endif - -/** Defines the maximal loop size to enable meta unrolling of loops */ -#ifndef EIGEN_UNROLLING_LIMIT -#define EIGEN_UNROLLING_LIMIT 400 -#endif - -#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR -#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER RowMajorBit -#else -#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER 0 -#endif - -#undef minor - -#define USING_PART_OF_NAMESPACE_EIGEN \ -EIGEN_USING_MATRIX_TYPEDEFS \ -using Eigen::Matrix; \ -using Eigen::MatrixBase; - -#ifdef NDEBUG -#define EIGEN_NO_DEBUG -#endif - -#ifndef ei_assert -#ifdef EIGEN_NO_DEBUG -#define ei_assert(x) -#else -#define ei_assert(x) assert(x) -#endif -#endif - -#ifdef EIGEN_INTERNAL_DEBUGGING -#define ei_internal_assert(x) ei_assert(x); -#else -#define ei_internal_assert(x) -#endif - -#ifdef EIGEN_NO_DEBUG -#define EIGEN_ONLY_USED_FOR_DEBUG(x) (void)x -#else -#define EIGEN_ONLY_USED_FOR_DEBUG(x) -#endif - -// FIXME with the always_inline attribute, -// gcc 3.4.x reports the following compilation error: -// Eval.h:91: sorry, unimplemented: inlining failed in call to 'const Eigen::Eval Eigen::MatrixBase::eval() const' -// : function body not available -#if (defined __GNUC__) && (__GNUC__!=3) -#define EIGEN_ALWAYS_INLINE __attribute__((always_inline)) -#else -#define EIGEN_ALWAYS_INLINE -#endif - -#if (defined __GNUC__) -#define EIGEN_ALIGN_128 __attribute__ ((aligned(16))) -#else -#define EIGEN_ALIGN_128 -#endif - -#define EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, Op) \ -template \ -Derived& operator Op(const MatrixBase& other) \ -{ \ - return Eigen::MatrixBase::operator Op(other); \ -} \ -Derived& operator Op(const Derived& other) \ -{ \ - return Eigen::MatrixBase::operator Op(other); \ -} - -#define EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, Op) \ -template \ -Derived& operator Op(const Other& scalar) \ -{ \ - return Eigen::MatrixBase::operator Op(scalar); \ -} - -#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \ -EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, =) \ -EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, +=) \ -EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, -=) \ -EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, *=) \ -EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=) - -#define _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, BaseClass) \ -typedef BaseClass Base; \ -typedef typename Eigen::ei_traits::Scalar Scalar; \ -typedef typename Base::PacketScalar PacketScalar; \ -typedef typename Eigen::ei_nested::type Nested; \ -typedef typename Eigen::ei_eval::type Eval; \ -enum { RowsAtCompileTime = Base::RowsAtCompileTime, \ - ColsAtCompileTime = Base::ColsAtCompileTime, \ - MaxRowsAtCompileTime = Base::MaxRowsAtCompileTime, \ - MaxColsAtCompileTime = Base::MaxColsAtCompileTime, \ - SizeAtCompileTime = Base::SizeAtCompileTime, \ - MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \ - IsVectorAtCompileTime = Base::IsVectorAtCompileTime, \ - Flags = Base::Flags, \ - CoeffReadCost = Base::CoeffReadCost }; - -#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \ -_EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::MatrixBase) \ -friend class Eigen::MatrixBase; - -#define EIGEN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b) - -const int Dynamic = 10000; - -// matrix/expression flags -const unsigned int RowMajorBit = 0x1; -const unsigned int EvalBeforeNestingBit = 0x2; -const unsigned int EvalBeforeAssigningBit = 0x4; -const unsigned int LargeBit = 0x8; -#ifdef EIGEN_VECTORIZE -const unsigned int VectorizableBit = 0x10; -#else -const unsigned int VectorizableBit = 0x0; -#endif - - -enum { ConditionalJumpCost = 5 }; - -enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight }; - -enum DirectionType { Vertical, Horizontal }; - -enum ProductEvaluationMode { UnrolledDotProduct, CacheOptimal }; +#ifndef EIGEN_META_H +#define EIGEN_META_H // just a workaround because GCC seems to not really like empty structs #ifdef __GNUG__ @@ -270,4 +130,57 @@ struct ei_result_of { typedef typename ei_binary_result_of_select::type type; }; -#endif // EIGEN_UTIL_H +template struct ei_eval +{ + typedef Matrix::Scalar, + ei_traits::RowsAtCompileTime, + ei_traits::ColsAtCompileTime, + ei_traits::Flags & ~(EvalBeforeNestingBit | EvalBeforeAssigningBit), + ei_traits::MaxRowsAtCompileTime, + ei_traits::MaxColsAtCompileTime> type; +}; + +template struct ei_unref { typedef T type; }; +template struct ei_unref { typedef T type; }; + +template struct ei_is_temporary +{ + enum { ret = 0 }; +}; + +template struct ei_is_temporary > +{ + enum { ret = 1 }; +}; + +template struct ei_nested +{ + typedef typename ei_meta_if< + ei_is_temporary::ret, + T, + typename ei_meta_if< + ei_traits::Flags & EvalBeforeNestingBit + || (n+1) * NumTraits::Scalar>::ReadCost < (n-1) * T::CoeffReadCost, + typename ei_eval::type, + const T& + >::ret + >::ret type; +}; + +template struct ei_functor_traits +{ + enum + { + Cost = 10, + IsVectorizable = false + }; +}; + +template struct ei_packet_traits +{ + typedef T type; + enum {size=1}; +}; + + +#endif // EIGEN_META_H