diff options
Diffstat (limited to 'Eigen')
-rw-r--r-- | Eigen/src/Core/CacheFriendlyProduct.h | 2 | ||||
-rw-r--r-- | Eigen/src/Core/DiagonalProduct.h | 4 | ||||
-rw-r--r-- | Eigen/src/Core/Map.h | 8 | ||||
-rw-r--r-- | Eigen/src/Core/Matrix.h | 159 | ||||
-rw-r--r-- | Eigen/src/Core/Transpose.h | 4 | ||||
-rw-r--r-- | Eigen/src/Core/util/Macros.h | 16 | ||||
-rw-r--r-- | Eigen/src/Core/util/Memory.h | 6 | ||||
-rw-r--r-- | Eigen/src/Core/util/StaticAssert.h | 3 | ||||
-rw-r--r-- | Eigen/src/StdVector/UnalignedType.h | 41 |
9 files changed, 153 insertions, 90 deletions
diff --git a/Eigen/src/Core/CacheFriendlyProduct.h b/Eigen/src/Core/CacheFriendlyProduct.h index b37dc8eb2..e2a501736 100644 --- a/Eigen/src/Core/CacheFriendlyProduct.h +++ b/Eigen/src/Core/CacheFriendlyProduct.h @@ -81,7 +81,7 @@ static void ei_cache_friendly_product( MaxBlockRows_ClampingMask = 0xFFFFF8, #endif // maximal size of the blocks fitted in L2 cache - MaxL2BlockSize = ei_L2_block_traits<EIGEN_TUNE_FOR_L2_CACHE_SIZE,Scalar>::width + MaxL2BlockSize = ei_L2_block_traits<EIGEN_TUNE_FOR_CPU_CACHE_SIZE,Scalar>::width }; const bool resIsAligned = (PacketSize==1) || (((resStride%PacketSize) == 0) && (size_t(res)%16==0)); diff --git a/Eigen/src/Core/DiagonalProduct.h b/Eigen/src/Core/DiagonalProduct.h index 5e23fb066..f33a26f98 100644 --- a/Eigen/src/Core/DiagonalProduct.h +++ b/Eigen/src/Core/DiagonalProduct.h @@ -73,7 +73,7 @@ struct ei_traits<Product<LhsNested, RhsNested, DiagonalProduct> > RemovedBits = ~((RhsFlags & RowMajorBit) && (!CanVectorizeLhs) ? 0 : RowMajorBit), Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits) - | (CanVectorizeLhs || CanVectorizeRhs ? PacketAccessBit : 0), + | (((CanVectorizeLhs&&RhsIsDiagonal) || (CanVectorizeRhs&&LhsIsDiagonal)) ? PacketAccessBit : 0), CoeffReadCost = NumTraits<Scalar>::MulCost + _LhsNested::CoeffReadCost + _RhsNested::CoeffReadCost }; @@ -114,12 +114,10 @@ template<typename LhsNested, typename RhsNested> class Product<LhsNested, RhsNes { if (RhsIsDiagonal) { - ei_assert((_LhsNested::Flags&RowMajorBit)==0); return ei_pmul(m_lhs.template packet<LoadMode>(row, col), ei_pset1(m_rhs.coeff(col, col))); } else { - ei_assert(_RhsNested::Flags&RowMajorBit); return ei_pmul(ei_pset1(m_lhs.coeff(row, row)), m_rhs.template packet<LoadMode>(row, col)); } } diff --git a/Eigen/src/Core/Map.h b/Eigen/src/Core/Map.h index 91ca5d649..5fe13005f 100644 --- a/Eigen/src/Core/Map.h +++ b/Eigen/src/Core/Map.h @@ -102,17 +102,13 @@ template<typename MatrixType, int PacketAccess> class Map * Only for fixed-size matrices and vectors. * \param data The array of data to copy * - * For dynamic-size matrices and vectors, see the variants taking additional int parameters - * for the dimensions. - * - * \sa Matrix(const Scalar *, int), Matrix(const Scalar *, int, int), - * Matrix::Map(const Scalar *) + * \sa Matrix::Map(const Scalar *) */ template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols> inline Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols> ::Matrix(const Scalar *data) { - *this = Eigen::Map<Matrix>(data); + _set_noalias(Eigen::Map<Matrix>(data)); } #endif // EIGEN_MAP_H diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h index c267d6415..482afe890 100644 --- a/Eigen/src/Core/Matrix.h +++ b/Eigen/src/Core/Matrix.h @@ -226,12 +226,11 @@ class Matrix */ inline void resize(int rows, int cols) { - ei_assert(rows > 0 - && (MaxRowsAtCompileTime == Dynamic || MaxRowsAtCompileTime >= rows) - && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) - && cols > 0 - && (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols) - && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)); + ei_assert(rows > 0 && cols > 0 && "a matrix cannot be resized to 0 size"); + ei_assert((MaxRowsAtCompileTime == Dynamic || MaxRowsAtCompileTime >= rows) + && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) + && (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols) + && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)); m_storage.resize(rows * cols, rows, cols); } @@ -249,49 +248,19 @@ class Matrix m_storage.resize(size, size, 1); } - /** Copies the value of the expression \a other into \c *this. - * - * \warning Note that the sizes of \c *this and \a other must match. - * If you want automatic resizing, then you must use the function set(). - * - * As a special exception, copying a row-vector into a vector (and conversely) - * is allowed. - * - * \sa set() - */ - template<typename OtherDerived> - EIGEN_STRONG_INLINE Matrix& operator=(const MatrixBase<OtherDerived>& other) - { - ei_assert(m_storage.data()!=0 && "you cannot use operator= with a non initialized matrix (instead use set()"); - return Base::operator=(other.derived()); - } - /** Copies the value of the expression \a other into \c *this with automatic resizing. * - * This function is the same than the assignment operator = excepted that \c *this might - * be resized to match the dimensions of \a other. + * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), + * it will be initialized. * * Note that copying a row-vector into a vector (and conversely) is allowed. * The resizing, if any, is then done in the appropriate way so that row-vectors * remain row-vectors and vectors remain vectors. - * - * \sa operator=() */ template<typename OtherDerived> - inline Matrix& set(const MatrixBase<OtherDerived>& other) + EIGEN_STRONG_INLINE Matrix& operator=(const MatrixBase<OtherDerived>& other) { - if(RowsAtCompileTime == 1) - { - ei_assert(other.isVector()); - resize(1, other.size()); - } - else if(ColsAtCompileTime == 1) - { - ei_assert(other.isVector()); - resize(other.size(), 1); - } - else resize(other.rows(), other.cols()); - return Base::operator=(other.derived()); + return _set(other); } /** This is a special case of the templated operator=. Its purpose is to @@ -299,7 +268,7 @@ class Matrix */ EIGEN_STRONG_INLINE Matrix& operator=(const Matrix& other) { - return operator=<Matrix>(other); + return _set(other); } EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Matrix, +=) @@ -311,34 +280,23 @@ class Matrix * * For fixed-size matrices, does nothing. * - * For dynamic-size matrices, creates an empty matrix of size null. - * \warning while creating such an \em null matrix is allowed, it \b cannot - * \b be \b used before having being resized or initialized with the function set(). - * In particular, initializing a null matrix with operator = is not supported. - * Finally, this constructor is the unique way to create null matrices: resizing + * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix + * is called a null matrix. This constructor is the unique way to create null matrices: resizing * a matrix to 0 is not supported. - * Here are some examples: - * \code - * MatrixXf r = MatrixXf::Random(3,4); // create a random matrix of floats - * MatrixXf m1, m2; // creates two null matrices of float * - * m1 = r; // illegal (raise an assertion) - * r = m1; // illegal (raise an assertion) - * m1 = m2; // illegal (raise an assertion) - * m1.set(r); // OK - * m2.resize(3,4); - * m2 = r; // OK - * \endcode - * - * \sa resize(int,int), set() + * \sa resize(int,int) */ EIGEN_STRONG_INLINE explicit Matrix() : m_storage() { - ei_assert(RowsAtCompileTime > 0 && ColsAtCompileTime > 0); + _check_template_params(); } +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal */ Matrix(ei_constructor_without_unaligned_array_assert) - : m_storage(ei_constructor_without_unaligned_array_assert()) {} + : m_storage(ei_constructor_without_unaligned_array_assert()) + {} +#endif /** Constructs a vector or row-vector with given dimension. \only_for_vectors * @@ -349,6 +307,7 @@ class Matrix EIGEN_STRONG_INLINE explicit Matrix(int dim) : m_storage(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim) { + _check_template_params(); EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix) ei_assert(dim > 0); ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim); @@ -366,6 +325,7 @@ class Matrix */ EIGEN_STRONG_INLINE Matrix(int x, int y) : m_storage(x*y, x, y) { + _check_template_params(); if((RowsAtCompileTime == 1 && ColsAtCompileTime == 2) || (RowsAtCompileTime == 2 && ColsAtCompileTime == 1)) { @@ -381,6 +341,7 @@ class Matrix /** constructs an initialized 2D vector with given coefficients */ EIGEN_STRONG_INLINE Matrix(const float& x, const float& y) { + _check_template_params(); EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 2) m_storage.data()[0] = x; m_storage.data()[1] = y; @@ -388,6 +349,7 @@ class Matrix /** constructs an initialized 2D vector with given coefficients */ EIGEN_STRONG_INLINE Matrix(const double& x, const double& y) { + _check_template_params(); EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 2) m_storage.data()[0] = x; m_storage.data()[1] = y; @@ -395,6 +357,7 @@ class Matrix /** constructs an initialized 3D vector with given coefficients */ EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z) { + _check_template_params(); EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 3) m_storage.data()[0] = x; m_storage.data()[1] = y; @@ -403,6 +366,7 @@ class Matrix /** constructs an initialized 4D vector with given coefficients */ EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w) { + _check_template_params(); EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 4) m_storage.data()[0] = x; m_storage.data()[1] = y; @@ -417,14 +381,15 @@ class Matrix EIGEN_STRONG_INLINE Matrix(const MatrixBase<OtherDerived>& other) : m_storage(other.rows() * other.cols(), other.rows(), other.cols()) { - ei_assign_selector<Matrix,OtherDerived,false>::run(*this, other.derived()); - //Base::operator=(other.derived()); + _check_template_params(); + _set_noalias(other); } /** Copy constructor */ EIGEN_STRONG_INLINE Matrix(const Matrix& other) : Base(), m_storage(other.rows() * other.cols(), other.rows(), other.cols()) { - Base::lazyAssign(other); + _check_template_params(); + _set_noalias(other); } /** Destructor */ inline ~Matrix() {} @@ -486,6 +451,72 @@ class Matrix #ifdef EIGEN_MATRIX_PLUGIN #include EIGEN_MATRIX_PLUGIN #endif + + private: + /** \internal Resizes *this in preparation for assigning \a other to it. + * Takes care of doing all the checking that's needed. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + */ + template<typename OtherDerived> + EIGEN_STRONG_INLINE void _resize_to_match(const MatrixBase<OtherDerived>& other) + { + if(RowsAtCompileTime == 1) + { + ei_assert(other.isVector()); + resize(1, other.size()); + } + else if(ColsAtCompileTime == 1) + { + ei_assert(other.isVector()); + resize(other.size(), 1); + } + else resize(other.rows(), other.cols()); + } + + /** \internal Copies the value of the expression \a other into \c *this with automatic resizing. + * + * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), + * it will be initialized. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + * + * \sa operator=(const MatrixBase<OtherDerived>&), _set_noalias() + */ + template<typename OtherDerived> + EIGEN_STRONG_INLINE Matrix& _set(const MatrixBase<OtherDerived>& other) + { + _resize_to_match(other); + return Base::operator=(other); + } + + /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which + * is the case when creating a new matrix) so one can enforce lazy evaluation. + * + * \sa operator=(const MatrixBase<OtherDerived>&), _set() + */ + template<typename OtherDerived> + EIGEN_STRONG_INLINE Matrix& _set_noalias(const MatrixBase<OtherDerived>& other) + { + _resize_to_match(other); + // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because + // it wouldn't allow to copy a row-vector into a column-vector. + return ei_assign_selector<Matrix,OtherDerived,false>::run(*this, other.derived()); + } + + static EIGEN_STRONG_INLINE void _check_template_params() + { + EIGEN_STATIC_ASSERT((_Rows > 0 + && _Cols > 0 + && _MaxRows <= _Rows + && _MaxCols <= _Cols + && (_Options & (AutoAlign|RowMajor)) == _Options), + INVALID_MATRIX_TEMPLATE_PARAMETERS) + } }; /** \defgroup matrixtypedefs Global matrix typedefs diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h index 93028ed49..48f067e7a 100644 --- a/Eigen/src/Core/Transpose.h +++ b/Eigen/src/Core/Transpose.h @@ -175,7 +175,7 @@ struct ei_inplace_transpose_selector<MatrixType,false> { // non square matrix if (m.rows()==m.cols()) m.template part<StrictlyUpperTriangular>().swap(m.transpose()); else - m.set(m.transpose().eval()); + m = m.transpose().eval(); } }; @@ -186,7 +186,7 @@ struct ei_inplace_transpose_selector<MatrixType,false> { // non square matrix * then this "in-place" version is probably the right choice because it provides * the following additional features: * - less error prone: doing the same operation with .transpose() requires special care: - * \code m.set(m.transpose().eval()); \endcode + * \code m = m.transpose().eval(); \endcode * - no temporary object is created (currently only for squared matrices) * - it allows future optimizations (cache friendliness, etc.) * diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h index 844b8831b..d3698e819 100644 --- a/Eigen/src/Core/util/Macros.h +++ b/Eigen/src/Core/util/Macros.h @@ -50,10 +50,18 @@ #define EIGEN_UNROLLING_LIMIT 100 #endif -/** \internal Define the maximal size in Bytes of L2 blocks. - * The current value is set to generate blocks of 256x256 for float */ -#ifndef EIGEN_TUNE_FOR_L2_CACHE_SIZE -#define EIGEN_TUNE_FOR_L2_CACHE_SIZE (sizeof(float)*256*256) +/** \internal Define the maximal size in Bytes of blocks fitting in CPU cache. + * The current value is set to generate blocks of 256x256 for float + * + * Typically for a single-threaded application you would set that to 25% of the size of your CPU caches in bytes + */ +#ifndef EIGEN_TUNE_FOR_CPU_CACHE_SIZE +#define EIGEN_TUNE_FOR_CPU_CACHE_SIZE (sizeof(float)*256*256) +#endif + +// FIXME this should go away quickly +#ifdef EIGEN_TUNE_FOR_L2_CACHE_SIZE +#error EIGEN_TUNE_FOR_L2_CACHE_SIZE is now called EIGEN_TUNE_FOR_CPU_CACHE_SIZE. #endif #define USING_PART_OF_NAMESPACE_EIGEN \ diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h index 3c9fdf5cc..792b269b8 100644 --- a/Eigen/src/Core/util/Memory.h +++ b/Eigen/src/Core/util/Memory.h @@ -115,11 +115,11 @@ template<> inline void* ei_conditional_aligned_malloc<false>(size_t size) ei_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)"); #endif - void *void_result = malloc(size); + void *result = malloc(size); #ifdef EIGEN_EXCEPTIONS - if(!void_result) throw std::bad_alloc(); + if(!result) throw std::bad_alloc(); #endif - return void_result; + return result; } /** allocates \a size objects of type T. The returned pointer is guaranteed to have 16 bytes alignment. diff --git a/Eigen/src/Core/util/StaticAssert.h b/Eigen/src/Core/util/StaticAssert.h index c8d944520..350630c0a 100644 --- a/Eigen/src/Core/util/StaticAssert.h +++ b/Eigen/src/Core/util/StaticAssert.h @@ -71,7 +71,8 @@ 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_COLUMN_MAJOR_MATRICES, + INVALID_MATRIX_TEMPLATE_PARAMETERS }; }; diff --git a/Eigen/src/StdVector/UnalignedType.h b/Eigen/src/StdVector/UnalignedType.h index 728235ac1..c67e3d905 100644 --- a/Eigen/src/StdVector/UnalignedType.h +++ b/Eigen/src/StdVector/UnalignedType.h @@ -32,13 +32,24 @@ template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int class ei_unaligned_type<Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> > : public Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> { + private: + template<typename Other> void _unaligned_copy(const Other& other) + { + if(other.size() == 0) return; + resize(other.rows(), other.cols()); + ei_assign_impl<ei_unaligned_type,aligned_base,NoVectorization>::run(*this, other); + } + public: typedef Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> aligned_base; ei_unaligned_type() : aligned_base(ei_constructor_without_unaligned_array_assert()) {} ei_unaligned_type(const aligned_base& other) : aligned_base(ei_constructor_without_unaligned_array_assert()) { - resize(other.rows(), other.cols()); - ei_assign_impl<ei_unaligned_type,aligned_base,NoVectorization>::run(*this, other); + _unaligned_copy(other); + } + ei_unaligned_type(const ei_unaligned_type& other) : aligned_base(ei_constructor_without_unaligned_array_assert()) + { + _unaligned_copy(other); } }; @@ -46,14 +57,23 @@ template<typename _Scalar, int _Dim> class ei_unaligned_type<Transform<_Scalar,_Dim> > : public Transform<_Scalar,_Dim> { + private: + template<typename Other> void _unaligned_copy(const Other& other) + { + // no resizing here, it's fixed-size anyway + ei_assign_impl<MatrixType,MatrixType,NoVectorization>::run(this->matrix(), other.matrix()); + } public: typedef Transform<_Scalar,_Dim> aligned_base; typedef typename aligned_base::MatrixType MatrixType; ei_unaligned_type() : aligned_base(ei_constructor_without_unaligned_array_assert()) {} ei_unaligned_type(const aligned_base& other) : aligned_base(ei_constructor_without_unaligned_array_assert()) { - // no resizing here, it's fixed-size anyway - ei_assign_impl<MatrixType,MatrixType,NoVectorization>::run(this->matrix(), other.matrix()); + _unaligned_copy(other); + } + ei_unaligned_type(const ei_unaligned_type& other) : aligned_base(ei_constructor_without_unaligned_array_assert()) + { + _unaligned_copy(other); } }; @@ -61,14 +81,23 @@ template<typename _Scalar> class ei_unaligned_type<Quaternion<_Scalar> > : public Quaternion<_Scalar> { + private: + template<typename Other> void _unaligned_copy(const Other& other) + { + // no resizing here, it's fixed-size anyway + ei_assign_impl<Coefficients,Coefficients,NoVectorization>::run(this->coeffs(), other.coeffs()); + } public: typedef Quaternion<_Scalar> aligned_base; typedef typename aligned_base::Coefficients Coefficients; ei_unaligned_type() : aligned_base(ei_constructor_without_unaligned_array_assert()) {} ei_unaligned_type(const aligned_base& other) : aligned_base(ei_constructor_without_unaligned_array_assert()) { - // no resizing here, it's fixed-size anyway - ei_assign_impl<Coefficients,Coefficients,NoVectorization>::run(this->coeffs(), other.coeffs()); + _unaligned_copy(other); + } + ei_unaligned_type(const ei_unaligned_type& other) : aligned_base(ei_constructor_without_unaligned_array_assert()) + { + _unaligned_copy(other); } }; |