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 99371c9d4SSatish Balay static PetscErrorCode PetscPythonFindExecutable(char pythonexe[], size_t len) { 10ace3abfcSBarry Smith PetscBool flag; 116e111a19SKarl Rupp 12c4aff060SBarry Smith PetscFunctionBegin; 13c4aff060SBarry Smith /* get the path for the Python interpreter executable */ 149566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(pythonexe, PETSC_PYTHON_EXE, len)); 159566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetString(NULL, NULL, "-python", pythonexe, len, &flag)); 16*48a46eb9SPierre Jolivet if (!flag || pythonexe[0] == 0) PetscCall(PetscStrncpy(pythonexe, PETSC_PYTHON_EXE, len)); 17c4aff060SBarry Smith PetscFunctionReturn(0); 18c4aff060SBarry Smith } 19c4aff060SBarry Smith 200dfec4cbSBarry Smith /* 210dfec4cbSBarry Smith Python does not appear to have a universal way to indicate the location of Python dynamic library so try several possibilities 220dfec4cbSBarry Smith */ 239371c9d4SSatish Balay static PetscErrorCode PetscPythonFindLibraryName(const char pythonexe[], const char attempt[], char pythonlib[], size_t pl, PetscBool *found) { 240dfec4cbSBarry Smith char command[2 * PETSC_MAX_PATH_LEN]; 25c4aff060SBarry Smith FILE *fp = NULL; 260dfec4cbSBarry Smith char *eol; 270dfec4cbSBarry Smith 280dfec4cbSBarry Smith PetscFunctionBegin; 290dfec4cbSBarry Smith /* call Python to find out the name of the Python dynamic library */ 309566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(command, pythonexe, sizeof(command))); 319566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(command, " ", sizeof(command))); 329566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(command, attempt, sizeof(command))); 330dfec4cbSBarry Smith #if defined(PETSC_HAVE_POPEN) 349566063dSJacob Faibussowitsch PetscCall(PetscPOpen(PETSC_COMM_SELF, NULL, command, "r", &fp)); 3508401ef6SPierre Jolivet PetscCheck(fgets(pythonlib, pl, fp), PETSC_COMM_SELF, PETSC_ERR_PLIB, "Python: bad output from executable: %s\nRunning: %s", pythonexe, command); 369566063dSJacob Faibussowitsch PetscCall(PetscPClose(PETSC_COMM_SELF, fp)); 370dfec4cbSBarry Smith #else 38691b26d3SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Python: Aborted due to missing popen()"); 390dfec4cbSBarry Smith #endif 400dfec4cbSBarry Smith /* remove newlines */ 419566063dSJacob Faibussowitsch PetscCall(PetscStrchr(pythonlib, '\n', &eol)); 420dfec4cbSBarry Smith if (eol) eol[0] = 0; 439566063dSJacob Faibussowitsch PetscCall(PetscTestFile(pythonlib, 'r', found)); 440dfec4cbSBarry Smith PetscFunctionReturn(0); 450dfec4cbSBarry Smith } 460dfec4cbSBarry Smith 479371c9d4SSatish Balay static PetscErrorCode PetscPythonFindLibrary(const char pythonexe[], char pythonlib[], size_t pl) { 48d118d7f3SJed Brown const char cmdline1[] = "-c 'import os, sysconfig; print(os.path.join(sysconfig.get_config_var(\"LIBDIR\"),sysconfig.get_config_var(\"LDLIBRARY\")))'"; 4982bdbe8dSSatish Balay const char cmdline2[] = "-c 'import os, sysconfig; print(os.path.join(sysconfig.get_path(\"stdlib\"),os.path.pardir,\"libpython\"+sysconfig.get_python_version()+\".dylib\"))'"; 50d118d7f3SJed Brown const char cmdline3[] = "-c 'import os, sysconfig; print(os.path.join(sysconfig.get_config_var(\"LIBPL\"),sysconfig.get_config_var(\"LDLIBRARY\")))'"; 51d118d7f3SJed Brown const char cmdline4[] = "-c 'import sysconfig; print(sysconfig.get_config_var(\"LIBPYTHON\"))'"; 52d118d7f3SJed Brown const char cmdline5[] = "-c 'import os, sysconfig; import sys;print(os.path.join(sysconfig.get_config_var(\"LIBDIR\"),\"libpython\"+sys.version[:3]+\".so\"))'"; 53702f9f58SSatish Balay 54ace3abfcSBarry Smith PetscBool found = PETSC_FALSE; 55c4aff060SBarry Smith 566e111a19SKarl Rupp PetscFunctionBegin; 57c4aff060SBarry Smith #if defined(PETSC_PYTHON_LIB) 589566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(pythonlib, PETSC_PYTHON_LIB, pl)); 59c4aff060SBarry Smith PetscFunctionReturn(0); 60c4aff060SBarry Smith #endif 61c4aff060SBarry Smith 629566063dSJacob Faibussowitsch PetscCall(PetscPythonFindLibraryName(pythonexe, cmdline1, pythonlib, pl, &found)); 63*48a46eb9SPierre Jolivet if (!found) PetscCall(PetscPythonFindLibraryName(pythonexe, cmdline2, pythonlib, pl, &found)); 64*48a46eb9SPierre Jolivet if (!found) PetscCall(PetscPythonFindLibraryName(pythonexe, cmdline3, pythonlib, pl, &found)); 65*48a46eb9SPierre Jolivet if (!found) PetscCall(PetscPythonFindLibraryName(pythonexe, cmdline4, pythonlib, pl, &found)); 66*48a46eb9SPierre Jolivet if (!found) PetscCall(PetscPythonFindLibraryName(pythonexe, cmdline5, pythonlib, pl, &found)); 679566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Python library %s found %d\n", pythonlib, found)); 68c4aff060SBarry Smith PetscFunctionReturn(0); 69c4aff060SBarry Smith } 70c4aff060SBarry Smith 71c4aff060SBarry Smith /* ---------------------------------------------------------------- */ 72c4aff060SBarry Smith 73c4aff060SBarry Smith typedef struct _Py_object_t PyObject; /* fake definition */ 74c4aff060SBarry Smith 7502c9f0b5SLisandro Dalcin static PyObject *Py_None = NULL; 76e0ab9aedSLisandro Dalcin 779ac80d5eSLisandro Dalcin static const char *(*Py_GetVersion)(void); 789ac80d5eSLisandro Dalcin 79c4aff060SBarry Smith static int (*Py_IsInitialized)(void); 80c4aff060SBarry Smith static void (*Py_InitializeEx)(int); 81c4aff060SBarry Smith static void (*Py_Finalize)(void); 82c4aff060SBarry Smith 8349a6f2e5SLisandro Dalcin static void (*PySys_SetArgv)(int, void *); 842f2e82b0SLisandro Dalcin static PyObject *(*PySys_GetObject)(const char *); 852f2e82b0SLisandro Dalcin static PyObject *(*PyObject_CallMethod)(PyObject *, const char *, const char *, ...); 86c4aff060SBarry Smith static PyObject *(*PyImport_ImportModule)(const char *); 87c4aff060SBarry Smith 88c4aff060SBarry Smith static void (*Py_IncRef)(PyObject *); 89c4aff060SBarry Smith static void (*Py_DecRef)(PyObject *); 90c4aff060SBarry Smith 91c4aff060SBarry Smith static void (*PyErr_Clear)(void); 92c4aff060SBarry Smith static PyObject *(*PyErr_Occurred)(void); 93e0ab9aedSLisandro Dalcin static void (*PyErr_Fetch)(PyObject **, PyObject **, PyObject **); 94e0ab9aedSLisandro Dalcin static void (*PyErr_NormalizeException)(PyObject **, PyObject **, PyObject **); 95e0ab9aedSLisandro Dalcin static void (*PyErr_Display)(PyObject *, PyObject *, PyObject *); 96e0ab9aedSLisandro Dalcin static void (*PyErr_Restore)(PyObject *, PyObject *, PyObject *); 97c4aff060SBarry Smith 989371c9d4SSatish Balay #define PetscDLPyLibOpen(libname) PetscDLLibraryAppend(PETSC_COMM_SELF, &PetscDLLibrariesLoaded, libname) 999371c9d4SSatish Balay #define PetscDLPyLibSym(symbol, value) PetscDLLibrarySym(PETSC_COMM_SELF, &PetscDLLibrariesLoaded, NULL, symbol, (void **)value) 100c4aff060SBarry Smith #define PetscDLPyLibClose(comm) \ 1019371c9d4SSatish Balay do { \ 1029371c9d4SSatish Balay } while (0) 103c4aff060SBarry Smith 1049371c9d4SSatish Balay static PetscErrorCode PetscPythonLoadLibrary(const char pythonlib[]) { 1056e111a19SKarl Rupp PetscFunctionBegin; 106c4aff060SBarry Smith /* open the Python dynamic library */ 1079566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibOpen(pythonlib)); 1089566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Python: loaded dynamic library %s\n", pythonlib)); 109c4aff060SBarry Smith /* look required symbols from the Python C-API */ 1109566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("_Py_NoneStruct", &Py_None)); 1119566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("Py_GetVersion", &Py_GetVersion)); 1129566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("Py_IsInitialized", &Py_IsInitialized)); 1139566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("Py_InitializeEx", &Py_InitializeEx)); 1149566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("Py_Finalize", &Py_Finalize)); 1159566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PySys_GetObject", &PySys_GetObject)); 1169566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PySys_SetArgv", &PySys_SetArgv)); 1179566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyObject_CallMethod", &PyObject_CallMethod)); 1189566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyImport_ImportModule", &PyImport_ImportModule)); 1199566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("Py_IncRef", &Py_IncRef)); 1209566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("Py_DecRef", &Py_DecRef)); 1219566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyErr_Clear", &PyErr_Clear)); 1229566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyErr_Occurred", &PyErr_Occurred)); 1239566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyErr_Fetch", &PyErr_Fetch)); 1249566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyErr_NormalizeException", &PyErr_NormalizeException)); 1259566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyErr_Display", &PyErr_Display)); 1269566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyErr_Restore", &PyErr_Restore)); 127c4aff060SBarry Smith /* XXX TODO: check that ALL symbols were there !!! */ 12828b400f6SJacob Faibussowitsch PetscCheck(Py_None, PETSC_COMM_SELF, PETSC_ERR_LIB, "Python: failed to load symbols from Python dynamic library %s", pythonlib); 12928b400f6SJacob Faibussowitsch PetscCheck(Py_GetVersion, PETSC_COMM_SELF, PETSC_ERR_LIB, "Python: failed to load symbols from Python dynamic library %s", pythonlib); 13028b400f6SJacob Faibussowitsch PetscCheck(Py_IsInitialized, PETSC_COMM_SELF, PETSC_ERR_LIB, "Python: failed to load symbols from Python dynamic library %s", pythonlib); 13128b400f6SJacob Faibussowitsch PetscCheck(Py_InitializeEx, PETSC_COMM_SELF, PETSC_ERR_LIB, "Python: failed to load symbols from Python dynamic library %s", pythonlib); 13228b400f6SJacob Faibussowitsch PetscCheck(Py_Finalize, PETSC_COMM_SELF, PETSC_ERR_LIB, "Python: failed to load symbols from Python dynamic library %s", pythonlib); 1339566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Python: all required symbols loaded from Python dynamic library %s\n", pythonlib)); 134c4aff060SBarry Smith PetscFunctionReturn(0); 135c4aff060SBarry Smith } 136c4aff060SBarry Smith 137c4aff060SBarry Smith /* ---------------------------------------------------------------- */ 138c4aff060SBarry Smith 139c4aff060SBarry Smith static char PetscPythonExe[PETSC_MAX_PATH_LEN] = {0}; 140c4aff060SBarry Smith static char PetscPythonLib[PETSC_MAX_PATH_LEN] = {0}; 141ace3abfcSBarry Smith static PetscBool PetscBeganPython = PETSC_FALSE; 142c4aff060SBarry Smith 143c4aff060SBarry Smith /*@C 144c4aff060SBarry Smith PetscPythonFinalize - Finalize Python. 145c4aff060SBarry Smith 146c4aff060SBarry Smith Level: intermediate 147c4aff060SBarry Smith 148c4aff060SBarry Smith @*/ 1499371c9d4SSatish Balay PetscErrorCode PetscPythonFinalize(void) { 150c4aff060SBarry Smith PetscFunctionBegin; 1519371c9d4SSatish Balay if (PetscBeganPython) { 1529371c9d4SSatish Balay if (Py_IsInitialized()) Py_Finalize(); 1539371c9d4SSatish Balay } 154c4aff060SBarry Smith PetscBeganPython = PETSC_FALSE; 155c4aff060SBarry Smith PetscFunctionReturn(0); 156c4aff060SBarry Smith } 157c4aff060SBarry Smith 158c4aff060SBarry Smith /*@C 159c4aff060SBarry Smith PetscPythonInitialize - Initialize Python and import petsc4py. 160c4aff060SBarry Smith 1611179163eSBarry Smith Input Parameters: 1620298fd71SBarry Smith + pyexe - path to the Python interpreter executable, or NULL. 1630298fd71SBarry Smith - pylib - full path to the Python dynamic library, or NULL. 164c4aff060SBarry Smith 165c4aff060SBarry Smith Level: intermediate 166c4aff060SBarry Smith 167c4aff060SBarry Smith @*/ 1689371c9d4SSatish Balay PetscErrorCode PetscPythonInitialize(const char pyexe[], const char pylib[]) { 16902c9f0b5SLisandro Dalcin PyObject *module = NULL; 1706e111a19SKarl Rupp 171c4aff060SBarry Smith PetscFunctionBegin; 172c4aff060SBarry Smith if (PetscBeganPython) PetscFunctionReturn(0); 173c4aff060SBarry Smith /* Python executable */ 174c4aff060SBarry Smith if (pyexe && pyexe[0] != 0) { 1759566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(PetscPythonExe, pyexe, sizeof(PetscPythonExe))); 176c4aff060SBarry Smith } else { 1779566063dSJacob Faibussowitsch PetscCall(PetscPythonFindExecutable(PetscPythonExe, sizeof(PetscPythonExe))); 178c4aff060SBarry Smith } 179c4aff060SBarry Smith /* Python dynamic library */ 180c4aff060SBarry Smith if (pylib && pylib[0] != 0) { 1819566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(PetscPythonLib, pylib, sizeof(PetscPythonLib))); 182c4aff060SBarry Smith } else { 1839566063dSJacob Faibussowitsch PetscCall(PetscPythonFindLibrary(PetscPythonExe, PetscPythonLib, sizeof(PetscPythonLib))); 184c4aff060SBarry Smith } 185c4aff060SBarry Smith /* dynamically load Python library */ 1869566063dSJacob Faibussowitsch PetscCall(PetscPythonLoadLibrary(PetscPythonLib)); 187c4aff060SBarry Smith /* initialize Python */ 188c4aff060SBarry Smith PetscBeganPython = PETSC_FALSE; 189c4aff060SBarry Smith if (!Py_IsInitialized()) { 1902f2e82b0SLisandro Dalcin static PetscBool registered = PETSC_FALSE; 1912f2e82b0SLisandro Dalcin const char *py_version; 1922f2e82b0SLisandro Dalcin PyObject *sys_path; 1932f2e82b0SLisandro Dalcin char path[PETSC_MAX_PATH_LEN] = {0}; 194a297a907SKarl Rupp 195095e973bSBarry Smith /* initialize Python. Py_InitializeEx() prints an error and EXITS the program if it is not successful! */ 196095e973bSBarry Smith PetscCall(PetscInfo(NULL, "Calling Py_InitializeEx(0);\n")); 1972f2e82b0SLisandro Dalcin Py_InitializeEx(0); /* 0: do not install signal handlers */ 198095e973bSBarry Smith PetscCall(PetscInfo(NULL, "Py_InitializeEx(0) called successfully;\n")); 199095e973bSBarry Smith 2002f2e82b0SLisandro Dalcin /* build 'sys.argv' list */ 2012f2e82b0SLisandro Dalcin py_version = Py_GetVersion(); 2029ac80d5eSLisandro Dalcin if (py_version[0] == '2') { 2039371c9d4SSatish Balay int argc = 0; 2049371c9d4SSatish Balay char *argv[1] = {NULL}; 2052f2e82b0SLisandro Dalcin PySys_SetArgv(argc, argv); 2062f2e82b0SLisandro Dalcin } 2072f2e82b0SLisandro Dalcin if (py_version[0] == '3') { 2089371c9d4SSatish Balay int argc = 0; 2099371c9d4SSatish Balay wchar_t *argv[1] = {NULL}; 21049a6f2e5SLisandro Dalcin PySys_SetArgv(argc, argv); 2112f2e82b0SLisandro Dalcin } 2122f2e82b0SLisandro Dalcin /* add PETSC_LIB_DIR in front of 'sys.path' */ 2132f2e82b0SLisandro Dalcin sys_path = PySys_GetObject("path"); 2142f2e82b0SLisandro Dalcin if (sys_path) { 2159566063dSJacob Faibussowitsch PetscCall(PetscStrreplace(PETSC_COMM_SELF, "${PETSC_LIB_DIR}", path, sizeof(path))); 2162f2e82b0SLisandro Dalcin Py_DecRef(PyObject_CallMethod(sys_path, "insert", "is", (int)0, (char *)path)); 21758c0e507SSatish Balay #if defined(PETSC_PETSC4PY_INSTALL_PATH) 21858c0e507SSatish Balay { 21958c0e507SSatish Balay char *rpath; 2209566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_PETSC4PY_INSTALL_PATH, &rpath)); 22158c0e507SSatish Balay Py_DecRef(PyObject_CallMethod(sys_path, "insert", "is", (int)0, rpath)); 2229566063dSJacob Faibussowitsch PetscCall(PetscFree(rpath)); 22358c0e507SSatish Balay } 22458c0e507SSatish Balay #endif 2259ac80d5eSLisandro Dalcin } 226c4aff060SBarry Smith /* register finalizer */ 227c4aff060SBarry Smith if (!registered) { 2289566063dSJacob Faibussowitsch PetscCall(PetscRegisterFinalize(PetscPythonFinalize)); 229c4aff060SBarry Smith registered = PETSC_TRUE; 230c4aff060SBarry Smith } 231c4aff060SBarry Smith PetscBeganPython = PETSC_TRUE; 232095e973bSBarry Smith PetscCall(PetscInfo(NULL, "Python initialize completed.\n")); 233c4aff060SBarry Smith } 234c4aff060SBarry Smith /* import 'petsc4py.PETSc' module */ 235c4aff060SBarry Smith module = PyImport_ImportModule("petsc4py.PETSc"); 236c4aff060SBarry Smith if (module) { 2379566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Python: successfully imported module 'petsc4py.PETSc'\n")); 2389371c9d4SSatish Balay Py_DecRef(module); 2399371c9d4SSatish Balay module = NULL; 240c4aff060SBarry Smith } else { 241e0ab9aedSLisandro Dalcin PetscPythonPrintError(); 242546078acSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Python: could not import module 'petsc4py.PETSc', perhaps your PYTHONPATH does not contain it"); 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 @*/ 2539371c9d4SSatish Balay PetscErrorCode PetscPythonPrintError(void) { 25402c9f0b5SLisandro Dalcin PyObject *exc = NULL, *val = NULL, *tb = NULL; 2556e111a19SKarl Rupp 256e0ab9aedSLisandro Dalcin PetscFunctionBegin; 257e0ab9aedSLisandro Dalcin if (!PetscBeganPython) PetscFunctionReturn(0); 258e0ab9aedSLisandro Dalcin if (!PyErr_Occurred()) PetscFunctionReturn(0); 259e0ab9aedSLisandro Dalcin PyErr_Fetch(&exc, &val, &tb); 260e0ab9aedSLisandro Dalcin PyErr_NormalizeException(&exc, &val, &tb); 261589a23caSBarry Smith PyErr_Display(exc ? exc : Py_None, val ? val : Py_None, tb ? tb : Py_None); 262e0ab9aedSLisandro Dalcin PyErr_Restore(exc, val, tb); 263e0ab9aedSLisandro Dalcin PetscFunctionReturn(0); 264e0ab9aedSLisandro Dalcin } 265e0ab9aedSLisandro Dalcin 266c4aff060SBarry Smith /* ---------------------------------------------------------------- */ 2675180491cSLisandro Dalcin 2688cc058d9SJed Brown PETSC_EXTERN PetscErrorCode (*PetscPythonMonitorSet_C)(PetscObject, const char[]); 2690298fd71SBarry Smith PetscErrorCode (*PetscPythonMonitorSet_C)(PetscObject, const char[]) = NULL; 2705180491cSLisandro Dalcin 2715180491cSLisandro Dalcin /*@C 2725180491cSLisandro Dalcin PetscPythonMonitorSet - Set Python monitor 2735180491cSLisandro Dalcin 2745180491cSLisandro Dalcin Level: developer 2755180491cSLisandro Dalcin 2765180491cSLisandro Dalcin @*/ 2779371c9d4SSatish Balay PetscErrorCode PetscPythonMonitorSet(PetscObject obj, const char url[]) { 2785180491cSLisandro Dalcin PetscFunctionBegin; 2795180491cSLisandro Dalcin PetscValidHeader(obj, 1); 2805180491cSLisandro Dalcin PetscValidCharPointer(url, 2); 2816c4ed002SBarry Smith if (!PetscPythonMonitorSet_C) { 2829566063dSJacob Faibussowitsch PetscCall(PetscPythonInitialize(NULL, NULL)); 28328b400f6SJacob Faibussowitsch PetscCheck(PetscPythonMonitorSet_C, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Couldn't initialize Python support for monitors"); 2845180491cSLisandro Dalcin } 2859566063dSJacob Faibussowitsch PetscCall(PetscPythonMonitorSet_C(obj, url)); 2865180491cSLisandro Dalcin PetscFunctionReturn(0); 2875180491cSLisandro Dalcin } 2885180491cSLisandro Dalcin 2895180491cSLisandro Dalcin /* ---------------------------------------------------------------- */ 290