#
# Double type ScaLAPACK routines:  Simple Drivers:  For Linear Equations
#
# Functions defined here:
#
# PDGESV
# PDPOSV

@PROBLEM pdgesv
@FUNCTION pdgesv
@LIB $(SCALAPACK_LIB_LINK)
@LIB $(BLACS_LIB_LINK)
@LIB $(BLAS_LIB_LINK)
@LIB -L$(MPI_DIR)/lib
@LIB -lmpich
@LANGUAGE FORTRAN
@MAJOR COL
@PATH /SCALAPACK/LinearSystem/
@DESCRIPTION
PDGESV computes the solution to a real system of linear equations

                      sub( A ) * X = sub( B ),

where sub( A ) = A(IA:IA+N-1,JA:JA+N-1) is an N-by-N distributed
matrix and X and sub( B ) = B(IB:IB+N-1,JB:JB+NRHS-1) are N-by-NRHS
distributed matrices.

The LU decomposition with partial pivoting and row interchanges is
used to factor sub( A ) as sub( A ) = P * L * U, where P is a permu-
tation matrix, L is unit lower triangular, and U is upper triangular.
L and U are stored in sub( A ). The factored form of sub( A ) is then
used to solve the system of equations sub( A ) * X = sub( B ).
http://www.netlib.org/scalapack/index.html
@PARALLEL MPI
@INPUT 2 
@OBJECT MATRIX D A
A       (local input/local output) DOUBLE PRECISION pointer into the
        local memory to an array of dimension (LLD_A,LOCc(JA+N-1)).
        On entry, the local pieces of the N-by-N distributed matrix
        sub( A ) to be factored.
@OBJECT MATRIX D RHS
B       (local input/local output) DOUBLE PRECISION pointer into the
        local memory to an array of dimension
        (LLD_B,LOCc(JB+NRHS-1)).  On entry, the right hand side
        distributed matrix sub( B ).
@OUTPUT 3
@OBJECT MATRIX D LU
A       (local input/local output) DOUBLE PRECISION pointer into the
        local memory to an array of dimension (LLD_A,LOCc(JA+N-1)).
        On exit, this array contains the
        local pieces of the factors L and U from the factorization
        sub( A ) = P*L*U; the unit diagonal elements of L are not
        stored.
@OBJECT MATRIX D Solution
B       (local input/local output) DOUBLE PRECISION pointer into the
        local memory to an array of dimension
        (LLD_B,LOCc(JB+NRHS-1)).  On entry, the right hand side
        distributed matrix sub( B ). On exit, if INFO = 0, sub( B )
        is overwritten by the solution distributed matrix X.
@OBJECT SCALAR I Info
INFO    (global output) INTEGER
        = 0:  successful exit
        < 0:  If the i-th argument is an array and the j-entry had
              an illegal value, then INFO = -(i*100+j), if the i-th
              argument is a scalar and had an illegal value, then
              INFO = -i.
        > 0:  If INFO = K, U(IA+K-1,JA+K-1) is exactly zero.
              The factorization has been completed, but the factor U
              is exactly singular, so the solution could not be
              computed.
@CUSTOMIZED SCALAPACK
@COMPLEXITY 4,5
@CALLINGSEQUENCE
@ARG mI0,nI0,mI1
#N
@ARG nI1
#NRHS
@ARG I0,O0
#A
@ARG lI0,lO0
#LDA
@ARG ?
#IPIV, ignore this for now
@ARG I1,O1
#B
@ARG lI1,lO1
#LDB
@ARG O2
#INFO

@CODE
extern void pdgesv(int *n, int *nrhs, double *a, int *ia, int *ja,
                   int *desca, int *ipiv, double *b, int *ib, int *jb,
                   int *descb, int *info);
extern int *makeIpiv(int);

int *ipiv;
int one=1;

ipiv=(int *)makeIpiv(*@mI0@);
@O2@=(int *)calloc(1,sizeof(int));
/* 
@O2@=(int *) malloc(sizeof(int));
*/

pdgesv(@mI0@,@nI1@,@I0@,&one,&one, @dI0@, ipiv, 
       @I1@, &one, &one, @dI1@, @O2@);

@O0@=@I0@;
@O1@=@I1@;
*@mO0@=*@mI0@;
*@nO0@=*@nI0@;
*@mO1@=*@mI1@;
*@nO1@=*@nI1@;

@dO0@ = @dI0@;
@dO1@ = @dI1@;

@END_CODE


@PROBLEM plinsol
@FUNCTION plinsol
@LANGUAGE FORTRAN
@MAJOR COL
@PATH /SCALAPACK/LinearSystem/
@DESCRIPTION
parallel solve of Ax=b using LU decomposition
@PARALLEL MPI
@INPUT 2 
@OBJECT MATRIX D A
Matrix A
@OBJECT MATRIX D RHS
Right Hand Side

@OUTPUT 1
@OBJECT MATRIX D Solution
Solution

@CUSTOMIZED SCALAPACK
@COMPLEXITY 4,5

@CALLINGSEQUENCE
@ARG mI0,nI0,mI1
#N
@ARG nI1
#NRHS
@ARG I0
#A
@ARG lI0
#LDA
@ARG ?
#IPIV, ignore this for now
@ARG I1,O0
#B
@ARG lI1,lO0
#LDB

@CODE
extern void pdgesv(int *n, int *nrhs, double *a, int *ia, int *ja,
                   int *desca, int *ipiv, double *b, int *ib, int *jb,
                   int *descb, int *info);
extern int *makeIpiv(int);
int *ipiv;
int one=1;
int info;

ipiv=(int *)makeIpiv(*@mI0@);

pdgesv(@mI0@,@nI1@,@I0@,&one,&one, @dI0@, ipiv, 
       @I1@, &one, &one, @dI1@, &info);

@O0@=@I1@;
*@mO0@=*@mI1@;
*@nO0@=*@nI1@;

@dO0@ = @dI1@;

@END_CODE

@PROBLEM pdposv
@FUNCTION pdposv
@LANGUAGE FORTRAN
@MAJOR COL
@PATH /SCALAPACK/LinearSystem/
@DESCRIPTION
PDPOSV computes the solution to a real system of linear equations

                      sub( A ) * X = sub( B ),

where sub( A ) denotes A(IA:IA+N-1,JA:JA+N-1) and is an N-by-N
symmetric distributed positive definite matrix and X and sub( B )
denoting B(IB:IB+N-1,JB:JB+NRHS-1) are N-by-NRHS distributed
matrices.

The Cholesky decomposition is used to factor sub( A ) as

                   sub( A ) = U**T * U,  if UPLO = 'U', or

                   sub( A ) = L * L**T,  if UPLO = 'L',

where U is an upper triangular matrix and L is a lower triangular
matrix.  The factored form of sub( A ) is then used to solve the
system of equations.
http://www.netlib.org/scalapack/index.html
@PARALLEL MPI
@INPUT 3
@OBJECT SCALAR CHAR uplo
UPLO    (global input) CHARACTER*1
        = 'U':  Upper triangle of sub( A ) is stored;
        = 'L':  Lower triangle of sub( A ) is stored.
@OBJECT MATRIX D A
A       (local input/local output) DOUBLE PRECISION pointer into the
        local memory to an array of dimension (LLD_A, LOCc(JA+N-1)).
        On entry, this array contains the local pieces of the
        N-by-N symmetric distributed matrix sub( A ) to be factored.
        If UPLO = 'U', the leading N-by-N upper triangular part of
        sub( A ) contains the upper triangular part of the matrix,
        and its strictly lower triangular part is not referenced.
        If UPLO = 'L', the leading N-by-N lower triangular part of
        sub( A ) contains the lower triangular part of the distribu-
        ted matrix, and its strictly upper triangular part is not
        referenced. 
@OBJECT MATRIX D RHS
B       (local input/local output) DOUBLE PRECISION pointer into the
        local memory to an array of dimension (LLD_B,LOC(JB+NRHS-1)).
        On entry, the local pieces of the right hand sides distribu-
        ted matrix sub( B ).
@OUTPUT 3
@OBJECT MATRIX D LLT
A       (local input/local output) DOUBLE PRECISION pointer into the
        local memory to an array of dimension (LLD_A, LOCc(JA+N-1)).
        On exit, if INFO = 0, this array contains the
        local pieces of the factor U or L from the Cholesky factori-
        zation sub( A ) = U**T*U or L*L**T.
@OBJECT MATRIX D Solution
B       (local input/local output) DOUBLE PRECISION pointer into the
        local memory to an array of dimension (LLD_B,LOC(JB+NRHS-1)).
        On exit, if INFO = 0, sub( B ) is over-
        written with the solution distributed matrix X.
@OBJECT SCALAR I Info
INFO    (global output) INTEGER
        = 0:  successful exit
        < 0:  If the i-th argument is an array and the j-entry had
              an illegal value, then INFO = -(i*100+j), if the i-th
              argument is a scalar and had an illegal value, then
              INFO = -i.
        > 0:  If INFO = K, the leading minor of order K,
              A(IA:IA+K-1,JA:JA+K-1) is not positive definite, and
              the factorization could not be completed, and the
              solution has not been computed.
@CUSTOMIZED SCALAPACK
@COMPLEXITY 4,5
@CALLINGSEQUENCE
@ARG I0
#UPLO
@ARG mI1,nI1,mI2
#N
@ARG nI2
#NRHS
@ARG I1,O0
#A
@ARG lI1,lO0
#LDA
@ARG I2,O1
#B
@ARG lI2,lO1
#LDB
@ARG O2
#INFO

@CODE
extern void pdposv(char *uplo, int *n, int *nrhs, double *a, int *ia,
                   int *ja, int *desca, double *b, int *ib, int *jb,
                   int *descb, int *info);

int one=1;

@O2@=(int *)calloc(1,sizeof(int));
/* @O2@=(int *) malloc(sizeof(int)); */


pdposv(@I0@,@mI1@,@nI2@,@I1@,&one,&one, @dI1@,
       @I2@, &one, &one, @dI2@, @O2@);

@O0@=@I1@;
*@mO0@=*@mI1@;
*@nO0@=*@nI1@;
@dO0@ = @dI1@;

@O1@=@I2@;
*@mO1@=*@mI2@;
*@nO1@=*@nI2@;
@dO1@ = @dI2@;

@END_CODE
