File tree Expand file tree Collapse file tree 5 files changed +53
-8
lines changed Expand file tree Collapse file tree 5 files changed +53
-8
lines changed Original file line number Diff line number Diff line change @@ -95,16 +95,14 @@ event_impl::event_impl(QueueImplPtr Queue) : MQueue(Queue) {
95
95
96
96
void event_impl::wait (
97
97
std::shared_ptr<cl::sycl::detail::event_impl> Self) const {
98
-
99
98
if (MEvent)
100
99
// presence of MEvent means the command has been enqueued, so no need to
101
100
// go via the slow path event waiting in the scheduler
102
101
waitInternal ();
103
102
else if (MCommand)
104
- detail::Scheduler::getInstance ().waitForEvent (std::move ( Self) );
103
+ detail::Scheduler::getInstance ().waitForEvent (Self);
105
104
if (MCommand && !SYCLConfig<SYCL_DISABLE_EXECUTION_GRAPH_CLEANUP>::get ())
106
- detail::Scheduler::getInstance ().cleanupFinishedCommands (
107
- static_cast <Command *>(MCommand));
105
+ detail::Scheduler::getInstance ().cleanupFinishedCommands (std::move (Self));
108
106
}
109
107
110
108
void event_impl::wait_and_throw (
Original file line number Diff line number Diff line change @@ -123,9 +123,13 @@ void Scheduler::waitForEvent(EventImplPtr Event) {
123
123
GraphProcessor::waitForEvent (std::move (Event));
124
124
}
125
125
126
- void Scheduler::cleanupFinishedCommands (Command *FinishedCmd ) {
126
+ void Scheduler::cleanupFinishedCommands (EventImplPtr FinishedEvent ) {
127
127
std::lock_guard<std::mutex> lock (MGraphLock);
128
- MGraphBuilder.cleanupFinishedCommands (FinishedCmd);
128
+ Command *FinishedCmd = static_cast <Command *>(FinishedEvent->getCommand ());
129
+ // The command might have been cleaned up (and set to nullptr) by another
130
+ // thread
131
+ if (FinishedCmd)
132
+ MGraphBuilder.cleanupFinishedCommands (FinishedCmd);
129
133
}
130
134
131
135
void Scheduler::removeMemoryObject (detail::SYCLMemObjI *MemObj) {
Original file line number Diff line number Diff line change @@ -79,7 +79,7 @@ class Scheduler {
79
79
80
80
// Removes finished non-leaf non-alloca commands from the subgraph (assuming
81
81
// that all its commands have been waited for).
82
- void cleanupFinishedCommands (Command *FinishedCmd );
82
+ void cleanupFinishedCommands (EventImplPtr FinishedEvent );
83
83
84
84
// Creates nodes in the graph, that update Req with the pointer to the host
85
85
// memory which contains the latest data of the memory object. New
Original file line number Diff line number Diff line change
1
+ // UNSUPPORTED: windows
2
+ // RUN: %clangxx -fsycl %s -o %t.out -lpthread
3
+ // RUN: %CPU_RUN_PLACEHOLDER %t.out
4
+ #include < CL/sycl.hpp>
5
+
6
+ #include < cassert>
7
+ #include < cstddef>
8
+ #include < thread>
9
+ #include < vector>
10
+
11
+ // This test checks that the command graph cleanup works properly when
12
+ // invoked from multiple threads.
13
+ using namespace cl ::sycl;
14
+
15
+ class Foo ;
16
+
17
+ event submitTask (queue &Q, buffer<int , 1 > &Buf) {
18
+ return Q.submit ([&](handler &Cgh) {
19
+ auto Acc = Buf.get_access <access::mode::read_write>(Cgh);
20
+ Cgh.single_task <Foo>([=]() { Acc[0 ] = 42 ; });
21
+ });
22
+ }
23
+
24
+ int main () {
25
+ queue Q;
26
+ buffer<int , 1 > Buf (range<1 >(1 ));
27
+
28
+ // Create multiple commands, each one dependent on the previous
29
+ std::vector<event> Events;
30
+ const std::size_t NTasks = 16 ;
31
+ for (std::size_t I = 0 ; I < NTasks; ++I)
32
+ Events.push_back (submitTask (Q, Buf));
33
+
34
+ // Initiate cleanup from multiple threads
35
+ std::vector<std::thread> Threads;
36
+ for (event &E : Events)
37
+ Threads.emplace_back ([&]() { E.wait (); });
38
+ for (std::thread &T : Threads)
39
+ T.join ();
40
+ }
Original file line number Diff line number Diff line change 1
1
// RUN: %clangxx -fsycl -I %sycl_source_dir %s -o %t.out
2
2
// RUN: %t.out
3
3
#include < CL/sycl.hpp>
4
+ #include < detail/event_impl.hpp>
4
5
#include < detail/scheduler/scheduler.hpp>
5
6
6
7
#include < algorithm>
@@ -76,7 +77,9 @@ int main() {
76
77
addEdge (InnerA, &LeafA, &AllocaA);
77
78
addEdge (InnerA, InnerB, &AllocaB);
78
79
79
- TS.cleanupFinishedCommands (InnerA);
80
+ std::shared_ptr<detail::event_impl> Event{new detail::event_impl{}};
81
+ Event->setCommand (InnerA);
82
+ TS.cleanupFinishedCommands (Event);
80
83
TS.removeRecordForMemObj (detail::getSyclObjImpl (BufC).get ());
81
84
82
85
assert (NInnerCommandsAlive == 0 );
You can’t perform that action at this time.
0 commit comments