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 if (nz != aij->nz) { 91 /* number of nonzeros in matrix has changed, so need new data structure */ 92 ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);CHKERRQ(ierr); 93 aij->nz = nz; 94 ierr = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->rmap->n+1,PetscInt,&aij->i);CHKERRQ(ierr); 95 aij->singlemalloc = PETSC_TRUE; 96 } 97 98 ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 99 /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 100 i = aij->i; 101 for (k=0; k<n+1; k++) { 102 i[k] = (PetscInt) ii[k]; 103 } 104 j = aij->j; 105 for (k=0; k<nz; k++) { 106 j[k] = (PetscInt) jj[k]; 107 } 108 109 for (k=0; k<mat->rmap->n; k++) { 110 aij->ilen[k] = aij->imax[k] = aij->i[k+1] - aij->i[k]; 111 } 112 113 ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 114 ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 115 PetscFunctionReturn(0); 116 } 117 EXTERN_C_END 118 119 120 EXTERN_C_BEGIN 121 #undef __FUNCT__ 122 #define __FUNCT__ "MatlabEngineGet_SeqAIJ" 123 PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject obj,void *mengine) 124 { 125 PetscErrorCode ierr; 126 Mat mat = (Mat)obj; 127 mxArray *mmat; 128 129 PetscFunctionBegin; 130 mmat = engGetVariable((Engine *)mengine,obj->name); 131 ierr = MatSeqAIJFromMatlab(mmat,mat);CHKERRQ(ierr); 132 PetscFunctionReturn(0); 133 } 134 EXTERN_C_END 135 136 #undef __FUNCT__ 137 #define __FUNCT__ "MatSolve_Matlab" 138 PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x) 139 { 140 PetscErrorCode ierr; 141 const char *_A,*_b,*_x; 142 143 PetscFunctionBegin; 144 /* make sure objects have names; use default if not */ 145 ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr); 146 ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr); 147 148 ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr); 149 ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr); 150 ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr); 151 ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)b);CHKERRQ(ierr); 152 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr); 153 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_b);CHKERRQ(ierr); 154 /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),stdout);CHKERRQ(ierr); */ 155 ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)x);CHKERRQ(ierr); 156 PetscFunctionReturn(0); 157 } 158 159 #undef __FUNCT__ 160 #define __FUNCT__ "MatLUFactorNumeric_Matlab" 161 PetscErrorCode MatLUFactorNumeric_Matlab(Mat F,Mat A,const MatFactorInfo *info) 162 { 163 PetscErrorCode ierr; 164 size_t len; 165 char *_A,*name; 166 PetscReal dtcol = info->dtcol; 167 168 PetscFunctionBegin; 169 if (F->factortype == MAT_FACTOR_ILU || info->dt > 0) { 170 if (info->dtcol == PETSC_DEFAULT) dtcol = .01; 171 F->ops->solve = MatSolve_Matlab; 172 F->factortype = MAT_FACTOR_LU; 173 ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr); 174 _A = ((PetscObject)A)->name; 175 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,dtcol);CHKERRQ(ierr); 176 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); 177 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr); 178 179 ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 180 ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 181 sprintf(name,"_%s",_A); 182 ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr); 183 ierr = PetscFree(name);CHKERRQ(ierr); 184 } else { 185 ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr); 186 _A = ((PetscObject)A)->name; 187 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"[l_%s,u_%s,p_%s] = lu(%s',%g);",_A,_A,_A,_A,dtcol);CHKERRQ(ierr); 188 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr); 189 ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 190 ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 191 sprintf(name,"_%s",_A); 192 ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr); 193 ierr = PetscFree(name);CHKERRQ(ierr); 194 F->ops->solve = MatSolve_Matlab; 195 } 196 PetscFunctionReturn(0); 197 } 198 199 #undef __FUNCT__ 200 #define __FUNCT__ "MatLUFactorSymbolic_Matlab" 201 PetscErrorCode MatLUFactorSymbolic_Matlab(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info) 202 { 203 PetscFunctionBegin; 204 if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square"); 205 F->ops->lufactornumeric = MatLUFactorNumeric_Matlab; 206 F->assembled = PETSC_TRUE; 207 PetscFunctionReturn(0); 208 } 209 210 EXTERN_C_BEGIN 211 #undef __FUNCT__ 212 #define __FUNCT__ "MatFactorGetSolverPackage_seqaij_matlab" 213 PetscErrorCode MatFactorGetSolverPackage_seqaij_matlab(Mat A,const MatSolverPackage *type) 214 { 215 PetscFunctionBegin; 216 *type = MATSOLVERMATLAB; 217 PetscFunctionReturn(0); 218 } 219 EXTERN_C_END 220 221 #undef __FUNCT__ 222 #define __FUNCT__ "MatGetFactor_seqaij_matlab" 223 PetscErrorCode MatGetFactor_seqaij_matlab(Mat A,MatFactorType ftype,Mat *F) 224 { 225 PetscErrorCode ierr; 226 227 PetscFunctionBegin; 228 if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square"); 229 ierr = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr); 230 ierr = MatSetSizes(*F,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 231 ierr = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr); 232 ierr = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr); 233 (*F)->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab; 234 (*F)->ops->ilufactorsymbolic = MatLUFactorSymbolic_Matlab; 235 ierr = PetscObjectComposeFunctionDynamic((PetscObject)(*F),"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_seqaij_matlab",MatFactorGetSolverPackage_seqaij_matlab);CHKERRQ(ierr); 236 237 (*F)->factortype = ftype; 238 PetscFunctionReturn(0); 239 } 240 241 242 /* --------------------------------------------------------------------------------*/ 243 244 #undef __FUNCT__ 245 #define __FUNCT__ "MatFactorInfo_Matlab" 246 PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer) 247 { 248 PetscErrorCode ierr; 249 250 PetscFunctionBegin; 251 ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters: -- not written yet!\n");CHKERRQ(ierr); 252 PetscFunctionReturn(0); 253 } 254 255 #undef __FUNCT__ 256 #define __FUNCT__ "MatView_Matlab" 257 PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer) 258 { 259 PetscErrorCode ierr; 260 PetscBool iascii; 261 PetscViewerFormat format; 262 263 PetscFunctionBegin; 264 ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr); 265 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 266 if (iascii) { 267 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 268 if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 269 ierr = MatFactorInfo_Matlab(A,viewer); 270 } 271 } 272 PetscFunctionReturn(0); 273 } 274 275 276 /*MC 277 MATSOLVERMATLAB - "matlab" - Providing direct solvers (LU and QR) and drop tolerance 278 based ILU factorization (ILUDT) for sequential matrices via the external package Matlab. 279 280 281 Works with MATSEQAIJ matrices. 282 283 Options Database Keys: 284 . -pc_factor_mat_solver_type matlab - selects Matlab to do the sparse factorization 285 286 287 Level: beginner 288 289 .seealso: PCLU 290 291 .seealso: PCFactorSetMatSolverPackage(), MatSolverPackage 292 M*/ 293 294