Re: [proto] Transform result_of nightmare and preserving terminal identity
On 31/10/12 21:28, Agustín K-ballo Bergé wrote: Quoting from my original mail, what I want is to replace the following geometric vector expression: p = q + r; by p[0] = q[0] + r[0], p[1] = q[1] + r[1], ..., p[N] = q[N] + r[N], p; It **can** be done with a transform and that's what I did. The optimized proto expression evaluates ~33% faster than the original proto expression. You could also evaluate the expression directly instead of rebuilding a new expression to evaluate. That would probably increase compilation performance. ___ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto
Re: [proto] Transform result_of nightmare and preserving terminal identity
On 31/10/2012 05:28 p.m., Agustín K-ballo Bergé wrote: On 31/10/2012 04:59 p.m., Eric Niebler wrote: >I will >continue my research by implementing a custom evaluation context that >does this optimization 'on the fly', without actually modifying the >expression. > Evaluation contexts are weaker than transforms. If it can't be done with a transform, it can't be done with a context. I can't tell from the code fragment what exactly you're doing with the transforms you've written, or whether they can be improved. Quoting from my original mail, what I want is to replace the following geometric vector expression: p = q + r; by p[0] = q[0] + r[0], p[1] = q[1] + r[1], ..., p[N] = q[N] + r[N], p; It **can** be done with a transform and that's what I did. The optimized proto expression evaluates ~33% faster than the original proto expression. I believe it can also be done with an evaluation context, that evaluates an expression N times with a component-wise evaluation context. A component-wise evaluation context would be a default context evaluation except that vector terminals are evaluated to one of its scalar components. Now that my transform finally works as intended, I will clean up the code and upload it somewhere for you and anyone interested to see it. I have uploaded my experiment to https://github.com/eggs-cpp/eggs-la . It only implements what is needed for my research, there are wholes pretty much everywhere. Agustín K-ballo Bergé.- http://fusionfenix.com ___ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto
Re: [proto] Transform result_of nightmare and preserving terminal identity
On 31/10/2012 04:59 p.m., Eric Niebler wrote: Proto expressions build and optimization times are not taken into >account. There is a considerable number of expression copies made by the >expression optimization that cannot be avoided by the compiler. > Expression copies ... during expression evaluation? I wonder why that's necessary. Not during expression evaluation, but during expression optimization. My optimization transform unrolls vector expressions into their component-wise expression equivalents; that generates a number of expressions that have to be held by value and hence copied. >I will >continue my research by implementing a custom evaluation context that >does this optimization 'on the fly', without actually modifying the >expression. > Evaluation contexts are weaker than transforms. If it can't be done with a transform, it can't be done with a context. I can't tell from the code fragment what exactly you're doing with the transforms you've written, or whether they can be improved. Quoting from my original mail, what I want is to replace the following geometric vector expression: p = q + r; by p[0] = q[0] + r[0], p[1] = q[1] + r[1], ..., p[N] = q[N] + r[N], p; It **can** be done with a transform and that's what I did. The optimized proto expression evaluates ~33% faster than the original proto expression. I believe it can also be done with an evaluation context, that evaluates an expression N times with a component-wise evaluation context. A component-wise evaluation context would be a default context evaluation except that vector terminals are evaluated to one of its scalar components. Now that my transform finally works as intended, I will clean up the code and upload it somewhere for you and anyone interested to see it. Agustín K-ballo Bergé.- http://fusionfenix.com ___ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto
Re: [proto] Transform result_of nightmare and preserving terminal identity
10/31/2012 12:30 PM, Agustín K-ballo Bergé wrote: > On 16/10/2012 03:50 p.m., Agustín K-ballo Bergé wrote: >> On 16/10/2012 02:22 a.m., Eric Niebler wrote: >>> Hi Agustín, >>> >>> This is just a quick note to let you know that I'm currently at the >>> standard committee meeting in Portland, and that I'll be unable to look >>> until this until I get back next week. >>> >> >> Thank you for letting me know. > > For future reference, my issue was resolved at StackOverflow. You can > find it here > http://stackoverflow.com/questions/13146537/boost-proto-and-complex-transform Heh, answered by me! Funny, I thought Bart's solution on this list had answered your question, so I didn't come back to it. > Preliminar tests for 1 evaluations of a simple expression `p = q > + r * 3.f` where p, q and r are geometric vectors of 3 ints give the > following promising times: > > Regular: 1.15s > Proto: 1.2s > Hand-Unrolled: 0.39s > Proto-Unrolled: 0.8s > > Proto expressions build and optimization times are not taken into > account. There is a considerable number of expression copies made by the > expression optimization that cannot be avoided by the compiler. Expression copies ... during expression evaluation? I wonder why that's necessary. > I will > continue my research by implementing a custom evaluation context that > does this optimization 'on the fly', without actually modifying the > expression. Evaluation contexts are weaker than transforms. If it can't be done with a transform, it can't be done with a context. I can't tell from the code fragment what exactly you're doing with the transforms you've written, or whether they can be improved. -- 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] Transform result_of nightmare and preserving terminal identity
On 16/10/2012 03:50 p.m., Agustín K-ballo Bergé wrote: On 16/10/2012 02:22 a.m., Eric Niebler wrote: Hi Agustín, This is just a quick note to let you know that I'm currently at the standard committee meeting in Portland, and that I'll be unable to look until this until I get back next week. Thank you for letting me know. Agustín K-ballo Bergé.- http://fusionfenix.com ___ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto For future reference, my issue was resolved at StackOverflow. You can find it here http://stackoverflow.com/questions/13146537/boost-proto-and-complex-transform Preliminar tests for 1 evaluations of a simple expression `p = q + r * 3.f` where p, q and r are geometric vectors of 3 ints give the following promising times: Regular: 1.15s Proto: 1.2s Hand-Unrolled: 0.39s Proto-Unrolled: 0.8s Proto expressions build and optimization times are not taken into account. There is a considerable number of expression copies made by the expression optimization that cannot be avoided by the compiler. I will continue my research by implementing a custom evaluation context that does this optimization 'on the fly', without actually modifying the expression. Agustín K-ballo Bergé.- http://fusionfenix.com ___ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto
Re: [proto] Transform result_of nightmare and preserving terminal identity
On 16/10/2012 07:24 a.m., Bart Janssens wrote: On Sun, Oct 14, 2012 at 1:20 AM, Agustín K-ballo Bergé wrote: When deep copying an expression the 'identity' of the terminals is lost, as each reference to a terminal results in a new hold by value terminal. Consequently, expressions with side effects (like assignment) no longer evaluate correctly. Is it possible to customize the expression 'semantics' so that when a deep copy is made terminals are copied only the first time they are seen, and subsequent uses refer to that first copy? Hi Agustín, Re-reading your question after Eric's nudge, I think this is similar to a question I asked a while ago. Eric proposed replacing the standard deep copy with a transform like this: struct DeepCopy : boost::proto::or_ < boost::proto::when // exceptions for terminals that need to be stored by value < boost::proto::or_ < boost::proto::terminal, boost::proto::terminal >, boost::proto::_make_terminal(boost::proto::_byval(boost::proto::_value)) >, boost::proto::terminal, boost::proto::nary_expr > > > { }; This can then be called like DeepCopy()(your_expr). The when<> template in here has some exceptions for terminals that I did want to keep by value, so if you remove that all terminals should be stored by reference in the copy. Concretely in the above example, const doubles and ints are stored by value in the copy, all other types including non-const doubles and ints are kept by reference. Hope this helps! Cheers, This is quite smart! If I can combine this with my domain's `as_child` then it is exactly what I need, I haven't even considered the possibility of using transforms there. Thank you for your help. Agustín K-ballo Bergé.- http://fusionfenix.com ___ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto
Re: [proto] Transform result_of nightmare and preserving terminal identity
On 16/10/2012 02:22 a.m., Eric Niebler wrote: Hi Agustín, This is just a quick note to let you know that I'm currently at the standard committee meeting in Portland, and that I'll be unable to look until this until I get back next week. Thank you for letting me know. Agustín K-ballo Bergé.- http://fusionfenix.com ___ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto
Re: [proto] Transform result_of nightmare and preserving terminal identity
On Sun, Oct 14, 2012 at 1:20 AM, Agustín K-ballo Bergé wrote: > When deep copying an expression the 'identity' of the terminals is lost, as > each reference to a terminal results in a new hold by value terminal. > Consequently, expressions with side effects (like assignment) no longer > evaluate correctly. Is it possible to customize the expression 'semantics' > so that when a deep copy is made terminals are copied only the first time > they are seen, and subsequent uses refer to that first copy? Hi Agustín, Re-reading your question after Eric's nudge, I think this is similar to a question I asked a while ago. Eric proposed replacing the standard deep copy with a transform like this: struct DeepCopy : boost::proto::or_ < boost::proto::when // exceptions for terminals that need to be stored by value < boost::proto::or_ < boost::proto::terminal, boost::proto::terminal >, boost::proto::_make_terminal(boost::proto::_byval(boost::proto::_value)) >, boost::proto::terminal, boost::proto::nary_expr > > > { }; This can then be called like DeepCopy()(your_expr). The when<> template in here has some exceptions for terminals that I did want to keep by value, so if you remove that all terminals should be stored by reference in the copy. Concretely in the above example, const doubles and ints are stored by value in the copy, all other types including non-const doubles and ints are kept by reference. Hope this helps! Cheers, -- Bart ___ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto
Re: [proto] Transform result_of nightmare and preserving terminal identity
On 10/13/2012 4:20 PM, Agustín K-ballo Bergé wrote: > Hi All, > > I'm experimenting with Proto to build a DSEL that operates on geometric > vectors. I'm trying to write a transform that would take an assign > expression and unroll it component wise. For instance, I want to replace Hi Agustín, This is just a quick note to let you know that I'm currently at the standard committee meeting in Portland, and that I'll be unable to look until this until I get back next week. Sorry for the delay. Maybe someone else on this list might be able to help (nudge!). You might also pose this question on stackoverflow.com. -- Eric Niebler BoostPro Computing http://www.boostpro.com ___ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto
[proto] Transform result_of nightmare and preserving terminal identity
Hi All, I'm experimenting with Proto to build a DSEL that operates on geometric vectors. I'm trying to write a transform that would take an assign expression and unroll it component wise. For instance, I want to replace p = q + r; by p[0] = q[0] + r[0], p[1] = q[1] + r[1], ..., p[N] = q[N] + r[N], p; So far I have been able to *mostly* make it work by making a transform template unroll_vector_expr that recursively unrolls the expression for each vector component, in conjunction with a distribute_subscript transform (which I shamelessly took from Eric's article on C++Next). I don't seem to understand whats the rationale for the 'parameters' used with `boost::result_of` and `result_of::make_expr`. The documentation, examples and internal code seem to mix `Expr`, `impl::expr` and `impl::expr_param`. I'm not sure what should I be using and when so that the `result_type` matches the actual result type. Currently I made it work by trial an error, by examining the error messages and fixing the `const` and `&` discrepancies (code for the transform attached). However, as soon as I deep copy the expression the terminals are no longer hold by reference and my code fails. Which incidentally brings me to my second question... When deep copying an expression the 'identity' of the terminals is lost, as each reference to a terminal results in a new hold by value terminal. Consequently, expressions with side effects (like assignment) no longer evaluate correctly. Is it possible to customize the expression 'semantics' so that when a deep copy is made terminals are copied only the first time they are seen, and subsequent uses refer to that first copy? Or should I be taking a completely different approach, perhaps by leaving operations with side effects outside of the grammar? Thanks in advance for any help, and sorry if any of my questions is trivial or erroneous. Agustín K-ballo Bergé.- http://fusionfenix.com struct distribute_subscript : or_< scalar_grammar , when< vector_literal , _make_subscript( _, _state ) > , plus< distribute_subscript, distribute_subscript > , minus< distribute_subscript, distribute_subscript > , multiplies< distribute_subscript, distribute_subscript > , divides< distribute_subscript, distribute_subscript > , assign< distribute_subscript, distribute_subscript > > {}; template< std::size_t I, std::size_t N > struct unroll_vector_expr_c; template< std::size_t N > struct unroll_vector_expr_c< 0, N > : transform< unroll_vector_expr_c< 0, N > > { template< typename Expr, typename State, typename Data > struct impl : transform_impl< Expr, State, Data > { typedef typename result_of::make_expr< tag::comma , typename boost::result_of< unroll_vector_expr_c< 1, N >( typename impl::expr ) >::type , typename impl::state >::type result_type; result_type operator ()( typename impl::expr_param expr , typename impl::state_param state , typename impl::data_param data ) const { return make_expr< tag::comma >( unroll_vector_expr_c< 1, N >()( expr ) , state ); } }; }; template< std::size_t I, std::size_t N > struct unroll_vector_expr_c : transform< unroll_vector_expr_c< I, N > > { template< typename Expr, typename State, typename Data > struct impl : transform_impl< Expr, State, Data > { typedef typename result_of::make_expr< tag::comma , typename boost::result_of< distribute_subscript( typename impl::expr_param , typename result_of::make_expr< tag::terminal , boost::mpl::size_t< I - 1 > >::type const& ) >::type , typename boost::result_of< unroll_vector_expr_c< I + 1, N >( typename impl::expr_param ) >::type >::type result_type; result_type operator ()( typename impl::expr_param expr , typename impl::state_param state , typename impl::data_param data ) const { return make_expr< tag::comma >( distribute_subscript()( expr , make_expr< tag::terminal >( boost::mpl::size_t< I - 1 >()