Re: [proto] Using proto with expressions containing matrices from the EIgen library

2010-11-18 Thread Eric Niebler
On 11/18/2010 9:28 AM, Bart Janssens wrote:
> On Thu, Oct 28, 2010 at 7:47 AM, Eric Niebler  wrote:
>> You should be asking yourself why you're trying to return expression
>> templates from a function. If you really need to do that, then you can't
>> go returning references to temporary objects.
> 
> Hi guys,
> 
> Just wanted to provide some closure to the subject, the Eigen
> developers provided me with a workaround that allows to store
> expression template operands by value instead of by reference, and
> they in fact opened a bug to better support the use case I brought up
> at:
> http://eigen.tuxfamily.org/bz/show_bug.cgi?id=99

Thanks for the update. That bug report is an interesting read. I
remember going through the same deliberations 5 years ago when I first
wrote Proto. And then again with Joel and Hartmut when Sprit2 moved to
Proto. (Remember the whole "flattening" argument?) They've come to
realize that they shouldn't be doing any fancy computation during ET
construction, and use separate "evaluators". But they seem to be
conflating node storage with expression evaluation, which are orthogonal
issues. (I may have simply misunderstood their design discussion.) They
also need something like Proto's expression extension mechanism, so that
their expression tree objects can still have the direct ceoff access
syntax they need.

Anyway, I'm very glad we don't have these problems anymore with Proto.

> Eric,
> 
> I am also following your suggestion to use transforms, since right now
> I'm mixing proto::eval and some transforms, but as I finally
> understand transforms a little better, it seems they can simplify my
> code quite a lot in this case.

Glad to hear it. I'm considering going through the docs and examples and
yanking most references to contexts and proto::eval. Transforms seem are
harder at first, but in the end they're really much simpler.

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] Using proto with expressions containing matrices from the EIgen library

2010-11-18 Thread Bart Janssens
On Thu, Oct 28, 2010 at 7:47 AM, Eric Niebler  wrote:
> You should be asking yourself why you're trying to return expression
> templates from a function. If you really need to do that, then you can't
> go returning references to temporary objects.

Hi guys,

Just wanted to provide some closure to the subject, the Eigen
developers provided me with a workaround that allows to store
expression template operands by value instead of by reference, and
they in fact opened a bug to better support the use case I brought up
at:
http://eigen.tuxfamily.org/bz/show_bug.cgi?id=99

Eric,

I am also following your suggestion to use transforms, since right now
I'm mixing proto::eval and some transforms, but as I finally
understand transforms a little better, it seems they can simplify my
code quite a lot in this case.

Cheers,

-- 
Bart
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] Using proto with expressions containing matrices from the EIgen library

2010-10-27 Thread Eric Niebler
On 10/27/2010 12:57 PM, Bart Janssens wrote:
> So to rephrase my question:
> let's say I want to evaluate proto expression "_cout << A * B * C". To
> do this, I traverse the tree and the following should happen:
>   1. B * C gets evaluated first, into an (Eigen) expression template
> that stores a reference to B and C. This is OK, since B and C are not
> temporaries.

Yes.

>   2. A*(result of B*C) gets evaluated, which may produce something
> that stores (result of B*C) by reference

Yes.

>   3. The final expression result is output using <<, and at that point
> the Eigen expression templates execute, expecting that all the
> referred variables still exist.

Yes. And they do because all the temporary objects that have been
created live until the end of the full expression, which includes the
output expression.

> So how can I make sure the (result of B*C) gets stored somewhere? 

(result of B*C) is a temporary object (X) that holds B and C by
reference. A*(B*C) is a temporary object (Y) that holds the temporary
object (X) by reference. This is all kosher. However, that's not what
your example was doing. Your example was RETURNING the equivalent of
A*(B*C) from a function. NOT GOOD. The temporary object (X) dies at the
end of the full expression in which it was created. That's the return
statement. By the time you try to traverse the expression to evaluate
it, (X) is dead and buried.

> If I
> can do that, then I can use this stored data to construct the
> A*(result of B*C) step, and it's safe even if it is done by reference.

You should be asking yourself why you're trying to return expression
templates from a function. If you really need to do that, then you can't
go returning references to temporary objects.

> For more complex expressions, all the steps in the tree would need to
> be stored like this. Once the call to operator<< finishes, this
> "temporary tree" can be discarded.
> 
> The problem I have here appears to be general to expression template
> matrix libraries, before Eigen we used our own matrix lib, and it
> exhibited the same problem.

Right. This problem has nothing at all to do with Proto.

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] Using proto with expressions containing matrices from the EIgen library

2010-10-27 Thread Bart Janssens
On Wed, Oct 27, 2010 at 6:57 PM, Eric Niebler  wrote:
> Are you saying that proto::eval is generating temporary matrices? I
> don't understand why, but there's always a way to get Proto to store
> intermediate nodes by value instead of by reference. Without knowing
> what you're doing, I can't say more.

No, but the return value of the operator() in the eval structs in the
context (in my first attempt) or the object created by the object
transform is sometimes stored by reference in the Eigen expression
templates. I'll give more details on what exactly I need below, based
on the sample I posted to the Eigen forum.

> Can ContextEvaluator ever return a reference to a temporary object? Is
No, never.

> Eigen::ProductReturnType::Type ever a reference? Does that
> type hold Left and Right by reference?
Yes, sometimes, and that is exactly the problem :) It deduces the need
for by-reference storage if it would otherwise need to do an expensive
copy, so it is crucial that this system can do its job in order to
preserve the performance of Eigen.

> Looking at that code, I strongly suspect that
> Eigen::ProductReturnType::Type is a type that holds Right
> by reference. In fact, I'm 99% sure it does. Print the name of the
> resulting type of Eigen::ProductReturnType::Type and see if
> that's the case. If so, you've found your bug. Can you see why?

Yup, it took me a while to figure out, but the purpose of the sample I
posted to Eigen is indeed to show this: the result of multb is stored
by reference in the result of multa, and this only gets evaluated on
the call to operator<<, so it tries to access a dangling reference to
the multb result which disappeared. In proto, multb becomes operator()
of an eval struct in a context, or the object constructed using an
object transform.

So to rephrase my question:
let's say I want to evaluate proto expression "_cout << A * B * C". To
do this, I traverse the tree and the following should happen:
  1. B * C gets evaluated first, into an (Eigen) expression template
that stores a reference to B and C. This is OK, since B and C are not
temporaries.
  2. A*(result of B*C) gets evaluated, which may produce something
that stores (result of B*C) by reference
  3. The final expression result is output using <<, and at that point
the Eigen expression templates execute, expecting that all the
referred variables still exist.

So how can I make sure the (result of B*C) gets stored somewhere? If I
can do that, then I can use this stored data to construct the
A*(result of B*C) step, and it's safe even if it is done by reference.
For more complex expressions, all the steps in the tree would need to
be stored like this. Once the call to operator<< finishes, this
"temporary tree" can be discarded.

The problem I have here appears to be general to expression template
matrix libraries, before Eigen we used our own matrix lib, and it
exhibited the same problem.

Kind regards,

-- 
Bart
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] Using proto with expressions containing matrices from the EIgen library

2010-10-27 Thread Joel Falcou

That's a tough one :/
Main problem is probably the fact you can't control when/Where eigen do 
his bidding.


Best shot is to externally make eigen temporary proto terminals, write a 
grammar that disable operators onthem and then write a transform dealing 
with the composite E.T AST.

___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto