\chapter{The mixed-\/spmv program }
\hypertarget{mixed_spmv}{}\label{mixed_spmv}\index{The mixed-\/spmv program@{The mixed-\/spmv program}}
The mixed spmv 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}

This mixed spmv example should give the usage of Ginkgo mixed precision. This example is meant for you to understand how Ginkgo works with different precision of data. We encourage you to play with the code, change the parameters and see what is best suited for your purposes.

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

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


\begin{DoxyCode}{0}
\DoxyCodeLine{\ *\ @param\ value\_dist\ \ distribution\ of\ \doxymbox{\hyperlink{namespacegko_ae749a5ea11a93c1bcc9158d9a6e9fb68af1f713c9e000f5d3f280adbd124df4f5}{array}}\ values}
\DoxyCodeLine{\ *\ @param\ engine\ \ a\ random\ engine}
\DoxyCodeLine{\ *}
\DoxyCodeLine{\ *\ @\textcolor{keywordflow}{return}\ ValueType}
\DoxyCodeLine{\ *\ /}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType,\ \textcolor{keyword}{typename}\ ValueDistribution,\ \textcolor{keyword}{typename}\ Engine>}
\DoxyCodeLine{\textcolor{keyword}{typename}\ std::enable\_if<!gko::is\_complex\_s<ValueType>::value,\ ValueType>::type}
\DoxyCodeLine{get\_rand\_value(ValueDistribution\&\&\ value\_dist,\ Engine\&\&\ gen)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ value\_dist(gen);}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{/\ **}
\DoxyCodeLine{\ *\ Specialization\ \textcolor{keywordflow}{for}\ complex\ types.}
\DoxyCodeLine{\ *}
\DoxyCodeLine{\ *\ @copydoc\ get\_rand\_value}
\DoxyCodeLine{\ *\ /}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType,\ \textcolor{keyword}{typename}\ ValueDistribution,\ \textcolor{keyword}{typename}\ Engine>}
\DoxyCodeLine{\textcolor{keyword}{typename}\ std::enable\_if<gko::is\_complex\_s<ValueType>::value,\ ValueType>::type}
\DoxyCodeLine{get\_rand\_value(ValueDistribution\&\&\ value\_dist,\ Engine\&\&\ gen)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ ValueType(value\_dist(gen),\ value\_dist(gen));}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{/\ **}
\DoxyCodeLine{\ *\ timing\ the\ apply\ \doxymbox{\hyperlink{namespacegko_1_1log_a15f71654c6c4f4defc95f9359343fa27af7235a61fdc3adc78d866fd8085d44db}{operation}}\ A-\/>apply(b,\ x).\ It\ will\ runs\ 2\ warmup\ and\ get}
\DoxyCodeLine{\ *\ average\ time\ among\ 10\ times.}
\DoxyCodeLine{\ *}
\DoxyCodeLine{\ *\ @\textcolor{keywordflow}{return}\ seconds}
\DoxyCodeLine{\ *\ /}
\DoxyCodeLine{\textcolor{keywordtype}{double}\ timing(std::shared\_ptr<const\ gko::Executor>\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ std::shared\_ptr<const\ gko::LinOp>\ A,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ std::shared\_ptr<const\ gko::LinOp>\ b,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ std::shared\_ptr<gko::LinOp>\ x)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{int}\ warmup\ =\ 2;}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{int}\ rep\ =\ 10;}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ i\ =\ 0;\ i\ <\ warmup;\ i++)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ A-\/>apply(b,\ x);}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{double}\ total\_sec\ =\ 0;}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ i\ =\ 0;\ i\ <\ rep;\ i++)\ \{}

\end{DoxyCode}


always clone the x in each apply


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ xx\ =\ x-\/>clone();}

\end{DoxyCode}


synchronize to make sure data is already on device


\begin{DoxyCode}{0}
\DoxyCodeLine{exec-\/>synchronize();}
\DoxyCodeLine{\textcolor{keyword}{auto}\ start\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{A-\/>apply(b,\ xx);}

\end{DoxyCode}


synchronize to make sure the operation is done


\begin{DoxyCode}{0}
\DoxyCodeLine{exec-\/>synchronize();}
\DoxyCodeLine{\textcolor{keyword}{auto}\ stop\ =\ std::chrono::steady\_clock::now();}

\end{DoxyCode}


get the duration in seconds


\begin{DoxyCode}{0}
\DoxyCodeLine{std::chrono::duration<double>\ duration\_time\ =\ stop\ -\/\ start;}
\DoxyCodeLine{total\_sec\ +=\ duration\_time.count();}
\DoxyCodeLine{\textcolor{keywordflow}{if}\ (i\ +\ 1\ ==\ rep)\ \{}

\end{DoxyCode}


copy the result back to x


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ x-\/>copy\_from(xx);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ total\_sec\ /\ rep;}
\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}


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\ }HighPrecision\ =\ double;}
\DoxyCodeLine{\textcolor{keyword}{using\ }RealValueType\ =\ \doxymbox{\hyperlink{namespacegko_a107302a750bfa82a2107c77293f791c9}{gko::remove\_complex<HighPrecision>}};}
\DoxyCodeLine{\textcolor{keyword}{using\ }LowPrecision\ =\ float;}
\DoxyCodeLine{\textcolor{keyword}{using\ }IndexType\ =\ int;}
\DoxyCodeLine{\textcolor{keyword}{using\ }hp\_vec\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<HighPrecision>}};}
\DoxyCodeLine{\textcolor{keyword}{using\ }lp\_vec\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<LowPrecision>}};}
\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_1Ell}{gko::\+matrix::\+\+Ell} 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_1Csr}{gko::\+matrix::\+\+Csr} or \doxylink{classgko_1_1matrix_1_1Sellp}{gko::\+matrix::\+\+Sellp} could also be used. Note. the behavior will depends GINKGO\+\_\+\+MIXED\+\_\+\+PRECISION flags and the actual implementation from different matrices.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{using\ }hp\_mtx\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Ell}{gko::matrix::Ell<HighPrecision,\ IndexType>}};}
\DoxyCodeLine{\textcolor{keyword}{using\ }lp\_mtx\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Ell}{gko::matrix::Ell<LowPrecision,\ IndexType>}};}

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


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

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

\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{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}


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

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


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ hp\_A\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(\doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<hp\_mtx>}}(std::ifstream(\textcolor{stringliteral}{"{}data/A.mtx"{}}),\ exec));}
\DoxyCodeLine{\textcolor{keyword}{auto}\ lp\_A\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(\doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<lp\_mtx>}}(std::ifstream(\textcolor{stringliteral}{"{}data/A.mtx"{}}),\ exec));}

\end{DoxyCode}


Set the shortcut for each dimension


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ A\_dim\ =\ hp\_A-\/>get\_size();}
\DoxyCodeLine{\textcolor{keyword}{auto}\ b\_dim\ =\ \doxymbox{\hyperlink{structgko_1_1dim}{gko::dim<2>}}\{A\_dim[1],\ 1\};}
\DoxyCodeLine{\textcolor{keyword}{auto}\ x\_dim\ =\ \doxymbox{\hyperlink{structgko_1_1dim}{gko::dim<2>}}\{A\_dim[0],\ b\_dim[1]\};}
\DoxyCodeLine{\textcolor{keyword}{auto}\ host\_b\ =\ hp\_vec::create(exec-\/>get\_master(),\ b\_dim);}

\end{DoxyCode}


fill the b vector with some random data


\begin{DoxyCode}{0}
\DoxyCodeLine{std::default\_random\_engine\ rand\_engine(32);}
\DoxyCodeLine{\textcolor{keyword}{auto}\ dist\ =\ std::uniform\_real\_distribution<RealValueType>(0.0,\ 1.0);}
\DoxyCodeLine{\textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ i\ =\ 0;\ i\ <\ host\_b-\/>get\_size()[0];\ i++)\ \{}
\DoxyCodeLine{\ \ \ \ host\_b-\/>at(i,\ 0)\ =\ get\_rand\_value<HighPrecision>(dist,\ rand\_engine);}
\DoxyCodeLine{\}}

\end{DoxyCode}


copy the data from host to device


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ hp\_b\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(\doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{gko::clone}}(exec,\ host\_b));}
\DoxyCodeLine{\textcolor{keyword}{auto}\ lp\_b\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(lp\_vec::create(exec));}
\DoxyCodeLine{lp\_b-\/>copy\_from(hp\_b);}

\end{DoxyCode}


create several result x vector in different precision


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ hp\_x\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(hp\_vec::create(exec,\ x\_dim));}
\DoxyCodeLine{\textcolor{keyword}{auto}\ lp\_x\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(lp\_vec::create(exec,\ x\_dim));}
\DoxyCodeLine{\textcolor{keyword}{auto}\ hplp\_x\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(hp\_x-\/>clone());}
\DoxyCodeLine{\textcolor{keyword}{auto}\ lplp\_x\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(hp\_x-\/>clone());}
\DoxyCodeLine{\textcolor{keyword}{auto}\ lphp\_x\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(hp\_x-\/>clone());}

\end{DoxyCode}


\label{mixed_spmv_Measurethetimeofapply}%
\Hypertarget{mixed_spmv_Measurethetimeofapply}%
 \doxysubsubsection*{Measure the time of apply}

We measure the time among different combination of apply operation.

Hp \texorpdfstring{$\ast$}{*} Hp -\/\texorpdfstring{$>$}{>} Hp


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ hp\_sec\ =\ timing(exec,\ hp\_A,\ hp\_b,\ hp\_x);}

\end{DoxyCode}


Lp \texorpdfstring{$\ast$}{*} Lp -\/\texorpdfstring{$>$}{>} Lp


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ lp\_sec\ =\ timing(exec,\ lp\_A,\ lp\_b,\ lp\_x);}

\end{DoxyCode}


Hp \texorpdfstring{$\ast$}{*} Lp -\/\texorpdfstring{$>$}{>} Hp


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ hplp\_sec\ =\ timing(exec,\ hp\_A,\ lp\_b,\ hplp\_x);}

\end{DoxyCode}


Lp \texorpdfstring{$\ast$}{*} Lp -\/\texorpdfstring{$>$}{>} Hp


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ lplp\_sec\ =\ timing(exec,\ lp\_A,\ lp\_b,\ lplp\_x);}

\end{DoxyCode}


Lp \texorpdfstring{$\ast$}{*} Hp -\/\texorpdfstring{$>$}{>} Hp


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ lphp\_sec\ =\ timing(exec,\ lp\_A,\ hp\_b,\ lphp\_x);}

\end{DoxyCode}


To measure error of result. neg\+\_\+one is an object that represent the number -\/1.\+0 which allows for a uniform interface when computing on any device. To compute the residual, all you need to do is call the add\+\_\+scaled method, which in this case is an axpy and equivalent to the LAPACK axpy routine. Finally, you compute the euclidean 2-\/norm with the compute\+\_\+norm2 function.


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ neg\_one\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<hp\_vec>}}(\{-\/1.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ hp\_x\_norm\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec-\/>get\_master());}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lp\_diff\_norm\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec-\/>get\_master());}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ hplp\_diff\_norm\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec-\/>get\_master());}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lplp\_diff\_norm\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec-\/>get\_master());}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lphp\_diff\_norm\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec-\/>get\_master());}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lp\_diff\ =\ hp\_x-\/>clone();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ hplp\_diff\ =\ hp\_x-\/>clone();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lplp\_diff\ =\ hp\_x-\/>clone();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lphp\_diff\ =\ hp\_x-\/>clone();}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ hp\_x-\/>compute\_norm2(hp\_x\_norm);}
\DoxyCodeLine{\ \ \ \ lp\_diff-\/>add\_scaled(neg\_one,\ lp\_x);}
\DoxyCodeLine{\ \ \ \ lp\_diff-\/>compute\_norm2(lp\_diff\_norm);}
\DoxyCodeLine{\ \ \ \ hplp\_diff-\/>add\_scaled(neg\_one,\ hplp\_x);}
\DoxyCodeLine{\ \ \ \ hplp\_diff-\/>compute\_norm2(hplp\_diff\_norm);}
\DoxyCodeLine{\ \ \ \ lplp\_diff-\/>add\_scaled(neg\_one,\ lplp\_x);}
\DoxyCodeLine{\ \ \ \ lplp\_diff-\/>compute\_norm2(lplp\_diff\_norm);}
\DoxyCodeLine{\ \ \ \ lphp\_diff-\/>add\_scaled(neg\_one,\ lphp\_x);}
\DoxyCodeLine{\ \ \ \ lphp\_diff-\/>compute\_norm2(lphp\_diff\_norm);}
\DoxyCodeLine{\ \ \ \ exec-\/>synchronize();}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ std::cout.precision(10);}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ std::scientific;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}High\ Precision\ time(s):\ "{}}\ <<\ hp\_sec\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}High\ Precision\ result\ norm:\ "{}}\ <<\ hp\_x\_norm-\/>at(0)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Low\ Precision\ time(s):\ "{}}\ <<\ lp\_sec\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Low\ Precision\ relative\ error:\ "{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ lp\_diff\_norm-\/>at(0)\ /\ hp\_x\_norm-\/>at(0)\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)n"{}};}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Hp\ *\ Lp\ -\/>\ Hp\ time(s):\ "{}}\ <<\ hplp\_sec\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Hp\ *\ Lp\ -\/>\ Hp\ relative\ error:\ "{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ hplp\_diff\_norm-\/>at(0)\ /\ hp\_x\_norm-\/>at(0)\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)n"{}};}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Lp\ *\ Lp\ -\/>\ Hp\ time(s):\ "{}}\ <<\ lplp\_sec\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Lp\ *\ Lp\ -\/>\ Hp\ relative\ error:\ "{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ lplp\_diff\_norm-\/>at(0)\ /\ hp\_x\_norm-\/>at(0)\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)n"{}};}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Lp\ *\ Hp\ -\/>\ Hp\ time(s):\ "{}}\ <<\ lplp\_sec\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Lp\ *\ Hp\ -\/>\ Hp\ relative\ error:\ "{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ lphp\_diff\_norm-\/>at(0)\ /\ hp\_x\_norm-\/>at(0)\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)n"{}};}
\DoxyCodeLine{\}}

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

The following is the expected result (omp):\+


\begin{DoxyCode}{0}
\DoxyCodeLine{High\ Precision\ time(s):\ 2.0568800000e-\/05}
\DoxyCodeLine{High\ Precision\ result\ norm:\ 1.7725534898e+05}
\DoxyCodeLine{Low\ Precision\ time(s):\ 2.0955600000e-\/05}
\DoxyCodeLine{Low\ Precision\ relative\ error:\ 9.1052887738e-\/08}
\DoxyCodeLine{Hp\ *\ Lp\ -\/>\ Hp\ time(s):\ 2.1186100000e-\/05}
\DoxyCodeLine{Hp\ *\ Lp\ -\/>\ Hp\ relative\ error:\ 3.7799774251e-\/08}
\DoxyCodeLine{Lp\ *\ Lp\ -\/>\ Hp\ time(s):\ 2.0312300000e-\/05}
\DoxyCodeLine{Lp\ *\ Lp\ -\/>\ Hp\ relative\ error:\ 5.7910008031e-\/08}
\DoxyCodeLine{Lp\ *\ Hp\ -\/>\ Hp\ time(s):\ 2.0312300000e-\/05}
\DoxyCodeLine{Lp\ *\ Hp\ -\/>\ Hp\ relative\ error:\ 3.7173133506e-\/08}

\end{DoxyCode}


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

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


\begin{DoxyCodeInclude}{0}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <ginkgo/ginkgo.hpp>}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <fstream>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <iostream>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <map>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <string>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <chrono>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <random>}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{namespace\ }\{}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType,\ \textcolor{keyword}{typename}\ ValueDistribution,\ \textcolor{keyword}{typename}\ Engine>}
\DoxyCodeLine{\textcolor{keyword}{typename}\ std::enable\_if<!gko::is\_complex\_s<ValueType>::value,\ ValueType>::type}
\DoxyCodeLine{get\_rand\_value(ValueDistribution\&\&\ value\_dist,\ Engine\&\&\ gen)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ value\_dist(gen);}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{template}\ <\textcolor{keyword}{typename}\ ValueType,\ \textcolor{keyword}{typename}\ ValueDistribution,\ \textcolor{keyword}{typename}\ Engine>}
\DoxyCodeLine{\textcolor{keyword}{typename}\ std::enable\_if<gko::is\_complex\_s<ValueType>::value,\ ValueType>::type}
\DoxyCodeLine{get\_rand\_value(ValueDistribution\&\&\ value\_dist,\ Engine\&\&\ gen)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ ValueType(value\_dist(gen),\ value\_dist(gen));}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{double}\ timing(std::shared\_ptr<const\ gko::Executor>\ exec,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ std::shared\_ptr<const\ gko::LinOp>\ A,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ std::shared\_ptr<const\ gko::LinOp>\ b,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ std::shared\_ptr<gko::LinOp>\ x)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{int}\ warmup\ =\ 2;}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{int}\ rep\ =\ 10;}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ i\ =\ 0;\ i\ <\ warmup;\ i++)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ A-\/>apply(b,\ x);}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{double}\ total\_sec\ =\ 0;}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ i\ =\ 0;\ i\ <\ rep;\ i++)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ xx\ =\ x-\/>clone();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec-\/>synchronize();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ start\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ A-\/>apply(b,\ xx);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ exec-\/>synchronize();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ stop\ =\ std::chrono::steady\_clock::now();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ std::chrono::duration<double>\ duration\_time\ =\ stop\ -\/\ start;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ total\_sec\ +=\ duration\_time.count();}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (i\ +\ 1\ ==\ rep)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ x-\/>copy\_from(xx);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ total\_sec\ /\ rep;}
\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\ }HighPrecision\ =\ double;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }RealValueType\ =\ \doxymbox{\hyperlink{namespacegko_a107302a750bfa82a2107c77293f791c9}{gko::remove\_complex<HighPrecision>}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }LowPrecision\ =\ float;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }IndexType\ =\ int;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }hp\_vec\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<HighPrecision>}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }lp\_vec\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<LowPrecision>}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }real\_vec\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<RealValueType>}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }hp\_mtx\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Ell}{gko::matrix::Ell<HighPrecision,\ IndexType>}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }lp\_mtx\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Ell}{gko::matrix::Ell<LowPrecision,\ IndexType>}};}
\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{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ hp\_A\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(\doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<hp\_mtx>}}(std::ifstream(\textcolor{stringliteral}{"{}data/A.mtx"{}}),\ exec));}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lp\_A\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(\doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<lp\_mtx>}}(std::ifstream(\textcolor{stringliteral}{"{}data/A.mtx"{}}),\ exec));}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ A\_dim\ =\ hp\_A-\/>get\_size();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ b\_dim\ =\ \doxymbox{\hyperlink{structgko_1_1dim}{gko::dim<2>}}\{A\_dim[1],\ 1\};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ x\_dim\ =\ \doxymbox{\hyperlink{structgko_1_1dim}{gko::dim<2>}}\{A\_dim[0],\ b\_dim[1]\};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ host\_b\ =\ hp\_vec::create(exec-\/>get\_master(),\ b\_dim);}
\DoxyCodeLine{\ \ \ \ std::default\_random\_engine\ rand\_engine(32);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ dist\ =\ std::uniform\_real\_distribution<RealValueType>(0.0,\ 1.0);}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ i\ =\ 0;\ i\ <\ host\_b-\/>get\_size()[0];\ i++)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ host\_b-\/>at(i,\ 0)\ =\ get\_rand\_value<HighPrecision>(dist,\ rand\_engine);}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ hp\_b\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(\doxymbox{\hyperlink{namespacegko_aa194e34282452493231ca7b01ffb5e64}{gko::clone}}(exec,\ host\_b));}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lp\_b\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(lp\_vec::create(exec));}
\DoxyCodeLine{\ \ \ \ lp\_b-\/>copy\_from(hp\_b);}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ hp\_x\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(hp\_vec::create(exec,\ x\_dim));}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lp\_x\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(lp\_vec::create(exec,\ x\_dim));}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ hplp\_x\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(hp\_x-\/>clone());}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lplp\_x\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(hp\_x-\/>clone());}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lphp\_x\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{share}}(hp\_x-\/>clone());}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ hp\_sec\ =\ timing(exec,\ hp\_A,\ hp\_b,\ hp\_x);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lp\_sec\ =\ timing(exec,\ lp\_A,\ lp\_b,\ lp\_x);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ hplp\_sec\ =\ timing(exec,\ hp\_A,\ lp\_b,\ hplp\_x);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lplp\_sec\ =\ timing(exec,\ lp\_A,\ lp\_b,\ lplp\_x);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lphp\_sec\ =\ timing(exec,\ lp\_A,\ hp\_b,\ lphp\_x);}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ neg\_one\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<hp\_vec>}}(\{-\/1.0\},\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ hp\_x\_norm\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec-\/>get\_master());}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lp\_diff\_norm\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec-\/>get\_master());}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ hplp\_diff\_norm\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec-\/>get\_master());}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lplp\_diff\_norm\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec-\/>get\_master());}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lphp\_diff\_norm\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<real\_vec>}}(\{0.0\},\ exec-\/>get\_master());}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lp\_diff\ =\ hp\_x-\/>clone();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ hplp\_diff\ =\ hp\_x-\/>clone();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lplp\_diff\ =\ hp\_x-\/>clone();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ lphp\_diff\ =\ hp\_x-\/>clone();}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ hp\_x-\/>compute\_norm2(hp\_x\_norm);}
\DoxyCodeLine{\ \ \ \ lp\_diff-\/>add\_scaled(neg\_one,\ lp\_x);}
\DoxyCodeLine{\ \ \ \ lp\_diff-\/>compute\_norm2(lp\_diff\_norm);}
\DoxyCodeLine{\ \ \ \ hplp\_diff-\/>add\_scaled(neg\_one,\ hplp\_x);}
\DoxyCodeLine{\ \ \ \ hplp\_diff-\/>compute\_norm2(hplp\_diff\_norm);}
\DoxyCodeLine{\ \ \ \ lplp\_diff-\/>add\_scaled(neg\_one,\ lplp\_x);}
\DoxyCodeLine{\ \ \ \ lplp\_diff-\/>compute\_norm2(lplp\_diff\_norm);}
\DoxyCodeLine{\ \ \ \ lphp\_diff-\/>add\_scaled(neg\_one,\ lphp\_x);}
\DoxyCodeLine{\ \ \ \ lphp\_diff-\/>compute\_norm2(lphp\_diff\_norm);}
\DoxyCodeLine{\ \ \ \ exec-\/>synchronize();}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ std::cout.precision(10);}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ std::scientific;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}High\ Precision\ time(s):\ "{}}\ <<\ hp\_sec\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}High\ Precision\ result\ norm:\ "{}}\ <<\ hp\_x\_norm-\/>at(0)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Low\ Precision\ time(s):\ "{}}\ <<\ lp\_sec\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Low\ Precision\ relative\ error:\ "{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ lp\_diff\_norm-\/>at(0)\ /\ hp\_x\_norm-\/>at(0)\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)n"{}};}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Hp\ *\ Lp\ -\/>\ Hp\ time(s):\ "{}}\ <<\ hplp\_sec\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Hp\ *\ Lp\ -\/>\ Hp\ relative\ error:\ "{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ hplp\_diff\_norm-\/>at(0)\ /\ hp\_x\_norm-\/>at(0)\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)n"{}};}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Lp\ *\ Lp\ -\/>\ Hp\ time(s):\ "{}}\ <<\ lplp\_sec\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Lp\ *\ Lp\ -\/>\ Hp\ relative\ error:\ "{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ lplp\_diff\_norm-\/>at(0)\ /\ hp\_x\_norm-\/>at(0)\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)n"{}};}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Lp\ *\ Hp\ -\/>\ Hp\ time(s):\ "{}}\ <<\ lplp\_sec\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ \textcolor{stringliteral}{"{}Lp\ *\ Hp\ -\/>\ Hp\ relative\ error:\ "{}}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ lphp\_diff\_norm-\/>at(0)\ /\ hp\_x\_norm-\/>at(0)\ <<\ \textcolor{stringliteral}{"{}\(\backslash\)n"{}};}
\DoxyCodeLine{\}}

\end{DoxyCodeInclude}
 