1.. _use_input_node: 2 3Using input_node 4================= 5 6 7By default, an ``input_node`` is constructed in the inactive state: 8 9 10:: 11 12 13 template< typename Body > input_node( graph &g, Body body, bool is_active=true ) 14 15 16To activate an inactive ``input_node``, you call the node's function 17activate: 18 19 20:: 21 22 23 input_node< int > src( g, src_body(10), false ); 24 // use it in calls to make_edge… 25 src.activate(); 26 27 28All ``input_node`` objects are constructed in the inactive state and usually 29activated after the entire flow graph is constructed. 30 31 32For example, you can use the code in `Data Flow 33Graph <Data_Flow_Graph.html#Data_Flow_Graph>`__. In that implementation, 34the ``input_node`` is constructed in the inactive state and activated after 35all other edges are made: 36 37 38:: 39 40 41 make_edge( squarer, summer ); 42 make_edge( cuber, summer ); 43 input_node< int > src( g, src_body(10), false ); 44 make_edge( src, squarer ); 45 make_edge( src, cuber ); 46 src.activate(); 47 g.wait_for_all(); 48 49 50In this example, if the ``input_node`` was toggled to the active state at the beginning, 51it might send a message to squarer immediately after the edge to 52squarer is connected. Later, when the edge to cuber is connected, cuber 53will receive all future messages, but may have already missed some. 54 55 56In general it is safest to create your ``input_node`` objects in the inactive 57state and then activate them after the whole graph is constructed. 58However, this approach serializes graph construction and graph 59execution. 60 61 62Some graphs can be constructed safely with ``input_node``s active, allowing 63the overlap of construction and execution. If your graph is a directed 64acyclic graph (DAG), and each ``input_node`` has only one successor, you 65can activate your ``input_node``s just after their construction if you construct the 66edges in reverse topological order; that is, make the edges at the 67largest depth in the tree first, and work back to the shallowest edges. 68For example, if src is an ``input_node`` and ``func1`` and ``func2`` are both 69function nodes, the following graph would not drop messages, even though 70src is activated just after its construction: 71 72 73:: 74 75 76 const int limit = 10; 77 int count = 0; 78 graph g; 79 oneapi::tbb::flow::graph g; 80 oneapi::tbb::flow::input_node<int> src( g, [&]( oneapi::tbb::flow_control &fc ) -> int { 81 if ( count < limit ) { 82 return ++count; 83 } 84 fc.stop(); 85 return {}; 86 }); 87 src.activate(); 88 89 oneapi::tbb::flow::function_node<int,int> func1( g, 1, []( int i ) -> int { 90 std::cout << i << "\n"; 91 return i; 92 } ); 93 oneapi::tbb::flow::function_node<int,int> func2( g, 1, []( int i ) -> int { 94 std::cout << i << "\n"; 95 return i; 96 } ); 97 98 99 make_edge( func1, func2 ); 100 make_edge( src, func1 ); 101 102 103 g.wait_for_all(); 104 105 106The above code is safe because the edge from ``func1`` to ``func2`` is made 107before the edge from src to ``func1``. If the edge from src to func1 were 108made first, ``func1`` might generate a message before ``func2`` is attached to 109it; that message would be dropped. Also, src has only a single 110successor. If src had more than one successor, the successor that is 111attached first might receive messages that do not reach the successors 112that are attached after it. 113 114