aboutsummaryrefslogtreecommitdiff
path: root/test/product_notemporary.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/product_notemporary.cpp')
-rw-r--r--test/product_notemporary.cpp55
1 files changed, 52 insertions, 3 deletions
diff --git a/test/product_notemporary.cpp b/test/product_notemporary.cpp
index 30592b79e..20cb7c080 100644
--- a/test/product_notemporary.cpp
+++ b/test/product_notemporary.cpp
@@ -11,11 +11,41 @@
#include "main.h"
+template<typename Dst, typename Lhs, typename Rhs>
+void check_scalar_multiple3(Dst &dst, const Lhs& A, const Rhs& B)
+{
+ VERIFY_EVALUATION_COUNT( (dst.noalias() = A * B), 0);
+ VERIFY_IS_APPROX( dst, (A.eval() * B.eval()).eval() );
+ VERIFY_EVALUATION_COUNT( (dst.noalias() += A * B), 0);
+ VERIFY_IS_APPROX( dst, 2*(A.eval() * B.eval()).eval() );
+ VERIFY_EVALUATION_COUNT( (dst.noalias() -= A * B), 0);
+ VERIFY_IS_APPROX( dst, (A.eval() * B.eval()).eval() );
+}
+
+template<typename Dst, typename Lhs, typename Rhs, typename S2>
+void check_scalar_multiple2(Dst &dst, const Lhs& A, const Rhs& B, S2 s2)
+{
+ CALL_SUBTEST( check_scalar_multiple3(dst, A, B) );
+ CALL_SUBTEST( check_scalar_multiple3(dst, A, -B) );
+ CALL_SUBTEST( check_scalar_multiple3(dst, A, s2*B) );
+ CALL_SUBTEST( check_scalar_multiple3(dst, A, B*s2) );
+ CALL_SUBTEST( check_scalar_multiple3(dst, A, (B*s2).conjugate()) );
+}
+
+template<typename Dst, typename Lhs, typename Rhs, typename S1, typename S2>
+void check_scalar_multiple1(Dst &dst, const Lhs& A, const Rhs& B, S1 s1, S2 s2)
+{
+ CALL_SUBTEST( check_scalar_multiple2(dst, A, B, s2) );
+ CALL_SUBTEST( check_scalar_multiple2(dst, -A, B, s2) );
+ CALL_SUBTEST( check_scalar_multiple2(dst, s1*A, B, s2) );
+ CALL_SUBTEST( check_scalar_multiple2(dst, A*s1, B, s2) );
+ CALL_SUBTEST( check_scalar_multiple2(dst, (A*s1).conjugate(), B, s2) );
+}
+
template<typename MatrixType> void product_notemporary(const MatrixType& m)
{
/* This test checks the number of temporaries created
* during the evaluation of a complex expression */
- typedef typename MatrixType::Index Index;
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
typedef Matrix<Scalar, 1, Dynamic> RowVectorType;
@@ -106,7 +136,9 @@ template<typename MatrixType> void product_notemporary(const MatrixType& m)
VERIFY_EVALUATION_COUNT( m3.noalias() = m1.block(r0,r0,r1,r1).template triangularView<UnitUpper>() * m2.block(r0,c0,r1,c1), 1);
// Zero temporaries for lazy products ...
+ m3.setRandom(rows,cols);
VERIFY_EVALUATION_COUNT( Scalar tmp = 0; tmp += Scalar(RealScalar(1)) / (m3.transpose().lazyProduct(m3)).diagonal().sum(), 0 );
+ VERIFY_EVALUATION_COUNT( m3.noalias() = m1.conjugate().lazyProduct(m2.conjugate()), 0);
// ... and even no temporary for even deeply (>=2) nested products
VERIFY_EVALUATION_COUNT( Scalar tmp = 0; tmp += Scalar(RealScalar(1)) / (m3.transpose() * m3).diagonal().sum(), 0 );
@@ -128,11 +160,19 @@ template<typename MatrixType> void product_notemporary(const MatrixType& m)
VERIFY_EVALUATION_COUNT( cvres.noalias() = (rm3+rm3) * (m1*cv1), 1 );
// Check outer products
+ #ifdef EIGEN_ALLOCA
+ bool temp_via_alloca = m3.rows()*sizeof(Scalar) <= EIGEN_STACK_ALLOCATION_LIMIT;
+ #else
+ bool temp_via_alloca = false;
+ #endif
m3 = cv1 * rv1;
VERIFY_EVALUATION_COUNT( m3.noalias() = cv1 * rv1, 0 );
- VERIFY_EVALUATION_COUNT( m3.noalias() = (cv1+cv1) * (rv1+rv1), 1 );
+ VERIFY_EVALUATION_COUNT( m3.noalias() = (cv1+cv1) * (rv1+rv1), temp_via_alloca ? 0 : 1 );
VERIFY_EVALUATION_COUNT( m3.noalias() = (m1*cv1) * (rv1), 1 );
VERIFY_EVALUATION_COUNT( m3.noalias() += (m1*cv1) * (rv1), 1 );
+ rm3 = cv1 * rv1;
+ VERIFY_EVALUATION_COUNT( rm3.noalias() = cv1 * rv1, 0 );
+ VERIFY_EVALUATION_COUNT( rm3.noalias() = (cv1+cv1) * (rv1+rv1), temp_via_alloca ? 0 : 1 );
VERIFY_EVALUATION_COUNT( rm3.noalias() = (cv1) * (rv1 * m1), 1 );
VERIFY_EVALUATION_COUNT( rm3.noalias() -= (cv1) * (rv1 * m1), 1 );
VERIFY_EVALUATION_COUNT( rm3.noalias() = (m1*cv1) * (rv1 * m1), 2 );
@@ -141,9 +181,18 @@ template<typename MatrixType> void product_notemporary(const MatrixType& m)
// Check nested products
VERIFY_EVALUATION_COUNT( cvres.noalias() = m1.adjoint() * m1 * cv1, 1 );
VERIFY_EVALUATION_COUNT( rvres.noalias() = rv1 * (m1 * m2.adjoint()), 1 );
+
+ // exhaustively check all scalar multiple combinations:
+ {
+ // Generic path:
+ check_scalar_multiple1(m3, m1, m2, s1, s2);
+ // Force fall back to coeff-based:
+ typename ColMajorMatrixType::BlockXpr m3_blck = m3.block(r0,r0,1,1);
+ check_scalar_multiple1(m3_blck, m1.block(r0,c0,1,1), m2.block(c0,r0,1,1), s1, s2);
+ }
}
-void test_product_notemporary()
+EIGEN_DECLARE_TEST(product_notemporary)
{
int s;
for(int i = 0; i < g_repeat; i++) {