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