c++ - TBB flow graph conditional execution -


it possible control execution path in tbb flow graph dynamically, using output of node condition variable determine whether node should launched?

there couple ways dynamically control messages go in flow::graph:

you can explicitly put messages other nodes in body of node. notice func_body puts message f1 or f2, depending on value of input. nodes not attached make_edge(), because flow of messages not controlled topology of graph:

template<typename t> struct func_body {     typedef tbb::flow::function_node<t,t> target_node_type;     target_node_type &my_n1;     target_node_type &my_n2;     func_body(target_node_type &node1, target_node_type &node2) : my_n1(node1), my_n2(node2) {}     tbb::flow::continue_msg operator()(const t& in) {         // computation         bool send_to_one = in > 0;         if(send_to_one) my_n1.try_put(in);         else            my_n2.try_put(in);         return tbb::flow::continue_msg();  // message discarded if no successor exists     } };  struct otherbody {     int operator()(const int& in) {         return in;     } };  int main() {     tbb::flow::graph g;     tbb::flow::function_node<int,int> f1(g, tbb::flow::unlimited, otherbody());     tbb::flow::function_node<int,int> f2(g, tbb::flow::unlimited, otherbody());     tbb::flow::function_node<int> cn(g, tbb::flow::unlimited, func_body<int>(f1,f2)); } 

or can use multifunction_node (note types of tuple , get templates in tbb::flow namespace, not std:: in old documentation.) notice in case attach f1 , f2 output ports of multifunction_node.

typedef tbb::flow::multifunction_node<int,tbb::flow::tuple<int,int> > mfnode;  struct mfunc_body {     void operator()(const int& in, mfnode::output_ports_type &op) {         // computation         bool send_to_one = in > 0;         if(send_to_one) tbb::flow::get<0>(op).try_put(in);         else            tbb::flow::get<1>(op).try_put(in);     } };  struct otherbody {     int operator()(const int& in) {         return in;     } };  int main() {     tbb::flow::graph g;     tbb::flow::function_node<int,int> f1(g, tbb::flow::unlimited, otherbody());     tbb::flow::function_node<int,int> f2(g, tbb::flow::unlimited, otherbody());     mfnode cn(g, tbb::flow::unlimited, mfunc_body());     tbb::flow::make_edge(tbb::flow::output_port<0>(cn), f1);     tbb::flow::make_edge(tbb::flow::output_port<1>(cn), f2);      // ... } 

currently these 2 methods functionally-identical; each spawn task execute body of function_nodes. in future multifunction_node case may optimized not spawn if 1 output port try_put() to.


Comments

Popular posts from this blog

javascript - DIV "hiding" when changing dropdown value -

Does Firefox offer AppleScript support to get URL of windows? -

android - How to install packaged app on Firefox for mobile? -