Re: [eigen] AVX/LRB and SSE with SoA support |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
Hello,
The Patch is attached.
The contents of array.h of my previous post are not included, because i
do not know how to do this in an Eigen-consistent way, that is useful
for everyone.
Thanks for all the time you invested in answering my questions.
Greetings,
Christoph
P.S. This is my first patch for an OS Project
exporting patch:
# HG changeset patch
# User Christoph Keller <christoph-keller@xxxxxx>
# Date 1281206527 -7200
# Node ID b47fa74480453245616db78da09c9ce7f89baa94
# Parent ae0be1bcc96c6ba0e94697f33c01366e720d3c81
+Binary operators, masked comparisons
diff -r ae0be1bcc96c -r b47fa7448045 Eigen/src/Core/ArrayBase.h
--- a/Eigen/src/Core/ArrayBase.h Thu Aug 05 08:56:19 2010 +0200
+++ b/Eigen/src/Core/ArrayBase.h Sat Aug 07 20:42:07 2010 +0200
@@ -148,6 +148,12 @@
template<typename OtherDerived>
Derived& operator/=(const ArrayBase<OtherDerived>& other);
+ template<typename OtherDerived>
+ Derived& operator|=(const ArrayBase<OtherDerived>& other);
+ template<typename OtherDerived>
+ Derived& operator&=(const ArrayBase<OtherDerived>& other);
+ template<typename OtherDerived>
+ Derived& operator^=(const ArrayBase<OtherDerived>& other);
public:
ArrayBase<Derived>& array() { return *this; }
const ArrayBase<Derived>& array() const { return *this; }
@@ -225,4 +231,34 @@
return derived();
}
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE Derived &
+ArrayBase<Derived>::operator|=(const ArrayBase<OtherDerived> &other)
+{
+ SelfCwiseBinaryOp<ei_scalar_or_op<Scalar>, Derived, OtherDerived> tmp(derived());
+ tmp = other;
+ return derived();
+}
+
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE Derived &
+ArrayBase<Derived>::operator&=(const ArrayBase<OtherDerived> &other)
+{
+ SelfCwiseBinaryOp<ei_scalar_and_op<Scalar>, Derived, OtherDerived> tmp(derived());
+ tmp = other;
+ return derived();
+}
+
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE Derived &
+ArrayBase<Derived>::operator^=(const ArrayBase<OtherDerived> &other)
+{
+ SelfCwiseBinaryOp<ei_scalar_xor_op<Scalar>, Derived, OtherDerived> tmp(derived());
+ tmp = other;
+ return derived();
+}
+
#endif // EIGEN_ARRAYBASE_H
diff -r ae0be1bcc96c -r b47fa7448045 Eigen/src/Core/Functors.h
--- a/Eigen/src/Core/Functors.h Thu Aug 05 08:56:19 2010 +0200
+++ b/Eigen/src/Core/Functors.h Sat Aug 07 20:42:07 2010 +0200
@@ -78,6 +78,186 @@
};
/** \internal
+ * \brief Template functor to compute the binary or of two scalars
+ *
+ * \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum()
+ */
+template<typename Scalar> struct ei_scalar_or_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_or_op)
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const
+ { unsigned tmp = (*((unsigned*)&a)) | (*((unsigned*)&b));
+ return *((float*)(&tmp));}
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
+ { return ei_por(a,b); }
+};
+
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_or_op<Scalar> > {
+ enum {
+ Cost = NumTraits<Scalar>::AddCost,
+ PacketAccess = ei_packet_traits<Scalar>::size>1
+ };
+};
+
+/** \internal
+ * \brief Template functor to compute the binary and of two scalars
+ *
+ * \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum()
+ */
+template<typename Scalar> struct ei_scalar_and_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_and_op)
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const
+ { unsigned tmp = (*((unsigned*)&a)) & *(((unsigned*)&b));
+ return *((float*)(&tmp)); }
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
+ { return ei_pand(a,b); }
+};
+
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_and_op<Scalar> > {
+ enum {
+ Cost = NumTraits<Scalar>::AddCost,
+ PacketAccess = ei_packet_traits<Scalar>::size>1
+ };
+};
+
+/** \internal
+ * \brief Template functor to compute the binary xor of two scalars
+ *
+ * \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum()
+ */
+template<typename Scalar> struct ei_scalar_xor_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_xor_op)
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const
+ { unsigned tmp = (*((unsigned*)&a)) ^ (*((unsigned*)&b));
+ return *((float*)(&tmp)); }
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
+ { return ei_pxor(a,b); }
+};
+
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_xor_op<Scalar> > {
+ enum {
+ Cost = NumTraits<Scalar>::AddCost,
+ PacketAccess = ei_packet_traits<Scalar>::size>1
+ };
+};
+
+/** \internal
+ * \brief Template functor to compare two scalars
+ *
+ * \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
+ */
+template<typename Scalar> struct ei_scalar_cmpgt_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cmpgt_op)
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const
+ { unsigned tmp = 0xFFFFFFFF;
+ return (a > b) ? (*((float*)(&tmp))):0; }
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
+ //{ return ei_pcmpgt(a,b); }
+ { return _mm_cmpgt_ps(a,b); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_cmpgt_op<Scalar> > {
+ enum {
+ Cost = NumTraits<Scalar>::MulCost,
+ PacketAccess = ei_packet_traits<Scalar>::size>1
+ };
+};
+
+/** \internal
+ * \brief Template functor to compare two scalars
+ *
+ * \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
+ */
+template<typename Scalar> struct ei_scalar_cmpngt_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cmpngt_op)
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const
+ { unsigned tmp = 0xFFFFFFFF;
+ return (a <= b) ? (*((float*)(&tmp))):0; }
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
+ { return ei_pcmpngt(a,b); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_cmpngt_op<Scalar> > {
+ enum {
+ Cost = NumTraits<Scalar>::MulCost,
+ PacketAccess = ei_packet_traits<Scalar>::size>1
+ };
+};
+
+/** \internal
+ * \brief Template functor to compare two scalars
+ *
+ * \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
+ */
+template<typename Scalar> struct ei_scalar_cmplt_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cmplt_op)
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const
+ { unsigned tmp = 0xFFFFFFFF;
+ return (a < b) ? (*((float*)(&tmp))):0; }
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
+ { return ei_pcmplt(a,b); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_cmplt_op<Scalar> > {
+ enum {
+ Cost = NumTraits<Scalar>::MulCost,
+ PacketAccess = ei_packet_traits<Scalar>::size>1
+ };
+};
+
+/** \internal
+ * \brief Template functor to compare two scalars
+ *
+ * \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
+ */
+template<typename Scalar> struct ei_scalar_cmpnlt_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cmpnlt_op)
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const
+ { unsigned tmp = 0xFFFFFFFF;
+ return (a >= b) ? (*((float*)(&tmp))):0; }
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
+ { return ei_pcmpnlt(a,b); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_cmpnlt_op<Scalar> > {
+ enum {
+ Cost = NumTraits<Scalar>::MulCost,
+ PacketAccess = ei_packet_traits<Scalar>::size>1
+ };
+};
+
+/** \internal
+ * \brief Template functor to compare two scalars
+ *
+ * \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
+ */
+template<typename Scalar> struct ei_scalar_cmpeq_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cmpeq_op)
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const
+ { unsigned tmp = 0xFFFFFFFF;
+ return (a == b) ? (*((float*)(&tmp))):0; }
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
+ { return ei_pcmpeq(a,b); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_cmpeq_op<Scalar> > {
+ enum {
+ Cost = NumTraits<Scalar>::MulCost,
+ PacketAccess = ei_packet_traits<Scalar>::size>1
+ };
+};
+
+/** \internal
* \brief Template functor to compute the conjugate product of two scalars
*
* This is a short cut for ei_conj(x) * y which is needed for optimization purpose
diff -r ae0be1bcc96c -r b47fa7448045 Eigen/src/Core/GenericPacketMath.h
--- a/Eigen/src/Core/GenericPacketMath.h Thu Aug 05 08:56:19 2010 +0200
+++ b/Eigen/src/Core/GenericPacketMath.h Sat Aug 07 20:42:07 2010 +0200
@@ -159,6 +159,26 @@
template<typename Packet> inline Packet
ei_pandnot(const Packet& a, const Packet& b) { return a & (!b); }
+/** \internal \returns a mask resulting of the comparison of \a a and \a b */
+template<typename Packet> inline Packet
+ei_pcmpgt(const Packet& a, const Packet& b);
+
+/** \internal \returns a mask resulting of the comparison of \a a and \a b */
+template<typename Packet> inline Packet
+ei_pcmpngt(const Packet& a, const Packet& b);
+
+/** \internal \returns a mask resulting of the comparison of \a a and \a b */
+template<typename Packet> inline Packet
+ei_pcmpeq(const Packet& a, const Packet& b);
+
+/** \internal \returns a mask resulting of the comparison of \a a and \a b */
+template<typename Packet> inline Packet
+ei_pcmplt(const Packet& a, const Packet& b);
+
+/** \internal \returns a mask resulting of the comparison of \a a and \a b */
+template<typename Packet> inline Packet
+ei_pcmpnlt(const Packet& a, const Packet& b);
+
/** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */
template<typename Packet> inline Packet
ei_pload(const typename ei_unpacket_traits<Packet>::type* from) { return *from; }
diff -r ae0be1bcc96c -r b47fa7448045 Eigen/src/plugins/ArrayCwiseBinaryOps.h
--- a/Eigen/src/plugins/ArrayCwiseBinaryOps.h Thu Aug 05 08:56:19 2010 +0200
+++ b/Eigen/src/plugins/ArrayCwiseBinaryOps.h Sat Aug 07 20:42:07 2010 +0200
@@ -38,6 +38,51 @@
*/
EIGEN_MAKE_CWISE_BINARY_OP(max,ei_scalar_max_op)
+/** \returns an expression of the mask of the comparision of \c *this and \a other
+ *
+ * \sa class CwiseBinaryOp, operator<()
+ */
+EIGEN_MAKE_CWISE_BINARY_OP(cmpgt,ei_scalar_cmpgt_op)
+
+/** \returns an expression of the mask of the comparision of \c *this and \a other
+ *
+ * \sa class CwiseBinaryOp, operator<=()
+ */
+EIGEN_MAKE_CWISE_BINARY_OP(cmpnlt,ei_scalar_cmpnlt_op)
+
+/** \returns an expression of the mask of the comparision of \c *this and \a other
+ *
+ * \sa class CwiseBinaryOp, operator>=()
+ */
+EIGEN_MAKE_CWISE_BINARY_OP(cmpngt,ei_scalar_cmpngt_op)
+
+/** \returns an expression of the mask of the comparision of \c *this and \a other
+ *
+ * \sa class CwiseBinaryOp, operator>()
+ */
+EIGEN_MAKE_CWISE_BINARY_OP(cmplt,ei_scalar_cmplt_op)
+
+/** \returns an expression of the mask of the comparision of \c *this and \a other
+ *
+ * \sa class CwiseBinaryOp, operator>()
+ */
+EIGEN_MAKE_CWISE_BINARY_OP(cmpeq,ei_scalar_cmpeq_op)
+
+/*If EIGEN_USE_MASK_COMPARISON is defined replace the usual comparison operators with
+ * operators using masks
+ */
+#ifndef EIGEN_PARSED_BY_DOXYGEN
+#ifdef EIGEN_RETURN_MASK_ON_COMPARISON
+EIGEN_MAKE_CWISE_BINARY_OP(operator>, ei_scalar_cmpgt_op)
+EIGEN_MAKE_CWISE_BINARY_OP(operator>=, ei_scalar_cmpnlt_op)
+EIGEN_MAKE_CWISE_BINARY_OP(operator<, ei_scalar_cmplt_op)
+EIGEN_MAKE_CWISE_BINARY_OP(operator<=, ei_scalar_cmpnlt_op)
+EIGEN_MAKE_CWISE_BINARY_OP(operator==, ei_scalar_cmpeq_op)
+#endif
+#endif
+
+#ifndef EIGEN_RETURN_MASK_ON_COMPARISON
+
/** \returns an expression of the coefficient-wise \< operator of *this and \a other
*
* Example: \include Cwise_less.cpp
@@ -88,6 +133,8 @@
*/
EIGEN_MAKE_CWISE_BINARY_OP(operator==,std::equal_to)
+#endif
+
/** \returns an expression of the coefficient-wise != operator of *this and \a other
*
* \warning this performs an exact comparison, which is generally a bad idea with floating-point types.
diff -r ae0be1bcc96c -r b47fa7448045 Eigen/src/plugins/CommonCwiseBinaryOps.h
--- a/Eigen/src/plugins/CommonCwiseBinaryOps.h Thu Aug 05 08:56:19 2010 +0200
+++ b/Eigen/src/plugins/CommonCwiseBinaryOps.h Sat Aug 07 20:42:07 2010 +0200
@@ -41,6 +41,24 @@
*/
EIGEN_MAKE_CWISE_BINARY_OP(operator+,ei_scalar_sum_op)
+/** \returns an expression of the binary or of \c *this and \a other
+ *
+ * \sa class CwiseBinaryOp, operator|=()
+ */
+EIGEN_MAKE_CWISE_BINARY_OP(operator|,ei_scalar_or_op)
+
+/** \returns an expression of the binary and of \c *this and \a other
+ *
+ * \sa class CwiseBinaryOp, operator&=()
+ */
+EIGEN_MAKE_CWISE_BINARY_OP(operator&,ei_scalar_and_op)
+
+/** \returns an expression of the binary xor of \c *this and \a other
+ *
+ * \sa class CwiseBinaryOp, operator^=()
+ */
+EIGEN_MAKE_CWISE_BINARY_OP(operator^,ei_scalar_xor_op)
+
/** \returns an expression of a custom coefficient-wise operator \a func of *this and \a other
*
* The template parameter \a CustomBinaryOp is the type of the functor