Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-30 08:46:16

0001 /*
0002     Copyright (c) 2005-2021 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::d1
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) {
0035         typename IndexerNodeBaseType::output_type o(K, v);
0036         return reinterpret_cast<IndexerNodeBaseType *>(p)->try_put_task(&o);
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             graph_task* (*indexer_node_put_task)(const T&, void *) = 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             graph_task* (*indexer_node_put_task)(const T&, void *) = 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         forward_function_ptr my_try_put_task;
0066         graph* my_graph;
0067     public:
0068         void set_up(void* p, forward_function_ptr f, graph& g) {
0069             my_indexer_ptr = p;
0070             my_try_put_task = f;
0071             my_graph = &g;
0072         }
0073 
0074     protected:
0075         template< typename R, typename B > friend class run_and_put_task;
0076         template<typename X, typename Y> friend class broadcast_cache;
0077         template<typename X, typename Y> friend class round_robin_cache;
0078         graph_task* try_put_task(const T &v) override {
0079             return my_try_put_task(v, my_indexer_ptr);
0080         }
0081 
0082         graph& graph_reference() const override {
0083             return *my_graph;
0084         }
0085     };
0086 
0087     template<typename InputTuple, typename OutputType, typename StructTypes>
0088     class indexer_node_FE {
0089     public:
0090         static const int N = std::tuple_size<InputTuple>::value;
0091         typedef OutputType output_type;
0092         typedef InputTuple input_type;
0093 
0094         // Some versions of Intel(R) C++ Compiler fail to generate an implicit constructor for the class which has std::tuple as a member.
0095         indexer_node_FE() : my_inputs() {}
0096 
0097         input_type &input_ports() { return my_inputs; }
0098     protected:
0099         input_type my_inputs;
0100     };
0101 
0102     //! indexer_node_base
0103     template<typename InputTuple, typename OutputType, typename StructTypes>
0104     class indexer_node_base : public graph_node, public indexer_node_FE<InputTuple, OutputType,StructTypes>,
0105                            public sender<OutputType> {
0106     protected:
0107        using graph_node::my_graph;
0108     public:
0109         static const size_t N = std::tuple_size<InputTuple>::value;
0110         typedef OutputType output_type;
0111         typedef StructTypes tuple_types;
0112         typedef typename sender<output_type>::successor_type successor_type;
0113         typedef indexer_node_FE<InputTuple, output_type,StructTypes> input_ports_type;
0114 
0115     private:
0116         // ----------- Aggregator ------------
0117         enum op_type { reg_succ, rem_succ, try__put_task
0118         };
0119         typedef indexer_node_base<InputTuple,output_type,StructTypes> class_type;
0120 
0121         class indexer_node_base_operation : public aggregated_operation<indexer_node_base_operation> {
0122         public:
0123             char type;
0124             union {
0125                 output_type const *my_arg;
0126                 successor_type *my_succ;
0127                 graph_task* bypass_t;
0128             };
0129             indexer_node_base_operation(const output_type* e, op_type t) :
0130                 type(char(t)), my_arg(e) {}
0131             indexer_node_base_operation(const successor_type &s, op_type t) : type(char(t)),
0132                 my_succ(const_cast<successor_type *>(&s)) {}
0133         };
0134 
0135         typedef aggregating_functor<class_type, indexer_node_base_operation> handler_type;
0136         friend class aggregating_functor<class_type, indexer_node_base_operation>;
0137         aggregator<handler_type, indexer_node_base_operation> my_aggregator;
0138 
0139         void handle_operations(indexer_node_base_operation* op_list) {
0140             indexer_node_base_operation *current;
0141             while(op_list) {
0142                 current = op_list;
0143                 op_list = op_list->next;
0144                 switch(current->type) {
0145 
0146                 case reg_succ:
0147                     my_successors.register_successor(*(current->my_succ));
0148                     current->status.store( SUCCEEDED, std::memory_order_release);
0149                     break;
0150 
0151                 case rem_succ:
0152                     my_successors.remove_successor(*(current->my_succ));
0153                     current->status.store( SUCCEEDED, std::memory_order_release);
0154                     break;
0155                 case try__put_task: {
0156                         current->bypass_t = my_successors.try_put_task(*(current->my_arg));
0157                         current->status.store( SUCCEEDED, std::memory_order_release);  // return of try_put_task actual return value
0158                     }
0159                     break;
0160                 }
0161             }
0162         }
0163         // ---------- end aggregator -----------
0164     public:
0165         indexer_node_base(graph& g) : graph_node(g), input_ports_type(), my_successors(this) {
0166             indexer_helper<StructTypes,N>::set_indexer_node_pointer(this->my_inputs, this, g);
0167             my_aggregator.initialize_handler(handler_type(this));
0168         }
0169 
0170         indexer_node_base(const indexer_node_base& other)
0171             : graph_node(other.my_graph), input_ports_type(), sender<output_type>(), my_successors(this)
0172         {
0173             indexer_helper<StructTypes,N>::set_indexer_node_pointer(this->my_inputs, this, other.my_graph);
0174             my_aggregator.initialize_handler(handler_type(this));
0175         }
0176 
0177         bool register_successor(successor_type &r) override {
0178             indexer_node_base_operation op_data(r, reg_succ);
0179             my_aggregator.execute(&op_data);
0180             return op_data.status == SUCCEEDED;
0181         }
0182 
0183         bool remove_successor( successor_type &r) override {
0184             indexer_node_base_operation op_data(r, rem_succ);
0185             my_aggregator.execute(&op_data);
0186             return op_data.status == SUCCEEDED;
0187         }
0188 
0189         graph_task* try_put_task(output_type const *v) { // not a virtual method in this class
0190             indexer_node_base_operation op_data(v, try__put_task);
0191             my_aggregator.execute(&op_data);
0192             return op_data.bypass_t;
0193         }
0194 
0195     protected:
0196         void reset_node(reset_flags f) override {
0197             if(f & rf_clear_edges) {
0198                 my_successors.clear();
0199             }
0200         }
0201 
0202     private:
0203         broadcast_cache<output_type, null_rw_mutex> my_successors;
0204     };  //indexer_node_base
0205 
0206 
0207     template<int N, typename InputTuple> struct input_types;
0208 
0209     template<typename InputTuple>
0210     struct input_types<1, InputTuple> {
0211         typedef typename std::tuple_element<0, InputTuple>::type first_type;
0212         typedef tagged_msg<size_t, first_type > type;
0213     };
0214 
0215     template<typename InputTuple>
0216     struct input_types<2, InputTuple> {
0217         typedef typename std::tuple_element<0, InputTuple>::type first_type;
0218         typedef typename std::tuple_element<1, InputTuple>::type second_type;
0219         typedef tagged_msg<size_t, first_type, second_type> type;
0220     };
0221 
0222     template<typename InputTuple>
0223     struct input_types<3, InputTuple> {
0224         typedef typename std::tuple_element<0, InputTuple>::type first_type;
0225         typedef typename std::tuple_element<1, InputTuple>::type second_type;
0226         typedef typename std::tuple_element<2, InputTuple>::type third_type;
0227         typedef tagged_msg<size_t, first_type, second_type, third_type> type;
0228     };
0229 
0230     template<typename InputTuple>
0231     struct input_types<4, InputTuple> {
0232         typedef typename std::tuple_element<0, InputTuple>::type first_type;
0233         typedef typename std::tuple_element<1, InputTuple>::type second_type;
0234         typedef typename std::tuple_element<2, InputTuple>::type third_type;
0235         typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
0236         typedef tagged_msg<size_t, first_type, second_type, third_type,
0237                                                       fourth_type> type;
0238     };
0239 
0240     template<typename InputTuple>
0241     struct input_types<5, InputTuple> {
0242         typedef typename std::tuple_element<0, InputTuple>::type first_type;
0243         typedef typename std::tuple_element<1, InputTuple>::type second_type;
0244         typedef typename std::tuple_element<2, InputTuple>::type third_type;
0245         typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
0246         typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
0247         typedef tagged_msg<size_t, first_type, second_type, third_type,
0248                                                       fourth_type, fifth_type> type;
0249     };
0250 
0251     template<typename InputTuple>
0252     struct input_types<6, InputTuple> {
0253         typedef typename std::tuple_element<0, InputTuple>::type first_type;
0254         typedef typename std::tuple_element<1, InputTuple>::type second_type;
0255         typedef typename std::tuple_element<2, InputTuple>::type third_type;
0256         typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
0257         typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
0258         typedef typename std::tuple_element<5, InputTuple>::type sixth_type;
0259         typedef tagged_msg<size_t, first_type, second_type, third_type,
0260                                                       fourth_type, fifth_type, sixth_type> type;
0261     };
0262 
0263     template<typename InputTuple>
0264     struct input_types<7, InputTuple> {
0265         typedef typename std::tuple_element<0, InputTuple>::type first_type;
0266         typedef typename std::tuple_element<1, InputTuple>::type second_type;
0267         typedef typename std::tuple_element<2, InputTuple>::type third_type;
0268         typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
0269         typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
0270         typedef typename std::tuple_element<5, InputTuple>::type sixth_type;
0271         typedef typename std::tuple_element<6, InputTuple>::type seventh_type;
0272         typedef tagged_msg<size_t, first_type, second_type, third_type,
0273                                                       fourth_type, fifth_type, sixth_type,
0274                                                       seventh_type> type;
0275     };
0276 
0277 
0278     template<typename InputTuple>
0279     struct input_types<8, InputTuple> {
0280         typedef typename std::tuple_element<0, InputTuple>::type first_type;
0281         typedef typename std::tuple_element<1, InputTuple>::type second_type;
0282         typedef typename std::tuple_element<2, InputTuple>::type third_type;
0283         typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
0284         typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
0285         typedef typename std::tuple_element<5, InputTuple>::type sixth_type;
0286         typedef typename std::tuple_element<6, InputTuple>::type seventh_type;
0287         typedef typename std::tuple_element<7, InputTuple>::type eighth_type;
0288         typedef tagged_msg<size_t, first_type, second_type, third_type,
0289                                                       fourth_type, fifth_type, sixth_type,
0290                                                       seventh_type, eighth_type> type;
0291     };
0292 
0293 
0294     template<typename InputTuple>
0295     struct input_types<9, InputTuple> {
0296         typedef typename std::tuple_element<0, InputTuple>::type first_type;
0297         typedef typename std::tuple_element<1, InputTuple>::type second_type;
0298         typedef typename std::tuple_element<2, InputTuple>::type third_type;
0299         typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
0300         typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
0301         typedef typename std::tuple_element<5, InputTuple>::type sixth_type;
0302         typedef typename std::tuple_element<6, InputTuple>::type seventh_type;
0303         typedef typename std::tuple_element<7, InputTuple>::type eighth_type;
0304         typedef typename std::tuple_element<8, InputTuple>::type nineth_type;
0305         typedef tagged_msg<size_t, first_type, second_type, third_type,
0306                                                       fourth_type, fifth_type, sixth_type,
0307                                                       seventh_type, eighth_type, nineth_type> type;
0308     };
0309 
0310     template<typename InputTuple>
0311     struct input_types<10, InputTuple> {
0312         typedef typename std::tuple_element<0, InputTuple>::type first_type;
0313         typedef typename std::tuple_element<1, InputTuple>::type second_type;
0314         typedef typename std::tuple_element<2, InputTuple>::type third_type;
0315         typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
0316         typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
0317         typedef typename std::tuple_element<5, InputTuple>::type sixth_type;
0318         typedef typename std::tuple_element<6, InputTuple>::type seventh_type;
0319         typedef typename std::tuple_element<7, InputTuple>::type eighth_type;
0320         typedef typename std::tuple_element<8, InputTuple>::type nineth_type;
0321         typedef typename std::tuple_element<9, InputTuple>::type tenth_type;
0322         typedef tagged_msg<size_t, first_type, second_type, third_type,
0323                                                       fourth_type, fifth_type, sixth_type,
0324                                                       seventh_type, eighth_type, nineth_type,
0325                                                       tenth_type> type;
0326     };
0327 
0328     // type generators
0329     template<typename OutputTuple>
0330     struct indexer_types : public input_types<std::tuple_size<OutputTuple>::value, OutputTuple> {
0331         static const int N = std::tuple_size<OutputTuple>::value;
0332         typedef typename input_types<N, OutputTuple>::type output_type;
0333         typedef typename wrap_tuple_elements<N,indexer_input_port,OutputTuple>::type input_ports_type;
0334         typedef indexer_node_FE<input_ports_type,output_type,OutputTuple> indexer_FE_type;
0335         typedef indexer_node_base<input_ports_type, output_type, OutputTuple> indexer_base_type;
0336     };
0337 
0338     template<class OutputTuple>
0339     class unfolded_indexer_node : public indexer_types<OutputTuple>::indexer_base_type {
0340     public:
0341         typedef typename indexer_types<OutputTuple>::input_ports_type input_ports_type;
0342         typedef OutputTuple tuple_types;
0343         typedef typename indexer_types<OutputTuple>::output_type output_type;
0344     private:
0345         typedef typename indexer_types<OutputTuple>::indexer_base_type base_type;
0346     public:
0347         unfolded_indexer_node(graph& g) : base_type(g) {}
0348         unfolded_indexer_node(const unfolded_indexer_node &other) : base_type(other) {}
0349     };
0350 
0351 #endif  /* __TBB__flow_graph_indexer_impl_H */