Actual source code: matlab.c

petsc-3.3-p7 2013-05-11
  2: #include <engine.h>   /* Matlab include file */
  3: #include <petscsys.h> 
  4: #include <stdarg.h>

  6: struct  _p_PetscMatlabEngine {
  7:   PETSCHEADER(int);
  8:   Engine   *ep;
  9:   char     buffer[1024];
 10: };

 12: PetscClassId MATLABENGINE_CLASSID = -1;

 16: /*@C
 17:     PetscMatlabEngineCreate - Creates a MATLAB engine object 

 19:     Not Collective

 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 PETSC_NULL)

 25:     Output Parameter:
 26: .   mengine - the resulting object

 28:    Options Database:
 29: .    -matlab_engine_graphics - allow the MATLAB engine to display graphics

 31:    Level: advanced

 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;

 46:   if (MATLABENGINE_CLASSID == -1) {
 47:     PetscClassIdRegister("MATLAB Engine",&MATLABENGINE_CLASSID);
 48:   }
 49:   PetscOptionsGetBool(PETSC_NULL,"-matlab_engine_graphics",&flg,PETSC_NULL);

 51:   PetscHeaderCreate(e,_p_PetscMatlabEngine,int,MATLABENGINE_CLASSID,0,"MatlabEngine","MATLAB Engine","Sys",comm,PetscMatlabEngineDestroy,0);

 53:   if (!machine) machine = "\0";
 54:   PetscStrcpy(buffer,PETSC_MATLAB_COMMAND);
 55:   if (!flg) {
 56:     PetscStrcat(buffer," -nodisplay ");
 57:   }
 58:   PetscStrcat(buffer," -nojvm ");
 59:   PetscInfo2(0,"Starting MATLAB engine on %s with command %s\n",machine,buffer);
 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);

 64:   MPI_Comm_rank(comm,&rank);
 65:   MPI_Comm_size(comm,&size);
 66:   sprintf(buffer,"MPI_Comm_rank = %d; MPI_Comm_size = %d;\n",rank,size);
 67:   engEvalString(e->ep, buffer);
 68:   PetscInfo1(0,"Started MATLAB engine on %s\n",machine);
 69: 
 70:   *mengine = e;
 71:   return(0);
 72: }

 76: /*@
 77:    PetscMatlabEngineDestroy - Destroys a vector.

 79:    Collective on PetscMatlabEngine

 81:    Input Parameters:
 82: .  e  - the engine

 84:    Level: advanced

 86: .seealso: PetscMatlabEnginCreate(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
 87:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
 88:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
 89: @*/
 90: PetscErrorCode  PetscMatlabEngineDestroy(PetscMatlabEngine *v)
 91: {
 94:   if (!*v) return(0);
 96:   if (--((PetscObject)(*v))->refct > 0) return(0);
 97:   PetscHeaderDestroy(v);
 98:   return(0);
 99: }

103: /*@C
104:     PetscMatlabEngineEvaluate - Evaluates a string in MATLAB

106:     Not Collective

108:     Input Parameters:
109: +   mengine - the MATLAB engine
110: -   string - format as in a printf()

112:    Level: advanced

114: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
115:           PetscMatlabEngineCreate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
116:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
117: @*/
118: PetscErrorCode  PetscMatlabEngineEvaluate(PetscMatlabEngine mengine,const char string[],...)
119: {
120:   va_list        Argp;
121:   char           buffer[1024];
123:   size_t         fullLength;

126:   va_start(Argp,string);
127:   PetscVSNPrintf(buffer,1024-9-5,string,&fullLength,Argp);
128:   va_end(Argp);

130:   PetscInfo1(0,"Evaluating MATLAB string: %s\n",buffer);
131:   engEvalString(mengine->ep, buffer);

133:   /* 
134:      Check for error in MATLAB: indicated by ? as first character in engine->buffer
135:   */
136:   if (mengine->buffer[4] == '?') {
137:     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in evaluating MATLAB command:%s\n%s",string,mengine->buffer);
138:   }

140:   PetscInfo1(0,"Done evaluating Matlab string: %s\n",buffer);
141:   return(0);
142: }

146: /*@C
147:     PetscMatlabEngineGetOutput - Gets a string buffer where the MATLAB output is 
148:           printed

150:     Not Collective

152:     Input Parameter:
153: .   mengine - the MATLAB engine

155:     Output Parameter:
156: .   string - buffer where MATLAB output is printed

158:    Level: advanced

160: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
161:           PetscMatlabEngineEvaluate(), PetscMatlabEngineCreate(), PetscMatlabEnginePrintOutput(),
162:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
163: @*/
164: PetscErrorCode  PetscMatlabEngineGetOutput(PetscMatlabEngine mengine,char **string)
165: {
167:   *string = mengine->buffer;
168:   return(0);
169: }

173: /*@C
174:     PetscMatlabEnginePrintOutput - prints the output from MATLAB

176:     Collective on PetscMatlabEngine

178:     Input Parameters:
179: .    mengine - the Matlab engine

181:    Level: advanced

183: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
184:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEngineCreate(),
185:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
186: @*/
187: PetscErrorCode  PetscMatlabEnginePrintOutput(PetscMatlabEngine mengine,FILE *fd)
188: {
190:   PetscMPIInt    rank;

193:   MPI_Comm_rank(((PetscObject)mengine)->comm,&rank);
194:   PetscSynchronizedFPrintf(((PetscObject)mengine)->comm,fd,"[%d]%s",rank,mengine->buffer);
195:   PetscSynchronizedFlush(((PetscObject)mengine)->comm);
196:   return(0);
197: }

201: /*@
202:     PetscMatlabEnginePut - Puts a Petsc object into the MATLAB space. For parallel objects,
203:       each processors part is put in a separate  MATLAB process.

205:     Collective on PetscObject

207:     Input Parameters:
208: +    mengine - the MATLAB engine
209: -    object - the PETSc object, for example Vec

211:    Level: advanced

213: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
214:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
215:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
216: @*/
217: PetscErrorCode  PetscMatlabEnginePut(PetscMatlabEngine mengine,PetscObject obj)
218: {
219:   PetscErrorCode ierr,(*put)(PetscObject,void*);
220: 
222:   PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",(void (**)(void))&put);
223:   if (!put) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be put into MATLAB engine",obj->class_name);
224:   PetscInfo(0,"Putting MATLAB object\n");
225:   (*put)(obj,mengine->ep);
226:   PetscInfo1(0,"Put MATLAB object: %s\n",obj->name);
227:   return(0);
228: }

232: /*@
233:     PetscMatlabEngineGet - Gets a variable from MATLAB into a PETSc object.

235:     Collective on PetscObject

237:     Input Parameters:
238: +    mengine - the MATLAB engine
239: -    object - the PETSc object, for example Vec

241:    Level: advanced

243: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
244:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
245:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
246: @*/
247: PetscErrorCode  PetscMatlabEngineGet(PetscMatlabEngine mengine,PetscObject obj)
248: {
249:   PetscErrorCode ierr,(*get)(PetscObject,void*);
250: 
252:   if (!obj->name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot get object that has no name");
253:   PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",(void (**)(void))&get);
254:   if (!get) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be gotten from MATLAB engine",obj->class_name);
255:   PetscInfo(0,"Getting MATLAB object\n");
256:   (*get)(obj,mengine->ep);
257:   PetscInfo1(0,"Got MATLAB object: %s\n",obj->name);
258:   return(0);
259: }

261: /*
262:     The variable Petsc_Matlab_Engine_keyval is used to indicate an MPI attribute that
263:   is attached to a communicator, in this case the attribute is a PetscMatlabEngine
264: */
265: static PetscMPIInt Petsc_Matlab_Engine_keyval = MPI_KEYVAL_INVALID;


270: /*@C
271:    PETSC_MATLAB_ENGINE_ - Creates a matlab engine shared by all processors 
272:                     in a communicator.

274:    Not Collective

276:    Input Parameter:
277: .  comm - the MPI communicator to share the engine

279:    Level: developer

281:    Notes: 
282:    Unlike almost all other PETSc routines, this does not return 
283:    an error code. Usually used in the form
284: $      PetscMatlabEngineYYY(XXX object,PETSC_MATLAB_ENGINE_(comm));

286: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
287:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
288:           PetscMatlabEngineCreate(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine,
289:           PETSC_MATLAB_ENGINE_WORLD, PETSC_MATLAB_ENGINE_SELF
290:  
291: @*/
292: PetscMatlabEngine  PETSC_MATLAB_ENGINE_(MPI_Comm comm)
293: {
295:   PetscBool         flg;
296:   PetscMatlabEngine mengine;

299:   if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) {
300:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0);
301:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
302:   }
303:   MPI_Attr_get(comm,Petsc_Matlab_Engine_keyval,(void **)&mengine,(int*)&flg);
304:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
305:   if (!flg) { /* viewer not yet created */
306:     char *machinename = 0,machine[64];

308:     PetscOptionsGetString(PETSC_NULL,"-matlab_engine_machine",machine,64,&flg);
309:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
310:     if (flg) machinename = machine;
311:     PetscMatlabEngineCreate(comm,machinename,&mengine);
312:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
313:     PetscObjectRegisterDestroy((PetscObject)mengine);
314:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
315:     MPI_Attr_put(comm,Petsc_Matlab_Engine_keyval,mengine);
316:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
317:   }
318:   PetscFunctionReturn(mengine);
319: }

323: /*@C
324:     PetscMatlabEnginePutArray - Puts an array into the MATLAB space, treating it as a Fortran style (column major ordering) array. For parallel objects,
325:       each processors part is put in a separate  MATLAB process.

327:     Collective on PetscObject

329:     Input Parameters:
330: +    mengine - the MATLAB engine
331: .    m,n - the dimensions of the array
332: .    array - the array (represented in one dimension)
333: -    name - the name of the array

335:    Level: advanced

337: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
338:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
339:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePut(), MatlabEngineGetArray(), PetscMatlabEngine
340: @*/
341: PetscErrorCode  PetscMatlabEnginePutArray(PetscMatlabEngine mengine,int m,int n,const PetscScalar *array,const char name[])
342: {
344:   mxArray *mat;
345: 
347:   PetscInfo1(0,"Putting MATLAB array %s\n",name);
348: #if !defined(PETSC_USE_COMPLEX)
349:   mat  = mxCreateDoubleMatrix(m,n,mxREAL);
350: #else
351:   mat  = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
352: #endif
353:   PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));
354:   engPutVariable(mengine->ep,name,mat);

356:   PetscInfo1(0,"Put MATLAB array %s\n",name);
357:   return(0);
358: }

362: /*@C
363:     PetscMatlabEngineGetArray - Gets a variable from Matlab into an array

365:     Not Collective

367:     Input Parameters:
368: +    mengine - the Matlab engine
369: .    m,n - the dimensions of the array
370: .    array - the array (represented in one dimension)
371: -    name - the name of the array

373:    Level: advanced

375: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
376:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
377:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGet(), PetscMatlabEngine
378: @*/
379: PetscErrorCode  PetscMatlabEngineGetArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,const char name[])
380: {
382:   mxArray *mat;
383: 
385:   PetscInfo1(0,"Getting MATLAB array %s\n",name);
386:   mat  = engGetVariable(mengine->ep,name);
387:   if (!mat) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
388:   PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));
389:   PetscInfo1(0,"Got MATLAB array %s\n",name);
390:   return(0);
391: }