1 2 /* 3 Provides an interface to the IBM RS6000 Essl sparse solver 4 5 */ 6 #include "src/mat/impls/aij/seq/aij.h" 7 /* #include <essl.h> This doesn't work! */ 8 9 typedef struct { 10 int n,nz; 11 PetscScalar *a; 12 int *ia; 13 int *ja; 14 int lna; 15 int iparm[5]; 16 PetscReal rparm[5]; 17 PetscReal oparm[5]; 18 PetscScalar *aux; 19 int naux; 20 21 PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*); 22 PetscErrorCode (*MatAssemblyEnd)(Mat,MatAssemblyType); 23 PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*); 24 PetscErrorCode (*MatDestroy)(Mat); 25 PetscTruth CleanUpESSL; 26 } Mat_Essl; 27 28 EXTERN PetscErrorCode MatDuplicate_Essl(Mat,MatDuplicateOption,Mat*); 29 30 EXTERN_C_BEGIN 31 #undef __FUNCT__ 32 #define __FUNCT__ "MatConvert_Essl_SeqAIJ" 33 PetscErrorCode MatConvert_Essl_SeqAIJ(Mat A,const MatType type,Mat *newmat) { 34 PetscErrorCode ierr; 35 Mat B=*newmat; 36 Mat_Essl *essl=(Mat_Essl*)A->spptr; 37 38 PetscFunctionBegin; 39 if (B != A) { 40 ierr = MatDuplicate(A,MAT_COPY_VALUES,&B); 41 } 42 B->ops->duplicate = essl->MatDuplicate; 43 B->ops->assemblyend = essl->MatAssemblyEnd; 44 B->ops->lufactorsymbolic = essl->MatLUFactorSymbolic; 45 B->ops->destroy = essl->MatDestroy; 46 47 /* free the Essl datastructures */ 48 ierr = PetscFree(essl);CHKERRQ(ierr); 49 ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 50 *newmat = B; 51 PetscFunctionReturn(0); 52 } 53 EXTERN_C_END 54 55 #undef __FUNCT__ 56 #define __FUNCT__ "MatDestroy_Essl" 57 PetscErrorCode MatDestroy_Essl(Mat A) 58 { 59 PetscErrorCode ierr; 60 Mat_Essl *essl=(Mat_Essl*)A->spptr; 61 62 PetscFunctionBegin; 63 if (essl->CleanUpESSL) { 64 ierr = PetscFree(essl->a);CHKERRQ(ierr); 65 } 66 ierr = MatConvert_Essl_SeqAIJ(A,MATSEQAIJ,&A); 67 ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 68 PetscFunctionReturn(0); 69 } 70 71 #undef __FUNCT__ 72 #define __FUNCT__ "MatSolve_Essl" 73 PetscErrorCode MatSolve_Essl(Mat A,Vec b,Vec x) { 74 Mat_Essl *essl = (Mat_Essl*)A->spptr; 75 PetscScalar *xx; 76 PetscErrorCode ierr; 77 int m,zero = 0; 78 79 PetscFunctionBegin; 80 ierr = VecGetLocalSize(b,&m);CHKERRQ(ierr); 81 ierr = VecCopy(b,x);CHKERRQ(ierr); 82 ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 83 dgss(&zero,&A->n,essl->a,essl->ia,essl->ja,&essl->lna,xx,essl->aux,&essl->naux); 84 ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 85 PetscFunctionReturn(0); 86 } 87 88 #undef __FUNCT__ 89 #define __FUNCT__ "MatLUFactorNumeric_Essl" 90 PetscErrorCode MatLUFactorNumeric_Essl(Mat A,Mat *F) { 91 Mat_SeqAIJ *aa=(Mat_SeqAIJ*)(A)->data; 92 Mat_Essl *essl=(Mat_Essl*)(*F)->spptr; 93 PetscErrorCode ierr; 94 int i,one = 1; 95 96 PetscFunctionBegin; 97 /* copy matrix data into silly ESSL data structure (1-based Frotran style) */ 98 for (i=0; i<A->m+1; i++) essl->ia[i] = aa->i[i] + 1; 99 for (i=0; i<aa->nz; i++) essl->ja[i] = aa->j[i] + 1; 100 101 ierr = PetscMemcpy(essl->a,aa->a,(aa->nz)*sizeof(PetscScalar));CHKERRQ(ierr); 102 103 /* set Essl options */ 104 essl->iparm[0] = 1; 105 essl->iparm[1] = 5; 106 essl->iparm[2] = 1; 107 essl->iparm[3] = 0; 108 essl->rparm[0] = 1.e-12; 109 essl->rparm[1] = A->lupivotthreshold; 110 111 dgsf(&one,&A->m,&essl->nz,essl->a,essl->ia,essl->ja,&essl->lna,essl->iparm, 112 essl->rparm,essl->oparm,essl->aux,&essl->naux); 113 114 PetscFunctionReturn(0); 115 } 116 117 #undef __FUNCT__ 118 #define __FUNCT__ "MatLUFactorSymbolic_Essl" 119 PetscErrorCode MatLUFactorSymbolic_Essl(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) { 120 Mat B; 121 Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 122 PetscErrorCode ierr; 123 int len; 124 Mat_Essl *essl; 125 PetscReal f = 1.0; 126 127 PetscFunctionBegin; 128 if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 129 ierr = MatCreate(A->comm,PETSC_DECIDE,PETSC_DECIDE,A->m,A->n,&B);CHKERRQ(ierr); 130 ierr = MatSetType(B,A->type_name);CHKERRQ(ierr); 131 ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 132 133 B->ops->solve = MatSolve_Essl; 134 B->ops->lufactornumeric = MatLUFactorNumeric_Essl; 135 B->factor = FACTOR_LU; 136 137 essl = (Mat_Essl *)(B->spptr); 138 139 /* allocate the work arrays required by ESSL */ 140 f = info->fill; 141 essl->nz = a->nz; 142 essl->lna = (int)a->nz*f; 143 essl->naux = 100 + 10*A->m; 144 145 /* since malloc is slow on IBM we try a single malloc */ 146 len = essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar); 147 ierr = PetscMalloc(len,&essl->a);CHKERRQ(ierr); 148 essl->aux = essl->a + essl->lna; 149 essl->ia = (int*)(essl->aux + essl->naux); 150 essl->ja = essl->ia + essl->lna; 151 essl->CleanUpESSL = PETSC_TRUE; 152 153 PetscLogObjectMemory(B,len+sizeof(Mat_Essl)); 154 *F = B; 155 PetscFunctionReturn(0); 156 } 157 158 #undef __FUNCT__ 159 #define __FUNCT__ "MatAssemblyEnd_Essl" 160 PetscErrorCode MatAssemblyEnd_Essl(Mat A,MatAssemblyType mode) { 161 PetscErrorCode ierr; 162 Mat_Essl *essl=(Mat_Essl*)(A->spptr); 163 164 PetscFunctionBegin; 165 ierr = (*essl->MatAssemblyEnd)(A,mode);CHKERRQ(ierr); 166 167 essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 168 A->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 169 PetscLogInfo(0,"Using ESSL for LU factorization and solves"); 170 PetscFunctionReturn(0); 171 } 172 173 EXTERN_C_BEGIN 174 #undef __FUNCT__ 175 #define __FUNCT__ "MatConvert_SeqAIJ_Essl" 176 PetscErrorCode MatConvert_SeqAIJ_Essl(Mat A,const MatType type,Mat *newmat) { 177 Mat B=*newmat; 178 PetscErrorCode ierr; 179 Mat_Essl *essl; 180 181 PetscFunctionBegin; 182 183 if (B != A) { 184 ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 185 } 186 187 ierr = PetscNew(Mat_Essl,&essl);CHKERRQ(ierr); 188 essl->MatDuplicate = A->ops->duplicate; 189 essl->MatAssemblyEnd = A->ops->assemblyend; 190 essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 191 essl->MatDestroy = A->ops->destroy; 192 essl->CleanUpESSL = PETSC_FALSE; 193 194 B->spptr = (void*)essl; 195 B->ops->duplicate = MatDuplicate_Essl; 196 B->ops->assemblyend = MatAssemblyEnd_Essl; 197 B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 198 B->ops->destroy = MatDestroy_Essl; 199 200 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_essl_C", 201 "MatConvert_SeqAIJ_Essl",MatConvert_SeqAIJ_Essl);CHKERRQ(ierr); 202 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_essl_seqaij_C", 203 "MatConvert_Essl_SeqAIJ",MatConvert_Essl_SeqAIJ);CHKERRQ(ierr); 204 ierr = PetscObjectChangeTypeName((PetscObject)B,type);CHKERRQ(ierr); 205 *newmat = B; 206 PetscFunctionReturn(0); 207 } 208 EXTERN_C_END 209 210 #undef __FUNCT__ 211 #define __FUNCT__ "MatDuplicate_Essl" 212 PetscErrorCode MatDuplicate_Essl(Mat A, MatDuplicateOption op, Mat *M) { 213 PetscErrorCode ierr; 214 Mat_Essl *lu = (Mat_Essl *)A->spptr; 215 216 PetscFunctionBegin; 217 ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr); 218 ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Essl));CHKERRQ(ierr); 219 PetscFunctionReturn(0); 220 } 221 222 /*MC 223 MATESSL - MATESSL = "essl" - A matrix type providing direct solvers (LU) for sequential matrices 224 via the external package ESSL. 225 226 If ESSL is installed (see the manual for 227 instructions on how to declare the existence of external packages), 228 a matrix type can be constructed which invokes ESSL solvers. 229 After calling MatCreate(...,A), simply call MatSetType(A,MATESSL). 230 This matrix type is only supported for double precision real. 231 232 This matrix inherits from MATSEQAIJ. As a result, MatSeqAIJSetPreallocation is 233 supported for this matrix type. One can also call MatConvert for an inplace conversion to or from 234 the MATSEQAIJ type without data copy. 235 236 Options Database Keys: 237 . -mat_type essl - sets the matrix type to "essl" during a call to MatSetFromOptions() 238 239 Level: beginner 240 241 .seealso: PCLU 242 M*/ 243 244 EXTERN_C_BEGIN 245 #undef __FUNCT__ 246 #define __FUNCT__ "MatCreate_Essl" 247 PetscErrorCode MatCreate_Essl(Mat A) 248 { 249 PetscErrorCode ierr; 250 251 PetscFunctionBegin; 252 /* Change type name before calling MatSetType to force proper construction of SeqAIJ and Essl types */ 253 ierr = PetscObjectChangeTypeName((PetscObject)A,MATESSL);CHKERRQ(ierr); 254 ierr = MatSetType(A,MATSEQAIJ); 255 ierr = MatConvert_SeqAIJ_Essl(A,MATESSL,&A);CHKERRQ(ierr); 256 PetscFunctionReturn(0); 257 } 258 EXTERN_C_END 259