\chapter{The performance-\/debugging program }
\hypertarget{performance_debugging}{}\label{performance_debugging}\index{The performance-\/debugging program@{The performance-\/debugging program}}
The simple solver with performance debugging example.

This example depends on 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}

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

This example runs a solver on a test problem and shows how to use loggers to debug performance and convergence rate. \label{three_pt_stencil_solver_CommProg}%
\Hypertarget{three_pt_stencil_solver_CommProg}%
 \doxysection*{The commented program}

creates a zero vector


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{std::unique\_ptr<vec<ValueType>>\ create\_vector(}
\DoxyCodeLine{\ \ \ \ std::shared\_ptr<const\ gko::Executor>\ exec,\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\ size,}
\DoxyCodeLine{\ \ \ \ ValueType\ value)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ res\ =\ vec<ValueType>::create(exec);}
\DoxyCodeLine{\ \ \ \ res-\/>read(\doxymbox{\hyperlink{structgko_1_1matrix__data}{gko::matrix\_data<ValueType>}}(\doxymbox{\hyperlink{structgko_1_1dim}{gko::dim<2>}}\{size,\ 1\},\ value));}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ res;}
\DoxyCodeLine{\}}

\end{DoxyCode}


utilities for computing norms and residuals


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{ValueType\ get\_first\_element(\textcolor{keyword}{const}\ vec<ValueType>*\ norm)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ norm-\/>get\_executor()-\/>copy\_val\_to\_host(norm-\/>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(\textcolor{keyword}{const}\ vec<ValueType>*\ b)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ exec\ =\ b-\/>get\_executor();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ b\_norm\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec<ValueType>}}>(\{0.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ b-\/>compute\_norm2(b\_norm);}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ get\_first\_element(b\_norm.get());}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{\doxymbox{\hyperlink{namespacegko_a107302a750bfa82a2107c77293f791c9}{gko::remove\_complex<ValueType>}}\ compute\_residual\_norm(}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*\ system\_matrix,\ \textcolor{keyword}{const}\ vec<ValueType>*\ b,}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ vec<ValueType>*\ x)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ exec\ =\ system\_matrix-\/>get\_executor();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ \doxymbox{\hyperlink{namespacegko_a0059e27f8f4bc348ff65c1e60caf47c8}{one}}\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<vec<ValueType>}}>(\{1.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ neg\_one\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<vec<ValueType>}}>(\{-\/1.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ res\ =\ \doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{gko::clone}}(b);}
\DoxyCodeLine{\ \ \ \ system\_matrix-\/>\doxymbox{\hyperlink{classgko_1_1LinOp_a8aba659b97d7bb9ad0c1a0d385c28f28}{apply}}(one,\ x,\ neg\_one,\ res);}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ compute\_norm(res.get());}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\}\ \ \textcolor{comment}{//\ namespace\ utils}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{namespace\ }loggers\ \{}

\end{DoxyCode}


A logger that accumulates the time of all operations. For each operation type (allocations, free, copy, internal operations i.\+e. kernels), the timing is taken before and after. This can create significant overhead since to ensure proper timings, calls to {\ttfamily synchronize} are required.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{struct\ }OperationLogger\ :\ \doxymbox{\hyperlink{classgko_1_1log_1_1Logger}{gko::log::Logger}}\ \{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_allocation\_started(\textcolor{keyword}{const}\ gko::Executor*\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\&)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>start\_operation(exec,\ \textcolor{stringliteral}{"{}allocate"{}});}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_allocation\_completed(\textcolor{keyword}{const}\ gko::Executor*\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\&,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>end\_operation(exec,\ \textcolor{stringliteral}{"{}allocate"{}});}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_free\_started(\textcolor{keyword}{const}\ gko::Executor*\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>start\_operation(exec,\ \textcolor{stringliteral}{"{}free"{}});}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_free\_completed(\textcolor{keyword}{const}\ gko::Executor*\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>end\_operation(exec,\ \textcolor{stringliteral}{"{}free"{}});}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_copy\_started(\textcolor{keyword}{const}\ gko::Executor*\ from,\ \textcolor{keyword}{const}\ gko::Executor*\ to,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&,\ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\&)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ from-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>start\_operation(to,\ \textcolor{stringliteral}{"{}copy"{}});}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_copy\_completed(\textcolor{keyword}{const}\ gko::Executor*\ from,\ \textcolor{keyword}{const}\ gko::Executor*\ to,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&,\ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\&)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ from-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>end\_operation(to,\ \textcolor{stringliteral}{"{}copy"{}});}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_operation\_launched(\textcolor{keyword}{const}\ gko::Executor*\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ gko::Operation*\ op)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>start\_operation(exec,\ op-\/>\doxymbox{\hyperlink{classgko_1_1Operation_ada3255c1fbae4a203627c0affce1aa23}{get\_name}}());}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_operation\_completed(\textcolor{keyword}{const}\ gko::Executor*\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ gko::Operation*\ op)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>end\_operation(exec,\ op-\/>\doxymbox{\hyperlink{classgko_1_1Operation_ada3255c1fbae4a203627c0affce1aa23}{get\_name}}());}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ write\_data(std::ostream\&\ ostream)}
\DoxyCodeLine{\ \ \ \ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keyword}{const}\ \textcolor{keyword}{auto}\&\ entry\ :\ total)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)t"{}}\ <<\ entry.first.c\_str()\ <<\ \textcolor{stringliteral}{"{}:\ "{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::chrono::duration\_cast<std::chrono::nanoseconds>(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ entry.second)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .count()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{private}:}

\end{DoxyCode}


Helper which synchronizes and starts the time before every operation.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ start\_operation(\textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1Executor}{gko::Executor}}*\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ std::string\&\ name)\textcolor{keyword}{\ const}}
\DoxyCodeLine{\textcolor{keyword}{}\{}
\DoxyCodeLine{\ \ \ \ nested.emplace\_back(0);}
\DoxyCodeLine{\ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\ \ \ \ start[name]\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{\}}

\end{DoxyCode}


Helper to compute the end time and store the operation\textquotesingle{}s time at its end. Also time nested operations.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ end\_operation(\textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1Executor}{gko::Executor}}*\ exec,\ \textcolor{keyword}{const}\ std::string\&\ name)\textcolor{keyword}{\ const}}
\DoxyCodeLine{\textcolor{keyword}{}\{}
\DoxyCodeLine{\ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ \textcolor{keyword}{auto}\ end\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ \textcolor{keyword}{auto}\ diff\ =\ end\ -\/\ start[name];}

\end{DoxyCode}


make sure timings for nested operations are not counted twice


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ total[name]\ +=\ diff\ -\/\ nested.back();}
\DoxyCodeLine{\ \ \ \ nested.pop\_back();}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{if}\ (nested.size()\ >\ 0)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ nested.back()\ +=\ diff;}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{mutable}\ std::map<std::string,\ std::chrono::steady\_clock::time\_point>\ start;}
\DoxyCodeLine{\textcolor{keyword}{mutable}\ std::map<std::string,\ std::chrono::steady\_clock::duration>\ total;}

\end{DoxyCode}


the position i of this vector holds the total time spend on child operations on nesting level i


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{mutable}\ std::vector<std::chrono::steady\_clock::duration>\ nested;}
\DoxyCodeLine{\};}

\end{DoxyCode}


This logger tracks the persistently allocated data


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{struct\ }StorageLogger\ :\ \doxymbox{\hyperlink{classgko_1_1log_1_1Logger}{gko::log::Logger}}\ \{}

\end{DoxyCode}


Store amount of bytes allocated on every allocation


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ on\_allocation\_completed(\textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1Executor}{gko::Executor}}*,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\&\ num\_bytes,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&\ location)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{}\{}
\DoxyCodeLine{\ \ \ \ storage[location]\ =\ num\_bytes;}
\DoxyCodeLine{\}}

\end{DoxyCode}


Reset the amount of bytes on every free


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ on\_free\_completed(\textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1Executor}{gko::Executor}}*,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&\ location)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{}\{}
\DoxyCodeLine{\ \ \ \ storage[location]\ =\ 0;}
\DoxyCodeLine{\}}

\end{DoxyCode}


Write the data after summing the total from all allocations


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ write\_data(std::ostream\&\ ostream)}
\DoxyCodeLine{\ \ \ \ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\ total\{\};}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keyword}{const}\ \textcolor{keyword}{auto}\&\ e\ :\ storage)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ total\ +=\ e.second;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}Storage:\ "{}}\ <<\ total\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{private}:}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{mutable}\ std::unordered\_map<gko::uintptr,\ gko::size\_type>\ storage;}
\DoxyCodeLine{\};}

\end{DoxyCode}


Logs true and recurrent residuals of the solver


\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}}\ \{}

\end{DoxyCode}


Depending on the available information, store the norm or compute it from the residual. If the true residual norm could not be computed, store the value {\ttfamily -\/1.\+0}.


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_iteration\_complete(\textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*,\ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\&,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*\ residual,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*\ solution,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*\ residual\_norm)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (residual\_norm)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ rec\_res\_norms.push\_back(utils::get\_first\_element(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as}}<real\_vec<ValueType>>(residual\_norm)));}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}\ \textcolor{keywordflow}{else}\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ rec\_res\_norms.push\_back(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ utils::compute\_norm(\doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as}}<vec<ValueType>>(residual)));}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (solution)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ true\_res\_norms.push\_back(utils::compute\_residual\_norm(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ matrix,\ b,\ \doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as}}<vec<ValueType>>(solution)));}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}\ \textcolor{keywordflow}{else}\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ true\_res\_norms.push\_back(-\/1.0);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ ResidualLogger(\textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*\ matrix,\ \textcolor{keyword}{const}\ vec<ValueType>*\ b)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ :\ \doxymbox{\hyperlink{namespacegko}{gko}}::log::Logger(\doxymbox{\hyperlink{namespacegko}{gko}}::log::Logger::iteration\_complete\_mask),}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ matrix\{matrix\},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ b\{b\}}
\DoxyCodeLine{\ \ \ \ \{\}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ write\_data(std::ostream\&\ ostream)}
\DoxyCodeLine{\ \ \ \ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}Recurrent\ Residual\ Norms:\ "{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}["{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keyword}{const}\ \textcolor{keyword}{auto}\&\ entry\ :\ rec\_res\_norms)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)t"{}}\ <<\ entry\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}];"{}}\ <<\ std::endl;}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}True\ Residual\ Norms:\ "{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}["{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keyword}{const}\ \textcolor{keyword}{auto}\&\ entry\ :\ true\_res\_norms)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)t"{}}\ <<\ entry\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}];"{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{private}:}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*\ matrix;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ vec<ValueType>*\ b;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{mutable}\ std::vector<gko::remove\_complex<ValueType>>\ rec\_res\_norms;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{mutable}\ std::vector<gko::remove\_complex<ValueType>>\ true\_res\_norms;}
\DoxyCodeLine{\};}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\}\ \ \textcolor{comment}{//\ namespace\ loggers}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{namespace\ }\{}

\end{DoxyCode}


Print usage help


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ print\_usage(\textcolor{keyword}{const}\ \textcolor{keywordtype}{char}*\ filename)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ std::cerr\ <<\ \textcolor{stringliteral}{"{}Usage:\ "{}}\ <<\ filename\ <<\ \textcolor{stringliteral}{"{}\ [executor]\ [matrix\ file]"{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::cerr\ <<\ \textcolor{stringliteral}{"{}matrix\ file\ should\ be\ a\ file\ in\ matrix\ market\ format.\ "{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{stringliteral}{"{}The\ file\ data/A.mtx\ is\ provided\ as\ an\ example."{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::exit(-\/1);}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ print\_vector(\textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<ValueType>}}*\ vec)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ elements\_to\_print\ =\ std::min(\doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}(10),\ vec-\/>get\_size()[0]);}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}["{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ i\ =\ 0;\ i\ <\ elements\_to\_print;\ ++i)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)t"{}}\ <<\ vec-\/>\doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense_a11528fc674c7885fbcb0936ef873f859}{at}}(i)\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}];"{}}\ <<\ std::endl;}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\}\ \ \textcolor{comment}{//\ namespace}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{int}\ main(\textcolor{keywordtype}{int}\ argc,\ \textcolor{keywordtype}{char}*\ argv[])}
\DoxyCodeLine{\{}

\end{DoxyCode}


Parametrize the benchmark here Pick a value type


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{using\ }ValueType\ =\ double;}
\DoxyCodeLine{\textcolor{keyword}{using\ }IndexType\ =\ int;}

\end{DoxyCode}


Pick a matrix format


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

\end{DoxyCode}


Pick a solver


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

\end{DoxyCode}


Pick a preconditioner type


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{using\ }preconditioner\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1IdentityFactory}{gko::matrix::IdentityFactory<ValueType>}};}

\end{DoxyCode}


Pick a residual norm reduction value


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a107302a750bfa82a2107c77293f791c9}{gko::remove\_complex<ValueType>}}\ reduction\_factor\ =\ 1e-\/12;}

\end{DoxyCode}


Pick an output file name


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{const}\ \textcolor{keyword}{auto}\ of\_name\ =\ \textcolor{stringliteral}{"{}log.txt"{}};}

\end{DoxyCode}


Simple shortcut


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{using\ }vec\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<ValueType>}};}

\end{DoxyCode}


Print version information


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

\end{DoxyCode}


Figure out where to run the code


\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{\}}

\end{DoxyCode}


Figure out where to run the code


\begin{DoxyCode}{0}
\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();\ \}\}\};}

\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}


Read the input matrix file directory


\begin{DoxyCode}{0}
\DoxyCodeLine{std::string\ input\_mtx\ =\ \textcolor{stringliteral}{"{}data/A.mtx"{}};}
\DoxyCodeLine{\textcolor{keywordflow}{if}\ (argc\ ==\ 3)\ \{}
\DoxyCodeLine{\ \ \ \ input\_mtx\ =\ std::string(argv[2]);}
\DoxyCodeLine{\}}

\end{DoxyCode}


Read data:\+ A is read from disk Create a Storage\+Logger to track the size of A


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ storage\_logger\ =\ std::make\_shared<loggers::StorageLogger>();}

\end{DoxyCode}


Add the logger to the executor


\begin{DoxyCode}{0}
\DoxyCodeLine{exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a520dad04b7e74f285ab0956873a5413d}{add\_logger}}(storage\_logger);}

\end{DoxyCode}


Read the matrix A from file


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ A\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{gko::share}}(\doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<mtx>}}(std::ifstream(input\_mtx),\ exec));}

\end{DoxyCode}


Remove the storage logger


\begin{DoxyCode}{0}
\DoxyCodeLine{exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_af04cdc1a9af6c8efc34ddebb9e7aaf00}{remove\_logger}}(storage\_logger);}

\end{DoxyCode}


Pick a maximum iteration count


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{const}\ \textcolor{keyword}{auto}\ max\_iters\ =\ A-\/>get\_size()[0];}

\end{DoxyCode}


Generate b and x vectors


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ b\ =\ utils::create\_vector<ValueType>(exec,\ A-\/>get\_size()[0],\ 1.0);}
\DoxyCodeLine{\textcolor{keyword}{auto}\ x\ =\ utils::create\_vector<ValueType>(exec,\ A-\/>get\_size()[0],\ 0.0);}

\end{DoxyCode}


Declare the solver factory. The preconditioner\textquotesingle{}s arguments should be adapted if needed.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ solver\_factory\ =}
\DoxyCodeLine{\ \ \ \ solver::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .with\_criteria(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ gko::stop::ResidualNorm<ValueType>::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_reduction\_factor(reduction\_factor),}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ gko::stop::Iteration::build().with\_max\_iters(max\_iters))}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .with\_preconditioner(preconditioner::create(exec))}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .on(exec);}

\end{DoxyCode}


Declare the output file for all our loggers


\begin{DoxyCode}{0}
\DoxyCodeLine{std::ofstream\ output\_file(of\_name);}

\end{DoxyCode}


Do a warmup run


\begin{DoxyCode}{0}
\DoxyCodeLine{\{}

\end{DoxyCode}


Clone x to not overwrite the original one


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ x\_clone\ =\ \doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{gko::clone}}(x);}

\end{DoxyCode}


Generate and call apply on a solver


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ solver\_factory-\/>generate(A)-\/>apply(b,\ x\_clone);}
\DoxyCodeLine{\ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\}}

\end{DoxyCode}


Do a timed run


\begin{DoxyCode}{0}
\DoxyCodeLine{\{}

\end{DoxyCode}


Clone x to not overwrite the original one


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ x\_clone\ =\ \doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{gko::clone}}(x);}

\end{DoxyCode}


Synchronize ensures no operation are ongoing


\begin{DoxyCode}{0}
\DoxyCodeLine{exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}

\end{DoxyCode}


Time before generate


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ g\_tic\ =\ std::chrono::steady\_clock::now();}

\end{DoxyCode}


Generate a solver


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ generated\_solver\ =\ solver\_factory-\/>generate(A);}
\DoxyCodeLine{exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}

\end{DoxyCode}


Time after generate


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ g\_tac\ =\ std::chrono::steady\_clock::now();}

\end{DoxyCode}


Compute the generation time


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ generate\_time\ =}
\DoxyCodeLine{\ \ \ \ std::chrono::duration\_cast<std::chrono::nanoseconds>(g\_tac\ -\/\ g\_tic);}

\end{DoxyCode}


Write the generate time to the output file


\begin{DoxyCode}{0}
\DoxyCodeLine{output\_file\ <<\ \textcolor{stringliteral}{"{}Generate\ time\ (ns):\ "{}}\ <<\ generate\_time.count()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ <<\ std::endl;}

\end{DoxyCode}


Similarly time the apply


\begin{DoxyCode}{0}
\DoxyCodeLine{exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\textcolor{keyword}{auto}\ a\_tic\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{generated\_solver-\/>apply(b,\ x\_clone);}
\DoxyCodeLine{exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\textcolor{keyword}{auto}\ a\_tac\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{\textcolor{keyword}{auto}\ apply\_time\ =}
\DoxyCodeLine{\ \ \ \ std::chrono::duration\_cast<std::chrono::nanoseconds>(a\_tac\ -\/\ a\_tic);}
\DoxyCodeLine{output\_file\ <<\ \textcolor{stringliteral}{"{}Apply\ time\ (ns):\ "{}}\ <<\ apply\_time.count()\ <<\ std::endl;}

\end{DoxyCode}


Compute the residual norm


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ residual\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ utils::compute\_residual\_norm(A.get(),\ b.get(),\ x\_clone.get());}
\DoxyCodeLine{\ \ \ \ output\_file\ <<\ \textcolor{stringliteral}{"{}Residual\_norm:\ "{}}\ <<\ residual\ <<\ std::endl;}
\DoxyCodeLine{\}}

\end{DoxyCode}


Log the internal operations using the Operation\+Logger without timing


\begin{DoxyCode}{0}
\DoxyCodeLine{\{}

\end{DoxyCode}


Create an Operation\+Logger to analyze the generate step


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ gen\_logger\ =\ std::make\_shared<loggers::OperationLogger>();}

\end{DoxyCode}


Add the generate logger to the executor


\begin{DoxyCode}{0}
\DoxyCodeLine{exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a520dad04b7e74f285ab0956873a5413d}{add\_logger}}(gen\_logger);}

\end{DoxyCode}


Generate a solver


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ generated\_solver\ =\ solver\_factory-\/>generate(A);}

\end{DoxyCode}


Remove the generate logger from the executor


\begin{DoxyCode}{0}
\DoxyCodeLine{exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_af04cdc1a9af6c8efc34ddebb9e7aaf00}{remove\_logger}}(gen\_logger);}

\end{DoxyCode}


Write the data to the output file


\begin{DoxyCode}{0}
\DoxyCodeLine{output\_file\ <<\ \textcolor{stringliteral}{"{}Generate\ operations\ times\ (ns):"{}}\ <<\ std::endl;}
\DoxyCodeLine{gen\_logger-\/>write\_data(output\_file);}

\end{DoxyCode}


Create an Operation\+Logger to analyze the apply step


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ apply\_logger\ =\ std::make\_shared<loggers::OperationLogger>();}
\DoxyCodeLine{exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a520dad04b7e74f285ab0956873a5413d}{add\_logger}}(apply\_logger);}

\end{DoxyCode}


Create a Residual\+Logger to log the recurrent residual


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ res\_logger\ =\ std::make\_shared<loggers::ResidualLogger<ValueType>>(}
\DoxyCodeLine{\ \ \ \ A.get(),\ b.get());}
\DoxyCodeLine{generated\_solver-\/>add\_logger(res\_logger);}

\end{DoxyCode}


Solve the system


\begin{DoxyCode}{0}
\DoxyCodeLine{generated\_solver-\/>apply(b,\ x);}
\DoxyCodeLine{exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_af04cdc1a9af6c8efc34ddebb9e7aaf00}{remove\_logger}}(apply\_logger);}

\end{DoxyCode}


Write the data to the output file


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ output\_file\ <<\ \textcolor{stringliteral}{"{}Apply\ operations\ times\ (ns):"{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ apply\_logger-\/>write\_data(output\_file);}
\DoxyCodeLine{\ \ \ \ res\_logger-\/>write\_data(output\_file);}
\DoxyCodeLine{\}}

\end{DoxyCode}


Print solution


\begin{DoxyCode}{0}
\DoxyCodeLine{std::cout\ <<\ \textcolor{stringliteral}{"{}Solution,\ first\ ten\ entries:\ \(\backslash\)n"{}};}
\DoxyCodeLine{print\_vector(x.get());}

\end{DoxyCode}


Print output file location


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}The\ performance\ and\ residual\ data\ can\ be\ found\ in\ "{}}\ <<\ of\_name}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::endl;}
\DoxyCodeLine{\}}

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

This is the expected standard output:\+


\begin{DoxyCode}{0}
\DoxyCodeLine{Solution,\ first\ ten\ entries:}
\DoxyCodeLine{[}
\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{];}
\DoxyCodeLine{The\ performance\ and\ residual\ data\ can\ be\ found\ in\ log.txt}

\end{DoxyCode}


Here is a sample output in the file log.\+txt:\+ 
\begin{DoxyCode}{0}
\DoxyCodeLine{Generate\ time\ (ns):\ 861}
\DoxyCodeLine{Apply\ time\ (ns):\ 108144}
\DoxyCodeLine{Residual\_norm:\ 2.10788e-\/15}
\DoxyCodeLine{Generate\ operations\ times\ (ns):}
\DoxyCodeLine{Apply\ operations\ times\ (ns):}
\DoxyCodeLine{\ \ \ \ allocate:\ 14991}
\DoxyCodeLine{\ \ \ \ cg::\doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{initialize}}\#8:\ 872}
\DoxyCodeLine{\ \ \ \ cg::step\_1\#5:\ 7683}
\DoxyCodeLine{\ \ \ \ cg::step\_2\#7:\ 7756}
\DoxyCodeLine{\ \ \ \ copy:\ 7751}
\DoxyCodeLine{\ \ \ \ csr::advanced\_spmv\#5:\ 21819}
\DoxyCodeLine{\ \ \ \ csr::spmv\#3:\ 20429}
\DoxyCodeLine{\ \ \ \ dense::compute\_dot\#3:\ 18043}
\DoxyCodeLine{\ \ \ \ dense::compute\_norm2\#2:\ 16726}
\DoxyCodeLine{\ \ \ \ free:\ 8857}
\DoxyCodeLine{\ \ \ \ residual\_norm::residual\_norm\#9:\ 3614}
\DoxyCodeLine{Recurrent\ Residual\ Norms:}
\DoxyCodeLine{[}
\DoxyCodeLine{\ \ \ \ 4.3589}
\DoxyCodeLine{\ \ \ \ 2.30455}
\DoxyCodeLine{\ \ \ \ 1.46771}
\DoxyCodeLine{\ \ \ \ 0.984875}
\DoxyCodeLine{\ \ \ \ 0.741833}
\DoxyCodeLine{\ \ \ \ 0.513623}
\DoxyCodeLine{\ \ \ \ 0.384165}
\DoxyCodeLine{\ \ \ \ 0.316439}
\DoxyCodeLine{\ \ \ \ 0.227709}
\DoxyCodeLine{\ \ \ \ 0.170312}
\DoxyCodeLine{\ \ \ \ 0.0973722}
\DoxyCodeLine{\ \ \ \ 0.0616831}
\DoxyCodeLine{\ \ \ \ 0.0454123}
\DoxyCodeLine{\ \ \ \ 0.031953}
\DoxyCodeLine{\ \ \ \ 0.0161606}
\DoxyCodeLine{\ \ \ \ 0.00657015}
\DoxyCodeLine{\ \ \ \ 0.00264367}
\DoxyCodeLine{\ \ \ \ 0.000858809}
\DoxyCodeLine{\ \ \ \ 0.000286461}
\DoxyCodeLine{\ \ \ \ 1.64195e-\/15}
\DoxyCodeLine{];}
\DoxyCodeLine{True\ Residual\ Norms:}
\DoxyCodeLine{[}
\DoxyCodeLine{\ \ \ \ 4.3589}
\DoxyCodeLine{\ \ \ \ 2.30455}
\DoxyCodeLine{\ \ \ \ 1.46771}
\DoxyCodeLine{\ \ \ \ 0.984875}
\DoxyCodeLine{\ \ \ \ 0.741833}
\DoxyCodeLine{\ \ \ \ 0.513623}
\DoxyCodeLine{\ \ \ \ 0.384165}
\DoxyCodeLine{\ \ \ \ 0.316439}
\DoxyCodeLine{\ \ \ \ 0.227709}
\DoxyCodeLine{\ \ \ \ 0.170312}
\DoxyCodeLine{\ \ \ \ 0.0973722}
\DoxyCodeLine{\ \ \ \ 0.0616831}
\DoxyCodeLine{\ \ \ \ 0.0454123}
\DoxyCodeLine{\ \ \ \ 0.031953}
\DoxyCodeLine{\ \ \ \ 0.0161606}
\DoxyCodeLine{\ \ \ \ 0.00657015}
\DoxyCodeLine{\ \ \ \ 0.00264367}
\DoxyCodeLine{\ \ \ \ 0.000858809}
\DoxyCodeLine{\ \ \ \ 0.000286461}
\DoxyCodeLine{\ \ \ \ 2.10788e-\/15}
\DoxyCodeLine{];}

\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{\textcolor{preprocessor}{\#include\ <algorithm>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <array>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <chrono>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <cstdlib>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <fstream>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <iomanip>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <iostream>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <map>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <ostream>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <sstream>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <string>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <unordered\_map>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <utility>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <vector>}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <ginkgo/ginkgo.hpp>}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{\textcolor{keyword}{using\ }vec\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<ValueType>}};}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{\textcolor{keyword}{using\ }real\_vec\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<gko::remove\_complex<ValueType>}}>;}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{namespace\ }utils\ \{}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{std::unique\_ptr<vec<ValueType>>\ create\_vector(}
\DoxyCodeLine{\ \ \ \ std::shared\_ptr<const\ gko::Executor>\ exec,\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\ size,}
\DoxyCodeLine{\ \ \ \ ValueType\ value)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ res\ =\ vec<ValueType>::create(exec);}
\DoxyCodeLine{\ \ \ \ res-\/>read(gko::matrix\_data<ValueType>(gko::dim<2>\{size,\ 1\},\ value));}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ res;}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{ValueType\ get\_first\_element(\textcolor{keyword}{const}\ vec<ValueType>*\ norm)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ norm-\/>get\_executor()-\/>copy\_val\_to\_host(norm-\/>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(\textcolor{keyword}{const}\ vec<ValueType>*\ b)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ exec\ =\ b-\/>get\_executor();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ b\_norm\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec<ValueType>}}>(\{0.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ b-\/>compute\_norm2(b\_norm);}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ get\_first\_element(b\_norm.get());}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{\doxymbox{\hyperlink{namespacegko_a107302a750bfa82a2107c77293f791c9}{gko::remove\_complex<ValueType>}}\ compute\_residual\_norm(}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ gko::LinOp*\ system\_matrix,\ \textcolor{keyword}{const}\ vec<ValueType>*\ b,}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ vec<ValueType>*\ x)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ exec\ =\ system\_matrix-\/>get\_executor();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ \doxymbox{\hyperlink{namespacegko_a0059e27f8f4bc348ff65c1e60caf47c8}{one}}\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<vec<ValueType>}}>(\{1.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ neg\_one\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<vec<ValueType>}}>(\{-\/1.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ res\ =\ \doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{gko::clone}}(b);}
\DoxyCodeLine{\ \ \ \ system\_matrix-\/>\doxymbox{\hyperlink{classgko_1_1LinOp_a8aba659b97d7bb9ad0c1a0d385c28f28}{apply}}(one,\ x,\ neg\_one,\ res);}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ compute\_norm(res.get());}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\}\ \ \textcolor{comment}{//\ namespace\ utils}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{namespace\ }loggers\ \{}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{struct\ }OperationLogger\ :\ gko::log::Logger\ \{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_allocation\_started(\textcolor{keyword}{const}\ gko::Executor*\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\&)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>start\_operation(exec,\ \textcolor{stringliteral}{"{}allocate"{}});}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_allocation\_completed(\textcolor{keyword}{const}\ gko::Executor*\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\&,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>end\_operation(exec,\ \textcolor{stringliteral}{"{}allocate"{}});}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_free\_started(\textcolor{keyword}{const}\ gko::Executor*\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>start\_operation(exec,\ \textcolor{stringliteral}{"{}free"{}});}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_free\_completed(\textcolor{keyword}{const}\ gko::Executor*\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>end\_operation(exec,\ \textcolor{stringliteral}{"{}free"{}});}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_copy\_started(\textcolor{keyword}{const}\ gko::Executor*\ from,\ \textcolor{keyword}{const}\ gko::Executor*\ to,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&,\ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\&)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ from-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>start\_operation(to,\ \textcolor{stringliteral}{"{}copy"{}});}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_copy\_completed(\textcolor{keyword}{const}\ gko::Executor*\ from,\ \textcolor{keyword}{const}\ gko::Executor*\ to,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&,\ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\&)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ from-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>end\_operation(to,\ \textcolor{stringliteral}{"{}copy"{}});}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_operation\_launched(\textcolor{keyword}{const}\ gko::Executor*\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ gko::Operation*\ op)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>start\_operation(exec,\ op-\/>\doxymbox{\hyperlink{classgko_1_1Operation_ada3255c1fbae4a203627c0affce1aa23}{get\_name}}());}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_operation\_completed(\textcolor{keyword}{const}\ gko::Executor*\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ gko::Operation*\ op)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ this-\/>end\_operation(exec,\ op-\/>\doxymbox{\hyperlink{classgko_1_1Operation_ada3255c1fbae4a203627c0affce1aa23}{get\_name}}());}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ write\_data(std::ostream\&\ ostream)}
\DoxyCodeLine{\ \ \ \ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keyword}{const}\ \textcolor{keyword}{auto}\&\ entry\ :\ total)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)t"{}}\ <<\ entry.first.c\_str()\ <<\ \textcolor{stringliteral}{"{}:\ "{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::chrono::duration\_cast<std::chrono::nanoseconds>(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ entry.second)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .count()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{private}:}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ start\_operation(\textcolor{keyword}{const}\ gko::Executor*\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ std::string\&\ name)\textcolor{keyword}{\ const}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ nested.emplace\_back(0);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ start[name]\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ end\_operation(\textcolor{keyword}{const}\ gko::Executor*\ exec,\ \textcolor{keyword}{const}\ std::string\&\ name)\textcolor{keyword}{\ const}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \textcolor{keyword}{auto}\ end\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \textcolor{keyword}{auto}\ diff\ =\ end\ -\/\ start[name];}
\DoxyCodeLine{\ \ \ \ \ \ \ \ total[name]\ +=\ diff\ -\/\ nested.back();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ nested.pop\_back();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (nested.size()\ >\ 0)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ nested.back()\ +=\ diff;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{mutable}\ std::map<std::string,\ std::chrono::steady\_clock::time\_point>\ start;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{mutable}\ std::map<std::string,\ std::chrono::steady\_clock::duration>\ total;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{mutable}\ std::vector<std::chrono::steady\_clock::duration>\ nested;}
\DoxyCodeLine{\};}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{struct\ }StorageLogger\ :\ gko::log::Logger\ \{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_allocation\_completed(\textcolor{keyword}{const}\ gko::Executor*,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\&\ num\_bytes,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&\ location)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ storage[location]\ =\ num\_bytes;}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_free\_completed(\textcolor{keyword}{const}\ gko::Executor*,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a70648f1299a0c1297e2bf86f47264626}{gko::uintptr}}\&\ location)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ storage[location]\ =\ 0;}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ write\_data(std::ostream\&\ ostream)}
\DoxyCodeLine{\ \ \ \ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\ total\{\};}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keyword}{const}\ \textcolor{keyword}{auto}\&\ e\ :\ storage)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ total\ +=\ e.second;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}Storage:\ "{}}\ <<\ total\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{private}:}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{mutable}\ std::unordered\_map<gko::uintptr,\ gko::size\_type>\ storage;}
\DoxyCodeLine{\};}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{\textcolor{keyword}{struct\ }ResidualLogger\ :\ gko::log::Logger\ \{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ on\_iteration\_complete(\textcolor{keyword}{const}\ gko::LinOp*,\ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\&,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ gko::LinOp*\ residual,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ gko::LinOp*\ solution,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ gko::LinOp*\ residual\_norm)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (residual\_norm)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ rec\_res\_norms.push\_back(utils::get\_first\_element(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as}}<real\_vec<ValueType>>(residual\_norm)));}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}\ \textcolor{keywordflow}{else}\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ rec\_res\_norms.push\_back(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ utils::compute\_norm(\doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as}}<vec<ValueType>>(residual)));}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (solution)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ true\_res\_norms.push\_back(utils::compute\_residual\_norm(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ matrix,\ b,\ \doxymbox{\hyperlink{namespacegko_ae3e355a655feea026a7c46814d37a9c9}{gko::as}}<vec<ValueType>>(solution)));}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}\ \textcolor{keywordflow}{else}\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ true\_res\_norms.push\_back(-\/1.0);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ ResidualLogger(\textcolor{keyword}{const}\ gko::LinOp*\ matrix,\ \textcolor{keyword}{const}\ vec<ValueType>*\ b)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ :\ gko::log::Logger(gko::log::Logger::iteration\_complete\_mask),}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ matrix\{matrix\},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ b\{b\}}
\DoxyCodeLine{\ \ \ \ \{\}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ write\_data(std::ostream\&\ ostream)}
\DoxyCodeLine{\ \ \ \ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}Recurrent\ Residual\ Norms:\ "{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}["{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keyword}{const}\ \textcolor{keyword}{auto}\&\ entry\ :\ rec\_res\_norms)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)t"{}}\ <<\ entry\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}];"{}}\ <<\ std::endl;}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}True\ Residual\ Norms:\ "{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}["{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keyword}{const}\ \textcolor{keyword}{auto}\&\ entry\ :\ true\_res\_norms)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)t"{}}\ <<\ entry\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ ostream\ <<\ \textcolor{stringliteral}{"{}];"{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{private}:}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ gko::LinOp*\ matrix;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ vec<ValueType>*\ b;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{mutable}\ std::vector<gko::remove\_complex<ValueType>>\ rec\_res\_norms;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{mutable}\ std::vector<gko::remove\_complex<ValueType>>\ true\_res\_norms;}
\DoxyCodeLine{\};}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\}\ \ \textcolor{comment}{//\ namespace\ loggers}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{namespace\ }\{}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ print\_usage(\textcolor{keyword}{const}\ \textcolor{keywordtype}{char}*\ filename)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ std::cerr\ <<\ \textcolor{stringliteral}{"{}Usage:\ "{}}\ <<\ filename\ <<\ \textcolor{stringliteral}{"{}\ [executor]\ [matrix\ file]"{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::cerr\ <<\ \textcolor{stringliteral}{"{}matrix\ file\ should\ be\ a\ file\ in\ matrix\ market\ format.\ "{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{stringliteral}{"{}The\ file\ data/A.mtx\ is\ provided\ as\ an\ example."{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::exit(-\/1);}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType>}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ print\_vector(\textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<ValueType>}}*\ vec)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ elements\_to\_print\ =\ std::min(\doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}(10),\ vec-\/>get\_size()[0]);}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}["{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ i\ =\ 0;\ i\ <\ elements\_to\_print;\ ++i)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)t"{}}\ <<\ vec-\/>\doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense_a11528fc674c7885fbcb0936ef873f859}{at}}(i)\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}];"{}}\ <<\ std::endl;}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\}\ \ \textcolor{comment}{//\ namespace}}
\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\ }IndexType\ =\ int;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }mtx\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Csr}{gko::matrix::Csr<ValueType,\ IndexType>}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }\doxymbox{\hyperlink{namespacegko_1_1log_a15f71654c6c4f4defc95f9359343fa27a7cbf673200498a0d1324f4330825202a}{solver}}\ =\ \doxymbox{\hyperlink{classgko_1_1solver_1_1Cg}{gko::solver::Cg<ValueType>}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }preconditioner\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1IdentityFactory}{gko::matrix::IdentityFactory<ValueType>}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{namespacegko_a107302a750bfa82a2107c77293f791c9}{gko::remove\_complex<ValueType>}}\ reduction\_factor\ =\ 1e-\/12;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ \textcolor{keyword}{auto}\ of\_name\ =\ \textcolor{stringliteral}{"{}log.txt"{}};}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }vec\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<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{\ \ \ \ std::string\ input\_mtx\ =\ \textcolor{stringliteral}{"{}data/A.mtx"{}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{if}\ (argc\ ==\ 3)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ input\_mtx\ =\ std::string(argv[2]);}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ storage\_logger\ =\ std::make\_shared<loggers::StorageLogger>();}
\DoxyCodeLine{\ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a520dad04b7e74f285ab0956873a5413d}{add\_logger}}(storage\_logger);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ A\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{gko::share}}(\doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<mtx>}}(std::ifstream(input\_mtx),\ exec));}
\DoxyCodeLine{\ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_af04cdc1a9af6c8efc34ddebb9e7aaf00}{remove\_logger}}(storage\_logger);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ \textcolor{keyword}{auto}\ max\_iters\ =\ A-\/>get\_size()[0];}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ b\ =\ utils::create\_vector<ValueType>(exec,\ A-\/>get\_size()[0],\ 1.0);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ x\ =\ utils::create\_vector<ValueType>(exec,\ A-\/>get\_size()[0],\ 0.0);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ solver\_factory\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ solver::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .with\_criteria(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ gko::stop::ResidualNorm<ValueType>::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_reduction\_factor(reduction\_factor),}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ gko::stop::Iteration::build().with\_max\_iters(max\_iters))}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .with\_preconditioner(preconditioner::create(exec))}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .on(exec);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ std::ofstream\ output\_file(of\_name);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ x\_clone\ =\ \doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{gko::clone}}(x);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ solver\_factory-\/>generate(A)-\/>apply(b,\ x\_clone);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ x\_clone\ =\ \doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{gko::clone}}(x);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ g\_tic\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ generated\_solver\ =\ solver\_factory-\/>generate(A);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ g\_tac\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ generate\_time\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ std::chrono::duration\_cast<std::chrono::nanoseconds>(g\_tac\ -\/\ g\_tic);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ output\_file\ <<\ \textcolor{stringliteral}{"{}Generate\ time\ (ns):\ "{}}\ <<\ generate\_time.count()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::endl;}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ a\_tic\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ generated\_solver-\/>apply(b,\ x\_clone);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a24eeee7648c0f0fd07c9866d07154875}{synchronize}}();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ a\_tac\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ apply\_time\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ std::chrono::duration\_cast<std::chrono::nanoseconds>(a\_tac\ -\/\ a\_tic);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ output\_file\ <<\ \textcolor{stringliteral}{"{}Apply\ time\ (ns):\ "{}}\ <<\ apply\_time.count()\ <<\ std::endl;}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ residual\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ utils::compute\_residual\_norm(A.get(),\ b.get(),\ x\_clone.get());}
\DoxyCodeLine{\ \ \ \ \ \ \ \ output\_file\ <<\ \textcolor{stringliteral}{"{}Residual\_norm:\ "{}}\ <<\ residual\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ gen\_logger\ =\ std::make\_shared<loggers::OperationLogger>();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a520dad04b7e74f285ab0956873a5413d}{add\_logger}}(gen\_logger);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ generated\_solver\ =\ solver\_factory-\/>generate(A);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_af04cdc1a9af6c8efc34ddebb9e7aaf00}{remove\_logger}}(gen\_logger);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ output\_file\ <<\ \textcolor{stringliteral}{"{}Generate\ operations\ times\ (ns):"{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ gen\_logger-\/>write\_data(output\_file);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ apply\_logger\ =\ std::make\_shared<loggers::OperationLogger>();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_a520dad04b7e74f285ab0956873a5413d}{add\_logger}}(apply\_logger);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ res\_logger\ =\ std::make\_shared<loggers::ResidualLogger<ValueType>>(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ A.get(),\ b.get());}
\DoxyCodeLine{\ \ \ \ \ \ \ \ generated\_solver-\/>add\_logger(res\_logger);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ generated\_solver-\/>apply(b,\ x);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec-\/>\doxymbox{\hyperlink{classgko_1_1Executor_af04cdc1a9af6c8efc34ddebb9e7aaf00}{remove\_logger}}(apply\_logger);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ output\_file\ <<\ \textcolor{stringliteral}{"{}Apply\ operations\ times\ (ns):"{}}\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ apply\_logger-\/>write\_data(output\_file);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ res\_logger-\/>write\_data(output\_file);}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Solution,\ first\ ten\ entries:\ \(\backslash\)n"{}};}
\DoxyCodeLine{\ \ \ \ print\_vector(x.get());}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}The\ performance\ and\ residual\ data\ can\ be\ found\ in\ "{}}\ <<\ of\_name}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::endl;}
\DoxyCodeLine{\}}

\end{DoxyCodeInclude}
 