File indexing completed on 2025-12-18 10:24:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef __TBB__flow_graph_indexer_impl_H
0018 #define __TBB__flow_graph_indexer_impl_H
0019
0020 #ifndef __TBB_flow_graph_H
0021 #error Do not #include this internal file directly; use public TBB headers instead.
0022 #endif
0023
0024
0025
0026 #include "_flow_graph_types_impl.h"
0027
0028
0029
0030
0031
0032
0033 template<typename IndexerNodeBaseType, typename T, size_t K>
0034 graph_task* do_try_put(const T &v, void *p __TBB_FLOW_GRAPH_METAINFO_ARG(const message_metainfo& metainfo)) {
0035 typename IndexerNodeBaseType::output_type o(K, v);
0036 return reinterpret_cast<IndexerNodeBaseType *>(p)->try_put_task(&o __TBB_FLOW_GRAPH_METAINFO_ARG(metainfo));
0037 }
0038
0039 template<typename TupleTypes,int N>
0040 struct indexer_helper {
0041 template<typename IndexerNodeBaseType, typename PortTuple>
0042 static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p, graph& g) {
0043 typedef typename std::tuple_element<N-1, TupleTypes>::type T;
0044 auto indexer_node_put_task = do_try_put<IndexerNodeBaseType, T, N-1>;
0045 std::get<N-1>(my_input).set_up(p, indexer_node_put_task, g);
0046 indexer_helper<TupleTypes,N-1>::template set_indexer_node_pointer<IndexerNodeBaseType,PortTuple>(my_input, p, g);
0047 }
0048 };
0049
0050 template<typename TupleTypes>
0051 struct indexer_helper<TupleTypes,1> {
0052 template<typename IndexerNodeBaseType, typename PortTuple>
0053 static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p, graph& g) {
0054 typedef typename std::tuple_element<0, TupleTypes>::type T;
0055 auto indexer_node_put_task = do_try_put<IndexerNodeBaseType, T, 0>;
0056 std::get<0>(my_input).set_up(p, indexer_node_put_task, g);
0057 }
0058 };
0059
0060 template<typename T>
0061 class indexer_input_port : public receiver<T> {
0062 private:
0063 void* my_indexer_ptr;
0064 typedef graph_task* (* forward_function_ptr)(T const &, void*
0065 __TBB_FLOW_GRAPH_METAINFO_ARG(const message_metainfo&));
0066 forward_function_ptr my_try_put_task;
0067 graph* my_graph;
0068 public:
0069 void set_up(void* p, forward_function_ptr f, graph& g) {
0070 my_indexer_ptr = p;
0071 my_try_put_task = f;
0072 my_graph = &g;
0073 }
0074
0075 protected:
0076 template< typename R, typename B > friend class run_and_put_task;
0077 template<typename X, typename Y> friend class broadcast_cache;
0078 template<typename X, typename Y> friend class round_robin_cache;
0079 graph_task* try_put_task(const T &v) override {
0080 return my_try_put_task(v, my_indexer_ptr __TBB_FLOW_GRAPH_METAINFO_ARG(message_metainfo{}));
0081 }
0082
0083 #if __TBB_PREVIEW_FLOW_GRAPH_TRY_PUT_AND_WAIT
0084 graph_task* try_put_task(const T& v, const message_metainfo& metainfo) override {
0085 return my_try_put_task(v, my_indexer_ptr, metainfo);
0086 }
0087 #endif
0088
0089 graph& graph_reference() const override {
0090 return *my_graph;
0091 }
0092 };
0093
0094 template<typename InputTuple, typename OutputType, typename StructTypes>
0095 class indexer_node_FE {
0096 public:
0097 static const int N = std::tuple_size<InputTuple>::value;
0098 typedef OutputType output_type;
0099 typedef InputTuple input_type;
0100
0101
0102 indexer_node_FE() : my_inputs() {}
0103
0104 input_type &input_ports() { return my_inputs; }
0105 protected:
0106 input_type my_inputs;
0107 };
0108
0109
0110 template<typename InputTuple, typename OutputType, typename StructTypes>
0111 class indexer_node_base : public graph_node, public indexer_node_FE<InputTuple, OutputType,StructTypes>,
0112 public sender<OutputType> {
0113 protected:
0114 using graph_node::my_graph;
0115 public:
0116 static const size_t N = std::tuple_size<InputTuple>::value;
0117 typedef OutputType output_type;
0118 typedef StructTypes tuple_types;
0119 typedef typename sender<output_type>::successor_type successor_type;
0120 typedef indexer_node_FE<InputTuple, output_type,StructTypes> input_ports_type;
0121
0122 private:
0123
0124 enum op_type { reg_succ, rem_succ, try__put_task
0125 };
0126 typedef indexer_node_base<InputTuple,output_type,StructTypes> class_type;
0127
0128 class indexer_node_base_operation : public d1::aggregated_operation<indexer_node_base_operation> {
0129 public:
0130 char type;
0131 union {
0132 output_type const *my_arg;
0133 successor_type *my_succ;
0134 graph_task* bypass_t;
0135 };
0136 #if __TBB_PREVIEW_FLOW_GRAPH_TRY_PUT_AND_WAIT
0137 message_metainfo const* metainfo;
0138 #endif
0139 indexer_node_base_operation(const output_type* e, op_type t) :
0140 type(char(t)), my_arg(e) __TBB_FLOW_GRAPH_METAINFO_ARG(metainfo(nullptr))
0141 {}
0142 #if __TBB_PREVIEW_FLOW_GRAPH_TRY_PUT_AND_WAIT
0143 indexer_node_base_operation(const output_type* e, op_type t, const message_metainfo& info)
0144 : type(char(t)), my_arg(e), metainfo(&info) {}
0145 #endif
0146 indexer_node_base_operation(const successor_type &s, op_type t) : type(char(t)),
0147 my_succ(const_cast<successor_type *>(&s)) {}
0148 };
0149
0150 typedef d1::aggregating_functor<class_type, indexer_node_base_operation> handler_type;
0151 friend class d1::aggregating_functor<class_type, indexer_node_base_operation>;
0152 d1::aggregator<handler_type, indexer_node_base_operation> my_aggregator;
0153
0154 void handle_operations(indexer_node_base_operation* op_list) {
0155 indexer_node_base_operation *current;
0156 while(op_list) {
0157 current = op_list;
0158 op_list = op_list->next;
0159 switch(current->type) {
0160
0161 case reg_succ:
0162 my_successors.register_successor(*(current->my_succ));
0163 current->status.store( SUCCEEDED, std::memory_order_release);
0164 break;
0165
0166 case rem_succ:
0167 my_successors.remove_successor(*(current->my_succ));
0168 current->status.store( SUCCEEDED, std::memory_order_release);
0169 break;
0170 case try__put_task: {
0171 current->bypass_t = my_successors.try_put_task(*(current->my_arg)
0172 __TBB_FLOW_GRAPH_METAINFO_ARG(*(current->metainfo)));
0173 current->status.store( SUCCEEDED, std::memory_order_release);
0174 }
0175 break;
0176 }
0177 }
0178 }
0179
0180 public:
0181 indexer_node_base(graph& g) : graph_node(g), input_ports_type(), my_successors(this) {
0182 indexer_helper<StructTypes,N>::set_indexer_node_pointer(this->my_inputs, this, g);
0183 my_aggregator.initialize_handler(handler_type(this));
0184 }
0185
0186 indexer_node_base(const indexer_node_base& other)
0187 : graph_node(other.my_graph), input_ports_type(), sender<output_type>(), my_successors(this)
0188 {
0189 indexer_helper<StructTypes,N>::set_indexer_node_pointer(this->my_inputs, this, other.my_graph);
0190 my_aggregator.initialize_handler(handler_type(this));
0191 }
0192
0193 bool register_successor(successor_type &r) override {
0194 indexer_node_base_operation op_data(r, reg_succ);
0195 my_aggregator.execute(&op_data);
0196 return op_data.status == SUCCEEDED;
0197 }
0198
0199 bool remove_successor( successor_type &r) override {
0200 indexer_node_base_operation op_data(r, rem_succ);
0201 my_aggregator.execute(&op_data);
0202 return op_data.status == SUCCEEDED;
0203 }
0204
0205
0206 graph_task* try_put_task(output_type const *v
0207 __TBB_FLOW_GRAPH_METAINFO_ARG(const message_metainfo& metainfo))
0208 {
0209 indexer_node_base_operation op_data(v, try__put_task __TBB_FLOW_GRAPH_METAINFO_ARG(metainfo));
0210 my_aggregator.execute(&op_data);
0211 return op_data.bypass_t;
0212 }
0213
0214 protected:
0215 void reset_node(reset_flags f) override {
0216 if(f & rf_clear_edges) {
0217 my_successors.clear();
0218 }
0219 }
0220
0221 private:
0222 broadcast_cache<output_type, null_rw_mutex> my_successors;
0223 };
0224
0225
0226 template<int N, typename InputTuple> struct input_types;
0227
0228 template<typename InputTuple>
0229 struct input_types<1, InputTuple> {
0230 typedef typename std::tuple_element<0, InputTuple>::type first_type;
0231 typedef tagged_msg<size_t, first_type > type;
0232 };
0233
0234 template<typename InputTuple>
0235 struct input_types<2, InputTuple> {
0236 typedef typename std::tuple_element<0, InputTuple>::type first_type;
0237 typedef typename std::tuple_element<1, InputTuple>::type second_type;
0238 typedef tagged_msg<size_t, first_type, second_type> type;
0239 };
0240
0241 template<typename InputTuple>
0242 struct input_types<3, InputTuple> {
0243 typedef typename std::tuple_element<0, InputTuple>::type first_type;
0244 typedef typename std::tuple_element<1, InputTuple>::type second_type;
0245 typedef typename std::tuple_element<2, InputTuple>::type third_type;
0246 typedef tagged_msg<size_t, first_type, second_type, third_type> type;
0247 };
0248
0249 template<typename InputTuple>
0250 struct input_types<4, InputTuple> {
0251 typedef typename std::tuple_element<0, InputTuple>::type first_type;
0252 typedef typename std::tuple_element<1, InputTuple>::type second_type;
0253 typedef typename std::tuple_element<2, InputTuple>::type third_type;
0254 typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
0255 typedef tagged_msg<size_t, first_type, second_type, third_type,
0256 fourth_type> type;
0257 };
0258
0259 template<typename InputTuple>
0260 struct input_types<5, InputTuple> {
0261 typedef typename std::tuple_element<0, InputTuple>::type first_type;
0262 typedef typename std::tuple_element<1, InputTuple>::type second_type;
0263 typedef typename std::tuple_element<2, InputTuple>::type third_type;
0264 typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
0265 typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
0266 typedef tagged_msg<size_t, first_type, second_type, third_type,
0267 fourth_type, fifth_type> type;
0268 };
0269
0270 template<typename InputTuple>
0271 struct input_types<6, InputTuple> {
0272 typedef typename std::tuple_element<0, InputTuple>::type first_type;
0273 typedef typename std::tuple_element<1, InputTuple>::type second_type;
0274 typedef typename std::tuple_element<2, InputTuple>::type third_type;
0275 typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
0276 typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
0277 typedef typename std::tuple_element<5, InputTuple>::type sixth_type;
0278 typedef tagged_msg<size_t, first_type, second_type, third_type,
0279 fourth_type, fifth_type, sixth_type> type;
0280 };
0281
0282 template<typename InputTuple>
0283 struct input_types<7, InputTuple> {
0284 typedef typename std::tuple_element<0, InputTuple>::type first_type;
0285 typedef typename std::tuple_element<1, InputTuple>::type second_type;
0286 typedef typename std::tuple_element<2, InputTuple>::type third_type;
0287 typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
0288 typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
0289 typedef typename std::tuple_element<5, InputTuple>::type sixth_type;
0290 typedef typename std::tuple_element<6, InputTuple>::type seventh_type;
0291 typedef tagged_msg<size_t, first_type, second_type, third_type,
0292 fourth_type, fifth_type, sixth_type,
0293 seventh_type> type;
0294 };
0295
0296
0297 template<typename InputTuple>
0298 struct input_types<8, InputTuple> {
0299 typedef typename std::tuple_element<0, InputTuple>::type first_type;
0300 typedef typename std::tuple_element<1, InputTuple>::type second_type;
0301 typedef typename std::tuple_element<2, InputTuple>::type third_type;
0302 typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
0303 typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
0304 typedef typename std::tuple_element<5, InputTuple>::type sixth_type;
0305 typedef typename std::tuple_element<6, InputTuple>::type seventh_type;
0306 typedef typename std::tuple_element<7, InputTuple>::type eighth_type;
0307 typedef tagged_msg<size_t, first_type, second_type, third_type,
0308 fourth_type, fifth_type, sixth_type,
0309 seventh_type, eighth_type> type;
0310 };
0311
0312
0313 template<typename InputTuple>
0314 struct input_types<9, InputTuple> {
0315 typedef typename std::tuple_element<0, InputTuple>::type first_type;
0316 typedef typename std::tuple_element<1, InputTuple>::type second_type;
0317 typedef typename std::tuple_element<2, InputTuple>::type third_type;
0318 typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
0319 typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
0320 typedef typename std::tuple_element<5, InputTuple>::type sixth_type;
0321 typedef typename std::tuple_element<6, InputTuple>::type seventh_type;
0322 typedef typename std::tuple_element<7, InputTuple>::type eighth_type;
0323 typedef typename std::tuple_element<8, InputTuple>::type nineth_type;
0324 typedef tagged_msg<size_t, first_type, second_type, third_type,
0325 fourth_type, fifth_type, sixth_type,
0326 seventh_type, eighth_type, nineth_type> type;
0327 };
0328
0329 template<typename InputTuple>
0330 struct input_types<10, InputTuple> {
0331 typedef typename std::tuple_element<0, InputTuple>::type first_type;
0332 typedef typename std::tuple_element<1, InputTuple>::type second_type;
0333 typedef typename std::tuple_element<2, InputTuple>::type third_type;
0334 typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
0335 typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
0336 typedef typename std::tuple_element<5, InputTuple>::type sixth_type;
0337 typedef typename std::tuple_element<6, InputTuple>::type seventh_type;
0338 typedef typename std::tuple_element<7, InputTuple>::type eighth_type;
0339 typedef typename std::tuple_element<8, InputTuple>::type nineth_type;
0340 typedef typename std::tuple_element<9, InputTuple>::type tenth_type;
0341 typedef tagged_msg<size_t, first_type, second_type, third_type,
0342 fourth_type, fifth_type, sixth_type,
0343 seventh_type, eighth_type, nineth_type,
0344 tenth_type> type;
0345 };
0346
0347
0348 template<typename OutputTuple>
0349 struct indexer_types : public input_types<std::tuple_size<OutputTuple>::value, OutputTuple> {
0350 static const int N = std::tuple_size<OutputTuple>::value;
0351 typedef typename input_types<N, OutputTuple>::type output_type;
0352 typedef typename wrap_tuple_elements<N,indexer_input_port,OutputTuple>::type input_ports_type;
0353 typedef indexer_node_FE<input_ports_type,output_type,OutputTuple> indexer_FE_type;
0354 typedef indexer_node_base<input_ports_type, output_type, OutputTuple> indexer_base_type;
0355 };
0356
0357 template<class OutputTuple>
0358 class unfolded_indexer_node : public indexer_types<OutputTuple>::indexer_base_type {
0359 public:
0360 typedef typename indexer_types<OutputTuple>::input_ports_type input_ports_type;
0361 typedef OutputTuple tuple_types;
0362 typedef typename indexer_types<OutputTuple>::output_type output_type;
0363 private:
0364 typedef typename indexer_types<OutputTuple>::indexer_base_type base_type;
0365 public:
0366 unfolded_indexer_node(graph& g) : base_type(g) {}
0367 unfolded_indexer_node(const unfolded_indexer_node &other) : base_type(other) {}
0368 };
0369
0370 #endif