Actual source code: matlab.c

petsc-3.9.4 2018-09-11
Report Typos and Errors

  2: #include <engine.h>   /* Matlab include file */
  3:  #include <petscsys.h>
  4:  #include <petscmatlab.h>
  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;

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

 18:     Not Collective

 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)

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

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

 30:    Level: advanced

 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;

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

 50:   PetscHeaderCreate(e,MATLABENGINE_CLASSID,"MatlabEngine","MATLAB Engine","Sys",comm,PetscMatlabEngineDestroy,NULL);

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

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

 69:   *mengine = e;
 70:   return(0);
 71: }

 73: /*@
 74:    PetscMatlabEngineDestroy - Destroys a vector.

 76:    Collective on PetscMatlabEngine

 78:    Input Parameters:
 79: .  e  - the engine

 81:    Level: advanced

 83: .seealso: PetscMatlabEnginCreate(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
 84:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
 85:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
 86: @*/
 87: PetscErrorCode  PetscMatlabEngineDestroy(PetscMatlabEngine *v)
 88: {

 92:   if (!*v) return(0);
 94:   if (--((PetscObject)(*v))->refct > 0) return(0);
 95:   PetscHeaderDestroy(v);
 96:   return(0);
 97: }

 99: /*@C
100:     PetscMatlabEngineEvaluate - Evaluates a string in MATLAB

102:     Not Collective

104:     Input Parameters:
105: +   mengine - the MATLAB engine
106: -   string - format as in a printf()

108:    Level: advanced

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];
119:   size_t         fullLength;

122:   va_start(Argp,string);
123:   PetscVSNPrintf(buffer,1024-9-5,string,&fullLength,Argp);
124:   va_end(Argp);

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

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

134:   PetscInfo1(0,"Done evaluating Matlab string: %s\n",buffer);
135:   return(0);
136: }

138: /*@C
139:     PetscMatlabEngineGetOutput - Gets a string buffer where the MATLAB output is
140:           printed

142:     Not Collective

144:     Input Parameter:
145: .   mengine - the MATLAB engine

147:     Output Parameter:
148: .   string - buffer where MATLAB output is printed

150:    Level: advanced

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: {
159:   *string = mengine->buffer;
160:   return(0);
161: }

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(PetscObjectComm((PetscObject)mengine),&rank);
184:   PetscSynchronizedFPrintf(PetscObjectComm((PetscObject)mengine),fd,"[%d]%s",rank,mengine->buffer);
185:   PetscSynchronizedFlush(PetscObjectComm((PetscObject)mengine),fd);
186:   return(0);
187: }

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.

193:     Collective on PetscObject

195:     Input Parameters:
196: +    mengine - the MATLAB engine
197: -    object - the PETSc object, for example Vec

199:    Level: advanced

201: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
202:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
203:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
204: @*/
205: PetscErrorCode  PetscMatlabEnginePut(PetscMatlabEngine mengine,PetscObject obj)
206: {
207:   PetscErrorCode ierr,(*put)(PetscObject,void*);

210:   PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",&put);
211:   if (!put) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be put into MATLAB engine",obj->class_name);
212:   PetscInfo(0,"Putting MATLAB object\n");
213:   (*put)(obj,mengine->ep);
214:   PetscInfo1(0,"Put MATLAB object: %s\n",obj->name);
215:   return(0);
216: }

218: /*@
219:     PetscMatlabEngineGet - Gets a variable from MATLAB into a PETSc object.

221:     Collective on PetscObject

223:     Input Parameters:
224: +    mengine - the MATLAB engine
225: -    object - the PETSc object, for example Vec

227:    Level: advanced

229: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
230:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
231:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
232: @*/
233: PetscErrorCode  PetscMatlabEngineGet(PetscMatlabEngine mengine,PetscObject obj)
234: {
235:   PetscErrorCode ierr,(*get)(PetscObject,void*);

238:   if (!obj->name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot get object that has no name");
239:   PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",&get);
240:   if (!get) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be gotten from MATLAB engine",obj->class_name);
241:   PetscInfo(0,"Getting MATLAB object\n");
242:   (*get)(obj,mengine->ep);
243:   PetscInfo1(0,"Got MATLAB object: %s\n",obj->name);
244:   return(0);
245: }

247: /*
248:     The variable Petsc_Matlab_Engine_keyval is used to indicate an MPI attribute that
249:   is attached to a communicator, in this case the attribute is a PetscMatlabEngine
250: */
251: static PetscMPIInt Petsc_Matlab_Engine_keyval = MPI_KEYVAL_INVALID;


254: /*@C
255:    PETSC_MATLAB_ENGINE_ - Creates a matlab engine shared by all processors
256:                     in a communicator.

258:    Not Collective

260:    Input Parameter:
261: .  comm - the MPI communicator to share the engine

263:    Level: developer

265:    Notes:
266:    Unlike almost all other PETSc routines, this does not return
267:    an error code. Usually used in the form
268: $      PetscMatlabEngineYYY(XXX object,PETSC_MATLAB_ENGINE_(comm));

270: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
271:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
272:           PetscMatlabEngineCreate(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine,
273:           PETSC_MATLAB_ENGINE_WORLD, PETSC_MATLAB_ENGINE_SELF

275: @*/
276: PetscMatlabEngine  PETSC_MATLAB_ENGINE_(MPI_Comm comm)
277: {
278:   PetscErrorCode    ierr;
279:   PetscBool         flg;
280:   PetscMatlabEngine mengine;

283:   if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) {
284:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0);
285:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
286:   }
287:   MPI_Comm_get_attr(comm,Petsc_Matlab_Engine_keyval,(void**)&mengine,(int*)&flg);
288:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
289:   if (!flg) { /* viewer not yet created */
290:     char *machinename = 0,machine[64];

292:     PetscOptionsGetString(NULL,NULL,"-matlab_engine_machine",machine,64,&flg);
293:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
294:     if (flg) machinename = machine;
295:     PetscMatlabEngineCreate(comm,machinename,&mengine);
296:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
297:     PetscObjectRegisterDestroy((PetscObject)mengine);
298:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
299:     MPI_Comm_set_attr(comm,Petsc_Matlab_Engine_keyval,mengine);
300:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
301:   }
302:   PetscFunctionReturn(mengine);
303: }

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

309:     Collective on PetscObject

311:     Input Parameters:
312: +    mengine - the MATLAB engine
313: .    m,n - the dimensions of the array
314: .    array - the array (represented in one dimension)
315: -    name - the name of the array

317:    Level: advanced

319: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
320:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
321:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePut(), MatlabEngineGetArray(), PetscMatlabEngine
322: @*/
323: PetscErrorCode  PetscMatlabEnginePutArray(PetscMatlabEngine mengine,int m,int n,const PetscScalar *array,const char name[])
324: {
326:   mxArray        *mat;

329:   PetscInfo1(0,"Putting MATLAB array %s\n",name);
330: #if !defined(PETSC_USE_COMPLEX)
331:   mat = mxCreateDoubleMatrix(m,n,mxREAL);
332: #else
333:   mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
334: #endif
335:   PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));
336:   engPutVariable(mengine->ep,name,mat);

338:   PetscInfo1(0,"Put MATLAB array %s\n",name);
339:   return(0);
340: }

342: /*@C
343:     PetscMatlabEngineGetArray - Gets a variable from Matlab into an array

345:     Not Collective

347:     Input Parameters:
348: +    mengine - the Matlab engine
349: .    m,n - the dimensions of the array
350: .    array - the array (represented in one dimension)
351: -    name - the name of the array

353:    Level: advanced

355: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
356:           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
357:           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGet(), PetscMatlabEngine
358: @*/
359: PetscErrorCode  PetscMatlabEngineGetArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,const char name[])
360: {
362:   mxArray        *mat;

365:   PetscInfo1(0,"Getting MATLAB array %s\n",name);
366:   mat  = engGetVariable(mengine->ep,name);
367:   if (!mat) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
368:   PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));
369:   PetscInfo1(0,"Got MATLAB array %s\n",name);
370:   return(0);
371: }