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