Actual source code: essl.c

petsc-master 2016-05-29
Report Typos and Errors
  2: /*
  3:         Provides an interface to the IBM RS6000 Essl sparse solver

  5: */
  6: #include <../src/mat/impls/aij/seq/aij.h>

  8: /* #include <essl.h> This doesn't work!  */

 10: PETSC_EXTERN void dgss(int*,int*,double*,int*,int*,int*,double*,double*,int*);
 11: PETSC_EXTERN void dgsf(int*,int*,int*,double*,int*,int*,int*,int*,double*,double*,double*,int*);

 13: typedef struct {
 14:   int         n,nz;
 15:   PetscScalar *a;
 16:   int         *ia;
 17:   int         *ja;
 18:   int         lna;
 19:   int         iparm[5];
 20:   PetscReal   rparm[5];
 21:   PetscReal   oparm[5];
 22:   PetscScalar *aux;
 23:   int         naux;

 25:   PetscBool   CleanUpESSL;
 26: } Mat_Essl;

 30: PetscErrorCode MatDestroy_Essl(Mat A)
 31: {
 33:   Mat_Essl       *essl=(Mat_Essl*)A->data;

 36:   if (essl->CleanUpESSL) {
 37:     PetscFree4(essl->a,essl->aux,essl->ia,essl->ja);
 38:   }
 39:   PetscFree(A->data);
 40:   return(0);
 41: }

 45: PetscErrorCode MatSolve_Essl(Mat A,Vec b,Vec x)
 46: {
 47:   Mat_Essl       *essl = (Mat_Essl*)A->data;
 48:   PetscScalar    *xx;
 50:   int            nessl,zero = 0;

 53:   PetscBLASIntCast(A->cmap->n,&nessl);
 54:   VecCopy(b,x);
 55:   VecGetArray(x,&xx);
 56:   dgss(&zero,&nessl,essl->a,essl->ia,essl->ja,&essl->lna,xx,essl->aux,&essl->naux);
 57:   VecRestoreArray(x,&xx);
 58:   return(0);
 59: }

 63: PetscErrorCode MatLUFactorNumeric_Essl(Mat F,Mat A,const MatFactorInfo *info)
 64: {
 65:   Mat_SeqAIJ     *aa  =(Mat_SeqAIJ*)(A)->data;
 66:   Mat_Essl       *essl=(Mat_Essl*)(F)->data;
 68:   int            nessl,i,one = 1;

 71:   PetscBLASIntCast(A->rmap->n,&nessl);
 72:   /* copy matrix data into silly ESSL data structure (1-based Frotran style) */
 73:   for (i=0; i<A->rmap->n+1; i++) essl->ia[i] = aa->i[i] + 1;
 74:   for (i=0; i<aa->nz; i++) essl->ja[i] = aa->j[i] + 1;

 76:   PetscMemcpy(essl->a,aa->a,(aa->nz)*sizeof(PetscScalar));

 78:   /* set Essl options */
 79:   essl->iparm[0] = 1;
 80:   essl->iparm[1] = 5;
 81:   essl->iparm[2] = 1;
 82:   essl->iparm[3] = 0;
 83:   essl->rparm[0] = 1.e-12;
 84:   essl->rparm[1] = 1.0;

 86:   PetscOptionsGetReal(((PetscObject)A)->prefix,"-matessl_lu_threshold",&essl->rparm[1],NULL);

 88:   dgsf(&one,&nessl,&essl->nz,essl->a,essl->ia,essl->ja,&essl->lna,essl->iparm,essl->rparm,essl->oparm,essl->aux,&essl->naux);

 90:   F->ops->solve     = MatSolve_Essl;
 91:   (F)->assembled    = PETSC_TRUE;
 92:   (F)->preallocated = PETSC_TRUE;
 93:   return(0);
 94: }




101: PetscErrorCode MatLUFactorSymbolic_Essl(Mat B,Mat A,IS r,IS c,const MatFactorInfo *info)
102: {
103:   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
105:   Mat_Essl       *essl;
106:   PetscReal      f = 1.0;

109:   essl = (Mat_Essl*)(B->data);

111:   /* allocate the work arrays required by ESSL */
112:   f    = info->fill;
113:   PetscBLASIntCast(a->nz,&essl->nz);
114:   PetscBLASIntCast((PetscInt)(a->nz*f),&essl->lna);
115:   PetscBLASIntCast(100 + 10*A->rmap->n,&essl->naux);

117:   /* since malloc is slow on IBM we try a single malloc */
118:   PetscMalloc4(essl->lna,&essl->a,essl->naux,&essl->aux,essl->lna,&essl->ia,essl->lna,&essl->ja);

120:   essl->CleanUpESSL = PETSC_TRUE;

122:   PetscLogObjectMemory((PetscObject)B,essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar));

124:   B->ops->lufactornumeric = MatLUFactorNumeric_Essl;
125:   return(0);
126: }

130: PetscErrorCode MatFactorGetSolverPackage_essl(Mat A,const MatSolverPackage *type)
131: {
133:   *type = MATSOLVERESSL;
134:   return(0);
135: }

137: /*MC
138:   MATSOLVERESSL - "essl" - Provides direct solvers (LU) for sequential matrices
139:                               via the external package ESSL.

141:   If ESSL is installed (see the manual for
142:   instructions on how to declare the existence of external packages),

144:   Works with MATSEQAIJ matrices

146:    Level: beginner

148: .seealso: PCLU, PCFactorSetMatSolverPackage(), MatSolverPackage
149: M*/

153: PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat A,MatFactorType ftype,Mat *F)
154: {
155:   Mat            B;
157:   Mat_Essl       *essl;

160:   if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square");
161:   MatCreate(PetscObjectComm((PetscObject)A),&B);
162:   MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,A->rmap->n,A->cmap->n);
163:   PetscStrallocpy("essl",&((PetscObject)B)->type_name);
164:   MatSetUp(B);

166:   PetscNewLog(B,&essl);

168:   B->data                  = essl;
169:   B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl;
170:   B->ops->destroy          = MatDestroy_Essl;
171:   B->ops->getinfo          = MatGetInfo_External;

173:   PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverPackage_C",MatFactorGetSolverPackage_essl);

175:   B->factortype = MAT_FACTOR_LU;
176:   PetscFree(B->solvertype);
177:   PetscStrallocpy(MATSOLVERESSL,&B->solvertype);

179:   *F            = B;
180:   return(0);
181: }

185: PETSC_EXTERN PetscErrorCode MatSolverPackageRegister_Essl(void)
186: {
189:   MatSolverPackageRegister(MATSOLVERESSL,MATSEQAIJ,          MAT_FACTOR_LU,MatGetFactor_seqaij_essl);
190:   return(0);
191: }