Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-18 10:24:17

0001 /*
0002     Copyright (c) 2005-2024 Intel Corporation
0003 
0004     Licensed under the Apache License, Version 2.0 (the "License");
0005     you may not use this file except in compliance with the License.
0006     You may obtain a copy of the License at
0007 
0008         http://www.apache.org/licenses/LICENSE-2.0
0009 
0010     Unless required by applicable law or agreed to in writing, software
0011     distributed under the License is distributed on an "AS IS" BASIS,
0012     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013     See the License for the specific language governing permissions and
0014     limitations under the License.
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 // included in namespace tbb::detail::d2
0025 
0026 #include "_flow_graph_types_impl.h"
0027 
0028     // Output of the indexer_node is a tbb::flow::tagged_msg, and will be of
0029     // the form  tagged_msg<tag, result>
0030     // where the value of tag will indicate which result was put to the
0031     // successor.
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         // Some versions of Intel(R) C++ Compiler fail to generate an implicit constructor for the class which has std::tuple as a member.
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     //! indexer_node_base
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         // ----------- Aggregator ------------
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);  // return of try_put_task actual return value
0174                     }
0175                     break;
0176                 }
0177             }
0178         }
0179         // ---------- end aggregator -----------
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         // not a virtual method in this class
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     };  //indexer_node_base
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     // type generators
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  /* __TBB__flow_graph_indexer_impl_H */