xref: /petsc/src/mat/impls/aij/seq/essl/essl.c (revision 6849ba73f22fecb8f92ef896a42e4e8bd4cd6965)
1e8aa55a4SKris Buschelman 
2e8aa55a4SKris Buschelman /*
3e8aa55a4SKris Buschelman         Provides an interface to the IBM RS6000 Essl sparse solver
4e8aa55a4SKris Buschelman 
5e8aa55a4SKris Buschelman */
6e8aa55a4SKris Buschelman #include "src/mat/impls/aij/seq/aij.h"
7e8aa55a4SKris Buschelman /* #include <essl.h> This doesn't work!  */
8e8aa55a4SKris Buschelman 
9e8aa55a4SKris Buschelman typedef struct {
10e8aa55a4SKris Buschelman   int         n,nz;
11e8aa55a4SKris Buschelman   PetscScalar *a;
12e8aa55a4SKris Buschelman   int         *ia;
13e8aa55a4SKris Buschelman   int         *ja;
14e8aa55a4SKris Buschelman   int         lna;
15e8aa55a4SKris Buschelman   int         iparm[5];
16e8aa55a4SKris Buschelman   PetscReal   rparm[5];
17e8aa55a4SKris Buschelman   PetscReal   oparm[5];
18e8aa55a4SKris Buschelman   PetscScalar *aux;
19e8aa55a4SKris Buschelman   int         naux;
20e8aa55a4SKris Buschelman 
21*6849ba73SBarry Smith   PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*);
22*6849ba73SBarry Smith   PetscErrorCode (*MatAssemblyEnd)(Mat,MatAssemblyType);
23*6849ba73SBarry Smith   PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*);
24*6849ba73SBarry Smith   PetscErrorCode (*MatDestroy)(Mat);
252f71e704SKris Buschelman   PetscTruth CleanUpESSL;
26f0c56d0fSKris Buschelman } Mat_Essl;
27f0c56d0fSKris Buschelman 
28dfbe8321SBarry Smith EXTERN PetscErrorCode MatDuplicate_Essl(Mat,MatDuplicateOption,Mat*);
29e8aa55a4SKris Buschelman 
30460c4903SKris Buschelman EXTERN_C_BEGIN
31460c4903SKris Buschelman #undef __FUNCT__
32460c4903SKris Buschelman #define __FUNCT__ "MatConvert_Essl_SeqAIJ"
33dfbe8321SBarry Smith PetscErrorCode MatConvert_Essl_SeqAIJ(Mat A,const MatType type,Mat *newmat) {
34dfbe8321SBarry Smith   PetscErrorCode ierr;
35460c4903SKris Buschelman   Mat      B=*newmat;
36f0c56d0fSKris Buschelman   Mat_Essl *essl=(Mat_Essl*)A->spptr;
37460c4903SKris Buschelman 
38460c4903SKris Buschelman   PetscFunctionBegin;
39460c4903SKris Buschelman   if (B != A) {
40460c4903SKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);
41f0c56d0fSKris Buschelman   }
42f0c56d0fSKris Buschelman   B->ops->duplicate        = essl->MatDuplicate;
43f0c56d0fSKris Buschelman   B->ops->assemblyend      = essl->MatAssemblyEnd;
442f71e704SKris Buschelman   B->ops->lufactorsymbolic = essl->MatLUFactorSymbolic;
452f71e704SKris Buschelman   B->ops->destroy          = essl->MatDestroy;
462f71e704SKris Buschelman 
47460c4903SKris Buschelman   /* free the Essl datastructures */
48460c4903SKris Buschelman   ierr = PetscFree(essl);CHKERRQ(ierr);
49460c4903SKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
50460c4903SKris Buschelman   *newmat = B;
51460c4903SKris Buschelman   PetscFunctionReturn(0);
52460c4903SKris Buschelman }
53460c4903SKris Buschelman EXTERN_C_END
54460c4903SKris Buschelman 
55e8aa55a4SKris Buschelman #undef __FUNCT__
56f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_Essl"
57dfbe8321SBarry Smith PetscErrorCode MatDestroy_Essl(Mat A)
58dfbe8321SBarry Smith {
59dfbe8321SBarry Smith   PetscErrorCode ierr;
60f0c56d0fSKris Buschelman   Mat_Essl *essl=(Mat_Essl*)A->spptr;
61e8aa55a4SKris Buschelman 
62e8aa55a4SKris Buschelman   PetscFunctionBegin;
632f71e704SKris Buschelman   if (essl->CleanUpESSL) {
642f71e704SKris Buschelman     ierr = PetscFree(essl->a);CHKERRQ(ierr);
65e8aa55a4SKris Buschelman   }
662f71e704SKris Buschelman   ierr = MatConvert_Essl_SeqAIJ(A,MATSEQAIJ,&A);
672f71e704SKris Buschelman   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
68460c4903SKris Buschelman   PetscFunctionReturn(0);
69460c4903SKris Buschelman }
70460c4903SKris Buschelman 
71460c4903SKris Buschelman #undef __FUNCT__
72f0c56d0fSKris Buschelman #define __FUNCT__ "MatSolve_Essl"
73dfbe8321SBarry Smith PetscErrorCode MatSolve_Essl(Mat A,Vec b,Vec x) {
74f0c56d0fSKris Buschelman   Mat_Essl    *essl = (Mat_Essl*)A->spptr;
75e8aa55a4SKris Buschelman   PetscScalar *xx;
76dfbe8321SBarry Smith   PetscErrorCode ierr;
77dfbe8321SBarry Smith   int         m,zero = 0;
78e8aa55a4SKris Buschelman 
79e8aa55a4SKris Buschelman   PetscFunctionBegin;
80e8aa55a4SKris Buschelman   ierr = VecGetLocalSize(b,&m);CHKERRQ(ierr);
81e8aa55a4SKris Buschelman   ierr = VecCopy(b,x);CHKERRQ(ierr);
82e8aa55a4SKris Buschelman   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
83e8aa55a4SKris Buschelman   dgss(&zero,&A->n,essl->a,essl->ia,essl->ja,&essl->lna,xx,essl->aux,&essl->naux);
84e8aa55a4SKris Buschelman   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
85e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
86e8aa55a4SKris Buschelman }
87e8aa55a4SKris Buschelman 
88e8aa55a4SKris Buschelman #undef __FUNCT__
89f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Essl"
90dfbe8321SBarry Smith PetscErrorCode MatLUFactorNumeric_Essl(Mat A,Mat *F) {
91e8aa55a4SKris Buschelman   Mat_SeqAIJ *aa=(Mat_SeqAIJ*)(A)->data;
92f0c56d0fSKris Buschelman   Mat_Essl   *essl=(Mat_Essl*)(*F)->spptr;
93*6849ba73SBarry Smith   PetscErrorCode ierr;
94*6849ba73SBarry Smith   int        i,one = 1;
95e8aa55a4SKris Buschelman 
96e8aa55a4SKris Buschelman   PetscFunctionBegin;
97e8aa55a4SKris Buschelman   /* copy matrix data into silly ESSL data structure (1-based Frotran style) */
98e8aa55a4SKris Buschelman   for (i=0; i<A->m+1; i++) essl->ia[i] = aa->i[i] + 1;
99e8aa55a4SKris Buschelman   for (i=0; i<aa->nz; i++) essl->ja[i]  = aa->j[i] + 1;
100e8aa55a4SKris Buschelman 
101e8aa55a4SKris Buschelman   ierr = PetscMemcpy(essl->a,aa->a,(aa->nz)*sizeof(PetscScalar));CHKERRQ(ierr);
102e8aa55a4SKris Buschelman 
103e8aa55a4SKris Buschelman   /* set Essl options */
104e8aa55a4SKris Buschelman   essl->iparm[0] = 1;
105e8aa55a4SKris Buschelman   essl->iparm[1] = 5;
106e8aa55a4SKris Buschelman   essl->iparm[2] = 1;
107e8aa55a4SKris Buschelman   essl->iparm[3] = 0;
108e8aa55a4SKris Buschelman   essl->rparm[0] = 1.e-12;
109e8aa55a4SKris Buschelman   essl->rparm[1] = A->lupivotthreshold;
110e8aa55a4SKris Buschelman 
111e8aa55a4SKris Buschelman   dgsf(&one,&A->m,&essl->nz,essl->a,essl->ia,essl->ja,&essl->lna,essl->iparm,
112e8aa55a4SKris Buschelman                essl->rparm,essl->oparm,essl->aux,&essl->naux);
113e8aa55a4SKris Buschelman 
114e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
115e8aa55a4SKris Buschelman }
116e8aa55a4SKris Buschelman 
117e8aa55a4SKris Buschelman #undef __FUNCT__
118f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Essl"
119dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Essl(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) {
120e8aa55a4SKris Buschelman   Mat        B;
121eef49c96SKris Buschelman   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
122dfbe8321SBarry Smith   PetscErrorCode ierr;
123dfbe8321SBarry Smith   int        len;
124f0c56d0fSKris Buschelman   Mat_Essl   *essl;
125e8aa55a4SKris Buschelman   PetscReal  f = 1.0;
126e8aa55a4SKris Buschelman 
127e8aa55a4SKris Buschelman   PetscFunctionBegin;
128e8aa55a4SKris Buschelman   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
129e8aa55a4SKris Buschelman   ierr = MatCreate(A->comm,PETSC_DECIDE,PETSC_DECIDE,A->m,A->n,&B);CHKERRQ(ierr);
130be5d1d56SKris Buschelman   ierr = MatSetType(B,A->type_name);CHKERRQ(ierr);
131e8aa55a4SKris Buschelman   ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
132e8aa55a4SKris Buschelman 
133f0c56d0fSKris Buschelman   B->ops->solve           = MatSolve_Essl;
134f0c56d0fSKris Buschelman   B->ops->lufactornumeric = MatLUFactorNumeric_Essl;
135e8aa55a4SKris Buschelman   B->factor               = FACTOR_LU;
136e8aa55a4SKris Buschelman 
137f0c56d0fSKris Buschelman   essl = (Mat_Essl *)(B->spptr);
138e8aa55a4SKris Buschelman 
139e8aa55a4SKris Buschelman   /* allocate the work arrays required by ESSL */
140e8aa55a4SKris Buschelman   f = info->fill;
141e8aa55a4SKris Buschelman   essl->nz   = a->nz;
142e8aa55a4SKris Buschelman   essl->lna  = (int)a->nz*f;
143e8aa55a4SKris Buschelman   essl->naux = 100 + 10*A->m;
144e8aa55a4SKris Buschelman 
145e8aa55a4SKris Buschelman   /* since malloc is slow on IBM we try a single malloc */
146e8aa55a4SKris Buschelman   len               = essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar);
147e8aa55a4SKris Buschelman   ierr              = PetscMalloc(len,&essl->a);CHKERRQ(ierr);
148e8aa55a4SKris Buschelman   essl->aux         = essl->a + essl->lna;
149e8aa55a4SKris Buschelman   essl->ia          = (int*)(essl->aux + essl->naux);
150e8aa55a4SKris Buschelman   essl->ja          = essl->ia + essl->lna;
1512f71e704SKris Buschelman   essl->CleanUpESSL = PETSC_TRUE;
152e8aa55a4SKris Buschelman 
153f0c56d0fSKris Buschelman   PetscLogObjectMemory(B,len+sizeof(Mat_Essl));
154e8aa55a4SKris Buschelman   *F = B;
155e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
156e8aa55a4SKris Buschelman }
157e8aa55a4SKris Buschelman 
1582f71e704SKris Buschelman #undef __FUNCT__
159f0c56d0fSKris Buschelman #define __FUNCT__ "MatAssemblyEnd_Essl"
160dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_Essl(Mat A,MatAssemblyType mode) {
161dfbe8321SBarry Smith   PetscErrorCode ierr;
162f0c56d0fSKris Buschelman   Mat_Essl *essl=(Mat_Essl*)(A->spptr);
1632f71e704SKris Buschelman 
1642f71e704SKris Buschelman   PetscFunctionBegin;
1652f71e704SKris Buschelman   ierr = (*essl->MatAssemblyEnd)(A,mode);CHKERRQ(ierr);
1662f71e704SKris Buschelman 
1672f71e704SKris Buschelman   essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic;
168f0c56d0fSKris Buschelman   A->ops->lufactorsymbolic  = MatLUFactorSymbolic_Essl;
169f0c56d0fSKris Buschelman   PetscLogInfo(0,"Using ESSL for LU factorization and solves");
1702f71e704SKris Buschelman   PetscFunctionReturn(0);
1712f71e704SKris Buschelman }
1722f71e704SKris Buschelman 
173460c4903SKris Buschelman EXTERN_C_BEGIN
174e8aa55a4SKris Buschelman #undef __FUNCT__
175460c4903SKris Buschelman #define __FUNCT__ "MatConvert_SeqAIJ_Essl"
176dfbe8321SBarry Smith PetscErrorCode MatConvert_SeqAIJ_Essl(Mat A,const MatType type,Mat *newmat) {
177460c4903SKris Buschelman   Mat      B=*newmat;
178dfbe8321SBarry Smith   PetscErrorCode ierr;
179f0c56d0fSKris Buschelman   Mat_Essl *essl;
180460c4903SKris Buschelman 
181e8aa55a4SKris Buschelman   PetscFunctionBegin;
182460c4903SKris Buschelman 
183460c4903SKris Buschelman   if (B != A) {
184460c4903SKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
185460c4903SKris Buschelman   }
186460c4903SKris Buschelman 
187f0c56d0fSKris Buschelman   ierr                      = PetscNew(Mat_Essl,&essl);CHKERRQ(ierr);
188f0c56d0fSKris Buschelman   essl->MatDuplicate        = A->ops->duplicate;
189460c4903SKris Buschelman   essl->MatAssemblyEnd      = A->ops->assemblyend;
190460c4903SKris Buschelman   essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic;
191460c4903SKris Buschelman   essl->MatDestroy          = A->ops->destroy;
1922f71e704SKris Buschelman   essl->CleanUpESSL         = PETSC_FALSE;
193460c4903SKris Buschelman 
1942f71e704SKris Buschelman   B->spptr                  = (void*)essl;
195f0c56d0fSKris Buschelman   B->ops->duplicate         = MatDuplicate_Essl;
196f0c56d0fSKris Buschelman   B->ops->assemblyend       = MatAssemblyEnd_Essl;
197f0c56d0fSKris Buschelman   B->ops->lufactorsymbolic  = MatLUFactorSymbolic_Essl;
198f0c56d0fSKris Buschelman   B->ops->destroy           = MatDestroy_Essl;
199460c4903SKris Buschelman 
200460c4903SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_essl_C",
201460c4903SKris Buschelman                                            "MatConvert_SeqAIJ_Essl",MatConvert_SeqAIJ_Essl);CHKERRQ(ierr);
202460c4903SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_essl_seqaij_C",
203460c4903SKris Buschelman                                            "MatConvert_Essl_SeqAIJ",MatConvert_Essl_SeqAIJ);CHKERRQ(ierr);
204460c4903SKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,type);CHKERRQ(ierr);
205460c4903SKris Buschelman   *newmat = B;
206e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
207e8aa55a4SKris Buschelman }
208460c4903SKris Buschelman EXTERN_C_END
209e8aa55a4SKris Buschelman 
210f0c56d0fSKris Buschelman #undef __FUNCT__
211f0c56d0fSKris Buschelman #define __FUNCT__ "MatDuplicate_Essl"
212dfbe8321SBarry Smith PetscErrorCode MatDuplicate_Essl(Mat A, MatDuplicateOption op, Mat *M) {
213dfbe8321SBarry Smith   PetscErrorCode ierr;
21413ee22deSSatish Balay   Mat_Essl *lu = (Mat_Essl *)A->spptr;
2158f340917SKris Buschelman 
216f0c56d0fSKris Buschelman   PetscFunctionBegin;
2178f340917SKris Buschelman   ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr);
2183f953163SKris Buschelman   ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Essl));CHKERRQ(ierr);
219f0c56d0fSKris Buschelman   PetscFunctionReturn(0);
220f0c56d0fSKris Buschelman }
221f0c56d0fSKris Buschelman 
2222f71e704SKris Buschelman /*MC
223fafad747SKris Buschelman   MATESSL - MATESSL = "essl" - A matrix type providing direct solvers (LU) for sequential matrices
2242f71e704SKris Buschelman   via the external package ESSL.
2252f71e704SKris Buschelman 
2262f71e704SKris Buschelman   If ESSL is installed (see the manual for
2272f71e704SKris Buschelman   instructions on how to declare the existence of external packages),
2282f71e704SKris Buschelman   a matrix type can be constructed which invokes ESSL solvers.
2292f71e704SKris Buschelman   After calling MatCreate(...,A), simply call MatSetType(A,MATESSL).
2302f71e704SKris Buschelman   This matrix type is only supported for double precision real.
2312f71e704SKris Buschelman 
2322f71e704SKris Buschelman   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
23328b08bd3SKris Buschelman   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
23428b08bd3SKris Buschelman   the MATSEQAIJ type without data copy.
2352f71e704SKris Buschelman 
2362f71e704SKris Buschelman   Options Database Keys:
2370bad9183SKris Buschelman . -mat_type essl - sets the matrix type to "essl" during a call to MatSetFromOptions()
2382f71e704SKris Buschelman 
2392f71e704SKris Buschelman    Level: beginner
2402f71e704SKris Buschelman 
2412f71e704SKris Buschelman .seealso: PCLU
2422f71e704SKris Buschelman M*/
2432f71e704SKris Buschelman 
244e8aa55a4SKris Buschelman EXTERN_C_BEGIN
245e8aa55a4SKris Buschelman #undef __FUNCT__
246f0c56d0fSKris Buschelman #define __FUNCT__ "MatCreate_Essl"
247dfbe8321SBarry Smith PetscErrorCode MatCreate_Essl(Mat A)
248dfbe8321SBarry Smith {
249dfbe8321SBarry Smith   PetscErrorCode ierr;
250e8aa55a4SKris Buschelman 
251e8aa55a4SKris Buschelman   PetscFunctionBegin;
2525441df8eSKris Buschelman   /* Change type name before calling MatSetType to force proper construction of SeqAIJ and Essl types */
2535441df8eSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)A,MATESSL);CHKERRQ(ierr);
254e8aa55a4SKris Buschelman   ierr = MatSetType(A,MATSEQAIJ);
255460c4903SKris Buschelman   ierr = MatConvert_SeqAIJ_Essl(A,MATESSL,&A);CHKERRQ(ierr);
256e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
257e8aa55a4SKris Buschelman }
2584eb8e494SKris Buschelman EXTERN_C_END
259