Ginkgo Generated from branch based on master. Ginkgo version 1.8.0
A numerical linear algebra library targeting many-core architectures
Loading...
Searching...
No Matches
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
20namespace gko {
21
22
23/* Eliminate circular dependencies the hard way */
24template <typename ValueType>
25class array;
26class Executor;
27class LinOp;
28class LinOpFactory;
30class Operation;
31class stopping_status;
32
33
34namespace batch {
35
36
37class BatchLinOp;
38class BatchLinOpFactory;
39
40template <typename ValueType>
42
43
44} // namespace batch
45
46
52namespace stop {
53class Criterion;
54} // namespace stop
55
56
57namespace log {
58
59
76class Logger {
77public:
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, ...) \
113protected: \
114 virtual void on_##_event_name(__VA_ARGS__) const {} \
115 \
116public: \
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,
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)
381protected:
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
411public:
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
424protected:
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
498public:
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
547public:
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
560protected:
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
583public:
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
647protected:
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
686private:
687 mask_type enabled_events_;
688};
689
690
696class Loggable {
697public:
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
748template <typename ConcreteLoggable, typename PolymorphicBase = Loggable>
749class EnableLogging : public PolymorphicBase {
750public:
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
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
782private:
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
817protected:
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_
The first step in using the Ginkgo library consists of creating an executor.
Definition executor.hpp:616
A LinOpFactory represents a higher order mapping which transforms one linear operator into another.
Definition lin_op.hpp:386
Definition lin_op.hpp:118
Operations can be used to define functionalities whose implementations differ among devices.
Definition executor.hpp:259
OutOfBoundsError is thrown if a memory access is detected to be out-of-bounds.
Definition exception.hpp:559
A PolymorphicObject is the abstract base for all "heavy" objects in Ginkgo that behave polymorphicall...
Definition polymorphic_object.hpp:44
An array is a container which encapsulates fixed-sized arrays, stored on the Executor tied to the arr...
Definition logger.hpp:25
MultiVector stores multiple vectors in a batched fashion and is useful for batched operations.
Definition logger.hpp:41
EnableLogging is a mixin which should be inherited by any class which wants to enable logging.
Definition logger.hpp:749
void clear_loggers() override
Remove all loggers registered at this object.
Definition logger.hpp:780
const std::vector< std::shared_ptr< const Logger > > & get_loggers() const override
Returns the vector containing all loggers registered at this object.
Definition logger.hpp:774
void add_logger(std::shared_ptr< const Logger > logger) override
Adds a new logger to the list of subscribed loggers.
Definition logger.hpp:751
void remove_logger(const Logger *logger) override
Removes a logger from the list of subscribed loggers.
Definition logger.hpp:756
Loggable class is an interface which should be implemented by classes wanting to support logging.
Definition logger.hpp:696
virtual const std::vector< std::shared_ptr< const Logger > > & get_loggers() const =0
Returns the vector containing all loggers registered at this object.
virtual void clear_loggers()=0
Remove all loggers registered at this object.
virtual void remove_logger(const Logger *logger)=0
Removes a logger from the list of subscribed loggers.
virtual void add_logger(std::shared_ptr< const Logger > logger)=0
Adds a new logger to the list of subscribed loggers.
Definition logger.hpp:76
static constexpr mask_type all_events_mask
Bitset Mask which activates all events.
Definition logger.hpp:89
static constexpr mask_type operation_events_mask
Bitset Mask which activates all operation events.
Definition logger.hpp:597
static constexpr mask_type batch_linop_factory_events_mask
Bitset Mask which activates all batch linop factory events.
Definition logger.hpp:629
static constexpr mask_type linop_events_mask
Bitset Mask which activates all linop events.
Definition logger.hpp:615
static constexpr mask_type polymorphic_object_events_mask
Bitset Mask which activates all polymorphic object events.
Definition logger.hpp:603
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
static constexpr mask_type criterion_events_mask
Bitset Mask which activates all criterion events.
Definition logger.hpp:636
static constexpr size_type event_count_max
Maximum amount of events (bits) with the current implementation.
Definition logger.hpp:84
static constexpr mask_type linop_factory_events_mask
Bitset Mask which activates all linop factory events.
Definition logger.hpp:622
static constexpr mask_type executor_events_mask
Bitset Mask which activates all executor events.
Definition logger.hpp:589
This class is used for function parameters in the place of raw pointers.
Definition utils_helper.hpp:43
T * get() const
Definition utils_helper.hpp:77
The Criterion class is a base class for all stopping criteria.
Definition criterion.hpp:36
This class is used to keep track of the stopping status of one vector.
Definition stopping_status.hpp:21
@ criterion
Stopping criterion events.
@ factory
LinOpFactory events.
The Ginkgo namespace.
Definition abstract_factory.hpp:20
std::uint8_t uint8
8-bit unsigned integral type.
Definition types.hpp:115
std::uint64_t uint64
64-bit unsigned integral type.
Definition types.hpp:132
std::uintptr_t uintptr
Unsigned integer type capable of holding a pointer to void.
Definition types.hpp:138
std::size_t size_type
Integral type used for allocation quantities.
Definition types.hpp:86
constexpr size_type byte_size
Number of bits in a byte.
Definition types.hpp:177
@ array
The matrix should be written as dense matrix in column-major order.