Actual source code: matlab.c
petsc-3.7.7 2017-09-25
2: #include <engine.h> /* Matlab include file */
3: #include <petscsys.h>
4: #include <petscmatlab.h> /*I "petscmatlab.h" I*/
5: #include <petsc/private/petscimpl.h>
7: struct _p_PetscMatlabEngine {
8: PETSCHEADER(int);
9: Engine *ep;
10: char buffer[1024];
11: };
13: PetscClassId MATLABENGINE_CLASSID = -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 NULL)
26: Output Parameter:
27: . mengine - the resulting object
29: Options Database:
30: . -matlab_engine_graphics - allow the MATLAB engine to display graphics
32: Level: advanced
34: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
35: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
36: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
37: @*/
38: PetscErrorCode PetscMatlabEngineCreate(MPI_Comm comm,const char machine[],PetscMatlabEngine *mengine)
39: {
40: PetscErrorCode ierr;
41: PetscMPIInt rank,size;
42: char buffer[256];
43: PetscMatlabEngine e;
44: PetscBool flg = PETSC_FALSE;
47: if (MATLABENGINE_CLASSID == -1) {
48: PetscClassIdRegister("MATLAB Engine",&MATLABENGINE_CLASSID);
49: }
50: PetscOptionsGetBool(NULL,NULL,"-matlab_engine_graphics",&flg,NULL);
52: PetscHeaderCreate(e,MATLABENGINE_CLASSID,"MatlabEngine","MATLAB Engine","Sys",comm,PetscMatlabEngineDestroy,NULL);
54: if (!machine) machine = "\0";
55: PetscStrcpy(buffer,PETSC_MATLAB_COMMAND);
56: if (!flg) {
57: PetscStrcat(buffer," -nodisplay ");
58: }
59: PetscStrcat(buffer," -nojvm ");
60: PetscInfo2(0,"Starting MATLAB engine on %s with command %s\n",machine,buffer);
61: e->ep = engOpen(buffer);
62: if (!e->ep) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to start MATLAB engine on %s",machine);
63: engOutputBuffer(e->ep,e->buffer,1024);
65: MPI_Comm_rank(comm,&rank);
66: MPI_Comm_size(comm,&size);
67: sprintf(buffer,"MPI_Comm_rank = %d; MPI_Comm_size = %d;\n",rank,size);
68: engEvalString(e->ep, buffer);
69: PetscInfo1(0,"Started MATLAB engine on %s\n",machine);
71: *mengine = e;
72: return(0);
73: }
77: /*@
78: PetscMatlabEngineDestroy - Destroys a vector.
80: Collective on PetscMatlabEngine
82: Input Parameters:
83: . e - the engine
85: Level: advanced
87: .seealso: PetscMatlabEnginCreate(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
88: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
89: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
90: @*/
91: PetscErrorCode PetscMatlabEngineDestroy(PetscMatlabEngine *v)
92: {
96: if (!*v) return(0);
98: if (--((PetscObject)(*v))->refct > 0) return(0);
99: PetscHeaderDestroy(v);
100: return(0);
101: }
105: /*@C
106: PetscMatlabEngineEvaluate - Evaluates a string in MATLAB
108: Not Collective
110: Input Parameters:
111: + mengine - the MATLAB engine
112: - string - format as in a printf()
114: Level: advanced
116: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
117: PetscMatlabEngineCreate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
118: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
119: @*/
120: PetscErrorCode PetscMatlabEngineEvaluate(PetscMatlabEngine mengine,const char string[],...)
121: {
122: va_list Argp;
123: char buffer[1024];
125: size_t fullLength;
128: va_start(Argp,string);
129: PetscVSNPrintf(buffer,1024-9-5,string,&fullLength,Argp);
130: va_end(Argp);
132: PetscInfo1(0,"Evaluating MATLAB string: %s\n",buffer);
133: engEvalString(mengine->ep, buffer);
135: /*
136: Check for error in MATLAB: indicated by ? as first character in engine->buffer
137: */
138: if (mengine->buffer[4] == '?') SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in evaluating MATLAB command:%s\n%s",string,mengine->buffer);
140: PetscInfo1(0,"Done evaluating Matlab string: %s\n",buffer);
141: return(0);
142: }
146: /*@C
147: PetscMatlabEngineGetOutput - Gets a string buffer where the MATLAB output is
148: printed
150: Not Collective
152: Input Parameter:
153: . mengine - the MATLAB engine
155: Output Parameter:
156: . string - buffer where MATLAB output is printed
158: Level: advanced
160: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
161: PetscMatlabEngineEvaluate(), PetscMatlabEngineCreate(), PetscMatlabEnginePrintOutput(),
162: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
163: @*/
164: PetscErrorCode PetscMatlabEngineGetOutput(PetscMatlabEngine mengine,char **string)
165: {
167: *string = mengine->buffer;
168: return(0);
169: }
173: /*@C
174: PetscMatlabEnginePrintOutput - prints the output from MATLAB
176: Collective on PetscMatlabEngine
178: Input Parameters:
179: . mengine - the Matlab engine
181: Level: advanced
183: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
184: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEngineCreate(),
185: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
186: @*/
187: PetscErrorCode PetscMatlabEnginePrintOutput(PetscMatlabEngine mengine,FILE *fd)
188: {
190: PetscMPIInt rank;
193: MPI_Comm_rank(PetscObjectComm((PetscObject)mengine),&rank);
194: PetscSynchronizedFPrintf(PetscObjectComm((PetscObject)mengine),fd,"[%d]%s",rank,mengine->buffer);
195: PetscSynchronizedFlush(PetscObjectComm((PetscObject)mengine),fd);
196: return(0);
197: }
201: /*@
202: PetscMatlabEnginePut - Puts a Petsc object into the MATLAB space. For parallel objects,
203: each processors part is put in a separate MATLAB process.
205: Collective on PetscObject
207: Input Parameters:
208: + mengine - the MATLAB engine
209: - object - the PETSc object, for example Vec
211: Level: advanced
213: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
214: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
215: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
216: @*/
217: PetscErrorCode PetscMatlabEnginePut(PetscMatlabEngine mengine,PetscObject obj)
218: {
219: PetscErrorCode ierr,(*put)(PetscObject,void*);
222: PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",&put);
223: if (!put) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be put into MATLAB engine",obj->class_name);
224: PetscInfo(0,"Putting MATLAB object\n");
225: (*put)(obj,mengine->ep);
226: PetscInfo1(0,"Put MATLAB object: %s\n",obj->name);
227: return(0);
228: }
232: /*@
233: PetscMatlabEngineGet - Gets a variable from MATLAB into a PETSc object.
235: Collective on PetscObject
237: Input Parameters:
238: + mengine - the MATLAB engine
239: - object - the PETSc object, for example Vec
241: Level: advanced
243: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
244: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
245: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
246: @*/
247: PetscErrorCode PetscMatlabEngineGet(PetscMatlabEngine mengine,PetscObject obj)
248: {
249: PetscErrorCode ierr,(*get)(PetscObject,void*);
252: if (!obj->name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot get object that has no name");
253: PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",&get);
254: if (!get) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be gotten from MATLAB engine",obj->class_name);
255: PetscInfo(0,"Getting MATLAB object\n");
256: (*get)(obj,mengine->ep);
257: PetscInfo1(0,"Got MATLAB object: %s\n",obj->name);
258: return(0);
259: }
261: /*
262: The variable Petsc_Matlab_Engine_keyval is used to indicate an MPI attribute that
263: is attached to a communicator, in this case the attribute is a PetscMatlabEngine
264: */
265: static PetscMPIInt Petsc_Matlab_Engine_keyval = MPI_KEYVAL_INVALID;
270: /*@C
271: PETSC_MATLAB_ENGINE_ - Creates a matlab engine shared by all processors
272: in a communicator.
274: Not Collective
276: Input Parameter:
277: . comm - the MPI communicator to share the engine
279: Level: developer
281: Notes:
282: Unlike almost all other PETSc routines, this does not return
283: an error code. Usually used in the form
284: $ PetscMatlabEngineYYY(XXX object,PETSC_MATLAB_ENGINE_(comm));
286: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
287: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
288: PetscMatlabEngineCreate(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine,
289: PETSC_MATLAB_ENGINE_WORLD, PETSC_MATLAB_ENGINE_SELF
291: @*/
292: PetscMatlabEngine PETSC_MATLAB_ENGINE_(MPI_Comm comm)
293: {
294: PetscErrorCode ierr;
295: PetscBool flg;
296: PetscMatlabEngine mengine;
299: if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) {
300: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0);
301: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
302: }
303: MPI_Attr_get(comm,Petsc_Matlab_Engine_keyval,(void**)&mengine,(int*)&flg);
304: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
305: if (!flg) { /* viewer not yet created */
306: char *machinename = 0,machine[64];
308: PetscOptionsGetString(NULL,NULL,"-matlab_engine_machine",machine,64,&flg);
309: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
310: if (flg) machinename = machine;
311: PetscMatlabEngineCreate(comm,machinename,&mengine);
312: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
313: PetscObjectRegisterDestroy((PetscObject)mengine);
314: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
315: MPI_Attr_put(comm,Petsc_Matlab_Engine_keyval,mengine);
316: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
317: }
318: PetscFunctionReturn(mengine);
319: }
323: /*@C
324: PetscMatlabEnginePutArray - Puts an array into the MATLAB space, treating it as a Fortran style (column major ordering) array. For parallel objects,
325: each processors part is put in a separate MATLAB process.
327: Collective on PetscObject
329: Input Parameters:
330: + mengine - the MATLAB engine
331: . m,n - the dimensions of the array
332: . array - the array (represented in one dimension)
333: - name - the name of the array
335: Level: advanced
337: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
338: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
339: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePut(), MatlabEngineGetArray(), PetscMatlabEngine
340: @*/
341: PetscErrorCode PetscMatlabEnginePutArray(PetscMatlabEngine mengine,int m,int n,const PetscScalar *array,const char name[])
342: {
344: mxArray *mat;
347: PetscInfo1(0,"Putting MATLAB array %s\n",name);
348: #if !defined(PETSC_USE_COMPLEX)
349: mat = mxCreateDoubleMatrix(m,n,mxREAL);
350: #else
351: mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
352: #endif
353: PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));
354: engPutVariable(mengine->ep,name,mat);
356: PetscInfo1(0,"Put MATLAB array %s\n",name);
357: return(0);
358: }
362: /*@C
363: PetscMatlabEngineGetArray - Gets a variable from Matlab into an array
365: Not Collective
367: Input Parameters:
368: + mengine - the Matlab engine
369: . m,n - the dimensions of the array
370: . array - the array (represented in one dimension)
371: - name - the name of the array
373: Level: advanced
375: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
376: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
377: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGet(), PetscMatlabEngine
378: @*/
379: PetscErrorCode PetscMatlabEngineGetArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,const char name[])
380: {
382: mxArray *mat;
385: PetscInfo1(0,"Getting MATLAB array %s\n",name);
386: mat = engGetVariable(mengine->ep,name);
387: if (!mat) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
388: PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));
389: PetscInfo1(0,"Got MATLAB array %s\n",name);
390: return(0);
391: }