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