MFEM  v4.1.0
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
ginkgo.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #ifndef MFEM_GINKGO
13 #define MFEM_GINKGO
14 
15 #include <iomanip>
16 #include <ios>
17 #include <string>
18 #include <vector>
19 #include <fstream>
20 #include <iostream>
21 
22 
23 #include "../config/config.hpp"
24 #include "operator.hpp"
25 #include "sparsemat.hpp"
26 #include "solvers.hpp"
27 
28 #ifdef MFEM_USE_GINKGO
29 #include <ginkgo/ginkgo.hpp>
30 #endif
31 
32 namespace mfem
33 {
34 namespace GinkgoWrappers
35 {
36 // Utility function which gets the scalar value of a Ginkgo gko::matrix::Dense
37 // matrix representing the norm of a vector.
38 template <typename ValueType=double>
39 double get_norm(const gko::matrix::Dense<ValueType> *norm)
40 {
41  // Put the value on CPU thanks to the master executor
42  auto cpu_norm = clone(norm->get_executor()->get_master(), norm);
43  // Return the scalar value contained at position (0, 0)
44  return cpu_norm->at(0, 0);
45 }
46 
47 // Utility function which computes the norm of a Ginkgo gko::matrix::Dense
48 // vector.
49 template <typename ValueType=double>
50 double compute_norm(const gko::matrix::Dense<ValueType> *b)
51 {
52  // Get the executor of the vector
53  auto exec = b->get_executor();
54  // Initialize a result scalar containing the value 0.0.
55  auto b_norm = gko::initialize<gko::matrix::Dense<ValueType>>({0.0}, exec);
56  // Use the dense `compute_norm2` function to compute the norm.
57  b->compute_norm2(lend(b_norm));
58  // Use the other utility function to return the norm contained in `b_norm``
59  return std::pow(get_norm(lend(b_norm)),2);
60 }
61 
62 /**
63  * Custom logger class which intercepts the residual norm scalar and solution
64  * vector in order to print a table of real vs recurrent (internal to the
65  * solvers) residual norms.
66  *
67  * This has been taken from the custom-logger example of Ginkgo. See the
68  * custom-logger example to understand how to write and modify your own loggers
69  * with Ginkgo.
70  *
71  * @ingroup GinkgoWrappers
72  */
73 template <typename ValueType=double>
74 struct ResidualLogger : gko::log::Logger
75 {
76  // Output the logger's data in a table format
77  void write() const
78  {
79  // Print a header for the table
80  mfem::out << "Iteration log with real residual norms:" << std::endl;
81  mfem::out << '|' << std::setw(10) << "Iteration" << '|' << std::setw(25)
82  << "Real Residual Norm" << '|' << std::endl;
83  // Print a separation line. Note that for creating `10` characters
84  // `std::setw()` should be set to `11`.
85  mfem::out << '|' << std::setfill('-') << std::setw(11) << '|' <<
86  std::setw(26) << '|' << std::setfill(' ') << std::endl;
87  // Print the data one by one in the form
88  mfem::out << std::scientific;
89  for (std::size_t i = 0; i < iterations.size(); i++)
90  {
91  mfem::out << '|' << std::setw(10) << iterations[i] << '|'
92  << std::setw(25) << real_norms[i] << '|' << std::endl;
93  }
94  // std::defaultfloat could be used here but some compilers do not support
95  // it properly, e.g. the Intel compiler
96  mfem::out.unsetf(std::ios_base::floatfield);
97  // Print a separation line
98  mfem::out << '|' << std::setfill('-') << std::setw(11) << '|' <<
99  std::setw(26) << '|' << std::setfill(' ') << std::endl;
100  }
101 
102  using gko_dense = gko::matrix::Dense<ValueType>;
103 
104  // Customize the logging hook which is called every time an iteration is
105  // completed
106  void on_iteration_complete(const gko::LinOp *,
107  const gko::size_type &iteration,
108  const gko::LinOp *residual,
109  const gko::LinOp *solution,
110  const gko::LinOp *residual_norm) const override
111  {
112  // // If the solver shares a residual norm, log its value
113  // if (residual_norm)
114  // {
115  // auto dense_norm = gko::as<gko_dense>(residual_norm);
116  // // Add the norm to the `recurrent_norms` vector
117  // recurrent_norms.push_back(get_norm(dense_norm));
118  // // Otherwise, use the recurrent residual vector
119  // }
120  // else
121  // {
122  // auto dense_residual = gko::as<gko_dense>(residual);
123  // // Compute the residual vector's norm
124  // auto norm = compute_norm(gko::lend(dense_residual));
125  // // Add the computed norm to the `recurrent_norms` vector
126  // recurrent_norms.push_back(norm);
127  // }
128 
129  // If the solver shares the current solution vector
130  if (solution)
131  {
132  // Store the matrix's executor
133  auto exec = matrix->get_executor();
134  // Create a scalar containing the value 1.0
135  auto one = gko::initialize<gko_dense>({1.0}, exec);
136  // Create a scalar containing the value -1.0
137  auto neg_one = gko::initialize<gko_dense>({-1.0}, exec);
138  // Instantiate a temporary result variable
139  auto res = gko::clone(b);
140  // Compute the real residual vector by calling apply on the system
141  // matrix
142  matrix->apply(gko::lend(one), gko::lend(solution),
143  gko::lend(neg_one), gko::lend(res));
144 
145  // Compute the norm of the residual vector and add it to the
146  // `real_norms` vector
147  real_norms.push_back(compute_norm(gko::lend(res)));
148  }
149  else
150  {
151  // Add to the `real_norms` vector the value -1.0 if it could not be
152  // computed
153  real_norms.push_back(-1.0);
154  }
155 
156  // Add the current iteration number to the `iterations` vector
157  iterations.push_back(iteration);
158  }
159 
160  // Construct the logger and store the system matrix and b vectors
161  ResidualLogger(std::shared_ptr<const gko::Executor> exec,
162  const gko::LinOp *matrix, const gko_dense *b)
163  : gko::log::Logger(exec,
164  gko::log::Logger::iteration_complete_mask),
165  matrix{matrix},
166  b{b}
167  {}
168 
169 private:
170  // Pointer to the system matrix
171  const gko::LinOp *matrix;
172  // Pointer to the right hand sides
173  const gko_dense *b;
174  // Vector which stores all the recurrent residual norms
175  mutable std::vector<ValueType> recurrent_norms{};
176  // Vector which stores all the real residual norms
177  mutable std::vector<ValueType> real_norms{};
178  // Vector which stores all the iteration numbers
179  mutable std::vector<std::size_t> iterations{};
180 };
181 
182 
183 /**
184 * This class forms the base class for all of Ginkgo's iterative solvers. The
185 * various derived classes only take the additional data that is specific to them
186 * and solve the given linear system. The entire collection of solvers that
187 * Ginkgo implements is available at the Ginkgo documentation and manual pages,
188 * https://ginkgo-project.github.io/ginkgo/doc/develop.
189 *
190 * @ingroup GinkgoWrappers
191 */
193 {
194 public:
195  /**
196  * Constructor.
197  *
198  * The @p exec_type defines the paradigm where the solution is computed.
199  * It is a string and the choices are "omp" , "reference" or "cuda".
200  * The respective strings create the respective executors as given below.
201  *
202  * Ginkgo currently supports three different executor types:
203  *
204  * + OmpExecutor specifies that the data should be stored and the
205  * associated operations executed on an OpenMP-supporting device (e.g.
206  * host CPU);
207  * ```
208  * auto omp = gko::create<gko::OmpExecutor>();
209  * ```
210  * + CudaExecutor specifies that the data should be stored and the
211  * operations executed on the NVIDIA GPU accelerator;
212  * ```
213  * if(gko::CudaExecutor::get_num_devices() > 0 ) {
214  * auto cuda = gko::create<gko::CudaExecutor>();
215  * }
216  * ```
217  * + ReferenceExecutor executes a non-optimized reference implementation,
218  * which can be used to debug the library.
219  * ```
220  * auto ref = gko::create<gko::ReferenceExecutor>();
221  * ```
222  *
223  * The following code snippet demonstrates the using of the OpenMP executor
224  * to create a solver which would use the OpenMP paradigm to the solve the
225  * system on the CPU.
226  *
227  * ```
228  * auto omp = gko::create<gko::OmpExecutor>();
229  * using cg = gko::solver::Cg<>;
230  * auto solver_gen =
231  * cg::build()
232  * .with_criteria(
233  * gko::stop::Iteration::build().with_max_iters(20u).on(omp),
234  * gko::stop::ResidualNormReduction<>::build()
235  * .with_reduction_factor(1e-6)
236  * .on(omp))
237  * .on(omp);
238  * auto solver = solver_gen->generate(system_matrix);
239  *
240  * solver->apply(lend(rhs), lend(solution));
241  * ```
242  */
243  GinkgoIterativeSolverBase(const std::string &exec_type, int print_iter,
244  int max_num_iter, double RTOLERANCE, double ATOLERANCE);
245 
246  /**
247  * Destructor.
248  */
249  virtual ~GinkgoIterativeSolverBase() = default;
250 
251  /**
252  * Initialize the matrix and copy over its data to Ginkgo's data structures.
253  */
254  void
255  initialize(const SparseMatrix *matrix);
256 
257  /**
258  * Solve the linear system <tt>Ax=b</tt>. Dependent on the information
259  * provided by derived classes one of Ginkgo's linear solvers is chosen.
260  */
261  void
262  apply(Vector &solution, const Vector &rhs);
263 
264  /**
265  * Solve the linear system <tt>Ax=b</tt>. Dependent on the information
266  * provided by derived classes one of Ginkgo's linear solvers is chosen.
267  */
268  void
269  solve(const SparseMatrix *matrix,
270  Vector & solution,
271  const Vector & rhs);
272 
273 
274 protected:
276  int max_iter;
277  double rel_tol;
278  double abs_tol;
279  mutable double final_norm;
280  mutable int final_iter;
281  mutable int converged;
282 
283  /**
284  * The Ginkgo generated solver factory object.
285  */
286  std::shared_ptr<gko::LinOpFactory> solver_gen;
287 
288  /**
289  * The residual criterion object that controls the reduction of the residual
290  * based on the tolerance set in the solver_control member.
291  */
292  std::shared_ptr<gko::stop::ResidualNormReduction<>::Factory>
294 
295  /**
296  * The Ginkgo convergence logger used to check for convergence and other
297  * solver data if needed.
298  */
299  std::shared_ptr<gko::log::Convergence<>> convergence_logger;
300 
301  /**
302  * The residual logger object used to check for convergence and other solver
303  * data if needed.
304  */
305  std::shared_ptr<ResidualLogger<>> residual_logger;
306 
307  /**
308  * The Ginkgo combined factory object is used to create a combined stopping
309  * criterion to be passed to the solver.
310  */
311  std::shared_ptr<gko::stop::Combined::Factory> combined_factory;
312 
313  /**
314  * The execution paradigm in Ginkgo. The choices are between
315  * `gko::OmpExecutor`, `gko::CudaExecutor` and `gko::ReferenceExecutor`
316  * and more details can be found in Ginkgo's documentation.
317  */
318  std::shared_ptr<gko::Executor> executor;
319 
320 private:
321  /**
322  * Initialize the Ginkgo logger object with event masks. Refer to the logging
323  * event masks in Ginkgo's .../include/ginkgo/core/log/logger.hpp.
324  */
325  void
326  initialize_ginkgo_log(gko::matrix::Dense<double>* b);
327 
328  /**
329  * Ginkgo matrix data structure. First template parameter is for storing the
330  * array of the non-zeros of the matrix. The second is for the row pointers
331  * and the column indices.
332  *
333  * @todo Templatize based on Matrix type.
334  */
335  std::shared_ptr<gko::matrix::Csr<>> system_matrix;
336 
337  /**
338  * The execution paradigm as a string to be set by the user. The choices are
339  * between `omp`, `cuda` and `reference` and more details can be found in
340  * Ginkgo's documentation.
341  */
342  const std::string exec_type;
343 };
344 
345 
346 /**
347  * An implementation of the solver interface using the Ginkgo CG solver.
348  *
349  * @ingroup GinkgoWrappers
350  */
352 {
353 public:
354  /**
355  * Constructor.
356  *
357  * @param[in] exec_type The execution paradigm for the solver.
358  * @param[in] print_iter A setting to control the printing to the screen.
359  * @param[in] max_num_iter The maximum number of iterations to be run.
360  * @param[in] RTOLERANCE The relative tolerance to be achieved.
361  * @param[in] ATOLERANCE The absolute tolerance to be achieved.
362  */
363  CGSolver(
364  const std::string & exec_type,
365  int print_iter,
366  int max_num_iter,
367  double RTOLERANCE,
368  double ATOLERANCE
369  );
370 
371  /**
372  * Constructor.
373  *
374  * @param[in] exec_type The execution paradigm for the solver.
375  * @param[in] print_iter A setting to control the printing to the screen.
376  * @param[in] max_num_iter The maximum number of iterations to be run.
377  * @param[in] RTOLERANCE The relative tolerance to be achieved.
378  * @param[in] ATOLERANCE The absolute tolerance to be achieved.
379  * @param[in] preconditioner The preconditioner for the solver.
380  */
381  CGSolver(
382  const std::string & exec_type,
383  int print_iter,
384  int max_num_iter,
385  double RTOLERANCE,
386  double ATOLERANCE,
387  const gko::LinOpFactory* preconditioner
388  );
389 };
390 
391 
392 /**
393  * An implementation of the solver interface using the Ginkgo BiCGStab solver.
394  *
395  * @ingroup GinkgoWrappers
396  */
398 {
399 public:
400  /**
401  * Constructor.
402  *
403  * @param[in] exec_type The execution paradigm for the solver.
404  * @param[in] print_iter A setting to control the printing to the screen.
405  * @param[in] max_num_iter The maximum number of iterations to be run.
406  * @param[in] RTOLERANCE The relative tolerance to be achieved.
407  * @param[in] ATOLERANCE The absolute tolerance to be achieved.
408  */
410  const std::string & exec_type,
411  int print_iter,
412  int max_num_iter,
413  double RTOLERANCE,
414  double ATOLERANCE
415  );
416 
417  /**
418  * Constructor.
419  *
420  * @param[in] exec_type The execution paradigm for the solver.
421  * @param[in] print_iter A setting to control the printing to the screen.
422  * @param[in] max_num_iter The maximum number of iterations to be run.
423  * @param[in] RTOLERANCE The relative tolerance to be achieved.
424  * @param[in] ATOLERANCE The absolute tolerance to be achieved.
425  * @param[in] preconditioner The preconditioner for the solver.
426  */
428  const std::string & exec_type,
429  int print_iter,
430  int max_num_iter,
431  double RTOLERANCE,
432  double ATOLERANCE,
433  const gko::LinOpFactory* preconditioner
434  );
435 
436 };
437 
438 /**
439  * An implementation of the solver interface using the Ginkgo CGS solver.
440  *
441  * CGS or the conjugate gradient square method is an iterative type Krylov
442  * subspace method which is suitable for general systems.
443  *
444  * @ingroup GinkgoWrappers
445  */
447 {
448 public:
449  /**
450  * Constructor.
451  *
452  * @param[in] exec_type The execution paradigm for the solver.
453  * @param[in] print_iter A setting to control the printing to the screen.
454  * @param[in] max_num_iter The maximum number of iterations to be run.
455  * @param[in] RTOLERANCE The relative tolerance to be achieved.
456  * @param[in] ATOLERANCE The absolute tolerance to be achieved.
457  */
458  CGSSolver(
459  const std::string & exec_type,
460  int print_iter,
461  int max_num_iter,
462  double RTOLERANCE,
463  double ATOLERANCE
464  );
465 
466  /**
467  * Constructor.
468  *
469  * @param[in] exec_type The execution paradigm for the solver.
470  * @param[in] print_iter A setting to control the printing to the screen.
471  * @param[in] max_num_iter The maximum number of iterations to be run.
472  * @param[in] RTOLERANCE The relative tolerance to be achieved.
473  * @param[in] ATOLERANCE The absolute tolerance to be achieved.
474  * @param[in] preconditioner The preconditioner for the solver.
475  */
476  CGSSolver(
477  const std::string & exec_type,
478  int print_iter,
479  int max_num_iter,
480  double RTOLERANCE,
481  double ATOLERANCE,
482  const gko::LinOpFactory* preconditioner
483  );
484 };
485 
486 /**
487  * An implementation of the solver interface using the Ginkgo FCG solver.
488  *
489  * FCG or the flexible conjugate gradient method is an iterative type Krylov
490  * subspace method which is suitable for symmetric positive definite methods.
491  *
492  * Though this method performs very well for symmetric positive definite
493  * matrices, it is in general not suitable for general matrices.
494  *
495  * In contrast to the standard CG based on the Polack-Ribiere formula, the
496  * flexible CG uses the Fletcher-Reeves formula for creating the orthonormal
497  * vectors spanning the Krylov subspace. This increases the computational cost
498  * of every Krylov solver iteration but allows for non-constant preconditioners.
499  *
500  * @ingroup GinkgoWrappers
501  */
503 {
504 public:
505  /**
506  * Constructor.
507  *
508  * @param[in] exec_type The execution paradigm for the solver.
509  * @param[in] print_iter A setting to control the printing to the screen.
510  * @param[in] max_num_iter The maximum number of iterations to be run.
511  * @param[in] RTOLERANCE The relative tolerance to be achieved.
512  * @param[in] ATOLERANCE The absolute tolerance to be achieved.
513  */
514  FCGSolver(
515  const std::string & exec_type,
516  int print_iter,
517  int max_num_iter,
518  double RTOLERANCE,
519  double ATOLERANCE
520  );
521 
522  /**
523  * Constructor.
524  *
525  * @param[in] exec_type The execution paradigm for the solver.
526  * @param[in] print_iter A setting to control the printing to the screen.
527  * @param[in] max_num_iter The maximum number of iterations to be run.
528  * @param[in] RTOLERANCE The relative tolerance to be achieved.
529  * @param[in] ATOLERANCE The absolute tolerance to be achieved.
530  * @param[in] preconditioner The preconditioner for the solver.
531  */
532  FCGSolver(
533  const std::string & exec_type,
534  int print_iter,
535  int max_num_iter,
536  double RTOLERANCE,
537  double ATOLERANCE,
538  const gko::LinOpFactory* preconditioner
539  );
540 };
541 
542 /**
543  * An implementation of the solver interface using the Ginkgo GMRES solver.
544  *
545  * @ingroup GinkgoWrappers
546  */
548 {
549 public:
550  void SetKDim(int dim) { m = dim; }
551 
552 
553  /**
554  * Constructor.
555  *
556  * @param[in] exec_type The execution paradigm for the solver.
557  * @param[in] print_iter A setting to control the printing to the screen.
558  * @param[in] max_num_iter The maximum number of iterations to be run.
559  * @param[in] RTOLERANCE The relative tolerance to be achieved.
560  * @param[in] ATOLERANCE The absolute tolerance to be achieved.
561  */
562  GMRESSolver(
563  const std::string & exec_type,
564  int print_iter,
565  int max_num_iter,
566  double RTOLERANCE,
567  double ATOLERANCE
568  );
569 
570  /**
571  * Constructor.
572  *
573  * @param[in] exec_type The execution paradigm for the solver.
574  * @param[in] print_iter A setting to control the printing to the screen.
575  * @param[in] max_num_iter The maximum number of iterations to be run.
576  * @param[in] RTOLERANCE The relative tolerance to be achieved.
577  * @param[in] ATOLERANCE The absolute tolerance to be achieved.
578  * @param[in] preconditioner The preconditioner for the solver.
579  */
580  GMRESSolver(
581  const std::string & exec_type,
582  int print_iter,
583  int max_num_iter,
584  double RTOLERANCE,
585  double ATOLERANCE,
586  const gko::LinOpFactory* preconditioner
587  );
588 
589 protected:
590  int m; // see SetKDim()
591 };
592 
593 /**
594  * An implementation of the solver interface using the Ginkgo IR solver.
595  *
596  * Iterative refinement (IR) is an iterative method that uses another coarse
597  * method to approximate the error of the current solution via the current
598  * residual.
599  *
600  * @ingroup GinkgoWrappers
601  */
603 {
604 public:
605  /**
606  * Constructor.
607  *
608  * @param[in] exec_type The execution paradigm for the solver.
609  * @param[in] print_iter A setting to control the printing to the screen.
610  * @param[in] max_num_iter The maximum number of iterations to be run.
611  * @param[in] RTOLERANCE The relative tolerance to be achieved.
612  * @param[in] ATOLERANCE The absolute tolerance to be achieved.
613  */
614  IRSolver(
615  const std::string & exec_type,
616  int print_iter,
617  int max_num_iter,
618  double RTOLERANCE,
619  double ATOLERANCE
620  );
621 
622  /**
623  * Constructor.
624  *
625  * @param[in] exec_type The execution paradigm for the solver.
626  * @param[in] print_iter A setting to control the printing to the screen.
627  * @param[in] max_num_iter The maximum number of iterations to be run.
628  * @param[in] RTOLERANCE The relative tolerance to be achieved.
629  * @param[in] ATOLERANCE The absolute tolerance to be achieved.
630  * @param[in] inner_solver The inner solver for the main solver.
631  */
632  IRSolver(
633  const std::string & exec_type,
634  int print_iter,
635  int max_num_iter,
636  double RTOLERANCE,
637  double ATOLERANCE,
638  const gko::LinOpFactory *inner_solver
639  );
640 };
641 
642 
643 } // namespace GinkgoWrappers
644 
645 }
646 
647 #endif // MFEM_GINKGO
CGSSolver(const std::string &exec_type, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Definition: ginkgo.cpp:339
ResidualLogger(std::shared_ptr< const gko::Executor > exec, const gko::LinOp *matrix, const gko_dense *b)
Definition: ginkgo.hpp:161
FCGSolver(const std::string &exec_type, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Definition: ginkgo.cpp:374
std::shared_ptr< ResidualLogger<> > residual_logger
Definition: ginkgo.hpp:305
void solve(const SparseMatrix *matrix, Vector &solution, const Vector &rhs)
Definition: ginkgo.cpp:258
GMRESSolver(const std::string &exec_type, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Definition: ginkgo.cpp:409
std::shared_ptr< gko::LinOpFactory > solver_gen
Definition: ginkgo.hpp:286
std::shared_ptr< gko::stop::Combined::Factory > combined_factory
Definition: ginkgo.hpp:311
double get_norm(const gko::matrix::Dense< ValueType > *norm)
Definition: ginkgo.hpp:39
CGSolver(const std::string &exec_type, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Definition: ginkgo.cpp:268
void on_iteration_complete(const gko::LinOp *, const gko::size_type &iteration, const gko::LinOp *residual, const gko::LinOp *solution, const gko::LinOp *residual_norm) const override
Definition: ginkgo.hpp:106
Data type sparse matrix.
Definition: sparsemat.hpp:40
std::shared_ptr< gko::stop::ResidualNormReduction<>::Factory > residual_criterion
Definition: ginkgo.hpp:293
double b
Definition: lissajous.cpp:42
void initialize(const SparseMatrix *matrix)
Definition: ginkgo.cpp:225
void apply(Vector &solution, const Vector &rhs)
Definition: ginkgo.cpp:85
BICGSTABSolver(const std::string &exec_type, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Definition: ginkgo.cpp:303
double compute_norm(const gko::matrix::Dense< ValueType > *b)
Definition: ginkgo.hpp:50
std::shared_ptr< gko::log::Convergence<> > convergence_logger
Definition: ginkgo.hpp:299
int dim
Definition: ex24.cpp:43
std::shared_ptr< gko::Executor > executor
Definition: ginkgo.hpp:318
Vector data type.
Definition: vector.hpp:48
IRSolver(const std::string &exec_type, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Definition: ginkgo.cpp:447
gko::matrix::Dense< ValueType > gko_dense
Definition: ginkgo.hpp:102
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition: globals.hpp:66
GinkgoIterativeSolverBase(const std::string &exec_type, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Definition: ginkgo.cpp:31