xref: /petsc/src/sys/classes/matlabengine/matlab.c (revision 2cb5e1cc91ad4e0472b8976614576d28ebef7100)
15c6c1daeSBarry Smith 
25c6c1daeSBarry 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
2957a177adSBarry Smith -    -matlab_engine_host - hostname, machine to run the MATLAB engine on
305c6c1daeSBarry Smith 
315c6c1daeSBarry Smith    Level: advanced
325c6c1daeSBarry Smith 
335c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
345c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
355c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
365c6c1daeSBarry Smith @*/
3757a177adSBarry Smith PetscErrorCode  PetscMatlabEngineCreate(MPI_Comm comm,const char host[],PetscMatlabEngine *mengine)
385c6c1daeSBarry Smith {
395c6c1daeSBarry Smith   PetscErrorCode    ierr;
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;
465c6c1daeSBarry Smith   if (MATLABENGINE_CLASSID == -1) {
475c6c1daeSBarry Smith     ierr = PetscClassIdRegister("MATLAB Engine",&MATLABENGINE_CLASSID);CHKERRQ(ierr);
485c6c1daeSBarry Smith   }
4973107ff1SLisandro Dalcin   ierr = PetscHeaderCreate(e,MATLABENGINE_CLASSID,"MatlabEngine","MATLAB Engine","Sys",comm,PetscMatlabEngineDestroy,NULL);CHKERRQ(ierr);
505c6c1daeSBarry Smith 
5157a177adSBarry Smith   if (!host) {
5257a177adSBarry Smith     char lhost[64];
5357a177adSBarry Smith 
5457a177adSBarry Smith     ierr = PetscOptionsGetString(NULL,NULL,"-matlab_engine_host",lhost,sizeof(lhost),&flg);CHKERRQ(ierr);
5557a177adSBarry Smith     if (flg) {host = lhost;}
56fc8a9adeSBarry Smith   }
5757a177adSBarry Smith   flg = PETSC_FALSE;
5857a177adSBarry Smith   ierr = PetscOptionsGetBool(NULL,NULL,"-matlab_engine_graphics",&flg,NULL);CHKERRQ(ierr);
5957a177adSBarry Smith 
6057a177adSBarry Smith   if (host) {
6157a177adSBarry Smith     ierr  = PetscInfo1(0,"Starting MATLAB engine on %s\n",host);CHKERRQ(ierr);
6257a177adSBarry Smith   } else {
6357a177adSBarry Smith 
6457a177adSBarry Smith   }
6557a177adSBarry Smith   if (host) {
6657a177adSBarry Smith     ierr = PetscStrcpy(buffer,"ssh ");CHKERRQ(ierr);
6757a177adSBarry Smith     ierr = PetscStrcat(buffer,host);CHKERRQ(ierr);
6857a177adSBarry Smith     ierr = PetscStrcat(buffer," \"");CHKERRQ(ierr);
6957a177adSBarry Smith     ierr = PetscStrlcat(buffer,PETSC_MATLAB_COMMAND,sizeof(buffer));CHKERRQ(ierr);
7057a177adSBarry Smith     if (!flg) {
7157a177adSBarry Smith       ierr = PetscStrlcat(buffer," -nodisplay ",sizeof(buffer));CHKERRQ(ierr);
7257a177adSBarry Smith     }
7357a177adSBarry Smith     ierr  = PetscStrlcat(buffer," -nosplash ",sizeof(buffer));CHKERRQ(ierr);
7457a177adSBarry Smith     ierr = PetscStrcat(buffer,"\"");CHKERRQ(ierr);
7557a177adSBarry Smith   } else {
76a126751eSBarry Smith     ierr = PetscStrncpy(buffer,PETSC_MATLAB_COMMAND,sizeof(buffer));CHKERRQ(ierr);
775c6c1daeSBarry Smith     if (!flg) {
78a126751eSBarry Smith       ierr = PetscStrlcat(buffer," -nodisplay ",sizeof(buffer));CHKERRQ(ierr);
795c6c1daeSBarry Smith     }
80fc8a9adeSBarry Smith     ierr  = PetscStrlcat(buffer," -nosplash ",sizeof(buffer));CHKERRQ(ierr);
81fc8a9adeSBarry Smith   }
8257a177adSBarry Smith   ierr  = PetscInfo1(0,"Starting MATLAB engine with command %s\n",buffer);CHKERRQ(ierr);
835c6c1daeSBarry Smith   e->ep = engOpen(buffer);
8457a177adSBarry Smith   if (!e->ep) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to start MATLAB engine with %s",buffer);
855c6c1daeSBarry Smith   engOutputBuffer(e->ep,e->buffer,1024);
865c6c1daeSBarry Smith 
875c6c1daeSBarry Smith   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
885c6c1daeSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
895c6c1daeSBarry Smith   sprintf(buffer,"MPI_Comm_rank = %d; MPI_Comm_size = %d;\n",rank,size);
905c6c1daeSBarry Smith   engEvalString(e->ep, buffer);
9157a177adSBarry Smith   if (host) {
9257a177adSBarry Smith     ierr = PetscInfo1(0,"Started MATLAB engine on %s\n",host);CHKERRQ(ierr);
93fc8a9adeSBarry Smith   } else {
94fc8a9adeSBarry Smith     ierr = PetscInfo(0,"Started MATLAB engine\n");CHKERRQ(ierr);
95fc8a9adeSBarry Smith   }
965c6c1daeSBarry Smith   *mengine = e;
975c6c1daeSBarry Smith   PetscFunctionReturn(0);
985c6c1daeSBarry Smith }
995c6c1daeSBarry Smith 
1005c6c1daeSBarry Smith /*@
101fc8a9adeSBarry Smith    PetscMatlabEngineDestroy - Shuts down a Matlab engine.
1025c6c1daeSBarry Smith 
1035c6c1daeSBarry Smith    Collective on PetscMatlabEngine
1045c6c1daeSBarry Smith 
1055c6c1daeSBarry Smith    Input Parameters:
1065c6c1daeSBarry Smith .  e  - the engine
1075c6c1daeSBarry Smith 
1085c6c1daeSBarry Smith    Level: advanced
1095c6c1daeSBarry Smith 
11069cdbcb9SBarry Smith .seealso: PetscMatlabEngineCreate(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
1115c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
1125c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
1135c6c1daeSBarry Smith @*/
1145c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEngineDestroy(PetscMatlabEngine *v)
1155c6c1daeSBarry Smith {
1165c6c1daeSBarry Smith   PetscErrorCode ierr;
1175fd66863SKarl Rupp 
1185c6c1daeSBarry Smith   PetscFunctionBegin;
1195c6c1daeSBarry Smith   if (!*v) PetscFunctionReturn(0);
1205c6c1daeSBarry Smith   PetscValidHeaderSpecific(*v,MATLABENGINE_CLASSID,1);
1215c6c1daeSBarry Smith   if (--((PetscObject)(*v))->refct > 0) PetscFunctionReturn(0);
122fc8a9adeSBarry Smith   ierr = PetscInfo(0,"Stopping MATLAB engine\n");CHKERRQ(ierr);
123fc8a9adeSBarry Smith   ierr = engClose((*v)->ep);
124fc8a9adeSBarry Smith   if (ierr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error closing Matlab engine");
125fc8a9adeSBarry Smith   ierr = PetscInfo(0,"MATLAB engine stopped\n");CHKERRQ(ierr);
1265c6c1daeSBarry Smith   ierr = PetscHeaderDestroy(v);CHKERRQ(ierr);
1275c6c1daeSBarry Smith   PetscFunctionReturn(0);
1285c6c1daeSBarry Smith }
1295c6c1daeSBarry Smith 
1305c6c1daeSBarry Smith /*@C
1315c6c1daeSBarry Smith     PetscMatlabEngineEvaluate - Evaluates a string in MATLAB
1325c6c1daeSBarry Smith 
1335c6c1daeSBarry Smith     Not Collective
1345c6c1daeSBarry Smith 
1355c6c1daeSBarry Smith     Input Parameters:
1365c6c1daeSBarry Smith +   mengine - the MATLAB engine
1375c6c1daeSBarry Smith -   string - format as in a printf()
1385c6c1daeSBarry 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   PetscErrorCode ierr;
1505c6c1daeSBarry Smith   size_t         fullLength;
1515c6c1daeSBarry Smith 
1525c6c1daeSBarry Smith   PetscFunctionBegin;
1535c6c1daeSBarry Smith   va_start(Argp,string);
1545c6c1daeSBarry Smith   ierr = PetscVSNPrintf(buffer,1024-9-5,string,&fullLength,Argp);CHKERRQ(ierr);
1555c6c1daeSBarry Smith   va_end(Argp);
1565c6c1daeSBarry Smith 
1575c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Evaluating MATLAB string: %s\n",buffer);CHKERRQ(ierr);
1585c6c1daeSBarry Smith   engEvalString(mengine->ep, buffer);
1595c6c1daeSBarry Smith 
1605c6c1daeSBarry Smith   /*
1615c6c1daeSBarry Smith      Check for error in MATLAB: indicated by ? as first character in engine->buffer
1625c6c1daeSBarry Smith   */
163f23aa3ddSBarry Smith   if (mengine->buffer[4] == '?') SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in evaluating MATLAB command:%s\n%s",string,mengine->buffer);
1645c6c1daeSBarry Smith 
1655c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Done evaluating Matlab string: %s\n",buffer);CHKERRQ(ierr);
1665c6c1daeSBarry Smith   PetscFunctionReturn(0);
1675c6c1daeSBarry Smith }
1685c6c1daeSBarry Smith 
1695c6c1daeSBarry Smith /*@C
1705c6c1daeSBarry Smith     PetscMatlabEngineGetOutput - Gets a string buffer where the MATLAB output is
1715c6c1daeSBarry Smith           printed
1725c6c1daeSBarry Smith 
1735c6c1daeSBarry Smith     Not Collective
1745c6c1daeSBarry Smith 
1755c6c1daeSBarry Smith     Input Parameter:
1765c6c1daeSBarry Smith .   mengine - the MATLAB engine
1775c6c1daeSBarry Smith 
1785c6c1daeSBarry Smith     Output Parameter:
1795c6c1daeSBarry Smith .   string - buffer where MATLAB output is printed
1805c6c1daeSBarry Smith 
1815c6c1daeSBarry Smith    Level: advanced
1825c6c1daeSBarry Smith 
1835c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
1845c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineCreate(), PetscMatlabEnginePrintOutput(),
1855c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
1865c6c1daeSBarry Smith @*/
1875c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEngineGetOutput(PetscMatlabEngine mengine,char **string)
1885c6c1daeSBarry Smith {
1895c6c1daeSBarry Smith   PetscFunctionBegin;
19057a177adSBarry Smith   if (!mengine) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_MATLAB_ENGINE_() failed");
1915c6c1daeSBarry Smith   *string = mengine->buffer;
1925c6c1daeSBarry Smith   PetscFunctionReturn(0);
1935c6c1daeSBarry Smith }
1945c6c1daeSBarry Smith 
1955c6c1daeSBarry Smith /*@C
1965c6c1daeSBarry Smith     PetscMatlabEnginePrintOutput - prints the output from MATLAB
1975c6c1daeSBarry Smith 
1985c6c1daeSBarry Smith     Collective on PetscMatlabEngine
1995c6c1daeSBarry Smith 
2005c6c1daeSBarry Smith     Input Parameters:
2015c6c1daeSBarry Smith .    mengine - the Matlab engine
2025c6c1daeSBarry Smith 
2035c6c1daeSBarry Smith    Level: advanced
2045c6c1daeSBarry Smith 
2055c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
2065c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEngineCreate(),
2075c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
2085c6c1daeSBarry Smith @*/
2095c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEnginePrintOutput(PetscMatlabEngine mengine,FILE *fd)
2105c6c1daeSBarry Smith {
2115c6c1daeSBarry Smith   PetscErrorCode ierr;
2125c6c1daeSBarry Smith   PetscMPIInt    rank;
2135c6c1daeSBarry Smith 
2145c6c1daeSBarry Smith   PetscFunctionBegin;
21557a177adSBarry Smith   if (!mengine) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_MATLAB_ENGINE_() failed");
216ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mengine),&rank);CHKERRQ(ierr);
217ce94432eSBarry Smith   ierr = PetscSynchronizedFPrintf(PetscObjectComm((PetscObject)mengine),fd,"[%d]%s",rank,mengine->buffer);CHKERRQ(ierr);
2180ec8b6e3SBarry Smith   ierr = PetscSynchronizedFlush(PetscObjectComm((PetscObject)mengine),fd);CHKERRQ(ierr);
2195c6c1daeSBarry Smith   PetscFunctionReturn(0);
2205c6c1daeSBarry Smith }
2215c6c1daeSBarry Smith 
2225c6c1daeSBarry Smith /*@
2235c6c1daeSBarry Smith     PetscMatlabEnginePut - Puts a Petsc object into the MATLAB space. For parallel objects,
2245c6c1daeSBarry Smith       each processors part is put in a separate  MATLAB process.
2255c6c1daeSBarry Smith 
2265c6c1daeSBarry Smith     Collective on PetscObject
2275c6c1daeSBarry Smith 
2285c6c1daeSBarry Smith     Input Parameters:
2295c6c1daeSBarry Smith +    mengine - the MATLAB engine
2305c6c1daeSBarry Smith -    object - the PETSc object, for example Vec
2315c6c1daeSBarry Smith 
2325c6c1daeSBarry Smith    Level: advanced
2335c6c1daeSBarry Smith 
2348966356dSPierre Jolivet    Note: Mats transferred between PETSc and MATLAB and vis versa are transposed in the other space
235ddcfb6fcSBarry Smith          (this is because MATLAB uses compressed column format and PETSc uses compressed row format)
236ddcfb6fcSBarry Smith 
2375c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
2385c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
23969cdbcb9SBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
2405c6c1daeSBarry Smith @*/
2415c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEnginePut(PetscMatlabEngine mengine,PetscObject obj)
2425c6c1daeSBarry Smith {
2435c6c1daeSBarry Smith   PetscErrorCode ierr,(*put)(PetscObject,void*);
2445c6c1daeSBarry Smith 
2455c6c1daeSBarry Smith   PetscFunctionBegin;
24657a177adSBarry Smith   if (!mengine) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_MATLAB_ENGINE_() failed");
2470005d66cSJed Brown   ierr = PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",&put);CHKERRQ(ierr);
2485c6c1daeSBarry Smith   if (!put) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be put into MATLAB engine",obj->class_name);
2495c6c1daeSBarry Smith   ierr = PetscInfo(0,"Putting MATLAB object\n");CHKERRQ(ierr);
2505c6c1daeSBarry Smith   ierr = (*put)(obj,mengine->ep);CHKERRQ(ierr);
2515c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Put MATLAB object: %s\n",obj->name);CHKERRQ(ierr);
2525c6c1daeSBarry Smith   PetscFunctionReturn(0);
2535c6c1daeSBarry Smith }
2545c6c1daeSBarry Smith 
2555c6c1daeSBarry Smith /*@
2565c6c1daeSBarry Smith     PetscMatlabEngineGet - Gets a variable from MATLAB into a PETSc object.
2575c6c1daeSBarry Smith 
2585c6c1daeSBarry Smith     Collective on PetscObject
2595c6c1daeSBarry Smith 
2605c6c1daeSBarry Smith     Input Parameters:
2615c6c1daeSBarry Smith +    mengine - the MATLAB engine
2625c6c1daeSBarry Smith -    object - the PETSc object, for example Vec
2635c6c1daeSBarry Smith 
2645c6c1daeSBarry Smith    Level: advanced
2655c6c1daeSBarry Smith 
2668966356dSPierre Jolivet    Note: Mats transferred between PETSc and MATLAB and vis versa are transposed in the other space
267ddcfb6fcSBarry Smith          (this is because MATLAB uses compressed column format and PETSc uses compressed row format)
268ddcfb6fcSBarry Smith 
2695c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
2705c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
27169cdbcb9SBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
2725c6c1daeSBarry Smith @*/
2735c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEngineGet(PetscMatlabEngine mengine,PetscObject obj)
2745c6c1daeSBarry Smith {
2755c6c1daeSBarry Smith   PetscErrorCode ierr,(*get)(PetscObject,void*);
2765c6c1daeSBarry Smith 
2775c6c1daeSBarry Smith   PetscFunctionBegin;
27857a177adSBarry Smith   if (!mengine) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_MATLAB_ENGINE_() failed");
2795c6c1daeSBarry Smith   if (!obj->name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot get object that has no name");
2800005d66cSJed Brown   ierr = PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",&get);CHKERRQ(ierr);
2815c6c1daeSBarry Smith   if (!get) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be gotten from MATLAB engine",obj->class_name);
2825c6c1daeSBarry Smith   ierr = PetscInfo(0,"Getting MATLAB object\n");CHKERRQ(ierr);
2835c6c1daeSBarry Smith   ierr = (*get)(obj,mengine->ep);CHKERRQ(ierr);
2845c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Got MATLAB object: %s\n",obj->name);CHKERRQ(ierr);
2855c6c1daeSBarry Smith   PetscFunctionReturn(0);
2865c6c1daeSBarry Smith }
2875c6c1daeSBarry Smith 
2885c6c1daeSBarry Smith /*
2895c6c1daeSBarry Smith     The variable Petsc_Matlab_Engine_keyval is used to indicate an MPI attribute that
2905c6c1daeSBarry Smith   is attached to a communicator, in this case the attribute is a PetscMatlabEngine
2915c6c1daeSBarry Smith */
2925c6c1daeSBarry Smith static PetscMPIInt Petsc_Matlab_Engine_keyval = MPI_KEYVAL_INVALID;
2935c6c1daeSBarry Smith 
2945c6c1daeSBarry Smith 
2955c6c1daeSBarry Smith /*@C
29657a177adSBarry Smith    PETSC_MATLAB_ENGINE_ - Creates a matlab engine on each process in a communicator.
2975c6c1daeSBarry Smith 
2985c6c1daeSBarry Smith    Not Collective
2995c6c1daeSBarry Smith 
3005c6c1daeSBarry Smith    Input Parameter:
3015c6c1daeSBarry Smith .  comm - the MPI communicator to share the engine
3025c6c1daeSBarry Smith 
30357a177adSBarry Smith    Options Database:
30457a177adSBarry Smith .  -matlab_engine_host - hostname
30557a177adSBarry Smith 
3065c6c1daeSBarry Smith    Level: developer
3075c6c1daeSBarry Smith 
3085c6c1daeSBarry Smith    Notes:
3095c6c1daeSBarry Smith    Unlike almost all other PETSc routines, this does not return
3105c6c1daeSBarry Smith    an error code. Usually used in the form
3115c6c1daeSBarry Smith $      PetscMatlabEngineYYY(XXX object,PETSC_MATLAB_ENGINE_(comm));
3125c6c1daeSBarry Smith 
3135c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
3145c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
3155c6c1daeSBarry Smith           PetscMatlabEngineCreate(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine,
3165c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_WORLD, PETSC_MATLAB_ENGINE_SELF
3175c6c1daeSBarry Smith 
3185c6c1daeSBarry Smith @*/
3195c6c1daeSBarry Smith PetscMatlabEngine  PETSC_MATLAB_ENGINE_(MPI_Comm comm)
3205c6c1daeSBarry Smith {
3215c6c1daeSBarry Smith   PetscErrorCode    ierr;
3225c6c1daeSBarry Smith   PetscBool         flg;
3235c6c1daeSBarry Smith   PetscMatlabEngine mengine;
3245c6c1daeSBarry Smith 
3255c6c1daeSBarry Smith   PetscFunctionBegin;
3265c6c1daeSBarry Smith   if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) {
32712801b39SBarry Smith     ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0);
32857a177adSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
3295c6c1daeSBarry Smith   }
33047435625SJed Brown   ierr = MPI_Comm_get_attr(comm,Petsc_Matlab_Engine_keyval,(void**)&mengine,(int*)&flg);
33157a177adSBarry Smith   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
3325c6c1daeSBarry Smith   if (!flg) { /* viewer not yet created */
33357a177adSBarry Smith     ierr = PetscMatlabEngineCreate(comm,NULL,&mengine);
33457a177adSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
3355c6c1daeSBarry Smith     ierr = PetscObjectRegisterDestroy((PetscObject)mengine);
33657a177adSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
33747435625SJed Brown     ierr = MPI_Comm_set_attr(comm,Petsc_Matlab_Engine_keyval,mengine);
338*2cb5e1ccSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
3395c6c1daeSBarry Smith   }
3405c6c1daeSBarry Smith   PetscFunctionReturn(mengine);
3415c6c1daeSBarry Smith }
3425c6c1daeSBarry Smith 
3435c6c1daeSBarry Smith /*@C
3445c6c1daeSBarry Smith     PetscMatlabEnginePutArray - Puts an array into the MATLAB space, treating it as a Fortran style (column major ordering) array. For parallel objects,
3455c6c1daeSBarry Smith       each processors part is put in a separate  MATLAB process.
3465c6c1daeSBarry Smith 
3475c6c1daeSBarry Smith     Collective on PetscObject
3485c6c1daeSBarry Smith 
3495c6c1daeSBarry Smith     Input Parameters:
3505c6c1daeSBarry Smith +    mengine - the MATLAB engine
3515c6c1daeSBarry Smith .    m,n - the dimensions of the array
3525c6c1daeSBarry Smith .    array - the array (represented in one dimension)
3535c6c1daeSBarry Smith -    name - the name of the array
3545c6c1daeSBarry Smith 
3555c6c1daeSBarry Smith    Level: advanced
3565c6c1daeSBarry Smith 
3575c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
3585c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
35969cdbcb9SBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePut(), PetscMatlabEngineGetArray(), PetscMatlabEngine
3605c6c1daeSBarry Smith @*/
3615c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEnginePutArray(PetscMatlabEngine mengine,int m,int n,const PetscScalar *array,const char name[])
3625c6c1daeSBarry Smith {
3635c6c1daeSBarry Smith   PetscErrorCode ierr;
3645c6c1daeSBarry Smith   mxArray        *mat;
3655c6c1daeSBarry Smith 
3665c6c1daeSBarry Smith   PetscFunctionBegin;
36757a177adSBarry Smith   if (!mengine) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_MATLAB_ENGINE_() failed");
3685c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Putting MATLAB array %s\n",name);CHKERRQ(ierr);
3695c6c1daeSBarry Smith #if !defined(PETSC_USE_COMPLEX)
3705c6c1daeSBarry Smith   mat = mxCreateDoubleMatrix(m,n,mxREAL);
3715c6c1daeSBarry Smith #else
3725c6c1daeSBarry Smith   mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
3735c6c1daeSBarry Smith #endif
374580bdb30SBarry Smith   ierr = PetscArraycpy(mxGetPr(mat),array,m*n);CHKERRQ(ierr);
3755c6c1daeSBarry Smith   engPutVariable(mengine->ep,name,mat);
3765c6c1daeSBarry Smith 
3775c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Put MATLAB array %s\n",name);CHKERRQ(ierr);
3785c6c1daeSBarry Smith   PetscFunctionReturn(0);
3795c6c1daeSBarry Smith }
3805c6c1daeSBarry Smith 
3815c6c1daeSBarry Smith /*@C
3825c6c1daeSBarry Smith     PetscMatlabEngineGetArray - Gets a variable from Matlab into an array
3835c6c1daeSBarry Smith 
3845c6c1daeSBarry Smith     Not Collective
3855c6c1daeSBarry Smith 
3865c6c1daeSBarry Smith     Input Parameters:
3875c6c1daeSBarry Smith +    mengine - the Matlab engine
3885c6c1daeSBarry Smith .    m,n - the dimensions of the array
3895c6c1daeSBarry Smith .    array - the array (represented in one dimension)
3905c6c1daeSBarry Smith -    name - the name of the array
3915c6c1daeSBarry Smith 
3925c6c1daeSBarry Smith    Level: advanced
3935c6c1daeSBarry Smith 
3945c6c1daeSBarry Smith .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
3955c6c1daeSBarry Smith           PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
3965c6c1daeSBarry Smith           PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGet(), PetscMatlabEngine
3975c6c1daeSBarry Smith @*/
3985c6c1daeSBarry Smith PetscErrorCode  PetscMatlabEngineGetArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,const char name[])
3995c6c1daeSBarry Smith {
4005c6c1daeSBarry Smith   PetscErrorCode ierr;
4015c6c1daeSBarry Smith   mxArray        *mat;
4025c6c1daeSBarry Smith 
4035c6c1daeSBarry Smith   PetscFunctionBegin;
40457a177adSBarry Smith   if (!mengine) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_MATLAB_ENGINE_() failed");
4055c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Getting MATLAB array %s\n",name);CHKERRQ(ierr);
4065c6c1daeSBarry Smith   mat  = engGetVariable(mengine->ep,name);
4075c6c1daeSBarry Smith   if (!mat) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
40869cdbcb9SBarry Smith   if (mxGetM(mat) != (size_t) m) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_LIB,"Array %s in matlab first dimension %d does not match requested size %d",name,(int)mxGetM(mat),m);
40969cdbcb9SBarry Smith   if (mxGetN(mat) != (size_t) n) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_LIB,"Array %s in matlab second dimension %d does not match requested size %d",name,(int)mxGetN(mat),m);
410580bdb30SBarry Smith   ierr = PetscArraycpy(array,mxGetPr(mat),m*n);CHKERRQ(ierr);
4115c6c1daeSBarry Smith   ierr = PetscInfo1(0,"Got MATLAB array %s\n",name);CHKERRQ(ierr);
4125c6c1daeSBarry Smith   PetscFunctionReturn(0);
4135c6c1daeSBarry Smith }
4145c6c1daeSBarry Smith 
4155c6c1daeSBarry Smith 
4165c6c1daeSBarry Smith 
4175c6c1daeSBarry Smith 
41869cdbcb9SBarry Smith 
41969cdbcb9SBarry Smith 
420