From 61b63255f1f25853d0af260ed7c0e04609e0466f Mon Sep 17 00:00:00 2001 From: Jason Burmark Date: Tue, 26 May 2026 16:26:46 -0700 Subject: [PATCH 1/6] Add basic implementation for SyclEvent This uses an empty submit to get an event as there is no way to get an event from a queue without doing some kind of work, hopefully this gives a real useful event. Also add an explicit constructor from a sycl::event to allow the possibility of wrapping an event created outside of SyclEvent. --- include/camp/resource/sycl.hpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/include/camp/resource/sycl.hpp b/include/camp/resource/sycl.hpp index 4206f29..a7b37f9 100644 --- a/include/camp/resource/sycl.hpp +++ b/include/camp/resource/sycl.hpp @@ -34,16 +34,28 @@ namespace resources class SyclEvent { public: - // TODO: make this actually work - SyclEvent(sycl::queue& CAMP_UNUSED_ARG(qu)) { m_event = sycl::event(); } + explicit SyclEvent(sycl::event e) + : m_event(std::move(e)) + {} + + // TODO: see what overhead an empty submit has + SyclEvent(sycl::queue& qu) + : m_event(qu.submit([&](::sycl::handler& CAMP_UNUSED_ARG(h)) {})) + {} SyclEvent(Sycl& res); - bool check() const { return true; } + bool check() const + { + return m_event.get_info() + == sycl::info::event_command_status::complete; + } + + void wait() const { m_event.wait(); } - void wait() const { getSyclEvent_t().wait(); } + sycl::event& getSyclEvent_t() { return m_event; } - sycl::event getSyclEvent_t() const { return m_event; } + sycl::event const& getSyclEvent_t() const { return m_event; } private: sycl::event m_event; @@ -356,7 +368,7 @@ namespace resources inline SyclEvent::SyclEvent(Sycl &res) : SyclEvent(res.get_queue()) - { } + {} } // namespace v1 From 640fc7f7e2ad1855644e595785e8c6da39080e1f Mon Sep 17 00:00:00 2001 From: Jason Burmark Date: Wed, 27 May 2026 10:03:45 -0700 Subject: [PATCH 2/6] Fix SyclEvent wait Make a copy of event to work around needing a non-const event. --- include/camp/resource/sycl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/camp/resource/sycl.hpp b/include/camp/resource/sycl.hpp index a7b37f9..2644797 100644 --- a/include/camp/resource/sycl.hpp +++ b/include/camp/resource/sycl.hpp @@ -51,7 +51,7 @@ namespace resources == sycl::info::event_command_status::complete; } - void wait() const { m_event.wait(); } + void wait() const { sycl::event(m_event).wait(); } sycl::event& getSyclEvent_t() { return m_event; } From a7240e9be96ac5a2ba546dbe4476b9670269ab06 Mon Sep 17 00:00:00 2001 From: Jason Burmark Date: Wed, 27 May 2026 10:23:07 -0700 Subject: [PATCH 3/6] Implement Sycl::wait_for Implemented via an empty submit that depends on the event. --- include/camp/resource/sycl.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/camp/resource/sycl.hpp b/include/camp/resource/sycl.hpp index 2644797..7e5ce57 100644 --- a/include/camp/resource/sycl.hpp +++ b/include/camp/resource/sycl.hpp @@ -277,7 +277,9 @@ namespace resources { auto* sycl_event = e->try_get(); if (sycl_event) { - (sycl_event->getSyclEvent_t()).wait(); + qu.submit([&](::sycl::handler& h) { + h.depends_on(sycl_event->getSyclEvent_t()); + }); } else { e->wait(); } From 875c63492f651785c843950bbe51f86b1dad014e Mon Sep 17 00:00:00 2001 From: Jason Burmark Date: Wed, 27 May 2026 10:29:46 -0700 Subject: [PATCH 4/6] Add test for event wait and check --- test/resource.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/test/resource.cpp b/test/resource.cpp index 55241a0..de134d6 100644 --- a/test/resource.cpp +++ b/test/resource.cpp @@ -658,6 +658,63 @@ TEST(CampResource, Wait) #endif } +template +void test_event_wait() +{ + auto r = Res(); + const auto typed_event = r.get_event(); + const Event event = r.get_event_erased(); + typed_event.wait(); + event.wait(); +} + +// +TEST(CampEvent, Wait) +{ + test_event_wait(); +#ifdef CAMP_HAVE_CUDA + test_event_wait(); +#endif +#ifdef CAMP_HAVE_HIP + test_event_wait(); +#endif +#ifdef CAMP_HAVE_OMP_OFFLOAD + test_event_wait(); +#endif +#ifdef CAMP_HAVE_SYCL + test_event_wait(); +#endif +} + +template +void test_event_check() +{ + auto r = Res(); + const auto typed_event = r.get_event(); + const Event event = r.get_event_erased(); + // checking in a loop should always eventually return true + while (!typed_event.check()) {} + while (!event.check()) {} +} + +// +TEST(CampEvent, Check) +{ + test_event_check(); +#ifdef CAMP_HAVE_CUDA + test_event_check(); +#endif +#ifdef CAMP_HAVE_HIP + test_event_check(); +#endif +#ifdef CAMP_HAVE_OMP_OFFLOAD + test_event_check(); +#endif +#ifdef CAMP_HAVE_SYCL + test_event_check(); +#endif +} + template void test_concrete_resource_trait() { From 525ce408020cb68fc01553fbe0c3c2c39eca9511 Mon Sep 17 00:00:00 2001 From: Jason Burmark Date: Wed, 27 May 2026 11:18:16 -0700 Subject: [PATCH 5/6] Disallow SyclEvent with out of order queue --- include/camp/resource/sycl.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/camp/resource/sycl.hpp b/include/camp/resource/sycl.hpp index 7e5ce57..7e6ebb3 100644 --- a/include/camp/resource/sycl.hpp +++ b/include/camp/resource/sycl.hpp @@ -40,8 +40,12 @@ namespace resources // TODO: see what overhead an empty submit has SyclEvent(sycl::queue& qu) - : m_event(qu.submit([&](::sycl::handler& CAMP_UNUSED_ARG(h)) {})) - {} + { + if (!qu.is_in_order()) { + ::camp::throw_re("Queue is not in_order."); + } + m_event = qu.submit([&](::sycl::handler& CAMP_UNUSED_ARG(h)) {}); + } SyclEvent(Sycl& res); From 5e5f968124cd1f93220f5f38f4789a4792a10996 Mon Sep 17 00:00:00 2001 From: Jason Burmark Date: Thu, 28 May 2026 11:44:12 -0700 Subject: [PATCH 6/6] Use mutable to avoid copy in SyclEvent::wait --- include/camp/resource/sycl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/camp/resource/sycl.hpp b/include/camp/resource/sycl.hpp index 7e6ebb3..90dc074 100644 --- a/include/camp/resource/sycl.hpp +++ b/include/camp/resource/sycl.hpp @@ -55,14 +55,14 @@ namespace resources == sycl::info::event_command_status::complete; } - void wait() const { sycl::event(m_event).wait(); } + void wait() const { m_event.wait(); } // sycl::event::wait is non-const sycl::event& getSyclEvent_t() { return m_event; } sycl::event const& getSyclEvent_t() const { return m_event; } private: - sycl::event m_event; + mutable sycl::event m_event; // mutable as use non-const member function }; class Sycl