Ginkgo  Generated from pipelines/1330831941 branch based on master. Ginkgo version 1.8.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 
16 #include <ginkgo/core/base/types.hpp>
17 #include <ginkgo/core/base/utils_helper.hpp>
18 
19 
20 namespace gko {
21 
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 
583 public:
584 #undef GKO_LOGGER_REGISTER_EVENT
585 
589  static constexpr mask_type executor_events_mask =
590  allocation_started_mask | allocation_completed_mask |
591  free_started_mask | free_completed_mask | copy_started_mask |
592  copy_completed_mask;
593 
597  static constexpr mask_type operation_events_mask =
598  operation_launched_mask | operation_completed_mask;
599 
603  static constexpr mask_type polymorphic_object_events_mask =
604  polymorphic_object_create_started_mask |
605  polymorphic_object_create_completed_mask |
606  polymorphic_object_copy_started_mask |
607  polymorphic_object_copy_completed_mask |
608  polymorphic_object_move_started_mask |
609  polymorphic_object_move_completed_mask |
610  polymorphic_object_deleted_mask;
611 
615  static constexpr mask_type linop_events_mask =
616  linop_apply_started_mask | linop_apply_completed_mask |
617  linop_advanced_apply_started_mask | linop_advanced_apply_completed_mask;
618 
622  static constexpr mask_type linop_factory_events_mask =
623  linop_factory_generate_started_mask |
624  linop_factory_generate_completed_mask;
625 
629  static constexpr mask_type batch_linop_factory_events_mask =
630  batch_linop_factory_generate_started_mask |
631  batch_linop_factory_generate_completed_mask;
632 
636  static constexpr mask_type criterion_events_mask =
637  criterion_check_started_mask | criterion_check_completed_mask;
638 
643  virtual bool needs_propagation() const { return false; }
644 
645  virtual ~Logger() = default;
646 
647 protected:
662  GKO_DEPRECATED("use single-parameter constructor")
663  explicit Logger(std::shared_ptr<const gko::Executor> exec,
664  const mask_type& enabled_events = all_events_mask)
665  : Logger{enabled_events}
666  {}
667 
682  explicit Logger(const mask_type& enabled_events = all_events_mask)
683  : enabled_events_{enabled_events}
684  {}
685 
686 private:
687  mask_type enabled_events_;
688 };
689 
690 
696 class Loggable {
697 public:
698  virtual ~Loggable() = default;
699 
705  virtual void add_logger(std::shared_ptr<const Logger> logger) = 0;
706 
716  virtual void remove_logger(const Logger* logger) = 0;
717 
719  {
720  remove_logger(logger.get());
721  }
722 
728  virtual const std::vector<std::shared_ptr<const Logger>>& get_loggers()
729  const = 0;
730 
732  virtual void clear_loggers() = 0;
733 };
734 
735 
748 template <typename ConcreteLoggable, typename PolymorphicBase = Loggable>
749 class EnableLogging : public PolymorphicBase {
750 public:
751  void add_logger(std::shared_ptr<const Logger> logger) override
752  {
753  loggers_.push_back(logger);
754  }
755 
756  void remove_logger(const Logger* logger) override
757  {
758  auto idx =
759  find_if(begin(loggers_), end(loggers_),
760  [&logger](const auto& l) { return l.get() == logger; });
761  if (idx != end(loggers_)) {
762  loggers_.erase(idx);
763  } else {
764  throw OutOfBoundsError(__FILE__, __LINE__, loggers_.size(),
765  loggers_.size());
766  }
767  }
768 
769  void remove_logger(ptr_param<const Logger> logger)
770  {
771  remove_logger(logger.get());
772  }
773 
774  const std::vector<std::shared_ptr<const Logger>>& get_loggers()
775  const override
776  {
777  return loggers_;
778  }
779 
780  void clear_loggers() override { loggers_.clear(); }
781 
782 private:
790  template <size_type Event, typename ConcreteLoggableT, typename = void>
791  struct propagate_log_helper {
792  template <typename... Args>
793  static void propagate_log(const ConcreteLoggableT*, Args&&...)
794  {}
795  };
796 
797  template <size_type Event, typename ConcreteLoggableT>
798  struct propagate_log_helper<
799  Event, ConcreteLoggableT,
800  xstd::void_t<
801  decltype(std::declval<ConcreteLoggableT>().get_executor())>> {
802  template <typename... Args>
803  static void propagate_log(const ConcreteLoggableT* loggable,
804  Args&&... args)
805  {
806  const auto exec = loggable->get_executor();
807  if (exec->should_propagate_log()) {
808  for (auto& logger : exec->get_loggers()) {
809  if (logger->needs_propagation()) {
810  logger->template on<Event>(std::forward<Args>(args)...);
811  }
812  }
813  }
814  }
815  };
816 
817 protected:
818  template <size_type Event, typename... Params>
819  void log(Params&&... params) const
820  {
821  propagate_log_helper<Event, ConcreteLoggable>::propagate_log(
822  static_cast<const ConcreteLoggable*>(this),
823  std::forward<Params>(params)...);
824  for (auto& logger : loggers_) {
825  logger->template on<Event>(std::forward<Params>(params)...);
826  }
827  }
828 
829  std::vector<std::shared_ptr<const Logger>> loggers_;
830 };
831 
832 
833 } // namespace log
834 } // namespace gko
835 
836 
837 #endif // GKO_PUBLIC_CORE_LOG_LOGGER_HPP_
gko::uint8
std::uint8_t uint8
8-bit unsigned integral type.
Definition: types.hpp:137
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:118
gko::OutOfBoundsError
OutOfBoundsError is thrown if a memory access is detected to be out-of-bounds.
Definition: exception.hpp:559
gko::log::Logger::executor_events_mask
static constexpr mask_type executor_events_mask
Bitset Mask which activates all executor events.
Definition: logger.hpp:589
gko::PolymorphicObject
A PolymorphicObject is the abstract base for all "heavy" objects in Ginkgo that behave polymorphicall...
Definition: polymorphic_object.hpp:44
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:160
gko::size_type
std::size_t size_type
Integral type used for allocation quantities.
Definition: types.hpp:108
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:615
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:199
gko::log::Loggable
Loggable class is an interface which should be implemented by classes wanting to support logging.
Definition: logger.hpp:696
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:629
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:27
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:636
gko::log::EnableLogging
EnableLogging is a mixin which should be inherited by any class which wants to enable logging.
Definition: logger.hpp:749
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:597
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:643
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:622
gko::LinOpFactory
A LinOpFactory represents a higher order mapping which transforms one linear operator into another.
Definition: lin_op.hpp:385
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:603
gko::uint64
std::uint64_t uint64
64-bit unsigned integral type.
Definition: types.hpp:154
gko::Operation
Operations can be used to define functionalities whose implementations differ among devices.
Definition: executor.hpp:259