Actual source code: python.c
1: #define PETSC_DLL
3: #include petsc.h
4: #include petscsys.h
6: /* ---------------------------------------------------------------- */
8: #if !defined(PETSC_PYTHON_EXE)
9: #define PETSC_PYTHON_EXE "python"
10: #endif
14: static PetscErrorCode PetscPythonFindExecutable(char pythonexe[PETSC_MAX_PATH_LEN])
15: {
16: PetscTruth flag;
19: /* get the path for the Python interpreter executable */
20: PetscStrncpy(pythonexe,PETSC_PYTHON_EXE,PETSC_MAX_PATH_LEN);
21: PetscOptionsGetString(PETSC_NULL,"-python",pythonexe,PETSC_MAX_PATH_LEN,&flag);
22: if (!flag || pythonexe[0]==0) {
23: PetscStrncpy(pythonexe,PETSC_PYTHON_EXE,PETSC_MAX_PATH_LEN);
24: }
25: return(0);
26: }
30: static PetscErrorCode PetscPythonFindLibrary(char pythonexe[PETSC_MAX_PATH_LEN],
31: char pythonlib[PETSC_MAX_PATH_LEN])
32: {
33: const char cmdline[] = "-c 'import sys; print(sys.exec_prefix); print(sys.version[:3])'";
34: char command[PETSC_MAX_PATH_LEN+1+sizeof(cmdline)+1];
35: char prefix[PETSC_MAX_PATH_LEN],version[8],sep[2]={PETSC_DIR_SEPARATOR, 0},*eol;
36: FILE* fp = NULL;
37: char path[PETSC_MAX_PATH_LEN+1];
38: PetscTruth found = PETSC_FALSE;
42: #if defined(PETSC_PYTHON_LIB)
43: PetscStrcpy(pythonlib,PETSC_PYTHON_LIB);
44: return(0);
45: #endif
46:
47: /* call Python to find out the name of the Python dynamic library */
48: PetscStrncpy(command,pythonexe,PETSC_MAX_PATH_LEN);
49: PetscStrcat(command," ");
50: PetscStrcat(command,cmdline);
51: #if defined(PETSC_HAVE_POPEN)
52: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,command,"r",&fp);
53: if (!fgets(prefix,sizeof(prefix),fp))
54: { SETERRQ1(PETSC_ERR_PLIB,"Python: bad output from executable: %s",pythonexe); }
55: if (!fgets(version,sizeof(version),fp))
56: { SETERRQ1(PETSC_ERR_PLIB,"Python: bad output from executable: %s",pythonexe); }
57: PetscPClose(PETSC_COMM_SELF,fp);
58: #else
59: SETERRQ(1,"Python: Aborted due to missing popen()");
60: #endif
61: /* remove newlines */
62: PetscStrchr(prefix,'\n',&eol);
63: if (eol) eol[0] = 0;
64: PetscStrchr(version,'\n',&eol);
65: if (eol) eol[0] = 0;
67: /* test for $prefix/lib64/libpythonX.X[.so]*/
68: PetscStrcpy(pythonlib,prefix);
69: PetscStrcat(pythonlib,sep);
70: PetscStrcat(pythonlib,"lib64");
71: PetscTestDirectory(pythonlib,'r',&found);
72: if (found) {
73: PetscStrcat(pythonlib,sep);
74: PetscStrcat(pythonlib,"libpython");
75: PetscStrcat(pythonlib,version);
76: PetscDLLibraryRetrieve(PETSC_COMM_SELF,pythonlib,path,PETSC_MAX_PATH_LEN,&found);
77: if (found) return(0);
78: }
80: /* test for $prefix/lib/libpythonX.X[.so]*/
81: PetscStrcpy(pythonlib,prefix);
82: PetscStrcat(pythonlib,sep);
83: PetscStrcat(pythonlib,"lib");
84: PetscTestDirectory(pythonlib,'r',&found);
85: if (found) {
86: PetscStrcat(pythonlib,sep);
87: PetscStrcat(pythonlib,"libpython");
88: PetscStrcat(pythonlib,version);
89: PetscDLLibraryRetrieve(PETSC_COMM_SELF,pythonlib,path,PETSC_MAX_PATH_LEN,&found);
90: if (found) return(0);
91: }
93: /* nothing good found */
94: PetscMemzero(pythonlib,PETSC_MAX_PATH_LEN);
95: PetscInfo(0,"Python dynamic library not found\n");
97: return(0);
98: }
100: /* ---------------------------------------------------------------- */
102: typedef struct _Py_object_t PyObject; /* fake definition */
104: static int (*Py_IsInitialized)(void);
105: static void (*Py_InitializeEx)(int);
106: static void (*Py_Finalize)(void);
108: static void (*PySys_SetArgv)(int, char **);
109: static PyObject* (*PyImport_ImportModule)(const char *);
111: static void (*Py_IncRef)(PyObject *);
112: static void (*Py_DecRef)(PyObject *);
114: static void (*PyErr_Clear)(void);
115: static PyObject* (*PyErr_Occurred)(void);
118: #define PetscDLPyLibOpen(libname) \
119: PetscDLLibraryAppend(PETSC_COMM_SELF,&DLLibrariesLoaded,libname)
120: #define PetscDLPyLibSym(symbol, value) \
121: PetscDLLibrarySym(PETSC_COMM_SELF,&DLLibrariesLoaded,PETSC_NULL,symbol,(void**)value)
122: #define PetscDLPyLibClose(comm) \
123: do { } while(0)
127: static PetscErrorCode PetscPythonLoadLibrary(const char pythonlib[])
128: {
132: /* open the Python dynamic library */
133: PetscDLPyLibOpen(pythonlib);
134: PetscInfo1(0,"Python: loaded dynamic library %s\n", pythonlib);
135: /* look required symbols from the Python C-API */
136: PetscDLPyLibSym("Py_IsInitialized" , &Py_IsInitialized );
137: PetscDLPyLibSym("Py_InitializeEx" , &Py_InitializeEx );
138: PetscDLPyLibSym("Py_Finalize" , &Py_Finalize );
139: PetscDLPyLibSym("PySys_SetArgv" , &PySys_SetArgv );
140: PetscDLPyLibSym("PyImport_ImportModule" , &PyImport_ImportModule );
141: PetscDLPyLibSym("Py_IncRef" , &Py_IncRef );
142: PetscDLPyLibSym("Py_DecRef" , &Py_DecRef );
143: PetscDLPyLibSym("PyErr_Clear" , &PyErr_Clear );
144: PetscDLPyLibSym("PyErr_Occurred" , &PyErr_Occurred );
145: /* XXX TODO: check that ALL symbols were there !!! */
146: if (!Py_IsInitialized) {SETERRQ(1,"Python: failed to load symbols from dynamic library");}
147: if (!Py_InitializeEx) {SETERRQ(1,"Python: failed to load symbols from dynamic library");}
148: if (!Py_Finalize) {SETERRQ(1,"Python: failed to load symbols from dynamic library");}
149: PetscInfo(0,"Python: all required symbols loaded from Python dynamic library\n");
151: return(0);
152: }
154: /* ---------------------------------------------------------------- */
156: static char PetscPythonExe[PETSC_MAX_PATH_LEN] = { 0 };
157: static char PetscPythonLib[PETSC_MAX_PATH_LEN] = { 0 };
158: static PetscTruth PetscBeganPython = PETSC_FALSE;
162: /*@C
163: PetscPythonFinalize - Finalize Python.
164:
165: Level: intermediate
167: .keywords: Python
168: @*/
169: PetscErrorCode PetscPythonFinalize(void)
170: {
172: if (PetscBeganPython) { if (Py_IsInitialized()) Py_Finalize(); }
173: PetscBeganPython = PETSC_FALSE;
174: return(0);
175: }
179: /*@C
180: PetscPythonInitialize - Initialize Python and import petsc4py.
182: Input Parameter:
183: + pyexe - path to the Python interpreter executable, or PETSC_NULL.
184: - pylib - full path to the Python dynamic library, or PETSC_NULL.
186: Level: intermediate
188: .keywords: Python
189:
190: @*/
191: PetscErrorCode PetscPythonInitialize(const char pyexe[],const char pylib[])
192: {
193: int argc = 0;
194: char **argv = 0;
195: PyObject *module = 0;
196: static PetscTruth registered = PETSC_FALSE;
197: PetscErrorCode ierr;
199: if (PetscBeganPython) return(0);
200: /* Python executable */
201: if (pyexe && pyexe[0] != 0) {
202: PetscStrncpy(PetscPythonExe,pyexe,sizeof(PetscPythonExe));
203: } else {
204: PetscPythonFindExecutable(PetscPythonExe);
205: }
206: /* Python dynamic library */
207: if (pylib && pylib[0] != 0) {
208: PetscStrncpy(PetscPythonLib,pylib,sizeof(PetscPythonLib));
209: } else {
210: PetscPythonFindLibrary(PetscPythonExe,PetscPythonLib);
211: }
212: /* dynamically load Python library */
213: PetscPythonLoadLibrary(PetscPythonLib);
214: /* initialize Python */
215: PetscBeganPython = PETSC_FALSE;
216: if (!Py_IsInitialized()) {
217: /* call below does not install signal handlers */
218: Py_InitializeEx(0);
219: /* call below required to build 'sys.argv' list */
220: PetscGetArgs(&argc,&argv);
221: if (argc && argv && argv[0]) PySys_SetArgv(argc,argv);
222: /* register finalizer */
223: if (!registered) {
224: PetscRegisterFinalize(PetscPythonFinalize);
225: registered = PETSC_TRUE;
226: }
227: PetscBeganPython = PETSC_TRUE;
228: }
229: /* import 'petsc4py.PETSc' module */
230: module = PyImport_ImportModule("petsc4py.PETSc");
231: if (module) {
232: PetscInfo(0,"Python: successfully imported module 'petsc4py.PETSc'\n");
233: Py_DecRef(module); module = 0;
234: } else {
235: SETERRQ(PETSC_ERR_PLIB,"Python: could not import module 'petsc4py.PETSc', perhaps your PYTHONPATH does not contain it\n");
236: }
237: return(0);
238: }
240: /* ---------------------------------------------------------------- */