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: #undef __FUNCT__
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 %sn",machine);
45: e->ep = engOpen(machine);
46: if (!e->ep) SETERRQ1(1,"Unable to start Matlab engine on %sn",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 %sn",machine);
54:
55: *mengine = e;
56: return(0);
57: }
59: #undef __FUNCT__
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: }
85: #undef __FUNCT__
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: %sn",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:%sn%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," %dn",&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: %sn",buffer);
149: return(0);
150: }
152: #undef __FUNCT__
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: }
179: #undef __FUNCT__
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: }
206: #undef __FUNCT__
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 objectn");
234: (*put)(obj,mengine->ep);
235: PetscLogInfo(0,"Put Matlab object: %sn",obj->name);
236: return(0);
237: }
239: #undef __FUNCT__
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 objectn");
269: (*get)(obj,mengine->ep);
270: PetscLogInfo(0,"Got Matlab object: %sn",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;
280: /*MC
281: PETSC_MATLAB_ENGINE_WORLD - same as PETSC_MATLAB_ENGINE_(PETSC_COMM_WORLD)
283: Level: developer
284: M*/
286: /*MC
287: PETSC_MATLAB_ENGINE_SELF - same as PETSC_MATLAB_ENGINE_(PETSC_COMM_SELF)
289: Level: developer
290: M*/
292: #undef __FUNCT__
294: /*@C
295: PETSC_MATLAB_ENGINE_ - Creates a matlab engine shared by all processors
296: in a communicator.
298: Not Collective
300: Input Parameter:
301: . comm - the MPI communicator to share the engine
303: Level: developer
305: Notes:
306: Unlike almost all other PETSc routines, this does not return
307: an error code. Usually used in the form
308: $ PetscMatlabEngineYYY(XXX object,PETSC_MATLAB_ENGINE_(comm));
310: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
311: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
312: PetscMatlabEngineCreate(), PetscMatlabEnginePutScalar(), PetscMatlabEngine,
313: PETSC_MATLAB_ENGINE_WORLD, PETSC_MATLAB_ENGINE_SELF
314:
315: @*/
316: PetscMatlabEngine PETSC_MATLAB_ENGINE_(MPI_Comm comm)
317: {
318: int ierr;
319: PetscTruth flg;
320: PetscMatlabEngine mengine;
323: if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) {
324: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0);
325: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
326: }
327: MPI_Attr_get(comm,Petsc_Matlab_Engine_keyval,(void **)&mengine,(int*)&flg);
328: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
329: if (!flg) { /* viewer not yet created */
330: char *machinename = 0,machine[64];
332: PetscOptionsGetString(PETSC_NULL,"-matlab_engine_machine",machine,64,&flg);
333: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
334: if (flg) machinename = machine;
335: PetscMatlabEngineCreate(comm,machinename,&mengine);
336: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
337: PetscObjectRegisterDestroy((PetscObject)mengine);
338: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
339: MPI_Attr_put(comm,Petsc_Matlab_Engine_keyval,mengine);
340: if (ierr) {PetscError(__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,__SDIR__,1,1," "); mengine = 0;}
341: }
342: PetscFunctionReturn(mengine);
343: }
345: #undef __FUNCT__
347: /*@C
348: PetscMatlabEnginePutArray - Puts a Petsc object into the Matlab space. For parallel objects,
349: each processors part is put in a seperate Matlab process.
351: Collective on PetscObject
353: Input Parameters:
354: + mengine - the Matlab engine
355: . m,n - the dimensions of the array
356: . array - the array (represented in one dimension)
357: - name - the name of the array
359: Level: advanced
361: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
362: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
363: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePut(), MatlabEngineGetArray(), PetscMatlabEngine
364: @*/
365: int PetscMatlabEnginePutArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,char *name)
366: {
367: int ierr;
368: mxArray *mat;
369:
371: PetscLogInfo(0,"Putting Matlab array %sn",name);
372: #if !defined(PETSC_USE_COMPLEX)
373: mat = mxCreateDoubleMatrix(m,n,mxREAL);
374: #else
375: mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
376: #endif
377: PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));
378: mxSetName(mat,name);
379: engPutArray(mengine->ep,mat);
381: PetscLogInfo(0,"Put Matlab array %sn",name);
382: return(0);
383: }
385: #undef __FUNCT__
387: /*@C
388: PetscMatlabEngineGetArray - Gets a variable from Matlab into an array
390: Not Collective
392: Input Parameters:
393: + mengine - the Matlab engine
394: . m,n - the dimensions of the array
395: . array - the array (represented in one dimension)
396: - name - the name of the array
398: Level: advanced
400: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
401: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
402: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGet(), PetscMatlabEngine
403: @*/
404: int PetscMatlabEngineGetArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,char *name)
405: {
406: int ierr;
407: mxArray *mat;
408:
410: PetscLogInfo(0,"Getting Matlab array %sn",name);
411: mat = engGetArray(mengine->ep,name);
412: if (!mat) SETERRQ1(1,"Unable to get array %s from matlab",name);
413: PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));
414: PetscLogInfo(0,"Got Matlab array %sn",name);
415: return(0);
416: }