kokkos-utils 0.0.2
 
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 <list>
5#include <ranges>
6
9
11{
12
13namespace impl
14{
15
28{
29 virtual ~ListenerConceptBase() = default;
30};
31
32template <Event EventType>
34{
35 virtual ~ListenerConceptCallOperator() = default;
36
37 virtual void operator()(const EventType& event) const = 0;
38};
39
40template <typename...>
42
43template <typename Callable>
45{
46 template <typename T> requires std::same_as<std::remove_cvref_t<T>, Callable>
47 explicit ListenerModelBase(T&& callable_) : callable(std::forward<T>(callable_)) {}
48
49 Callable callable;
50};
51
52template <Event EventType, typename ListenerModel>
54{
55 void operator()(const EventType& event) const override
56 {
57 // Distinguish between a callable object that is a function object and one that is a shared pointer.
58 if constexpr (std::is_invocable_v<decltype(static_cast<const ListenerModel*>(this)->callable), const EventType&>) {
59 static_cast<const ListenerModel*>(this)->callable.operator()(event);
60 } else {
61 static_cast<const ListenerModel*>(this)->callable->operator()(event);
62 }
63 };
64};
65
66template <typename Callable, Event... EventTypes>
67struct ListenerModel<Callable, EventTypes...>
68 : public ListenerModelCallOperator<EventTypes, ListenerModel<Callable, EventTypes...>>...,
69 public ListenerModelBase<Callable>
70{
71 using event_type_list_t = Kokkos::Impl::type_list<EventTypes...>;
72
74};
75
76template <typename Callable, Event... EventTypes>
77struct ListenerModel<Callable, Kokkos::Impl::type_list<EventTypes...>>
78 : public ListenerModel<Callable, EventTypes...>
79{
80 using event_type_list_t = Kokkos::Impl::type_list<EventTypes...>;
81
82 using ListenerModel<Callable, EventTypes...>::ListenerModel;
83};
84
86template <Event EventType>
88{
89 using type = std::list<const ListenerConceptCallOperator<EventType>*>;
90};
91
98>;
100
101} // namespace impl
102
140{
141public:
142 using listener_list_t = std::list<std::unique_ptr<impl::ListenerConceptBase>>;
143 using listener_list_const_iter_t = typename listener_list_t::const_iterator;
145
146public:
147 Manager(const Manager&) = delete;
148 Manager& operator=(const Manager&) = delete;
149
151
152protected:
157 Manager() : context_callbacks(Kokkos::Tools::Experimental::get_callbacks()) {}
158
159public:
160 static void initialize() { if(singleton == nullptr) singleton = new Manager(); }
161 static void finalize() { if(singleton != nullptr) { delete singleton; singleton = nullptr; }}
162
163 static bool is_initialized() { return singleton != nullptr; }
164
165 static Manager& get_instance() { return *singleton; }
166
172 template <Listener Callable>
173 static listener_list_const_iter_t register_listener(std::shared_ptr<Callable> callable)
174 {
175 using event_type_list_t = listener_event_type_list_t<Callable>;
176 using listener_model_t = impl::ListenerModel<std::shared_ptr<Callable>, event_type_list_t>;
177 return register_listener_impl<listener_model_t>(std::move(callable));
178 }
179
186 template <typename T> requires Listener<std::remove_cvref_t<T>>
188 {
189 using event_type_list_t = listener_event_type_list_t<std::remove_cvref_t<T>>;
190 using listener_model_t = impl::ListenerModel<std::remove_cvref_t<T>, event_type_list_t>;
191 return register_listener_impl<listener_model_t>(std::forward<T>(callable));
192 }
193
195 template <Listener Callable>
196 static void unregister_listener(const Callable* const callable)
197 {
198 using event_type_list_t = listener_event_type_list_t<Callable>;
199
200 using listener_model_t = impl::ListenerModel<std::shared_ptr<Callable>, event_type_list_t>;
201
203
204 const auto iter = std::ranges::find_if(
205 listeners,
206 [&] (const std::unique_ptr<impl::ListenerConceptBase>& listener)
207 {
208 auto* const listener_ptr = dynamic_cast<listener_model_t*>(listener.get());
209 return listener_ptr == nullptr ? false : listener_ptr->callable.get() == callable;
210 }
211 );
212
214 get<Kokkos::utils::impl::type_list_index_v<EventType, EventTypeList>>(get_instance().registered_callbacks).remove(
215 dynamic_cast<const impl::ListenerConceptCallOperator<EventType>*>(iter->get())
216 );
217 });
218
219 listeners.erase(iter);
220
222 }
223
225 {
227 get<Kokkos::utils::impl::type_list_index_v<EventType, EventTypeList>>(get_instance().registered_callbacks).remove(
228 dynamic_cast<const impl::ListenerConceptCallOperator<EventType>*>(iter->get())
229 );
230 });
231
232 get_instance().listeners.erase(iter);
233
235 }
236
237private:
243 Kokkos::Tools::Experimental::set_callbacks(context_callbacks);
244 }
245
246 template <typename ListenerModelType, typename CallableType>
248 {
249 using event_type_list_t = typename ListenerModelType::event_type_list_t;
250
252
254 const auto iter = listeners.insert(
255 listeners.end(), std::make_unique<ListenerModelType>(std::forward<CallableType>(callable))
256 );
257
261 get<Kokkos::utils::impl::type_list_index_v<EventType, EventTypeList>>(get_instance().registered_callbacks).push_back(
262 dynamic_cast<const impl::ListenerConceptCallOperator<EventType>*>(iter->get())
263 );
264 });
265
267
268 return iter;
269 }
270
282
283 template <Event EventType>
285 {
287 get<Kokkos::utils::impl::type_list_index_v<EventType, EventTypeList>>(registered_callbacks).empty()
290 );
291 }
292
295 template <Event EventType>
297 {
298 return [] <typename... Args>(Args... args) -> void {
299 EventType event{args...};
300 get_instance().dispatch(event);
301 };
302 }
303
304 template <BeginEvent EventType>
306 {
307 return [] (const char* name, const uint32_t dev_id, uint64_t* event_id) -> void
308 {
309 EventType event{ .name = name, .dev_id = dev_id, .event_id = *event_id };
310 get_instance().dispatch(event);
311 *event_id = event.event_id;
312 };
313 }
314
315 template <DataEvent EventType>
317 {
318 return [] (Kokkos_Profiling_SpaceHandle kpsh, const char* name, const void* ptr, uint64_t size) -> void
319 {
320 EventType event{ .alloc = { .kpsh = kpsh, .name = name, .ptr = ptr, .size = size } };
321 get_instance().dispatch(event);
322 };
323 }
324
325 template <Event EventType> requires std::same_as<EventType, BeginDeepCopyEvent>
327 {
328 return [] (Kokkos_Profiling_SpaceHandle dst_kpsh, const char* dst_name, const void* dst_ptr,
329 Kokkos_Profiling_SpaceHandle src_kpsh, const char* src_name, const void* src_ptr, uint64_t size) -> void
330 {
331 EventType event{
332 .dst = { .kpsh = dst_kpsh, .name = dst_name, .ptr = dst_ptr, .size = size },
333 .src = { .kpsh = src_kpsh, .name = src_name, .ptr = src_ptr, .size = size }
334 };
335 get_instance().dispatch(event);
336 };
337 }
338
339 template <Event EventType> requires std::same_as<EventType, CreateProfileSectionEvent>
341 {
342 return [] (const char* name, uint32_t* section_id) -> void
343 {
344 EventType event{ .name = name, .section_id = *section_id };
345 get_instance().dispatch(event);
346 *section_id = event.section_id;
347 };
348 }
349
354 template <Event EventType>
355 void dispatch(EventType& event)
356 {
358
360 }
361
363 template <Event EventType>
364 void dispatch_context_callback(EventType& event)
365 {
367
368 if (context_callback) {
369 dispatch_context_callback_for_event_type_impl(context_callback, event);
370 } else {
372 }
373 }
374
375 template <typename ContextCallbackType, BeginEvent EventType>
376 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, EventType& event) {
377 context_callback(event.name.c_str(), event.dev_id, &event.event_id);
378 }
379
380 template <typename ContextCallbackType, EndEvent EventType>
381 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const EventType& event) {
382 context_callback(event.event_id);
383 }
384
385 template <typename ContextCallbackType, DataEvent EventType>
386 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const EventType& event) {
387 context_callback(event.alloc.kpsh, event.alloc.name.c_str(), event.alloc.ptr, event.alloc.size);
388 }
389
390 template <typename ContextCallbackType>
391 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const BeginDeepCopyEvent& event) {
392 context_callback(event.dst.kpsh, event.dst.name.c_str(), event.dst.ptr,
393 event.src.kpsh, event.src.name.c_str(), event.src.ptr, event.src.size);
394 }
395
396 template <typename ContextCallbackType>
397 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const EndDeepCopyEvent& /* event */) {
398 context_callback();
399 }
400
401 template <typename ContextCallbackType>
402 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, CreateProfileSectionEvent& event) {
403 context_callback(event.name.c_str(), &event.section_id);
404 }
405
406 template <typename ContextCallbackType, ProfileSectionManipulationEvent EventType>
407 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const EventType& event) {
408 context_callback(event.section_id);
409 }
410
411 template <typename ContextCallbackType>
412 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const PushRegionEvent& event) {
413 context_callback(event.name.c_str());
414 }
415
416 template <typename ContextCallbackType>
417 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const PopRegionEvent& /* event */) {
418 context_callback();
419 }
420
421 template <typename ContextCallbackType>
422 static void dispatch_context_callback_for_event_type_impl(ContextCallbackType* context_callback, const ProfileEvent& event) {
423 context_callback(event.name.c_str());
424 }
425
426 template <Event EventType>
427 void increment_id_if_needed_for_event_type_impl(EventType& /* event */) {}
428
429 template <BeginEvent EventType>
431 event.event_id = next_event_id++;
432 }
433
437
438 template <Event EventType>
439 void dispatch_registered_callbacks(const EventType& event) const
440 {
442 listener->operator()(event);
443 }
444 }
445
446private:
448
450
451 static inline Manager* singleton = nullptr;
452
453 Kokkos::Tools::Experimental::EventSet context_callbacks {};
454
455 uint64_t next_event_id = 0;
456 uint32_t next_section_id = 0;
457};
458
459} // namespace Kokkos::utils::callbacks
460
461#endif // KOKKOS_UTILS_CALLBACKS_MANAGER_HPP
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, const EndDeepCopyEvent &)
Definition Manager.hpp:397
void set_dispatching_callback_impl() const
Definition Manager.hpp:284
std::list< std::unique_ptr< impl::ListenerConceptBase > > listener_list_t
Definition Manager.hpp:142
static void unregister_listener(const Callable *const callable)
Unregister a callable object as a listener.
Definition Manager.hpp:196
static Manager & get_instance()
Definition Manager.hpp:165
void dispatch_registered_callbacks(const EventType &event) const
Definition Manager.hpp:439
static auto create_dispatching_callback_for_event_type_impl()
Definition Manager.hpp:340
void reset_context_callbacks() const
Uses Kokkos::Tools::Experimental::set_callbacks to restore the Kokkos callback function pointers to t...
Definition Manager.hpp:242
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, const ProfileEvent &event)
Definition Manager.hpp:422
Manager(const Manager &)=delete
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, const PushRegionEvent &event)
Definition Manager.hpp:412
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, CreateProfileSectionEvent &event)
Definition Manager.hpp:402
void dispatch_context_callback(EventType &event)
Dispatch the event to the context callback, if any is set in Kokkos.
Definition Manager.hpp:364
static listener_list_const_iter_t register_listener(T &&callable)
Definition Manager.hpp:187
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, EventType &event)
Definition Manager.hpp:376
listener_call_opr_list_tuple_t registered_callbacks
Definition Manager.hpp:447
Manager()
Constructor. Retrieves and stores the Kokkos::Tools::Experimental::EventSet containing the Kokkos cal...
Definition Manager.hpp:157
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, const BeginDeepCopyEvent &event)
Definition Manager.hpp:391
void set_dispatching_callbacks() const
Uses the setters Kokkos::Tools::Experimental::set_<event_type_name>_callback to set the Kokkos callba...
Definition Manager.hpp:276
void dispatch(EventType &event)
Dispatch first the context callback, if any is set in Kokkos, and then sequentially the registered ca...
Definition Manager.hpp:355
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, const PopRegionEvent &)
Definition Manager.hpp:417
void increment_id_if_needed_for_event_type_impl(CreateProfileSectionEvent &event)
Definition Manager.hpp:434
impl::listener_call_opr_list_tuple_t listener_call_opr_list_tuple_t
Definition Manager.hpp:144
static void dispatch_context_callback_for_event_type_impl(ContextCallbackType *context_callback, const EventType &event)
Definition Manager.hpp:381
static auto create_dispatching_callback_for_event_type_impl()
Definition Manager.hpp:296
void increment_id_if_needed_for_event_type_impl(EventType &event)
Definition Manager.hpp:430
typename listener_list_t::const_iterator listener_list_const_iter_t
Definition Manager.hpp:143
Manager & operator=(const Manager &)=delete
static void unregister_listener(const listener_list_const_iter_t &iter)
Definition Manager.hpp:224
void increment_id_if_needed_for_event_type_impl(EventType &)
Definition Manager.hpp:427
static listener_list_const_iter_t register_listener_impl(CallableType &&callable)
Definition Manager.hpp:247
Kokkos::Tools::Experimental::EventSet context_callbacks
Definition Manager.hpp:453
static auto create_dispatching_callback_for_event_type_impl()
Definition Manager.hpp:326
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:173
Callable is a listener if it is invocable with at least one event type from Kokkos::utils::callbacks:...
Definition Listener.hpp:31
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:96
Kokkos::Impl::filter_type_list_t< impl::IsListenerFor< Callable >::template type, EventTypeList > listener_event_type_list_t
Type list holding the event types that Callable can be a listener for.
Definition Listener.hpp:39
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 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:103
Begin-deep-copy event associated with Kokkos::Tools::Experimental::EventSet::begin_deep_copy.
Definition Events.hpp:129
Create-profile-section event associated with Kokkos::Tools::Experimental::EventSet::create_profile_se...
Definition Events.hpp:144
End-deep-copy event associated with Kokkos::Tools::Experimental::EventSet::end_deep_copy.
Definition Events.hpp:138
Pop-region event associated with Kokkos::Tools::Experimental::EventSet::pop_region.
Definition Events.hpp:185
Profile event associated with Kokkos::Tools::Experimental::EventSet::profile_event.
Definition Events.hpp:191
Push-region event associated with Kokkos::Tools::Experimental::EventSet::push_region.
Definition Events.hpp:177
Helper struct needed for the implementation of Kokkos::utils::callbacks::impl::listener_call_opr_list...
Definition Manager.hpp:88
std::list< const ListenerConceptCallOperator< EventType > * > type
Definition Manager.hpp:89
Helper structures used by Kokkos::utils::callbacks::Manager to store and call registered listeners.
Definition Manager.hpp:28
virtual void operator()(const EventType &event) const =0
void operator()(const EventType &event) const override
Definition Manager.hpp:55