Actual source code: matlab.c
1: #define PETSC_DLL
3: #include "engine.h" /* Matlab include file */
4: #include petsc.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: PetscLogClassRegister(&MATLABENGINE_COOKIE,"Matlab Engine");
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(machine);
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 (--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 flops;
113: size_t len;
116: PetscStrcpy(buffer,"flops(0);");
117: va_start(Argp,string);
118: PetscVSNPrintf(buffer+9,1024-9-5,string,Argp);
119: va_end(Argp);
120: PetscStrcat(buffer,",flops");
122: PetscInfo1(0,"Evaluating Matlab string: %s\n",buffer);
123: engEvalString(mengine->ep, buffer);
125: /*
126: Check for error in Matlab: indicated by ? as first character in engine->buffer
127: */
129: if (mengine->buffer[4] == '?') {
130: SETERRQ2(PETSC_ERR_LIB,"Error in evaluating Matlab command:%s\n%s",string,mengine->buffer);
131: }
133: /*
134: Get flop number back from Matlab output
135: */
136: PetscStrlen(mengine->buffer,&len);
137: len -= 2;
138: while (len > 0) {
139: len--;
140: if (mengine->buffer[len] == ' ') break;
141: if (mengine->buffer[len] == '\n') break;
142: if (mengine->buffer[len] == '\t') break;
143: }
144: sscanf(mengine->buffer+len," %d\n",&flops);
145: PetscLogFlops(flops);
146: /* strip out of engine->buffer the end part about flops */
147: if (len < 14) SETERRQ1(PETSC_ERR_LIB,"Error from Matlab %s",mengine->buffer);
148: len -= 14;
149: mengine->buffer[len] = 0;
151: PetscInfo1(0,"Done evaluating Matlab string: %s\n",buffer);
152: return(0);
153: }
157: /*@C
158: PetscMatlabEngineGetOutput - Gets a string buffer where the Matlab output is
159: printed
161: Not Collective
163: Input Parameter:
164: . mengine - the Matlab engine
166: Output Parameter:
167: . string - buffer where Matlab output is printed
169: Level: advanced
171: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
172: PetscMatlabEngineEvaluate(), PetscMatlabEngineCreate(), PetscMatlabEnginePrintOutput(),
173: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
174: @*/
175: PetscErrorCode PetscMatlabEngineGetOutput(PetscMatlabEngine mengine,char **string)
176: {
178: *string = mengine->buffer;
179: return(0);
180: }
184: /*@C
185: PetscMatlabEnginePrintOutput - prints the output from Matlab
187: Collective on PetscMatlabEngine
189: Input Parameters:
190: . mengine - the Matlab engine
192: Level: advanced
194: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
195: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEngineCreate(),
196: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
197: @*/
198: PetscErrorCode PetscMatlabEnginePrintOutput(PetscMatlabEngine mengine,FILE *fd)
199: {
201: PetscMPIInt rank;
204: MPI_Comm_rank(mengine->comm,&rank);
205: PetscSynchronizedFPrintf(mengine->comm,fd,"[%d]%s",rank,mengine->buffer);
206: PetscSynchronizedFlush(mengine->comm);
207: return(0);
208: }
212: /*@
213: PetscMatlabEnginePut - Puts a Petsc object into the Matlab space. For parallel objects,
214: each processors part is put in a separate Matlab process.
216: Collective on PetscObject
218: Input Parameters:
219: + mengine - the Matlab engine
220: - object - the PETSc object, for example Vec
222: Level: advanced
224: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
225: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
226: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
227: @*/
228: PetscErrorCode PetscMatlabEnginePut(PetscMatlabEngine mengine,PetscObject obj)
229: {
230: PetscErrorCode ierr,(*put)(PetscObject,void*);
231:
233: PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",(void (**)(void))&put);
234: if (!put) {
235: SETERRQ1(PETSC_ERR_SUP,"Object %s cannot be put into Matlab engine",obj->class_name);
236: }
237: PetscInfo(0,"Putting Matlab object\n");
238: (*put)(obj,mengine->ep);
239: PetscInfo1(0,"Put Matlab object: %s\n",obj->name);
240: return(0);
241: }
245: /*@
246: PetscMatlabEngineGet - Gets a variable from Matlab into a PETSc object.
248: Collective on PetscObject
250: Input Parameters:
251: + mengine - the Matlab engine
252: - object - the PETSc object, for example Vec
254: Level: advanced
256: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
257: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
258: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
259: @*/
260: PetscErrorCode PetscMatlabEngineGet(PetscMatlabEngine mengine,PetscObject obj)
261: {
262: PetscErrorCode ierr,(*get)(PetscObject,void*);
263:
265: if (!obj->name) {
266: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot get object that has no name");
267: }
268: PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",(void (**)(void))&get);
269: if (!get) {
270: SETERRQ1(PETSC_ERR_SUP,"Object %s cannot be gotten from Matlab engine",obj->class_name);
271: }
272: PetscInfo(0,"Getting Matlab object\n");
273: (*get)(obj,mengine->ep);
274: PetscInfo1(0,"Got Matlab object: %s\n",obj->name);
275: return(0);
276: }
278: /*
279: The variable Petsc_Matlab_Engine_keyval is used to indicate an MPI attribute that
280: is attached to a communicator, in this case the attribute is a PetscMatlabEngine
281: */
282: static PetscMPIInt Petsc_Matlab_Engine_keyval = MPI_KEYVAL_INVALID;
287: /*@C
288: PETSC_MATLAB_ENGINE_ - Creates a matlab engine shared by all processors
289: in a communicator.
291: Not Collective
293: Input Parameter:
294: . comm - the MPI communicator to share the engine
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
307:
308: @*/
309: PetscMatlabEngine PETSC_MATLAB_ENGINE_(MPI_Comm comm)
310: {
312: PetscTruth flg;
313: PetscMatlabEngine mengine;
316: if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) {
317: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0);
318: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
319: }
320: MPI_Attr_get(comm,Petsc_Matlab_Engine_keyval,(void **)&mengine,(int*)&flg);
321: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
322: if (!flg) { /* viewer not yet created */
323: char *machinename = 0,machine[64];
325: PetscOptionsGetString(PETSC_NULL,"-matlab_engine_machine",machine,64,&flg);
326: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
327: if (flg) machinename = machine;
328: PetscMatlabEngineCreate(comm,machinename,&mengine);
329: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
330: PetscObjectRegisterDestroy((PetscObject)mengine);
331: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
332: MPI_Attr_put(comm,Petsc_Matlab_Engine_keyval,mengine);
333: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
334: }
335: PetscFunctionReturn(mengine);
336: }
340: /*@C
341: PetscMatlabEnginePutArray - Puts a Petsc object into the Matlab space. For parallel objects,
342: each processors part is put in a separate Matlab process.
344: Collective on PetscObject
346: Input Parameters:
347: + mengine - the Matlab engine
348: . m,n - the dimensions of the array
349: . array - the array (represented in one dimension)
350: - name - the name of the array
352: Level: advanced
354: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
355: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
356: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePut(), MatlabEngineGetArray(), PetscMatlabEngine
357: @*/
358: PetscErrorCode PetscMatlabEnginePutArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,const char name[])
359: {
361: mxArray *mat;
362:
364: PetscInfo1(0,"Putting Matlab array %s\n",name);
365: #if !defined(PETSC_USE_COMPLEX)
366: mat = mxCreateDoubleMatrix(m,n,mxREAL);
367: #else
368: mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
369: #endif
370: PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));
371: engPutVariable(mengine->ep,name,mat);
373: PetscInfo1(0,"Put Matlab array %s\n",name);
374: return(0);
375: }
379: /*@C
380: PetscMatlabEngineGetArray - Gets a variable from Matlab into an array
382: Not Collective
384: Input Parameters:
385: + mengine - the Matlab engine
386: . m,n - the dimensions of the array
387: . array - the array (represented in one dimension)
388: - name - the name of the array
390: Level: advanced
392: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
393: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
394: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGet(), PetscMatlabEngine
395: @*/
396: PetscErrorCode PetscMatlabEngineGetArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,const char name[])
397: {
399: mxArray *mat;
400:
402: PetscInfo1(0,"Getting Matlab array %s\n",name);
403: mat = engGetVariable(mengine->ep,name);
404: if (!mat) SETERRQ1(PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
405: PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));
406: PetscInfo1(0,"Got Matlab array %s\n",name);
407: return(0);
408: }