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 9d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscPythonFindExecutable(char pythonexe[], size_t len) 10d71ae5a4SJacob Faibussowitsch { 11ace3abfcSBarry Smith PetscBool flag; 126e111a19SKarl Rupp 13c4aff060SBarry Smith PetscFunctionBegin; 14c4aff060SBarry Smith /* get the path for the Python interpreter executable */ 159566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(pythonexe, PETSC_PYTHON_EXE, len)); 169566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetString(NULL, NULL, "-python", pythonexe, len, &flag)); 1748a46eb9SPierre Jolivet if (!flag || pythonexe[0] == 0) PetscCall(PetscStrncpy(pythonexe, PETSC_PYTHON_EXE, len)); 18*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19c4aff060SBarry Smith } 20c4aff060SBarry Smith 210dfec4cbSBarry Smith /* 220dfec4cbSBarry Smith Python does not appear to have a universal way to indicate the location of Python dynamic library so try several possibilities 230dfec4cbSBarry Smith */ 24d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscPythonFindLibraryName(const char pythonexe[], const char attempt[], char pythonlib[], size_t pl, PetscBool *found) 25d71ae5a4SJacob Faibussowitsch { 260dfec4cbSBarry Smith char command[2 * PETSC_MAX_PATH_LEN]; 27c4aff060SBarry Smith FILE *fp = NULL; 280dfec4cbSBarry Smith char *eol; 290dfec4cbSBarry Smith 300dfec4cbSBarry Smith PetscFunctionBegin; 310dfec4cbSBarry Smith /* call Python to find out the name of the Python dynamic library */ 329566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(command, pythonexe, sizeof(command))); 339566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(command, " ", sizeof(command))); 349566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(command, attempt, sizeof(command))); 350dfec4cbSBarry Smith #if defined(PETSC_HAVE_POPEN) 369566063dSJacob Faibussowitsch PetscCall(PetscPOpen(PETSC_COMM_SELF, NULL, command, "r", &fp)); 3708401ef6SPierre Jolivet PetscCheck(fgets(pythonlib, pl, fp), PETSC_COMM_SELF, PETSC_ERR_PLIB, "Python: bad output from executable: %s\nRunning: %s", pythonexe, command); 389566063dSJacob Faibussowitsch PetscCall(PetscPClose(PETSC_COMM_SELF, fp)); 390dfec4cbSBarry Smith #else 40691b26d3SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Python: Aborted due to missing popen()"); 410dfec4cbSBarry Smith #endif 420dfec4cbSBarry Smith /* remove newlines */ 439566063dSJacob Faibussowitsch PetscCall(PetscStrchr(pythonlib, '\n', &eol)); 440dfec4cbSBarry Smith if (eol) eol[0] = 0; 459566063dSJacob Faibussowitsch PetscCall(PetscTestFile(pythonlib, 'r', found)); 46*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 470dfec4cbSBarry Smith } 480dfec4cbSBarry Smith 49d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscPythonFindLibrary(const char pythonexe[], char pythonlib[], size_t pl) 50d71ae5a4SJacob Faibussowitsch { 51d118d7f3SJed Brown const char cmdline1[] = "-c 'import os, sysconfig; print(os.path.join(sysconfig.get_config_var(\"LIBDIR\"),sysconfig.get_config_var(\"LDLIBRARY\")))'"; 5282bdbe8dSSatish 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\"))'"; 53d118d7f3SJed Brown const char cmdline3[] = "-c 'import os, sysconfig; print(os.path.join(sysconfig.get_config_var(\"LIBPL\"),sysconfig.get_config_var(\"LDLIBRARY\")))'"; 54d118d7f3SJed Brown const char cmdline4[] = "-c 'import sysconfig; print(sysconfig.get_config_var(\"LIBPYTHON\"))'"; 55d118d7f3SJed Brown const char cmdline5[] = "-c 'import os, sysconfig; import sys;print(os.path.join(sysconfig.get_config_var(\"LIBDIR\"),\"libpython\"+sys.version[:3]+\".so\"))'"; 56702f9f58SSatish Balay 57ace3abfcSBarry Smith PetscBool found = PETSC_FALSE; 58c4aff060SBarry Smith 596e111a19SKarl Rupp PetscFunctionBegin; 60c4aff060SBarry Smith #if defined(PETSC_PYTHON_LIB) 619566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(pythonlib, PETSC_PYTHON_LIB, pl)); 62*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 63c4aff060SBarry Smith #endif 64c4aff060SBarry Smith 659566063dSJacob Faibussowitsch PetscCall(PetscPythonFindLibraryName(pythonexe, cmdline1, pythonlib, pl, &found)); 6648a46eb9SPierre Jolivet if (!found) PetscCall(PetscPythonFindLibraryName(pythonexe, cmdline2, pythonlib, pl, &found)); 6748a46eb9SPierre Jolivet if (!found) PetscCall(PetscPythonFindLibraryName(pythonexe, cmdline3, pythonlib, pl, &found)); 6848a46eb9SPierre Jolivet if (!found) PetscCall(PetscPythonFindLibraryName(pythonexe, cmdline4, pythonlib, pl, &found)); 6948a46eb9SPierre Jolivet if (!found) PetscCall(PetscPythonFindLibraryName(pythonexe, cmdline5, pythonlib, pl, &found)); 709566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Python library %s found %d\n", pythonlib, found)); 71*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 72c4aff060SBarry Smith } 73c4aff060SBarry Smith 74c4aff060SBarry Smith /* ---------------------------------------------------------------- */ 75c4aff060SBarry Smith 76c4aff060SBarry Smith typedef struct _Py_object_t PyObject; /* fake definition */ 77c4aff060SBarry Smith 7802c9f0b5SLisandro Dalcin static PyObject *Py_None = NULL; 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 8649a6f2e5SLisandro Dalcin static void (*PySys_SetArgv)(int, void *); 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 1019371c9d4SSatish Balay #define PetscDLPyLibOpen(libname) PetscDLLibraryAppend(PETSC_COMM_SELF, &PetscDLLibrariesLoaded, libname) 1029371c9d4SSatish Balay #define PetscDLPyLibSym(symbol, value) PetscDLLibrarySym(PETSC_COMM_SELF, &PetscDLLibrariesLoaded, NULL, symbol, (void **)value) 103c4aff060SBarry Smith #define PetscDLPyLibClose(comm) \ 1049371c9d4SSatish Balay do { \ 1059371c9d4SSatish Balay } while (0) 106c4aff060SBarry Smith 107d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscPythonLoadLibrary(const char pythonlib[]) 108d71ae5a4SJacob Faibussowitsch { 1096e111a19SKarl Rupp PetscFunctionBegin; 110c4aff060SBarry Smith /* open the Python dynamic library */ 1119566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibOpen(pythonlib)); 1129566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Python: loaded dynamic library %s\n", pythonlib)); 113c4aff060SBarry Smith /* look required symbols from the Python C-API */ 1149566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("_Py_NoneStruct", &Py_None)); 1159566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("Py_GetVersion", &Py_GetVersion)); 1169566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("Py_IsInitialized", &Py_IsInitialized)); 1179566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("Py_InitializeEx", &Py_InitializeEx)); 1189566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("Py_Finalize", &Py_Finalize)); 1199566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PySys_GetObject", &PySys_GetObject)); 1209566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PySys_SetArgv", &PySys_SetArgv)); 1219566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyObject_CallMethod", &PyObject_CallMethod)); 1229566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyImport_ImportModule", &PyImport_ImportModule)); 1239566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("Py_IncRef", &Py_IncRef)); 1249566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("Py_DecRef", &Py_DecRef)); 1259566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyErr_Clear", &PyErr_Clear)); 1269566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyErr_Occurred", &PyErr_Occurred)); 1279566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyErr_Fetch", &PyErr_Fetch)); 1289566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyErr_NormalizeException", &PyErr_NormalizeException)); 1299566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyErr_Display", &PyErr_Display)); 1309566063dSJacob Faibussowitsch PetscCall(PetscDLPyLibSym("PyErr_Restore", &PyErr_Restore)); 131c4aff060SBarry Smith /* XXX TODO: check that ALL symbols were there !!! */ 13228b400f6SJacob Faibussowitsch PetscCheck(Py_None, PETSC_COMM_SELF, PETSC_ERR_LIB, "Python: failed to load symbols from Python dynamic library %s", pythonlib); 13328b400f6SJacob Faibussowitsch PetscCheck(Py_GetVersion, PETSC_COMM_SELF, PETSC_ERR_LIB, "Python: failed to load symbols from Python dynamic library %s", pythonlib); 13428b400f6SJacob Faibussowitsch PetscCheck(Py_IsInitialized, PETSC_COMM_SELF, PETSC_ERR_LIB, "Python: failed to load symbols from Python dynamic library %s", pythonlib); 13528b400f6SJacob Faibussowitsch PetscCheck(Py_InitializeEx, PETSC_COMM_SELF, PETSC_ERR_LIB, "Python: failed to load symbols from Python dynamic library %s", pythonlib); 13628b400f6SJacob Faibussowitsch PetscCheck(Py_Finalize, PETSC_COMM_SELF, PETSC_ERR_LIB, "Python: failed to load symbols from Python dynamic library %s", pythonlib); 1379566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Python: all required symbols loaded from Python dynamic library %s\n", pythonlib)); 138*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 139c4aff060SBarry Smith } 140c4aff060SBarry Smith 141c4aff060SBarry Smith /* ---------------------------------------------------------------- */ 142c4aff060SBarry Smith 143c4aff060SBarry Smith static char PetscPythonExe[PETSC_MAX_PATH_LEN] = {0}; 144c4aff060SBarry Smith static char PetscPythonLib[PETSC_MAX_PATH_LEN] = {0}; 145ace3abfcSBarry Smith static PetscBool PetscBeganPython = PETSC_FALSE; 146c4aff060SBarry Smith 147c4aff060SBarry Smith /*@C 148811af0c4SBarry Smith PetscPythonFinalize - Finalize PETSc for use with Python. 149c4aff060SBarry Smith 150c4aff060SBarry Smith Level: intermediate 151c4aff060SBarry Smith 152811af0c4SBarry Smith .seealso: `PetscPythonInitialize()`, `PetscPythonPrintError()` 153c4aff060SBarry Smith @*/ 154d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPythonFinalize(void) 155d71ae5a4SJacob Faibussowitsch { 156c4aff060SBarry Smith PetscFunctionBegin; 1579371c9d4SSatish Balay if (PetscBeganPython) { 1589371c9d4SSatish Balay if (Py_IsInitialized()) Py_Finalize(); 1599371c9d4SSatish Balay } 160c4aff060SBarry Smith PetscBeganPython = PETSC_FALSE; 161*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 162c4aff060SBarry Smith } 163c4aff060SBarry Smith 164c4aff060SBarry Smith /*@C 165811af0c4SBarry Smith PetscPythonInitialize - Initialize Python for use with PETSc and import petsc4py. 166c4aff060SBarry Smith 1671179163eSBarry Smith Input Parameters: 1680298fd71SBarry Smith + pyexe - path to the Python interpreter executable, or NULL. 1690298fd71SBarry Smith - pylib - full path to the Python dynamic library, or NULL. 170c4aff060SBarry Smith 171c4aff060SBarry Smith Level: intermediate 172c4aff060SBarry Smith 173811af0c4SBarry Smith .seealso: `PetscPythonFinalize()`, `PetscPythonPrintError()` 174c4aff060SBarry Smith @*/ 175d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPythonInitialize(const char pyexe[], const char pylib[]) 176d71ae5a4SJacob Faibussowitsch { 17702c9f0b5SLisandro Dalcin PyObject *module = NULL; 1786e111a19SKarl Rupp 179c4aff060SBarry Smith PetscFunctionBegin; 180*3ba16761SJacob Faibussowitsch if (PetscBeganPython) PetscFunctionReturn(PETSC_SUCCESS); 181c4aff060SBarry Smith /* Python executable */ 182c4aff060SBarry Smith if (pyexe && pyexe[0] != 0) { 1839566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(PetscPythonExe, pyexe, sizeof(PetscPythonExe))); 184c4aff060SBarry Smith } else { 1859566063dSJacob Faibussowitsch PetscCall(PetscPythonFindExecutable(PetscPythonExe, sizeof(PetscPythonExe))); 186c4aff060SBarry Smith } 187c4aff060SBarry Smith /* Python dynamic library */ 188c4aff060SBarry Smith if (pylib && pylib[0] != 0) { 1899566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(PetscPythonLib, pylib, sizeof(PetscPythonLib))); 190c4aff060SBarry Smith } else { 1919566063dSJacob Faibussowitsch PetscCall(PetscPythonFindLibrary(PetscPythonExe, PetscPythonLib, sizeof(PetscPythonLib))); 192c4aff060SBarry Smith } 193c4aff060SBarry Smith /* dynamically load Python library */ 1949566063dSJacob Faibussowitsch PetscCall(PetscPythonLoadLibrary(PetscPythonLib)); 195c4aff060SBarry Smith /* initialize Python */ 196c4aff060SBarry Smith PetscBeganPython = PETSC_FALSE; 197c4aff060SBarry Smith if (!Py_IsInitialized()) { 1982f2e82b0SLisandro Dalcin static PetscBool registered = PETSC_FALSE; 1992f2e82b0SLisandro Dalcin const char *py_version; 2002f2e82b0SLisandro Dalcin PyObject *sys_path; 2012f2e82b0SLisandro Dalcin char path[PETSC_MAX_PATH_LEN] = {0}; 202a297a907SKarl Rupp 203095e973bSBarry Smith /* initialize Python. Py_InitializeEx() prints an error and EXITS the program if it is not successful! */ 204095e973bSBarry Smith PetscCall(PetscInfo(NULL, "Calling Py_InitializeEx(0);\n")); 2052f2e82b0SLisandro Dalcin Py_InitializeEx(0); /* 0: do not install signal handlers */ 206095e973bSBarry Smith PetscCall(PetscInfo(NULL, "Py_InitializeEx(0) called successfully;\n")); 207095e973bSBarry Smith 2082f2e82b0SLisandro Dalcin /* build 'sys.argv' list */ 2092f2e82b0SLisandro Dalcin py_version = Py_GetVersion(); 2109ac80d5eSLisandro Dalcin if (py_version[0] == '2') { 2119371c9d4SSatish Balay int argc = 0; 2129371c9d4SSatish Balay char *argv[1] = {NULL}; 2132f2e82b0SLisandro Dalcin PySys_SetArgv(argc, argv); 2142f2e82b0SLisandro Dalcin } 2152f2e82b0SLisandro Dalcin if (py_version[0] == '3') { 2169371c9d4SSatish Balay int argc = 0; 2179371c9d4SSatish Balay wchar_t *argv[1] = {NULL}; 21849a6f2e5SLisandro Dalcin PySys_SetArgv(argc, argv); 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) { 2239566063dSJacob Faibussowitsch PetscCall(PetscStrreplace(PETSC_COMM_SELF, "${PETSC_LIB_DIR}", path, sizeof(path))); 2242f2e82b0SLisandro Dalcin Py_DecRef(PyObject_CallMethod(sys_path, "insert", "is", (int)0, (char *)path)); 22558c0e507SSatish Balay #if defined(PETSC_PETSC4PY_INSTALL_PATH) 22658c0e507SSatish Balay { 22758c0e507SSatish Balay char *rpath; 2289566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_PETSC4PY_INSTALL_PATH, &rpath)); 22958c0e507SSatish Balay Py_DecRef(PyObject_CallMethod(sys_path, "insert", "is", (int)0, rpath)); 2309566063dSJacob Faibussowitsch PetscCall(PetscFree(rpath)); 23158c0e507SSatish Balay } 23258c0e507SSatish Balay #endif 2339ac80d5eSLisandro Dalcin } 234c4aff060SBarry Smith /* register finalizer */ 235c4aff060SBarry Smith if (!registered) { 2369566063dSJacob Faibussowitsch PetscCall(PetscRegisterFinalize(PetscPythonFinalize)); 237c4aff060SBarry Smith registered = PETSC_TRUE; 238c4aff060SBarry Smith } 239c4aff060SBarry Smith PetscBeganPython = PETSC_TRUE; 240095e973bSBarry Smith PetscCall(PetscInfo(NULL, "Python initialize completed.\n")); 241c4aff060SBarry Smith } 242c4aff060SBarry Smith /* import 'petsc4py.PETSc' module */ 243c4aff060SBarry Smith module = PyImport_ImportModule("petsc4py.PETSc"); 244c4aff060SBarry Smith if (module) { 2459566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Python: successfully imported module 'petsc4py.PETSc'\n")); 2469371c9d4SSatish Balay Py_DecRef(module); 2479371c9d4SSatish Balay module = NULL; 248c4aff060SBarry Smith } else { 249*3ba16761SJacob Faibussowitsch PetscCall(PetscPythonPrintError()); 250546078acSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Python: could not import module 'petsc4py.PETSc', perhaps your PYTHONPATH does not contain it"); 251c4aff060SBarry Smith } 252*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 253c4aff060SBarry Smith } 254c4aff060SBarry Smith 255e0ab9aedSLisandro Dalcin /*@C 256811af0c4SBarry Smith PetscPythonPrintError - Print any current Python errors. 257e0ab9aedSLisandro Dalcin 258e0ab9aedSLisandro Dalcin Level: developer 259e0ab9aedSLisandro Dalcin 260811af0c4SBarry Smith .seealso: `PetscPythonInitialize()`, `PetscPythonFinalize()` 261e0ab9aedSLisandro Dalcin @*/ 262d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPythonPrintError(void) 263d71ae5a4SJacob Faibussowitsch { 26402c9f0b5SLisandro Dalcin PyObject *exc = NULL, *val = NULL, *tb = NULL; 2656e111a19SKarl Rupp 266e0ab9aedSLisandro Dalcin PetscFunctionBegin; 267*3ba16761SJacob Faibussowitsch if (!PetscBeganPython) PetscFunctionReturn(PETSC_SUCCESS); 268*3ba16761SJacob Faibussowitsch if (!PyErr_Occurred()) PetscFunctionReturn(PETSC_SUCCESS); 269e0ab9aedSLisandro Dalcin PyErr_Fetch(&exc, &val, &tb); 270e0ab9aedSLisandro Dalcin PyErr_NormalizeException(&exc, &val, &tb); 271589a23caSBarry Smith PyErr_Display(exc ? exc : Py_None, val ? val : Py_None, tb ? tb : Py_None); 272e0ab9aedSLisandro Dalcin PyErr_Restore(exc, val, tb); 273*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 274e0ab9aedSLisandro Dalcin } 275e0ab9aedSLisandro Dalcin 276c4aff060SBarry Smith /* ---------------------------------------------------------------- */ 2775180491cSLisandro Dalcin 2788cc058d9SJed Brown PETSC_EXTERN PetscErrorCode (*PetscPythonMonitorSet_C)(PetscObject, const char[]); 2790298fd71SBarry Smith PetscErrorCode (*PetscPythonMonitorSet_C)(PetscObject, const char[]) = NULL; 2805180491cSLisandro Dalcin 2815180491cSLisandro Dalcin /*@C 282811af0c4SBarry Smith PetscPythonMonitorSet - Set a Python monitor for a `PetscObject` 2835180491cSLisandro Dalcin 2845180491cSLisandro Dalcin Level: developer 2855180491cSLisandro Dalcin 286811af0c4SBarry Smith .seealso: `PetscPythonInitialize()`, `PetscPythonFinalize()`, `PetscPythonPrintError()` 2875180491cSLisandro Dalcin @*/ 288d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPythonMonitorSet(PetscObject obj, const char url[]) 289d71ae5a4SJacob Faibussowitsch { 2905180491cSLisandro Dalcin PetscFunctionBegin; 2915180491cSLisandro Dalcin PetscValidHeader(obj, 1); 2925180491cSLisandro Dalcin PetscValidCharPointer(url, 2); 2936c4ed002SBarry Smith if (!PetscPythonMonitorSet_C) { 2949566063dSJacob Faibussowitsch PetscCall(PetscPythonInitialize(NULL, NULL)); 29528b400f6SJacob Faibussowitsch PetscCheck(PetscPythonMonitorSet_C, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Couldn't initialize Python support for monitors"); 2965180491cSLisandro Dalcin } 2979566063dSJacob Faibussowitsch PetscCall(PetscPythonMonitorSet_C(obj, url)); 298*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2995180491cSLisandro Dalcin } 3005180491cSLisandro Dalcin 3015180491cSLisandro Dalcin /* ---------------------------------------------------------------- */ 302