xref: /petsc/src/binding/petsc4py/src/petsc4py/PETSc/Log.pyx (revision 226f8a8a5081bc6ad7227cd631662400f0d6e2a0)
1# --------------------------------------------------------------------
2
3cdef object functools = None
4import functools
5
6# --------------------------------------------------------------------
7
8cdef class Log:
9    """Logging support."""
10
11    @classmethod
12    def Stage(cls, name: str) -> LogStage:
13        """Create a log stage.
14
15        Not collective.
16
17        Parameters
18        ----------
19        name
20            Stage name.
21
22        Returns
23        -------
24        stage : LogStage
25            The log stage. If a stage already exists with name ``name`` then
26            it is reused.
27
28        See Also
29        --------
30        petsc.PetscLogStageRegister
31
32        """
33        if not name: raise ValueError("empty name")
34        cdef const char *cname = NULL
35        name = str2bytes(name, &cname)
36        cdef PetscLogStage stageid = -1
37        cdef LogStage stage = get_LogStage(name)
38        if stage is not None: return stage
39        CHKERR(PetscLogStageFindId(cname, &stageid))
40        if stageid == -1:
41            CHKERR(PetscLogStageRegister(cname, &stageid))
42        stage = reg_LogStage(name, stageid)
43        return stage
44
45    @classmethod
46    def Class(cls, name: str) -> LogClass:
47        """Create a log class.
48
49        Not collective.
50
51        Parameters
52        ----------
53        name
54            Class name.
55
56        Returns
57        -------
58        klass : LogClass
59            The log class. If a class already exists with name ``name`` then
60            it is reused.
61
62        See Also
63        --------
64        petsc.PetscClassIdRegister
65
66        """
67        if not name: raise ValueError("empty name")
68        cdef const char *cname = NULL
69        name = str2bytes(name, &cname)
70        cdef PetscLogClass classid = -1
71        cdef LogClass klass = get_LogClass(name)
72        if klass is not None: return klass
73        CHKERR(PetscLogClassFindId(cname, &classid))
74        if classid == -1:
75            CHKERR(PetscLogClassRegister(cname, &classid))
76        klass = reg_LogClass(name, classid)
77        return klass
78
79    @classmethod
80    def Event(cls, name: str, klass: LogClass | None = None) -> LogEvent:
81        """Create a log event.
82
83        Not collective.
84
85        Parameters
86        ----------
87        name
88            Event name.
89        klass
90            Log class. If `None`, defaults to ``PETSC_OBJECT_CLASSID``.
91
92        Returns
93        -------
94        event : LogEvent
95            The log event. If an event already exists with name ``name`` then
96            it is reused.
97
98        See Also
99        --------
100        petsc.PetscLogEventRegister
101
102        """
103        if not name: raise ValueError("empty name")
104        cdef const char *cname = NULL
105        name = str2bytes(name, &cname)
106        cdef PetscLogClass classid = PETSC_OBJECT_CLASSID
107        cdef PetscLogEvent eventid = -1
108        if klass is not None: classid = klass
109        cdef LogEvent event = get_LogEvent(name)
110        if event is not None: return event
111        CHKERR(PetscLogEventFindId(cname, &eventid))
112        if eventid == -1:
113            CHKERR(PetscLogEventRegister(cname, classid, &eventid))
114        event = reg_LogEvent(name, eventid)
115        return event
116
117    @classmethod
118    def begin(cls) -> None:
119        """Turn on logging of objects and events.
120
121        Collective.
122
123        See Also
124        --------
125        petsc.PetscLogDefaultBegin
126
127        """
128        CHKERR(PetscLogDefaultBegin())
129
130    @classmethod
131    def view(cls, Viewer viewer=None) -> None:
132        """Print the log.
133
134        Collective.
135
136        Parameters
137        ----------
138        viewer
139            A `Viewer` instance or `None` for the default viewer.
140
141        See Also
142        --------
143        petsc_options, petsc.PetscLogView
144
145        """
146        cdef PetscViewer vwr = NULL
147        if viewer is not None: vwr = viewer.vwr
148        if vwr == NULL: vwr = PETSC_VIEWER_STDOUT_WORLD
149        CHKERR(PetscLogView(vwr))
150
151    @classmethod
152    def logFlops(cls, flops: float) -> None:
153        """Add floating point operations to the current event.
154
155        Not collective.
156
157        Parameters
158        ----------
159        flops
160            The number of flops to log.
161
162        See Also
163        --------
164        petsc.PetscLogFlops
165
166        """
167        cdef PetscLogDouble cflops=flops
168        CHKERR(PetscLogFlops(cflops))
169
170    @classmethod
171    def addFlops(cls, flops: float) -> None:
172        """Add floating point operations to the current event.
173
174        Not collective.
175
176        Parameters
177        ----------
178        flops
179            The number of flops to log.
180
181        Notes
182        -----
183        This method exists for backward compatibility.
184
185        See Also
186        --------
187        logFlops, petsc.PetscLogFlops
188
189        """
190        cdef PetscLogDouble cflops=flops
191        CHKERR(PetscLogFlops(cflops))
192
193    @classmethod
194    def getFlops(cls) -> float:
195        """Return the number of flops used on this processor since the program began.
196
197        Not collective.
198
199        Returns
200        -------
201        float
202            Number of floating point operations.
203
204        See Also
205        --------
206        petsc.PetscGetFlops
207
208        """
209        cdef PetscLogDouble cflops=0
210        CHKERR(PetscGetFlops(&cflops))
211        return cflops
212
213    @classmethod
214    def getTime(cls) -> float:
215        """Return the current time of day in seconds.
216
217        Collective.
218
219        Returns
220        -------
221        wctime : float
222            Current time.
223
224        See Also
225        --------
226        petsc.PetscTime
227
228        """
229        cdef PetscLogDouble wctime=0
230        CHKERR(PetscTime(&wctime))
231        return wctime
232
233    @classmethod
234    def getCPUTime(cls) -> float:
235        """Return the CPU time."""
236        cdef PetscLogDouble cputime=0
237        CHKERR(PetscGetCPUTime(&cputime))
238        return cputime
239
240    @classmethod
241    def EventDecorator(cls, name=None, klass=None) -> Any:
242        """Decorate a function with a `PETSc` event."""
243        def decorator(func):
244            @functools.wraps(func)
245            def wrapped_func(*args, **kwargs):
246                if name:
247                    name_ = name
248                else:
249                    name_ = ".".join([func.__module__, getattr(func, "__qualname__", func.__name__)])
250                with cls.Event(name_, klass):
251                    return func(*args, **kwargs)
252            return wrapped_func
253        return decorator
254
255    @classmethod
256    def isActive(cls) -> bool:
257        """Return whether logging is currently in progress.
258
259        Not collective.
260
261        See Also
262        --------
263        petsc.PetscLogIsActive
264
265        """
266        cdef PetscBool flag = PETSC_FALSE
267        CHKERR(PetscLogIsActive(&flag))
268        return toBool(flag)
269
270# --------------------------------------------------------------------
271
272cdef class LogStage:
273    """Logging support for different stages."""
274
275    cdef PetscLogStage id
276
277    property id:
278        """The log stage identifier."""
279        def __get__(self) -> int:
280            return self.id
281
282    def __cinit__(self):
283        self.id = 0
284
285    def __int__(self):
286        return <int> self.id
287
288    def __enter__(self):
289        self.push()
290        return self
291
292    def __exit__(self, *exc):
293        self.pop()
294
295    #
296
297    def push(self) -> None:
298        """Push a stage on the logging stack.
299
300        Logically collective.
301
302        See Also
303        --------
304        LogStage.pop, petsc.PetscLogStagePush
305
306        """
307        CHKERR(PetscLogStagePush(self.id))
308
309    def pop(self) -> None:
310        """Pop a stage from the logging stack.
311
312        Logically collective.
313
314        See Also
315        --------
316        LogStage.push, petsc.PetscLogStagePop
317
318        """
319        <void>self # unused
320        CHKERR(PetscLogStagePop())
321
322    #
323
324    def getName(self) -> str:
325        """Return the current stage name."""
326        cdef const char *cval = NULL
327        CHKERR(PetscLogStageFindName(self.id, &cval))
328        return bytes2str(cval)
329
330    property name:
331        """The current stage name."""
332        def __get__(self) -> str:
333            return self.getName()
334
335        def __set__(self, value):
336            <void>self; <void>value # unused
337            raise TypeError("readonly attribute")
338
339    #
340
341    def activate(self) -> None:
342        """Activate the stage.
343
344        Logically collective.
345
346        See Also
347        --------
348        petsc.PetscLogStageSetActive
349
350        """
351        CHKERR(PetscLogStageSetActive(self.id, PETSC_TRUE))
352
353    def deactivate(self) -> None:
354        """Deactivate the stage.
355
356        Logically collective.
357
358        See Also
359        --------
360        petsc.PetscLogStageSetActive
361
362        """
363        CHKERR(PetscLogStageSetActive(self.id, PETSC_FALSE))
364
365    def getActive(self) -> bool:
366        """Check if the stage is activated.
367
368        Not collective.
369
370        See Also
371        --------
372        petsc.PetscLogStageGetActive
373
374        """
375        cdef PetscBool flag = PETSC_FALSE
376        CHKERR(PetscLogStageGetActive(self.id, &flag))
377        return toBool(flag)
378
379    def setActive(self, flag: bool) -> None:
380        """Activate or deactivate the current stage.
381
382        Logically collective.
383
384        See Also
385        --------
386        petsc.PetscLogStageSetActive
387
388        """
389        cdef PetscBool tval = PETSC_FALSE
390        if flag: tval = PETSC_TRUE
391        CHKERR(PetscLogStageSetActive(self.id, tval))
392
393    property active:
394        """Whether the stage is activate."""
395        def __get__(self) -> bool:
396            return self.getActive()
397
398        def __set__(self, value):
399            self.setActive(value)
400
401    #
402
403    def getVisible(self) -> bool:
404        """Return whether the stage is visible.
405
406        Not collective.
407
408        See Also
409        --------
410        LogStage.setVisible, petsc.PetscLogStageSetVisible
411
412        """
413        cdef PetscBool flag = PETSC_FALSE
414        CHKERR(PetscLogStageGetVisible(self.id, &flag))
415        return toBool(flag)
416
417    def setVisible(self, flag: bool) -> None:
418        """Set the visibility of the stage.
419
420        Logically collective.
421
422        Parameters
423        ----------
424        flag
425            `True` to make the stage visible, `False` otherwise.
426
427        See Also
428        --------
429        LogStage.getVisible, petsc.PetscLogStageSetVisible
430
431        """
432        cdef PetscBool tval = PETSC_FALSE
433        if flag: tval = PETSC_TRUE
434        CHKERR(PetscLogStageSetVisible(self.id, tval))
435
436    property visible:
437        """Whether the stage is visible."""
438        def __get__(self) -> bool:
439            return self.getVisible()
440
441        def __set__(self, value):
442            self.setVisible(value)
443
444
445cdef dict stage_registry = {}
446
447cdef LogStage get_LogStage(object name):
448    return stage_registry.get(name)
449
450cdef LogStage reg_LogStage(object name, PetscLogStage stageid):
451    cdef LogStage stage = LogStage()
452    stage.id = stageid
453    stage_registry[name] = stage
454    return stage
455
456# --------------------------------------------------------------------
457
458cdef class LogClass:
459    """Logging support."""
460
461    cdef PetscLogClass id
462
463    property id:
464        """The log class identifier."""
465        def __get__(self) -> int:
466            return self.id
467
468    def __cinit__(self):
469        self.id = PETSC_OBJECT_CLASSID
470
471    def __int__(self):
472        return <int> self.id
473
474    #
475
476    def getName(self) -> str:
477        """Return the log class name."""
478        cdef const char *cval = NULL
479        CHKERR(PetscLogClassFindName(self.id, &cval))
480        return bytes2str(cval)
481
482    property name:
483        """The log class name."""
484        def __get__(self) -> str:
485            return self.getName()
486
487        def __set__(self, value):
488            <void>self; <void>value # unused
489            raise TypeError("readonly attribute")
490
491    #
492
493    def activate(self) -> None:
494        """Activate the log class."""
495        CHKERR(PetscLogClassActivate(self.id))
496
497    def deactivate(self) -> None:
498        """Deactivate the log class."""
499        CHKERR(PetscLogClassDeactivate(self.id))
500
501    def getActive(self) -> bool:
502        """Not implemented."""
503        <void>self # unused
504        raise NotImplementedError
505
506    def setActive(self, flag: bool) -> None:
507        """Activate or deactivate the log class."""
508        if flag:
509            CHKERR(PetscLogClassActivate(self.id))
510        else:
511            CHKERR(PetscLogClassDeactivate(self.id))
512
513    property active:
514        """Log class activation."""
515        def __get__(self) -> bool:
516            return self.getActive()
517
518        def __set__(self, value):
519            self.setActive(value)
520
521
522cdef dict class_registry = {}
523
524cdef LogClass get_LogClass(object name):
525    return class_registry.get(name)
526
527cdef LogClass reg_LogClass(object name, PetscLogClass classid):
528    cdef LogClass klass = LogClass()
529    klass.id = classid
530    class_registry[name] = klass
531    return klass
532
533# --------------------------------------------------------------------
534
535cdef class LogEvent:
536    """Logging support."""
537
538    cdef PetscLogEvent id
539
540    property id:
541        """The log event identifier."""
542        def __get__(self) -> int:
543            return self.id
544
545    def __cinit__(self):
546        self.id = 0
547
548    def __int__(self):
549        return <int> self.id
550
551    def __enter__(self):
552        self.begin()
553        return self
554
555    def __exit__(self, *exc):
556        self.end()
557
558    def begin(self, *objs) -> None:
559        """Log the beginning of a user event.
560
561        Collective.
562
563        Parameters
564        ----------
565        *objs
566            objects associated with the event
567
568        See Also
569        --------
570        petsc.PetscLogEventBegin
571
572        """
573        cdef PetscObject o[4]
574        event_args2objs(objs, o)
575        CHKERR(PetscLogEventBegin(self.id, o[0], o[1], o[2], o[3]))
576
577    def end(self, *objs) -> None:
578        """Log the end of a user event.
579
580        Collective.
581
582        Parameters
583        ----------
584        *objs
585            Objects associated with the event.
586
587        See Also
588        --------
589        petsc.PetscLogEventEnd
590
591        """
592        cdef PetscObject o[4]
593        event_args2objs(objs, o)
594        CHKERR(PetscLogEventEnd(self.id, o[0], o[1], o[2], o[3]))
595
596    #
597    def getName(self) -> str:
598        """The current event name."""
599        cdef const char *cval = NULL
600        CHKERR(PetscLogEventFindName(self.id, &cval))
601        return bytes2str(cval)
602
603    property name:
604        """The current event name."""
605        def __get__(self) ->str:
606            return self.getName()
607
608        def __set__(self, value):
609            <void>self; <void>value # unused
610            raise TypeError("readonly attribute")
611
612    #
613
614    def activate(self) -> None:
615        """Indicate that the event should be logged.
616
617        Logically collective.
618
619        See Also
620        --------
621        petsc.PetscLogEventActivate
622
623        """
624        CHKERR(PetscLogEventActivate(self.id))
625
626    def deactivate(self) -> None:
627        """Indicate that the event should not be logged.
628
629        Logically collective.
630
631        See Also
632        --------
633        petsc.PetscLogEventDeactivate
634
635        """
636        CHKERR(PetscLogEventDeactivate(self.id))
637
638    def getActive(self) -> bool:
639        """Not implemented."""
640        <void>self # unused
641        raise NotImplementedError
642
643    def setActive(self, flag: bool) -> None:
644        """Indicate whether or not the event should be logged.
645
646        Logically collective.
647
648        Parameters
649        ----------
650        flag
651            Activate or deactivate the event.
652
653        See Also
654        --------
655        petsc.PetscLogEventDeactivate, petsc.PetscLogEventActivate
656
657        """
658        if flag:
659            CHKERR(PetscLogEventActivate(self.id))
660        else:
661            CHKERR(PetscLogEventDeactivate(self.id))
662
663    property active:
664        """Event activation."""
665        def __get__(self) -> bool:
666            return self.getActive()
667
668        def __set__(self, value):
669            self.setActive(value)
670
671    def getActiveAll(self) -> bool:
672        """Not implemented."""
673        <void>self # unused
674        raise NotImplementedError
675
676    def setActiveAll(self, flag: bool) -> None:
677        """Turn on logging of all events.
678
679        Logically collective.
680
681        Parameters
682        ----------
683        flag
684            Activate (if `True`) or deactivate (if `False`) the logging of all events.
685
686        See Also
687        --------
688        petsc.PetscLogEventSetActiveAll
689
690        """
691        cdef PetscBool tval = PETSC_FALSE
692        if flag: tval = PETSC_TRUE
693        CHKERR(PetscLogEventSetActiveAll(self.id, tval))
694
695    property active_all:
696        """All events activation."""
697        def __get__(self) -> bool:
698            self.getActiveAll()
699
700        def __set__(self, value):
701            self.setActiveAll(value)
702
703    #
704
705    def getPerfInfo(self, stage: int | None = None) -> dict:
706        """Get the performance information about the given event in the given event.
707
708        Not collective.
709
710        Parameters
711        ----------
712        stage
713            The stage number.
714
715        Returns
716        -------
717        info : dict
718            This structure is filled with the performance information.
719
720        See Also
721        --------
722        petsc.PetscLogEventGetPerfInfo
723
724        """
725        cdef PetscEventPerfInfo info
726        cdef PetscInt cstage = PETSC_DETERMINE
727        if stage is not None: cstage = asInt(stage)
728        CHKERR(PetscLogEventGetPerfInfo(<int>cstage, self.id, &info))
729        return info
730
731cdef dict event_registry = {}
732
733cdef LogEvent get_LogEvent(object name):
734    return event_registry.get(name)
735
736cdef LogEvent reg_LogEvent(object name, PetscLogEvent eventid):
737    cdef LogEvent event = LogEvent()
738    event.id = eventid
739    event_registry[name] = event
740    return event
741
742# --------------------------------------------------------------------
743