Ginkgo  Generated from pipelines/2662685947 branch based on develop. Ginkgo version 2.0.0
A numerical linear algebra library targeting many-core architectures
record.hpp
1 // SPDX-FileCopyrightText: 2017 - 2026 The Ginkgo authors
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 #ifndef GKO_PUBLIC_CORE_LOG_RECORD_HPP_
6 #define GKO_PUBLIC_CORE_LOG_RECORD_HPP_
7 
8 
9 #include <deque>
10 #include <memory>
11 
12 #include <ginkgo/core/log/logger.hpp>
13 #include <ginkgo/core/matrix/dense.hpp>
14 #include <ginkgo/core/stop/criterion.hpp>
15 
16 
17 namespace gko {
18 
24 namespace log {
25 namespace detail {
26 
27 
28 template <typename T>
29 std::unique_ptr<T> clone_or_nullptr(T* input)
30 {
31  // whether throw exception if input is not cloneable?
32  if (auto tmp = dynamic_cast<const Cloneable*>(input)) {
33  return as<T>(tmp->clone());
34  }
35  return nullptr;
36 }
37 
38 
39 } // namespace detail
40 
41 
46  std::unique_ptr<const LinOp> solver;
47  std::unique_ptr<const LinOp> right_hand_side;
48  std::unique_ptr<const LinOp> solution;
49  const size_type num_iterations;
50  std::unique_ptr<const LinOp> residual;
51  std::unique_ptr<const LinOp> residual_norm;
52  std::unique_ptr<const LinOp> implicit_sq_residual_norm;
54  bool all_stopped;
55 
56  iteration_complete_data(const LinOp* solver, const LinOp* right_hand_side,
57  const LinOp* solution,
58  const size_type num_iterations,
59  const LinOp* residual = nullptr,
60  const LinOp* residual_norm = nullptr,
61  const LinOp* implicit_sq_residual_norm = nullptr,
62  const gko::array<stopping_status>* status = nullptr,
63  bool all_stopped = false)
64  : num_iterations{num_iterations}, all_stopped(all_stopped)
65  {
66  this->solver = detail::clone_or_nullptr(solver);
67  this->solution = detail::clone_or_nullptr(solution);
68  if (right_hand_side != nullptr) {
69  this->right_hand_side = detail::clone_or_nullptr(right_hand_side);
70  }
71  if (residual != nullptr) {
72  this->residual = detail::clone_or_nullptr(residual);
73  }
74  if (residual_norm != nullptr) {
75  this->residual_norm = detail::clone_or_nullptr(residual_norm);
76  }
77  if (implicit_sq_residual_norm != nullptr) {
78  this->implicit_sq_residual_norm =
79  detail::clone_or_nullptr(implicit_sq_residual_norm);
80  }
81  if (status != nullptr) {
82  this->status = *status;
83  }
84  }
85 };
86 
87 
91 struct executor_data {
92  const Executor* exec;
93  const size_type num_bytes;
94  const uintptr location;
95 };
96 
97 
102  const Executor* exec;
103  const Operation* operation;
104 };
105 
106 
111  const Executor* exec;
112  std::unique_ptr<const PolymorphicObject> input;
113  std::unique_ptr<const PolymorphicObject> output; // optional
114 
115  polymorphic_object_data(const Executor* exec,
116  const PolymorphicObject* input,
117  const PolymorphicObject* output = nullptr)
118  : exec{exec}
119  {
120  this->input = detail::clone_or_nullptr(input);
121  if (output != nullptr) {
122  this->output = detail::clone_or_nullptr(output);
123  }
124  }
125 };
126 
127 
131 struct linop_data {
132  std::unique_ptr<const LinOp> A;
133  std::unique_ptr<const LinOp> alpha;
134  std::unique_ptr<const LinOp> b;
135  std::unique_ptr<const LinOp> beta;
136  std::unique_ptr<const LinOp> x;
137 
138  linop_data(const LinOp* A, const LinOp* alpha, const LinOp* b,
139  const LinOp* beta, const LinOp* x)
140  {
141  this->A = detail::clone_or_nullptr(A);
142  if (alpha != nullptr) {
143  this->alpha = detail::clone_or_nullptr(alpha);
144  }
145  this->b = detail::clone_or_nullptr(b);
146  if (beta != nullptr) {
147  this->beta = detail::clone_or_nullptr(beta);
148  }
149  this->x = detail::clone_or_nullptr(x);
150  }
151 };
152 
153 
158  const LinOpFactory* factory;
159  std::unique_ptr<const LinOp> input;
160  std::unique_ptr<const LinOp> output;
161 
162  linop_factory_data(const LinOpFactory* factory, const LinOp* input,
163  const LinOp* output)
164  : factory{factory}
165  {
166  this->input = detail::clone_or_nullptr(input);
167  if (output != nullptr) {
168  this->output = detail::clone_or_nullptr(output);
169  }
170  }
171 };
172 
173 
178  const stop::Criterion* criterion;
179  const size_type num_iterations;
180  std::unique_ptr<const LinOp> residual;
181  std::unique_ptr<const LinOp> residual_norm;
182  std::unique_ptr<const LinOp> solution;
183  const uint8 stopping_id;
184  const bool set_finalized;
185  const array<stopping_status>* status;
186  const bool oneChanged;
187  const bool converged;
188 
190  const size_type& num_iterations, const LinOp* residual,
191  const LinOp* residual_norm, const LinOp* solution,
192  const uint8 stopping_id, const bool set_finalized,
193  const array<stopping_status>* status = nullptr,
194  const bool oneChanged = false, const bool converged = false)
195  : criterion{criterion},
196  num_iterations{num_iterations},
197  residual{nullptr},
198  residual_norm{nullptr},
199  solution{nullptr},
200  stopping_id{stopping_id},
201  set_finalized{set_finalized},
202  status{status},
203  oneChanged{oneChanged},
204  converged{converged}
205  {
206  if (residual != nullptr) {
207  this->residual = detail::clone_or_nullptr(residual);
208  }
209  if (residual_norm != nullptr) {
210  this->residual_norm = detail::clone_or_nullptr(residual_norm);
211  }
212  if (solution != nullptr) {
213  this->solution = detail::clone_or_nullptr(solution);
214  }
215  }
216 };
217 
218 
229 class Record : public Logger {
230 public:
234  struct logged_data {
235  std::deque<std::unique_ptr<executor_data>> allocation_started;
236  std::deque<std::unique_ptr<executor_data>> allocation_completed;
237  std::deque<std::unique_ptr<executor_data>> free_started;
238  std::deque<std::unique_ptr<executor_data>> free_completed;
239  std::deque<std::unique_ptr<std::tuple<executor_data, executor_data>>>
240  copy_started;
241  std::deque<std::unique_ptr<std::tuple<executor_data, executor_data>>>
242  copy_completed;
243 
244  std::deque<std::unique_ptr<operation_data>> operation_launched;
245  std::deque<std::unique_ptr<operation_data>> operation_completed;
246 
247  std::deque<std::unique_ptr<polymorphic_object_data>>
248  polymorphic_object_create_started;
249  std::deque<std::unique_ptr<polymorphic_object_data>>
250  polymorphic_object_create_completed;
251  std::deque<std::unique_ptr<polymorphic_object_data>>
252  polymorphic_object_copy_started;
253  std::deque<std::unique_ptr<polymorphic_object_data>>
254  polymorphic_object_copy_completed;
255  std::deque<std::unique_ptr<polymorphic_object_data>>
256  polymorphic_object_move_started;
257  std::deque<std::unique_ptr<polymorphic_object_data>>
258  polymorphic_object_move_completed;
259  std::deque<std::unique_ptr<polymorphic_object_data>>
260  polymorphic_object_deleted;
261 
262  std::deque<std::unique_ptr<linop_data>> linop_apply_started;
263  std::deque<std::unique_ptr<linop_data>> linop_apply_completed;
264  std::deque<std::unique_ptr<linop_data>> linop_advanced_apply_started;
265  std::deque<std::unique_ptr<linop_data>> linop_advanced_apply_completed;
266  std::deque<std::unique_ptr<linop_factory_data>>
267  linop_factory_generate_started;
268  std::deque<std::unique_ptr<linop_factory_data>>
269  linop_factory_generate_completed;
270 
271  std::deque<std::unique_ptr<criterion_data>> criterion_check_started;
272  std::deque<std::unique_ptr<criterion_data>> criterion_check_completed;
273 
274  std::deque<std::unique_ptr<iteration_complete_data>>
275  iteration_completed;
276  };
277 
278  /* Executor events */
279  void on_allocation_started(const Executor* exec,
280  const size_type& num_bytes) const override;
281 
282  void on_allocation_completed(const Executor* exec,
283  const size_type& num_bytes,
284  const uintptr& location) const override;
285 
286  void on_free_started(const Executor* exec,
287  const uintptr& location) const override;
288 
289  void on_free_completed(const Executor* exec,
290  const uintptr& location) const override;
291 
292  void on_copy_started(const Executor* from, const Executor* to,
293  const uintptr& location_from,
294  const uintptr& location_to,
295  const size_type& num_bytes) const override;
296 
297  void on_copy_completed(const Executor* from, const Executor* to,
298  const uintptr& location_from,
299  const uintptr& location_to,
300  const size_type& num_bytes) const override;
301 
302  /* Operation events */
303  void on_operation_launched(const Executor* exec,
304  const Operation* operation) const override;
305 
306  void on_operation_completed(const Executor* exec,
307  const Operation* operation) const override;
308 
309  /* PolymorphicObject events */
311  const Executor* exec, const PolymorphicObject* po) const override;
312 
314  const Executor* exec, const PolymorphicObject* input,
315  const PolymorphicObject* output) const override;
316 
318  const Executor* exec, const PolymorphicObject* from,
319  const PolymorphicObject* to) const override;
320 
322  const Executor* exec, const PolymorphicObject* from,
323  const PolymorphicObject* to) const override;
324 
326  const Executor* exec, const PolymorphicObject* from,
327  const PolymorphicObject* to) const override;
328 
330  const Executor* exec, const PolymorphicObject* from,
331  const PolymorphicObject* to) const override;
332 
334  const Executor* exec, const PolymorphicObject* po) const override;
335 
336  /* LinOp events */
337  void on_linop_apply_started(const LinOp* A, const LinOp* b,
338  const LinOp* x) const override;
339 
340  void on_linop_apply_completed(const LinOp* A, const LinOp* b,
341  const LinOp* x) const override;
342 
343  void on_linop_advanced_apply_started(const LinOp* A, const LinOp* alpha,
344  const LinOp* b, const LinOp* beta,
345  const LinOp* x) const override;
346 
347  void on_linop_advanced_apply_completed(const LinOp* A, const LinOp* alpha,
348  const LinOp* b, const LinOp* beta,
349  const LinOp* x) const override;
350 
351  /* LinOpFactory events */
353  const LinOp* input) const override;
354 
356  const LinOpFactory* factory, const LinOp* input,
357  const LinOp* output) const override;
358 
359  /* Criterion events */
361  const size_type& num_iterations,
362  const LinOp* residual,
363  const LinOp* residual_norm,
364  const LinOp* solution,
365  const uint8& stopping_id,
366  const bool& set_finalized) const override;
367 
369  const stop::Criterion* criterion, const size_type& num_iterations,
370  const LinOp* residual, const LinOp* residual_norm,
371  const LinOp* implicit_residual_norm_sq, const LinOp* solution,
372  const uint8& stopping_id, const bool& set_finalized,
373  const array<stopping_status>* status, const bool& one_changed,
374  const bool& all_converged) const override;
375 
377  const stop::Criterion* criterion, const size_type& num_iterations,
378  const LinOp* residual, const LinOp* residual_norm,
379  const LinOp* solution, const uint8& stopping_id,
380  const bool& set_finalized, const array<stopping_status>* status,
381  const bool& one_changed, const bool& all_converged) const override;
382 
383  /* Internal solver events */
385  const LinOp* solver, const LinOp* right_hand_side, const LinOp* x,
386  const size_type& num_iterations, const LinOp* residual,
387  const LinOp* residual_norm, const LinOp* implicit_resnorm_sq,
388  const array<stopping_status>* status, bool stopped) const override;
389 
390  GKO_DEPRECATED(
391  "Please use the version with the additional stopping "
392  "information.")
393  void on_iteration_complete(const LinOp* solver,
394  const size_type& num_iterations,
395  const LinOp* residual, const LinOp* solution,
396  const LinOp* residual_norm) const override;
397 
398  GKO_DEPRECATED(
399  "Please use the version with the additional stopping "
400  "information.")
402  const LinOp* solver, const size_type& num_iterations,
403  const LinOp* residual, const LinOp* solution,
404  const LinOp* residual_norm,
405  const LinOp* implicit_sq_residual_norm) const override;
406 
421  GKO_DEPRECATED("use two-parameter create")
422  static std::unique_ptr<Record> create(
423  std::shared_ptr<const Executor> exec,
424  const mask_type& enabled_events = Logger::all_events_mask,
425  size_type max_storage = 1)
426  {
427  return std::unique_ptr<Record>(new Record(enabled_events, max_storage));
428  }
429 
444  static std::unique_ptr<Record> create(
445  const mask_type& enabled_events = Logger::all_events_mask,
446  size_type max_storage = 1)
447  {
448  return std::unique_ptr<Record>(new Record(enabled_events, max_storage));
449  }
450 
456  const logged_data& get() const noexcept { return data_; }
457 
461  logged_data& get() noexcept { return data_; }
462 
463 protected:
475  GKO_DEPRECATED("use two-parameter constructor")
476  explicit Record(std::shared_ptr<const gko::Executor> exec,
477  const mask_type& enabled_events = Logger::all_events_mask,
478  size_type max_storage = 0)
479  : Record(enabled_events, max_storage)
480  {}
481 
492  explicit Record(const mask_type& enabled_events = Logger::all_events_mask,
493  size_type max_storage = 0)
494  : Logger(enabled_events), max_storage_{max_storage}
495  {}
496 
505  template <typename deque_type>
506  void append_deque(std::deque<deque_type>& deque, deque_type object) const
507  {
508  if (this->max_storage_ && deque.size() == this->max_storage_) {
509  deque.pop_front();
510  }
511  deque.push_back(std::move(object));
512  }
513 
514 private:
515  mutable logged_data data_{};
516  size_type max_storage_{};
517 };
518 
519 
520 } // namespace log
521 } // namespace gko
522 
523 
524 #endif // GKO_PUBLIC_CORE_LOG_RECORD_HPP_
gko::uint8
std::uint8_t uint8
8-bit unsigned integral type.
Definition: types.hpp:119
gko::log::profile_event_category::solver
Solver events.
gko::log::Record::on_free_completed
void on_free_completed(const Executor *exec, const uintptr &location) const override
Executor's free completed event.
gko::log::Record::create
static std::unique_ptr< Record > create(const mask_type &enabled_events=Logger::all_events_mask, size_type max_storage=1)
Creates a Record logger.
Definition: record.hpp:444
gko::LinOp
Definition: lin_op.hpp:117
gko::log::Record::on_iteration_complete
void on_iteration_complete(const LinOp *solver, const LinOp *right_hand_side, const LinOp *x, const size_type &num_iterations, const LinOp *residual, const LinOp *residual_norm, const LinOp *implicit_resnorm_sq, const array< stopping_status > *status, bool stopped) const override
Register the iteration_complete event which logs every completed iterations.
gko::log::linop_data
Struct representing LinOp related data.
Definition: record.hpp:131
gko::log::polymorphic_object_data
Struct representing PolymorphicObject related data.
Definition: record.hpp:110
gko::log::Record::create
static std::unique_ptr< Record > create(std::shared_ptr< const Executor > exec, const mask_type &enabled_events=Logger::all_events_mask, size_type max_storage=1)
Creates a Record logger.
Definition: record.hpp:422
gko::PolymorphicObject
A PolymorphicObject is the abstract base for all "heavy" objects in Ginkgo that behave polymorphicall...
Definition: polymorphic_object.hpp:46
gko::log::profile_event_category::factory
LinOpFactory events.
gko::log::Record::on_polymorphic_object_deleted
void on_polymorphic_object_deleted(const Executor *exec, const PolymorphicObject *po) const override
PolymorphicObject's deleted event.
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::log::Record::get
logged_data & get() noexcept
Definition: record.hpp:461
gko::log::operation_data
Struct representing Operator related data.
Definition: record.hpp:101
gko::log::Record::on_copy_started
void on_copy_started(const Executor *from, const Executor *to, const uintptr &location_from, const uintptr &location_to, const size_type &num_bytes) const override
Executor's copy started event.
gko::log::Record::on_copy_completed
void on_copy_completed(const Executor *from, const Executor *to, const uintptr &location_from, const uintptr &location_to, const size_type &num_bytes) const override
Executor's copy completed event.
gko::log::Record::on_polymorphic_object_create_started
void on_polymorphic_object_create_started(const Executor *exec, const PolymorphicObject *po) const override
PolymorphicObject's create started event.
gko
The Ginkgo namespace.
Definition: abstract_factory.hpp:20
gko::log::Record::on_operation_launched
void on_operation_launched(const Executor *exec, const Operation *operation) const override
Executor's operation launched event (method run).
gko::log::Record::on_criterion_check_completed
void on_criterion_check_completed(const stop::Criterion *criterion, const size_type &num_iterations, const LinOp *residual, const LinOp *residual_norm, const LinOp *implicit_residual_norm_sq, const LinOp *solution, const uint8 &stopping_id, const bool &set_finalized, const array< stopping_status > *status, const bool &one_changed, const bool &all_converged) const override
stop::Criterion's check completed event.
gko::log::criterion_data
Struct representing Criterion related data.
Definition: record.hpp:177
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::version
This structure is used to represent versions of various Ginkgo modules.
Definition: version.hpp:25
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::Record
Record is a Logger which logs every event to an object.
Definition: record.hpp:229
gko::log::iteration_complete_data
Struct representing iteration complete related data.
Definition: record.hpp:45
gko::log::Record::logged_data
Struct storing the actually logged data.
Definition: record.hpp:234
gko::log::Record::on_linop_advanced_apply_completed
void on_linop_advanced_apply_completed(const LinOp *A, const LinOp *alpha, const LinOp *b, const LinOp *beta, const LinOp *x) const override
LinOp's advanced apply completed event.
gko::log::Record::on_linop_factory_generate_completed
void on_linop_factory_generate_completed(const LinOpFactory *factory, const LinOp *input, const LinOp *output) const override
LinOp Factory's generate completed event.
gko::log::Logger
Definition: logger.hpp:76
gko::log::Record::on_polymorphic_object_copy_completed
void on_polymorphic_object_copy_completed(const Executor *exec, const PolymorphicObject *from, const PolymorphicObject *to) const override
PolymorphicObject's copy completed event.
gko::log::Record::on_linop_advanced_apply_started
void on_linop_advanced_apply_started(const LinOp *A, const LinOp *alpha, const LinOp *b, const LinOp *beta, const LinOp *x) const override
LinOp's advanced apply started event.
gko::log::executor_data
Struct representing Executor related data.
Definition: record.hpp:91
gko::stop::Criterion
The Criterion class is a base class for all stopping criteria.
Definition: criterion.hpp:36
gko::log::Record::on_linop_apply_started
void on_linop_apply_started(const LinOp *A, const LinOp *b, const LinOp *x) const override
LinOp's apply started event.
gko::log::Record::on_allocation_completed
void on_allocation_completed(const Executor *exec, const size_type &num_bytes, const uintptr &location) const override
Executor's allocation completed event.
gko::log::Record::on_free_started
void on_free_started(const Executor *exec, const uintptr &location) const override
Executor's free started event.
gko::log::Record::on_polymorphic_object_create_completed
void on_polymorphic_object_create_completed(const Executor *exec, const PolymorphicObject *input, const PolymorphicObject *output) const override
PolymorphicObject's create completed event.
gko::log::Record::on_polymorphic_object_move_completed
void on_polymorphic_object_move_completed(const Executor *exec, const PolymorphicObject *from, const PolymorphicObject *to) const override
PolymorphicObject's move completed event.
gko::log::profile_event_category::operation
Kernel execution and data movement.
gko::Executor
The first step in using the Ginkgo library consists of creating an executor.
Definition: executor.hpp:616
gko::log::Record::on_operation_completed
void on_operation_completed(const Executor *exec, const Operation *operation) const override
Executor's operation completed event (method run).
gko::log::Record::on_criterion_check_started
void on_criterion_check_started(const stop::Criterion *criterion, const size_type &num_iterations, const LinOp *residual, const LinOp *residual_norm, const LinOp *solution, const uint8 &stopping_id, const bool &set_finalized) const override
stop::Criterion's check started event.
gko::log::linop_factory_data
Struct representing LinOp factory related data.
Definition: record.hpp:157
gko::log::Record::on_linop_factory_generate_started
void on_linop_factory_generate_started(const LinOpFactory *factory, const LinOp *input) const override
LinOp Factory's generate started event.
gko::log::Record::on_polymorphic_object_copy_started
void on_polymorphic_object_copy_started(const Executor *exec, const PolymorphicObject *from, const PolymorphicObject *to) const override
PolymorphicObject's copy started event.
gko::LinOpFactory
A LinOpFactory represents a higher order mapping which transforms one linear operator into another.
Definition: lin_op.hpp:343
gko::log::Record::on_linop_apply_completed
void on_linop_apply_completed(const LinOp *A, const LinOp *b, const LinOp *x) const override
LinOp's apply completed event.
gko::Operation
Operations can be used to define functionalities whose implementations differ among devices.
Definition: executor.hpp:258
gko::log::Record::on_polymorphic_object_move_started
void on_polymorphic_object_move_started(const Executor *exec, const PolymorphicObject *from, const PolymorphicObject *to) const override
PolymorphicObject's move started event.
gko::log::Record::on_allocation_started
void on_allocation_started(const Executor *exec, const size_type &num_bytes) const override
Executor's allocation started event.
gko::log::Record::get
const logged_data & get() const noexcept
Returns the logged data.
Definition: record.hpp:456