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: };
15: /*@C
16: PetscMatlabEngineCreate - Creates a Matlab engine object
18: Not Collective
20: Input Parameters:
21: + comm - a seperate Matlab engine is started for each process in the communicator
22: - machine - name of machine where Matlab engine is to be run (usually PETSC_NULL)
24: Output Parameter:
25: . mengine - the resulting object
27: Level: advanced
29: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
30: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
31: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutScalar(), PetscMatlabEngine
32: @*/
33: int PetscMatlabEngineCreate(MPI_Comm comm,char *machine,PetscMatlabEngine *mengine)
34: {
35: int ierr,rank,size;
36: char buffer[128];
37: PetscMatlabEngine e;
40: PetscHeaderCreate(e,_p_PetscMatlabEngine,int,MATLABENGINE_COOKIE,0,"MatlabEngine",comm,PetscMatlabEngineDestroy,0);
41: PetscLogObjectCreate(e);
43: if (!machine) machine = "\0";
44: PetscLogInfo(0,"Starting Matlab engine on %s\n",machine);
45: e->ep = engOpen(machine);
46: if (!e->ep) SETERRQ1(1,"Unable to start Matlab engine on %s\n",machine);
47: engOutputBuffer(e->ep,e->buffer,1024);
49: MPI_Comm_rank(comm,&rank);
50: MPI_Comm_size(comm,&size);
51: sprintf(buffer,"MPI_Comm_rank = %d; MPI_Comm_size = %d;\n",rank,size);
52: engEvalString(e->ep, buffer);
53: PetscLogInfo(0,"Started Matlab engine on %s\n",machine);
54:
55: *mengine = e;
56: return(0);
57: }
61: /*@C
62: PetscMatlabEngineDestroy - Destroys a vector.
64: Collective on PetscMatlabEngine
66: Input Parameters:
67: . e - the engine
69: Level: advanced
71: .seealso: PetscMatlabEnginCreate(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
72: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
73: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutScalar(), PetscMatlabEngine
74: @*/
75: int PetscMatlabEngineDestroy(PetscMatlabEngine v)
76: {
79: if (--v->refct > 0) return(0);
80: PetscLogObjectDestroy(v);
81: PetscHeaderDestroy(v);
82: return(0);
83: }
87: /*@C
88: PetscMatlabEngineEvaluate - Evaluates a string in Matlab
90: Not Collective
92: Input Parameters:
93: + mengine - the Matlab engine
94: - string - format as in a printf()
96: Level: advanced
98: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
99: PetscMatlabEngineCreate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
100: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutScalar(), PetscMatlabEngine
101: @*/
102: int PetscMatlabEngineEvaluate(PetscMatlabEngine mengine,char *string,...)
103: {
104: va_list Argp;
105: char buffer[1024];
106: int ierr,len,flops;
109: PetscStrcpy(buffer,"flops(0);");
110: va_start(Argp,string);
111: #if defined(PETSC_HAVE_VPRINTF_CHAR)
112: vsprintf(buffer+9,string,(char *)Argp);
113: #else
114: vsprintf(buffer+9,string,Argp);
115: #endif
116: va_end(Argp);
117: PetscStrcat(buffer,",flops");
119: PetscLogInfo(0,"Evaluating Matlab string: %s\n",buffer);
120: engEvalString(mengine->ep, buffer);
122: /*
123: Check for error in Matlab: indicated by ? as first character in engine->buffer
124: */
126: if (mengine->buffer[4] == '?') {
127: SETERRQ2(1,"Error in evaluating Matlab command:%s\n%s",string,mengine->buffer);
128: }
130: /*
131: Get flop number back from Matlab output
132: */
133: PetscStrlen(mengine->buffer,&len);
134: len -= 2;
135: while (len >= 0) {
136: len--;
137: if (mengine->buffer[len] == ' ') break;
138: if (mengine->buffer[len] == '\n') break;
139: if (mengine->buffer[len] == '\t') break;
140: }
141: sscanf(mengine->buffer+len," %d\n",&flops);
142: PetscLogFlops(flops);
143: /* strip out of engine->buffer the end part about flops */
144: if (len < 14) SETERRQ1(1,"Error from Matlab %s",mengine->buffer);
145: len -= 14;
146: mengine->buffer[len] = 0;
148: PetscLogInfo(0,"Done evaluating Matlab string: %s\n",buffer);
149: return(0);
150: }
154: /*@C
155: PetscMatlabEngineGetOutput - Gets a string buffer where the Matlab output is
156: printed
158: Not Collective
160: Input Parameter:
161: . mengine - the Matlab engine
163: Output Parameter:
164: . string - buffer where Matlab output is printed
166: Level: advanced
168: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
169: PetscMatlabEngineEvaluate(), PetscMatlabEngineCreate(), PetscMatlabEnginePrintOutput(),
170: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutScalar(), PetscMatlabEngine
171: @*/
172: int PetscMatlabEngineGetOutput(PetscMatlabEngine mengine,char **string)
173: {
175: *string = mengine->buffer;
176: return(0);
177: }
181: /*@C
182: PetscMatlabEnginePrintOutput - prints the output from Matlab
184: Collective on PetscMatlabEngine
186: Input Parameters:
187: . mengine - the Matlab engine
189: Level: advanced
191: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
192: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEngineCreate(),
193: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutScalar(), PetscMatlabEngine
194: @*/
195: int PetscMatlabEnginePrintOutput(PetscMatlabEngine mengine,FILE *fd)
196: {
197: int ierr,rank;
200: MPI_Comm_rank(mengine->comm,&rank);
201: PetscSynchronizedFPrintf(mengine->comm,fd,"[%d]%s",rank,mengine->buffer);
202: PetscSynchronizedFlush(mengine->comm);
203: return(0);
204: }
208: /*@C
209: PetscMatlabEnginePut - Puts a Petsc object into the Matlab space. For parallel objects,
210: each processors part is put in a seperate Matlab process.
212: Collective on PetscObject
214: Input Parameters:
215: + mengine - the Matlab engine
216: - object - the PETSc object, for example Vec
218: Level: advanced
220: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
221: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
222: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
223: @*/
224: int PetscMatlabEnginePut(PetscMatlabEngine mengine,PetscObject obj)
225: {
226: int ierr,(*put)(PetscObject,void*);
227:
229: PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",(void (**)(void))&put);
230: if (!put) {
231: SETERRQ1(1,"Object %s cannot be put into Matlab engine",obj->class_name);
232: }
233: PetscLogInfo(0,"Putting Matlab object\n");
234: (*put)(obj,mengine->ep);
235: PetscLogInfo(0,"Put Matlab object: %s\n",obj->name);
236: return(0);
237: }
241: /*@C
242: PetscMatlabEngineGet - Gets a variable from Matlab into a PETSc object.
244: Collective on PetscObject
246: Input Parameters:
247: + mengine - the Matlab engine
248: - object - the PETSc object, for example Vec
250: Level: advanced
252: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
253: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
254: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
255: @*/
256: int PetscMatlabEngineGet(PetscMatlabEngine mengine,PetscObject obj)
257: {
258: int ierr,(*get)(PetscObject,void*);
259:
261: if (!obj->name) {
262: SETERRQ(1,"Cannot get object that has no name");
263: }
264: PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",(void (**)(void))&get);
265: if (!get) {
266: SETERRQ1(1,"Object %s cannot be get into Matlab engine",obj->class_name);
267: }
268: PetscLogInfo(0,"Getting Matlab object\n");
269: (*get)(obj,mengine->ep);
270: PetscLogInfo(0,"Got Matlab object: %s\n",obj->name);
271: return(0);
272: }
274: /*
275: The variable Petsc_Matlab_Engine_keyval is used to indicate an MPI attribute that
276: is attached to a communicator, in this case the attribute is a PetscMatlabEngine
277: */
278: static int Petsc_Matlab_Engine_keyval = MPI_KEYVAL_INVALID;
283: /*@C
284: PETSC_MATLAB_ENGINE_ - Creates a matlab engine shared by all processors
285: in a communicator.
287: Not Collective
289: Input Parameter:
290: . comm - the MPI communicator to share the engine
292: Level: developer
294: Notes:
295: Unlike almost all other PETSc routines, this does not return
296: an error code. Usually used in the form
297: $ PetscMatlabEngineYYY(XXX object,PETSC_MATLAB_ENGINE_(comm));
299: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
300: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
301: PetscMatlabEngineCreate(), PetscMatlabEnginePutScalar(), PetscMatlabEngine,
302: PETSC_MATLAB_ENGINE_WORLD, PETSC_MATLAB_ENGINE_SELF
303:
304: @*/
305: PetscMatlabEngine PETSC_MATLAB_ENGINE_(MPI_Comm comm)
306: {
307: int ierr;
308: PetscTruth flg;
309: PetscMatlabEngine mengine;
312: if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) {
313: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0);
314: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
315: }
316: MPI_Attr_get(comm,Petsc_Matlab_Engine_keyval,(void **)&mengine,(int*)&flg);
317: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
318: if (!flg) { /* viewer not yet created */
319: char *machinename = 0,machine[64];
321: PetscOptionsGetString(PETSC_NULL,"-matlab_engine_machine",machine,64,&flg);
322: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
323: if (flg) machinename = machine;
324: PetscMatlabEngineCreate(comm,machinename,&mengine);
325: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
326: PetscObjectRegisterDestroy((PetscObject)mengine);
327: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
328: MPI_Attr_put(comm,Petsc_Matlab_Engine_keyval,mengine);
329: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
330: }
331: PetscFunctionReturn(mengine);
332: }
336: /*@C
337: PetscMatlabEnginePutArray - Puts a Petsc object into the Matlab space. For parallel objects,
338: each processors part is put in a seperate Matlab process.
340: Collective on PetscObject
342: Input Parameters:
343: + mengine - the Matlab engine
344: . m,n - the dimensions of the array
345: . array - the array (represented in one dimension)
346: - name - the name of the array
348: Level: advanced
350: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
351: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
352: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePut(), MatlabEngineGetArray(), PetscMatlabEngine
353: @*/
354: int PetscMatlabEnginePutArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,char *name)
355: {
356: int ierr;
357: mxArray *mat;
358:
360: PetscLogInfo(0,"Putting Matlab array %s\n",name);
361: #if !defined(PETSC_USE_COMPLEX)
362: mat = mxCreateDoubleMatrix(m,n,mxREAL);
363: #else
364: mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
365: #endif
366: PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));
367: mxSetName(mat,name);
368: engPutArray(mengine->ep,mat);
370: PetscLogInfo(0,"Put Matlab array %s\n",name);
371: return(0);
372: }
376: /*@C
377: PetscMatlabEngineGetArray - Gets a variable from Matlab into an array
379: Not Collective
381: Input Parameters:
382: + mengine - the Matlab engine
383: . m,n - the dimensions of the array
384: . array - the array (represented in one dimension)
385: - name - the name of the array
387: Level: advanced
389: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
390: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
391: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGet(), PetscMatlabEngine
392: @*/
393: int PetscMatlabEngineGetArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,char *name)
394: {
395: int ierr;
396: mxArray *mat;
397:
399: PetscLogInfo(0,"Getting Matlab array %s\n",name);
400: mat = engGetArray(mengine->ep,name);
401: if (!mat) SETERRQ1(1,"Unable to get array %s from matlab",name);
402: PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));
403: PetscLogInfo(0,"Got Matlab array %s\n",name);
404: return(0);
405: }