1919
2020#include " oneapi/tbb/concurrent_unordered_map.h"
2121#include " oneapi/tbb/flow_graph.h"
22- #include " spdlog/spdlog.h"
2322
2423#include < atomic>
2524#include < cassert>
@@ -43,7 +42,7 @@ namespace phlex::experimental {
4342
4443 virtual tbb::flow::sender<message>& sender () = 0;
4544 virtual tbb::flow::sender<message>& to_output () = 0;
46- virtual tbb::flow::receiver<message >& flush_port () = 0;
45+ virtual tbb::flow::receiver<flush_message >& flush_port () = 0;
4746 virtual product_specifications const & output () const = 0;
4847 virtual std::size_t product_count () const = 0;
4948 };
@@ -77,40 +76,36 @@ namespace phlex::experimental {
7776 initializer_{std::move (initializer)},
7877 output_{to_product_specifications (full_name (), std::move (output), make_type_ids<R>())},
7978 partition_{std::move (partition)},
80- flush_receiver_{
81- g,
82- tbb::flow::unlimited,
83- [this ](message const & msg) -> tbb::flow::continue_msg {
84- auto const & [store, original_message_id] = std::tie (msg.store , msg.original_id );
85- if (store->index ()->layer_name () != partition_) {
86- return {};
87- }
88-
89- counter_for (store->index ()->hash ()).set_flush_value (store, original_message_id);
90- emit_and_evict_if_done (store->index ());
91- return {};
92- }},
79+ flush_receiver_{g,
80+ tbb::flow::unlimited,
81+ [this ](flush_message const & msg) -> tbb::flow::continue_msg {
82+ auto const & [index, counts, original_message_id] = msg;
83+ if (index->layer_name () != partition_) {
84+ return {};
85+ }
86+
87+ counter_for (index->hash ()).set_flush_value (counts, original_message_id);
88+ emit_and_evict_if_done (index);
89+ return {};
90+ }},
9391 join_{make_join_or_none (g, std::make_index_sequence<N>{})},
9492 fold_{
9593 g, concurrency, [this , ft = alg.release_algorithm ()](messages_t <N> const & messages, auto &) {
9694 // N.B. The assumption is that a fold will *never* need to cache
9795 // the product store it creates. Any flush messages *do not* need
9896 // to be propagated to downstream nodes.
9997 auto const & msg = most_derived (messages);
100- auto const & store = msg.store ;
101-
102- assert (not store->is_flush ());
98+ auto const & index = msg.store ->index ();
10399
104- if (not store->index ()->parent (partition_)) {
100+ auto fold_index = index->parent (partition_);
101+ if (not fold_index) {
105102 return ;
106103 }
107104
108- auto const & fold_index = store->index ()->parent (partition_);
109- assert (fold_index);
110- auto const & id_hash_for_counter = fold_index->hash ();
105+ auto const & index_hash_for_counter = fold_index->hash ();
111106
112107 call (ft, messages, std::make_index_sequence<N>{});
113- counter_for (id_hash_for_counter ).increment (store-> index () ->layer_hash ());
108+ counter_for (index_hash_for_counter ).increment (index->layer_hash ());
114109
115110 emit_and_evict_if_done (fold_index);
116111 }}
@@ -123,7 +118,7 @@ namespace phlex::experimental {
123118 {
124119 if (auto counter = done_with (fold_index->hash ())) {
125120 auto parent = std::make_shared<product_store>(fold_index, this ->full_name ());
126- commit_ (* parent);
121+ commit_ (parent);
127122 ++product_count_;
128123 output_port<0 >(fold_).try_put ({parent, counter->original_message_id ()});
129124 }
@@ -136,21 +131,21 @@ namespace phlex::experimental {
136131
137132 std::vector<tbb::flow::receiver<message>*> ports () override { return input_ports<N>(join_); }
138133
139- tbb::flow::receiver<message >& flush_port () override { return flush_receiver_; }
134+ tbb::flow::receiver<flush_message >& flush_port () override { return flush_receiver_; }
140135 tbb::flow::sender<message>& sender () override { return output_port<0ull >(fold_); }
141136 tbb::flow::sender<message>& to_output () override { return sender (); }
142137 product_specifications const & output () const override { return output_; }
143138
144139 template <std::size_t ... Is>
145140 void call (function_t const & ft, messages_t <N> const & messages, std::index_sequence<Is...>)
146141 {
147- auto const & parent_id = * most_derived (messages).store ->index ()->parent (partition_);
142+ auto const parent_index = most_derived (messages).store ->index ()->parent (partition_);
148143 // FIXME: Not the safest approach!
149- auto it = results_.find (parent_id );
144+ auto it = results_.find (parent_index-> hash () );
150145 if (it == results_.end ()) {
151146 it =
152147 results_
153- .insert ({parent_id ,
148+ .insert ({parent_index-> hash () ,
154149 initialized_object (std::move (initializer_),
155150 std::make_index_sequence<std::tuple_size_v<InitTuple>>{})})
156151 .first ;
@@ -169,13 +164,13 @@ namespace phlex::experimental {
169164 new R{std::forward<std::tuple_element_t <Is, InitTuple>>(std::get<Is>(tuple))...}};
170165 }
171166
172- void commit_ (product_store & store)
167+ auto commit_ (product_store_ptr & store)
173168 {
174- auto & result = results_.at (* store. index ());
169+ auto & result = results_.at (store-> index ()-> hash ());
175170 if constexpr (requires { send (*result); }) {
176- store. add_product (output ()[0 ].name (), send (*result));
171+ store-> add_product (output ()[0 ].name (), send (*result));
177172 } else {
178- store. add_product (output ()[0 ].name (), std::move (* result));
173+ store-> add_product (output ()[0 ].name (), std::move (result));
179174 }
180175 // Reclaim some memory; it would be better to erase the entire entry from the map,
181176 // but that is not thread-safe.
@@ -186,10 +181,10 @@ namespace phlex::experimental {
186181 input_retriever_types<input_parameter_types> input_{input_arguments<input_parameter_types>()};
187182 product_specifications output_;
188183 std::string partition_;
189- tbb::flow::function_node<message > flush_receiver_;
184+ tbb::flow::function_node<flush_message > flush_receiver_;
190185 join_or_none_t <N> join_;
191186 tbb::flow::multifunction_node<messages_t <N>, messages_t <1 >> fold_;
192- tbb::concurrent_unordered_map<data_cell_index, std::unique_ptr<R>> results_;
187+ tbb::concurrent_unordered_map<data_cell_index::hash_type , std::unique_ptr<R>> results_;
193188 std::atomic<std::size_t > calls_;
194189 std::atomic<std::size_t > product_count_;
195190 };
0 commit comments