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: /* ---------------------------------------------------------------- */