\section{Preconditioner routines}
\label{sec:precs}

% \section{Preconditioners}
\label{sec:psprecs}
The base PSBLAS library  contains the implementation of some simple
preconditioning techniques:
\begin{itemize}
\item Diagonal Scaling
\item Block Jacobi with ILU(0) factorization
\item Block Jacobi with an approximate inverse
%% \item Additive Schwarz with the Restricted Additive Schwarz and
%%   Additive Schwarz with Harmonic extensions;
\end{itemize}
The supporting data type and subroutine interfaces are defined in the
module  \verb|psb_prec_mod|.
The old interfaces \verb|psb_precinit| and  \verb|psb_precbld| are still supported for
backward compatibility
%% We also provide a companion  package of multi-level Additive
%%   Schwarz preconditioners called MD2P4; this is actually a family of 
%%   preconditioners since there is the possibility to choose between
%%   many variants, and is currently in an experimental stateIts
%%   documentation is planned to appear after stabilization of the
%%   package, which will characterize release  2.1 of our library.


\clearpage\subsection{init --- Initialize a  preconditioner}

\begin{verbatim}
call prec%init(icontxt,ptype, info)
\end{verbatim}

\begin{description}
\item[Type:] Asynchronous.
\item[\bf On Entry]
\item[icontxt] the communication context.\\
Scope:{\bf global}.\\
Type:{\bf required}.\\
Intent: {\bf in}.\\
Specified as: an integer value.
\item[ptype] the type of preconditioner. 
Scope: {\bf global} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: a character string, see usage notes.
%% \item[iv] integer parameters for the precondtioner. 
%% Scope: {\bf global} \\
%% Type: {\bf required}\\
%% Specified as: an integer array, see usage notes. 
%% \item[rs] 
%% Scope: {\bf global} \\
%% Type: {\bf optional}\\
%% Specified as: a long precision real number.
\item[\bf On Exit]

\item[prec] 
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf inout}.\\
Specified as: a preconditioner data structure \precdata.
\item[info] 
Scope: {\bf global} \\
Type: {\bf required}\\
Intent: {\bf out}.\\
Error code: if no error, 0 is returned.
\end{description}
{\par\noindent\large\bfseries Notes}
%% The PSBLAS 2.0 contains a number of preconditioners, ranging from a
%% simple diagonal scaling to 2-level domain decomposition. These
%% preconditioners may use the SuperLU or the UMFPACK software, if
%% installed; see~\cite{SUPERLU,UMFPACK}. 
Legal inputs to this subroutine are interpreted depending on the
$ptype$ string as follows\footnote{The string is case-insensitive}:
\begin{description}
\item[NONE] No preconditioning, i.e. the preconditioner is just a copy
  operator.
\item[DIAG] Diagonal scaling; each entry of the input vector is
  multiplied by the reciprocal of the sum of the absolute values of
  the coefficients in the corresponding row of matrix  $A$;
\item[BJAC] Precondition by a factorization or an approximante inverse
  of the   block-diagonal of matrix $A$, where block boundaries are
  determined   by the data allocation boundaries for each process;
  requires no   communication.  See also Table-\ref{tab:p_subsolve_1}. 
\end{description}



\clearpage

\subsection{Set\label{sec:precset} --- set preconditioner parameters}

\begin{center}
\fortinline|call p%set(what,val,info)|
\end{center}

\noindent
This method sets the parameters defining the subdomain solver when the
preconditioner type is \verb|BJAC|. More precisely, the parameter
identified by \fortinline|what| is assigned the value 
contained in \fortinline|val|.

{\vskip1.5\baselineskip\noindent\large\bfseries Arguments} \smallskip

\begin{tabular}{p{1.2cm}p{12cm}}
\fortinline|what|   & \fortinline|character(len=*)|. \\
              & The parameter to be set. It can be specified through its name;
                the string is case-insensitive. See
                Table~\ref{tab:p_subsolve_1}.\\
\fortinline|val |   & \fortinline|integer| \emph{or} \fortinline|character(len=*)| \emph{or}
                \fortinline|real(psb_spk_)| \emph{or} \fortinline|real(psb_dpk_)|,
                \fortinline|intent(in)|.\\
              & The value of the parameter to be set. The list of allowed
                values and the corresponding data types is given in
                Table~\ref{tab:p_subsolve_1}.
                When the value is of type \fortinline|character(len=*)|,
                it is also treated as case insensitive.\\
\fortinline|info|   & \fortinline|integer, intent(out)|.\\
              & Error code. If no error, 0 is returned. See Section~\ref{sec:errors}
                for details.
\end{tabular}


\noindent
A number of subdomain solvers can be chosen with this method;
a list of the parameters that can be set, along with their allowed and
default values, is given in Table-\ref{tab:p_subsolve_1}.\\


\bsideways
\begin{center}
\small
% \begin{tabular}{|p{3.6cm}|l|p{1.9cm}|p{3.6cm}|p{6.5cm}|}
\begin{tabular}{|p{3.2cm}|l|p{2.6cm}|p{2.6cm}|p{6.7cm}|}
\hline
\fortinline|what|              & \textsc{data type}        &  \fortinline|val|      &  \textsc{default}  &
\textsc{comments} \\ \hline

\fortinline|'SUB_SOLVE'|  & \fortinline|character(len=*)|
                         & \fortinline|'ILU'| \par
                           \fortinline|'ILUT'| \par 
                            \par \fortinline|'INVT'| \par \fortinline|'INVK'| \par \fortinline|'AINV'|
                         & 
                         & The local solver to be used with the smoother or one-level
                            preconditioner  ILU($p$),  ILU($p,t$), 
                           Approximate Inverses  INVK($p,q$),
                           INVT($p_1,p2,t_1,t_2$) and
                           AINV($t$); note  that approximate inverses
                           are specifically suited for GPUs since they
                           do not employ triangular system solve
                           kernels,
                           see~\cite{BERTACCINIFILIPPONE}.\\ \hline
\fortinline|'SUB_FILLIN'|  & \fortinline|integer|
                         & Any integer \par number~$\ge 0$
                         & 0
                         & Fill-in level $p$ of the incomplete LU factorizations. \\ \hline
\fortinline|'SUB_ILUTHRS'|  & \fortinline|real(kind_parameter)|
                         & Any real number~$\ge 0$
                         & 0
                         & Drop tolerance $t$ in the ILU($p,t$) factorization. \\ \hline
\fortinline|'ILU_ALG'|  & \fortinline|character(len=*)|
                         & \fortinline|'MILU'|
                         & \fortinline|'NONE'|
                         & ILU algorithmic variant \\ \hline
\fortinline|'ILUT_SCALE'|  & \fortinline|character(len=*)|
                          & \fortinline|'MAXVAL'| \par
                            \fortinline|'DIAG'| \par
                            \fortinline|'ARSWUM'| \par
                            \fortinline|'ARCSUM'| \par
                            \fortinline|'ACLSUM'| \par
                            \fortinline|'NONE'| 
                         & \fortinline|'NONE'|
                         & ILU scaling strategy \\ \hline
\fortinline|'INV_FILLIN'|  & \fortinline|integer|
                         & Any integer \par number~$\ge 0$
                         & 0
                         & Second fill-in level $q$ of the INVK($p,q$)
                           approximate inverse. \\ \hline
\fortinline|'INV_ILUTHRS'|  & \fortinline|real(kind_parameter)|
                         & Any real number~$\ge 0$
                         & 0
                         & Second drop tolerance $s$ in the
                           INVT($t,s$) approximate inverse. \\ \hline
\fortinline|'AINV_ALG'|  & \fortinline|character(len=*)|
                         & \fortinline|'LLK'| \par
                            \fortinline|'SYM-LLK'| \par
                            \fortinline|'STAB-LLK'| \par
                            \fortinline|'MLK,LMX'| 
                         & \fortinline|'LLK'|
                         & AINV algorithmic strategy. \\ \hline
\end{tabular}
\end{center}
\caption{Parameters defining the solver of the BJAC
  preconditioner.\label{tab:p_subsolve_1}} 
 \esideways




\clearpage\subsection{build --- Builds a preconditioner}

\begin{verbatim}
call prec%build(a, desc_a, info[,amold,vmold,imold])
\end{verbatim}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[a] the system sparse matrix.
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}, target.\\
Specified as: a sparse matrix data structure \spdata.
\item[prec] the preconditioner.\\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf inout}.\\
Specified as: an already initialized precondtioner data structure \precdata\\
\item[desc\_a] the problem communication descriptor. 
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}, target.\\
Specified as: a communication descriptor data structure \descdata.
%% \item[upd] 
%% Scope: {\bf global} \\
%% Type: {\bf optional}\\
%% Intent: {\bf in}.\\
%% Specified as: a character.
\item[amold] The desired dynamic type for the internal matrix storage.\\
Scope: {\bf local}.\\
Type: {\bf optional}.\\
Intent: {\bf in}.\\
Specified as: an object of a class derived from \spbasedata. 
\item[vmold] The desired dynamic type for the internal vector storage.\\
Scope: {\bf local}.\\
Type: {\bf optional}.\\
Intent: {\bf in}.\\
Specified as: an object of a class derived from \vbasedata. 
\item[imold] The desired dynamic type for the internal integer vector storage.\\
Scope: {\bf local}.\\
Type: {\bf optional}.\\
Intent: {\bf in}.\\
Specified as: an object of a class derived from (integer) \vbasedata. 
\end{description}

\begin{description}
\item[\bf On Return]
\item[prec] the preconditioner.\\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf inout}.\\
Specified as: a precondtioner data structure \precdata\\
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected. 
\end{description}
The \verb|amold|, \verb|vmold| and \verb|imold|  arguments may be
employed to interface with special devices, such as GPUs and other
accelerators. 



\clearpage\subsection{apply --- Preconditioner application
  routine}

\begin{verbatim}
call prec%apply(x,y,desc_a,info,trans,work)
call prec%apply(x,desc_a,info,trans)
\end{verbatim}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[prec] the preconditioner.
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: a preconditioner data structure \precdata.
\item[x] the source vector.
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf inout}.\\
Specified as:  a rank one array or an object of type \vdata. 
\item[desc\_a] the problem communication descriptor.
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: a communication data structure \descdata.
\item[trans] 
Scope: {\bf } \\
Type: {\bf optional}\\
Intent: {\bf in}.\\
Specified as: a character.
\item[work] an optional work space
Scope: {\bf local} \\
Type: {\bf optional}\\
Intent: {\bf inout}.\\
Specified as: a double precision array.
\end{description}

\begin{description}
\item[\bf On Return]
\item[y] the destination vector.
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf inout}.\\
Specified as:  a rank one array or an object of type \vdata.
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected. 
\end{description}
{\par\noindent\large\bfseries Notes}
This method is almost always called  by the iterative methods of
Sec.~\ref{sec:methods}; it is extremely unlikely to be needed directly
by the application developer.


\clearpage\subsection{descr --- Prints a description of current
  preconditioner}

\begin{verbatim}
call prec%descr(info)
call prec%descr(info,iout, root)
\end{verbatim}

\begin{description}
\item[Type:] Asynchronous.
\item[\bf On Entry]
\item[prec] the preconditioner.
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: a preconditioner data structure \precdata.
\item[iout] output unit.
Scope: {\bf local} \\
Type: {\bf optional}\\
Intent: {\bf in}.\\
Specified as: an integer number. Default: default output unit.
\item[root] Process from which to print
Scope: {\bf local} \\
Type: {\bf optional}\\
Intent: {\bf in}.\\
Specified as: an integer number between 0 and $np-1$, in which case
the specified process will print the description, or $-1$, in which case
all processes will print. Default: 0. 
\item[\bf On Return]
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected. 
\end{description}



\clearpage\subsection{clone --- clone  current
  preconditioner}
\begin{verbatim}
call  prec%clone(precout,info)
\end{verbatim}

\begin{description}
\item[Type:] Asynchronous.
\item[\bf On Entry]
\item[prec] the preconditioner.\\
Scope: {\bf local}.\\
% Type: {\bf required}.\\
% Intent: {\bf in}.\\
% Specified as: a object of type \descdata.
\end{description}

\begin{description}
\item[\bf On Return]
\item[precout] A copy of the input object.
\item[info] Return code. 
\end{description}


\clearpage\subsection{free --- Free a  preconditioner}

\begin{verbatim}
call prec%free(info)
\end{verbatim}

\begin{description}
\item[Type:] Asynchronous.
\item[\bf On Entry]
\item[prec] the preconditioner.\\
Scope: {\bf local}.\\
Type: {\bf required}\\
Intent: {\bf inout}.\\
Specified as: a preconditioner data structure \precdata.
%% \item[iv] integer parameters for the precondtioner. 
%% Scope: {\bf global} \\
%% Type: {\bf required}\\
%% Specified as: an integer array, see usage notes. 
%% \item[rs] 
%% Scope: {\bf global} \\
%% Type: {\bf optional}\\
%% Specified as: a long precision real number.
\item[\bf On Exit]

\item[prec] 
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf inout}.\\
Specified as: a preconditioner data structure \precdata.
\item[info] 
Scope: {\bf global} \\
Type: {\bf required}\\
Intent: {\bf out}.\\
Error code: if no error, 0 is returned.
\end{description}
{\par\noindent\large\bfseries Notes}
%% The PSBLAS 2.0 contains a number of preconditioners, ranging from a
%% simple diagonal scaling to 2-level domain decomposition. These
%% preconditioners may use the SuperLU or the UMFPACK software, if
%% installed; see~\cite{SUPERLU,UMFPACK}. 
Releases all internal storage.


\clearpage\subsection{allocate\_wrk --- preconditioner}
\label{sec:allocatewrk}
\begin{verbatim}
call prec%allocate_wrk(info[,vmold])
\end{verbatim}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[prec] the preconditioner.\\
Scope: {\bf local}.\\
Type: {\bf required}\\
Intent: {\bf inout}.\\
Specified as: a preconditioner data structure \precdata.
\item[vmold] The desired dynamic type for the internal vector storage.\\
Scope: {\bf local}.\\
Type: {\bf optional}.\\
Intent: {\bf in}.\\
Specified as: an object of a class derived from \vbasedata. 
\item[\bf On Exit]

\item[prec] 
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf inout}.\\
Specified as: a preconditioner data structure \precdata.
\item[info] 
Scope: {\bf global} \\
Type: {\bf required}\\
Intent: {\bf out}.\\
Error code: if no error, 0 is returned.
\end{description}
{\par\noindent\large\bfseries Notes}
%% The PSBLAS 2.0 contains a number of preconditioners, ranging from a
%% simple diagonal scaling to 2-level domain decomposition. These
%% preconditioners may use the SuperLU or the UMFPACK software, if
%% installed; see~\cite{SUPERLU,UMFPACK}. 
Preconditioners often need internal work storage during their
application at each iteration of a linear solver method: in many
situations this can be  accomplished by allocating and releasing
memory ``on the fly''. However, when running on an accelerator through
e.g. the CUDA enabled data strutures of Sec.~\ref{sec:cudastruct} and
~\ref{sec:cudaenv},  memory allocation and deallocation usually have a
much larger overhead, significantly affecting performance. To
alleviate this problem we define this method that preallocates
internal storage; it is intended to be invoked prior to the iterative
solver method, so that the necessary internal work storage is
available throughout the iterative method application.

When using GPUs or other specialized devices, the \fortinline|vmold|
argument is also necessary to ensure the internal work vectors are of
the appropriate dynamic type to exploit the accelerator hardware.


\clearpage\subsection{deallocate\_wrk --- preconditioner}

\begin{verbatim}
call prec%allocate_wrk(info)
call prec%free_wrk(info)
\end{verbatim}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[prec] the preconditioner.\\
Scope: {\bf local}.\\
Type: {\bf required}\\
Intent: {\bf inout}.\\
Specified as: a preconditioner data structure \precdata.
\item[\bf On Exit]

\item[prec] 
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf inout}.\\
Specified as: a preconditioner data structure \precdata.
\item[info] 
Scope: {\bf global} \\
Type: {\bf required}\\
Intent: {\bf out}.\\
Error code: if no error, 0 is returned.
\end{description}
{\par\noindent\large\bfseries Notes}
%% The PSBLAS 2.0 contains a number of preconditioners, ranging from a
%% simple diagonal scaling to 2-level domain decomposition. These
%% preconditioners may use the SuperLU or the UMFPACK software, if
%% installed; see~\cite{SUPERLU,UMFPACK}. 
Deallocates preconditioner internal work storage; to be invoked after an
iterative solver has completed execution, see the discussion in
Sec.~\ref{sec:allocatewrk}. 


%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "userguide"
%%% End: 
