Actual source code: matlab.c
petsc-3.7.1 2016-05-15
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,NULL,"-matlab_engine_graphics",&flg,NULL);

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

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