Ginkgo  Generated from pipelines/1680925034 branch based on develop. Ginkgo version 1.10.0
A numerical linear algebra library targeting many-core architectures
logger.hpp
1 // SPDX-FileCopyrightText: 2017 - 2024 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 class half;
22 
23 /* Eliminate circular dependencies the hard way */
24 template <typename ValueType>
25 class array;
26 class Executor;
27 class LinOp;
28 class LinOpFactory;
29 class PolymorphicObject;
30 class Operation;
31 class stopping_status;
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 
590  virtual void on_batch_solver_completed(
591  const array<int>& iters, const array<gko::half>& residual_norms) const
592  {}
593 
594 public:
595 #undef GKO_LOGGER_REGISTER_EVENT
596 
600  static constexpr mask_type executor_events_mask =
601  allocation_started_mask | allocation_completed_mask |
602  free_started_mask | free_completed_mask | copy_started_mask |
603  copy_completed_mask;
604 
608  static constexpr mask_type operation_events_mask =
609  operation_launched_mask | operation_completed_mask;
610 
614  static constexpr mask_type polymorphic_object_events_mask =
615  polymorphic_object_create_started_mask |
616  polymorphic_object_create_completed_mask |
617  polymorphic_object_copy_started_mask |
618  polymorphic_object_copy_completed_mask |
619  polymorphic_object_move_started_mask |
620  polymorphic_object_move_completed_mask |
621  polymorphic_object_deleted_mask;
622 
626  static constexpr mask_type linop_events_mask =
627  linop_apply_started_mask | linop_apply_completed_mask |
628  linop_advanced_apply_started_mask | linop_advanced_apply_completed_mask;
629 
633  static constexpr mask_type linop_factory_events_mask =
634  linop_factory_generate_started_mask |
635  linop_factory_generate_completed_mask;
636 
640  static constexpr mask_type batch_linop_factory_events_mask =
641  batch_linop_factory_generate_started_mask |
642  batch_linop_factory_generate_completed_mask;
643 
647  static constexpr mask_type criterion_events_mask =
648  criterion_check_started_mask | criterion_check_completed_mask;
649 
654  virtual bool needs_propagation() const { return false; }
655 
656  virtual ~Logger() = default;
657 
658 protected:
673  GKO_DEPRECATED("use single-parameter constructor")
674  explicit Logger(std::shared_ptr<const gko::Executor> exec,
675  const mask_type& enabled_events = all_events_mask)
676  : Logger{enabled_events}
677  {}
678 
693  explicit Logger(const mask_type& enabled_events = all_events_mask)
694  : enabled_events_{enabled_events}
695  {}
696 
697 private:
698  mask_type enabled_events_;
699 };
700 
701 
707 class Loggable {
708 public:
709  virtual ~Loggable() = default;
710 
716  virtual void add_logger(std::shared_ptr<const Logger> logger) = 0;
717 
727  virtual void remove_logger(const Logger* logger) = 0;
728 
730  {
731  remove_logger(logger.get());
732  }
733 
739  virtual const std::vector<std::shared_ptr<const Logger>>& get_loggers()
740  const = 0;
741 
743  virtual void clear_loggers() = 0;
744 };
745 
746 
759 template <typename ConcreteLoggable, typename PolymorphicBase = Loggable>
760 class EnableLogging : public PolymorphicBase {
761 public:
762  void add_logger(std::shared_ptr<const Logger> logger) override
763  {
764  loggers_.push_back(logger);
765  }
766 
767  void remove_logger(const Logger* logger) override
768  {
769  auto idx =
770  find_if(begin(loggers_), end(loggers_),
771  [&logger](const auto& l) { return l.get() == logger; });
772  if (idx != end(loggers_)) {
773  loggers_.erase(idx);
774  } else {
775  throw OutOfBoundsError(__FILE__, __LINE__, loggers_.size(),
776  loggers_.size());
777  }
778  }
779 
780  void remove_logger(ptr_param<const Logger> logger)
781  {
782  remove_logger(logger.get());
783  }
784 
785  const std::vector<std::shared_ptr<const Logger>>& get_loggers()
786  const override
787  {
788  return loggers_;
789  }
790 
791  void clear_loggers() override { loggers_.clear(); }
792 
793 private:
801  template <size_type Event, typename ConcreteLoggableT, typename = void>
802  struct propagate_log_helper {
803  template <typename... Args>
804  static void propagate_log(const ConcreteLoggableT*, Args&&...)
805  {}
806  };
807 
808  template <size_type Event, typename ConcreteLoggableT>
809  struct propagate_log_helper<
810  Event, ConcreteLoggableT,
811  std::void_t<
812  decltype(std::declval<ConcreteLoggableT>().get_executor())>> {
813  template <typename... Args>
814  static void propagate_log(const ConcreteLoggableT* loggable,
815  Args&&... args)
816  {
817  const auto exec = loggable->get_executor();
818  if (exec->should_propagate_log()) {
819  for (auto& logger : exec->get_loggers()) {
820  if (logger->needs_propagation()) {
821  logger->template on<Event>(std::forward<Args>(args)...);
822  }
823  }
824  }
825  }
826  };
827 
828 protected:
829  template <size_type Event, typename... Params>
830  void log(Params&&... params) const
831  {
832  propagate_log_helper<Event, ConcreteLoggable>::propagate_log(
833  static_cast<const ConcreteLoggable*>(this),
834  std::forward<Params>(params)...);
835  for (auto& logger : loggers_) {
836  logger->template on<Event>(std::forward<Params>(params)...);
837  }
838  }
839 
840  std::vector<std::shared_ptr<const Logger>> loggers_;
841 };
842 
843 
844 } // namespace log
845 } // namespace gko
846 
847 
848 #endif // GKO_PUBLIC_CORE_LOG_LOGGER_HPP_
gko::uint8
std::uint8_t uint8
8-bit unsigned integral type.
Definition: types.hpp:118
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:600
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:141
gko::size_type
std::size_t size_type
Integral type used for allocation quantities.
Definition: types.hpp:89
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:626
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:177
gko::log::Loggable
Loggable class is an interface which should be implemented by classes wanting to support logging.
Definition: logger.hpp:707
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:640
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:647
gko::log::EnableLogging
EnableLogging is a mixin which should be inherited by any class which wants to enable logging.
Definition: logger.hpp:760
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: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:608
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:654
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:633
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:614
gko::uint64
std::uint64_t uint64
64-bit unsigned integral type.
Definition: types.hpp:135
gko::Operation
Operations can be used to define functionalities whose implementations differ among devices.
Definition: executor.hpp:258