Ginkgo  Generated from pipelines/2837190956 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:
438  GKO_DEPRECATED(
439  "Please use the version with the additional stopping "
440  "information.")
441  virtual void on_iteration_complete(const LinOp* solver, const size_type& it,
442  const LinOp* r, const LinOp* x = nullptr,
443  const LinOp* tau = nullptr) const
444  {}
445 
460  GKO_DEPRECATED(
461  "Please use the version with the additional stopping "
462  "information.")
463  virtual void on_iteration_complete(const LinOp* solver, const size_type& it,
464  const LinOp* r, const LinOp* x,
465  const LinOp* tau,
466  const LinOp* implicit_tau_sq) const
467  {
468  GKO_BEGIN_DISABLE_DEPRECATION_WARNINGS
469  this->on_iteration_complete(solver, it, r, x, tau);
470  GKO_END_DISABLE_DEPRECATION_WARNINGS
471  }
472 
488  virtual void on_iteration_complete(const LinOp* solver, const LinOp* b,
489  const LinOp* x, const size_type& it,
490  const LinOp* r, const LinOp* tau,
491  const LinOp* implicit_tau_sq,
492  const array<stopping_status>* status,
493  bool stopped) const
494  {
495  GKO_BEGIN_DISABLE_DEPRECATION_WARNINGS
496  this->on_iteration_complete(solver, it, r, x, tau, implicit_tau_sq);
497  GKO_END_DISABLE_DEPRECATION_WARNINGS
498  }
499 
500 public:
508  GKO_LOGGER_REGISTER_EVENT(22, polymorphic_object_move_started,
509  const Executor* exec,
510  const PolymorphicObject* input,
511  const PolymorphicObject* output)
512 
513 
520  GKO_LOGGER_REGISTER_EVENT(23, polymorphic_object_move_completed,
521  const Executor* exec,
522  const PolymorphicObject* input,
523  const PolymorphicObject* output)
524 
525 
532  GKO_LOGGER_REGISTER_EVENT(24, batch_linop_factory_generate_started,
533  const batch::BatchLinOpFactory* factory,
534  const batch::BatchLinOp* input)
535 
536 
544  GKO_LOGGER_REGISTER_EVENT(25, batch_linop_factory_generate_completed,
545  const batch::BatchLinOpFactory* factory,
546  const batch::BatchLinOp* input,
547  const batch::BatchLinOp* output)
548 
549 public:
550  static constexpr size_type batch_solver_completed{26};
551  static constexpr mask_type batch_solver_completed_mask{mask_type{1} << 26};
552 
553  template <size_type Event, typename... Params>
554  std::enable_if_t<Event == 26 && (26 < event_count_max)> on(
555  Params&&... params) const
556  {
557  if (enabled_events_ & batch_solver_completed_mask) {
558  this->on_batch_solver_completed(std::forward<Params>(params)...);
559  }
560  }
561 
562 protected:
570  virtual void on_batch_solver_completed(
571  const array<int>& iters, const array<double>& residual_norms) const
572  {}
573 
581  virtual void on_batch_solver_completed(
582  const array<int>& iters, const array<float>& residual_norms) const
583  {}
584 
585 
586 #if GINKGO_ENABLE_HALF
587 
588 
596  virtual void on_batch_solver_completed(
597  const array<int>& iters,
598  const array<gko::float16>& residual_norms) const
599  {}
600 
601 
602 #endif
603 
604 
605 #if GINKGO_ENABLE_BFLOAT16
606 
607 
615  virtual void on_batch_solver_completed(
616  const array<int>& iters,
617  const array<gko::bfloat16>& residual_norms) const
618  {}
619 
620 
621 #endif
622 
623 
624 public:
625 #undef GKO_LOGGER_REGISTER_EVENT
626 
630  static constexpr mask_type executor_events_mask =
631  allocation_started_mask | allocation_completed_mask |
632  free_started_mask | free_completed_mask | copy_started_mask |
633  copy_completed_mask;
634 
638  static constexpr mask_type operation_events_mask =
639  operation_launched_mask | operation_completed_mask;
640 
644  static constexpr mask_type polymorphic_object_events_mask =
645  polymorphic_object_create_started_mask |
646  polymorphic_object_create_completed_mask |
647  polymorphic_object_copy_started_mask |
648  polymorphic_object_copy_completed_mask |
649  polymorphic_object_move_started_mask |
650  polymorphic_object_move_completed_mask |
651  polymorphic_object_deleted_mask;
652 
656  static constexpr mask_type linop_events_mask =
657  linop_apply_started_mask | linop_apply_completed_mask |
658  linop_advanced_apply_started_mask | linop_advanced_apply_completed_mask;
659 
663  static constexpr mask_type linop_factory_events_mask =
664  linop_factory_generate_started_mask |
665  linop_factory_generate_completed_mask;
666 
670  static constexpr mask_type batch_linop_factory_events_mask =
671  batch_linop_factory_generate_started_mask |
672  batch_linop_factory_generate_completed_mask;
673 
677  static constexpr mask_type criterion_events_mask =
678  criterion_check_started_mask | criterion_check_completed_mask;
679 
684  virtual bool needs_propagation() const { return false; }
685 
686  virtual ~Logger() = default;
687 
688 protected:
703  GKO_DEPRECATED("use single-parameter constructor")
704  explicit Logger(std::shared_ptr<const gko::Executor> exec,
705  const mask_type& enabled_events = all_events_mask)
706  : Logger{enabled_events}
707  {}
708 
723  explicit Logger(const mask_type& enabled_events = all_events_mask)
724  : enabled_events_{enabled_events}
725  {}
726 
727 private:
728  mask_type enabled_events_;
729 };
730 
731 
737 class Loggable {
738 public:
739  virtual ~Loggable() = default;
740 
746  virtual void add_logger(std::shared_ptr<const Logger> logger) = 0;
747 
757  virtual void remove_logger(const Logger* logger) = 0;
758 
760  {
761  remove_logger(logger.get());
762  }
763 
769  virtual const std::vector<std::shared_ptr<const Logger>>& get_loggers()
770  const = 0;
771 
773  virtual void clear_loggers() = 0;
774 };
775 
776 
789 template <typename ConcreteLoggable, typename PolymorphicBase = Loggable>
790 class EnableLogging : public PolymorphicBase {
791  template <typename T>
792  friend class gko::EnableCloneable;
793 
794 public:
795  void add_logger(std::shared_ptr<const Logger> logger) override
796  {
797  loggers_.push_back(logger);
798  }
799 
800  void remove_logger(const Logger* logger) override
801  {
802  auto idx =
803  find_if(begin(loggers_), end(loggers_),
804  [&logger](const auto& l) { return l.get() == logger; });
805  if (idx != end(loggers_)) {
806  loggers_.erase(idx);
807  } else {
808  throw OutOfBoundsError(__FILE__, __LINE__, loggers_.size(),
809  loggers_.size());
810  }
811  }
812 
813  void remove_logger(ptr_param<const Logger> logger)
814  {
815  remove_logger(logger.get());
816  }
817 
818  const std::vector<std::shared_ptr<const Logger>>& get_loggers()
819  const override
820  {
821  return loggers_;
822  }
823 
824  void clear_loggers() override { loggers_.clear(); }
825 
826 private:
834  template <size_type Event, typename ConcreteLoggableT, typename = void>
835  struct propagate_log_helper {
836  template <typename... Args>
837  static void propagate_log(const ConcreteLoggableT*, Args&&...)
838  {}
839  };
840 
841  template <size_type Event, typename ConcreteLoggableT>
842  struct propagate_log_helper<
843  Event, ConcreteLoggableT,
844  std::void_t<
845  decltype(std::declval<ConcreteLoggableT>().get_executor())>> {
846  template <typename... Args>
847  static void propagate_log(const ConcreteLoggableT* loggable,
848  Args&&... args)
849  {
850  const auto exec = loggable->get_executor();
851  if (exec->should_propagate_log()) {
852  for (auto& logger : exec->get_loggers()) {
853  if (logger->needs_propagation()) {
854  logger->template on<Event>(std::forward<Args>(args)...);
855  }
856  }
857  }
858  }
859  };
860 
861 protected:
862  template <size_type Event, typename... Params>
863  void log(Params&&... params) const
864  {
865  propagate_log_helper<Event, ConcreteLoggable>::propagate_log(
866  static_cast<const ConcreteLoggable*>(this),
867  std::forward<Params>(params)...);
868  for (auto& logger : loggers_) {
869  logger->template on<Event>(std::forward<Params>(params)...);
870  }
871  }
872 
873  std::vector<std::shared_ptr<const Logger>> loggers_;
874 };
875 
876 
877 } // namespace log
878 } // namespace gko
879 
880 
881 #endif // GKO_PUBLIC_CORE_LOG_LOGGER_HPP_
gko::uint8
std::uint8_t uint8
8-bit unsigned integral type.
Definition: types.hpp:130
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:550
gko::log::Logger::executor_events_mask
static constexpr mask_type executor_events_mask
Bitset Mask which activates all executor events.
Definition: logger.hpp:630
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:153
gko::size_type
std::size_t size_type
Integral type used for allocation quantities.
Definition: types.hpp:101
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:656
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:189
gko::log::Loggable
Loggable class is an interface which should be implemented by classes wanting to support logging.
Definition: logger.hpp:737
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:670
gko
The Ginkgo namespace.
Definition: abstract_factory.hpp:19
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:677
gko::log::EnableLogging
EnableLogging is a mixin which should be inherited by any class which wants to enable logging.
Definition: logger.hpp:790
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:638
gko::EnableCloneable
This mixin is used to enable a default Cloneable::clone() implementation and similar for objects that...
Definition: polymorphic_object.hpp:376
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:684
gko::Executor
The first step in using the Ginkgo library consists of creating an executor.
Definition: executor.hpp:615
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:663
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:644
gko::uint64
std::uint64_t uint64
64-bit unsigned integral type.
Definition: types.hpp:147
gko::Operation
Operations can be used to define functionalities whose implementations differ among devices.
Definition: executor.hpp:257