Re: [eigen] Eigen Types as Parameters for Functions

[ Thread Index | Date Index | More Archives ]

On Wed, Jun 27, 2012 at 3:16 PM, Christoph Hertzberg
<chtz@xxxxxxxxxxxxxxxxxxxxxxxx> wrote:
> On 27.06.2012 14:41, Gael Guennebaud wrote:
>> The current implementation is only a first draft which clearly needs
>> some improvements.
>> On Wed, Jun 27, 2012 at 11:14 AM, Christoph Hertzberg
>> <chtz@xxxxxxxxxxxxxxxxxxxxxxxx> wrote:
>>> some questions/notes:
>>> * Does A.row(3); change after calling foo1(A.row(3))? (i.e. is it
>>>  copied back?) -- you could simply copy it back in the destructor, if
>>>  match_helper<Derived>::type() is false_type.
>>>  If you think back-copying causes too much performance penalty, you
>>>  need to forbid this.
>>>  Furthermore, it sometimes might be useful to mark Ref as a pure
>>>  "out-ref" in this case, saving the copy from A.row() to m_object.
>> That's a very good remark, and currently I don't have a strong opinion
>> whether we should copy-back or forbid it. The copy-back option is ok
>> when Ref is used for function arguments and in sequential algorithms,
>> but very dangerous in all other cases. For instance, I was thinking
>> about Ref<> inside Eigen itself to reduce template instantiations. In
>> this case you clearly don't want the copy-back approach.
>>  On the other hand, I known it would be very convenient for many
>> users. Proposing both might be overkill.
> Naturally, you would never copy back a Ref<const ...> (which I guess is your
> usual internal use-case?).

Of course this only concerns the non const version.

> I just noted that, unfortunately, the copy-back will not be as simple to
> implement as I thought, because you don't have the type of Derived available
> in the destructor.

Maybe Ref<> could store the address of a copy back function
"generated" through templates by the compiler. This copy-back function
would start by doing a void* to Derived* reinterpret_cast and then
does the job. Sounds a bit complicated though.

> In my current approach [1] (limited to non-strided vectors) I do not allow
> copy-backs, and I currently need to pass expression.eval(), if expression
> itself is not a direct-access expression -- saving the m_object member at
> the cost of less elegant code in this case.
> [1]

Sure, enforcing users to explicitly call eval() solves a lot of
problems for us (including the one below), but is more painful for the

>>> * If you pass, for example, a Ref<Vector4d>, don't you have a Vector4d
>>>  (the m_object member) lying on the stack then? That might cause
>>>  alignment issues if the stack is not aligned (I did not test it yet).
>> I don't think that's a problem because if the compiler does not know
>> how to align the stack then we cannot use aligned objects at all, not
>> only inside Ref<>.
> I thought, this was a different thing for function arguments, because there
> is usually no padding between function parameters:

You are right, for instance for MSVC:

> Wouldn't it be possible to pass a const Ref<>& instead of passing Ref by
> value? You could make all assignment functions of Ref be const w/o losing
> const-correctness, as they would not modify Ref itself, but the referenced
> object (which itself has an optional const-modifier).
> A draw-back of this solution is that another stage of dereferencing is
> required.

That's the solution I wanted to suggest. I proposed to pass the Ref<>
objects by value mostly because it looks better for writable
arguments. Having a "const Ref<VectorXf>&" writable is a bit
dangerous. But if we agree that copy-back is a no go, then the
internal m_object will exists only for const version so one could pass
by a const reference for const arguments, and by value for writable


> Christoph
> --
> ----------------------------------------------
> Dipl.-Inf. Christoph Hertzberg
> Cartesium 0.049
> Universität Bremen
> Enrique-Schmidt-Straße 5
> 28359 Bremen
> Tel: +49 (421) 218-64252
> ----------------------------------------------

Mail converted by MHonArc 2.6.19+