Bugzilla – Attachment 655 Details for
Bug 408
block() does not allow recursion
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Forgot Password
Login:
[x]
This bugzilla service is closed. All entries have been migrated to
https://gitlab.com/libeigen/eigen
[patch]
Patch to fuse Block<Block<X>> as Block<X>
fuse_block_block.diff (text/plain), 14.62 KB, created by
Gael Guennebaud
on 2016-02-23 10:16:20 UTC
(
hide
)
Description:
Patch to fuse Block<Block<X>> as Block<X>
Filename:
MIME Type:
Creator:
Gael Guennebaud
Created:
2016-02-23 10:16:20 UTC
Size:
14.62 KB
patch
obsolete
># HG changeset patch ># Parent 437cf67061229cc2869c4b7c8e390891a1ae8b1f > >diff --git a/Eigen/src/Core/Block.h b/Eigen/src/Core/Block.h >--- a/Eigen/src/Core/Block.h >+++ b/Eigen/src/Core/Block.h >@@ -1,12 +1,12 @@ > // This file is part of Eigen, a lightweight C++ template library > // for linear algebra. > // >-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> >+// Copyright (C) 2008-2016 Gael Guennebaud <gael.guennebaud@inria.fr> > // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> > // > // This Source Code Form is subject to the terms of the Mozilla > // Public License v. 2.0. If a copy of the MPL was not distributed > // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. > > #ifndef EIGEN_BLOCK_H > #define EIGEN_BLOCK_H >@@ -49,17 +49,17 @@ struct traits<Block<XprType, BlockRows, > > // FIXME, this traits is rather specialized for dense object and it needs to be cleaned further > FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0, > FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0, > Flags = (traits<XprType>::Flags & (DirectAccessBit | (InnerPanel?CompressedAccessBit:0))) | FlagsLvalueBit | FlagsRowMajorBit, > // FIXME DirectAccessBit should not be handled by expressions > // > // Alignment is needed by MapBase's assertions >- // We can sefely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the respective evaluator >+ // We can safely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the respective evaluator > Alignment = 0 > }; > }; > > template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false, > bool HasDirectAccess = internal::has_direct_access<XprType>::ret> class BlockImpl_dense; > > } // end namespace internal >@@ -141,19 +141,129 @@ template<typename XprType, int BlockRows > Index blockRows, Index blockCols) > : Impl(xpr, startRow, startCol, blockRows, blockCols) > { > eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows) > && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols)); > eigen_assert(startRow >= 0 && blockRows >= 0 && startRow <= xpr.rows() - blockRows > && startCol >= 0 && blockCols >= 0 && startCol <= xpr.cols() - blockCols); > } >+ > }; >- >-// The generic default implementation for dense block simplu forward to the internal::BlockImpl_dense >+ >+// Fuse any Block<Block<X>> expressions as a Block<X> expression >+// This is the non-const specialization >+template<typename XprType, int BlockRows0, int BlockCols0, bool InnerPanel0, int BlockRows, int BlockCols, bool InnerPanel> >+class Block<Block<XprType, BlockRows0, BlockCols0, InnerPanel0>, BlockRows, BlockCols, InnerPanel> >+ : public Block<XprType,BlockRows,BlockCols,InnerPanel && InnerPanel0> >+{ >+ typedef Block<XprType,BlockRows0,BlockCols0,InnerPanel0> ArgType; >+ typedef Block<XprType,BlockRows,BlockCols,InnerPanel && InnerPanel0> Base; >+public: >+ using Base::operator=; >+ >+ /** Column or Row constructor >+ */ >+ EIGEN_DEVICE_FUNC >+ template<typename OtherBlock> >+ inline Block(OtherBlock &blk, Index i) >+ : Base(blk.nestedExpression(), >+ blk.startRow() + ((BlockRows==1) && (BlockCols==ArgType::ColsAtCompileTime) ? i : 0), >+ blk.startCol() + ((BlockRows==ArgType::RowsAtCompileTime) && (BlockCols==1) ? i : 0), >+ BlockRows==1 ? 1 : blk.rows(), >+ BlockCols==1 ? 1 : blk.cols() >+ ) >+ { >+ eigen_assert( (i>=0) && ( >+ ((BlockRows==1) && (BlockCols==ArgType::ColsAtCompileTime) && i<blk.rows()) >+ ||((BlockRows==ArgType::RowsAtCompileTime) && (BlockCols==1) && i<blk.cols()))); >+ } >+ >+ /** Fixed-size constructor >+ */ >+ EIGEN_DEVICE_FUNC >+ template<typename OtherBlock> >+ inline Block(OtherBlock &blk, Index startRow, Index startCol) >+ : Base(blk.nestedExpression(), >+ blk.startRow() + startRow, >+ blk.startCol() + startCol) >+ { >+ EIGEN_STATIC_ASSERT(Base::RowsAtCompileTime!=Dynamic && Base::ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE) >+ eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= blk.rows() >+ && startCol >= 0 && BlockCols >= 0 && startCol + BlockCols <= blk.cols()); >+ } >+ >+ /** Dynamic-size constructor >+ */ >+ EIGEN_DEVICE_FUNC >+ template<typename OtherBlock> >+ inline Block(OtherBlock &blk, Index startRow, Index startCol, Index blockRows, Index blockCols) >+ : Base(blk.nestedExpression(), blk.startRow() + startRow, blk.startCol() + startCol, blockRows, blockCols) >+ { >+ eigen_assert((Base::RowsAtCompileTime==Dynamic || Base::RowsAtCompileTime==blockRows) >+ && (Base::ColsAtCompileTime==Dynamic || Base::ColsAtCompileTime==blockCols)); >+ eigen_assert(startRow >= 0 && blockRows >= 0 && startRow <= blk.rows() - blockRows >+ && startCol >= 0 && blockCols >= 0 && startCol <= blk.cols() - blockCols); >+ } >+}; >+ >+// Fuse any Block<const Block<X>> expressions as a Block<const X> expression >+// This is the const specialization >+template<typename XprType, int BlockRows0, int BlockCols0, bool InnerPanel0, int BlockRows, int BlockCols, bool InnerPanel> >+class Block<const Block<XprType, BlockRows0, BlockCols0, InnerPanel0>, BlockRows, BlockCols, InnerPanel> >+ : public Block<const XprType,BlockRows,BlockCols,InnerPanel && InnerPanel0> >+{ >+ typedef Block<XprType, BlockRows0, BlockCols0, InnerPanel0> ArgType; >+ typedef Block<const XprType,BlockRows,BlockCols,InnerPanel && InnerPanel0> Base; >+public: >+ using Base::operator=; >+ >+ /** Column or Row constructor >+ */ >+ EIGEN_DEVICE_FUNC >+ inline Block(const ArgType &blk, Index i) >+ : Base(blk.nestedExpression(), >+ blk.startRow() + ((BlockRows==1) && (BlockCols==ArgType::ColsAtCompileTime) ? i : 0), >+ blk.startCol() + ((BlockRows==ArgType::RowsAtCompileTime) && (BlockCols==1) ? i : 0), >+ BlockRows==1 ? 1 : blk.rows(), >+ BlockCols==1 ? 1 : blk.cols() >+ ) >+ { >+ eigen_assert( (i>=0) && ( >+ ((BlockRows==1) && (BlockCols==ArgType::ColsAtCompileTime) && i<blk.rows()) >+ ||((BlockRows==ArgType::RowsAtCompileTime) && (BlockCols==1) && i<blk.cols()))); >+ } >+ >+ /** Fixed-size constructor >+ */ >+ EIGEN_DEVICE_FUNC >+ inline Block(const ArgType &blk, Index startRow, Index startCol) >+ : Base(blk.nestedExpression(), >+ blk.startRow() + startRow, >+ blk.startCol() + startCol) >+ { >+ EIGEN_STATIC_ASSERT(Base::RowsAtCompileTime!=Dynamic && Base::ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE) >+ eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= blk.rows() >+ && startCol >= 0 && BlockCols >= 0 && startCol + BlockCols <= blk.cols()); >+ } >+ >+ /** Dynamic-size constructor >+ */ >+ EIGEN_DEVICE_FUNC >+ inline Block(const ArgType &blk, Index startRow, Index startCol, Index blockRows, Index blockCols) >+ : Base(blk.nestedExpression(), blk.startRow() + startRow, blk.startCol() + startCol, blockRows, blockCols) >+ { >+ eigen_assert((Base::RowsAtCompileTime==Dynamic || Base::RowsAtCompileTime==blockRows) >+ && (Base::ColsAtCompileTime==Dynamic || Base::ColsAtCompileTime==blockCols)); >+ eigen_assert(startRow >= 0 && blockRows >= 0 && startRow <= blk.rows() - blockRows >+ && startCol >= 0 && blockCols >= 0 && startCol <= blk.cols() - blockCols); >+ } >+}; >+ >+// The generic default implementation for dense block simply forward to the internal::BlockImpl_dense > // that must be specialized for direct and non-direct access... > template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> > class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense> > : public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> > { > typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl; > typedef typename XprType::StorageIndex StorageIndex; > public: >diff --git a/test/block.cpp b/test/block.cpp >--- a/test/block.cpp >+++ b/test/block.cpp >@@ -178,16 +178,118 @@ template<typename MatrixType> void block > VERIFY_IS_EQUAL(dv, dm); > dm.setZero(); > dv.setZero(); > dm = m1.row(r1).segment(c1,c2-c1+1).transpose(); > dv = m1.transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0); > VERIFY_IS_EQUAL(dv, dm); > } > >+template<typename T> >+bool same_type(const T&, const T&) { return true; } >+ >+template<typename Expr, typename Ref, typename ExprFused> >+void checkbb(const DenseBase<Expr> &a_xpr, const DenseBase<Ref> &a_ref, const DenseBase<ExprFused> &a_xprfused) >+{ >+ const Expr& xpr(a_xpr.derived()); >+ const Ref& ref(a_ref.derived()); >+ const ExprFused& xprfused(a_xprfused.derived()); >+ >+ VERIFY_IS_APPROX(xprfused, ref); >+ >+ VERIFY(same_type<ExprFused>(xpr, xprfused)); >+ >+ VERIFY_IS_EQUAL(ExprFused::Flags, Expr::Flags); >+ VERIFY_IS_EQUAL(ExprFused::RowsAtCompileTime, Expr::RowsAtCompileTime); >+ VERIFY_IS_EQUAL(ExprFused::ColsAtCompileTime, Expr::ColsAtCompileTime); >+ >+ typedef internal::evaluator<ExprFused> EvalFused; >+ typedef internal::evaluator<Expr> EvalExpr; >+ VERIFY_IS_EQUAL(EvalFused::Flags, EvalExpr::Flags); >+ VERIFY_IS_EQUAL(EvalFused::Alignment, EvalExpr::Alignment); >+ >+ VERIFY_IS_APPROX(xpr.derived(), ref); >+ VERIFY_IS_APPROX(xpr, ref); >+} >+ >+template<typename MatrixType> >+void check_block_block_fusion(const MatrixType &m) >+{ >+ Index rows = m.rows(); >+ Index cols = m.cols(); >+ >+ MatrixType m1 = MatrixType::Random(rows, cols), >+ m2 = MatrixType::Random(rows, cols); >+ >+ Index r1 = internal::random<Index>(0,rows-1); >+ Index c1 = internal::random<Index>(0,cols-1); >+ Index nr1 = internal::random<Index>(1,rows-r1); >+ Index nc1 = internal::random<Index>(1,cols-c1); >+ >+ Index r2 = internal::random<Index>(0,nr1-1); >+ Index c2 = internal::random<Index>(0,nc1-1); >+ Index nr2 = internal::random<Index>(1,nr1-r2); >+ Index nc2 = internal::random<Index>(1,nc1-c2); >+ >+ CALL_SUBTEST( checkbb(m1.block(r1,c1, nr1,nc1).block(r2,c2,nr2,nc2), >+ m1.block(r1,c1, nr1,nc1).eval().block(r2,c2,nr2,nc2).eval(), >+ m1.block(r1+r2, c1+c2, nr2, nc2)) ); >+ CALL_SUBTEST( checkbb((m1+m2).block(r1,c1, nr1,nc1).block(r2,c2,nr2,nc2), >+ (m1+m2).block(r1,c1, nr1,nc1).eval().block(r2,c2,nr2,nc2).eval(), >+ (m1+m2).block(r1+r2, c1+c2, nr2, nc2)) ); >+ >+ CALL_SUBTEST( checkbb(m1.block(r1,c1, nr1,nc1).row(r2), >+ m1.block(r1,c1, nr1,nc1).eval().row(r2).eval(), >+ m1.template block<1,Dynamic>(r1+r2, c1, 1, nc1)) ); >+ CALL_SUBTEST( checkbb((m1+m2).block(r1,c1, nr1,nc1).row(r2), >+ (m1+m2).block(r1,c1, nr1,nc1).eval().row(r2).eval(), >+ (m1+m2).template block<1,Dynamic>(r1+r2, c1, 1, nc1)) ); >+ >+ CALL_SUBTEST( checkbb(m1.block(r1,c1, nr1,nc1).col(c2), >+ m1.block(r1,c1, nr1,nc1).eval().col(c2).eval(), >+ m1.template block<Dynamic,1>(r1, c1+c2, nr1, 1)) ); >+ CALL_SUBTEST( checkbb((m1+m2).block(r1,c1, nr1,nc1).col(c2), >+ (m1+m2).block(r1,c1, nr1,nc1).eval().col(c2).eval(), >+ (m1+m2).template block<Dynamic,1>(r1, c1+c2, nr1, 1)) ); >+ >+ CALL_SUBTEST( checkbb(m1.row(r1).segment(c1,nc1), >+ m1.row(r1).eval().segment(c1,nc1).eval(), >+ m1.template block<1,Dynamic>(r1, c1, 1, nc1)) ); >+ CALL_SUBTEST( checkbb((m1+m2).row(r1).segment(c1,nc1), >+ (m1+m2).row(r1).eval().segment(c1,nc1).eval(), >+ (m1+m2).template block<1,Dynamic>(r1, c1, 1, nc1)) ); >+ >+ CALL_SUBTEST( checkbb(m1.col(c1).segment(r1,nr1), >+ m1.col(c1).eval().segment(r1,nr1).eval(), >+ m1.template block<Dynamic,1>(r1, c1, nr1, 1)) ); >+ CALL_SUBTEST( checkbb((m1+m2).col(c1).segment(r1,nr1), >+ (m1+m2).col(c1).eval().segment(r1,nr1).eval(), >+ (m1+m2).template block<Dynamic,1>(r1, c1, nr1, 1)) ); >+ >+ CALL_SUBTEST( checkbb(m1.middleCols(c1,nc1).col(c2).segment(r1,nr1), >+ m1.middleCols(c1,nc1).eval().col(c2).eval().segment(r1,nr1).eval(), >+ m1.template block<Dynamic,1>(r1, c1+c2, nr1, 1)) ); >+ CALL_SUBTEST( checkbb((m1+m2).middleCols(c1,nc1).col(c2).segment(r1,nr1), >+ (m1+m2).middleCols(c1,nc1).eval().col(c2).eval().segment(r1,nr1).eval(), >+ (m1+m2).template block<Dynamic,1>(r1, c1+c2, nr1, 1)) ); >+ >+ CALL_SUBTEST( checkbb(m1.row(r1).col(c1), >+ m1.row(r1).eval().col(c1).eval(), >+ m1.template block<1,1>(r1, c1)) ); >+ CALL_SUBTEST( checkbb((m1+m2).row(r1).col(c1), >+ (m1+m2).row(r1).eval().col(c1).eval(), >+ (m1+m2).template block<1,1>(r1, c1)) ); >+ >+ CALL_SUBTEST( checkbb(m1.row(r1).col(c1).segment(0,1), >+ m1.row(r1).eval().col(c1).eval().segment(0,1).eval(), >+ m1.template block<Dynamic,1>(r1, c1, 1,1)) ); >+ CALL_SUBTEST( checkbb((m1+m2).row(r1).col(c1).segment(0,1), >+ (m1+m2).row(r1).eval().col(c1).eval().segment(0,1).eval(), >+ (m1+m2).template block<Dynamic,1>(r1, c1, 1,1)) ); >+} > > template<typename MatrixType> > void compare_using_data_and_stride(const MatrixType& m) > { > typedef typename MatrixType::Index Index; > Index rows = m.rows(); > Index cols = m.cols(); > Index size = m.size(); >@@ -246,14 +348,23 @@ void test_block() > CALL_SUBTEST_2( block(Matrix4d()) ); > CALL_SUBTEST_3( block(MatrixXcf(3, 3)) ); > CALL_SUBTEST_4( block(MatrixXi(8, 12)) ); > CALL_SUBTEST_5( block(MatrixXcd(20, 20)) ); > CALL_SUBTEST_6( block(MatrixXf(20, 20)) ); > > CALL_SUBTEST_8( block(Matrix<float,Dynamic,4>(3, 4)) ); > >+ CALL_SUBTEST_9( check_block_block_fusion(MatrixXi(internal::random(1,50), internal::random(1,50))) ); >+ CALL_SUBTEST_9( check_block_block_fusion(Matrix4i()) ); >+ CALL_SUBTEST_9( check_block_block_fusion(Matrix3i()) ); >+ >+ CALL_SUBTEST_9( check_block_block_fusion(MatrixXd(internal::random(1,50), internal::random(1,50))) ); >+ CALL_SUBTEST_9( check_block_block_fusion(Matrix4d()) ); >+ CALL_SUBTEST_9( check_block_block_fusion(Matrix3d()) ); >+ CALL_SUBTEST_9( check_block_block_fusion(Matrix2d()) ); >+ > #ifndef EIGEN_DEFAULT_TO_ROW_MAJOR > CALL_SUBTEST_6( data_and_stride(MatrixXf(internal::random(5,50), internal::random(5,50))) ); > CALL_SUBTEST_7( data_and_stride(Matrix<int,Dynamic,Dynamic,RowMajor>(internal::random(5,50), internal::random(5,50))) ); > #endif > } > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 408
:
655
|
660
|
664