merge and add start/end to Eigen2Support

This commit is contained in:
Gael Guennebaud
2010-01-05 13:07:32 +01:00
78 changed files with 1072 additions and 592 deletions

View File

@@ -223,7 +223,8 @@ struct ei_blas_traits<Transpose<NestedXpr> >
typedef typename NestedXpr::Scalar Scalar;
typedef ei_blas_traits<NestedXpr> Base;
typedef Transpose<NestedXpr> XprType;
typedef Transpose<typename Base::_ExtractType> ExtractType;
typedef Transpose<typename Base::_ExtractType> ExtractType;
typedef Transpose<typename Base::_ExtractType> _ExtractType;
typedef typename ei_meta_if<int(Base::ActualAccess)==HasDirectAccess,
ExtractType,
typename ExtractType::PlainMatrixType

View File

@@ -209,27 +209,53 @@ template<typename T, bool Align> inline void ei_conditional_aligned_delete(T *pt
ei_conditional_aligned_free<Align>(ptr);
}
/** \internal \returns the number of elements which have to be skipped to
* find the first 16-byte aligned element
/** \internal \returns the index of the first element of the array that is well aligned for vectorization.
*
* There is also the variant ei_alignmentOffset(const MatrixBase&, Integer) defined in Coeffs.h.
* \param array the address of the start of the array
* \param size the size of the array
*
* \note If no element of the array is well aligned, the size of the array is returned. Typically,
* for example with SSE, "well aligned" means 16-byte-aligned. If vectorization is disabled or if the
* packet size for the given scalar type is 1, then everything is considered well-aligned.
*
* \note If the scalar type is vectorizable, we rely on the following assumptions: sizeof(Scalar) is a
* power of 2, the packet size in bytes is also a power of 2, and is a multiple of sizeof(Scalar). On the
* other hand, we do not assume that the array address is a multiple of sizeof(Scalar), as that fails for
* example with Scalar=double on certain 32-bit platforms, see bug #79.
*
* There is also the variant ei_first_aligned(const MatrixBase&, Integer) defined in Coeffs.h.
*/
template<typename Scalar, typename Integer>
inline static Integer ei_alignmentOffset(const Scalar* ptr, Integer maxOffset)
inline static Integer ei_first_aligned(const Scalar* array, Integer size)
{
typedef typename ei_packet_traits<Scalar>::type Packet;
const Integer PacketSize = ei_packet_traits<Scalar>::size;
const Integer PacketAlignedMask = PacketSize-1;
const bool Vectorized = PacketSize>1;
return Vectorized
? std::min<Integer>( (PacketSize - (Integer((size_t(ptr)/sizeof(Scalar))) & PacketAlignedMask))
& PacketAlignedMask, maxOffset)
: 0;
enum { PacketSize = ei_packet_traits<Scalar>::size,
PacketAlignedMask = PacketSize-1
};
if(PacketSize==1)
{
// Either there is no vectorization, or a packet consists of exactly 1 scalar so that all elements
// of the array have the same aligment.
return 0;
}
else if(size_t(array) & (sizeof(Scalar)-1))
{
// There is vectorization for this scalar type, but the array is not aligned to the size of a single scalar.
// Consequently, no element of the array is well aligned.
return size;
}
else
{
return std::min<Integer>( (PacketSize - (Integer((size_t(array)/sizeof(Scalar))) & PacketAlignedMask))
& PacketAlignedMask, size);
}
}
/** \internal
* ei_aligned_stack_alloc(SIZE) allocates an aligned buffer of SIZE bytes
* on the stack if SIZE is smaller than EIGEN_STACK_ALLOCATION_LIMIT.
* on the stack if SIZE is smaller than EIGEN_STACK_ALLOCATION_LIMIT, and
* if stack allocation is supported by the platform (currently, this is linux only).
* Otherwise the memory is allocated on the heap.
* Data allocated with ei_aligned_stack_alloc \b must be freed by calling ei_aligned_stack_free(PTR,SIZE).
* \code
@@ -381,10 +407,10 @@ public:
ei_aligned_free( p );
}
bool operator!=(const aligned_allocator<T>& other) const
bool operator!=(const aligned_allocator<T>& ) const
{ return false; }
bool operator==(const aligned_allocator<T>& other) const
bool operator==(const aligned_allocator<T>& ) const
{ return true; }
};

View File

@@ -109,23 +109,6 @@ template<int _Rows, int _Cols> struct ei_size_at_compile_time
* whereas ei_eval is a const reference in the case of a matrix
*/
// template<typename Derived> class MatrixBase;
// template<typename Derived> class ArrayBase;
// template<typename Object> struct ei_is_matrix_or_array
// {
// struct is_matrix {int a[1];};
// struct is_array {int a[2];};
// struct is_none {int a[3];};
//
// template<typename T>
// static is_matrix testBaseClass(const MatrixBase<T>*);
// template<typename T>
// static is_array testBaseClass(const ArrayBase<T>*);
// // static is_none testBaseClass(...);
//
// enum {BaseClassType = sizeof(testBaseClass(static_cast<const Object*>(0)))};
// };
template<typename T, typename StorageType = typename ei_traits<T>::StorageType> class ei_plain_matrix_type;
template<typename T, typename BaseClassType> struct ei_plain_matrix_type_dense;
template<typename T> struct ei_plain_matrix_type<T,Dense>