Skip to content

[SYCL] Simplify secondary queue usage #18642

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: sycl
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ event submit_with_event_impl(const queue &Q, PropertiesT Props,
CommandGroupFunc &&CGF,
const sycl::detail::code_location &CodeLoc) {
return Q.submit_with_event<__SYCL_USE_FALLBACK_ASSERT>(
Props, detail::type_erased_cgfo_ty{CGF}, nullptr, CodeLoc);
Props, detail::type_erased_cgfo_ty{CGF}, CodeLoc);
}
} // namespace detail

Expand Down
2 changes: 0 additions & 2 deletions sycl/include/sycl/handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -456,14 +456,12 @@ class __SYCL_EXPORT handler {
/// is null if no secondary queue is associated with the submission.
/// \param CallerNeedsEvent indicates if the event resulting from this handler
/// is needed by the caller.
#ifndef __INTEL_PREVIEW_BREAKING_CHANGES
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: This was redundant.

// TODO: This function is not used anymore, remove it in the next
// ABI-breaking window.
handler(std::shared_ptr<detail::queue_impl> Queue,
std::shared_ptr<detail::queue_impl> PrimaryQueue,
std::shared_ptr<detail::queue_impl> SecondaryQueue,
bool CallerNeedsEvent);
#endif
__SYCL_DLL_LOCAL handler(std::shared_ptr<detail::queue_impl> Queue,
detail::queue_impl *SecondaryQueue,
bool CallerNeedsEvent);
Expand Down
64 changes: 10 additions & 54 deletions sycl/include/sycl/queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ auto get_native(const SyclObjectT &Obj)
namespace detail {
class queue_impl;

inline event submitAssertCapture(const queue &, event &, queue *,
inline event submitAssertCapture(const queue &, event &,
const detail::code_location &);

// Function to postprocess submitted command
Expand All @@ -87,8 +87,10 @@ class __SYCL_EXPORT SubmissionInfo {
sycl::detail::optional<SubmitPostProcessF> &PostProcessorFunc();
const sycl::detail::optional<SubmitPostProcessF> &PostProcessorFunc() const;

#ifndef __INTEL_PREVIEW_BREAKING_CHANGES
std::shared_ptr<detail::queue_impl> &SecondaryQueue();
const std::shared_ptr<detail::queue_impl> &SecondaryQueue() const;
#endif

ext::oneapi::experimental::event_mode_enum &EventMode();
const ext::oneapi::experimental::event_mode_enum &EventMode() const;
Expand Down Expand Up @@ -434,21 +436,18 @@ class __SYCL_EXPORT queue : public detail::OwnerLessBase<queue> {
/// Submits a command group function object to the queue, in order to be
/// scheduled for execution on the device.
///
/// On a kernel error, this command group function object is then scheduled
/// for execution on a secondary queue.
///
/// \param CGF is a function object containing command group.
/// \param SecondaryQueue is a fallback SYCL queue.
/// \param SecondaryQueue is a fallback SYCL queue. (unused)
/// \param CodeLoc is the code location of the submit call (default argument)
/// \return a SYCL event object, which corresponds to the queue the command
/// group is being enqueued on.
template <typename T>
std::enable_if_t<std::is_invocable_r_v<void, T, handler &>, event> submit(
T CGF, queue &SecondaryQueue,
T CGF, [[maybe_unused]] queue &SecondaryQueue,
const detail::code_location &CodeLoc = detail::code_location::current()) {
return submit_with_event<__SYCL_USE_FALLBACK_ASSERT>(
sycl::ext::oneapi::experimental::empty_properties_t{},
detail::type_erased_cgfo_ty{CGF}, &SecondaryQueue, CodeLoc);
detail::type_erased_cgfo_ty{CGF}, CodeLoc);
}

/// Prevents any commands submitted afterward to this queue from executing
Expand Down Expand Up @@ -3582,7 +3581,7 @@ class __SYCL_EXPORT queue : public detail::OwnerLessBase<queue> {
-> backend_return_t<BackendName, SyclObjectT>;

#if __SYCL_USE_FALLBACK_ASSERT
friend event detail::submitAssertCapture(const queue &, event &, queue *,
friend event detail::submitAssertCapture(const queue &, event &,
const detail::code_location &);
#endif

Expand Down Expand Up @@ -3686,47 +3685,6 @@ class __SYCL_EXPORT queue : public detail::OwnerLessBase<queue> {
const detail::code_location &CodeLoc,
bool IsTopCodeLoc) const;

/// Submits a command group function object to the queue, in order to be
/// scheduled for execution on the device.
///
/// \param Props is a property list with submission properties.
/// \param CGF is a function object containing command group.
/// \param SecondaryQueuePtr is a pointer to the secondary queue.
/// \param CodeLoc is the code location of the submit call (default argument)
/// \return a SYCL event object for the submitted command group.
//
// UseFallBackAssert as template param vs `#if` in function body is necessary
// to prevent ODR-violation between TUs built with different fallback assert
// modes.
template <bool UseFallbackAssert, typename PropertiesT>
event submit_with_event(PropertiesT Props,
const detail::type_erased_cgfo_ty &CGF,
queue *SecondaryQueuePtr,
const detail::code_location &CodeLoc =
detail::code_location::current()) const {
detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
detail::v1::SubmissionInfo SI{};
ProcessSubmitProperties(Props, SI);
if (SecondaryQueuePtr)
SI.SecondaryQueue() = detail::getSyclObjImpl(*SecondaryQueuePtr);
if constexpr (UseFallbackAssert)
SI.PostProcessorFunc() =
[this, &SecondaryQueuePtr,
&TlsCodeLocCapture](bool IsKernel, bool KernelUsesAssert, event &E) {
if (IsKernel && !device_has(aspect::ext_oneapi_native_assert) &&
KernelUsesAssert && !device_has(aspect::accelerator)) {
// __devicelib_assert_fail isn't supported by Device-side Runtime
// Linking against fallback impl of __devicelib_assert_fail is
// performed by program manager class
// Fallback assert isn't supported for FPGA
submitAssertCapture(*this, E, SecondaryQueuePtr,
TlsCodeLocCapture.query());
}
};
return submit_with_event_impl(CGF, SI, TlsCodeLocCapture.query(),
TlsCodeLocCapture.isToplevel());
}

/// Submits a command group function object to the queue, in order to be
/// scheduled for execution on the device.
///
Expand Down Expand Up @@ -3756,7 +3714,7 @@ class __SYCL_EXPORT queue : public detail::OwnerLessBase<queue> {
// Linking against fallback impl of __devicelib_assert_fail is
// performed by program manager class
// Fallback assert isn't supported for FPGA
submitAssertCapture(*this, E, nullptr, TlsCodeLocCapture.query());
submitAssertCapture(*this, E, TlsCodeLocCapture.query());
}
};
return submit_with_event_impl(CGF, SI, TlsCodeLocCapture.query(),
Expand Down Expand Up @@ -3955,15 +3913,13 @@ class AssertInfoCopier;
* Submit copy task for assert failure flag and host-task to check the flag
* \param Event kernel's event to depend on i.e. the event represents the
* kernel to check for assertion failure
* \param SecondaryQueue secondary queue for submit process, null if not used
* \returns host tasks event
*
* This method doesn't belong to queue class to overcome msvc behaviour due to
* which it gets compiled and exported without any integration header and, thus,
* with no proper KernelInfo instance.
*/
event submitAssertCapture(const queue &Self, event &Event,
queue *SecondaryQueue,
const detail::code_location &CodeLoc) {
buffer<detail::AssertHappened, 1> Buffer{1};

Expand Down Expand Up @@ -4019,10 +3975,10 @@ event submitAssertCapture(const queue &Self, event &Event,

CopierEv = Self.submit_with_event<true>(
sycl::ext::oneapi::experimental::empty_properties_t{}, CopierCGF,
SecondaryQueue, CodeLoc);
CodeLoc);
CheckerEv = Self.submit_with_event<true>(
sycl::ext::oneapi::experimental::empty_properties_t{}, CheckerCGF,
SecondaryQueue, CodeLoc);
CodeLoc);

return CheckerEv;
}
Expand Down
8 changes: 1 addition & 7 deletions sycl/source/detail/handler_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ enum class HandlerSubmissionState : std::uint8_t {

class handler_impl {
public:
handler_impl(queue_impl *SubmissionSecondaryQueue, bool EventNeeded)
: MSubmissionSecondaryQueue(SubmissionSecondaryQueue),
MEventNeeded(EventNeeded) {};
handler_impl(bool EventNeeded) : MEventNeeded(EventNeeded) {};

handler_impl(
std::shared_ptr<ext::oneapi::experimental::detail::graph_impl> Graph)
Expand Down Expand Up @@ -67,10 +65,6 @@ class handler_impl {
/// Registers mutually exclusive submission states.
HandlerSubmissionState MSubmissionState = HandlerSubmissionState::NO_STATE;

/// Pointer to the secondary queue implementation. Nullptr if no
/// secondary queue fallback was given in the associated submission.
queue_impl *MSubmissionSecondaryQueue = nullptr;

/// Bool stores information about whether the event resulting from the
/// corresponding work is required.
bool MEventNeeded = true;
Expand Down
24 changes: 6 additions & 18 deletions sycl/source/detail/queue_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,18 +306,18 @@ void queue_impl::addEvent(const detail::EventImplPtr &EventImpl) {

detail::EventImplPtr
queue_impl::submit_impl(const detail::type_erased_cgfo_ty &CGF,
queue_impl *SecondaryQueue, bool CallerNeedsEvent,
const detail::code_location &Loc, bool IsTopCodeLoc,
bool CallerNeedsEvent, const detail::code_location &Loc,
bool IsTopCodeLoc,
const v1::SubmissionInfo &SubmitInfo) {
#ifdef __INTEL_PREVIEW_BREAKING_CHANGES
detail::handler_impl HandlerImplVal(SecondaryQueue, CallerNeedsEvent);
detail::handler_impl HandlerImplVal(CallerNeedsEvent);
detail::handler_impl *HandlerImpl = &HandlerImplVal;
// Inlining `Self` results in a crash when SYCL RT is built using MSVC with
// optimizations enabled. No crash if built using OneAPI.
auto Self = shared_from_this();
handler Handler(HandlerImpl, Self);
#else
handler Handler(shared_from_this(), SecondaryQueue, CallerNeedsEvent);
handler Handler(shared_from_this(), CallerNeedsEvent);
auto &HandlerImpl = detail::getSyclObjImpl(Handler);
#endif

Expand Down Expand Up @@ -399,8 +399,8 @@ queue_impl::submit_impl(const detail::type_erased_cgfo_ty &CGF,
Stream->generateFlushCommand(ServiceCGH);
};
detail::type_erased_cgfo_ty CGF{L};
detail::EventImplPtr FlushEvent = submit_impl(
CGF, SecondaryQueue, /*CallerNeedsEvent*/ true, Loc, IsTopCodeLoc, {});
detail::EventImplPtr FlushEvent =
submit_impl(CGF, /*CallerNeedsEvent*/ true, Loc, IsTopCodeLoc, {});
if (EventImpl)
EventImpl->attachEventToCompleteWeak(FlushEvent);
registerStreamServiceEvent(FlushEvent);
Expand All @@ -409,18 +409,6 @@ queue_impl::submit_impl(const detail::type_erased_cgfo_ty &CGF,
return EventImpl;
}

#ifndef __INTEL_PREVIEW_BREAKING_CHANGES
detail::EventImplPtr
queue_impl::submit_impl(const detail::type_erased_cgfo_ty &CGF,
const std::shared_ptr<queue_impl> & /*PrimaryQueue*/,
const std::shared_ptr<queue_impl> &SecondaryQueue,
bool CallerNeedsEvent, const detail::code_location &Loc,
bool IsTopCodeLoc, const SubmissionInfo &SubmitInfo) {
return submit_impl(CGF, SecondaryQueue.get(), CallerNeedsEvent, Loc,
IsTopCodeLoc, SubmitInfo);
}
#endif

template <typename HandlerFuncT>
event queue_impl::submitWithHandler(const std::vector<event> &DepEvents,
bool CallerNeedsEvent,
Expand Down
39 changes: 5 additions & 34 deletions sycl/source/detail/queue_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ enum QueueOrder { Ordered, OOO };
// Implementation of the submission information storage.
struct SubmissionInfoImpl {
optional<detail::SubmitPostProcessF> MPostProcessorFunc = std::nullopt;
#ifndef __INTEL_PREVIEW_BREAKING_CHANGES
std::shared_ptr<detail::queue_impl> MSecondaryQueue = nullptr;
#endif
ext::oneapi::experimental::event_mode_enum MEventMode =
ext::oneapi::experimental::event_mode_enum::none;
};
Expand Down Expand Up @@ -331,22 +333,16 @@ class queue_impl : public std::enable_shared_from_this<queue_impl> {
/// Submits a command group function object to the queue, in order to be
/// scheduled for execution on the device.
///
/// On a kernel error, this command group function object is then scheduled
/// for execution on a secondary queue.
///
/// \param CGF is a function object containing command group.
/// \param SecondQueue is a shared_ptr to the secondary queue.
/// \param Loc is the code location of the submit call (default argument)
/// \param StoreAdditionalInfo makes additional info be stored in event_impl
/// \return a SYCL event object, which corresponds to the queue the command
/// group is being enqueued on.
event submit(const detail::type_erased_cgfo_ty &CGF,
const std::shared_ptr<queue_impl> &SecondQueue,
const detail::code_location &Loc, bool IsTopCodeLoc,
const SubmitPostProcessF *PostProcess = nullptr) {
event ResEvent;
v1::SubmissionInfo SI{};
SI.SecondaryQueue() = SecondQueue;
if (PostProcess)
SI.PostProcessorFunc() = *PostProcess;
return submit_with_event(CGF, SI, Loc, IsTopCodeLoc);
Expand All @@ -364,18 +360,16 @@ class queue_impl : public std::enable_shared_from_this<queue_impl> {
const v1::SubmissionInfo &SubmitInfo,
const detail::code_location &Loc, bool IsTopCodeLoc) {

detail::EventImplPtr ResEvent =
submit_impl(CGF, SubmitInfo.SecondaryQueue().get(),
/*CallerNeedsEvent=*/true, Loc, IsTopCodeLoc, SubmitInfo);
detail::EventImplPtr ResEvent = submit_impl(CGF, /*CallerNeedsEvent=*/true,
Loc, IsTopCodeLoc, SubmitInfo);
return createSyclObjFromImpl<event>(ResEvent);
}

void submit_without_event(const detail::type_erased_cgfo_ty &CGF,
const v1::SubmissionInfo &SubmitInfo,
const detail::code_location &Loc,
bool IsTopCodeLoc) {
submit_impl(CGF, SubmitInfo.SecondaryQueue().get(),
/*CallerNeedsEvent=*/false, Loc, IsTopCodeLoc, SubmitInfo);
submit_impl(CGF, /*CallerNeedsEvent=*/false, Loc, IsTopCodeLoc, SubmitInfo);
}

/// Performs a blocking wait for the completion of all enqueued tasks in the
Expand Down Expand Up @@ -878,38 +872,15 @@ class queue_impl : public std::enable_shared_from_this<queue_impl> {
PostProcess(IsKernel, KernelUsesAssert, Event);
}

#ifndef __INTEL_PREVIEW_BREAKING_CHANGES
/// Performs command group submission to the queue.
///
/// \param CGF is a function object containing command group.
/// \param PrimaryQueue is a pointer to the primary queue. This may be the
/// same as this.
/// \param SecondaryQueue is a pointer to the secondary queue. This may be the
/// same as this.
/// \param CallerNeedsEvent is a boolean indicating whether the event is
/// required by the user after the call.
/// \param Loc is the code location of the submit call (default argument)
/// \param SubmitInfo is additional optional information for the submission.
/// \return a SYCL event representing submitted command group.
detail::EventImplPtr
submit_impl(const detail::type_erased_cgfo_ty &CGF,
const std::shared_ptr<queue_impl> &PrimaryQueue,
const std::shared_ptr<queue_impl> &SecondaryQueue,
bool CallerNeedsEvent, const detail::code_location &Loc,
bool IsTopCodeLoc, const SubmissionInfo &SubmitInfo);
#endif

/// Performs command group submission to the queue.
///
/// \param CGF is a function object containing command group.
/// \param SecondaryQueue is a pointer to the secondary queue.
/// \param CallerNeedsEvent is a boolean indicating whether the event is
/// required by the user after the call.
/// \param Loc is the code location of the submit call (default argument)
/// \param SubmitInfo is additional optional information for the submission.
/// \return a SYCL event representing submitted command group.
detail::EventImplPtr submit_impl(const detail::type_erased_cgfo_ty &CGF,
queue_impl *SecondaryQueue,
bool CallerNeedsEvent,
const detail::code_location &Loc,
bool IsTopCodeLoc,
Expand Down
8 changes: 0 additions & 8 deletions sycl/source/detail/scheduler/scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,14 +591,6 @@ class Scheduler {

void cleanupCommand(Command *Cmd, bool AllowUnsubmitted = false);

/// Reschedules the command passed using Queue provided.
///
/// This can lead to rescheduling of all dependent commands. This can be
/// used when the user provides a "secondary" queue to the submit method
/// which may be used when the command fails to enqueue/execute in the
/// primary queue.
void rescheduleCommand(Command *Cmd, const QueueImplPtr &Queue);

/// \return a pointer to the corresponding memory object record for the
/// SYCL memory object provided, or nullptr if it does not exist.
MemObjRecord *getMemObjRecord(SYCLMemObjI *MemObject);
Expand Down
Loading
Loading