xref: /petsc/src/mat/impls/aij/seq/essl/essl.c (revision 5c9eb25f753630cfd361293e05e7358a00a954ac)
1be1d678aSKris Buschelman #define PETSCMAT_DLL
2e8aa55a4SKris Buschelman 
3e8aa55a4SKris Buschelman /*
4e8aa55a4SKris Buschelman         Provides an interface to the IBM RS6000 Essl sparse solver
5e8aa55a4SKris Buschelman 
6e8aa55a4SKris Buschelman */
7e8aa55a4SKris Buschelman #include "src/mat/impls/aij/seq/aij.h"
8b24902e0SBarry Smith 
9e8aa55a4SKris Buschelman /* #include <essl.h> This doesn't work!  */
10e8aa55a4SKris Buschelman 
11d3bad8c4SBarry Smith EXTERN_C_BEGIN
12d3bad8c4SBarry Smith void dgss(int*,int*,double*,int*,int*,int*,double*,double*,int*);
13d3bad8c4SBarry Smith void dgsf(int*,int*,int*,double*,int*,int*,int*,int*,double*,double*,double*,int*);
14d3bad8c4SBarry Smith EXTERN_C_END
15d3bad8c4SBarry Smith 
16e8aa55a4SKris Buschelman typedef struct {
17e8aa55a4SKris Buschelman   int         n,nz;
18e8aa55a4SKris Buschelman   PetscScalar *a;
19e8aa55a4SKris Buschelman   int         *ia;
20e8aa55a4SKris Buschelman   int         *ja;
21e8aa55a4SKris Buschelman   int         lna;
22e8aa55a4SKris Buschelman   int         iparm[5];
23e8aa55a4SKris Buschelman   PetscReal   rparm[5];
24e8aa55a4SKris Buschelman   PetscReal   oparm[5];
25e8aa55a4SKris Buschelman   PetscScalar *aux;
26e8aa55a4SKris Buschelman   int         naux;
27e8aa55a4SKris Buschelman 
282f71e704SKris Buschelman   PetscTruth CleanUpESSL;
29f0c56d0fSKris Buschelman } Mat_Essl;
30f0c56d0fSKris Buschelman 
31e8aa55a4SKris Buschelman #undef __FUNCT__
32f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_Essl"
33dfbe8321SBarry Smith PetscErrorCode MatDestroy_Essl(Mat A)
34dfbe8321SBarry Smith {
35dfbe8321SBarry Smith   PetscErrorCode ierr;
36f0c56d0fSKris Buschelman   Mat_Essl       *essl=(Mat_Essl*)A->spptr;
37e8aa55a4SKris Buschelman 
38e8aa55a4SKris Buschelman   PetscFunctionBegin;
392f71e704SKris Buschelman   if (essl->CleanUpESSL) {
402f71e704SKris Buschelman     ierr = PetscFree(essl->a);CHKERRQ(ierr);
41e8aa55a4SKris Buschelman   }
42b24902e0SBarry Smith   ierr = PetscFree(essl);CHKERRQ(ierr);
43b24902e0SBarry Smith   ierr = MatDestroy_SeqAIJ(A);CHKERRQ(ierr);
44460c4903SKris Buschelman   PetscFunctionReturn(0);
45460c4903SKris Buschelman }
46460c4903SKris Buschelman 
47460c4903SKris Buschelman #undef __FUNCT__
48f0c56d0fSKris Buschelman #define __FUNCT__ "MatSolve_Essl"
49b24902e0SBarry Smith PetscErrorCode MatSolve_Essl(Mat A,Vec b,Vec x)
50b24902e0SBarry Smith {
51f0c56d0fSKris Buschelman   Mat_Essl       *essl = (Mat_Essl*)A->spptr;
52e8aa55a4SKris Buschelman   PetscScalar    *xx;
53dfbe8321SBarry Smith   PetscErrorCode ierr;
54dfbe8321SBarry Smith   int            m,zero = 0;
55e8aa55a4SKris Buschelman 
56e8aa55a4SKris Buschelman   PetscFunctionBegin;
57e8aa55a4SKris Buschelman   ierr = VecGetLocalSize(b,&m);CHKERRQ(ierr);
58e8aa55a4SKris Buschelman   ierr = VecCopy(b,x);CHKERRQ(ierr);
59e8aa55a4SKris Buschelman   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
602a4c71feSBarry Smith   dgss(&zero,&A->cmap.n,essl->a,essl->ia,essl->ja,&essl->lna,xx,essl->aux,&essl->naux);
61e8aa55a4SKris Buschelman   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
62e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
63e8aa55a4SKris Buschelman }
64e8aa55a4SKris Buschelman 
65e8aa55a4SKris Buschelman #undef __FUNCT__
66f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Essl"
67b24902e0SBarry Smith PetscErrorCode MatLUFactorNumeric_Essl(Mat A,MatFactorInfo *info,Mat *F)
68b24902e0SBarry Smith {
69e8aa55a4SKris Buschelman   Mat_SeqAIJ     *aa=(Mat_SeqAIJ*)(A)->data;
70f0c56d0fSKris Buschelman   Mat_Essl       *essl=(Mat_Essl*)(*F)->spptr;
716849ba73SBarry Smith   PetscErrorCode ierr;
726849ba73SBarry Smith   int            i,one = 1;
73e8aa55a4SKris Buschelman 
74e8aa55a4SKris Buschelman   PetscFunctionBegin;
75e8aa55a4SKris Buschelman   /* copy matrix data into silly ESSL data structure (1-based Frotran style) */
762a4c71feSBarry Smith   for (i=0; i<A->rmap.n+1; i++) essl->ia[i] = aa->i[i] + 1;
77e8aa55a4SKris Buschelman   for (i=0; i<aa->nz; i++) essl->ja[i]  = aa->j[i] + 1;
78e8aa55a4SKris Buschelman 
79e8aa55a4SKris Buschelman   ierr = PetscMemcpy(essl->a,aa->a,(aa->nz)*sizeof(PetscScalar));CHKERRQ(ierr);
80e8aa55a4SKris Buschelman 
81e8aa55a4SKris Buschelman   /* set Essl options */
82e8aa55a4SKris Buschelman   essl->iparm[0] = 1;
83e8aa55a4SKris Buschelman   essl->iparm[1] = 5;
84e8aa55a4SKris Buschelman   essl->iparm[2] = 1;
85e8aa55a4SKris Buschelman   essl->iparm[3] = 0;
86e8aa55a4SKris Buschelman   essl->rparm[0] = 1.e-12;
8762331464SKris Buschelman   essl->rparm[1] = 1.0;
887adad957SLisandro Dalcin   ierr = PetscOptionsGetReal(((PetscObject)A)->prefix,"-matessl_lu_threshold",&essl->rparm[1],PETSC_NULL);CHKERRQ(ierr);
89e8aa55a4SKris Buschelman 
90b24902e0SBarry Smith   dgsf(&one,&A->rmap.n,&essl->nz,essl->a,essl->ia,essl->ja,&essl->lna,essl->iparm,essl->rparm,essl->oparm,essl->aux,&essl->naux);
91e8aa55a4SKris Buschelman 
92d3bad8c4SBarry Smith   (*F)->assembled = PETSC_TRUE;
93*5c9eb25fSBarry Smith   (*F)->preallocated = PETSC_TRUE;
94e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
95e8aa55a4SKris Buschelman }
96e8aa55a4SKris Buschelman 
97b24902e0SBarry Smith 
98e8aa55a4SKris Buschelman #undef __FUNCT__
99f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Essl"
100b24902e0SBarry Smith PetscErrorCode MatLUFactorSymbolic_Essl(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
101b24902e0SBarry Smith {
102e8aa55a4SKris Buschelman   Mat            B;
103eef49c96SKris Buschelman   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
104dfbe8321SBarry Smith   PetscErrorCode ierr;
105dfbe8321SBarry Smith   int            len;
106f0c56d0fSKris Buschelman   Mat_Essl       *essl;
107e8aa55a4SKris Buschelman   PetscReal      f = 1.0;
108e8aa55a4SKris Buschelman 
109e8aa55a4SKris Buschelman   PetscFunctionBegin;
1102a4c71feSBarry Smith   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
1117adad957SLisandro Dalcin   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
1122a4c71feSBarry Smith   ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
1137adad957SLisandro Dalcin   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
114e8aa55a4SKris Buschelman   ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
115e8aa55a4SKris Buschelman 
116f0c56d0fSKris Buschelman   B->ops->solve           = MatSolve_Essl;
117f0c56d0fSKris Buschelman   B->ops->lufactornumeric = MatLUFactorNumeric_Essl;
118*5c9eb25fSBarry Smith   B->factor               = MAT_FACTOR_LU;
119e8aa55a4SKris Buschelman 
120f0c56d0fSKris Buschelman   essl = (Mat_Essl *)(B->spptr);
121e8aa55a4SKris Buschelman 
122e8aa55a4SKris Buschelman   /* allocate the work arrays required by ESSL */
123e8aa55a4SKris Buschelman   f = info->fill;
124e8aa55a4SKris Buschelman   essl->nz   = a->nz;
125e8aa55a4SKris Buschelman   essl->lna  = (int)a->nz*f;
1262a4c71feSBarry Smith   essl->naux = 100 + 10*A->rmap.n;
127e8aa55a4SKris Buschelman 
128e8aa55a4SKris Buschelman   /* since malloc is slow on IBM we try a single malloc */
129e8aa55a4SKris Buschelman   len               = essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar);
130e8aa55a4SKris Buschelman   ierr              = PetscMalloc(len,&essl->a);CHKERRQ(ierr);
131e8aa55a4SKris Buschelman   essl->aux         = essl->a + essl->lna;
132e8aa55a4SKris Buschelman   essl->ia          = (int*)(essl->aux + essl->naux);
133e8aa55a4SKris Buschelman   essl->ja          = essl->ia + essl->lna;
1342f71e704SKris Buschelman   essl->CleanUpESSL = PETSC_TRUE;
135e8aa55a4SKris Buschelman 
13638f2d2fdSLisandro Dalcin   ierr = PetscLogObjectMemory(B,len);CHKERRQ(ierr);
137e8aa55a4SKris Buschelman   *F = B;
138e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
139e8aa55a4SKris Buschelman }
140e8aa55a4SKris Buschelman 
1412f71e704SKris Buschelman /*MC
142fafad747SKris Buschelman   MATESSL - MATESSL = "essl" - A matrix type providing direct solvers (LU) for sequential matrices
1432f71e704SKris Buschelman   via the external package ESSL.
1442f71e704SKris Buschelman 
1452f71e704SKris Buschelman   If ESSL is installed (see the manual for
1462f71e704SKris Buschelman   instructions on how to declare the existence of external packages),
1472f71e704SKris Buschelman   a matrix type can be constructed which invokes ESSL solvers.
1482f71e704SKris Buschelman   After calling MatCreate(...,A), simply call MatSetType(A,MATESSL).
1492f71e704SKris Buschelman   This matrix type is only supported for double precision real.
1502f71e704SKris Buschelman 
1512f71e704SKris Buschelman   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
15228b08bd3SKris Buschelman   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
15328b08bd3SKris Buschelman   the MATSEQAIJ type without data copy.
1542f71e704SKris Buschelman 
1552f71e704SKris Buschelman   Options Database Keys:
1560bad9183SKris Buschelman . -mat_type essl - sets the matrix type to "essl" during a call to MatSetFromOptions()
1572f71e704SKris Buschelman 
1582f71e704SKris Buschelman    Level: beginner
1592f71e704SKris Buschelman 
1602f71e704SKris Buschelman .seealso: PCLU
1612f71e704SKris Buschelman M*/
1622f71e704SKris Buschelman 
163e8aa55a4SKris Buschelman #undef __FUNCT__
164b24902e0SBarry Smith #define __FUNCT__ "MatGetFactor_seqaij_essl"
165*5c9eb25fSBarry Smith PetscErrorCode MatGetFactor_seqaij_essl(Mat A,MatFactorType ftype,Mat *F)
166dfbe8321SBarry Smith {
167b24902e0SBarry Smith   Mat            B;
168b24902e0SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
169dfbe8321SBarry Smith   PetscErrorCode ierr;
170b24902e0SBarry Smith   Mat_Essl       *essl;
171e8aa55a4SKris Buschelman 
172e8aa55a4SKris Buschelman   PetscFunctionBegin;
173b24902e0SBarry Smith   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
174b24902e0SBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
175b24902e0SBarry Smith   ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
176b24902e0SBarry Smith   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
177b24902e0SBarry Smith   ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
178b24902e0SBarry Smith 
179b24902e0SBarry Smith   ierr = PetscNewLog(B,Mat_Essl,&essl);CHKERRQ(ierr);
180b24902e0SBarry Smith   B->spptr                 = essl;
181b24902e0SBarry Smith   B->ops->solve            = MatSolve_Essl;
182b24902e0SBarry Smith   B->ops->lufactornumeric  = MatLUFactorNumeric_Essl;
183b24902e0SBarry Smith   B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl;
184*5c9eb25fSBarry Smith   B->factor                = MAT_FACTOR_LU;
185b24902e0SBarry Smith   *F                       = B;
186e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
187e8aa55a4SKris Buschelman }
188