aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core/MapBase.h
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2009-10-23 14:26:14 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2009-10-23 14:26:14 +0200
commita382963b04d4b847c6b0ef0611511fb6a8e11718 (patch)
treead12bedf1d6537b14219889c49b82773a9bc8fab /Eigen/src/Core/MapBase.h
parent83a7b7c44c4842e1cfa89179624f4448d39a9e5b (diff)
* extend Map to allow the user to specify whether the mapped data
is aligned or not. This is done using the Aligned constant: Map<MatrixType,Aligned>::Map(data); * rename ForceAligned to EnforceAlignedAccess, and update its doc, and emphasize this is mainly an internal stuff.
Diffstat (limited to 'Eigen/src/Core/MapBase.h')
-rw-r--r--Eigen/src/Core/MapBase.h40
1 files changed, 28 insertions, 12 deletions
diff --git a/Eigen/src/Core/MapBase.h b/Eigen/src/Core/MapBase.h
index 88a3fac1e..8770732de 100644
--- a/Eigen/src/Core/MapBase.h
+++ b/Eigen/src/Core/MapBase.h
@@ -32,11 +32,17 @@
*
* Expression classes inheriting MapBase must define the constant \c PacketAccess,
* and type \c AlignedDerivedType in their respective ei_traits<> specialization structure.
- * The value of \c PacketAccess can be either:
- * - \b ForceAligned which enforces both aligned loads and stores
- * - \b AsRequested which is the default behavior
+ * The value of \c PacketAccess can be either \b AsRequested, or set to \b EnforceAlignedAccess which
+ * enforces both aligned loads and stores.
+ *
+ * \c EnforceAlignedAccess is automatically set in expressions such as
+ * \code A += B; \endcode where A is either a Block or a Map. Here,
+ * this expression is transfomed into \code A = A_with_EnforceAlignedAccess + B; \endcode
+ * avoiding unaligned loads from A. Indeed, since Eigen's packet evaluation mechanism
+ * automatically align to the destination matrix, we know that loads to A will be aligned too.
+ *
* The type \c AlignedDerivedType should correspond to the equivalent expression type
- * with \c PacketAccess being \c ForceAligned.
+ * with \c PacketAccess set to \c EnforceAlignedAccess.
*
* \sa class Map, class Block
*/
@@ -79,19 +85,19 @@ template<typename Derived> class MapBase
* \sa MapBase::stride() */
inline const Scalar* data() const { return m_data; }
- template<bool IsForceAligned,typename Dummy> struct force_aligned_impl {
+ template<bool IsEnforceAlignedAccess,typename Dummy> struct force_aligned_impl {
static AlignedDerivedType run(MapBase& a) { return a.derived(); }
};
template<typename Dummy> struct force_aligned_impl<false,Dummy> {
- static AlignedDerivedType run(MapBase& a) { return a.derived()._convertToForceAligned(); }
+ static AlignedDerivedType run(MapBase& a) { return a.derived()._convertToEnforceAlignedAccess(); }
};
/** \returns an expression equivalent to \c *this but having the \c PacketAccess constant
- * set to \c ForceAligned. Must be reimplemented by the derived class. */
+ * set to \c EnforceAlignedAccess. Must be reimplemented by the derived class. */
AlignedDerivedType forceAligned()
{
- return force_aligned_impl<int(PacketAccess)==int(ForceAligned),Derived>::run(*this);
+ return force_aligned_impl<int(PacketAccess)==int(EnforceAlignedAccess),Derived>::run(*this);
}
inline const Scalar& coeff(int row, int col) const
@@ -131,7 +137,7 @@ template<typename Derived> class MapBase
template<int LoadMode>
inline PacketScalar packet(int row, int col) const
{
- return ei_ploadt<Scalar, int(PacketAccess) == ForceAligned ? Aligned : LoadMode>
+ return ei_ploadt<Scalar, int(PacketAccess) == EnforceAlignedAccess ? Aligned : LoadMode>
(m_data + (IsRowMajor ? col + row * stride()
: row + col * stride()));
}
@@ -139,13 +145,13 @@ template<typename Derived> class MapBase
template<int LoadMode>
inline PacketScalar packet(int index) const
{
- return ei_ploadt<Scalar, int(PacketAccess) == ForceAligned ? Aligned : LoadMode>(m_data + index);
+ return ei_ploadt<Scalar, int(PacketAccess) == EnforceAlignedAccess ? Aligned : LoadMode>(m_data + index);
}
template<int StoreMode>
inline void writePacket(int row, int col, const PacketScalar& x)
{
- ei_pstoret<Scalar, PacketScalar, int(PacketAccess) == ForceAligned ? Aligned : StoreMode>
+ ei_pstoret<Scalar, PacketScalar, int(PacketAccess) == EnforceAlignedAccess ? Aligned : StoreMode>
(const_cast<Scalar*>(m_data) + (IsRowMajor ? col + row * stride()
: row + col * stride()), x);
}
@@ -153,13 +159,14 @@ template<typename Derived> class MapBase
template<int StoreMode>
inline void writePacket(int index, const PacketScalar& x)
{
- ei_pstoret<Scalar, PacketScalar, int(PacketAccess) == ForceAligned ? Aligned : StoreMode>
+ ei_pstoret<Scalar, PacketScalar, int(PacketAccess) == EnforceAlignedAccess ? Aligned : StoreMode>
(const_cast<Scalar*>(m_data) + index, x);
}
inline MapBase(const Scalar* data) : m_data(data), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
{
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
+ checkDataAlignment();
}
inline MapBase(const Scalar* data, int size)
@@ -170,6 +177,7 @@ template<typename Derived> class MapBase
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
ei_assert(size >= 0);
ei_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
+ checkDataAlignment();
}
inline MapBase(const Scalar* data, int rows, int cols)
@@ -178,6 +186,7 @@ template<typename Derived> class MapBase
ei_assert( (data == 0)
|| ( rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
+ checkDataAlignment();
}
Derived& operator=(const MapBase& other)
@@ -215,6 +224,13 @@ template<typename Derived> class MapBase
{ return derived() = forceAligned() / other; }
protected:
+
+ void checkDataAlignment() const
+ {
+ ei_assert( ((!(ei_traits<Derived>::Flags&AlignedBit))
+ || ((std::size_t(m_data)&0xf)==0)) && "data is not aligned");
+ }
+
const Scalar* EIGEN_RESTRICT m_data;
const ei_int_if_dynamic<RowsAtCompileTime> m_rows;
const ei_int_if_dynamic<ColsAtCompileTime> m_cols;