Skip to content

Commit d304712

Browse files
vossmjpkboyarinov
andauthored
Fix for overwrite_node to continue_node accounting (#1729)
Co-authored-by: Konstantin Boyarinov <[email protected]>
1 parent e3ab04b commit d304712

File tree

4 files changed

+69
-3
lines changed

4 files changed

+69
-3
lines changed

include/oneapi/tbb/flow_graph.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ class receiver {
329329
virtual graph& graph_reference() const = 0;
330330

331331
template<typename TT, typename M> friend class successor_cache;
332+
template< typename TTT > friend class overwrite_node;
332333
virtual bool is_continue_receiver() { return false; }
333334

334335
// TODO revamp: reconsider the inheritance and move node priority out of receiver
@@ -3318,6 +3319,12 @@ class overwrite_node : public graph_node, public receiver<T>, public sender<T> {
33183319
spin_mutex::scoped_lock l( my_mutex );
33193320
if (my_buffer_is_valid && is_graph_active( my_graph )) {
33203321
// We have a valid value that must be forwarded immediately.
3322+
if (s.is_continue_receiver()) {
3323+
// try_put can never fail, since continue_receivers always accept
3324+
my_successors.register_successor( s );
3325+
s.try_put( my_buffer );
3326+
return true;
3327+
}
33213328
bool ret = s.try_put( my_buffer );
33223329
if ( ret ) {
33233330
// We add the successor that accepted our put

test/common/graph_utils.h

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2005-2024 Intel Corporation
2+
Copyright (c) 2005-2025 Intel Corporation
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -696,6 +696,47 @@ void test_reserving_nodes() {
696696
CHECK(end_receiver.my_count == 2 * N);
697697
}
698698

699+
template<typename BufferNode>
700+
void test_nested_make_edge_single_item_buffer_to_continue_receiver() {
701+
tbb::flow::graph g;
702+
703+
using msg_t = tbb::flow::continue_msg;
704+
using cnode_t = tbb::flow::continue_node<msg_t>;
705+
706+
std::atomic<int> count(0);
707+
708+
// make a single item buffer and fill it
709+
BufferNode b{g};
710+
b.try_put(msg_t{});
711+
712+
cnode_t execute_one_time{g,
713+
[&](const msg_t& m) {
714+
++count;
715+
return m;
716+
}};
717+
718+
cnode_t edge_adder{g,
719+
[&](const msg_t& m) {
720+
// should increment predecessor count on execute_one_time
721+
// should NOT cause execute_one_time to immediately execute
722+
// since it has 2 predecessors, edge_adder and b
723+
tbb::flow::make_edge(b, execute_one_time);
724+
return m;
725+
}};
726+
727+
tbb::flow::make_edge(edge_adder, execute_one_time);
728+
729+
// execute_one should execute
730+
edge_adder.try_put(msg_t{});
731+
g.wait_for_all();
732+
733+
// execute_one should NOT execute, it has 2 predecessors and
734+
// has seen a total of 3 messages
735+
execute_one_time.try_put(msg_t{});
736+
g.wait_for_all();
737+
CHECK_MESSAGE ((count == 1), "node should only execute once");
738+
}
739+
699740
namespace lightweight_testing {
700741

701742
typedef std::tuple<int, int> output_tuple_type;

test/tbb/test_overwrite_node.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2005-2024 Intel Corporation
2+
Copyright (c) 2005-2025 Intel Corporation
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -423,3 +423,13 @@ TEST_CASE("test overwrite_node try_put_and_wait") {
423423
test_overwrite_node_try_put_and_wait();
424424
}
425425
#endif
426+
427+
//! Test for nested make_edge from predecessor of continue_node that adds edge to overwrite_node
428+
//! \brief \ref error_guessing
429+
TEST_CASE("Nested make_edge to continue_node") {
430+
tbb::flow::graph g;
431+
432+
using msg_t = tbb::flow::continue_msg;
433+
using buffer_t = tbb::flow::overwrite_node<msg_t>;
434+
test_nested_make_edge_single_item_buffer_to_continue_receiver<buffer_t>();
435+
}

test/tbb/test_write_once_node.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2005-2024 Intel Corporation
2+
Copyright (c) 2005-2025 Intel Corporation
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -380,3 +380,11 @@ TEST_CASE("test write_once_node try_put_and_wait") {
380380
test_try_put_and_wait();
381381
}
382382
#endif
383+
384+
//! Test for nested make_edge from predecessor of continue_node that adds edge to write_once_node
385+
//! \brief \ref error_guessing
386+
TEST_CASE("Nested make_edge write_once_node to continue_node") {
387+
using msg_t = tbb::flow::continue_msg;
388+
using buffer_t = tbb::flow::write_once_node<msg_t>;
389+
test_nested_make_edge_single_item_buffer_to_continue_receiver<buffer_t>();
390+
}

0 commit comments

Comments
 (0)