Actual source code: pythonsys.c

  1: #define PETSC_DLL

 3:  #include petscsys.h

  5: /* ---------------------------------------------------------------- */

  7: #if !defined(PETSC_PYTHON_EXE)
  8: #define PETSC_PYTHON_EXE "python"
  9: #endif

 13: static PetscErrorCode PetscPythonFindExecutable(char pythonexe[PETSC_MAX_PATH_LEN])
 14: {
 15:   PetscTruth     flag;
 18:   /* get the path for the Python interpreter executable */
 19:   PetscStrncpy(pythonexe,PETSC_PYTHON_EXE,PETSC_MAX_PATH_LEN);
 20:   PetscOptionsGetString(PETSC_NULL,"-python",pythonexe,PETSC_MAX_PATH_LEN,&flag);
 21:   if (!flag || pythonexe[0]==0) {
 22:     PetscStrncpy(pythonexe,PETSC_PYTHON_EXE,PETSC_MAX_PATH_LEN);
 23:   }
 24:   return(0);
 25: }

 29: static PetscErrorCode PetscPythonFindLibrary(char pythonexe[PETSC_MAX_PATH_LEN], 
 30:                                              char pythonlib[PETSC_MAX_PATH_LEN])
 31: {
 32:   const char cmdline[] = "-c 'import sys; print(sys.exec_prefix); print(sys.version[:3])'";
 33:   char command[PETSC_MAX_PATH_LEN+1+sizeof(cmdline)+1];
 34:   char prefix[PETSC_MAX_PATH_LEN],version[8],sep[2]={PETSC_DIR_SEPARATOR, 0},*eol;
 35:   FILE* fp = NULL;
 36:   char path[PETSC_MAX_PATH_LEN+1];
 37:   PetscTruth found = PETSC_FALSE;

 41: #if defined(PETSC_PYTHON_LIB)
 42:   PetscStrcpy(pythonlib,PETSC_PYTHON_LIB);
 43:   return(0);
 44: #endif
 45: 
 46:   /* call Python to find out the name of the Python dynamic library */
 47:   PetscStrncpy(command,pythonexe,PETSC_MAX_PATH_LEN);
 48:   PetscStrcat(command," ");
 49:   PetscStrcat(command,cmdline);
 50: #if defined(PETSC_HAVE_POPEN)
 51:   PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,command,"r",&fp);
 52:   if (!fgets(prefix,sizeof(prefix),fp))
 53:     { SETERRQ1(PETSC_ERR_PLIB,"Python: bad output from executable: %s",pythonexe); }
 54:   if (!fgets(version,sizeof(version),fp))
 55:     { SETERRQ1(PETSC_ERR_PLIB,"Python: bad output from executable: %s",pythonexe); }
 56:   PetscPClose(PETSC_COMM_SELF,fp);
 57: #else
 58:   SETERRQ(1,"Python: Aborted due to missing popen()");
 59: #endif
 60:   /* remove newlines */
 61:   PetscStrchr(prefix,'\n',&eol);
 62:   if (eol) eol[0] = 0;
 63:   PetscStrchr(version,'\n',&eol);
 64:   if (eol) eol[0] = 0;

 66:   /* test for $prefix/lib64/libpythonX.X[.so]*/
 67:   PetscStrcpy(pythonlib,prefix);
 68:   PetscStrcat(pythonlib,sep);
 69:   PetscStrcat(pythonlib,"lib64");
 70:   PetscTestDirectory(pythonlib,'r',&found);
 71:   if (found) {
 72:     PetscStrcat(pythonlib,sep);
 73:     PetscStrcat(pythonlib,"libpython");
 74:     PetscStrcat(pythonlib,version);
 75:     PetscDLLibraryRetrieve(PETSC_COMM_SELF,pythonlib,path,PETSC_MAX_PATH_LEN,&found);
 76:     if (found) return(0);
 77:   }

 79:   /* test for $prefix/lib/libpythonX.X[.so]*/
 80:   PetscStrcpy(pythonlib,prefix);
 81:   PetscStrcat(pythonlib,sep);
 82:   PetscStrcat(pythonlib,"lib");
 83:   PetscTestDirectory(pythonlib,'r',&found);
 84:   if (found) {
 85:     PetscStrcat(pythonlib,sep);
 86:     PetscStrcat(pythonlib,"libpython");
 87:     PetscStrcat(pythonlib,version);
 88:     PetscDLLibraryRetrieve(PETSC_COMM_SELF,pythonlib,path,PETSC_MAX_PATH_LEN,&found);
 89:     if (found) return(0);
 90:   }

 92:   /* nothing good found */
 93:   PetscMemzero(pythonlib,PETSC_MAX_PATH_LEN);
 94:   PetscInfo(0,"Python dynamic library not found\n");

 96:   return(0);
 97: }

 99: /* ---------------------------------------------------------------- */

101: typedef struct _Py_object_t PyObject; /* fake definition */

103: static int            (*Py_IsInitialized)(void);
104: static void           (*Py_InitializeEx)(int);
105: static void           (*Py_Finalize)(void);

107: static void      (*PySys_SetArgv)(int, char **);
108: static PyObject* (*PyImport_ImportModule)(const char *);

110: static void      (*Py_IncRef)(PyObject *);
111: static void      (*Py_DecRef)(PyObject *);

113: static void      (*PyErr_Clear)(void);
114: static PyObject* (*PyErr_Occurred)(void);


117: #define PetscDLPyLibOpen(libname) \
118:   PetscDLLibraryAppend(PETSC_COMM_SELF,&DLLibrariesLoaded,libname)
119: #define PetscDLPyLibSym(symbol, value) \
120:   PetscDLLibrarySym(PETSC_COMM_SELF,&DLLibrariesLoaded,PETSC_NULL,symbol,(void**)value)
121: #define PetscDLPyLibClose(comm) \
122:   do { } while(0)

126: static PetscErrorCode PetscPythonLoadLibrary(const char pythonlib[])
127: {

131:   /* open the Python dynamic library */
132:   PetscDLPyLibOpen(pythonlib);
133:   PetscInfo1(0,"Python: loaded dynamic library %s\n", pythonlib);
134:   /* look required symbols from the Python C-API */
135:   PetscDLPyLibSym("Py_IsInitialized"      , &Py_IsInitialized      );
136:   PetscDLPyLibSym("Py_InitializeEx"       , &Py_InitializeEx       );
137:   PetscDLPyLibSym("Py_Finalize"           , &Py_Finalize           );
138:   PetscDLPyLibSym("PySys_SetArgv"         , &PySys_SetArgv         );
139:   PetscDLPyLibSym("PyImport_ImportModule" , &PyImport_ImportModule );
140:   PetscDLPyLibSym("Py_IncRef"             , &Py_IncRef             );
141:   PetscDLPyLibSym("Py_DecRef"             , &Py_DecRef             );
142:   PetscDLPyLibSym("PyErr_Clear"           , &PyErr_Clear           );
143:   PetscDLPyLibSym("PyErr_Occurred"        , &PyErr_Occurred        );
144:   /* XXX TODO: check that ALL symbols were there !!! */
145:   if (!Py_IsInitialized) {SETERRQ(1,"Python: failed to load symbols from dynamic library");}
146:   if (!Py_InitializeEx)  {SETERRQ(1,"Python: failed to load symbols from dynamic library");}
147:   if (!Py_Finalize)      {SETERRQ(1,"Python: failed to load symbols from dynamic library");}
148:   PetscInfo(0,"Python: all required symbols loaded from Python dynamic library\n");

150:   return(0);
151: }

153: /* ---------------------------------------------------------------- */

155: static char       PetscPythonExe[PETSC_MAX_PATH_LEN] = { 0 };
156: static char       PetscPythonLib[PETSC_MAX_PATH_LEN] = { 0 };
157: static PetscTruth PetscBeganPython = PETSC_FALSE;

161: /*@C
162:   PetscPythonFinalize - Finalize Python.
163:   
164:   Level: intermediate

166: .keywords: Python
167: @*/
168: PetscErrorCode  PetscPythonFinalize(void)
169: {
171:   if (PetscBeganPython) { if (Py_IsInitialized()) Py_Finalize(); }
172:   PetscBeganPython = PETSC_FALSE;
173:   return(0);
174: }

178: /*@C
179:   PetscPythonInitialize - Initialize Python and import petsc4py.

181:    Input Parameter:
182: +  pyexe - path to the Python interpreter executable, or PETSC_NULL.
183: -  pylib - full path to the Python dynamic library, or PETSC_NULL.

185:   Level: intermediate

187: .keywords: Python
188:   
189: @*/
190: PetscErrorCode  PetscPythonInitialize(const char pyexe[],const char pylib[])
191: {
192:   int               argc       = 0;
193:   char              **argv     = 0;
194:   PyObject          *module    = 0;
195:   static PetscTruth registered = PETSC_FALSE;
196:   PetscErrorCode    ierr;
198:   if (PetscBeganPython) return(0);
199:   /* Python executable */
200:   if (pyexe && pyexe[0] != 0) {
201:     PetscStrncpy(PetscPythonExe,pyexe,sizeof(PetscPythonExe));
202:   } else {
203:     PetscPythonFindExecutable(PetscPythonExe);
204:   }
205:   /* Python dynamic library */
206:   if (pylib && pylib[0] != 0) {
207:     PetscStrncpy(PetscPythonLib,pylib,sizeof(PetscPythonLib));
208:   } else {
209:     PetscPythonFindLibrary(PetscPythonExe,PetscPythonLib);
210:   }
211:   /* dynamically load Python library */
212:   PetscPythonLoadLibrary(PetscPythonLib);
213:   /* initialize Python */
214:   PetscBeganPython = PETSC_FALSE;
215:   if (!Py_IsInitialized()) {
216:     /* call below does not install signal handlers */
217:     Py_InitializeEx(0);
218:     /* call below required to build 'sys.argv' list */
219:     PetscGetArgs(&argc,&argv);
220:     if (argc && argv && argv[0]) PySys_SetArgv(argc,argv);
221:     /* register finalizer */
222:     if (!registered) {
223:       PetscRegisterFinalize(PetscPythonFinalize);
224:       registered = PETSC_TRUE;
225:     }
226:     PetscBeganPython = PETSC_TRUE;
227:   }
228:   /* import 'petsc4py.PETSc' module */
229:   module = PyImport_ImportModule("petsc4py.PETSc");
230:   if (module) {
231:     PetscInfo(0,"Python: successfully imported  module 'petsc4py.PETSc'\n");
232:     Py_DecRef(module); module = 0;
233:   } else {
234:     SETERRQ(PETSC_ERR_PLIB,"Python: could not import module 'petsc4py.PETSc', perhaps your PYTHONPATH does not contain it\n");
235:   }
236:   return(0);
237: }

239: /* ---------------------------------------------------------------- */