\doxysection{gko::\+Operation Class Reference}
\hypertarget{classgko_1_1Operation}{}\label{classgko_1_1Operation}\index{gko::Operation@{gko::Operation}}


Operations can be used to define functionalities whose implementations differ among devices.  




{\ttfamily \+\#include $<$ginkgo/\+core/\+base/\+executor.\+hpp$>$}



Inheritance diagram for gko::\+Operation:\+
\nopagebreak
\begin{figure}[H]
\begin{center}
\leavevmode
\includegraphics[width=235pt]{classgko_1_1Operation__inherit__graph}
\end{center}
\end{figure}
\doxysubsubsection*{Public Member Functions}
\begin{DoxyCompactItemize}
\item 
\Hypertarget{classgko_1_1Operation_a2b5cd402406c1749b23df06be6d53637}\label{classgko_1_1Operation_a2b5cd402406c1749b23df06be6d53637} 
virtual void {\bfseries run} (std::\+shared\+\_\+ptr$<$ const \doxymbox{\hyperlink{classgko_1_1OmpExecutor}{Omp\+Executor}} $>$) const
\item 
\Hypertarget{classgko_1_1Operation_aaf3b457bd9522005e230b557882b1615}\label{classgko_1_1Operation_aaf3b457bd9522005e230b557882b1615} 
virtual void {\bfseries run} (std::\+shared\+\_\+ptr$<$ const \doxymbox{\hyperlink{classgko_1_1HipExecutor}{Hip\+Executor}} $>$) const
\item 
\Hypertarget{classgko_1_1Operation_aedeae9ad780ef795586b28bc465cea1c}\label{classgko_1_1Operation_aedeae9ad780ef795586b28bc465cea1c} 
virtual void {\bfseries run} (std::\+shared\+\_\+ptr$<$ const \doxymbox{\hyperlink{classgko_1_1DpcppExecutor}{Dpcpp\+Executor}} $>$) const
\item 
\Hypertarget{classgko_1_1Operation_aa09b89cdd9526e2654aedb5b83b8b5ef}\label{classgko_1_1Operation_aa09b89cdd9526e2654aedb5b83b8b5ef} 
virtual void {\bfseries run} (std::\+shared\+\_\+ptr$<$ const \doxymbox{\hyperlink{classgko_1_1CudaExecutor}{Cuda\+Executor}} $>$) const
\item 
\Hypertarget{classgko_1_1Operation_ae67f83384d2df18660c2bac839a4bec3}\label{classgko_1_1Operation_ae67f83384d2df18660c2bac839a4bec3} 
virtual void {\bfseries run} (std::\+shared\+\_\+ptr$<$ const \doxymbox{\hyperlink{classgko_1_1ReferenceExecutor}{Reference\+Executor}} $>$ executor) const
\item 
virtual const char \texorpdfstring{$\ast$}{*} \doxymbox{\hyperlink{classgko_1_1Operation_ada3255c1fbae4a203627c0affce1aa23}{get\+\_\+name}} () const noexcept
\begin{DoxyCompactList}\small\item\em Returns the operation\textquotesingle{}s name. \end{DoxyCompactList}\end{DoxyCompactItemize}


\doxysubsection{Detailed Description}
Operations can be used to define functionalities whose implementations differ among devices. 

This is done by extending the \doxylink{classgko_1_1Operation}{Operation} class and implementing the overloads of the Operation::\+run() method for all \doxylink{classgko_1_1Executor}{Executor} types. When invoking the \doxylink{classgko_1_1Executor_a1de8e2668b76e66690acf5eef9e8324d}{Executor::\+run()} method with the \doxylink{classgko_1_1Operation}{Operation} as input, the library will select the Operation::\+run() overload corresponding to the dynamic type of the \doxylink{classgko_1_1Executor}{Executor} instance.

Consider an overload of {\ttfamily operator\texorpdfstring{$<$}{<}\texorpdfstring{$<$}{<}} for Executors, which prints some basic device information (e.\+g. device type and id) of the \doxylink{classgko_1_1Executor}{Executor} to a C++ stream:\+


\begin{DoxyCode}{0}
\DoxyCodeLine{std::ostream\&\ operator<<(std::ostream\ \&os,\ \textcolor{keyword}{const}\ gko::Executor\ \&exec);}

\end{DoxyCode}


One possible implementation would be to use RTTI to find the dynamic type of the \doxylink{classgko_1_1Executor}{Executor}, However, using the \doxylink{classgko_1_1Operation}{Operation} feature of Ginkgo, there is a more elegant approach which utilizes polymorphism. The first step is to define an \doxylink{classgko_1_1Operation}{Operation} that will print the desired information for each \doxylink{classgko_1_1Executor}{Executor} type.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{class\ }DeviceInfoPrinter\ :\ \textcolor{keyword}{public}\ gko::Operation\ \{}
\DoxyCodeLine{\textcolor{keyword}{public}:}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{explicit}\ DeviceInfoPrinter(std::ostream\ \&os)\ :\ os\_(os)\ \{\}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ run(\textcolor{keyword}{const}\ gko::OmpExecutor\ *)\textcolor{keyword}{\ const\ override\ }\{\ os\_\ <<\ \textcolor{stringliteral}{"{}OMP"{}};\ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ run(\textcolor{keyword}{const}\ gko::CudaExecutor\ *exec)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{\ os\_\ <<\ \textcolor{stringliteral}{"{}CUDA("{}}\ <<\ exec-\/>\doxymbox{\hyperlink{classgko_1_1CudaExecutor_a7cfa915eadd2329eb897dc1ee2712488}{get\_device\_id}}()\ <<\ \textcolor{stringliteral}{"{})"{}};\ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ run(\textcolor{keyword}{const}\ gko::HipExecutor\ *exec)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{\ os\_\ <<\ \textcolor{stringliteral}{"{}HIP("{}}\ <<\ exec-\/>\doxymbox{\hyperlink{classgko_1_1HipExecutor_a37a35665c3983e56105c6acea9de73c6}{get\_device\_id}}()\ <<\ \textcolor{stringliteral}{"{})"{}};\ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ run(\textcolor{keyword}{const}\ gko::DpcppExecutor\ *exec)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{\ os\_\ <<\ \textcolor{stringliteral}{"{}DPC++("{}}\ <<\ exec-\/>\doxymbox{\hyperlink{classgko_1_1DpcppExecutor_aefdd7095f2d18ff8e4ab8354006f305b}{get\_device\_id}}()\ <<\ \textcolor{stringliteral}{"{})"{}};\ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{comment}{//\ This\ is\ optional,\ if\ not\ overloaded,\ defaults\ to\ OmpExecutor\ overload}}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{void}\ run(\textcolor{keyword}{const}\ gko::ReferenceExecutor\ *)\textcolor{keyword}{\ const\ override}}
\DoxyCodeLine{\textcolor{keyword}{\ \ \ \ }\{\ os\_\ <<\ \textcolor{stringliteral}{"{}Reference\ CPU"{}};\ \}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{private}:}
\DoxyCodeLine{\ \ \ \ std::ostream\ \&os\_;}
\DoxyCodeLine{\};}

\end{DoxyCode}


Using Device\+Info\+Printer, the implementation of {\ttfamily operator\texorpdfstring{$<$}{<}\texorpdfstring{$<$}{<}} is as simple as calling the run() method of the executor.


\begin{DoxyCode}{0}
\DoxyCodeLine{std::ostream\&\ operator<<(std::ostream\ \&os,\ \textcolor{keyword}{const}\ gko::Executor\ \&exec)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ DeviceInfoPrinter\ printer(os);}
\DoxyCodeLine{\ \ \ \ exec.\doxymbox{\hyperlink{classgko_1_1Executor_a1de8e2668b76e66690acf5eef9e8324d}{run}}(printer);}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ os;}
\DoxyCodeLine{\}}

\end{DoxyCode}


Now it is possible to write the following code:\+


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ omp\ =\ \doxymbox{\hyperlink{classgko_1_1OmpExecutor_af977cb680e0427ca4eb71eb7b1266211}{gko::OmpExecutor::create}}();}
\DoxyCodeLine{std::cout\ <<\ *omp\ <<\ std::endl}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ <<\ *\doxymbox{\hyperlink{classgko_1_1CudaExecutor_a075a1957241de65c0cad59f9534430a2}{gko::CudaExecutor::create}}(0,\ omp)\ <<\ std::endl}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ <<\ *\doxymbox{\hyperlink{classgko_1_1HipExecutor_a8afc5210bf8dd8aedfceab4b73f0047b}{gko::HipExecutor::create}}(0,\ omp)\ <<\ std::endl}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ <<\ *\doxymbox{\hyperlink{classgko_1_1DpcppExecutor_af69a356ee07f641010df5d2e9e518bb0}{gko::DpcppExecutor::create}}(0,\ omp)\ <<\ std::endl}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ <<\ *gko::ReferenceExecutor::create()\ <<\ std::endl;}

\end{DoxyCode}


which produces the expected output:\+


\begin{DoxyCode}{0}
\DoxyCodeLine{OMP}
\DoxyCodeLine{CUDA(0)}
\DoxyCodeLine{HIP(0)}
\DoxyCodeLine{DPC++(0)}
\DoxyCodeLine{Reference\ CPU}

\end{DoxyCode}


One might feel that this code is too complicated for such a simple task. Luckily, there is an overload of the \doxylink{classgko_1_1Executor_a1de8e2668b76e66690acf5eef9e8324d}{Executor::\+run()} method, which is designed to facilitate writing simple operations like this one. The method takes four closures as input:\+ one which is run for OMP, one for CUDA executors, one for HIP executors, and the last one for DPC++ executors. Using this method, there is no need to implement an \doxylink{classgko_1_1Operation}{Operation} subclass:\+


\begin{DoxyCode}{0}
\DoxyCodeLine{std::ostream\&\ operator<<(std::ostream\ \&os,\ \textcolor{keyword}{const}\ gko::Executor\ \&exec)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ exec.\doxymbox{\hyperlink{classgko_1_1Executor_a1de8e2668b76e66690acf5eef9e8324d}{run}}(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ [\&]()\ \{\ os\ <<\ \textcolor{stringliteral}{"{}OMP"{}};\ \},\ \ \textcolor{comment}{//\ OMP\ closure}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ [\&]()\ \{\ os\ <<\ \textcolor{stringliteral}{"{}CUDA("{}}\ \ \ \ \textcolor{comment}{//\ CUDA\ closure}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ \textcolor{keyword}{static\_cast<}gko::CudaExecutor\&\textcolor{keyword}{>}(exec)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .get\_device\_id()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ \textcolor{stringliteral}{"{})"{}};\ \},}
\DoxyCodeLine{\ \ \ \ \ \ \ \ [\&]()\ \{\ os\ <<\ \textcolor{stringliteral}{"{}HIP("{}}\ \ \ \ \textcolor{comment}{//\ HIP\ closure}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ \textcolor{keyword}{static\_cast<}gko::HipExecutor\&\textcolor{keyword}{>}(exec)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .get\_device\_id()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ \textcolor{stringliteral}{"{})"{}};\ \});}
\DoxyCodeLine{\ \ \ \ \ \ \ \ [\&]()\ \{\ os\ <<\ \textcolor{stringliteral}{"{}DPC++("{}}\ \ \ \ \textcolor{comment}{//\ DPC++\ closure}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ \textcolor{keyword}{static\_cast<}gko::DpcppExecutor\&\textcolor{keyword}{>}(exec)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .get\_device\_id()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <<\ \textcolor{stringliteral}{"{})"{}};\ \});}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ os;}
\DoxyCodeLine{\}}

\end{DoxyCode}


Using this approach, however, it is impossible to distinguish between a \doxylink{classgko_1_1OmpExecutor}{Omp\+Executor} and \doxylink{classgko_1_1ReferenceExecutor}{Reference\+Executor}, as both of them call the OMP closure. 

\label{doc-func-members}
\Hypertarget{classgko_1_1Operation_doc-func-members}
\doxysubsection{Member Function Documentation}
\Hypertarget{classgko_1_1Operation_ada3255c1fbae4a203627c0affce1aa23}\index{gko::Operation@{gko::Operation}!get\_name@{get\_name}}
\index{get\_name@{get\_name}!gko::Operation@{gko::Operation}}
\doxysubsubsection{\texorpdfstring{get\_name()}{get\_name()}}
{\footnotesize\ttfamily \label{classgko_1_1Operation_ada3255c1fbae4a203627c0affce1aa23} 
virtual const char \texorpdfstring{$\ast$}{*} gko::\+\+Operation::\+get\+\_\+name (\begin{DoxyParamCaption}{}{}\end{DoxyParamCaption}) const\hspace{0.3cm}{\ttfamily [virtual]}, {\ttfamily [noexcept]}}



Returns the operation\textquotesingle{}s name. 

\begin{DoxyReturn}{Returns}
the operation\textquotesingle{}s name 
\end{DoxyReturn}


References \doxymbox{\hyperlink{classgko_1_1Operation_ada3255c1fbae4a203627c0affce1aa23}{get\+\_\+name()}}.



Referenced by \doxymbox{\hyperlink{classgko_1_1Operation_ada3255c1fbae4a203627c0affce1aa23}{get\+\_\+name()}}.



The documentation for this class was generated from the following file:\+\begin{DoxyCompactItemize}
\item 
ginkgo/\+core/\+base/\+executor.\+hpp\end{DoxyCompactItemize}
