\chapter{The cb-\/gmres program }
\hypertarget{cb_gmres}{}\label{cb_gmres}\index{The cb-\/gmres program@{The cb-\/gmres program}}
The CB-\/\+GMRES solver example.

 \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 showcases the usage of the Ginkgo solver CB-\/\+GMRES (Compressed Basis GMRES). A small system is solved with two un-\/preconditioned CB-\/\+GMRES solvers:\+
\begin{DoxyEnumerate}
\item without compressing the krylov basis; it uses double precision for both the matrix and the krylov basis, and
\item with a compression of the krylov basis; it uses double precision for the matrix and all arithmetic operations, while using single precision for the storage of the krylov basis
\end{DoxyEnumerate}

Both solves are timed and the residual norm of each solution is computed to show that both solutions are correct. \label{three_pt_stencil_solver_CommProg}%
\Hypertarget{three_pt_stencil_solver_CommProg}%
 \doxysection*{The commented program}

Make sure all previous executor operations have finished before starting the time


\begin{DoxyCode}{0}
\DoxyCodeLine{exec-\/>synchronize();}
\DoxyCodeLine{\textcolor{keyword}{auto}\ tic\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{\doxymbox{\hyperlink{namespacegko_1_1log_a15f71654c6c4f4defc95f9359343fa27a7cbf673200498a0d1324f4330825202a}{solver}}-\/>apply(b,\ x\_copy);}

\end{DoxyCode}


Make sure all computations are done before stopping the time


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ exec-\/>synchronize();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ tac\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{\ \ \ \ duration\ +=\ std::chrono::duration<double>(tac\ -\/\ tic).count();}
\DoxyCodeLine{\}}

\end{DoxyCode}


Copy the solution back to x, so the caller has the result


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ x-\/>copy\_from(x\_copy);}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ duration\ /\ \textcolor{keyword}{static\_cast<}\textcolor{keywordtype}{double}\textcolor{keyword}{>}(repeats);}
\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_1CbGmres}{gko::\+solver::\+\+Cb\+Gmres} is used here, but any other solver class can also be used.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{using\ }cb\_gmres\ =\ \doxymbox{\hyperlink{classgko_1_1solver_1_1CbGmres}{gko::solver::CbGmres<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;}
\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{\}}

\end{DoxyCode}


Map which generates the appropriate executor


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


Note:\+ this matrix is copied from "{}\+SOURCE\+\_\+\+DIR/\+matrices"{} instead of from the local directory. For details, see "{}examples/\+cb-\/gmres/\+\+CMake\+Lists.\+txt"{}


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

\end{DoxyCode}


Create a uniform right-\/hand side with a norm2 of 1 on the host (norm2(b) == 1), followed by copying it to the actual executor (to make sure it also works for GPUs)


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{const}\ \textcolor{keyword}{auto}\ A\_size\ =\ A-\/>get\_size();}
\DoxyCodeLine{\textcolor{keyword}{auto}\ b\_host\ =\ vec::create(exec-\/>get\_master(),\ \doxymbox{\hyperlink{structgko_1_1dim}{gko::dim<2>}}\{A\_size[0],\ 1\});}
\DoxyCodeLine{\textcolor{keywordflow}{for}\ (\doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\ i\ =\ 0;\ i\ <\ A\_size[0];\ ++i)\ \{}
\DoxyCodeLine{\ \ \ \ b\_host-\/>at(i,\ 0)\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ ValueType\{1\}\ /\ std::sqrt(\textcolor{keyword}{static\_cast<}ValueType\textcolor{keyword}{>}(A\_size[0]));}
\DoxyCodeLine{\}}
\DoxyCodeLine{\textcolor{keyword}{auto}\ b\_norm\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec);}
\DoxyCodeLine{b\_host-\/>compute\_norm2(b\_norm);}
\DoxyCodeLine{\textcolor{keyword}{auto}\ b\ =\ \doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{clone}}(exec,\ b\_host);}

\end{DoxyCode}


As an initial guess, use the right-\/hand side


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ x\_keep\ =\ \doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{clone}}(b);}
\DoxyCodeLine{\textcolor{keyword}{auto}\ x\_reduce\ =\ \doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{clone}}(x\_keep);}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{const}\ RealValueType\ reduction\_factor\{1e-\/6\};}

\end{DoxyCode}


Generate two solver factories:\+ {\ttfamily \+\_\+keep} uses the same precision for the krylov basis as the matrix, and {\ttfamily \+\_\+reduce} uses one precision below it. If {\ttfamily Value\+Type} is double, then {\ttfamily \+\_\+reduce} uses float as the krylov basis storage type


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ solver\_gen\_keep\ =}
\DoxyCodeLine{\ \ \ \ cb\_gmres::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .with\_criteria(gko::stop::Iteration::build().with\_max\_iters(1000u),}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ gko::stop::ResidualNorm<ValueType>::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_baseline(gko::stop::mode::rhs\_norm)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_reduction\_factor(reduction\_factor))}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .with\_krylov\_dim(100u)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .with\_storage\_precision(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ gko::solver::cb\_gmres::storage\_precision::keep)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .on(exec);}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{auto}\ solver\_gen\_reduce\ =}
\DoxyCodeLine{\ \ \ \ cb\_gmres::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .with\_criteria(gko::stop::Iteration::build().with\_max\_iters(1000u),}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ gko::stop::ResidualNorm<ValueType>::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_baseline(gko::stop::mode::rhs\_norm)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_reduction\_factor(reduction\_factor))}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .with\_krylov\_dim(100u)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .with\_storage\_precision(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ gko::solver::cb\_gmres::storage\_precision::reduce1)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .on(exec);}

\end{DoxyCode}


Generate the actual solver from the factory and the matrix.


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

\end{DoxyCode}


Solve both system and measure the time for each.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ time\_keep\ =}
\DoxyCodeLine{\ \ \ \ measure\_solve\_time\_in\_s(exec,\ solver\_keep.get(),\ b.get(),\ x\_keep.get());}
\DoxyCodeLine{\textcolor{keyword}{auto}\ time\_reduce\ =\ measure\_solve\_time\_in\_s(exec,\ solver\_reduce.get(),}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ b.get(),\ x\_reduce.get());}

\end{DoxyCode}


Make sure the output is in scientific notation for easier comparison


\begin{DoxyCode}{0}
\DoxyCodeLine{std::cout\ <<\ std::scientific;}

\end{DoxyCode}


Note:\+ The time might not be significantly different since the matrix is quite small


\begin{DoxyCode}{0}
\DoxyCodeLine{std::cout\ <<\ \textcolor{stringliteral}{"{}Solve\ time\ without\ compression:\ "{}}\ <<\ time\_keep\ <<\ \textcolor{stringliteral}{"{}\ s\(\backslash\)n"{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ <<\ \textcolor{stringliteral}{"{}Solve\ time\ with\ compression:\ \ \ \ "{}}\ <<\ time\_reduce\ <<\ \textcolor{stringliteral}{"{}\ s\(\backslash\)n"{}};}

\end{DoxyCode}


To measure if your solution has actually converged, the error of the solution is measured. one, neg\+\_\+one are objects that represent the numbers which allow for a uniform interface when computing on any device. To compute the residual, the (advanced) apply method is used.


\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{}
\DoxyCodeLine{\textcolor{keyword}{auto}\ res\_norm\_keep\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec);}
\DoxyCodeLine{\textcolor{keyword}{auto}\ res\_norm\_reduce\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec);}
\DoxyCodeLine{\textcolor{keyword}{auto}\ tmp\ =\ \doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{gko::clone}}(b);}

\end{DoxyCode}


tmp = Ax -\/ tmp


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ A-\/>apply(one,\ x\_keep,\ neg\_one,\ tmp);}
\DoxyCodeLine{\ \ \ \ tmp-\/>compute\_norm2(res\_norm\_keep);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)nResidual\ norm\ without\ compression:\(\backslash\)n"{}};}
\DoxyCodeLine{\ \ \ \ \doxymbox{\hyperlink{namespacegko_af82d8f7795fefcf5f38a38895e316c02}{write}}(std::cout,\ res\_norm\_keep);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ tmp-\/>copy\_from(b);}
\DoxyCodeLine{\ \ \ \ A-\/>apply(one,\ x\_reduce,\ neg\_one,\ tmp);}
\DoxyCodeLine{\ \ \ \ tmp-\/>compute\_norm2(res\_norm\_reduce);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)nResidual\ norm\ with\ compression:\(\backslash\)n"{}};}
\DoxyCodeLine{\ \ \ \ \doxymbox{\hyperlink{namespacegko_af82d8f7795fefcf5f38a38895e316c02}{write}}(std::cout,\ res\_norm\_reduce);}
\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{Solve\ time\ without\ compression:\ 1.842690e-\/04\ s}
\DoxyCodeLine{Solve\ time\ with\ compression:\ \ \ \ 1.589936e-\/04\ s}
\DoxyCodeLine{}
\DoxyCodeLine{Residual\ norm\ without\ compression:}
\DoxyCodeLine{\%\%MatrixMarket\ matrix\ \doxymbox{\hyperlink{namespacegko_ae749a5ea11a93c1bcc9158d9a6e9fb68af1f713c9e000f5d3f280adbd124df4f5}{array}}\ \doxymbox{\hyperlink{namespacegko_af21648097306adbabc6234b4609ce297}{real}}\ general}
\DoxyCodeLine{1\ 1}
\DoxyCodeLine{2.430544e-\/07}
\DoxyCodeLine{}
\DoxyCodeLine{Residual\ norm\ with\ compression:}
\DoxyCodeLine{\%\%MatrixMarket\ matrix\ \doxymbox{\hyperlink{namespacegko_ae749a5ea11a93c1bcc9158d9a6e9fb68af1f713c9e000f5d3f280adbd124df4f5}{array}}\ \doxymbox{\hyperlink{namespacegko_af21648097306adbabc6234b4609ce297}{real}}\ general}
\DoxyCodeLine{1\ 1}
\DoxyCodeLine{3.437257e-\/07}

\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\ <chrono>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <cmath>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <fstream>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <iostream>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <map>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <string>}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <ginkgo/ginkgo.hpp>}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{double}\ measure\_solve\_time\_in\_s(std::shared\_ptr<const\ gko::Executor>\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*\ solver,\ \textcolor{keyword}{const}\ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*\ b,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \doxymbox{\hyperlink{classgko_1_1LinOp}{gko::LinOp}}*\ x)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{constexpr}\ \textcolor{keywordtype}{int}\ repeats\{5\};}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{double}\ duration\{0\};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ x\_copy\ =\ \doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{clone}}(x);}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ i\ =\ 0;\ i\ <\ repeats;\ ++i)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (i\ !=\ 0)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ x\_copy-\/>copy\_from(x);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec-\/>synchronize();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ tic\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \doxymbox{\hyperlink{namespacegko_1_1log_a15f71654c6c4f4defc95f9359343fa27a7cbf673200498a0d1324f4330825202a}{solver}}-\/>apply(b,\ x\_copy);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec-\/>synchronize();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ tac\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ duration\ +=\ std::chrono::duration<double>(tac\ -\/\ tic).count();}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ x-\/>copy\_from(x\_copy);}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ duration\ /\ \textcolor{keyword}{static\_cast<}\textcolor{keywordtype}{double}\textcolor{keyword}{>}(repeats);}
\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\ }cb\_gmres\ =\ \doxymbox{\hyperlink{classgko_1_1solver_1_1CbGmres}{gko::solver::CbGmres<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}{const}\ \textcolor{keyword}{auto}\ A\_size\ =\ A-\/>get\_size();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ b\_host\ =\ vec::create(exec-\/>get\_master(),\ \doxymbox{\hyperlink{structgko_1_1dim}{gko::dim<2>}}\{A\_size[0],\ 1\});}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{for}\ (\doxymbox{\hyperlink{namespacegko_a9579c98b1d85bf4ad02d7cb5b96fc771}{gko::size\_type}}\ i\ =\ 0;\ i\ <\ A\_size[0];\ ++i)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ b\_host-\/>at(i,\ 0)\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ ValueType\{1\}\ /\ std::sqrt(\textcolor{keyword}{static\_cast<}ValueType\textcolor{keyword}{>}(A\_size[0]));}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ b\_norm\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ b\_host-\/>compute\_norm2(b\_norm);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ b\ =\ \doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{clone}}(exec,\ b\_host);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ x\_keep\ =\ \doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{clone}}(b);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ x\_reduce\ =\ \doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{clone}}(x\_keep);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{const}\ RealValueType\ reduction\_factor\{1e-\/6\};}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ solver\_gen\_keep\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ cb\_gmres::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .with\_criteria(gko::stop::Iteration::build().with\_max\_iters(1000u),}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ gko::stop::ResidualNorm<ValueType>::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_baseline(gko::stop::mode::rhs\_norm)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_reduction\_factor(reduction\_factor))}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .with\_krylov\_dim(100u)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .with\_storage\_precision(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ gko::solver::cb\_gmres::storage\_precision::keep)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .on(exec);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ solver\_gen\_reduce\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ cb\_gmres::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .with\_criteria(gko::stop::Iteration::build().with\_max\_iters(1000u),}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ gko::stop::ResidualNorm<ValueType>::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_baseline(gko::stop::mode::rhs\_norm)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_reduction\_factor(reduction\_factor))}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .with\_krylov\_dim(100u)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .with\_storage\_precision(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ gko::solver::cb\_gmres::storage\_precision::reduce1)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .on(exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ solver\_keep\ =\ solver\_gen\_keep-\/>generate(A);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ solver\_reduce\ =\ solver\_gen\_reduce-\/>generate(A);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ time\_keep\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ measure\_solve\_time\_in\_s(exec,\ solver\_keep.get(),\ b.get(),\ x\_keep.get());}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ time\_reduce\ =\ measure\_solve\_time\_in\_s(exec,\ solver\_reduce.get(),}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ b.get(),\ x\_reduce.get());}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ std::scientific;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Solve\ time\ without\ compression:\ "{}}\ <<\ time\_keep\ <<\ \textcolor{stringliteral}{"{}\ s\(\backslash\)n"{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ \textcolor{stringliteral}{"{}Solve\ time\ with\ compression:\ \ \ \ "{}}\ <<\ time\_reduce\ <<\ \textcolor{stringliteral}{"{}\ s\(\backslash\)n"{}};}
\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{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ res\_norm\_keep\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ res\_norm\_reduce\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ tmp\ =\ \doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{gko::clone}}(b);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ A-\/>apply(one,\ x\_keep,\ neg\_one,\ tmp);}
\DoxyCodeLine{\ \ \ \ tmp-\/>compute\_norm2(res\_norm\_keep);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)nResidual\ norm\ without\ compression:\(\backslash\)n"{}};}
\DoxyCodeLine{\ \ \ \ \doxymbox{\hyperlink{namespacegko_af82d8f7795fefcf5f38a38895e316c02}{write}}(std::cout,\ res\_norm\_keep);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ tmp-\/>copy\_from(b);}
\DoxyCodeLine{\ \ \ \ A-\/>apply(one,\ x\_reduce,\ neg\_one,\ tmp);}
\DoxyCodeLine{\ \ \ \ tmp-\/>compute\_norm2(res\_norm\_reduce);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)nResidual\ norm\ with\ compression:\(\backslash\)n"{}};}
\DoxyCodeLine{\ \ \ \ \doxymbox{\hyperlink{namespacegko_af82d8f7795fefcf5f38a38895e316c02}{write}}(std::cout,\ res\_norm\_reduce);}
\DoxyCodeLine{\}}

\end{DoxyCodeInclude}
 