17 #include <shared_mutex>
18 #include <type_traits>
22 #ifdef ALPAKA_ACC_SYCL_ENABLED
24 # include <sycl/sycl.hpp>
28 template<
typename T,
typename =
void>
29 inline constexpr
auto is_sycl_task =
false;
32 inline constexpr
auto is_sycl_task<T, std::void_t<decltype(T::is_sycl_task)>> =
true;
34 template<
typename T,
typename =
void>
35 inline constexpr
auto is_sycl_kernel =
false;
38 inline constexpr
auto is_sycl_kernel<T, std::void_t<decltype(T::is_sycl_kernel)>> =
true;
40 class QueueGenericSyclImpl
43 QueueGenericSyclImpl(sycl::context context, sycl::device device)
47 {sycl::property::queue::enable_profiling{}, sycl::property::queue::in_order{}}}
52 QueueGenericSyclImpl(QueueGenericSyclImpl
const& other) =
delete;
53 auto operator=(QueueGenericSyclImpl
const& rhs) -> QueueGenericSyclImpl& =
delete;
55 QueueGenericSyclImpl(QueueGenericSyclImpl&& other) noexcept =
delete;
56 auto operator=(QueueGenericSyclImpl&& rhs) noexcept -> QueueGenericSyclImpl& =
delete;
58 ~QueueGenericSyclImpl()
62 m_queue.wait_and_throw();
64 catch(sycl::exception
const& err)
66 std::cerr <<
"Caught SYCL exception while destructing a SYCL queue: " << err.what() <<
" ("
67 << err.code() <<
')' << std::endl;
69 catch(std::exception
const& err)
71 std::cerr <<
"The following runtime error(s) occured while destructing a SYCL queue:" << err.what()
77 auto clean_dependencies() ->
void
81 auto const old_end =
std::end(m_dependencies);
82 auto const new_end = std::remove_if(
86 return ev.get_info<sycl::info::event::command_execution_status>()
87 == sycl::info::event_command_status::complete;
90 m_dependencies.erase(new_end, old_end);
93 auto register_dependency(sycl::event event) ->
void
95 std::lock_guard<std::shared_mutex> lock{m_mutex};
98 m_dependencies.push_back(event);
101 auto empty() const ->
bool
103 std::shared_lock<std::shared_mutex> lock{m_mutex};
104 return m_last_event.get_info<sycl::info::event::command_execution_status>()
105 == sycl::info::event_command_status::complete;
111 m_queue.wait_and_throw();
114 auto get_last_event() const -> sycl::event
116 std::shared_lock<std::shared_mutex> lock{m_mutex};
120 template<
bool TBlocking,
typename TTask>
121 auto enqueue(TTask
const& task) ->
void
124 std::lock_guard<std::shared_mutex> lock{m_mutex};
126 clean_dependencies();
129 if constexpr(is_sycl_task<TTask> && !is_sycl_kernel<TTask>)
131 m_last_event = task(m_queue, m_dependencies);
135 m_last_event = m_queue.submit(
136 [
this, &task](sycl::handler& cgh)
138 if(!m_dependencies.empty())
139 cgh.depends_on(m_dependencies);
141 if constexpr(is_sycl_kernel<TTask>)
148 m_dependencies.clear();
151 if constexpr(TBlocking)
160 std::vector<sycl::event> m_dependencies;
161 sycl::event m_last_event;
162 std::shared_mutex
mutable m_mutex;
168 template<
typename TDev,
bool TBlocking>
169 class QueueGenericSyclBase
172 QueueGenericSyclBase(TDev
const& dev)
174 , m_spQueueImpl{std::make_shared<detail::QueueGenericSyclImpl>(
178 m_dev.m_impl->register_queue(m_spQueueImpl);
181 friend auto operator==(QueueGenericSyclBase
const& lhs, QueueGenericSyclBase
const& rhs) ->
bool
183 return (lhs.m_dev == rhs.m_dev) && (lhs.m_spQueueImpl == rhs.m_spQueueImpl);
186 friend auto operator!=(QueueGenericSyclBase
const& lhs, QueueGenericSyclBase
const& rhs) ->
bool
188 return !(lhs == rhs);
193 return m_spQueueImpl->getNativeHandle();
197 std::shared_ptr<detail::QueueGenericSyclImpl> m_spQueueImpl;
203 template<
typename TDev>
204 class EventGenericSycl;
210 template<
typename TDev,
bool TBlocking>
211 struct DevType<detail::QueueGenericSyclBase<TDev, TBlocking>>
217 template<
typename TDev,
bool TBlocking>
218 struct GetDev<detail::QueueGenericSyclBase<TDev, TBlocking>>
220 static auto getDev(detail::QueueGenericSyclBase<TDev, TBlocking>
const& queue)
228 template<
typename TDev,
bool TBlocking>
229 struct EventType<detail::QueueGenericSyclBase<TDev, TBlocking>>
231 using type = EventGenericSycl<TDev>;
235 template<
typename TDev,
bool TBlocking,
typename TTask>
236 struct Enqueue<detail::QueueGenericSyclBase<TDev, TBlocking>, TTask>
238 static auto enqueue(detail::QueueGenericSyclBase<TDev, TBlocking>& queue, TTask
const& task) ->
void
241 queue.m_spQueueImpl->template enqueue<TBlocking>(task);
246 template<
typename TDev,
bool TBlocking>
247 struct Empty<detail::QueueGenericSyclBase<TDev, TBlocking>>
249 static auto empty(detail::QueueGenericSyclBase<TDev, TBlocking>
const& queue) ->
bool
252 return queue.m_spQueueImpl->empty();
260 template<
typename TDev,
bool TBlocking>
261 struct CurrentThreadWaitFor<detail::QueueGenericSyclBase<TDev, TBlocking>>
263 static auto currentThreadWaitFor(detail::QueueGenericSyclBase<TDev, TBlocking>
const& queue) ->
void
266 queue.m_spQueueImpl->wait();
271 template<
typename TDev,
bool TBlocking>
272 struct NativeHandle<detail::QueueGenericSyclBase<TDev, TBlocking>>
274 [[nodiscard]]
static auto getNativeHandle(detail::QueueGenericSyclBase<TDev, TBlocking>
const& queue)
276 return queue.getNativeHandle();
#define ALPAKA_DEBUG_MINIMAL_LOG_SCOPE
ALPAKA_FN_HOST auto end(TView &view) -> Iterator< TView >
ALPAKA_FN_HOST auto begin(TView &view) -> Iterator< TView >
The alpaka accelerator library.
constexpr ALPAKA_FN_HOST_ACC bool operator==(Complex< T > const &lhs, Complex< T > const &rhs)
Equality of two complex numbers.
decltype(getNativeHandle(std::declval< TImpl >())) NativeHandle
Alias to the type of the native handle.
ALPAKA_FN_HOST auto getDev(T const &t)
ALPAKA_FN_HOST auto getNativeHandle(TImpl const &impl)
Get the native handle of the alpaka object. It will return the alpaka object handle if there is any,...
ALPAKA_FN_HOST auto empty(TQueue const &queue) -> bool
Tests if the queue is empty (all ops in the given queue have been completed).
ALPAKA_FN_HOST auto enqueue(TQueue &queue, TTask &&task) -> void
Queues the given task in the given queue.
ALPAKA_FN_HOST auto wait(TAwaited const &awaited) -> void
Waits the thread for the completion of the given awaited action to complete.
constexpr ALPAKA_FN_HOST_ACC bool operator!=(Complex< T > const &lhs, Complex< T > const &rhs)
Inequality of two complex numbers.
static auto getNativeHandle(TImpl const &)