* move memory related stuff to util/Memory.h

* clean ugly doxygen inheritence of expressions
* keep improving the documentation... slowly !
This commit is contained in:
Gael Guennebaud
2008-08-26 19:12:23 +00:00
parent 3e526dcdbd
commit 00a8d314c5
35 changed files with 445 additions and 188 deletions

View File

@@ -88,7 +88,11 @@ struct ei_traits<Block<MatrixType, BlockRows, BlockCols, _PacketAccess, _DirectA
};
template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess, int _DirectAccessStatus> class Block
#ifndef EIGEN_PARSED_BY_DOXYGEN
: public MatrixBase<Block<MatrixType, BlockRows, BlockCols, PacketAccess, _DirectAccessStatus> >
#else
: public MatrixBase
#endif
{
public:
@@ -211,7 +215,11 @@ template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess, in
/** \internal */
template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess>
class Block<MatrixType,BlockRows,BlockCols,PacketAccess,HasDirectAccess>
#ifndef EIGEN_PARSED_BY_DOXYGEN
: public MapBase<Block<MatrixType, BlockRows, BlockCols,PacketAccess,HasDirectAccess> >
#else
: public MapBase
#endif
{
public:

View File

@@ -76,7 +76,11 @@ struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
template<typename BinaryOp, typename Lhs, typename Rhs>
class CwiseBinaryOp : ei_no_assignment_operator,
#ifndef EIGEN_PARSED_BY_DOXYGEN
public MatrixBase<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
#else
public MatrixBase
#endif
{
public:
@@ -183,7 +187,7 @@ MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
*
* Example: \include Cwise_product.cpp
* Output: \verbinclude Cwise_product.out
*
*
* \sa class CwiseBinaryOp, operator/(), square()
*/
template<typename ExpressionType>

View File

@@ -60,7 +60,11 @@ struct ei_traits<CwiseNullaryOp<NullaryOp, MatrixType> >
template<typename NullaryOp, typename MatrixType>
class CwiseNullaryOp : ei_no_assignment_operator,
#ifndef EIGEN_PARSED_BY_DOXYGEN
public MatrixBase<CwiseNullaryOp<NullaryOp, MatrixType> >
#else
public MatrixBase
#endif
{
public:

View File

@@ -63,7 +63,11 @@ struct ei_traits<CwiseUnaryOp<UnaryOp, MatrixType> >
template<typename UnaryOp, typename MatrixType>
class CwiseUnaryOp : ei_no_assignment_operator,
#ifndef EIGEN_PARSED_BY_DOXYGEN
public MatrixBase<CwiseUnaryOp<UnaryOp, MatrixType> >
#else
public MatrixBase
#endif
{
public:

View File

@@ -60,7 +60,11 @@ struct ei_traits<DiagonalCoeffs<MatrixType> >
};
template<typename MatrixType> class DiagonalCoeffs
: public MatrixBase<DiagonalCoeffs<MatrixType> >
#ifndef EIGEN_PARSED_BY_DOXYGEN
: public MatrixBase<DiagonalCoeffs<MatrixType> >
#else
: public MatrixBase
#endif
{
public:

View File

@@ -56,7 +56,11 @@ struct ei_traits<DiagonalMatrix<CoeffsVectorType> >
template<typename CoeffsVectorType>
class DiagonalMatrix : ei_no_assignment_operator,
public MatrixBase<DiagonalMatrix<CoeffsVectorType> >
#ifndef EIGEN_PARSED_BY_DOXYGEN
public MatrixBase<DiagonalMatrix<CoeffsVectorType> >
#else
public MatrixBase
#endif
{
public:

View File

@@ -61,7 +61,11 @@ struct ei_traits<Product<LhsNested, RhsNested, DiagonalProduct> >
};
template<typename LhsNested, typename RhsNested> class Product<LhsNested, RhsNested, DiagonalProduct> : ei_no_assignment_operator,
#ifndef EIGEN_PARSED_BY_DOXYGEN
public MatrixBase<Product<LhsNested, RhsNested, DiagonalProduct> >
#else
public MatrixBase
#endif
{
typedef typename ei_traits<Product>::_LhsNested _LhsNested;
typedef typename ei_traits<Product>::_RhsNested _RhsNested;

View File

@@ -55,7 +55,11 @@ struct ei_traits<Flagged<ExpressionType, Added, Removed> >
};
template<typename ExpressionType, unsigned int Added, unsigned int Removed> class Flagged
#ifndef EIGEN_PARSED_BY_DOXYGEN
: public MatrixBase<Flagged<ExpressionType, Added, Removed> >
#else
: public MatrixBase
#endif
{
public:

View File

@@ -2,6 +2,7 @@
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob@math.jussieu.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -22,88 +23,95 @@
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_DUMMY_PACKET_MATH_H
#define EIGEN_DUMMY_PACKET_MATH_H
#ifndef EIGEN_GENERIC_PACKET_MATH_H
#define EIGEN_GENERIC_PACKET_MATH_H
/** \internal
* \file GenericPacketMath.h
*
* Default implementation for types not supported by the vectorization.
* In practice these functions are provided to make easier the writting
* of generic vectorized code.
*/
// Default implementation for types not supported by the vectorization.
// In practice these functions are provided to make easier the writting
// of generic vectorized code. However, at runtime, they should never be
// called, TODO so sould we raise an assertion or not ?
/** \internal \returns a + b (coeff-wise) */
template <typename Packet> inline Packet
template<typename Packet> inline Packet
ei_padd(const Packet& a,
const Packet& b) { return a+b; }
/** \internal \returns a - b (coeff-wise) */
template <typename Packet> inline Packet
template<typename Packet> inline Packet
ei_psub(const Packet& a,
const Packet& b) { return a-b; }
/** \internal \returns a * b (coeff-wise) */
template <typename Packet> inline Packet
template<typename Packet> inline Packet
ei_pmul(const Packet& a,
const Packet& b) { return a*b; }
/** \internal \returns a / b (coeff-wise) */
template <typename Packet> inline Packet
template<typename Packet> inline Packet
ei_pdiv(const Packet& a,
const Packet& b) { return a/b; }
/** \internal \returns the min of \a a and \a b (coeff-wise) */
template <typename Packet> inline Packet
template<typename Packet> inline Packet
ei_pmin(const Packet& a,
const Packet& b) { return std::min(a, b); }
/** \internal \returns the max of \a a and \a b (coeff-wise) */
template <typename Packet> inline Packet
template<typename Packet> inline Packet
ei_pmax(const Packet& a,
const Packet& b) { return std::max(a, b); }
/** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */
template <typename Scalar> inline typename ei_packet_traits<Scalar>::type
template<typename Scalar> inline typename ei_packet_traits<Scalar>::type
ei_pload(const Scalar* from) { return *from; }
/** \internal \returns a packet version of \a *from, (un-aligned load) */
template <typename Scalar> inline typename ei_packet_traits<Scalar>::type
template<typename Scalar> inline typename ei_packet_traits<Scalar>::type
ei_ploadu(const Scalar* from) { return *from; }
/** \internal \returns a packet with constant coefficients \a a, e.g.: (a,a,a,a) */
template <typename Scalar> inline typename ei_packet_traits<Scalar>::type
template<typename Scalar> inline typename ei_packet_traits<Scalar>::type
ei_pset1(const Scalar& a) { return a; }
/** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */
template <typename Scalar, typename Packet> inline void ei_pstore(Scalar* to, const Packet& from)
template<typename Scalar, typename Packet> inline void ei_pstore(Scalar* to, const Packet& from)
{ (*to) = from; }
/** \internal copy the packet \a from to \a *to, (un-aligned store) */
template <typename Scalar, typename Packet> inline void ei_pstoreu(Scalar* to, const Packet& from)
template<typename Scalar, typename Packet> inline void ei_pstoreu(Scalar* to, const Packet& from)
{ (*to) = from; }
/** \internal \returns the first element of a packet */
template <typename Packet> inline typename ei_unpacket_traits<Packet>::type ei_pfirst(const Packet& a)
template<typename Packet> inline typename ei_unpacket_traits<Packet>::type ei_pfirst(const Packet& a)
{ return a; }
/** \internal \returns a packet where the element i contains the sum of the packet of \a vec[i] */
template <typename Packet> inline Packet
template<typename Packet> inline Packet
ei_preduxp(const Packet* vecs) { return vecs[0]; }
/** \internal \returns the sum of the elements of \a a*/
template <typename Packet> inline typename ei_unpacket_traits<Packet>::type ei_predux(const Packet& a)
template<typename Packet> inline typename ei_unpacket_traits<Packet>::type ei_predux(const Packet& a)
{ return a; }
////////////
/***************************************************************************
* The following functions might not have to be overwritten for vectorized types
***************************************************************************/
/** \internal \returns a * b + c (coeff-wise) */
template <typename Packet> inline Packet
template<typename Packet> inline Packet
ei_pmadd(const Packet& a,
const Packet& b,
const Packet& c)
{ return ei_padd(ei_pmul(a, b),c); }
/** \internal \returns a packet version of \a *from. If LoadMode equals Aligned, \a from must be 16 bytes aligned */
template <typename Scalar, int LoadMode> inline typename ei_packet_traits<Scalar>::type ei_ploadt(const Scalar* from)
/** \internal \returns a packet version of \a *from.
* \If LoadMode equals Aligned, \a from must be 16 bytes aligned */
template<typename Scalar, int LoadMode>
inline typename ei_packet_traits<Scalar>::type ei_ploadt(const Scalar* from)
{
if(LoadMode == Aligned)
return ei_pload(from);
@@ -111,8 +119,10 @@ template <typename Scalar, int LoadMode> inline typename ei_packet_traits<Scalar
return ei_ploadu(from);
}
/** \internal copy the packet \a from to \a *to. If StoreMode equals Aligned, \a to must be 16 bytes aligned */
template <typename Scalar, typename Packet, int LoadMode> inline void ei_pstoret(Scalar* to, const Packet& from)
/** \internal copy the packet \a from to \a *to.
* If StoreMode equals Aligned, \a to must be 16 bytes aligned */
template<typename Scalar, typename Packet, int LoadMode>
inline void ei_pstoret(Scalar* to, const Packet& from)
{
if(LoadMode == Aligned)
ei_pstore(to, from);
@@ -120,21 +130,7 @@ template <typename Scalar, typename Packet, int LoadMode> inline void ei_pstoret
ei_pstoreu(to, from);
}
/** \internal \returns the number of elements which have to be skipped such that data are aligned */
template<typename Scalar>
inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset)
{
typedef typename ei_packet_traits<Scalar>::type Packet;
const int PacketSize = ei_packet_traits<Scalar>::size;
const int PacketAlignedMask = PacketSize-1;
const bool Vectorized = PacketSize>1;
return Vectorized
? std::min<int>( (PacketSize - ((size_t(ptr)/sizeof(Scalar)) & PacketAlignedMask))
& PacketAlignedMask, maxOffset)
: 0;
}
/** \internal specialization of ei_palign() */
/** \internal default implementation of ei_palign() allowing partial specialization */
template<int Offset,typename PacketType>
struct ei_palign_impl
{
@@ -150,5 +146,5 @@ inline void ei_palign(PacketType& first, const PacketType& second)
ei_palign_impl<Offset,PacketType>::run(first,second);
}
#endif // EIGEN_DUMMY_PACKET_MATH_H
#endif // EIGEN_GENERIC_PACKET_MATH_H

View File

@@ -57,7 +57,11 @@ struct ei_traits<Map<MatrixType, _PacketAccess> > : public ei_traits<MatrixType>
};
template<typename MatrixType, int PacketAccess> class Map
#ifndef EIGEN_PARSED_BY_DOXYGEN
: public MapBase<Map<MatrixType, PacketAccess> >
#else
: public MapBase
#endif
{
public:

View File

@@ -96,7 +96,12 @@ struct ei_traits<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols
};
template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols>
class Matrix : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols> >
class Matrix
#ifndef EIGEN_PARSED_BY_DOXYGEN
: public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols> >
#else
: public MatrixBase
#endif
{
public:
EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix)
@@ -369,6 +374,8 @@ class Matrix : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _M
};
/** \defgroup matrixtypedefs Global matrix typedefs
*
* \ingroup Core_Module
*
* Eigen defines several typedef shortcuts for most common matrix and vector types.
*

View File

@@ -39,44 +39,6 @@
*/
template<typename T, int Size, int _Rows, int _Cols> class ei_matrix_storage;
template <typename T, int Size, bool Align> struct ei_aligned_array
{
EIGEN_ALIGN_128 T array[Size];
};
template <typename T, int Size> struct ei_aligned_array<T,Size,false>
{
T array[Size];
};
template<typename T>
inline T* ei_aligned_malloc(size_t size)
{
#ifdef EIGEN_VECTORIZE
if (ei_packet_traits<T>::size>1)
{
void* ptr;
if (posix_memalign(&ptr, 16, size*sizeof(T))==0)
return static_cast<T*>(ptr);
else
return 0;
}
else
#endif
return new T[size];
}
template<typename T>
inline void ei_aligned_free(T* ptr)
{
#ifdef EIGEN_VECTORIZE
if (ei_packet_traits<T>::size>1)
free(ptr);
else
#endif
delete[] ptr;
}
// purely fixed-size matrix
template<typename T, int Size, int _Rows, int _Cols> class ei_matrix_storage
{

View File

@@ -58,7 +58,11 @@ struct ei_traits<Minor<MatrixType> >
};
template<typename MatrixType> class Minor
#ifndef EIGEN_PARSED_BY_DOXYGEN
: public MatrixBase<Minor<MatrixType> >
#else
: public MatrixBase
#endif
{
public:

View File

@@ -52,7 +52,11 @@ struct ei_traits<NestByValue<ExpressionType> >
};
template<typename ExpressionType> class NestByValue
#ifndef EIGEN_PARSED_BY_DOXYGEN
: public MatrixBase<NestByValue<ExpressionType> >
#else
: public MatrixBase
#endif
{
public:

View File

@@ -59,7 +59,11 @@ struct ei_traits<Part<MatrixType, Mode> >
};
template<typename MatrixType, unsigned int Mode> class Part
#ifndef EIGEN_PARSED_BY_DOXYGEN
: public MatrixBase<Part<MatrixType, Mode> >
#else
: public MatrixBase
#endif
{
public:

View File

@@ -168,7 +168,11 @@ struct ei_traits<Product<LhsNested, RhsNested, ProductMode> >
};
template<typename LhsNested, typename RhsNested, int ProductMode> class Product : ei_no_assignment_operator,
#ifndef EIGEN_PARSED_BY_DOXYGEN
public MatrixBase<Product<LhsNested, RhsNested, ProductMode> >
#else
public MatrixBase
#endif
{
public:

View File

@@ -46,7 +46,11 @@ struct ei_traits<SwapWrapper<ExpressionType> >
};
template<typename ExpressionType> class SwapWrapper
#ifndef EIGEN_PARSED_BY_DOXYGEN
: public MatrixBase<SwapWrapper<ExpressionType> >
#else
: public MatrixBase
#endif
{
public:

View File

@@ -57,7 +57,11 @@ struct ei_traits<Transpose<MatrixType> >
};
template<typename MatrixType> class Transpose
#ifndef EIGEN_PARSED_BY_DOXYGEN
: public MatrixBase<Transpose<MatrixType> >
#else
: public MatrixBase
#endif
{
public:

View File

@@ -29,6 +29,7 @@
const int Dynamic = 10000;
/** \defgroup flags
* \ingroup Core_Module
*
* These are the possible bits which can be OR'ed to constitute the flags of a matrix or
* expression.

View File

@@ -153,16 +153,4 @@ _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::MatrixBase<Derived>)
#define EIGEN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b)
#define EIGEN_ENUM_MAX(a,b) (((int)a >= (int)b) ? (int)a : (int)b)
/* ei_alloc_stack(TYPE,SIZE) allocates sizeof(TYPE)*SIZE bytes on the stack if sizeof(TYPE)*SIZE is smaller
* than EIGEN_STACK_ALLOCATION_LIMIT. Otherwise the memory is allocated using the operator new.
* Data allocated with ei_alloc_stack must be freed calling ei_free_stack(PTR,TYPE,SIZE)
*/
#ifdef __linux__
# define ei_alloc_stack(TYPE,SIZE) ((sizeof(TYPE)*(SIZE)>16000000) ? new TYPE[SIZE] : (TYPE*)alloca(sizeof(TYPE)*(SIZE)))
# define ei_free_stack(PTR,TYPE,SIZE) if (sizeof(TYPE)*SIZE>16000000) delete[] PTR
#else
# define ei_alloc_stack(TYPE,SIZE) new TYPE[SIZE]
# define ei_free_stack(PTR,TYPE,SIZE) delete[] PTR
#endif
#endif // EIGEN_MACROS_H

View File

@@ -0,0 +1,109 @@
// 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 <g.gael@free.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob@math.jussieu.fr>
//
// 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 <http://www.gnu.org/licenses/>.
#ifndef EIGEN_MEMORY_H
#define EIGEN_MEMORY_H
#ifdef EIGEN_VECTORIZE
// it seems we cannot assume posix_memalign is defined in the stdlib header
extern "C" int posix_memalign (void **, size_t, size_t) throw ();
#endif
/** \internal
* Static array automatically aligned if the total byte size is a multiple of 16
*/
template <typename T, int Size, bool Align> struct ei_aligned_array
{
EIGEN_ALIGN_128 T array[Size];
};
template <typename T, int Size> struct ei_aligned_array<T,Size,false>
{
T array[Size];
};
/** \internal allocates \a size * sizeof(\a T) bytes with a 16 bytes based alignement */
template<typename T>
inline T* ei_aligned_malloc(size_t size)
{
#ifdef EIGEN_VECTORIZE
if (ei_packet_traits<T>::size>1)
{
void* ptr;
if (posix_memalign(&ptr, 16, size*sizeof(T))==0)
return static_cast<T*>(ptr);
else
return 0;
}
else
#endif
return new T[size];
}
/** \internal free memory allocated with ei_aligned_malloc */
template<typename T>
inline void ei_aligned_free(T* ptr)
{
#ifdef EIGEN_VECTORIZE
if (ei_packet_traits<T>::size>1)
free(ptr);
else
#endif
delete[] ptr;
}
/** \internal \returns the number of elements which have to be skipped such that data are 16 bytes aligned */
template<typename Scalar>
inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset)
{
typedef typename ei_packet_traits<Scalar>::type Packet;
const int PacketSize = ei_packet_traits<Scalar>::size;
const int PacketAlignedMask = PacketSize-1;
const bool Vectorized = PacketSize>1;
return Vectorized
? std::min<int>( (PacketSize - ((size_t(ptr)/sizeof(Scalar)) & PacketAlignedMask))
& PacketAlignedMask, maxOffset)
: 0;
}
/** \internal
* ei_alloc_stack(TYPE,SIZE) allocates sizeof(TYPE)*SIZE bytes on the stack if sizeof(TYPE)*SIZE is
* smaller than EIGEN_STACK_ALLOCATION_LIMIT. Otherwise the memory is allocated using the operator new.
* Data allocated with ei_alloc_stack \b must be freed calling ei_free_stack(PTR,TYPE,SIZE).
* \code
* float * data = ei_alloc_stack(float,array.size());
* // ...
* ei_free_stack(data,float,array.size());
* \endcode
*/
#ifdef __linux__
# define ei_alloc_stack(TYPE,SIZE) ((sizeof(TYPE)*(SIZE)>16000000) ? new TYPE[SIZE] : (TYPE*)alloca(sizeof(TYPE)*(SIZE)))
# define ei_free_stack(PTR,TYPE,SIZE) if (sizeof(TYPE)*SIZE>16000000) delete[] PTR
#else
# define ei_alloc_stack(TYPE,SIZE) new TYPE[SIZE]
# define ei_free_stack(PTR,TYPE,SIZE) delete[] PTR
#endif
#endif // EIGEN_MEMORY_H