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 { 49*0ee64c2aSStefano Zampini // clang-format off 50*0ee64c2aSStefano Zampini const char *const cmdlines[] = {"-c 'import os, sysconfig; print(os.path.join(sysconfig.get_config_var(\"LIBDIR\"),sysconfig.get_config_var(\"LDLIBRARY\")))'", 51*0ee64c2aSStefano Zampini "-c 'import os, sysconfig; print(os.path.join(sysconfig.get_path(\"stdlib\"),os.path.pardir,\"libpython\"+sysconfig.get_python_version()+\".dylib\"))'", 52*0ee64c2aSStefano Zampini "-c 'import os, sysconfig; print(os.path.join(sysconfig.get_path(\"stdlib\"),os.path.pardir,\"libpython\"+sysconfig.get_python_version()+\".so\"))'", 53*0ee64c2aSStefano Zampini "-c 'import os, sysconfig; print(os.path.join(sysconfig.get_config_var(\"LIBPL\"),sysconfig.get_config_var(\"LDLIBRARY\")))'", 54*0ee64c2aSStefano Zampini "-c 'import sysconfig; print(sysconfig.get_config_var(\"LIBPYTHON\"))'", 55*0ee64c2aSStefano Zampini "-c 'import os, sysconfig; print(os.path.join(sysconfig.get_config_var(\"LIBDIR\"),\"libpython\"+sysconfig.get_python_version()+\".dylib\"))'", 56*0ee64c2aSStefano Zampini "-c 'import os, sysconfig; print(os.path.join(sysconfig.get_config_var(\"LIBDIR\"),\"libpython\"+sysconfig.get_python_version()+\".so\"))'"}; 57*0ee64c2aSStefano Zampini // clang-format on 58702f9f58SSatish Balay 59ace3abfcSBarry Smith PetscBool found = PETSC_FALSE; 60c4aff060SBarry Smith 616e111a19SKarl Rupp PetscFunctionBegin; 62c4aff060SBarry Smith #if defined(PETSC_PYTHON_LIB) 639566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(pythonlib, PETSC_PYTHON_LIB, pl)); 643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 65c4aff060SBarry Smith #endif 66c4aff060SBarry Smith 67*0ee64c2aSStefano Zampini for (size_t i = 0; i < PETSC_STATIC_ARRAY_LENGTH(cmdlines); i++) { 68*0ee64c2aSStefano Zampini PetscCall(PetscInfo(NULL, "Looking for Python library with \"%s %s\"\n", pythonexe, cmdlines[i])); 69*0ee64c2aSStefano Zampini PetscCall(PetscPythonFindLibraryName(pythonexe, cmdlines[i], pythonlib, pl, &found)); 70*0ee64c2aSStefano Zampini if (found) break; 71*0ee64c2aSStefano Zampini } 729566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Python library %s found %d\n", pythonlib, found)); 733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 1383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 139c4aff060SBarry Smith } 140c4aff060SBarry Smith 141c4aff060SBarry Smith static char PetscPythonExe[PETSC_MAX_PATH_LEN] = {0}; 142c4aff060SBarry Smith static char PetscPythonLib[PETSC_MAX_PATH_LEN] = {0}; 143ace3abfcSBarry Smith static PetscBool PetscBeganPython = PETSC_FALSE; 144c4aff060SBarry Smith 145c4aff060SBarry Smith /*@C 146811af0c4SBarry Smith PetscPythonFinalize - Finalize PETSc for use with Python. 147c4aff060SBarry Smith 148c4aff060SBarry Smith Level: intermediate 149c4aff060SBarry Smith 150811af0c4SBarry Smith .seealso: `PetscPythonInitialize()`, `PetscPythonPrintError()` 151c4aff060SBarry Smith @*/ 152d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPythonFinalize(void) 153d71ae5a4SJacob Faibussowitsch { 154c4aff060SBarry Smith PetscFunctionBegin; 1559371c9d4SSatish Balay if (PetscBeganPython) { 1569371c9d4SSatish Balay if (Py_IsInitialized()) Py_Finalize(); 1579371c9d4SSatish Balay } 158c4aff060SBarry Smith PetscBeganPython = PETSC_FALSE; 1593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 160c4aff060SBarry Smith } 161c4aff060SBarry Smith 162c4aff060SBarry Smith /*@C 163811af0c4SBarry Smith PetscPythonInitialize - Initialize Python for use with PETSc and import petsc4py. 164c4aff060SBarry Smith 1651179163eSBarry Smith Input Parameters: 16621532e8aSBarry Smith + pyexe - path to the Python interpreter executable, or `NULL`. 16721532e8aSBarry Smith - pylib - full path to the Python dynamic library, or `NULL`. 168c4aff060SBarry Smith 169c4aff060SBarry Smith Level: intermediate 170c4aff060SBarry Smith 171811af0c4SBarry Smith .seealso: `PetscPythonFinalize()`, `PetscPythonPrintError()` 172c4aff060SBarry Smith @*/ 173d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPythonInitialize(const char pyexe[], const char pylib[]) 174d71ae5a4SJacob Faibussowitsch { 17502c9f0b5SLisandro Dalcin PyObject *module = NULL; 1766e111a19SKarl Rupp 177c4aff060SBarry Smith PetscFunctionBegin; 1783ba16761SJacob Faibussowitsch if (PetscBeganPython) PetscFunctionReturn(PETSC_SUCCESS); 179c4aff060SBarry Smith /* Python executable */ 180c4aff060SBarry Smith if (pyexe && pyexe[0] != 0) { 1819566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(PetscPythonExe, pyexe, sizeof(PetscPythonExe))); 182c4aff060SBarry Smith } else { 1839566063dSJacob Faibussowitsch PetscCall(PetscPythonFindExecutable(PetscPythonExe, sizeof(PetscPythonExe))); 184c4aff060SBarry Smith } 185c4aff060SBarry Smith /* Python dynamic library */ 186c4aff060SBarry Smith if (pylib && pylib[0] != 0) { 1879566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(PetscPythonLib, pylib, sizeof(PetscPythonLib))); 188c4aff060SBarry Smith } else { 1899566063dSJacob Faibussowitsch PetscCall(PetscPythonFindLibrary(PetscPythonExe, PetscPythonLib, sizeof(PetscPythonLib))); 190c4aff060SBarry Smith } 191c4aff060SBarry Smith /* dynamically load Python library */ 1929566063dSJacob Faibussowitsch PetscCall(PetscPythonLoadLibrary(PetscPythonLib)); 193c4aff060SBarry Smith /* initialize Python */ 194c4aff060SBarry Smith PetscBeganPython = PETSC_FALSE; 195c4aff060SBarry Smith if (!Py_IsInitialized()) { 1962f2e82b0SLisandro Dalcin static PetscBool registered = PETSC_FALSE; 1972f2e82b0SLisandro Dalcin const char *py_version; 1982f2e82b0SLisandro Dalcin PyObject *sys_path; 1992f2e82b0SLisandro Dalcin char path[PETSC_MAX_PATH_LEN] = {0}; 200a297a907SKarl Rupp 201095e973bSBarry Smith /* initialize Python. Py_InitializeEx() prints an error and EXITS the program if it is not successful! */ 202095e973bSBarry Smith PetscCall(PetscInfo(NULL, "Calling Py_InitializeEx(0);\n")); 2032f2e82b0SLisandro Dalcin Py_InitializeEx(0); /* 0: do not install signal handlers */ 204095e973bSBarry Smith PetscCall(PetscInfo(NULL, "Py_InitializeEx(0) called successfully;\n")); 205095e973bSBarry Smith 2062f2e82b0SLisandro Dalcin /* build 'sys.argv' list */ 2072f2e82b0SLisandro Dalcin py_version = Py_GetVersion(); 2089ac80d5eSLisandro Dalcin if (py_version[0] == '2') { 2099371c9d4SSatish Balay int argc = 0; 2109371c9d4SSatish Balay char *argv[1] = {NULL}; 2112f2e82b0SLisandro Dalcin PySys_SetArgv(argc, argv); 2122f2e82b0SLisandro Dalcin } 2132f2e82b0SLisandro Dalcin if (py_version[0] == '3') { 2149371c9d4SSatish Balay int argc = 0; 2159371c9d4SSatish Balay wchar_t *argv[1] = {NULL}; 21649a6f2e5SLisandro Dalcin PySys_SetArgv(argc, argv); 2172f2e82b0SLisandro Dalcin } 2182f2e82b0SLisandro Dalcin /* add PETSC_LIB_DIR in front of 'sys.path' */ 2192f2e82b0SLisandro Dalcin sys_path = PySys_GetObject("path"); 2202f2e82b0SLisandro Dalcin if (sys_path) { 2219566063dSJacob Faibussowitsch PetscCall(PetscStrreplace(PETSC_COMM_SELF, "${PETSC_LIB_DIR}", path, sizeof(path))); 2222f2e82b0SLisandro Dalcin Py_DecRef(PyObject_CallMethod(sys_path, "insert", "is", (int)0, (char *)path)); 22358c0e507SSatish Balay #if defined(PETSC_PETSC4PY_INSTALL_PATH) 22458c0e507SSatish Balay { 22558c0e507SSatish Balay char *rpath; 2269566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_PETSC4PY_INSTALL_PATH, &rpath)); 22758c0e507SSatish Balay Py_DecRef(PyObject_CallMethod(sys_path, "insert", "is", (int)0, rpath)); 2289566063dSJacob Faibussowitsch PetscCall(PetscFree(rpath)); 22958c0e507SSatish Balay } 23058c0e507SSatish Balay #endif 2319ac80d5eSLisandro Dalcin } 232c4aff060SBarry Smith /* register finalizer */ 233c4aff060SBarry Smith if (!registered) { 2349566063dSJacob Faibussowitsch PetscCall(PetscRegisterFinalize(PetscPythonFinalize)); 235c4aff060SBarry Smith registered = PETSC_TRUE; 236c4aff060SBarry Smith } 237c4aff060SBarry Smith PetscBeganPython = PETSC_TRUE; 238095e973bSBarry Smith PetscCall(PetscInfo(NULL, "Python initialize completed.\n")); 239c4aff060SBarry Smith } 240c4aff060SBarry Smith /* import 'petsc4py.PETSc' module */ 241c4aff060SBarry Smith module = PyImport_ImportModule("petsc4py.PETSc"); 242c4aff060SBarry Smith if (module) { 2439566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Python: successfully imported module 'petsc4py.PETSc'\n")); 2449371c9d4SSatish Balay Py_DecRef(module); 2459371c9d4SSatish Balay module = NULL; 246c4aff060SBarry Smith } else { 2473ba16761SJacob Faibussowitsch PetscCall(PetscPythonPrintError()); 248546078acSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Python: could not import module 'petsc4py.PETSc', perhaps your PYTHONPATH does not contain it"); 249c4aff060SBarry Smith } 2503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 251c4aff060SBarry Smith } 252c4aff060SBarry Smith 253e0ab9aedSLisandro Dalcin /*@C 254811af0c4SBarry Smith PetscPythonPrintError - Print any current Python errors. 255e0ab9aedSLisandro Dalcin 256e0ab9aedSLisandro Dalcin Level: developer 257e0ab9aedSLisandro Dalcin 258811af0c4SBarry Smith .seealso: `PetscPythonInitialize()`, `PetscPythonFinalize()` 259e0ab9aedSLisandro Dalcin @*/ 260d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPythonPrintError(void) 261d71ae5a4SJacob Faibussowitsch { 26202c9f0b5SLisandro Dalcin PyObject *exc = NULL, *val = NULL, *tb = NULL; 2636e111a19SKarl Rupp 264e0ab9aedSLisandro Dalcin PetscFunctionBegin; 2653ba16761SJacob Faibussowitsch if (!PetscBeganPython) PetscFunctionReturn(PETSC_SUCCESS); 2663ba16761SJacob Faibussowitsch if (!PyErr_Occurred()) PetscFunctionReturn(PETSC_SUCCESS); 267e0ab9aedSLisandro Dalcin PyErr_Fetch(&exc, &val, &tb); 268e0ab9aedSLisandro Dalcin PyErr_NormalizeException(&exc, &val, &tb); 269589a23caSBarry Smith PyErr_Display(exc ? exc : Py_None, val ? val : Py_None, tb ? tb : Py_None); 270e0ab9aedSLisandro Dalcin PyErr_Restore(exc, val, tb); 2713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 272e0ab9aedSLisandro Dalcin } 273e0ab9aedSLisandro Dalcin 2748cc058d9SJed Brown PETSC_EXTERN PetscErrorCode (*PetscPythonMonitorSet_C)(PetscObject, const char[]); 2750298fd71SBarry Smith PetscErrorCode (*PetscPythonMonitorSet_C)(PetscObject, const char[]) = NULL; 2765180491cSLisandro Dalcin 2775180491cSLisandro Dalcin /*@C 278811af0c4SBarry Smith PetscPythonMonitorSet - Set a Python monitor for a `PetscObject` 2795180491cSLisandro Dalcin 2805180491cSLisandro Dalcin Level: developer 2815180491cSLisandro Dalcin 282811af0c4SBarry Smith .seealso: `PetscPythonInitialize()`, `PetscPythonFinalize()`, `PetscPythonPrintError()` 2835180491cSLisandro Dalcin @*/ 284d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPythonMonitorSet(PetscObject obj, const char url[]) 285d71ae5a4SJacob Faibussowitsch { 2865180491cSLisandro Dalcin PetscFunctionBegin; 2875180491cSLisandro Dalcin PetscValidHeader(obj, 1); 2884f572ea9SToby Isaac PetscAssertPointer(url, 2); 2896c4ed002SBarry Smith if (!PetscPythonMonitorSet_C) { 2909566063dSJacob Faibussowitsch PetscCall(PetscPythonInitialize(NULL, NULL)); 29128b400f6SJacob Faibussowitsch PetscCheck(PetscPythonMonitorSet_C, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Couldn't initialize Python support for monitors"); 2925180491cSLisandro Dalcin } 2939566063dSJacob Faibussowitsch PetscCall(PetscPythonMonitorSet_C(obj, url)); 2943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2955180491cSLisandro Dalcin } 296