Ginkgo  Generated from pipelines/1868155508 branch based on main. Ginkgo version 1.10.0
A numerical linear algebra library targeting many-core architectures
logger.hpp
1 // SPDX-FileCopyrightText: 2017 - 2025 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 
31 
32 namespace batch {
33 
34 
35 class BatchLinOp;
36 class BatchLinOpFactory;
37 
38 template <typename ValueType>
39 class MultiVector;
40 
41 
42 } // namespace batch
43 
44 
50 namespace stop {
51 class Criterion;
52 } // namespace stop
53 
54 
55 namespace log {
56 
57 
74 class Logger {
75 public:
77  using mask_type = gko::uint64;
78 
82  static constexpr size_type event_count_max = sizeof(mask_type) * byte_size;
83 
87  static constexpr mask_type all_events_mask = ~mask_type{0};
88 
110 #define GKO_LOGGER_REGISTER_EVENT(_id, _event_name, ...) \
111 protected: \
112  virtual void on_##_event_name(__VA_ARGS__) const {} \
113  \
114 public: \
115  template <size_type Event, typename... Params> \
116  std::enable_if_t<Event == _id && (_id < event_count_max)> on( \
117  Params&&... params) const \
118  { \
119  if (enabled_events_ & (mask_type{1} << _id)) { \
120  this->on_##_event_name(std::forward<Params>(params)...); \
121  } \
122  } \
123  static constexpr size_type _event_name{_id}; \
124  static constexpr mask_type _event_name##_mask{mask_type{1} << _id};
125 
132  GKO_LOGGER_REGISTER_EVENT(0, allocation_started, const Executor* exec,
133  const size_type& num_bytes)
134 
135 
142  GKO_LOGGER_REGISTER_EVENT(1, allocation_completed, const Executor* exec,
143  const size_type& num_bytes,
144  const uintptr& location)
145 
146 
152  GKO_LOGGER_REGISTER_EVENT(2, free_started, const Executor* exec,
153  const uintptr& location)
154 
155 
161  GKO_LOGGER_REGISTER_EVENT(3, free_completed, const Executor* exec,
162  const uintptr& location)
163 
164 
173  GKO_LOGGER_REGISTER_EVENT(4, copy_started, const Executor* exec_from,
174  const Executor* exec_to, const uintptr& loc_from,
175  const uintptr& loc_to, const size_type& num_bytes)
176 
177 
186  GKO_LOGGER_REGISTER_EVENT(5, copy_completed, const Executor* exec_from,
187  const Executor* exec_to, const uintptr& loc_from,
188  const uintptr& loc_to, const size_type& num_bytes)
189 
190 
196  GKO_LOGGER_REGISTER_EVENT(6, operation_launched, const Executor* exec,
197  const Operation* op)
198 
199 
210  GKO_LOGGER_REGISTER_EVENT(7, operation_completed, const Executor* exec,
211  const Operation* op)
212 
213 
219  GKO_LOGGER_REGISTER_EVENT(8, polymorphic_object_create_started,
220  const Executor* exec, const PolymorphicObject* po)
221 
222 
229  GKO_LOGGER_REGISTER_EVENT(9, polymorphic_object_create_completed,
230  const Executor* exec,
231  const PolymorphicObject* input,
232  const PolymorphicObject* output)
233 
234 
241  GKO_LOGGER_REGISTER_EVENT(10, polymorphic_object_copy_started,
242  const Executor* exec,
243  const PolymorphicObject* input,
244  const PolymorphicObject* output)
245 
246 
253  GKO_LOGGER_REGISTER_EVENT(11, polymorphic_object_copy_completed,
254  const Executor* exec,
255  const PolymorphicObject* input,
256  const PolymorphicObject* output)
257 
258 
264  GKO_LOGGER_REGISTER_EVENT(12, polymorphic_object_deleted,
265  const Executor* exec, const PolymorphicObject* po)
266 
267 
274  GKO_LOGGER_REGISTER_EVENT(13, linop_apply_started, const LinOp* A,
275  const LinOp* b, const LinOp* x)
276 
277 
284  GKO_LOGGER_REGISTER_EVENT(14, linop_apply_completed, const LinOp* A,
285  const LinOp* b, const LinOp* x)
286 
287 
296  GKO_LOGGER_REGISTER_EVENT(15, linop_advanced_apply_started, const LinOp* A,
297  const LinOp* alpha, const LinOp* b,
298  const LinOp* beta, const LinOp* x)
299 
300 
309  GKO_LOGGER_REGISTER_EVENT(16, linop_advanced_apply_completed,
310  const LinOp* A, const LinOp* alpha,
311  const LinOp* b, const LinOp* beta, const LinOp* x)
312 
313 
320  GKO_LOGGER_REGISTER_EVENT(17, linop_factory_generate_started,
321  const LinOpFactory* factory, const LinOp* input)
322 
323 
331  GKO_LOGGER_REGISTER_EVENT(18, linop_factory_generate_completed,
332  const LinOpFactory* factory, const LinOp* input,
333  const LinOp* output)
334 
335 
346  GKO_LOGGER_REGISTER_EVENT(19, criterion_check_started,
347  const stop::Criterion* criterion,
348  const size_type& it, const LinOp* r,
349  const LinOp* tau, const LinOp* x,
350  const uint8& stopping_id,
351  const bool& set_finalized)
352 
353 
373  GKO_LOGGER_REGISTER_EVENT(
374  20, criterion_check_completed, const stop::Criterion* criterion,
375  const size_type& it, const LinOp* r, const LinOp* tau, const LinOp* x,
376  const uint8& stopping_id, const bool& set_finalized,
377  const array<stopping_status>* status, const bool& one_changed,
378  const bool& all_converged)
379 protected:
397  virtual void on_criterion_check_completed(
398  const stop::Criterion* criterion, const size_type& it, const LinOp* r,
399  const LinOp* tau, const LinOp* implicit_tau_sq, const LinOp* x,
400  const uint8& stopping_id, const bool& set_finalized,
401  const array<stopping_status>* status, const bool& one_changed,
402  const bool& all_converged) const
403  {
404  this->on_criterion_check_completed(criterion, it, r, tau, x,
405  stopping_id, set_finalized, status,
406  one_changed, all_converged);
407  }
408 
409 public:
410  static constexpr size_type iteration_complete{21};
411  static constexpr mask_type iteration_complete_mask{mask_type{1} << 21};
412 
413  template <size_type Event, typename... Params>
414  std::enable_if_t<Event == 21 && (21 < event_count_max)> on(
415  Params&&... params) const
416  {
417  if (enabled_events_ & (mask_type{1} << 21)) {
418  this->on_iteration_complete(std::forward<Params>(params)...);
419  }
420  }
421 
422 protected:
435  GKO_DEPRECATED(
436  "Please use the version with the additional stopping "
437  "information.")
438  virtual void on_iteration_complete(const LinOp* solver, const size_type& it,
439  const LinOp* r, const LinOp* x = nullptr,
440  const LinOp* tau = nullptr) const
441  {}
442 
456  GKO_DEPRECATED(
457  "Please use the version with the additional stopping "
458  "information.")
459  virtual void on_iteration_complete(const LinOp* solver, const size_type& it,
460  const LinOp* r, const LinOp* x,
461  const LinOp* tau,
462  const LinOp* implicit_tau_sq) const
463  {
464  GKO_BEGIN_DISABLE_DEPRECATION_WARNINGS
465  this->on_iteration_complete(solver, it, r, x, tau);
466  GKO_END_DISABLE_DEPRECATION_WARNINGS
467  }
468 
484  virtual void on_iteration_complete(const LinOp* solver, const LinOp* b,
485  const LinOp* x, const size_type& it,
486  const LinOp* r, const LinOp* tau,
487  const LinOp* implicit_tau_sq,
488  const array<stopping_status>* status,
489  bool stopped) const
490  {
491  GKO_BEGIN_DISABLE_DEPRECATION_WARNINGS
492  this->on_iteration_complete(solver, it, r, x, tau, implicit_tau_sq);
493  GKO_END_DISABLE_DEPRECATION_WARNINGS
494  }
495 
496 public:
504  GKO_LOGGER_REGISTER_EVENT(22, polymorphic_object_move_started,
505  const Executor* exec,
506  const PolymorphicObject* input,
507  const PolymorphicObject* output)
508 
509 
516  GKO_LOGGER_REGISTER_EVENT(23, polymorphic_object_move_completed,
517  const Executor* exec,
518  const PolymorphicObject* input,
519  const PolymorphicObject* output)
520 
521 
528  GKO_LOGGER_REGISTER_EVENT(24, batch_linop_factory_generate_started,
529  const batch::BatchLinOpFactory* factory,
530  const batch::BatchLinOp* input)
531 
532 
540  GKO_LOGGER_REGISTER_EVENT(25, batch_linop_factory_generate_completed,
541  const batch::BatchLinOpFactory* factory,
542  const batch::BatchLinOp* input,
543  const batch::BatchLinOp* output)
544 
545 public:
546  static constexpr size_type batch_solver_completed{26};
547  static constexpr mask_type batch_solver_completed_mask{mask_type{1} << 26};
548 
549  template <size_type Event, typename... Params>
550  std::enable_if_t<Event == 26 && (26 < event_count_max)> on(
551  Params&&... params) const
552  {
553  if (enabled_events_ & batch_solver_completed_mask) {
554  this->on_batch_solver_completed(std::forward<Params>(params)...);
555  }
556  }
557 
558 protected:
566  virtual void on_batch_solver_completed(
567  const array<int>& iters, const array<double>& residual_norms) const
568  {}
569 
577  virtual void on_batch_solver_completed(
578  const array<int>& iters, const array<float>& residual_norms) const
579  {}
580 
581 
582 #if GINKGO_ENABLE_HALF
583 
584 
592  virtual void on_batch_solver_completed(
593  const array<int>& iters,
594  const array<gko::float16>& residual_norms) const
595  {}
596 
597 
598 #endif
599 
600 
601 #if GINKGO_ENABLE_BFLOAT16
602 
603 
611  virtual void on_batch_solver_completed(
612  const array<int>& iters,
613  const array<gko::bfloat16>& residual_norms) const
614  {}
615 
616 
617 #endif
618 
619 
620 public:
621 #undef GKO_LOGGER_REGISTER_EVENT
622 
626  static constexpr mask_type executor_events_mask =
627  allocation_started_mask | allocation_completed_mask |
628  free_started_mask | free_completed_mask | copy_started_mask |
629  copy_completed_mask;
630 
634  static constexpr mask_type operation_events_mask =
635  operation_launched_mask | operation_completed_mask;
636 
640  static constexpr mask_type polymorphic_object_events_mask =
641  polymorphic_object_create_started_mask |
642  polymorphic_object_create_completed_mask |
643  polymorphic_object_copy_started_mask |
644  polymorphic_object_copy_completed_mask |
645  polymorphic_object_move_started_mask |
646  polymorphic_object_move_completed_mask |
647  polymorphic_object_deleted_mask;
648 
652  static constexpr mask_type linop_events_mask =
653  linop_apply_started_mask | linop_apply_completed_mask |
654  linop_advanced_apply_started_mask | linop_advanced_apply_completed_mask;
655 
659  static constexpr mask_type linop_factory_events_mask =
660  linop_factory_generate_started_mask |
661  linop_factory_generate_completed_mask;
662 
666  static constexpr mask_type batch_linop_factory_events_mask =
667  batch_linop_factory_generate_started_mask |
668  batch_linop_factory_generate_completed_mask;
669 
673  static constexpr mask_type criterion_events_mask =
674  criterion_check_started_mask | criterion_check_completed_mask;
675 
680  virtual bool needs_propagation() const { return false; }
681 
682  virtual ~Logger() = default;
683 
684 protected:
699  GKO_DEPRECATED("use single-parameter constructor")
700  explicit Logger(std::shared_ptr<const gko::Executor> exec,
701  const mask_type& enabled_events = all_events_mask)
702  : Logger{enabled_events}
703  {}
704 
719  explicit Logger(const mask_type& enabled_events = all_events_mask)
720  : enabled_events_{enabled_events}
721  {}
722 
723 private:
724  mask_type enabled_events_;
725 };
726 
727 
733 class Loggable {
734 public:
735  virtual ~Loggable() = default;
736 
742  virtual void add_logger(std::shared_ptr<const Logger> logger) = 0;
743 
753  virtual void remove_logger(const Logger* logger) = 0;
754 
756  {
757  remove_logger(logger.get());
758  }
759 
765  virtual const std::vector<std::shared_ptr<const Logger>>& get_loggers()
766  const = 0;
767 
769  virtual void clear_loggers() = 0;
770 };
771 
772 
785 template <typename ConcreteLoggable, typename PolymorphicBase = Loggable>
786 class EnableLogging : public PolymorphicBase {
787 public:
788  void add_logger(std::shared_ptr<const Logger> logger) override
789  {
790  loggers_.push_back(logger);
791  }
792 
793  void remove_logger(const Logger* logger) override
794  {
795  auto idx =
796  find_if(begin(loggers_), end(loggers_),
797  [&logger](const auto& l) { return l.get() == logger; });
798  if (idx != end(loggers_)) {
799  loggers_.erase(idx);
800  } else {
801  throw OutOfBoundsError(__FILE__, __LINE__, loggers_.size(),
802  loggers_.size());
803  }
804  }
805 
806  void remove_logger(ptr_param<const Logger> logger)
807  {
808  remove_logger(logger.get());
809  }
810 
811  const std::vector<std::shared_ptr<const Logger>>& get_loggers()
812  const override
813  {
814  return loggers_;
815  }
816 
817  void clear_loggers() override { loggers_.clear(); }
818 
819 private:
827  template <size_type Event, typename ConcreteLoggableT, typename = void>
828  struct propagate_log_helper {
829  template <typename... Args>
830  static void propagate_log(const ConcreteLoggableT*, Args&&...)
831  {}
832  };
833 
834  template <size_type Event, typename ConcreteLoggableT>
835  struct propagate_log_helper<
836  Event, ConcreteLoggableT,
837  std::void_t<
838  decltype(std::declval<ConcreteLoggableT>().get_executor())>> {
839  template <typename... Args>
840  static void propagate_log(const ConcreteLoggableT* loggable,
841  Args&&... args)
842  {
843  const auto exec = loggable->get_executor();
844  if (exec->should_propagate_log()) {
845  for (auto& logger : exec->get_loggers()) {
846  if (logger->needs_propagation()) {
847  logger->template on<Event>(std::forward<Args>(args)...);
848  }
849  }
850  }
851  }
852  };
853 
854 protected:
855  template <size_type Event, typename... Params>
856  void log(Params&&... params) const
857  {
858  propagate_log_helper<Event, ConcreteLoggable>::propagate_log(
859  static_cast<const ConcreteLoggable*>(this),
860  std::forward<Params>(params)...);
861  for (auto& logger : loggers_) {
862  logger->template on<Event>(std::forward<Params>(params)...);
863  }
864  }
865 
866  std::vector<std::shared_ptr<const Logger>> loggers_;
867 };
868 
869 
870 } // namespace log
871 } // namespace gko
872 
873 
874 #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:626
gko::PolymorphicObject
A PolymorphicObject is the abstract base for all "heavy" objects in Ginkgo that behave polymorphicall...
Definition: polymorphic_object.hpp:52
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:75
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:652
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:733
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:666
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:82
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:87
gko::log::Logger::criterion_events_mask
static constexpr mask_type criterion_events_mask
Bitset Mask which activates all criterion events.
Definition: logger.hpp:673
gko::log::EnableLogging
EnableLogging is a mixin which should be inherited by any class which wants to enable logging.
Definition: logger.hpp:786
gko::ptr_param
This class is used for function parameters in the place of raw pointers.
Definition: utils_helper.hpp:41
gko::log::Logger
Definition: logger.hpp:74
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:634
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:680
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:659
gko::LinOpFactory
A LinOpFactory represents a higher order mapping which transforms one linear operator into another.
Definition: lin_op.hpp:384
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:640
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