\chapter{The custom-\/logger program }
\hypertarget{custom_logger}{}\label{custom_logger}\index{The custom-\/logger program@{The custom-\/logger program}}
The simple solver with a custom logger example.

This example depends on simple-\/solver, simple-\/solver-\/logging, minimal-\/cuda-\/solver.

 \label{three_pt_stencil_solver_Intro}%
\Hypertarget{three_pt_stencil_solver_Intro}%
 \label{three_pt_stencil_solver_Introduction}%
\Hypertarget{three_pt_stencil_solver_Introduction}%
\doxysection*{Introduction}

The custom-\/logger example shows how Ginkgo\textquotesingle{}s API can be leveraged to implement application-\/specific callbacks for Ginkgo\textquotesingle{}s events. This is the most basic way of extending Ginkgo and a good first step for any application developer who wants to adapt Ginkgo to his specific needs.

Ginkgo\textquotesingle{}s \doxylink{classgko_1_1log_1_1Logger}{gko::\+log::\+\+Logger} abstraction provides hooks to the events that happen during the library execution. These hooks concern any low-\/level event such as memory allocations, deallocations, copies and kernel launches up to high-\/level events such as linear operator applications and completion of solver iterations.

In this example, a simple logger is implemented to track the solver\textquotesingle{}s recurrent residual norm and compute the true residual norm. At the end of the solver execution, a comparison table is shown on-\/screen.

\label{three_pt_stencil_solver_Abouttheexample}%
\Hypertarget{three_pt_stencil_solver_Abouttheexample}%
\doxysubsubsection*{About the example }

Each example has the following sections:\+ 
\begin{DoxyEnumerate}
\item {\bfseries{Introduction:\+}}This gives an overview of the example and mentions any interesting aspects in the example that might help the reader. 
\item {\bfseries{The commented program:\+}} This section is intended for you to understand the details of the example so that you can play with it and understand Ginkgo and its features better. 
\item {\bfseries{Results:\+}} This section shows the results of the code when run. Though the results may not be completely the same, you can expect the behaviour to be similar. 
\item {\bfseries{The plain program:\+}} This is the complete code without any comments to have an complete overview of the code. 
\end{DoxyEnumerate}\label{three_pt_stencil_solver_CommProg}%
\Hypertarget{three_pt_stencil_solver_CommProg}%
 \doxysection*{The commented program}


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ mtx-\/>get\_executor()-\/>copy\_val\_to\_host(mtx-\/>get\_const\_values());}
\DoxyCodeLine{\}}

\end{DoxyCode}


Utility function which computes the norm of a Ginkgo \doxylink{classgko_1_1matrix_1_1Dense}{gko::\+matrix::\+\+Dense} vector.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{\doxymbox{\hyperlink{namespacegko_a107302a750bfa82a2107c77293f791c9}{gko::remove\_complex<ValueType>}}\ compute\_norm(}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<ValueType>}}*\ b)}
\DoxyCodeLine{\{}

\end{DoxyCode}


Get the executor of the vector


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ exec\ =\ b-\/>get\_executor();}

\end{DoxyCode}


Initialize a result scalar containing the value 0.\+0.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ b\_norm\ =}
\DoxyCodeLine{\ \ \ \ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<gko::matrix::Dense<gko::remove\_complex<ValueType>}}>>(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \{0.0\},\ exec);}

\end{DoxyCode}


Use the dense {\ttfamily compute\+\_\+norm2} function to compute the norm.


\begin{DoxyCode}{0}
\DoxyCodeLine{b-\/>\doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense_aed62418c4ecb58c4855b0bea1b7a680d}{compute\_norm2}}(b\_norm);}

\end{DoxyCode}


Use the other utility function to return the norm contained in {\ttfamily b\+\_\+norm}


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ get\_first\_element(b\_norm.get());}
\DoxyCodeLine{\}}

\end{DoxyCode}


Custom logger class which intercepts the residual norm scalar and solution vector in order to print a table of real vs recurrent (internal to the solvers) residual norms.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{\textcolor{keyword}{struct\ }ResidualLogger\ :\ \doxymbox{\hyperlink{classgko_1_1log_1_1Logger}{gko::log::Logger}}\ \{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }RealValueType\ =\ \doxymbox{\hyperlink{namespacegko_a107302a750bfa82a2107c77293f791c9}{gko::remove\_complex<ValueType>}};}

\end{DoxyCode}


Output the logger\textquotesingle{}s data in a table format


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ \doxymbox{\hyperlink{namespacegko_af82d8f7795fefcf5f38a38895e316c02}{write}}()\textcolor{keyword}{\ const}}
\DoxyCodeLine{\textcolor{keyword}{}\{}

\end{DoxyCode}


Print a header for the table


\begin{DoxyCode}{0}
\DoxyCodeLine{std::cout\ <<\ \textcolor{stringliteral}{"{}Recurrent\ vs\ true\ vs\ implicit\ residual\ norm:"{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ <<\ std::endl;}
\DoxyCodeLine{std::cout\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(10)\ <<\ \textcolor{stringliteral}{"{}Iteration"{}}\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(25)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ <<\ \textcolor{stringliteral}{"{}Recurrent\ Residual\ Norm"{}}\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(25)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ <<\ \textcolor{stringliteral}{"{}True\ Residual\ Norm"{}}\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(25)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ <<\ \textcolor{stringliteral}{"{}Implicit\ Residual\ Norm"{}}\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::endl;}

\end{DoxyCode}


Print a separation line. Note that for creating {\ttfamily 10} characters {\ttfamily std::\+setw()} should be set to {\ttfamily 11}.


\begin{DoxyCode}{0}
\DoxyCodeLine{std::cout\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setfill(\textcolor{charliteral}{'-\/'})\ <<\ std::setw(11)\ <<\ \textcolor{charliteral}{'|'}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ <<\ std::setw(26)\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(26)\ <<\ \textcolor{charliteral}{'|'}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ <<\ std::setw(26)\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setfill(\textcolor{charliteral}{'\ '})\ <<\ std::endl;}

\end{DoxyCode}


Print the data one by one in the form


\begin{DoxyCode}{0}
\DoxyCodeLine{std::cout\ <<\ std::scientific;}
\DoxyCodeLine{\textcolor{keywordflow}{for}\ (std::size\_t\ i\ =\ 0;\ i\ <\ iterations.size();\ i++)\ \{}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(10)\ <<\ iterations[i]\ <<\ \textcolor{charliteral}{'|'}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::setw(25)\ <<\ recurrent\_norms[i]\ <<\ \textcolor{charliteral}{'|'}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::setw(25)\ <<\ real\_norms[i]\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(25)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ implicit\_norms[i]\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::endl;}
\DoxyCodeLine{\}}

\end{DoxyCode}


std::\+defaultfloat could be used here but some compilers do not support it properly, e.\+g. the Intel compiler


\begin{DoxyCode}{0}
\DoxyCodeLine{std::cout.unsetf(std::ios\_base::floatfield);}

\end{DoxyCode}


Print a separation line


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setfill(\textcolor{charliteral}{'-\/'})\ <<\ std::setw(11)\ <<\ \textcolor{charliteral}{'|'}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::setw(26)\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(26)\ <<\ \textcolor{charliteral}{'|'}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::setw(26)\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setfill(\textcolor{charliteral}{'\ '})\ <<\ std::endl;}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{using\ }gko\_dense\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<ValueType>}};}
\DoxyCodeLine{\textcolor{keyword}{using\ }gko\_real\_dense\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<RealValueType>}};}

\end{DoxyCode}


Customize the logging hook which is called everytime an iteration is completed


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ on\_iteration\_complete(\textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*\ solver,\ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*\ b,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*\ solution,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\&\ iteration,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*\ residual,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*\ residual\_norm,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*\ implicit\_sq\_residual\_norm,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1array}{gko::array<gko::stopping\_status>}}*,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordtype}{bool})\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{}\{}

\end{DoxyCode}


If the solver shares a residual norm, log its value


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordflow}{if}\ (residual\_norm)\ \{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ dense\_norm\ =\ \doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as<gko\_real\_dense>}}(residual\_norm);}

\end{DoxyCode}


Add the norm to the {\ttfamily recurrent\+\_\+norms} vector


\begin{DoxyCode}{0}
\DoxyCodeLine{recurrent\_norms.push\_back(get\_first\_element(dense\_norm));}

\end{DoxyCode}


Otherwise, use the recurrent residual vector


\begin{DoxyCode}{0}
\DoxyCodeLine{\}\ \textcolor{keywordflow}{else}\ \{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ dense\_residual\ =\ \doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as<gko\_dense>}}(residual);}

\end{DoxyCode}


Compute the residual vector\textquotesingle{}s norm


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ norm\ =\ compute\_norm(dense\_residual);}

\end{DoxyCode}


Add the computed norm to the {\ttfamily recurrent\+\_\+norms} vector


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ recurrent\_norms.push\_back(norm);}
\DoxyCodeLine{\}}

\end{DoxyCode}


If the solver shares the current solution vector


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordflow}{if}\ (solution)\ \{}

\end{DoxyCode}


Extract the matrix from the solver


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ matrix\ =\ \doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as<gko::solver::detail::SolverBaseLinOp>}}(solver)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\/>get\_system\_matrix();}

\end{DoxyCode}


Store the matrix\textquotesingle{}s executor


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ exec\ =\ matrix-\/>get\_executor();}

\end{DoxyCode}


Create a scalar containing the value 1.\+0


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ \doxymbox{\hyperlink{namespacegko_a0059e27f8f4bc348ff65c1e60caf47c8}{one}}\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<gko\_dense>}}(\{1.0\},\ exec);}

\end{DoxyCode}


Create a scalar containing the value -\/1.\+0


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ neg\_one\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<gko\_dense>}}(\{-\/1.0\},\ exec);}

\end{DoxyCode}


Instantiate a temporary result variable


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ res\ =\ \doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as<gko\_dense>}}(\doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{gko::clone}}(b));}

\end{DoxyCode}


Compute the real residual vector by calling apply on the system matrix


\begin{DoxyCode}{0}
\DoxyCodeLine{matrix-\/>apply(one,\ solution,\ neg\_one,\ res);}

\end{DoxyCode}


Compute the norm of the residual vector and add it to the {\ttfamily real\+\_\+norms} vector


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ real\_norms.push\_back(compute\_norm(res.get()));}
\DoxyCodeLine{\}\ \textcolor{keywordflow}{else}\ \{}

\end{DoxyCode}


Add to the {\ttfamily real\+\_\+norms} vector the value -\/1.\+0 if it could not be computed


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ real\_norms.push\_back(-\/1.0);}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordflow}{if}\ (implicit\_sq\_residual\_norm)\ \{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ dense\_norm\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as<gko\_real\_dense>}}(implicit\_sq\_residual\_norm);}

\end{DoxyCode}


Add the norm to the {\ttfamily implicit\+\_\+norms} vector


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ implicit\_norms.push\_back(std::sqrt(get\_first\_element(dense\_norm)));}
\DoxyCodeLine{\}\ \textcolor{keywordflow}{else}\ \{}

\end{DoxyCode}


Add to the {\ttfamily implicit\+\_\+norms} vector the value -\/1.\+0 if it could not be computed


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ implicit\_norms.push\_back(-\/1.0);}
\DoxyCodeLine{\}}

\end{DoxyCode}


Add the current iteration number to the {\ttfamily iterations} vector


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ iterations.push\_back(iteration);}
\DoxyCodeLine{\}}

\end{DoxyCode}


Construct the logger


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ ResidualLogger()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ :\ \doxymbox{\hyperlink{namespacegko}{gko}}::log::Logger(\doxymbox{\hyperlink{namespacegko}{gko}}::log::Logger::iteration\_complete\_mask)}
\DoxyCodeLine{\ \ \ \ \{\}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{private}:}

\end{DoxyCode}


Vector which stores all the recurrent residual norms


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{mutable}\ std::vector<RealValueType>\ recurrent\_norms\{\};}

\end{DoxyCode}


Vector which stores all the real residual norms


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{mutable}\ std::vector<RealValueType>\ real\_norms\{\};}

\end{DoxyCode}


Vector which stores all the implicit residual norms


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{mutable}\ std::vector<RealValueType>\ implicit\_norms\{\};}

\end{DoxyCode}


Vector which stores all the iteration numbers


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{mutable}\ std::vector<std::size\_t>\ iterations\{\};}
\DoxyCodeLine{\};}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{int}\ main(\textcolor{keywordtype}{int}\ argc,\ \textcolor{keywordtype}{char}*\ argv[])}
\DoxyCodeLine{\{}

\end{DoxyCode}


Use some shortcuts. In Ginkgo, vectors are seen as a \doxylink{classgko_1_1matrix_1_1Dense}{gko::\+matrix::\+\+Dense} with one column/\+one row. The advantage of this concept is that using multiple vectors is a now a natural extension of adding columns/\+rows are necessary.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{using\ }ValueType\ =\ double;}
\DoxyCodeLine{\textcolor{keyword}{using\ }RealValueType\ =\ \doxymbox{\hyperlink{namespacegko_a107302a750bfa82a2107c77293f791c9}{gko::remove\_complex<ValueType>}};}
\DoxyCodeLine{\textcolor{keyword}{using\ }IndexType\ =\ int;}
\DoxyCodeLine{\textcolor{keyword}{using\ }vec\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<ValueType>}};}
\DoxyCodeLine{\textcolor{keyword}{using\ }real\_vec\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<RealValueType>}};}

\end{DoxyCode}


The \doxylink{classgko_1_1matrix_1_1Csr}{gko::\+matrix::\+\+Csr} class is used here, but any other matrix class such as \doxylink{classgko_1_1matrix_1_1Coo}{gko::\+matrix::\+\+Coo}, \doxylink{classgko_1_1matrix_1_1Hybrid}{gko::\+matrix::\+\+Hybrid}, \doxylink{classgko_1_1matrix_1_1Ell}{gko::\+matrix::\+\+Ell} or \doxylink{classgko_1_1matrix_1_1Sellp}{gko::\+matrix::\+\+Sellp} could also be used.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{using\ }mtx\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Csr}{gko::matrix::Csr<ValueType,\ IndexType>}};}

\end{DoxyCode}


The \doxylink{classgko_1_1solver_1_1Cg}{gko::\+solver::\+\+Cg} is used here, but any other solver class can also be used.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{using\ }cg\ =\ \doxymbox{\hyperlink{classgko_1_1solver_1_1Cg}{gko::solver::Cg<ValueType>}};}

\end{DoxyCode}


Print the ginkgo version information.


\begin{DoxyCode}{0}
\DoxyCodeLine{std::cout\ <<\ \doxymbox{\hyperlink{classgko_1_1version__info_ab13efac1405dd90951d2d9485acc4f30}{gko::version\_info::get}}()\ <<\ std::endl;}

\end{DoxyCode}


\label{simple_solver_Wheredoyouwanttorunyoursolver}%
\Hypertarget{simple_solver_Wheredoyouwanttorunyoursolver}%
 \doxysubsubsection*{Where do you want to run your solver ?}

The \doxylink{classgko_1_1Executor}{gko::\+\+Executor} class is one of the cornerstones of Ginkgo. Currently, we have support for an \doxylink{classgko_1_1OmpExecutor}{gko::\+\+Omp\+Executor}, which uses Open\+MP multi-\/threading in most of its kernels, a \doxylink{classgko_1_1ReferenceExecutor}{gko::\+\+Reference\+Executor}, a single threaded specialization of the Open\+MP executor and a \doxylink{classgko_1_1CudaExecutor}{gko::\+\+Cuda\+Executor} which runs the code on a NVIDIA GPU if available. \begin{DoxyNote}{Note}
With the help of C++, you see that you only ever need to change the executor and all the other functions/\+ routines within Ginkgo should automatically work and run on the executor with any other changes.
\end{DoxyNote}

\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordflow}{if}\ (argc\ ==\ 2\ \&\&\ (std::string(argv[1])\ ==\ \textcolor{stringliteral}{"{}-\/-\/help"{}}))\ \{}
\DoxyCodeLine{\ \ \ \ std::cerr\ <<\ \textcolor{stringliteral}{"{}Usage:\ "{}}\ <<\ argv[0]\ <<\ \textcolor{stringliteral}{"{}\ [executor]"{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::exit(-\/1);}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{const}\ \textcolor{keyword}{auto}\ executor\_string\ =\ argc\ >=\ 2\ ?\ argv[1]\ :\ \textcolor{stringliteral}{"{}reference"{}};}

\end{DoxyCode}


Figure out where to run the code


\begin{DoxyCode}{0}
\DoxyCodeLine{std::map<std::string,\ std::function<std::shared\_ptr<gko::Executor>()>>}
\DoxyCodeLine{\ \ \ \ exec\_map\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \{\textcolor{stringliteral}{"{}omp"{}},\ []\ \{\ \textcolor{keywordflow}{return}\ \doxymbox{\hyperlink{classgko_1_1OmpExecutor_af977cb680e0427ca4eb71eb7b1266211}{gko::OmpExecutor::create}}();\ \}\},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \{\textcolor{stringliteral}{"{}cuda"{}},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ []\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{return}\ \doxymbox{\hyperlink{classgko_1_1CudaExecutor_a075a1957241de65c0cad59f9534430a2}{gko::CudaExecutor::create}}(0,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \doxymbox{\hyperlink{classgko_1_1OmpExecutor_af977cb680e0427ca4eb71eb7b1266211}{gko::OmpExecutor::create}}());}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \}\},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \{\textcolor{stringliteral}{"{}hip"{}},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ []\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{return}\ \doxymbox{\hyperlink{classgko_1_1HipExecutor_a8afc5210bf8dd8aedfceab4b73f0047b}{gko::HipExecutor::create}}(0,\ \doxymbox{\hyperlink{classgko_1_1OmpExecutor_af977cb680e0427ca4eb71eb7b1266211}{gko::OmpExecutor::create}}());}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \}\},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \{\textcolor{stringliteral}{"{}dpcpp"{}},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ []\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{return}\ \doxymbox{\hyperlink{classgko_1_1DpcppExecutor_af69a356ee07f641010df5d2e9e518bb0}{gko::DpcppExecutor::create}}(0,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \doxymbox{\hyperlink{classgko_1_1OmpExecutor_af977cb680e0427ca4eb71eb7b1266211}{gko::OmpExecutor::create}}());}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \}\},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \{\textcolor{stringliteral}{"{}reference"{}},\ []\ \{\ \textcolor{keywordflow}{return}\ gko::ReferenceExecutor::create();\ \}\}\};}

\end{DoxyCode}


executor where Ginkgo will perform the computation


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{const}\ \textcolor{keyword}{auto}\ exec\ =\ exec\_map.at(executor\_string)();\ \ \textcolor{comment}{//\ throws\ if\ not\ valid}}

\end{DoxyCode}


\label{simple_solver_Readingyourdataandtransfertotheproperdevice}%
\Hypertarget{simple_solver_Readingyourdataandtransfertotheproperdevice}%
 \doxysubsubsection*{Reading your data and transfer to the proper device.}

Read the matrix, right hand side and the initial solution using the read function. \begin{DoxyNote}{Note}
Ginkgo uses C++ smart pointers to automatically manage memory. To this end, we use our own object ownership transfer functions that under the hood call the required smart pointer functions to manage object ownership. \doxylink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{gko::\+share} and \doxylink{namespacegko_abc3b2c363d6eb3d9837a6d9efa589844}{gko::\+give} are the functions that you would need to use.
\end{DoxyNote}

\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ A\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(\doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<mtx>}}(std::ifstream(\textcolor{stringliteral}{"{}data/A.mtx"{}}),\ exec));}
\DoxyCodeLine{\textcolor{keyword}{auto}\ b\ =\ \doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<vec>}}(std::ifstream(\textcolor{stringliteral}{"{}data/b.mtx"{}}),\ exec);}
\DoxyCodeLine{\textcolor{keyword}{auto}\ x\ =\ \doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<vec>}}(std::ifstream(\textcolor{stringliteral}{"{}data/x0.mtx"{}}),\ exec);}
\DoxyCodeLine{\textcolor{keyword}{const}\ RealValueType\ reduction\_factor\ =\ 1e-\/7;}

\end{DoxyCode}


\label{simple_solver_Creatingthesolver}%
\Hypertarget{simple_solver_Creatingthesolver}%
 \doxysubsubsection*{Creating the solver}

Generate the \doxylink{namespacegko_1_1solver}{gko::\+solver} factory. Ginkgo uses the concept of Factories to build solvers with certain properties. Observe the Fluent interface used here. Here a cg solver is generated with a stopping criteria of maximum iterations of 20 and a residual norm reduction of 1e-\/15. You also observe that the stopping criteria(gko::\+stop) are also generated from factories using their build methods. You need to specify the executors which each of the object needs to be built on.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ solver\_gen\ =}
\DoxyCodeLine{\ \ \ \ cg::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .with\_criteria(gko::stop::Iteration::build().with\_max\_iters(20u),}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ gko::stop::ResidualNorm<ValueType>::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_reduction\_factor(reduction\_factor))}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .on(exec);}

\end{DoxyCode}


Instantiate a Residual\+Logger logger.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ logger\ =\ std::make\_shared<ResidualLogger<ValueType>>();}

\end{DoxyCode}


Add the previously created logger to the solver factory. The logger will be automatically propagated to all solvers created from this factory.


\begin{DoxyCode}{0}
\DoxyCodeLine{solver\_gen-\/>add\_logger(logger);}

\end{DoxyCode}


Generate the solver from the matrix. The solver factory built in the previous step takes a "{}matrix"{}(a \doxylink{classgko_1_1LinOp}{gko::\+\+Lin\+Op} to be more general) as an input. In this case we provide it with a full matrix that we previously read, but as the solver only effectively uses the apply() method within the provided "{}matrix"{} object, you can effectively create a \doxylink{classgko_1_1LinOp}{gko::\+\+Lin\+Op} class with your own apply implementation to accomplish more tasks. We will see an example of how this can be done in the custom-\/matrix-\/format example


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ \doxymbox{\hyperlink{namespacegko_1_1log_a15f71654c6c4f4defc95f9359343fa27a7cbf673200498a0d1324f4330825202a}{solver}}\ =\ solver\_gen-\/>generate(A);}

\end{DoxyCode}


Finally, solve the system. The solver, being a \doxylink{classgko_1_1LinOp}{gko::\+\+Lin\+Op}, can be applied to a right hand side, b to obtain the solution, x.


\begin{DoxyCode}{0}
\DoxyCodeLine{\doxymbox{\hyperlink{namespacegko_1_1log_a15f71654c6c4f4defc95f9359343fa27a7cbf673200498a0d1324f4330825202a}{solver}}-\/>apply(b,\ x);}

\end{DoxyCode}


Print the solution to the command line.


\begin{DoxyCode}{0}
\DoxyCodeLine{std::cout\ <<\ \textcolor{stringliteral}{"{}Solution\ (x):\(\backslash\)n"{}};}
\DoxyCodeLine{\doxymbox{\hyperlink{namespacegko_af82d8f7795fefcf5f38a38895e316c02}{write}}(std::cout,\ x);}

\end{DoxyCode}


Print the table of the residuals obtained from the logger


\begin{DoxyCode}{0}
\DoxyCodeLine{logger-\/>write();}

\end{DoxyCode}


To measure if your solution has actually converged, you can measure the error of the solution. one, neg\+\_\+one are objects that represent the numbers which allow for a uniform interface when computing on any device. To compute the residual, all you need to do is call the apply method, which in this case is an spmv and equivalent to the LAPACK z\+\_\+spmv routine. Finally, you compute the euclidean 2-\/norm with the compute\+\_\+norm2 function.


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ \doxymbox{\hyperlink{namespacegko_a0059e27f8f4bc348ff65c1e60caf47c8}{one}}\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<vec>}}(\{1.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ neg\_one\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<vec>}}(\{-\/1.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ res\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ A-\/>apply(one,\ x,\ neg\_one,\ b);}
\DoxyCodeLine{\ \ \ \ b-\/>compute\_norm2(res);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Residual\ norm\ sqrt(r\string^T\ r):\(\backslash\)n"{}};}
\DoxyCodeLine{\ \ \ \ \doxymbox{\hyperlink{namespacegko_af82d8f7795fefcf5f38a38895e316c02}{write}}(std::cout,\ res);}
\DoxyCodeLine{\}}

\end{DoxyCode}
 \label{three_pt_stencil_solver_Results}%
\Hypertarget{three_pt_stencil_solver_Results}%
\doxysection*{Results}

The following is the expected result:\+


\begin{DoxyCode}{0}
\DoxyCodeLine{Solution\ (x):}
\DoxyCodeLine{\%\%MatrixMarket\ matrix\ \doxymbox{\hyperlink{namespacegko_ae749a5ea11a93c1bcc9158d9a6e9fb68af1f713c9e000f5d3f280adbd124df4f5}{array}}\ \doxymbox{\hyperlink{namespacegko_af21648097306adbabc6234b4609ce297}{real}}\ general}
\DoxyCodeLine{19\ 1}
\DoxyCodeLine{0.252218}
\DoxyCodeLine{0.108645}
\DoxyCodeLine{0.0662811}
\DoxyCodeLine{0.0630433}
\DoxyCodeLine{0.0384088}
\DoxyCodeLine{0.0396536}
\DoxyCodeLine{0.0402648}
\DoxyCodeLine{0.0338935}
\DoxyCodeLine{0.0193098}
\DoxyCodeLine{0.0234653}
\DoxyCodeLine{0.0211499}
\DoxyCodeLine{0.0196413}
\DoxyCodeLine{0.0199151}
\DoxyCodeLine{0.0181674}
\DoxyCodeLine{0.0162722}
\DoxyCodeLine{0.0150714}
\DoxyCodeLine{0.0107016}
\DoxyCodeLine{0.0121141}
\DoxyCodeLine{0.0123025}
\DoxyCodeLine{Recurrent\ vs\ true\ vs\ implicit\ residual\ norm:}
\DoxyCodeLine{|\ Iteration|\ \ Recurrent\ Residual\ Norm|\ \ \ \ \ \ \ True\ Residual\ Norm|\ \ \ Implicit\ Residual\ Norm|}
\DoxyCodeLine{|-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/|-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/|-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/|-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ \ 0|\ \ \ \ \ \ \ \ \ \ \ \ \ 4.358899e+00|\ \ \ \ \ \ \ \ \ \ \ \ \ 4.358899e+00|\ \ \ \ \ \ \ \ \ \ \ \ \ 4.358899e+00|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ \ 1|\ \ \ \ \ \ \ \ \ \ \ \ \ 2.304548e+00|\ \ \ \ \ \ \ \ \ \ \ \ \ 2.304548e+00|\ \ \ \ \ \ \ \ \ \ \ \ \ 2.304548e+00|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ \ 2|\ \ \ \ \ \ \ \ \ \ \ \ \ 1.467706e+00|\ \ \ \ \ \ \ \ \ \ \ \ \ 1.467706e+00|\ \ \ \ \ \ \ \ \ \ \ \ \ 1.467706e+00|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ \ 3|\ \ \ \ \ \ \ \ \ \ \ \ \ 9.848751e-\/01|\ \ \ \ \ \ \ \ \ \ \ \ \ 9.848751e-\/01|\ \ \ \ \ \ \ \ \ \ \ \ \ 9.848751e-\/01|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ \ 4|\ \ \ \ \ \ \ \ \ \ \ \ \ 7.418330e-\/01|\ \ \ \ \ \ \ \ \ \ \ \ \ 7.418330e-\/01|\ \ \ \ \ \ \ \ \ \ \ \ \ 7.418330e-\/01|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ \ 5|\ \ \ \ \ \ \ \ \ \ \ \ \ 5.136231e-\/01|\ \ \ \ \ \ \ \ \ \ \ \ \ 5.136231e-\/01|\ \ \ \ \ \ \ \ \ \ \ \ \ 5.136231e-\/01|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ \ 6|\ \ \ \ \ \ \ \ \ \ \ \ \ 3.841650e-\/01|\ \ \ \ \ \ \ \ \ \ \ \ \ 3.841650e-\/01|\ \ \ \ \ \ \ \ \ \ \ \ \ 3.841650e-\/01|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ \ 7|\ \ \ \ \ \ \ \ \ \ \ \ \ 3.164394e-\/01|\ \ \ \ \ \ \ \ \ \ \ \ \ 3.164394e-\/01|\ \ \ \ \ \ \ \ \ \ \ \ \ 3.164394e-\/01|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ \ 8|\ \ \ \ \ \ \ \ \ \ \ \ \ 2.277088e-\/01|\ \ \ \ \ \ \ \ \ \ \ \ \ 2.277088e-\/01|\ \ \ \ \ \ \ \ \ \ \ \ \ 2.277088e-\/01|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ \ 9|\ \ \ \ \ \ \ \ \ \ \ \ \ 1.703121e-\/01|\ \ \ \ \ \ \ \ \ \ \ \ \ 1.703121e-\/01|\ \ \ \ \ \ \ \ \ \ \ \ \ 1.703121e-\/01|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ 10|\ \ \ \ \ \ \ \ \ \ \ \ \ 9.737220e-\/02|\ \ \ \ \ \ \ \ \ \ \ \ \ 9.737220e-\/02|\ \ \ \ \ \ \ \ \ \ \ \ \ 9.737220e-\/02|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ 11|\ \ \ \ \ \ \ \ \ \ \ \ \ 6.168306e-\/02|\ \ \ \ \ \ \ \ \ \ \ \ \ 6.168306e-\/02|\ \ \ \ \ \ \ \ \ \ \ \ \ 6.168306e-\/02|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ 12|\ \ \ \ \ \ \ \ \ \ \ \ \ 4.541231e-\/02|\ \ \ \ \ \ \ \ \ \ \ \ \ 4.541231e-\/02|\ \ \ \ \ \ \ \ \ \ \ \ \ 4.541231e-\/02|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ 13|\ \ \ \ \ \ \ \ \ \ \ \ \ 3.195304e-\/02|\ \ \ \ \ \ \ \ \ \ \ \ \ 3.195304e-\/02|\ \ \ \ \ \ \ \ \ \ \ \ \ 3.195304e-\/02|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ 14|\ \ \ \ \ \ \ \ \ \ \ \ \ 1.616058e-\/02|\ \ \ \ \ \ \ \ \ \ \ \ \ 1.616058e-\/02|\ \ \ \ \ \ \ \ \ \ \ \ \ 1.616058e-\/02|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ 15|\ \ \ \ \ \ \ \ \ \ \ \ \ 6.570152e-\/03|\ \ \ \ \ \ \ \ \ \ \ \ \ 6.570152e-\/03|\ \ \ \ \ \ \ \ \ \ \ \ \ 6.570152e-\/03|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ 16|\ \ \ \ \ \ \ \ \ \ \ \ \ 2.643669e-\/03|\ \ \ \ \ \ \ \ \ \ \ \ \ 2.643669e-\/03|\ \ \ \ \ \ \ \ \ \ \ \ \ 2.643669e-\/03|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ 17|\ \ \ \ \ \ \ \ \ \ \ \ \ 8.588089e-\/04|\ \ \ \ \ \ \ \ \ \ \ \ \ 8.588089e-\/04|\ \ \ \ \ \ \ \ \ \ \ \ \ 8.588089e-\/04|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ 18|\ \ \ \ \ \ \ \ \ \ \ \ \ 2.864613e-\/04|\ \ \ \ \ \ \ \ \ \ \ \ \ 2.864613e-\/04|\ \ \ \ \ \ \ \ \ \ \ \ \ 2.864613e-\/04|}
\DoxyCodeLine{|\ \ \ \ \ \ \ \ 19|\ \ \ \ \ \ \ \ \ \ \ \ \ 1.641952e-\/15|\ \ \ \ \ \ \ \ \ \ \ \ \ 2.107881e-\/15|\ \ \ \ \ \ \ \ \ \ \ \ \ 1.641952e-\/15|}
\DoxyCodeLine{|-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/|-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/|-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/|-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/|}
\DoxyCodeLine{Residual\ norm\ sqrt(r\string^T\ r):}
\DoxyCodeLine{\%\%MatrixMarket\ matrix\ \doxymbox{\hyperlink{namespacegko_ae749a5ea11a93c1bcc9158d9a6e9fb68af1f713c9e000f5d3f280adbd124df4f5}{array}}\ \doxymbox{\hyperlink{namespacegko_af21648097306adbabc6234b4609ce297}{real}}\ general}
\DoxyCodeLine{1\ 1}
\DoxyCodeLine{2.10788e-\/15}

\end{DoxyCode}


\label{three_pt_stencil_solver_Commentsaboutprogramminganddebugging}%
\Hypertarget{three_pt_stencil_solver_Commentsaboutprogramminganddebugging}%
\doxysubsubsection*{Comments about programming and debugging }

\label{three_pt_stencil_solver_PlainProg}%
\Hypertarget{three_pt_stencil_solver_PlainProg}%
 \doxysection*{The plain program}


\begin{DoxyCodeInclude}{0}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <ginkgo/ginkgo.hpp>}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <fstream>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <map>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <iomanip>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <ios>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <iostream>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <string>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <vector>}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{ValueType\ get\_first\_element(\textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<ValueType>}}*\ mtx)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ mtx-\/>get\_executor()-\/>copy\_val\_to\_host(mtx-\/>\doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense_a78f311b47437fb90e470b7506234292a}{get\_const\_values}}());}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{\doxymbox{\hyperlink{namespacegko_a107302a750bfa82a2107c77293f791c9}{gko::remove\_complex<ValueType>}}\ compute\_norm(}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<ValueType>}}*\ b)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ exec\ =\ b-\/>get\_executor();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ b\_norm\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<gko::matrix::Dense<gko::remove\_complex<ValueType>}}>>(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \{0.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ b-\/>\doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense_aed62418c4ecb58c4855b0bea1b7a680d}{compute\_norm2}}(b\_norm);}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ get\_first\_element(b\_norm.get());}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{\textcolor{keyword}{struct\ }ResidualLogger\ :\ \doxymbox{\hyperlink{classgko_1_1log_1_1Logger}{gko::log::Logger}}\ \{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }RealValueType\ =\ \doxymbox{\hyperlink{namespacegko_a107302a750bfa82a2107c77293f791c9}{gko::remove\_complex<ValueType>}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ \doxymbox{\hyperlink{namespacegko_af82d8f7795fefcf5f38a38895e316c02}{write}}()\textcolor{keyword}{\ const}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Recurrent\ vs\ true\ vs\ implicit\ residual\ norm:"{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ std::cout\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(10)\ <<\ \textcolor{stringliteral}{"{}Iteration"{}}\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(25)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ \textcolor{stringliteral}{"{}Recurrent\ Residual\ Norm"{}}\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(25)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ \textcolor{stringliteral}{"{}True\ Residual\ Norm"{}}\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(25)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ \textcolor{stringliteral}{"{}Implicit\ Residual\ Norm"{}}\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ std::cout\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setfill(\textcolor{charliteral}{'-\/'})\ <<\ std::setw(11)\ <<\ \textcolor{charliteral}{'|'}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::setw(26)\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(26)\ <<\ \textcolor{charliteral}{'|'}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::setw(26)\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setfill(\textcolor{charliteral}{'\ '})\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ std::cout\ <<\ std::scientific;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{for}\ (std::size\_t\ i\ =\ 0;\ i\ <\ iterations.size();\ i++)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ std::cout\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(10)\ <<\ iterations[i]\ <<\ \textcolor{charliteral}{'|'}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::setw(25)\ <<\ recurrent\_norms[i]\ <<\ \textcolor{charliteral}{'|'}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::setw(25)\ <<\ real\_norms[i]\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(25)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ implicit\_norms[i]\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ std::cout.unsetf(std::ios\_base::floatfield);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ std::cout\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setfill(\textcolor{charliteral}{'-\/'})\ <<\ std::setw(11)\ <<\ \textcolor{charliteral}{'|'}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::setw(26)\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setw(26)\ <<\ \textcolor{charliteral}{'|'}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::setw(26)\ <<\ \textcolor{charliteral}{'|'}\ <<\ std::setfill(\textcolor{charliteral}{'\ '})\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }gko\_dense\ =\ gko::matrix::Dense<ValueType>;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }gko\_real\_dense\ =\ gko::matrix::Dense<RealValueType>;}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_iteration\_complete(\textcolor{keyword}{const}\ gko::LinOp*\ solver,\ \textcolor{keyword}{const}\ gko::LinOp*\ b,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ gko::LinOp*\ solution,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\&\ iteration,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ gko::LinOp*\ residual,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ gko::LinOp*\ residual\_norm,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ gko::LinOp*\ implicit\_sq\_residual\_norm,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ gko::array<gko::stopping\_status>*,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordtype}{bool})\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (residual\_norm)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ dense\_norm\ =\ \doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as<gko\_real\_dense>}}(residual\_norm);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ recurrent\_norms.push\_back(get\_first\_element(dense\_norm));}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}\ \textcolor{keywordflow}{else}\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ dense\_residual\ =\ \doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as<gko\_dense>}}(residual);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ norm\ =\ compute\_norm(dense\_residual);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ recurrent\_norms.push\_back(norm);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (solution)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ matrix\ =\ \doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as<gko::solver::detail::SolverBaseLinOp>}}(solver)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\/>get\_system\_matrix();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ exec\ =\ matrix-\/>get\_executor();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ \doxymbox{\hyperlink{namespacegko_a0059e27f8f4bc348ff65c1e60caf47c8}{one}}\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<gko\_dense>}}(\{1.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ neg\_one\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<gko\_dense>}}(\{-\/1.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ res\ =\ \doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as<gko\_dense>}}(\doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{gko::clone}}(b));}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ matrix-\/>apply(one,\ solution,\ neg\_one,\ res);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ real\_norms.push\_back(compute\_norm(res.get()));}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}\ \textcolor{keywordflow}{else}\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ real\_norms.push\_back(-\/1.0);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (implicit\_sq\_residual\_norm)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ dense\_norm\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as<gko\_real\_dense>}}(implicit\_sq\_residual\_norm);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ implicit\_norms.push\_back(std::sqrt(get\_first\_element(dense\_norm)));}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}\ \textcolor{keywordflow}{else}\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ implicit\_norms.push\_back(-\/1.0);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ iterations.push\_back(iteration);}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ ResidualLogger()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ :\ gko::log::Logger(gko::log::Logger::iteration\_complete\_mask)}
\DoxyCodeLine{\ \ \ \ \{\}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{private}:}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{mutable}\ std::vector<RealValueType>\ recurrent\_norms\{\};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{mutable}\ std::vector<RealValueType>\ real\_norms\{\};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{mutable}\ std::vector<RealValueType>\ implicit\_norms\{\};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{mutable}\ std::vector<std::size\_t>\ iterations\{\};}
\DoxyCodeLine{\};}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{int}\ main(\textcolor{keywordtype}{int}\ argc,\ \textcolor{keywordtype}{char}*\ argv[])}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }ValueType\ =\ double;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }RealValueType\ =\ \doxymbox{\hyperlink{namespacegko_a107302a750bfa82a2107c77293f791c9}{gko::remove\_complex<ValueType>}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }IndexType\ =\ int;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }vec\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<ValueType>}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }real\_vec\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<RealValueType>}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }mtx\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Csr}{gko::matrix::Csr<ValueType,\ IndexType>}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }cg\ =\ \doxymbox{\hyperlink{classgko_1_1solver_1_1Cg}{gko::solver::Cg<ValueType>}};}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \doxymbox{\hyperlink{classgko_1_1version__info_ab13efac1405dd90951d2d9485acc4f30}{gko::version\_info::get}}()\ <<\ std::endl;}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{if}\ (argc\ ==\ 2\ \&\&\ (std::string(argv[1])\ ==\ \textcolor{stringliteral}{"{}-\/-\/help"{}}))\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ std::cerr\ <<\ \textcolor{stringliteral}{"{}Usage:\ "{}}\ <<\ argv[0]\ <<\ \textcolor{stringliteral}{"{}\ [executor]"{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ std::exit(-\/1);}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ \textcolor{keyword}{auto}\ executor\_string\ =\ argc\ >=\ 2\ ?\ argv[1]\ :\ \textcolor{stringliteral}{"{}reference"{}};}
\DoxyCodeLine{\ \ \ \ std::map<std::string,\ std::function<std::shared\_ptr<gko::Executor>()>>}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec\_map\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \{\textcolor{stringliteral}{"{}omp"{}},\ []\ \{\ \textcolor{keywordflow}{return}\ \doxymbox{\hyperlink{classgko_1_1OmpExecutor_af977cb680e0427ca4eb71eb7b1266211}{gko::OmpExecutor::create}}();\ \}\},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \{\textcolor{stringliteral}{"{}cuda"{}},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ []\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{return}\ \doxymbox{\hyperlink{classgko_1_1CudaExecutor_a075a1957241de65c0cad59f9534430a2}{gko::CudaExecutor::create}}(0,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \doxymbox{\hyperlink{classgko_1_1OmpExecutor_af977cb680e0427ca4eb71eb7b1266211}{gko::OmpExecutor::create}}());}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \}\},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \{\textcolor{stringliteral}{"{}hip"{}},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ []\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{return}\ \doxymbox{\hyperlink{classgko_1_1HipExecutor_a8afc5210bf8dd8aedfceab4b73f0047b}{gko::HipExecutor::create}}(0,\ \doxymbox{\hyperlink{classgko_1_1OmpExecutor_af977cb680e0427ca4eb71eb7b1266211}{gko::OmpExecutor::create}}());}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \}\},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \{\textcolor{stringliteral}{"{}dpcpp"{}},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ []\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{return}\ \doxymbox{\hyperlink{classgko_1_1DpcppExecutor_af69a356ee07f641010df5d2e9e518bb0}{gko::DpcppExecutor::create}}(0,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \doxymbox{\hyperlink{classgko_1_1OmpExecutor_af977cb680e0427ca4eb71eb7b1266211}{gko::OmpExecutor::create}}());}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \}\},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \{\textcolor{stringliteral}{"{}reference"{}},\ []\ \{\ \textcolor{keywordflow}{return}\ gko::ReferenceExecutor::create();\ \}\}\};}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ \textcolor{keyword}{auto}\ exec\ =\ exec\_map.at(executor\_string)();\ \ \textcolor{comment}{//\ throws\ if\ not\ valid}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ A\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(\doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<mtx>}}(std::ifstream(\textcolor{stringliteral}{"{}data/A.mtx"{}}),\ exec));}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ b\ =\ \doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<vec>}}(std::ifstream(\textcolor{stringliteral}{"{}data/b.mtx"{}}),\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ x\ =\ \doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<vec>}}(std::ifstream(\textcolor{stringliteral}{"{}data/x0.mtx"{}}),\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ RealValueType\ reduction\_factor\ =\ 1e-\/7;}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ solver\_gen\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ cg::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .with\_criteria(gko::stop::Iteration::build().with\_max\_iters(20u),}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ gko::stop::ResidualNorm<ValueType>::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_reduction\_factor(reduction\_factor))}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .on(exec);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ logger\ =\ std::make\_shared<ResidualLogger<ValueType>>();}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ solver\_gen-\/>add\_logger(logger);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ \doxymbox{\hyperlink{namespacegko_1_1log_a15f71654c6c4f4defc95f9359343fa27a7cbf673200498a0d1324f4330825202a}{solver}}\ =\ solver\_gen-\/>generate(A);}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \doxymbox{\hyperlink{namespacegko_1_1log_a15f71654c6c4f4defc95f9359343fa27a7cbf673200498a0d1324f4330825202a}{solver}}-\/>apply(b,\ x);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Solution\ (x):\(\backslash\)n"{}};}
\DoxyCodeLine{\ \ \ \ \doxymbox{\hyperlink{namespacegko_af82d8f7795fefcf5f38a38895e316c02}{write}}(std::cout,\ x);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ logger-\/>write();}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ \doxymbox{\hyperlink{namespacegko_a0059e27f8f4bc348ff65c1e60caf47c8}{one}}\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<vec>}}(\{1.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ neg\_one\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<vec>}}(\{-\/1.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ res\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ A-\/>apply(one,\ x,\ neg\_one,\ b);}
\DoxyCodeLine{\ \ \ \ b-\/>compute\_norm2(res);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Residual\ norm\ sqrt(r\string^T\ r):\(\backslash\)n"{}};}
\DoxyCodeLine{\ \ \ \ \doxymbox{\hyperlink{namespacegko_af82d8f7795fefcf5f38a38895e316c02}{write}}(std::cout,\ res);}
\DoxyCodeLine{\}}

\end{DoxyCodeInclude}
 