Ginkgo  Generated from pipelines/1556235455 branch based on develop. Ginkgo version 1.9.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 
22 /* Eliminate circular dependencies the hard way */
23 template <typename ValueType>
24 class array;
25 class Executor;
26 class LinOp;
27 class LinOpFactory;
28 class PolymorphicObject;
29 class Operation;
30 class stopping_status;
31 
32 
33 namespace batch {
34 
35 
36 class BatchLinOp;
37 class BatchLinOpFactory;
38 
39 template <typename ValueType>
40 class MultiVector;
41 
42 
43 } // namespace batch
44 
45 
51 namespace stop {
52 class Criterion;
53 } // namespace stop
54 
55 
56 namespace log {
57 
58 
75 class Logger {
76 public:
78  using mask_type = gko::uint64;
79 
83  static constexpr size_type event_count_max = sizeof(mask_type) * byte_size;
84 
88  static constexpr mask_type all_events_mask = ~mask_type{0};
89 
111 #define GKO_LOGGER_REGISTER_EVENT(_id, _event_name, ...) \
112 protected: \
113  virtual void on_##_event_name(__VA_ARGS__) const {} \
114  \
115 public: \
116  template <size_type Event, typename... Params> \
117  std::enable_if_t<Event == _id && (_id < event_count_max)> on( \
118  Params&&... params) const \
119  { \
120  if (enabled_events_ & (mask_type{1} << _id)) { \
121  this->on_##_event_name(std::forward<Params>(params)...); \
122  } \
123  } \
124  static constexpr size_type _event_name{_id}; \
125  static constexpr mask_type _event_name##_mask{mask_type{1} << _id};
126 
133  GKO_LOGGER_REGISTER_EVENT(0, allocation_started, const Executor* exec,
134  const size_type& num_bytes)
135 
136 
143  GKO_LOGGER_REGISTER_EVENT(1, allocation_completed, const Executor* exec,
144  const size_type& num_bytes,
145  const uintptr& location)
146 
147 
153  GKO_LOGGER_REGISTER_EVENT(2, free_started, const Executor* exec,
154  const uintptr& location)
155 
156 
162  GKO_LOGGER_REGISTER_EVENT(3, free_completed, const Executor* exec,
163  const uintptr& location)
164 
165 
174  GKO_LOGGER_REGISTER_EVENT(4, copy_started, const Executor* exec_from,
175  const Executor* exec_to, const uintptr& loc_from,
176  const uintptr& loc_to, const size_type& num_bytes)
177 
178 
187  GKO_LOGGER_REGISTER_EVENT(5, copy_completed, const Executor* exec_from,
188  const Executor* exec_to, const uintptr& loc_from,
189  const uintptr& loc_to, const size_type& num_bytes)
190 
191 
197  GKO_LOGGER_REGISTER_EVENT(6, operation_launched, const Executor* exec,
198  const Operation* op)
199 
200 
211  GKO_LOGGER_REGISTER_EVENT(7, operation_completed, const Executor* exec,
212  const Operation* op)
213 
214 
220  GKO_LOGGER_REGISTER_EVENT(8, polymorphic_object_create_started,
221  const Executor* exec, const PolymorphicObject* po)
222 
223 
230  GKO_LOGGER_REGISTER_EVENT(9, polymorphic_object_create_completed,
231  const Executor* exec,
232  const PolymorphicObject* input,
233  const PolymorphicObject* output)
234 
235 
242  GKO_LOGGER_REGISTER_EVENT(10, polymorphic_object_copy_started,
243  const Executor* exec,
244  const PolymorphicObject* input,
245  const PolymorphicObject* output)
246 
247 
254  GKO_LOGGER_REGISTER_EVENT(11, polymorphic_object_copy_completed,
255  const Executor* exec,
256  const PolymorphicObject* input,
257  const PolymorphicObject* output)
258 
259 
265  GKO_LOGGER_REGISTER_EVENT(12, polymorphic_object_deleted,
266  const Executor* exec, const PolymorphicObject* po)
267 
268 
275  GKO_LOGGER_REGISTER_EVENT(13, linop_apply_started, const LinOp* A,
276  const LinOp* b, const LinOp* x)
277 
278 
285  GKO_LOGGER_REGISTER_EVENT(14, linop_apply_completed, const LinOp* A,
286  const LinOp* b, const LinOp* x)
287 
288 
297  GKO_LOGGER_REGISTER_EVENT(15, linop_advanced_apply_started, const LinOp* A,
298  const LinOp* alpha, const LinOp* b,
299  const LinOp* beta, const LinOp* x)
300 
301 
310  GKO_LOGGER_REGISTER_EVENT(16, linop_advanced_apply_completed,
311  const LinOp* A, const LinOp* alpha,
312  const LinOp* b, const LinOp* beta, const LinOp* x)
313 
314 
321  GKO_LOGGER_REGISTER_EVENT(17, linop_factory_generate_started,
322  const LinOpFactory* factory, const LinOp* input)
323 
324 
332  GKO_LOGGER_REGISTER_EVENT(18, linop_factory_generate_completed,
333  const LinOpFactory* factory, const LinOp* input,
334  const LinOp* output)
335 
336 
347  GKO_LOGGER_REGISTER_EVENT(19, criterion_check_started,
348  const stop::Criterion* criterion,
349  const size_type& it, const LinOp* r,
350  const LinOp* tau, const LinOp* x,
351  const uint8& stopping_id,
352  const bool& set_finalized)
353 
354 
374  GKO_LOGGER_REGISTER_EVENT(
375  20, criterion_check_completed, const stop::Criterion* criterion,
376  const size_type& it, const LinOp* r, const LinOp* tau, const LinOp* x,
377  const uint8& stopping_id, const bool& set_finalized,
378  const array<stopping_status>* status, const bool& one_changed,
379  const bool& all_converged)
380 protected:
398  virtual void on_criterion_check_completed(
399  const stop::Criterion* criterion, const size_type& it, const LinOp* r,
400  const LinOp* tau, const LinOp* implicit_tau_sq, const LinOp* x,
401  const uint8& stopping_id, const bool& set_finalized,
402  const array<stopping_status>* status, const bool& one_changed,
403  const bool& all_converged) const
404  {
405  this->on_criterion_check_completed(criterion, it, r, tau, x,
406  stopping_id, set_finalized, status,
407  one_changed, all_converged);
408  }
409 
410 public:
411  static constexpr size_type iteration_complete{21};
412  static constexpr mask_type iteration_complete_mask{mask_type{1} << 21};
413 
414  template <size_type Event, typename... Params>
415  std::enable_if_t<Event == 21 && (21 < event_count_max)> on(
416  Params&&... params) const
417  {
418  if (enabled_events_ & (mask_type{1} << 21)) {
419  this->on_iteration_complete(std::forward<Params>(params)...);
420  }
421  }
422 
423 protected:
436  GKO_DEPRECATED(
437  "Please use the version with the additional stopping "
438  "information.")
439  virtual void on_iteration_complete(const LinOp* solver, const size_type& it,
440  const LinOp* r, const LinOp* x = nullptr,
441  const LinOp* tau = nullptr) const
442  {}
443 
457  GKO_DEPRECATED(
458  "Please use the version with the additional stopping "
459  "information.")
460  virtual void on_iteration_complete(const LinOp* solver, const size_type& it,
461  const LinOp* r, const LinOp* x,
462  const LinOp* tau,
463  const LinOp* implicit_tau_sq) const
464  {
465  GKO_BEGIN_DISABLE_DEPRECATION_WARNINGS
466  this->on_iteration_complete(solver, it, r, x, tau);
467  GKO_END_DISABLE_DEPRECATION_WARNINGS
468  }
469 
485  virtual void on_iteration_complete(const LinOp* solver, const LinOp* b,
486  const LinOp* x, const size_type& it,
487  const LinOp* r, const LinOp* tau,
488  const LinOp* implicit_tau_sq,
489  const array<stopping_status>* status,
490  bool stopped) const
491  {
492  GKO_BEGIN_DISABLE_DEPRECATION_WARNINGS
493  this->on_iteration_complete(solver, it, r, x, tau, implicit_tau_sq);
494  GKO_END_DISABLE_DEPRECATION_WARNINGS
495  }
496 
497 public:
505  GKO_LOGGER_REGISTER_EVENT(22, polymorphic_object_move_started,
506  const Executor* exec,
507  const PolymorphicObject* input,
508  const PolymorphicObject* output)
509 
510 
517  GKO_LOGGER_REGISTER_EVENT(23, polymorphic_object_move_completed,
518  const Executor* exec,
519  const PolymorphicObject* input,
520  const PolymorphicObject* output)
521 
522 
529  GKO_LOGGER_REGISTER_EVENT(24, batch_linop_factory_generate_started,
530  const batch::BatchLinOpFactory* factory,
531  const batch::BatchLinOp* input)
532 
533 
541  GKO_LOGGER_REGISTER_EVENT(25, batch_linop_factory_generate_completed,
542  const batch::BatchLinOpFactory* factory,
543  const batch::BatchLinOp* input,
544  const batch::BatchLinOp* output)
545 
546 public:
547  static constexpr size_type batch_solver_completed{26};
548  static constexpr mask_type batch_solver_completed_mask{mask_type{1} << 26};
549 
550  template <size_type Event, typename... Params>
551  std::enable_if_t<Event == 26 && (26 < event_count_max)> on(
552  Params&&... params) const
553  {
554  if (enabled_events_ & batch_solver_completed_mask) {
555  this->on_batch_solver_completed(std::forward<Params>(params)...);
556  }
557  }
558 
559 protected:
567  virtual void on_batch_solver_completed(
568  const array<int>& iters, const array<double>& residual_norms) const
569  {}
570 
578  virtual void on_batch_solver_completed(
579  const array<int>& iters, const array<float>& residual_norms) const
580  {}
581 
582 public:
583 #undef GKO_LOGGER_REGISTER_EVENT
584 
588  static constexpr mask_type executor_events_mask =
589  allocation_started_mask | allocation_completed_mask |
590  free_started_mask | free_completed_mask | copy_started_mask |
591  copy_completed_mask;
592 
596  static constexpr mask_type operation_events_mask =
597  operation_launched_mask | operation_completed_mask;
598 
602  static constexpr mask_type polymorphic_object_events_mask =
603  polymorphic_object_create_started_mask |
604  polymorphic_object_create_completed_mask |
605  polymorphic_object_copy_started_mask |
606  polymorphic_object_copy_completed_mask |
607  polymorphic_object_move_started_mask |
608  polymorphic_object_move_completed_mask |
609  polymorphic_object_deleted_mask;
610 
614  static constexpr mask_type linop_events_mask =
615  linop_apply_started_mask | linop_apply_completed_mask |
616  linop_advanced_apply_started_mask | linop_advanced_apply_completed_mask;
617 
621  static constexpr mask_type linop_factory_events_mask =
622  linop_factory_generate_started_mask |
623  linop_factory_generate_completed_mask;
624 
628  static constexpr mask_type batch_linop_factory_events_mask =
629  batch_linop_factory_generate_started_mask |
630  batch_linop_factory_generate_completed_mask;
631 
635  static constexpr mask_type criterion_events_mask =
636  criterion_check_started_mask | criterion_check_completed_mask;
637 
642  virtual bool needs_propagation() const { return false; }
643 
644  virtual ~Logger() = default;
645 
646 protected:
661  GKO_DEPRECATED("use single-parameter constructor")
662  explicit Logger(std::shared_ptr<const gko::Executor> exec,
663  const mask_type& enabled_events = all_events_mask)
664  : Logger{enabled_events}
665  {}
666 
681  explicit Logger(const mask_type& enabled_events = all_events_mask)
682  : enabled_events_{enabled_events}
683  {}
684 
685 private:
686  mask_type enabled_events_;
687 };
688 
689 
695 class Loggable {
696 public:
697  virtual ~Loggable() = default;
698 
704  virtual void add_logger(std::shared_ptr<const Logger> logger) = 0;
705 
715  virtual void remove_logger(const Logger* logger) = 0;
716 
718  {
719  remove_logger(logger.get());
720  }
721 
727  virtual const std::vector<std::shared_ptr<const Logger>>& get_loggers()
728  const = 0;
729 
731  virtual void clear_loggers() = 0;
732 };
733 
734 
747 template <typename ConcreteLoggable, typename PolymorphicBase = Loggable>
748 class EnableLogging : public PolymorphicBase {
749 public:
750  void add_logger(std::shared_ptr<const Logger> logger) override
751  {
752  loggers_.push_back(logger);
753  }
754 
755  void remove_logger(const Logger* logger) override
756  {
757  auto idx =
758  find_if(begin(loggers_), end(loggers_),
759  [&logger](const auto& l) { return l.get() == logger; });
760  if (idx != end(loggers_)) {
761  loggers_.erase(idx);
762  } else {
763  throw OutOfBoundsError(__FILE__, __LINE__, loggers_.size(),
764  loggers_.size());
765  }
766  }
767 
768  void remove_logger(ptr_param<const Logger> logger)
769  {
770  remove_logger(logger.get());
771  }
772 
773  const std::vector<std::shared_ptr<const Logger>>& get_loggers()
774  const override
775  {
776  return loggers_;
777  }
778 
779  void clear_loggers() override { loggers_.clear(); }
780 
781 private:
789  template <size_type Event, typename ConcreteLoggableT, typename = void>
790  struct propagate_log_helper {
791  template <typename... Args>
792  static void propagate_log(const ConcreteLoggableT*, Args&&...)
793  {}
794  };
795 
796  template <size_type Event, typename ConcreteLoggableT>
797  struct propagate_log_helper<
798  Event, ConcreteLoggableT,
799  std::void_t<
800  decltype(std::declval<ConcreteLoggableT>().get_executor())>> {
801  template <typename... Args>
802  static void propagate_log(const ConcreteLoggableT* loggable,
803  Args&&... args)
804  {
805  const auto exec = loggable->get_executor();
806  if (exec->should_propagate_log()) {
807  for (auto& logger : exec->get_loggers()) {
808  if (logger->needs_propagation()) {
809  logger->template on<Event>(std::forward<Args>(args)...);
810  }
811  }
812  }
813  }
814  };
815 
816 protected:
817  template <size_type Event, typename... Params>
818  void log(Params&&... params) const
819  {
820  propagate_log_helper<Event, ConcreteLoggable>::propagate_log(
821  static_cast<const ConcreteLoggable*>(this),
822  std::forward<Params>(params)...);
823  for (auto& logger : loggers_) {
824  logger->template on<Event>(std::forward<Params>(params)...);
825  }
826  }
827 
828  std::vector<std::shared_ptr<const Logger>> loggers_;
829 };
830 
831 
832 } // namespace log
833 } // namespace gko
834 
835 
836 #endif // GKO_PUBLIC_CORE_LOG_LOGGER_HPP_
gko::uint8
std::uint8_t uint8
8-bit unsigned integral type.
Definition: types.hpp:115
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:588
gko::PolymorphicObject
A PolymorphicObject is the abstract base for all "heavy" objects in Ginkgo that behave polymorphicall...
Definition: polymorphic_object.hpp:43
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:138
gko::size_type
std::size_t size_type
Integral type used for allocation quantities.
Definition: types.hpp:86
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:614
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:695
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:628
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:83
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:88
gko::log::Logger::criterion_events_mask
static constexpr mask_type criterion_events_mask
Bitset Mask which activates all criterion events.
Definition: logger.hpp:635
gko::log::EnableLogging
EnableLogging is a mixin which should be inherited by any class which wants to enable logging.
Definition: logger.hpp:748
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:75
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:596
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:642
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:621
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:602
gko::uint64
std::uint64_t uint64
64-bit unsigned integral type.
Definition: types.hpp:132
gko::Operation
Operations can be used to define functionalities whose implementations differ among devices.
Definition: executor.hpp:258