Actual source code: matlab.c
petsc-3.11.4 2019-09-28
2: #include <engine.h> /* Matlab include file */
3: #include <petscsys.h>
4: #include <petscmatlab.h>
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;
15: /*@C
16: PetscMatlabEngineCreate - Creates a MATLAB engine object
18: Not Collective
20: Input Parameters:
21: + comm - a separate MATLAB engine is started for each process in the communicator
22: - machine - name of machine where MATLAB engine is to be run (usually NULL)
24: Output Parameter:
25: . mengine - the resulting object
27: Options Database:
28: . -matlab_engine_graphics - allow the MATLAB engine to display graphics
30: Level: advanced
32: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
33: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
34: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
35: @*/
36: PetscErrorCode PetscMatlabEngineCreate(MPI_Comm comm,const char machine[],PetscMatlabEngine *mengine)
37: {
38: PetscErrorCode ierr;
39: PetscMPIInt rank,size;
40: char buffer[256];
41: PetscMatlabEngine e;
42: PetscBool flg = PETSC_FALSE;
45: if (MATLABENGINE_CLASSID == -1) {
46: PetscClassIdRegister("MATLAB Engine",&MATLABENGINE_CLASSID);
47: }
48: PetscOptionsGetBool(NULL,NULL,"-matlab_engine_graphics",&flg,NULL);
50: PetscHeaderCreate(e,MATLABENGINE_CLASSID,"MatlabEngine","MATLAB Engine","Sys",comm,PetscMatlabEngineDestroy,NULL);
52: if (!machine) machine = "\0";
53: PetscStrncpy(buffer,PETSC_MATLAB_COMMAND,sizeof(buffer));
54: if (!flg) {
55: PetscStrlcat(buffer," -nodisplay ",sizeof(buffer));
56: }
57: PetscStrlcat(buffer," -nojvm ",sizeof(buffer));
58: PetscInfo2(0,"Starting MATLAB engine on %s with command %s\n",machine,buffer);
59: e->ep = engOpen(buffer);
60: if (!e->ep) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to start MATLAB engine on %s",machine);
61: engOutputBuffer(e->ep,e->buffer,1024);
63: MPI_Comm_rank(comm,&rank);
64: MPI_Comm_size(comm,&size);
65: sprintf(buffer,"MPI_Comm_rank = %d; MPI_Comm_size = %d;\n",rank,size);
66: engEvalString(e->ep, buffer);
67: PetscInfo1(0,"Started MATLAB engine on %s\n",machine);
69: *mengine = e;
70: return(0);
71: }
73: /*@
74: PetscMatlabEngineDestroy - Destroys a vector.
76: Collective on PetscMatlabEngine
78: Input Parameters:
79: . e - the engine
81: Level: advanced
83: .seealso: PetscMatlabEnginCreate(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
84: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
85: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
86: @*/
87: PetscErrorCode PetscMatlabEngineDestroy(PetscMatlabEngine *v)
88: {
92: if (!*v) return(0);
94: if (--((PetscObject)(*v))->refct > 0) return(0);
95: PetscHeaderDestroy(v);
96: return(0);
97: }
99: /*@C
100: PetscMatlabEngineEvaluate - Evaluates a string in MATLAB
102: Not Collective
104: Input Parameters:
105: + mengine - the MATLAB engine
106: - string - format as in a printf()
108: Level: advanced
110: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
111: PetscMatlabEngineCreate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
112: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
113: @*/
114: PetscErrorCode PetscMatlabEngineEvaluate(PetscMatlabEngine mengine,const char string[],...)
115: {
116: va_list Argp;
117: char buffer[1024];
119: size_t fullLength;
122: va_start(Argp,string);
123: PetscVSNPrintf(buffer,1024-9-5,string,&fullLength,Argp);
124: va_end(Argp);
126: PetscInfo1(0,"Evaluating MATLAB string: %s\n",buffer);
127: engEvalString(mengine->ep, buffer);
129: /*
130: Check for error in MATLAB: indicated by ? as first character in engine->buffer
131: */
132: if (mengine->buffer[4] == '?') SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in evaluating MATLAB command:%s\n%s",string,mengine->buffer);
134: PetscInfo1(0,"Done evaluating Matlab string: %s\n",buffer);
135: return(0);
136: }
138: /*@C
139: PetscMatlabEngineGetOutput - Gets a string buffer where the MATLAB output is
140: printed
142: Not Collective
144: Input Parameter:
145: . mengine - the MATLAB engine
147: Output Parameter:
148: . string - buffer where MATLAB output is printed
150: Level: advanced
152: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
153: PetscMatlabEngineEvaluate(), PetscMatlabEngineCreate(), PetscMatlabEnginePrintOutput(),
154: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
155: @*/
156: PetscErrorCode PetscMatlabEngineGetOutput(PetscMatlabEngine mengine,char **string)
157: {
159: *string = mengine->buffer;
160: return(0);
161: }
163: /*@C
164: PetscMatlabEnginePrintOutput - prints the output from MATLAB
166: Collective on PetscMatlabEngine
168: Input Parameters:
169: . mengine - the Matlab engine
171: Level: advanced
173: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
174: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEngineCreate(),
175: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine
176: @*/
177: PetscErrorCode PetscMatlabEnginePrintOutput(PetscMatlabEngine mengine,FILE *fd)
178: {
180: PetscMPIInt rank;
183: MPI_Comm_rank(PetscObjectComm((PetscObject)mengine),&rank);
184: PetscSynchronizedFPrintf(PetscObjectComm((PetscObject)mengine),fd,"[%d]%s",rank,mengine->buffer);
185: PetscSynchronizedFlush(PetscObjectComm((PetscObject)mengine),fd);
186: return(0);
187: }
189: /*@
190: PetscMatlabEnginePut - Puts a Petsc object into the MATLAB space. For parallel objects,
191: each processors part is put in a separate MATLAB process.
193: Collective on PetscObject
195: Input Parameters:
196: + mengine - the MATLAB engine
197: - object - the PETSc object, for example Vec
199: Level: advanced
201: Note: Mats transfered between PETSc and MATLAB and vis versa are transposed in the other space
202: (this is because MATLAB uses compressed column format and PETSc uses compressed row format)
204: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
205: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
206: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
207: @*/
208: PetscErrorCode PetscMatlabEnginePut(PetscMatlabEngine mengine,PetscObject obj)
209: {
210: PetscErrorCode ierr,(*put)(PetscObject,void*);
213: PetscObjectQueryFunction(obj,"PetscMatlabEnginePut_C",&put);
214: if (!put) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be put into MATLAB engine",obj->class_name);
215: PetscInfo(0,"Putting MATLAB object\n");
216: (*put)(obj,mengine->ep);
217: PetscInfo1(0,"Put MATLAB object: %s\n",obj->name);
218: return(0);
219: }
221: /*@
222: PetscMatlabEngineGet - Gets a variable from MATLAB into a PETSc object.
224: Collective on PetscObject
226: Input Parameters:
227: + mengine - the MATLAB engine
228: - object - the PETSc object, for example Vec
230: Level: advanced
232: Note: Mats transfered between PETSc and MATLAB and vis versa are transposed in the other space
233: (this is because MATLAB uses compressed column format and PETSc uses compressed row format)
235: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
236: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
237: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), MatlabEngineGetArray(), PetscMatlabEngine
238: @*/
239: PetscErrorCode PetscMatlabEngineGet(PetscMatlabEngine mengine,PetscObject obj)
240: {
241: PetscErrorCode ierr,(*get)(PetscObject,void*);
244: if (!obj->name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot get object that has no name");
245: PetscObjectQueryFunction(obj,"PetscMatlabEngineGet_C",&get);
246: if (!get) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Object %s cannot be gotten from MATLAB engine",obj->class_name);
247: PetscInfo(0,"Getting MATLAB object\n");
248: (*get)(obj,mengine->ep);
249: PetscInfo1(0,"Got MATLAB object: %s\n",obj->name);
250: return(0);
251: }
253: /*
254: The variable Petsc_Matlab_Engine_keyval is used to indicate an MPI attribute that
255: is attached to a communicator, in this case the attribute is a PetscMatlabEngine
256: */
257: static PetscMPIInt Petsc_Matlab_Engine_keyval = MPI_KEYVAL_INVALID;
260: /*@C
261: PETSC_MATLAB_ENGINE_ - Creates a matlab engine shared by all processors
262: in a communicator.
264: Not Collective
266: Input Parameter:
267: . comm - the MPI communicator to share the engine
269: Level: developer
271: Notes:
272: Unlike almost all other PETSc routines, this does not return
273: an error code. Usually used in the form
274: $ PetscMatlabEngineYYY(XXX object,PETSC_MATLAB_ENGINE_(comm));
276: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEnginePut(), PetscMatlabEngineGet(),
277: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
278: PetscMatlabEngineCreate(), PetscMatlabEnginePutArray(), PetscMatlabEngineGetArray(), PetscMatlabEngine,
279: PETSC_MATLAB_ENGINE_WORLD, PETSC_MATLAB_ENGINE_SELF
281: @*/
282: PetscMatlabEngine PETSC_MATLAB_ENGINE_(MPI_Comm comm)
283: {
284: PetscErrorCode ierr;
285: PetscBool flg;
286: PetscMatlabEngine mengine;
289: if (Petsc_Matlab_Engine_keyval == MPI_KEYVAL_INVALID) {
290: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Matlab_Engine_keyval,0);
291: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
292: }
293: MPI_Comm_get_attr(comm,Petsc_Matlab_Engine_keyval,(void**)&mengine,(int*)&flg);
294: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
295: if (!flg) { /* viewer not yet created */
296: char *machinename = 0,machine[64];
298: PetscOptionsGetString(NULL,NULL,"-matlab_engine_machine",machine,64,&flg);
299: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
300: if (flg) machinename = machine;
301: PetscMatlabEngineCreate(comm,machinename,&mengine);
302: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
303: PetscObjectRegisterDestroy((PetscObject)mengine);
304: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
305: MPI_Comm_set_attr(comm,Petsc_Matlab_Engine_keyval,mengine);
306: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_MATLAB_ENGINE_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); mengine = 0;}
307: }
308: PetscFunctionReturn(mengine);
309: }
311: /*@C
312: PetscMatlabEnginePutArray - Puts an array into the MATLAB space, treating it as a Fortran style (column major ordering) array. For parallel objects,
313: each processors part is put in a separate MATLAB process.
315: Collective on PetscObject
317: Input Parameters:
318: + mengine - the MATLAB engine
319: . m,n - the dimensions of the array
320: . array - the array (represented in one dimension)
321: - name - the name of the array
323: Level: advanced
325: .seealso: PetscMatlabEngineDestroy(), PetscMatlabEngineCreate(), PetscMatlabEngineGet(),
326: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
327: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePut(), MatlabEngineGetArray(), PetscMatlabEngine
328: @*/
329: PetscErrorCode PetscMatlabEnginePutArray(PetscMatlabEngine mengine,int m,int n,const PetscScalar *array,const char name[])
330: {
332: mxArray *mat;
335: PetscInfo1(0,"Putting MATLAB array %s\n",name);
336: #if !defined(PETSC_USE_COMPLEX)
337: mat = mxCreateDoubleMatrix(m,n,mxREAL);
338: #else
339: mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
340: #endif
341: PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));
342: engPutVariable(mengine->ep,name,mat);
344: PetscInfo1(0,"Put MATLAB array %s\n",name);
345: return(0);
346: }
348: /*@C
349: PetscMatlabEngineGetArray - Gets a variable from Matlab into an array
351: Not Collective
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(), PetscMatlabEnginePut(), PetscMatlabEngineCreate(),
362: PetscMatlabEngineEvaluate(), PetscMatlabEngineGetOutput(), PetscMatlabEnginePrintOutput(),
363: PETSC_MATLAB_ENGINE_(), PetscMatlabEnginePutArray(), PetscMatlabEngineGet(), PetscMatlabEngine
364: @*/
365: PetscErrorCode PetscMatlabEngineGetArray(PetscMatlabEngine mengine,int m,int n,PetscScalar *array,const char name[])
366: {
368: mxArray *mat;
371: PetscInfo1(0,"Getting MATLAB array %s\n",name);
372: mat = engGetVariable(mengine->ep,name);
373: if (!mat) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
374: PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));
375: PetscInfo1(0,"Got MATLAB array %s\n",name);
376: return(0);
377: }