1af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 2c4aff060SBarry Smith 3c4aff060SBarry Smith #if !defined(PETSC_PYTHON_EXE) 4c4aff060SBarry Smith #define PETSC_PYTHON_EXE "python" 5c4aff060SBarry Smith #endif 6c4aff060SBarry Smith 7d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscPythonFindExecutable(char pythonexe[], size_t len) 8d71ae5a4SJacob Faibussowitsch { 9ace3abfcSBarry Smith PetscBool flag; 106e111a19SKarl Rupp 11c4aff060SBarry Smith PetscFunctionBegin; 12c4aff060SBarry Smith /* get the path for the Python interpreter executable */ 139566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(pythonexe, PETSC_PYTHON_EXE, len)); 149566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetString(NULL, NULL, "-python", pythonexe, len, &flag)); 1548a46eb9SPierre Jolivet if (!flag || pythonexe[0] == 0) PetscCall(PetscStrncpy(pythonexe, PETSC_PYTHON_EXE, len)); 163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17c4aff060SBarry Smith } 18c4aff060SBarry Smith 190dfec4cbSBarry Smith /* 200dfec4cbSBarry Smith Python does not appear to have a universal way to indicate the location of Python dynamic library so try several possibilities 210dfec4cbSBarry Smith */ 22d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscPythonFindLibraryName(const char pythonexe[], const char attempt[], char pythonlib[], size_t pl, PetscBool *found) 23d71ae5a4SJacob Faibussowitsch { 240dfec4cbSBarry Smith char command[2 * PETSC_MAX_PATH_LEN]; 25c4aff060SBarry Smith FILE *fp = NULL; 26bbcf679cSJacob Faibussowitsch char *eol = NULL; 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)); 443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 450dfec4cbSBarry Smith } 460dfec4cbSBarry Smith 47d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscPythonFindLibrary(const char pythonexe[], char pythonlib[], size_t pl) 48d71ae5a4SJacob Faibussowitsch { 49d118d7f3SJed Brown const char cmdline1[] = "-c 'import os, sysconfig; print(os.path.join(sysconfig.get_config_var(\"LIBDIR\"),sysconfig.get_config_var(\"LDLIBRARY\")))'"; 5082bdbe8dSSatish 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\"))'"; 51d118d7f3SJed Brown const char cmdline3[] = "-c 'import os, sysconfig; print(os.path.join(sysconfig.get_config_var(\"LIBPL\"),sysconfig.get_config_var(\"LDLIBRARY\")))'"; 52d118d7f3SJed Brown const char cmdline4[] = "-c 'import sysconfig; print(sysconfig.get_config_var(\"LIBPYTHON\"))'"; 53d118d7f3SJed Brown const char cmdline5[] = "-c 'import os, sysconfig; import sys;print(os.path.join(sysconfig.get_config_var(\"LIBDIR\"),\"libpython\"+sys.version[:3]+\".so\"))'"; 54702f9f58SSatish Balay 55ace3abfcSBarry Smith PetscBool found = PETSC_FALSE; 56c4aff060SBarry Smith 576e111a19SKarl Rupp PetscFunctionBegin; 58c4aff060SBarry Smith #if defined(PETSC_PYTHON_LIB) 599566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(pythonlib, PETSC_PYTHON_LIB, pl)); 603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 61c4aff060SBarry Smith #endif 62c4aff060SBarry Smith 639566063dSJacob Faibussowitsch PetscCall(PetscPythonFindLibraryName(pythonexe, cmdline1, pythonlib, pl, &found)); 6448a46eb9SPierre Jolivet if (!found) PetscCall(PetscPythonFindLibraryName(pythonexe, cmdline2, pythonlib, pl, &found)); 6548a46eb9SPierre Jolivet if (!found) PetscCall(PetscPythonFindLibraryName(pythonexe, cmdline3, pythonlib, pl, &found)); 6648a46eb9SPierre Jolivet if (!found) PetscCall(PetscPythonFindLibraryName(pythonexe, cmdline4, pythonlib, pl, &found)); 6748a46eb9SPierre Jolivet if (!found) PetscCall(PetscPythonFindLibraryName(pythonexe, cmdline5, pythonlib, pl, &found)); 689566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Python library %s found %d\n", pythonlib, found)); 693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 70c4aff060SBarry Smith } 71c4aff060SBarry Smith 72c4aff060SBarry Smith typedef struct _Py_object_t PyObject; /* fake definition */ 73c4aff060SBarry Smith 7402c9f0b5SLisandro Dalcin static PyObject *Py_None = NULL; 75e0ab9aedSLisandro Dalcin 769ac80d5eSLisandro Dalcin static const char *(*Py_GetVersion)(void); 779ac80d5eSLisandro Dalcin 78c4aff060SBarry Smith static int (*Py_IsInitialized)(void); 79c4aff060SBarry Smith static void (*Py_InitializeEx)(int); 80c4aff060SBarry Smith static void (*Py_Finalize)(void); 81c4aff060SBarry Smith 8249a6f2e5SLisandro Dalcin static void (*PySys_SetArgv)(int, void *); 832f2e82b0SLisandro Dalcin static PyObject *(*PySys_GetObject)(const char *); 842f2e82b0SLisandro Dalcin static PyObject *(*PyObject_CallMethod)(PyObject *, const char *, const char *, ...); 85c4aff060SBarry Smith static PyObject *(*PyImport_ImportModule)(const char *); 86c4aff060SBarry Smith 87c4aff060SBarry Smith static void (*Py_IncRef)(PyObject *); 88c4aff060SBarry Smith static void (*Py_DecRef)(PyObject *); 89c4aff060SBarry Smith 90c4aff060SBarry Smith static void (*PyErr_Clear)(void); 91c4aff060SBarry Smith static PyObject *(*PyErr_Occurred)(void); 92e0ab9aedSLisandro Dalcin static void (*PyErr_Fetch)(PyObject **, PyObject **, PyObject **); 93e0ab9aedSLisandro Dalcin static void (*PyErr_NormalizeException)(PyObject **, PyObject **, PyObject **); 94e0ab9aedSLisandro Dalcin static void (*PyErr_Display)(PyObject *, PyObject *, PyObject *); 95e0ab9aedSLisandro Dalcin static void (*PyErr_Restore)(PyObject *, PyObject *, PyObject *); 96c4aff060SBarry Smith 979371c9d4SSatish Balay #define PetscDLPyLibOpen(libname) PetscDLLibraryAppend(PETSC_COMM_SELF, &PetscDLLibrariesLoaded, libname) 989371c9d4SSatish Balay #define PetscDLPyLibSym(symbol, value) PetscDLLibrarySym(PETSC_COMM_SELF, &PetscDLLibrariesLoaded, NULL, symbol, (void **)value) 99c4aff060SBarry Smith #define PetscDLPyLibClose(comm) \ 1009371c9d4SSatish Balay do { \ 1019371c9d4SSatish Balay } while (0) 102c4aff060SBarry Smith 103d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscPythonLoadLibrary(const char pythonlib[]) 104d71ae5a4SJacob Faibussowitsch { 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)); 1343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 135c4aff060SBarry Smith } 136c4aff060SBarry Smith 137c4aff060SBarry Smith static char PetscPythonExe[PETSC_MAX_PATH_LEN] = {0}; 138c4aff060SBarry Smith static char PetscPythonLib[PETSC_MAX_PATH_LEN] = {0}; 139ace3abfcSBarry Smith static PetscBool PetscBeganPython = PETSC_FALSE; 140c4aff060SBarry Smith 141c4aff060SBarry Smith /*@C 142811af0c4SBarry Smith PetscPythonFinalize - Finalize PETSc for use with Python. 143c4aff060SBarry Smith 144c4aff060SBarry Smith Level: intermediate 145c4aff060SBarry Smith 146811af0c4SBarry Smith .seealso: `PetscPythonInitialize()`, `PetscPythonPrintError()` 147c4aff060SBarry Smith @*/ 148d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPythonFinalize(void) 149d71ae5a4SJacob Faibussowitsch { 150c4aff060SBarry Smith PetscFunctionBegin; 1519371c9d4SSatish Balay if (PetscBeganPython) { 1529371c9d4SSatish Balay if (Py_IsInitialized()) Py_Finalize(); 1539371c9d4SSatish Balay } 154c4aff060SBarry Smith PetscBeganPython = PETSC_FALSE; 1553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 156c4aff060SBarry Smith } 157c4aff060SBarry Smith 158c4aff060SBarry Smith /*@C 159811af0c4SBarry Smith PetscPythonInitialize - Initialize Python for use with PETSc and import petsc4py. 160c4aff060SBarry Smith 1611179163eSBarry Smith Input Parameters: 16221532e8aSBarry Smith + pyexe - path to the Python interpreter executable, or `NULL`. 16321532e8aSBarry Smith - pylib - full path to the Python dynamic library, or `NULL`. 164c4aff060SBarry Smith 165c4aff060SBarry Smith Level: intermediate 166c4aff060SBarry Smith 167811af0c4SBarry Smith .seealso: `PetscPythonFinalize()`, `PetscPythonPrintError()` 168c4aff060SBarry Smith @*/ 169d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPythonInitialize(const char pyexe[], const char pylib[]) 170d71ae5a4SJacob Faibussowitsch { 17102c9f0b5SLisandro Dalcin PyObject *module = NULL; 1726e111a19SKarl Rupp 173c4aff060SBarry Smith PetscFunctionBegin; 1743ba16761SJacob Faibussowitsch if (PetscBeganPython) PetscFunctionReturn(PETSC_SUCCESS); 175c4aff060SBarry Smith /* Python executable */ 176c4aff060SBarry Smith if (pyexe && pyexe[0] != 0) { 1779566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(PetscPythonExe, pyexe, sizeof(PetscPythonExe))); 178c4aff060SBarry Smith } else { 1799566063dSJacob Faibussowitsch PetscCall(PetscPythonFindExecutable(PetscPythonExe, sizeof(PetscPythonExe))); 180c4aff060SBarry Smith } 181c4aff060SBarry Smith /* Python dynamic library */ 182c4aff060SBarry Smith if (pylib && pylib[0] != 0) { 1839566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(PetscPythonLib, pylib, sizeof(PetscPythonLib))); 184c4aff060SBarry Smith } else { 1859566063dSJacob Faibussowitsch PetscCall(PetscPythonFindLibrary(PetscPythonExe, PetscPythonLib, sizeof(PetscPythonLib))); 186c4aff060SBarry Smith } 187c4aff060SBarry Smith /* dynamically load Python library */ 1889566063dSJacob Faibussowitsch PetscCall(PetscPythonLoadLibrary(PetscPythonLib)); 189c4aff060SBarry Smith /* initialize Python */ 190c4aff060SBarry Smith PetscBeganPython = PETSC_FALSE; 191c4aff060SBarry Smith if (!Py_IsInitialized()) { 1922f2e82b0SLisandro Dalcin static PetscBool registered = PETSC_FALSE; 1932f2e82b0SLisandro Dalcin const char *py_version; 1942f2e82b0SLisandro Dalcin PyObject *sys_path; 1952f2e82b0SLisandro Dalcin char path[PETSC_MAX_PATH_LEN] = {0}; 196a297a907SKarl Rupp 197095e973bSBarry Smith /* initialize Python. Py_InitializeEx() prints an error and EXITS the program if it is not successful! */ 198095e973bSBarry Smith PetscCall(PetscInfo(NULL, "Calling Py_InitializeEx(0);\n")); 1992f2e82b0SLisandro Dalcin Py_InitializeEx(0); /* 0: do not install signal handlers */ 200095e973bSBarry Smith PetscCall(PetscInfo(NULL, "Py_InitializeEx(0) called successfully;\n")); 201095e973bSBarry Smith 2022f2e82b0SLisandro Dalcin /* build 'sys.argv' list */ 2032f2e82b0SLisandro Dalcin py_version = Py_GetVersion(); 2049ac80d5eSLisandro Dalcin if (py_version[0] == '2') { 2059371c9d4SSatish Balay int argc = 0; 2069371c9d4SSatish Balay char *argv[1] = {NULL}; 2072f2e82b0SLisandro Dalcin PySys_SetArgv(argc, argv); 2082f2e82b0SLisandro Dalcin } 2092f2e82b0SLisandro Dalcin if (py_version[0] == '3') { 2109371c9d4SSatish Balay int argc = 0; 2119371c9d4SSatish Balay wchar_t *argv[1] = {NULL}; 21249a6f2e5SLisandro Dalcin PySys_SetArgv(argc, argv); 2132f2e82b0SLisandro Dalcin } 2142f2e82b0SLisandro Dalcin /* add PETSC_LIB_DIR in front of 'sys.path' */ 2152f2e82b0SLisandro Dalcin sys_path = PySys_GetObject("path"); 2162f2e82b0SLisandro Dalcin if (sys_path) { 2179566063dSJacob Faibussowitsch PetscCall(PetscStrreplace(PETSC_COMM_SELF, "${PETSC_LIB_DIR}", path, sizeof(path))); 2182f2e82b0SLisandro Dalcin Py_DecRef(PyObject_CallMethod(sys_path, "insert", "is", (int)0, (char *)path)); 21958c0e507SSatish Balay #if defined(PETSC_PETSC4PY_INSTALL_PATH) 22058c0e507SSatish Balay { 22158c0e507SSatish Balay char *rpath; 2229566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_PETSC4PY_INSTALL_PATH, &rpath)); 22358c0e507SSatish Balay Py_DecRef(PyObject_CallMethod(sys_path, "insert", "is", (int)0, rpath)); 2249566063dSJacob Faibussowitsch PetscCall(PetscFree(rpath)); 22558c0e507SSatish Balay } 22658c0e507SSatish Balay #endif 2279ac80d5eSLisandro Dalcin } 228c4aff060SBarry Smith /* register finalizer */ 229c4aff060SBarry Smith if (!registered) { 2309566063dSJacob Faibussowitsch PetscCall(PetscRegisterFinalize(PetscPythonFinalize)); 231c4aff060SBarry Smith registered = PETSC_TRUE; 232c4aff060SBarry Smith } 233c4aff060SBarry Smith PetscBeganPython = PETSC_TRUE; 234095e973bSBarry Smith PetscCall(PetscInfo(NULL, "Python initialize completed.\n")); 235c4aff060SBarry Smith } 236c4aff060SBarry Smith /* import 'petsc4py.PETSc' module */ 237c4aff060SBarry Smith module = PyImport_ImportModule("petsc4py.PETSc"); 238c4aff060SBarry Smith if (module) { 2399566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Python: successfully imported module 'petsc4py.PETSc'\n")); 2409371c9d4SSatish Balay Py_DecRef(module); 2419371c9d4SSatish Balay module = NULL; 242c4aff060SBarry Smith } else { 2433ba16761SJacob Faibussowitsch PetscCall(PetscPythonPrintError()); 244546078acSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Python: could not import module 'petsc4py.PETSc', perhaps your PYTHONPATH does not contain it"); 245c4aff060SBarry Smith } 2463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 247c4aff060SBarry Smith } 248c4aff060SBarry Smith 249e0ab9aedSLisandro Dalcin /*@C 250811af0c4SBarry Smith PetscPythonPrintError - Print any current Python errors. 251e0ab9aedSLisandro Dalcin 252e0ab9aedSLisandro Dalcin Level: developer 253e0ab9aedSLisandro Dalcin 254811af0c4SBarry Smith .seealso: `PetscPythonInitialize()`, `PetscPythonFinalize()` 255e0ab9aedSLisandro Dalcin @*/ 256d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPythonPrintError(void) 257d71ae5a4SJacob Faibussowitsch { 25802c9f0b5SLisandro Dalcin PyObject *exc = NULL, *val = NULL, *tb = NULL; 2596e111a19SKarl Rupp 260e0ab9aedSLisandro Dalcin PetscFunctionBegin; 2613ba16761SJacob Faibussowitsch if (!PetscBeganPython) PetscFunctionReturn(PETSC_SUCCESS); 2623ba16761SJacob Faibussowitsch if (!PyErr_Occurred()) PetscFunctionReturn(PETSC_SUCCESS); 263e0ab9aedSLisandro Dalcin PyErr_Fetch(&exc, &val, &tb); 264e0ab9aedSLisandro Dalcin PyErr_NormalizeException(&exc, &val, &tb); 265589a23caSBarry Smith PyErr_Display(exc ? exc : Py_None, val ? val : Py_None, tb ? tb : Py_None); 266e0ab9aedSLisandro Dalcin PyErr_Restore(exc, val, tb); 2673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 268e0ab9aedSLisandro Dalcin } 269e0ab9aedSLisandro Dalcin 2708cc058d9SJed Brown PETSC_EXTERN PetscErrorCode (*PetscPythonMonitorSet_C)(PetscObject, const char[]); 2710298fd71SBarry Smith PetscErrorCode (*PetscPythonMonitorSet_C)(PetscObject, const char[]) = NULL; 2725180491cSLisandro Dalcin 2735180491cSLisandro Dalcin /*@C 274811af0c4SBarry Smith PetscPythonMonitorSet - Set a Python monitor for a `PetscObject` 2755180491cSLisandro Dalcin 2765180491cSLisandro Dalcin Level: developer 2775180491cSLisandro Dalcin 278811af0c4SBarry Smith .seealso: `PetscPythonInitialize()`, `PetscPythonFinalize()`, `PetscPythonPrintError()` 2795180491cSLisandro Dalcin @*/ 280d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPythonMonitorSet(PetscObject obj, const char url[]) 281d71ae5a4SJacob Faibussowitsch { 2825180491cSLisandro Dalcin PetscFunctionBegin; 2835180491cSLisandro Dalcin PetscValidHeader(obj, 1); 284*4f572ea9SToby Isaac PetscAssertPointer(url, 2); 2856c4ed002SBarry Smith if (!PetscPythonMonitorSet_C) { 2869566063dSJacob Faibussowitsch PetscCall(PetscPythonInitialize(NULL, NULL)); 28728b400f6SJacob Faibussowitsch PetscCheck(PetscPythonMonitorSet_C, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Couldn't initialize Python support for monitors"); 2885180491cSLisandro Dalcin } 2899566063dSJacob Faibussowitsch PetscCall(PetscPythonMonitorSet_C(obj, url)); 2903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2915180491cSLisandro Dalcin } 292