From d622da0165d0aa1865d134e9f8632cbdf99adea1 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Mon, 28 Mar 2022 13:23:56 +0300 Subject: [PATCH 01/21] Fix lost dependencies in case of depends_on usage and blocking commands Signed-off-by: Tikhomirova, Kseniya --- sycl/source/detail/scheduler/commands.hpp | 4 ++++ sycl/source/detail/scheduler/graph_processor.cpp | 14 +++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sycl/source/detail/scheduler/commands.hpp b/sycl/source/detail/scheduler/commands.hpp index 0a4a55579c078..537d5c2e1013c 100644 --- a/sycl/source/detail/scheduler/commands.hpp +++ b/sycl/source/detail/scheduler/commands.hpp @@ -252,6 +252,10 @@ class Command { return MPreparedHostDepsEvents; } + const std::vector &getPreparedDepsEvents() const { + return MPreparedDepsEvents; + } + /// Contains list of dependencies(edges) std::vector MDeps; /// Contains list of commands that depend on the command. diff --git a/sycl/source/detail/scheduler/graph_processor.cpp b/sycl/source/detail/scheduler/graph_processor.cpp index 6e533df30a09c..672a885a467b5 100644 --- a/sycl/source/detail/scheduler/graph_processor.cpp +++ b/sycl/source/detail/scheduler/graph_processor.cpp @@ -58,11 +58,15 @@ bool Scheduler::GraphProcessor::enqueueCommand( return false; } - // Recursively enqueue all the dependencies first and - // exit immediately if any of the commands cannot be enqueued. - for (DepDesc &Dep : Cmd->MDeps) { - if (!enqueueCommand(Dep.MDepCommand, EnqueueResult, ToCleanUp, Blocking)) - return false; + // Recursively enqueue all explicit dependencies first (deps built via + // depends_on) and implicit (mem obj requirement) and exit immediately if any + // of the commands cannot be enqueued. If not to do that we may end up with + // the case when not all MPreparedDepsEvents contain PiEvent and on enqueueImp + // some of dependencies may be lost. + for (const EventImplPtr &Event : Cmd->getPreparedDepsEvents()) { + if (Command *DepCmd = static_cast(Event->getCommand())) + if (!enqueueCommand(DepCmd, EnqueueResult, ToCleanUp, Blocking)) + return false; } // Asynchronous host operations (amongst dependencies of an arbitrary command) From f4b9a4f6852ea0b93c9b55a0790dcb7daa0d85bc Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Mon, 28 Mar 2022 16:03:51 +0300 Subject: [PATCH 02/21] Move empty node commands cleanup to post-enqueue cleanup (fixes cleanup of blocked commands) Signed-off-by: Tikhomirova, Kseniya --- sycl/source/detail/scheduler/commands.cpp | 5 +---- sycl/source/detail/scheduler/scheduler.cpp | 6 ------ 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/sycl/source/detail/scheduler/commands.cpp b/sycl/source/detail/scheduler/commands.cpp index f9b36419f6294..b285174ee31a9 100644 --- a/sycl/source/detail/scheduler/commands.cpp +++ b/sycl/source/detail/scheduler/commands.cpp @@ -589,10 +589,7 @@ const QueueImplPtr &Command::getWorkerQueue() const { return MQueue; } bool Command::producesPiEvent() const { return true; } -bool Command::supportsPostEnqueueCleanup() const { - // Isolated commands are cleaned up separately - return !MUsers.empty() || !MDeps.empty(); -} +bool Command::supportsPostEnqueueCleanup() const { return true; } Command *Command::addDep(DepDesc NewDep, std::vector &ToCleanUp) { Command *ConnectionCmd = nullptr; diff --git a/sycl/source/detail/scheduler/scheduler.cpp b/sycl/source/detail/scheduler/scheduler.cpp index 8354e9c8d7b0b..d68ab79126350 100644 --- a/sycl/source/detail/scheduler/scheduler.cpp +++ b/sycl/source/detail/scheduler/scheduler.cpp @@ -156,12 +156,6 @@ EventImplPtr Scheduler::addCG(std::unique_ptr CommandGroup, CleanUp(); std::rethrow_exception(std::current_exception()); } - - // If there are no memory dependencies decouple and free the command. - // Though, dismiss ownership of native kernel command group as it's - // resources may be in use by backend and synchronization point here is - // at native kernel execution finish. - CleanUp(); } } cleanupCommands(ToCleanUp); From 6bc9474d9bf817607c5afc8e1f4b46de37b77ad1 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Mon, 28 Mar 2022 17:09:05 +0300 Subject: [PATCH 03/21] Update unit test for post enqueue cleanup & wait Signed-off-by: Tikhomirova, Kseniya --- sycl/unittests/scheduler/WaitAfterCleanup.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sycl/unittests/scheduler/WaitAfterCleanup.cpp b/sycl/unittests/scheduler/WaitAfterCleanup.cpp index 1f21dae6ff597..54b7e15746f8c 100644 --- a/sycl/unittests/scheduler/WaitAfterCleanup.cpp +++ b/sycl/unittests/scheduler/WaitAfterCleanup.cpp @@ -8,10 +8,24 @@ #include "SchedulerTest.hpp" #include "SchedulerTestUtils.hpp" +#include using namespace cl::sycl; +TEST_F(SchedulerTest, PostEnqueueCleanupForCommandDefault) { + auto Cmd = new MockCommand(detail::getSyclObjImpl(MQueue)); + auto Event = Cmd->getEvent(); + ASSERT_FALSE(Event == nullptr) << "Command must have an event\n"; + + detail::Scheduler::getInstance().waitForEvent(Event); + EXPECT_EQ(Event->getCommand(), nullptr) << "Command should be cleaned up\n"; +} + TEST_F(SchedulerTest, WaitAfterCleanup) { + unittest::ScopedEnvVar DisabledCleanup{ + "SYCL_DISABLE_POST_ENQUEUE_CLEANUP", "1", + detail::SYCLConfig::reset}; + auto Cmd = new MockCommand(detail::getSyclObjImpl(MQueue)); auto Event = Cmd->getEvent(); ASSERT_FALSE(Event == nullptr) << "Command must have an event\n"; From 1238b1ea1fd7eea2133db479583acb6c59dd6c0f Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Tue, 29 Mar 2022 17:18:25 +0300 Subject: [PATCH 04/21] Fix lost dependencies Signed-off-by: Tikhomirova, Kseniya --- sycl/source/detail/scheduler/graph_processor.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sycl/source/detail/scheduler/graph_processor.cpp b/sycl/source/detail/scheduler/graph_processor.cpp index 672a885a467b5..0f250732253e0 100644 --- a/sycl/source/detail/scheduler/graph_processor.cpp +++ b/sycl/source/detail/scheduler/graph_processor.cpp @@ -58,11 +58,15 @@ bool Scheduler::GraphProcessor::enqueueCommand( return false; } - // Recursively enqueue all explicit dependencies first (deps built via - // depends_on) and implicit (mem obj requirement) and exit immediately if any - // of the commands cannot be enqueued. If not to do that we may end up with - // the case when not all MPreparedDepsEvents contain PiEvent and on enqueueImp - // some of dependencies may be lost. + // Recursively enqueue all the implicit dependencies first and + // exit immediately if any of the commands cannot be enqueued. + for (DepDesc &Dep : Cmd->MDeps) { + if (!enqueueCommand(Dep.MDepCommand, EnqueueResult, ToCleanUp, Blocking)) + return false; + } + + // Recursively enqueue all the implicit + explicit dependencies first and + // exit immediately if any of the commands cannot be enqueued. for (const EventImplPtr &Event : Cmd->getPreparedDepsEvents()) { if (Command *DepCmd = static_cast(Event->getCommand())) if (!enqueueCommand(DepCmd, EnqueueResult, ToCleanUp, Blocking)) From 03e7541c9f51b4a87ef4025280fd49b9b25ac05d Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Thu, 31 Mar 2022 17:14:50 +0300 Subject: [PATCH 05/21] Move event skip for in-order queue to getPIEvents Signed-off-by: Tikhomirova, Kseniya --- sycl/source/detail/event_impl.hpp | 7 +++ sycl/source/detail/scheduler/commands.cpp | 48 +++++++++++-------- sycl/source/detail/scheduler/commands.hpp | 11 +++-- .../detail/scheduler/graph_processor.cpp | 7 --- 4 files changed, 43 insertions(+), 30 deletions(-) diff --git a/sycl/source/detail/event_impl.hpp b/sycl/source/detail/event_impl.hpp index 505543143ed5f..1426fdc73e765 100644 --- a/sycl/source/detail/event_impl.hpp +++ b/sycl/source/detail/event_impl.hpp @@ -209,6 +209,11 @@ class event_impl { } bool needsCleanupAfterWait() { return MNeedsCleanupAfterWait; } + /// Returns worker queue for command. + /// + /// @return a reference to MWorkerQueue. + QueueImplPtr &getWorkerQueue() { return MWorkerQueue; }; + private: // When instrumentation is enabled emits trace event for event wait begin and // returns the telemetry event generated for the wait @@ -228,6 +233,8 @@ class event_impl { std::weak_ptr MQueue; const bool MIsProfilingEnabled = false; + QueueImplPtr MWorkerQueue; + /// Dependency events prepared for waiting by backend. std::vector MPreparedDepsEvents; std::vector MPreparedHostDepsEvents; diff --git a/sycl/source/detail/scheduler/commands.cpp b/sycl/source/detail/scheduler/commands.cpp index b285174ee31a9..f3ca80af3afac 100644 --- a/sycl/source/detail/scheduler/commands.cpp +++ b/sycl/source/detail/scheduler/commands.cpp @@ -169,12 +169,26 @@ static std::string commandToName(Command::CommandType Type) { } #endif -static std::vector -getPiEvents(const std::vector &EventImpls) { +std::vector +Command::getPiEvents(const std::vector &EventImpls) const { std::vector RetPiEvents; for (auto &EventImpl : EventImpls) { - if (EventImpl->getHandleRef() != nullptr) - RetPiEvents.push_back(EventImpl->getHandleRef()); + if (EventImpl->getHandleRef() == nullptr) + continue; + + // Do not add redundant event dependencies for in-order queues. + // At this stage dependency is definitely pi task and need to check if + // current one is a host task. In this case we should not skip pi event due + // to different sync mechanisms for different task types on in-order queue. + auto WorkerQueue = getWorkerQueue(); + if (EventImpl->getWorkerQueue() == WorkerQueue && + WorkerQueue->has_property() && + (MType != CommandType::RUN_CG /* host task has this type also */ || + (static_cast(this))->getCG().getType() != + CG::CGTYPE::CodeplayHostTask)) + continue; + + RetPiEvents.push_back(EventImpl->getHandleRef()); } return RetPiEvents; @@ -206,7 +220,8 @@ class DispatchHostTask { // sophisticated waiting mechanism to allow to utilize this thread for any // other available job and resume once all required events are ready. for (auto &PluginWithEvents : RequiredEventsPerPlugin) { - std::vector RawEvents = getPiEvents(PluginWithEvents.second); + std::vector RawEvents = + MThisCmd->getPiEvents(PluginWithEvents.second); try { PluginWithEvents.first->call(RawEvents.size(), RawEvents.data()); @@ -359,10 +374,12 @@ void Command::waitForEvents(QueueImplPtr Queue, Command::Command(CommandType Type, QueueImplPtr Queue) : MQueue(std::move(Queue)), MEvent(std::make_shared(MQueue)), + MWorkerQueue(MEvent->getWorkerQueue()), MPreparedDepsEvents(MEvent->getPreparedDepsEvents()), MPreparedHostDepsEvents(MEvent->getPreparedHostDepsEvents()), MType(Type) { MSubmittedQueue = MQueue; + MWorkerQueue = MQueue; MEvent->setCommand(this); MEvent->setContextImpl(MQueue->getContextImplPtr()); MEnqueueStatus = EnqueueResultT::SyclEnqueueReady; @@ -564,12 +581,6 @@ Command *Command::processDepEvent(EventImplPtr DepEvent, const DepDesc &Dep, Command *ConnectionCmd = nullptr; - // Do not add redundant event dependencies for in-order queues. - if (Dep.MDepCommand && Dep.MDepCommand->getWorkerQueue() == WorkerQueue && - WorkerQueue->has_property() && - getType() != CommandType::HOST_TASK) - return nullptr; - ContextImplPtr DepEventContext = DepEvent->getContextImpl(); // If contexts don't match we'll connect them using host task if (DepEventContext != WorkerContext && !WorkerContext->is_host()) { @@ -585,7 +596,10 @@ const ContextImplPtr &Command::getWorkerContext() const { return MQueue->getContextImplPtr(); } -const QueueImplPtr &Command::getWorkerQueue() const { return MQueue; } +const QueueImplPtr &Command::getWorkerQueue() const { + assert(MWorkerQueue && "MWorkerQueue must not be nullptr"); + return MWorkerQueue; +} bool Command::producesPiEvent() const { return true; } @@ -1258,6 +1272,7 @@ MemCpyCommand::MemCpyCommand(Requirement SrcReq, MDstAllocaCmd(DstAllocaCmd) { if (!MSrcQueue->is_host()) MEvent->setContextImpl(MSrcQueue->getContextImplPtr()); + MWorkerQueue = MQueue->is_host() ? MSrcQueue : MQueue; emitInstrumentationDataProxy(); } @@ -1296,10 +1311,6 @@ const ContextImplPtr &MemCpyCommand::getWorkerContext() const { return getWorkerQueue()->getContextImplPtr(); } -const QueueImplPtr &MemCpyCommand::getWorkerQueue() const { - return MQueue->is_host() ? MSrcQueue : MQueue; -} - bool MemCpyCommand::producesPiEvent() const { // TODO remove this workaround once the batching issue is addressed in Level // Zero plugin. @@ -1439,6 +1450,7 @@ MemCpyCommandHost::MemCpyCommandHost(Requirement SrcReq, MSrcAllocaCmd(SrcAllocaCmd), MDstReq(std::move(DstReq)), MDstPtr(DstPtr) { if (!MSrcQueue->is_host()) MEvent->setContextImpl(MSrcQueue->getContextImplPtr()); + MWorkerQueue = MQueue->is_host() ? MSrcQueue : MQueue; emitInstrumentationDataProxy(); } @@ -1477,10 +1489,6 @@ const ContextImplPtr &MemCpyCommandHost::getWorkerContext() const { return getWorkerQueue()->getContextImplPtr(); } -const QueueImplPtr &MemCpyCommandHost::getWorkerQueue() const { - return MQueue->is_host() ? MSrcQueue : MQueue; -} - cl_int MemCpyCommandHost::enqueueImp() { const QueueImplPtr &Queue = getWorkerQueue(); waitForPreparedHostEvents(); diff --git a/sycl/source/detail/scheduler/commands.hpp b/sycl/source/detail/scheduler/commands.hpp index 537d5c2e1013c..64efea2cc2133 100644 --- a/sycl/source/detail/scheduler/commands.hpp +++ b/sycl/source/detail/scheduler/commands.hpp @@ -199,7 +199,7 @@ class Command { /// Get the queue this command will be submitted to. Could differ from MQueue /// for memory copy commands. - virtual const QueueImplPtr &getWorkerQueue() const; + const QueueImplPtr &getWorkerQueue() const; /// Returns true iff the command produces a PI event on non-host devices. virtual bool producesPiEvent() const; @@ -207,11 +207,18 @@ class Command { /// Returns true iff this command can be freed by post enqueue cleanup. virtual bool supportsPostEnqueueCleanup() const; + /// Collect PI events from EventImpls and filter out some of them in case of + /// in order queue + std::vector + getPiEvents(const std::vector &EventImpls) const; + protected: QueueImplPtr MQueue; QueueImplPtr MSubmittedQueue; EventImplPtr MEvent; + QueueImplPtr &MWorkerQueue; + /// Dependency events prepared for waiting by backend. /// See processDepEvent for details. std::vector &MPreparedDepsEvents; @@ -493,7 +500,6 @@ class MemCpyCommand : public Command { const Requirement *getRequirement() const final { return &MDstReq; } void emitInstrumentationData() final; const ContextImplPtr &getWorkerContext() const final; - const QueueImplPtr &getWorkerQueue() const final; bool producesPiEvent() const final; private: @@ -518,7 +524,6 @@ class MemCpyCommandHost : public Command { const Requirement *getRequirement() const final { return &MDstReq; } void emitInstrumentationData() final; const ContextImplPtr &getWorkerContext() const final; - const QueueImplPtr &getWorkerQueue() const final; private: cl_int enqueueImp() final; diff --git a/sycl/source/detail/scheduler/graph_processor.cpp b/sycl/source/detail/scheduler/graph_processor.cpp index 0f250732253e0..f02cbea1a2f94 100644 --- a/sycl/source/detail/scheduler/graph_processor.cpp +++ b/sycl/source/detail/scheduler/graph_processor.cpp @@ -58,13 +58,6 @@ bool Scheduler::GraphProcessor::enqueueCommand( return false; } - // Recursively enqueue all the implicit dependencies first and - // exit immediately if any of the commands cannot be enqueued. - for (DepDesc &Dep : Cmd->MDeps) { - if (!enqueueCommand(Dep.MDepCommand, EnqueueResult, ToCleanUp, Blocking)) - return false; - } - // Recursively enqueue all the implicit + explicit dependencies first and // exit immediately if any of the commands cannot be enqueued. for (const EventImplPtr &Event : Cmd->getPreparedDepsEvents()) { From 8e2ea56a9043779e544dde8892e6e5c22c77f8f5 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Mon, 28 Mar 2022 11:01:14 +0300 Subject: [PATCH 06/21] Add test with kernel usage and make MockHandler common Signed-off-by: Tikhomirova, Kseniya --- .../scheduler/SchedulerTestUtils.hpp | 60 +++++++++++++++++++ .../scheduler/StreamInitDependencyOnHost.cpp | 45 ++++---------- 2 files changed, 71 insertions(+), 34 deletions(-) diff --git a/sycl/unittests/scheduler/SchedulerTestUtils.hpp b/sycl/unittests/scheduler/SchedulerTestUtils.hpp index f4dcc4e0f215f..36775d3ff9946 100644 --- a/sycl/unittests/scheduler/SchedulerTestUtils.hpp +++ b/sycl/unittests/scheduler/SchedulerTestUtils.hpp @@ -213,3 +213,63 @@ cl::sycl::detail::Requirement getMockRequirement(const MemObjT &MemObj) { /*Dims*/ 0, /*ElementSize*/ 0}; } + +class MockHandler : public sycl::handler { +public: + MockHandler(std::shared_ptr Queue, bool IsHost) + : sycl::handler(Queue, IsHost) {} + // Methods + using cl::sycl::handler::evictHandlerImpl; + using cl::sycl::handler::getType; + + sycl::detail::NDRDescT &getNDRDesc() { return MNDRDesc; } + sycl::detail::code_location &getCodeLoc() { return MCodeLoc; } + sycl::detail::CG::CGTYPE &getCGType() { return MCGType; } + std::vector> &getStreamStorage() { + return MStreamStorage; + } + std::unique_ptr &getHostKernel() { + return MHostKernel; + } + std::vector> &getArgsStorage() { return MArgsStorage; } + std::vector &getAccStorage() { + return MAccStorage; + } + std::vector> &getSharedPtrStorage() { + return MSharedPtrStorage; + } + std::vector &getRequirements() { + return MRequirements; + } + std::vector &getEvents() { return MEvents; } + std::vector &getArgs() { return MArgs; } + std::string &getKernelName() { return MKernelName; } + sycl::detail::OSModuleHandle &getOSModuleHandle() { return MOSModuleHandle; } + std::shared_ptr &getKernel() { return MKernel; } + + void setType(sycl::detail::CG::CGTYPE Type) { + static_cast(this)->MCGType = Type; + } + + template + void setHostKernel(KernelType Kernel) { + static_cast(this)->MHostKernel.reset( + new sycl::detail::HostKernel(Kernel)); + } + + template void setNDRangeDesc(sycl::nd_range Range) { + static_cast(this)->MNDRDesc.set(std::move(Range)); + } + + void addStream(const sycl::detail::StreamImplPtr &Stream) { + sycl::handler::addStream(Stream); + } + + std::unique_ptr finalize() { + throw sycl::runtime_error("Unhandled type of command group", + PI_INVALID_OPERATION); + + return nullptr; + } +}; \ No newline at end of file diff --git a/sycl/unittests/scheduler/StreamInitDependencyOnHost.cpp b/sycl/unittests/scheduler/StreamInitDependencyOnHost.cpp index ef8c4c0895df8..a56681b46eb37 100644 --- a/sycl/unittests/scheduler/StreamInitDependencyOnHost.cpp +++ b/sycl/unittests/scheduler/StreamInitDependencyOnHost.cpp @@ -19,45 +19,22 @@ using namespace cl::sycl; inline constexpr auto DisablePostEnqueueCleanupName = "SYCL_DISABLE_POST_ENQUEUE_CLEANUP"; -class MockHandler : public sycl::handler { +class MockHandlerStreamInit : public MockHandler { public: - MockHandler(std::shared_ptr Queue, bool IsHost) - : sycl::handler(Queue, IsHost) {} - - void setType(detail::CG::CGTYPE Type) { - static_cast(this)->MCGType = Type; - } - - template - void setHostKernel(KernelType Kernel) { - static_cast(this)->MHostKernel.reset( - new sycl::detail::HostKernel(Kernel)); - } - - template void setNDRangeDesc(sycl::nd_range Range) { - static_cast(this)->MNDRDesc.set(std::move(Range)); - } - - void addStream(const detail::StreamImplPtr &Stream) { - sycl::handler::addStream(Stream); - } - + MockHandlerStreamInit(std::shared_ptr Queue, bool IsHost) + : MockHandler(Queue, IsHost) {} std::unique_ptr finalize() { - auto CGH = static_cast(this); std::shared_ptr Impl = evictHandlerImpl(); std::unique_ptr CommandGroup; - switch (CGH->MCGType) { + switch (getType()) { case detail::CG::Kernel: case detail::CG::RunOnHostIntel: { - CommandGroup.reset(new detail::CGExecKernel( - std::move(CGH->MNDRDesc), std::move(CGH->MHostKernel), - std::move(CGH->MKernel), std::move(CGH->MArgsStorage), - std::move(CGH->MAccStorage), std::move(CGH->MSharedPtrStorage), - std::move(CGH->MRequirements), std::move(CGH->MEvents), - std::move(CGH->MArgs), std::move(CGH->MKernelName), - std::move(CGH->MOSModuleHandle), std::move(CGH->MStreamStorage), - std::move(Impl->MAuxiliaryResources), CGH->MCGType, CGH->MCodeLoc)); + CommandGroup.reset(new sycl::detail::CGExecKernel( + getNDRDesc(), std::move(getHostKernel()), getKernel(), + getArgsStorage(), getAccStorage(), getSharedPtrStorage(), + getRequirements(), getEvents(), getArgs(), getKernelName(), + getOSModuleHandle(), getStreamStorage(), Impl->MAuxiliaryResources, + getCGType(), getCodeLoc())); break; } default: @@ -107,7 +84,7 @@ TEST_F(SchedulerTest, StreamInitDependencyOnHost) { detail::QueueImplPtr HQueueImpl = detail::getSyclObjImpl(HQueue); // Emulating processing of command group function - MockHandler MockCGH(HQueueImpl, true); + MockHandlerStreamInit MockCGH(HQueueImpl, true); MockCGH.setType(detail::CG::Kernel); auto EmptyKernel = [](sycl::nd_item<1>) {}; From 9bd31fbd0563e08d4d79935eb68f2c8c48a8f186 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Fri, 1 Apr 2022 10:21:56 +0300 Subject: [PATCH 07/21] Add unit tests Signed-off-by: Tikhomirova, Kseniya --- sycl/unittests/scheduler/CMakeLists.txt | 1 + .../scheduler/EnqueueWithDependsOnDeps.cpp | 389 ++++++++++++++++++ .../scheduler/SchedulerTestUtils.hpp | 2 + 3 files changed, 392 insertions(+) create mode 100644 sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp diff --git a/sycl/unittests/scheduler/CMakeLists.txt b/sycl/unittests/scheduler/CMakeLists.txt index 98518b2229274..683c78b79ef22 100644 --- a/sycl/unittests/scheduler/CMakeLists.txt +++ b/sycl/unittests/scheduler/CMakeLists.txt @@ -21,4 +21,5 @@ add_sycl_unittest(SchedulerTests OBJECT utils.cpp LeafLimitDiffContexts.cpp InOrderQueueSyncCheck.cpp + EnqueueWithDependsOnDeps.cpp ) diff --git a/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp b/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp new file mode 100644 index 0000000000000..adb9782010257 --- /dev/null +++ b/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp @@ -0,0 +1,389 @@ +//==------------ EnqueueWithDependsOnDeps.cpp --- Scheduler unit tests------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "SchedulerTest.hpp" +#include "SchedulerTestUtils.hpp" +#include + +#include +#include +#include +#include + +#include + +using namespace sycl; +using EventImplPtr = std::shared_ptr; + +namespace DependsOnTest { +class MockHandlerCustom : public MockHandler { +public: + MockHandlerCustom(std::shared_ptr Queue, + bool IsHost) + : MockHandler(Queue, IsHost) {} + + std::unique_ptr finalize() { + std::shared_ptr Impl = evictHandlerImpl(); + std::unique_ptr CommandGroup; + switch (getType()) { + case sycl::detail::CG::Kernel: { + CommandGroup.reset(new sycl::detail::CGExecKernel( + getNDRDesc(), std::move(getHostKernel()), getKernel(), + getArgsStorage(), getAccStorage(), getSharedPtrStorage(), + getRequirements(), getEvents(), getArgs(), getKernelName(), + getOSModuleHandle(), getStreamStorage(), Impl->MAuxiliaryResources, + getCGType(), getCodeLoc())); + break; + } + case sycl::detail::CG::CodeplayHostTask: { + CommandGroup.reset(new detail::CGHostTask( + std::move(getHostTask()), getQueue(), getQueue()->getContextImplPtr(), + getArgs(), getArgsStorage(), getAccStorage(), getSharedPtrStorage(), + getRequirements(), getEvents(), getCGType(), getCodeLoc())); + break; + } + default: + throw sycl::runtime_error("Unhandled type of command group", + PI_INVALID_OPERATION); + } + + return CommandGroup; + } +}; +} // namespace DependsOnTest + +detail::Command *AddTaskCG(bool IsHost, MockScheduler &MS, + detail::QueueImplPtr DevQueue, + const std::vector &Events) { + std::vector ToEnqueue; + + kernel_bundle KernelBundle = + sycl::get_kernel_bundle( + DevQueue->get_context()); + auto ExecBundle = sycl::build(KernelBundle); + + // Emulating processing of command group function + DependsOnTest::MockHandlerCustom MockCGH(DevQueue, false); + MockCGH.use_kernel_bundle(ExecBundle); + + for (auto EventImpl : Events) + MockCGH.depends_on(detail::createSyclObjFromImpl(EventImpl)); + + if (IsHost) + MockCGH.host_task([] {}); + else + MockCGH.single_task([] {}); + + std::unique_ptr CmdGroup = MockCGH.finalize(); + + detail::Command *NewCmd = + MS.addCG(std::move(CmdGroup), + IsHost ? MS.getDefaultHostQueue() : DevQueue, ToEnqueue); + EXPECT_EQ(ToEnqueue.size(), 0u); + return NewCmd; +} + +inline constexpr auto DisablePostEnqueueCleanupName = + "SYCL_DISABLE_POST_ENQUEUE_CLEANUP"; + +TEST_F(SchedulerTest, EnqueueNoMemObjTwoHostTasks) { + // Checks enqueue of two dependent host tasks + + unittest::ScopedEnvVar DisabledCleanup{ + DisablePostEnqueueCleanupName, "1", + detail::SYCLConfig::reset}; + + default_selector Selector; + platform Plt{Selector}; + if (Plt.is_host()) { + std::cout << "Not run due to host-only environment\n"; + return; + } + queue QueueDev(context(Plt), Selector); + MockScheduler MS; + + detail::QueueImplPtr QueueDevImpl = detail::getSyclObjImpl(QueueDev); + detail::QueueImplPtr QueueHostImpl = MS.getDefaultHostQueue(); + + std::vector Events; + + detail::Command *Cmd1 = AddTaskCG(true, MS, QueueDevImpl, Events); + EventImplPtr Cmd1Event = Cmd1->getEvent(); + + // Simulate depends_on() call + Events.push_back(Cmd1Event); + detail::Command *Cmd2 = AddTaskCG(true, MS, QueueDevImpl, Events); + EventImplPtr Cmd2Event = Cmd2->getEvent(); + + detail::EnqueueResultT Result; + EXPECT_TRUE(MS.enqueueCommand(Cmd2, Result, detail::BlockingT::NON_BLOCKING)); + + // Preconditions for post enqueue checks + EXPECT_TRUE(Cmd1->isSuccessfullyEnqueued()); + EXPECT_TRUE(Cmd2->isSuccessfullyEnqueued()); + + Cmd2Event->wait(Cmd2Event); + EXPECT_EQ(Cmd1Event->get_info(), + info::event_command_status::complete); + EXPECT_EQ(Cmd2Event->get_info(), + info::event_command_status::complete); +} + +TEST_F(SchedulerTest, EnqueueNoMemObjKernelDepHost) { + // Checks enqueue of kernel depending on host task + unittest::ScopedEnvVar DisabledCleanup{ + DisablePostEnqueueCleanupName, "1", + detail::SYCLConfig::reset}; + + default_selector Selector; + platform Plt{Selector}; + if (Plt.is_host()) { + std::cout << "Not run due to host-only environment\n"; + return; + } + unittest::PiMock Mock{Plt}; + setupDefaultMockAPIs(Mock); + + queue QueueDev(context(Plt), Selector); + MockScheduler MS; + + detail::QueueImplPtr QueueDevImpl = detail::getSyclObjImpl(QueueDev); + + std::vector Events; + + detail::Command *Cmd1 = AddTaskCG(true, MS, QueueDevImpl, Events); + EventImplPtr Cmd1Event = Cmd1->getEvent(); + + // Simulate depends_on() call + Events.push_back(Cmd1Event); + detail::Command *Cmd2 = AddTaskCG(false, MS, QueueDevImpl, Events); + EventImplPtr Cmd2Event = Cmd2->getEvent(); + + detail::EnqueueResultT Result; + EXPECT_TRUE(MS.enqueueCommand(Cmd2, Result, detail::BlockingT::NON_BLOCKING)); + + // Preconditions for post enqueue checks + EXPECT_TRUE(Cmd1->isSuccessfullyEnqueued()); + EXPECT_TRUE(Cmd2->isSuccessfullyEnqueued()); + + Cmd2Event->wait(Cmd2Event); +} + +TEST_F(SchedulerTest, EnqueueNoMemObjHostDepKernel) { + // Checks enqueue of host task depending on kernel + unittest::ScopedEnvVar DisabledCleanup{ + DisablePostEnqueueCleanupName, "1", + detail::SYCLConfig::reset}; + + default_selector Selector; + platform Plt{Selector}; + if (Plt.is_host()) { + std::cout << "Not run due to host-only environment\n"; + return; + } + unittest::PiMock Mock{Plt}; + setupDefaultMockAPIs(Mock); + + queue QueueDev(context(Plt), Selector); + MockScheduler MS; + + detail::QueueImplPtr QueueDevImpl = detail::getSyclObjImpl(QueueDev); + + std::vector Events; + + detail::Command *Cmd1 = AddTaskCG(false, MS, QueueDevImpl, Events); + EventImplPtr Cmd1Event = Cmd1->getEvent(); + + // Simulate depends_on() call + Events.push_back(Cmd1Event); + detail::Command *Cmd2 = AddTaskCG(true, MS, QueueDevImpl, Events); + EventImplPtr Cmd2Event = Cmd2->getEvent(); + + detail::EnqueueResultT Result; + EXPECT_TRUE(MS.enqueueCommand(Cmd2, Result, detail::BlockingT::NON_BLOCKING)); + + // Preconditions for post enqueue checks + EXPECT_TRUE(Cmd1->isSuccessfullyEnqueued()); + EXPECT_TRUE(Cmd2->isSuccessfullyEnqueued()); + Cmd2Event->wait(Cmd2Event); +} + +TEST_F(SchedulerTest, EnqueueNoMemObjDoubleKernelDepHostBlocked) { + // Checks blocking command tranfer for dependent kernels and enqueue of root + // kernel on host task completion + unittest::ScopedEnvVar DisabledCleanup{ + DisablePostEnqueueCleanupName, "1", + detail::SYCLConfig::reset}; + + default_selector Selector; + platform Plt{Selector}; + if (Plt.is_host()) { + std::cout << "Not run due to host-only environment\n"; + return; + } + unittest::PiMock Mock{Plt}; + setupDefaultMockAPIs(Mock); + + queue QueueDev(context(Plt), Selector); + MockScheduler MS; + + detail::QueueImplPtr QueueDevImpl = detail::getSyclObjImpl(QueueDev); + + std::vector Events; + + detail::Command *Cmd1 = AddTaskCG(true, MS, QueueDevImpl, Events); + EventImplPtr Cmd1Event = Cmd1->getEvent(); + Cmd1->MEnqueueStatus = detail::EnqueueResultT::SyclEnqueueBlocked; + + // Depends on host task + Events.push_back(Cmd1Event); + detail::Command *Cmd2 = AddTaskCG(false, MS, QueueDevImpl, Events); + EventImplPtr Cmd2Event = Cmd2->getEvent(); + + // Depends on kernel depending on host task + Events.clear(); + Events.push_back(Cmd2Event); + detail::Command *Cmd3 = AddTaskCG(false, MS, QueueDevImpl, Events); + EventImplPtr Cmd3Event = Cmd2->getEvent(); + + detail::EnqueueResultT Result; + EXPECT_FALSE( + MS.enqueueCommand(Cmd2, Result, detail::BlockingT::NON_BLOCKING)); + EXPECT_EQ(Result.MResult, detail::EnqueueResultT::SyclEnqueueBlocked); + EXPECT_EQ(Result.MCmd, static_cast(Cmd1)); + EXPECT_FALSE( + MS.enqueueCommand(Cmd3, Result, detail::BlockingT::NON_BLOCKING)); + EXPECT_EQ(Result.MResult, detail::EnqueueResultT::SyclEnqueueBlocked); + EXPECT_EQ(Result.MCmd, static_cast(Cmd1)); + + // Preconditions for post enqueue checks + EXPECT_FALSE(Cmd1->isSuccessfullyEnqueued()); + EXPECT_FALSE(Cmd2->isSuccessfullyEnqueued()); + EXPECT_FALSE(Cmd3->isSuccessfullyEnqueued()); + + Cmd1->MEnqueueStatus = detail::EnqueueResultT::SyclEnqueueReady; + + EXPECT_TRUE(MS.enqueueCommand(Cmd3, Result, detail::BlockingT::NON_BLOCKING)); + + EXPECT_TRUE(Cmd1->isSuccessfullyEnqueued()); + EXPECT_TRUE(Cmd2->isSuccessfullyEnqueued()); + EXPECT_TRUE(Cmd3->isSuccessfullyEnqueued()); + + Cmd3Event->wait(Cmd2Event); +} + +std::vector> PassedNumEvents; +inline pi_result redefinedEventsWaitCustom(pi_uint32 num_events, + const pi_event *event_list) { + PassedNumEvents.push_back(std::make_pair(num_events, event_list)); + return PI_SUCCESS; +} + +std::vector> PassedNumEventsToLaunch; +inline pi_result redefinedEnqueueKernelLaunchCustom( + pi_queue, pi_kernel, pi_uint32, const size_t *, const size_t *, + const size_t *, pi_uint32 num_events, const pi_event *event_list, + pi_event *event) { + PassedNumEventsToLaunch.push_back(std::make_pair(num_events, event_list)); + *event = reinterpret_cast(new int{}); + return PI_SUCCESS; +} + +void EventsWaitVerification(queue &QueueDev) { + MockScheduler MS; + + detail::QueueImplPtr QueueDevImpl = detail::getSyclObjImpl(QueueDev); + + std::vector Events; + + detail::Command *Cmd1 = AddTaskCG(true, MS, QueueDevImpl, Events); + EventImplPtr Cmd1Event = Cmd1->getEvent(); + + // Depends on host task + Events.push_back(Cmd1Event); + detail::Command *Cmd2 = AddTaskCG(false, MS, QueueDevImpl, Events); + EventImplPtr Cmd2Event = Cmd2->getEvent(); + + // Depends on kernel depending on host task + Events.clear(); + Events.push_back(Cmd2Event); + detail::Command *Cmd3 = AddTaskCG(false, MS, QueueDevImpl, Events); + EventImplPtr Cmd3Event = Cmd2->getEvent(); + + detail::EnqueueResultT Result; + EXPECT_TRUE(MS.enqueueCommand(Cmd3, Result, detail::BlockingT::NON_BLOCKING)); + Cmd3Event->wait(Cmd3Event); + + // One piEventsWait call: + // kernel2 waits for kernel 1 by sending event list to enqueue launch call + // (depending on queue property). Cmd3Event.wait() waits for kernel2 via + // piEventsWait. + ASSERT_EQ(PassedNumEvents.size(), 1u); + auto [EventCount, EventArr] = PassedNumEvents[0]; + ASSERT_EQ(EventCount, 1u); + EXPECT_EQ(*EventArr, Cmd3Event->getHandleRef()); +} + +TEST_F(SchedulerTest, InOrderEnqueueNoMemObjDoubleKernelDepHost) { + // Checks blocking command tranfer for dependent kernels and enqueue of root + // kernel on host task completion + unittest::ScopedEnvVar DisabledCleanup{ + DisablePostEnqueueCleanupName, "1", + detail::SYCLConfig::reset}; + + default_selector Selector; + platform Plt{Selector}; + if (Plt.is_host()) { + std::cout << "Not run due to host-only environment\n"; + return; + } + unittest::PiMock Mock{Plt}; + setupDefaultMockAPIs(Mock); + Mock.redefine(redefinedEventsWaitCustom); + Mock.redefine( + redefinedEnqueueKernelLaunchCustom); + + { + queue QueueDev(context(Plt), Selector); + PassedNumEvents.clear(); + PassedNumEventsToLaunch.clear(); + EventsWaitVerification(QueueDev); + // 1st -> kernel after host, no pi events + // 2nd -> kernel after kernel, 1 pi event + ASSERT_EQ(PassedNumEventsToLaunch.size(), 2u); + { + auto [EventCount, EventArr] = PassedNumEventsToLaunch[0]; + EXPECT_EQ(EventCount, 0u); + EXPECT_EQ(EventArr, nullptr); + } + { + auto [EventCount, EventArr] = PassedNumEventsToLaunch[1]; + EXPECT_EQ(EventCount, 1u); + } + } + + { + queue QueueDev(context(Plt), Selector, property::queue::in_order()); + PassedNumEvents.clear(); + PassedNumEventsToLaunch.clear(); + EventsWaitVerification(QueueDev); + // 1st -> kernel after host, no pi events + // 2nd -> kernel after kernel and in order queue, 0 pi event + ASSERT_EQ(PassedNumEventsToLaunch.size(), 2u); + { + auto [EventCount, EventArr] = PassedNumEventsToLaunch[0]; + EXPECT_EQ(EventCount, 0u); + EXPECT_EQ(EventArr, nullptr); + } + { + auto [EventCount, EventArr] = PassedNumEventsToLaunch[1]; + EXPECT_EQ(EventCount, 0u); + EXPECT_EQ(EventArr, nullptr); + } + } +} \ No newline at end of file diff --git a/sycl/unittests/scheduler/SchedulerTestUtils.hpp b/sycl/unittests/scheduler/SchedulerTestUtils.hpp index 36775d3ff9946..ae8238c9895dc 100644 --- a/sycl/unittests/scheduler/SchedulerTestUtils.hpp +++ b/sycl/unittests/scheduler/SchedulerTestUtils.hpp @@ -246,6 +246,8 @@ class MockHandler : public sycl::handler { std::string &getKernelName() { return MKernelName; } sycl::detail::OSModuleHandle &getOSModuleHandle() { return MOSModuleHandle; } std::shared_ptr &getKernel() { return MKernel; } + std::unique_ptr &getHostTask() { return MHostTask; } + std::shared_ptr &getQueue() { return MQueue; } void setType(sycl::detail::CG::CGTYPE Type) { static_cast(this)->MCGType = Type; From 17309be43f6bd711019a7512c3fd0e19f403ed51 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Fri, 1 Apr 2022 10:22:33 +0300 Subject: [PATCH 08/21] Minor fix for event status handling (covered by tests above) Signed-off-by: Tikhomirova, Kseniya --- sycl/source/detail/event_impl.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sycl/source/detail/event_impl.cpp b/sycl/source/detail/event_impl.cpp index 76c7db81ee5d0..9dcd34a8670aa 100644 --- a/sycl/source/detail/event_impl.cpp +++ b/sycl/source/detail/event_impl.cpp @@ -326,9 +326,10 @@ event_impl::get_info() const { return get_event_info::get( this->getHandleRef(), this->getPlugin()); } - return MHostEvent && MState.load() != HES_Complete - ? sycl::info::event_command_status::submitted - : info::event_command_status::complete; + if (MHostEvent && MState.load() == HES_Complete) + return info::event_command_status::complete; + + return sycl::info::event_command_status::submitted; } static uint64_t getTimestamp() { From b04d724aadacc13efe654d6ba8c7ea5b612f08b1 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Fri, 1 Apr 2022 12:47:45 +0300 Subject: [PATCH 09/21] Fix test failure Signed-off-by: Tikhomirova, Kseniya --- sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp b/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp index adb9782010257..2ddc4cefc0f85 100644 --- a/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp +++ b/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp @@ -104,6 +104,9 @@ TEST_F(SchedulerTest, EnqueueNoMemObjTwoHostTasks) { std::cout << "Not run due to host-only environment\n"; return; } + unittest::PiMock Mock{Plt}; + setupDefaultMockAPIs(Mock); + queue QueueDev(context(Plt), Selector); MockScheduler MS; From 5a82065c4ef41f28daecf485019e528d56b0d48b Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Fri, 1 Apr 2022 13:35:11 +0300 Subject: [PATCH 10/21] Fix event status handling 2 Signed-off-by: Tikhomirova, Kseniya --- sycl/source/detail/event_impl.cpp | 18 +++++++++++------- .../scheduler/EnqueueWithDependsOnDeps.cpp | 2 -- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/sycl/source/detail/event_impl.cpp b/sycl/source/detail/event_impl.cpp index 9dcd34a8670aa..0261673977b4c 100644 --- a/sycl/source/detail/event_impl.cpp +++ b/sycl/source/detail/event_impl.cpp @@ -322,14 +322,18 @@ event_impl::get_info() const { if (MState == HES_Discarded) return info::event_command_status::ext_oneapi_unknown; - if (!MHostEvent && MEvent) { - return get_event_info::get( - this->getHandleRef(), this->getPlugin()); + if (!MHostEvent) { + // Command is enqueued and PiEvent is ready + if (MEvent) + return get_event_info::get( + this->getHandleRef(), this->getPlugin()); + // Command is blocked and not enqueued, PiEvent is not assigned yet + else if (MCommand) + return sycl::info::event_command_status::submitted; } - if (MHostEvent && MState.load() == HES_Complete) - return info::event_command_status::complete; - - return sycl::info::event_command_status::submitted; + return MHostEvent && MState.load() != HES_Complete + ? sycl::info::event_command_status::submitted + : info::event_command_status::complete; } static uint64_t getTimestamp() { diff --git a/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp b/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp index 2ddc4cefc0f85..5a11d494637b0 100644 --- a/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp +++ b/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp @@ -104,8 +104,6 @@ TEST_F(SchedulerTest, EnqueueNoMemObjTwoHostTasks) { std::cout << "Not run due to host-only environment\n"; return; } - unittest::PiMock Mock{Plt}; - setupDefaultMockAPIs(Mock); queue QueueDev(context(Plt), Selector); MockScheduler MS; From a94e5130c3f6f8c96db4625a20dd38146d51bc75 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Fri, 1 Apr 2022 19:14:05 +0300 Subject: [PATCH 11/21] Limit backends for test Signed-off-by: Tikhomirova, Kseniya --- .../scheduler/EnqueueWithDependsOnDeps.cpp | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp b/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp index 5a11d494637b0..d397041c3f680 100644 --- a/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp +++ b/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp @@ -104,6 +104,12 @@ TEST_F(SchedulerTest, EnqueueNoMemObjTwoHostTasks) { std::cout << "Not run due to host-only environment\n"; return; } + // This test only contains device image for SPIR-V capable devices. + if (Plt.get_backend() != sycl::backend::opencl && + Plt.get_backend() != sycl::backend::ext_oneapi_level_zero) { + std::cout << "Only OpenCL and Level Zero are supported for this test\n"; + return; + } queue QueueDev(context(Plt), Selector); MockScheduler MS; @@ -147,6 +153,13 @@ TEST_F(SchedulerTest, EnqueueNoMemObjKernelDepHost) { std::cout << "Not run due to host-only environment\n"; return; } + // This test only contains device image for SPIR-V capable devices. + if (Plt.get_backend() != sycl::backend::opencl && + Plt.get_backend() != sycl::backend::ext_oneapi_level_zero) { + std::cout << "Only OpenCL and Level Zero are supported for this test\n"; + return; + } + unittest::PiMock Mock{Plt}; setupDefaultMockAPIs(Mock); @@ -187,6 +200,13 @@ TEST_F(SchedulerTest, EnqueueNoMemObjHostDepKernel) { std::cout << "Not run due to host-only environment\n"; return; } + // This test only contains device image for SPIR-V capable devices. + if (Plt.get_backend() != sycl::backend::opencl && + Plt.get_backend() != sycl::backend::ext_oneapi_level_zero) { + std::cout << "Only OpenCL and Level Zero are supported for this test\n"; + return; + } + unittest::PiMock Mock{Plt}; setupDefaultMockAPIs(Mock); @@ -227,6 +247,12 @@ TEST_F(SchedulerTest, EnqueueNoMemObjDoubleKernelDepHostBlocked) { std::cout << "Not run due to host-only environment\n"; return; } + // This test only contains device image for SPIR-V capable devices. + if (Plt.get_backend() != sycl::backend::opencl && + Plt.get_backend() != sycl::backend::ext_oneapi_level_zero) { + std::cout << "Only OpenCL and Level Zero are supported for this test\n"; + return; + } unittest::PiMock Mock{Plt}; setupDefaultMockAPIs(Mock); @@ -343,6 +369,12 @@ TEST_F(SchedulerTest, InOrderEnqueueNoMemObjDoubleKernelDepHost) { std::cout << "Not run due to host-only environment\n"; return; } + // This test only contains device image for SPIR-V capable devices. + if (Plt.get_backend() != sycl::backend::opencl && + Plt.get_backend() != sycl::backend::ext_oneapi_level_zero) { + std::cout << "Only OpenCL and Level Zero are supported for this test\n"; + return; + } unittest::PiMock Mock{Plt}; setupDefaultMockAPIs(Mock); Mock.redefine(redefinedEventsWaitCustom); From 78643fc3f532595d0746e2435007d533bb995ac6 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Mon, 4 Apr 2022 12:15:28 +0300 Subject: [PATCH 12/21] Fix tests Signed-off-by: Tikhomirova, Kseniya --- .../scheduler/EnqueueWithDependsOnDeps.cpp | 15 ++++++++------- .../scheduler/InOrderQueueHostTaskDeps.cpp | 1 - 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp b/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp index d397041c3f680..f15e9bd2d4681 100644 --- a/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp +++ b/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp @@ -62,22 +62,23 @@ detail::Command *AddTaskCG(bool IsHost, MockScheduler &MS, const std::vector &Events) { std::vector ToEnqueue; - kernel_bundle KernelBundle = - sycl::get_kernel_bundle( - DevQueue->get_context()); - auto ExecBundle = sycl::build(KernelBundle); - // Emulating processing of command group function DependsOnTest::MockHandlerCustom MockCGH(DevQueue, false); - MockCGH.use_kernel_bundle(ExecBundle); for (auto EventImpl : Events) MockCGH.depends_on(detail::createSyclObjFromImpl(EventImpl)); if (IsHost) MockCGH.host_task([] {}); - else + else { + kernel_bundle KernelBundle = + sycl::get_kernel_bundle( + DevQueue->get_context()); + auto ExecBundle = sycl::build(KernelBundle); + MockCGH.use_kernel_bundle(ExecBundle); + MockCGH.single_task([] {}); + } std::unique_ptr CmdGroup = MockCGH.finalize(); diff --git a/sycl/unittests/scheduler/InOrderQueueHostTaskDeps.cpp b/sycl/unittests/scheduler/InOrderQueueHostTaskDeps.cpp index 99a12427c5e7a..e5925747cd4f3 100644 --- a/sycl/unittests/scheduler/InOrderQueueHostTaskDeps.cpp +++ b/sycl/unittests/scheduler/InOrderQueueHostTaskDeps.cpp @@ -63,7 +63,6 @@ TEST_F(SchedulerTest, InOrderQueueHostTaskDeps) { }); InOrderQueue .submit([&](sycl::handler &CGH) { - CGH.use_kernel_bundle(ExecBundle); CGH.host_task([=] {}); }) .wait(); From 8b9d95fcd6d1bcf54be4a6ac4e61c3ef707ae58b Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Mon, 4 Apr 2022 13:52:43 +0300 Subject: [PATCH 13/21] Fix clang-format Signed-off-by: Tikhomirova, Kseniya --- sycl/unittests/scheduler/InOrderQueueHostTaskDeps.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sycl/unittests/scheduler/InOrderQueueHostTaskDeps.cpp b/sycl/unittests/scheduler/InOrderQueueHostTaskDeps.cpp index e5925747cd4f3..6ad52327419d7 100644 --- a/sycl/unittests/scheduler/InOrderQueueHostTaskDeps.cpp +++ b/sycl/unittests/scheduler/InOrderQueueHostTaskDeps.cpp @@ -61,10 +61,7 @@ TEST_F(SchedulerTest, InOrderQueueHostTaskDeps) { CGH.use_kernel_bundle(ExecBundle); CGH.single_task([] {}); }); - InOrderQueue - .submit([&](sycl::handler &CGH) { - CGH.host_task([=] {}); - }) + InOrderQueue.submit([&](sycl::handler &CGH) { CGH.host_task([=] {}); }) .wait(); EXPECT_TRUE(GEventsWaitCounter == 1); From a0c087b43012eb41111cefb0bf79b9e659bce928 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Thu, 11 Aug 2022 07:16:12 -0700 Subject: [PATCH 14/21] Fix comments Signed-off-by: Tikhomirova, Kseniya --- sycl/source/detail/event_impl.cpp | 2 +- sycl/source/detail/queue_impl.hpp | 4 +++- sycl/source/detail/scheduler/commands.cpp | 17 ++++++++++------- sycl/source/detail/scheduler/commands.hpp | 2 ++ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/sycl/source/detail/event_impl.cpp b/sycl/source/detail/event_impl.cpp index 4941505fe029d..b84c5633a0d19 100644 --- a/sycl/source/detail/event_impl.cpp +++ b/sycl/source/detail/event_impl.cpp @@ -360,7 +360,7 @@ event_impl::get_info() { if (!MHostEvent) { // Command is enqueued and PiEvent is ready if (MEvent) - return get_event_info::get( + return get_event_info( this->getHandleRef(), this->getPlugin()); // Command is blocked and not enqueued, PiEvent is not assigned yet else if (MCommand) diff --git a/sycl/source/detail/queue_impl.hpp b/sycl/source/detail/queue_impl.hpp index 846445f9271f0..f8075d287333c 100644 --- a/sycl/source/detail/queue_impl.hpp +++ b/sycl/source/detail/queue_impl.hpp @@ -123,7 +123,7 @@ class queue_impl { } if (!MHostQueue) { const QueueOrder QOrder = - MPropList.has_property() + MIsInorder ? QueueOrder::Ordered : QueueOrder::OOO; MQueues.push_back(createQueue(QOrder)); @@ -208,6 +208,8 @@ class queue_impl { /// \return true if this queue has discard_events support. bool has_discard_events_support() const { return MHasDiscardEventsSupport; } + bool isInOrder() const { return MIsInorder; } + /// Queries SYCL queue for information. /// /// The return type depends on information being queried. diff --git a/sycl/source/detail/scheduler/commands.cpp b/sycl/source/detail/scheduler/commands.cpp index 1fabbeac694d7..73c4122542c81 100644 --- a/sycl/source/detail/scheduler/commands.cpp +++ b/sycl/source/detail/scheduler/commands.cpp @@ -214,9 +214,9 @@ Command::getPiEvents(const std::vector &EventImpls) const { // At this stage dependency is definitely pi task and need to check if // current one is a host task. In this case we should not skip pi event due // to different sync mechanisms for different task types on in-order queue. - auto WorkerQueue = getWorkerQueue(); + const auto& WorkerQueue = getWorkerQueue(); if (EventImpl->getWorkerQueue() == WorkerQueue && - WorkerQueue->has_property() && + WorkerQueue->isInOrder() && (MType != CommandType::RUN_CG /* host task has this type also */ || (static_cast(this))->getCG().getType() != CG::CGTYPE::CodeplayHostTask)) @@ -228,6 +228,13 @@ Command::getPiEvents(const std::vector &EventImpls) const { return RetPiEvents; } +bool Command::isHostTask() const +{ + return (MType == CommandType::RUN_CG) /* host task has this type also */&& + ((static_cast(this))->getCG().getType() == + CG::CGTYPE::CodeplayHostTask); +} + static void flushCrossQueueDeps(const std::vector &EventImpls, const QueueImplPtr &Queue) { for (auto &EventImpl : EventImpls) { @@ -1531,11 +1538,7 @@ const ContextImplPtr &MemCpyCommandHost::getWorkerContext() const { return getWorkerQueue()->getContextImplPtr(); } -const QueueImplPtr &MemCpyCommandHost::getWorkerQueue() const { - return MQueue->is_host() ? MSrcQueue : MQueue; -} - -cl_int MemCpyCommandHost::enqueueImp() { +pi_int32 MemCpyCommandHost::enqueueImp() { const QueueImplPtr &Queue = getWorkerQueue(); waitForPreparedHostEvents(); std::vector EventImpls = MPreparedDepsEvents; diff --git a/sycl/source/detail/scheduler/commands.hpp b/sycl/source/detail/scheduler/commands.hpp index 3e3bfec44fee1..4df8bbeadfa8d 100644 --- a/sycl/source/detail/scheduler/commands.hpp +++ b/sycl/source/detail/scheduler/commands.hpp @@ -212,6 +212,8 @@ class Command { std::vector getPiEvents(const std::vector &EventImpls) const; + bool isHostTask() const; + protected: QueueImplPtr MQueue; QueueImplPtr MSubmittedQueue; From 9fe1ea79bfe49ed8ad4cdc5d1b68c05d85fdf107 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Thu, 11 Aug 2022 07:22:54 -0700 Subject: [PATCH 15/21] Add missed part for comments Signed-off-by: Tikhomirova, Kseniya --- sycl/source/detail/scheduler/commands.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sycl/source/detail/scheduler/commands.cpp b/sycl/source/detail/scheduler/commands.cpp index 73c4122542c81..59a13ec41707d 100644 --- a/sycl/source/detail/scheduler/commands.cpp +++ b/sycl/source/detail/scheduler/commands.cpp @@ -216,10 +216,7 @@ Command::getPiEvents(const std::vector &EventImpls) const { // to different sync mechanisms for different task types on in-order queue. const auto& WorkerQueue = getWorkerQueue(); if (EventImpl->getWorkerQueue() == WorkerQueue && - WorkerQueue->isInOrder() && - (MType != CommandType::RUN_CG /* host task has this type also */ || - (static_cast(this))->getCG().getType() != - CG::CGTYPE::CodeplayHostTask)) + WorkerQueue->isInOrder() && !isHostTask()) continue; RetPiEvents.push_back(EventImpl->getHandleRef()); From 23707d35f8ab991a30e82e0d3246e37409b41206 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Thu, 11 Aug 2022 07:48:29 -0700 Subject: [PATCH 16/21] Fix clang-format Signed-off-by: Tikhomirova, Kseniya --- sycl/source/detail/queue_impl.hpp | 4 +--- sycl/source/detail/scheduler/commands.cpp | 11 ++++------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/sycl/source/detail/queue_impl.hpp b/sycl/source/detail/queue_impl.hpp index f8075d287333c..507a0aaae9f90 100644 --- a/sycl/source/detail/queue_impl.hpp +++ b/sycl/source/detail/queue_impl.hpp @@ -123,9 +123,7 @@ class queue_impl { } if (!MHostQueue) { const QueueOrder QOrder = - MIsInorder - ? QueueOrder::Ordered - : QueueOrder::OOO; + MIsInorder ? QueueOrder::Ordered : QueueOrder::OOO; MQueues.push_back(createQueue(QOrder)); } } diff --git a/sycl/source/detail/scheduler/commands.cpp b/sycl/source/detail/scheduler/commands.cpp index 59a13ec41707d..5c0cc4a7ba251 100644 --- a/sycl/source/detail/scheduler/commands.cpp +++ b/sycl/source/detail/scheduler/commands.cpp @@ -214,7 +214,7 @@ Command::getPiEvents(const std::vector &EventImpls) const { // At this stage dependency is definitely pi task and need to check if // current one is a host task. In this case we should not skip pi event due // to different sync mechanisms for different task types on in-order queue. - const auto& WorkerQueue = getWorkerQueue(); + const auto &WorkerQueue = getWorkerQueue(); if (EventImpl->getWorkerQueue() == WorkerQueue && WorkerQueue->isInOrder() && !isHostTask()) continue; @@ -225,11 +225,10 @@ Command::getPiEvents(const std::vector &EventImpls) const { return RetPiEvents; } -bool Command::isHostTask() const -{ - return (MType == CommandType::RUN_CG) /* host task has this type also */&& +bool Command::isHostTask() const { + return (MType == CommandType::RUN_CG) /* host task has this type also */ && ((static_cast(this))->getCG().getType() == - CG::CGTYPE::CodeplayHostTask); + CG::CGTYPE::CodeplayHostTask); } static void flushCrossQueueDeps(const std::vector &EventImpls, @@ -947,7 +946,6 @@ void AllocaCommand::printDot(std::ostream &Stream) const { Stream << " Link : " << this->MLinkedAllocaCmd << "\\n"; Stream << "\"];" << std::endl; - for (const auto &Dep : MDeps) { if (Dep.MDepCommand == nullptr) continue; @@ -1093,7 +1091,6 @@ pi_int32 ReleaseCommand::enqueueImp() { // 3. Device alloca in the pair should be in active state in order to be // correctly released. - // There is no actual memory allocation if a host alloca command is created // being linked to a device allocation. SkipRelease |= CurAllocaIsHost && !MAllocaCmd->MIsLeaderAlloca; From 460ff51a234b670d80118896b494c88a3e5ac11a Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Fri, 12 Aug 2022 03:15:59 -0700 Subject: [PATCH 17/21] FIx error code Signed-off-by: Tikhomirova, Kseniya --- sycl/unittests/scheduler/SchedulerTestUtils.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/unittests/scheduler/SchedulerTestUtils.hpp b/sycl/unittests/scheduler/SchedulerTestUtils.hpp index 2af6faf54b830..27d78dab508eb 100644 --- a/sycl/unittests/scheduler/SchedulerTestUtils.hpp +++ b/sycl/unittests/scheduler/SchedulerTestUtils.hpp @@ -266,7 +266,7 @@ class MockHandler : public sycl::handler { std::unique_ptr finalize() { throw sycl::runtime_error("Unhandled type of command group", - PI_INVALID_OPERATION); + CL_INVALID_OPERATION); return nullptr; } From df467f59bcc42da094c65d9816983884697baa01 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Fri, 12 Aug 2022 03:28:27 -0700 Subject: [PATCH 18/21] Update namespaces Signed-off-by: Tikhomirova, Kseniya --- sycl/unittests/scheduler/SchedulerTestUtils.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/unittests/scheduler/SchedulerTestUtils.hpp b/sycl/unittests/scheduler/SchedulerTestUtils.hpp index 27d78dab508eb..4a7161eae9bde 100644 --- a/sycl/unittests/scheduler/SchedulerTestUtils.hpp +++ b/sycl/unittests/scheduler/SchedulerTestUtils.hpp @@ -215,8 +215,8 @@ class MockHandler : public sycl::handler { MockHandler(std::shared_ptr Queue, bool IsHost) : sycl::handler(Queue, IsHost) {} // Methods - using cl::sycl::handler::evictHandlerImpl; - using cl::sycl::handler::getType; + using sycl::handler::evictHandlerImpl; + using sycl::handler::getType; sycl::detail::NDRDescT &getNDRDesc() { return MNDRDesc; } sycl::detail::code_location &getCodeLoc() { return MCodeLoc; } From e4da9340c25e0962fcdd418835852f47b4eed242 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Fri, 12 Aug 2022 07:53:15 -0700 Subject: [PATCH 19/21] Fix unittests build Signed-off-by: Tikhomirova, Kseniya --- sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp b/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp index f15e9bd2d4681..dea8ced5beb8f 100644 --- a/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp +++ b/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp @@ -49,14 +49,13 @@ class MockHandlerCustom : public MockHandler { } default: throw sycl::runtime_error("Unhandled type of command group", - PI_INVALID_OPERATION); + CL_INVALID_OPERATION); } return CommandGroup; } }; } // namespace DependsOnTest - detail::Command *AddTaskCG(bool IsHost, MockScheduler &MS, detail::QueueImplPtr DevQueue, const std::vector &Events) { @@ -76,8 +75,7 @@ detail::Command *AddTaskCG(bool IsHost, MockScheduler &MS, DevQueue->get_context()); auto ExecBundle = sycl::build(KernelBundle); MockCGH.use_kernel_bundle(ExecBundle); - - MockCGH.single_task([] {}); + MockCGH.single_task>([]{}); } std::unique_ptr CmdGroup = MockCGH.finalize(); From 8eec835528018d48491460f0f8bae9fafe2d989f Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Tue, 16 Aug 2022 08:41:14 -0700 Subject: [PATCH 20/21] Revert condition state Signed-off-by: Tikhomirova, Kseniya --- sycl/source/detail/event_impl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sycl/source/detail/event_impl.cpp b/sycl/source/detail/event_impl.cpp index b84c5633a0d19..beda90171243a 100644 --- a/sycl/source/detail/event_impl.cpp +++ b/sycl/source/detail/event_impl.cpp @@ -366,7 +366,8 @@ event_impl::get_info() { else if (MCommand) return sycl::info::event_command_status::submitted; } - return MState.load() != HES_Complete + + return MHostEvent && MState.load() != HES_Complete ? sycl::info::event_command_status::submitted : info::event_command_status::complete; } From 7d5def94400fe92b178f43bcc778a0bd9b00d9b6 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Mon, 29 Aug 2022 07:26:23 -0700 Subject: [PATCH 21/21] Fix comments Signed-off-by: Tikhomirova, Kseniya --- sycl/source/detail/scheduler/commands.cpp | 2 +- .../detail/scheduler/graph_processor.cpp | 20 ++--- .../scheduler/EnqueueWithDependsOnDeps.cpp | 79 +++++++------------ .../scheduler/SchedulerTestUtils.hpp | 4 +- 4 files changed, 38 insertions(+), 67 deletions(-) diff --git a/sycl/source/detail/scheduler/commands.cpp b/sycl/source/detail/scheduler/commands.cpp index b1cb1444f24b7..445eb1fa79879 100644 --- a/sycl/source/detail/scheduler/commands.cpp +++ b/sycl/source/detail/scheduler/commands.cpp @@ -214,7 +214,7 @@ Command::getPiEvents(const std::vector &EventImpls) const { // At this stage dependency is definitely pi task and need to check if // current one is a host task. In this case we should not skip pi event due // to different sync mechanisms for different task types on in-order queue. - const auto &WorkerQueue = getWorkerQueue(); + const QueueImplPtr &WorkerQueue = getWorkerQueue(); if (EventImpl->getWorkerQueue() == WorkerQueue && WorkerQueue->isInOrder() && !isHostTask()) continue; diff --git a/sycl/source/detail/scheduler/graph_processor.cpp b/sycl/source/detail/scheduler/graph_processor.cpp index a08805035ae3e..900fa713d58ce 100644 --- a/sycl/source/detail/scheduler/graph_processor.cpp +++ b/sycl/source/detail/scheduler/graph_processor.cpp @@ -58,24 +58,20 @@ bool Scheduler::GraphProcessor::enqueueCommand( return false; } - // Recursively enqueue all the implicit + explicit dependencies first and - // exit immediately if any of the commands cannot be enqueued. + // Recursively enqueue all the implicit + explicit backend level dependencies + // first and exit immediately if any of the commands cannot be enqueued. for (const EventImplPtr &Event : Cmd->getPreparedDepsEvents()) { if (Command *DepCmd = static_cast(Event->getCommand())) if (!enqueueCommand(DepCmd, EnqueueResult, ToCleanUp, Blocking)) return false; } - // Asynchronous host operations (amongst dependencies of an arbitrary command) - // are not supported (see Command::processDepEvent method). This impacts - // operation of host-task feature a lot with hangs and long-runs. Hence we - // have this workaround here. - // This workaround is safe as long as the only asynchronous host operation we - // have is a host task. - // This may iterate over some of dependencies in Cmd->MDeps. Though, the - // enqueue operation is idempotent and the second call will result in no-op. - // TODO remove the workaround when proper fix for host-task dispatching is - // implemented. + // Recursively enqueue all the implicit + explicit host dependencies and + // exit immediately if any of the commands cannot be enqueued. + // Host task execution is asynchronous. In current implementation enqueue for + // this command will wait till host task completion by waitInternal call on + // MHostDepsEvents. TO FIX: implement enqueue of blocked commands on host task + // completion stage and eliminate this event waiting in enqueue. for (const EventImplPtr &Event : Cmd->getPreparedHostDepsEvents()) { if (Command *DepCmd = static_cast(Event->getCommand())) if (!enqueueCommand(DepCmd, EnqueueResult, ToCleanUp, Blocking)) diff --git a/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp b/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp index 399c75eb932fd..d06df85f4d07a 100644 --- a/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp +++ b/sycl/unittests/scheduler/EnqueueWithDependsOnDeps.cpp @@ -33,11 +33,10 @@ class MockHandlerCustom : public MockHandler { case sycl::detail::CG::Kernel: { CommandGroup.reset(new sycl::detail::CGExecKernel( getNDRDesc(), std::move(getHostKernel()), getKernel(), - std::move(MImpl->MKernelBundle), - getArgsStorage(), getAccStorage(), getSharedPtrStorage(), - getRequirements(), getEvents(), getArgs(), getKernelName(), - getOSModuleHandle(), getStreamStorage(), MImpl->MAuxiliaryResources, - getCGType(), getCodeLoc())); + std::move(MImpl->MKernelBundle), getArgsStorage(), getAccStorage(), + getSharedPtrStorage(), getRequirements(), getEvents(), getArgs(), + getKernelName(), getOSModuleHandle(), getStreamStorage(), + MImpl->MAuxiliaryResources, getCGType(), getCodeLoc())); break; } case sycl::detail::CG::CodeplayHostTask: { @@ -49,7 +48,7 @@ class MockHandlerCustom : public MockHandler { } default: throw sycl::runtime_error("Unhandled type of command group", - CL_INVALID_OPERATION); + PI_ERROR_INVALID_OPERATION); } return CommandGroup; @@ -75,7 +74,7 @@ detail::Command *AddTaskCG(bool IsHost, MockScheduler &MS, DevQueue->get_context()); auto ExecBundle = sycl::build(KernelBundle); MockCGH.use_kernel_bundle(ExecBundle); - MockCGH.single_task>([]{}); + MockCGH.single_task>([] {}); } std::unique_ptr CmdGroup = MockCGH.finalize(); @@ -87,6 +86,20 @@ detail::Command *AddTaskCG(bool IsHost, MockScheduler &MS, return NewCmd; } +bool CheckTestExecutionRequirements(const platform &plt) { + if (plt.is_host()) { + std::cout << "Not run due to host-only environment\n"; + return false; + } + // This test only contains device image for SPIR-V capable devices. + if (plt.get_backend() != sycl::backend::opencl && + plt.get_backend() != sycl::backend::ext_oneapi_level_zero) { + std::cout << "Only OpenCL and Level Zero are supported for this test\n"; + return false; + } + return true; +} + inline constexpr auto DisablePostEnqueueCleanupName = "SYCL_DISABLE_POST_ENQUEUE_CLEANUP"; @@ -99,16 +112,8 @@ TEST_F(SchedulerTest, EnqueueNoMemObjTwoHostTasks) { default_selector Selector; platform Plt{Selector}; - if (Plt.is_host()) { - std::cout << "Not run due to host-only environment\n"; - return; - } - // This test only contains device image for SPIR-V capable devices. - if (Plt.get_backend() != sycl::backend::opencl && - Plt.get_backend() != sycl::backend::ext_oneapi_level_zero) { - std::cout << "Only OpenCL and Level Zero are supported for this test\n"; + if (!CheckTestExecutionRequirements(Plt)) return; - } queue QueueDev(context(Plt), Selector); MockScheduler MS; @@ -148,16 +153,8 @@ TEST_F(SchedulerTest, EnqueueNoMemObjKernelDepHost) { default_selector Selector; platform Plt{Selector}; - if (Plt.is_host()) { - std::cout << "Not run due to host-only environment\n"; - return; - } - // This test only contains device image for SPIR-V capable devices. - if (Plt.get_backend() != sycl::backend::opencl && - Plt.get_backend() != sycl::backend::ext_oneapi_level_zero) { - std::cout << "Only OpenCL and Level Zero are supported for this test\n"; + if (!CheckTestExecutionRequirements(Plt)) return; - } unittest::PiMock Mock{Plt}; setupDefaultMockAPIs(Mock); @@ -195,16 +192,8 @@ TEST_F(SchedulerTest, EnqueueNoMemObjHostDepKernel) { default_selector Selector; platform Plt{Selector}; - if (Plt.is_host()) { - std::cout << "Not run due to host-only environment\n"; + if (!CheckTestExecutionRequirements(Plt)) return; - } - // This test only contains device image for SPIR-V capable devices. - if (Plt.get_backend() != sycl::backend::opencl && - Plt.get_backend() != sycl::backend::ext_oneapi_level_zero) { - std::cout << "Only OpenCL and Level Zero are supported for this test\n"; - return; - } unittest::PiMock Mock{Plt}; setupDefaultMockAPIs(Mock); @@ -242,16 +231,9 @@ TEST_F(SchedulerTest, EnqueueNoMemObjDoubleKernelDepHostBlocked) { default_selector Selector; platform Plt{Selector}; - if (Plt.is_host()) { - std::cout << "Not run due to host-only environment\n"; - return; - } - // This test only contains device image for SPIR-V capable devices. - if (Plt.get_backend() != sycl::backend::opencl && - Plt.get_backend() != sycl::backend::ext_oneapi_level_zero) { - std::cout << "Only OpenCL and Level Zero are supported for this test\n"; + if (!CheckTestExecutionRequirements(Plt)) return; - } + unittest::PiMock Mock{Plt}; setupDefaultMockAPIs(Mock); @@ -364,16 +346,9 @@ TEST_F(SchedulerTest, InOrderEnqueueNoMemObjDoubleKernelDepHost) { default_selector Selector; platform Plt{Selector}; - if (Plt.is_host()) { - std::cout << "Not run due to host-only environment\n"; + if (!CheckTestExecutionRequirements(Plt)) return; - } - // This test only contains device image for SPIR-V capable devices. - if (Plt.get_backend() != sycl::backend::opencl && - Plt.get_backend() != sycl::backend::ext_oneapi_level_zero) { - std::cout << "Only OpenCL and Level Zero are supported for this test\n"; - return; - } + unittest::PiMock Mock{Plt}; setupDefaultMockAPIs(Mock); Mock.redefine(redefinedEventsWaitCustom); diff --git a/sycl/unittests/scheduler/SchedulerTestUtils.hpp b/sycl/unittests/scheduler/SchedulerTestUtils.hpp index 8075c25bd151d..02511f92eca69 100644 --- a/sycl/unittests/scheduler/SchedulerTestUtils.hpp +++ b/sycl/unittests/scheduler/SchedulerTestUtils.hpp @@ -215,8 +215,8 @@ class MockHandler : public sycl::handler { MockHandler(std::shared_ptr Queue, bool IsHost) : sycl::handler(Queue, IsHost) {} // Methods - using sycl::handler::MImpl; using sycl::handler::getType; + using sycl::handler::MImpl; sycl::detail::NDRDescT &getNDRDesc() { return MNDRDesc; } sycl::detail::code_location &getCodeLoc() { return MCodeLoc; } @@ -266,7 +266,7 @@ class MockHandler : public sycl::handler { std::unique_ptr finalize() { throw sycl::runtime_error("Unhandled type of command group", - CL_INVALID_OPERATION); + PI_ERROR_INVALID_OPERATION); return nullptr; }