diff --git a/sycl/source/detail/scheduler/commands.cpp b/sycl/source/detail/scheduler/commands.cpp index e0f28f1b9c2de..d6514c90c014a 100644 --- a/sycl/source/detail/scheduler/commands.cpp +++ b/sycl/source/detail/scheduler/commands.cpp @@ -169,7 +169,7 @@ class DispatchHostTask { ExecCGCommand *MThisCmd; std::vector MReqToMem; - void waitForEvents() const { + pi_result waitForEvents() const { std::map> RequiredEventsPerPlugin; @@ -185,26 +185,24 @@ class DispatchHostTask { // other available job and resume once all required events are ready. for (auto &PluginWithEvents : RequiredEventsPerPlugin) { std::vector RawEvents = getPiEvents(PluginWithEvents.second); - PluginWithEvents.first->call(RawEvents.size(), - RawEvents.data()); + pi_result Error = + PluginWithEvents.first->call_nocheck( + RawEvents.size(), RawEvents.data()); + + if (Error != PI_SUCCESS) + return Error; } - // wait for dependency host events + // Wait for dependency host events. + // Host events can't throw exceptions so don't try to catch it. for (const EventImplPtr &Event : MThisCmd->MPreparedHostDepsEvents) { Event->waitInternal(); } - } - -public: - DispatchHostTask(ExecCGCommand *ThisCmd, - std::vector ReqToMem) - : MThisCmd{ThisCmd}, MReqToMem(std::move(ReqToMem)) {} - - void operator()() const { - waitForEvents(); - assert(MThisCmd->getCG().getType() == CG::CGTYPE::CODEPLAY_HOST_TASK); + return PI_SUCCESS; + } + pi_result executeHostTask() const { CGHostTask &HostTask = static_cast(MThisCmd->getCG()); try { @@ -219,10 +217,16 @@ class DispatchHostTask { HostTask.MHostTask->call(); } catch (...) { HostTask.MQueue->reportAsyncException(std::current_exception()); + + return PI_ERROR_UNKNOWN; } HostTask.MHostTask.reset(); + return PI_SUCCESS; + } + + void unblockGraph() const { // unblock user empty command here EmptyCommand *EmptyCmd = MThisCmd->MEmptyCmd; assert(EmptyCmd && "No empty command found"); @@ -248,6 +252,35 @@ class DispatchHostTask { Scheduler::enqueueLeavesOfReqUnlocked(Dep.MDepRequirement); } } + +public: + DispatchHostTask(ExecCGCommand *ThisCmd, + std::vector ReqToMem) + : MThisCmd{ThisCmd}, MReqToMem(std::move(ReqToMem)) {} + + void operator()() const { + assert(MThisCmd->getCG().getType() == CG::CGTYPE::CODEPLAY_HOST_TASK); + + CGHostTask &HostTask = static_cast(MThisCmd->getCG()); + + pi_result WaitResult = waitForEvents(); + if (WaitResult != PI_SUCCESS) { + std::exception_ptr EPtr = std::make_exception_ptr(sycl::runtime_error( + std::string("Couldn't wait for host-task's dependencies"), + WaitResult)); + HostTask.MQueue->reportAsyncException(EPtr); + + // reset host-task's lambda and quit + HostTask.MHostTask.reset(); + return; + } + + if (executeHostTask() != PI_SUCCESS) + // The failure was reported already. No need to duplicate it here. + return; + + unblockGraph(); + } }; void Command::waitForPreparedHostEvents() const {