Actual source code: matlab.c

petsc-dev 2014-07-23
Report Typos and Errors
  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>

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

 13: PetscClassId MATLABENGINE_CLASSID = -1;

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

 20:     Not Collective

 22:     Input Parameters:
 23: +   comm - a separate MATLAB engine is started for each process in the communicator
 24: -   machine - name of machine where MATLAB engine is to be run (usually NULL)

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

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

 32:    Level: advanced

 34: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
 35:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
 36:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
 37: @*/
 38: PetscErrorCode  PetscMatlabEngineCreate(MPI_Comm comm,const char machine[],PetscMatlabEngine *mengine)
 39: {
 40:   PetscErrorCode    ierr;
 41:   PetscMPIInt       rank,size;
 42:   char              buffer[256];
 43:   PetscMatlabEngine e;
 44:   PetscBool         flg = PETSC_FALSE;

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

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

 54:   if (!machine) machine = "\0";
 55:   PetscStrcpy(buffer,PETSC_MATLAB_COMMAND);
 56:   if (!flg) {
 57:     PetscStrcat(buffer," -nodisplay ");
 58:   }
 59:   PetscStrcat(buffer," -nojvm ");
 60:   PetscInfo2(0,"Starting MATLAB engine on %s with command %s\n",machine,buffer);
 61:   e->ep = engOpen(buffer);
 62:   if (!e->ep) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to start MATLAB engine on %s\n",machine);
 63:   engOutputBuffer(e->ep,e->buffer,1024);

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

 71:   *mengine = e;
 72:   return(0);
 73: }

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

 80:    Collective on PetscMatlabEngine

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

 85:    Level: advanced

 87: .seealso: PetscMatlabEnginCreate(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
 88:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
 89:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
 90: @*/
 91: PetscErrorCode  PetscMatlabEngineDestroy(PetscMatlabEngine *v)
 92: {

 96:   if (!*v) return(0);
 98:   if (--((PetscObject)(*v))->refct > 0) return(0);
 99:   PetscHeaderDestroy(v);
100:   return(0);
101: }

105: /*@C
106:     PetscMatlabEngineEvaluate - Evaluates a string in MATLAB

108:     Not Collective

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

114:    Level: advanced

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

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

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

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

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(PetscObjectComm((PetscObject)mengine),&rank);
194:   PetscSynchronizedFPrintf(PetscObjectComm((PetscObject)mengine),fd,"[%d]%s",rank,mengine->buffer);
195:   PetscSynchronizedFlush(PetscObjectComm((PetscObject)mengine),fd);
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*);

222:   PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",&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*);

252:   if (!obj->name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot get object that has no name");
253:   PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",&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

291: @*/
292: PetscMatlabEngine  PETSC_MATLAB_ENGINE_(MPI_Comm comm)
293: {
294:   PetscErrorCode    ierr;
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__,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__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
305:   if (!flg) { /* viewer not yet created */
306:     char *machinename = 0,machine[64];

308:     PetscOptionsGetString(NULL,"-matlab_engine_machine",machine,64,&flg);
309:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,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__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
313:     PetscObjectRegisterDestroy((PetscObject)mengine);
314:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,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__,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;

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;

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: }