kokkos-utils 0.0.4
 
Loading...
Searching...
No Matches
Manager.hpp
Go to the documentation of this file.
1#ifndef KOKKOS_UTILS_CALLBACKS_MANAGER_HPP
2#define KOKKOS_UTILS_CALLBACKS_MANAGER_HPP
3
4#include <atomic>
5#include <list>
6#include <ranges>
7
10
12{
13
14namespace impl
15{
16
29{
30 virtual ~ListenerConceptBase() = default;
31};
32
33template <Event EventType>
35{
36 virtual ~ListenerConceptCallOperator() = default;
37
38 virtual void operator()(const EventType& event) const = 0;
39};
40
41template <typename...>
43
44template <typename Callable>
46{
47 template <typename T> requires std::same_as<std::remove_cvref_t<T>, Callable>
48 explicit ListenerModelBase(T&& callable_) : callable(std::forward<T>(callable_)) {}
49
50 Callable callable;
51};
52
53template <Event EventType, typename ListenerModel>
55{
56 void operator()(const EventType& event) const override
57 {
58 // Distinguish between a callable object that is a function object and one that is a shared pointer.
59 if constexpr (std::is_invocable_v<decltype(static_cast<const ListenerModel*>(this)->callable), const EventType&>) {
60 static_cast<const ListenerModel*>(this)->callable.operator()(event);
61 } else {
62 static_cast<const ListenerModel*>(this)->callable->operator()(event);
63 }
64 };
65};
66
67template <typename Callable, Event... EventTypes>
68struct ListenerModel<Callable, EventTypes...>
69 : public ListenerModelCallOperator<EventTypes, ListenerModel<Callable, EventTypes...>>...,
70 public ListenerModelBase<Callable>
71{
72 using event_type_list_t = Kokkos::Impl::type_list<EventTypes...>;
73
75};
76
77template <typename Callable, Event... EventTypes>
78struct ListenerModel<Callable, Kokkos::Impl::type_list<EventTypes...>>
79 : public ListenerModel<Callable, EventTypes...>
80{
81 using event_type_list_t = Kokkos::Impl::type_list<EventTypes...>;
82
83 using ListenerModel<Callable, EventTypes...>::ListenerModel;
84};
85
87template <Event EventType>
89{
90 using type = std::list<const ListenerConceptCallOperator<EventType>*>;
91};
92
99>;
101
102} // namespace impl
103
141{
142public:
143 using listener_list_t = std::list<std::unique_ptr<impl::ListenerConceptBase>>;
144 using listener_list_const_iter_t = typename listener_list_t::const_iterator;
146
147public:
148 Manager(const Manager&) = delete;
149 Manager& operator=(const Manager&) = delete;
150
152
153protected:
158 Manager() : context_callbacks(Kokkos::Tools::Experimental::get_callbacks()) {}
159
160public:
161 static void initialize() { if(singleton == nullptr) singleton = new Manager(); }
162 static void finalize() { if(singleton != nullptr) { delete singleton; singleton = nullptr; }}
163
164 static bool is_initialized() { return singleton != nullptr; }
165
166 static Manager& get_instance() { return *singleton; }
167
173 template <Listener Callable>
174 static listener_list_const_iter_t register_listener(std::shared_ptr<Callable> callable)
175 {
176 using event_type_list_t = listener_event_type_list_t<Callable>;
177 using listener_model_t = impl::ListenerModel<std::shared_ptr<Callable>, event_type_list_t>;
178 return register_listener_impl<listener_model_t>(std::move(callable));
179 }
180
187 template <typename T> requires Listener<std::remove_cvref_t<T>>
189 {
190 using event_type_list_t = listener_event_type_list_t<std::remove_cvref_t<T>>;
191 using listener_model_t = impl::ListenerModel<std::remove_cvref_t<T>, event_type_list_t>;
192 return register_listener_impl<listener_model_t>(std::forward<T>(callable));
193 }
194
196 template <Listener Callable>
197 static void unregister_listener(const Callable* const callable)
198 {
199 using event_type_list_t = listener_event_type_list_t<Callable>;
200
201 using listener_model_t = impl::ListenerModel<std::shared_ptr<Callable>, event_type_list_t>;
202
204
205 const auto iter = std::ranges::find_if(
206 listeners,
207 [&] (const std::unique_ptr<impl::ListenerConceptBase>& listener)
208 {
209 auto* const listener_ptr = dynamic_cast<listener_model_t*>(listener.get());
210 return listener_ptr == nullptr ? false : listener_ptr->callable.get() == callable;
211 }
212 );
213
216 get<Kokkos::utils::impl::type_list_index_v<EventType, EventTypeList>>(get_instance().registered_callbacks).remove(
217 dynamic_cast<const impl::ListenerConceptCallOperator<EventType>*>(iter->get())
218 );
219 }
220 });
221
222 listeners.erase(iter);
223
225 }
226
228 {
230 get<Kokkos::utils::impl::type_list_index_v<EventType, EventTypeList>>(get_instance().registered_callbacks).remove(
231 dynamic_cast<const impl::ListenerConceptCallOperator<EventType>*>(iter->get())
232 );
233 });
234
235 get_instance().listeners.erase(iter);
236
238 }
239
241 template <Event EventType>
242 void dispatch(const EventType& event) const {
243 for (const auto& listener: this->listeners) {
244 if (const auto* const callable = dynamic_cast<const impl::ListenerConceptCallOperator<EventType>*>(listener.get()); callable != nullptr) {
245 callable->operator()(event);
246 }
247 }
248 }
249
251 auto get_next_event_id() noexcept {
252 return next_event_id.fetch_add(1, std::memory_order_relaxed);
253 }
254
256 auto get_next_section_id() noexcept {
257 return next_section_id.fetch_add(1, std::memory_order_relaxed);
258 }
259
260private:
266 Kokkos::Tools::Experimental::set_callbacks(context_callbacks);
267 }
268
269 template <typename ListenerModelType, typename CallableType>
271 {
272 using event_type_list_t = typename ListenerModelType::event_type_list_t;
273
275
277 const auto iter = listeners.insert(
278 listeners.end(), std::make_unique<ListenerModelType>(std::forward<CallableType>(callable))
279 );
280
285 get<Kokkos::utils::impl::type_list_index_v<EventType, EventTypeList>>(get_instance().registered_callbacks).push_back(
286 dynamic_cast<const impl::ListenerConceptCallOperator<EventType>*>(iter->get())
287 );
288 }
289 });
290
292
293 return iter;
294 }
295
307
308 template <Event EventType>
310 {
312 get<Kokkos::utils::impl::type_list_index_v<EventType, EventTypeList>>(registered_callbacks).empty()
315 );
316 }
317
320 template <Event EventType>
322 {
323 return [] <typename... Args>(Args... args) -> void {
324 EventType event{args...};
325 get_instance().dispatch(event);
326 };
327 }
328
329 template <BeginEvent EventType>
331 {
332 return [] (const char* name, const uint32_t dev_id, EventTraits::event_id_t* event_id) -> void
333 {
334 EventType event{ .name = name, .dev_id = dev_id, .event_id = *event_id };
335 get_instance().dispatch(event);
336 *event_id = event.event_id;
337 };
338 }
339
340 template <DataEvent EventType>
342 {
343 return [] (Kokkos_Profiling_SpaceHandle kpsh, const char* name, const void* ptr, uint64_t size) -> void
344 {
345 EventType event{ .alloc = { .kpsh = kpsh, .name = name, .ptr = ptr, .size = size } };
346 get_instance().dispatch(event);
347 };
348 }
349
350 template <Event EventType> requires std::same_as<EventType, BeginDeepCopyEvent>
352 {
353 return [] (Kokkos_Profiling_SpaceHandle dst_kpsh, const char* dst_name, const void* dst_ptr,
354 Kokkos_Profiling_SpaceHandle src_kpsh, const char* src_name, const void* src_ptr, uint64_t size) -> void
355 {
356 EventType event{
357 .dst = { .kpsh = dst_kpsh, .name = dst_name, .ptr = dst_ptr, .size = size },
358 .src = { .kpsh = src_kpsh, .name = src_name, .ptr = src_ptr, .size = size }
359 };
360 get_instance().dispatch(event);
361 };
362 }
363
364 template <Event EventType> requires std::same_as<EventType, CreateProfileSectionEvent>
366 {
367 return [] (const char* name, uint32_t* section_id) -> void
368 {
369 EventType event{ .name = name, .section_id = *section_id };
370 get_instance().dispatch(event);
371 *section_id = event.section_id;
372 };
373 }
374
379 template <Event EventType>
380 void dispatch(EventType& event)
381 {
383
385 }
386
388 template <Event EventType>
389 void dispatch_context_callback(EventType& event)
390 {
392
393 if (context_callback) {
394 dispatch_context_callback_for_event_type_impl(context_callback, event);
395 } else {
397 }
398 }
399
400 template <typename ContextCallbackType, BeginEvent EventType>
401 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, EventType& event) {
402 context_callback(event.name.c_str(), event.dev_id, &event.event_id);
403 }
404
405 template <typename ContextCallbackType, EndEvent EventType>
406 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const EventType& event) {
407 context_callback(event.event_id);
408 }
409
410 template <typename ContextCallbackType, DataEvent EventType>
411 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const EventType& event) {
412 context_callback(event.alloc.kpsh, event.alloc.name.c_str(), event.alloc.ptr, event.alloc.size);
413 }
414
415 template <typename ContextCallbackType>
416 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const BeginDeepCopyEvent& event) {
417 context_callback(event.dst.kpsh, event.dst.name.c_str(), event.dst.ptr,
418 event.src.kpsh, event.src.name.c_str(), event.src.ptr, event.src.size);
419 }
420
421 template <typename ContextCallbackType>
422 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const EndDeepCopyEvent& /* event */) {
423 context_callback();
424 }
425
426 template <typename ContextCallbackType>
427 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, CreateProfileSectionEvent& event) {
428 context_callback(event.name.c_str(), &event.section_id);
429 }
430
431 template <typename ContextCallbackType, ProfileSectionManipulationEvent EventType>
432 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const EventType& event) {
433 context_callback(event.section_id);
434 }
435
436 template <typename ContextCallbackType>
437 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const PushRegionEvent& event) {
438 context_callback(event.name.c_str());
439 }
440
441 template <typename ContextCallbackType>
442 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const PopRegionEvent& /* event */) {
443 context_callback();
444 }
445
446 template <typename ContextCallbackType>
447 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const ProfileEvent& event) {
448 context_callback(event.name.c_str());
449 }
450
451 template <Event EventType>
452 void increment_id_if_needed_for_event_type_impl(EventType& /* event */) {}
453
454 template <BeginEvent EventType>
456 event.event_id = this->get_next_event_id();
457 }
458
462
463 template <Event EventType>
464 void dispatch_registered_callbacks(const EventType& event) const
465 {
467 listener->operator()(event);
468 }
469 }
470
471private:
473
475
476 static inline Manager* singleton = nullptr;
477
478 Kokkos::Tools::Experimental::EventSet context_callbacks {};
479
480 std::atomic<EventTraits::event_id_t> next_event_id{0};
481 std::atomic<uint32_t> next_section_id{0};
482};
483
485template <Event EventType>
486void dispatch(const EventType& event) {
489}
490
495
496inline auto get_next_section_id() noexcept {
498}
499
500} // namespace Kokkos::utils::callbacks
501
502#endif // KOKKOS_UTILS_CALLBACKS_MANAGER_HPP
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, const EndDeepCopyEvent &)
Definition Manager.hpp:422
void set_dispatching_callback_impl() const
Definition Manager.hpp:309
std::list< std::unique_ptr< impl::ListenerConceptBase > > listener_list_t
Definition Manager.hpp:143
static void unregister_listener(const Callable *const callable)
Unregister a callable object as a listener.
Definition Manager.hpp:197
static Manager & get_instance()
Definition Manager.hpp:166
void dispatch_registered_callbacks(const EventType &event) const
Definition Manager.hpp:464
static auto create_dispatching_callback_for_event_type_impl()
Definition Manager.hpp:365
void reset_context_callbacks() const
Uses Kokkos::Tools::Experimental::set_callbacks to restore the Kokkos callback function pointers to t...
Definition Manager.hpp:265
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, const ProfileEvent &event)
Definition Manager.hpp:447
Manager(const Manager &)=delete
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, const PushRegionEvent &event)
Definition Manager.hpp:437
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, CreateProfileSectionEvent &event)
Definition Manager.hpp:427
void dispatch_context_callback(EventType &event)
Dispatch the event to the context callback, if any is set in Kokkos.
Definition Manager.hpp:389
static listener_list_const_iter_t register_listener(T &&callable)
Definition Manager.hpp:188
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, EventType &event)
Definition Manager.hpp:401
listener_call_opr_list_tuple_t registered_callbacks
Definition Manager.hpp:472
auto get_next_event_id() noexcept
Get the next available event ID.
Definition Manager.hpp:251
void dispatch(const EventType &event) const
Dispatch the event to all registered listeners that can handle it.
Definition Manager.hpp:242
std::atomic< uint32_t > next_section_id
Definition Manager.hpp:481
Manager()
Constructor. Retrieves and stores the Kokkos::Tools::Experimental::EventSet containing the Kokkos cal...
Definition Manager.hpp:158
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, const BeginDeepCopyEvent &event)
Definition Manager.hpp:416
void set_dispatching_callbacks() const
Uses the setters Kokkos::Tools::Experimental::set_<event_type_name>_callback to set the Kokkos callba...
Definition Manager.hpp:301
std::atomic< EventTraits::event_id_t > next_event_id
Definition Manager.hpp:480
void dispatch(EventType &event)
Dispatch first the context callback, if any is set in Kokkos, and then sequentially the registered ca...
Definition Manager.hpp:380
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, const PopRegionEvent &)
Definition Manager.hpp:442
void increment_id_if_needed_for_event_type_impl(CreateProfileSectionEvent &event)
Definition Manager.hpp:459
impl::listener_call_opr_list_tuple_t listener_call_opr_list_tuple_t
Definition Manager.hpp:145
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, const EventType &event)
Definition Manager.hpp:406
static auto create_dispatching_callback_for_event_type_impl()
Definition Manager.hpp:321
void increment_id_if_needed_for_event_type_impl(EventType &event)
Definition Manager.hpp:455
typename listener_list_t::const_iterator listener_list_const_iter_t
Definition Manager.hpp:144
Manager & operator=(const Manager &)=delete
static void unregister_listener(const listener_list_const_iter_t &iter)
Definition Manager.hpp:227
void increment_id_if_needed_for_event_type_impl(EventType &)
Definition Manager.hpp:452
static listener_list_const_iter_t register_listener_impl(CallableType &&callable)
Definition Manager.hpp:270
Kokkos::Tools::Experimental::EventSet context_callbacks
Definition Manager.hpp:478
static auto create_dispatching_callback_for_event_type_impl()
Definition Manager.hpp:351
auto get_next_section_id() noexcept
Get the next available section ID.
Definition Manager.hpp:256
static listener_list_const_iter_t register_listener(std::shared_ptr< Callable > callable)
Register a callable object, passed as a shared pointer, as a listener.
Definition Manager.hpp:174
Kokkos::utils::impl::type_list_to_tuple_t< Kokkos::utils::impl::transform_type_list_t< ListOfListenerCallOprPerEventTypeTransformer, EventTypeList > > listener_call_opr_list_tuple_t
Type of container used by Kokkos::utils::callbacks::Manager to store pointers to the registered liste...
Definition Manager.hpp:97
auto get_next_event_id() noexcept
If the Manager is initialized, return Manager::get_next_event_id. Otherwise, return EventTraits::inva...
Definition Manager.hpp:492
typename impl::ListenerEventTypeList< Callable >::type listener_event_type_list_t
Type list holding the event types that Callable can be a listener for.
Definition Listener.hpp:72
auto get_next_section_id() noexcept
Definition Manager.hpp:496
void dispatch(const EventType &event)
If the Manager is initialized, call Manager::dispatch with event.
Definition Manager.hpp:486
auto get_callback_from_eventset(const Kokkos::Tools::Experimental::EventSet &event_set)
auto get_callback_setter()
Get the setter function of a Kokkos profiling callback corresponding to EventType.
constexpr bool type_list_contains_v
Definition type_list.hpp:73
constexpr void for_each(Callable callable)
Calls the instantiation of the call operator of a callable object for each type in a Kokkos::Impl::ty...
typename TransformTypeList< TransformerType, T >::type transform_type_list_t
typename TypeListToTuple< T >::type type_list_to_tuple_t
constexpr size_t type_list_index_v
Kokkos_Profiling_SpaceHandle kpsh
Definition Events.hpp:110
Begin-deep-copy event associated with Kokkos::Tools::Experimental::EventSet::begin_deep_copy.
Definition Events.hpp:136
Create-profile-section event associated with Kokkos::Tools::Experimental::EventSet::create_profile_se...
Definition Events.hpp:151
End-deep-copy event associated with Kokkos::Tools::Experimental::EventSet::end_deep_copy.
Definition Events.hpp:145
static constexpr event_id_t invalid_event_id
Definition Events.hpp:17
Pop-region event associated with Kokkos::Tools::Experimental::EventSet::pop_region.
Definition Events.hpp:192
Profile event associated with Kokkos::Tools::Experimental::EventSet::profile_event.
Definition Events.hpp:198
Push-region event associated with Kokkos::Tools::Experimental::EventSet::push_region.
Definition Events.hpp:184
Helper struct needed for the implementation of Kokkos::utils::callbacks::impl::listener_call_opr_list...
Definition Manager.hpp:89
std::list< const ListenerConceptCallOperator< EventType > * > type
Definition Manager.hpp:90
Helper structures used by Kokkos::utils::callbacks::Manager to store and call registered listeners.
Definition Manager.hpp:29
virtual void operator()(const EventType &event) const =0
void operator()(const EventType &event) const override
Definition Manager.hpp:56