Ginkgo  Generated from pipelines/2662685947 branch based on develop. Ginkgo version 2.0.0
A numerical linear algebra library targeting many-core architectures
logger.hpp
1 // SPDX-FileCopyrightText: 2017 - 2026 The Ginkgo authors
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 #ifndef GKO_PUBLIC_CORE_LOG_LOGGER_HPP_
6 #define GKO_PUBLIC_CORE_LOG_LOGGER_HPP_
7 
8 
9 #include <algorithm>
10 #include <memory>
11 #include <string>
12 #include <type_traits>
13 #include <vector>
14 
15 #include <ginkgo/core/base/types.hpp>
16 #include <ginkgo/core/base/utils_helper.hpp>
17 
18 
19 namespace gko {
20 
21 /* Eliminate circular dependencies the hard way */
22 template <typename ValueType>
23 class array;
24 class Executor;
25 class LinOp;
26 class LinOpFactory;
27 class PolymorphicObject;
28 class Operation;
29 class stopping_status;
30 template <typename T>
31 class EnableCloneable;
32 
33 
34 namespace batch {
35 
36 
37 class BatchLinOp;
38 class BatchLinOpFactory;
39 
40 template <typename ValueType>
41 class MultiVector;
42 
43 
44 } // namespace batch
45 
46 
52 namespace stop {
53 class Criterion;
54 } // namespace stop
55 
56 
57 namespace log {
58 
59 
76 class Logger {
77 public:
79  using mask_type = gko::uint64;
80 
84  static constexpr size_type event_count_max = sizeof(mask_type) * byte_size;
85 
89  static constexpr mask_type all_events_mask = ~mask_type{0};
90 
112 #define GKO_LOGGER_REGISTER_EVENT(_id, _event_name, ...) \
113 protected: \
114  virtual void on_##_event_name(__VA_ARGS__) const {} \
115  \
116 public: \
117  template <size_type Event, typename... Params> \
118  std::enable_if_t<Event == _id && (_id < event_count_max)> on( \
119  Params&&... params) const \
120  { \
121  if (enabled_events_ & (mask_type{1} << _id)) { \
122  this->on_##_event_name(std::forward<Params>(params)...); \
123  } \
124  } \
125  static constexpr size_type _event_name{_id}; \
126  static constexpr mask_type _event_name##_mask{mask_type{1} << _id};
127 
134  GKO_LOGGER_REGISTER_EVENT(0, allocation_started, const Executor* exec,
135  const size_type& num_bytes)
136 
137 
144  GKO_LOGGER_REGISTER_EVENT(1, allocation_completed, const Executor* exec,
145  const size_type& num_bytes,
146  const uintptr& location)
147 
148 
154  GKO_LOGGER_REGISTER_EVENT(2, free_started, const Executor* exec,
155  const uintptr& location)
156 
157 
163  GKO_LOGGER_REGISTER_EVENT(3, free_completed, const Executor* exec,
164  const uintptr& location)
165 
166 
175  GKO_LOGGER_REGISTER_EVENT(4, copy_started, const Executor* exec_from,
176  const Executor* exec_to, const uintptr& loc_from,
177  const uintptr& loc_to, const size_type& num_bytes)
178 
179 
188  GKO_LOGGER_REGISTER_EVENT(5, copy_completed, const Executor* exec_from,
189  const Executor* exec_to, const uintptr& loc_from,
190  const uintptr& loc_to, const size_type& num_bytes)
191 
192 
198  GKO_LOGGER_REGISTER_EVENT(6, operation_launched, const Executor* exec,
199  const Operation* op)
200 
201 
212  GKO_LOGGER_REGISTER_EVENT(7, operation_completed, const Executor* exec,
213  const Operation* op)
214 
215 
221  GKO_LOGGER_REGISTER_EVENT(8, polymorphic_object_create_started,
222  const Executor* exec, const PolymorphicObject* po)
223 
224 
231  GKO_LOGGER_REGISTER_EVENT(9, polymorphic_object_create_completed,
232  const Executor* exec,
233  const PolymorphicObject* input,
234  const PolymorphicObject* output)
235 
236 
243  GKO_LOGGER_REGISTER_EVENT(10, polymorphic_object_copy_started,
244  const Executor* exec,
245  const PolymorphicObject* input,
246  const PolymorphicObject* output)
247 
248 
255  GKO_LOGGER_REGISTER_EVENT(11, polymorphic_object_copy_completed,
256  const Executor* exec,
257  const PolymorphicObject* input,
258  const PolymorphicObject* output)
259 
260 
266  GKO_LOGGER_REGISTER_EVENT(12, polymorphic_object_deleted,
267  const Executor* exec, const PolymorphicObject* po)
268 
269 
276  GKO_LOGGER_REGISTER_EVENT(13, linop_apply_started, const LinOp* A,
277  const LinOp* b, const LinOp* x)
278 
279 
286  GKO_LOGGER_REGISTER_EVENT(14, linop_apply_completed, const LinOp* A,
287  const LinOp* b, const LinOp* x)
288 
289 
298  GKO_LOGGER_REGISTER_EVENT(15, linop_advanced_apply_started, const LinOp* A,
299  const LinOp* alpha, const LinOp* b,
300  const LinOp* beta, const LinOp* x)
301 
302 
311  GKO_LOGGER_REGISTER_EVENT(16, linop_advanced_apply_completed,
312  const LinOp* A, const LinOp* alpha,
313  const LinOp* b, const LinOp* beta, const LinOp* x)
314 
315 
322  GKO_LOGGER_REGISTER_EVENT(17, linop_factory_generate_started,
323  const LinOpFactory* factory, const LinOp* input)
324 
325 
333  GKO_LOGGER_REGISTER_EVENT(18, linop_factory_generate_completed,
334  const LinOpFactory* factory, const LinOp* input,
335  const LinOp* output)
336 
337 
348  GKO_LOGGER_REGISTER_EVENT(19, criterion_check_started,
349  const stop::Criterion* criterion,
350  const size_type& it, const LinOp* r,
351  const LinOp* tau, const LinOp* x,
352  const uint8& stopping_id,
353  const bool& set_finalized)
354 
355 
375  GKO_LOGGER_REGISTER_EVENT(
376  20, criterion_check_completed, const stop::Criterion* criterion,
377  const size_type& it, const LinOp* r, const LinOp* tau, const LinOp* x,
378  const uint8& stopping_id, const bool& set_finalized,
379  const array<stopping_status>* status, const bool& one_changed,
380  const bool& all_converged)
381 protected:
399  virtual void on_criterion_check_completed(
400  const stop::Criterion* criterion, const size_type& it, const LinOp* r,
401  const LinOp* tau, const LinOp* implicit_tau_sq, const LinOp* x,
402  const uint8& stopping_id, const bool& set_finalized,
403  const array<stopping_status>* status, const bool& one_changed,
404  const bool& all_converged) const
405  {
406  this->on_criterion_check_completed(criterion, it, r, tau, x,
407  stopping_id, set_finalized, status,
408  one_changed, all_converged);
409  }
410 
411 public:
412  static constexpr size_type iteration_complete{21};
413  static constexpr mask_type iteration_complete_mask{mask_type{1} << 21};
414 
415  template <size_type Event, typename... Params>
416  std::enable_if_t<Event == 21 && (21 < event_count_max)> on(
417  Params&&... params) const
418  {
419  if (enabled_events_ & (mask_type{1} << 21)) {
420  this->on_iteration_complete(std::forward<Params>(params)...);
421  }
422  }
423 
424 protected:
437  GKO_DEPRECATED(
438  "Please use the version with the additional stopping "
439  "information.")
440  virtual void on_iteration_complete(const LinOp* solver, const size_type& it,
441  const LinOp* r, const LinOp* x = nullptr,
442  const LinOp* tau = nullptr) const
443  {}
444 
458  GKO_DEPRECATED(
459  "Please use the version with the additional stopping "
460  "information.")
461  virtual void on_iteration_complete(const LinOp* solver, const size_type& it,
462  const LinOp* r, const LinOp* x,
463  const LinOp* tau,
464  const LinOp* implicit_tau_sq) const
465  {
466  GKO_BEGIN_DISABLE_DEPRECATION_WARNINGS
467  this->on_iteration_complete(solver, it, r, x, tau);
468  GKO_END_DISABLE_DEPRECATION_WARNINGS
469  }
470 
486  virtual void on_iteration_complete(const LinOp* solver, const LinOp* b,
487  const LinOp* x, const size_type& it,
488  const LinOp* r, const LinOp* tau,
489  const LinOp* implicit_tau_sq,
490  const array<stopping_status>* status,
491  bool stopped) const
492  {
493  GKO_BEGIN_DISABLE_DEPRECATION_WARNINGS
494  this->on_iteration_complete(solver, it, r, x, tau, implicit_tau_sq);
495  GKO_END_DISABLE_DEPRECATION_WARNINGS
496  }
497 
498 public:
506  GKO_LOGGER_REGISTER_EVENT(22, polymorphic_object_move_started,
507  const Executor* exec,
508  const PolymorphicObject* input,
509  const PolymorphicObject* output)
510 
511 
518  GKO_LOGGER_REGISTER_EVENT(23, polymorphic_object_move_completed,
519  const Executor* exec,
520  const PolymorphicObject* input,
521  const PolymorphicObject* output)
522 
523 
530  GKO_LOGGER_REGISTER_EVENT(24, batch_linop_factory_generate_started,
531  const batch::BatchLinOpFactory* factory,
532  const batch::BatchLinOp* input)
533 
534 
542  GKO_LOGGER_REGISTER_EVENT(25, batch_linop_factory_generate_completed,
543  const batch::BatchLinOpFactory* factory,
544  const batch::BatchLinOp* input,
545  const batch::BatchLinOp* output)
546 
547 public:
548  static constexpr size_type batch_solver_completed{26};
549  static constexpr mask_type batch_solver_completed_mask{mask_type{1} << 26};
550 
551  template <size_type Event, typename... Params>
552  std::enable_if_t<Event == 26 && (26 < event_count_max)> on(
553  Params&&... params) const
554  {
555  if (enabled_events_ & batch_solver_completed_mask) {
556  this->on_batch_solver_completed(std::forward<Params>(params)...);
557  }
558  }
559 
560 protected:
568  virtual void on_batch_solver_completed(
569  const array<int>& iters, const array<double>& residual_norms) const
570  {}
571 
579  virtual void on_batch_solver_completed(
580  const array<int>& iters, const array<float>& residual_norms) const
581  {}
582 
583 
584 #if GINKGO_ENABLE_HALF
585 
586 
594  virtual void on_batch_solver_completed(
595  const array<int>& iters,
596  const array<gko::float16>& residual_norms) const
597  {}
598 
599 
600 #endif
601 
602 
603 #if GINKGO_ENABLE_BFLOAT16
604 
605 
613  virtual void on_batch_solver_completed(
614  const array<int>& iters,
615  const array<gko::bfloat16>& residual_norms) const
616  {}
617 
618 
619 #endif
620 
621 
622 public:
623 #undef GKO_LOGGER_REGISTER_EVENT
624 
628  static constexpr mask_type executor_events_mask =
629  allocation_started_mask | allocation_completed_mask |
630  free_started_mask | free_completed_mask | copy_started_mask |
631  copy_completed_mask;
632 
636  static constexpr mask_type operation_events_mask =
637  operation_launched_mask | operation_completed_mask;
638 
642  static constexpr mask_type polymorphic_object_events_mask =
643  polymorphic_object_create_started_mask |
644  polymorphic_object_create_completed_mask |
645  polymorphic_object_copy_started_mask |
646  polymorphic_object_copy_completed_mask |
647  polymorphic_object_move_started_mask |
648  polymorphic_object_move_completed_mask |
649  polymorphic_object_deleted_mask;
650 
654  static constexpr mask_type linop_events_mask =
655  linop_apply_started_mask | linop_apply_completed_mask |
656  linop_advanced_apply_started_mask | linop_advanced_apply_completed_mask;
657 
661  static constexpr mask_type linop_factory_events_mask =
662  linop_factory_generate_started_mask |
663  linop_factory_generate_completed_mask;
664 
668  static constexpr mask_type batch_linop_factory_events_mask =
669  batch_linop_factory_generate_started_mask |
670  batch_linop_factory_generate_completed_mask;
671 
675  static constexpr mask_type criterion_events_mask =
676  criterion_check_started_mask | criterion_check_completed_mask;
677 
682  virtual bool needs_propagation() const { return false; }
683 
684  virtual ~Logger() = default;
685 
686 protected:
701  GKO_DEPRECATED("use single-parameter constructor")
702  explicit Logger(std::shared_ptr<const gko::Executor> exec,
703  const mask_type& enabled_events = all_events_mask)
704  : Logger{enabled_events}
705  {}
706 
721  explicit Logger(const mask_type& enabled_events = all_events_mask)
722  : enabled_events_{enabled_events}
723  {}
724 
725 private:
726  mask_type enabled_events_;
727 };
728 
729 
735 class Loggable {
736 public:
737  virtual ~Loggable() = default;
738 
744  virtual void add_logger(std::shared_ptr<const Logger> logger) = 0;
745 
755  virtual void remove_logger(const Logger* logger) = 0;
756 
758  {
759  remove_logger(logger.get());
760  }
761 
767  virtual const std::vector<std::shared_ptr<const Logger>>& get_loggers()
768  const = 0;
769 
771  virtual void clear_loggers() = 0;
772 };
773 
774 
787 template <typename ConcreteLoggable, typename PolymorphicBase = Loggable>
788 class EnableLogging : public PolymorphicBase {
789  template <typename T>
790  friend class gko::EnableCloneable;
791 
792 public:
793  void add_logger(std::shared_ptr<const Logger> logger) override
794  {
795  loggers_.push_back(logger);
796  }
797 
798  void remove_logger(const Logger* logger) override
799  {
800  auto idx =
801  find_if(begin(loggers_), end(loggers_),
802  [&logger](const auto& l) { return l.get() == logger; });
803  if (idx != end(loggers_)) {
804  loggers_.erase(idx);
805  } else {
806  throw OutOfBoundsError(__FILE__, __LINE__, loggers_.size(),
807  loggers_.size());
808  }
809  }
810 
811  void remove_logger(ptr_param<const Logger> logger)
812  {
813  remove_logger(logger.get());
814  }
815 
816  const std::vector<std::shared_ptr<const Logger>>& get_loggers()
817  const override
818  {
819  return loggers_;
820  }
821 
822  void clear_loggers() override { loggers_.clear(); }
823 
824 private:
832  template <size_type Event, typename ConcreteLoggableT, typename = void>
833  struct propagate_log_helper {
834  template <typename... Args>
835  static void propagate_log(const ConcreteLoggableT*, Args&&...)
836  {}
837  };
838 
839  template <size_type Event, typename ConcreteLoggableT>
840  struct propagate_log_helper<
841  Event, ConcreteLoggableT,
842  std::void_t<
843  decltype(std::declval<ConcreteLoggableT>().get_executor())>> {
844  template <typename... Args>
845  static void propagate_log(const ConcreteLoggableT* loggable,
846  Args&&... args)
847  {
848  const auto exec = loggable->get_executor();
849  if (exec->should_propagate_log()) {
850  for (auto& logger : exec->get_loggers()) {
851  if (logger->needs_propagation()) {
852  logger->template on<Event>(std::forward<Args>(args)...);
853  }
854  }
855  }
856  }
857  };
858 
859 protected:
860  template <size_type Event, typename... Params>
861  void log(Params&&... params) const
862  {
863  propagate_log_helper<Event, ConcreteLoggable>::propagate_log(
864  static_cast<const ConcreteLoggable*>(this),
865  std::forward<Params>(params)...);
866  for (auto& logger : loggers_) {
867  logger->template on<Event>(std::forward<Params>(params)...);
868  }
869  }
870 
871  std::vector<std::shared_ptr<const Logger>> loggers_;
872 };
873 
874 
875 } // namespace log
876 } // namespace gko
877 
878 
879 #endif // GKO_PUBLIC_CORE_LOG_LOGGER_HPP_
gko::uint8
std::uint8_t uint8
8-bit unsigned integral type.
Definition: types.hpp:119
gko::log::Loggable::remove_logger
virtual void remove_logger(const Logger *logger)=0
Removes a logger from the list of subscribed loggers.
gko::log::profile_event_category::solver
Solver events.
gko::layout_type::array
The matrix should be written as dense matrix in column-major order.
gko::LinOp
Definition: lin_op.hpp:117
gko::OutOfBoundsError
OutOfBoundsError is thrown if a memory access is detected to be out-of-bounds.
Definition: exception.hpp:558
gko::log::Logger::executor_events_mask
static constexpr mask_type executor_events_mask
Bitset Mask which activates all executor events.
Definition: logger.hpp:628
gko::PolymorphicObject
A PolymorphicObject is the abstract base for all "heavy" objects in Ginkgo that behave polymorphicall...
Definition: polymorphic_object.hpp:46
gko::log::profile_event_category::factory
LinOpFactory events.
gko::log::profile_event_category::criterion
Stopping criterion events.
gko::uintptr
std::uintptr_t uintptr
Unsigned integer type capable of holding a pointer to void.
Definition: types.hpp:142
gko::size_type
std::size_t size_type
Integral type used for allocation quantities.
Definition: types.hpp:90
gko::ptr_param::get
T * get() const
Definition: utils_helper.hpp:77
gko::log::Loggable::clear_loggers
virtual void clear_loggers()=0
Remove all loggers registered at this object.
gko::log::Logger::linop_events_mask
static constexpr mask_type linop_events_mask
Bitset Mask which activates all linop events.
Definition: logger.hpp:654
gko::log::Loggable::add_logger
virtual void add_logger(std::shared_ptr< const Logger > logger)=0
Adds a new logger to the list of subscribed loggers.
gko::byte_size
constexpr size_type byte_size
Number of bits in a byte.
Definition: types.hpp:178
gko::log::Loggable
Loggable class is an interface which should be implemented by classes wanting to support logging.
Definition: logger.hpp:735
gko::log::Logger::batch_linop_factory_events_mask
static constexpr mask_type batch_linop_factory_events_mask
Bitset Mask which activates all batch linop factory events.
Definition: logger.hpp:668
gko
The Ginkgo namespace.
Definition: abstract_factory.hpp:20
gko::log::Logger::event_count_max
static constexpr size_type event_count_max
Maximum amount of events (bits) with the current implementation.
Definition: logger.hpp:84
gko::array
An array is a container which encapsulates fixed-sized arrays, stored on the Executor tied to the arr...
Definition: array.hpp:26
gko::log::Logger::all_events_mask
static constexpr mask_type all_events_mask
Bitset Mask which activates all events.
Definition: logger.hpp:89
gko::log::Logger::criterion_events_mask
static constexpr mask_type criterion_events_mask
Bitset Mask which activates all criterion events.
Definition: logger.hpp:675
gko::log::EnableLogging
EnableLogging is a mixin which should be inherited by any class which wants to enable logging.
Definition: logger.hpp:788
gko::ptr_param
This class is used for function parameters in the place of raw pointers.
Definition: utils_helper.hpp:43
gko::log::Logger
Definition: logger.hpp:76
gko::log::Loggable::get_loggers
virtual const std::vector< std::shared_ptr< const Logger > > & get_loggers() const =0
Returns the vector containing all loggers registered at this object.
gko::stop::Criterion
The Criterion class is a base class for all stopping criteria.
Definition: criterion.hpp:36
gko::log::Logger::operation_events_mask
static constexpr mask_type operation_events_mask
Bitset Mask which activates all operation events.
Definition: logger.hpp:636
gko::EnableCloneable
This mixin is used to enable a default Cloneable::clone() implementation and similar for objects that...
Definition: polymorphic_object.hpp:369
gko::log::Logger::needs_propagation
virtual bool needs_propagation() const
Returns true if this logger, when attached to an Executor, needs to be forwarded all events from obje...
Definition: logger.hpp:682
gko::Executor
The first step in using the Ginkgo library consists of creating an executor.
Definition: executor.hpp:616
gko::log::Logger::linop_factory_events_mask
static constexpr mask_type linop_factory_events_mask
Bitset Mask which activates all linop factory events.
Definition: logger.hpp:661
gko::LinOpFactory
A LinOpFactory represents a higher order mapping which transforms one linear operator into another.
Definition: lin_op.hpp:343
gko::log::Logger::polymorphic_object_events_mask
static constexpr mask_type polymorphic_object_events_mask
Bitset Mask which activates all polymorphic object events.
Definition: logger.hpp:642
gko::uint64
std::uint64_t uint64
64-bit unsigned integral type.
Definition: types.hpp:136
gko::Operation
Operations can be used to define functionalities whose implementations differ among devices.
Definition: executor.hpp:258