Actual source code: matlab.c
2: #include <engine.h> /* MATLAB include file */
3: #include <petscsys.h>
4: #include <petscmatlab.h>
5: #include <petsc/private/petscimpl.h>
7: struct _p_PetscMatlabEngine {
8: PETSCHEADER(int);
9: Engine *ep;
10: char buffer[1024];
11: };
13: PetscClassId MATLABENGINE_CLASSID = -1;
15: /*@C
16: PetscMatlabEngineCreate - Creates a MATLAB engine object
18: Not Collective
20: Input Parameters:
21: + comm - a separate MATLAB engine is started for each process in the communicator
22: - host - name of machine where MATLAB engine is to be run (usually NULL)
24: Output Parameter:
25: . mengine - the resulting object
27: Options Database:
28: + -matlab_engine_graphics - allow the MATLAB engine to display graphics
29: . -matlab_engine_host - hostname, machine to run the MATLAB engine on
30: - -info - print out all requests to MATLAB and all if its responses (for debugging)
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 host[],PetscMatlabEngine *mengine)
39: {
40: PetscMPIInt rank,size;
41: char buffer[256];
42: PetscMatlabEngine e;
43: PetscBool flg = PETSC_FALSE;
45: if (MATLABENGINE_CLASSID == -1) PetscClassIdRegister("MATLAB Engine",&MATLABENGINE_CLASSID);
46: PetscHeaderCreate(e,MATLABENGINE_CLASSID,"MatlabEngine","MATLAB Engine","Sys",comm,PetscMatlabEngineDestroy,NULL);
48: if (!host) {
49: char lhost[64];
51: PetscOptionsGetString(NULL,NULL,"-matlab_engine_host",lhost,sizeof(lhost),&flg);
52: if (flg) {host = lhost;}
53: }
54: flg = PETSC_FALSE;
55: PetscOptionsGetBool(NULL,NULL,"-matlab_engine_graphics",&flg,NULL);
57: if (host) {
58: PetscInfo(0,"Starting MATLAB engine on %s\n",host);
59: } else {
61: }
62: if (host) {
63: PetscStrcpy(buffer,"ssh ");
64: PetscStrcat(buffer,host);
65: PetscStrcat(buffer," \"");
66: PetscStrlcat(buffer,PETSC_MATLAB_COMMAND,sizeof(buffer));
67: if (!flg) {
68: PetscStrlcat(buffer," -nodisplay ",sizeof(buffer));
69: }
70: PetscStrlcat(buffer," -nosplash ",sizeof(buffer));
71: PetscStrcat(buffer,"\"");
72: } else {
73: PetscStrncpy(buffer,PETSC_MATLAB_COMMAND,sizeof(buffer));
74: if (!flg) {
75: PetscStrlcat(buffer," -nodisplay ",sizeof(buffer));
76: }
77: PetscStrlcat(buffer," -nosplash ",sizeof(buffer));
78: }
79: PetscInfo(0,"Starting MATLAB engine with command %s\n",buffer);
80: e->ep = engOpen(buffer);
82: engOutputBuffer(e->ep,e->buffer,sizeof(e->buffer));
83: if (host) {
84: PetscInfo(0,"Started MATLAB engine on %s\n",host);
85: } else {
86: PetscInfo(0,"Started MATLAB engine\n");
87: }
89: MPI_Comm_rank(comm,&rank);
90: MPI_Comm_size(comm,&size);
91: PetscMatlabEngineEvaluate(e,"MPI_Comm_rank = %d; MPI_Comm_size = %d;\n",rank,size);
92: *mengine = e;
93: return 0;
94: }
96: /*@
97: PetscMatlabEngineDestroy - Shuts down a MATLAB engine.
99: Collective on PetscMatlabEngine
101: Input Parameters:
102: . e - the engine
104: Level: advanced
106: .seealso: PetscMatlabEngineCreate(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
107: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
108: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
109: @*/
110: PetscErrorCode PetscMatlabEngineDestroy(PetscMatlabEngine *v)
111: {
114: if (!*v) return 0;
116: if (--((PetscObject)(*v))->refct > 0) return 0;
117: PetscInfo(0,"Stopping MATLAB engine\n");
118: engClose((*v)->ep);
120: PetscInfo(0,"MATLAB engine stopped\n");
121: PetscHeaderDestroy(v);
122: return 0;
123: }
125: /*@C
126: PetscMatlabEngineEvaluate - Evaluates a string in MATLAB
128: Not Collective
130: Input Parameters:
131: + mengine - the MATLAB engine
132: - string - format as in a printf()
134: Notes:
135: Run the PETSc program with -info to always have printed back MATLAB's response to the string evaluation
137: Level: advanced
139: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
140: PetscMatlabEngineCreate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
141: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
142: @*/
143: PetscErrorCode PetscMatlabEngineEvaluate(PetscMatlabEngine mengine,const char string[],...)
144: {
145: va_list Argp;
146: char buffer[1024];
147: size_t fullLength;
149: va_start(Argp,string);
150: PetscVSNPrintf(buffer,sizeof(buffer)-9-5,string,&fullLength,Argp);
151: va_end(Argp);
153: PetscInfo(0,"Evaluating MATLAB string: %s\n",buffer);
154: engEvalString(mengine->ep, buffer);
155: PetscInfo(0,"Done evaluating MATLAB string: %s\n",buffer);
156: PetscInfo(0," MATLAB output message: %s\n",mengine->buffer);
158: /*
159: Check for error in MATLAB: indicated by ? as first character in engine->buffer
160: */
162: return 0;
163: }
165: /*@C
166: PetscMatlabEngineGetOutput - Gets a string buffer where the MATLAB output is
167: printed
169: Not Collective
171: Input Parameter:
172: . mengine - the MATLAB engine
174: Output Parameter:
175: . string - buffer where MATLAB output is printed
177: Level: advanced
179: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
180: PetscMatlabEngineEvaluate(), PetscMatlabEngineCreate(), PetscMatlabEnginePrintOutput(),
181: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
182: @*/
183: PetscErrorCode PetscMatlabEngineGetOutput(PetscMatlabEngine mengine,char **string)
184: {
186: *string = mengine->buffer;
187: return 0;
188: }
190: /*@C
191: PetscMatlabEnginePrintOutput - prints the output from MATLAB
193: Collective on PetscMatlabEngine
195: Input Parameters:
196: . mengine - the Matlab engine
198: Level: advanced
200: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
201: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEngineCreate(),
202: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
203: @*/
204: PetscErrorCode PetscMatlabEnginePrintOutput(PetscMatlabEngine mengine,FILE *fd)
205: {
206: PetscMPIInt rank;
209: MPI_Comm_rank(PetscObjectComm((PetscObject)mengine),&rank);
210: PetscSynchronizedFPrintf(PetscObjectComm((PetscObject)mengine),fd,"[%d]%s",rank,mengine->buffer);
211: PetscSynchronizedFlush(PetscObjectComm((PetscObject)mengine),fd);
212: return 0;
213: }
215: /*@
216: PetscMatlabEnginePut - Puts a Petsc object into the MATLAB space. For parallel objects,
217: each processors part is put in a separate MATLAB process.
219: Collective on PetscObject
221: Input Parameters:
222: + mengine - the MATLAB engine
223: - object - the PETSc object, for example Vec
225: Level: advanced
227: Note: Mats transferred between PETSc and MATLAB and vis versa are transposed in the other space
228: (this is because MATLAB uses compressed column format and PETSc uses compressed row format)
230: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
231: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
232: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
233: @*/
234: PetscErrorCode PetscMatlabEnginePut(PetscMatlabEngine mengine,PetscObject obj)
235: {
236: PetscErrorCode (*put)(PetscObject,void*);
239: PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",&put);
241: PetscInfo(0,"Putting MATLAB object\n");
242: (*put)(obj,mengine->ep);
243: PetscInfo(0,"Put MATLAB object: %s\n",obj->name);
244: return 0;
245: }
247: /*@
248: PetscMatlabEngineGet - Gets a variable from MATLAB into a PETSc object.
250: Collective on PetscObject
252: Input Parameters:
253: + mengine - the MATLAB engine
254: - object - the PETSc object, for example Vec
256: Level: advanced
258: Note: Mats transferred between PETSc and MATLAB and vis versa are transposed in the other space
259: (this is because MATLAB uses compressed column format and PETSc uses compressed row format)
261: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
262: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
263: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
264: @*/
265: PetscErrorCode PetscMatlabEngineGet(PetscMatlabEngine mengine,PetscObject obj)
266: {
267: PetscErrorCode (*get)(PetscObject,void*);
271: PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",&get);
273: PetscInfo(0,"Getting MATLAB object\n");
274: (*get)(obj,mengine->ep);
275: PetscInfo(0,"Got MATLAB object: %s\n",obj->name);
276: return 0;
277: }
279: /*
280: The variable Petsc_Matlab_Engine_keyval is used to indicate an MPI attribute that
281: is attached to a communicator, in this case the attribute is a PetscMatlabEngine
282: */
283: static PetscMPIInt Petsc_Matlab_Engine_keyval = MPI_KEYVAL_INVALID;
285: /*@C
286: PETSC_MATLAB_ENGINE_ - Creates a MATLAB engine on each process in a communicator.
288: Not Collective
290: Input Parameter:
291: . comm - the MPI communicator to share the engine
293: Options Database:
294: . -matlab_engine_host - hostname
296: Level: developer
298: Notes:
299: Unlike almost all other PETSc routines, this does not return
300: an error code. Usually used in the form
301: $ PetscMatlabEngineYYY(XXX object,PETSC_MATLAB_ENGINE_(comm));
303: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
304: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
305: PetscMatlabEngineCreate(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine,
306: PETSC_MATLAB_ENGINE_WORLD, PETSC_MATLAB_ENGINE_SELF
308: @*/
309: PetscMatlabEngine PETSC_MATLAB_ENGINE_(MPI_Comm comm)
310: {
311: PetscErrorCode ierr;
312: PetscBool flg;
313: PetscMatlabEngine mengine;
315: if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) {
316: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0);
317: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return NULL;}
318: }
319: MPI_Comm_get_attr(comm,Petsc_Matlab_Engine_keyval,(void**)&mengine,(int*)&flg);
320: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return NULL;}
321: if (!flg) { /* viewer not yet created */
322: PetscMatlabEngineCreate(comm,NULL,&mengine);
323: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");return NULL;}
324: PetscObjectRegisterDestroy((PetscObject)mengine);
325: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");return NULL;}
326: MPI_Comm_set_attr(comm,Petsc_Matlab_Engine_keyval,mengine);
327: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return NULL;}
328: }
329: return mengine;
330: }
332: /*@C
333: PetscMatlabEnginePutArray - Puts an array into the MATLAB space, treating it as a Fortran style (column major ordering) array. For parallel objects,
334: each processors part is put in a separate MATLAB process.
336: Collective on PetscObject
338: Input Parameters:
339: + mengine - the MATLAB engine
340: . m,n - the dimensions of the array
341: . array - the array (represented in one dimension)
342: - name - the name of the array
344: Level: advanced
346: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
347: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
348: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePut(), PetscMatlabEngineGetArray(), PetscMatlabEngine
349: @*/
350: PetscErrorCode PetscMatlabEnginePutArray(PetscMatlabEngine mengine,int m,int n,const PetscScalar *array,const char name[])
351: {
352: mxArray *mat;
355: PetscInfo(0,"Putting MATLAB array %s\n",name);
356: #if !defined(PETSC_USE_COMPLEX)
357: mat = mxCreateDoubleMatrix(m,n,mxREAL);
358: #else
359: mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
360: #endif
361: PetscArraycpy(mxGetPr(mat),array,m*n);
362: engPutVariable(mengine->ep,name,mat);
364: PetscInfo(0,"Put MATLAB array %s\n",name);
365: return 0;
366: }
368: /*@C
369: PetscMatlabEngineGetArray - Gets a variable from MATLAB into an array
371: Not Collective
373: Input Parameters:
374: + mengine - the MATLAB engine
375: . m,n - the dimensions of the array
376: . array - the array (represented in one dimension)
377: - name - the name of the array
379: Level: advanced
381: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
382: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
383: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGet(), PetscMatlabEngine
384: @*/
385: PetscErrorCode PetscMatlabEngineGetArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,const char name[])
386: {
387: mxArray *mat;
390: PetscInfo(0,"Getting MATLAB array %s\n",name);
391: mat = engGetVariable(mengine->ep,name);
395: PetscArraycpy(array,mxGetPr(mat),m*n);
396: PetscInfo(0,"Got MATLAB array %s\n",name);
397: return 0;
398: }