Actual source code: matlab.c
1: /* $Id: matlab.c,v 1.17 2001/08/06 21:14:26 bsmith Exp $ #include "petsc.h" */
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: int MATLABENGINE_COOKIE = -1;
17: /*@C
18: PetscMatlabEngineCreate - Creates a Matlab engine object
20: Not Collective
22: Input Parameters:
23: + comm - a seperate 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: int PetscMatlabEngineCreate(MPI_Comm comm,const char machine[],PetscMatlabEngine *mengine)
36: {
37: int ierr,rank,size;
38: char buffer[128];
39: PetscMatlabEngine e;
42: if (MATLABENGINE_COOKIE == -1) {
43: PetscLogClassRegister(&MATLABENGINE_COOKIE,"Matlab Engine");
44: }
45: PetscHeaderCreate(e,_p_PetscMatlabEngine,int,MATLABENGINE_COOKIE,0,"MatlabEngine",comm,PetscMatlabEngineDestroy,0);
46: PetscLogObjectCreate(e);
48: if (!machine) machine = "\0";
49: PetscLogInfo(0,"Starting Matlab engine on %s\n",machine);
50: e->ep = engOpen(machine);
51: if (!e->ep) SETERRQ1(1,"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: PetscLogInfo(0,"Started Matlab engine on %s\n",machine);
59:
60: *mengine = e;
61: return(0);
62: }
66: /*@C
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: int PetscMatlabEngineDestroy(PetscMatlabEngine v)
81: {
84: if (--v->refct > 0) return(0);
85: PetscLogObjectDestroy(v);
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: int PetscMatlabEngineEvaluate(PetscMatlabEngine mengine,const char string[],...)
108: {
109: va_list Argp;
110: char buffer[1024];
111: int ierr,len,flops;
114: PetscStrcpy(buffer,"flops(0);");
115: va_start(Argp,string);
116: #if defined(PETSC_HAVE_VPRINTF_CHAR)
117: vsprintf(buffer+9,string,(char *)Argp);
118: #else
119: vsprintf(buffer+9,string,Argp);
120: #endif
121: va_end(Argp);
122: PetscStrcat(buffer,",flops");
124: PetscLogInfo(0,"Evaluating Matlab string: %s\n",buffer);
125: engEvalString(mengine->ep, buffer);
127: /*
128: Check for error in Matlab: indicated by ? as first character in engine->buffer
129: */
131: if (mengine->buffer[4] == '?') {
132: SETERRQ2(1,"Error in evaluating Matlab command:%s\n%s",string,mengine->buffer);
133: }
135: /*
136: Get flop number back from Matlab output
137: */
138: PetscStrlen(mengine->buffer,&len);
139: len -= 2;
140: while (len >= 0) {
141: len--;
142: if (mengine->buffer[len] == ' ') break;
143: if (mengine->buffer[len] == '\n') break;
144: if (mengine->buffer[len] == '\t') break;
145: }
146: sscanf(mengine->buffer+len," %d\n",&flops);
147: PetscLogFlops(flops);
148: /* strip out of engine->buffer the end part about flops */
149: if (len < 14) SETERRQ1(1,"Error from Matlab %s",mengine->buffer);
150: len -= 14;
151: mengine->buffer[len] = 0;
153: PetscLogInfo(0,"Done evaluating Matlab string: %s\n",buffer);
154: return(0);
155: }
159: /*@C
160: PetscMatlabEngineGetOutput - Gets a string buffer where the Matlab output is
161: printed
163: Not Collective
165: Input Parameter:
166: . mengine - the Matlab engine
168: Output Parameter:
169: . string - buffer where Matlab output is printed
171: Level: advanced
173: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
174: PetscMatlabEngineEvaluate(), PetscMatlabEngineCreate(), PetscMatlabEnginePrintOutput(),
175: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
176: @*/
177: int PetscMatlabEngineGetOutput(PetscMatlabEngine mengine,char **string)
178: {
180: *string = mengine->buffer;
181: return(0);
182: }
186: /*@C
187: PetscMatlabEnginePrintOutput - prints the output from Matlab
189: Collective on PetscMatlabEngine
191: Input Parameters:
192: . mengine - the Matlab engine
194: Level: advanced
196: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
197: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEngineCreate(),
198: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
199: @*/
200: int PetscMatlabEnginePrintOutput(PetscMatlabEngine mengine,FILE *fd)
201: {
202: int ierr,rank;
205: MPI_Comm_rank(mengine->comm,&rank);
206: PetscSynchronizedFPrintf(mengine->comm,fd,"[%d]%s",rank,mengine->buffer);
207: PetscSynchronizedFlush(mengine->comm);
208: return(0);
209: }
213: /*@C
214: PetscMatlabEnginePut - Puts a Petsc object into the Matlab space. For parallel objects,
215: each processors part is put in a seperate Matlab process.
217: Collective on PetscObject
219: Input Parameters:
220: + mengine - the Matlab engine
221: - object - the PETSc object, for example Vec
223: Level: advanced
225: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
226: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
227: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
228: @*/
229: int PetscMatlabEnginePut(PetscMatlabEngine mengine,PetscObject obj)
230: {
231: int ierr,(*put)(PetscObject,void*);
232:
234: PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",(void (**)(void))&put);
235: if (!put) {
236: SETERRQ1(1,"Object %s cannot be put into Matlab engine",obj->class_name);
237: }
238: PetscLogInfo(0,"Putting Matlab object\n");
239: (*put)(obj,mengine->ep);
240: PetscLogInfo(0,"Put Matlab object: %s\n",obj->name);
241: return(0);
242: }
246: /*@C
247: PetscMatlabEngineGet - Gets a variable from Matlab into a PETSc object.
249: Collective on PetscObject
251: Input Parameters:
252: + mengine - the Matlab engine
253: - object - the PETSc object, for example Vec
255: Level: advanced
257: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
258: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
259: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
260: @*/
261: int PetscMatlabEngineGet(PetscMatlabEngine mengine,PetscObject obj)
262: {
263: int ierr,(*get)(PetscObject,void*);
264:
266: if (!obj->name) {
267: SETERRQ(1,"Cannot get object that has no name");
268: }
269: PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",(void (**)(void))&get);
270: if (!get) {
271: SETERRQ1(1,"Object %s cannot be get into Matlab engine",obj->class_name);
272: }
273: PetscLogInfo(0,"Getting Matlab object\n");
274: (*get)(obj,mengine->ep);
275: PetscLogInfo(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 int Petsc_Matlab_Engine_keyval = MPI_KEYVAL_INVALID;
288: /*@C
289: PETSC_MATLAB_ENGINE_ - Creates a matlab engine shared by all processors
290: in a communicator.
292: Not Collective
294: Input Parameter:
295: . comm - the MPI communicator to share the engine
297: Level: developer
299: Notes:
300: Unlike almost all other PETSc routines, this does not return
301: an error code. Usually used in the form
302: $ PetscMatlabEngineYYY(XXX object,PETSC_MATLAB_ENGINE_(comm));
304: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
305: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
306: PetscMatlabEngineCreate(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine,
307: PETSC_MATLAB_ENGINE_WORLD, PETSC_MATLAB_ENGINE_SELF
308:
309: @*/
310: PetscMatlabEngine PETSC_MATLAB_ENGINE_(MPI_Comm comm)
311: {
312: int ierr;
313: PetscTruth flg;
314: PetscMatlabEngine mengine;
317: if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) {
318: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0);
319: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
320: }
321: MPI_Attr_get(comm,Petsc_Matlab_Engine_keyval,(void **)&mengine,(int*)&flg);
322: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
323: if (!flg) { /* viewer not yet created */
324: char *machinename = 0,machine[64];
326: PetscOptionsGetString(PETSC_NULL,"-matlab_engine_machine",machine,64,&flg);
327: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
328: if (flg) machinename = machine;
329: PetscMatlabEngineCreate(comm,machinename,&mengine);
330: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
331: PetscObjectRegisterDestroy((PetscObject)mengine);
332: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
333: MPI_Attr_put(comm,Petsc_Matlab_Engine_keyval,mengine);
334: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
335: }
336: PetscFunctionReturn(mengine);
337: }
341: /*@C
342: PetscMatlabEnginePutArray - Puts a Petsc object into the Matlab space. For parallel objects,
343: each processors part is put in a seperate Matlab process.
345: Collective on PetscObject
347: Input Parameters:
348: + mengine - the Matlab engine
349: . m,n - the dimensions of the array
350: . array - the array (represented in one dimension)
351: - name - the name of the array
353: Level: advanced
355: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
356: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
357: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePut(), MatlabEngineGetArray(), PetscMatlabEngine
358: @*/
359: int PetscMatlabEnginePutArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,const char name[])
360: {
361: int ierr;
362: mxArray *mat;
363:
365: PetscLogInfo(0,"Putting Matlab array %s\n",name);
366: #if !defined(PETSC_USE_COMPLEX)
367: mat = mxCreateDoubleMatrix(m,n,mxREAL);
368: #else
369: mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
370: #endif
371: PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));
372: engPutVariable(mengine->ep,name,mat);
374: PetscLogInfo(0,"Put Matlab array %s\n",name);
375: return(0);
376: }
380: /*@C
381: PetscMatlabEngineGetArray - Gets a variable from Matlab into an array
383: Not Collective
385: Input Parameters:
386: + mengine - the Matlab engine
387: . m,n - the dimensions of the array
388: . array - the array (represented in one dimension)
389: - name - the name of the array
391: Level: advanced
393: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
394: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
395: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGet(), PetscMatlabEngine
396: @*/
397: int PetscMatlabEngineGetArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,const char name[])
398: {
399: int ierr;
400: mxArray *mat;
401:
403: PetscLogInfo(0,"Getting Matlab array %s\n",name);
404: mat = engGetVariable(mengine->ep,name);
405: if (!mat) SETERRQ1(1,"Unable to get array %s from matlab",name);
406: PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));
407: PetscLogInfo(0,"Got Matlab array %s\n",name);
408: return(0);
409: }