/** \file scalapack.h
 *
 *  \brief Interface to some ScaLAPACK functions.
 */

#ifndef __SCALAPACK_H__
#define __SCALAPACK_H__

#include "blas_lapack.h"

extern "C" {

ftn_int FORTRAN(pjlaenv)(ftn_int*            ICTXT,
                         ftn_int*            ISPEC,
                         ftn_char            NAME,
                         ftn_char            OPTS,
                         ftn_int*            N1,
                         ftn_int*            N2,
                         ftn_int*            N3,
                         ftn_int*            N4,
                         ftn_len             NAME_len,
                         ftn_len             OPTS_len);

void FORTRAN(psgetrf)(ftn_int*            M,
                      ftn_int*            N,
                      ftn_single*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            IPIV,
                      ftn_int*            INFO);

void FORTRAN(pdgetrf)(ftn_int*            M,
                      ftn_int*            N,
                      ftn_double*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            IPIV,
                      ftn_int*            INFO);

void FORTRAN(pcgetrf)(ftn_int*            M,
                      ftn_int*            N,
                      ftn_complex*        A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            IPIV,
                      ftn_int*            INFO);

void FORTRAN(pzgetrf)(ftn_int*            M,
                      ftn_int*            N,
                      ftn_double_complex* A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            IPIV,
                      ftn_int*            INFO);

void FORTRAN(psgetri)(ftn_int*            N,
                      ftn_single*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            IPIV,
                      ftn_single*         WORK,
                      ftn_int*            LWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            INFO);

void FORTRAN(pdgetri)(ftn_int*            N,
                      ftn_double*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            IPIV,
                      ftn_double*         WORK,
                      ftn_int*            LWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            INFO);

void FORTRAN(pcgetri)(ftn_int*            N,
                      ftn_complex*        A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            IPIV,
                      ftn_complex*        WORK,
                      ftn_int*            LWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            INFO);

void FORTRAN(pzgetri)(ftn_int*            N,
                      ftn_double_complex* A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            IPIV,
                      ftn_double_complex* WORK,
                      ftn_int*            LWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            INFO);

void FORTRAN(pssygvx)(ftn_int*            IBTYPE,
                      ftn_char            JOBZ,
                      ftn_char            RANGE,
                      ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_single*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_single*         B,
                      ftn_int*            IB,
                      ftn_int*            JB,
                      ftn_int*            DESCB,
                      ftn_single*         VL,
                      ftn_single*         VU,
                      ftn_int*            IL,
                      ftn_int*            IU,
                      ftn_double const*   ABSTOL,
                      ftn_int*            M,
                      ftn_int*            NZ,
                      ftn_single*         W,
                      ftn_double const*   ORFAC,
                      ftn_single*         Z,
                      ftn_int*            IZ,
                      ftn_int*            JZ,
                      ftn_int*            DESCZ,
                      ftn_single*         WORK,
                      ftn_int*            LWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            IFAIL,
                      ftn_int*            ICLUSTR,
                      ftn_single*         GAP,
                      ftn_int*            INFO,
                      ftn_len             JOBZ_len,
                      ftn_len             RANGE_len,
                      ftn_len             UPLO_len);

void FORTRAN(pdsygvx)(ftn_int*            IBTYPE,
                      ftn_char            JOBZ,
                      ftn_char            RANGE,
                      ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_double*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_double*         B,
                      ftn_int*            IB,
                      ftn_int*            JB,
                      ftn_int*            DESCB,
                      ftn_double*         VL,
                      ftn_double*         VU,
                      ftn_int*            IL,
                      ftn_int*            IU,
                      ftn_double const*   ABSTOL,
                      ftn_int*            M,
                      ftn_int*            NZ,
                      ftn_double*         W,
                      ftn_double const*   ORFAC,
                      ftn_double*         Z,
                      ftn_int*            IZ,
                      ftn_int*            JZ,
                      ftn_int*            DESCZ,
                      ftn_double*         WORK,
                      ftn_int*            LWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            IFAIL,
                      ftn_int*            ICLUSTR,
                      ftn_double*         GAP,
                      ftn_int*            INFO,
                      ftn_len             JOBZ_len,
                      ftn_len             RANGE_len,
                      ftn_len             UPLO_len);

void FORTRAN(pchegvx)(ftn_int*            IBTYPE,
                      ftn_char            JOBZ,
                      ftn_char            RANGE,
                      ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_complex*        A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_complex*        B,
                      ftn_int*            IB,
                      ftn_int*            JB,
                      ftn_int*            DESCB,
                      ftn_single*         VL,
                      ftn_single*         VU,
                      ftn_int*            IL,
                      ftn_int*            IU,
                      ftn_double const*   ABSTOL,
                      ftn_int*            M,
                      ftn_int*            NZ,
                      ftn_single*         W,
                      ftn_double const*   ORFAC,
                      ftn_complex*        Z,
                      ftn_int*            IZ,
                      ftn_int*            JZ,
                      ftn_int*            DESCZ,
                      ftn_complex*        WORK,
                      ftn_int*            LWORK,
                      ftn_single*         RWORK,
                      ftn_int*            LRWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            IFAIL,
                      ftn_int*            ICLUSTR,
                      ftn_single*         GAP,
                      ftn_int*            INFO,
                      ftn_len             JOBZ_len,
                      ftn_len             RANGE_len,
                      ftn_len             UPLO_len);

void FORTRAN(pzhegvx)(ftn_int*            IBTYPE,
                      ftn_char            JOBZ,
                      ftn_char            RANGE,
                      ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_double_complex* A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_double_complex* B,
                      ftn_int*            IB,
                      ftn_int*            JB,
                      ftn_int*            DESCB,
                      ftn_double*         VL,
                      ftn_double*         VU,
                      ftn_int*            IL,
                      ftn_int*            IU,
                      ftn_double const*   ABSTOL,
                      ftn_int*            M,
                      ftn_int*            NZ,
                      ftn_double*         W,
                      ftn_double const*   ORFAC,
                      ftn_double_complex* Z,
                      ftn_int*            IZ,
                      ftn_int*            JZ,
                      ftn_int*            DESCZ,
                      ftn_double_complex* WORK,
                      ftn_int*            LWORK,
                      ftn_double*         RWORK,
                      ftn_int*            LRWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            IFAIL,
                      ftn_int*            ICLUSTR,
                      ftn_double*         GAP,
                      ftn_int*            INFO,
                      ftn_len             JOBZ_len,
                      ftn_len             RANGE_len,
                      ftn_len             UPLO_len);

void FORTRAN(pssyevx)(ftn_char            JOBZ,
                      ftn_char            RANGE,
                      ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_single*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_single*         VL,
                      ftn_single*         VU,
                      ftn_int*            IL,
                      ftn_int*            IU,
                      ftn_double const*   ABSTOL,
                      ftn_int*            M,
                      ftn_int*            NZ,
                      ftn_single*         W,
                      ftn_double const*   ORFAC,
                      ftn_single*         Z,
                      ftn_int*            IZ,
                      ftn_int*            JZ,
                      ftn_int*            DESCZ,
                      ftn_single*         WORK,
                      ftn_int*            LWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            IFAIL,
                      ftn_int*            ICLUSTR,
                      ftn_single*         GAP,
                      ftn_int*            INFO,
                      ftn_len             JOBZ_len,
                      ftn_len             RANGE_len,
                      ftn_len             UPLO_len);

void FORTRAN(pdsyevx)(ftn_char            JOBZ,
                      ftn_char            RANGE,
                      ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_double*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_double*         VL,
                      ftn_double*         VU,
                      ftn_int*            IL,
                      ftn_int*            IU,
                      ftn_double const*   ABSTOL,
                      ftn_int*            M,
                      ftn_int*            NZ,
                      ftn_double*         W,
                      ftn_double const*   ORFAC,
                      ftn_double*         Z,
                      ftn_int*            IZ,
                      ftn_int*            JZ,
                      ftn_int*            DESCZ,
                      ftn_double*         WORK,
                      ftn_int*            LWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            IFAIL,
                      ftn_int*            ICLUSTR,
                      ftn_double*         GAP,
                      ftn_int*            INFO,
                      ftn_len             JOBZ_len,
                      ftn_len             RANGE_len,
                      ftn_len             UPLO_len);

void FORTRAN(pcheevx)(ftn_char            JOBZ,
                      ftn_char            RANGE,
                      ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_complex*        A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_single*         VL,
                      ftn_single*         VU,
                      ftn_int*            IL,
                      ftn_int*            IU,
                      ftn_double const*   ABSTOL,
                      ftn_int*            M,
                      ftn_int*            NZ,
                      ftn_single*         W,
                      ftn_double const*   ORFAC,
                      ftn_complex*        Z,
                      ftn_int*            IZ,
                      ftn_int*            JZ,
                      ftn_int*            DESCZ,
                      ftn_complex*        WORK,
                      ftn_int*            LWORK,
                      ftn_single*         RWORK,
                      ftn_int*            LRWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            IFAIL,
                      ftn_int*            ICLUSTR,
                      ftn_single*         GAP,
                      ftn_int*            INFO,
                      ftn_len             JOBZ_len,
                      ftn_len             RANGE_len,
                      ftn_len             UPLO_len);

void FORTRAN(pzheevx)(ftn_char            JOBZ,
                      ftn_char            RANGE,
                      ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_double_complex* A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_double*         VL,
                      ftn_double*         VU,
                      ftn_int*            IL,
                      ftn_int*            IU,
                      ftn_double const*   ABSTOL,
                      ftn_int*            M,
                      ftn_int*            NZ,
                      ftn_double*         W,
                      ftn_double const*   ORFAC,
                      ftn_double_complex* Z,
                      ftn_int*            IZ,
                      ftn_int*            JZ,
                      ftn_int*            DESCZ,
                      ftn_double_complex* WORK,
                      ftn_int*            LWORK,
                      ftn_double*         RWORK,
                      ftn_int*            LRWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            IFAIL,
                      ftn_int*            ICLUSTR,
                      ftn_double*         GAP,
                      ftn_int*            INFO,
                      ftn_len             JOBZ_len,
                      ftn_len             RANGE_len,
                      ftn_len             UPLO_len);

void FORTRAN(pssyevd)(ftn_char            JOBZ,
                      ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_single*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_single*         W,
                      ftn_single*         Z,
                      ftn_int*            IZ,
                      ftn_int*            JZ,
                      ftn_int*            DESCZ,
                      ftn_single*         WORK,
                      ftn_int*            LWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            INFO,
                      ftn_len             JOBZ_len,
                      ftn_len             UPLO_len);

void FORTRAN(pdsyevd)(ftn_char            JOBZ,
                      ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_double*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_double*         W,
                      ftn_double*         Z,
                      ftn_int*            IZ,
                      ftn_int*            JZ,
                      ftn_int*            DESCZ,
                      ftn_double*         WORK,
                      ftn_int*            LWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            INFO,
                      ftn_len             JOBZ_len,
                      ftn_len             UPLO_len);

void FORTRAN(pcheevd)(ftn_char            JOBZ,
                      ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_complex*        A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_single*         W,
                      ftn_complex*        Z,
                      ftn_int*            IZ,
                      ftn_int*            JZ,
                      ftn_int*            DESCZ,
                      ftn_complex*        WORK,
                      ftn_int*            LWORK,
                      ftn_single*         RWORK,
                      ftn_int*            LRWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            INFO,
                      ftn_len             JOBZ_len,
                      ftn_len             UPLO_len);

void FORTRAN(pzheevd)(ftn_char            JOBZ,
                      ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_double_complex* A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_double*         W,
                      ftn_double_complex* Z,
                      ftn_int*            IZ,
                      ftn_int*            JZ,
                      ftn_int*            DESCZ,
                      ftn_double_complex* WORK,
                      ftn_int*            LWORK,
                      ftn_double*         RWORK,
                      ftn_int*            LRWORK,
                      ftn_int*            IWORK,
                      ftn_int*            LIWORK,
                      ftn_int*            INFO,
                      ftn_len             JOBZ_len,
                      ftn_len             UPLO_len);

void FORTRAN(pspotrf)(ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_single*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            INFO,
                      ftn_len             UPLO_len);

void FORTRAN(pdpotrf)(ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_double*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            INFO,
                      ftn_len             UPLO_len);

void FORTRAN(pcpotrf)(ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_complex*        A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            INFO,
                      ftn_len             UPLO_len);

void FORTRAN(pzpotrf)(ftn_char            UPLO,
                      ftn_int*            N,
                      ftn_double_complex* A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            INFO,
                      ftn_len             UPLO_len);

void FORTRAN(pstrtri)(ftn_char            UPLO,
                      ftn_char            DIAG,
                      ftn_int*            N,
                      ftn_single*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            INFO,
                      ftn_len             UPLO_len,
                      ftn_len             DIAG_len);

void FORTRAN(pdtrtri)(ftn_char            UPLO,
                      ftn_char            DIAG,
                      ftn_int*            N,
                      ftn_double*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            INFO,
                      ftn_len             UPLO_len,
                      ftn_len             DIAG_len);

void FORTRAN(pctrtri)(ftn_char            UPLO,
                      ftn_char            DIAG,
                      ftn_int*            N,
                      ftn_complex*        A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            INFO,
                      ftn_len             UPLO_len,
                      ftn_len             DIAG_len);

void FORTRAN(pztrtri)(ftn_char            UPLO,
                      ftn_char            DIAG,
                      ftn_int*            N,
                      ftn_double_complex* A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_int*            INFO,
                      ftn_len             UPLO_len,
                      ftn_len             DIAG_len);

void FORTRAN(psgeqrf)(ftn_int*            M,
                      ftn_int*            N,
                      ftn_single*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_single*         TAU,
                      ftn_single*         WORK,
                      ftn_int*            LWORK,
                      ftn_int*            INFO);

void FORTRAN(pdgeqrf)(ftn_int*            M,
                      ftn_int*            N,
                      ftn_double*         A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_double*         TAU,
                      ftn_double*         WORK,
                      ftn_int*            LWORK,
                      ftn_int*            INFO);

void FORTRAN(pcgeqrf)(ftn_int*            M,
                      ftn_int*            N,
                      ftn_complex*        A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_complex*        TAU,
                      ftn_complex*        WORK,
                      ftn_int*            LWORK,
                      ftn_int*            INFO);

void FORTRAN(pzgeqrf)(ftn_int*            M,
                      ftn_int*            N,
                      ftn_double_complex* A,
                      ftn_int*            IA,
                      ftn_int*            JA,
                      ftn_int*            DESCA,
                      ftn_double_complex* TAU,
                      ftn_double_complex* WORK,
                      ftn_int*            LWORK,
                      ftn_int*            INFO);

}

#endif
