xref: /petsc/src/binding/petsc4py/src/petsc4py/PETSc/PETSc.pyx (revision 51b144c619aff302b570817d6f78637b8418d403)
1# --------------------------------------------------------------------
2
3cdef extern from * nogil:
4    """
5    #include "pyapicompat.h"
6    #include "lib-petsc/compat.h"
7    #include "lib-petsc/custom.h"
8
9    /* Silence Clang warnings in Cython-generated C code */
10    #if defined(__clang__)
11      #pragma clang diagnostic ignored "-Wextra-semi-stmt"
12      #pragma clang diagnostic ignored "-Wparentheses-equality"
13      #pragma clang diagnostic ignored "-Wunreachable-code-fallthrough"
14      #pragma clang diagnostic ignored "-Woverlength-strings"
15      #pragma clang diagnostic ignored "-Wunreachable-code"
16      #pragma clang diagnostic ignored "-Wundef"
17    #elif defined(__GNUC__) || defined(__GNUG__)
18      #pragma GCC diagnostic ignored "-Wstrict-aliasing"
19      #pragma GCC diagnostic ignored "-Wtype-limits"
20    #endif
21    """
22
23# --------------------------------------------------------------------
24
25cdef extern from * nogil:
26    ctypedef ssize_t Py_intptr_t
27    ctypedef size_t  Py_uintptr_t
28
29# --------------------------------------------------------------------
30
31cdef inline object bytes2str(const char p[]):
32    if p == NULL:
33        return None
34    cdef bytes s = <char*>p
35    if isinstance(s, str):
36        return s
37    else:
38        return s.decode()
39
40cdef inline object str2bytes(object s, const char *p[]):
41    if s is None:
42        p[0] = NULL
43        return None
44    if not isinstance(s, bytes):
45        s = s.encode()
46    p[0] = <const char*>(<char*>s)
47    return s
48
49cdef inline object S_(const char p[]):
50    if p == NULL: return None
51    cdef object s = <char*>p
52    return s if isinstance(s, str) else s.decode()
53
54
55# --------------------------------------------------------------------
56
57# SETERR Support
58# --------------
59
60cdef extern from "Python.h":
61    void PyErr_SetObject(object, object)
62    PyObject *PyExc_RuntimeError
63    PyObject *PyErr_GetRaisedException()
64    void PyErr_SetRaisedException(PyObject*)
65    void PyException_SetCause(PyObject*, PyObject*)
66
67cdef object PetscError = <object>PyExc_RuntimeError
68
69cdef inline void PetscTracebackAdd(object exc) noexcept:
70    if (<void*>PetscError) == NULL: return
71    global tracebacklist
72    exc._traceback[:] = tracebacklist[:]
73    del tracebacklist[:]
74
75cdef inline int SETERR(PetscErrorCode ierr) noexcept nogil:
76    cdef PyObject *exception = NULL, *cause = NULL
77    with gil:
78        cause = PyErr_GetRaisedException()
79        if (<void*>PetscError) != NULL:
80            PyErr_SetObject(PetscError, <long>ierr)
81        else:
82            PyErr_SetObject(<object>PyExc_RuntimeError, <long>ierr)
83        exception = PyErr_GetRaisedException()
84        PetscTracebackAdd(<object>exception)
85        PyException_SetCause(exception, cause)
86        PyErr_SetRaisedException(exception)
87    return 0
88
89cdef inline PetscErrorCode CHKERR(PetscErrorCode ierr) except PETSC_ERR_PYTHON nogil:
90    if ierr == PETSC_SUCCESS:
91        return PETSC_SUCCESS # no error
92    <void>SETERR(ierr)
93    return PETSC_ERR_PYTHON
94
95# SETERRMPI Support
96# -----------------
97
98cdef extern from * nogil:
99    enum: MPI_SUCCESS
100    enum: MPI_MAX_ERROR_STRING
101    int MPI_Error_string(int, char[], int*)
102    PetscErrorCode PetscSNPrintf(char[], size_t, const char[], ...)
103    PetscErrorCode PetscERROR(MPI_Comm, const char[], PetscErrorCode, int, const char[], const char[])
104
105cdef inline int SETERRMPI(int ierr) noexcept nogil:
106    cdef char mpi_err_str[MPI_MAX_ERROR_STRING]
107    cdef int  result_len = <int>sizeof(mpi_err_str)
108    <void>memset(mpi_err_str, 0, <size_t>result_len)
109    <void>MPI_Error_string(ierr, mpi_err_str, &result_len)
110    <void>result_len  # unused-but-set-variable
111    cdef char error_str[MPI_MAX_ERROR_STRING+64]
112    <void>PetscSNPrintf(error_str, sizeof(error_str), b"MPI Error %s %d", mpi_err_str, ierr)
113    <void>PetscERROR(PETSC_COMM_SELF, "Unknown Python Function", PETSC_ERR_MPI, PETSC_ERROR_INITIAL, "%s", error_str)
114    <void>SETERR(PETSC_ERR_MPI)
115    return 0
116
117cdef inline PetscErrorCode CHKERRMPI(int ierr) except PETSC_ERR_PYTHON nogil:
118    if ierr == MPI_SUCCESS:
119        return PETSC_SUCCESS
120    <void>SETERRMPI(ierr)
121    return PETSC_ERR_PYTHON
122
123# --------------------------------------------------------------------
124
125# PETSc support
126# -------------
127
128cdef extern from * nogil:
129    ctypedef bint      PetscBool
130    const    PetscBool PETSC_TRUE
131    const    PetscBool PETSC_FALSE
132    ctypedef long      PetscInt
133    ctypedef long long PetscInt64
134    ctypedef double    PetscReal
135    ctypedef double    PetscScalar
136    ctypedef ptrdiff_t PetscCount
137
138cdef extern from "<petsc4py/pyscalar.h>":
139    object      PyPetscScalar_FromPetscScalar(PetscScalar)
140    PetscScalar PyPetscScalar_AsPetscScalar(object) except? <PetscScalar>-1.0
141
142cdef extern from "<petsc4py/pybuffer.h>":
143    int  PyPetscBuffer_FillInfo(Py_buffer*, void*, PetscInt, char, int, int) except -1
144    void PyPetscBuffer_Release(Py_buffer*)
145
146cdef inline object toBool(PetscBool value):
147    return True if value == PETSC_TRUE else False
148cdef inline PetscBool asBool(object value) except? <PetscBool>0:
149    return PETSC_TRUE if value else PETSC_FALSE
150
151cdef inline object toInt(PetscInt value):
152    return value
153cdef inline PetscInt asInt(object value) except? -1:
154    return value
155
156cdef inline object toReal(PetscReal value):
157    return value
158cdef inline PetscReal asReal(object value) except? -1:
159    return value
160
161cdef inline object toScalar(PetscScalar value):
162    return PyPetscScalar_FromPetscScalar(value)
163cdef inline PetscScalar asScalar(object value) except? <PetscScalar>-1.0:
164    return PyPetscScalar_AsPetscScalar(value)
165
166# --------------------------------------------------------------------
167
168# NumPy support
169# -------------
170
171include "arraynpy.pxi"
172
173import_array()
174
175IntType     = PyArray_TypeObjectFromType(NPY_PETSC_INT)
176RealType    = PyArray_TypeObjectFromType(NPY_PETSC_REAL)
177ScalarType  = PyArray_TypeObjectFromType(NPY_PETSC_SCALAR)
178ComplexType = PyArray_TypeObjectFromType(NPY_PETSC_COMPLEX)
179
180include "dlpack.pxi"
181
182# --------------------------------------------------------------------
183
184include "typing.pxi"
185include "petscdef.pxi"
186include "petscmem.pxi"
187include "petscopt.pxi"
188include "petscmpi.pxi"
189include "petscsys.pxi"
190include "petsclog.pxi"
191include "petscobj.pxi"
192include "petscvwr.pxi"
193include "petscrand.pxi"
194include "petscdevice.pxi"
195include "petsclayout.pxi"
196include "petscis.pxi"
197include "petscsf.pxi"
198include "petscvec.pxi"
199include "petscdt.pxi"
200include "petscfe.pxi"
201include "petscsct.pxi"
202include "petscsec.pxi"
203include "petscmat.pxi"
204include "petscmatpartitioning.pxi"
205include "petscpc.pxi"
206include "petscksp.pxi"
207include "petscsnes.pxi"
208include "petscts.pxi"
209include "petsctao.pxi"
210include "petscao.pxi"
211include "petscdm.pxi"
212include "petscds.pxi"
213include "petscdmda.pxi"
214include "petscdmplex.pxi"
215include "petscdmstag.pxi"
216include "petscdmcomposite.pxi"
217include "petscdmshell.pxi"
218include "petscdmlabel.pxi"
219include "petscdmswarm.pxi"
220include "petscpartitioner.pxi"
221include "petscspace.pxi"
222include "petscdmutils.pxi"
223include "petscpyappctx.pxi"
224include "petscregressor.pxi"
225
226# --------------------------------------------------------------------
227
228__doc__ = """
229Portable, Extensible Toolkit for Scientific Computation.
230"""
231
232include "Const.pyx"
233include "Error.pyx"
234include "Options.pyx"
235include "Sys.pyx"
236include "Log.pyx"
237include "Comm.pyx"
238include "Object.pyx"
239include "Viewer.pyx"
240include "Random.pyx"
241include "Device.pyx"
242include "IS.pyx"
243include "SF.pyx"
244include "Vec.pyx"
245include "DT.pyx"
246include "FE.pyx"
247include "Scatter.pyx"
248include "Section.pyx"
249include "Mat.pyx"
250include "MatPartitioning.pyx"
251include "PC.pyx"
252include "KSP.pyx"
253include "SNES.pyx"
254include "TS.pyx"
255include "TAO.pyx"
256include "AO.pyx"
257include "DM.pyx"
258include "DS.pyx"
259include "DMDA.pyx"
260include "DMPlex.pyx"
261include "DMStag.pyx"
262include "DMComposite.pyx"
263include "DMShell.pyx"
264include "DMLabel.pyx"
265include "DMSwarm.pyx"
266include "Partitioner.pyx"
267include "Space.pyx"
268include "DMUtils.pyx"
269include "Regressor.pyx"
270
271# --------------------------------------------------------------------
272
273include "CAPI.pyx"
274include "libpetsc4py.pyx"
275
276# --------------------------------------------------------------------
277
278cdef extern from "Python.h":
279    int Py_IsInitialized() nogil
280    int PyList_Insert(object, Py_ssize_t, object) except -1
281    int PyList_Append(object, object) except -1
282
283cdef extern from * nogil:
284    PetscErrorCode PetscTBEH(MPI_Comm, int, char*, char*, int, PetscErrorType, char*, void*)
285
286cdef object tracebacklist = []
287
288cdef PetscErrorCode traceback(
289    MPI_Comm       comm,
290    int            line,
291    const char    *cfunc,
292    const char    *cfile,
293    PetscErrorCode n,
294    PetscErrorType p,
295    const char    *mess,
296    void          *ctx,
297) except (<PetscErrorCode>-1) with gil:
298    cdef PetscLogDouble mem=0
299    cdef PetscLogDouble rss=0
300    cdef const char    *text=NULL
301    global tracebacklist
302    cdef object tbl = tracebacklist
303    cdef object fun = bytes2str(cfunc)
304    cdef object fnm = bytes2str(cfile)
305    cdef object m = "%s() at %s:%d" % (fun, fnm, line)
306    PyList_Insert(tbl, 0, m)
307    if p != PETSC_ERROR_INITIAL:
308        return n
309    #
310    del tbl[1:] # clear any previous stuff
311    if n == PETSC_ERR_MEM: # special case
312        PetscMallocGetCurrentUsage(&mem)
313        PetscMemoryGetCurrentUsage(&rss)
314        m = (
315            "Out of memory. "
316            "Allocated: %d, "
317            "Used by process: %d"
318        ) % (mem, rss)
319        PyList_Append(tbl, m)
320    else:
321        PetscErrorMessage(n, &text, NULL)
322    if text != NULL: PyList_Append(tbl, bytes2str(text))
323    if mess != NULL: PyList_Append(tbl, bytes2str(mess))
324    <void>comm # unused
325    <void>ctx  # unused
326    return n
327
328cdef PetscErrorCode PetscPythonErrorHandler(
329    MPI_Comm       comm,
330    int            line,
331    const char    *cfunc,
332    const char    *cfile,
333    PetscErrorCode n,
334    PetscErrorType p,
335    const char    *mess,
336    void          *ctx,
337) except (<PetscErrorCode>-1) nogil:
338    global tracebacklist
339    if (<void*>tracebacklist) != NULL and Py_IsInitialized():
340        return traceback(comm, line, cfunc, cfile, n, p, mess, ctx)
341    else:
342        return PetscTBEH(comm, line, cfunc, cfile, n, p, mess, ctx)
343
344# --------------------------------------------------------------------
345
346cdef extern from "<stdlib.h>" nogil:
347    void* malloc(size_t)
348    void* realloc (void*, size_t)
349    void free(void*)
350
351cdef extern from "<stdarg.h>" nogil:
352    ctypedef struct va_list:
353        pass
354
355cdef extern from "<string.h>" nogil:
356    void* memset(void*, int, size_t)
357    void* memcpy(void*, void*, size_t)
358    char* strdup(char*)
359
360cdef extern from "<stdio.h>" nogil:
361    ctypedef struct FILE
362    FILE *stderr
363    int fprintf(FILE *, char *, ...)
364
365cdef extern from "Python.h":
366    int Py_AtExit(void (*)() noexcept nogil)
367    void PySys_WriteStderr(char*, ...)
368
369cdef extern from * nogil:
370    """
371    #include "lib-petsc/initpkg.h"
372    """
373    PetscErrorCode PetscInitializePackageAll()
374
375cdef int    PyPetsc_Argc = 0
376cdef char** PyPetsc_Argv = NULL
377
378cdef int getinitargs(object args, int *argc, char **argv[]) except -1:
379    # allocate command line arguments
380    cdef int i, c = 0
381    cdef char **v = NULL
382    if args is None: args = []
383    args = [str(a).encode() for a in args]
384    args = [a for a in args if a]
385    c = <int> len(args)
386    v = <char**> malloc(<size_t>(c+1)*sizeof(char*))
387    if v == NULL: raise MemoryError
388    memset(v, 0, <size_t>(c+1)*sizeof(char*))
389    try:
390        for 0 <= i < c:
391            v[i] = strdup(args[i])
392            if v[i] == NULL:
393                raise MemoryError
394    except Exception:
395        delinitargs(&c, &v); raise
396    argc[0] = c; argv[0] = v
397    return 0
398
399cdef void delinitargs(int *argc, char **argv[]) noexcept nogil:
400    # deallocate command line arguments
401    cdef int i, c = argc[0]
402    cdef char** v = argv[0]
403    argc[0] = 0; argv[0] = NULL
404    if c >= 0 and v != NULL:
405        for 0 <= i < c:
406            if  v[i] != NULL: free(v[i])
407        free(v)
408
409cdef void finalize() noexcept nogil:
410    cdef int ierr = 0
411    # deallocate command line arguments
412    global PyPetsc_Argc, PyPetsc_Argv
413    global PetscVFPrintf, prevfprintf
414    delinitargs(&PyPetsc_Argc, &PyPetsc_Argv)
415    # manage PETSc finalization
416    if not (<int>PetscInitializeCalled): return
417    if (<int>PetscFinalizeCalled): return
418    # stop stdout/stderr redirect
419    if (prevfprintf != NULL):
420        PetscVFPrintf = prevfprintf
421        prevfprintf = NULL
422    # deinstall Python error handler
423    ierr = PetscPopErrorHandler()
424    if ierr != 0:
425        fprintf(stderr,
426                "PetscPopErrorHandler() failed "
427                "[error code: %d]\n", ierr)
428    # finalize PETSc
429    ierr = PetscFinalize()
430    if ierr != 0:
431        fprintf(stderr,
432                "PetscFinalize() failed "
433                "[error code: %d]\n", ierr)
434    # and we are done, see you later !!
435
436# --------------------------------------------------------------------
437
438cdef extern from *:
439    PetscErrorCode (*PetscVFPrintf)(FILE*, const char*, va_list) except PETSC_ERR_PYTHON nogil
440
441cdef PetscErrorCode (*prevfprintf)(FILE*, const char*, va_list) except PETSC_ERR_PYTHON nogil
442prevfprintf = NULL
443
444cdef PetscErrorCode PetscVFPrintf_PythonStdStream(
445    FILE *fd, const char fmt[], va_list ap,
446) except PETSC_ERR_PYTHON with gil:
447    import sys
448    cdef char cstring[8192]
449    cdef size_t stringlen = sizeof(cstring)
450    cdef size_t final_pos = 0
451    if (fd == PETSC_STDOUT) and not (sys.stdout == sys.__stdout__):
452        CHKERR(PetscVSNPrintf(&cstring[0], stringlen, fmt, &final_pos, ap))
453        if final_pos > 0 and cstring[final_pos-1] == '\x00':
454            final_pos -= 1
455        ustring = cstring[:final_pos].decode('UTF-8')
456        sys.stdout.write(ustring)
457    elif (fd == PETSC_STDERR) and not (sys.stderr == sys.__stderr__):
458        CHKERR(PetscVSNPrintf(&cstring[0], stringlen, fmt, &final_pos, ap))
459        if final_pos > 0 and cstring[final_pos-1] == '\x00':
460            final_pos -= 1
461        ustring = cstring[:final_pos].decode('UTF-8')
462        sys.stderr.write(ustring)
463    else:
464        CHKERR(PetscVFPrintfDefault(fd, fmt, ap))
465    return PETSC_SUCCESS
466
467cdef int _push_vfprintf(
468    PetscErrorCode (*vfprintf)(FILE*, const char*, va_list) except PETSC_ERR_PYTHON nogil,
469) except -1:
470    global PetscVFPrintf, prevfprintf
471    assert prevfprintf == NULL
472    prevfprintf = PetscVFPrintf
473    PetscVFPrintf = vfprintf
474
475cdef int _pop_vfprintf() except -1:
476    global PetscVFPrintf, prevfprintf
477    assert prevfprintf != NULL
478    PetscVFPrintf = prevfprintf
479    prevfprintf == NULL
480
481cdef int initialize(object args, object comm) except -1:
482    if (<int>PetscInitializeCalled): return 1
483    if (<int>PetscFinalizeCalled):   return 0
484    # allocate command line arguments
485    global PyPetsc_Argc, PyPetsc_Argv
486    getinitargs(args, &PyPetsc_Argc, &PyPetsc_Argv)
487    # communicator
488    global PETSC_COMM_WORLD
489    PETSC_COMM_WORLD = def_Comm(comm, PETSC_COMM_WORLD)
490    # initialize PETSc
491    CHKERR(PetscInitialize(&PyPetsc_Argc, &PyPetsc_Argv, NULL, NULL))
492    # install Python error handler
493    cdef PetscErrorHandlerFunction handler = NULL
494    handler = <PetscErrorHandlerFunction>PetscPythonErrorHandler
495    CHKERR(PetscPushErrorHandler(handler, NULL))
496    # redirect PETSc std streams
497    import sys
498    if (sys.stdout != sys.__stdout__) or (sys.stderr != sys.__stderr__):
499        _push_vfprintf(&PetscVFPrintf_PythonStdStream)
500    # register finalization function
501    if Py_AtExit(finalize) < 0:
502        PySys_WriteStderr(b"warning: could not register %s with Py_AtExit()",
503                          b"PetscFinalize()")
504    return 1 # and we are done, enjoy !!
505
506cdef extern from * nogil:
507    PetscClassId PETSC_OBJECT_CLASSID           "PETSC_OBJECT_CLASSID"
508    PetscClassId PETSC_VIEWER_CLASSID           "PETSC_VIEWER_CLASSID"
509    PetscClassId PETSC_RANDOM_CLASSID           "PETSC_RANDOM_CLASSID"
510    PetscClassId PETSC_IS_CLASSID               "IS_CLASSID"
511    PetscClassId PETSC_LGMAP_CLASSID            "IS_LTOGM_CLASSID"
512    PetscClassId PETSC_SF_CLASSID               "PETSCSF_CLASSID"
513    PetscClassId PETSC_VEC_CLASSID              "VEC_CLASSID"
514    PetscClassId PETSC_SECTION_CLASSID          "PETSC_SECTION_CLASSID"
515    PetscClassId PETSC_MAT_CLASSID              "MAT_CLASSID"
516    PetscClassId PETSC_MAT_PARTITIONING_CLASSID "MAT_PARTITIONING_CLASSID"
517    PetscClassId PETSC_NULLSPACE_CLASSID        "MAT_NULLSPACE_CLASSID"
518    PetscClassId PETSC_PC_CLASSID               "PC_CLASSID"
519    PetscClassId PETSC_KSP_CLASSID              "KSP_CLASSID"
520    PetscClassId PETSC_SNES_CLASSID             "SNES_CLASSID"
521    PetscClassId PETSC_TS_CLASSID               "TS_CLASSID"
522    PetscClassId PETSC_TAO_CLASSID              "TAO_CLASSID"
523    PetscClassId PETSC_AO_CLASSID               "AO_CLASSID"
524    PetscClassId PETSC_DM_CLASSID               "DM_CLASSID"
525    PetscClassId PETSC_DS_CLASSID               "PETSCDS_CLASSID"
526    PetscClassId PETSC_PARTITIONER_CLASSID      "PETSCPARTITIONER_CLASSID"
527    PetscClassId PETSC_FE_CLASSID               "PETSCFE_CLASSID"
528    PetscClassId PETSC_DMLABEL_CLASSID          "DMLABEL_CLASSID"
529    PetscClassId PETSC_SPACE_CLASSID            "PETSCSPACE_CLASSID"
530    PetscClassId PETSC_DUALSPACE_CLASSID        "PETSCDUALSPACE_CLASSID"
531    PetscClassId PETSC_DEVICE_CLASSID           "PETSC_DEVICE_CLASSID"
532    PetscClassId PETSC_DEVICE_CONTEXT_CLASSID   "PETSC_DEVICE_CONTEXT_CLASSID"
533    PetscClassId PETSC_REGRESSOR_CLASSID        "PETSCREGRESSOR_CLASSID"
534
535cdef bint registercalled = 0
536
537cdef const char *citation = b"""\
538@Article{Dalcin2011,
539  Author = {Lisandro D. Dalcin and Rodrigo R. Paz and Pablo A. Kler and Alejandro Cosimo},
540  Title = {Parallel distributed computing using {P}ython},
541  Journal = {Advances in Water Resources},
542  Note = {New Computational Methods and Software Tools},
543  Volume = {34},
544  Number = {9},
545  Pages = {1124--1139},
546  Year = {2011},
547  DOI = {https://doi.org/10.1016/j.advwatres.2011.04.013}
548}
549"""
550
551cdef int register() except -1:
552    global registercalled
553    if registercalled: return 0
554    registercalled = True
555    # register citation
556    CHKERR(PetscCitationsRegister(citation, NULL))
557    # make sure all PETSc packages are initialized
558    CHKERR(PetscInitializePackageAll())
559    # register custom implementations
560    CHKERR(PetscPythonRegisterAll())
561    # register Python types
562    PyPetscType_Register(PETSC_OBJECT_CLASSID,           Object)
563    PyPetscType_Register(PETSC_VIEWER_CLASSID,           Viewer)
564    PyPetscType_Register(PETSC_RANDOM_CLASSID,           Random)
565    PyPetscType_Register(PETSC_DEVICE_CLASSID,           Device)
566    PyPetscType_Register(PETSC_DEVICE_CONTEXT_CLASSID,   DeviceContext)
567    PyPetscType_Register(PETSC_IS_CLASSID,               IS)
568    PyPetscType_Register(PETSC_LGMAP_CLASSID,            LGMap)
569    PyPetscType_Register(PETSC_SF_CLASSID,               SF)
570    PyPetscType_Register(PETSC_VEC_CLASSID,              Vec)
571    PyPetscType_Register(PETSC_SECTION_CLASSID,          Section)
572    PyPetscType_Register(PETSC_MAT_CLASSID,              Mat)
573    PyPetscType_Register(PETSC_MAT_PARTITIONING_CLASSID, MatPartitioning)
574    PyPetscType_Register(PETSC_NULLSPACE_CLASSID,        NullSpace)
575    PyPetscType_Register(PETSC_PC_CLASSID,               PC)
576    PyPetscType_Register(PETSC_KSP_CLASSID,              KSP)
577    PyPetscType_Register(PETSC_SNES_CLASSID,             SNES)
578    PyPetscType_Register(PETSC_TS_CLASSID,               TS)
579    PyPetscType_Register(PETSC_TAO_CLASSID,              TAO)
580    PyPetscType_Register(PETSC_PARTITIONER_CLASSID,      Partitioner)
581    PyPetscType_Register(PETSC_AO_CLASSID,               AO)
582    PyPetscType_Register(PETSC_DM_CLASSID,               DM)
583    PyPetscType_Register(PETSC_DS_CLASSID,               DS)
584    PyPetscType_Register(PETSC_FE_CLASSID,               FE)
585    PyPetscType_Register(PETSC_DMLABEL_CLASSID,          DMLabel)
586    PyPetscType_Register(PETSC_SPACE_CLASSID,            Space)
587    PyPetscType_Register(PETSC_DUALSPACE_CLASSID,        DualSpace)
588    PyPetscType_Register(PETSC_REGRESSOR_CLASSID,        Regressor)
589    return 0 # and we are done, enjoy !!
590
591# --------------------------------------------------------------------
592
593
594def _initialize(args=None, comm=None):
595    import atexit
596    global PetscError
597    PetscError = Error
598    #
599    cdef int ready = initialize(args, comm)
600    if ready: register()
601    #
602    global __COMM_SELF__, __COMM_WORLD__
603    __COMM_SELF__.comm  = PETSC_COMM_SELF
604    __COMM_WORLD__.comm = PETSC_COMM_WORLD
605    #
606    global PETSC_COMM_DEFAULT
607    PETSC_COMM_DEFAULT = PETSC_COMM_WORLD
608    # Register finalizer
609    atexit.register(_pre_finalize)
610
611
612def _pre_finalize():
613    # Called while the Python interpreter is still running
614    garbage_cleanup()
615
616
617def _finalize():
618    finalize()
619    #
620    global __COMM_SELF__
621    __COMM_SELF__.comm  = MPI_COMM_NULL
622    global __COMM_WORLD__
623    __COMM_WORLD__.comm = MPI_COMM_NULL
624    #
625    global PETSC_COMM_DEFAULT
626    PETSC_COMM_DEFAULT = MPI_COMM_NULL
627    #
628    global type_registry
629    type_registry.clear()
630    global stage_registry
631    stage_registry.clear()
632    global class_registry
633    class_registry.clear()
634    global event_registry
635    event_registry.clear()
636    global citations_registry
637    citations_registry.clear()
638
639
640def _push_python_vfprintf():
641    _push_vfprintf(&PetscVFPrintf_PythonStdStream)
642
643
644def _pop_python_vfprintf():
645    _pop_vfprintf()
646
647
648def _stdout_is_stderr():
649    global PETSC_STDOUT, PETSC_STDERR
650    return PETSC_STDOUT == PETSC_STDERR
651
652# --------------------------------------------------------------------
653