xref: /petsc/src/sys/classes/matlabengine/matlab.c (revision a3afe2d1ed14aa25e6e8bcdd861505b3816b69e5)
15c6c1daeSBarry Smith 
25c6c1daeSBarry Smith #include <engine.h>   /* Matlab include file */
35c6c1daeSBarry Smith #include <petscsys.h>
4*a3afe2d1SBarry Smith #include <petscmatlab.h>               /*I   "petscmatlab.h"  I*/
553a1d35cSJose E. Roman #include <petsc-private/petscimpl.h>
65c6c1daeSBarry Smith 
75c6c1daeSBarry Smith struct  _p_PetscMatlabEngine {
85c6c1daeSBarry Smith   PETSCHEADER(int);
95c6c1daeSBarry Smith   Engine *ep;
105c6c1daeSBarry Smith   char   buffer[1024];
115c6c1daeSBarry Smith };
125c6c1daeSBarry Smith 
135c6c1daeSBarry Smith PetscClassId MATLABENGINE_CLASSID = -1;
145c6c1daeSBarry Smith 
155c6c1daeSBarry Smith #undef __FUNCT__
165c6c1daeSBarry Smith #define __FUNCT__ "PetscMatlabEngineCreate"
175c6c1daeSBarry Smith /*@C
185c6c1daeSBarry Smith     PetscMatlabEngineCreate - Creates a MATLAB engine object
195c6c1daeSBarry Smith 
205c6c1daeSBarry Smith     Not Collective
215c6c1daeSBarry Smith 
225c6c1daeSBarry Smith     Input Parameters:
235c6c1daeSBarry Smith +   comm - a separate MATLAB engine is started for each process in the communicator
240298fd71SBarry Smith -   machine - name of machine where MATLAB engine is to be run (usually NULL)
255c6c1daeSBarry Smith 
265c6c1daeSBarry Smith     Output Parameter:
275c6c1daeSBarry Smith .   mengine - the resulting object
285c6c1daeSBarry Smith 
295c6c1daeSBarry Smith    Options Database:
305c6c1daeSBarry Smith .    -matlab_engine_graphics - allow the MATLAB engine to display graphics
315c6c1daeSBarry Smith 
325c6c1daeSBarry Smith    Level: advanced
335c6c1daeSBarry Smith 
345c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
355c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
365c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
375c6c1daeSBarry Smith @*/
385c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEngineCreate(MPI_Comm comm,const char machine[],PetscMatlabEngine *mengine)
395c6c1daeSBarry Smith {
405c6c1daeSBarry Smith   PetscErrorCode    ierr;
415c6c1daeSBarry Smith   PetscMPIInt       rank,size;
425c6c1daeSBarry Smith   char              buffer[256];
435c6c1daeSBarry Smith   PetscMatlabEngine e;
445c6c1daeSBarry Smith   PetscBool         flg = PETSC_FALSE;
455c6c1daeSBarry Smith 
465c6c1daeSBarry Smith   PetscFunctionBegin;
475c6c1daeSBarry Smith   if (MATLABENGINE_CLASSID == -1) {
485c6c1daeSBarry Smith     ierr = PetscClassIdRegister("MATLAB Engine",&MATLABENGINE_CLASSID);CHKERRQ(ierr);
495c6c1daeSBarry Smith   }
500298fd71SBarry Smith   ierr = PetscOptionsGetBool(NULL,"-matlab_engine_graphics",&flg,NULL);CHKERRQ(ierr);
515c6c1daeSBarry Smith 
5267c2884eSBarry Smith   ierr = PetscHeaderCreate(e,_p_PetscMatlabEngine,int,MATLABENGINE_CLASSID,"MatlabEngine","MATLAB Engine","Sys",comm,PetscMatlabEngineDestroy,0);CHKERRQ(ierr);
535c6c1daeSBarry Smith 
545c6c1daeSBarry Smith   if (!machine) machine = "\0";
555c6c1daeSBarry Smith   ierr = PetscStrcpy(buffer,PETSC_MATLAB_COMMAND);CHKERRQ(ierr);
565c6c1daeSBarry Smith   if (!flg) {
575c6c1daeSBarry Smith     ierr = PetscStrcat(buffer," -nodisplay ");CHKERRQ(ierr);
585c6c1daeSBarry Smith   }
595c6c1daeSBarry Smith   ierr  = PetscStrcat(buffer," -nojvm ");CHKERRQ(ierr);
605c6c1daeSBarry Smith   ierr  = PetscInfo2(0,"Starting MATLAB engine on %s with command %s\n",machine,buffer);CHKERRQ(ierr);
615c6c1daeSBarry Smith   e->ep = engOpen(buffer);
625c6c1daeSBarry Smith   if (!e->ep) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to start MATLAB engine on %s\n",machine);
635c6c1daeSBarry Smith   engOutputBuffer(e->ep,e->buffer,1024);
645c6c1daeSBarry Smith 
655c6c1daeSBarry Smith   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
665c6c1daeSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
675c6c1daeSBarry Smith   sprintf(buffer,"MPI_Comm_rank = %d; MPI_Comm_size = %d;\n",rank,size);
685c6c1daeSBarry Smith   engEvalString(e->ep, buffer);
695c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Started MATLAB engine on %s\n",machine);CHKERRQ(ierr);
705c6c1daeSBarry Smith 
715c6c1daeSBarry Smith   *mengine = e;
725c6c1daeSBarry Smith   PetscFunctionReturn(0);
735c6c1daeSBarry Smith }
745c6c1daeSBarry Smith 
755c6c1daeSBarry Smith #undef __FUNCT__
765c6c1daeSBarry Smith #define __FUNCT__ "PetscMatlabEngineDestroy"
775c6c1daeSBarry Smith /*@
785c6c1daeSBarry Smith    PetscMatlabEngineDestroy - Destroys a vector.
795c6c1daeSBarry Smith 
805c6c1daeSBarry Smith    Collective on PetscMatlabEngine
815c6c1daeSBarry Smith 
825c6c1daeSBarry Smith    Input Parameters:
835c6c1daeSBarry Smith .  e  - the engine
845c6c1daeSBarry Smith 
855c6c1daeSBarry Smith    Level: advanced
865c6c1daeSBarry Smith 
875c6c1daeSBarry Smith .seealso: PetscMatlabEnginCreate(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
885c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
895c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
905c6c1daeSBarry Smith @*/
915c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEngineDestroy(PetscMatlabEngine *v)
925c6c1daeSBarry Smith {
935c6c1daeSBarry Smith   PetscErrorCode ierr;
945fd66863SKarl Rupp 
955c6c1daeSBarry Smith   PetscFunctionBegin;
965c6c1daeSBarry Smith   if (!*v) PetscFunctionReturn(0);
975c6c1daeSBarry Smith   PetscValidHeaderSpecific(*v,MATLABENGINE_CLASSID,1);
985c6c1daeSBarry Smith   if (--((PetscObject)(*v))->refct > 0) PetscFunctionReturn(0);
995c6c1daeSBarry Smith   ierr = PetscHeaderDestroy(v);CHKERRQ(ierr);
1005c6c1daeSBarry Smith   PetscFunctionReturn(0);
1015c6c1daeSBarry Smith }
1025c6c1daeSBarry Smith 
1035c6c1daeSBarry Smith #undef __FUNCT__
1045c6c1daeSBarry Smith #define __FUNCT__ "PetscMatlabEngineEvaluate"
1055c6c1daeSBarry Smith /*@C
1065c6c1daeSBarry Smith     PetscMatlabEngineEvaluate - Evaluates a string in MATLAB
1075c6c1daeSBarry Smith 
1085c6c1daeSBarry Smith     Not Collective
1095c6c1daeSBarry Smith 
1105c6c1daeSBarry Smith     Input Parameters:
1115c6c1daeSBarry Smith +   mengine - the MATLAB engine
1125c6c1daeSBarry Smith -   string - format as in a printf()
1135c6c1daeSBarry Smith 
1145c6c1daeSBarry Smith    Level: advanced
1155c6c1daeSBarry Smith 
1165c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
1175c6c1daeSBarry Smith           PetscMatlabEngineCreate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
1185c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
1195c6c1daeSBarry Smith @*/
1205c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEngineEvaluate(PetscMatlabEngine mengine,const char string[],...)
1215c6c1daeSBarry Smith {
1225c6c1daeSBarry Smith   va_list        Argp;
1235c6c1daeSBarry Smith   char           buffer[1024];
1245c6c1daeSBarry Smith   PetscErrorCode ierr;
1255c6c1daeSBarry Smith   size_t         fullLength;
1265c6c1daeSBarry Smith 
1275c6c1daeSBarry Smith   PetscFunctionBegin;
1285c6c1daeSBarry Smith   va_start(Argp,string);
1295c6c1daeSBarry Smith   ierr = PetscVSNPrintf(buffer,1024-9-5,string,&fullLength,Argp);CHKERRQ(ierr);
1305c6c1daeSBarry Smith   va_end(Argp);
1315c6c1daeSBarry Smith 
1325c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Evaluating MATLAB string: %s\n",buffer);CHKERRQ(ierr);
1335c6c1daeSBarry Smith   engEvalString(mengine->ep, buffer);
1345c6c1daeSBarry Smith 
1355c6c1daeSBarry Smith   /*
1365c6c1daeSBarry Smith      Check for error in MATLAB: indicated by ? as first character in engine->buffer
1375c6c1daeSBarry Smith   */
138f23aa3ddSBarry Smith   if (mengine->buffer[4] == '?') SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in evaluating MATLAB command:%s\n%s",string,mengine->buffer);
1395c6c1daeSBarry Smith 
1405c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Done evaluating Matlab string: %s\n",buffer);CHKERRQ(ierr);
1415c6c1daeSBarry Smith   PetscFunctionReturn(0);
1425c6c1daeSBarry Smith }
1435c6c1daeSBarry Smith 
1445c6c1daeSBarry Smith #undef __FUNCT__
1455c6c1daeSBarry Smith #define __FUNCT__ "PetscMatlabEngineGetOutput"
1465c6c1daeSBarry Smith /*@C
1475c6c1daeSBarry Smith     PetscMatlabEngineGetOutput - Gets a string buffer where the MATLAB output is
1485c6c1daeSBarry Smith           printed
1495c6c1daeSBarry Smith 
1505c6c1daeSBarry Smith     Not Collective
1515c6c1daeSBarry Smith 
1525c6c1daeSBarry Smith     Input Parameter:
1535c6c1daeSBarry Smith .   mengine - the MATLAB engine
1545c6c1daeSBarry Smith 
1555c6c1daeSBarry Smith     Output Parameter:
1565c6c1daeSBarry Smith .   string - buffer where MATLAB output is printed
1575c6c1daeSBarry Smith 
1585c6c1daeSBarry Smith    Level: advanced
1595c6c1daeSBarry Smith 
1605c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
1615c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineCreate(), PetscMatlabEnginePrintOutput(),
1625c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
1635c6c1daeSBarry Smith @*/
1645c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEngineGetOutput(PetscMatlabEngine mengine,char **string)
1655c6c1daeSBarry Smith {
1665c6c1daeSBarry Smith   PetscFunctionBegin;
1675c6c1daeSBarry Smith   *string = mengine->buffer;
1685c6c1daeSBarry Smith   PetscFunctionReturn(0);
1695c6c1daeSBarry Smith }
1705c6c1daeSBarry Smith 
1715c6c1daeSBarry Smith #undef __FUNCT__
1725c6c1daeSBarry Smith #define __FUNCT__ "PetscMatlabEnginePrintOutput"
1735c6c1daeSBarry Smith /*@C
1745c6c1daeSBarry Smith     PetscMatlabEnginePrintOutput - prints the output from MATLAB
1755c6c1daeSBarry Smith 
1765c6c1daeSBarry Smith     Collective on PetscMatlabEngine
1775c6c1daeSBarry Smith 
1785c6c1daeSBarry Smith     Input Parameters:
1795c6c1daeSBarry Smith .    mengine - the Matlab engine
1805c6c1daeSBarry Smith 
1815c6c1daeSBarry Smith    Level: advanced
1825c6c1daeSBarry Smith 
1835c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
1845c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEngineCreate(),
1855c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
1865c6c1daeSBarry Smith @*/
1875c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEnginePrintOutput(PetscMatlabEngine mengine,FILE *fd)
1885c6c1daeSBarry Smith {
1895c6c1daeSBarry Smith   PetscErrorCode ierr;
1905c6c1daeSBarry Smith   PetscMPIInt    rank;
1915c6c1daeSBarry Smith 
1925c6c1daeSBarry Smith   PetscFunctionBegin;
193ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mengine),&rank);CHKERRQ(ierr);
194ce94432eSBarry Smith   ierr = PetscSynchronizedFPrintf(PetscObjectComm((PetscObject)mengine),fd,"[%d]%s",rank,mengine->buffer);CHKERRQ(ierr);
195ce94432eSBarry Smith   ierr = PetscSynchronizedFlush(PetscObjectComm((PetscObject)mengine));CHKERRQ(ierr);
1965c6c1daeSBarry Smith   PetscFunctionReturn(0);
1975c6c1daeSBarry Smith }
1985c6c1daeSBarry Smith 
1995c6c1daeSBarry Smith #undef __FUNCT__
2005c6c1daeSBarry Smith #define __FUNCT__ "PetscMatlabEnginePut"
2015c6c1daeSBarry Smith /*@
2025c6c1daeSBarry Smith     PetscMatlabEnginePut - Puts a Petsc object into the MATLAB space. For parallel objects,
2035c6c1daeSBarry Smith       each processors part is put in a separate  MATLAB process.
2045c6c1daeSBarry Smith 
2055c6c1daeSBarry Smith     Collective on PetscObject
2065c6c1daeSBarry Smith 
2075c6c1daeSBarry Smith     Input Parameters:
2085c6c1daeSBarry Smith +    mengine - the MATLAB engine
2095c6c1daeSBarry Smith -    object - the PETSc object, for example Vec
2105c6c1daeSBarry Smith 
2115c6c1daeSBarry Smith    Level: advanced
2125c6c1daeSBarry Smith 
2135c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
2145c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
2155c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
2165c6c1daeSBarry Smith @*/
2175c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEnginePut(PetscMatlabEngine mengine,PetscObject obj)
2185c6c1daeSBarry Smith {
2195c6c1daeSBarry Smith   PetscErrorCode ierr,(*put)(PetscObject,void*);
2205c6c1daeSBarry Smith 
2215c6c1daeSBarry Smith   PetscFunctionBegin;
2220005d66cSJed Brown   ierr = PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",&put);CHKERRQ(ierr);
2235c6c1daeSBarry Smith   if (!put) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be put into MATLAB engine",obj->class_name);
2245c6c1daeSBarry Smith   ierr = PetscInfo(0,"Putting MATLAB object\n");CHKERRQ(ierr);
2255c6c1daeSBarry Smith   ierr = (*put)(obj,mengine->ep);CHKERRQ(ierr);
2265c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Put MATLAB object: %s\n",obj->name);CHKERRQ(ierr);
2275c6c1daeSBarry Smith   PetscFunctionReturn(0);
2285c6c1daeSBarry Smith }
2295c6c1daeSBarry Smith 
2305c6c1daeSBarry Smith #undef __FUNCT__
2315c6c1daeSBarry Smith #define __FUNCT__ "PetscMatlabEngineGet"
2325c6c1daeSBarry Smith /*@
2335c6c1daeSBarry Smith     PetscMatlabEngineGet - Gets a variable from MATLAB into a PETSc object.
2345c6c1daeSBarry Smith 
2355c6c1daeSBarry Smith     Collective on PetscObject
2365c6c1daeSBarry Smith 
2375c6c1daeSBarry Smith     Input Parameters:
2385c6c1daeSBarry Smith +    mengine - the MATLAB engine
2395c6c1daeSBarry Smith -    object - the PETSc object, for example Vec
2405c6c1daeSBarry Smith 
2415c6c1daeSBarry Smith    Level: advanced
2425c6c1daeSBarry Smith 
2435c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
2445c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
2455c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
2465c6c1daeSBarry Smith @*/
2475c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEngineGet(PetscMatlabEngine mengine,PetscObject obj)
2485c6c1daeSBarry Smith {
2495c6c1daeSBarry Smith   PetscErrorCode ierr,(*get)(PetscObject,void*);
2505c6c1daeSBarry Smith 
2515c6c1daeSBarry Smith   PetscFunctionBegin;
2525c6c1daeSBarry Smith   if (!obj->name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot get object that has no name");
2530005d66cSJed Brown   ierr = PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",&get);CHKERRQ(ierr);
2545c6c1daeSBarry Smith   if (!get) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be gotten from MATLAB engine",obj->class_name);
2555c6c1daeSBarry Smith   ierr = PetscInfo(0,"Getting MATLAB object\n");CHKERRQ(ierr);
2565c6c1daeSBarry Smith   ierr = (*get)(obj,mengine->ep);CHKERRQ(ierr);
2575c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Got MATLAB object: %s\n",obj->name);CHKERRQ(ierr);
2585c6c1daeSBarry Smith   PetscFunctionReturn(0);
2595c6c1daeSBarry Smith }
2605c6c1daeSBarry Smith 
2615c6c1daeSBarry Smith /*
2625c6c1daeSBarry Smith     The variable Petsc_Matlab_Engine_keyval is used to indicate an MPI attribute that
2635c6c1daeSBarry Smith   is attached to a communicator, in this case the attribute is a PetscMatlabEngine
2645c6c1daeSBarry Smith */
2655c6c1daeSBarry Smith static PetscMPIInt Petsc_Matlab_Engine_keyval = MPI_KEYVAL_INVALID;
2665c6c1daeSBarry Smith 
2675c6c1daeSBarry Smith 
2685c6c1daeSBarry Smith #undef __FUNCT__
2695c6c1daeSBarry Smith #define __FUNCT__ "PETSC_MATLAB_ENGINE_"
2705c6c1daeSBarry Smith /*@C
2715c6c1daeSBarry Smith    PETSC_MATLAB_ENGINE_ - Creates a matlab engine shared by all processors
2725c6c1daeSBarry Smith                     in a communicator.
2735c6c1daeSBarry Smith 
2745c6c1daeSBarry Smith    Not Collective
2755c6c1daeSBarry Smith 
2765c6c1daeSBarry Smith    Input Parameter:
2775c6c1daeSBarry Smith .  comm - the MPI communicator to share the engine
2785c6c1daeSBarry Smith 
2795c6c1daeSBarry Smith    Level: developer
2805c6c1daeSBarry Smith 
2815c6c1daeSBarry Smith    Notes:
2825c6c1daeSBarry Smith    Unlike almost all other PETSc routines, this does not return
2835c6c1daeSBarry Smith    an error code. Usually used in the form
2845c6c1daeSBarry Smith $      PetscMatlabEngineYYY(XXX object,PETSC_MATLAB_ENGINE_(comm));
2855c6c1daeSBarry Smith 
2865c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
2875c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
2885c6c1daeSBarry Smith           PetscMatlabEngineCreate(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine,
2895c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_WORLD, PETSC_MATLAB_ENGINE_SELF
2905c6c1daeSBarry Smith 
2915c6c1daeSBarry Smith @*/
2925c6c1daeSBarry Smith PetscMatlabEngine  PETSC_MATLAB_ENGINE_(MPI_Comm comm)
2935c6c1daeSBarry Smith {
2945c6c1daeSBarry Smith   PetscErrorCode    ierr;
2955c6c1daeSBarry Smith   PetscBool         flg;
2965c6c1daeSBarry Smith   PetscMatlabEngine mengine;
2975c6c1daeSBarry Smith 
2985c6c1daeSBarry Smith   PetscFunctionBegin;
2995c6c1daeSBarry Smith   if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) {
3005c6c1daeSBarry Smith     ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0);
3015c6c1daeSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
3025c6c1daeSBarry Smith   }
3035c6c1daeSBarry Smith   ierr = MPI_Attr_get(comm,Petsc_Matlab_Engine_keyval,(void**)&mengine,(int*)&flg);
3045c6c1daeSBarry Smith   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
3055c6c1daeSBarry Smith   if (!flg) { /* viewer not yet created */
3065c6c1daeSBarry Smith     char *machinename = 0,machine[64];
3075c6c1daeSBarry Smith 
3080298fd71SBarry Smith     ierr = PetscOptionsGetString(NULL,"-matlab_engine_machine",machine,64,&flg);
3095c6c1daeSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
3105c6c1daeSBarry Smith     if (flg) machinename = machine;
3115c6c1daeSBarry Smith     ierr = PetscMatlabEngineCreate(comm,machinename,&mengine);
3125c6c1daeSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
3135c6c1daeSBarry Smith     ierr = PetscObjectRegisterDestroy((PetscObject)mengine);
3145c6c1daeSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
3155c6c1daeSBarry Smith     ierr = MPI_Attr_put(comm,Petsc_Matlab_Engine_keyval,mengine);
3165c6c1daeSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
3175c6c1daeSBarry Smith   }
3185c6c1daeSBarry Smith   PetscFunctionReturn(mengine);
3195c6c1daeSBarry Smith }
3205c6c1daeSBarry Smith 
3215c6c1daeSBarry Smith #undef __FUNCT__
3225c6c1daeSBarry Smith #define __FUNCT__ "PetscMatlabEnginePutArray"
3235c6c1daeSBarry Smith /*@C
3245c6c1daeSBarry Smith     PetscMatlabEnginePutArray - Puts an array into the MATLAB space, treating it as a Fortran style (column major ordering) array. For parallel objects,
3255c6c1daeSBarry Smith       each processors part is put in a separate  MATLAB process.
3265c6c1daeSBarry Smith 
3275c6c1daeSBarry Smith     Collective on PetscObject
3285c6c1daeSBarry Smith 
3295c6c1daeSBarry Smith     Input Parameters:
3305c6c1daeSBarry Smith +    mengine - the MATLAB engine
3315c6c1daeSBarry Smith .    m,n - the dimensions of the array
3325c6c1daeSBarry Smith .    array - the array (represented in one dimension)
3335c6c1daeSBarry Smith -    name - the name of the array
3345c6c1daeSBarry Smith 
3355c6c1daeSBarry Smith    Level: advanced
3365c6c1daeSBarry Smith 
3375c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
3385c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
3395c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePut(), MatlabEngineGetArray(), PetscMatlabEngine
3405c6c1daeSBarry Smith @*/
3415c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEnginePutArray(PetscMatlabEngine mengine,int m,int n,const PetscScalar *array,const char name[])
3425c6c1daeSBarry Smith {
3435c6c1daeSBarry Smith   PetscErrorCode ierr;
3445c6c1daeSBarry Smith   mxArray        *mat;
3455c6c1daeSBarry Smith 
3465c6c1daeSBarry Smith   PetscFunctionBegin;
3475c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Putting MATLAB array %s\n",name);CHKERRQ(ierr);
3485c6c1daeSBarry Smith #if !defined(PETSC_USE_COMPLEX)
3495c6c1daeSBarry Smith   mat = mxCreateDoubleMatrix(m,n,mxREAL);
3505c6c1daeSBarry Smith #else
3515c6c1daeSBarry Smith   mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
3525c6c1daeSBarry Smith #endif
3535c6c1daeSBarry Smith   ierr = PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));CHKERRQ(ierr);
3545c6c1daeSBarry Smith   engPutVariable(mengine->ep,name,mat);
3555c6c1daeSBarry Smith 
3565c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Put MATLAB array %s\n",name);CHKERRQ(ierr);
3575c6c1daeSBarry Smith   PetscFunctionReturn(0);
3585c6c1daeSBarry Smith }
3595c6c1daeSBarry Smith 
3605c6c1daeSBarry Smith #undef __FUNCT__
3615c6c1daeSBarry Smith #define __FUNCT__ "PetscMatlabEngineGetArray"
3625c6c1daeSBarry Smith /*@C
3635c6c1daeSBarry Smith     PetscMatlabEngineGetArray - Gets a variable from Matlab into an array
3645c6c1daeSBarry Smith 
3655c6c1daeSBarry Smith     Not Collective
3665c6c1daeSBarry Smith 
3675c6c1daeSBarry Smith     Input Parameters:
3685c6c1daeSBarry Smith +    mengine - the Matlab engine
3695c6c1daeSBarry Smith .    m,n - the dimensions of the array
3705c6c1daeSBarry Smith .    array - the array (represented in one dimension)
3715c6c1daeSBarry Smith -    name - the name of the array
3725c6c1daeSBarry Smith 
3735c6c1daeSBarry Smith    Level: advanced
3745c6c1daeSBarry Smith 
3755c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
3765c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
3775c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGet(), PetscMatlabEngine
3785c6c1daeSBarry Smith @*/
3795c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEngineGetArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,const char name[])
3805c6c1daeSBarry Smith {
3815c6c1daeSBarry Smith   PetscErrorCode ierr;
3825c6c1daeSBarry Smith   mxArray        *mat;
3835c6c1daeSBarry Smith 
3845c6c1daeSBarry Smith   PetscFunctionBegin;
3855c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Getting MATLAB array %s\n",name);CHKERRQ(ierr);
3865c6c1daeSBarry Smith   mat  = engGetVariable(mengine->ep,name);
3875c6c1daeSBarry Smith   if (!mat) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
3885c6c1daeSBarry Smith   ierr = PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));CHKERRQ(ierr);
3895c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Got MATLAB array %s\n",name);CHKERRQ(ierr);
3905c6c1daeSBarry Smith   PetscFunctionReturn(0);
3915c6c1daeSBarry Smith }
3925c6c1daeSBarry Smith 
3935c6c1daeSBarry Smith 
3945c6c1daeSBarry Smith 
3955c6c1daeSBarry Smith 
396