1af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 2c4aff060SBarry Smith 3c4aff060SBarry Smith /* ---------------------------------------------------------------- */ 4c4aff060SBarry Smith 5c4aff060SBarry Smith #if !defined(PETSC_PYTHON_EXE) 6c4aff060SBarry Smith #define PETSC_PYTHON_EXE "python" 7c4aff060SBarry Smith #endif 8c4aff060SBarry Smith 9c4aff060SBarry Smith static PetscErrorCode PetscPythonFindExecutable(char pythonexe[PETSC_MAX_PATH_LEN]) 10c4aff060SBarry Smith { 11ace3abfcSBarry Smith PetscBool flag; 12c4aff060SBarry Smith PetscErrorCode ierr; 136e111a19SKarl Rupp 14c4aff060SBarry Smith PetscFunctionBegin; 15c4aff060SBarry Smith /* get the path for the Python interpreter executable */ 16c4aff060SBarry Smith ierr = PetscStrncpy(pythonexe,PETSC_PYTHON_EXE,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 17c5929fdfSBarry Smith ierr = PetscOptionsGetString(NULL,NULL,"-python",pythonexe,PETSC_MAX_PATH_LEN,&flag);CHKERRQ(ierr); 18c4aff060SBarry Smith if (!flag || pythonexe[0]==0) { 19c4aff060SBarry Smith ierr = PetscStrncpy(pythonexe,PETSC_PYTHON_EXE,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 20c4aff060SBarry Smith } 21c4aff060SBarry Smith PetscFunctionReturn(0); 22c4aff060SBarry Smith } 23c4aff060SBarry Smith 24412d63f8SBarry Smith static PetscErrorCode PetscPythonFindLibrary(const char pythonexe[PETSC_MAX_PATH_LEN],char pythonlib[PETSC_MAX_PATH_LEN]) 25c4aff060SBarry Smith { 26*84b215baSBarry Smith const char cmdline1[] = "-c 'from distutils import sysconfig; print(sysconfig.get_config_var(\"LIBPYTHON\"))'"; 27*84b215baSBarry Smith const char cmdline2[] = "-c 'import os;from distutils import sysconfig; print(os.path.join(sysconfig.get_config_var(\"LIBPL\"),sysconfig.get_config_var(\"LDLIBRARY\")))'"; 28*84b215baSBarry Smith char command[PETSC_MAX_PATH_LEN+1+sizeof(cmdline2)+1],*eol; 29c4aff060SBarry Smith FILE *fp = NULL; 30ace3abfcSBarry Smith PetscBool found = PETSC_FALSE; 31c4aff060SBarry Smith PetscErrorCode ierr; 32c4aff060SBarry Smith 336e111a19SKarl Rupp PetscFunctionBegin; 34c4aff060SBarry Smith #if defined(PETSC_PYTHON_LIB) 35c4aff060SBarry Smith ierr = PetscStrcpy(pythonlib,PETSC_PYTHON_LIB);CHKERRQ(ierr); 36c4aff060SBarry Smith PetscFunctionReturn(0); 37c4aff060SBarry Smith #endif 38c4aff060SBarry Smith 39c4aff060SBarry Smith /* call Python to find out the name of the Python dynamic library */ 40c4aff060SBarry Smith ierr = PetscStrncpy(command,pythonexe,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 41c4aff060SBarry Smith ierr = PetscStrcat(command," ");CHKERRQ(ierr); 42*84b215baSBarry Smith ierr = PetscStrcat(command,cmdline1);CHKERRQ(ierr); 43c4aff060SBarry Smith #if defined(PETSC_HAVE_POPEN) 440298fd71SBarry Smith ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fp);CHKERRQ(ierr); 45412d63f8SBarry Smith if (!fgets(pythonlib,PETSC_MAX_PATH_LEN,fp)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Python: bad output from executable: %s",pythonexe); 46016831caSBarry Smith ierr = PetscPClose(PETSC_COMM_SELF,fp);CHKERRQ(ierr); 47c4aff060SBarry Smith #else 48e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,1,"Python: Aborted due to missing popen()"); 49c4aff060SBarry Smith #endif 50c4aff060SBarry Smith /* remove newlines */ 51412d63f8SBarry Smith ierr = PetscStrchr(pythonlib,'\n',&eol);CHKERRQ(ierr); 52c4aff060SBarry Smith if (eol) eol[0] = 0; 53412d63f8SBarry Smith ierr = PetscTestFile(pythonlib,'r',&found);CHKERRQ(ierr); 54*84b215baSBarry Smith if (!found) { 55*84b215baSBarry Smith ierr = PetscStrncpy(command,pythonexe,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 56*84b215baSBarry Smith ierr = PetscStrcat(command," ");CHKERRQ(ierr); 57*84b215baSBarry Smith ierr = PetscStrcat(command,cmdline2);CHKERRQ(ierr); 58*84b215baSBarry Smith #if defined(PETSC_HAVE_POPEN) 59*84b215baSBarry Smith ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fp);CHKERRQ(ierr); 60*84b215baSBarry Smith if (!fgets(pythonlib,PETSC_MAX_PATH_LEN,fp)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Python: bad output from executable: %s",pythonexe); 61*84b215baSBarry Smith ierr = PetscPClose(PETSC_COMM_SELF,fp);CHKERRQ(ierr); 62*84b215baSBarry Smith #else 63*84b215baSBarry Smith SETERRQ(PETSC_COMM_SELF,1,"Python: Aborted due to missing popen()"); 64*84b215baSBarry Smith #endif 65*84b215baSBarry Smith /* remove newlines */ 66*84b215baSBarry Smith ierr = PetscStrchr(pythonlib,'\n',&eol);CHKERRQ(ierr); 67*84b215baSBarry Smith if (eol) eol[0] = 0; 68*84b215baSBarry Smith ierr = PetscTestFile(pythonlib,'r',&found);CHKERRQ(ierr); 69*84b215baSBarry Smith } 70412d63f8SBarry Smith ierr = PetscInfo2(0,"Python library %s found %d\n",pythonlib,found);CHKERRQ(ierr); 71c4aff060SBarry Smith PetscFunctionReturn(0); 72c4aff060SBarry Smith } 73c4aff060SBarry Smith 74c4aff060SBarry Smith /* ---------------------------------------------------------------- */ 75c4aff060SBarry Smith 76c4aff060SBarry Smith typedef struct _Py_object_t PyObject; /* fake definition */ 77c4aff060SBarry Smith 78e0ab9aedSLisandro Dalcin static PyObject* Py_None = 0; 79e0ab9aedSLisandro Dalcin 809ac80d5eSLisandro Dalcin static const char* (*Py_GetVersion)(void); 819ac80d5eSLisandro Dalcin 82c4aff060SBarry Smith static int (*Py_IsInitialized)(void); 83c4aff060SBarry Smith static void (*Py_InitializeEx)(int); 84c4aff060SBarry Smith static void (*Py_Finalize)(void); 85c4aff060SBarry Smith 86c4aff060SBarry Smith static void (*PySys_SetArgv)(int,char**); 872f2e82b0SLisandro Dalcin static PyObject* (*PySys_GetObject)(const char*); 882f2e82b0SLisandro Dalcin static PyObject* (*PyObject_CallMethod)(PyObject*,const char*, const char*, ...); 89c4aff060SBarry Smith static PyObject* (*PyImport_ImportModule)(const char*); 90c4aff060SBarry Smith 91c4aff060SBarry Smith static void (*Py_IncRef)(PyObject*); 92c4aff060SBarry Smith static void (*Py_DecRef)(PyObject*); 93c4aff060SBarry Smith 94c4aff060SBarry Smith static void (*PyErr_Clear)(void); 95c4aff060SBarry Smith static PyObject* (*PyErr_Occurred)(void); 96e0ab9aedSLisandro Dalcin static void (*PyErr_Fetch)(PyObject**,PyObject**,PyObject**); 97e0ab9aedSLisandro Dalcin static void (*PyErr_NormalizeException)(PyObject**,PyObject**, PyObject**); 98e0ab9aedSLisandro Dalcin static void (*PyErr_Display)(PyObject*,PyObject*,PyObject*); 99e0ab9aedSLisandro Dalcin static void (*PyErr_Restore)(PyObject*,PyObject*,PyObject*); 100c4aff060SBarry Smith 101c4aff060SBarry Smith 102c4aff060SBarry Smith #define PetscDLPyLibOpen(libname) \ 103d44a1e48SBarry Smith PetscDLLibraryAppend(PETSC_COMM_SELF,&PetscDLLibrariesLoaded,libname) 104c4aff060SBarry Smith #define PetscDLPyLibSym(symbol, value) \ 1050298fd71SBarry Smith PetscDLLibrarySym(PETSC_COMM_SELF,&PetscDLLibrariesLoaded,NULL,symbol,(void**)value) 106c4aff060SBarry Smith #define PetscDLPyLibClose(comm) \ 107c4aff060SBarry Smith do { } while (0) 108c4aff060SBarry Smith 109c4aff060SBarry Smith static PetscErrorCode PetscPythonLoadLibrary(const char pythonlib[]) 110c4aff060SBarry Smith { 111c4aff060SBarry Smith PetscErrorCode ierr; 112c4aff060SBarry Smith 1136e111a19SKarl Rupp PetscFunctionBegin; 114c4aff060SBarry Smith /* open the Python dynamic library */ 115c4aff060SBarry Smith ierr = PetscDLPyLibOpen(pythonlib);CHKERRQ(ierr); 116c4aff060SBarry Smith ierr = PetscInfo1(0,"Python: loaded dynamic library %s\n", pythonlib);CHKERRQ(ierr); 117c4aff060SBarry Smith /* look required symbols from the Python C-API */ 118e0ab9aedSLisandro Dalcin ierr = PetscDLPyLibSym("_Py_NoneStruct" , &Py_None );CHKERRQ(ierr); 1199ac80d5eSLisandro Dalcin ierr = PetscDLPyLibSym("Py_GetVersion" , &Py_GetVersion );CHKERRQ(ierr); 120c4aff060SBarry Smith ierr = PetscDLPyLibSym("Py_IsInitialized" , &Py_IsInitialized );CHKERRQ(ierr); 121c4aff060SBarry Smith ierr = PetscDLPyLibSym("Py_InitializeEx" , &Py_InitializeEx );CHKERRQ(ierr); 122c4aff060SBarry Smith ierr = PetscDLPyLibSym("Py_Finalize" , &Py_Finalize );CHKERRQ(ierr); 1232f2e82b0SLisandro Dalcin ierr = PetscDLPyLibSym("PySys_GetObject" , &PySys_GetObject );CHKERRQ(ierr); 124c4aff060SBarry Smith ierr = PetscDLPyLibSym("PySys_SetArgv" , &PySys_SetArgv );CHKERRQ(ierr); 1252f2e82b0SLisandro Dalcin ierr = PetscDLPyLibSym("PyObject_CallMethod" , &PyObject_CallMethod );CHKERRQ(ierr); 126c4aff060SBarry Smith ierr = PetscDLPyLibSym("PyImport_ImportModule" , &PyImport_ImportModule );CHKERRQ(ierr); 127c4aff060SBarry Smith ierr = PetscDLPyLibSym("Py_IncRef" , &Py_IncRef );CHKERRQ(ierr); 128c4aff060SBarry Smith ierr = PetscDLPyLibSym("Py_DecRef" , &Py_DecRef );CHKERRQ(ierr); 129c4aff060SBarry Smith ierr = PetscDLPyLibSym("PyErr_Clear" , &PyErr_Clear );CHKERRQ(ierr); 130c4aff060SBarry Smith ierr = PetscDLPyLibSym("PyErr_Occurred" , &PyErr_Occurred );CHKERRQ(ierr); 131e0ab9aedSLisandro Dalcin ierr = PetscDLPyLibSym("PyErr_Fetch" , &PyErr_Fetch );CHKERRQ(ierr); 132e0ab9aedSLisandro Dalcin ierr = PetscDLPyLibSym("PyErr_NormalizeException", &PyErr_NormalizeException);CHKERRQ(ierr); 133e0ab9aedSLisandro Dalcin ierr = PetscDLPyLibSym("PyErr_Display", &PyErr_Display );CHKERRQ(ierr); 134e0ab9aedSLisandro Dalcin ierr = PetscDLPyLibSym("PyErr_Restore", &PyErr_Restore );CHKERRQ(ierr); 135c4aff060SBarry Smith /* XXX TODO: check that ALL symbols were there !!! */ 136e0ab9aedSLisandro Dalcin if (!Py_None) SETERRQ(PETSC_COMM_SELF,1,"Python: failed to load symbols from dynamic library"); 1379ac80d5eSLisandro Dalcin if (!Py_GetVersion) SETERRQ(PETSC_COMM_SELF,1,"Python: failed to load symbols from dynamic library"); 138c1235816SBarry Smith if (!Py_IsInitialized) SETERRQ(PETSC_COMM_SELF,1,"Python: failed to load symbols from dynamic library"); 139c1235816SBarry Smith if (!Py_InitializeEx) SETERRQ(PETSC_COMM_SELF,1,"Python: failed to load symbols from dynamic library"); 140c1235816SBarry Smith if (!Py_Finalize) SETERRQ(PETSC_COMM_SELF,1,"Python: failed to load symbols from dynamic library"); 141c4aff060SBarry Smith ierr = PetscInfo(0,"Python: all required symbols loaded from Python dynamic library\n");CHKERRQ(ierr); 142c4aff060SBarry Smith PetscFunctionReturn(0); 143c4aff060SBarry Smith } 144c4aff060SBarry Smith 145c4aff060SBarry Smith /* ---------------------------------------------------------------- */ 146c4aff060SBarry Smith 147c4aff060SBarry Smith static char PetscPythonExe[PETSC_MAX_PATH_LEN] = { 0 }; 148c4aff060SBarry Smith static char PetscPythonLib[PETSC_MAX_PATH_LEN] = { 0 }; 149ace3abfcSBarry Smith static PetscBool PetscBeganPython = PETSC_FALSE; 150c4aff060SBarry Smith 151c4aff060SBarry Smith /*@C 152c4aff060SBarry Smith PetscPythonFinalize - Finalize Python. 153c4aff060SBarry Smith 154c4aff060SBarry Smith Level: intermediate 155c4aff060SBarry Smith 156c4aff060SBarry Smith .keywords: Python 157c4aff060SBarry Smith @*/ 1587087cfbeSBarry Smith PetscErrorCode PetscPythonFinalize(void) 159c4aff060SBarry Smith { 160c4aff060SBarry Smith PetscFunctionBegin; 161c4aff060SBarry Smith if (PetscBeganPython) { if (Py_IsInitialized()) Py_Finalize(); } 162c4aff060SBarry Smith PetscBeganPython = PETSC_FALSE; 163c4aff060SBarry Smith PetscFunctionReturn(0); 164c4aff060SBarry Smith } 165c4aff060SBarry Smith 166c4aff060SBarry Smith /*@C 167c4aff060SBarry Smith PetscPythonInitialize - Initialize Python and import petsc4py. 168c4aff060SBarry Smith 169c4aff060SBarry Smith Input Parameter: 1700298fd71SBarry Smith + pyexe - path to the Python interpreter executable, or NULL. 1710298fd71SBarry Smith - pylib - full path to the Python dynamic library, or NULL. 172c4aff060SBarry Smith 173c4aff060SBarry Smith Level: intermediate 174c4aff060SBarry Smith 175c4aff060SBarry Smith .keywords: Python 176c4aff060SBarry Smith 177c4aff060SBarry Smith @*/ 1787087cfbeSBarry Smith PetscErrorCode PetscPythonInitialize(const char pyexe[],const char pylib[]) 179c4aff060SBarry Smith { 180c4aff060SBarry Smith PyObject *module = 0; 181c4aff060SBarry Smith PetscErrorCode ierr; 1826e111a19SKarl Rupp 183c4aff060SBarry Smith PetscFunctionBegin; 184c4aff060SBarry Smith if (PetscBeganPython) PetscFunctionReturn(0); 185c4aff060SBarry Smith /* Python executable */ 186c4aff060SBarry Smith if (pyexe && pyexe[0] != 0) { 187c4aff060SBarry Smith ierr = PetscStrncpy(PetscPythonExe,pyexe,sizeof(PetscPythonExe));CHKERRQ(ierr); 188c4aff060SBarry Smith } else { 189c4aff060SBarry Smith ierr = PetscPythonFindExecutable(PetscPythonExe);CHKERRQ(ierr); 190c4aff060SBarry Smith } 191c4aff060SBarry Smith /* Python dynamic library */ 192c4aff060SBarry Smith if (pylib && pylib[0] != 0) { 193c4aff060SBarry Smith ierr = PetscStrncpy(PetscPythonLib,pylib,sizeof(PetscPythonLib));CHKERRQ(ierr); 194c4aff060SBarry Smith } else { 195c4aff060SBarry Smith ierr = PetscPythonFindLibrary(PetscPythonExe,PetscPythonLib);CHKERRQ(ierr); 196c4aff060SBarry Smith } 197c4aff060SBarry Smith /* dynamically load Python library */ 198c4aff060SBarry Smith ierr = PetscPythonLoadLibrary(PetscPythonLib);CHKERRQ(ierr); 199c4aff060SBarry Smith /* initialize Python */ 200c4aff060SBarry Smith PetscBeganPython = PETSC_FALSE; 201c4aff060SBarry Smith if (!Py_IsInitialized()) { 2022f2e82b0SLisandro Dalcin static PetscBool registered = PETSC_FALSE; 2032f2e82b0SLisandro Dalcin const char *py_version; 2042f2e82b0SLisandro Dalcin PyObject *sys_path; 2052f2e82b0SLisandro Dalcin char path[PETSC_MAX_PATH_LEN] = { 0 }; 206a297a907SKarl Rupp 2072f2e82b0SLisandro Dalcin /* initialize Python */ 2082f2e82b0SLisandro Dalcin Py_InitializeEx(0); /* 0: do not install signal handlers */ 2092f2e82b0SLisandro Dalcin /* build 'sys.argv' list */ 2102f2e82b0SLisandro Dalcin py_version = Py_GetVersion(); 2119ac80d5eSLisandro Dalcin if (py_version[0] == '2') { 2122f2e82b0SLisandro Dalcin int argc = 0; char **argv = 0; 213c4aff060SBarry Smith ierr = PetscGetArgs(&argc,&argv);CHKERRQ(ierr); 2142f2e82b0SLisandro Dalcin PySys_SetArgv(argc,argv); 2152f2e82b0SLisandro Dalcin } 2162f2e82b0SLisandro Dalcin if (py_version[0] == '3') { 2172f2e82b0SLisandro Dalcin /* XXX 'argv' is type 'wchar_t**' */ 2180298fd71SBarry Smith PySys_SetArgv(0,NULL); 2192f2e82b0SLisandro Dalcin } 2202f2e82b0SLisandro Dalcin /* add PETSC_LIB_DIR in front of 'sys.path' */ 2212f2e82b0SLisandro Dalcin sys_path = PySys_GetObject("path"); 2222f2e82b0SLisandro Dalcin if (sys_path) { 2232f2e82b0SLisandro Dalcin ierr = PetscStrreplace(PETSC_COMM_SELF,"${PETSC_LIB_DIR}",path,sizeof(path));CHKERRQ(ierr); 2242f2e82b0SLisandro Dalcin Py_DecRef(PyObject_CallMethod(sys_path,"insert","is",(int)0,(char*)path)); 2259ac80d5eSLisandro Dalcin } 226c4aff060SBarry Smith /* register finalizer */ 227c4aff060SBarry Smith if (!registered) { 228c4aff060SBarry Smith ierr = PetscRegisterFinalize(PetscPythonFinalize);CHKERRQ(ierr); 229a297a907SKarl Rupp 230c4aff060SBarry Smith registered = PETSC_TRUE; 231c4aff060SBarry Smith } 232c4aff060SBarry Smith PetscBeganPython = PETSC_TRUE; 233c4aff060SBarry Smith } 234c4aff060SBarry Smith /* import 'petsc4py.PETSc' module */ 235c4aff060SBarry Smith module = PyImport_ImportModule("petsc4py.PETSc"); 236c4aff060SBarry Smith if (module) { 237c4aff060SBarry Smith ierr = PetscInfo(0,"Python: successfully imported module 'petsc4py.PETSc'\n");CHKERRQ(ierr); 238a297a907SKarl Rupp 239c4aff060SBarry Smith Py_DecRef(module); module = 0; 240c4aff060SBarry Smith } else { 241e0ab9aedSLisandro Dalcin PetscPythonPrintError(); 242e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Python: could not import module 'petsc4py.PETSc', perhaps your PYTHONPATH does not contain it\n"); 243c4aff060SBarry Smith } 244c4aff060SBarry Smith PetscFunctionReturn(0); 245c4aff060SBarry Smith } 246c4aff060SBarry Smith 247e0ab9aedSLisandro Dalcin /*@C 248e0ab9aedSLisandro Dalcin PetscPythonPrintError - Print Python errors. 249e0ab9aedSLisandro Dalcin 250e0ab9aedSLisandro Dalcin Level: developer 251e0ab9aedSLisandro Dalcin 252e0ab9aedSLisandro Dalcin .keywords: Python 253e0ab9aedSLisandro Dalcin 254e0ab9aedSLisandro Dalcin @*/ 2557087cfbeSBarry Smith PetscErrorCode PetscPythonPrintError(void) 256e0ab9aedSLisandro Dalcin { 257e0ab9aedSLisandro Dalcin PyObject *exc=0, *val=0, *tb=0; 2586e111a19SKarl Rupp 259e0ab9aedSLisandro Dalcin PetscFunctionBegin; 260e0ab9aedSLisandro Dalcin if (!PetscBeganPython) PetscFunctionReturn(0); 261e0ab9aedSLisandro Dalcin if (!PyErr_Occurred()) PetscFunctionReturn(0); 262e0ab9aedSLisandro Dalcin PyErr_Fetch(&exc,&val,&tb); 263e0ab9aedSLisandro Dalcin PyErr_NormalizeException(&exc,&val,&tb); 264e0ab9aedSLisandro Dalcin PyErr_Display(exc ? exc : Py_None, 265e0ab9aedSLisandro Dalcin val ? val : Py_None, 266e0ab9aedSLisandro Dalcin tb ? tb : Py_None); 267e0ab9aedSLisandro Dalcin PyErr_Restore(exc,val,tb); 268e0ab9aedSLisandro Dalcin PetscFunctionReturn(0); 269e0ab9aedSLisandro Dalcin } 270e0ab9aedSLisandro Dalcin 271c4aff060SBarry Smith /* ---------------------------------------------------------------- */ 2725180491cSLisandro Dalcin 2738cc058d9SJed Brown PETSC_EXTERN PetscErrorCode (*PetscPythonMonitorSet_C)(PetscObject,const char[]); 2740298fd71SBarry Smith PetscErrorCode (*PetscPythonMonitorSet_C)(PetscObject,const char[]) = NULL; 2755180491cSLisandro Dalcin 2765180491cSLisandro Dalcin /*@C 2775180491cSLisandro Dalcin PetscPythonMonitorSet - Set Python monitor 2785180491cSLisandro Dalcin 2795180491cSLisandro Dalcin Level: developer 2805180491cSLisandro Dalcin 2815180491cSLisandro Dalcin .keywords: Python 2825180491cSLisandro Dalcin 2835180491cSLisandro Dalcin @*/ 2845180491cSLisandro Dalcin PetscErrorCode PetscPythonMonitorSet(PetscObject obj, const char url[]) 2855180491cSLisandro Dalcin { 2865180491cSLisandro Dalcin PetscErrorCode ierr; 2876e111a19SKarl Rupp 2885180491cSLisandro Dalcin PetscFunctionBegin; 2895180491cSLisandro Dalcin PetscValidHeader(obj,1); 2905180491cSLisandro Dalcin PetscValidCharPointer(url,2); 2916c4ed002SBarry Smith if (!PetscPythonMonitorSet_C) { 2920298fd71SBarry Smith ierr = PetscPythonInitialize(NULL,NULL);CHKERRQ(ierr); 2936c4ed002SBarry Smith if (!PetscPythonMonitorSet_C) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Couldn't initialize Python support for monitors"); 2945180491cSLisandro Dalcin } 2955180491cSLisandro Dalcin ierr = PetscPythonMonitorSet_C(obj,url);CHKERRQ(ierr); 2965180491cSLisandro Dalcin PetscFunctionReturn(0); 2975180491cSLisandro Dalcin } 2985180491cSLisandro Dalcin 2995180491cSLisandro Dalcin /* ---------------------------------------------------------------- */ 300