generate an n-deep runtime for loop
Hello, I have a fusion sequence of optionals, for e.g. fusion::vector< optional< variant< std::vector<double>, triplet<double>, pair<double>, double> >, optional< variant< std::vector<int>, triplet<int>, pair<int>, int> >, optional< variant< std::vector<double>, triplet<double>, pair<double>, double> >
The size of fusion::vector is variable. The optionals are never empty. In 1 possible instance of this fusion vector, we have these runtime values { 5.5, 10.1, 15.7, 30.9 //std::vector<double> v1 5:15:5 // triplet<int> range from 5 to 10 incrementing with 4 5.4 // double, value fixed at 5.4 } I wish to generate at runtime the following code (not always 3-deep for loops, the 3 would be known at compile time, but the bounds of the indices in the for loops are only known at runtime) for (size_t index1=0; index1< v1.size(); ++index1) { for (int index2=5; index2<=15; index2+=5) { for (double index3=5.4; index3<=5.4; ++index3) { // some code } } } is this possible? regards,
<snip> is this possible? Yes, you'll need to build a recursive function that takes your vector and an mpl::int_ as a n arguments, geenrate a for loop on current fusion element
Hicham Mouline wrote: then call itself while incrementing the mpl::int_. Terminal case stop the for loop generation and generate the inner body. -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35
----- Original Message ----- From: "joel falcou" <joel.falcou@lri.fr> To: <boost-users@lists.boost.org> Sent: Friday, January 22, 2010 1:41 AM Subject: Re: [Boost-users] generate an n-deep runtime for loop
<snip> is this possible? Yes, you'll need to build a recursive function that takes your vector and an mpl::int_ as a n arguments, geenrate a for loop on current fusion element
Hicham Mouline wrote: then call itself while incrementing the mpl::int_. Terminal case stop the for loop generation and generate the inner body.
I am gonna try this: /// Seq is fusion::vector< optional< variant<> >, optional< variant<> >, ...., optional< variant<> > > /// InnerBody is a callable that takes as many arguments as there are elements in the Seq template <typename Seq, typename InnerBody, template MplIntegral> void for_recurse(const Seq& seq, const InnerBody& body) { // check requirements are compile time // generate the for loop // for each iteration, call for_recurse with seq reduced } //partial specialization for the 0 case template <typename Seq, typename InnerBody> void for_recurse< mpl::int_<0> >(const Seq& seq, const InnerBody& body) { body( ... ); // somehow call body with all the arguments accumulated so far , how? } regards,
----- Original Message ----- From: "joel falcou" <joel.falcou@lri.fr> To: <boost-users@lists.boost.org> Sent: Friday, January 22, 2010 1:41 AM Subject: Re: [Boost-users] generate an n-deep runtime for loop
<snip> is this possible? Yes, you'll need to build a recursive function that takes your vector and an mpl::int_ as a n arguments, geenrate a for loop on current fusion element
Hicham Mouline wrote: then call itself while incrementing the mpl::int_. Terminal case stop the for loop generation and generate the inner body.
I have a fusion sequence (const Seq& seq), and during the recursion process, I want to process the front element, then pass to the next step, the remainder of the seq. I can't seem to find the algorithm for this, rds,
----- Original Message ----- From: "joel falcou" <joel.falcou@lri.fr> To: <boost-users@lists.boost.org> Sent: Friday, January 22, 2010 1:41 AM Subject: Re: [Boost-users] generate an n-deep runtime for loop
Hicham Mouline wrote:
Please refer to the first post of this thread for the initial question. I believe the compiler got stuck in an infinite loop of template instantiations from my code. It hasn't stopped printing instantiation backtraces when I interrupted it and never reached printing the actuall error :-) The code is ///@param params_seq fusion::vector< variant<>, variant<>, ...., variant<>
///@param body a callable that takes a parameters_t const-ref as an argument /// template <typename parameters_t, typename params_1_n_seq_t, typename inner_body_t, typename N = typename boost::fusion::result_of::size<parameters_t>::type > struct for_recursive { void operator()(parameters_t& params, const params_1_n_seq_t& params_seq, const inner_body_t& body) const { for_iterate<N>( boost::fusion::front(params_seq), params, params_seq, body ); } }; /// Partial specialization for case 0 template <typename parameters_t, typename params_1_n_seq_t, typename inner_body_t> struct for_recursive< parameters_t, params_1_n_seq_t, inner_body_t, boost::mpl::int_<0> > { void operator()(parameters_t& params, const params_1_n_seq_t& params_seq, const inner_body_t& body) const { body(params); } }; Is the second half a partial specialization of the primary template, for the case N = int_<0> ? for_iterate is a template function that applies a visitor on the front variant of the sequence. The visitor then calls for_recursive<>::operator() back with the fusion sequence with the front popped, and N decremented by 1, mpl::minus<N, int_<1>>... template <typename N, typename T, typename parameters_t, typename params_1_n_seq_t, typename inner_body_t> void for_iterate( const boost::variant< std::vector<T>, range_incr<T>, range<T>, T >& v, parameters_t& params, const params_1_n_seq_t& params_seq, const inner_body_t& body ) { boost::apply_visitor( for_iterate_visitor<T,parameters_t,params_1_n_seq_t,inner_body_t,N>(params, params_seq, body), v ); } This visitor is below: /// /// visitor for the "for iterator" /// template <typename T, typename parameters_t, typename params_1_n_seq_t, typename inner_body_t, typename N> class for_iterate_visitor: public boost::static_visitor<> { public: for_iterate_visitor(parameters_t& params, const params_1_n_seq_t& params_seq, const inner_body_t& body) : params_(params), params_seq_(params_seq), params_reduced_seq_( boost::fusion::pop_front(params_seq) ), body_(body) {} private: typedef typename boost::fusion::result_of::size<parameters_t>::type size_of_parameters_t; typedef typename boost::mpl::minus< size_of_parameters_t , N >::type Index; typedef typename boost::mpl::minus<N, boost::mpl::int_<1> >::type Nminus1; typedef typename boost::fusion::result_of::pop_front<const params_1_n_seq_t>::type params_1_n_reduced_seq_t; public: void operator()( const std::vector<T>& v ) const { for (size_t index=0; index<v.size(); ++index) { boost::fusion::at<Index, parameters_t>(params_) = v[index]; for_recursive<parameters_t, params_1_n_reduced_seq_t, inner_body_t, Nminus1>()( params_, params_reduced_seq_, body_ ); } } void operator()( const range_incr<T>& r) const { for (T param=r.min; param<=r.max; param+=r.incr) { boost::fusion::at<Index, parameters_t>(params_) = param; for_recursive<parameters_t, params_1_n_reduced_seq_t, inner_body_t, Nminus1>()( params_, params_reduced_seq_, body_ ); } } void operator()( const range<T>& r ) const { for (T param=r.min; param<=r.max; ++param) { boost::fusion::at<Index, parameters_t>(params_) = param; for_recursive<parameters_t, params_1_n_reduced_seq_t, inner_body_t, Nminus1>()( params_, params_reduced_seq_, body_ ); } } void operator()( T param ) const { boost::fusion::at<Index, parameters_t>(params_) = param; for_recursive<parameters_t, params_1_n_reduced_seq_t, inner_body_t, Nminus1>()( params_, params_reduced_seq_, body_ ); } private: parameters_t& params_; const params_1_n_seq_t& params_seq_; const params_1_n_reduced_seq_t& params_reduced_seq_; const inner_body_t& body_; }; The full code doesn't compile, the entry point is for_recursive<params1_t, params1_1_n_seq_t, for_print_it>()( p, p2, for_print_it() ); struct for_print_it { void operator()(const params1& p) const { std::cout<< p.field1<<std::endl; } }; regards,
----- Original Message ----- From: "joel falcou" <joel.falcou@lri.fr> To: <boost-users@lists.boost.org> Sent: Friday, January 22, 2010 1:41 AM Subject: Re: [Boost-users] generate an n-deep runtime for loop
Hicham Mouline wrote: I believe the compiler got stuck in an infinite loop of template instantiations from my code. It hasn't stopped printing instantiation backtraces when I interrupted it and never reached printing the actuall error :-)
instead of using mpl integral constants as template argument, I used size_t, then the recursion terminates at 0. The n-deep for loop generation works perfectly well, fantastic. A later stage refinement will be parallelization of the whole n-deep for loop (I'll try openmp). regards,
participants (2)
-
Hicham Mouline
-
joel falcou