Home ⌂Doc Index ◂Up ▴
Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
_flow_graph_indexer_impl.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2005-2020 Intel Corporation
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16 
17 #ifndef __TBB__flow_graph_indexer_impl_H
18 #define __TBB__flow_graph_indexer_impl_H
19 
20 #ifndef __TBB_flow_graph_H
21 #error Do not #include this internal file directly; use public TBB headers instead.
22 #endif
23 
24 #include "_flow_graph_types_impl.h"
25 
26 namespace internal {
27 
28  // Output of the indexer_node is a tbb::flow::tagged_msg, and will be of
29  // the form tagged_msg<tag, result>
30  // where the value of tag will indicate which result was put to the
31  // successor.
32 
33  template<typename IndexerNodeBaseType, typename T, size_t K>
34  task* do_try_put(const T &v, void *p) {
35  typename IndexerNodeBaseType::output_type o(K, v);
36  return reinterpret_cast<IndexerNodeBaseType *>(p)->try_put_task(&o);
37  }
38 
39  template<typename TupleTypes,int N>
40  struct indexer_helper {
41  template<typename IndexerNodeBaseType, typename PortTuple>
42  static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p, graph& g) {
43  typedef typename tuple_element<N-1, TupleTypes>::type T;
44  task *(*indexer_node_put_task)(const T&, void *) = do_try_put<IndexerNodeBaseType, T, N-1>;
45  tbb::flow::get<N-1>(my_input).set_up(p, indexer_node_put_task, g);
46  indexer_helper<TupleTypes,N-1>::template set_indexer_node_pointer<IndexerNodeBaseType,PortTuple>(my_input, p, g);
47  }
48  template<typename InputTuple>
49  static inline void reset_inputs(InputTuple &my_input, reset_flags f) {
51  tbb::flow::get<N-1>(my_input).reset_receiver(f);
52  }
53 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
54  template<typename InputTuple>
55  static inline void extract(InputTuple &my_input) {
57  tbb::flow::get<N-1>(my_input).extract_receiver();
58  }
59 #endif
60  };
61 
62  template<typename TupleTypes>
63  struct indexer_helper<TupleTypes,1> {
64  template<typename IndexerNodeBaseType, typename PortTuple>
65  static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p, graph& g) {
66  typedef typename tuple_element<0, TupleTypes>::type T;
67  task *(*indexer_node_put_task)(const T&, void *) = do_try_put<IndexerNodeBaseType, T, 0>;
68  tbb::flow::get<0>(my_input).set_up(p, indexer_node_put_task, g);
69  }
70  template<typename InputTuple>
71  static inline void reset_inputs(InputTuple &my_input, reset_flags f) {
72  tbb::flow::get<0>(my_input).reset_receiver(f);
73  }
74 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
75  template<typename InputTuple>
76  static inline void extract(InputTuple &my_input) {
77  tbb::flow::get<0>(my_input).extract_receiver();
78  }
79 #endif
80  };
81 
82  template<typename T>
83  class indexer_input_port : public receiver<T> {
84  private:
86  typedef task* (* forward_function_ptr)(T const &, void* );
88 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
89  spin_mutex my_pred_mutex;
90  typedef typename receiver<T>::built_predecessors_type built_predecessors_type;
91  built_predecessors_type my_built_predecessors;
92 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
93  graph* my_graph;
94  public:
95 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
96  indexer_input_port() : my_pred_mutex(), my_graph(NULL) {}
97  indexer_input_port( const indexer_input_port & other) : receiver<T>(), my_pred_mutex(), my_graph(other.my_graph) {
98  }
99 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
100  void set_up(void* p, forward_function_ptr f, graph& g) {
101  my_indexer_ptr = p;
102  my_try_put_task = f;
103  my_graph = &g;
104  }
105 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
106  typedef typename receiver<T>::predecessor_list_type predecessor_list_type;
107  typedef typename receiver<T>::predecessor_type predecessor_type;
108 
109  built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; }
110 
111  size_t predecessor_count() __TBB_override {
112  spin_mutex::scoped_lock l(my_pred_mutex);
113  return my_built_predecessors.edge_count();
114  }
115  void internal_add_built_predecessor(predecessor_type &p) __TBB_override {
116  spin_mutex::scoped_lock l(my_pred_mutex);
117  my_built_predecessors.add_edge(p);
118  }
119  void internal_delete_built_predecessor(predecessor_type &p) __TBB_override {
120  spin_mutex::scoped_lock l(my_pred_mutex);
121  my_built_predecessors.delete_edge(p);
122  }
123  void copy_predecessors( predecessor_list_type &v) __TBB_override {
124  spin_mutex::scoped_lock l(my_pred_mutex);
125  my_built_predecessors.copy_edges(v);
126  }
127 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
128  protected:
129  template< typename R, typename B > friend class run_and_put_task;
130  template<typename X, typename Y> friend class internal::broadcast_cache;
131  template<typename X, typename Y> friend class internal::round_robin_cache;
133  return my_try_put_task(v, my_indexer_ptr);
134  }
135 
137  return *my_graph;
138  }
139 
140  public:
141 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
142  void reset_receiver(reset_flags f) __TBB_override { if(f&rf_clear_edges) my_built_predecessors.clear(); }
143 #else
145 #endif
146 
147 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
148  void extract_receiver() { my_built_predecessors.receiver_extract(*this); }
149 #endif
150  };
151 
152  template<typename InputTuple, typename OutputType, typename StructTypes>
154  public:
156  typedef OutputType output_type;
157  typedef InputTuple input_type;
158 
159  // Some versions of Intel(R) C++ Compiler fail to generate an implicit constructor for the class which has std::tuple as a member.
161 
163  protected:
165  };
166 
168  template<typename InputTuple, typename OutputType, typename StructTypes>
169  class indexer_node_base : public graph_node, public indexer_node_FE<InputTuple, OutputType,StructTypes>,
170  public sender<OutputType> {
171  protected:
172  using graph_node::my_graph;
173  public:
175  typedef OutputType output_type;
176  typedef StructTypes tuple_types;
177  typedef typename sender<output_type>::successor_type successor_type;
179 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
180  typedef typename sender<output_type>::built_successors_type built_successors_type;
181  typedef typename sender<output_type>::successor_list_type successor_list_type;
182 #endif
183 
184  private:
185  // ----------- Aggregator ------------
187 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
188  , add_blt_succ, del_blt_succ,
189  blt_succ_cnt, blt_succ_cpy
190 #endif
191  };
193 
194  class indexer_node_base_operation : public aggregated_operation<indexer_node_base_operation> {
195  public:
196  char type;
197  union {
201 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
202  size_t cnt_val;
203  successor_list_type *succv;
204 #endif
205  };
207  type(char(t)), my_arg(e) {}
209  my_succ(const_cast<successor_type *>(&s)) {}
211  };
212 
216 
219  while(op_list) {
220  current = op_list;
221  op_list = op_list->next;
222  switch(current->type) {
223 
224  case reg_succ:
227  break;
228 
229  case rem_succ:
232  break;
233  case try__put_task: {
234  current->bypass_t = my_successors.try_put_task(*(current->my_arg));
235  __TBB_store_with_release(current->status, SUCCEEDED); // return of try_put_task actual return value
236  }
237  break;
238 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
239  case add_blt_succ:
240  my_successors.internal_add_built_successor(*(current->my_succ));
242  break;
243  case del_blt_succ:
244  my_successors.internal_delete_built_successor(*(current->my_succ));
246  break;
247  case blt_succ_cnt:
248  current->cnt_val = my_successors.successor_count();
250  break;
251  case blt_succ_cpy:
252  my_successors.copy_successors(*(current->succv));
254  break;
255 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
256  }
257  }
258  }
259  // ---------- end aggregator -----------
260  public:
261  indexer_node_base(graph& g) : graph_node(g), input_ports_type() {
263  my_successors.set_owner(this);
264  my_aggregator.initialize_handler(handler_type(this));
265  }
266 
267  indexer_node_base(const indexer_node_base& other) : graph_node(other.my_graph), input_ports_type(), sender<output_type>() {
269  my_successors.set_owner(this);
270  my_aggregator.initialize_handler(handler_type(this));
271  }
272 
275  my_aggregator.execute(&op_data);
276  return op_data.status == SUCCEEDED;
277  }
278 
281  my_aggregator.execute(&op_data);
282  return op_data.status == SUCCEEDED;
283  }
284 
285  task * try_put_task(output_type const *v) { // not a virtual method in this class
287  my_aggregator.execute(&op_data);
288  return op_data.bypass_t;
289  }
290 
291 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
292 
293  built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); }
294 
295  void internal_add_built_successor( successor_type &r) __TBB_override {
296  indexer_node_base_operation op_data(r, add_blt_succ);
297  my_aggregator.execute(&op_data);
298  }
299 
300  void internal_delete_built_successor( successor_type &r) __TBB_override {
301  indexer_node_base_operation op_data(r, del_blt_succ);
302  my_aggregator.execute(&op_data);
303  }
304 
305  size_t successor_count() __TBB_override {
306  indexer_node_base_operation op_data(blt_succ_cnt);
307  my_aggregator.execute(&op_data);
308  return op_data.cnt_val;
309  }
310 
311  void copy_successors( successor_list_type &v) __TBB_override {
312  indexer_node_base_operation op_data(blt_succ_cpy);
313  op_data.succv = &v;
314  my_aggregator.execute(&op_data);
315  }
316  void extract() __TBB_override {
317  my_successors.built_successors().sender_extract(*this);
318  indexer_helper<StructTypes,N>::extract(this->my_inputs);
319  }
320 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
321  protected:
323  if(f & rf_clear_edges) {
326  }
327  }
328 
329  private:
331  }; //indexer_node_base
332 
333 
334  template<int N, typename InputTuple> struct input_types;
335 
336  template<typename InputTuple>
337  struct input_types<1, InputTuple> {
340  };
341 
342  template<typename InputTuple>
343  struct input_types<2, InputTuple> {
347  };
348 
349  template<typename InputTuple>
350  struct input_types<3, InputTuple> {
355  };
356 
357  template<typename InputTuple>
358  struct input_types<4, InputTuple> {
363  typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
365  };
366 
367  template<typename InputTuple>
368  struct input_types<5, InputTuple> {
374  typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
376  };
377 
378  template<typename InputTuple>
379  struct input_types<6, InputTuple> {
386  typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
388  };
389 
390  template<typename InputTuple>
391  struct input_types<7, InputTuple> {
399  typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
402  };
403 
404 
405  template<typename InputTuple>
406  struct input_types<8, InputTuple> {
415  typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
418  };
419 
420 
421  template<typename InputTuple>
422  struct input_types<9, InputTuple> {
432  typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
435  };
436 
437  template<typename InputTuple>
438  struct input_types<10, InputTuple> {
449  typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
453  };
454 
455  // type generators
456  template<typename OutputTuple>
457  struct indexer_types : public input_types<tuple_size<OutputTuple>::value, OutputTuple> {
463  };
464 
465  template<class OutputTuple>
466  class unfolded_indexer_node : public indexer_types<OutputTuple>::indexer_base_type {
467  public:
469  typedef OutputTuple tuple_types;
471  private:
473  public:
476  };
477 
478 } /* namespace internal */
479 
480 #endif /* __TBB__flow_graph_indexer_impl_H */
A cache of successors that are put in a round-robin fashion.
tuple_element< 2, InputTuple >::type third_type
internal::tagged_msg< size_t, first_type, second_type > type
internal::indexer_node_base< input_ports_type, output_type, OutputTuple > indexer_base_type
tuple_element< 3, InputTuple >::type fourth_type
bool remove_successor(successor_type &r) __TBB_override
Removes a successor from this node.
tuple_element< 8, InputTuple >::type nineth_type
tuple_element< 8, InputTuple >::type nineth_type
tuple_element< 0, InputTuple >::type first_type
indexer_node_base< InputTuple, output_type, StructTypes > class_type
tuple_element< 5, InputTuple >::type sixth_type
internal::tagged_msg< size_t, first_type, second_type, third_type, fourth_type > type
tuple_element< 2, InputTuple >::type third_type
tuple_element< 0, InputTuple >::type first_type
tuple_element< 2, InputTuple >::type third_type
tuple_element< 0, InputTuple >::type first_type
tuple_element< 1, InputTuple >::type second_type
tuple_element< 1, InputTuple >::type second_type
void handle_operations(indexer_node_base_operation *op_list)
unfolded_indexer_node(const unfolded_indexer_node &other)
task * do_try_put(const T &v, void *p)
tuple_element< 6, InputTuple >::type seventh_type
uintptr_t status
Zero value means "wait" status, all other values are "user" specified values and are defined into the...
tuple_element< 4, InputTuple >::type fifth_type
tuple_element< 5, InputTuple >::type sixth_type
tuple_element< 0, InputTuple >::type first_type
indexer_node_FE< InputTuple, output_type, StructTypes > input_ports_type
tuple_element< 0, InputTuple >::type first_type
internal::tagged_msg< size_t, first_type, second_type, third_type > type
tuple_element< 1, InputTuple >::type second_type
tuple_element< 3, InputTuple >::type fourth_type
tuple_element< 0, InputTuple >::type first_type
tuple_element< 9, InputTuple >::type tenth_type
tuple_element< 6, InputTuple >::type seventh_type
void set_up(void *p, forward_function_ptr f, graph &g)
sender< output_type >::successor_type successor_type
internal::tagged_msg< size_t, first_type, second_type, third_type, fourth_type, fifth_type > type
void reset_node(reset_flags f) __TBB_override
internal::tagged_msg< size_t, first_type, second_type, third_type, fourth_type, fifth_type, sixth_type, seventh_type, eighth_type, nineth_type, tenth_type > type
tuple_element< 4, InputTuple >::type fifth_type
tuple_element< 0, InputTuple >::type first_type
input_types< N, OutputTuple >::type output_type
void __TBB_store_with_release(volatile T &location, V value)
Definition: tbb_machine.h:713
tuple_element< 2, InputTuple >::type third_type
task * try_put_task(const T &t) __TBB_override
tuple_element< 0, InputTuple >::type first_type
tuple_element< 4, InputTuple >::type fifth_type
internal::tagged_msg< size_t, first_type, second_type, third_type, fourth_type, fifth_type, sixth_type, seventh_type, eighth_type, nineth_type > type
tuple_element< 3, InputTuple >::type fourth_type
static void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p, graph &g)
tuple_element< 6, InputTuple >::type seventh_type
tuple_element< 2, InputTuple >::type third_type
tuple_element< 7, InputTuple >::type eighth_type
tuple_element< 4, InputTuple >::type fifth_type
tuple_element< 4, InputTuple >::type fifth_type
tuple_element< 2, InputTuple >::type third_type
tuple_element< 1, InputTuple >::type second_type
tuple_element< 1, InputTuple >::type second_type
tuple_element< 1, InputTuple >::type second_type
tuple_element< 3, InputTuple >::type fourth_type
task * try_put_task(output_type const *v)
tuple_element< 2, InputTuple >::type third_type
void remove_successor(successor_type &r)
void const char const char int ITT_FORMAT __itt_group_sync p
tuple_element< 4, InputTuple >::type fifth_type
wrap_tuple_elements< N, indexer_input_port, OutputTuple >::type input_ports_type
tuple_element< 3, InputTuple >::type fourth_type
A cache of successors that are broadcast to.
static void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p, graph &g)
internal::tagged_msg< size_t, first_type, second_type, third_type, fourth_type, fifth_type, sixth_type, seventh_type > type
static void reset_inputs(InputTuple &my_input, reset_flags f)
aggregator< handler_type, indexer_node_base_operation > my_aggregator
tuple_element< 1, InputTuple >::type second_type
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task * task
void register_successor(successor_type &r)
tuple_element< 1, InputTuple >::type second_type
tuple_element< 2, InputTuple >::type third_type
indexer_types< OutputTuple >::indexer_base_type base_type
tuple_element< 7, InputTuple >::type eighth_type
task *(* forward_function_ptr)(T const &, void *)
tuple_element< 5, InputTuple >::type sixth_type
static void reset_inputs(InputTuple &my_input, reset_flags f)
internal::indexer_node_FE< input_ports_type, output_type, OutputTuple > indexer_FE_type
tuple_element< 7, InputTuple >::type eighth_type
internal::tagged_msg< size_t, first_type, second_type, third_type, fourth_type, fifth_type, sixth_type > type
#define __TBB_override
Definition: tbb_stddef.h:240
tuple_element< 3, InputTuple >::type fourth_type
void reset_receiver(reset_flags) __TBB_override
void const char const char int ITT_FORMAT __itt_group_sync s
graph & graph_reference() const __TBB_override
tuple_element< 5, InputTuple >::type sixth_type
indexer_types< OutputTuple >::output_type output_type
indexer_node_base(const indexer_node_base &other)
internal::aggregating_functor< class_type, indexer_node_base_operation > handler_type
tuple_element< 5, InputTuple >::type sixth_type
indexer_types< OutputTuple >::input_ports_type input_ports_type
void set_owner(owner_type *owner)
task * try_put_task(const T &v) __TBB_override
tuple_element< 3, InputTuple >::type fourth_type
tuple_element< 0, InputTuple >::type first_type
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type type
tuple_element< 0, InputTuple >::type first_type
broadcast_cache< output_type, null_rw_mutex > my_successors
internal::tagged_msg< size_t, first_type > type
tuple_element< 6, InputTuple >::type seventh_type
tuple_element< 1, InputTuple >::type second_type
bool register_successor(successor_type &r) __TBB_override
Add a new successor to this node.
internal::tagged_msg< size_t, first_type, second_type, third_type, fourth_type, fifth_type, sixth_type, seventh_type, eighth_type > type

Copyright © 2005-2020 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.