1 2 #include <engine.h> /* Matlab include file */ 3 #include <petscsys.h> 4 #include <stdarg.h> 5 6 struct _p_PetscMatlabEngine { 7 PETSCHEADER(int); 8 Engine *ep; 9 char buffer[1024]; 10 }; 11 12 PetscClassId MATLABENGINE_CLASSID = -1; 13 14 #undef __FUNCT__ 15 #define __FUNCT__ "PetscMatlabEngineCreate" 16 /*@C 17 PetscMatlabEngineCreate - Creates a MATLAB engine object 18 19 Not Collective 20 21 Input Parameters: 22 + comm - a separate MATLAB engine is started for each process in the communicator 23 - machine - name of machine where MATLAB engine is to be run (usually NULL) 24 25 Output Parameter: 26 . mengine - the resulting object 27 28 Options Database: 29 . -matlab_engine_graphics - allow the MATLAB engine to display graphics 30 31 Level: advanced 32 33 .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(), 34 PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(), 35 PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine 36 @*/ 37 PetscErrorCode PetscMatlabEngineCreate(MPI_Comm comm,const char machine[],PetscMatlabEngine *mengine) 38 { 39 PetscErrorCode ierr; 40 PetscMPIInt rank,size; 41 char buffer[256]; 42 PetscMatlabEngine e; 43 PetscBool flg = PETSC_FALSE; 44 45 PetscFunctionBegin; 46 if (MATLABENGINE_CLASSID == -1) { 47 ierr = PetscClassIdRegister("MATLAB Engine",&MATLABENGINE_CLASSID);CHKERRQ(ierr); 48 } 49 ierr = PetscOptionsGetBool(NULL,"-matlab_engine_graphics",&flg,NULL);CHKERRQ(ierr); 50 51 ierr = PetscHeaderCreate(e,_p_PetscMatlabEngine,int,MATLABENGINE_CLASSID,0,"MatlabEngine","MATLAB Engine","Sys",comm,PetscMatlabEngineDestroy,0);CHKERRQ(ierr); 52 53 if (!machine) machine = "\0"; 54 ierr = PetscStrcpy(buffer,PETSC_MATLAB_COMMAND);CHKERRQ(ierr); 55 if (!flg) { 56 ierr = PetscStrcat(buffer," -nodisplay ");CHKERRQ(ierr); 57 } 58 ierr = PetscStrcat(buffer," -nojvm ");CHKERRQ(ierr); 59 ierr = PetscInfo2(0,"Starting MATLAB engine on %s with command %s\n",machine,buffer);CHKERRQ(ierr); 60 e->ep = engOpen(buffer); 61 if (!e->ep) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to start MATLAB engine on %s\n",machine); 62 engOutputBuffer(e->ep,e->buffer,1024); 63 64 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 65 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 66 sprintf(buffer,"MPI_Comm_rank = %d; MPI_Comm_size = %d;\n",rank,size); 67 engEvalString(e->ep, buffer); 68 ierr = PetscInfo1(0,"Started MATLAB engine on %s\n",machine);CHKERRQ(ierr); 69 70 *mengine = e; 71 PetscFunctionReturn(0); 72 } 73 74 #undef __FUNCT__ 75 #define __FUNCT__ "PetscMatlabEngineDestroy" 76 /*@ 77 PetscMatlabEngineDestroy - Destroys a vector. 78 79 Collective on PetscMatlabEngine 80 81 Input Parameters: 82 . e - the engine 83 84 Level: advanced 85 86 .seealso: PetscMatlabEnginCreate(), PetscMatlabEnginePut(), PetscMatlabEngineGet(), 87 PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(), 88 PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine 89 @*/ 90 PetscErrorCode PetscMatlabEngineDestroy(PetscMatlabEngine *v) 91 { 92 PetscErrorCode ierr; 93 94 PetscFunctionBegin; 95 if (!*v) PetscFunctionReturn(0); 96 PetscValidHeaderSpecific(*v,MATLABENGINE_CLASSID,1); 97 if (--((PetscObject)(*v))->refct > 0) PetscFunctionReturn(0); 98 ierr = PetscHeaderDestroy(v);CHKERRQ(ierr); 99 PetscFunctionReturn(0); 100 } 101 102 #undef __FUNCT__ 103 #define __FUNCT__ "PetscMatlabEngineEvaluate" 104 /*@C 105 PetscMatlabEngineEvaluate - Evaluates a string in MATLAB 106 107 Not Collective 108 109 Input Parameters: 110 + mengine - the MATLAB engine 111 - string - format as in a printf() 112 113 Level: advanced 114 115 .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(), 116 PetscMatlabEngineCreate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(), 117 PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine 118 @*/ 119 PetscErrorCode PetscMatlabEngineEvaluate(PetscMatlabEngine mengine,const char string[],...) 120 { 121 va_list Argp; 122 char buffer[1024]; 123 PetscErrorCode ierr; 124 size_t fullLength; 125 126 PetscFunctionBegin; 127 va_start(Argp,string); 128 ierr = PetscVSNPrintf(buffer,1024-9-5,string,&fullLength,Argp);CHKERRQ(ierr); 129 va_end(Argp); 130 131 ierr = PetscInfo1(0,"Evaluating MATLAB string: %s\n",buffer);CHKERRQ(ierr); 132 engEvalString(mengine->ep, buffer); 133 134 /* 135 Check for error in MATLAB: indicated by ? as first character in engine->buffer 136 */ 137 if (mengine->buffer[4] == '?') SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in evaluating MATLAB command:%s\n%s",string,mengine->buffer); 138 139 ierr = PetscInfo1(0,"Done evaluating Matlab string: %s\n",buffer);CHKERRQ(ierr); 140 PetscFunctionReturn(0); 141 } 142 143 #undef __FUNCT__ 144 #define __FUNCT__ "PetscMatlabEngineGetOutput" 145 /*@C 146 PetscMatlabEngineGetOutput - Gets a string buffer where the MATLAB output is 147 printed 148 149 Not Collective 150 151 Input Parameter: 152 . mengine - the MATLAB engine 153 154 Output Parameter: 155 . string - buffer where MATLAB output is printed 156 157 Level: advanced 158 159 .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(), 160 PetscMatlabEngineEvaluate(), PetscMatlabEngineCreate(), PetscMatlabEnginePrintOutput(), 161 PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine 162 @*/ 163 PetscErrorCode PetscMatlabEngineGetOutput(PetscMatlabEngine mengine,char **string) 164 { 165 PetscFunctionBegin; 166 *string = mengine->buffer; 167 PetscFunctionReturn(0); 168 } 169 170 #undef __FUNCT__ 171 #define __FUNCT__ "PetscMatlabEnginePrintOutput" 172 /*@C 173 PetscMatlabEnginePrintOutput - prints the output from MATLAB 174 175 Collective on PetscMatlabEngine 176 177 Input Parameters: 178 . mengine - the Matlab engine 179 180 Level: advanced 181 182 .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(), 183 PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEngineCreate(), 184 PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine 185 @*/ 186 PetscErrorCode PetscMatlabEnginePrintOutput(PetscMatlabEngine mengine,FILE *fd) 187 { 188 PetscErrorCode ierr; 189 PetscMPIInt rank; 190 191 PetscFunctionBegin; 192 ierr = MPI_Comm_rank(((PetscObject)mengine)->comm,&rank);CHKERRQ(ierr); 193 ierr = PetscSynchronizedFPrintf(((PetscObject)mengine)->comm,fd,"[%d]%s",rank,mengine->buffer);CHKERRQ(ierr); 194 ierr = PetscSynchronizedFlush(((PetscObject)mengine)->comm);CHKERRQ(ierr); 195 PetscFunctionReturn(0); 196 } 197 198 #undef __FUNCT__ 199 #define __FUNCT__ "PetscMatlabEnginePut" 200 /*@ 201 PetscMatlabEnginePut - Puts a Petsc object into the MATLAB space. For parallel objects, 202 each processors part is put in a separate MATLAB process. 203 204 Collective on PetscObject 205 206 Input Parameters: 207 + mengine - the MATLAB engine 208 - object - the PETSc object, for example Vec 209 210 Level: advanced 211 212 .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(), 213 PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(), 214 PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine 215 @*/ 216 PetscErrorCode PetscMatlabEnginePut(PetscMatlabEngine mengine,PetscObject obj) 217 { 218 PetscErrorCode ierr,(*put)(PetscObject,void*); 219 220 PetscFunctionBegin; 221 ierr = PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",(void (**)(void))&put);CHKERRQ(ierr); 222 if (!put) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be put into MATLAB engine",obj->class_name); 223 ierr = PetscInfo(0,"Putting MATLAB object\n");CHKERRQ(ierr); 224 ierr = (*put)(obj,mengine->ep);CHKERRQ(ierr); 225 ierr = PetscInfo1(0,"Put MATLAB object: %s\n",obj->name);CHKERRQ(ierr); 226 PetscFunctionReturn(0); 227 } 228 229 #undef __FUNCT__ 230 #define __FUNCT__ "PetscMatlabEngineGet" 231 /*@ 232 PetscMatlabEngineGet - Gets a variable from MATLAB into a PETSc object. 233 234 Collective on PetscObject 235 236 Input Parameters: 237 + mengine - the MATLAB engine 238 - object - the PETSc object, for example Vec 239 240 Level: advanced 241 242 .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(), 243 PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(), 244 PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine 245 @*/ 246 PetscErrorCode PetscMatlabEngineGet(PetscMatlabEngine mengine,PetscObject obj) 247 { 248 PetscErrorCode ierr,(*get)(PetscObject,void*); 249 250 PetscFunctionBegin; 251 if (!obj->name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot get object that has no name"); 252 ierr = PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",(void (**)(void))&get);CHKERRQ(ierr); 253 if (!get) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be gotten from MATLAB engine",obj->class_name); 254 ierr = PetscInfo(0,"Getting MATLAB object\n");CHKERRQ(ierr); 255 ierr = (*get)(obj,mengine->ep);CHKERRQ(ierr); 256 ierr = PetscInfo1(0,"Got MATLAB object: %s\n",obj->name);CHKERRQ(ierr); 257 PetscFunctionReturn(0); 258 } 259 260 /* 261 The variable Petsc_Matlab_Engine_keyval is used to indicate an MPI attribute that 262 is attached to a communicator, in this case the attribute is a PetscMatlabEngine 263 */ 264 static PetscMPIInt Petsc_Matlab_Engine_keyval = MPI_KEYVAL_INVALID; 265 266 267 #undef __FUNCT__ 268 #define __FUNCT__ "PETSC_MATLAB_ENGINE_" 269 /*@C 270 PETSC_MATLAB_ENGINE_ - Creates a matlab engine shared by all processors 271 in a communicator. 272 273 Not Collective 274 275 Input Parameter: 276 . comm - the MPI communicator to share the engine 277 278 Level: developer 279 280 Notes: 281 Unlike almost all other PETSc routines, this does not return 282 an error code. Usually used in the form 283 $ PetscMatlabEngineYYY(XXX object,PETSC_MATLAB_ENGINE_(comm)); 284 285 .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(), 286 PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(), 287 PetscMatlabEngineCreate(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine, 288 PETSC_MATLAB_ENGINE_WORLD, PETSC_MATLAB_ENGINE_SELF 289 290 @*/ 291 PetscMatlabEngine PETSC_MATLAB_ENGINE_(MPI_Comm comm) 292 { 293 PetscErrorCode ierr; 294 PetscBool flg; 295 PetscMatlabEngine mengine; 296 297 PetscFunctionBegin; 298 if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) { 299 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0); 300 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;} 301 } 302 ierr = MPI_Attr_get(comm,Petsc_Matlab_Engine_keyval,(void**)&mengine,(int*)&flg); 303 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;} 304 if (!flg) { /* viewer not yet created */ 305 char *machinename = 0,machine[64]; 306 307 ierr = PetscOptionsGetString(NULL,"-matlab_engine_machine",machine,64,&flg); 308 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;} 309 if (flg) machinename = machine; 310 ierr = PetscMatlabEngineCreate(comm,machinename,&mengine); 311 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;} 312 ierr = PetscObjectRegisterDestroy((PetscObject)mengine); 313 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;} 314 ierr = MPI_Attr_put(comm,Petsc_Matlab_Engine_keyval,mengine); 315 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;} 316 } 317 PetscFunctionReturn(mengine); 318 } 319 320 #undef __FUNCT__ 321 #define __FUNCT__ "PetscMatlabEnginePutArray" 322 /*@C 323 PetscMatlabEnginePutArray - Puts an array into the MATLAB space, treating it as a Fortran style (column major ordering) array. For parallel objects, 324 each processors part is put in a separate MATLAB process. 325 326 Collective on PetscObject 327 328 Input Parameters: 329 + mengine - the MATLAB engine 330 . m,n - the dimensions of the array 331 . array - the array (represented in one dimension) 332 - name - the name of the array 333 334 Level: advanced 335 336 .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(), 337 PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(), 338 PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePut(), MatlabEngineGetArray(), PetscMatlabEngine 339 @*/ 340 PetscErrorCode PetscMatlabEnginePutArray(PetscMatlabEngine mengine,int m,int n,const PetscScalar *array,const char name[]) 341 { 342 PetscErrorCode ierr; 343 mxArray *mat; 344 345 PetscFunctionBegin; 346 ierr = PetscInfo1(0,"Putting MATLAB array %s\n",name);CHKERRQ(ierr); 347 #if !defined(PETSC_USE_COMPLEX) 348 mat = mxCreateDoubleMatrix(m,n,mxREAL); 349 #else 350 mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX); 351 #endif 352 ierr = PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));CHKERRQ(ierr); 353 engPutVariable(mengine->ep,name,mat); 354 355 ierr = PetscInfo1(0,"Put MATLAB array %s\n",name);CHKERRQ(ierr); 356 PetscFunctionReturn(0); 357 } 358 359 #undef __FUNCT__ 360 #define __FUNCT__ "PetscMatlabEngineGetArray" 361 /*@C 362 PetscMatlabEngineGetArray - Gets a variable from Matlab into an array 363 364 Not Collective 365 366 Input Parameters: 367 + mengine - the Matlab engine 368 . m,n - the dimensions of the array 369 . array - the array (represented in one dimension) 370 - name - the name of the array 371 372 Level: advanced 373 374 .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(), 375 PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(), 376 PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGet(), PetscMatlabEngine 377 @*/ 378 PetscErrorCode PetscMatlabEngineGetArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,const char name[]) 379 { 380 PetscErrorCode ierr; 381 mxArray *mat; 382 383 PetscFunctionBegin; 384 ierr = PetscInfo1(0,"Getting MATLAB array %s\n",name);CHKERRQ(ierr); 385 mat = engGetVariable(mengine->ep,name); 386 if (!mat) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to get array %s from matlab",name); 387 ierr = PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));CHKERRQ(ierr); 388 ierr = PetscInfo1(0,"Got MATLAB array %s\n",name);CHKERRQ(ierr); 389 PetscFunctionReturn(0); 390 } 391 392 393 394 395