Re: [proto] Precomputing common matrix products in an expression

2012-07-15 Thread Eric Niebler
On 7/14/2012 11:07 PM, Mathias Gaunard wrote:
> On 07/15/2012 08:04 AM, Mathias Gaunard wrote:
> 
>> Assuming your expressions are CopyConstructible

For the record, in proto-11 no rvalues are stored by reference within
expressions by default.

> You'd also need them to be EqualityComparable or to use a comparator to
> use them as keys. A recursive call to fusion::equal_to would probably be
> a good definition.

That wouldn't check the tag type. But as Bart says, this is unnecessary
in his case.

In proto-11, expressions currently satisfy EqualityComparable.
operator== builds an expression node that has an implicit conversion to
bool IFF the left and right operands are compatible. Likewise for the
other relational operators. This is admittedly a kludge and I'm not sure
how I feel about it.

-- 
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] Precomputing common matrix products in an expression

2012-07-15 Thread Mathias Gaunard

On 07/15/2012 10:25 AM, Bart Janssens wrote:


OK, thanks for the comments. It's similar to what I had in mind, but
(unless I'm missing something) all product terms in our expressions
should have a distinct type if they represent different values, so I
could get away with just using a fusion map and avoid the copying and
even the map lookup.


In which case, you can replace the std::map by a 
boost::optional.

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


Re: [proto] Precomputing common matrix products in an expression

2012-07-15 Thread Bart Janssens
On Sun, Jul 15, 2012 at 8:04 AM, Mathias Gaunard
 wrote:
> Of course Proto expressions are not safely CopyConstructible by default, so
> you'd have to be careful to make it work.
>
> This is a global approach, so you'll end up committing to memory all your
> past results. This is probably not desirable so you might prefer storing the
> map in the state instead of a singleton.

OK, thanks for the comments. It's similar to what I had in mind, but
(unless I'm missing something) all product terms in our expressions
should have a distinct type if they represent different values, so I
could get away with just using a fusion map and avoid the copying and
even the map lookup.

Given the performance hit we're currently taking due to the many
evaluations, I'll definitely try to implement this. Another
alternative would be some sort of temporary values, but that places
the burden of isolating common terms on the user and I think it would
be almost as complicated to add support for this.

The main thing I'm still concerned about is how to recurse over the
expression in a way that can handle nested products. Ideally, the
"leaf" products should be evaluated and stored in the map first, so
subsequent higher level multiply expressions that use the result can
look it up, even while the map is still being constructed.

Cheers,

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


Re: [proto] Precomputing common matrix products in an expression

2012-07-15 Thread Thomas Heller
On Friday, July 13, 2012 21:51:40 Bart Janssens wrote:
> Hi guys,
> 
> I've been thinking about a feature for our DSEL, where lots of matrix
> products can occur in an expression. Part of an expression might be:
> nu_eff * transpose(nabla(u)) * nabla(u) + transpose(N(u) +
> coeffs.tau_su*u_adv*nabla(u)) * u_adv*nabla(u)
> 
> Here, u_adv*nabla(u) is a vector-matrix product that occurs twice, so
> it would be beneficial to calculate it only once. I was wondering if
> it would be doable to construct a fusion map, with as keys the type of
> each product occurring in an expression, and evaluate each member of
> the map before evaluating the actual expression. When the expression
> is evaluated, matrix products would then be looked up in the map.
> 
> Does this sound like something that's doable? I'm assuming the fold
> transform can help me in the construction of the fusion map. Note also
> that each matrix has a compile-time size, so any stored temporary
> would need to have its type computed.

In a way, this reminds me of how local variables in phoenix work.
You have the key (the variables name) which is a distinct type, and you look 
up the value of that key in a fusion map. The only real difference is that 
local variables aren't computed lazily, but that should be a nobrainer to add. 
Might get interesting in a multi-threaded environment though.

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


Re: [proto] Precomputing common matrix products in an expression

2012-07-14 Thread Mathias Gaunard

On 07/15/2012 08:04 AM, Mathias Gaunard wrote:


Assuming your expressions are CopyConstructible


You'd also need them to be EqualityComparable or to use a comparator to 
use them as keys. A recursive call to fusion::equal_to would probably be 
a good definition.

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


Re: [proto] Precomputing common matrix products in an expression

2012-07-14 Thread Mathias Gaunard

On 07/14/2012 08:46 AM, Joel Falcou wrote:


In NT2, we use a schedule transform that iterate the expression tree and
evaluate expression tagged as being needed to be evaluated once and
store them in some shared_ptr like terminal. This allow us to "schedule"
our loop nests in the proper order.

This "scheduling" is what requried us to store everything proto by value
inside expression. Mathias correct me if I diverge.


I don't see how this has anything to do with what the OP wants, which is 
memoization. The "once" in NT2 only has to do with how loops are 
expanded, it doesn't prevent the same expression from being evaluated 
every time it's called.


We don't do anything of the sort, but I don't see any difficulty in 
doing this.


Assuming your expressions are CopyConstructible and you evaluate your 
expressions with something like this being called recursively


template
struct evaluate
{
   typedef ... result_type;
   result_type operator()(Expr& e) const
   {
  ...
   }
};

You could just replace it with

template
struct memoize_evaluate
{
   typedef evaluate impl;
   typedef typename impl::result_type result_type;

   result_type operator()(Expr& e) const
   {
 typename result_map::iterator it = get_results().find(e);
 if(it != get_results().end())
   return *it;

 return get_results().insert(std::make_pair(e, impl()(e))).first;
   }

private:
   typedef std::map result_map;
   static result_map& get_results()
   {
 static result_map results;
 return results;
   }

};

Of course Proto expressions are not safely CopyConstructible by default, 
so you'd have to be careful to make it work.


This is a global approach, so you'll end up committing to memory all 
your past results. This is probably not desirable so you might prefer 
storing the map in the state instead of a singleton.

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


Re: [proto] Precomputing common matrix products in an expression

2012-07-13 Thread Joel Falcou

Le 13/07/2012 23:55, Eric Niebler a écrit :

This is an instance of the larger "common subexpression elimination"
problem. The problem is complicated by the fact that it can't be solved
with type information alone. u_adv*nable(u) might have the same type as
u_adv*nable(v) but different values. A hybrid solution is needed where
you cache a set of results indexed both by type information and the
identities (addresses) of the constituents of the subexpressions. This
is hard, and nobody has attempted it yet. I can give you encouragement,
but not guidance. If you find a general and elegant solution, it would
certainly be worth putting in Proto, since lots of folks would benefit.



In NT2, we use a schedule transform that iterate the expression tree and
evaluate expression tagged as being needed to be evaluated once and 
store them in some shared_ptr like terminal. This allow us to "schedule"

our loop nests in the proper order.

This "scheduling" is what requried us to store everything proto by value 
inside expression. Mathias correct me if I diverge.


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


Re: [proto] Precomputing common matrix products in an expression

2012-07-13 Thread Bart Janssens
On Fri, Jul 13, 2012 at 11:55 PM, Eric Niebler  wrote:
> On 7/13/2012 12:51 PM, Bart Janssens wrote:
> This is an instance of the larger "common subexpression elimination"
> problem. The problem is complicated by the fact that it can't be solved
> with type information alone. u_adv*nable(u) might have the same type as
> u_adv*nable(v) but different values. A hybrid solution is needed where
> you cache a set of results indexed both by type information and the
> identities (addresses) of the constituents of the subexpressions. This
> is hard, and nobody has attempted it yet. I can give you encouragement,
> but not guidance. If you find a general and elegant solution, it would
> certainly be worth putting in Proto, since lots of folks would benefit.

OK, in my case things are somewhat simpler after all then, since every
multiplication does have a distinct type, the u and u_adv are also
proto terminals, distinguished using an mpl integer, so that's why I
was hoping that a fusion map combined with some clever expression
analysis would suffice.

Cheers,

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


Re: [proto] Precomputing common matrix products in an expression

2012-07-13 Thread Eric Niebler
On 7/13/2012 12:51 PM, Bart Janssens wrote:
> Hi guys,
> 
> I've been thinking about a feature for our DSEL, where lots of matrix
> products can occur in an expression. Part of an expression might be:
> nu_eff * transpose(nabla(u)) * nabla(u) + transpose(N(u) +
> coeffs.tau_su*u_adv*nabla(u)) * u_adv*nabla(u)
> 
> Here, u_adv*nabla(u) is a vector-matrix product that occurs twice, so
> it would be beneficial to calculate it only once. I was wondering if
> it would be doable to construct a fusion map, with as keys the type of
> each product occurring in an expression, and evaluate each member of
> the map before evaluating the actual expression. When the expression
> is evaluated, matrix products would then be looked up in the map.
> 
> Does this sound like something that's doable? I'm assuming the fold
> transform can help me in the construction of the fusion map. Note also
> that each matrix has a compile-time size, so any stored temporary
> would need to have its type computed.

This is an instance of the larger "common subexpression elimination"
problem. The problem is complicated by the fact that it can't be solved
with type information alone. u_adv*nable(u) might have the same type as
u_adv*nable(v) but different values. A hybrid solution is needed where
you cache a set of results indexed both by type information and the
identities (addresses) of the constituents of the subexpressions. This
is hard, and nobody has attempted it yet. I can give you encouragement,
but not guidance. If you find a general and elegant solution, it would
certainly be worth putting in Proto, since lots of folks would benefit.

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com


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