From ce08eaa2db58bba0cef4bdcda77df97c73e418e1 Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Wed, 16 Apr 2025 10:10:22 -0400 Subject: [PATCH 01/21] Remove discard_events queue prop Signed-off-by: JackAKirk --- .../sycl_ext_oneapi_graph.asciidoc | 10 - ...l_ext_oneapi_discard_queue_events.asciidoc | 212 ------------- .../sycl_ext_oneapi_queue_empty.asciidoc | 7 +- .../sycl/properties/queue_properties.def | 2 - sycl/source/detail/queue_impl.cpp | 14 +- sycl/source/detail/queue_impl.hpp | 29 +- sycl/source/detail/scheduler/commands.cpp | 2 +- sycl/source/handler.cpp | 2 +- sycl/source/queue.cpp | 4 +- .../Adapters/level_zero_batch_test.cpp | 27 -- .../level_zero_dynamic_batch_test.cpp | 6 - sycl/test-e2e/Basic/in_order_queue_status.cpp | 13 - .../discard_events_accessors.cpp | 94 ------ .../discard_events_check_images.cpp | 203 ------------- .../discard_events_kernel_using_assert.hpp | 47 --- .../discard_events_l0_inorder.cpp | 164 ---------- .../DiscardEvents/discard_events_l0_leak.cpp | 47 --- .../discard_events_mixed_calls.cpp | 286 ------------------ .../discard_events_test_queue_ops.hpp | 130 -------- .../discard_events_using_assert.cpp | 17 -- .../discard_events_using_assert_ndebug.cpp | 13 - .../DiscardEvents/discard_events_usm.cpp | 109 ------- .../discard_events_usm_ooo_queue.cpp | 133 -------- sycl/test-e2e/DiscardEvents/invalid_event.cpp | 93 ------ .../invalid_event_exceptions.cpp | 168 ---------- .../no-unsupported-without-info.cpp | 2 - sycl/unittests/queue/Properties.cpp | 2 - 27 files changed, 12 insertions(+), 1824 deletions(-) delete mode 100644 sycl/doc/extensions/supported/sycl_ext_oneapi_discard_queue_events.asciidoc delete mode 100644 sycl/test-e2e/DiscardEvents/discard_events_accessors.cpp delete mode 100644 sycl/test-e2e/DiscardEvents/discard_events_check_images.cpp delete mode 100644 sycl/test-e2e/DiscardEvents/discard_events_kernel_using_assert.hpp delete mode 100644 sycl/test-e2e/DiscardEvents/discard_events_l0_inorder.cpp delete mode 100644 sycl/test-e2e/DiscardEvents/discard_events_l0_leak.cpp delete mode 100644 sycl/test-e2e/DiscardEvents/discard_events_mixed_calls.cpp delete mode 100644 sycl/test-e2e/DiscardEvents/discard_events_test_queue_ops.hpp delete mode 100644 sycl/test-e2e/DiscardEvents/discard_events_using_assert.cpp delete mode 100644 sycl/test-e2e/DiscardEvents/discard_events_using_assert_ndebug.cpp delete mode 100644 sycl/test-e2e/DiscardEvents/discard_events_usm.cpp delete mode 100644 sycl/test-e2e/DiscardEvents/discard_events_usm_ooo_queue.cpp delete mode 100644 sycl/test-e2e/DiscardEvents/invalid_event.cpp delete mode 100644 sycl/test-e2e/DiscardEvents/invalid_event_exceptions.cpp diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_graph.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_graph.asciidoc index ccdcf50049fee..7b4e93ee1b776 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_graph.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_graph.asciidoc @@ -2161,16 +2161,6 @@ code `invalid` if a user tries to add them to a graph. Removing this restriction is something we may look at for future revisions of `sycl_ext_oneapi_graph`. -==== sycl_ext_oneapi_discard_queue_events - -When recording a `sycl::queue` which has been created with the -`ext::oneapi::property::queue::discard_event` property, it is invalid to -use these events returned from queue submissions to create graph edges. This is -in-keeping with the -link:../supported/sycl_ext_oneapi_discard_queue_events.asciidoc[sycl_ext_oneapi_discard_queue_events] -specification wording that `handler::depends_on()` throws an exception when -passed an invalid event. - ==== sycl_ext_oneapi_enqueue_barrier The new handler methods, and queue shortcuts, defined by diff --git a/sycl/doc/extensions/supported/sycl_ext_oneapi_discard_queue_events.asciidoc b/sycl/doc/extensions/supported/sycl_ext_oneapi_discard_queue_events.asciidoc deleted file mode 100644 index f8e62d21a9a31..0000000000000 --- a/sycl/doc/extensions/supported/sycl_ext_oneapi_discard_queue_events.asciidoc +++ /dev/null @@ -1,212 +0,0 @@ -= sycl_ext_oneapi_discard_queue_events -:source-highlighter: coderay -:coderay-linenums-mode: table - -// This section needs to be after the document title. -:doctype: book -:toc2: -:toc: left -:encoding: utf-8 -:lang: en - -:blank: pass:[ +] - -// Set the default source code type in this document to C++, -// for syntax highlighting purposes. This is needed because -// docbook uses c++ and html5 uses cpp. -:language: {basebackend@docbook:c++:cpp} - -// This is necessary for asciidoc, but not for asciidoctor -:cpp: C++ - -== Introduction - -IMPORTANT: This specification is a draft. - -NOTE: Khronos(R) is a registered trademark and SYCL(TM) and SPIR(TM) are -trademarks of The Khronos Group Inc. OpenCL(TM) is a trademark of Apple Inc. -used by permission by Khronos. - -This document describes an extension that introduces a `discard_events` property for -SYCL queues. This property enables developers to inform a SYCL implementation that -the events returned from queue operations will not be used. - -== Notice - -Copyright (c) 2021 Intel Corporation. All rights reserved. - -== Status - -Working Draft - -This is a preview extension specification, intended to provide early access to -a feature for review and community feedback. When the feature matures, this -specification may be released as a formal extension. - -Because the interfaces defined by this specification are not final and are -subject to change they are not intended to be used by shipping software -products. - -== Version - -Revision: 1 - -== Contributors - -Alexander Flegontov, Intel + -Greg Lueck, Intel + -John Pennycook, Intel + -Vlad Romanov, Intel - -== Dependencies - -This extension is written against the SYCL 2020 specification, Revision 4. - -== Feature Test Macro - -This extension provides a feature-test macro as described in the core SYCL -specification section 6.3.3 "Feature test macros". Therefore, an -implementation supporting this extension must predefine the macro -`SYCL_EXT_ONEAPI_DISCARD_QUEUE_EVENTS` to one of the values defined in the table below. -Applications can test for the existence of this macro to determine if the -implementation supports this feature, or applications can test the macro's -value to determine which of the extension's APIs the implementation supports. - -[%header,cols="1,5"] -|=== -|Value |Description -|1 |Initial extension version. Base features are supported. -|=== - -== Overview - -This extension adds `ext::oneapi::property::queue::discard_events` property for `sycl::queue`, -by using this property the application informs a SYCL implementation that it will not use the event -returned by any of the `queue` member functions. (i.e submit, parallel_for, copy, memset and others.) -When the application creates a queue with this property, -the implementation may be able to optimize some operations on the `queue`. -The `discard_events` property is incompatible with `enable_profiling`. -Attempts to construct a `queue` with both properties raises `errc::invalid`. - -Below is a usage example: -[source,c++] ----- - sycl::property_list props{ext::oneapi::property::queue::discard_events{}, - property::queue::in_order{}}; - sycl::queue Queue( props ); - - // some USM preparations .. - - sycl::event e1, e2, e3; - - // returning "invalid" events from each submission function: - e1 = Queue.parallel_for(NDRange, [=](nd_item<1> item){ do_smth1(); }); - - e2 = Queue.single_task([=](){ do_smth2(); }); - - e3 = Queue.submit([&](handler &CGH) { CGH.parallel_for(NDRange, [=](nd_item<1> item){ do_smth3(); }); }); - - Queue.wait(); ----- - -In the example above, the application doesn't use sycl events: `e1`, `e2`, `e3` -and is waiting for the end of work by `queue::wait()`. -When the queue is created with the `discard_events` property, -the returned events will be _invalid_ events, which are `sycl::event` objects that have limited capability. -See the description of behavior for this event below for details. - -Here, only those member functions for the _invalid_ event are described that have behavior different from the default event behavior: -[source,c++] ----- -// must throw an exception with the errc::invalid error code. -std::vector get_wait_list(); - -// must throw an exception with the errc::invalid error code. -void wait(); - -// if invalid event is passed into the function, must throw an exception with the errc::invalid error code. -static void wait(const std::vector &eventList); - -// must throw an exception with the errc::invalid error code. -void wait_and_throw(); - -// if invalid event is passed into the function, must throw an exception with the errc::invalid error code. -static void wait_and_throw(const std::vector &eventList); - -// must return info::event_command_status::ext_oneapi_unknown -get_info() const; ----- - -The behavior when _invalid_ event is passed into handler API: -[source,c++] ----- -// must throw an exception with the errc::invalid error code. -handler::depends_on(event Event) - -// must throw an exception with the errc::invalid error code. -handler::depends_on(const std::vector &Events) ----- - -A new enumerator value is also added to the `info::event_command_status` enumeration, -which is returned by `get_info()` as described above: -[source,c++] ----- -namespace sycl { -namespace info { - -enum class event_command_status : int { - // ... - ext_oneapi_unknown -}; - -} // namespace info -} // namespace sycl ----- - -== Optimization behavior for DPC++ - -This non-normative section describes the conditions when the DPC++ implementation provides an optimization benefit* for the `discard_events` property. - - - The queue must be constructed with the `in_order` property. - - A kernel submitted to the queue must not use the link:../supported/sycl_ext_oneapi_assert.asciidoc[fallback assert feature]. - - A queue operation submitted to the queue must not use streams or buffer / image accessors. However, local accessors do not inhibit optimization. - - Any queue operations using Level Zero backend temporarily work without optimization. - -*The benefit is that a low-level event is not created from backend, thereby saving time. - -See the behavior details for each condition below: - -=== Using out-of-order queue - -No optimization if a queue is created with the `discard_events` property and -the property list does not include `in_order` property. - -=== Using fallback assert feature - -No optimization if the application calls the `assert` macro from a command that is submitted to the queue unless -the device has native support for assertions (as specified by `aspect::ext_oneapi_native_assert`). - -=== Using streams or buffer / image accessors (excluding local accessors) - -No optimization if a queue operation that uses stream objects or buffer / image accessors is submitted to a queue created with -the `discard_events` property. But using local accessors does not affect optimization. - -=== Using Level Zero backend - -Since Level Zero adapter support is required to be able to not create a low-level event, -any queue operations using the Level Zero backend temporarily work without optimization. - - -== Issues - -None. - -== Revision History - -[cols="5,15,15,70"] -[grid="rows"] -[options="header"] -|======================================== -|Rev|Date|Author|Changes -|1|2021-11-09|Alexander Flegontov |*Initial public working draft* -|======================================== diff --git a/sycl/doc/extensions/supported/sycl_ext_oneapi_queue_empty.asciidoc b/sycl/doc/extensions/supported/sycl_ext_oneapi_queue_empty.asciidoc index 2d56fdafc9f0c..24659deef2d42 100644 --- a/sycl/doc/extensions/supported/sycl_ext_oneapi_queue_empty.asciidoc +++ b/sycl/doc/extensions/supported/sycl_ext_oneapi_queue_empty.asciidoc @@ -46,9 +46,10 @@ This extension is supported by {dpcpp} on all backends except OpenCL. [NOTE] ==== Currently support for OpenCL backend is limited, API introduced by this extension -can be called only for in-order queues which doesn't have `discard_events` property. -Exception is thrown if new API is called on other type of queue. OpenCL currently -doesn't have an API to get queue status. +can be called only for in-order queues that have only enqueued operations +returning events. Exception is thrown if new API is called following operations +that did not return a sycl::event, because OpenCL currently doesn't have an API +to get queue status. ==== diff --git a/sycl/include/sycl/properties/queue_properties.def b/sycl/include/sycl/properties/queue_properties.def index 6e0f3fd700952..95470699a0435 100644 --- a/sycl/include/sycl/properties/queue_properties.def +++ b/sycl/include/sycl/properties/queue_properties.def @@ -9,8 +9,6 @@ __SYCL_DATA_LESS_PROP(property::queue, in_order, InOrder) __SYCL_DATA_LESS_PROP(property::queue, enable_profiling, QueueEnableProfiling) -__SYCL_DATA_LESS_PROP(ext::oneapi::property::queue, discard_events, - DiscardEvents) __SYCL_DATA_LESS_PROP(ext::oneapi::property::queue, priority_normal, QueuePriorityNormal) __SYCL_DATA_LESS_PROP(ext::oneapi::property::queue, priority_low, diff --git a/sycl/source/detail/queue_impl.cpp b/sycl/source/detail/queue_impl.cpp index ef00ec1a8fb9c..48d63229638ae 100644 --- a/sycl/source/detail/queue_impl.cpp +++ b/sycl/source/detail/queue_impl.cpp @@ -291,8 +291,6 @@ sycl::detail::optional queue_impl::getLastEvent() { std::lock_guard Lock{MMutex}; if (MGraph.expired() && !MDefaultGraphDeps.LastEventPtr) return std::nullopt; - if (MDiscardEvents) - return createDiscardedEvent(); if (!MGraph.expired() && MExtGraphDeps.LastEventPtr) return detail::createSyclObjFromImpl(MExtGraphDeps.LastEventPtr); return detail::createSyclObjFromImpl(MDefaultGraphDeps.LastEventPtr); @@ -404,7 +402,7 @@ event queue_impl::submitMemOpHelper(const std::shared_ptr &Self, // handler rather than by-passing the scheduler. if (MGraph.expired() && Scheduler::areEventsSafeForSchedulerBypass( ExpandedDepEvents, MContext)) { - if ((MDiscardEvents || !CallerNeedsEvent) && + if (!CallerNeedsEvent && supportsDiscardingPiEvents()) { NestedCallsTracker tracker; MemOpFunc(MemOpArgs..., getUrEvents(ExpandedDepEvents), @@ -449,7 +447,7 @@ event queue_impl::submitMemOpHelper(const std::shared_ptr &Self, EventToStoreIn = EventImpl; } - return discard_or_return(ResEvent); + return ResEvent; } } return submitWithHandler(Self, DepEvents, CallerNeedsEvent, HandlerFunc); @@ -686,7 +684,7 @@ ur_native_handle_t queue_impl::getNative(int32_t &NativeHandleDesc) const { bool queue_impl::ext_oneapi_empty() const { // If we have in-order queue where events are not discarded then just check // the status of the last event. - if (isInOrder() && !MDiscardEvents) { + if (isInOrder()) { std::lock_guard Lock(MMutex); // If there is no last event we know that no work has been submitted, so it // must be trivially empty. @@ -726,12 +724,6 @@ bool queue_impl::ext_oneapi_empty() const { return true; } -event queue_impl::discard_or_return(const event &Event) { - if (!(MDiscardEvents)) - return Event; - return createDiscardedEvent(); -} - void queue_impl::revisitUnenqueuedCommandsState( const EventImplPtr &CompletedHostTask) { if (MIsInorder) diff --git a/sycl/source/detail/queue_impl.hpp b/sycl/source/detail/queue_impl.hpp index 5db9d7e75305e..b0829ad9a90a0 100644 --- a/sycl/source/detail/queue_impl.hpp +++ b/sycl/source/detail/queue_impl.hpp @@ -116,17 +116,11 @@ class queue_impl { : MDevice(Device), MContext(Context), MAsyncHandler(AsyncHandler), MPropList(PropList), MIsInorder(has_property()), - MDiscardEvents( - has_property()), MIsProfilingEnabled(has_property()), MQueueID{ MNextAvailableQueueID.fetch_add(1, std::memory_order_relaxed)} { verifyProps(PropList); if (has_property()) { - if (has_property()) - throw sycl::exception(make_error_code(errc::invalid), - "Queue cannot be constructed with both of " - "discard_events and enable_profiling."); // fallback profiling support. See MFallbackProfiling if (MDevice->has(aspect::queue_profiling)) { // When urDeviceGetGlobalTimestamps is not supported, compute the @@ -184,12 +178,6 @@ class queue_impl { private: void queue_impl_interop(ur_queue_handle_t UrQueue) { - if (has_property() && - has_property()) { - throw sycl::exception(make_error_code(errc::invalid), - "Queue cannot be constructed with both of " - "discard_events and enable_profiling."); - } MQueue = UrQueue; @@ -227,8 +215,6 @@ class queue_impl { const async_handler &AsyncHandler) : MContext(Context), MAsyncHandler(AsyncHandler), MIsInorder(has_property()), - MDiscardEvents( - has_property()), MIsProfilingEnabled(has_property()), MQueueID{ MNextAvailableQueueID.fetch_add(1, std::memory_order_relaxed)} { @@ -246,8 +232,6 @@ class queue_impl { const async_handler &AsyncHandler, const property_list &PropList) : MContext(Context), MAsyncHandler(AsyncHandler), MPropList(PropList), MIsInorder(has_property()), - MDiscardEvents( - has_property()), MIsProfilingEnabled(has_property()), MQueueID{ MNextAvailableQueueID.fetch_add(1, std::memory_order_relaxed)} { @@ -294,9 +278,6 @@ class queue_impl { /// \return an associated SYCL device. device get_device() const { return createSyclObjFromImpl(MDevice); } - /// \return true if the discard event property was set at time of creation. - bool hasDiscardEventsProperty() const { return MDiscardEvents; } - /// \return true if this queue allows for discarded events. bool supportsDiscardingPiEvents() const { return MIsInorder; } @@ -382,7 +363,7 @@ class queue_impl { event ResEvent = submit_impl(CGF, Self, Self, nullptr, /*CallerNeedsEvent=*/true, Loc, IsTopCodeLoc, SubmitInfo); - return discard_or_return(ResEvent); + return ResEvent; } void submit_without_event(const detail::type_erased_cgfo_ty &CGF, @@ -465,11 +446,6 @@ class queue_impl { ext::oneapi::cuda::property::queue::use_default_stream>()) { CreationFlags |= UR_QUEUE_FLAG_USE_DEFAULT_STREAM; } - if (PropList.has_property()) { - // Pass this flag to the Level Zero adapter to be able to check it from - // queue property. - CreationFlags |= UR_QUEUE_FLAG_DISCARD_EVENTS; - } // Track that priority settings are not ambiguous. bool PrioritySeen = false; if (PropList @@ -724,7 +700,6 @@ class queue_impl { #endif protected: - event discard_or_return(const event &Event); template EventImplPtr insertHelperBarrier(const HandlerType &Handler) { @@ -1028,8 +1003,6 @@ class queue_impl { CheckLockCheck> MInOrderExternalEvent; public: - // Queue constructed with the discard_events property - const bool MDiscardEvents; const bool MIsProfilingEnabled; protected: diff --git a/sycl/source/detail/scheduler/commands.cpp b/sycl/source/detail/scheduler/commands.cpp index bf0a061fbee35..64915cf04daab 100644 --- a/sycl/source/detail/scheduler/commands.cpp +++ b/sycl/source/detail/scheduler/commands.cpp @@ -3124,7 +3124,7 @@ ur_result_t ExecCGCommand::enqueueImpQueue() { // the queue has the discard property or the command has been explicitly // marked as not needing an event, e.g. if the user did not ask for one, and // if the queue supports discarded UR event and there are no requirements. - bool DiscardUrEvent = MQueue && (MQueue->MDiscardEvents || !MEventNeeded) && + bool DiscardUrEvent = MQueue && !MEventNeeded && MQueue->supportsDiscardingPiEvents() && MCommandGroup->getRequirements().size() == 0; diff --git a/sycl/source/handler.cpp b/sycl/source/handler.cpp index 5446cffb7cae4..f94eff876cde0 100644 --- a/sycl/source/handler.cpp +++ b/sycl/source/handler.cpp @@ -509,7 +509,7 @@ event handler::finalize() { const detail::EventImplPtr &LastEventImpl = detail::getSyclObjImpl(MLastEvent); - bool DiscardEvent = (MQueue->MDiscardEvents || !impl->MEventNeeded) && + bool DiscardEvent = !impl->MEventNeeded && MQueue->supportsDiscardingPiEvents(); if (DiscardEvent) { // Kernel only uses assert if it's non interop one diff --git a/sycl/source/queue.cpp b/sycl/source/queue.cpp index ec2fe68792c51..cd4f26f09f0a2 100644 --- a/sycl/source/queue.cpp +++ b/sycl/source/queue.cpp @@ -319,7 +319,7 @@ getBarrierEventForInorderQueueHelper(const detail::QueueImplPtr QueueImpl) { /// \return a SYCL event object, which corresponds to the queue the command /// group is being enqueued on. event queue::ext_oneapi_submit_barrier(const detail::code_location &CodeLoc) { - if (is_in_order() && !impl->hasCommandGraph() && !impl->MDiscardEvents && + if (is_in_order() && !impl->hasCommandGraph() && !impl->MIsProfilingEnabled) { event InOrderLastEvent = getBarrierEventForInorderQueueHelper(impl); // If the last event was discarded, fall back to enqueuing a barrier. @@ -347,7 +347,7 @@ event queue::ext_oneapi_submit_barrier(const std::vector &WaitList, return (EventImpl->isDefaultConstructed() || EventImpl->isNOP()) && !EventImpl->hasCommandGraph(); }); - if (is_in_order() && !impl->hasCommandGraph() && !impl->MDiscardEvents && + if (is_in_order() && !impl->hasCommandGraph() && !impl->MIsProfilingEnabled && AllEventsEmptyOrNop) { event InOrderLastEvent = getBarrierEventForInorderQueueHelper(impl); // If the last event was discarded, fall back to enqueuing a barrier. diff --git a/sycl/test-e2e/Adapters/level_zero_batch_test.cpp b/sycl/test-e2e/Adapters/level_zero_batch_test.cpp index da3ff2359c624..8f6e4e0f6a563 100644 --- a/sycl/test-e2e/Adapters/level_zero_batch_test.cpp +++ b/sycl/test-e2e/Adapters/level_zero_batch_test.cpp @@ -2,7 +2,6 @@ // RUN: %{build} -o %t.ooo.out // RUN: %{build} -DUSING_INORDER -o %t.ino.out -// RUN: %{build} -DUSING_DISCARD_EVENTS -o %t.discard_events.out // UNSUPPORTED: ze_debug, level_zero_v2_adapter // To test batching on out-of-order queue: @@ -49,28 +48,6 @@ // Set batching to 9 explicitly // RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=9 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.ino.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB9 %s -// To test batching on in-order queue with discard_events: -// Set batching to 4 explicitly -// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=4 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB4 %s - -// Set batching to 1 explicitly -// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=1 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB1 %s - -// Set batching to 3 explicitly -// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=3 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB3 %s - -// Set batching to 5 explicitly -// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=5 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB5 %s - -// Set batching to 7 explicitly -// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=7 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB7 %s - -// Set batching to 8 explicitly -// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=8 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB8 %s - -// Set batching to 9 explicitly -// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=9 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB9 %s - // level_zero_batch_test.cpp // // This tests the level zero adapter's kernel batching code. The default @@ -292,10 +269,6 @@ int main(int argc, char *argv[]) { #ifdef USING_INORDER sycl::property_list Props{sycl::property::queue::in_order{}}; -#elif USING_DISCARD_EVENTS - sycl::property_list Props{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; #else sycl::property_list Props{}; #endif diff --git a/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp b/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp index 9f8688efcc3aa..0c974d2b306e6 100644 --- a/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp +++ b/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp @@ -3,12 +3,10 @@ // RUN: %{build} -o %t.ooo.out // RUN: %{build} -DUSING_INORDER -o %t.ino.out -// RUN: %{build} -DUSING_DISCARD_EVENTS -o %t.discard_events.out // Check that dynamic batching raises/lowers batch size // RUN: env SYCL_UR_TRACE=2 UR_L0_DEBUG=1 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 %{run} %t.ooo.out 2>&1 | FileCheck --check-prefixes=CKALL,CKDYN %s // RUN: env SYCL_UR_TRACE=2 UR_L0_DEBUG=1 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 %{run} %t.ino.out 2>&1 | FileCheck --check-prefixes=CKALL,CKDYN %s -// RUN: env SYCL_UR_TRACE=2 UR_L0_DEBUG=1 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKDYN %s // level_zero_dynamic_batch_test.cpp // @@ -67,10 +65,6 @@ int main(int argc, char *argv[]) { #ifdef USING_INORDER sycl::property_list Props{sycl::property::queue::in_order{}}; -#elif USING_DISCARD_EVENTS - sycl::property_list Props{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; #else sycl::property_list Props{}; #endif diff --git a/sycl/test-e2e/Basic/in_order_queue_status.cpp b/sycl/test-e2e/Basic/in_order_queue_status.cpp index 68b8b990d1b3d..bfa15932c8401 100644 --- a/sycl/test-e2e/Basic/in_order_queue_status.cpp +++ b/sycl/test-e2e/Basic/in_order_queue_status.cpp @@ -66,19 +66,6 @@ int main() { queue Q1{property::queue::in_order()}; TestFunc(Q1); - // Test in-order queue with discard_events property. - sycl::property_list Props{ - property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - queue Q2{Props}; - - bool ExceptionThrown = false; - try { - TestFunc(Q2); - } catch (sycl::exception &E) { - ExceptionThrown = true; - } - // Feature is not supported for OpenCL, exception must be thrown. if (Q2.get_device().get_backend() == backend::opencl) return ExceptionThrown ? 0 : -1; diff --git a/sycl/test-e2e/DiscardEvents/discard_events_accessors.cpp b/sycl/test-e2e/DiscardEvents/discard_events_accessors.cpp deleted file mode 100644 index 59e0a7f62650f..0000000000000 --- a/sycl/test-e2e/DiscardEvents/discard_events_accessors.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// RUN: %{build} -o %t.out -// -// RUN: env SYCL_UR_TRACE=2 %{run} %t.out &> %t.txt ; FileCheck %s --input-file %t.txt -// -// The test checks that the last parameter is `nullptr` for -// urEnqueueKernelLaunch for USM kernel using local accessor, but -// is not `nullptr` for kernel using buffer accessor. -// -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: .phEvent = nullptr -// -// CHECK-NOT: <--- urEnqueueKernelLaunch({{.*}}.phEvent = nullptr -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK: The test passed. - -#include -#include -#include -#include -#include - -using namespace sycl; -static constexpr int MAGIC_NUM = -1; -static constexpr size_t BUFFER_SIZE = 16; - -void RunKernelHelper(sycl::queue Q, - const std::function &TestFunction) { - int *Harray = sycl::malloc_host(BUFFER_SIZE, Q); - assert(Harray != nullptr); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - Harray[i] = MAGIC_NUM; - } - - TestFunction(Harray); - - // Checks result - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - size_t expected = i + 10; - assert(Harray[i] == expected); - } - free(Harray, Q); -} - -int main(int Argc, const char *Argv[]) { - - sycl::property_list props{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue Q(props); - sycl::nd_range<1> NDRange(BUFFER_SIZE, BUFFER_SIZE); - sycl::range<1> Range(BUFFER_SIZE); - - RunKernelHelper(Q, [&](int *Harray) { - Q.submit([&](sycl::handler &CGH) { - const size_t LocalMemSize = BUFFER_SIZE; - sycl::local_accessor LocalAcc(LocalMemSize, CGH); - - CGH.parallel_for( - NDRange, [=](sycl::nd_item<1> ndi) { - size_t i = ndi.get_global_id(0); - int *Ptr = LocalAcc.get_multi_ptr().get(); - Ptr[i] = i + 5; - Harray[i] = Ptr[i] + 5; - }); - }); - Q.wait(); - }); - - RunKernelHelper(Q, [&](int *Harray) { - sycl::buffer Buf(Range); - Q.submit([&](sycl::handler &CGH) { - auto Acc = Buf.get_access(CGH); - CGH.parallel_for( - Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - Harray[i] = i + 10; - Acc[i] = i + 20; - }); - }); - Q.wait(); - - // Checks result - sycl::host_accessor HostAcc(Buf, sycl::read_only); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - size_t expected = i + 20; - assert(HostAcc[i] == expected); - } - }); - - std::cout << "The test passed." << std::endl; - return 0; -} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_check_images.cpp b/sycl/test-e2e/DiscardEvents/discard_events_check_images.cpp deleted file mode 100644 index e9f8588124b07..0000000000000 --- a/sycl/test-e2e/DiscardEvents/discard_events_check_images.cpp +++ /dev/null @@ -1,203 +0,0 @@ -// UNSUPPORTED: target-amd -// REQUIRES: aspect-ext_intel_legacy_image -// -// RUN: %{build} -o %t.out -// -// RUN: %{run} %t.out image -// RUN: %{run} %t.out mixed -// -// Note that the tests use image functionality and if you have problems with -// the tests, please check if they pass without the discard_events property, if -// they don't pass then it's most likely a general issue unrelated to -// discard_events. - -// 1. There is a SPIR-V spec issue that blocks generation of valid SPIR-V code -// for the OpenCL environments support of the "Unknown" image format: -// https://github.com/KhronosGroup/SPIRV-Headers/issues/487 -// 2. The PR https://github.com/llvm/llvm-project/pull/127242 in upstream needs -// to be merged with intel/llvm to address an issue of mapping from SPIR-V -// friendly builtins to Image Read/Write instructions After the 1 issue is -// resolved and 2 is merged we will re-enable Image support. -// UNSUPPORTED: spirv-backend && arch-intel_gpu_bmg_g21 -// UNSUPPORTED-TRACKER: https://github.com/KhronosGroup/SPIRV-Headers/issues/487 - -#include "../helpers.hpp" // for printableVec -#include -#include -#include -#include -#include -#include -#include - -using namespace sycl; -static constexpr size_t BUFFER_SIZE = 1024; -static constexpr int MAX_ITER_NUM1 = 10; -static constexpr int MAX_ITER_NUM2 = 10; -static constexpr int InitialVal = MAX_ITER_NUM1; - -void TestHelper(sycl::queue Q, - const std::function ImgSize, int *Harray, - sycl::image<2> Img)> &Function) { - int *Harray = sycl::malloc_shared(BUFFER_SIZE, Q); - assert(Harray != nullptr); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - Harray[i] = 0; - } - - const sycl::image_channel_order ChanOrder = sycl::image_channel_order::rgba; - const sycl::image_channel_type ChanType = - sycl::image_channel_type::signed_int32; - - const sycl::range<2> ImgSize(sycl::sqrt(static_cast(BUFFER_SIZE)), - sycl::sqrt(static_cast(BUFFER_SIZE))); - std::vector ImgHostData( - ImgSize.size(), {InitialVal, InitialVal, InitialVal, InitialVal}); - sycl::image<2> Img(ImgHostData.data(), ChanOrder, ChanType, ImgSize); - - Function(ImgSize, Harray, Img); - - free(Harray, Q); -} - -void IfTrueIncrementUSM(sycl::queue Q, sycl::range<1> Range, int *Harray, - int ValueToCheck) { - Q.submit([&](sycl::handler &CGH) { - CGH.parallel_for(Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (Harray[i] == ValueToCheck) { - Harray[i] += 1; - } - }); - }); -} - -void IfTrueIncrementImageAndUSM(sycl::queue Q, sycl::range<2> ImgSize, - int *Harray, sycl::image<2> Img, - int HarrayValueToCheck, int ImageValueToCheck) { - Q.submit([&](sycl::handler &CGH) { - auto Img1Acc = Img.get_access(CGH); - auto Img2Acc = Img.get_access(CGH); - CGH.parallel_for(ImgSize, [=](sycl::item<2> Item) { - size_t i = Item.get_linear_id(); - if (Harray[i] == HarrayValueToCheck) { - sycl::int4 Data = Img1Acc.read(sycl::int2{Item[0], Item[1]}); - if (Data[0] == ImageValueToCheck && Data[1] == ImageValueToCheck && - Data[2] == ImageValueToCheck && Data[3] == ImageValueToCheck) { - Data[0]++; - Data[3] = Data[2] = Data[1] = Data[0]; - Img2Acc.write(sycl::int2{Item[0], Item[1]}, Data); - } - ++Harray[i]; - } - }); - }); -} - -void RunTest_ImageTest(sycl::queue Q) { - TestHelper(Q, [&](sycl::range<2> ImgSize, int *Harray, sycl::image<2> Img) { - sycl::range<1> Range(BUFFER_SIZE); - for (int i = 0; i < MAX_ITER_NUM1; ++i) - IfTrueIncrementUSM(Q, Range, Harray, (i)); - - for (int i = 0; i < MAX_ITER_NUM2; ++i) - IfTrueIncrementImageAndUSM(Q, ImgSize, Harray, Img, (MAX_ITER_NUM1 + i), - (InitialVal + i)); - Q.wait(); - - // check results - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1 + MAX_ITER_NUM2; - assert(Harray[i] == expected); - } - - { - auto HostAcc = - Img.template get_access(); - int expected = InitialVal + MAX_ITER_NUM2; - for (int X = 0; X < ImgSize[0]; ++X) - for (int Y = 0; Y < ImgSize[1]; ++Y) { - sycl::int4 Vec1 = sycl::int4(expected); - sycl::int4 Vec2 = HostAcc.read(sycl::int2{X, Y}); - if (Vec1[0] != Vec2[0] || Vec1[1] != Vec2[1] || Vec1[2] != Vec2[2] || - Vec1[3] != Vec2[3]) { - std::cerr << "Failed" << std::endl; - std::cerr << "Element [ " << X << ", " << Y << " ]" << std::endl; - std::cerr << "Expected: " << printableVec(Vec1) << std::endl; - std::cerr << " Got : " << printableVec(Vec2) << std::endl; - assert(false && "ImageTest failed!"); - } - } - } - }); -} - -void RunTest_ImageTest_Mixed(sycl::queue Q) { - TestHelper(Q, [&](sycl::range<2> ImgSize, int *Harray, sycl::image<2> Img) { - sycl::range<1> Range(BUFFER_SIZE); - - for (int i = 0; i < MAX_ITER_NUM1; ++i) { - IfTrueIncrementUSM(Q, Range, Harray, (i * 2)); - IfTrueIncrementImageAndUSM(Q, ImgSize, Harray, Img, (i * 2 + 1), - (InitialVal + i)); - } - - for (int i = 0; i < MAX_ITER_NUM2; ++i) { - IfTrueIncrementImageAndUSM(Q, ImgSize, Harray, Img, - (MAX_ITER_NUM1 * 2 + i * 2), - (InitialVal + MAX_ITER_NUM1 + i)); - IfTrueIncrementUSM(Q, Range, Harray, (MAX_ITER_NUM1 * 2 + i * 2 + 1)); - } - - Q.wait(); - - // check results - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1 * 2 + MAX_ITER_NUM2 * 2; - assert(Harray[i] == expected); - } - - { - auto HostAcc = - Img.template get_access(); - int expected = InitialVal + MAX_ITER_NUM1 + MAX_ITER_NUM2; - for (int X = 0; X < ImgSize[0]; ++X) - for (int Y = 0; Y < ImgSize[1]; ++Y) { - sycl::int4 Vec1 = sycl::int4(expected); - sycl::int4 Vec2 = HostAcc.read(sycl::int2{X, Y}); - if (Vec1[0] != Vec2[0] || Vec1[1] != Vec2[1] || Vec1[2] != Vec2[2] || - Vec1[3] != Vec2[3]) { - std::cerr << "Failed" << std::endl; - std::cerr << "Element [ " << X << ", " << Y << " ]" << std::endl; - std::cerr << "Expected: " << printableVec(Vec1) << std::endl; - std::cerr << " Got : " << printableVec(Vec2) << std::endl; - assert(false && "ImageTest_Mixed failed!"); - } - } - } - }); -} - -int main(int Argc, const char *Argv[]) { - assert(Argc == 2 && "Invalid number of arguments"); - std::string TestType(Argv[1]); - - sycl::property_list props{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue Q(props); - - auto dev = Q.get_device(); - if (TestType == "image") { - std::cerr << "RunTest_ImageTest" << std::endl; - RunTest_ImageTest(Q); - } else if (TestType == "mixed") { - std::cerr << "RunTest_ImageTest_Mixed" << std::endl; - RunTest_ImageTest_Mixed(Q); - } else { - assert(0 && "Unsupported test type!"); - } - - std::cout << "The test passed." << std::endl; - return 0; -} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_kernel_using_assert.hpp b/sycl/test-e2e/DiscardEvents/discard_events_kernel_using_assert.hpp deleted file mode 100644 index 1856d9a1ccfae..0000000000000 --- a/sycl/test-e2e/DiscardEvents/discard_events_kernel_using_assert.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include -#include -#include -#include - -using namespace sycl; -static constexpr int MAGIC_NUM = -1; -static constexpr size_t BUFFER_SIZE = 16; - -int main(int Argc, const char *Argv[]) { - - sycl::property_list Props{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue Q(Props); - - sycl::range<1> Range(BUFFER_SIZE); - int *Harray = sycl::malloc_host(BUFFER_SIZE, Q); - if (Harray == nullptr) { - return -1; - } - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - Harray[i] = MAGIC_NUM; - } - - Q.submit([&](sycl::handler &CGH) { - CGH.parallel_for( - Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - Harray[i] = i + 10; - assert(Harray[i] == i + 10 && "assert message"); - }); - }); - Q.wait(); - - // Checks result - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - size_t expected = i + 10; - if (Harray[i] != expected) - return -1; - } - free(Harray, Q); - - std::cout << "The test passed." << std::endl; - return 0; -} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_l0_inorder.cpp b/sycl/test-e2e/DiscardEvents/discard_events_l0_inorder.cpp deleted file mode 100644 index c23bb4a6175fc..0000000000000 --- a/sycl/test-e2e/DiscardEvents/discard_events_l0_inorder.cpp +++ /dev/null @@ -1,164 +0,0 @@ -// REQUIRES: level_zero -// -// RUN: %{build} -o %t.out -// -// RUN: env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_PI_LEVEL_ZERO_BATCH_SIZE=0 ONEAPI_DEVICE_SELECTOR="level_zero:*" %{run} %t.out -// RUN: env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_PI_LEVEL_ZERO_BATCH_SIZE=1 ONEAPI_DEVICE_SELECTOR="level_zero:*" %{run} %t.out -// RUN: env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_PI_LEVEL_ZERO_BATCH_SIZE=2 ONEAPI_DEVICE_SELECTOR="level_zero:*" %{run} %t.out -// RUN: env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_PI_LEVEL_ZERO_BATCH_SIZE=3 ONEAPI_DEVICE_SELECTOR="level_zero:*" %{run} %t.out -// -// The test is to check the execution of different queue operations has in-order -// semantics regardless of batching. -// -// IMPORTANT NOTE: this is a critical test, double-check if your changes are -// related to L0 barriers that provide links between commands within the same -// command-list or if your changes are related to L0 events and links between -// command-lists. if you have problems with this test, first see if other tests -// related to discard_events pass. And please check if the test passes without -// the discard_events property, if it doesn't pass then it's most likely a -// general issue unrelated to discard_events. - -#include -#include -#include -#include -#include -#include - -static constexpr int MAGIC_NUM1 = 2; - -sycl::aspect getUSMAspect(sycl::usm::alloc Alloc) { - if (Alloc == sycl::usm::alloc::host) - return sycl::aspect::usm_host_allocations; - - if (Alloc == sycl::usm::alloc::device) - return sycl::aspect::usm_device_allocations; - - assert(Alloc == sycl::usm::alloc::shared && "Unknown USM allocation type"); - return sycl::aspect::usm_shared_allocations; -} - -void RunCalculation(sycl::queue queue, sycl::usm::alloc AllocType) { - int buffer_size = 100; - sycl::range<1> range(buffer_size); - auto Dev = queue.get_device(); - if (!Dev.has(getUSMAspect(AllocType))) - return; - - int *values1 = - sycl::malloc(buffer_size, Dev, queue.get_context(), AllocType); - int *values2 = - sycl::malloc(buffer_size, Dev, queue.get_context(), AllocType); - int *values3 = - sycl::malloc(buffer_size, Dev, queue.get_context(), AllocType); - - std::vector values(buffer_size, 0); - std::iota(values.begin(), values.end(), 0); - - std::vector vec1(buffer_size, 0); - std::vector vec2(buffer_size, 0); - std::vector vec3(buffer_size, 0); - - try { - queue.memcpy(values1, values.data(), buffer_size * sizeof(int)); - queue.memcpy(values2, values1, buffer_size * sizeof(int)); - queue.memcpy(values3, values2, buffer_size * sizeof(int)); - queue.memset(values1, 0, buffer_size * sizeof(int)); - - queue.submit([&](sycl::handler &cgh) { - cgh.parallel_for(range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (values1[i] == 0) - if (values2[i] == i) - if (values3[i] == i) { - values1[i] += i; - values2[i] = MAGIC_NUM1; - values3[i] = i; - } - }); - }); - - queue.submit([&](sycl::handler &cgh) { - cgh.parallel_for(range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (values1[i] == i) - if (values2[i] == MAGIC_NUM1) - if (values3[i] == i) { - values1[i] += 10; - } - }); - }); - - queue.memcpy(values.data(), values1, buffer_size * sizeof(int)); - queue.memcpy(values2, values.data(), buffer_size * sizeof(int)); - - queue.submit([&](sycl::handler &cgh) { - cgh.parallel_for(range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (values1[i] == i + 10) - if (values2[i] == i + 10) - if (values3[i] == i) { - values1[i] += 100; - values2[i] = i; - } - }); - }); - - queue.submit([&](sycl::handler &cgh) { - cgh.parallel_for(range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (values1[i] == i + 110) - if (values2[i] == i) - if (values3[i] == i) { - values1[i] += 1000; - } - }); - }); - - queue.submit([&](sycl::handler &cgh) { - cgh.parallel_for(range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (values1[i] == i + 1110) - if (values2[i] == i) - if (values3[i] == i) { - values1[i] += 10000; - } - }); - }); - - queue.memcpy(vec1.data(), values1, buffer_size * sizeof(int)); - queue.memcpy(vec2.data(), values2, buffer_size * sizeof(int)); - queue.memcpy(vec3.data(), values3, buffer_size * sizeof(int)); - - queue.wait(); - - for (int i = 0; i < buffer_size; ++i) { - int expected = i + 11110; - assert(vec1[i] == expected); - expected = i; - assert(vec2[i] == expected); - assert(vec3[i] == expected); - } - - } catch (sycl::exception &e) { - std::cout << "Exception: " << std::string(e.what()) << std::endl; - } - - free(values1, queue); - free(values2, queue); - free(values3, queue); -} - -int main(int argc, char *argv[]) { - sycl::property_list Props{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue queue(Props); - - RunCalculation(queue, sycl::usm::alloc::host); - RunCalculation(queue, sycl::usm::alloc::shared); - RunCalculation(queue, sycl::usm::alloc::device); - - std::cout << "The test passed." << std::endl; - return 0; -} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_l0_leak.cpp b/sycl/test-e2e/DiscardEvents/discard_events_l0_leak.cpp deleted file mode 100644 index adbffd60d98b1..0000000000000 --- a/sycl/test-e2e/DiscardEvents/discard_events_l0_leak.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// REQUIRES: level_zero -// -// RUN: %{build} -o %t.out -// -// RUN: env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_PI_LEVEL_ZERO_BATCH_SIZE=4 ONEAPI_DEVICE_SELECTOR='level_zero:*' %{l0_leak_check} %{run} %t.out wait 2>&1 | FileCheck %s -// RUN: env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_PI_LEVEL_ZERO_BATCH_SIZE=4 ONEAPI_DEVICE_SELECTOR='level_zero:*' %{l0_leak_check} %{run} %t.out nowait 2>&1 | FileCheck %s -// -// CHECK-NOT: LEAK -// -// The test is to check that there are no leaks reported with the embedded -// UR_L0_LEAKS_DEBUG=1 ( %{l0_leak_check} ) testing capability. -// In addition to general leak checking, especially for discard_events, the test -// checks that urKernelRelease to be executed for each kernel call, and -// EventRelease for events, that are used for dependencies between -// command-lists. - -#include -#include -int main(int argc, char *argv[]) { - assert(argc == 2 && "Invalid number of arguments"); - std::string use_queue_finish(argv[1]); - - bool use = false; - if (use_queue_finish == "wait") { - use = true; - std::cerr << "Use queue::wait" << std::endl; - } else if (use_queue_finish == "nowait") { - std::cerr << "No wait. Ensure resources are released anyway" << std::endl; - } else { - assert(0 && "Unsupported parameter value"); - } - - sycl::property_list Props{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue q(Props); - - // test has multiple command-lists thanks to this loop and fixed batch size. - for (size_t i = 0; i < 100; ++i) - q.single_task([]() {}); - - if (use) - q.wait(); - - std::cout << "The test passed." << std::endl; - return 0; -} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_mixed_calls.cpp b/sycl/test-e2e/DiscardEvents/discard_events_mixed_calls.cpp deleted file mode 100644 index 041519a64d900..0000000000000 --- a/sycl/test-e2e/DiscardEvents/discard_events_mixed_calls.cpp +++ /dev/null @@ -1,286 +0,0 @@ -// RUN: %{build} -o %t.out - -// The purpose of all tests is to make sure in-order semantics works correctly -// using discard_events and alternating event and eventless kernel calls in -// different ways. - -// The test checks that eventless kernel calls work correctly after several -// event kernel calls. -// RUN: %{run} %t.out accessor-usm - -// The test checks that event kernel calls work correctly after several -// eventless kernel calls. -// RUN: %{run} %t.out usm-accessor - -// The test checks that alternating event and eventless kernel calls work -// correctly. -// RUN: %{run} %t.out mixed - -// The test checks that urEnqueueMemBufferMap and urEnqueueMemUnmap work -// correctly when we alternate between event and eventless kernel calls. -// RUN: %{run} %t.out map-unmap - -// Note that the tests use buffer functionality and if you have problems with -// the tests, please check if they pass without the discard_events property, if -// they don't pass then it's most likely a general issue unrelated to -// discard_events. -// REQUIRES: aspect-usm_shared_allocations -#include -#include -#include -#include -#include - -using namespace sycl; -static constexpr size_t BUFFER_SIZE = 1024; -static constexpr int MAX_ITER_NUM1 = 10; -static constexpr int MAX_ITER_NUM2 = 10; - -void TestHelper(sycl::queue Q, - const std::function Range, int *Harray, - sycl::buffer Buf)> &Function) { - int *Harray = sycl::malloc_shared(BUFFER_SIZE, Q); - assert(Harray != nullptr); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - Harray[i] = 0; - } - - sycl::range<1> Range(BUFFER_SIZE); - sycl::buffer Buf(Range); - - Function(Range, Harray, Buf); - - free(Harray, Q); -} - -void IfTrueIncrementUSM(sycl::queue Q, sycl::range<1> Range, int *Harray, - int ValueToCheck) { - Q.submit([&](sycl::handler &CGH) { - CGH.parallel_for(Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (Harray[i] == ValueToCheck) { - Harray[i] += 1; - } - }); - }); -} - -void IfTrueIncrementBufferAndUSM(sycl::queue Q, sycl::range<1> Range, - int *Harray, sycl::buffer Buf, - int ValueToCheck) { - Q.submit([&](sycl::handler &CGH) { - auto Acc = Buf.get_access(CGH); - CGH.parallel_for( - Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (Harray[i] == ValueToCheck) { - ++Acc[i]; - ++Harray[i]; - } - }); - }); -} - -void RunTest_USM_Accessor(sycl::queue Q) { - TestHelper(Q, [&](sycl::range<1> Range, int *Harray, - sycl::buffer Buf) { - { - sycl::host_accessor HostAcc(Buf); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - HostAcc[i] = 0; - } - } - - for (int i = 0; i < MAX_ITER_NUM1; ++i) - IfTrueIncrementUSM(Q, Range, Harray, (i)); - - for (int i = 0; i < MAX_ITER_NUM2; ++i) - IfTrueIncrementBufferAndUSM(Q, Range, Harray, Buf, (MAX_ITER_NUM1 + i)); - - Q.wait(); - - // check results - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1 + MAX_ITER_NUM2; - assert(Harray[i] == expected); - } - { - sycl::host_accessor HostAcc(Buf, sycl::read_only); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM2; - assert(HostAcc[i] == expected); - } - } - }); -} - -void RunTest_Accessor_USM(sycl::queue Q) { - TestHelper( - Q, [&](sycl::range<1> Range, int *Harray, sycl::buffer Buf) { - { - sycl::host_accessor HostAcc(Buf); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - HostAcc[i] = 0; - } - } - - for (int i = 0; i < MAX_ITER_NUM1; ++i) - IfTrueIncrementBufferAndUSM(Q, Range, Harray, Buf, (i)); - - for (int i = 0; i < MAX_ITER_NUM2; ++i) - IfTrueIncrementUSM(Q, Range, Harray, (MAX_ITER_NUM1 + i)); - - Q.wait(); - - // check results - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1 + MAX_ITER_NUM2; - assert(Harray[i] == expected); - } - { - sycl::host_accessor HostAcc(Buf, sycl::read_only); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1; - assert(HostAcc[i] == expected); - } - } - }); -} - -void RunTest_Mixed(sycl::queue Q) { - TestHelper( - Q, [&](sycl::range<1> Range, int *Harray, sycl::buffer Buf) { - { - sycl::host_accessor HostAcc(Buf); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - HostAcc[i] = 0; - } - } - - for (int i = 0; i < MAX_ITER_NUM1; ++i) { - IfTrueIncrementUSM(Q, Range, Harray, (i * 2)); - IfTrueIncrementBufferAndUSM(Q, Range, Harray, Buf, (i * 2 + 1)); - } - - for (int i = 0; i < MAX_ITER_NUM2; ++i) { - IfTrueIncrementBufferAndUSM(Q, Range, Harray, Buf, - (MAX_ITER_NUM1 * 2 + i * 2)); - IfTrueIncrementUSM(Q, Range, Harray, (MAX_ITER_NUM1 * 2 + i * 2 + 1)); - } - - Q.wait(); - - // check results - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1 * 2 + MAX_ITER_NUM2 * 2; - assert(Harray[i] == expected); - } - { - sycl::host_accessor HostAcc(Buf, sycl::read_only); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1 + MAX_ITER_NUM2; - assert(HostAcc[i] == expected); - } - } - }); -} - -void RunTest_MemBufferMapUnMap(sycl::queue Q) { - TestHelper( - Q, [&](sycl::range<1> Range, int *Harray, sycl::buffer Buf) { - Q.submit([&](sycl::handler &CGH) { - auto Acc = Buf.get_access(CGH); - CGH.parallel_for(Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - Harray[i] = i; - Acc[i] = i; - }); - }); - - Q.submit([&](sycl::handler &CGH) { - CGH.parallel_for(Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (Harray[i] == i) - Harray[i] += 10; - }); - }); - - { - // waiting for all queue operations in urEnqueueMemBufferMap and then - // checking buffer - sycl::host_accessor HostAcc(Buf); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = i; - assert(HostAcc[i] == expected); - } - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - HostAcc[i] += 10; - } - } - - Q.submit([&](sycl::handler &CGH) { - CGH.parallel_for(Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (Harray[i] == (i + 10)) - Harray[i] += 100; - }); - }); - - Q.submit([&](sycl::handler &CGH) { - // waiting for all queue operations in urEnqueueMemUnmap and then - // using buffer - auto Acc = Buf.get_access(CGH); - CGH.parallel_for(Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (Acc[i] == (i + 10)) - if (Harray[i] == (i + 110)) { - Harray[i] += 1000; - Acc[i] += 100; - } - }); - }); - Q.wait(); - - // check results - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = i + 1110; - assert(Harray[i] == expected); - } - { - sycl::host_accessor HostAcc(Buf, sycl::read_only); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = i + 110; - assert(HostAcc[i] == expected); - } - } - }); -} - -int main(int Argc, const char *Argv[]) { - assert(Argc == 2 && "Invalid number of arguments"); - std::string TestType(Argv[1]); - - sycl::property_list props{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue Q(props); - - if (TestType == "accessor-usm") { - std::cerr << "RunTest_Accessor_USM" << std::endl; - RunTest_Accessor_USM(Q); - } else if (TestType == "usm-accessor") { - std::cerr << "RunTest_USM_Accessor" << std::endl; - RunTest_USM_Accessor(Q); - } else if (TestType == "mixed") { - std::cerr << "RunTest_Mixed" << std::endl; - RunTest_Mixed(Q); - } else if (TestType == "map-unmap") { - std::cerr << "RunTest_MemBufferMapUnMap" << std::endl; - RunTest_MemBufferMapUnMap(Q); - } else { - assert(0 && "Unsupported test type!"); - } - - std::cout << "The test passed." << std::endl; - return 0; -} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_test_queue_ops.hpp b/sycl/test-e2e/DiscardEvents/discard_events_test_queue_ops.hpp deleted file mode 100644 index 81b7a64201cd9..0000000000000 --- a/sycl/test-e2e/DiscardEvents/discard_events_test_queue_ops.hpp +++ /dev/null @@ -1,130 +0,0 @@ - -#include -#include -#include -#include -#include - -using namespace sycl; - -void CheckArray(sycl::queue Q, int *x, size_t buffer_size, int expected) { - Q.wait(); - for (size_t i = 0; i < buffer_size; ++i) - assert(x[i] == expected); -} - -static constexpr size_t BUFFER_SIZE = 16; - -void TestQueueOperations(sycl::queue Q) { - sycl::range<1> Range(BUFFER_SIZE); - auto Dev = Q.get_device(); - auto Ctx = Q.get_context(); - int *x = sycl::malloc_shared(BUFFER_SIZE, Q); - assert(x != nullptr); - int *y = sycl::malloc_shared(BUFFER_SIZE, Q); - assert(y != nullptr); - - Q.memset(x, 0, BUFFER_SIZE * sizeof(int)); - CheckArray(Q, x, BUFFER_SIZE, 0); - - Q.memcpy(y, x, BUFFER_SIZE * sizeof(int)); - CheckArray(Q, y, BUFFER_SIZE, 0); - - Q.fill(y, 1, BUFFER_SIZE); - CheckArray(Q, y, BUFFER_SIZE, 1); - - Q.copy(y, x, BUFFER_SIZE); - CheckArray(Q, x, BUFFER_SIZE, 1); - - Q.prefetch(y, BUFFER_SIZE * sizeof(int)); - Q.mem_advise(y, BUFFER_SIZE * sizeof(int), 0); - Q.ext_oneapi_submit_barrier(); - - Q.single_task([=] { - for (auto i = 0u; i < BUFFER_SIZE; ++i) - y[i] *= 2; - }); - CheckArray(Q, y, BUFFER_SIZE, 2); - - Q.parallel_for(Range, - [=](sycl::item<1> itemID) { y[itemID.get_id(0)] *= 3; }); - CheckArray(Q, y, BUFFER_SIZE, 6); - - // Creates new queue with the same context/device, but without discard_events - // property. This queue returns a normal event, not a discarded one. - sycl::queue RegularQ(Ctx, Dev, sycl::property::queue::in_order{}); - int *x1 = sycl::malloc_shared(BUFFER_SIZE, RegularQ); - assert(x1 != nullptr); - auto event = RegularQ.memset(x1, 0, BUFFER_SIZE * sizeof(int)); - - Q.memcpy(y, x, 0, event); - CheckArray(Q, y, BUFFER_SIZE, 6); - - Q.wait(); - free(x, Q); - free(y, Q); - free(x1, RegularQ); -} - -void TestQueueOperationsViaSubmit(sycl::queue Q) { - sycl::range<1> Range(BUFFER_SIZE); - auto Dev = Q.get_device(); - auto Ctx = Q.get_context(); - int *x = sycl::malloc_shared(BUFFER_SIZE, Q); - assert(x != nullptr); - int *y = sycl::malloc_shared(BUFFER_SIZE, Q); - assert(y != nullptr); - - Q.submit( - [&](sycl::handler &CGH) { CGH.memset(x, 0, BUFFER_SIZE * sizeof(int)); }); - CheckArray(Q, x, BUFFER_SIZE, 0); - - Q.submit( - [&](sycl::handler &CGH) { CGH.memcpy(y, x, BUFFER_SIZE * sizeof(int)); }); - CheckArray(Q, y, BUFFER_SIZE, 0); - - Q.submit([&](sycl::handler &CGH) { CGH.fill(y, 1, BUFFER_SIZE); }); - CheckArray(Q, y, BUFFER_SIZE, 1); - - Q.submit([&](sycl::handler &CGH) { CGH.copy(y, x, BUFFER_SIZE); }); - CheckArray(Q, x, BUFFER_SIZE, 1); - - Q.submit( - [&](sycl::handler &CGH) { CGH.prefetch(y, BUFFER_SIZE * sizeof(int)); }); - Q.submit([&](sycl::handler &CGH) { - CGH.mem_advise(y, BUFFER_SIZE * sizeof(int), 0); - }); - Q.submit([&](sycl::handler &CGH) { CGH.ext_oneapi_barrier(); }); - - Q.submit([&](sycl::handler &CGH) { - CGH.single_task([=] { - for (auto i = 0u; i < BUFFER_SIZE; ++i) - y[i] *= 2; - }); - }); - CheckArray(Q, y, BUFFER_SIZE, 2); - - Q.submit([&](sycl::handler &CGH) { - CGH.parallel_for(Range, - [=](sycl::item<1> itemID) { y[itemID.get_id(0)] *= 3; }); - }); - CheckArray(Q, y, BUFFER_SIZE, 6); - - // Creates new queue with the same context/device, but without discard_events - // property. This queue returns a normal event, not a discarded one. - sycl::queue RegularQ(Ctx, Dev, sycl::property::queue::in_order{}); - int *x1 = sycl::malloc_shared(BUFFER_SIZE, RegularQ); - assert(x1 != nullptr); - auto event = RegularQ.memset(x1, 0, BUFFER_SIZE * sizeof(int)); - - Q.submit([&](sycl::handler &CGH) { - CGH.depends_on(event); - CGH.memcpy(y, x, 0); - }); - CheckArray(Q, y, BUFFER_SIZE, 6); - - Q.wait(); - free(x, Q); - free(y, Q); - free(x1, RegularQ); -} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_using_assert.cpp b/sycl/test-e2e/DiscardEvents/discard_events_using_assert.cpp deleted file mode 100644 index 5d965b1c27ff1..0000000000000 --- a/sycl/test-e2e/DiscardEvents/discard_events_using_assert.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// FIXME unsupported on CUDA and HIP until fallback libdevice becomes available -// UNSUPPORTED: cuda || hip -// -// RUN: %{build} -o %t.out -// -// RUN: env SYCL_UR_TRACE=2 %{run} %t.out &> %t.txt ; FileCheck %s --input-file %t.txt -// -// The test checks that the last parameter is not `nullptr` for -// urEnqueueKernelLaunch. -// -// CHECK-NOT: <--- urEnqueueKernelLaunch({{.*}}.phEvent = nullptr -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK: The test passed. - -#include "discard_events_kernel_using_assert.hpp" diff --git a/sycl/test-e2e/DiscardEvents/discard_events_using_assert_ndebug.cpp b/sycl/test-e2e/DiscardEvents/discard_events_using_assert_ndebug.cpp deleted file mode 100644 index cdfbbe1386ed5..0000000000000 --- a/sycl/test-e2e/DiscardEvents/discard_events_using_assert_ndebug.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %{build} -DNDEBUG -o %t.out -// -// RUN: env SYCL_UR_TRACE=2 %{run} %t.out &> %t.txt ; FileCheck %s --input-file %t.txt -// -// The test checks that the last parameter is `nullptr` for -// urEnqueueKernelLaunch. -// -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: .phEvent = nullptr -// -// CHECK: The test passed. - -#include "discard_events_kernel_using_assert.hpp" diff --git a/sycl/test-e2e/DiscardEvents/discard_events_usm.cpp b/sycl/test-e2e/DiscardEvents/discard_events_usm.cpp deleted file mode 100644 index 8c446fee88365..0000000000000 --- a/sycl/test-e2e/DiscardEvents/discard_events_usm.cpp +++ /dev/null @@ -1,109 +0,0 @@ -// RUN: %{build} -o %t.out -// -// On level_zero Q.fill uses urEnqueueKernelLaunch and not urEnqueueUSMFill -// due to https://github.com/intel/llvm/issues/13787 -// -// RUN: env SYCL_UR_TRACE=2 %{run} %t.out &> %t.txt ; FileCheck %s --input-file %t.txt --check-prefixes=CHECK%if level_zero %{,CHECK-L0%} %else %{,CHECK-OTHER%} -// -// REQUIRES: aspect-usm_shared_allocations -// The test checks that the last parameter is `nullptr` for all UR calls that -// should discard events. -// {{0|0000000000000000}} is required for various output on Linux and Windows. -// NOTE: urEnqueueUSMPrefetch and urEnqueueUSMAdvise in the CUDA and -// HIP backends may return a warning result on Windows with error-code -// 66 (UR_RESULT_ERROR_ADAPTER_SPECIFIC) if USM managed memory is not -// supported or if unsupported advice flags are used for the latter API. -// Since it is a warning it is safe to ignore for this test. -// -// Everything that follows TestQueueOperations() -// CHECK: <--- urEnqueueUSMFill -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueUSMMemcpy -// CHECK: .phEvent = nullptr -// -// Level-zero backend doesn't use urEnqueueUSMFill -// CHECK-L0: <--- urEnqueueKernelLaunch -// CHECK-L0: .phEvent = nullptr -// CHECK-OTHER: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr -// -// ---> urEnqueueUSMMemcpy( -// CHECK: <--- urEnqueueUSMMemcpy -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueUSMPrefetch -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueUSMAdvise -// CHECK: .phEvent = nullptr -// CHECK: -> {{UR_RESULT_SUCCESS|UR_RESULT_ERROR_ADAPTER_SPECIFIC}} -// -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: .phEvent = nullptr -// -// RegularQueue -// CHECK-NOT: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMFill -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK: <--- urEnqueueEventsWait -// CHECK: .phEvent = nullptr -// -// Everything that follows TestQueueOperationsViaSubmit() -// CHECK: <--- urEnqueueUSMFill -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueUSMMemcpy -// CHECK: .phEvent = nullptr -// -// Level-zero backend doesn't use urEnqueueUSMFill -// CHECK-L0: <--- urEnqueueKernelLaunch -// CHECK-L0: .phEvent = nullptr -// CHECK-OTHER: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr -// -// ---> urEnqueueUSMMemcpy( -// CHECK: <--- urEnqueueUSMMemcpy -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueUSMPrefetch -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueUSMAdvise -// CHECK: .phEvent = nullptr -// CHECK-SAME: ) -> {{UR_RESULT_SUCCESS|UR_RESULT_ERROR_ADAPTER_SPECIFIC}} -// -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: .phEvent = nullptr -// -// RegularQueue -// CHECK-NOT: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMFill -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK: <--- urEnqueueEventsWait -// CHECK: .phEvent = nullptr -// -// CHECK: The test passed. - -#include "discard_events_test_queue_ops.hpp" -#include -int main(int Argc, const char *Argv[]) { - - sycl::property_list Props{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue Q(Props); - - TestQueueOperations(Q); - - TestQueueOperationsViaSubmit(Q); - - std::cout << "The test passed." << std::endl; - return 0; -} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_usm_ooo_queue.cpp b/sycl/test-e2e/DiscardEvents/discard_events_usm_ooo_queue.cpp deleted file mode 100644 index 3aa91ed17cd32..0000000000000 --- a/sycl/test-e2e/DiscardEvents/discard_events_usm_ooo_queue.cpp +++ /dev/null @@ -1,133 +0,0 @@ -// RUN: %{build} -o %t.out -// -// On level_zero Q.fill uses urEnqueueKernelLaunch and not urEnqueueUSMFill -// due to https://github.com/intel/llvm/issues/13787 -// -// RUN: env SYCL_UR_TRACE=2 %{run} %t.out &> %t.txt ; FileCheck %s --input-file %t.txt --check-prefixes=CHECK%if level_zero %{,CHECK-L0%} %else %{,CHECK-OTHER%} -// -// REQUIRES: aspect-usm_shared_allocations -// The test checks that the last parameter is not `nullptr` for all UR calls -// that should discard events. -// {{0|0000000000000000}} is required for various output on Linux and Windows. -// NOTE: urEnqueueUSMPrefetch and urEnqueueUSMAdvise in the CUDA and -// HIP backends may return a warning result on Windows with error-code -// 66 (UR_RESULT_ERROR_ADAPTER_SPECIFIC) if USM managed memory is not -// supported or if unsupported advice flags are used for the latter API. -// Since it is a warning it is safe to ignore for this test. -// -// Everything that follows TestQueueOperations() -// CHECK-NOT: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMFill -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK-NOT: <--- urEnqueueUSMMemcpy({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMMemcpy -// CHECK: -> UR_RESULT_SUCCESS -// -// Level-zero backend doesn't use urEnqueueUSMFill -// CHECK-L0: <--- urEnqueueKernelLaunch -// CHECK-L0: .phEvent = {{[0-9a-f]+}} -// CHECK-OTHER: <--- urEnqueueUSMFill({{.*}} .phEvent = {{[0-9a-f]+}} -// CHECK: -> UR_RESULT_SUCCESS -// -// ---> urEnqueueUSMMemcpy( -// CHECK-NOT: <--- urEnqueueUSMMemcpy({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMMemcpy -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK-NOT: <--- urEnqueueUSMPrefetch({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMPrefetch -// CHECK: -> {{UR_RESULT_SUCCESS|UR_RESULT_ERROR_ADAPTER_SPECIFIC}} -// -// CHECK-NOT: <--- urEnqueueUSMAdvise({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMAdvise -// CHECK: -> {{UR_RESULT_SUCCESS|UR_RESULT_ERROR_ADAPTER_SPECIFIC}} -// -// CHECK-NOT: <--- urEnqueueEventsWaitWithBarrier({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueEventsWaitWithBarrier -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK-NOT: <--- urEnqueueKernelLaunch({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK-NOT: <--- urEnqueueKernelLaunch({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: -> UR_RESULT_SUCCESS -// -// RegularQueue -// CHECK-NOT: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMFill -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK-NOT: <--- urEnqueueEventsWait({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueEventsWait -// CHECK: -> UR_RESULT_SUCCESS -// -// Everything that follows TestQueueOperationsViaSubmit() -// CHECK-NOT: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMFill -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK-NOT: <--- urEnqueueUSMMemcpy({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMMemcpy -// CHECK: -> UR_RESULT_SUCCESS -// -// Level-zero backend doesn't use urEnqueueUSMFill -// CHECK-L0: <--- urEnqueueKernelLaunch -// CHECK-L0: .phEvent = {{[0-9a-f]+}} -// CHECK-OTHER: <--- urEnqueueUSMFill({{.*}} .phEvent = {{[0-9a-f]+}} -// CHECK: -> UR_RESULT_SUCCESS -// -// ---> urEnqueueUSMMemcpy( -// CHECK-NOT: <--- urEnqueueUSMMemcpy({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMMemcpy -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK-NOT: <--- urEnqueueUSMPrefetch({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMPrefetch -// CHECK: ) -> {{UR_RESULT_SUCCESS|UR_RESULT_ERROR_ADAPTER_SPECIFIC}} -// -// CHECK-NOT: <--- urEnqueueUSMAdvise({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMAdvise -// CHECK: ) -> {{UR_RESULT_SUCCESS|UR_RESULT_ERROR_ADAPTER_SPECIFIC}} -// -// CHECK-NOT: <--- urEnqueueEventsWaitWithBarrier({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueEventsWaitWithBarrier -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK-NOT: <--- urEnqueueKernelLaunch({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK-NOT: <--- urEnqueueKernelLaunch({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: -> UR_RESULT_SUCCESS -// -// RegularQueue -// CHECK-NOT: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMFill -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK-NOT: <--- urEnqueueEventsWait({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueEventsWait -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK: The test passed. - -#include "discard_events_test_queue_ops.hpp" -#include - -int main(int Argc, const char *Argv[]) { - - sycl::property_list Props{ - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue OOO_Q(Props); - - TestQueueOperations(OOO_Q); - - TestQueueOperationsViaSubmit(OOO_Q); - - std::cout << "The test passed." << std::endl; - return 0; -} diff --git a/sycl/test-e2e/DiscardEvents/invalid_event.cpp b/sycl/test-e2e/DiscardEvents/invalid_event.cpp deleted file mode 100644 index 4badd247767a8..0000000000000 --- a/sycl/test-e2e/DiscardEvents/invalid_event.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// RUN: %{build} -o %t.out -// RUN: %{run} %t.out - -// The test checks that each queue method call returns a discarded event -// with the status "ext_oneapi_unknown" - -#include -#include -#include -#include -#include - -using namespace sycl; -static constexpr size_t BUFFER_SIZE = 16; - -void QueueAPIsReturnDiscardedEvent(sycl::queue Q) { - sycl::range<1> range(BUFFER_SIZE); - - auto Dev = Q.get_device(); - int *x = sycl::malloc_device(BUFFER_SIZE, Q); - assert(x != nullptr); - int *y = sycl::malloc_device(BUFFER_SIZE, Q); - assert(y != nullptr); - - sycl::event DiscardedEvent; - - DiscardedEvent = Q.memset(x, 0, BUFFER_SIZE * sizeof(int)); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.memcpy(y, x, BUFFER_SIZE * sizeof(int)); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.fill(y, 1, BUFFER_SIZE); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.copy(y, x, BUFFER_SIZE); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.prefetch(y, BUFFER_SIZE * sizeof(int)); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.mem_advise(y, BUFFER_SIZE * sizeof(int), 0); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.single_task([=] {}); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.submit([&](sycl::handler &CGH) { - CGH.parallel_for(range, [=](sycl::item<1> itemID) {}); - }); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.ext_oneapi_submit_barrier(); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - Q.wait(); - free(x, Q); - free(y, Q); -} - -int main(int Argc, const char *Argv[]) { - sycl::property_list Props1{ - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue OOO_Queue(Props1); - QueueAPIsReturnDiscardedEvent(OOO_Queue); - - sycl::property_list Props2{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue Inorder_Queue(Props2); - QueueAPIsReturnDiscardedEvent(Inorder_Queue); - - std::cout << "The test passed." << std::endl; - return 0; -} diff --git a/sycl/test-e2e/DiscardEvents/invalid_event_exceptions.cpp b/sycl/test-e2e/DiscardEvents/invalid_event_exceptions.cpp deleted file mode 100644 index 6da5b087474a9..0000000000000 --- a/sycl/test-e2e/DiscardEvents/invalid_event_exceptions.cpp +++ /dev/null @@ -1,168 +0,0 @@ -// RUN: %{build} -o %t.out -// -// RUN: %{run} %t.out -// -// The test checks 3 things: -// 1. An attempt to construct a queue with both properties(discard_events and -// enable_profiling) throws an exception. -// 2. Checks the APIs for discarded event that should throw an exception that -// they do it. -// 3. An attempt to pass discarded event into depends_on throws an exception. - -#include -#include -#include -#include - -using namespace sycl; - -void DiscardedEventWaitExceptionHelper( - const std::function &FunctionToTry) { - try { - FunctionToTry(); - assert(false && "No exception was thrown."); - } catch (const sycl::exception &e) { - assert(e.code().value() == static_cast(sycl::errc::invalid) && - "sycl::exception code was not the expected sycl::errc::invalid."); - } catch (...) { - assert(false && - "Unexpected exception was thrown in kernel invocation function."); - } -} - -void DependsOnDiscardedEventException(sycl::queue Q) { - auto DiscardedEvent = - Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); - - Q.submit([&](sycl::handler &CGH) { - try { - CGH.depends_on(DiscardedEvent); - assert(false && "No exception was thrown."); - } catch (const sycl::exception &e) { - assert(e.code().value() == static_cast(sycl::errc::invalid) && - "sycl::exception code was not the expected sycl::errc::invalid."); - } catch (...) { - assert(false && - "Unexpected exception was thrown in kernel invocation function."); - } - CGH.single_task([] {}); - }); - - sycl::event e1, e2; - Q.submit([&](sycl::handler &CGH) { - try { - CGH.depends_on({e1, DiscardedEvent, e2}); - assert(false && "No exception was thrown."); - } catch (const sycl::exception &e) { - assert(e.code().value() == static_cast(sycl::errc::invalid) && - "sycl::exception code was not the expected sycl::errc::invalid."); - } catch (...) { - assert(false && - "Unexpected exception was thrown in kernel invocation function."); - } - CGH.single_task([] {}); - }); - - sycl::queue RegularQ; - RegularQ.submit([&](sycl::handler &CGH) { - try { - CGH.depends_on(DiscardedEvent); - assert(false && "No exception was thrown."); - } catch (const sycl::exception &e) { - assert(e.code().value() == static_cast(sycl::errc::invalid) && - "sycl::exception code was not the expected sycl::errc::invalid."); - } catch (...) { - assert(false && - "Unexpected exception was thrown in kernel invocation function."); - } - CGH.single_task([] {}); - }); - - RegularQ.submit([&](sycl::handler &CGH) { - try { - CGH.depends_on({e1, DiscardedEvent, e2}); - assert(false && "No exception was thrown."); - } catch (const sycl::exception &e) { - assert(e.code().value() == static_cast(sycl::errc::invalid) && - "sycl::exception code was not the expected sycl::errc::invalid."); - } catch (...) { - assert(false && - "Unexpected exception was thrown in kernel invocation function."); - } - CGH.single_task([] {}); - }); -} - -void CheckDiscardedEventAPIException(sycl::queue Q) { - DiscardedEventWaitExceptionHelper([&]() { - auto DiscardedEvent = - Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); - DiscardedEvent.wait(); - }); - - DiscardedEventWaitExceptionHelper([&]() { - auto DiscardedEvent = - Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); - sycl::event::wait({DiscardedEvent}); - }); - - DiscardedEventWaitExceptionHelper([&]() { - auto DiscardedEvent = - Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); - DiscardedEvent.wait_and_throw(); - }); - - DiscardedEventWaitExceptionHelper([&]() { - auto DiscardedEvent = - Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); - sycl::event::wait_and_throw({DiscardedEvent}); - }); - - DiscardedEventWaitExceptionHelper([&]() { - auto DiscardedEvent = - Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); - DiscardedEvent.get_wait_list(); - }); -} - -void CreatingEnableProfilingQueueException(sycl::property_list Props) { - try { - sycl::queue Q{Props}; - assert(false && "No exception was thrown."); - } catch (const sycl::exception &e) { - assert(e.code().value() == static_cast(sycl::errc::invalid) && - "sycl::exception code was not the expected sycl::errc::invalid."); - } catch (...) { - assert(false && - "Unexpected exception was thrown in kernel invocation function."); - } -} - -int main(int Argc, const char *Argv[]) { - sycl::property_list Props1{ - sycl::property::queue::enable_profiling{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - CreatingEnableProfilingQueueException(Props1); - - sycl::property_list Props2{ - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue OOO_Queue(Props2); - DependsOnDiscardedEventException(OOO_Queue); - CheckDiscardedEventAPIException(OOO_Queue); - - sycl::property_list Props3{ - sycl::property::queue::in_order{}, - sycl::property::queue::enable_profiling{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - CreatingEnableProfilingQueueException(Props3); - - sycl::property_list Props4{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue Inorder_Queue(Props4); - DependsOnDiscardedEventException(Inorder_Queue); - CheckDiscardedEventAPIException(Inorder_Queue); - - std::cout << "The test passed." << std::endl; - return 0; -} diff --git a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp index 25a69fbdbef7d..38d2a1277c622 100644 --- a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp +++ b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp @@ -119,8 +119,6 @@ // CHECK-NEXT: DeviceLib/separate_compile_test.cpp // CHECK-NEXT: DeviceLib/std_complex_math_fp64_test.cpp // CHECK-NEXT: DeviceLib/std_complex_math_test.cpp -// CHECK-NEXT: DiscardEvents/discard_events_check_images.cpp -// CHECK-NEXT: DiscardEvents/discard_events_using_assert.cpp // CHECK-NEXT: ESIMD/PerformanceTests/BitonicSortK.cpp // CHECK-NEXT: ESIMD/PerformanceTests/BitonicSortKv2.cpp // CHECK-NEXT: ESIMD/PerformanceTests/Stencil.cpp diff --git a/sycl/unittests/queue/Properties.cpp b/sycl/unittests/queue/Properties.cpp index af7c6c941ef08..a897081af3b31 100644 --- a/sycl/unittests/queue/Properties.cpp +++ b/sycl/unittests/queue/Properties.cpp @@ -26,8 +26,6 @@ TEST(QueueProperties, ValidDatalessProperties) { sycl::unittest::UrMock<> Mock; DatalessQueuePropertyCheck(); DatalessQueuePropertyCheck(); - DatalessQueuePropertyCheck< - sycl::ext::oneapi::property::queue::discard_events>(); DatalessQueuePropertyCheck< sycl::ext::oneapi::property::queue::priority_normal>(); DatalessQueuePropertyCheck< From 7541349357f6295bf59a042658c444adaa1e2b8e Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Wed, 16 Apr 2025 11:00:45 -0400 Subject: [PATCH 02/21] Fix test fail Signed-off-by: JackAKirk --- sycl/test-e2e/Basic/in_order_queue_status.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sycl/test-e2e/Basic/in_order_queue_status.cpp b/sycl/test-e2e/Basic/in_order_queue_status.cpp index bfa15932c8401..a41989fb73db7 100644 --- a/sycl/test-e2e/Basic/in_order_queue_status.cpp +++ b/sycl/test-e2e/Basic/in_order_queue_status.cpp @@ -66,9 +66,5 @@ int main() { queue Q1{property::queue::in_order()}; TestFunc(Q1); - // Feature is not supported for OpenCL, exception must be thrown. - if (Q2.get_device().get_backend() == backend::opencl) - return ExceptionThrown ? 0 : -1; - return 0; } From 83334018017d8984c2fe213335eea7679d28285a Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Wed, 16 Apr 2025 11:37:06 -0400 Subject: [PATCH 03/21] Fix failure Signed-off-by: JackAKirk --- sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp index 38d2a1277c622..a32abb0ce2981 100644 --- a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp +++ b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp @@ -54,7 +54,7 @@ // tests to match the required format and in that case you should just update // (i.e. reduce) the number and the list below. // -// NUMBER-OF-UNSUPPORTED-WITHOUT-INFO: 273 +// NUMBER-OF-UNSUPPORTED-WITHOUT-INFO: 271 // // List of improperly UNSUPPORTED tests. // Remove the CHECK once the test has been properly UNSUPPORTED. From 23b29916118a07bbf71c7ba2b73cf1dccdcec27b Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Thu, 17 Apr 2025 12:46:05 +0100 Subject: [PATCH 04/21] Remove dead code in event_impl Signed-off-by: JackAKirk --- sycl/source/detail/event_impl.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sycl/source/detail/event_impl.cpp b/sycl/source/detail/event_impl.cpp index f0908eb9742b5..73c421fc5e42f 100644 --- a/sycl/source/detail/event_impl.cpp +++ b/sycl/source/detail/event_impl.cpp @@ -519,11 +519,6 @@ ur_native_handle_t event_impl::getNative() { } std::vector event_impl::getWaitList() { - if (MState == HES_Discarded) - throw sycl::exception( - make_error_code(errc::invalid), - "get_wait_list() cannot be used for a discarded event."); - std::lock_guard Lock(MMutex); std::vector Result; From df7342948ac4052a924074b64541e66be522bd56 Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Thu, 17 Apr 2025 15:00:51 +0100 Subject: [PATCH 05/21] Add back discard_event queue prop - Make the prop no-op - add back full testing initially - deprecate discard_events extension Signed-off-by: JackAKirk --- ...l_ext_oneapi_discard_queue_events.asciidoc | 211 +++++++++++++ ...l_ext_oneapi_discard_queue_events.asciidoc | 2 + .../sycl/properties/queue_properties.def | 2 + .../Adapters/level_zero_batch_test.cpp | 27 ++ .../level_zero_dynamic_batch_test.cpp | 5 + sycl/test-e2e/Basic/in_order_queue_status.cpp | 17 ++ .../discard_events_accessors.cpp | 94 ++++++ .../discard_events_check_images.cpp | 203 +++++++++++++ .../discard_events_kernel_using_assert.hpp | 47 +++ .../discard_events_l0_inorder.cpp | 164 ++++++++++ .../DiscardEvents/discard_events_l0_leak.cpp | 47 +++ .../discard_events_mixed_calls.cpp | 286 ++++++++++++++++++ .../discard_events_test_queue_ops.hpp | 130 ++++++++ .../discard_events_using_assert.cpp | 17 ++ .../discard_events_using_assert_ndebug.cpp | 13 + .../DiscardEvents/discard_events_usm.cpp | 109 +++++++ .../discard_events_usm_ooo_queue.cpp | 133 ++++++++ sycl/test-e2e/DiscardEvents/invalid_event.cpp | 93 ++++++ .../invalid_event_exceptions.cpp | 168 ++++++++++ .../no-unsupported-without-info.cpp | 4 +- sycl/unittests/queue/Properties.cpp | 2 + 21 files changed, 1773 insertions(+), 1 deletion(-) create mode 100644 sycl/doc/extensions/deprecated/sycl_ext_oneapi_discard_queue_events.asciidoc create mode 100644 sycl/doc/extensions/supported/sycl_ext_oneapi_discard_queue_events.asciidoc create mode 100644 sycl/test-e2e/DiscardEvents/discard_events_accessors.cpp create mode 100644 sycl/test-e2e/DiscardEvents/discard_events_check_images.cpp create mode 100644 sycl/test-e2e/DiscardEvents/discard_events_kernel_using_assert.hpp create mode 100644 sycl/test-e2e/DiscardEvents/discard_events_l0_inorder.cpp create mode 100644 sycl/test-e2e/DiscardEvents/discard_events_l0_leak.cpp create mode 100644 sycl/test-e2e/DiscardEvents/discard_events_mixed_calls.cpp create mode 100644 sycl/test-e2e/DiscardEvents/discard_events_test_queue_ops.hpp create mode 100644 sycl/test-e2e/DiscardEvents/discard_events_using_assert.cpp create mode 100644 sycl/test-e2e/DiscardEvents/discard_events_using_assert_ndebug.cpp create mode 100644 sycl/test-e2e/DiscardEvents/discard_events_usm.cpp create mode 100644 sycl/test-e2e/DiscardEvents/discard_events_usm_ooo_queue.cpp create mode 100644 sycl/test-e2e/DiscardEvents/invalid_event.cpp create mode 100644 sycl/test-e2e/DiscardEvents/invalid_event_exceptions.cpp diff --git a/sycl/doc/extensions/deprecated/sycl_ext_oneapi_discard_queue_events.asciidoc b/sycl/doc/extensions/deprecated/sycl_ext_oneapi_discard_queue_events.asciidoc new file mode 100644 index 0000000000000..d8a084aa42b25 --- /dev/null +++ b/sycl/doc/extensions/deprecated/sycl_ext_oneapi_discard_queue_events.asciidoc @@ -0,0 +1,211 @@ += sycl_ext_oneapi_discard_queue_events +:source-highlighter: coderay +:coderay-linenums-mode: table + +// This section needs to be after the document title. +:doctype: book +:toc2: +:toc: left +:encoding: utf-8 +:lang: en + +:blank: pass:[ +] + +// Set the default source code type in this document to C++, +// for syntax highlighting purposes. This is needed because +// docbook uses c++ and html5 uses cpp. +:language: {basebackend@docbook:c++:cpp} + +// This is necessary for asciidoc, but not for asciidoctor +:cpp: C++ + +== Introduction + +IMPORTANT: This specification is a draft. + +NOTE: Khronos(R) is a registered trademark and SYCL(TM) and SPIR(TM) are +trademarks of The Khronos Group Inc. OpenCL(TM) is a trademark of Apple Inc. +used by permission by Khronos. + +This document describes an extension that introduces a `discard_events` property for +SYCL queues. This property enables developers to inform a SYCL implementation that +the events returned from queue operations will not be used. + +== Notice + +Copyright (c) 2021 Intel Corporation. All rights reserved. + +== Status + +This extension has been deprecated. Although the interfaces defined in this +specification are still supported in {dpcpp}, we expect that they will be +removed in an upcoming {dpcpp} release. The optimizations enabled by these +interfaces have already been disabled in the compiler. The functionality of +this extension has been replaced by the sycl_ext_oneapi_enqueue_functions +extension: see link:../experimental/sycl_ext_oneapi_enqueue_functions.asciidoc[here]. +*Shipping software products should stop using APIs defined in this +specification and use this alternative instead.* + +== Version + +Revision: 1 + +== Contributors + +Alexander Flegontov, Intel + +Greg Lueck, Intel + +John Pennycook, Intel + +Vlad Romanov, Intel + +== Dependencies + +This extension is written against the SYCL 2020 specification, Revision 4. + +== Feature Test Macro + +This extension provides a feature-test macro as described in the core SYCL +specification section 6.3.3 "Feature test macros". Therefore, an +implementation supporting this extension must predefine the macro +`SYCL_EXT_ONEAPI_DISCARD_QUEUE_EVENTS` to one of the values defined in the table below. +Applications can test for the existence of this macro to determine if the +implementation supports this feature, or applications can test the macro's +value to determine which of the extension's APIs the implementation supports. + +[%header,cols="1,5"] +|=== +|Value |Description +|1 |Initial extension version. Base features are supported. +|=== + +== Overview + +This extension adds `ext::oneapi::property::queue::discard_events` property for `sycl::queue`, +by using this property the application informs a SYCL implementation that it will not use the event +returned by any of the `queue` member functions. (i.e submit, parallel_for, copy, memset and others.) +When the application creates a queue with this property, +the implementation may be able to optimize some operations on the `queue`. +The `discard_events` property is incompatible with `enable_profiling`. +Attempts to construct a `queue` with both properties raises `errc::invalid`. + +Below is a usage example: +[source,c++] +---- + sycl::property_list props{ext::oneapi::property::queue::discard_events{}, + property::queue::in_order{}}; + sycl::queue Queue( props ); + + // some USM preparations .. + + sycl::event e1, e2, e3; + + // returning "invalid" events from each submission function: + e1 = Queue.parallel_for(NDRange, [=](nd_item<1> item){ do_smth1(); }); + + e2 = Queue.single_task([=](){ do_smth2(); }); + + e3 = Queue.submit([&](handler &CGH) { CGH.parallel_for(NDRange, [=](nd_item<1> item){ do_smth3(); }); }); + + Queue.wait(); +---- + +In the example above, the application doesn't use sycl events: `e1`, `e2`, `e3` +and is waiting for the end of work by `queue::wait()`. +When the queue is created with the `discard_events` property, +the returned events will be _invalid_ events, which are `sycl::event` objects that have limited capability. +See the description of behavior for this event below for details. + +Here, only those member functions for the _invalid_ event are described that have behavior different from the default event behavior: +[source,c++] +---- +// must throw an exception with the errc::invalid error code. +std::vector get_wait_list(); + +// must throw an exception with the errc::invalid error code. +void wait(); + +// if invalid event is passed into the function, must throw an exception with the errc::invalid error code. +static void wait(const std::vector &eventList); + +// must throw an exception with the errc::invalid error code. +void wait_and_throw(); + +// if invalid event is passed into the function, must throw an exception with the errc::invalid error code. +static void wait_and_throw(const std::vector &eventList); + +// must return info::event_command_status::ext_oneapi_unknown +get_info() const; +---- + +The behavior when _invalid_ event is passed into handler API: +[source,c++] +---- +// must throw an exception with the errc::invalid error code. +handler::depends_on(event Event) + +// must throw an exception with the errc::invalid error code. +handler::depends_on(const std::vector &Events) +---- + +A new enumerator value is also added to the `info::event_command_status` enumeration, +which is returned by `get_info()` as described above: +[source,c++] +---- +namespace sycl { +namespace info { + +enum class event_command_status : int { + // ... + ext_oneapi_unknown +}; + +} // namespace info +} // namespace sycl +---- + +== Optimization behavior for DPC++ + +This non-normative section describes the conditions when the DPC++ implementation provides an optimization benefit* for the `discard_events` property. + + - The queue must be constructed with the `in_order` property. + - A kernel submitted to the queue must not use the link:../supported/sycl_ext_oneapi_assert.asciidoc[fallback assert feature]. + - A queue operation submitted to the queue must not use streams or buffer / image accessors. However, local accessors do not inhibit optimization. + - Any queue operations using Level Zero backend temporarily work without optimization. + +*The benefit is that a low-level event is not created from backend, thereby saving time. + +See the behavior details for each condition below: + +=== Using out-of-order queue + +No optimization if a queue is created with the `discard_events` property and +the property list does not include `in_order` property. + +=== Using fallback assert feature + +No optimization if the application calls the `assert` macro from a command that is submitted to the queue unless +the device has native support for assertions (as specified by `aspect::ext_oneapi_native_assert`). + +=== Using streams or buffer / image accessors (excluding local accessors) + +No optimization if a queue operation that uses stream objects or buffer / image accessors is submitted to a queue created with +the `discard_events` property. But using local accessors does not affect optimization. + +=== Using Level Zero backend + +Since Level Zero adapter support is required to be able to not create a low-level event, +any queue operations using the Level Zero backend temporarily work without optimization. + + +== Issues + +None. + +== Revision History + +[cols="5,15,15,70"] +[grid="rows"] +[options="header"] +|======================================== +|Rev|Date|Author|Changes +|1|2021-11-09|Alexander Flegontov |*Initial public working draft* +|======================================== diff --git a/sycl/doc/extensions/supported/sycl_ext_oneapi_discard_queue_events.asciidoc b/sycl/doc/extensions/supported/sycl_ext_oneapi_discard_queue_events.asciidoc new file mode 100644 index 0000000000000..a0712992ab880 --- /dev/null +++ b/sycl/doc/extensions/supported/sycl_ext_oneapi_discard_queue_events.asciidoc @@ -0,0 +1,2 @@ +This extension has been deprecated, but the specification is still available +link:../deprecated/sycl_ext_oneapi_discard_queue_events.asciidoc[here]. diff --git a/sycl/include/sycl/properties/queue_properties.def b/sycl/include/sycl/properties/queue_properties.def index 95470699a0435..6e0f3fd700952 100644 --- a/sycl/include/sycl/properties/queue_properties.def +++ b/sycl/include/sycl/properties/queue_properties.def @@ -9,6 +9,8 @@ __SYCL_DATA_LESS_PROP(property::queue, in_order, InOrder) __SYCL_DATA_LESS_PROP(property::queue, enable_profiling, QueueEnableProfiling) +__SYCL_DATA_LESS_PROP(ext::oneapi::property::queue, discard_events, + DiscardEvents) __SYCL_DATA_LESS_PROP(ext::oneapi::property::queue, priority_normal, QueuePriorityNormal) __SYCL_DATA_LESS_PROP(ext::oneapi::property::queue, priority_low, diff --git a/sycl/test-e2e/Adapters/level_zero_batch_test.cpp b/sycl/test-e2e/Adapters/level_zero_batch_test.cpp index 8f6e4e0f6a563..da3ff2359c624 100644 --- a/sycl/test-e2e/Adapters/level_zero_batch_test.cpp +++ b/sycl/test-e2e/Adapters/level_zero_batch_test.cpp @@ -2,6 +2,7 @@ // RUN: %{build} -o %t.ooo.out // RUN: %{build} -DUSING_INORDER -o %t.ino.out +// RUN: %{build} -DUSING_DISCARD_EVENTS -o %t.discard_events.out // UNSUPPORTED: ze_debug, level_zero_v2_adapter // To test batching on out-of-order queue: @@ -48,6 +49,28 @@ // Set batching to 9 explicitly // RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=9 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.ino.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB9 %s +// To test batching on in-order queue with discard_events: +// Set batching to 4 explicitly +// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=4 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB4 %s + +// Set batching to 1 explicitly +// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=1 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB1 %s + +// Set batching to 3 explicitly +// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=3 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB3 %s + +// Set batching to 5 explicitly +// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=5 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB5 %s + +// Set batching to 7 explicitly +// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=7 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB7 %s + +// Set batching to 8 explicitly +// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=8 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB8 %s + +// Set batching to 9 explicitly +// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=9 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB9 %s + // level_zero_batch_test.cpp // // This tests the level zero adapter's kernel batching code. The default @@ -269,6 +292,10 @@ int main(int argc, char *argv[]) { #ifdef USING_INORDER sycl::property_list Props{sycl::property::queue::in_order{}}; +#elif USING_DISCARD_EVENTS + sycl::property_list Props{ + sycl::property::queue::in_order{}, + sycl::ext::oneapi::property::queue::discard_events{}}; #else sycl::property_list Props{}; #endif diff --git a/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp b/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp index 0c974d2b306e6..458b866964eac 100644 --- a/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp +++ b/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp @@ -3,6 +3,7 @@ // RUN: %{build} -o %t.ooo.out // RUN: %{build} -DUSING_INORDER -o %t.ino.out +// RUN: %{build} -DUSING_DISCARD_EVENTS -o %t.discard_events.out // Check that dynamic batching raises/lowers batch size // RUN: env SYCL_UR_TRACE=2 UR_L0_DEBUG=1 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 %{run} %t.ooo.out 2>&1 | FileCheck --check-prefixes=CKALL,CKDYN %s @@ -65,6 +66,10 @@ int main(int argc, char *argv[]) { #ifdef USING_INORDER sycl::property_list Props{sycl::property::queue::in_order{}}; +#elif USING_DISCARD_EVENTS + sycl::property_list Props{ + sycl::property::queue::in_order{}, + sycl::ext::oneapi::property::queue::discard_events{}}; #else sycl::property_list Props{}; #endif diff --git a/sycl/test-e2e/Basic/in_order_queue_status.cpp b/sycl/test-e2e/Basic/in_order_queue_status.cpp index a41989fb73db7..68b8b990d1b3d 100644 --- a/sycl/test-e2e/Basic/in_order_queue_status.cpp +++ b/sycl/test-e2e/Basic/in_order_queue_status.cpp @@ -66,5 +66,22 @@ int main() { queue Q1{property::queue::in_order()}; TestFunc(Q1); + // Test in-order queue with discard_events property. + sycl::property_list Props{ + property::queue::in_order{}, + sycl::ext::oneapi::property::queue::discard_events{}}; + queue Q2{Props}; + + bool ExceptionThrown = false; + try { + TestFunc(Q2); + } catch (sycl::exception &E) { + ExceptionThrown = true; + } + + // Feature is not supported for OpenCL, exception must be thrown. + if (Q2.get_device().get_backend() == backend::opencl) + return ExceptionThrown ? 0 : -1; + return 0; } diff --git a/sycl/test-e2e/DiscardEvents/discard_events_accessors.cpp b/sycl/test-e2e/DiscardEvents/discard_events_accessors.cpp new file mode 100644 index 0000000000000..59e0a7f62650f --- /dev/null +++ b/sycl/test-e2e/DiscardEvents/discard_events_accessors.cpp @@ -0,0 +1,94 @@ +// RUN: %{build} -o %t.out +// +// RUN: env SYCL_UR_TRACE=2 %{run} %t.out &> %t.txt ; FileCheck %s --input-file %t.txt +// +// The test checks that the last parameter is `nullptr` for +// urEnqueueKernelLaunch for USM kernel using local accessor, but +// is not `nullptr` for kernel using buffer accessor. +// +// CHECK: <--- urEnqueueKernelLaunch +// CHECK: .phEvent = nullptr +// +// CHECK-NOT: <--- urEnqueueKernelLaunch({{.*}}.phEvent = nullptr +// CHECK: <--- urEnqueueKernelLaunch +// CHECK: -> UR_RESULT_SUCCESS +// +// CHECK: The test passed. + +#include +#include +#include +#include +#include + +using namespace sycl; +static constexpr int MAGIC_NUM = -1; +static constexpr size_t BUFFER_SIZE = 16; + +void RunKernelHelper(sycl::queue Q, + const std::function &TestFunction) { + int *Harray = sycl::malloc_host(BUFFER_SIZE, Q); + assert(Harray != nullptr); + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + Harray[i] = MAGIC_NUM; + } + + TestFunction(Harray); + + // Checks result + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + size_t expected = i + 10; + assert(Harray[i] == expected); + } + free(Harray, Q); +} + +int main(int Argc, const char *Argv[]) { + + sycl::property_list props{ + sycl::property::queue::in_order{}, + sycl::ext::oneapi::property::queue::discard_events{}}; + sycl::queue Q(props); + sycl::nd_range<1> NDRange(BUFFER_SIZE, BUFFER_SIZE); + sycl::range<1> Range(BUFFER_SIZE); + + RunKernelHelper(Q, [&](int *Harray) { + Q.submit([&](sycl::handler &CGH) { + const size_t LocalMemSize = BUFFER_SIZE; + sycl::local_accessor LocalAcc(LocalMemSize, CGH); + + CGH.parallel_for( + NDRange, [=](sycl::nd_item<1> ndi) { + size_t i = ndi.get_global_id(0); + int *Ptr = LocalAcc.get_multi_ptr().get(); + Ptr[i] = i + 5; + Harray[i] = Ptr[i] + 5; + }); + }); + Q.wait(); + }); + + RunKernelHelper(Q, [&](int *Harray) { + sycl::buffer Buf(Range); + Q.submit([&](sycl::handler &CGH) { + auto Acc = Buf.get_access(CGH); + CGH.parallel_for( + Range, [=](sycl::item<1> itemID) { + size_t i = itemID.get_id(0); + Harray[i] = i + 10; + Acc[i] = i + 20; + }); + }); + Q.wait(); + + // Checks result + sycl::host_accessor HostAcc(Buf, sycl::read_only); + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + size_t expected = i + 20; + assert(HostAcc[i] == expected); + } + }); + + std::cout << "The test passed." << std::endl; + return 0; +} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_check_images.cpp b/sycl/test-e2e/DiscardEvents/discard_events_check_images.cpp new file mode 100644 index 0000000000000..e9f8588124b07 --- /dev/null +++ b/sycl/test-e2e/DiscardEvents/discard_events_check_images.cpp @@ -0,0 +1,203 @@ +// UNSUPPORTED: target-amd +// REQUIRES: aspect-ext_intel_legacy_image +// +// RUN: %{build} -o %t.out +// +// RUN: %{run} %t.out image +// RUN: %{run} %t.out mixed +// +// Note that the tests use image functionality and if you have problems with +// the tests, please check if they pass without the discard_events property, if +// they don't pass then it's most likely a general issue unrelated to +// discard_events. + +// 1. There is a SPIR-V spec issue that blocks generation of valid SPIR-V code +// for the OpenCL environments support of the "Unknown" image format: +// https://github.com/KhronosGroup/SPIRV-Headers/issues/487 +// 2. The PR https://github.com/llvm/llvm-project/pull/127242 in upstream needs +// to be merged with intel/llvm to address an issue of mapping from SPIR-V +// friendly builtins to Image Read/Write instructions After the 1 issue is +// resolved and 2 is merged we will re-enable Image support. +// UNSUPPORTED: spirv-backend && arch-intel_gpu_bmg_g21 +// UNSUPPORTED-TRACKER: https://github.com/KhronosGroup/SPIRV-Headers/issues/487 + +#include "../helpers.hpp" // for printableVec +#include +#include +#include +#include +#include +#include +#include + +using namespace sycl; +static constexpr size_t BUFFER_SIZE = 1024; +static constexpr int MAX_ITER_NUM1 = 10; +static constexpr int MAX_ITER_NUM2 = 10; +static constexpr int InitialVal = MAX_ITER_NUM1; + +void TestHelper(sycl::queue Q, + const std::function ImgSize, int *Harray, + sycl::image<2> Img)> &Function) { + int *Harray = sycl::malloc_shared(BUFFER_SIZE, Q); + assert(Harray != nullptr); + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + Harray[i] = 0; + } + + const sycl::image_channel_order ChanOrder = sycl::image_channel_order::rgba; + const sycl::image_channel_type ChanType = + sycl::image_channel_type::signed_int32; + + const sycl::range<2> ImgSize(sycl::sqrt(static_cast(BUFFER_SIZE)), + sycl::sqrt(static_cast(BUFFER_SIZE))); + std::vector ImgHostData( + ImgSize.size(), {InitialVal, InitialVal, InitialVal, InitialVal}); + sycl::image<2> Img(ImgHostData.data(), ChanOrder, ChanType, ImgSize); + + Function(ImgSize, Harray, Img); + + free(Harray, Q); +} + +void IfTrueIncrementUSM(sycl::queue Q, sycl::range<1> Range, int *Harray, + int ValueToCheck) { + Q.submit([&](sycl::handler &CGH) { + CGH.parallel_for(Range, [=](sycl::item<1> itemID) { + size_t i = itemID.get_id(0); + if (Harray[i] == ValueToCheck) { + Harray[i] += 1; + } + }); + }); +} + +void IfTrueIncrementImageAndUSM(sycl::queue Q, sycl::range<2> ImgSize, + int *Harray, sycl::image<2> Img, + int HarrayValueToCheck, int ImageValueToCheck) { + Q.submit([&](sycl::handler &CGH) { + auto Img1Acc = Img.get_access(CGH); + auto Img2Acc = Img.get_access(CGH); + CGH.parallel_for(ImgSize, [=](sycl::item<2> Item) { + size_t i = Item.get_linear_id(); + if (Harray[i] == HarrayValueToCheck) { + sycl::int4 Data = Img1Acc.read(sycl::int2{Item[0], Item[1]}); + if (Data[0] == ImageValueToCheck && Data[1] == ImageValueToCheck && + Data[2] == ImageValueToCheck && Data[3] == ImageValueToCheck) { + Data[0]++; + Data[3] = Data[2] = Data[1] = Data[0]; + Img2Acc.write(sycl::int2{Item[0], Item[1]}, Data); + } + ++Harray[i]; + } + }); + }); +} + +void RunTest_ImageTest(sycl::queue Q) { + TestHelper(Q, [&](sycl::range<2> ImgSize, int *Harray, sycl::image<2> Img) { + sycl::range<1> Range(BUFFER_SIZE); + for (int i = 0; i < MAX_ITER_NUM1; ++i) + IfTrueIncrementUSM(Q, Range, Harray, (i)); + + for (int i = 0; i < MAX_ITER_NUM2; ++i) + IfTrueIncrementImageAndUSM(Q, ImgSize, Harray, Img, (MAX_ITER_NUM1 + i), + (InitialVal + i)); + Q.wait(); + + // check results + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + int expected = MAX_ITER_NUM1 + MAX_ITER_NUM2; + assert(Harray[i] == expected); + } + + { + auto HostAcc = + Img.template get_access(); + int expected = InitialVal + MAX_ITER_NUM2; + for (int X = 0; X < ImgSize[0]; ++X) + for (int Y = 0; Y < ImgSize[1]; ++Y) { + sycl::int4 Vec1 = sycl::int4(expected); + sycl::int4 Vec2 = HostAcc.read(sycl::int2{X, Y}); + if (Vec1[0] != Vec2[0] || Vec1[1] != Vec2[1] || Vec1[2] != Vec2[2] || + Vec1[3] != Vec2[3]) { + std::cerr << "Failed" << std::endl; + std::cerr << "Element [ " << X << ", " << Y << " ]" << std::endl; + std::cerr << "Expected: " << printableVec(Vec1) << std::endl; + std::cerr << " Got : " << printableVec(Vec2) << std::endl; + assert(false && "ImageTest failed!"); + } + } + } + }); +} + +void RunTest_ImageTest_Mixed(sycl::queue Q) { + TestHelper(Q, [&](sycl::range<2> ImgSize, int *Harray, sycl::image<2> Img) { + sycl::range<1> Range(BUFFER_SIZE); + + for (int i = 0; i < MAX_ITER_NUM1; ++i) { + IfTrueIncrementUSM(Q, Range, Harray, (i * 2)); + IfTrueIncrementImageAndUSM(Q, ImgSize, Harray, Img, (i * 2 + 1), + (InitialVal + i)); + } + + for (int i = 0; i < MAX_ITER_NUM2; ++i) { + IfTrueIncrementImageAndUSM(Q, ImgSize, Harray, Img, + (MAX_ITER_NUM1 * 2 + i * 2), + (InitialVal + MAX_ITER_NUM1 + i)); + IfTrueIncrementUSM(Q, Range, Harray, (MAX_ITER_NUM1 * 2 + i * 2 + 1)); + } + + Q.wait(); + + // check results + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + int expected = MAX_ITER_NUM1 * 2 + MAX_ITER_NUM2 * 2; + assert(Harray[i] == expected); + } + + { + auto HostAcc = + Img.template get_access(); + int expected = InitialVal + MAX_ITER_NUM1 + MAX_ITER_NUM2; + for (int X = 0; X < ImgSize[0]; ++X) + for (int Y = 0; Y < ImgSize[1]; ++Y) { + sycl::int4 Vec1 = sycl::int4(expected); + sycl::int4 Vec2 = HostAcc.read(sycl::int2{X, Y}); + if (Vec1[0] != Vec2[0] || Vec1[1] != Vec2[1] || Vec1[2] != Vec2[2] || + Vec1[3] != Vec2[3]) { + std::cerr << "Failed" << std::endl; + std::cerr << "Element [ " << X << ", " << Y << " ]" << std::endl; + std::cerr << "Expected: " << printableVec(Vec1) << std::endl; + std::cerr << " Got : " << printableVec(Vec2) << std::endl; + assert(false && "ImageTest_Mixed failed!"); + } + } + } + }); +} + +int main(int Argc, const char *Argv[]) { + assert(Argc == 2 && "Invalid number of arguments"); + std::string TestType(Argv[1]); + + sycl::property_list props{ + sycl::property::queue::in_order{}, + sycl::ext::oneapi::property::queue::discard_events{}}; + sycl::queue Q(props); + + auto dev = Q.get_device(); + if (TestType == "image") { + std::cerr << "RunTest_ImageTest" << std::endl; + RunTest_ImageTest(Q); + } else if (TestType == "mixed") { + std::cerr << "RunTest_ImageTest_Mixed" << std::endl; + RunTest_ImageTest_Mixed(Q); + } else { + assert(0 && "Unsupported test type!"); + } + + std::cout << "The test passed." << std::endl; + return 0; +} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_kernel_using_assert.hpp b/sycl/test-e2e/DiscardEvents/discard_events_kernel_using_assert.hpp new file mode 100644 index 0000000000000..1856d9a1ccfae --- /dev/null +++ b/sycl/test-e2e/DiscardEvents/discard_events_kernel_using_assert.hpp @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include + +using namespace sycl; +static constexpr int MAGIC_NUM = -1; +static constexpr size_t BUFFER_SIZE = 16; + +int main(int Argc, const char *Argv[]) { + + sycl::property_list Props{ + sycl::property::queue::in_order{}, + sycl::ext::oneapi::property::queue::discard_events{}}; + sycl::queue Q(Props); + + sycl::range<1> Range(BUFFER_SIZE); + int *Harray = sycl::malloc_host(BUFFER_SIZE, Q); + if (Harray == nullptr) { + return -1; + } + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + Harray[i] = MAGIC_NUM; + } + + Q.submit([&](sycl::handler &CGH) { + CGH.parallel_for( + Range, [=](sycl::item<1> itemID) { + size_t i = itemID.get_id(0); + Harray[i] = i + 10; + assert(Harray[i] == i + 10 && "assert message"); + }); + }); + Q.wait(); + + // Checks result + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + size_t expected = i + 10; + if (Harray[i] != expected) + return -1; + } + free(Harray, Q); + + std::cout << "The test passed." << std::endl; + return 0; +} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_l0_inorder.cpp b/sycl/test-e2e/DiscardEvents/discard_events_l0_inorder.cpp new file mode 100644 index 0000000000000..c23bb4a6175fc --- /dev/null +++ b/sycl/test-e2e/DiscardEvents/discard_events_l0_inorder.cpp @@ -0,0 +1,164 @@ +// REQUIRES: level_zero +// +// RUN: %{build} -o %t.out +// +// RUN: env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_PI_LEVEL_ZERO_BATCH_SIZE=0 ONEAPI_DEVICE_SELECTOR="level_zero:*" %{run} %t.out +// RUN: env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_PI_LEVEL_ZERO_BATCH_SIZE=1 ONEAPI_DEVICE_SELECTOR="level_zero:*" %{run} %t.out +// RUN: env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_PI_LEVEL_ZERO_BATCH_SIZE=2 ONEAPI_DEVICE_SELECTOR="level_zero:*" %{run} %t.out +// RUN: env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_PI_LEVEL_ZERO_BATCH_SIZE=3 ONEAPI_DEVICE_SELECTOR="level_zero:*" %{run} %t.out +// +// The test is to check the execution of different queue operations has in-order +// semantics regardless of batching. +// +// IMPORTANT NOTE: this is a critical test, double-check if your changes are +// related to L0 barriers that provide links between commands within the same +// command-list or if your changes are related to L0 events and links between +// command-lists. if you have problems with this test, first see if other tests +// related to discard_events pass. And please check if the test passes without +// the discard_events property, if it doesn't pass then it's most likely a +// general issue unrelated to discard_events. + +#include +#include +#include +#include +#include +#include + +static constexpr int MAGIC_NUM1 = 2; + +sycl::aspect getUSMAspect(sycl::usm::alloc Alloc) { + if (Alloc == sycl::usm::alloc::host) + return sycl::aspect::usm_host_allocations; + + if (Alloc == sycl::usm::alloc::device) + return sycl::aspect::usm_device_allocations; + + assert(Alloc == sycl::usm::alloc::shared && "Unknown USM allocation type"); + return sycl::aspect::usm_shared_allocations; +} + +void RunCalculation(sycl::queue queue, sycl::usm::alloc AllocType) { + int buffer_size = 100; + sycl::range<1> range(buffer_size); + auto Dev = queue.get_device(); + if (!Dev.has(getUSMAspect(AllocType))) + return; + + int *values1 = + sycl::malloc(buffer_size, Dev, queue.get_context(), AllocType); + int *values2 = + sycl::malloc(buffer_size, Dev, queue.get_context(), AllocType); + int *values3 = + sycl::malloc(buffer_size, Dev, queue.get_context(), AllocType); + + std::vector values(buffer_size, 0); + std::iota(values.begin(), values.end(), 0); + + std::vector vec1(buffer_size, 0); + std::vector vec2(buffer_size, 0); + std::vector vec3(buffer_size, 0); + + try { + queue.memcpy(values1, values.data(), buffer_size * sizeof(int)); + queue.memcpy(values2, values1, buffer_size * sizeof(int)); + queue.memcpy(values3, values2, buffer_size * sizeof(int)); + queue.memset(values1, 0, buffer_size * sizeof(int)); + + queue.submit([&](sycl::handler &cgh) { + cgh.parallel_for(range, [=](sycl::item<1> itemID) { + size_t i = itemID.get_id(0); + if (values1[i] == 0) + if (values2[i] == i) + if (values3[i] == i) { + values1[i] += i; + values2[i] = MAGIC_NUM1; + values3[i] = i; + } + }); + }); + + queue.submit([&](sycl::handler &cgh) { + cgh.parallel_for(range, [=](sycl::item<1> itemID) { + size_t i = itemID.get_id(0); + if (values1[i] == i) + if (values2[i] == MAGIC_NUM1) + if (values3[i] == i) { + values1[i] += 10; + } + }); + }); + + queue.memcpy(values.data(), values1, buffer_size * sizeof(int)); + queue.memcpy(values2, values.data(), buffer_size * sizeof(int)); + + queue.submit([&](sycl::handler &cgh) { + cgh.parallel_for(range, [=](sycl::item<1> itemID) { + size_t i = itemID.get_id(0); + if (values1[i] == i + 10) + if (values2[i] == i + 10) + if (values3[i] == i) { + values1[i] += 100; + values2[i] = i; + } + }); + }); + + queue.submit([&](sycl::handler &cgh) { + cgh.parallel_for(range, [=](sycl::item<1> itemID) { + size_t i = itemID.get_id(0); + if (values1[i] == i + 110) + if (values2[i] == i) + if (values3[i] == i) { + values1[i] += 1000; + } + }); + }); + + queue.submit([&](sycl::handler &cgh) { + cgh.parallel_for(range, [=](sycl::item<1> itemID) { + size_t i = itemID.get_id(0); + if (values1[i] == i + 1110) + if (values2[i] == i) + if (values3[i] == i) { + values1[i] += 10000; + } + }); + }); + + queue.memcpy(vec1.data(), values1, buffer_size * sizeof(int)); + queue.memcpy(vec2.data(), values2, buffer_size * sizeof(int)); + queue.memcpy(vec3.data(), values3, buffer_size * sizeof(int)); + + queue.wait(); + + for (int i = 0; i < buffer_size; ++i) { + int expected = i + 11110; + assert(vec1[i] == expected); + expected = i; + assert(vec2[i] == expected); + assert(vec3[i] == expected); + } + + } catch (sycl::exception &e) { + std::cout << "Exception: " << std::string(e.what()) << std::endl; + } + + free(values1, queue); + free(values2, queue); + free(values3, queue); +} + +int main(int argc, char *argv[]) { + sycl::property_list Props{ + sycl::property::queue::in_order{}, + sycl::ext::oneapi::property::queue::discard_events{}}; + sycl::queue queue(Props); + + RunCalculation(queue, sycl::usm::alloc::host); + RunCalculation(queue, sycl::usm::alloc::shared); + RunCalculation(queue, sycl::usm::alloc::device); + + std::cout << "The test passed." << std::endl; + return 0; +} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_l0_leak.cpp b/sycl/test-e2e/DiscardEvents/discard_events_l0_leak.cpp new file mode 100644 index 0000000000000..adbffd60d98b1 --- /dev/null +++ b/sycl/test-e2e/DiscardEvents/discard_events_l0_leak.cpp @@ -0,0 +1,47 @@ +// REQUIRES: level_zero +// +// RUN: %{build} -o %t.out +// +// RUN: env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_PI_LEVEL_ZERO_BATCH_SIZE=4 ONEAPI_DEVICE_SELECTOR='level_zero:*' %{l0_leak_check} %{run} %t.out wait 2>&1 | FileCheck %s +// RUN: env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_PI_LEVEL_ZERO_BATCH_SIZE=4 ONEAPI_DEVICE_SELECTOR='level_zero:*' %{l0_leak_check} %{run} %t.out nowait 2>&1 | FileCheck %s +// +// CHECK-NOT: LEAK +// +// The test is to check that there are no leaks reported with the embedded +// UR_L0_LEAKS_DEBUG=1 ( %{l0_leak_check} ) testing capability. +// In addition to general leak checking, especially for discard_events, the test +// checks that urKernelRelease to be executed for each kernel call, and +// EventRelease for events, that are used for dependencies between +// command-lists. + +#include +#include +int main(int argc, char *argv[]) { + assert(argc == 2 && "Invalid number of arguments"); + std::string use_queue_finish(argv[1]); + + bool use = false; + if (use_queue_finish == "wait") { + use = true; + std::cerr << "Use queue::wait" << std::endl; + } else if (use_queue_finish == "nowait") { + std::cerr << "No wait. Ensure resources are released anyway" << std::endl; + } else { + assert(0 && "Unsupported parameter value"); + } + + sycl::property_list Props{ + sycl::property::queue::in_order{}, + sycl::ext::oneapi::property::queue::discard_events{}}; + sycl::queue q(Props); + + // test has multiple command-lists thanks to this loop and fixed batch size. + for (size_t i = 0; i < 100; ++i) + q.single_task([]() {}); + + if (use) + q.wait(); + + std::cout << "The test passed." << std::endl; + return 0; +} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_mixed_calls.cpp b/sycl/test-e2e/DiscardEvents/discard_events_mixed_calls.cpp new file mode 100644 index 0000000000000..041519a64d900 --- /dev/null +++ b/sycl/test-e2e/DiscardEvents/discard_events_mixed_calls.cpp @@ -0,0 +1,286 @@ +// RUN: %{build} -o %t.out + +// The purpose of all tests is to make sure in-order semantics works correctly +// using discard_events and alternating event and eventless kernel calls in +// different ways. + +// The test checks that eventless kernel calls work correctly after several +// event kernel calls. +// RUN: %{run} %t.out accessor-usm + +// The test checks that event kernel calls work correctly after several +// eventless kernel calls. +// RUN: %{run} %t.out usm-accessor + +// The test checks that alternating event and eventless kernel calls work +// correctly. +// RUN: %{run} %t.out mixed + +// The test checks that urEnqueueMemBufferMap and urEnqueueMemUnmap work +// correctly when we alternate between event and eventless kernel calls. +// RUN: %{run} %t.out map-unmap + +// Note that the tests use buffer functionality and if you have problems with +// the tests, please check if they pass without the discard_events property, if +// they don't pass then it's most likely a general issue unrelated to +// discard_events. +// REQUIRES: aspect-usm_shared_allocations +#include +#include +#include +#include +#include + +using namespace sycl; +static constexpr size_t BUFFER_SIZE = 1024; +static constexpr int MAX_ITER_NUM1 = 10; +static constexpr int MAX_ITER_NUM2 = 10; + +void TestHelper(sycl::queue Q, + const std::function Range, int *Harray, + sycl::buffer Buf)> &Function) { + int *Harray = sycl::malloc_shared(BUFFER_SIZE, Q); + assert(Harray != nullptr); + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + Harray[i] = 0; + } + + sycl::range<1> Range(BUFFER_SIZE); + sycl::buffer Buf(Range); + + Function(Range, Harray, Buf); + + free(Harray, Q); +} + +void IfTrueIncrementUSM(sycl::queue Q, sycl::range<1> Range, int *Harray, + int ValueToCheck) { + Q.submit([&](sycl::handler &CGH) { + CGH.parallel_for(Range, [=](sycl::item<1> itemID) { + size_t i = itemID.get_id(0); + if (Harray[i] == ValueToCheck) { + Harray[i] += 1; + } + }); + }); +} + +void IfTrueIncrementBufferAndUSM(sycl::queue Q, sycl::range<1> Range, + int *Harray, sycl::buffer Buf, + int ValueToCheck) { + Q.submit([&](sycl::handler &CGH) { + auto Acc = Buf.get_access(CGH); + CGH.parallel_for( + Range, [=](sycl::item<1> itemID) { + size_t i = itemID.get_id(0); + if (Harray[i] == ValueToCheck) { + ++Acc[i]; + ++Harray[i]; + } + }); + }); +} + +void RunTest_USM_Accessor(sycl::queue Q) { + TestHelper(Q, [&](sycl::range<1> Range, int *Harray, + sycl::buffer Buf) { + { + sycl::host_accessor HostAcc(Buf); + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + HostAcc[i] = 0; + } + } + + for (int i = 0; i < MAX_ITER_NUM1; ++i) + IfTrueIncrementUSM(Q, Range, Harray, (i)); + + for (int i = 0; i < MAX_ITER_NUM2; ++i) + IfTrueIncrementBufferAndUSM(Q, Range, Harray, Buf, (MAX_ITER_NUM1 + i)); + + Q.wait(); + + // check results + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + int expected = MAX_ITER_NUM1 + MAX_ITER_NUM2; + assert(Harray[i] == expected); + } + { + sycl::host_accessor HostAcc(Buf, sycl::read_only); + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + int expected = MAX_ITER_NUM2; + assert(HostAcc[i] == expected); + } + } + }); +} + +void RunTest_Accessor_USM(sycl::queue Q) { + TestHelper( + Q, [&](sycl::range<1> Range, int *Harray, sycl::buffer Buf) { + { + sycl::host_accessor HostAcc(Buf); + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + HostAcc[i] = 0; + } + } + + for (int i = 0; i < MAX_ITER_NUM1; ++i) + IfTrueIncrementBufferAndUSM(Q, Range, Harray, Buf, (i)); + + for (int i = 0; i < MAX_ITER_NUM2; ++i) + IfTrueIncrementUSM(Q, Range, Harray, (MAX_ITER_NUM1 + i)); + + Q.wait(); + + // check results + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + int expected = MAX_ITER_NUM1 + MAX_ITER_NUM2; + assert(Harray[i] == expected); + } + { + sycl::host_accessor HostAcc(Buf, sycl::read_only); + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + int expected = MAX_ITER_NUM1; + assert(HostAcc[i] == expected); + } + } + }); +} + +void RunTest_Mixed(sycl::queue Q) { + TestHelper( + Q, [&](sycl::range<1> Range, int *Harray, sycl::buffer Buf) { + { + sycl::host_accessor HostAcc(Buf); + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + HostAcc[i] = 0; + } + } + + for (int i = 0; i < MAX_ITER_NUM1; ++i) { + IfTrueIncrementUSM(Q, Range, Harray, (i * 2)); + IfTrueIncrementBufferAndUSM(Q, Range, Harray, Buf, (i * 2 + 1)); + } + + for (int i = 0; i < MAX_ITER_NUM2; ++i) { + IfTrueIncrementBufferAndUSM(Q, Range, Harray, Buf, + (MAX_ITER_NUM1 * 2 + i * 2)); + IfTrueIncrementUSM(Q, Range, Harray, (MAX_ITER_NUM1 * 2 + i * 2 + 1)); + } + + Q.wait(); + + // check results + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + int expected = MAX_ITER_NUM1 * 2 + MAX_ITER_NUM2 * 2; + assert(Harray[i] == expected); + } + { + sycl::host_accessor HostAcc(Buf, sycl::read_only); + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + int expected = MAX_ITER_NUM1 + MAX_ITER_NUM2; + assert(HostAcc[i] == expected); + } + } + }); +} + +void RunTest_MemBufferMapUnMap(sycl::queue Q) { + TestHelper( + Q, [&](sycl::range<1> Range, int *Harray, sycl::buffer Buf) { + Q.submit([&](sycl::handler &CGH) { + auto Acc = Buf.get_access(CGH); + CGH.parallel_for(Range, [=](sycl::item<1> itemID) { + size_t i = itemID.get_id(0); + Harray[i] = i; + Acc[i] = i; + }); + }); + + Q.submit([&](sycl::handler &CGH) { + CGH.parallel_for(Range, [=](sycl::item<1> itemID) { + size_t i = itemID.get_id(0); + if (Harray[i] == i) + Harray[i] += 10; + }); + }); + + { + // waiting for all queue operations in urEnqueueMemBufferMap and then + // checking buffer + sycl::host_accessor HostAcc(Buf); + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + int expected = i; + assert(HostAcc[i] == expected); + } + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + HostAcc[i] += 10; + } + } + + Q.submit([&](sycl::handler &CGH) { + CGH.parallel_for(Range, [=](sycl::item<1> itemID) { + size_t i = itemID.get_id(0); + if (Harray[i] == (i + 10)) + Harray[i] += 100; + }); + }); + + Q.submit([&](sycl::handler &CGH) { + // waiting for all queue operations in urEnqueueMemUnmap and then + // using buffer + auto Acc = Buf.get_access(CGH); + CGH.parallel_for(Range, [=](sycl::item<1> itemID) { + size_t i = itemID.get_id(0); + if (Acc[i] == (i + 10)) + if (Harray[i] == (i + 110)) { + Harray[i] += 1000; + Acc[i] += 100; + } + }); + }); + Q.wait(); + + // check results + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + int expected = i + 1110; + assert(Harray[i] == expected); + } + { + sycl::host_accessor HostAcc(Buf, sycl::read_only); + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + int expected = i + 110; + assert(HostAcc[i] == expected); + } + } + }); +} + +int main(int Argc, const char *Argv[]) { + assert(Argc == 2 && "Invalid number of arguments"); + std::string TestType(Argv[1]); + + sycl::property_list props{ + sycl::property::queue::in_order{}, + sycl::ext::oneapi::property::queue::discard_events{}}; + sycl::queue Q(props); + + if (TestType == "accessor-usm") { + std::cerr << "RunTest_Accessor_USM" << std::endl; + RunTest_Accessor_USM(Q); + } else if (TestType == "usm-accessor") { + std::cerr << "RunTest_USM_Accessor" << std::endl; + RunTest_USM_Accessor(Q); + } else if (TestType == "mixed") { + std::cerr << "RunTest_Mixed" << std::endl; + RunTest_Mixed(Q); + } else if (TestType == "map-unmap") { + std::cerr << "RunTest_MemBufferMapUnMap" << std::endl; + RunTest_MemBufferMapUnMap(Q); + } else { + assert(0 && "Unsupported test type!"); + } + + std::cout << "The test passed." << std::endl; + return 0; +} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_test_queue_ops.hpp b/sycl/test-e2e/DiscardEvents/discard_events_test_queue_ops.hpp new file mode 100644 index 0000000000000..81b7a64201cd9 --- /dev/null +++ b/sycl/test-e2e/DiscardEvents/discard_events_test_queue_ops.hpp @@ -0,0 +1,130 @@ + +#include +#include +#include +#include +#include + +using namespace sycl; + +void CheckArray(sycl::queue Q, int *x, size_t buffer_size, int expected) { + Q.wait(); + for (size_t i = 0; i < buffer_size; ++i) + assert(x[i] == expected); +} + +static constexpr size_t BUFFER_SIZE = 16; + +void TestQueueOperations(sycl::queue Q) { + sycl::range<1> Range(BUFFER_SIZE); + auto Dev = Q.get_device(); + auto Ctx = Q.get_context(); + int *x = sycl::malloc_shared(BUFFER_SIZE, Q); + assert(x != nullptr); + int *y = sycl::malloc_shared(BUFFER_SIZE, Q); + assert(y != nullptr); + + Q.memset(x, 0, BUFFER_SIZE * sizeof(int)); + CheckArray(Q, x, BUFFER_SIZE, 0); + + Q.memcpy(y, x, BUFFER_SIZE * sizeof(int)); + CheckArray(Q, y, BUFFER_SIZE, 0); + + Q.fill(y, 1, BUFFER_SIZE); + CheckArray(Q, y, BUFFER_SIZE, 1); + + Q.copy(y, x, BUFFER_SIZE); + CheckArray(Q, x, BUFFER_SIZE, 1); + + Q.prefetch(y, BUFFER_SIZE * sizeof(int)); + Q.mem_advise(y, BUFFER_SIZE * sizeof(int), 0); + Q.ext_oneapi_submit_barrier(); + + Q.single_task([=] { + for (auto i = 0u; i < BUFFER_SIZE; ++i) + y[i] *= 2; + }); + CheckArray(Q, y, BUFFER_SIZE, 2); + + Q.parallel_for(Range, + [=](sycl::item<1> itemID) { y[itemID.get_id(0)] *= 3; }); + CheckArray(Q, y, BUFFER_SIZE, 6); + + // Creates new queue with the same context/device, but without discard_events + // property. This queue returns a normal event, not a discarded one. + sycl::queue RegularQ(Ctx, Dev, sycl::property::queue::in_order{}); + int *x1 = sycl::malloc_shared(BUFFER_SIZE, RegularQ); + assert(x1 != nullptr); + auto event = RegularQ.memset(x1, 0, BUFFER_SIZE * sizeof(int)); + + Q.memcpy(y, x, 0, event); + CheckArray(Q, y, BUFFER_SIZE, 6); + + Q.wait(); + free(x, Q); + free(y, Q); + free(x1, RegularQ); +} + +void TestQueueOperationsViaSubmit(sycl::queue Q) { + sycl::range<1> Range(BUFFER_SIZE); + auto Dev = Q.get_device(); + auto Ctx = Q.get_context(); + int *x = sycl::malloc_shared(BUFFER_SIZE, Q); + assert(x != nullptr); + int *y = sycl::malloc_shared(BUFFER_SIZE, Q); + assert(y != nullptr); + + Q.submit( + [&](sycl::handler &CGH) { CGH.memset(x, 0, BUFFER_SIZE * sizeof(int)); }); + CheckArray(Q, x, BUFFER_SIZE, 0); + + Q.submit( + [&](sycl::handler &CGH) { CGH.memcpy(y, x, BUFFER_SIZE * sizeof(int)); }); + CheckArray(Q, y, BUFFER_SIZE, 0); + + Q.submit([&](sycl::handler &CGH) { CGH.fill(y, 1, BUFFER_SIZE); }); + CheckArray(Q, y, BUFFER_SIZE, 1); + + Q.submit([&](sycl::handler &CGH) { CGH.copy(y, x, BUFFER_SIZE); }); + CheckArray(Q, x, BUFFER_SIZE, 1); + + Q.submit( + [&](sycl::handler &CGH) { CGH.prefetch(y, BUFFER_SIZE * sizeof(int)); }); + Q.submit([&](sycl::handler &CGH) { + CGH.mem_advise(y, BUFFER_SIZE * sizeof(int), 0); + }); + Q.submit([&](sycl::handler &CGH) { CGH.ext_oneapi_barrier(); }); + + Q.submit([&](sycl::handler &CGH) { + CGH.single_task([=] { + for (auto i = 0u; i < BUFFER_SIZE; ++i) + y[i] *= 2; + }); + }); + CheckArray(Q, y, BUFFER_SIZE, 2); + + Q.submit([&](sycl::handler &CGH) { + CGH.parallel_for(Range, + [=](sycl::item<1> itemID) { y[itemID.get_id(0)] *= 3; }); + }); + CheckArray(Q, y, BUFFER_SIZE, 6); + + // Creates new queue with the same context/device, but without discard_events + // property. This queue returns a normal event, not a discarded one. + sycl::queue RegularQ(Ctx, Dev, sycl::property::queue::in_order{}); + int *x1 = sycl::malloc_shared(BUFFER_SIZE, RegularQ); + assert(x1 != nullptr); + auto event = RegularQ.memset(x1, 0, BUFFER_SIZE * sizeof(int)); + + Q.submit([&](sycl::handler &CGH) { + CGH.depends_on(event); + CGH.memcpy(y, x, 0); + }); + CheckArray(Q, y, BUFFER_SIZE, 6); + + Q.wait(); + free(x, Q); + free(y, Q); + free(x1, RegularQ); +} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_using_assert.cpp b/sycl/test-e2e/DiscardEvents/discard_events_using_assert.cpp new file mode 100644 index 0000000000000..5d965b1c27ff1 --- /dev/null +++ b/sycl/test-e2e/DiscardEvents/discard_events_using_assert.cpp @@ -0,0 +1,17 @@ +// FIXME unsupported on CUDA and HIP until fallback libdevice becomes available +// UNSUPPORTED: cuda || hip +// +// RUN: %{build} -o %t.out +// +// RUN: env SYCL_UR_TRACE=2 %{run} %t.out &> %t.txt ; FileCheck %s --input-file %t.txt +// +// The test checks that the last parameter is not `nullptr` for +// urEnqueueKernelLaunch. +// +// CHECK-NOT: <--- urEnqueueKernelLaunch({{.*}}.phEvent = nullptr +// CHECK: <--- urEnqueueKernelLaunch +// CHECK: -> UR_RESULT_SUCCESS +// +// CHECK: The test passed. + +#include "discard_events_kernel_using_assert.hpp" diff --git a/sycl/test-e2e/DiscardEvents/discard_events_using_assert_ndebug.cpp b/sycl/test-e2e/DiscardEvents/discard_events_using_assert_ndebug.cpp new file mode 100644 index 0000000000000..cdfbbe1386ed5 --- /dev/null +++ b/sycl/test-e2e/DiscardEvents/discard_events_using_assert_ndebug.cpp @@ -0,0 +1,13 @@ +// RUN: %{build} -DNDEBUG -o %t.out +// +// RUN: env SYCL_UR_TRACE=2 %{run} %t.out &> %t.txt ; FileCheck %s --input-file %t.txt +// +// The test checks that the last parameter is `nullptr` for +// urEnqueueKernelLaunch. +// +// CHECK: <--- urEnqueueKernelLaunch +// CHECK: .phEvent = nullptr +// +// CHECK: The test passed. + +#include "discard_events_kernel_using_assert.hpp" diff --git a/sycl/test-e2e/DiscardEvents/discard_events_usm.cpp b/sycl/test-e2e/DiscardEvents/discard_events_usm.cpp new file mode 100644 index 0000000000000..8c446fee88365 --- /dev/null +++ b/sycl/test-e2e/DiscardEvents/discard_events_usm.cpp @@ -0,0 +1,109 @@ +// RUN: %{build} -o %t.out +// +// On level_zero Q.fill uses urEnqueueKernelLaunch and not urEnqueueUSMFill +// due to https://github.com/intel/llvm/issues/13787 +// +// RUN: env SYCL_UR_TRACE=2 %{run} %t.out &> %t.txt ; FileCheck %s --input-file %t.txt --check-prefixes=CHECK%if level_zero %{,CHECK-L0%} %else %{,CHECK-OTHER%} +// +// REQUIRES: aspect-usm_shared_allocations +// The test checks that the last parameter is `nullptr` for all UR calls that +// should discard events. +// {{0|0000000000000000}} is required for various output on Linux and Windows. +// NOTE: urEnqueueUSMPrefetch and urEnqueueUSMAdvise in the CUDA and +// HIP backends may return a warning result on Windows with error-code +// 66 (UR_RESULT_ERROR_ADAPTER_SPECIFIC) if USM managed memory is not +// supported or if unsupported advice flags are used for the latter API. +// Since it is a warning it is safe to ignore for this test. +// +// Everything that follows TestQueueOperations() +// CHECK: <--- urEnqueueUSMFill +// CHECK: .phEvent = nullptr +// +// CHECK: <--- urEnqueueUSMMemcpy +// CHECK: .phEvent = nullptr +// +// Level-zero backend doesn't use urEnqueueUSMFill +// CHECK-L0: <--- urEnqueueKernelLaunch +// CHECK-L0: .phEvent = nullptr +// CHECK-OTHER: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr +// +// ---> urEnqueueUSMMemcpy( +// CHECK: <--- urEnqueueUSMMemcpy +// CHECK: .phEvent = nullptr +// +// CHECK: <--- urEnqueueUSMPrefetch +// CHECK: .phEvent = nullptr +// +// CHECK: <--- urEnqueueUSMAdvise +// CHECK: .phEvent = nullptr +// CHECK: -> {{UR_RESULT_SUCCESS|UR_RESULT_ERROR_ADAPTER_SPECIFIC}} +// +// CHECK: <--- urEnqueueKernelLaunch +// CHECK: .phEvent = nullptr +// +// CHECK: <--- urEnqueueKernelLaunch +// CHECK: .phEvent = nullptr +// +// RegularQueue +// CHECK-NOT: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueUSMFill +// CHECK: -> UR_RESULT_SUCCESS +// +// CHECK: <--- urEnqueueEventsWait +// CHECK: .phEvent = nullptr +// +// Everything that follows TestQueueOperationsViaSubmit() +// CHECK: <--- urEnqueueUSMFill +// CHECK: .phEvent = nullptr +// +// CHECK: <--- urEnqueueUSMMemcpy +// CHECK: .phEvent = nullptr +// +// Level-zero backend doesn't use urEnqueueUSMFill +// CHECK-L0: <--- urEnqueueKernelLaunch +// CHECK-L0: .phEvent = nullptr +// CHECK-OTHER: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr +// +// ---> urEnqueueUSMMemcpy( +// CHECK: <--- urEnqueueUSMMemcpy +// CHECK: .phEvent = nullptr +// +// CHECK: <--- urEnqueueUSMPrefetch +// CHECK: .phEvent = nullptr +// +// CHECK: <--- urEnqueueUSMAdvise +// CHECK: .phEvent = nullptr +// CHECK-SAME: ) -> {{UR_RESULT_SUCCESS|UR_RESULT_ERROR_ADAPTER_SPECIFIC}} +// +// CHECK: <--- urEnqueueKernelLaunch +// CHECK: .phEvent = nullptr +// +// CHECK: <--- urEnqueueKernelLaunch +// CHECK: .phEvent = nullptr +// +// RegularQueue +// CHECK-NOT: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueUSMFill +// CHECK: -> UR_RESULT_SUCCESS +// +// CHECK: <--- urEnqueueEventsWait +// CHECK: .phEvent = nullptr +// +// CHECK: The test passed. + +#include "discard_events_test_queue_ops.hpp" +#include +int main(int Argc, const char *Argv[]) { + + sycl::property_list Props{ + sycl::property::queue::in_order{}, + sycl::ext::oneapi::property::queue::discard_events{}}; + sycl::queue Q(Props); + + TestQueueOperations(Q); + + TestQueueOperationsViaSubmit(Q); + + std::cout << "The test passed." << std::endl; + return 0; +} diff --git a/sycl/test-e2e/DiscardEvents/discard_events_usm_ooo_queue.cpp b/sycl/test-e2e/DiscardEvents/discard_events_usm_ooo_queue.cpp new file mode 100644 index 0000000000000..3aa91ed17cd32 --- /dev/null +++ b/sycl/test-e2e/DiscardEvents/discard_events_usm_ooo_queue.cpp @@ -0,0 +1,133 @@ +// RUN: %{build} -o %t.out +// +// On level_zero Q.fill uses urEnqueueKernelLaunch and not urEnqueueUSMFill +// due to https://github.com/intel/llvm/issues/13787 +// +// RUN: env SYCL_UR_TRACE=2 %{run} %t.out &> %t.txt ; FileCheck %s --input-file %t.txt --check-prefixes=CHECK%if level_zero %{,CHECK-L0%} %else %{,CHECK-OTHER%} +// +// REQUIRES: aspect-usm_shared_allocations +// The test checks that the last parameter is not `nullptr` for all UR calls +// that should discard events. +// {{0|0000000000000000}} is required for various output on Linux and Windows. +// NOTE: urEnqueueUSMPrefetch and urEnqueueUSMAdvise in the CUDA and +// HIP backends may return a warning result on Windows with error-code +// 66 (UR_RESULT_ERROR_ADAPTER_SPECIFIC) if USM managed memory is not +// supported or if unsupported advice flags are used for the latter API. +// Since it is a warning it is safe to ignore for this test. +// +// Everything that follows TestQueueOperations() +// CHECK-NOT: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueUSMFill +// CHECK: -> UR_RESULT_SUCCESS +// +// CHECK-NOT: <--- urEnqueueUSMMemcpy({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueUSMMemcpy +// CHECK: -> UR_RESULT_SUCCESS +// +// Level-zero backend doesn't use urEnqueueUSMFill +// CHECK-L0: <--- urEnqueueKernelLaunch +// CHECK-L0: .phEvent = {{[0-9a-f]+}} +// CHECK-OTHER: <--- urEnqueueUSMFill({{.*}} .phEvent = {{[0-9a-f]+}} +// CHECK: -> UR_RESULT_SUCCESS +// +// ---> urEnqueueUSMMemcpy( +// CHECK-NOT: <--- urEnqueueUSMMemcpy({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueUSMMemcpy +// CHECK: -> UR_RESULT_SUCCESS +// +// CHECK-NOT: <--- urEnqueueUSMPrefetch({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueUSMPrefetch +// CHECK: -> {{UR_RESULT_SUCCESS|UR_RESULT_ERROR_ADAPTER_SPECIFIC}} +// +// CHECK-NOT: <--- urEnqueueUSMAdvise({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueUSMAdvise +// CHECK: -> {{UR_RESULT_SUCCESS|UR_RESULT_ERROR_ADAPTER_SPECIFIC}} +// +// CHECK-NOT: <--- urEnqueueEventsWaitWithBarrier({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueEventsWaitWithBarrier +// CHECK: -> UR_RESULT_SUCCESS +// +// CHECK-NOT: <--- urEnqueueKernelLaunch({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueKernelLaunch +// CHECK: -> UR_RESULT_SUCCESS +// +// CHECK-NOT: <--- urEnqueueKernelLaunch({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueKernelLaunch +// CHECK: -> UR_RESULT_SUCCESS +// +// RegularQueue +// CHECK-NOT: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueUSMFill +// CHECK: -> UR_RESULT_SUCCESS +// +// CHECK-NOT: <--- urEnqueueEventsWait({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueEventsWait +// CHECK: -> UR_RESULT_SUCCESS +// +// Everything that follows TestQueueOperationsViaSubmit() +// CHECK-NOT: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueUSMFill +// CHECK: -> UR_RESULT_SUCCESS +// +// CHECK-NOT: <--- urEnqueueUSMMemcpy({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueUSMMemcpy +// CHECK: -> UR_RESULT_SUCCESS +// +// Level-zero backend doesn't use urEnqueueUSMFill +// CHECK-L0: <--- urEnqueueKernelLaunch +// CHECK-L0: .phEvent = {{[0-9a-f]+}} +// CHECK-OTHER: <--- urEnqueueUSMFill({{.*}} .phEvent = {{[0-9a-f]+}} +// CHECK: -> UR_RESULT_SUCCESS +// +// ---> urEnqueueUSMMemcpy( +// CHECK-NOT: <--- urEnqueueUSMMemcpy({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueUSMMemcpy +// CHECK: -> UR_RESULT_SUCCESS +// +// CHECK-NOT: <--- urEnqueueUSMPrefetch({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueUSMPrefetch +// CHECK: ) -> {{UR_RESULT_SUCCESS|UR_RESULT_ERROR_ADAPTER_SPECIFIC}} +// +// CHECK-NOT: <--- urEnqueueUSMAdvise({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueUSMAdvise +// CHECK: ) -> {{UR_RESULT_SUCCESS|UR_RESULT_ERROR_ADAPTER_SPECIFIC}} +// +// CHECK-NOT: <--- urEnqueueEventsWaitWithBarrier({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueEventsWaitWithBarrier +// CHECK: -> UR_RESULT_SUCCESS +// +// CHECK-NOT: <--- urEnqueueKernelLaunch({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueKernelLaunch +// CHECK: -> UR_RESULT_SUCCESS +// +// CHECK-NOT: <--- urEnqueueKernelLaunch({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueKernelLaunch +// CHECK: -> UR_RESULT_SUCCESS +// +// RegularQueue +// CHECK-NOT: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueUSMFill +// CHECK: -> UR_RESULT_SUCCESS +// +// CHECK-NOT: <--- urEnqueueEventsWait({{.*}} .phEvent = nullptr +// CHECK: <--- urEnqueueEventsWait +// CHECK: -> UR_RESULT_SUCCESS +// +// CHECK: The test passed. + +#include "discard_events_test_queue_ops.hpp" +#include + +int main(int Argc, const char *Argv[]) { + + sycl::property_list Props{ + sycl::ext::oneapi::property::queue::discard_events{}}; + sycl::queue OOO_Q(Props); + + TestQueueOperations(OOO_Q); + + TestQueueOperationsViaSubmit(OOO_Q); + + std::cout << "The test passed." << std::endl; + return 0; +} diff --git a/sycl/test-e2e/DiscardEvents/invalid_event.cpp b/sycl/test-e2e/DiscardEvents/invalid_event.cpp new file mode 100644 index 0000000000000..4badd247767a8 --- /dev/null +++ b/sycl/test-e2e/DiscardEvents/invalid_event.cpp @@ -0,0 +1,93 @@ +// RUN: %{build} -o %t.out +// RUN: %{run} %t.out + +// The test checks that each queue method call returns a discarded event +// with the status "ext_oneapi_unknown" + +#include +#include +#include +#include +#include + +using namespace sycl; +static constexpr size_t BUFFER_SIZE = 16; + +void QueueAPIsReturnDiscardedEvent(sycl::queue Q) { + sycl::range<1> range(BUFFER_SIZE); + + auto Dev = Q.get_device(); + int *x = sycl::malloc_device(BUFFER_SIZE, Q); + assert(x != nullptr); + int *y = sycl::malloc_device(BUFFER_SIZE, Q); + assert(y != nullptr); + + sycl::event DiscardedEvent; + + DiscardedEvent = Q.memset(x, 0, BUFFER_SIZE * sizeof(int)); + assert( + DiscardedEvent.get_info() == + sycl::info::event_command_status::ext_oneapi_unknown); + + DiscardedEvent = Q.memcpy(y, x, BUFFER_SIZE * sizeof(int)); + assert( + DiscardedEvent.get_info() == + sycl::info::event_command_status::ext_oneapi_unknown); + + DiscardedEvent = Q.fill(y, 1, BUFFER_SIZE); + assert( + DiscardedEvent.get_info() == + sycl::info::event_command_status::ext_oneapi_unknown); + + DiscardedEvent = Q.copy(y, x, BUFFER_SIZE); + assert( + DiscardedEvent.get_info() == + sycl::info::event_command_status::ext_oneapi_unknown); + + DiscardedEvent = Q.prefetch(y, BUFFER_SIZE * sizeof(int)); + assert( + DiscardedEvent.get_info() == + sycl::info::event_command_status::ext_oneapi_unknown); + + DiscardedEvent = Q.mem_advise(y, BUFFER_SIZE * sizeof(int), 0); + assert( + DiscardedEvent.get_info() == + sycl::info::event_command_status::ext_oneapi_unknown); + + DiscardedEvent = Q.single_task([=] {}); + assert( + DiscardedEvent.get_info() == + sycl::info::event_command_status::ext_oneapi_unknown); + + DiscardedEvent = Q.submit([&](sycl::handler &CGH) { + CGH.parallel_for(range, [=](sycl::item<1> itemID) {}); + }); + assert( + DiscardedEvent.get_info() == + sycl::info::event_command_status::ext_oneapi_unknown); + + DiscardedEvent = Q.ext_oneapi_submit_barrier(); + assert( + DiscardedEvent.get_info() == + sycl::info::event_command_status::ext_oneapi_unknown); + + Q.wait(); + free(x, Q); + free(y, Q); +} + +int main(int Argc, const char *Argv[]) { + sycl::property_list Props1{ + sycl::ext::oneapi::property::queue::discard_events{}}; + sycl::queue OOO_Queue(Props1); + QueueAPIsReturnDiscardedEvent(OOO_Queue); + + sycl::property_list Props2{ + sycl::property::queue::in_order{}, + sycl::ext::oneapi::property::queue::discard_events{}}; + sycl::queue Inorder_Queue(Props2); + QueueAPIsReturnDiscardedEvent(Inorder_Queue); + + std::cout << "The test passed." << std::endl; + return 0; +} diff --git a/sycl/test-e2e/DiscardEvents/invalid_event_exceptions.cpp b/sycl/test-e2e/DiscardEvents/invalid_event_exceptions.cpp new file mode 100644 index 0000000000000..6da5b087474a9 --- /dev/null +++ b/sycl/test-e2e/DiscardEvents/invalid_event_exceptions.cpp @@ -0,0 +1,168 @@ +// RUN: %{build} -o %t.out +// +// RUN: %{run} %t.out +// +// The test checks 3 things: +// 1. An attempt to construct a queue with both properties(discard_events and +// enable_profiling) throws an exception. +// 2. Checks the APIs for discarded event that should throw an exception that +// they do it. +// 3. An attempt to pass discarded event into depends_on throws an exception. + +#include +#include +#include +#include + +using namespace sycl; + +void DiscardedEventWaitExceptionHelper( + const std::function &FunctionToTry) { + try { + FunctionToTry(); + assert(false && "No exception was thrown."); + } catch (const sycl::exception &e) { + assert(e.code().value() == static_cast(sycl::errc::invalid) && + "sycl::exception code was not the expected sycl::errc::invalid."); + } catch (...) { + assert(false && + "Unexpected exception was thrown in kernel invocation function."); + } +} + +void DependsOnDiscardedEventException(sycl::queue Q) { + auto DiscardedEvent = + Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); + + Q.submit([&](sycl::handler &CGH) { + try { + CGH.depends_on(DiscardedEvent); + assert(false && "No exception was thrown."); + } catch (const sycl::exception &e) { + assert(e.code().value() == static_cast(sycl::errc::invalid) && + "sycl::exception code was not the expected sycl::errc::invalid."); + } catch (...) { + assert(false && + "Unexpected exception was thrown in kernel invocation function."); + } + CGH.single_task([] {}); + }); + + sycl::event e1, e2; + Q.submit([&](sycl::handler &CGH) { + try { + CGH.depends_on({e1, DiscardedEvent, e2}); + assert(false && "No exception was thrown."); + } catch (const sycl::exception &e) { + assert(e.code().value() == static_cast(sycl::errc::invalid) && + "sycl::exception code was not the expected sycl::errc::invalid."); + } catch (...) { + assert(false && + "Unexpected exception was thrown in kernel invocation function."); + } + CGH.single_task([] {}); + }); + + sycl::queue RegularQ; + RegularQ.submit([&](sycl::handler &CGH) { + try { + CGH.depends_on(DiscardedEvent); + assert(false && "No exception was thrown."); + } catch (const sycl::exception &e) { + assert(e.code().value() == static_cast(sycl::errc::invalid) && + "sycl::exception code was not the expected sycl::errc::invalid."); + } catch (...) { + assert(false && + "Unexpected exception was thrown in kernel invocation function."); + } + CGH.single_task([] {}); + }); + + RegularQ.submit([&](sycl::handler &CGH) { + try { + CGH.depends_on({e1, DiscardedEvent, e2}); + assert(false && "No exception was thrown."); + } catch (const sycl::exception &e) { + assert(e.code().value() == static_cast(sycl::errc::invalid) && + "sycl::exception code was not the expected sycl::errc::invalid."); + } catch (...) { + assert(false && + "Unexpected exception was thrown in kernel invocation function."); + } + CGH.single_task([] {}); + }); +} + +void CheckDiscardedEventAPIException(sycl::queue Q) { + DiscardedEventWaitExceptionHelper([&]() { + auto DiscardedEvent = + Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); + DiscardedEvent.wait(); + }); + + DiscardedEventWaitExceptionHelper([&]() { + auto DiscardedEvent = + Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); + sycl::event::wait({DiscardedEvent}); + }); + + DiscardedEventWaitExceptionHelper([&]() { + auto DiscardedEvent = + Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); + DiscardedEvent.wait_and_throw(); + }); + + DiscardedEventWaitExceptionHelper([&]() { + auto DiscardedEvent = + Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); + sycl::event::wait_and_throw({DiscardedEvent}); + }); + + DiscardedEventWaitExceptionHelper([&]() { + auto DiscardedEvent = + Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); + DiscardedEvent.get_wait_list(); + }); +} + +void CreatingEnableProfilingQueueException(sycl::property_list Props) { + try { + sycl::queue Q{Props}; + assert(false && "No exception was thrown."); + } catch (const sycl::exception &e) { + assert(e.code().value() == static_cast(sycl::errc::invalid) && + "sycl::exception code was not the expected sycl::errc::invalid."); + } catch (...) { + assert(false && + "Unexpected exception was thrown in kernel invocation function."); + } +} + +int main(int Argc, const char *Argv[]) { + sycl::property_list Props1{ + sycl::property::queue::enable_profiling{}, + sycl::ext::oneapi::property::queue::discard_events{}}; + CreatingEnableProfilingQueueException(Props1); + + sycl::property_list Props2{ + sycl::ext::oneapi::property::queue::discard_events{}}; + sycl::queue OOO_Queue(Props2); + DependsOnDiscardedEventException(OOO_Queue); + CheckDiscardedEventAPIException(OOO_Queue); + + sycl::property_list Props3{ + sycl::property::queue::in_order{}, + sycl::property::queue::enable_profiling{}, + sycl::ext::oneapi::property::queue::discard_events{}}; + CreatingEnableProfilingQueueException(Props3); + + sycl::property_list Props4{ + sycl::property::queue::in_order{}, + sycl::ext::oneapi::property::queue::discard_events{}}; + sycl::queue Inorder_Queue(Props4); + DependsOnDiscardedEventException(Inorder_Queue); + CheckDiscardedEventAPIException(Inorder_Queue); + + std::cout << "The test passed." << std::endl; + return 0; +} diff --git a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp index a32abb0ce2981..25a69fbdbef7d 100644 --- a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp +++ b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp @@ -54,7 +54,7 @@ // tests to match the required format and in that case you should just update // (i.e. reduce) the number and the list below. // -// NUMBER-OF-UNSUPPORTED-WITHOUT-INFO: 271 +// NUMBER-OF-UNSUPPORTED-WITHOUT-INFO: 273 // // List of improperly UNSUPPORTED tests. // Remove the CHECK once the test has been properly UNSUPPORTED. @@ -119,6 +119,8 @@ // CHECK-NEXT: DeviceLib/separate_compile_test.cpp // CHECK-NEXT: DeviceLib/std_complex_math_fp64_test.cpp // CHECK-NEXT: DeviceLib/std_complex_math_test.cpp +// CHECK-NEXT: DiscardEvents/discard_events_check_images.cpp +// CHECK-NEXT: DiscardEvents/discard_events_using_assert.cpp // CHECK-NEXT: ESIMD/PerformanceTests/BitonicSortK.cpp // CHECK-NEXT: ESIMD/PerformanceTests/BitonicSortKv2.cpp // CHECK-NEXT: ESIMD/PerformanceTests/Stencil.cpp diff --git a/sycl/unittests/queue/Properties.cpp b/sycl/unittests/queue/Properties.cpp index a897081af3b31..af7c6c941ef08 100644 --- a/sycl/unittests/queue/Properties.cpp +++ b/sycl/unittests/queue/Properties.cpp @@ -26,6 +26,8 @@ TEST(QueueProperties, ValidDatalessProperties) { sycl::unittest::UrMock<> Mock; DatalessQueuePropertyCheck(); DatalessQueuePropertyCheck(); + DatalessQueuePropertyCheck< + sycl::ext::oneapi::property::queue::discard_events>(); DatalessQueuePropertyCheck< sycl::ext::oneapi::property::queue::priority_normal>(); DatalessQueuePropertyCheck< From 18fe7b78b0f4018807109d9bf082f12ccb9b4ec5 Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Thu, 17 Apr 2025 15:07:02 +0100 Subject: [PATCH 06/21] Add back missed change Signed-off-by: JackAKirk --- sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp b/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp index 458b866964eac..9f8688efcc3aa 100644 --- a/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp +++ b/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp @@ -8,6 +8,7 @@ // Check that dynamic batching raises/lowers batch size // RUN: env SYCL_UR_TRACE=2 UR_L0_DEBUG=1 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 %{run} %t.ooo.out 2>&1 | FileCheck --check-prefixes=CKALL,CKDYN %s // RUN: env SYCL_UR_TRACE=2 UR_L0_DEBUG=1 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 %{run} %t.ino.out 2>&1 | FileCheck --check-prefixes=CKALL,CKDYN %s +// RUN: env SYCL_UR_TRACE=2 UR_L0_DEBUG=1 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKDYN %s // level_zero_dynamic_batch_test.cpp // From 68a9dc08dd4c4779b5c68379543f62d58157b4e5 Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Mon, 21 Apr 2025 09:20:39 +0100 Subject: [PATCH 07/21] Remove out of date tests - Update docs - Fix format Signed-off-by: JackAKirk --- .../sycl_ext_oneapi_graph.asciidoc | 10 ++ sycl/source/detail/queue_impl.cpp | 3 +- sycl/source/detail/queue_impl.hpp | 1 - sycl/source/handler.cpp | 4 +- sycl/source/queue.cpp | 7 +- sycl/test-e2e/Basic/in_order_queue_status.cpp | 12 +- .../discard_events_accessors.cpp | 6 +- .../discard_events_using_assert_ndebug.cpp | 13 -- .../DiscardEvents/discard_events_usm.cpp | 109 ------------ sycl/test-e2e/DiscardEvents/invalid_event.cpp | 93 ---------- .../invalid_event_exceptions.cpp | 168 ------------------ 11 files changed, 19 insertions(+), 407 deletions(-) delete mode 100644 sycl/test-e2e/DiscardEvents/discard_events_using_assert_ndebug.cpp delete mode 100644 sycl/test-e2e/DiscardEvents/discard_events_usm.cpp delete mode 100644 sycl/test-e2e/DiscardEvents/invalid_event.cpp delete mode 100644 sycl/test-e2e/DiscardEvents/invalid_event_exceptions.cpp diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_graph.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_graph.asciidoc index 7b4e93ee1b776..ccdcf50049fee 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_graph.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_graph.asciidoc @@ -2161,6 +2161,16 @@ code `invalid` if a user tries to add them to a graph. Removing this restriction is something we may look at for future revisions of `sycl_ext_oneapi_graph`. +==== sycl_ext_oneapi_discard_queue_events + +When recording a `sycl::queue` which has been created with the +`ext::oneapi::property::queue::discard_event` property, it is invalid to +use these events returned from queue submissions to create graph edges. This is +in-keeping with the +link:../supported/sycl_ext_oneapi_discard_queue_events.asciidoc[sycl_ext_oneapi_discard_queue_events] +specification wording that `handler::depends_on()` throws an exception when +passed an invalid event. + ==== sycl_ext_oneapi_enqueue_barrier The new handler methods, and queue shortcuts, defined by diff --git a/sycl/source/detail/queue_impl.cpp b/sycl/source/detail/queue_impl.cpp index 48d63229638ae..72aec2b6943f5 100644 --- a/sycl/source/detail/queue_impl.cpp +++ b/sycl/source/detail/queue_impl.cpp @@ -402,8 +402,7 @@ event queue_impl::submitMemOpHelper(const std::shared_ptr &Self, // handler rather than by-passing the scheduler. if (MGraph.expired() && Scheduler::areEventsSafeForSchedulerBypass( ExpandedDepEvents, MContext)) { - if (!CallerNeedsEvent && - supportsDiscardingPiEvents()) { + if (!CallerNeedsEvent && supportsDiscardingPiEvents()) { NestedCallsTracker tracker; MemOpFunc(MemOpArgs..., getUrEvents(ExpandedDepEvents), /*PiEvent*/ nullptr, /*EventImplPtr*/ nullptr); diff --git a/sycl/source/detail/queue_impl.hpp b/sycl/source/detail/queue_impl.hpp index b0829ad9a90a0..c35b42a837d8a 100644 --- a/sycl/source/detail/queue_impl.hpp +++ b/sycl/source/detail/queue_impl.hpp @@ -700,7 +700,6 @@ class queue_impl { #endif protected: - template EventImplPtr insertHelperBarrier(const HandlerType &Handler) { auto ResEvent = std::make_shared(Handler.MQueue); diff --git a/sycl/source/handler.cpp b/sycl/source/handler.cpp index f94eff876cde0..58f0c480c90bf 100644 --- a/sycl/source/handler.cpp +++ b/sycl/source/handler.cpp @@ -509,8 +509,8 @@ event handler::finalize() { const detail::EventImplPtr &LastEventImpl = detail::getSyclObjImpl(MLastEvent); - bool DiscardEvent = !impl->MEventNeeded && - MQueue->supportsDiscardingPiEvents(); + bool DiscardEvent = + !impl->MEventNeeded && MQueue->supportsDiscardingPiEvents(); if (DiscardEvent) { // Kernel only uses assert if it's non interop one bool KernelUsesAssert = diff --git a/sycl/source/queue.cpp b/sycl/source/queue.cpp index cd4f26f09f0a2..69b69d83364cd 100644 --- a/sycl/source/queue.cpp +++ b/sycl/source/queue.cpp @@ -319,8 +319,7 @@ getBarrierEventForInorderQueueHelper(const detail::QueueImplPtr QueueImpl) { /// \return a SYCL event object, which corresponds to the queue the command /// group is being enqueued on. event queue::ext_oneapi_submit_barrier(const detail::code_location &CodeLoc) { - if (is_in_order() && !impl->hasCommandGraph() && - !impl->MIsProfilingEnabled) { + if (is_in_order() && !impl->hasCommandGraph() && !impl->MIsProfilingEnabled) { event InOrderLastEvent = getBarrierEventForInorderQueueHelper(impl); // If the last event was discarded, fall back to enqueuing a barrier. if (!detail::getSyclObjImpl(InOrderLastEvent)->isDiscarded()) @@ -347,8 +346,8 @@ event queue::ext_oneapi_submit_barrier(const std::vector &WaitList, return (EventImpl->isDefaultConstructed() || EventImpl->isNOP()) && !EventImpl->hasCommandGraph(); }); - if (is_in_order() && !impl->hasCommandGraph() && - !impl->MIsProfilingEnabled && AllEventsEmptyOrNop) { + if (is_in_order() && !impl->hasCommandGraph() && !impl->MIsProfilingEnabled && + AllEventsEmptyOrNop) { event InOrderLastEvent = getBarrierEventForInorderQueueHelper(impl); // If the last event was discarded, fall back to enqueuing a barrier. if (!detail::getSyclObjImpl(InOrderLastEvent)->isDiscarded()) diff --git a/sycl/test-e2e/Basic/in_order_queue_status.cpp b/sycl/test-e2e/Basic/in_order_queue_status.cpp index 68b8b990d1b3d..da4a111cde561 100644 --- a/sycl/test-e2e/Basic/in_order_queue_status.cpp +++ b/sycl/test-e2e/Basic/in_order_queue_status.cpp @@ -71,17 +71,7 @@ int main() { property::queue::in_order{}, sycl::ext::oneapi::property::queue::discard_events{}}; queue Q2{Props}; - - bool ExceptionThrown = false; - try { - TestFunc(Q2); - } catch (sycl::exception &E) { - ExceptionThrown = true; - } - - // Feature is not supported for OpenCL, exception must be thrown. - if (Q2.get_device().get_backend() == backend::opencl) - return ExceptionThrown ? 0 : -1; + TestFunc(Q2); return 0; } diff --git a/sycl/test-e2e/DiscardEvents/discard_events_accessors.cpp b/sycl/test-e2e/DiscardEvents/discard_events_accessors.cpp index 59e0a7f62650f..5cdbd0f73e683 100644 --- a/sycl/test-e2e/DiscardEvents/discard_events_accessors.cpp +++ b/sycl/test-e2e/DiscardEvents/discard_events_accessors.cpp @@ -2,12 +2,10 @@ // // RUN: env SYCL_UR_TRACE=2 %{run} %t.out &> %t.txt ; FileCheck %s --input-file %t.txt // -// The test checks that the last parameter is `nullptr` for -// urEnqueueKernelLaunch for USM kernel using local accessor, but -// is not `nullptr` for kernel using buffer accessor. +// The test checks that the last parameter is not `nullptr` for +// urEnqueueKernelLaunch for a kernel using buffer accessor. // // CHECK: <--- urEnqueueKernelLaunch -// CHECK: .phEvent = nullptr // // CHECK-NOT: <--- urEnqueueKernelLaunch({{.*}}.phEvent = nullptr // CHECK: <--- urEnqueueKernelLaunch diff --git a/sycl/test-e2e/DiscardEvents/discard_events_using_assert_ndebug.cpp b/sycl/test-e2e/DiscardEvents/discard_events_using_assert_ndebug.cpp deleted file mode 100644 index cdfbbe1386ed5..0000000000000 --- a/sycl/test-e2e/DiscardEvents/discard_events_using_assert_ndebug.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %{build} -DNDEBUG -o %t.out -// -// RUN: env SYCL_UR_TRACE=2 %{run} %t.out &> %t.txt ; FileCheck %s --input-file %t.txt -// -// The test checks that the last parameter is `nullptr` for -// urEnqueueKernelLaunch. -// -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: .phEvent = nullptr -// -// CHECK: The test passed. - -#include "discard_events_kernel_using_assert.hpp" diff --git a/sycl/test-e2e/DiscardEvents/discard_events_usm.cpp b/sycl/test-e2e/DiscardEvents/discard_events_usm.cpp deleted file mode 100644 index 8c446fee88365..0000000000000 --- a/sycl/test-e2e/DiscardEvents/discard_events_usm.cpp +++ /dev/null @@ -1,109 +0,0 @@ -// RUN: %{build} -o %t.out -// -// On level_zero Q.fill uses urEnqueueKernelLaunch and not urEnqueueUSMFill -// due to https://github.com/intel/llvm/issues/13787 -// -// RUN: env SYCL_UR_TRACE=2 %{run} %t.out &> %t.txt ; FileCheck %s --input-file %t.txt --check-prefixes=CHECK%if level_zero %{,CHECK-L0%} %else %{,CHECK-OTHER%} -// -// REQUIRES: aspect-usm_shared_allocations -// The test checks that the last parameter is `nullptr` for all UR calls that -// should discard events. -// {{0|0000000000000000}} is required for various output on Linux and Windows. -// NOTE: urEnqueueUSMPrefetch and urEnqueueUSMAdvise in the CUDA and -// HIP backends may return a warning result on Windows with error-code -// 66 (UR_RESULT_ERROR_ADAPTER_SPECIFIC) if USM managed memory is not -// supported or if unsupported advice flags are used for the latter API. -// Since it is a warning it is safe to ignore for this test. -// -// Everything that follows TestQueueOperations() -// CHECK: <--- urEnqueueUSMFill -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueUSMMemcpy -// CHECK: .phEvent = nullptr -// -// Level-zero backend doesn't use urEnqueueUSMFill -// CHECK-L0: <--- urEnqueueKernelLaunch -// CHECK-L0: .phEvent = nullptr -// CHECK-OTHER: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr -// -// ---> urEnqueueUSMMemcpy( -// CHECK: <--- urEnqueueUSMMemcpy -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueUSMPrefetch -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueUSMAdvise -// CHECK: .phEvent = nullptr -// CHECK: -> {{UR_RESULT_SUCCESS|UR_RESULT_ERROR_ADAPTER_SPECIFIC}} -// -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: .phEvent = nullptr -// -// RegularQueue -// CHECK-NOT: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMFill -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK: <--- urEnqueueEventsWait -// CHECK: .phEvent = nullptr -// -// Everything that follows TestQueueOperationsViaSubmit() -// CHECK: <--- urEnqueueUSMFill -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueUSMMemcpy -// CHECK: .phEvent = nullptr -// -// Level-zero backend doesn't use urEnqueueUSMFill -// CHECK-L0: <--- urEnqueueKernelLaunch -// CHECK-L0: .phEvent = nullptr -// CHECK-OTHER: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr -// -// ---> urEnqueueUSMMemcpy( -// CHECK: <--- urEnqueueUSMMemcpy -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueUSMPrefetch -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueUSMAdvise -// CHECK: .phEvent = nullptr -// CHECK-SAME: ) -> {{UR_RESULT_SUCCESS|UR_RESULT_ERROR_ADAPTER_SPECIFIC}} -// -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: .phEvent = nullptr -// -// CHECK: <--- urEnqueueKernelLaunch -// CHECK: .phEvent = nullptr -// -// RegularQueue -// CHECK-NOT: <--- urEnqueueUSMFill({{.*}} .phEvent = nullptr -// CHECK: <--- urEnqueueUSMFill -// CHECK: -> UR_RESULT_SUCCESS -// -// CHECK: <--- urEnqueueEventsWait -// CHECK: .phEvent = nullptr -// -// CHECK: The test passed. - -#include "discard_events_test_queue_ops.hpp" -#include -int main(int Argc, const char *Argv[]) { - - sycl::property_list Props{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue Q(Props); - - TestQueueOperations(Q); - - TestQueueOperationsViaSubmit(Q); - - std::cout << "The test passed." << std::endl; - return 0; -} diff --git a/sycl/test-e2e/DiscardEvents/invalid_event.cpp b/sycl/test-e2e/DiscardEvents/invalid_event.cpp deleted file mode 100644 index 4badd247767a8..0000000000000 --- a/sycl/test-e2e/DiscardEvents/invalid_event.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// RUN: %{build} -o %t.out -// RUN: %{run} %t.out - -// The test checks that each queue method call returns a discarded event -// with the status "ext_oneapi_unknown" - -#include -#include -#include -#include -#include - -using namespace sycl; -static constexpr size_t BUFFER_SIZE = 16; - -void QueueAPIsReturnDiscardedEvent(sycl::queue Q) { - sycl::range<1> range(BUFFER_SIZE); - - auto Dev = Q.get_device(); - int *x = sycl::malloc_device(BUFFER_SIZE, Q); - assert(x != nullptr); - int *y = sycl::malloc_device(BUFFER_SIZE, Q); - assert(y != nullptr); - - sycl::event DiscardedEvent; - - DiscardedEvent = Q.memset(x, 0, BUFFER_SIZE * sizeof(int)); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.memcpy(y, x, BUFFER_SIZE * sizeof(int)); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.fill(y, 1, BUFFER_SIZE); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.copy(y, x, BUFFER_SIZE); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.prefetch(y, BUFFER_SIZE * sizeof(int)); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.mem_advise(y, BUFFER_SIZE * sizeof(int), 0); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.single_task([=] {}); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.submit([&](sycl::handler &CGH) { - CGH.parallel_for(range, [=](sycl::item<1> itemID) {}); - }); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - DiscardedEvent = Q.ext_oneapi_submit_barrier(); - assert( - DiscardedEvent.get_info() == - sycl::info::event_command_status::ext_oneapi_unknown); - - Q.wait(); - free(x, Q); - free(y, Q); -} - -int main(int Argc, const char *Argv[]) { - sycl::property_list Props1{ - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue OOO_Queue(Props1); - QueueAPIsReturnDiscardedEvent(OOO_Queue); - - sycl::property_list Props2{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue Inorder_Queue(Props2); - QueueAPIsReturnDiscardedEvent(Inorder_Queue); - - std::cout << "The test passed." << std::endl; - return 0; -} diff --git a/sycl/test-e2e/DiscardEvents/invalid_event_exceptions.cpp b/sycl/test-e2e/DiscardEvents/invalid_event_exceptions.cpp deleted file mode 100644 index 6da5b087474a9..0000000000000 --- a/sycl/test-e2e/DiscardEvents/invalid_event_exceptions.cpp +++ /dev/null @@ -1,168 +0,0 @@ -// RUN: %{build} -o %t.out -// -// RUN: %{run} %t.out -// -// The test checks 3 things: -// 1. An attempt to construct a queue with both properties(discard_events and -// enable_profiling) throws an exception. -// 2. Checks the APIs for discarded event that should throw an exception that -// they do it. -// 3. An attempt to pass discarded event into depends_on throws an exception. - -#include -#include -#include -#include - -using namespace sycl; - -void DiscardedEventWaitExceptionHelper( - const std::function &FunctionToTry) { - try { - FunctionToTry(); - assert(false && "No exception was thrown."); - } catch (const sycl::exception &e) { - assert(e.code().value() == static_cast(sycl::errc::invalid) && - "sycl::exception code was not the expected sycl::errc::invalid."); - } catch (...) { - assert(false && - "Unexpected exception was thrown in kernel invocation function."); - } -} - -void DependsOnDiscardedEventException(sycl::queue Q) { - auto DiscardedEvent = - Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); - - Q.submit([&](sycl::handler &CGH) { - try { - CGH.depends_on(DiscardedEvent); - assert(false && "No exception was thrown."); - } catch (const sycl::exception &e) { - assert(e.code().value() == static_cast(sycl::errc::invalid) && - "sycl::exception code was not the expected sycl::errc::invalid."); - } catch (...) { - assert(false && - "Unexpected exception was thrown in kernel invocation function."); - } - CGH.single_task([] {}); - }); - - sycl::event e1, e2; - Q.submit([&](sycl::handler &CGH) { - try { - CGH.depends_on({e1, DiscardedEvent, e2}); - assert(false && "No exception was thrown."); - } catch (const sycl::exception &e) { - assert(e.code().value() == static_cast(sycl::errc::invalid) && - "sycl::exception code was not the expected sycl::errc::invalid."); - } catch (...) { - assert(false && - "Unexpected exception was thrown in kernel invocation function."); - } - CGH.single_task([] {}); - }); - - sycl::queue RegularQ; - RegularQ.submit([&](sycl::handler &CGH) { - try { - CGH.depends_on(DiscardedEvent); - assert(false && "No exception was thrown."); - } catch (const sycl::exception &e) { - assert(e.code().value() == static_cast(sycl::errc::invalid) && - "sycl::exception code was not the expected sycl::errc::invalid."); - } catch (...) { - assert(false && - "Unexpected exception was thrown in kernel invocation function."); - } - CGH.single_task([] {}); - }); - - RegularQ.submit([&](sycl::handler &CGH) { - try { - CGH.depends_on({e1, DiscardedEvent, e2}); - assert(false && "No exception was thrown."); - } catch (const sycl::exception &e) { - assert(e.code().value() == static_cast(sycl::errc::invalid) && - "sycl::exception code was not the expected sycl::errc::invalid."); - } catch (...) { - assert(false && - "Unexpected exception was thrown in kernel invocation function."); - } - CGH.single_task([] {}); - }); -} - -void CheckDiscardedEventAPIException(sycl::queue Q) { - DiscardedEventWaitExceptionHelper([&]() { - auto DiscardedEvent = - Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); - DiscardedEvent.wait(); - }); - - DiscardedEventWaitExceptionHelper([&]() { - auto DiscardedEvent = - Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); - sycl::event::wait({DiscardedEvent}); - }); - - DiscardedEventWaitExceptionHelper([&]() { - auto DiscardedEvent = - Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); - DiscardedEvent.wait_and_throw(); - }); - - DiscardedEventWaitExceptionHelper([&]() { - auto DiscardedEvent = - Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); - sycl::event::wait_and_throw({DiscardedEvent}); - }); - - DiscardedEventWaitExceptionHelper([&]() { - auto DiscardedEvent = - Q.submit([&](sycl::handler &CGH) { CGH.single_task([] {}); }); - DiscardedEvent.get_wait_list(); - }); -} - -void CreatingEnableProfilingQueueException(sycl::property_list Props) { - try { - sycl::queue Q{Props}; - assert(false && "No exception was thrown."); - } catch (const sycl::exception &e) { - assert(e.code().value() == static_cast(sycl::errc::invalid) && - "sycl::exception code was not the expected sycl::errc::invalid."); - } catch (...) { - assert(false && - "Unexpected exception was thrown in kernel invocation function."); - } -} - -int main(int Argc, const char *Argv[]) { - sycl::property_list Props1{ - sycl::property::queue::enable_profiling{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - CreatingEnableProfilingQueueException(Props1); - - sycl::property_list Props2{ - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue OOO_Queue(Props2); - DependsOnDiscardedEventException(OOO_Queue); - CheckDiscardedEventAPIException(OOO_Queue); - - sycl::property_list Props3{ - sycl::property::queue::in_order{}, - sycl::property::queue::enable_profiling{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - CreatingEnableProfilingQueueException(Props3); - - sycl::property_list Props4{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue Inorder_Queue(Props4); - DependsOnDiscardedEventException(Inorder_Queue); - CheckDiscardedEventAPIException(Inorder_Queue); - - std::cout << "The test passed." << std::endl; - return 0; -} From 956774f7b36f618344c542e34234125451ecdc4c Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Tue, 22 Apr 2025 09:05:23 -0400 Subject: [PATCH 08/21] Add compile time deprecation warning Signed-off-by: JackAKirk --- .../sycl_ext_oneapi_discard_queue_events.asciidoc | 13 +++++++------ .../sycl_ext_oneapi_discard_queue_events.asciidoc | 10 ++++++++++ sycl/include/sycl/properties/queue_properties.def | 10 ++++++++-- sycl/include/sycl/properties/queue_properties.hpp | 10 +++++++--- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/sycl/doc/extensions/deprecated/sycl_ext_oneapi_discard_queue_events.asciidoc b/sycl/doc/extensions/deprecated/sycl_ext_oneapi_discard_queue_events.asciidoc index d8a084aa42b25..c037d3e1a652a 100644 --- a/sycl/doc/extensions/deprecated/sycl_ext_oneapi_discard_queue_events.asciidoc +++ b/sycl/doc/extensions/deprecated/sycl_ext_oneapi_discard_queue_events.asciidoc @@ -8,6 +8,7 @@ :toc: left :encoding: utf-8 :lang: en +:dpcpp: pass:[DPC++] :blank: pass:[ +] @@ -37,12 +38,12 @@ Copyright (c) 2021 Intel Corporation. All rights reserved. == Status -This extension has been deprecated. Although the interfaces defined in this -specification are still supported in {dpcpp}, we expect that they will be -removed in an upcoming {dpcpp} release. The optimizations enabled by these -interfaces have already been disabled in the compiler. The functionality of -this extension has been replaced by the sycl_ext_oneapi_enqueue_functions -extension: see link:../experimental/sycl_ext_oneapi_enqueue_functions.asciidoc[here]. +This extension has been deprecated. This extension no longer provides any +benefit. Although the interfaces defined in this specification are still +supported in {dpcpp}, we expect that they will be removed in an upcoming {dpcpp} +release. The optimizations enabled by these interfaces have already been +disabled in the compiler. The functionality of this extension has been +replaced by the sycl_ext_oneapi_enqueue_functions extension: see link:../experimental/sycl_ext_oneapi_enqueue_functions.asciidoc[here]. *Shipping software products should stop using APIs defined in this specification and use this alternative instead.* diff --git a/sycl/doc/extensions/supported/sycl_ext_oneapi_discard_queue_events.asciidoc b/sycl/doc/extensions/supported/sycl_ext_oneapi_discard_queue_events.asciidoc index a0712992ab880..1aad0d0cd8490 100644 --- a/sycl/doc/extensions/supported/sycl_ext_oneapi_discard_queue_events.asciidoc +++ b/sycl/doc/extensions/supported/sycl_ext_oneapi_discard_queue_events.asciidoc @@ -1,2 +1,12 @@ +:dpcpp: pass:[DPC++] + This extension has been deprecated, but the specification is still available link:../deprecated/sycl_ext_oneapi_discard_queue_events.asciidoc[here]. +This extension no longer provides any benefit. Although the interfaces defined +in this specification are still supported in {dpcpp}, we expect that they will +be removed in an upcoming {dpcpp} release. The optimizations enabled by these +interfaces have already been disabled in the compiler. The functionality of +this extension has been replaced by the sycl_ext_oneapi_enqueue_functions +extension: see link:../experimental/sycl_ext_oneapi_enqueue_functions.asciidoc[here]. +*Shipping software products should stop using APIs defined in this +specification and use this alternative instead.* diff --git a/sycl/include/sycl/properties/queue_properties.def b/sycl/include/sycl/properties/queue_properties.def index 6e0f3fd700952..5391f4743d306 100644 --- a/sycl/include/sycl/properties/queue_properties.def +++ b/sycl/include/sycl/properties/queue_properties.def @@ -5,12 +5,13 @@ #ifndef __SYCL_MANUALLY_DEFINED_PROP #define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) #endif +#ifndef __SYCL_DATA_LESS_PROP_DEPRECATED_ALIAS +#define __SYCL_DATA_LESS_PROP_DEPRECATED_ALIAS(NS_QUALIFIER, PROP_NAME, ENUM_VAL, WARNING) +#endif __SYCL_DATA_LESS_PROP(property::queue, in_order, InOrder) __SYCL_DATA_LESS_PROP(property::queue, enable_profiling, QueueEnableProfiling) -__SYCL_DATA_LESS_PROP(ext::oneapi::property::queue, discard_events, - DiscardEvents) __SYCL_DATA_LESS_PROP(ext::oneapi::property::queue, priority_normal, QueuePriorityNormal) __SYCL_DATA_LESS_PROP(ext::oneapi::property::queue, priority_low, @@ -31,5 +32,10 @@ __SYCL_MANUALLY_DEFINED_PROP(property::queue::cuda, use_default_stream) // Contains data field, defined explicitly. __SYCL_MANUALLY_DEFINED_PROP(ext::intel::property::queue, compute_index) +__SYCL_DATA_LESS_PROP_DEPRECATED_ALIAS( + ext::oneapi::property::queue, discard_events, DiscardEvents, + __SYCL2020_DEPRECATED("use sycl_ext_oneapi_enqueue_functions instead")) + #undef __SYCL_DATA_LESS_PROP #undef __SYCL_MANUALLY_DEFINED_PROP +#undef __SYCL_DATA_LESS_PROP_DEPRECATED_ALIAS diff --git a/sycl/include/sycl/properties/queue_properties.hpp b/sycl/include/sycl/properties/queue_properties.hpp index 1e5dbec090f3a..cb20761069376 100644 --- a/sycl/include/sycl/properties/queue_properties.hpp +++ b/sycl/include/sycl/properties/queue_properties.hpp @@ -16,11 +16,15 @@ namespace sycl { inline namespace _V1 { -#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ +#define __SYCL_DATA_LESS_PROP_DEPRECATED_ALIAS(NS_QUALIFIER, PROP_NAME, \ + ENUM_VAL, WARNING) \ namespace NS_QUALIFIER { \ - class PROP_NAME \ + class WARNING PROP_NAME \ : public sycl::detail::DataLessProperty {}; \ - } + } \ + WARNING inline constexpr NS_QUALIFIER::PROP_NAME PROP_NAME; +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ + __SYCL_DATA_LESS_PROP_DEPRECATED_ALIAS(NS_QUALIFIER, PROP_NAME, ENUM_VAL, ) #include From 63f142e7c43e7d0b8e7b30c819131b5a8fee009b Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Tue, 22 Apr 2025 09:50:20 -0400 Subject: [PATCH 09/21] Move DiscardEvents tests to DeprecatedFeatures deleted some more unnecessary tests. Signed-off-by: JackAKirk --- .../Adapters/level_zero_batch_test.cpp | 27 ------------------- .../level_zero_dynamic_batch_test.cpp | 6 ----- sycl/test-e2e/Basic/in_order_queue_status.cpp | 7 ----- .../discard_events_accessors.cpp | 0 .../discard_events_check_images.cpp | 0 .../discard_events_kernel_using_assert.hpp | 0 .../discard_events_l0_inorder.cpp | 0 .../DiscardEvents/discard_events_l0_leak.cpp | 0 .../discard_events_mixed_calls.cpp | 0 .../discard_events_test_queue_ops.hpp | 0 .../discard_events_using_assert.cpp | 0 .../discard_events_usm_ooo_queue.cpp | 0 12 files changed, 40 deletions(-) rename sycl/test-e2e/{ => DeprecatedFeatures}/DiscardEvents/discard_events_accessors.cpp (100%) rename sycl/test-e2e/{ => DeprecatedFeatures}/DiscardEvents/discard_events_check_images.cpp (100%) rename sycl/test-e2e/{ => DeprecatedFeatures}/DiscardEvents/discard_events_kernel_using_assert.hpp (100%) rename sycl/test-e2e/{ => DeprecatedFeatures}/DiscardEvents/discard_events_l0_inorder.cpp (100%) rename sycl/test-e2e/{ => DeprecatedFeatures}/DiscardEvents/discard_events_l0_leak.cpp (100%) rename sycl/test-e2e/{ => DeprecatedFeatures}/DiscardEvents/discard_events_mixed_calls.cpp (100%) rename sycl/test-e2e/{ => DeprecatedFeatures}/DiscardEvents/discard_events_test_queue_ops.hpp (100%) rename sycl/test-e2e/{ => DeprecatedFeatures}/DiscardEvents/discard_events_using_assert.cpp (100%) rename sycl/test-e2e/{ => DeprecatedFeatures}/DiscardEvents/discard_events_usm_ooo_queue.cpp (100%) diff --git a/sycl/test-e2e/Adapters/level_zero_batch_test.cpp b/sycl/test-e2e/Adapters/level_zero_batch_test.cpp index da3ff2359c624..8f6e4e0f6a563 100644 --- a/sycl/test-e2e/Adapters/level_zero_batch_test.cpp +++ b/sycl/test-e2e/Adapters/level_zero_batch_test.cpp @@ -2,7 +2,6 @@ // RUN: %{build} -o %t.ooo.out // RUN: %{build} -DUSING_INORDER -o %t.ino.out -// RUN: %{build} -DUSING_DISCARD_EVENTS -o %t.discard_events.out // UNSUPPORTED: ze_debug, level_zero_v2_adapter // To test batching on out-of-order queue: @@ -49,28 +48,6 @@ // Set batching to 9 explicitly // RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=9 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.ino.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB9 %s -// To test batching on in-order queue with discard_events: -// Set batching to 4 explicitly -// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=4 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB4 %s - -// Set batching to 1 explicitly -// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=1 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB1 %s - -// Set batching to 3 explicitly -// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=3 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB3 %s - -// Set batching to 5 explicitly -// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=5 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB5 %s - -// Set batching to 7 explicitly -// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=7 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB7 %s - -// Set batching to 8 explicitly -// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=8 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB8 %s - -// Set batching to 9 explicitly -// RUN: env SYCL_PI_LEVEL_ZERO_BATCH_SIZE=9 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 SYCL_UR_TRACE=2 UR_L0_DEBUG=1 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKB9 %s - // level_zero_batch_test.cpp // // This tests the level zero adapter's kernel batching code. The default @@ -292,10 +269,6 @@ int main(int argc, char *argv[]) { #ifdef USING_INORDER sycl::property_list Props{sycl::property::queue::in_order{}}; -#elif USING_DISCARD_EVENTS - sycl::property_list Props{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; #else sycl::property_list Props{}; #endif diff --git a/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp b/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp index 9f8688efcc3aa..0c974d2b306e6 100644 --- a/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp +++ b/sycl/test-e2e/Adapters/level_zero_dynamic_batch_test.cpp @@ -3,12 +3,10 @@ // RUN: %{build} -o %t.ooo.out // RUN: %{build} -DUSING_INORDER -o %t.ino.out -// RUN: %{build} -DUSING_DISCARD_EVENTS -o %t.discard_events.out // Check that dynamic batching raises/lowers batch size // RUN: env SYCL_UR_TRACE=2 UR_L0_DEBUG=1 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 %{run} %t.ooo.out 2>&1 | FileCheck --check-prefixes=CKALL,CKDYN %s // RUN: env SYCL_UR_TRACE=2 UR_L0_DEBUG=1 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 %{run} %t.ino.out 2>&1 | FileCheck --check-prefixes=CKALL,CKDYN %s -// RUN: env SYCL_UR_TRACE=2 UR_L0_DEBUG=1 SYCL_PI_LEVEL_ZERO_DEVICE_SCOPE_EVENTS=2 SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 %{run} %t.discard_events.out 2>&1 | FileCheck --check-prefixes=CKALL,CKDYN %s // level_zero_dynamic_batch_test.cpp // @@ -67,10 +65,6 @@ int main(int argc, char *argv[]) { #ifdef USING_INORDER sycl::property_list Props{sycl::property::queue::in_order{}}; -#elif USING_DISCARD_EVENTS - sycl::property_list Props{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; #else sycl::property_list Props{}; #endif diff --git a/sycl/test-e2e/Basic/in_order_queue_status.cpp b/sycl/test-e2e/Basic/in_order_queue_status.cpp index da4a111cde561..a41989fb73db7 100644 --- a/sycl/test-e2e/Basic/in_order_queue_status.cpp +++ b/sycl/test-e2e/Basic/in_order_queue_status.cpp @@ -66,12 +66,5 @@ int main() { queue Q1{property::queue::in_order()}; TestFunc(Q1); - // Test in-order queue with discard_events property. - sycl::property_list Props{ - property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - queue Q2{Props}; - TestFunc(Q2); - return 0; } diff --git a/sycl/test-e2e/DiscardEvents/discard_events_accessors.cpp b/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_accessors.cpp similarity index 100% rename from sycl/test-e2e/DiscardEvents/discard_events_accessors.cpp rename to sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_accessors.cpp diff --git a/sycl/test-e2e/DiscardEvents/discard_events_check_images.cpp b/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_check_images.cpp similarity index 100% rename from sycl/test-e2e/DiscardEvents/discard_events_check_images.cpp rename to sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_check_images.cpp diff --git a/sycl/test-e2e/DiscardEvents/discard_events_kernel_using_assert.hpp b/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_kernel_using_assert.hpp similarity index 100% rename from sycl/test-e2e/DiscardEvents/discard_events_kernel_using_assert.hpp rename to sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_kernel_using_assert.hpp diff --git a/sycl/test-e2e/DiscardEvents/discard_events_l0_inorder.cpp b/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_l0_inorder.cpp similarity index 100% rename from sycl/test-e2e/DiscardEvents/discard_events_l0_inorder.cpp rename to sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_l0_inorder.cpp diff --git a/sycl/test-e2e/DiscardEvents/discard_events_l0_leak.cpp b/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_l0_leak.cpp similarity index 100% rename from sycl/test-e2e/DiscardEvents/discard_events_l0_leak.cpp rename to sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_l0_leak.cpp diff --git a/sycl/test-e2e/DiscardEvents/discard_events_mixed_calls.cpp b/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_mixed_calls.cpp similarity index 100% rename from sycl/test-e2e/DiscardEvents/discard_events_mixed_calls.cpp rename to sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_mixed_calls.cpp diff --git a/sycl/test-e2e/DiscardEvents/discard_events_test_queue_ops.hpp b/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_test_queue_ops.hpp similarity index 100% rename from sycl/test-e2e/DiscardEvents/discard_events_test_queue_ops.hpp rename to sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_test_queue_ops.hpp diff --git a/sycl/test-e2e/DiscardEvents/discard_events_using_assert.cpp b/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_using_assert.cpp similarity index 100% rename from sycl/test-e2e/DiscardEvents/discard_events_using_assert.cpp rename to sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_using_assert.cpp diff --git a/sycl/test-e2e/DiscardEvents/discard_events_usm_ooo_queue.cpp b/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_usm_ooo_queue.cpp similarity index 100% rename from sycl/test-e2e/DiscardEvents/discard_events_usm_ooo_queue.cpp rename to sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_usm_ooo_queue.cpp From 411370315ca1260195775309f8a7cb53ec2a5b7d Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Tue, 22 Apr 2025 10:40:56 -0400 Subject: [PATCH 10/21] Add deprec warning test - remove ValidDatalessProperties test for discard_events which does not expect warning, use deprec warning test to replace it - Remove sycl::image tests with discard_events that duplicate testing of basic queue for this deprecated feature Signed-off-by: JackAKirk --- .../discard_events_check_images.cpp | 203 ------------------ .../discard_events_mixed_calls.cpp | 60 +++--- sycl/test/warnings/warnings_deprecated.cpp | 3 + sycl/unittests/queue/Properties.cpp | 2 - 4 files changed, 33 insertions(+), 235 deletions(-) delete mode 100644 sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_check_images.cpp diff --git a/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_check_images.cpp b/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_check_images.cpp deleted file mode 100644 index e9f8588124b07..0000000000000 --- a/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_check_images.cpp +++ /dev/null @@ -1,203 +0,0 @@ -// UNSUPPORTED: target-amd -// REQUIRES: aspect-ext_intel_legacy_image -// -// RUN: %{build} -o %t.out -// -// RUN: %{run} %t.out image -// RUN: %{run} %t.out mixed -// -// Note that the tests use image functionality and if you have problems with -// the tests, please check if they pass without the discard_events property, if -// they don't pass then it's most likely a general issue unrelated to -// discard_events. - -// 1. There is a SPIR-V spec issue that blocks generation of valid SPIR-V code -// for the OpenCL environments support of the "Unknown" image format: -// https://github.com/KhronosGroup/SPIRV-Headers/issues/487 -// 2. The PR https://github.com/llvm/llvm-project/pull/127242 in upstream needs -// to be merged with intel/llvm to address an issue of mapping from SPIR-V -// friendly builtins to Image Read/Write instructions After the 1 issue is -// resolved and 2 is merged we will re-enable Image support. -// UNSUPPORTED: spirv-backend && arch-intel_gpu_bmg_g21 -// UNSUPPORTED-TRACKER: https://github.com/KhronosGroup/SPIRV-Headers/issues/487 - -#include "../helpers.hpp" // for printableVec -#include -#include -#include -#include -#include -#include -#include - -using namespace sycl; -static constexpr size_t BUFFER_SIZE = 1024; -static constexpr int MAX_ITER_NUM1 = 10; -static constexpr int MAX_ITER_NUM2 = 10; -static constexpr int InitialVal = MAX_ITER_NUM1; - -void TestHelper(sycl::queue Q, - const std::function ImgSize, int *Harray, - sycl::image<2> Img)> &Function) { - int *Harray = sycl::malloc_shared(BUFFER_SIZE, Q); - assert(Harray != nullptr); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - Harray[i] = 0; - } - - const sycl::image_channel_order ChanOrder = sycl::image_channel_order::rgba; - const sycl::image_channel_type ChanType = - sycl::image_channel_type::signed_int32; - - const sycl::range<2> ImgSize(sycl::sqrt(static_cast(BUFFER_SIZE)), - sycl::sqrt(static_cast(BUFFER_SIZE))); - std::vector ImgHostData( - ImgSize.size(), {InitialVal, InitialVal, InitialVal, InitialVal}); - sycl::image<2> Img(ImgHostData.data(), ChanOrder, ChanType, ImgSize); - - Function(ImgSize, Harray, Img); - - free(Harray, Q); -} - -void IfTrueIncrementUSM(sycl::queue Q, sycl::range<1> Range, int *Harray, - int ValueToCheck) { - Q.submit([&](sycl::handler &CGH) { - CGH.parallel_for(Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (Harray[i] == ValueToCheck) { - Harray[i] += 1; - } - }); - }); -} - -void IfTrueIncrementImageAndUSM(sycl::queue Q, sycl::range<2> ImgSize, - int *Harray, sycl::image<2> Img, - int HarrayValueToCheck, int ImageValueToCheck) { - Q.submit([&](sycl::handler &CGH) { - auto Img1Acc = Img.get_access(CGH); - auto Img2Acc = Img.get_access(CGH); - CGH.parallel_for(ImgSize, [=](sycl::item<2> Item) { - size_t i = Item.get_linear_id(); - if (Harray[i] == HarrayValueToCheck) { - sycl::int4 Data = Img1Acc.read(sycl::int2{Item[0], Item[1]}); - if (Data[0] == ImageValueToCheck && Data[1] == ImageValueToCheck && - Data[2] == ImageValueToCheck && Data[3] == ImageValueToCheck) { - Data[0]++; - Data[3] = Data[2] = Data[1] = Data[0]; - Img2Acc.write(sycl::int2{Item[0], Item[1]}, Data); - } - ++Harray[i]; - } - }); - }); -} - -void RunTest_ImageTest(sycl::queue Q) { - TestHelper(Q, [&](sycl::range<2> ImgSize, int *Harray, sycl::image<2> Img) { - sycl::range<1> Range(BUFFER_SIZE); - for (int i = 0; i < MAX_ITER_NUM1; ++i) - IfTrueIncrementUSM(Q, Range, Harray, (i)); - - for (int i = 0; i < MAX_ITER_NUM2; ++i) - IfTrueIncrementImageAndUSM(Q, ImgSize, Harray, Img, (MAX_ITER_NUM1 + i), - (InitialVal + i)); - Q.wait(); - - // check results - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1 + MAX_ITER_NUM2; - assert(Harray[i] == expected); - } - - { - auto HostAcc = - Img.template get_access(); - int expected = InitialVal + MAX_ITER_NUM2; - for (int X = 0; X < ImgSize[0]; ++X) - for (int Y = 0; Y < ImgSize[1]; ++Y) { - sycl::int4 Vec1 = sycl::int4(expected); - sycl::int4 Vec2 = HostAcc.read(sycl::int2{X, Y}); - if (Vec1[0] != Vec2[0] || Vec1[1] != Vec2[1] || Vec1[2] != Vec2[2] || - Vec1[3] != Vec2[3]) { - std::cerr << "Failed" << std::endl; - std::cerr << "Element [ " << X << ", " << Y << " ]" << std::endl; - std::cerr << "Expected: " << printableVec(Vec1) << std::endl; - std::cerr << " Got : " << printableVec(Vec2) << std::endl; - assert(false && "ImageTest failed!"); - } - } - } - }); -} - -void RunTest_ImageTest_Mixed(sycl::queue Q) { - TestHelper(Q, [&](sycl::range<2> ImgSize, int *Harray, sycl::image<2> Img) { - sycl::range<1> Range(BUFFER_SIZE); - - for (int i = 0; i < MAX_ITER_NUM1; ++i) { - IfTrueIncrementUSM(Q, Range, Harray, (i * 2)); - IfTrueIncrementImageAndUSM(Q, ImgSize, Harray, Img, (i * 2 + 1), - (InitialVal + i)); - } - - for (int i = 0; i < MAX_ITER_NUM2; ++i) { - IfTrueIncrementImageAndUSM(Q, ImgSize, Harray, Img, - (MAX_ITER_NUM1 * 2 + i * 2), - (InitialVal + MAX_ITER_NUM1 + i)); - IfTrueIncrementUSM(Q, Range, Harray, (MAX_ITER_NUM1 * 2 + i * 2 + 1)); - } - - Q.wait(); - - // check results - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1 * 2 + MAX_ITER_NUM2 * 2; - assert(Harray[i] == expected); - } - - { - auto HostAcc = - Img.template get_access(); - int expected = InitialVal + MAX_ITER_NUM1 + MAX_ITER_NUM2; - for (int X = 0; X < ImgSize[0]; ++X) - for (int Y = 0; Y < ImgSize[1]; ++Y) { - sycl::int4 Vec1 = sycl::int4(expected); - sycl::int4 Vec2 = HostAcc.read(sycl::int2{X, Y}); - if (Vec1[0] != Vec2[0] || Vec1[1] != Vec2[1] || Vec1[2] != Vec2[2] || - Vec1[3] != Vec2[3]) { - std::cerr << "Failed" << std::endl; - std::cerr << "Element [ " << X << ", " << Y << " ]" << std::endl; - std::cerr << "Expected: " << printableVec(Vec1) << std::endl; - std::cerr << " Got : " << printableVec(Vec2) << std::endl; - assert(false && "ImageTest_Mixed failed!"); - } - } - } - }); -} - -int main(int Argc, const char *Argv[]) { - assert(Argc == 2 && "Invalid number of arguments"); - std::string TestType(Argv[1]); - - sycl::property_list props{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue Q(props); - - auto dev = Q.get_device(); - if (TestType == "image") { - std::cerr << "RunTest_ImageTest" << std::endl; - RunTest_ImageTest(Q); - } else if (TestType == "mixed") { - std::cerr << "RunTest_ImageTest_Mixed" << std::endl; - RunTest_ImageTest_Mixed(Q); - } else { - assert(0 && "Unsupported test type!"); - } - - std::cout << "The test passed." << std::endl; - return 0; -} diff --git a/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_mixed_calls.cpp b/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_mixed_calls.cpp index 041519a64d900..d96ff826a8fdd 100644 --- a/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_mixed_calls.cpp +++ b/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_mixed_calls.cpp @@ -115,36 +115,36 @@ void RunTest_USM_Accessor(sycl::queue Q) { } void RunTest_Accessor_USM(sycl::queue Q) { - TestHelper( - Q, [&](sycl::range<1> Range, int *Harray, sycl::buffer Buf) { - { - sycl::host_accessor HostAcc(Buf); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - HostAcc[i] = 0; - } - } - - for (int i = 0; i < MAX_ITER_NUM1; ++i) - IfTrueIncrementBufferAndUSM(Q, Range, Harray, Buf, (i)); - - for (int i = 0; i < MAX_ITER_NUM2; ++i) - IfTrueIncrementUSM(Q, Range, Harray, (MAX_ITER_NUM1 + i)); - - Q.wait(); - - // check results - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1 + MAX_ITER_NUM2; - assert(Harray[i] == expected); - } - { - sycl::host_accessor HostAcc(Buf, sycl::read_only); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1; - assert(HostAcc[i] == expected); - } - } - }); + TestHelper(Q, + [&](sycl::range<1> Range, int *Harray, sycl::buffer Buf) { + { + sycl::host_accessor HostAcc(Buf); + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + HostAcc[i] = 0; + } + } + + for (int i = 0; i < MAX_ITER_NUM1; ++i) + IfTrueIncrementBufferAndUSM(Q, Range, Harray, Buf, (i)); + + for (int i = 0; i < MAX_ITER_NUM2; ++i) + IfTrueIncrementUSM(Q, Range, Harray, (MAX_ITER_NUM1 + i)); + + Q.wait(); + + // check results + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + int expected = MAX_ITER_NUM1 + MAX_ITER_NUM2; + assert(Harray[i] == expected); + } + { + sycl::host_accessor HostAcc(Buf, sycl::read_only); + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + int expected = MAX_ITER_NUM1; + assert(HostAcc[i] == expected); + } + } + }); } void RunTest_Mixed(sycl::queue Q) { diff --git a/sycl/test/warnings/warnings_deprecated.cpp b/sycl/test/warnings/warnings_deprecated.cpp index 6fc3e220bc0e3..7b070582f2e32 100644 --- a/sycl/test/warnings/warnings_deprecated.cpp +++ b/sycl/test/warnings/warnings_deprecated.cpp @@ -7,5 +7,8 @@ int main() { // expected-warning@+1{{'atomic64' is deprecated: use sycl::aspect::atomic64 instead}} sycl::info::device::atomic64 atomic_64; (void)atomic_64; + + // expected-warning@+1{{'discard_events' is deprecated: use sycl_ext_oneapi_enqueue_functions instead}} + sycl::property_list props{sycl::ext::oneapi::property::queue::discard_events{}}; return 0; } diff --git a/sycl/unittests/queue/Properties.cpp b/sycl/unittests/queue/Properties.cpp index af7c6c941ef08..a897081af3b31 100644 --- a/sycl/unittests/queue/Properties.cpp +++ b/sycl/unittests/queue/Properties.cpp @@ -26,8 +26,6 @@ TEST(QueueProperties, ValidDatalessProperties) { sycl::unittest::UrMock<> Mock; DatalessQueuePropertyCheck(); DatalessQueuePropertyCheck(); - DatalessQueuePropertyCheck< - sycl::ext::oneapi::property::queue::discard_events>(); DatalessQueuePropertyCheck< sycl::ext::oneapi::property::queue::priority_normal>(); DatalessQueuePropertyCheck< From 4161333c541135618890dde77ebe40901f7b4ff1 Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Tue, 22 Apr 2025 11:03:03 -0400 Subject: [PATCH 11/21] Remove unnecessary test Signed-off-by: JackAKirk --- .../discard_events_mixed_calls.cpp | 286 ------------------ 1 file changed, 286 deletions(-) delete mode 100644 sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_mixed_calls.cpp diff --git a/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_mixed_calls.cpp b/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_mixed_calls.cpp deleted file mode 100644 index d96ff826a8fdd..0000000000000 --- a/sycl/test-e2e/DeprecatedFeatures/DiscardEvents/discard_events_mixed_calls.cpp +++ /dev/null @@ -1,286 +0,0 @@ -// RUN: %{build} -o %t.out - -// The purpose of all tests is to make sure in-order semantics works correctly -// using discard_events and alternating event and eventless kernel calls in -// different ways. - -// The test checks that eventless kernel calls work correctly after several -// event kernel calls. -// RUN: %{run} %t.out accessor-usm - -// The test checks that event kernel calls work correctly after several -// eventless kernel calls. -// RUN: %{run} %t.out usm-accessor - -// The test checks that alternating event and eventless kernel calls work -// correctly. -// RUN: %{run} %t.out mixed - -// The test checks that urEnqueueMemBufferMap and urEnqueueMemUnmap work -// correctly when we alternate between event and eventless kernel calls. -// RUN: %{run} %t.out map-unmap - -// Note that the tests use buffer functionality and if you have problems with -// the tests, please check if they pass without the discard_events property, if -// they don't pass then it's most likely a general issue unrelated to -// discard_events. -// REQUIRES: aspect-usm_shared_allocations -#include -#include -#include -#include -#include - -using namespace sycl; -static constexpr size_t BUFFER_SIZE = 1024; -static constexpr int MAX_ITER_NUM1 = 10; -static constexpr int MAX_ITER_NUM2 = 10; - -void TestHelper(sycl::queue Q, - const std::function Range, int *Harray, - sycl::buffer Buf)> &Function) { - int *Harray = sycl::malloc_shared(BUFFER_SIZE, Q); - assert(Harray != nullptr); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - Harray[i] = 0; - } - - sycl::range<1> Range(BUFFER_SIZE); - sycl::buffer Buf(Range); - - Function(Range, Harray, Buf); - - free(Harray, Q); -} - -void IfTrueIncrementUSM(sycl::queue Q, sycl::range<1> Range, int *Harray, - int ValueToCheck) { - Q.submit([&](sycl::handler &CGH) { - CGH.parallel_for(Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (Harray[i] == ValueToCheck) { - Harray[i] += 1; - } - }); - }); -} - -void IfTrueIncrementBufferAndUSM(sycl::queue Q, sycl::range<1> Range, - int *Harray, sycl::buffer Buf, - int ValueToCheck) { - Q.submit([&](sycl::handler &CGH) { - auto Acc = Buf.get_access(CGH); - CGH.parallel_for( - Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (Harray[i] == ValueToCheck) { - ++Acc[i]; - ++Harray[i]; - } - }); - }); -} - -void RunTest_USM_Accessor(sycl::queue Q) { - TestHelper(Q, [&](sycl::range<1> Range, int *Harray, - sycl::buffer Buf) { - { - sycl::host_accessor HostAcc(Buf); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - HostAcc[i] = 0; - } - } - - for (int i = 0; i < MAX_ITER_NUM1; ++i) - IfTrueIncrementUSM(Q, Range, Harray, (i)); - - for (int i = 0; i < MAX_ITER_NUM2; ++i) - IfTrueIncrementBufferAndUSM(Q, Range, Harray, Buf, (MAX_ITER_NUM1 + i)); - - Q.wait(); - - // check results - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1 + MAX_ITER_NUM2; - assert(Harray[i] == expected); - } - { - sycl::host_accessor HostAcc(Buf, sycl::read_only); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM2; - assert(HostAcc[i] == expected); - } - } - }); -} - -void RunTest_Accessor_USM(sycl::queue Q) { - TestHelper(Q, - [&](sycl::range<1> Range, int *Harray, sycl::buffer Buf) { - { - sycl::host_accessor HostAcc(Buf); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - HostAcc[i] = 0; - } - } - - for (int i = 0; i < MAX_ITER_NUM1; ++i) - IfTrueIncrementBufferAndUSM(Q, Range, Harray, Buf, (i)); - - for (int i = 0; i < MAX_ITER_NUM2; ++i) - IfTrueIncrementUSM(Q, Range, Harray, (MAX_ITER_NUM1 + i)); - - Q.wait(); - - // check results - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1 + MAX_ITER_NUM2; - assert(Harray[i] == expected); - } - { - sycl::host_accessor HostAcc(Buf, sycl::read_only); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1; - assert(HostAcc[i] == expected); - } - } - }); -} - -void RunTest_Mixed(sycl::queue Q) { - TestHelper( - Q, [&](sycl::range<1> Range, int *Harray, sycl::buffer Buf) { - { - sycl::host_accessor HostAcc(Buf); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - HostAcc[i] = 0; - } - } - - for (int i = 0; i < MAX_ITER_NUM1; ++i) { - IfTrueIncrementUSM(Q, Range, Harray, (i * 2)); - IfTrueIncrementBufferAndUSM(Q, Range, Harray, Buf, (i * 2 + 1)); - } - - for (int i = 0; i < MAX_ITER_NUM2; ++i) { - IfTrueIncrementBufferAndUSM(Q, Range, Harray, Buf, - (MAX_ITER_NUM1 * 2 + i * 2)); - IfTrueIncrementUSM(Q, Range, Harray, (MAX_ITER_NUM1 * 2 + i * 2 + 1)); - } - - Q.wait(); - - // check results - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1 * 2 + MAX_ITER_NUM2 * 2; - assert(Harray[i] == expected); - } - { - sycl::host_accessor HostAcc(Buf, sycl::read_only); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = MAX_ITER_NUM1 + MAX_ITER_NUM2; - assert(HostAcc[i] == expected); - } - } - }); -} - -void RunTest_MemBufferMapUnMap(sycl::queue Q) { - TestHelper( - Q, [&](sycl::range<1> Range, int *Harray, sycl::buffer Buf) { - Q.submit([&](sycl::handler &CGH) { - auto Acc = Buf.get_access(CGH); - CGH.parallel_for(Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - Harray[i] = i; - Acc[i] = i; - }); - }); - - Q.submit([&](sycl::handler &CGH) { - CGH.parallel_for(Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (Harray[i] == i) - Harray[i] += 10; - }); - }); - - { - // waiting for all queue operations in urEnqueueMemBufferMap and then - // checking buffer - sycl::host_accessor HostAcc(Buf); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = i; - assert(HostAcc[i] == expected); - } - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - HostAcc[i] += 10; - } - } - - Q.submit([&](sycl::handler &CGH) { - CGH.parallel_for(Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (Harray[i] == (i + 10)) - Harray[i] += 100; - }); - }); - - Q.submit([&](sycl::handler &CGH) { - // waiting for all queue operations in urEnqueueMemUnmap and then - // using buffer - auto Acc = Buf.get_access(CGH); - CGH.parallel_for(Range, [=](sycl::item<1> itemID) { - size_t i = itemID.get_id(0); - if (Acc[i] == (i + 10)) - if (Harray[i] == (i + 110)) { - Harray[i] += 1000; - Acc[i] += 100; - } - }); - }); - Q.wait(); - - // check results - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = i + 1110; - assert(Harray[i] == expected); - } - { - sycl::host_accessor HostAcc(Buf, sycl::read_only); - for (size_t i = 0; i < BUFFER_SIZE; ++i) { - int expected = i + 110; - assert(HostAcc[i] == expected); - } - } - }); -} - -int main(int Argc, const char *Argv[]) { - assert(Argc == 2 && "Invalid number of arguments"); - std::string TestType(Argv[1]); - - sycl::property_list props{ - sycl::property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - sycl::queue Q(props); - - if (TestType == "accessor-usm") { - std::cerr << "RunTest_Accessor_USM" << std::endl; - RunTest_Accessor_USM(Q); - } else if (TestType == "usm-accessor") { - std::cerr << "RunTest_USM_Accessor" << std::endl; - RunTest_USM_Accessor(Q); - } else if (TestType == "mixed") { - std::cerr << "RunTest_Mixed" << std::endl; - RunTest_Mixed(Q); - } else if (TestType == "map-unmap") { - std::cerr << "RunTest_MemBufferMapUnMap" << std::endl; - RunTest_MemBufferMapUnMap(Q); - } else { - assert(0 && "Unsupported test type!"); - } - - std::cout << "The test passed." << std::endl; - return 0; -} From ccdb6ecf820a5ee7d677716090fb34e034fe80a9 Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Tue, 22 Apr 2025 11:22:21 -0400 Subject: [PATCH 12/21] Update unsupp-without-info Fix format Signed-off-by: JackAKirk --- .../test/e2e_test_requirements/no-unsupported-without-info.cpp | 2 +- sycl/test/warnings/warnings_deprecated.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp index 25a69fbdbef7d..852c256456baa 100644 --- a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp +++ b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp @@ -54,7 +54,7 @@ // tests to match the required format and in that case you should just update // (i.e. reduce) the number and the list below. // -// NUMBER-OF-UNSUPPORTED-WITHOUT-INFO: 273 +// NUMBER-OF-UNSUPPORTED-WITHOUT-INFO: 272 // // List of improperly UNSUPPORTED tests. // Remove the CHECK once the test has been properly UNSUPPORTED. diff --git a/sycl/test/warnings/warnings_deprecated.cpp b/sycl/test/warnings/warnings_deprecated.cpp index 7b070582f2e32..ba74956ab99c8 100644 --- a/sycl/test/warnings/warnings_deprecated.cpp +++ b/sycl/test/warnings/warnings_deprecated.cpp @@ -9,6 +9,7 @@ int main() { (void)atomic_64; // expected-warning@+1{{'discard_events' is deprecated: use sycl_ext_oneapi_enqueue_functions instead}} - sycl::property_list props{sycl::ext::oneapi::property::queue::discard_events{}}; + sycl::property_list props{ + sycl::ext::oneapi::property::queue::discard_events{}}; return 0; } From 0a34aa349aad91aa76dd1ee451d71cfae932153d Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Wed, 23 Apr 2025 07:10:14 -0400 Subject: [PATCH 13/21] Fix verifyProps Fix warnings check line Signed-off-by: JackAKirk --- sycl/source/detail/queue_impl.cpp | 6 ++++-- .../e2e_test_requirements/no-unsupported-without-info.cpp | 1 - sycl/test/warnings/warnings_deprecated.cpp | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/sycl/source/detail/queue_impl.cpp b/sycl/source/detail/queue_impl.cpp index 72aec2b6943f5..41a5122711770 100644 --- a/sycl/source/detail/queue_impl.cpp +++ b/sycl/source/detail/queue_impl.cpp @@ -769,10 +769,13 @@ void queue_impl::doUnenqueuedCommandCleanup( void queue_impl::verifyProps(const property_list &Props) const { auto CheckDataLessProperties = [](int PropertyKind) { +#define __SYCL_DATA_LESS_PROP_DEPRECATED_ALIAS(NS_QUALIFIER, PROP_NAME, \ + ENUM_VAL, WARNING) \ + case NS_QUALIFIER::PROP_NAME::getKind(): \ + return true; #define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ case NS_QUALIFIER::PROP_NAME::getKind(): \ return true; -#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) switch (PropertyKind) { #include default: @@ -780,7 +783,6 @@ void queue_impl::verifyProps(const property_list &Props) const { } }; auto CheckPropertiesWithData = [](int PropertyKind) { -#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) #define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) \ case NS_QUALIFIER::PROP_NAME::getKind(): \ return true; diff --git a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp index 852c256456baa..04ba1d17cb1c4 100644 --- a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp +++ b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp @@ -119,7 +119,6 @@ // CHECK-NEXT: DeviceLib/separate_compile_test.cpp // CHECK-NEXT: DeviceLib/std_complex_math_fp64_test.cpp // CHECK-NEXT: DeviceLib/std_complex_math_test.cpp -// CHECK-NEXT: DiscardEvents/discard_events_check_images.cpp // CHECK-NEXT: DiscardEvents/discard_events_using_assert.cpp // CHECK-NEXT: ESIMD/PerformanceTests/BitonicSortK.cpp // CHECK-NEXT: ESIMD/PerformanceTests/BitonicSortKv2.cpp diff --git a/sycl/test/warnings/warnings_deprecated.cpp b/sycl/test/warnings/warnings_deprecated.cpp index ba74956ab99c8..3dbf0d96ccfc3 100644 --- a/sycl/test/warnings/warnings_deprecated.cpp +++ b/sycl/test/warnings/warnings_deprecated.cpp @@ -8,7 +8,7 @@ int main() { sycl::info::device::atomic64 atomic_64; (void)atomic_64; - // expected-warning@+1{{'discard_events' is deprecated: use sycl_ext_oneapi_enqueue_functions instead}} + // expected-warning@+2{{'discard_events' is deprecated: use sycl_ext_oneapi_enqueue_functions instead}} sycl::property_list props{ sycl::ext::oneapi::property::queue::discard_events{}}; return 0; From 24f7fd624216548abaf72a66966579385e73a78d Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Wed, 23 Apr 2025 07:37:16 -0400 Subject: [PATCH 14/21] Update file dir in test Signed-off-by: JackAKirk --- sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp index 04ba1d17cb1c4..dc556cf46b6d9 100644 --- a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp +++ b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp @@ -119,7 +119,7 @@ // CHECK-NEXT: DeviceLib/separate_compile_test.cpp // CHECK-NEXT: DeviceLib/std_complex_math_fp64_test.cpp // CHECK-NEXT: DeviceLib/std_complex_math_test.cpp -// CHECK-NEXT: DiscardEvents/discard_events_using_assert.cpp +// CHECK-NEXT: DeprecatedFeatures/DiscardEvents/discard_events_using_assert.cpp // CHECK-NEXT: ESIMD/PerformanceTests/BitonicSortK.cpp // CHECK-NEXT: ESIMD/PerformanceTests/BitonicSortKv2.cpp // CHECK-NEXT: ESIMD/PerformanceTests/Stencil.cpp From 39f00da28984f406d37e1cc85ddd51f302a09e9c Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Wed, 23 Apr 2025 09:19:43 -0400 Subject: [PATCH 15/21] Move check next to correct place Signed-off-by: JackAKirk --- sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp index dc556cf46b6d9..f1d9b6fb195c2 100644 --- a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp +++ b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp @@ -92,6 +92,7 @@ // CHECK-NEXT: Basic/image/image_accessor_range.cpp // CHECK-NEXT: Basic/kernel_info_attr.cpp // CHECK-NEXT: Basic/submit_time.cpp +// CHECK-NEXT: DeprecatedFeatures/DiscardEvents/discard_events_using_assert.cpp // CHECK-NEXT: DeviceImageDependencies/dynamic.cpp // CHECK-NEXT: DeviceImageDependencies/math_device_lib.cpp // CHECK-NEXT: DeviceImageDependencies/objects.cpp @@ -119,7 +120,6 @@ // CHECK-NEXT: DeviceLib/separate_compile_test.cpp // CHECK-NEXT: DeviceLib/std_complex_math_fp64_test.cpp // CHECK-NEXT: DeviceLib/std_complex_math_test.cpp -// CHECK-NEXT: DeprecatedFeatures/DiscardEvents/discard_events_using_assert.cpp // CHECK-NEXT: ESIMD/PerformanceTests/BitonicSortK.cpp // CHECK-NEXT: ESIMD/PerformanceTests/BitonicSortKv2.cpp // CHECK-NEXT: ESIMD/PerformanceTests/Stencil.cpp From 2f41fca55720f058b8bf678b68b0e809d728cf6e Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Wed, 23 Apr 2025 10:49:39 -0400 Subject: [PATCH 16/21] Add back queuePropertyCheck Signed-off-by: JackAKirk --- sycl/unittests/queue/Properties.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sycl/unittests/queue/Properties.cpp b/sycl/unittests/queue/Properties.cpp index a897081af3b31..af7c6c941ef08 100644 --- a/sycl/unittests/queue/Properties.cpp +++ b/sycl/unittests/queue/Properties.cpp @@ -26,6 +26,8 @@ TEST(QueueProperties, ValidDatalessProperties) { sycl::unittest::UrMock<> Mock; DatalessQueuePropertyCheck(); DatalessQueuePropertyCheck(); + DatalessQueuePropertyCheck< + sycl::ext::oneapi::property::queue::discard_events>(); DatalessQueuePropertyCheck< sycl::ext::oneapi::property::queue::priority_normal>(); DatalessQueuePropertyCheck< From bdb05ac4e7e3cc7e5d5f64e1bde3ab5aa8638031 Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Mon, 12 May 2025 10:00:12 +0100 Subject: [PATCH 17/21] supportsDiscardingPiEvents isn't needed Signed-off-by: JackAKirk --- sycl/source/detail/queue_impl.cpp | 4 ++-- sycl/source/detail/scheduler/commands.cpp | 1 - sycl/source/handler.cpp | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/sycl/source/detail/queue_impl.cpp b/sycl/source/detail/queue_impl.cpp index 01a54347bfdba..0750a042ea2b8 100644 --- a/sycl/source/detail/queue_impl.cpp +++ b/sycl/source/detail/queue_impl.cpp @@ -442,7 +442,7 @@ event queue_impl::submitWithHandler(const std::shared_ptr &Self, }; detail::type_erased_cgfo_ty CGF{L}; - if (!CallerNeedsEvent && supportsDiscardingPiEvents()) { + if (!CallerNeedsEvent) { submit_without_event(CGF, Self, SI, /*CodeLoc*/ {}, /*IsTopCodeLoc*/ true); return createDiscardedEvent(); @@ -471,7 +471,7 @@ event queue_impl::submitMemOpHelper(const std::shared_ptr &Self, // handler rather than by-passing the scheduler. if (MGraph.expired() && Scheduler::areEventsSafeForSchedulerBypass( ExpandedDepEvents, MContext)) { - if (!CallerNeedsEvent && supportsDiscardingPiEvents()) { + if (!CallerNeedsEvent) { NestedCallsTracker tracker; MemOpFunc(MemOpArgs..., getUrEvents(ExpandedDepEvents), /*PiEvent*/ nullptr); diff --git a/sycl/source/detail/scheduler/commands.cpp b/sycl/source/detail/scheduler/commands.cpp index c4eb71e1ed66f..50639b2a23cbe 100644 --- a/sycl/source/detail/scheduler/commands.cpp +++ b/sycl/source/detail/scheduler/commands.cpp @@ -3115,7 +3115,6 @@ ur_result_t ExecCGCommand::enqueueImpQueue() { // marked as not needing an event, e.g. if the user did not ask for one, and // if the queue supports discarded UR event and there are no requirements. bool DiscardUrEvent = MQueue && !MEventNeeded && - MQueue->supportsDiscardingPiEvents() && MCommandGroup->getRequirements().size() == 0; ur_event_handle_t UREvent = nullptr; diff --git a/sycl/source/handler.cpp b/sycl/source/handler.cpp index 1c604405d14eb..58d666372f657 100644 --- a/sycl/source/handler.cpp +++ b/sycl/source/handler.cpp @@ -521,8 +521,7 @@ event handler::finalize() { const detail::EventImplPtr &LastEventImpl = detail::getSyclObjImpl(MLastEvent); - bool DiscardEvent = - !impl->MEventNeeded && MQueue->supportsDiscardingPiEvents(); + bool DiscardEvent = !impl->MEventNeeded; if (DiscardEvent) { // Kernel only uses assert if it's non interop one bool KernelUsesAssert = From e24eec26d67640a658b2cd2aef71e2100d3d9fa2 Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Mon, 12 May 2025 10:11:21 +0100 Subject: [PATCH 18/21] Fix format Signed-off-by: JackAKirk --- sycl/source/detail/scheduler/commands.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sycl/source/detail/scheduler/commands.cpp b/sycl/source/detail/scheduler/commands.cpp index 50639b2a23cbe..a45151fcd08e0 100644 --- a/sycl/source/detail/scheduler/commands.cpp +++ b/sycl/source/detail/scheduler/commands.cpp @@ -3110,12 +3110,11 @@ ur_result_t ExecCGCommand::enqueueImpQueue() { auto RawEvents = getUrEvents(EventImpls); flushCrossQueueDeps(EventImpls, MWorkerQueue); - // We can omit creating a UR event and create a "discarded" event if either - // the queue has the discard property or the command has been explicitly - // marked as not needing an event, e.g. if the user did not ask for one, and - // if the queue supports discarded UR event and there are no requirements. - bool DiscardUrEvent = MQueue && !MEventNeeded && - MCommandGroup->getRequirements().size() == 0; + // We can omit creating a UR event and create a "discarded" event if the + // command has been explicitly marked as not needing an event, e.g. if the + // user did not ask for one, and there are no requirements. + bool DiscardUrEvent = + MQueue && !MEventNeeded && MCommandGroup->getRequirements().size() == 0; ur_event_handle_t UREvent = nullptr; ur_event_handle_t *Event = DiscardUrEvent ? nullptr : &UREvent; From 4af7981ee3c28d42eea27df0ff6dfab2aa0c15b5 Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Mon, 12 May 2025 10:33:05 +0100 Subject: [PATCH 19/21] Fix mistake in merge Signed-off-by: JackAKirk --- sycl/source/detail/queue_impl.hpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/sycl/source/detail/queue_impl.hpp b/sycl/source/detail/queue_impl.hpp index 61ab586fbcaa3..9bcabe21e7e38 100644 --- a/sycl/source/detail/queue_impl.hpp +++ b/sycl/source/detail/queue_impl.hpp @@ -119,13 +119,7 @@ class queue_impl { MNextAvailableQueueID.fetch_add(1, std::memory_order_relaxed)} { verifyProps(PropList); if (has_property()) { - // fallback profiling support. See MFallbackProfiling - if (MDevice->has(aspect::queue_profiling)) { - // When urDeviceGetGlobalTimestamps is not supported, compute the - // profiling time OpenCL version < 2.1 case - if (!getDeviceImplPtr()->isGetDeviceAndHostTimerSupported()) - MFallbackProfiling = true; - } else { + if (!MDevice.has(aspect::queue_profiling)) { throw sycl::exception(make_error_code(errc::feature_not_supported), "Cannot enable profiling, the associated device " "does not have the queue_profiling aspect"); From 9b4a27b5704dce6a3e35482f70b43b67ac8fde96 Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Mon, 12 May 2025 10:58:07 +0100 Subject: [PATCH 20/21] Remove discard_events prop from test Failure due to deprecation warning, duplicate test case not necessary Signed-off-by: JackAKirk --- .../Basic/in_order_queue_status_khr_empty.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/sycl/test-e2e/Basic/in_order_queue_status_khr_empty.cpp b/sycl/test-e2e/Basic/in_order_queue_status_khr_empty.cpp index b0a6601fe9ee8..268ccc124163a 100644 --- a/sycl/test-e2e/Basic/in_order_queue_status_khr_empty.cpp +++ b/sycl/test-e2e/Basic/in_order_queue_status_khr_empty.cpp @@ -66,22 +66,5 @@ int main() { queue Q1{property::queue::in_order()}; TestFunc(Q1); - // Test in-order queue with discard_events property. - sycl::property_list Props{ - property::queue::in_order{}, - sycl::ext::oneapi::property::queue::discard_events{}}; - queue Q2{Props}; - - bool ExceptionThrown = false; - try { - TestFunc(Q2); - } catch (sycl::exception &E) { - ExceptionThrown = true; - } - - // Feature is not supported for OpenCL, exception must be thrown. - if (Q2.get_device().get_backend() == backend::opencl) - return ExceptionThrown ? 0 : -1; - return 0; } From 4e9ecc67a30ce1e7420186863e1e5d655714e57c Mon Sep 17 00:00:00 2001 From: JackAKirk Date: Mon, 12 May 2025 08:54:13 -0400 Subject: [PATCH 21/21] Add back supportsDiscardingPiEvents Turns out EnqueueFunctions submit_without_event still creates events for oo queue, and things break if supportsDiscardingPiEvents isn't used Signed-off-by: JackAKirk --- sycl/source/detail/queue_impl.cpp | 4 ++-- sycl/source/detail/queue_impl.hpp | 3 +++ sycl/source/detail/scheduler/commands.cpp | 5 +++-- sycl/source/handler.cpp | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/sycl/source/detail/queue_impl.cpp b/sycl/source/detail/queue_impl.cpp index 0750a042ea2b8..01a54347bfdba 100644 --- a/sycl/source/detail/queue_impl.cpp +++ b/sycl/source/detail/queue_impl.cpp @@ -442,7 +442,7 @@ event queue_impl::submitWithHandler(const std::shared_ptr &Self, }; detail::type_erased_cgfo_ty CGF{L}; - if (!CallerNeedsEvent) { + if (!CallerNeedsEvent && supportsDiscardingPiEvents()) { submit_without_event(CGF, Self, SI, /*CodeLoc*/ {}, /*IsTopCodeLoc*/ true); return createDiscardedEvent(); @@ -471,7 +471,7 @@ event queue_impl::submitMemOpHelper(const std::shared_ptr &Self, // handler rather than by-passing the scheduler. if (MGraph.expired() && Scheduler::areEventsSafeForSchedulerBypass( ExpandedDepEvents, MContext)) { - if (!CallerNeedsEvent) { + if (!CallerNeedsEvent && supportsDiscardingPiEvents()) { NestedCallsTracker tracker; MemOpFunc(MemOpArgs..., getUrEvents(ExpandedDepEvents), /*PiEvent*/ nullptr); diff --git a/sycl/source/detail/queue_impl.hpp b/sycl/source/detail/queue_impl.hpp index 9bcabe21e7e38..8a0a1476c2ee1 100644 --- a/sycl/source/detail/queue_impl.hpp +++ b/sycl/source/detail/queue_impl.hpp @@ -278,6 +278,9 @@ class queue_impl { /// \return an associated SYCL device. device get_device() const { return createSyclObjFromImpl(MDevice); } + /// \return true if this queue allows for discarded events. + bool supportsDiscardingPiEvents() const { return MIsInorder; } + bool isInOrder() const { return MIsInorder; } /// Queries SYCL queue for information. diff --git a/sycl/source/detail/scheduler/commands.cpp b/sycl/source/detail/scheduler/commands.cpp index a45151fcd08e0..783ce3b1412bb 100644 --- a/sycl/source/detail/scheduler/commands.cpp +++ b/sycl/source/detail/scheduler/commands.cpp @@ -3113,8 +3113,9 @@ ur_result_t ExecCGCommand::enqueueImpQueue() { // We can omit creating a UR event and create a "discarded" event if the // command has been explicitly marked as not needing an event, e.g. if the // user did not ask for one, and there are no requirements. - bool DiscardUrEvent = - MQueue && !MEventNeeded && MCommandGroup->getRequirements().size() == 0; + bool DiscardUrEvent = MQueue && !MEventNeeded && + MQueue->supportsDiscardingPiEvents() && + MCommandGroup->getRequirements().size() == 0; ur_event_handle_t UREvent = nullptr; ur_event_handle_t *Event = DiscardUrEvent ? nullptr : &UREvent; diff --git a/sycl/source/handler.cpp b/sycl/source/handler.cpp index 58d666372f657..1c604405d14eb 100644 --- a/sycl/source/handler.cpp +++ b/sycl/source/handler.cpp @@ -521,7 +521,8 @@ event handler::finalize() { const detail::EventImplPtr &LastEventImpl = detail::getSyclObjImpl(MLastEvent); - bool DiscardEvent = !impl->MEventNeeded; + bool DiscardEvent = + !impl->MEventNeeded && MQueue->supportsDiscardingPiEvents(); if (DiscardEvent) { // Kernel only uses assert if it's non interop one bool KernelUsesAssert =