1 #define PETSCMAT_DLL 2 3 /* 4 Provides an interface for the Matlab engine sparse solver 5 6 */ 7 #include "../src/mat/impls/aij/seq/aij.h" 8 9 #include "engine.h" /* Matlab include file */ 10 #include "mex.h" /* Matlab include file */ 11 12 EXTERN_C_BEGIN 13 #undef __FUNCT__ 14 #define __FUNCT__ "MatSeqAIJToMatlab" 15 mxArray *MatSeqAIJToMatlab(Mat B) 16 { 17 PetscErrorCode ierr; 18 Mat_SeqAIJ *aij = (Mat_SeqAIJ*)B->data; 19 mwIndex i,*ii,*jj; 20 mxArray *mat; 21 22 PetscFunctionBegin; 23 mat = mxCreateSparse(B->cmap->n,B->rmap->n,aij->nz,mxREAL); 24 ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar)); 25 /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 26 jj = mxGetIr(mat); 27 for (i=0; i<aij->nz; i++) jj[i] = aij->j[i]; 28 ii = mxGetJc(mat); 29 for (i=0; i<B->rmap->n+1; i++) ii[i] = aij->i[i]; 30 31 PetscFunctionReturn(mat); 32 } 33 EXTERN_C_END 34 35 36 EXTERN_C_BEGIN 37 #undef __FUNCT__ 38 #define __FUNCT__ "MatlabEnginePut_SeqAIJ" 39 PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject obj,void *mengine) 40 { 41 PetscErrorCode ierr; 42 mxArray *mat; 43 44 PetscFunctionBegin; 45 mat = MatSeqAIJToMatlab((Mat)obj);CHKERRQ(ierr); 46 ierr = PetscObjectName(obj);CHKERRQ(ierr); 47 engPutVariable((Engine *)mengine,obj->name,mat); 48 PetscFunctionReturn(0); 49 } 50 EXTERN_C_END 51 52 EXTERN_C_BEGIN 53 #undef __FUNCT__ 54 #define __FUNCT__ "MatSeqAIJFromMatlab" 55 /*@C 56 MatSeqAIJFromMatlab - Given a Matlab sparse matrix, fills a SeqAIJ matrix with its transpose. 57 58 Not Collective 59 60 Input Parameters: 61 + mmat - a Matlab sparse matris 62 - mat - a already created MATSEQAIJ 63 64 @*/ 65 PetscErrorCode MatSeqAIJFromMatlab(mxArray *mmat,Mat mat) 66 { 67 PetscErrorCode ierr; 68 PetscInt nz,n,m,*i,*j,k; 69 mwIndex nnz,nn,nm,*ii,*jj; 70 Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 71 72 PetscFunctionBegin; 73 nn = mxGetN(mmat); /* rows of transpose of matrix */ 74 nm = mxGetM(mmat); 75 nnz = (mxGetJc(mmat))[nn]; 76 ii = mxGetJc(mmat); 77 jj = mxGetIr(mmat); 78 n = (PetscInt) nn; 79 m = (PetscInt) nm; 80 nz = (PetscInt) nnz; 81 82 if (mat->rmap->n < 0 && mat->cmap->n < 0) { 83 /* matrix has not yet had its size set */ 84 ierr = MatSetSizes(mat,n,m,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 85 ierr = MatPreallocated(mat);CHKERRQ(ierr); 86 } else { 87 if (mat->rmap->n != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot change size of PETSc matrix %D to %D",mat->rmap->n,n); 88 if (mat->cmap->n != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot change size of PETSc matrix %D to %D",mat->cmap->n,m); 89 } 90 ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);CHKERRQ(ierr); 91 92 aij->nz = nz; 93 ierr = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->rmap->n+1,PetscInt,&aij->i);CHKERRQ(ierr); 94 aij->singlemalloc = PETSC_TRUE; 95 96 ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 97 /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 98 i = aij->i; 99 for (k=0; k<n+1; k++) { 100 i[k] = (PetscInt) ii[k]; 101 } 102 j = aij->j; 103 for (k=0; k<nz; k++) { 104 j[k] = (PetscInt) jj[k]; 105 } 106 107 for (k=0; k<mat->rmap->n; k++) { 108 aij->ilen[k] = aij->imax[k] = aij->i[k+1] - aij->i[k]; 109 } 110 111 ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 112 ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 113 PetscFunctionReturn(0); 114 } 115 EXTERN_C_END 116 117 118 EXTERN_C_BEGIN 119 #undef __FUNCT__ 120 #define __FUNCT__ "MatlabEngineGet_SeqAIJ" 121 PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject obj,void *mengine) 122 { 123 PetscErrorCode ierr; 124 Mat mat = (Mat)obj; 125 mxArray *mmat; 126 127 PetscFunctionBegin; 128 mmat = engGetVariable((Engine *)mengine,obj->name); 129 ierr = MatSeqAIJFromMatlab(mmat,mat);CHKERRQ(ierr); 130 PetscFunctionReturn(0); 131 } 132 EXTERN_C_END 133 134 #undef __FUNCT__ 135 #define __FUNCT__ "MatSolve_Matlab" 136 PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x) 137 { 138 PetscErrorCode ierr; 139 const char *_A,*_b,*_x; 140 141 PetscFunctionBegin; 142 /* make sure objects have names; use default if not */ 143 ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr); 144 ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr); 145 146 ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr); 147 ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr); 148 ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr); 149 ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)b);CHKERRQ(ierr); 150 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr); 151 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_b);CHKERRQ(ierr); 152 /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),stdout);CHKERRQ(ierr); */ 153 ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)x);CHKERRQ(ierr); 154 PetscFunctionReturn(0); 155 } 156 157 #undef __FUNCT__ 158 #define __FUNCT__ "MatLUFactorNumeric_Matlab" 159 PetscErrorCode MatLUFactorNumeric_Matlab(Mat F,Mat A,const MatFactorInfo *info) 160 { 161 PetscErrorCode ierr; 162 size_t len; 163 char *_A,*name; 164 PetscReal dtcol = info->dtcol; 165 166 PetscFunctionBegin; 167 if (F->factortype == MAT_FACTOR_ILU || info->dt > 0) { 168 if (info->dtcol == PETSC_DEFAULT) dtcol = .01; 169 F->ops->solve = MatSolve_Matlab; 170 F->factortype = MAT_FACTOR_LU; 171 ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr); 172 _A = ((PetscObject)A)->name; 173 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,dtcol);CHKERRQ(ierr); 174 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"[l_%s,u_%s,p_%s] = luinc(%s',info_%s);",_A,_A,_A,_A,_A);CHKERRQ(ierr); 175 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr); 176 177 ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 178 ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 179 sprintf(name,"_%s",_A); 180 ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr); 181 ierr = PetscFree(name);CHKERRQ(ierr); 182 } else { 183 ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr); 184 _A = ((PetscObject)A)->name; 185 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"[l_%s,u_%s,p_%s] = lu(%s',%g);",_A,_A,_A,_A,dtcol);CHKERRQ(ierr); 186 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr); 187 ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 188 ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 189 sprintf(name,"_%s",_A); 190 ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr); 191 ierr = PetscFree(name);CHKERRQ(ierr); 192 F->ops->solve = MatSolve_Matlab; 193 } 194 PetscFunctionReturn(0); 195 } 196 197 #undef __FUNCT__ 198 #define __FUNCT__ "MatLUFactorSymbolic_Matlab" 199 PetscErrorCode MatLUFactorSymbolic_Matlab(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info) 200 { 201 PetscFunctionBegin; 202 if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square"); 203 F->ops->lufactornumeric = MatLUFactorNumeric_Matlab; 204 F->assembled = PETSC_TRUE; 205 PetscFunctionReturn(0); 206 } 207 208 EXTERN_C_BEGIN 209 #undef __FUNCT__ 210 #define __FUNCT__ "MatFactorGetSolverPackage_seqaij_matlab" 211 PetscErrorCode MatFactorGetSolverPackage_seqaij_matlab(Mat A,const MatSolverPackage *type) 212 { 213 PetscFunctionBegin; 214 *type = MATSOLVERMATLAB; 215 PetscFunctionReturn(0); 216 } 217 EXTERN_C_END 218 219 #undef __FUNCT__ 220 #define __FUNCT__ "MatGetFactor_seqaij_matlab" 221 PetscErrorCode MatGetFactor_seqaij_matlab(Mat A,MatFactorType ftype,Mat *F) 222 { 223 PetscErrorCode ierr; 224 225 PetscFunctionBegin; 226 if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square"); 227 ierr = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr); 228 ierr = MatSetSizes(*F,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 229 ierr = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr); 230 ierr = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr); 231 (*F)->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab; 232 (*F)->ops->ilufactorsymbolic = MatLUFactorSymbolic_Matlab; 233 ierr = PetscObjectComposeFunctionDynamic((PetscObject)(*F),"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_seqaij_matlab",MatFactorGetSolverPackage_seqaij_matlab);CHKERRQ(ierr); 234 235 (*F)->factortype = ftype; 236 PetscFunctionReturn(0); 237 } 238 239 240 /* --------------------------------------------------------------------------------*/ 241 242 #undef __FUNCT__ 243 #define __FUNCT__ "MatFactorInfo_Matlab" 244 PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer) 245 { 246 PetscErrorCode ierr; 247 248 PetscFunctionBegin; 249 ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters: -- not written yet!\n");CHKERRQ(ierr); 250 PetscFunctionReturn(0); 251 } 252 253 #undef __FUNCT__ 254 #define __FUNCT__ "MatView_Matlab" 255 PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer) 256 { 257 PetscErrorCode ierr; 258 PetscBool iascii; 259 PetscViewerFormat format; 260 261 PetscFunctionBegin; 262 ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr); 263 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 264 if (iascii) { 265 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 266 if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 267 ierr = MatFactorInfo_Matlab(A,viewer); 268 } 269 } 270 PetscFunctionReturn(0); 271 } 272 273 274 /*MC 275 MATSOLVERMATLAB - "matlab" - Providing direct solvers (LU and QR) and drop tolerance 276 based ILU factorization (ILUDT) for sequential matrices via the external package Matlab. 277 278 279 Works with MATSEQAIJ matrices. 280 281 Options Database Keys: 282 . -pc_factor_mat_solver_type matlab - selects Matlab to do the sparse factorization 283 284 285 Level: beginner 286 287 .seealso: PCLU 288 289 .seealso: PCFactorSetMatSolverPackage(), MatSolverPackage 290 M*/ 291 292