Actual source code: matlab.c
1: #define PETSC_DLL
3: #include "engine.h" /* Matlab include file */
4: #include petscsys.h
5: #include <stdarg.h>
7: struct _p_PetscMatlabEngine {
8: PETSCHEADER(int);
9: Engine *ep;
10: char buffer[1024];
11: };
13: PetscCookie MATLABENGINE_COOKIE = -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 PETSC_NULL)
26: Output Parameter:
27: . mengine - the resulting object
29: Level: advanced
31: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
32: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
33: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
34: @*/
35: PetscErrorCode PetscMatlabEngineCreate(MPI_Comm comm,const char machine[],PetscMatlabEngine *mengine)
36: {
37: PetscErrorCode ierr;
38: PetscMPIInt rank,size;
39: char buffer[256];
40: PetscMatlabEngine e;
43: if (MATLABENGINE_COOKIE == -1) {
44: PetscCookieRegister("Matlab Engine",&MATLABENGINE_COOKIE);
45: }
46: PetscHeaderCreate(e,_p_PetscMatlabEngine,int,MATLABENGINE_COOKIE,0,"MatlabEngine",comm,PetscMatlabEngineDestroy,0);
48: if (!machine) machine = "\0";
49: PetscInfo1(0,"Starting Matlab engine on %s\n",machine);
50: e->ep = engOpen("matlab -nodisplay -nojvm");
51: if (!e->ep) SETERRQ1(PETSC_ERR_LIB,"Unable to start Matlab engine on %s\n",machine);
52: engOutputBuffer(e->ep,e->buffer,1024);
54: MPI_Comm_rank(comm,&rank);
55: MPI_Comm_size(comm,&size);
56: sprintf(buffer,"MPI_Comm_rank = %d; MPI_Comm_size = %d;\n",rank,size);
57: engEvalString(e->ep, buffer);
58: PetscInfo1(0,"Started Matlab engine on %s\n",machine);
59:
60: *mengine = e;
61: return(0);
62: }
66: /*@
67: PetscMatlabEngineDestroy - Destroys a vector.
69: Collective on PetscMatlabEngine
71: Input Parameters:
72: . e - the engine
74: Level: advanced
76: .seealso: PetscMatlabEnginCreate(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
77: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
78: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
79: @*/
80: PetscErrorCode PetscMatlabEngineDestroy(PetscMatlabEngine v)
81: {
85: if (--((PetscObject)v)->refct > 0) return(0);
86: PetscHeaderDestroy(v);
87: return(0);
88: }
92: /*@C
93: PetscMatlabEngineEvaluate - Evaluates a string in Matlab
95: Not Collective
97: Input Parameters:
98: + mengine - the Matlab engine
99: - string - format as in a printf()
101: Level: advanced
103: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
104: PetscMatlabEngineCreate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
105: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
106: @*/
107: PetscErrorCode PetscMatlabEngineEvaluate(PetscMatlabEngine mengine,const char string[],...)
108: {
109: va_list Argp;
110: char buffer[1024];
112: int fullLength;
113: size_t len;
116: va_start(Argp,string);
117: PetscVSNPrintf(buffer,1024-9-5,string,&fullLength,Argp);
118: va_end(Argp);
120: PetscInfo1(0,"Evaluating Matlab string: %s\n",buffer);
121: engEvalString(mengine->ep, buffer);
123: /*
124: Check for error in Matlab: indicated by ? as first character in engine->buffer
125: */
126: if (mengine->buffer[4] == '?') {
127: SETERRQ2(PETSC_ERR_LIB,"Error in evaluating Matlab command:%s\n%s",string,mengine->buffer);
128: }
130: PetscInfo1(0,"Done evaluating Matlab string: %s\n",buffer);
131: return(0);
132: }
136: /*@C
137: PetscMatlabEngineGetOutput - Gets a string buffer where the Matlab output is
138: printed
140: Not Collective
142: Input Parameter:
143: . mengine - the Matlab engine
145: Output Parameter:
146: . string - buffer where Matlab output is printed
148: Level: advanced
150: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
151: PetscMatlabEngineEvaluate(), PetscMatlabEngineCreate(), PetscMatlabEnginePrintOutput(),
152: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
153: @*/
154: PetscErrorCode PetscMatlabEngineGetOutput(PetscMatlabEngine mengine,char **string)
155: {
157: *string = mengine->buffer;
158: return(0);
159: }
163: /*@C
164: PetscMatlabEnginePrintOutput - prints the output from Matlab
166: Collective on PetscMatlabEngine
168: Input Parameters:
169: . mengine - the Matlab engine
171: Level: advanced
173: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
174: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEngineCreate(),
175: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
176: @*/
177: PetscErrorCode PetscMatlabEnginePrintOutput(PetscMatlabEngine mengine,FILE *fd)
178: {
180: PetscMPIInt rank;
183: MPI_Comm_rank(((PetscObject)mengine)->comm,&rank);
184: PetscSynchronizedFPrintf(((PetscObject)mengine)->comm,fd,"[%d]%s",rank,mengine->buffer);
185: PetscSynchronizedFlush(((PetscObject)mengine)->comm);
186: return(0);
187: }
191: /*@
192: PetscMatlabEnginePut - Puts a Petsc object into the Matlab space. For parallel objects,
193: each processors part is put in a separate Matlab process.
195: Collective on PetscObject
197: Input Parameters:
198: + mengine - the Matlab engine
199: - object - the PETSc object, for example Vec
201: Level: advanced
203: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
204: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
205: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
206: @*/
207: PetscErrorCode PetscMatlabEnginePut(PetscMatlabEngine mengine,PetscObject obj)
208: {
209: PetscErrorCode ierr,(*put)(PetscObject,void*);
210:
212: PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",(void (**)(void))&put);
213: if (!put) {
214: SETERRQ1(PETSC_ERR_SUP,"Object %s cannot be put into Matlab engine",obj->class_name);
215: }
216: PetscInfo(0,"Putting Matlab object\n");
217: (*put)(obj,mengine->ep);
218: PetscInfo1(0,"Put Matlab object: %s\n",obj->name);
219: return(0);
220: }
224: /*@
225: PetscMatlabEngineGet - Gets a variable from Matlab into a PETSc object.
227: Collective on PetscObject
229: Input Parameters:
230: + mengine - the Matlab engine
231: - object - the PETSc object, for example Vec
233: Level: advanced
235: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
236: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
237: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
238: @*/
239: PetscErrorCode PetscMatlabEngineGet(PetscMatlabEngine mengine,PetscObject obj)
240: {
241: PetscErrorCode ierr,(*get)(PetscObject,void*);
242:
244: if (!obj->name) {
245: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot get object that has no name");
246: }
247: PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",(void (**)(void))&get);
248: if (!get) {
249: SETERRQ1(PETSC_ERR_SUP,"Object %s cannot be gotten from Matlab engine",obj->class_name);
250: }
251: PetscInfo(0,"Getting Matlab object\n");
252: (*get)(obj,mengine->ep);
253: PetscInfo1(0,"Got Matlab object: %s\n",obj->name);
254: return(0);
255: }
257: /*
258: The variable Petsc_Matlab_Engine_keyval is used to indicate an MPI attribute that
259: is attached to a communicator, in this case the attribute is a PetscMatlabEngine
260: */
261: static PetscMPIInt Petsc_Matlab_Engine_keyval = MPI_KEYVAL_INVALID;
266: /*@C
267: PETSC_MATLAB_ENGINE_ - Creates a matlab engine shared by all processors
268: in a communicator.
270: Not Collective
272: Input Parameter:
273: . comm - the MPI communicator to share the engine
275: Level: developer
277: Notes:
278: Unlike almost all other PETSc routines, this does not return
279: an error code. Usually used in the form
280: $ PetscMatlabEngineYYY(XXX object,PETSC_MATLAB_ENGINE_(comm));
282: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
283: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
284: PetscMatlabEngineCreate(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine,
285: PETSC_MATLAB_ENGINE_WORLD, PETSC_MATLAB_ENGINE_SELF
286:
287: @*/
288: PetscMatlabEngine PETSC_MATLAB_ENGINE_(MPI_Comm comm)
289: {
291: PetscTruth flg;
292: PetscMatlabEngine mengine;
295: if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) {
296: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0);
297: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
298: }
299: MPI_Attr_get(comm,Petsc_Matlab_Engine_keyval,(void **)&mengine,(int*)&flg);
300: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
301: if (!flg) { /* viewer not yet created */
302: char *machinename = 0,machine[64];
304: PetscOptionsGetString(PETSC_NULL,"-matlab_engine_machine",machine,64,&flg);
305: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
306: if (flg) machinename = machine;
307: PetscMatlabEngineCreate(comm,machinename,&mengine);
308: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
309: PetscObjectRegisterDestroy((PetscObject)mengine);
310: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
311: MPI_Attr_put(comm,Petsc_Matlab_Engine_keyval,mengine);
312: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
313: }
314: PetscFunctionReturn(mengine);
315: }
319: /*@C
320: PetscMatlabEnginePutArray - Puts a Petsc object into the Matlab space. For parallel objects,
321: each processors part is put in a separate Matlab process.
323: Collective on PetscObject
325: Input Parameters:
326: + mengine - the Matlab engine
327: . m,n - the dimensions of the array
328: . array - the array (represented in one dimension)
329: - name - the name of the array
331: Level: advanced
333: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
334: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
335: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePut(), MatlabEngineGetArray(), PetscMatlabEngine
336: @*/
337: PetscErrorCode PetscMatlabEnginePutArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,const char name[])
338: {
340: mxArray *mat;
341:
343: PetscInfo1(0,"Putting Matlab array %s\n",name);
344: #if !defined(PETSC_USE_COMPLEX)
345: mat = mxCreateDoubleMatrix(m,n,mxREAL);
346: #else
347: mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
348: #endif
349: PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));
350: engPutVariable(mengine->ep,name,mat);
352: PetscInfo1(0,"Put Matlab array %s\n",name);
353: return(0);
354: }
358: /*@C
359: PetscMatlabEngineGetArray - Gets a variable from Matlab into an array
361: Not Collective
363: Input Parameters:
364: + mengine - the Matlab engine
365: . m,n - the dimensions of the array
366: . array - the array (represented in one dimension)
367: - name - the name of the array
369: Level: advanced
371: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
372: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
373: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGet(), PetscMatlabEngine
374: @*/
375: PetscErrorCode PetscMatlabEngineGetArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,const char name[])
376: {
378: mxArray *mat;
379:
381: PetscInfo1(0,"Getting Matlab array %s\n",name);
382: mat = engGetVariable(mengine->ep,name);
383: if (!mat) SETERRQ1(PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
384: PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));
385: PetscInfo1(0,"Got Matlab array %s\n",name);
386: return(0);
387: }