matrix - Large block coefficient-wise multiplication fails in Eigen library C++ -
i've read through lot of documentation, if find i've missed can explain away issue i'll pleased. background, i'm compiling on x86 windows 10 in visual studio 2015 using 3.2.7 eigen library. 3.2.7 version may , while there have been releases since then, haven't seen in changelog indicate issue has been solved.
the issue seems appear matrices above size. don't know if byproduct of specific system or inherent eigen.
the following code produces access violation in both debug , release mode.
int mx1rows = 255, cols = 254; {//this has access violation @ assignment of mx2 eigen::matrixxd mx1(mx1rows, cols); eigen::matrixxd mx2(mx1rows + 1, cols); eigen::block<eigen::matrixxd, -1, -1, false> temp = mx2.toprows(mx1rows); mx2 = temp.array() * mx1.array();//error }
i believe assignment of coefficient-wise multiplication safe since result should aliased.
this issue becomes interesting when mx1rows reduced value 254, access violation doesn't appear. that's correct, mx2 dimensions of 256 254 produce problem dimensions 255 254 don't. if increase column size can access violation, problem has total number of entries. issue appears if mx1 , mx2 filled values, having filled matrixes not necessary reproduce issue.
similar code not assign toprows() block temp not produce access violation in release mode. believe there more since identified issue in code considerably more complex , appeared after number of loops (the matrix sizes consistent between loops). there going on in code haven't been able isolate conditions under access violation appears after number of loops.
what curious know is
1) using eigen in wrong way?
2) able reproduce issue? (what environment particulars?)
3) bug in eigen library?
it's easy enough work around problem assigning block temporary matrix instead of block, if inefficient, i'm not interested in hearing that.
the problem temp
references coefficients held mx2
, in last assignment, mx2
first resized before expression gets evaluated. therefore, during actual evaluation of expression, temp
references garbage. more precisely, here generated (in simplified manner):
double* temp_data = mx2.data; free(mx2.data); mx2.data = malloc(sizeof(double)*mx1rows*cols); for(j=0;j<cols;++j) for(i=0;i<mx1rows;++i) mx2(i,j) = temp_data[i+j*(mw1rows+1)] * mx1(i,j);
this called aliasing issue.
you can workaround evaluating expression in temporary:
mx2 = (temp.array() * mx1.array()).eval();
another solution copy mx2.toprows(.)
true matrixxd
holding own memory:
matrixxd temp = mx2.toprows(mx1rows); mx2 = temp.array() * mx1.array();
yet solution evaluate temp
, resize afterward:
block<matrixxd, -1, -1, false> temp = mx2.toprows(mx1rows); temp = temp.array() * mx1.array(); mx2.conservativeresize(mx1rows,cols);
Comments
Post a Comment