Skip to content

Commit 310b3e2

Browse files
v-klochkovvladimirlaz
authored andcommitted
[SYCL] Added missing wait(), wait_and_throw(), get_wait_list() methods to event class
Signed-off-by: Klochkov, Vyacheslav N <[email protected]> Signed-off-by: Vladimir Lazarev <[email protected]>
1 parent c701af3 commit 310b3e2

File tree

6 files changed

+127
-11
lines changed

6 files changed

+127
-11
lines changed

sycl/include/CL/sycl/detail/event_impl.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ class event_impl {
3333
// Self is needed in order to pass shared_ptr to Scheduler.
3434
void wait(std::shared_ptr<cl::sycl::detail::event_impl> Self) const;
3535

36+
void wait_and_throw(std::shared_ptr<cl::sycl::detail::event_impl> Self);
37+
3638
template <info::event_profiling param>
3739
typename info::param_traits<info::event_profiling, param>::return_type
3840
get_profiling_info() const;

sycl/include/CL/sycl/detail/scheduler/scheduler.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <iostream>
2323
#include <map>
2424
#include <set>
25+
#include <unordered_set>
2526
#include <vector>
2627

2728
namespace cl {
@@ -157,6 +158,10 @@ class Scheduler {
157158
// Waits for the event passed.
158159
void waitForEvent(EventImplPtr Event);
159160

161+
// Calls asynchronous handler for the passed event Event
162+
// and for those other events that Event depends on.
163+
void throwForEventRecursive(EventImplPtr Event);
164+
160165
// Adds new node to graph, creating an Alloca and MemMove commands if
161166
// needed.
162167
cl::sycl::event addNode(Node NewNode);
@@ -195,6 +200,12 @@ class Scheduler {
195200
enum DumpOptions { Text = 0, WholeGraph = 1, RunGraph = 2 };
196201
bool getDumpFlagValue(DumpOptions DumpOption);
197202

203+
// Recursively walks through the dependencies and initializes
204+
// the given EventsSet with the events that the Event
205+
// waits for. The unordered_set is used to collect unuque events,
206+
// and the unordered_set is convenient as it does not need operator<().
207+
void getDepEventsRecursive(std::unordered_set<cl::sycl::event> &EventsSet,
208+
EventImplPtr Event);
198209
protected:
199210
// TODO: Add releasing of OpenCL buffers.
200211

@@ -208,7 +219,6 @@ class Scheduler {
208219
// Recursively generates dot records for the command passed and all that the
209220
// command depends on.
210221
void printGraphForCommand(CommandPtr Cmd, std::ostream &Stream) const;
211-
212222
private:
213223
Scheduler();
214224
~Scheduler();
@@ -223,6 +233,15 @@ class Scheduler {
223233

224234
Scheduler(Scheduler const &) = delete;
225235
Scheduler &operator=(Scheduler const &) = delete;
236+
237+
// Returns the pointer to the command associated with the given event,
238+
// or nullptr if none is found.
239+
CommandPtr getCmdForEvent(EventImplPtr Event);
240+
241+
// Basically it is the helper method for throwForEventRecursive() now.
242+
// It calls async handler for the command Cmd and those other
243+
// commands that Cmd depends on.
244+
void throwForCmdRecursive(std::shared_ptr<Command> Cmd);
226245
};
227246

228247
} // namespace simple_scheduler

sycl/include/CL/sycl/event.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@ class event {
4141

4242
bool is_host() const;
4343

44-
void wait() const;
44+
vector_class<event> get_wait_list();
4545

46-
// vector_class<event> get_wait_list();
46+
void wait();
4747

48-
// static void wait(const vector_class<event> &eventList);
48+
static void wait(const vector_class<event> &EventList);
4949

50-
// void wait_and_throw();
50+
void wait_and_throw();
5151

52-
// static void wait_and_throw(const vector_class<event> &eventList);
52+
static void wait_and_throw(const vector_class<event> &EventList);
5353

5454
template <info::event param>
5555
typename info::param_traits<info::event, param>::return_type get_info() const;

sycl/source/detail/event_impl.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ void event_impl::wait(
7272
simple_scheduler::Scheduler::getInstance().waitForEvent(Self);
7373
}
7474

75+
76+
void event_impl::wait_and_throw(
77+
std::shared_ptr<cl::sycl::detail::event_impl> Self) {
78+
wait(Self);
79+
cl::sycl::simple_scheduler::Scheduler::getInstance().throwForEventRecursive(
80+
Self);
81+
}
82+
7583
template <>
7684
cl_ulong
7785
event_impl::get_profiling_info<info::event_profiling::command_submit>() const {

sycl/source/detail/scheduler/scheduler.cpp

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <cassert>
1818
#include <fstream>
1919
#include <set>
20+
#include <unordered_set>
2021
#include <vector>
2122

2223
namespace cl {
@@ -40,16 +41,31 @@ void Node::addInteropArg(shared_ptr_class<void> Ptr, size_t Size,
4041
m_InteropArgs.emplace_back(Ptr, Size, ArgIndex, BufReq);
4142
}
4243

43-
// Waits for the event passed.
44-
void Scheduler::waitForEvent(EventImplPtr Event) {
44+
CommandPtr Scheduler::getCmdForEvent(EventImplPtr Event) {
45+
// TODO: Currently, this method searches for the command in
46+
// m_BuffersEvolution, which seems expensive, especially
47+
// taking into account that this operation may be called
48+
// from another loop. Need to optimize this method, for example,
49+
// by adding a direct link from 'event' to the 'command' it
50+
// is associated with.
4551
for (auto &BufEvolution : m_BuffersEvolution) {
4652
for (auto &Cmd : BufEvolution.second) {
4753
if (detail::getSyclObjImpl(Cmd->getEvent()) == Event) {
48-
enqueueAndWaitForCommand(Cmd);
49-
return;
54+
return Cmd;
5055
}
5156
}
5257
}
58+
return nullptr;
59+
}
60+
61+
// Waits for the event passed.
62+
void Scheduler::waitForEvent(EventImplPtr Event) {
63+
auto Cmd = getCmdForEvent(Event);
64+
if (Cmd) {
65+
enqueueAndWaitForCommand(Cmd);
66+
return;
67+
}
68+
5369
for (auto &Evnt : m_EventsWithoutRequirements) {
5470
if (Evnt == Event) {
5571
Evnt->waitInternal();
@@ -58,6 +74,51 @@ void Scheduler::waitForEvent(EventImplPtr Event) {
5874
}
5975
}
6076

77+
// Calls async handler for the given command Cmd and those other
78+
// commands that Cmd depends on.
79+
void Scheduler::throwForCmdRecursive(std::shared_ptr<Command> Cmd) {
80+
if (Cmd == nullptr) {
81+
return;
82+
}
83+
84+
auto QImpl = Cmd->getQueue();
85+
QImpl->throw_asynchronous();
86+
87+
std::vector<std::pair<std::shared_ptr<Command>, BufferReqPtr>> Deps =
88+
Cmd->getDependencies();
89+
for (auto D : Deps) {
90+
throwForCmdRecursive(D.first);
91+
}
92+
}
93+
94+
// Calls async handler for the given event Event and those other
95+
// events that Event depends on.
96+
void Scheduler::throwForEventRecursive(EventImplPtr Event) {
97+
auto Cmd = getCmdForEvent(Event);
98+
if (Cmd) {
99+
throwForCmdRecursive(Cmd);
100+
}
101+
}
102+
103+
void Scheduler::getDepEventsRecursive(
104+
std::unordered_set<cl::sycl::event> &EventsSet,
105+
EventImplPtr Event) {
106+
auto Cmd = getCmdForEvent(Event);
107+
if (Cmd == nullptr) {
108+
return;
109+
}
110+
111+
std::vector<std::pair<std::shared_ptr<Command>, BufferReqPtr>> Deps =
112+
Cmd->getDependencies();
113+
for (auto D : Deps) {
114+
auto DepEvent = D.first->getEvent();
115+
EventsSet.insert(DepEvent);
116+
117+
auto DepEventImpl = cl::sycl::detail::getSyclObjImpl(DepEvent);
118+
getDepEventsRecursive(EventsSet, DepEventImpl);
119+
}
120+
}
121+
61122
void Scheduler::print(std::ostream &Stream) const {
62123
Stream << "======================================" << std::endl;
63124
Stream << "Graph dump" << std::endl;

sycl/source/event.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111
#include <CL/sycl/detail/common.hpp>
1212
#include <CL/sycl/detail/event_impl.hpp>
1313
#include <CL/sycl/event.hpp>
14+
#include <CL/sycl/detail/scheduler/scheduler.h>
15+
1416
#include <CL/sycl/stl.hpp>
1517

1618
#include <memory>
19+
#include <unordered_set>
1720

1821
namespace cl {
1922
namespace sycl {
@@ -31,7 +34,30 @@ cl_event event::get() { return impl->get(); }
3134

3235
bool event::is_host() const { return impl->is_host(); }
3336

34-
void event::wait() const { impl->wait(impl); }
37+
void event::wait() { impl->wait(impl); }
38+
39+
void event::wait(const vector_class<event> &EventList) {
40+
for (auto E : EventList) {
41+
E.wait();
42+
}
43+
}
44+
45+
void event::wait_and_throw() { impl->wait_and_throw(impl); }
46+
47+
void event::wait_and_throw(const vector_class<event> &EventList) {
48+
for (auto E : EventList) {
49+
E.wait_and_throw();
50+
}
51+
}
52+
53+
vector_class<event> event::get_wait_list() {
54+
std::unordered_set<event> DepEventsSet;
55+
cl::sycl::simple_scheduler::Scheduler::getInstance().getDepEventsRecursive(
56+
DepEventsSet, impl);
57+
58+
vector_class<event> DepEventsVec(DepEventsSet.begin(), DepEventsSet.end());
59+
return DepEventsVec;
60+
}
3561

3662
event::event(std::shared_ptr<detail::event_impl> event_impl)
3763
: impl(event_impl) {}

0 commit comments

Comments
 (0)