xref: /petsc/src/mat/impls/aij/seq/essl/essl.c (revision 5441df8ea7fc15821ed1fa0916d70c7c3774aeba)
1e8aa55a4SKris Buschelman /*$Id: essl.c,v 1.49 2001/08/07 03:02:47 balay Exp $*/
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"
8e8aa55a4SKris Buschelman /* #include <essl.h> This doesn't work!  */
9e8aa55a4SKris Buschelman 
10e8aa55a4SKris Buschelman typedef struct {
11e8aa55a4SKris Buschelman   int         n,nz;
12e8aa55a4SKris Buschelman   PetscScalar *a;
13e8aa55a4SKris Buschelman   int         *ia;
14e8aa55a4SKris Buschelman   int         *ja;
15e8aa55a4SKris Buschelman   int         lna;
16e8aa55a4SKris Buschelman   int         iparm[5];
17e8aa55a4SKris Buschelman   PetscReal   rparm[5];
18e8aa55a4SKris Buschelman   PetscReal   oparm[5];
19e8aa55a4SKris Buschelman   PetscScalar *aux;
20e8aa55a4SKris Buschelman   int         naux;
21e8aa55a4SKris Buschelman 
22f0c56d0fSKris Buschelman   int (*MatDuplicate)(Mat,MatDuplicateOption,Mat*);
23460c4903SKris Buschelman   int (*MatAssemblyEnd)(Mat,MatAssemblyType);
24460c4903SKris Buschelman   int (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*);
25e8aa55a4SKris Buschelman   int (*MatDestroy)(Mat);
262f71e704SKris Buschelman   PetscTruth CleanUpESSL;
27f0c56d0fSKris Buschelman } Mat_Essl;
28f0c56d0fSKris Buschelman 
29f0c56d0fSKris Buschelman EXTERN int MatDuplicate_Essl(Mat,MatDuplicateOption,Mat*);
30e8aa55a4SKris Buschelman 
31460c4903SKris Buschelman EXTERN_C_BEGIN
32460c4903SKris Buschelman #undef __FUNCT__
33460c4903SKris Buschelman #define __FUNCT__ "MatConvert_Essl_SeqAIJ"
34460c4903SKris Buschelman int MatConvert_Essl_SeqAIJ(Mat A,MatType type,Mat *newmat) {
35460c4903SKris Buschelman   int      ierr;
36460c4903SKris Buschelman   Mat      B=*newmat;
37f0c56d0fSKris Buschelman   Mat_Essl *essl=(Mat_Essl*)A->spptr;
38460c4903SKris Buschelman 
39460c4903SKris Buschelman   PetscFunctionBegin;
40460c4903SKris Buschelman   if (B != A) {
41460c4903SKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);
42f0c56d0fSKris Buschelman   }
43f0c56d0fSKris Buschelman   B->ops->duplicate        = essl->MatDuplicate;
44f0c56d0fSKris Buschelman   B->ops->assemblyend      = essl->MatAssemblyEnd;
452f71e704SKris Buschelman   B->ops->lufactorsymbolic = essl->MatLUFactorSymbolic;
462f71e704SKris Buschelman   B->ops->destroy          = essl->MatDestroy;
472f71e704SKris Buschelman 
48460c4903SKris Buschelman   /* free the Essl datastructures */
49460c4903SKris Buschelman   ierr = PetscFree(essl);CHKERRQ(ierr);
50460c4903SKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
51460c4903SKris Buschelman   *newmat = B;
52460c4903SKris Buschelman   PetscFunctionReturn(0);
53460c4903SKris Buschelman }
54460c4903SKris Buschelman EXTERN_C_END
55460c4903SKris Buschelman 
56e8aa55a4SKris Buschelman #undef __FUNCT__
57f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_Essl"
58f0c56d0fSKris Buschelman int MatDestroy_Essl(Mat A) {
59460c4903SKris Buschelman   int       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"
73f0c56d0fSKris Buschelman int MatSolve_Essl(Mat A,Vec b,Vec x) {
74f0c56d0fSKris Buschelman   Mat_Essl    *essl = (Mat_Essl*)A->spptr;
75e8aa55a4SKris Buschelman   PetscScalar *xx;
76e8aa55a4SKris Buschelman   int         ierr,m,zero = 0;
77e8aa55a4SKris Buschelman 
78e8aa55a4SKris Buschelman   PetscFunctionBegin;
79e8aa55a4SKris Buschelman   ierr = VecGetLocalSize(b,&m);CHKERRQ(ierr);
80e8aa55a4SKris Buschelman   ierr = VecCopy(b,x);CHKERRQ(ierr);
81e8aa55a4SKris Buschelman   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
82e8aa55a4SKris Buschelman   dgss(&zero,&A->n,essl->a,essl->ia,essl->ja,&essl->lna,xx,essl->aux,&essl->naux);
83e8aa55a4SKris Buschelman   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
84e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
85e8aa55a4SKris Buschelman }
86e8aa55a4SKris Buschelman 
87e8aa55a4SKris Buschelman #undef __FUNCT__
88f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Essl"
89f0c56d0fSKris Buschelman int MatLUFactorNumeric_Essl(Mat A,Mat *F) {
90e8aa55a4SKris Buschelman   Mat_SeqAIJ *aa=(Mat_SeqAIJ*)(A)->data;
91f0c56d0fSKris Buschelman   Mat_Essl   *essl=(Mat_Essl*)(*F)->spptr;
92e8aa55a4SKris Buschelman   int        i,ierr,one = 1;
93e8aa55a4SKris Buschelman 
94e8aa55a4SKris Buschelman   PetscFunctionBegin;
95e8aa55a4SKris Buschelman   /* copy matrix data into silly ESSL data structure (1-based Frotran style) */
96e8aa55a4SKris Buschelman   for (i=0; i<A->m+1; i++) essl->ia[i] = aa->i[i] + 1;
97e8aa55a4SKris Buschelman   for (i=0; i<aa->nz; i++) essl->ja[i]  = aa->j[i] + 1;
98e8aa55a4SKris Buschelman 
99e8aa55a4SKris Buschelman   ierr = PetscMemcpy(essl->a,aa->a,(aa->nz)*sizeof(PetscScalar));CHKERRQ(ierr);
100e8aa55a4SKris Buschelman 
101e8aa55a4SKris Buschelman   /* set Essl options */
102e8aa55a4SKris Buschelman   essl->iparm[0] = 1;
103e8aa55a4SKris Buschelman   essl->iparm[1] = 5;
104e8aa55a4SKris Buschelman   essl->iparm[2] = 1;
105e8aa55a4SKris Buschelman   essl->iparm[3] = 0;
106e8aa55a4SKris Buschelman   essl->rparm[0] = 1.e-12;
107e8aa55a4SKris Buschelman   essl->rparm[1] = A->lupivotthreshold;
108e8aa55a4SKris Buschelman 
109e8aa55a4SKris Buschelman   dgsf(&one,&A->m,&essl->nz,essl->a,essl->ia,essl->ja,&essl->lna,essl->iparm,
110e8aa55a4SKris Buschelman                essl->rparm,essl->oparm,essl->aux,&essl->naux);
111e8aa55a4SKris Buschelman 
112e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
113e8aa55a4SKris Buschelman }
114e8aa55a4SKris Buschelman 
115e8aa55a4SKris Buschelman #undef __FUNCT__
116f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Essl"
117f0c56d0fSKris Buschelman int MatLUFactorSymbolic_Essl(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) {
118e8aa55a4SKris Buschelman   Mat        B;
119eef49c96SKris Buschelman   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
120eef49c96SKris Buschelman   int        ierr,len;
121f0c56d0fSKris Buschelman   Mat_Essl   *essl;
122e8aa55a4SKris Buschelman   PetscReal  f = 1.0;
123e8aa55a4SKris Buschelman 
124e8aa55a4SKris Buschelman   PetscFunctionBegin;
125e8aa55a4SKris Buschelman   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
126e8aa55a4SKris Buschelman   ierr = MatCreate(A->comm,PETSC_DECIDE,PETSC_DECIDE,A->m,A->n,&B);CHKERRQ(ierr);
127e8aa55a4SKris Buschelman   ierr = MatSetType(B,MATESSL);CHKERRQ(ierr);
128e8aa55a4SKris Buschelman   ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
129e8aa55a4SKris Buschelman 
130f0c56d0fSKris Buschelman   B->ops->solve           = MatSolve_Essl;
131f0c56d0fSKris Buschelman   B->ops->lufactornumeric = MatLUFactorNumeric_Essl;
132e8aa55a4SKris Buschelman   B->factor               = FACTOR_LU;
133e8aa55a4SKris Buschelman 
134f0c56d0fSKris Buschelman   essl = (Mat_Essl *)(B->spptr);
135e8aa55a4SKris Buschelman 
136e8aa55a4SKris Buschelman   /* allocate the work arrays required by ESSL */
137e8aa55a4SKris Buschelman   f = info->fill;
138e8aa55a4SKris Buschelman   essl->nz   = a->nz;
139e8aa55a4SKris Buschelman   essl->lna  = (int)a->nz*f;
140e8aa55a4SKris Buschelman   essl->naux = 100 + 10*A->m;
141e8aa55a4SKris Buschelman 
142e8aa55a4SKris Buschelman   /* since malloc is slow on IBM we try a single malloc */
143e8aa55a4SKris Buschelman   len               = essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar);
144e8aa55a4SKris Buschelman   ierr              = PetscMalloc(len,&essl->a);CHKERRQ(ierr);
145e8aa55a4SKris Buschelman   essl->aux         = essl->a + essl->lna;
146e8aa55a4SKris Buschelman   essl->ia          = (int*)(essl->aux + essl->naux);
147e8aa55a4SKris Buschelman   essl->ja          = essl->ia + essl->lna;
1482f71e704SKris Buschelman   essl->CleanUpESSL = PETSC_TRUE;
149e8aa55a4SKris Buschelman 
150f0c56d0fSKris Buschelman   PetscLogObjectMemory(B,len+sizeof(Mat_Essl));
151e8aa55a4SKris Buschelman   *F = B;
152e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
153e8aa55a4SKris Buschelman }
154e8aa55a4SKris Buschelman 
1552f71e704SKris Buschelman #undef __FUNCT__
156f0c56d0fSKris Buschelman #define __FUNCT__ "MatAssemblyEnd_Essl"
157f0c56d0fSKris Buschelman int MatAssemblyEnd_Essl(Mat A,MatAssemblyType mode) {
1582f71e704SKris Buschelman   int      ierr;
159f0c56d0fSKris Buschelman   Mat_Essl *essl=(Mat_Essl*)(A->spptr);
1602f71e704SKris Buschelman 
1612f71e704SKris Buschelman   PetscFunctionBegin;
1622f71e704SKris Buschelman   ierr = (*essl->MatAssemblyEnd)(A,mode);CHKERRQ(ierr);
1632f71e704SKris Buschelman 
1642f71e704SKris Buschelman   essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic;
165f0c56d0fSKris Buschelman   A->ops->lufactorsymbolic  = MatLUFactorSymbolic_Essl;
166f0c56d0fSKris Buschelman   PetscLogInfo(0,"Using ESSL for LU factorization and solves");
1672f71e704SKris Buschelman   PetscFunctionReturn(0);
1682f71e704SKris Buschelman }
1692f71e704SKris Buschelman 
170460c4903SKris Buschelman EXTERN_C_BEGIN
171e8aa55a4SKris Buschelman #undef __FUNCT__
172460c4903SKris Buschelman #define __FUNCT__ "MatConvert_SeqAIJ_Essl"
173460c4903SKris Buschelman int MatConvert_SeqAIJ_Essl(Mat A,MatType type,Mat *newmat) {
174460c4903SKris Buschelman   Mat      B=*newmat;
175460c4903SKris Buschelman   int      ierr;
176f0c56d0fSKris Buschelman   Mat_Essl *essl;
177460c4903SKris Buschelman 
178e8aa55a4SKris Buschelman   PetscFunctionBegin;
179460c4903SKris Buschelman 
180460c4903SKris Buschelman   if (B != A) {
181460c4903SKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
182460c4903SKris Buschelman   }
183460c4903SKris Buschelman 
184f0c56d0fSKris Buschelman   ierr                      = PetscNew(Mat_Essl,&essl);CHKERRQ(ierr);
185f0c56d0fSKris Buschelman   essl->MatDuplicate        = A->ops->duplicate;
186460c4903SKris Buschelman   essl->MatAssemblyEnd      = A->ops->assemblyend;
187460c4903SKris Buschelman   essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic;
188460c4903SKris Buschelman   essl->MatDestroy          = A->ops->destroy;
1892f71e704SKris Buschelman   essl->CleanUpESSL         = PETSC_FALSE;
190460c4903SKris Buschelman 
1912f71e704SKris Buschelman   B->spptr                  = (void *)essl;
192f0c56d0fSKris Buschelman   B->ops->duplicate         = MatDuplicate_Essl;
193f0c56d0fSKris Buschelman   B->ops->assemblyend       = MatAssemblyEnd_Essl;
194f0c56d0fSKris Buschelman   B->ops->lufactorsymbolic  = MatLUFactorSymbolic_Essl;
195f0c56d0fSKris Buschelman   B->ops->destroy           = MatDestroy_Essl;
196460c4903SKris Buschelman 
197460c4903SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_essl_C",
198460c4903SKris Buschelman                                            "MatConvert_SeqAIJ_Essl",MatConvert_SeqAIJ_Essl);CHKERRQ(ierr);
199460c4903SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_essl_seqaij_C",
200460c4903SKris Buschelman                                            "MatConvert_Essl_SeqAIJ",MatConvert_Essl_SeqAIJ);CHKERRQ(ierr);
201460c4903SKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,type);CHKERRQ(ierr);
202460c4903SKris Buschelman   *newmat = B;
203e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
204e8aa55a4SKris Buschelman }
205460c4903SKris Buschelman EXTERN_C_END
206e8aa55a4SKris Buschelman 
207f0c56d0fSKris Buschelman #undef __FUNCT__
208f0c56d0fSKris Buschelman #define __FUNCT__ "MatDuplicate_Essl"
209f0c56d0fSKris Buschelman int MatDuplicate_Essl(Mat A, MatDuplicateOption op, Mat *M) {
210f0c56d0fSKris Buschelman   int ierr;
211f0c56d0fSKris Buschelman   PetscFunctionBegin;
212f0c56d0fSKris Buschelman   ierr = (*A->ops->duplicate)(A,op,M);CHKERRQ(ierr);
213f0c56d0fSKris Buschelman   ierr = MatConvert_SeqAIJ_Essl(*M,MATESSL,M);CHKERRQ(ierr);
214f0c56d0fSKris Buschelman   PetscFunctionReturn(0);
215f0c56d0fSKris Buschelman }
216f0c56d0fSKris Buschelman 
2172f71e704SKris Buschelman /*MC
2182f71e704SKris Buschelman   MATESSL - a matrix type providing direct solvers (LU) for sequential matrices
2192f71e704SKris Buschelman   via the external package ESSL.
2202f71e704SKris Buschelman 
2212f71e704SKris Buschelman   If ESSL is installed (see the manual for
2222f71e704SKris Buschelman   instructions on how to declare the existence of external packages),
2232f71e704SKris Buschelman   a matrix type can be constructed which invokes ESSL solvers.
2242f71e704SKris Buschelman   After calling MatCreate(...,A), simply call MatSetType(A,MATESSL).
2252f71e704SKris Buschelman   This matrix type is only supported for double precision real.
2262f71e704SKris Buschelman 
2272f71e704SKris Buschelman   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
2282f71e704SKris Buschelman   supported for this matrix type.
2292f71e704SKris Buschelman 
2302f71e704SKris Buschelman   Options Database Keys:
2312f71e704SKris Buschelman . -mat_type essl - sets the matrix type to essl during a call to MatSetFromOptions()
2322f71e704SKris Buschelman 
2332f71e704SKris Buschelman    Level: beginner
2342f71e704SKris Buschelman 
2352f71e704SKris Buschelman .seealso: PCLU
2362f71e704SKris Buschelman M*/
2372f71e704SKris Buschelman 
238e8aa55a4SKris Buschelman EXTERN_C_BEGIN
239e8aa55a4SKris Buschelman #undef __FUNCT__
240f0c56d0fSKris Buschelman #define __FUNCT__ "MatCreate_Essl"
241f0c56d0fSKris Buschelman int MatCreate_Essl(Mat A) {
242e8aa55a4SKris Buschelman   int ierr;
243e8aa55a4SKris Buschelman 
244e8aa55a4SKris Buschelman   PetscFunctionBegin;
245*5441df8eSKris Buschelman   /* Change type name before calling MatSetType to force proper construction of SeqAIJ and Essl types */
246*5441df8eSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)A,MATESSL);CHKERRQ(ierr);
247e8aa55a4SKris Buschelman   ierr = MatSetType(A,MATSEQAIJ);
248460c4903SKris Buschelman   ierr = MatConvert_SeqAIJ_Essl(A,MATESSL,&A);CHKERRQ(ierr);
249e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
250e8aa55a4SKris Buschelman }
2514eb8e494SKris Buschelman EXTERN_C_END
252