xref: /petsc/src/mat/impls/aij/seq/essl/essl.c (revision be5d1d56a128fdbca06f8d9818f1d611ccde2ba2)
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"
348e9aea5cSBarry Smith int MatConvert_Essl_SeqAIJ(Mat A,const 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);
127*be5d1d56SKris Buschelman   ierr = MatSetType(B,A->type_name);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"
1738e9aea5cSBarry Smith int MatConvert_SeqAIJ_Essl(Mat A,const 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;
21113ee22deSSatish Balay   Mat_Essl *lu = (Mat_Essl *)A->spptr;
2128f340917SKris Buschelman 
213f0c56d0fSKris Buschelman   PetscFunctionBegin;
2148f340917SKris Buschelman   ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr);
215f0c56d0fSKris Buschelman   ierr = MatConvert_SeqAIJ_Essl(*M,MATESSL,M);CHKERRQ(ierr);
2163f953163SKris Buschelman   ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Essl));CHKERRQ(ierr);
217f0c56d0fSKris Buschelman   PetscFunctionReturn(0);
218f0c56d0fSKris Buschelman }
219f0c56d0fSKris Buschelman 
2202f71e704SKris Buschelman /*MC
221fafad747SKris Buschelman   MATESSL - MATESSL = "essl" - A matrix type providing direct solvers (LU) for sequential matrices
2222f71e704SKris Buschelman   via the external package ESSL.
2232f71e704SKris Buschelman 
2242f71e704SKris Buschelman   If ESSL is installed (see the manual for
2252f71e704SKris Buschelman   instructions on how to declare the existence of external packages),
2262f71e704SKris Buschelman   a matrix type can be constructed which invokes ESSL solvers.
2272f71e704SKris Buschelman   After calling MatCreate(...,A), simply call MatSetType(A,MATESSL).
2282f71e704SKris Buschelman   This matrix type is only supported for double precision real.
2292f71e704SKris Buschelman 
2302f71e704SKris Buschelman   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
23128b08bd3SKris Buschelman   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
23228b08bd3SKris Buschelman   the MATSEQAIJ type without data copy.
2332f71e704SKris Buschelman 
2342f71e704SKris Buschelman   Options Database Keys:
2350bad9183SKris Buschelman . -mat_type essl - sets the matrix type to "essl" during a call to MatSetFromOptions()
2362f71e704SKris Buschelman 
2372f71e704SKris Buschelman    Level: beginner
2382f71e704SKris Buschelman 
2392f71e704SKris Buschelman .seealso: PCLU
2402f71e704SKris Buschelman M*/
2412f71e704SKris Buschelman 
242e8aa55a4SKris Buschelman EXTERN_C_BEGIN
243e8aa55a4SKris Buschelman #undef __FUNCT__
244f0c56d0fSKris Buschelman #define __FUNCT__ "MatCreate_Essl"
245f0c56d0fSKris Buschelman int MatCreate_Essl(Mat A) {
246e8aa55a4SKris Buschelman   int ierr;
247e8aa55a4SKris Buschelman 
248e8aa55a4SKris Buschelman   PetscFunctionBegin;
2495441df8eSKris Buschelman   /* Change type name before calling MatSetType to force proper construction of SeqAIJ and Essl types */
2505441df8eSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)A,MATESSL);CHKERRQ(ierr);
251e8aa55a4SKris Buschelman   ierr = MatSetType(A,MATSEQAIJ);
252460c4903SKris Buschelman   ierr = MatConvert_SeqAIJ_Essl(A,MATESSL,&A);CHKERRQ(ierr);
253e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
254e8aa55a4SKris Buschelman }
2554eb8e494SKris Buschelman EXTERN_C_END
256