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