Re: [eigen] resizing in ReturnByValue assignment |
[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]
On 03/08/2010 09:56 AM, Benoit Jacob wrote:
2010/3/8 Mark Borgerding<mark@xxxxxxxxxxxxxx>:My concern is that there is no value added by the initial resize. At best it is a NOOP. At worst, it is a silent performance killer when resizes don't match exactly. In the case of Inverse FFTs, the size of the output depend on the TYPE of output requested. This is NOT available during the construction of the proxy object. It is not available until the evalTo is called.Strange. We didn't design ReturnByValue for this use case. So your problem is deeper: you can't, then, implement rows()/cols() in the ReturnByValue-derived class. This means that, calling foo() your function returning a ReturnByValue object, you can't support general arithmetic expressions like some_matrix + foo() as that would require foo() to evaluate into a temporary matrix, but it can't know its size (or that would be far too complex logic to determine in general from the expression it is being nested into).
Now I see the need for the rows,cols in nested expressions. This need is not evident in the simple case
some_matrix = foo(); but some_matrix = foo()*42; is nested and requires more knowledge.Actually, the limitation goes well beyond not knowing the size. The ReturnByValue needs to know the type of temporary to be created first (by ReturnType typedef).
This knowledge can be provided by casting to a temporary (see example code below), but that is not a perfect solution either, since it requires actual allocation of a temporary, rather than a chainable placeholder.
// pre-example code VectorXf real1,real2; VectorXcf cpx1; real1.setRandom(len); FFT<float> fft; fft.SetFlag( fft.HalfSpectrum ); fft.fwd(cpx1,real1); // EXAMPLE CODEfft.inv(real2,cpx1); // #1 original style calling convention, destination is first arg real2 = fft.inv(cpx1); // #2 this succeeds, but has an extra resize in DenseStorageBase::operator= real2 = fft.inv(cpx1)*42; // #3 this fails to compile -- cannot infer result type real2 = VectorXf(fft.inv(cpx1))*42; // #4 this succeeds, but has extra resize from #2 plus a heavyweight temporary object
The fact that #3 does not work and #4 is not efficient does not detract from how much prettier #2 is compared with #1. I very much like the style of ReturnByValue. I refuse to give up on it yet for Eigen::FFT.
Option 1.Is there a proxy matrix type that would allow one to explicitly name the type of matrix expected, but defer its actual creation until later?
Option 2.Alternately, I propose a companion, simpler, ReturnByValue class that retains most of the syntactic benefits of the ReturnByValue , but cannot be nested in an expression (unless explicitly casted). Perhaps a specialization of ReturnByValue would provide the simpler proxy I need.
-- Mark
Mail converted by MHonArc 2.6.19+ | http://listengine.tuxfamily.org/ |