Actual source code: matlab.c

  1: #define PETSC_DLL

  3: #include "engine.h"   /* Matlab include file */
 4:  #include petscsys.h
  5: #include <stdarg.h>

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

 13: PetscCookie MATLABENGINE_COOKIE = -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 PETSC_NULL)

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

 29:    Level: advanced

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

 43:   if (MATLABENGINE_COOKIE == -1) {
 44:     PetscCookieRegister("Matlab Engine",&MATLABENGINE_COOKIE);
 45:   }
 46:   PetscHeaderCreate(e,_p_PetscMatlabEngine,int,MATLABENGINE_COOKIE,0,"MatlabEngine",comm,PetscMatlabEngineDestroy,0);

 48:   if (!machine) machine = "\0";
 49:   PetscInfo1(0,"Starting Matlab engine on %s\n",machine);
 50:   e->ep = engOpen("matlab -nodisplay -nojvm");
 51:   if (!e->ep) SETERRQ1(PETSC_ERR_LIB,"Unable to start Matlab engine on %s\n",machine);
 52:   engOutputBuffer(e->ep,e->buffer,1024);

 54:   MPI_Comm_rank(comm,&rank);
 55:   MPI_Comm_size(comm,&size);
 56:   sprintf(buffer,"MPI_Comm_rank = %d; MPI_Comm_size = %d;\n",rank,size);
 57:   engEvalString(e->ep, buffer);
 58:   PetscInfo1(0,"Started Matlab engine on %s\n",machine);
 59: 
 60:   *mengine = e;
 61:   return(0);
 62: }

 66: /*@
 67:    PetscMatlabEngineDestroy - Destroys a vector.

 69:    Collective on PetscMatlabEngine

 71:    Input Parameters:
 72: .  e  - the engine

 74:    Level: advanced

 76: .seealso: PetscMatlabEnginCreate(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
 77:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
 78:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
 79: @*/
 80: PetscErrorCode  PetscMatlabEngineDestroy(PetscMatlabEngine v)
 81: {
 85:   if (--((PetscObject)v)->refct > 0) return(0);
 86:   PetscHeaderDestroy(v);
 87:   return(0);
 88: }

 92: /*@C
 93:     PetscMatlabEngineEvaluate - Evaluates a string in Matlab

 95:     Not Collective

 97:     Input Parameters:
 98: +   mengine - the Matlab engine
 99: -   string - format as in a printf()

101:    Level: advanced

103: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
104:           PetscMatlabEngineCreate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
105:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
106: @*/
107: PetscErrorCode  PetscMatlabEngineEvaluate(PetscMatlabEngine mengine,const char string[],...)
108: {
109:   va_list           Argp;
110:   char              buffer[1024];
112:   int               fullLength;
113:   size_t            len;

116:   va_start(Argp,string);
117:   PetscVSNPrintf(buffer,1024-9-5,string,&fullLength,Argp);
118:   va_end(Argp);

120:   PetscInfo1(0,"Evaluating Matlab string: %s\n",buffer);
121:   engEvalString(mengine->ep, buffer);

123:   /* 
124:      Check for error in Matlab: indicated by ? as first character in engine->buffer
125:   */
126:   if (mengine->buffer[4] == '?') {
127:     SETERRQ2(PETSC_ERR_LIB,"Error in evaluating Matlab command:%s\n%s",string,mengine->buffer);
128:   }

130:   PetscInfo1(0,"Done evaluating Matlab string: %s\n",buffer);
131:   return(0);
132: }

136: /*@C
137:     PetscMatlabEngineGetOutput - Gets a string buffer where the Matlab output is 
138:           printed

140:     Not Collective

142:     Input Parameter:
143: .   mengine - the Matlab engine

145:     Output Parameter:
146: .   string - buffer where Matlab output is printed

148:    Level: advanced

150: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
151:           PetscMatlabEngineEvaluate(), PetscMatlabEngineCreate(), PetscMatlabEnginePrintOutput(),
152:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
153: @*/
154: PetscErrorCode  PetscMatlabEngineGetOutput(PetscMatlabEngine mengine,char **string)
155: {
157:   *string = mengine->buffer;
158:   return(0);
159: }

163: /*@C
164:     PetscMatlabEnginePrintOutput - prints the output from Matlab

166:     Collective on PetscMatlabEngine

168:     Input Parameters:
169: .    mengine - the Matlab engine

171:    Level: advanced

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: {
180:   PetscMPIInt    rank;

183:   MPI_Comm_rank(((PetscObject)mengine)->comm,&rank);
184:   PetscSynchronizedFPrintf(((PetscObject)mengine)->comm,fd,"[%d]%s",rank,mengine->buffer);
185:   PetscSynchronizedFlush(((PetscObject)mengine)->comm);
186:   return(0);
187: }

191: /*@
192:     PetscMatlabEnginePut - Puts a Petsc object into the Matlab space. For parallel objects,
193:       each processors part is put in a separate  Matlab process.

195:     Collective on PetscObject

197:     Input Parameters:
198: +    mengine - the Matlab engine
199: -    object - the PETSc object, for example Vec

201:    Level: advanced

203: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
204:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
205:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
206: @*/
207: PetscErrorCode  PetscMatlabEnginePut(PetscMatlabEngine mengine,PetscObject obj)
208: {
209:   PetscErrorCode ierr,(*put)(PetscObject,void*);
210: 
212:   PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",(void (**)(void))&put);
213:   if (!put) {
214:     SETERRQ1(PETSC_ERR_SUP,"Object %s cannot be put into Matlab engine",obj->class_name);
215:   }
216:   PetscInfo(0,"Putting Matlab object\n");
217:   (*put)(obj,mengine->ep);
218:   PetscInfo1(0,"Put Matlab object: %s\n",obj->name);
219:   return(0);
220: }

224: /*@
225:     PetscMatlabEngineGet - Gets a variable from Matlab into a PETSc object.

227:     Collective on PetscObject

229:     Input Parameters:
230: +    mengine - the Matlab engine
231: -    object - the PETSc object, for example Vec

233:    Level: advanced

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: 
244:   if (!obj->name) {
245:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot get object that has no name");
246:   }
247:   PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",(void (**)(void))&get);
248:   if (!get) {
249:     SETERRQ1(PETSC_ERR_SUP,"Object %s cannot be gotten from Matlab engine",obj->class_name);
250:   }
251:   PetscInfo(0,"Getting Matlab object\n");
252:   (*get)(obj,mengine->ep);
253:   PetscInfo1(0,"Got Matlab object: %s\n",obj->name);
254:   return(0);
255: }

257: /*
258:     The variable Petsc_Matlab_Engine_keyval is used to indicate an MPI attribute that
259:   is attached to a communicator, in this case the attribute is a PetscMatlabEngine
260: */
261: static PetscMPIInt Petsc_Matlab_Engine_keyval = MPI_KEYVAL_INVALID;


266: /*@C
267:    PETSC_MATLAB_ENGINE_ - Creates a matlab engine shared by all processors 
268:                     in a communicator.

270:    Not Collective

272:    Input Parameter:
273: .  comm - the MPI communicator to share the engine

275:    Level: developer

277:    Notes: 
278:    Unlike almost all other PETSc routines, this does not return 
279:    an error code. Usually used in the form
280: $      PetscMatlabEngineYYY(XXX object,PETSC_MATLAB_ENGINE_(comm));

282: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
283:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
284:           PetscMatlabEngineCreate(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine,
285:           PETSC_MATLAB_ENGINE_WORLD, PETSC_MATLAB_ENGINE_SELF
286:  
287: @*/
288: PetscMatlabEngine  PETSC_MATLAB_ENGINE_(MPI_Comm comm)
289: {
291:   PetscTruth        flg;
292:   PetscMatlabEngine mengine;

295:   if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) {
296:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0);
297:     if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
298:   }
299:   MPI_Attr_get(comm,Petsc_Matlab_Engine_keyval,(void **)&mengine,(int*)&flg);
300:   if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
301:   if (!flg) { /* viewer not yet created */
302:     char *machinename = 0,machine[64];

304:     PetscOptionsGetString(PETSC_NULL,"-matlab_engine_machine",machine,64,&flg);
305:     if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
306:     if (flg) machinename = machine;
307:     PetscMatlabEngineCreate(comm,machinename,&mengine);
308:     if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
309:     PetscObjectRegisterDestroy((PetscObject)mengine);
310:     if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
311:     MPI_Attr_put(comm,Petsc_Matlab_Engine_keyval,mengine);
312:     if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
313:   }
314:   PetscFunctionReturn(mengine);
315: }

319: /*@C
320:     PetscMatlabEnginePutArray - Puts a Petsc object into the Matlab space. For parallel objects,
321:       each processors part is put in a separate  Matlab process.

323:     Collective on PetscObject

325:     Input Parameters:
326: +    mengine - the Matlab engine
327: .    m,n - the dimensions of the array
328: .    array - the array (represented in one dimension)
329: -    name - the name of the array

331:    Level: advanced

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

352:   PetscInfo1(0,"Put Matlab array %s\n",name);
353:   return(0);
354: }

358: /*@C
359:     PetscMatlabEngineGetArray - Gets a variable from Matlab into an array

361:     Not Collective

363:     Input Parameters:
364: +    mengine - the Matlab engine
365: .    m,n - the dimensions of the array
366: .    array - the array (represented in one dimension)
367: -    name - the name of the array

369:    Level: advanced

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