This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Assert in lazyAssign

Tags: None
(comma "," separated)
ilysenkov
Registered Member
Posts
2
Karma
0
OS

Assert in lazyAssign

Fri Jul 09, 2010 7:28 am
Hi there!

I have a very simple piece of code:

Code: Select all
#include <Eigen/Core>
#include <stdio.h>
using namespace Eigen;

int main()
{
    Matrix<float, Dynamic, Dynamic> mat1( 10, 1000 );
    Matrix<float, Dynamic, Dynamic> mat2( 32, 1000 );

    Matrix<float, Dynamic, Dynamic> result = mat1.row(2)*mat2.transpose();
    printf("Size: %d x %d\n", result.rows(), result.cols() );

    Matrix<float, 1, Dynamic> result2 = mat1.row(2)*mat2.transpose();
    printf("Size: %d x %d\n", result2.rows(), result2.cols() );

    Matrix<float, Dynamic, Dynamic> result3 = mat1.row(2);
    result3 = result3*mat2.transpose();
    printf("Size: %d x %d\n", result3.rows(), result3.cols() );

    return 0;
}


But I have an assert in lazyAssign due to evaluation of first result matrix:

Code: Select all
eigen/Eigen/src/Core/Assign.h:431: Derived& Eigen::MatrixBase<Derived>::lazyAssign(const Eigen::MatrixBase<OtherDerived>&) [with OtherDerived = Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000>, Derived = Eigen::Map<Eigen::Matrix<float, 10000, 1, 0, 10000, 1>, 1>]: Assertion `rows() == other.rows() && cols() == other.cols()' failed.
Aborted


If I compile with -DEIGEN_NO_DEBUG option I have unexpected output:
Code: Select all
Size: 32 x 1
Size: 1 x 32
Size: 1 x 32


So why I can't just write Matrix<float, Dynamic, Dynamic> result = mat1.row(2)*mat2.transpose(); ?

P.S. I have Ubuntu 9.10 x86_64, gcc 4.4.1 and Eigen 2.0.14.
jitseniesen
Registered Member
Posts
204
Karma
2

Re: Assert in lazyAssign

Fri Jul 09, 2010 9:02 am
I don't yet know what's going on here. But I can reproduce it with gcc 4.3 and I can't see anything wrong with the code, so it does seem to be a bug in Eigen. The code seems to work fine with gcc 4.1. It appears possible to work around the bug with gcc 4.3 by replacing the line
Code: Select all
Matrix<float, Dynamic, Dynamic> result = mat1.row(2)*mat2.transpose();

by
Code: Select all
Matrix<float, Dynamic, Dynamic> result;
result = mat1.row(2)*mat2.transpose();


Most worryingly for Eigen, the code written by OP does not compile with the current development version; it hits the static assertion YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX in MapBase.h:162 .
User avatar
bjacob
Registered Member
Posts
658
Karma
3

Re: Assert in lazyAssign

Fri Jul 09, 2010 5:20 pm
Uh oh. Looks like we have some big fish to fry today :)


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
User avatar
bjacob
Registered Member
Posts
658
Karma
3

Re: Assert in lazyAssign

Fri Jul 09, 2010 5:37 pm
I can reproduce the bug with gcc 4.4. The reason why GCC 4.1 works is that it's vectorization-related. Indeed, with -DEIGEN_DONT_VECTORIZE it works.


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
User avatar
bjacob
Registered Member
Posts
658
Karma
3

Re: Assert in lazyAssign

Fri Jul 09, 2010 5:41 pm
The bug is twofold.

1) as you can see from the assert message, the rhs is a Dynamic x Dynamic matrix. It should be a row-vector (1 x Dynamic).

2) the left-hand side is initialized with size 32x1 whereas the right hand side has size 1x32. Since moreover the right-hand side is not a vector expression (see point 1), no transposing happens, leading to the size mismatch assertion failure.


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
User avatar
bjacob
Registered Member
Posts
658
Karma
3

Re: Assert in lazyAssign

Fri Jul 09, 2010 6:06 pm
Nevermind point 1), I'm stupid, you _are_ assigning that to a matrix. So at least the bug is not twofold :)


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
User avatar
bjacob
Registered Member
Posts
658
Karma
3

Re: Assert in lazyAssign

Fri Jul 09, 2010 6:22 pm
The bug is actually something internal to the product code. The mismatched size is on a Map, which is created internally in the product code. See backtrace:

Code: Select all
(gdb) bt
#0  0x000000381e0329c5 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x000000381e0341a5 in abort () at abort.c:92
#2  0x000000381e02b945 in __assert_fail (assertion=0x405e78 "rows() == other.rows() && cols() == other.cols()", file=<value optimized out>, line=435, function=<value optimized out>)
    at assert.c:81
#3  0x0000000000404f56 in Eigen::MatrixBase<Eigen::Map<Eigen::Matrix<float, 10000, 1, 0, 10000, 1>, 1> >::lazyAssign<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000> > (
    this=0x7fffffffdd10, other=...) at eigen2.0/Eigen/src/Core/Assign.h:435
#4  0x000000000040496d in Eigen::ei_assign_selector<Eigen::Map<Eigen::Matrix<float, 10000, 1, 0, 10000, 1>, 1>, Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000>, false, false>::run
    (dst=..., other=...) at eigen2.0/Eigen/src/Core/Assign.h:451
#5  0x0000000000404538 in Eigen::MatrixBase<Eigen::Map<Eigen::Matrix<float, 10000, 1, 0, 10000, 1>, 1> >::operator=<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000> > (
    this=0x7fffffffdd10, other=...) at eigen2.0/Eigen/src/Core/Assign.h:475
#6  0x0000000000403ef3 in Eigen::MapBase<Eigen::Map<Eigen::Matrix<float, 10000, 1, 0, 10000, 1>, 1> >::operator=<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000> > (
    this=0x7fffffffdd10, other=...) at eigen2.0/Eigen/src/Core/MapBase.h:177
#7  0x0000000000403be0 in Eigen::Map<Eigen::Matrix<float, 10000, 1, 0, 10000, 1>, 1>::operator=<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000> > (this=0x7fffffffdd10, other=...)
    at eigen2.0/Eigen/src/Core/Map.h:95
#8  0x00000000004037dc in Eigen::ei_cache_friendly_product_selector<Eigen::Product<Eigen::Block<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000>, 1, 10000, 1, 32> const&, Eigen::Transpose<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000> > const&, 1>, 1, 0, 32, 10000, 1, 32>::run<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000> > (res=..., product=...)
    at eigen2.0/Eigen/src/Core/Product.h:617
#9  0x000000000040363c in Eigen::MatrixBase<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000> >::lazyAssign<Eigen::Block<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000>, 1, 10000, 1, 32> const&, Eigen::Transpose<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000> > const&> (this=0x7fffffffde80, product=...) at eigen2.0/Eigen/src/Core/Product.h:732
#10 0x00000000004034fa in Eigen::MatrixBase<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000> >::lazyAssign<Eigen::Product<Eigen::Block<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000>, 1, 10000, 1, 32> const&, Eigen::Transpose<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000> > const&, 1> > (this=0x7fffffffde80, other=...)
    at eigen2.0/Eigen/src/Core/MatrixBase.h:246
#11 0x00000000004033a0 in Eigen::ei_assign_selector<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000>, Eigen::Flagged<Eigen::Product<Eigen::Block<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000>, 1, 10000, 1, 32> const&, Eigen::Transpose<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000> > const&, 1>, 0u, 6u>, false, false>::run (dst=..., other=...)
    at eigen2.0/Eigen/src/Core/Assign.h:451
#12 0x00000000004030eb in Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000>::_set_noalias<Eigen::Flagged<Eigen::Product<Eigen::Block<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000>, 1, 10000, 1, 32> const&, Eigen::Transpose<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000> > const&, 1>, 0u, 6u> > (this=0x7fffffffde80, other=...)
    at eigen2.0/Eigen/src/Core/Matrix.h:566
#13 0x0000000000402c45 in Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000>::Matrix<Eigen::Flagged<Eigen::Product<Eigen::Block<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000>, 1, 10000, 1, 32> const&, Eigen::Transpose<Eigen::Matrix<float, 10000, 10000, 2, 10000, 10000> > const&, 1>, 0u, 6u> > (this=0x7fffffffde80, other=...)
    at eigen2.0/Eigen/src/Core/Matrix.h:409
#14 0x0000000000400e39 in main () at fun.cpp:14


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: Assert in lazyAssign

Fri Jul 09, 2010 6:50 pm
thanks to all, bug fixed in the 2.0 branch.

For the devel branch I added a unit test which fails to compile. I'll fix later when updating the matrix-vector product because I don't want to do the work twice.... (moving from [] to .coeff() to [] again... don't follow me ? nevermind ;) )
User avatar
bjacob
Registered Member
Posts
658
Karma
3

Re: Assert in lazyAssign

Fri Jul 09, 2010 9:04 pm
ilysenkov: are you (is your company) OK to use the 2.0 branch off hg for now? Or do you need (for a concrete reason) us to release 2.0.15 soon?


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
ilysenkov
Registered Member
Posts
2
Karma
0
OS

Re: Assert in lazyAssign

Sat Jul 10, 2010 9:05 am
Thanks for very quick response and fix!

bjacob: We are developing OpenCV library and using Eigen to speed up matrix multiplication if Eigen is installed on user's computer. We can't assume users will have latest version of Eigen with this bug fixed. So I just rewrote my code to sidestep this bug and we don't need new release.

Thanks again for your help!
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: Assert in lazyAssign

Sat Jul 10, 2010 9:06 pm
for the record this is also fixed in the devel branch


Bookmarks



Who is online

Registered users: Bing [Bot], Google [Bot], Sogou [Bot]