Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:12:47

0001 /*
0002     Copyright (c) 2005-2020 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 #include "_flow_graph_types_impl.h"
0025 
0026 namespace internal {
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     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 tuple_element<N-1, TupleTypes>::type T;
0044             task *(*indexer_node_put_task)(const T&, void *) = do_try_put<IndexerNodeBaseType, T, N-1>;
0045             tbb::flow::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         template<typename InputTuple>
0049         static inline void reset_inputs(InputTuple &my_input, reset_flags f) {
0050             indexer_helper<TupleTypes,N-1>::reset_inputs(my_input, f);
0051             tbb::flow::get<N-1>(my_input).reset_receiver(f);
0052         }
0053 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0054         template<typename InputTuple>
0055         static inline void extract(InputTuple &my_input) {
0056             indexer_helper<TupleTypes,N-1>::extract(my_input);
0057             tbb::flow::get<N-1>(my_input).extract_receiver();
0058         }
0059 #endif
0060     };
0061 
0062     template<typename TupleTypes>
0063     struct indexer_helper<TupleTypes,1> {
0064         template<typename IndexerNodeBaseType, typename PortTuple>
0065         static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p, graph& g) {
0066             typedef typename tuple_element<0, TupleTypes>::type T;
0067             task *(*indexer_node_put_task)(const T&, void *) = do_try_put<IndexerNodeBaseType, T, 0>;
0068             tbb::flow::get<0>(my_input).set_up(p, indexer_node_put_task, g);
0069         }
0070         template<typename InputTuple>
0071         static inline void reset_inputs(InputTuple &my_input, reset_flags f) {
0072             tbb::flow::get<0>(my_input).reset_receiver(f);
0073         }
0074 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0075         template<typename InputTuple>
0076         static inline void extract(InputTuple &my_input) {
0077             tbb::flow::get<0>(my_input).extract_receiver();
0078         }
0079 #endif
0080     };
0081 
0082     template<typename T>
0083     class indexer_input_port : public receiver<T> {
0084     private:
0085         void* my_indexer_ptr;
0086         typedef task* (* forward_function_ptr)(T const &, void* );
0087         forward_function_ptr my_try_put_task;
0088 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0089         spin_mutex my_pred_mutex;
0090         typedef typename receiver<T>::built_predecessors_type built_predecessors_type;
0091         built_predecessors_type my_built_predecessors;
0092 #endif  /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
0093         graph* my_graph;
0094     public:
0095 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0096         indexer_input_port() : my_pred_mutex(), my_graph(NULL) {}
0097         indexer_input_port( const indexer_input_port & other) : receiver<T>(), my_pred_mutex(), my_graph(other.my_graph) {
0098         }
0099 #endif  /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
0100         void set_up(void* p, forward_function_ptr f, graph& g) {
0101             my_indexer_ptr = p;
0102             my_try_put_task = f;
0103             my_graph = &g;
0104         }
0105 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0106         typedef typename receiver<T>::predecessor_list_type predecessor_list_type;
0107         typedef typename receiver<T>::predecessor_type predecessor_type;
0108 
0109         built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; }
0110 
0111         size_t predecessor_count() __TBB_override {
0112             spin_mutex::scoped_lock l(my_pred_mutex);
0113             return my_built_predecessors.edge_count();
0114         }
0115         void internal_add_built_predecessor(predecessor_type &p) __TBB_override {
0116             spin_mutex::scoped_lock l(my_pred_mutex);
0117             my_built_predecessors.add_edge(p);
0118         }
0119         void internal_delete_built_predecessor(predecessor_type &p) __TBB_override {
0120             spin_mutex::scoped_lock l(my_pred_mutex);
0121             my_built_predecessors.delete_edge(p);
0122         }
0123         void copy_predecessors( predecessor_list_type &v) __TBB_override {
0124             spin_mutex::scoped_lock l(my_pred_mutex);
0125             my_built_predecessors.copy_edges(v);
0126         }
0127 #endif  /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
0128     protected:
0129         template< typename R, typename B > friend class run_and_put_task;
0130         template<typename X, typename Y> friend class internal::broadcast_cache;
0131         template<typename X, typename Y> friend class internal::round_robin_cache;
0132         task *try_put_task(const T &v) __TBB_override {
0133             return my_try_put_task(v, my_indexer_ptr);
0134         }
0135 
0136         graph& graph_reference() const __TBB_override {
0137             return *my_graph;
0138         }
0139 
0140     public:
0141 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0142         void reset_receiver(reset_flags f) __TBB_override { if(f&rf_clear_edges) my_built_predecessors.clear(); }
0143 #else
0144         void reset_receiver(reset_flags /*f*/) __TBB_override { }
0145 #endif
0146 
0147 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0148         void extract_receiver() { my_built_predecessors.receiver_extract(*this); }
0149 #endif
0150     };
0151 
0152     template<typename InputTuple, typename OutputType, typename StructTypes>
0153     class indexer_node_FE {
0154     public:
0155         static const int N = tbb::flow::tuple_size<InputTuple>::value;
0156         typedef OutputType output_type;
0157         typedef InputTuple input_type;
0158 
0159         // Some versions of Intel(R) C++ Compiler fail to generate an implicit constructor for the class which has std::tuple as a member.
0160         indexer_node_FE() : my_inputs() {}
0161 
0162         input_type &input_ports() { return my_inputs; }
0163     protected:
0164         input_type my_inputs;
0165     };
0166 
0167     //! indexer_node_base
0168     template<typename InputTuple, typename OutputType, typename StructTypes>
0169     class indexer_node_base : public graph_node, public indexer_node_FE<InputTuple, OutputType,StructTypes>,
0170                            public sender<OutputType> {
0171     protected:
0172        using graph_node::my_graph;
0173     public:
0174         static const size_t N = tbb::flow::tuple_size<InputTuple>::value;
0175         typedef OutputType output_type;
0176         typedef StructTypes tuple_types;
0177         typedef typename sender<output_type>::successor_type successor_type;
0178         typedef indexer_node_FE<InputTuple, output_type,StructTypes> input_ports_type;
0179 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0180         typedef typename sender<output_type>::built_successors_type built_successors_type;
0181         typedef typename sender<output_type>::successor_list_type successor_list_type;
0182 #endif
0183 
0184     private:
0185         // ----------- Aggregator ------------
0186         enum op_type { reg_succ, rem_succ, try__put_task
0187 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0188             , add_blt_succ, del_blt_succ,
0189              blt_succ_cnt, blt_succ_cpy
0190 #endif
0191         };
0192         typedef indexer_node_base<InputTuple,output_type,StructTypes> class_type;
0193 
0194         class indexer_node_base_operation : public aggregated_operation<indexer_node_base_operation> {
0195         public:
0196             char type;
0197             union {
0198                 output_type const *my_arg;
0199                 successor_type *my_succ;
0200                 task *bypass_t;
0201 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0202                 size_t cnt_val;
0203                 successor_list_type *succv;
0204 #endif
0205             };
0206             indexer_node_base_operation(const output_type* e, op_type t) :
0207                 type(char(t)), my_arg(e) {}
0208             indexer_node_base_operation(const successor_type &s, op_type t) : type(char(t)),
0209                 my_succ(const_cast<successor_type *>(&s)) {}
0210             indexer_node_base_operation(op_type t) : type(char(t)) {}
0211         };
0212 
0213         typedef internal::aggregating_functor<class_type, indexer_node_base_operation> handler_type;
0214         friend class internal::aggregating_functor<class_type, indexer_node_base_operation>;
0215         aggregator<handler_type, indexer_node_base_operation> my_aggregator;
0216 
0217         void handle_operations(indexer_node_base_operation* op_list) {
0218             indexer_node_base_operation *current;
0219             while(op_list) {
0220                 current = op_list;
0221                 op_list = op_list->next;
0222                 switch(current->type) {
0223 
0224                 case reg_succ:
0225                     my_successors.register_successor(*(current->my_succ));
0226                     __TBB_store_with_release(current->status, SUCCEEDED);
0227                     break;
0228 
0229                 case rem_succ:
0230                     my_successors.remove_successor(*(current->my_succ));
0231                     __TBB_store_with_release(current->status, SUCCEEDED);
0232                     break;
0233                 case try__put_task: {
0234                         current->bypass_t = my_successors.try_put_task(*(current->my_arg));
0235                         __TBB_store_with_release(current->status, SUCCEEDED);  // return of try_put_task actual return value
0236                     }
0237                     break;
0238 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0239                 case add_blt_succ:
0240                     my_successors.internal_add_built_successor(*(current->my_succ));
0241                     __TBB_store_with_release(current->status, SUCCEEDED);
0242                     break;
0243                 case del_blt_succ:
0244                     my_successors.internal_delete_built_successor(*(current->my_succ));
0245                     __TBB_store_with_release(current->status, SUCCEEDED);
0246                     break;
0247                 case blt_succ_cnt:
0248                     current->cnt_val = my_successors.successor_count();
0249                     __TBB_store_with_release(current->status, SUCCEEDED);
0250                     break;
0251                 case blt_succ_cpy:
0252                     my_successors.copy_successors(*(current->succv));
0253                     __TBB_store_with_release(current->status, SUCCEEDED);
0254                     break;
0255 #endif  /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
0256                 }
0257             }
0258         }
0259         // ---------- end aggregator -----------
0260     public:
0261         indexer_node_base(graph& g) : graph_node(g), input_ports_type() {
0262             indexer_helper<StructTypes,N>::set_indexer_node_pointer(this->my_inputs, this, g);
0263             my_successors.set_owner(this);
0264             my_aggregator.initialize_handler(handler_type(this));
0265         }
0266 
0267         indexer_node_base(const indexer_node_base& other) : graph_node(other.my_graph), input_ports_type(), sender<output_type>() {
0268             indexer_helper<StructTypes,N>::set_indexer_node_pointer(this->my_inputs, this, other.my_graph);
0269             my_successors.set_owner(this);
0270             my_aggregator.initialize_handler(handler_type(this));
0271         }
0272 
0273         bool register_successor(successor_type &r) __TBB_override {
0274             indexer_node_base_operation op_data(r, reg_succ);
0275             my_aggregator.execute(&op_data);
0276             return op_data.status == SUCCEEDED;
0277         }
0278 
0279         bool remove_successor( successor_type &r) __TBB_override {
0280             indexer_node_base_operation op_data(r, rem_succ);
0281             my_aggregator.execute(&op_data);
0282             return op_data.status == SUCCEEDED;
0283         }
0284 
0285         task * try_put_task(output_type const *v) { // not a virtual method in this class
0286             indexer_node_base_operation op_data(v, try__put_task);
0287             my_aggregator.execute(&op_data);
0288             return op_data.bypass_t;
0289         }
0290 
0291 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0292 
0293         built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); }
0294 
0295         void internal_add_built_successor( successor_type &r) __TBB_override {
0296             indexer_node_base_operation op_data(r, add_blt_succ);
0297             my_aggregator.execute(&op_data);
0298         }
0299 
0300         void internal_delete_built_successor( successor_type &r) __TBB_override {
0301             indexer_node_base_operation op_data(r, del_blt_succ);
0302             my_aggregator.execute(&op_data);
0303         }
0304 
0305         size_t successor_count() __TBB_override {
0306             indexer_node_base_operation op_data(blt_succ_cnt);
0307             my_aggregator.execute(&op_data);
0308             return op_data.cnt_val;
0309         }
0310 
0311         void copy_successors( successor_list_type &v) __TBB_override {
0312             indexer_node_base_operation op_data(blt_succ_cpy);
0313             op_data.succv = &v;
0314             my_aggregator.execute(&op_data);
0315         }
0316         void extract() __TBB_override {
0317             my_successors.built_successors().sender_extract(*this);
0318             indexer_helper<StructTypes,N>::extract(this->my_inputs);
0319         }
0320 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
0321     protected:
0322         void reset_node(reset_flags f) __TBB_override {
0323             if(f & rf_clear_edges) {
0324                 my_successors.clear();
0325                 indexer_helper<StructTypes,N>::reset_inputs(this->my_inputs,f);
0326             }
0327         }
0328 
0329     private:
0330         broadcast_cache<output_type, null_rw_mutex> my_successors;
0331     };  //indexer_node_base
0332 
0333 
0334     template<int N, typename InputTuple> struct input_types;
0335 
0336     template<typename InputTuple>
0337     struct input_types<1, InputTuple> {
0338         typedef typename tuple_element<0, InputTuple>::type first_type;
0339         typedef typename internal::tagged_msg<size_t, first_type > type;
0340     };
0341 
0342     template<typename InputTuple>
0343     struct input_types<2, InputTuple> {
0344         typedef typename tuple_element<0, InputTuple>::type first_type;
0345         typedef typename tuple_element<1, InputTuple>::type second_type;
0346         typedef typename internal::tagged_msg<size_t, first_type, second_type> type;
0347     };
0348 
0349     template<typename InputTuple>
0350     struct input_types<3, InputTuple> {
0351         typedef typename tuple_element<0, InputTuple>::type first_type;
0352         typedef typename tuple_element<1, InputTuple>::type second_type;
0353         typedef typename tuple_element<2, InputTuple>::type third_type;
0354         typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type> type;
0355     };
0356 
0357     template<typename InputTuple>
0358     struct input_types<4, InputTuple> {
0359         typedef typename tuple_element<0, InputTuple>::type first_type;
0360         typedef typename tuple_element<1, InputTuple>::type second_type;
0361         typedef typename tuple_element<2, InputTuple>::type third_type;
0362         typedef typename tuple_element<3, InputTuple>::type fourth_type;
0363         typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
0364                                                       fourth_type> type;
0365     };
0366 
0367     template<typename InputTuple>
0368     struct input_types<5, InputTuple> {
0369         typedef typename tuple_element<0, InputTuple>::type first_type;
0370         typedef typename tuple_element<1, InputTuple>::type second_type;
0371         typedef typename tuple_element<2, InputTuple>::type third_type;
0372         typedef typename tuple_element<3, InputTuple>::type fourth_type;
0373         typedef typename tuple_element<4, InputTuple>::type fifth_type;
0374         typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
0375                                                       fourth_type, fifth_type> type;
0376     };
0377 
0378     template<typename InputTuple>
0379     struct input_types<6, InputTuple> {
0380         typedef typename tuple_element<0, InputTuple>::type first_type;
0381         typedef typename tuple_element<1, InputTuple>::type second_type;
0382         typedef typename tuple_element<2, InputTuple>::type third_type;
0383         typedef typename tuple_element<3, InputTuple>::type fourth_type;
0384         typedef typename tuple_element<4, InputTuple>::type fifth_type;
0385         typedef typename tuple_element<5, InputTuple>::type sixth_type;
0386         typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
0387                                                       fourth_type, fifth_type, sixth_type> type;
0388     };
0389 
0390     template<typename InputTuple>
0391     struct input_types<7, InputTuple> {
0392         typedef typename tuple_element<0, InputTuple>::type first_type;
0393         typedef typename tuple_element<1, InputTuple>::type second_type;
0394         typedef typename tuple_element<2, InputTuple>::type third_type;
0395         typedef typename tuple_element<3, InputTuple>::type fourth_type;
0396         typedef typename tuple_element<4, InputTuple>::type fifth_type;
0397         typedef typename tuple_element<5, InputTuple>::type sixth_type;
0398         typedef typename tuple_element<6, InputTuple>::type seventh_type;
0399         typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
0400                                                       fourth_type, fifth_type, sixth_type,
0401                                                       seventh_type> type;
0402     };
0403 
0404 
0405     template<typename InputTuple>
0406     struct input_types<8, InputTuple> {
0407         typedef typename tuple_element<0, InputTuple>::type first_type;
0408         typedef typename tuple_element<1, InputTuple>::type second_type;
0409         typedef typename tuple_element<2, InputTuple>::type third_type;
0410         typedef typename tuple_element<3, InputTuple>::type fourth_type;
0411         typedef typename tuple_element<4, InputTuple>::type fifth_type;
0412         typedef typename tuple_element<5, InputTuple>::type sixth_type;
0413         typedef typename tuple_element<6, InputTuple>::type seventh_type;
0414         typedef typename tuple_element<7, InputTuple>::type eighth_type;
0415         typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
0416                                                       fourth_type, fifth_type, sixth_type,
0417                                                       seventh_type, eighth_type> type;
0418     };
0419 
0420 
0421     template<typename InputTuple>
0422     struct input_types<9, InputTuple> {
0423         typedef typename tuple_element<0, InputTuple>::type first_type;
0424         typedef typename tuple_element<1, InputTuple>::type second_type;
0425         typedef typename tuple_element<2, InputTuple>::type third_type;
0426         typedef typename tuple_element<3, InputTuple>::type fourth_type;
0427         typedef typename tuple_element<4, InputTuple>::type fifth_type;
0428         typedef typename tuple_element<5, InputTuple>::type sixth_type;
0429         typedef typename tuple_element<6, InputTuple>::type seventh_type;
0430         typedef typename tuple_element<7, InputTuple>::type eighth_type;
0431         typedef typename tuple_element<8, InputTuple>::type nineth_type;
0432         typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
0433                                                       fourth_type, fifth_type, sixth_type,
0434                                                       seventh_type, eighth_type, nineth_type> type;
0435     };
0436 
0437     template<typename InputTuple>
0438     struct input_types<10, InputTuple> {
0439         typedef typename tuple_element<0, InputTuple>::type first_type;
0440         typedef typename tuple_element<1, InputTuple>::type second_type;
0441         typedef typename tuple_element<2, InputTuple>::type third_type;
0442         typedef typename tuple_element<3, InputTuple>::type fourth_type;
0443         typedef typename tuple_element<4, InputTuple>::type fifth_type;
0444         typedef typename tuple_element<5, InputTuple>::type sixth_type;
0445         typedef typename tuple_element<6, InputTuple>::type seventh_type;
0446         typedef typename tuple_element<7, InputTuple>::type eighth_type;
0447         typedef typename tuple_element<8, InputTuple>::type nineth_type;
0448         typedef typename tuple_element<9, InputTuple>::type tenth_type;
0449         typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
0450                                                       fourth_type, fifth_type, sixth_type,
0451                                                       seventh_type, eighth_type, nineth_type,
0452                                                       tenth_type> type;
0453     };
0454 
0455     // type generators
0456     template<typename OutputTuple>
0457     struct indexer_types : public input_types<tuple_size<OutputTuple>::value, OutputTuple> {
0458         static const int N = tbb::flow::tuple_size<OutputTuple>::value;
0459         typedef typename input_types<N, OutputTuple>::type output_type;
0460         typedef typename wrap_tuple_elements<N,indexer_input_port,OutputTuple>::type input_ports_type;
0461         typedef internal::indexer_node_FE<input_ports_type,output_type,OutputTuple> indexer_FE_type;
0462         typedef internal::indexer_node_base<input_ports_type, output_type, OutputTuple> indexer_base_type;
0463     };
0464 
0465     template<class OutputTuple>
0466     class unfolded_indexer_node : public indexer_types<OutputTuple>::indexer_base_type {
0467     public:
0468         typedef typename indexer_types<OutputTuple>::input_ports_type input_ports_type;
0469         typedef OutputTuple tuple_types;
0470         typedef typename indexer_types<OutputTuple>::output_type output_type;
0471     private:
0472         typedef typename indexer_types<OutputTuple>::indexer_base_type base_type;
0473     public:
0474         unfolded_indexer_node(graph& g) : base_type(g) {}
0475         unfolded_indexer_node(const unfolded_indexer_node &other) : base_type(other) {}
0476     };
0477 
0478 } /* namespace internal */
0479 
0480 #endif  /* __TBB__flow_graph_indexer_impl_H */