Ginkgo  Generated from tags/v1.0.0^0 branch based on master. Ginkgo version 1.0.0
A numerical linear algebra library targeting many-core architectures
record.hpp
1 /*******************************<GINKGO LICENSE>******************************
2 Copyright (c) 2017-2019, the Ginkgo authors
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 
16 3. Neither the name of the copyright holder nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 ******************************<GINKGO LICENSE>*******************************/
32 
33 #ifndef GKO_CORE_LOG_RECORD_HPP_
34 #define GKO_CORE_LOG_RECORD_HPP_
35 
36 
37 #include <ginkgo/core/log/logger.hpp>
38 
39 
40 #include <deque>
41 #include <memory>
42 
43 
44 #include <ginkgo/core/matrix/dense.hpp>
45 #include <ginkgo/core/stop/criterion.hpp>
46 
47 
48 namespace gko {
49 
55 namespace log {
56 
57 
62  std::unique_ptr<const LinOp> solver;
63  const size_type num_iterations;
64  std::unique_ptr<const LinOp> residual;
65  std::unique_ptr<const LinOp> solution;
66  std::unique_ptr<const LinOp> residual_norm;
67 
68  iteration_complete_data(const LinOp *solver, const size_type num_iterations,
69  const LinOp *residual = nullptr,
70  const LinOp *solution = nullptr,
71  const LinOp *residual_norm = nullptr)
72  : solver{nullptr},
73  num_iterations{num_iterations},
74  residual{nullptr},
75  solution{nullptr},
76  residual_norm{nullptr}
77  {
78  this->solver = solver->clone();
79  if (residual != nullptr) {
80  this->residual = residual->clone();
81  }
82  if (solution != nullptr) {
83  this->solution = solution->clone();
84  }
85  if (residual_norm != nullptr) {
86  this->residual_norm = residual_norm->clone();
87  }
88  }
89 };
90 
91 
95 struct executor_data {
96  const Executor *exec;
97  const size_type num_bytes;
98  const uintptr location;
99 };
100 
101 
106  const Executor *exec;
107  const Operation *operation;
108 };
109 
110 
115  const Executor *exec;
116  std::unique_ptr<const PolymorphicObject> input;
117  std::unique_ptr<const PolymorphicObject> output; // optional
118 
119  polymorphic_object_data(const Executor *exec,
120  const PolymorphicObject *input,
121  const PolymorphicObject *output = nullptr)
122  : exec{exec}
123  {
124  this->input = input->clone();
125  if (output != nullptr) {
126  this->output = output->clone();
127  }
128  }
129 };
130 
131 
135 struct linop_data {
136  std::unique_ptr<const LinOp> A;
137  std::unique_ptr<const LinOp> alpha;
138  std::unique_ptr<const LinOp> b;
139  std::unique_ptr<const LinOp> beta;
140  std::unique_ptr<const LinOp> x;
141 
142  linop_data(const LinOp *A, const LinOp *alpha, const LinOp *b,
143  const LinOp *beta, const LinOp *x)
144  {
145  this->A = A->clone();
146  if (alpha != nullptr) {
147  this->alpha = alpha->clone();
148  }
149  this->b = b->clone();
150  if (beta != nullptr) {
151  this->beta = beta->clone();
152  }
153  this->x = x->clone();
154  }
155 };
156 
157 
162  const LinOpFactory *factory;
163  std::unique_ptr<const LinOp> input;
164  std::unique_ptr<const LinOp> output;
165 
166  linop_factory_data(const LinOpFactory *factory, const LinOp *input,
167  const LinOp *output)
168  : factory{factory}
169  {
170  this->input = input->clone();
171  if (output != nullptr) {
172  this->output = output->clone();
173  }
174  }
175 };
176 
177 
182  const stop::Criterion *criterion;
183  const size_type num_iterations;
184  std::unique_ptr<const LinOp> residual;
185  std::unique_ptr<const LinOp> residual_norm;
186  std::unique_ptr<const LinOp> solution;
187  const uint8 stopping_id;
188  const bool set_finalized;
189  const Array<stopping_status> *status;
190  const bool oneChanged;
191  const bool converged;
192 
193  criterion_data(const stop::Criterion *criterion,
194  const size_type &num_iterations, const LinOp *residual,
195  const LinOp *residual_norm, const LinOp *solution,
196  const uint8 stopping_id, const bool set_finalized,
197  const Array<stopping_status> *status = nullptr,
198  const bool oneChanged = false, const bool converged = false)
199  : criterion{criterion},
200  num_iterations{num_iterations},
201  residual{nullptr},
202  residual_norm{nullptr},
203  solution{nullptr},
204  stopping_id{stopping_id},
205  set_finalized{set_finalized},
206  status{status},
207  oneChanged{oneChanged},
208  converged{converged}
209  {
210  if (residual != nullptr) {
211  this->residual = std::unique_ptr<const LinOp>(residual->clone());
212  }
213  if (residual_norm != nullptr) {
214  this->residual_norm =
215  std::unique_ptr<const LinOp>(residual_norm->clone());
216  }
217  if (solution != nullptr) {
218  this->solution = std::unique_ptr<const LinOp>(solution->clone());
219  }
220  }
221 };
222 
223 
234 class Record : public Logger {
235 public:
239  struct logged_data {
240  std::deque<std::unique_ptr<executor_data>> allocation_started;
241  std::deque<std::unique_ptr<executor_data>> allocation_completed;
242  std::deque<std::unique_ptr<executor_data>> free_started;
243  std::deque<std::unique_ptr<executor_data>> free_completed;
244  std::deque<std::unique_ptr<std::tuple<executor_data, executor_data>>>
245  copy_started;
246  std::deque<std::unique_ptr<std::tuple<executor_data, executor_data>>>
247  copy_completed;
248 
249  std::deque<std::unique_ptr<operation_data>> operation_launched;
250  std::deque<std::unique_ptr<operation_data>> operation_completed;
251 
252  std::deque<std::unique_ptr<polymorphic_object_data>>
253  polymorphic_object_create_started;
254  std::deque<std::unique_ptr<polymorphic_object_data>>
255  polymorphic_object_create_completed;
256  std::deque<std::unique_ptr<polymorphic_object_data>>
257  polymorphic_object_copy_started;
258  std::deque<std::unique_ptr<polymorphic_object_data>>
259  polymorphic_object_copy_completed;
260  std::deque<std::unique_ptr<polymorphic_object_data>>
261  polymorphic_object_deleted;
262 
263  std::deque<std::unique_ptr<linop_data>> linop_apply_started;
264  std::deque<std::unique_ptr<linop_data>> linop_apply_completed;
265  std::deque<std::unique_ptr<linop_data>> linop_advanced_apply_started;
266  std::deque<std::unique_ptr<linop_data>> linop_advanced_apply_completed;
267  std::deque<std::unique_ptr<linop_factory_data>>
268  linop_factory_generate_started;
269  std::deque<std::unique_ptr<linop_factory_data>>
270  linop_factory_generate_completed;
271 
272  std::deque<std::unique_ptr<criterion_data>> criterion_check_started;
273  std::deque<std::unique_ptr<criterion_data>> criterion_check_completed;
274 
275  std::deque<std::unique_ptr<iteration_complete_data>>
276  iteration_completed;
277  };
278 
279  /* Executor events */
280  void on_allocation_started(const Executor *exec,
281  const size_type &num_bytes) const override;
282 
283  void on_allocation_completed(const Executor *exec,
284  const size_type &num_bytes,
285  const uintptr &location) const override;
286 
287  void on_free_started(const Executor *exec,
288  const uintptr &location) const override;
289 
290  void on_free_completed(const Executor *exec,
291  const uintptr &location) const override;
292 
293  void on_copy_started(const Executor *from, const Executor *to,
294  const uintptr &location_from,
295  const uintptr &location_to,
296  const size_type &num_bytes) const override;
297 
298  void on_copy_completed(const Executor *from, const Executor *to,
299  const uintptr &location_from,
300  const uintptr &location_to,
301  const size_type &num_bytes) const override;
302 
303  /* Operation events */
304  void on_operation_launched(const Executor *exec,
305  const Operation *operation) const override;
306 
307  void on_operation_completed(const Executor *exec,
308  const Operation *operation) const override;
309 
310  /* PolymorphicObject events */
311  void on_polymorphic_object_create_started(
312  const Executor *exec, const PolymorphicObject *po) const override;
313 
314  void on_polymorphic_object_create_completed(
315  const Executor *exec, const PolymorphicObject *input,
316  const PolymorphicObject *output) const override;
317 
318  void on_polymorphic_object_copy_started(
319  const Executor *exec, const PolymorphicObject *from,
320  const PolymorphicObject *to) const override;
321 
322  void on_polymorphic_object_copy_completed(
323  const Executor *exec, const PolymorphicObject *from,
324  const PolymorphicObject *to) const override;
325 
326  void on_polymorphic_object_deleted(
327  const Executor *exec, const PolymorphicObject *po) const override;
328 
329  /* LinOp events */
330  void on_linop_apply_started(const LinOp *A, const LinOp *b,
331  const LinOp *x) const override;
332 
333  void on_linop_apply_completed(const LinOp *A, const LinOp *b,
334  const LinOp *x) const override;
335 
336  void on_linop_advanced_apply_started(const LinOp *A, const LinOp *alpha,
337  const LinOp *b, const LinOp *beta,
338  const LinOp *x) const override;
339 
340  void on_linop_advanced_apply_completed(const LinOp *A, const LinOp *alpha,
341  const LinOp *b, const LinOp *beta,
342  const LinOp *x) const override;
343 
344  /* LinOpFactory events */
345  void on_linop_factory_generate_started(const LinOpFactory *factory,
346  const LinOp *input) const override;
347 
348  void on_linop_factory_generate_completed(
349  const LinOpFactory *factory, const LinOp *input,
350  const LinOp *output) const override;
351 
352  /* Criterion events */
353  void on_criterion_check_started(const stop::Criterion *criterion,
354  const size_type &num_iterations,
355  const LinOp *residual,
356  const LinOp *residual_norm,
357  const LinOp *solution,
358  const uint8 &stopping_id,
359  const bool &set_finalized) const override;
360 
361  void on_criterion_check_completed(
362  const stop::Criterion *criterion, const size_type &num_iterations,
363  const LinOp *residual, const LinOp *residual_norm,
364  const LinOp *solution, const uint8 &stopping_id,
365  const bool &set_finalized, const Array<stopping_status> *status,
366  const bool &one_changed, const bool &all_converged) const override;
367 
368  /* Internal solver events */
369  void on_iteration_complete(
370  const LinOp *solver, const size_type &num_iterations,
371  const LinOp *residual, const LinOp *solution = nullptr,
372  const LinOp *residual_norm = nullptr) const override;
373 
374 
393  static std::unique_ptr<Record> create(
394  std::shared_ptr<const Executor> exec,
395  const mask_type &enabled_events = Logger::all_events_mask,
396  size_type max_storage = 1)
397  {
398  return std::unique_ptr<Record>(
399  new Record(exec, enabled_events, max_storage));
400  }
401 
407  const logged_data &get() const noexcept { return data_; }
408 
412  logged_data &get() noexcept { return data_; }
413 
414 protected:
426  explicit Record(std::shared_ptr<const gko::Executor> exec,
427  const mask_type &enabled_events = Logger::all_events_mask,
428  size_type max_storage = 0)
429  : Logger(exec, enabled_events), max_storage_{max_storage}
430  {}
431 
440  template <typename deque_type>
441  void append_deque(std::deque<deque_type> &deque, deque_type object) const
442  {
443  if (this->max_storage_ && deque.size() == this->max_storage_) {
444  deque.pop_front();
445  }
446  deque.push_back(std::move(object));
447  }
448 
449 private:
450  mutable logged_data data_{};
451  size_type max_storage_{};
452 };
453 
454 
455 } // namespace log
456 } // namespace gko
457 
458 
459 #endif // GKO_CORE_LOG_RECORD_HPP_
Struct representing Operator related data.
Definition: record.hpp:105
Definition: logger.hpp:90
std::unique_ptr< PolymorphicObject > clone(std::shared_ptr< const Executor > exec) const
Creates a clone of the object.
Definition: polymorphic_object.hpp:122
Struct representing iteration complete related data.
Definition: record.hpp:61
Struct representing LinOp factory related data.
Definition: record.hpp:161
A LinOpFactory represents a higher order mapping which transforms one linear operator into another...
Definition: lin_op.hpp:356
Struct representing PolymorphicObject related data.
Definition: record.hpp:114
std::size_t size_type
Integral type used for allocation quantities.
Definition: types.hpp:94
The Ginkgo namespace.
Definition: abstract_factory.hpp:45
A PolymorphicObject is the abstract base for all "heavy" objects in Ginkgo that behave polymorphicall...
Definition: polymorphic_object.hpp:67
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:393
Definition: lin_op.hpp:134
std::uint8_t uint8
8-bit unsigned integral type.
Definition: types.hpp:123
Operations can be used to define functionalities whose implementations differ among devices...
Definition: executor.hpp:173
Struct storing the actually logged data.
Definition: record.hpp:239
An Array is a container which encapsulates fixed-sized arrays, stored on the Executor tied to the Arr...
Definition: array.hpp:63
Struct representing Executor related data.
Definition: record.hpp:95
static constexpr mask_type all_events_mask
Bitset Mask which activates all events.
Definition: logger.hpp:103
The Criterion class is a base class for all stopping criteria.
Definition: criterion.hpp:63
Struct representing Criterion related data.
Definition: record.hpp:181
The first step in using the Ginkgo library consists of creating an executor.
Definition: executor.hpp:410
Record is a Logger which logs every event to an object.
Definition: record.hpp:234
Struct representing LinOp related data.
Definition: record.hpp:135