xref: /petsc/src/sys/classes/matlabengine/matlab.c (revision 28b400f66ebc7ae0049166a2294dfcd3df27e64b)
15c6c1daeSBarry Smith 
2540acb9aSBarry Smith #include <engine.h>   /* MATLAB include file */
35c6c1daeSBarry Smith #include <petscsys.h>
4a3afe2d1SBarry Smith #include <petscmatlab.h>               /*I   "petscmatlab.h"  I*/
5af0996ceSBarry Smith #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 /*@C
165c6c1daeSBarry Smith     PetscMatlabEngineCreate - Creates a MATLAB engine object
175c6c1daeSBarry Smith 
185c6c1daeSBarry Smith     Not Collective
195c6c1daeSBarry Smith 
205c6c1daeSBarry Smith     Input Parameters:
215c6c1daeSBarry Smith +   comm - a separate MATLAB engine is started for each process in the communicator
2257a177adSBarry Smith -   host - name of machine where MATLAB engine is to be run (usually NULL)
235c6c1daeSBarry Smith 
245c6c1daeSBarry Smith     Output Parameter:
255c6c1daeSBarry Smith .   mengine - the resulting object
265c6c1daeSBarry Smith 
275c6c1daeSBarry Smith    Options Database:
2857a177adSBarry Smith +    -matlab_engine_graphics - allow the MATLAB engine to display graphics
29540acb9aSBarry Smith .    -matlab_engine_host - hostname, machine to run the MATLAB engine on
30540acb9aSBarry Smith -    -info - print out all requests to MATLAB and all if its responses (for debugging)
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 @*/
3857a177adSBarry Smith PetscErrorCode  PetscMatlabEngineCreate(MPI_Comm comm,const char host[],PetscMatlabEngine *mengine)
395c6c1daeSBarry Smith {
405c6c1daeSBarry Smith   PetscMPIInt       rank,size;
415c6c1daeSBarry Smith   char              buffer[256];
425c6c1daeSBarry Smith   PetscMatlabEngine e;
4357a177adSBarry Smith   PetscBool         flg = PETSC_FALSE;
445c6c1daeSBarry Smith 
455c6c1daeSBarry Smith   PetscFunctionBegin;
465f80ce2aSJacob Faibussowitsch   if (MATLABENGINE_CLASSID == -1) CHKERRQ(PetscClassIdRegister("MATLAB Engine",&MATLABENGINE_CLASSID));
475f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscHeaderCreate(e,MATLABENGINE_CLASSID,"MatlabEngine","MATLAB Engine","Sys",comm,PetscMatlabEngineDestroy,NULL));
485c6c1daeSBarry Smith 
4957a177adSBarry Smith   if (!host) {
5057a177adSBarry Smith     char lhost[64];
5157a177adSBarry Smith 
525f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscOptionsGetString(NULL,NULL,"-matlab_engine_host",lhost,sizeof(lhost),&flg));
5357a177adSBarry Smith     if (flg) {host = lhost;}
54fc8a9adeSBarry Smith   }
5557a177adSBarry Smith   flg = PETSC_FALSE;
565f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-matlab_engine_graphics",&flg,NULL));
5757a177adSBarry Smith 
5857a177adSBarry Smith   if (host) {
595f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscInfo(0,"Starting MATLAB engine on %s\n",host));
6057a177adSBarry Smith   } else {
6157a177adSBarry Smith 
6257a177adSBarry Smith   }
6357a177adSBarry Smith   if (host) {
645f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcpy(buffer,"ssh "));
655f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcat(buffer,host));
665f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcat(buffer," \""));
675f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrlcat(buffer,PETSC_MATLAB_COMMAND,sizeof(buffer)));
6857a177adSBarry Smith     if (!flg) {
695f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscStrlcat(buffer," -nodisplay ",sizeof(buffer)));
7057a177adSBarry Smith     }
715f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrlcat(buffer," -nosplash ",sizeof(buffer)));
725f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcat(buffer,"\""));
7357a177adSBarry Smith   } else {
745f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrncpy(buffer,PETSC_MATLAB_COMMAND,sizeof(buffer)));
755c6c1daeSBarry Smith     if (!flg) {
765f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscStrlcat(buffer," -nodisplay ",sizeof(buffer)));
775c6c1daeSBarry Smith     }
785f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrlcat(buffer," -nosplash ",sizeof(buffer)));
79fc8a9adeSBarry Smith   }
805f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscInfo(0,"Starting MATLAB engine with command %s\n",buffer));
815c6c1daeSBarry Smith   e->ep = engOpen(buffer);
82*28b400f6SJacob Faibussowitsch   PetscCheck(e->ep,PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to start MATLAB engine with %s",buffer);
83540acb9aSBarry Smith   engOutputBuffer(e->ep,e->buffer,sizeof(e->buffer));
8457a177adSBarry Smith   if (host) {
855f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscInfo(0,"Started MATLAB engine on %s\n",host));
86fc8a9adeSBarry Smith   } else {
875f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscInfo(0,"Started MATLAB engine\n"));
88fc8a9adeSBarry Smith   }
89540acb9aSBarry Smith 
905f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(comm,&rank));
915f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_size(comm,&size));
925f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscMatlabEngineEvaluate(e,"MPI_Comm_rank = %d; MPI_Comm_size = %d;\n",rank,size));
935c6c1daeSBarry Smith   *mengine = e;
945c6c1daeSBarry Smith   PetscFunctionReturn(0);
955c6c1daeSBarry Smith }
965c6c1daeSBarry Smith 
975c6c1daeSBarry Smith /*@
98540acb9aSBarry Smith    PetscMatlabEngineDestroy - Shuts down a MATLAB engine.
995c6c1daeSBarry Smith 
1005c6c1daeSBarry Smith    Collective on PetscMatlabEngine
1015c6c1daeSBarry Smith 
1025c6c1daeSBarry Smith    Input Parameters:
1035c6c1daeSBarry Smith .  e  - the engine
1045c6c1daeSBarry Smith 
1055c6c1daeSBarry Smith    Level: advanced
1065c6c1daeSBarry Smith 
10769cdbcb9SBarry Smith .seealso: PetscMatlabEngineCreate(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
1085c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
1095c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
1105c6c1daeSBarry Smith @*/
1115c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEngineDestroy(PetscMatlabEngine *v)
1125c6c1daeSBarry Smith {
1135c6c1daeSBarry Smith   PetscErrorCode ierr;
1145fd66863SKarl Rupp 
1155c6c1daeSBarry Smith   PetscFunctionBegin;
1165c6c1daeSBarry Smith   if (!*v) PetscFunctionReturn(0);
1175c6c1daeSBarry Smith   PetscValidHeaderSpecific(*v,MATLABENGINE_CLASSID,1);
1185c6c1daeSBarry Smith   if (--((PetscObject)(*v))->refct > 0) PetscFunctionReturn(0);
1195f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscInfo(0,"Stopping MATLAB engine\n"));
120fc8a9adeSBarry Smith   ierr = engClose((*v)->ep);
121*28b400f6SJacob Faibussowitsch   PetscCheck(!ierr,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error closing Matlab engine");
1225f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscInfo(0,"MATLAB engine stopped\n"));
1235f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscHeaderDestroy(v));
1245c6c1daeSBarry Smith   PetscFunctionReturn(0);
1255c6c1daeSBarry Smith }
1265c6c1daeSBarry Smith 
1275c6c1daeSBarry Smith /*@C
1285c6c1daeSBarry Smith     PetscMatlabEngineEvaluate - Evaluates a string in MATLAB
1295c6c1daeSBarry Smith 
1305c6c1daeSBarry Smith     Not Collective
1315c6c1daeSBarry Smith 
1325c6c1daeSBarry Smith     Input Parameters:
1335c6c1daeSBarry Smith +   mengine - the MATLAB engine
1345c6c1daeSBarry Smith -   string - format as in a printf()
1355c6c1daeSBarry Smith 
136540acb9aSBarry Smith    Notes:
137540acb9aSBarry Smith      Run the PETSc program with -info to always have printed back MATLAB's response to the string evaluation
138540acb9aSBarry Smith 
1395c6c1daeSBarry Smith    Level: advanced
1405c6c1daeSBarry Smith 
1415c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
1425c6c1daeSBarry Smith           PetscMatlabEngineCreate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
1435c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
1445c6c1daeSBarry Smith @*/
1455c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEngineEvaluate(PetscMatlabEngine mengine,const char string[],...)
1465c6c1daeSBarry Smith {
1475c6c1daeSBarry Smith   va_list        Argp;
1485c6c1daeSBarry Smith   char           buffer[1024];
1495c6c1daeSBarry Smith   size_t         fullLength;
1505c6c1daeSBarry Smith 
1515c6c1daeSBarry Smith   PetscFunctionBegin;
1525c6c1daeSBarry Smith   va_start(Argp,string);
1535f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscVSNPrintf(buffer,sizeof(buffer)-9-5,string,&fullLength,Argp));
1545c6c1daeSBarry Smith   va_end(Argp);
1555c6c1daeSBarry Smith 
1565f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscInfo(0,"Evaluating MATLAB string: %s\n",buffer));
1575c6c1daeSBarry Smith   engEvalString(mengine->ep, buffer);
1585f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscInfo(0,"Done evaluating MATLAB string: %s\n",buffer));
1595f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscInfo(0,"  MATLAB output message: %s\n",mengine->buffer));
1605c6c1daeSBarry Smith 
1615c6c1daeSBarry Smith   /*
1625c6c1daeSBarry Smith      Check for error in MATLAB: indicated by ? as first character in engine->buffer
1635c6c1daeSBarry Smith   */
1642c71b3e2SJacob Faibussowitsch   PetscCheckFalse(mengine->buffer[4] == '?',PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in evaluating MATLAB command:%s\n%s",string,mengine->buffer);
1655c6c1daeSBarry Smith   PetscFunctionReturn(0);
1665c6c1daeSBarry Smith }
1675c6c1daeSBarry Smith 
1685c6c1daeSBarry Smith /*@C
1695c6c1daeSBarry Smith     PetscMatlabEngineGetOutput - Gets a string buffer where the MATLAB output is
1705c6c1daeSBarry Smith           printed
1715c6c1daeSBarry Smith 
1725c6c1daeSBarry Smith     Not Collective
1735c6c1daeSBarry Smith 
1745c6c1daeSBarry Smith     Input Parameter:
1755c6c1daeSBarry Smith .   mengine - the MATLAB engine
1765c6c1daeSBarry Smith 
1775c6c1daeSBarry Smith     Output Parameter:
1785c6c1daeSBarry Smith .   string - buffer where MATLAB output is printed
1795c6c1daeSBarry Smith 
1805c6c1daeSBarry Smith    Level: advanced
1815c6c1daeSBarry Smith 
1825c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
1835c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineCreate(), PetscMatlabEnginePrintOutput(),
1845c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
1855c6c1daeSBarry Smith @*/
1865c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEngineGetOutput(PetscMatlabEngine mengine,char **string)
1875c6c1daeSBarry Smith {
1885c6c1daeSBarry Smith   PetscFunctionBegin;
189*28b400f6SJacob Faibussowitsch   PetscCheck(mengine,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_MATLAB_ENGINE_() failed");
1905c6c1daeSBarry Smith   *string = mengine->buffer;
1915c6c1daeSBarry Smith   PetscFunctionReturn(0);
1925c6c1daeSBarry Smith }
1935c6c1daeSBarry Smith 
1945c6c1daeSBarry Smith /*@C
1955c6c1daeSBarry Smith     PetscMatlabEnginePrintOutput - prints the output from MATLAB
1965c6c1daeSBarry Smith 
1975c6c1daeSBarry Smith     Collective on PetscMatlabEngine
1985c6c1daeSBarry Smith 
1995c6c1daeSBarry Smith     Input Parameters:
2005c6c1daeSBarry Smith .    mengine - the Matlab engine
2015c6c1daeSBarry Smith 
2025c6c1daeSBarry Smith    Level: advanced
2035c6c1daeSBarry Smith 
2045c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
2055c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEngineCreate(),
2065c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
2075c6c1daeSBarry Smith @*/
2085c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEnginePrintOutput(PetscMatlabEngine mengine,FILE *fd)
2095c6c1daeSBarry Smith {
2105c6c1daeSBarry Smith   PetscMPIInt    rank;
2115c6c1daeSBarry Smith 
2125c6c1daeSBarry Smith   PetscFunctionBegin;
2135f80ce2aSJacob Faibussowitsch   PetscCheck(mengine,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_MATLAB_ENGINE_() failed");
2145f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)mengine),&rank));
2155f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSynchronizedFPrintf(PetscObjectComm((PetscObject)mengine),fd,"[%d]%s",rank,mengine->buffer));
2165f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSynchronizedFlush(PetscObjectComm((PetscObject)mengine),fd));
2175c6c1daeSBarry Smith   PetscFunctionReturn(0);
2185c6c1daeSBarry Smith }
2195c6c1daeSBarry Smith 
2205c6c1daeSBarry Smith /*@
2215c6c1daeSBarry Smith     PetscMatlabEnginePut - Puts a Petsc object into the MATLAB space. For parallel objects,
2225c6c1daeSBarry Smith       each processors part is put in a separate  MATLAB process.
2235c6c1daeSBarry Smith 
2245c6c1daeSBarry Smith     Collective on PetscObject
2255c6c1daeSBarry Smith 
2265c6c1daeSBarry Smith     Input Parameters:
2275c6c1daeSBarry Smith +    mengine - the MATLAB engine
2285c6c1daeSBarry Smith -    object - the PETSc object, for example Vec
2295c6c1daeSBarry Smith 
2305c6c1daeSBarry Smith    Level: advanced
2315c6c1daeSBarry Smith 
2328966356dSPierre Jolivet    Note: Mats transferred between PETSc and MATLAB and vis versa are transposed in the other space
233ddcfb6fcSBarry Smith          (this is because MATLAB uses compressed column format and PETSc uses compressed row format)
234ddcfb6fcSBarry Smith 
2355c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
2365c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
23769cdbcb9SBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
2385c6c1daeSBarry Smith @*/
2395c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEnginePut(PetscMatlabEngine mengine,PetscObject obj)
2405c6c1daeSBarry Smith {
2415f80ce2aSJacob Faibussowitsch   PetscErrorCode (*put)(PetscObject,void*);
2425c6c1daeSBarry Smith 
2435c6c1daeSBarry Smith   PetscFunctionBegin;
2445f80ce2aSJacob Faibussowitsch   PetscCheck(mengine,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_MATLAB_ENGINE_() failed");
2455f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",&put));
2465f80ce2aSJacob Faibussowitsch   PetscCheck(put,PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be put into MATLAB engine",obj->class_name);
2475f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscInfo(0,"Putting MATLAB object\n"));
2485f80ce2aSJacob Faibussowitsch   CHKERRQ((*put)(obj,mengine->ep));
2495f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscInfo(0,"Put MATLAB object: %s\n",obj->name));
2505c6c1daeSBarry Smith   PetscFunctionReturn(0);
2515c6c1daeSBarry Smith }
2525c6c1daeSBarry Smith 
2535c6c1daeSBarry Smith /*@
2545c6c1daeSBarry Smith     PetscMatlabEngineGet - Gets a variable from MATLAB into a PETSc object.
2555c6c1daeSBarry Smith 
2565c6c1daeSBarry Smith     Collective on PetscObject
2575c6c1daeSBarry Smith 
2585c6c1daeSBarry Smith     Input Parameters:
2595c6c1daeSBarry Smith +    mengine - the MATLAB engine
2605c6c1daeSBarry Smith -    object - the PETSc object, for example Vec
2615c6c1daeSBarry Smith 
2625c6c1daeSBarry Smith    Level: advanced
2635c6c1daeSBarry Smith 
2648966356dSPierre Jolivet    Note: Mats transferred between PETSc and MATLAB and vis versa are transposed in the other space
265ddcfb6fcSBarry Smith          (this is because MATLAB uses compressed column format and PETSc uses compressed row format)
266ddcfb6fcSBarry Smith 
2675c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
2685c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
26969cdbcb9SBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
2705c6c1daeSBarry Smith @*/
2715c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEngineGet(PetscMatlabEngine mengine,PetscObject obj)
2725c6c1daeSBarry Smith {
2735f80ce2aSJacob Faibussowitsch   PetscErrorCode (*get)(PetscObject,void*);
2745c6c1daeSBarry Smith 
2755c6c1daeSBarry Smith   PetscFunctionBegin;
2765f80ce2aSJacob Faibussowitsch   PetscCheck(mengine,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_MATLAB_ENGINE_() failed");
2775f80ce2aSJacob Faibussowitsch   PetscCheck(obj->name,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot get object that has no name");
2785f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",&get));
2795f80ce2aSJacob Faibussowitsch   PetscCheck(get,PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be gotten from MATLAB engine",obj->class_name);
2805f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscInfo(0,"Getting MATLAB object\n"));
2815f80ce2aSJacob Faibussowitsch   CHKERRQ((*get)(obj,mengine->ep));
2825f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscInfo(0,"Got MATLAB object: %s\n",obj->name));
2835c6c1daeSBarry Smith   PetscFunctionReturn(0);
2845c6c1daeSBarry Smith }
2855c6c1daeSBarry Smith 
2865c6c1daeSBarry Smith /*
2875c6c1daeSBarry Smith     The variable Petsc_Matlab_Engine_keyval is used to indicate an MPI attribute that
2885c6c1daeSBarry Smith   is attached to a communicator, in this case the attribute is a PetscMatlabEngine
2895c6c1daeSBarry Smith */
2905c6c1daeSBarry Smith static PetscMPIInt Petsc_Matlab_Engine_keyval = MPI_KEYVAL_INVALID;
2915c6c1daeSBarry Smith 
2925c6c1daeSBarry Smith /*@C
293540acb9aSBarry Smith    PETSC_MATLAB_ENGINE_ - Creates a MATLAB engine on each process in a communicator.
2945c6c1daeSBarry Smith 
2955c6c1daeSBarry Smith    Not Collective
2965c6c1daeSBarry Smith 
2975c6c1daeSBarry Smith    Input Parameter:
2985c6c1daeSBarry Smith .  comm - the MPI communicator to share the engine
2995c6c1daeSBarry Smith 
30057a177adSBarry Smith    Options Database:
30157a177adSBarry Smith .  -matlab_engine_host - hostname
30257a177adSBarry Smith 
3035c6c1daeSBarry Smith    Level: developer
3045c6c1daeSBarry Smith 
3055c6c1daeSBarry Smith    Notes:
3065c6c1daeSBarry Smith    Unlike almost all other PETSc routines, this does not return
3075c6c1daeSBarry Smith    an error code. Usually used in the form
3085c6c1daeSBarry Smith $      PetscMatlabEngineYYY(XXX object,PETSC_MATLAB_ENGINE_(comm));
3095c6c1daeSBarry Smith 
3105c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
3115c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
3125c6c1daeSBarry Smith           PetscMatlabEngineCreate(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine,
3135c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_WORLD, PETSC_MATLAB_ENGINE_SELF
3145c6c1daeSBarry Smith 
3155c6c1daeSBarry Smith @*/
3165c6c1daeSBarry Smith PetscMatlabEngine  PETSC_MATLAB_ENGINE_(MPI_Comm comm)
3175c6c1daeSBarry Smith {
3185c6c1daeSBarry Smith   PetscErrorCode    ierr;
3195c6c1daeSBarry Smith   PetscBool         flg;
3205c6c1daeSBarry Smith   PetscMatlabEngine mengine;
3215c6c1daeSBarry Smith 
3225c6c1daeSBarry Smith   PetscFunctionBegin;
3235c6c1daeSBarry Smith   if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) {
32412801b39SBarry Smith     ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0);
32557a177adSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
3265c6c1daeSBarry Smith   }
32747435625SJed Brown   ierr = MPI_Comm_get_attr(comm,Petsc_Matlab_Engine_keyval,(void**)&mengine,(int*)&flg);
32857a177adSBarry Smith   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
3295c6c1daeSBarry Smith   if (!flg) { /* viewer not yet created */
33057a177adSBarry Smith     ierr = PetscMatlabEngineCreate(comm,NULL,&mengine);
33157a177adSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
3325c6c1daeSBarry Smith     ierr = PetscObjectRegisterDestroy((PetscObject)mengine);
33357a177adSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
33447435625SJed Brown     ierr = MPI_Comm_set_attr(comm,Petsc_Matlab_Engine_keyval,mengine);
3352cb5e1ccSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
3365c6c1daeSBarry Smith   }
3375c6c1daeSBarry Smith   PetscFunctionReturn(mengine);
3385c6c1daeSBarry Smith }
3395c6c1daeSBarry Smith 
3405c6c1daeSBarry Smith /*@C
3415c6c1daeSBarry Smith     PetscMatlabEnginePutArray - Puts an array into the MATLAB space, treating it as a Fortran style (column major ordering) array. For parallel objects,
3425c6c1daeSBarry Smith       each processors part is put in a separate  MATLAB process.
3435c6c1daeSBarry Smith 
3445c6c1daeSBarry Smith     Collective on PetscObject
3455c6c1daeSBarry Smith 
3465c6c1daeSBarry Smith     Input Parameters:
3475c6c1daeSBarry Smith +    mengine - the MATLAB engine
3485c6c1daeSBarry Smith .    m,n - the dimensions of the array
3495c6c1daeSBarry Smith .    array - the array (represented in one dimension)
3505c6c1daeSBarry Smith -    name - the name of the array
3515c6c1daeSBarry Smith 
3525c6c1daeSBarry Smith    Level: advanced
3535c6c1daeSBarry Smith 
3545c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
3555c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
35669cdbcb9SBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePut(), PetscMatlabEngineGetArray(), PetscMatlabEngine
3575c6c1daeSBarry Smith @*/
3585c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEnginePutArray(PetscMatlabEngine mengine,int m,int n,const PetscScalar *array,const char name[])
3595c6c1daeSBarry Smith {
3605c6c1daeSBarry Smith   mxArray *mat;
3615c6c1daeSBarry Smith 
3625c6c1daeSBarry Smith   PetscFunctionBegin;
3635f80ce2aSJacob Faibussowitsch   PetscCheck(mengine,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_MATLAB_ENGINE_() failed");
3645f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscInfo(0,"Putting MATLAB array %s\n",name));
3655c6c1daeSBarry Smith #if !defined(PETSC_USE_COMPLEX)
3665c6c1daeSBarry Smith   mat = mxCreateDoubleMatrix(m,n,mxREAL);
3675c6c1daeSBarry Smith #else
3685c6c1daeSBarry Smith   mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
3695c6c1daeSBarry Smith #endif
3705f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscArraycpy(mxGetPr(mat),array,m*n));
3715c6c1daeSBarry Smith   engPutVariable(mengine->ep,name,mat);
3725c6c1daeSBarry Smith 
3735f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscInfo(0,"Put MATLAB array %s\n",name));
3745c6c1daeSBarry Smith   PetscFunctionReturn(0);
3755c6c1daeSBarry Smith }
3765c6c1daeSBarry Smith 
3775c6c1daeSBarry Smith /*@C
378540acb9aSBarry Smith     PetscMatlabEngineGetArray - Gets a variable from MATLAB into an array
3795c6c1daeSBarry Smith 
3805c6c1daeSBarry Smith     Not Collective
3815c6c1daeSBarry Smith 
3825c6c1daeSBarry Smith     Input Parameters:
383540acb9aSBarry Smith +    mengine - the MATLAB engine
3845c6c1daeSBarry Smith .    m,n - the dimensions of the array
3855c6c1daeSBarry Smith .    array - the array (represented in one dimension)
3865c6c1daeSBarry Smith -    name - the name of the array
3875c6c1daeSBarry Smith 
3885c6c1daeSBarry Smith    Level: advanced
3895c6c1daeSBarry Smith 
3905c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
3915c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
3925c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGet(), PetscMatlabEngine
3935c6c1daeSBarry Smith @*/
3945c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEngineGetArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,const char name[])
3955c6c1daeSBarry Smith {
3965c6c1daeSBarry Smith   mxArray        *mat;
3975c6c1daeSBarry Smith 
3985c6c1daeSBarry Smith   PetscFunctionBegin;
3995f80ce2aSJacob Faibussowitsch   PetscCheck(mengine,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_MATLAB_ENGINE_() failed");
4005f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscInfo(0,"Getting MATLAB array %s\n",name));
4015c6c1daeSBarry Smith   mat  = engGetVariable(mengine->ep,name);
4025f80ce2aSJacob Faibussowitsch   PetscCheck(mat,PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
4035f80ce2aSJacob Faibussowitsch   PetscCheck(mxGetM(mat) == (size_t) m,PETSC_COMM_SELF,PETSC_ERR_LIB,"Array %s in MATLAB first dimension %d does not match requested size %d",name,(int)mxGetM(mat),m);
4045f80ce2aSJacob Faibussowitsch   PetscCheck(mxGetN(mat) == (size_t) n,PETSC_COMM_SELF,PETSC_ERR_LIB,"Array %s in MATLAB second dimension %d does not match requested size %d",name,(int)mxGetN(mat),m);
4055f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscArraycpy(array,mxGetPr(mat),m*n));
4065f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscInfo(0,"Got MATLAB array %s\n",name));
4075c6c1daeSBarry Smith   PetscFunctionReturn(0);
4085c6c1daeSBarry Smith }
409