xref: /petsc/src/mat/impls/aij/seq/essl/essl.c (revision 52e6d16ba989af9362d0fcebb12e73dd7c9666ed)
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 
216849ba73SBarry Smith   PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*);
226849ba73SBarry Smith   PetscErrorCode (*MatAssemblyEnd)(Mat,MatAssemblyType);
236849ba73SBarry Smith   PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*);
246849ba73SBarry 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);
49901853e0SKris Buschelman 
50901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_essl_C","",PETSC_NULL);CHKERRQ(ierr);
51901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_essl_seqaij_C","",PETSC_NULL);CHKERRQ(ierr);
52901853e0SKris Buschelman 
53460c4903SKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
54460c4903SKris Buschelman   *newmat = B;
55460c4903SKris Buschelman   PetscFunctionReturn(0);
56460c4903SKris Buschelman }
57460c4903SKris Buschelman EXTERN_C_END
58460c4903SKris Buschelman 
59e8aa55a4SKris Buschelman #undef __FUNCT__
60f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_Essl"
61dfbe8321SBarry Smith PetscErrorCode MatDestroy_Essl(Mat A)
62dfbe8321SBarry Smith {
63dfbe8321SBarry Smith   PetscErrorCode ierr;
64f0c56d0fSKris Buschelman   Mat_Essl *essl=(Mat_Essl*)A->spptr;
65e8aa55a4SKris Buschelman 
66e8aa55a4SKris Buschelman   PetscFunctionBegin;
672f71e704SKris Buschelman   if (essl->CleanUpESSL) {
682f71e704SKris Buschelman     ierr = PetscFree(essl->a);CHKERRQ(ierr);
69e8aa55a4SKris Buschelman   }
702f71e704SKris Buschelman   ierr = MatConvert_Essl_SeqAIJ(A,MATSEQAIJ,&A);
712f71e704SKris Buschelman   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
72460c4903SKris Buschelman   PetscFunctionReturn(0);
73460c4903SKris Buschelman }
74460c4903SKris Buschelman 
75460c4903SKris Buschelman #undef __FUNCT__
76f0c56d0fSKris Buschelman #define __FUNCT__ "MatSolve_Essl"
77dfbe8321SBarry Smith PetscErrorCode MatSolve_Essl(Mat A,Vec b,Vec x) {
78f0c56d0fSKris Buschelman   Mat_Essl    *essl = (Mat_Essl*)A->spptr;
79e8aa55a4SKris Buschelman   PetscScalar *xx;
80dfbe8321SBarry Smith   PetscErrorCode ierr;
81dfbe8321SBarry Smith   int         m,zero = 0;
82e8aa55a4SKris Buschelman 
83e8aa55a4SKris Buschelman   PetscFunctionBegin;
84e8aa55a4SKris Buschelman   ierr = VecGetLocalSize(b,&m);CHKERRQ(ierr);
85e8aa55a4SKris Buschelman   ierr = VecCopy(b,x);CHKERRQ(ierr);
86e8aa55a4SKris Buschelman   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
87e8aa55a4SKris Buschelman   dgss(&zero,&A->n,essl->a,essl->ia,essl->ja,&essl->lna,xx,essl->aux,&essl->naux);
88e8aa55a4SKris Buschelman   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
89e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
90e8aa55a4SKris Buschelman }
91e8aa55a4SKris Buschelman 
92e8aa55a4SKris Buschelman #undef __FUNCT__
93f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Essl"
94af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_Essl(Mat A,MatFactorInfo *info,Mat *F) {
95e8aa55a4SKris Buschelman   Mat_SeqAIJ     *aa=(Mat_SeqAIJ*)(A)->data;
96f0c56d0fSKris Buschelman   Mat_Essl       *essl=(Mat_Essl*)(*F)->spptr;
976849ba73SBarry Smith   PetscErrorCode ierr;
986849ba73SBarry Smith   int            i,one = 1;
99e8aa55a4SKris Buschelman 
100e8aa55a4SKris Buschelman   PetscFunctionBegin;
101e8aa55a4SKris Buschelman   /* copy matrix data into silly ESSL data structure (1-based Frotran style) */
102e8aa55a4SKris Buschelman   for (i=0; i<A->m+1; i++) essl->ia[i] = aa->i[i] + 1;
103e8aa55a4SKris Buschelman   for (i=0; i<aa->nz; i++) essl->ja[i]  = aa->j[i] + 1;
104e8aa55a4SKris Buschelman 
105e8aa55a4SKris Buschelman   ierr = PetscMemcpy(essl->a,aa->a,(aa->nz)*sizeof(PetscScalar));CHKERRQ(ierr);
106e8aa55a4SKris Buschelman 
107e8aa55a4SKris Buschelman   /* set Essl options */
108e8aa55a4SKris Buschelman   essl->iparm[0] = 1;
109e8aa55a4SKris Buschelman   essl->iparm[1] = 5;
110e8aa55a4SKris Buschelman   essl->iparm[2] = 1;
111e8aa55a4SKris Buschelman   essl->iparm[3] = 0;
112e8aa55a4SKris Buschelman   essl->rparm[0] = 1.e-12;
113e8aa55a4SKris Buschelman   essl->rparm[1] = A->lupivotthreshold;
114e8aa55a4SKris Buschelman 
115e8aa55a4SKris Buschelman   dgsf(&one,&A->m,&essl->nz,essl->a,essl->ia,essl->ja,&essl->lna,essl->iparm,
116e8aa55a4SKris Buschelman                essl->rparm,essl->oparm,essl->aux,&essl->naux);
117e8aa55a4SKris Buschelman 
118e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
119e8aa55a4SKris Buschelman }
120e8aa55a4SKris Buschelman 
121e8aa55a4SKris Buschelman #undef __FUNCT__
122f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Essl"
123dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Essl(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) {
124e8aa55a4SKris Buschelman   Mat        B;
125eef49c96SKris Buschelman   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
126dfbe8321SBarry Smith   PetscErrorCode ierr;
127dfbe8321SBarry Smith   int        len;
128f0c56d0fSKris Buschelman   Mat_Essl   *essl;
129e8aa55a4SKris Buschelman   PetscReal  f = 1.0;
130e8aa55a4SKris Buschelman 
131e8aa55a4SKris Buschelman   PetscFunctionBegin;
132e8aa55a4SKris Buschelman   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
133e8aa55a4SKris Buschelman   ierr = MatCreate(A->comm,PETSC_DECIDE,PETSC_DECIDE,A->m,A->n,&B);CHKERRQ(ierr);
134be5d1d56SKris Buschelman   ierr = MatSetType(B,A->type_name);CHKERRQ(ierr);
135e8aa55a4SKris Buschelman   ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
136e8aa55a4SKris Buschelman 
137f0c56d0fSKris Buschelman   B->ops->solve           = MatSolve_Essl;
138f0c56d0fSKris Buschelman   B->ops->lufactornumeric = MatLUFactorNumeric_Essl;
139e8aa55a4SKris Buschelman   B->factor               = FACTOR_LU;
140e8aa55a4SKris Buschelman 
141f0c56d0fSKris Buschelman   essl = (Mat_Essl *)(B->spptr);
142e8aa55a4SKris Buschelman 
143e8aa55a4SKris Buschelman   /* allocate the work arrays required by ESSL */
144e8aa55a4SKris Buschelman   f = info->fill;
145e8aa55a4SKris Buschelman   essl->nz   = a->nz;
146e8aa55a4SKris Buschelman   essl->lna  = (int)a->nz*f;
147e8aa55a4SKris Buschelman   essl->naux = 100 + 10*A->m;
148e8aa55a4SKris Buschelman 
149e8aa55a4SKris Buschelman   /* since malloc is slow on IBM we try a single malloc */
150e8aa55a4SKris Buschelman   len               = essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar);
151e8aa55a4SKris Buschelman   ierr              = PetscMalloc(len,&essl->a);CHKERRQ(ierr);
152e8aa55a4SKris Buschelman   essl->aux         = essl->a + essl->lna;
153e8aa55a4SKris Buschelman   essl->ia          = (int*)(essl->aux + essl->naux);
154e8aa55a4SKris Buschelman   essl->ja          = essl->ia + essl->lna;
1552f71e704SKris Buschelman   essl->CleanUpESSL = PETSC_TRUE;
156e8aa55a4SKris Buschelman 
157*52e6d16bSBarry Smith   ierr = PetscLogObjectMemory(B,len+sizeof(Mat_Essl));CHKERRQ(ierr);
158e8aa55a4SKris Buschelman   *F = B;
159e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
160e8aa55a4SKris Buschelman }
161e8aa55a4SKris Buschelman 
1622f71e704SKris Buschelman #undef __FUNCT__
163f0c56d0fSKris Buschelman #define __FUNCT__ "MatAssemblyEnd_Essl"
164dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_Essl(Mat A,MatAssemblyType mode) {
165dfbe8321SBarry Smith   PetscErrorCode ierr;
166f0c56d0fSKris Buschelman   Mat_Essl *essl=(Mat_Essl*)(A->spptr);
1672f71e704SKris Buschelman 
1682f71e704SKris Buschelman   PetscFunctionBegin;
1692f71e704SKris Buschelman   ierr = (*essl->MatAssemblyEnd)(A,mode);CHKERRQ(ierr);
1702f71e704SKris Buschelman 
1712f71e704SKris Buschelman   essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic;
172f0c56d0fSKris Buschelman   A->ops->lufactorsymbolic  = MatLUFactorSymbolic_Essl;
173*52e6d16bSBarry Smith   PetscLogInfo(0,"MatAssemblyEnd_Essl:Using ESSL for LU factorization and solves");
1742f71e704SKris Buschelman   PetscFunctionReturn(0);
1752f71e704SKris Buschelman }
1762f71e704SKris Buschelman 
177460c4903SKris Buschelman EXTERN_C_BEGIN
178e8aa55a4SKris Buschelman #undef __FUNCT__
179460c4903SKris Buschelman #define __FUNCT__ "MatConvert_SeqAIJ_Essl"
180521d7252SBarry Smith PetscErrorCode MatConvert_SeqAIJ_Essl(Mat A,const MatType type,Mat *newmat)
181521d7252SBarry Smith {
182460c4903SKris Buschelman   Mat      B=*newmat;
183dfbe8321SBarry Smith   PetscErrorCode ierr;
184f0c56d0fSKris Buschelman   Mat_Essl *essl;
185460c4903SKris Buschelman 
186e8aa55a4SKris Buschelman   PetscFunctionBegin;
187460c4903SKris Buschelman   if (B != A) {
188460c4903SKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
189460c4903SKris Buschelman   }
190460c4903SKris Buschelman 
191f0c56d0fSKris Buschelman   ierr                      = PetscNew(Mat_Essl,&essl);CHKERRQ(ierr);
192f0c56d0fSKris Buschelman   essl->MatDuplicate        = A->ops->duplicate;
193460c4903SKris Buschelman   essl->MatAssemblyEnd      = A->ops->assemblyend;
194460c4903SKris Buschelman   essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic;
195460c4903SKris Buschelman   essl->MatDestroy          = A->ops->destroy;
1962f71e704SKris Buschelman   essl->CleanUpESSL         = PETSC_FALSE;
197460c4903SKris Buschelman 
1982f71e704SKris Buschelman   B->spptr                  = (void*)essl;
199f0c56d0fSKris Buschelman   B->ops->duplicate         = MatDuplicate_Essl;
200f0c56d0fSKris Buschelman   B->ops->assemblyend       = MatAssemblyEnd_Essl;
201f0c56d0fSKris Buschelman   B->ops->lufactorsymbolic  = MatLUFactorSymbolic_Essl;
202f0c56d0fSKris Buschelman   B->ops->destroy           = MatDestroy_Essl;
203460c4903SKris Buschelman 
204460c4903SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_essl_C",
205460c4903SKris Buschelman                                            "MatConvert_SeqAIJ_Essl",MatConvert_SeqAIJ_Essl);CHKERRQ(ierr);
206460c4903SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_essl_seqaij_C",
207460c4903SKris Buschelman                                            "MatConvert_Essl_SeqAIJ",MatConvert_Essl_SeqAIJ);CHKERRQ(ierr);
208460c4903SKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,type);CHKERRQ(ierr);
209460c4903SKris Buschelman   *newmat = B;
210e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
211e8aa55a4SKris Buschelman }
212460c4903SKris Buschelman EXTERN_C_END
213e8aa55a4SKris Buschelman 
214f0c56d0fSKris Buschelman #undef __FUNCT__
215f0c56d0fSKris Buschelman #define __FUNCT__ "MatDuplicate_Essl"
216dfbe8321SBarry Smith PetscErrorCode MatDuplicate_Essl(Mat A, MatDuplicateOption op, Mat *M) {
217dfbe8321SBarry Smith   PetscErrorCode ierr;
21813ee22deSSatish Balay   Mat_Essl *lu = (Mat_Essl *)A->spptr;
2198f340917SKris Buschelman 
220f0c56d0fSKris Buschelman   PetscFunctionBegin;
2218f340917SKris Buschelman   ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr);
2223f953163SKris Buschelman   ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Essl));CHKERRQ(ierr);
223f0c56d0fSKris Buschelman   PetscFunctionReturn(0);
224f0c56d0fSKris Buschelman }
225f0c56d0fSKris Buschelman 
2262f71e704SKris Buschelman /*MC
227fafad747SKris Buschelman   MATESSL - MATESSL = "essl" - A matrix type providing direct solvers (LU) for sequential matrices
2282f71e704SKris Buschelman   via the external package ESSL.
2292f71e704SKris Buschelman 
2302f71e704SKris Buschelman   If ESSL is installed (see the manual for
2312f71e704SKris Buschelman   instructions on how to declare the existence of external packages),
2322f71e704SKris Buschelman   a matrix type can be constructed which invokes ESSL solvers.
2332f71e704SKris Buschelman   After calling MatCreate(...,A), simply call MatSetType(A,MATESSL).
2342f71e704SKris Buschelman   This matrix type is only supported for double precision real.
2352f71e704SKris Buschelman 
2362f71e704SKris Buschelman   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
23728b08bd3SKris Buschelman   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
23828b08bd3SKris Buschelman   the MATSEQAIJ type without data copy.
2392f71e704SKris Buschelman 
2402f71e704SKris Buschelman   Options Database Keys:
2410bad9183SKris Buschelman . -mat_type essl - sets the matrix type to "essl" during a call to MatSetFromOptions()
2422f71e704SKris Buschelman 
2432f71e704SKris Buschelman    Level: beginner
2442f71e704SKris Buschelman 
2452f71e704SKris Buschelman .seealso: PCLU
2462f71e704SKris Buschelman M*/
2472f71e704SKris Buschelman 
248e8aa55a4SKris Buschelman EXTERN_C_BEGIN
249e8aa55a4SKris Buschelman #undef __FUNCT__
250f0c56d0fSKris Buschelman #define __FUNCT__ "MatCreate_Essl"
251dfbe8321SBarry Smith PetscErrorCode MatCreate_Essl(Mat A)
252dfbe8321SBarry Smith {
253dfbe8321SBarry Smith   PetscErrorCode ierr;
254e8aa55a4SKris Buschelman 
255e8aa55a4SKris Buschelman   PetscFunctionBegin;
2565441df8eSKris Buschelman   /* Change type name before calling MatSetType to force proper construction of SeqAIJ and Essl types */
2575441df8eSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)A,MATESSL);CHKERRQ(ierr);
258e8aa55a4SKris Buschelman   ierr = MatSetType(A,MATSEQAIJ);
259460c4903SKris Buschelman   ierr = MatConvert_SeqAIJ_Essl(A,MATESSL,&A);CHKERRQ(ierr);
260e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
261e8aa55a4SKris Buschelman }
2624eb8e494SKris Buschelman EXTERN_C_END
263