diff --git a/sycl/source/queue.cpp b/sycl/source/queue.cpp index ed0b0e42e6e6f..f2519fe311d12 100644 --- a/sycl/source/queue.cpp +++ b/sycl/source/queue.cpp @@ -327,24 +327,6 @@ void queue::wait_and_throw_proxy(const detail::code_location &CodeLoc) { impl->wait_and_throw(CodeLoc); } -static event -getBarrierEventForInorderQueueHelper(detail::queue_impl &QueueImpl) { - // This function should not be called when a queue is recording to a graph, - // as a graph can record from multiple queues and we cannot guarantee the - // last node added by an in-order queue will be the last node added to the - // graph. - assert(!QueueImpl.hasCommandGraph() && - "Should not be called in on graph recording."); - - sycl::detail::optional LastEvent = QueueImpl.getLastEvent(); - if (LastEvent) - return *LastEvent; - - // If there was no last event, we create an empty one. - return detail::createSyclObjFromImpl( - detail::event_impl::create_default_event()); -} - /// Prevents any commands submitted afterward to this queue from executing /// until all commands previously submitted to this queue have entered the /// complete state. @@ -367,18 +349,17 @@ event queue::ext_oneapi_submit_barrier(const detail::code_location &CodeLoc) { /// group is being enqueued on. event queue::ext_oneapi_submit_barrier(const std::vector &WaitList, const detail::code_location &CodeLoc) { + + // If waitlist contains only empty, default constructed events, ignore + // them. bool AllEventsEmptyOrNop = std::all_of( begin(WaitList), end(WaitList), [&](const event &Event) -> bool { detail::event_impl &EventImpl = *detail::getSyclObjImpl(Event); return (EventImpl.isDefaultConstructed() || EventImpl.isNOP()) && !EventImpl.hasCommandGraph(); }); - if (is_in_order() && !impl->hasCommandGraph() && !impl->MIsProfilingEnabled && - AllEventsEmptyOrNop) { - return getBarrierEventForInorderQueueHelper(*impl); - } - if (WaitList.empty()) + if (WaitList.empty() || AllEventsEmptyOrNop) return submit([=](handler &CGH) { CGH.ext_oneapi_barrier(); }, CodeLoc); else return submit([=](handler &CGH) { CGH.ext_oneapi_barrier(WaitList); }, diff --git a/sycl/test-e2e/InorderQueue/in_order_ext_oneapi_submit_barrier.cpp b/sycl/test-e2e/InorderQueue/in_order_ext_oneapi_submit_barrier.cpp index f4396e6b31b73..f2b1fba5b9359 100644 --- a/sycl/test-e2e/InorderQueue/in_order_ext_oneapi_submit_barrier.cpp +++ b/sycl/test-e2e/InorderQueue/in_order_ext_oneapi_submit_barrier.cpp @@ -53,28 +53,13 @@ int main() { std::cout << "Test 2" << std::endl; *Res = 0; - auto Event1 = Q.submit( - [&](sycl::handler &CGH) { CGH.host_task([&] { *Res += 1; }); }); - auto BarrierEvent1 = Q.ext_oneapi_submit_barrier(); - assert(checkBarrierEvent(Q.get_backend(), Event1, BarrierEvent1, - false /* host tasks used */)); - auto Event2 = Q.submit([&](sycl::handler &CGH) { CGH.fill(Res, 10, 1); }); + Q.submit([&](sycl::handler &CGH) { CGH.host_task([&] { *Res += 1; }); }); + Q.ext_oneapi_submit_barrier(); + Q.submit([&](sycl::handler &CGH) { CGH.fill(Res, 10, 1); }); Q.wait(); assert(*Res == 10); } - - { - // Test cast 3 - empty queue. - std::cout << "Test 3" << std::endl; - sycl::queue EmptyQ({sycl::property::queue::in_order{}}); - auto BarrierEvent = EmptyQ.ext_oneapi_submit_barrier(); - assert( - BarrierEvent.get_info() == - sycl::info::event_command_status::complete); - BarrierEvent.wait(); - } - { // Test cast 4 - graph. sycl::queue GQueue{sycl::property::queue::in_order{}}; diff --git a/sycl/test-e2e/Regression/ext_oneapi_barrier_opt.cpp b/sycl/test-e2e/Regression/ext_oneapi_barrier_opt.cpp deleted file mode 100644 index 2275c35616945..0000000000000 --- a/sycl/test-e2e/Regression/ext_oneapi_barrier_opt.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// RUN: %{build} %threads_lib -o %t.out -// RUN: %{run} %t.out - -// Check that ext_oneapi_submit_barrier works fine in the scenarios -// when provided waitlist consists of only empty events. - -#include -#include -#include - -#include - -#include - -static constexpr int niter = 1024; -static constexpr int nthreads = 2; - -std::array mutexes; -std::array, nthreads> events; - -void threadFunction(int tid) { - sycl::device dev; - std::cout << dev.get_info() << std::endl; - sycl::context ctx{dev}; - sycl::queue q1{ctx, dev, {sycl::property::queue::in_order()}}; - sycl::queue q2{ctx, dev, {sycl::property::queue::in_order()}}; - for (int i = 0; i < niter; i++) { - sycl::event ev1 = q1.ext_oneapi_submit_barrier(); - q2.ext_oneapi_submit_barrier({ev1}); - sycl::event ev2 = q2.ext_oneapi_submit_barrier(); - q1.ext_oneapi_submit_barrier({ev2}); - } -} - -int main() { - std::array threads; - - for (int i = 0; i < nthreads; i++) { - threads[i] = std::thread{threadFunction, i}; - } - - for (int i = 0; i < nthreads; i++) { - threads[i].join(); - } - std::cout << "All threads have finished." << std::endl; - - return 0; -} diff --git a/sycl/unittests/Extensions/CMakeLists.txt b/sycl/unittests/Extensions/CMakeLists.txt index da81e86c23f38..f4bdfa81f69dc 100644 --- a/sycl/unittests/Extensions/CMakeLists.txt +++ b/sycl/unittests/Extensions/CMakeLists.txt @@ -12,6 +12,7 @@ add_sycl_unittest(ExtensionsTests OBJECT CompositeDevice.cpp OneAPIProd.cpp EnqueueFunctionsEvents.cpp + ExtOneapiBarrierOpt.cpp ProfilingTag.cpp KernelProperties.cpp NoDeviceIPVersion.cpp diff --git a/sycl/unittests/Extensions/ExtOneapiBarrierOpt.cpp b/sycl/unittests/Extensions/ExtOneapiBarrierOpt.cpp new file mode 100644 index 0000000000000..2b96e0b8b7c0a --- /dev/null +++ b/sycl/unittests/Extensions/ExtOneapiBarrierOpt.cpp @@ -0,0 +1,60 @@ +//==------------------- ExtOneapiBarrierOpt.cpp ----------------------------==// +// +// 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 +#include +#include +#include + +using namespace sycl; + +inline thread_local uint32_t NumEventsInWaitList; + +static ur_result_t redefinedEnqueueEventsWaitWithBarrierExt(void *pParams) { + auto params = + *static_cast(pParams); + NumEventsInWaitList = *(params.pnumEventsInWaitList); + return UR_RESULT_SUCCESS; +} + +class ExtOneapiBarrierOptTest : public ::testing::Test { +public: + ExtOneapiBarrierOptTest() : Mock{} {} + +protected: + void SetUp() override { NumEventsInWaitList = 0; } + +protected: + sycl::unittest::UrMock<> Mock; +}; + +// Check that ext_oneapi_submit_barrier works fine in the scenarios +// when provided waitlist consists of only empty events. +// Tets for https://github.com/intel/llvm/pull/12951 +TEST_F(ExtOneapiBarrierOptTest, EmptyEventTest) { + sycl::queue q1{{sycl::property::queue::in_order()}}; + + mock::getCallbacks().set_after_callback( + "urEnqueueEventsWaitWithBarrierExt", + &redefinedEnqueueEventsWaitWithBarrierExt); + + NumEventsInWaitList = 100; + q1.ext_oneapi_submit_barrier(); + ASSERT_EQ(0u, NumEventsInWaitList); + + // ext_oneapi_submit_barrier should ignore empty, default constructed events. + sycl::event E1{}; + NumEventsInWaitList = 100; + q1.ext_oneapi_submit_barrier({E1}); + ASSERT_EQ(0u, NumEventsInWaitList); + + sycl::event E2{}; + NumEventsInWaitList = 100; + q1.ext_oneapi_submit_barrier({E1, E2}); + ASSERT_EQ(0u, NumEventsInWaitList); +}