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