Actual source code: matlab.c

  1: /* $Id: matlab.c,v 1.17 2001/08/06 21:14:26 bsmith Exp $ #include "petsc.h" */

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

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

 13: #undef __FUNCT__  
 15: /*@C
 16:     PetscMatlabEngineCreate - Creates a Matlab engine object 

 18:     Not Collective

 20:     Input Parameters:
 21: +   comm - a seperate Matlab engine is started for each process in the communicator
 22: -   machine - name of machine where Matlab engine is to be run (usually PETSC_NULL)

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

 27:    Level: advanced

 29: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
 30:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
 31:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutScalar(), PetscMatlabEngine
 32: @*/
 33: int PetscMatlabEngineCreate(MPI_Comm comm,char *machine,PetscMatlabEngine *mengine)
 34: {
 35:   int               ierr,rank,size;
 36:   char              buffer[128];
 37:   PetscMatlabEngine e;

 40:   PetscHeaderCreate(e,_p_PetscMatlabEngine,int,MATLABENGINE_COOKIE,0,"MatlabEngine",comm,PetscMatlabEngineDestroy,0);
 41:   PetscLogObjectCreate(e);

 43:   if (!machine) machine = "0";
 44:   PetscLogInfo(0,"Starting Matlab engine on %sn",machine);
 45:   e->ep = engOpen(machine);
 46:   if (!e->ep) SETERRQ1(1,"Unable to start Matlab engine on %sn",machine);
 47:   engOutputBuffer(e->ep,e->buffer,1024);

 49:   MPI_Comm_rank(comm,&rank);
 50:   MPI_Comm_size(comm,&size);
 51:   sprintf(buffer,"MPI_Comm_rank = %d; MPI_Comm_size = %d;n",rank,size);
 52:   engEvalString(e->ep, buffer);
 53:   PetscLogInfo(0,"Started Matlab engine on %sn",machine);
 54: 
 55:   *mengine = e;
 56:   return(0);
 57: }

 59: #undef __FUNCT__  
 61: /*@C
 62:    PetscMatlabEngineDestroy - Destroys a vector.

 64:    Collective on PetscMatlabEngine

 66:    Input Parameters:
 67: .  e  - the engine

 69:    Level: advanced

 71: .seealso: PetscMatlabEnginCreate(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
 72:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
 73:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutScalar(), PetscMatlabEngine
 74: @*/
 75: int PetscMatlabEngineDestroy(PetscMatlabEngine v)
 76: {
 79:   if (--v->refct > 0) return(0);
 80:   PetscLogObjectDestroy(v);
 81:   PetscHeaderDestroy(v);
 82:   return(0);
 83: }

 85: #undef __FUNCT__  
 87: /*@C
 88:     PetscMatlabEngineEvaluate - Evaluates a string in Matlab

 90:     Not Collective

 92:     Input Parameters:
 93: +   mengine - the Matlab engine
 94: -   string - format as in a printf()

 96:    Level: advanced

 98: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
 99:           PetscMatlabEngineCreate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
100:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutScalar(), PetscMatlabEngine
101: @*/
102: int PetscMatlabEngineEvaluate(PetscMatlabEngine mengine,char *string,...)
103: {
104:   va_list           Argp;
105:   char              buffer[1024];
106:   int               ierr,len,flops;

109:   PetscStrcpy(buffer,"flops(0);");
110:   va_start(Argp,string);
111: #if defined(PETSC_HAVE_VPRINTF_CHAR)
112:   vsprintf(buffer+9,string,(char *)Argp);
113: #else
114:   vsprintf(buffer+9,string,Argp);
115: #endif
116:   va_end(Argp);
117:   PetscStrcat(buffer,",flops");

119:   PetscLogInfo(0,"Evaluating Matlab string: %sn",buffer);
120:   engEvalString(mengine->ep, buffer);

122:   /* 
123:      Check for error in Matlab: indicated by ? as first character in engine->buffer
124:   */

126:   if (mengine->buffer[4] == '?') {
127:     SETERRQ2(1,"Error in evaluating Matlab command:%sn%s",string,mengine->buffer);
128:   }

130:   /*
131:      Get flop number back from Matlab output
132:   */
133:   PetscStrlen(mengine->buffer,&len);
134:   len -= 2;
135:   while (len >= 0) {
136:     len--;
137:     if (mengine->buffer[len] == ' ') break;
138:     if (mengine->buffer[len] == 'n') break;
139:     if (mengine->buffer[len] == 't') break;
140:   }
141:   sscanf(mengine->buffer+len," %dn",&flops);
142:   PetscLogFlops(flops);
143:   /* strip out of engine->buffer the end part about flops */
144:   if (len < 14) SETERRQ1(1,"Error from Matlab %s",mengine->buffer);
145:   len -= 14;
146:   mengine->buffer[len] = 0;

148:   PetscLogInfo(0,"Done evaluating Matlab string: %sn",buffer);
149:   return(0);
150: }

152: #undef __FUNCT__  
154: /*@C
155:     PetscMatlabEngineGetOutput - Gets a string buffer where the Matlab output is 
156:           printed

158:     Not Collective

160:     Input Parameter:
161: .   mengine - the Matlab engine

163:     Output Parameter:
164: .   string - buffer where Matlab output is printed

166:    Level: advanced

168: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
169:           PetscMatlabEngineEvaluate(), PetscMatlabEngineCreate(), PetscMatlabEnginePrintOutput(),
170:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutScalar(), PetscMatlabEngine
171: @*/
172: int PetscMatlabEngineGetOutput(PetscMatlabEngine mengine,char **string)
173: {
175:   *string = mengine->buffer;
176:   return(0);
177: }

179: #undef __FUNCT__  
181: /*@C
182:     PetscMatlabEnginePrintOutput - prints the output from Matlab

184:     Collective on PetscMatlabEngine

186:     Input Parameters:
187: .    mengine - the Matlab engine

189:    Level: advanced

191: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
192:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEngineCreate(),
193:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutScalar(), PetscMatlabEngine
194: @*/
195: int PetscMatlabEnginePrintOutput(PetscMatlabEngine mengine,FILE *fd)
196: {
197:   int  ierr,rank;

200:   MPI_Comm_rank(mengine->comm,&rank);
201:   PetscSynchronizedFPrintf(mengine->comm,fd,"[%d]%s",rank,mengine->buffer);
202:   PetscSynchronizedFlush(mengine->comm);
203:   return(0);
204: }

206: #undef __FUNCT__  
208: /*@C
209:     PetscMatlabEnginePut - Puts a Petsc object into the Matlab space. For parallel objects,
210:       each processors part is put in a seperate  Matlab process.

212:     Collective on PetscObject

214:     Input Parameters:
215: +    mengine - the Matlab engine
216: -    object - the PETSc object, for example Vec

218:    Level: advanced

220: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
221:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
222:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
223: @*/
224: int PetscMatlabEnginePut(PetscMatlabEngine mengine,PetscObject obj)
225: {
226:   int ierr,(*put)(PetscObject,void*);
227: 
229:   PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",(void (**)(void))&put);
230:   if (!put) {
231:     SETERRQ1(1,"Object %s cannot be put into Matlab engine",obj->class_name);
232:   }
233:   PetscLogInfo(0,"Putting Matlab objectn");
234:   (*put)(obj,mengine->ep);
235:   PetscLogInfo(0,"Put Matlab object: %sn",obj->name);
236:   return(0);
237: }

239: #undef __FUNCT__  
241: /*@C
242:     PetscMatlabEngineGet - Gets a variable from Matlab into a PETSc object.

244:     Collective on PetscObject

246:     Input Parameters:
247: +    mengine - the Matlab engine
248: -    object - the PETSc object, for example Vec

250:    Level: advanced

252: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
253:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
254:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
255: @*/
256: int PetscMatlabEngineGet(PetscMatlabEngine mengine,PetscObject obj)
257: {
258:   int ierr,(*get)(PetscObject,void*);
259: 
261:   if (!obj->name) {
262:     SETERRQ(1,"Cannot get object that has no name");
263:   }
264:   PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",(void (**)(void))&get);
265:   if (!get) {
266:     SETERRQ1(1,"Object %s cannot be get into Matlab engine",obj->class_name);
267:   }
268:   PetscLogInfo(0,"Getting Matlab objectn");
269:   (*get)(obj,mengine->ep);
270:   PetscLogInfo(0,"Got Matlab object: %sn",obj->name);
271:   return(0);
272: }

274: /*
275:     The variable Petsc_Matlab_Engine_keyval is used to indicate an MPI attribute that
276:   is attached to a communicator, in this case the attribute is a PetscMatlabEngine
277: */
278: static int Petsc_Matlab_Engine_keyval = MPI_KEYVAL_INVALID;

280: /*MC
281:   PETSC_MATLAB_ENGINE_WORLD - same as PETSC_MATLAB_ENGINE_(PETSC_COMM_WORLD)

283:   Level: developer
284: M*/

286: /*MC
287:   PETSC_MATLAB_ENGINE_SELF - same as PETSC_MATLAB_ENGINE_(PETSC_COMM_SELF)

289:   Level: developer
290: M*/

292: #undef __FUNCT__  
294: /*@C
295:    PETSC_MATLAB_ENGINE_ - Creates a matlab engine shared by all processors 
296:                     in a communicator.

298:    Not Collective

300:    Input Parameter:
301: .  comm - the MPI communicator to share the engine

303:    Level: developer

305:    Notes: 
306:    Unlike almost all other PETSc routines, this does not return 
307:    an error code. Usually used in the form
308: $      PetscMatlabEngineYYY(XXX object,PETSC_MATLAB_ENGINE_(comm));

310: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
311:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
312:           PetscMatlabEngineCreate(), PetscMatlabEnginePutScalar(), PetscMatlabEngine,
313:           PETSC_MATLAB_ENGINE_WORLD, PETSC_MATLAB_ENGINE_SELF
314:  
315: @*/
316: PetscMatlabEngine PETSC_MATLAB_ENGINE_(MPI_Comm comm)
317: {
318:   int               ierr;
319:   PetscTruth        flg;
320:   PetscMatlabEngine mengine;

323:   if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) {
324:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0);
325:     if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
326:   }
327:   MPI_Attr_get(comm,Petsc_Matlab_Engine_keyval,(void **)&mengine,(int*)&flg);
328:   if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
329:   if (!flg) { /* viewer not yet created */
330:     char *machinename = 0,machine[64];

332:     PetscOptionsGetString(PETSC_NULL,"-matlab_engine_machine",machine,64,&flg);
333:     if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
334:     if (flg) machinename = machine;
335:     PetscMatlabEngineCreate(comm,machinename,&mengine);
336:     if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
337:     PetscObjectRegisterDestroy((PetscObject)mengine);
338:     if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
339:     MPI_Attr_put(comm,Petsc_Matlab_Engine_keyval,mengine);
340:     if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
341:   }
342:   PetscFunctionReturn(mengine);
343: }

345: #undef __FUNCT__  
347: /*@C
348:     PetscMatlabEnginePutArray - Puts a Petsc object into the Matlab space. For parallel objects,
349:       each processors part is put in a seperate  Matlab process.

351:     Collective on PetscObject

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

359:    Level: advanced

361: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
362:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
363:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePut(), MatlabEngineGetArray(), PetscMatlabEngine
364: @*/
365: int PetscMatlabEnginePutArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,char *name)
366: {
367:   int     ierr;
368:   mxArray *mat;
369: 
371:   PetscLogInfo(0,"Putting Matlab array %sn",name);
372: #if !defined(PETSC_USE_COMPLEX)
373:   mat  = mxCreateDoubleMatrix(m,n,mxREAL);
374: #else
375:   mat  = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
376: #endif
377:   PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));
378:   mxSetName(mat,name);
379:   engPutArray(mengine->ep,mat);

381:   PetscLogInfo(0,"Put Matlab array %sn",name);
382:   return(0);
383: }

385: #undef __FUNCT__  
387: /*@C
388:     PetscMatlabEngineGetArray - Gets a variable from Matlab into an array

390:     Not Collective

392:     Input Parameters:
393: +    mengine - the Matlab engine
394: .    m,n - the dimensions of the array
395: .    array - the array (represented in one dimension)
396: -    name - the name of the array

398:    Level: advanced

400: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
401:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
402:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGet(), PetscMatlabEngine
403: @*/
404: int PetscMatlabEngineGetArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,char *name)
405: {
406:   int     ierr;
407:   mxArray *mat;
408: 
410:   PetscLogInfo(0,"Getting Matlab array %sn",name);
411:   mat  = engGetArray(mengine->ep,name);
412:   if (!mat) SETERRQ1(1,"Unable to get array %s from matlab",name);
413:   PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));
414:   PetscLogInfo(0,"Got Matlab array %sn",name);
415:   return(0);
416: }