1 2 /* 3 PETSc code to log object creation and destruction and PETSc events. 4 5 This provides the public API used by the rest of PETSc and by users. 6 7 These routines use a private API that is not used elsewhere in PETSc and is not 8 accessible to users. The private API is defined in logimpl.h and the utils directory. 9 10 */ 11 #include <petsc/private/logimpl.h> /*I "petscsys.h" I*/ 12 #include <petsc/private/loghandlerimpl.h> 13 #include <petsctime.h> 14 #include <petscviewer.h> 15 #include <petscdevice.h> 16 #include <petsc/private/deviceimpl.h> 17 #if defined(PETSC_HAVE_TAU_PERFSTUBS) 18 #include <../src/sys/perfstubs/timer.h> 19 #endif 20 21 #if defined(PETSC_HAVE_THREADSAFETY) 22 23 PetscInt petsc_log_gid = -1; /* Global threadId counter */ 24 PETSC_TLS PetscInt petsc_log_tid = -1; /* Local threadId */ 25 26 /* shared variables */ 27 PetscSpinlock PetscLogSpinLock; 28 PetscHMapEvent eventInfoMap_th = NULL; 29 30 PetscInt PetscLogGetTid(void) 31 { 32 if (petsc_log_tid < 0) { 33 PetscCall(PetscSpinlockLock(&PetscLogSpinLock)); 34 petsc_log_tid = ++petsc_log_gid; 35 PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock)); 36 } 37 return petsc_log_tid; 38 } 39 40 #endif 41 42 PetscLogEvent PETSC_LARGEST_EVENT = PETSC_EVENT; 43 44 /* Global counters */ 45 PetscLogDouble petsc_BaseTime = 0.0; 46 PetscLogDouble petsc_TotalFlops = 0.0; /* The number of flops */ 47 PetscLogDouble petsc_send_ct = 0.0; /* The number of sends */ 48 PetscLogDouble petsc_recv_ct = 0.0; /* The number of receives */ 49 PetscLogDouble petsc_send_len = 0.0; /* The total length of all sent messages */ 50 PetscLogDouble petsc_recv_len = 0.0; /* The total length of all received messages */ 51 PetscLogDouble petsc_isend_ct = 0.0; /* The number of immediate sends */ 52 PetscLogDouble petsc_irecv_ct = 0.0; /* The number of immediate receives */ 53 PetscLogDouble petsc_isend_len = 0.0; /* The total length of all immediate send messages */ 54 PetscLogDouble petsc_irecv_len = 0.0; /* The total length of all immediate receive messages */ 55 PetscLogDouble petsc_wait_ct = 0.0; /* The number of waits */ 56 PetscLogDouble petsc_wait_any_ct = 0.0; /* The number of anywaits */ 57 PetscLogDouble petsc_wait_all_ct = 0.0; /* The number of waitalls */ 58 PetscLogDouble petsc_sum_of_waits_ct = 0.0; /* The total number of waits */ 59 PetscLogDouble petsc_allreduce_ct = 0.0; /* The number of reductions */ 60 PetscLogDouble petsc_gather_ct = 0.0; /* The number of gathers and gathervs */ 61 PetscLogDouble petsc_scatter_ct = 0.0; /* The number of scatters and scattervs */ 62 63 /* Thread Local storage */ 64 PETSC_TLS PetscLogDouble petsc_TotalFlops_th = 0.0; 65 PETSC_TLS PetscLogDouble petsc_send_ct_th = 0.0; 66 PETSC_TLS PetscLogDouble petsc_recv_ct_th = 0.0; 67 PETSC_TLS PetscLogDouble petsc_send_len_th = 0.0; 68 PETSC_TLS PetscLogDouble petsc_recv_len_th = 0.0; 69 PETSC_TLS PetscLogDouble petsc_isend_ct_th = 0.0; 70 PETSC_TLS PetscLogDouble petsc_irecv_ct_th = 0.0; 71 PETSC_TLS PetscLogDouble petsc_isend_len_th = 0.0; 72 PETSC_TLS PetscLogDouble petsc_irecv_len_th = 0.0; 73 PETSC_TLS PetscLogDouble petsc_wait_ct_th = 0.0; 74 PETSC_TLS PetscLogDouble petsc_wait_any_ct_th = 0.0; 75 PETSC_TLS PetscLogDouble petsc_wait_all_ct_th = 0.0; 76 PETSC_TLS PetscLogDouble petsc_sum_of_waits_ct_th = 0.0; 77 PETSC_TLS PetscLogDouble petsc_allreduce_ct_th = 0.0; 78 PETSC_TLS PetscLogDouble petsc_gather_ct_th = 0.0; 79 PETSC_TLS PetscLogDouble petsc_scatter_ct_th = 0.0; 80 81 PetscLogDouble petsc_ctog_ct = 0.0; /* The total number of CPU to GPU copies */ 82 PetscLogDouble petsc_gtoc_ct = 0.0; /* The total number of GPU to CPU copies */ 83 PetscLogDouble petsc_ctog_sz = 0.0; /* The total size of CPU to GPU copies */ 84 PetscLogDouble petsc_gtoc_sz = 0.0; /* The total size of GPU to CPU copies */ 85 PetscLogDouble petsc_ctog_ct_scalar = 0.0; /* The total number of CPU to GPU copies */ 86 PetscLogDouble petsc_gtoc_ct_scalar = 0.0; /* The total number of GPU to CPU copies */ 87 PetscLogDouble petsc_ctog_sz_scalar = 0.0; /* The total size of CPU to GPU copies */ 88 PetscLogDouble petsc_gtoc_sz_scalar = 0.0; /* The total size of GPU to CPU copies */ 89 PetscLogDouble petsc_gflops = 0.0; /* The flops done on a GPU */ 90 PetscLogDouble petsc_gtime = 0.0; /* The time spent on a GPU */ 91 92 PETSC_TLS PetscLogDouble petsc_ctog_ct_th = 0.0; 93 PETSC_TLS PetscLogDouble petsc_gtoc_ct_th = 0.0; 94 PETSC_TLS PetscLogDouble petsc_ctog_sz_th = 0.0; 95 PETSC_TLS PetscLogDouble petsc_gtoc_sz_th = 0.0; 96 PETSC_TLS PetscLogDouble petsc_ctog_ct_scalar_th = 0.0; 97 PETSC_TLS PetscLogDouble petsc_gtoc_ct_scalar_th = 0.0; 98 PETSC_TLS PetscLogDouble petsc_ctog_sz_scalar_th = 0.0; 99 PETSC_TLS PetscLogDouble petsc_gtoc_sz_scalar_th = 0.0; 100 PETSC_TLS PetscLogDouble petsc_gflops_th = 0.0; 101 PETSC_TLS PetscLogDouble petsc_gtime_th = 0.0; 102 103 PetscBool PetscLogMemory = PETSC_FALSE; 104 PetscBool PetscLogSyncOn = PETSC_FALSE; 105 106 PetscBool PetscLogGpuTimeFlag = PETSC_FALSE; 107 108 PetscLogState petsc_log_state = NULL; 109 110 #define PETSC_LOG_HANDLER_HOT_BLANK \ 111 { \ 112 NULL, NULL, NULL, NULL, NULL, NULL \ 113 } 114 115 PetscLogHandlerHot PetscLogHandlers[PETSC_LOG_HANDLER_MAX] = { 116 PETSC_LOG_HANDLER_HOT_BLANK, 117 PETSC_LOG_HANDLER_HOT_BLANK, 118 PETSC_LOG_HANDLER_HOT_BLANK, 119 PETSC_LOG_HANDLER_HOT_BLANK, 120 }; 121 122 #undef PETSC_LOG_HANDLERS_HOT_BLANK 123 124 #if defined(PETSC_USE_LOG) 125 #include <petscmachineinfo.h> 126 #include <petscconfiginfo.h> 127 128 /* used in the MPI_XXX() count macros in petsclog.h */ 129 130 /* Action and object logging variables */ 131 Action *petsc_actions = NULL; 132 Object *petsc_objects = NULL; 133 PetscBool petsc_logActions = PETSC_FALSE; 134 PetscBool petsc_logObjects = PETSC_FALSE; 135 int petsc_numActions = 0, petsc_maxActions = 100; 136 int petsc_numObjects = 0, petsc_maxObjects = 100; 137 int petsc_numObjectsDestroyed = 0; 138 139 #include <../src/sys/logging/handler/impls/default/logdefault.h> 140 141 #if defined(PETSC_HAVE_THREADSAFETY) 142 PetscErrorCode PetscAddLogDouble(PetscLogDouble *tot, PetscLogDouble *tot_th, PetscLogDouble tmp) 143 { 144 *tot_th += tmp; 145 PetscCall(PetscSpinlockLock(&PetscLogSpinLock)); 146 *tot += tmp; 147 PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock)); 148 return PETSC_SUCCESS; 149 } 150 151 PetscErrorCode PetscAddLogDoubleCnt(PetscLogDouble *cnt, PetscLogDouble *tot, PetscLogDouble *cnt_th, PetscLogDouble *tot_th, PetscLogDouble tmp) 152 { 153 *cnt_th = *cnt_th + 1; 154 *tot_th += tmp; 155 PetscCall(PetscSpinlockLock(&PetscLogSpinLock)); 156 *tot += (PetscLogDouble)(tmp); 157 *cnt += *cnt + 1; 158 PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock)); 159 return PETSC_SUCCESS; 160 } 161 162 #endif 163 164 static PetscErrorCode PetscLogTryGetHandler(PetscLogHandlerType type, PetscLogHandler *handler) 165 { 166 PetscFunctionBegin; 167 PetscAssertPointer(handler, 2); 168 *handler = NULL; 169 for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) { 170 PetscLogHandler h = PetscLogHandlers[i].handler; 171 if (h) { 172 PetscBool match; 173 174 PetscCall(PetscObjectTypeCompare((PetscObject)h, type, &match)); 175 if (match) { 176 *handler = PetscLogHandlers[i].handler; 177 PetscFunctionReturn(PETSC_SUCCESS); 178 } 179 } 180 } 181 PetscFunctionReturn(PETSC_SUCCESS); 182 } 183 184 /*@ 185 PetscLogGetState - Get the `PetscLogState` for PETSc's global logging, used 186 by all default log handlers (`PetscLogDefaultBegin()`, 187 `PetscLogNestedBegin()`, `PetscLogTraceBegin()`, `PetscLogMPEBegin()`, 188 `PetscLogPerfstubsBegin()`). 189 190 Collective on `PETSC_COMM_WORLD` 191 192 Output Parameter: 193 . state - The `PetscLogState` changed by registrations (such as `PetscLogEventRegister()`) and actions (such as `PetscLogEventBegin()` or `PetscLogStagePush()`) 194 195 Level: developer 196 197 .seealso: [](ch_profiling), `PetscLogState` 198 @*/ 199 PetscErrorCode PetscLogGetState(PetscLogState *state) 200 { 201 PetscFunctionBegin; 202 PetscAssertPointer(state, 1); 203 if (!petsc_log_state) { 204 fprintf(stderr, "PETSC ERROR: Logging has not been enabled.\nYou might have forgotten to call PetscInitialize().\n"); 205 PETSCABORT(MPI_COMM_WORLD, PETSC_ERR_SUP); 206 } 207 *state = petsc_log_state; 208 PetscFunctionReturn(PETSC_SUCCESS); 209 } 210 211 /* Logging functions */ 212 PetscErrorCode (*PetscLogPHC)(PetscObject) = NULL; 213 PetscErrorCode (*PetscLogPHD)(PetscObject) = NULL; 214 PetscErrorCode (*PetscLogPLB)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = NULL; 215 PetscErrorCode (*PetscLogPLE)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = NULL; 216 217 static PetscErrorCode PetscLogHandlerCopyToHot(PetscLogHandler h, PetscLogHandlerHot *hot) 218 { 219 PetscFunctionBegin; 220 hot->handler = h; 221 hot->eventBegin = h->ops->eventbegin; 222 hot->eventEnd = h->ops->eventend; 223 hot->eventSync = h->ops->eventsync; 224 hot->objectCreate = h->ops->objectcreate; 225 hot->objectDestroy = h->ops->objectdestroy; 226 PetscFunctionReturn(PETSC_SUCCESS); 227 } 228 229 /*@ 230 PetscLogHandlerStart - Connect a log handler to PETSc's global logging stream and state. 231 232 Logically collective 233 234 Input Parameters: 235 . h - a `PetscLogHandler` 236 237 Level: developer 238 239 Notes: 240 241 Users should only need this if they create their own log handlers: handlers that are started 242 from the command line (such as `-log_view` and `-log_trace`) or from a function like 243 `PetscLogNestedBegin()` will automatically be started. 244 245 There is a limit of `PESC_LOG_HANDLER_MAX` handlers that can be active at one time. 246 247 To disconnect a handler from the global stream call `PetscLogHandlerStop()`. 248 249 When a log handler is started, stages that have already been pushed with `PetscLogStagePush()`, 250 will be pushed for the new log handler, but it will not be informed of any events that are 251 in progress. It is recommended to start any user-defined log handlers immediately following 252 before any user-defined stages are pushed. 253 254 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStop()` 255 @*/ 256 PetscErrorCode PetscLogHandlerStart(PetscLogHandler h) 257 { 258 PetscFunctionBegin; 259 for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) { 260 if (PetscLogHandlers[i].handler == h) PetscFunctionReturn(PETSC_SUCCESS); 261 } 262 for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) { 263 if (PetscLogHandlers[i].handler == NULL) { 264 PetscCall(PetscObjectReference((PetscObject)h)); 265 PetscCall(PetscLogHandlerCopyToHot(h, &PetscLogHandlers[i])); 266 if (petsc_log_state) { 267 PetscLogStage stack_height; 268 PetscIntStack orig_stack, temp_stack; 269 270 PetscCall(PetscLogHandlerSetState(h, petsc_log_state)); 271 stack_height = petsc_log_state->stage_stack->top + 1; 272 PetscCall(PetscIntStackCreate(&temp_stack)); 273 orig_stack = petsc_log_state->stage_stack; 274 petsc_log_state->stage_stack = temp_stack; 275 petsc_log_state->current_stage = -1; 276 for (int s = 0; s < stack_height; s++) { 277 PetscLogStage stage = (PetscLogStage)orig_stack->stack[s]; 278 PetscCall(PetscLogHandlerStagePush(h, stage)); 279 PetscCall(PetscIntStackPush(temp_stack, stage)); 280 petsc_log_state->current_stage = stage; 281 } 282 PetscCall(PetscIntStackDestroy(temp_stack)); 283 petsc_log_state->stage_stack = orig_stack; 284 } 285 PetscFunctionReturn(PETSC_SUCCESS); 286 } 287 } 288 SETERRQ(PetscObjectComm((PetscObject)h), PETSC_ERR_ARG_WRONGSTATE, "%d log handlers already started, cannot start another", PETSC_LOG_HANDLER_MAX); 289 PetscFunctionReturn(PETSC_SUCCESS); 290 } 291 292 /*@ 293 PetscLogHandlerStop - Disconnect a log handler from PETSc's global logging stream. 294 295 Logically collective 296 297 Input Parameters: 298 . h - a `PetscLogHandler` 299 300 Level: developer 301 302 Note: 303 After `PetscLogHandlerStop()`, the handler can still access the global logging state 304 with `PetscLogHandlerGetState()`, so that it can access the registry when post-processing 305 (for instance, in `PetscLogHandlerView()`), 306 307 When a log handler is stopped, the remaining stages will be popped before it is 308 disconnected from the log stream. 309 310 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStart()` 311 @*/ 312 PetscErrorCode PetscLogHandlerStop(PetscLogHandler h) 313 { 314 PetscFunctionBegin; 315 for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) { 316 if (PetscLogHandlers[i].handler == h) { 317 if (petsc_log_state) { 318 PetscLogState state; 319 PetscLogStage stack_height; 320 PetscIntStack orig_stack, temp_stack; 321 322 PetscCall(PetscLogHandlerGetState(h, &state)); 323 PetscCheck(state == petsc_log_state, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "Called PetscLogHandlerStop() for a PetscLogHander that was not started."); 324 stack_height = petsc_log_state->stage_stack->top + 1; 325 PetscCall(PetscIntStackCreate(&temp_stack)); 326 orig_stack = petsc_log_state->stage_stack; 327 petsc_log_state->stage_stack = temp_stack; 328 for (int s = 0; s < stack_height; s++) { 329 PetscLogStage stage = (PetscLogStage)orig_stack->stack[s]; 330 331 PetscCall(PetscIntStackPush(temp_stack, stage)); 332 } 333 for (int s = 0; s < stack_height; s++) { 334 PetscLogStage stage; 335 PetscBool empty; 336 337 PetscCall(PetscIntStackPop(temp_stack, &stage)); 338 PetscCall(PetscIntStackEmpty(temp_stack, &empty)); 339 if (!empty) { 340 PetscCall(PetscIntStackTop(temp_stack, &petsc_log_state->current_stage)); 341 } else petsc_log_state->current_stage = -1; 342 PetscCall(PetscLogHandlerStagePop(h, stage)); 343 } 344 PetscCall(PetscIntStackDestroy(temp_stack)); 345 petsc_log_state->stage_stack = orig_stack; 346 PetscCall(PetscIntStackTop(petsc_log_state->stage_stack, &petsc_log_state->current_stage)); 347 } 348 PetscCall(PetscArrayzero(&PetscLogHandlers[i], 1)); 349 PetscCall(PetscObjectDereference((PetscObject)h)); 350 } 351 } 352 PetscFunctionReturn(PETSC_SUCCESS); 353 } 354 /*@C 355 PetscLogSet - Sets the logging functions called at the beginning and ending of every event. 356 357 Not Collective 358 359 Input Parameters: 360 + b - The function called at beginning of event 361 - e - The function called at end of event 362 363 Level: developer 364 365 Developer Notes: 366 The default loggers are `PetscLogEventBeginDefault()` and `PetscLogEventEndDefault()`. 367 368 .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogDefaultBegin()`, `PetscLogAllBegin()`, `PetscLogTraceBegin()`, `PetscLogEventBeginDefault()`, `PetscLogEventEndDefault()` 369 @*/ 370 PetscErrorCode PetscLogSet(PetscErrorCode (*b)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject), PetscErrorCode (*e)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject)) 371 { 372 PetscFunctionBegin; 373 PetscLogPLB = b; 374 PetscLogPLE = e; 375 PetscFunctionReturn(PETSC_SUCCESS); 376 } 377 378 /*@C 379 PetscLogIsActive - Check if logging is currently in progress. 380 381 Not Collective 382 383 Output Parameter: 384 . isActive - `PETSC_TRUE` if logging is in progress, `PETSC_FALSE` otherwise 385 386 Level: beginner 387 388 .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogAllBegin()`, `PetscLogSet()` 389 @*/ 390 PetscErrorCode PetscLogIsActive(PetscBool *isActive) 391 { 392 PetscFunctionBegin; 393 *isActive = (PetscLogPLB && PetscLogPLE) ? PETSC_TRUE : PETSC_FALSE; 394 PetscFunctionReturn(PETSC_SUCCESS); 395 } 396 397 static PetscErrorCode PetscLogTypeBegin(PetscLogHandlerType type) 398 { 399 PetscLogHandler handler; 400 401 PetscFunctionBegin; 402 PetscCall(PetscLogTryGetHandler(type, &handler)); 403 if (handler) PetscFunctionReturn(PETSC_SUCCESS); 404 PetscCall(PetscLogHandlerCreate(PETSC_COMM_WORLD, &handler)); 405 PetscCall(PetscLogHandlerSetType(handler, type)); 406 PetscCall(PetscLogHandlerStart(handler)); 407 PetscCall(PetscLogHandlerDestroy(&handler)); 408 PetscFunctionReturn(PETSC_SUCCESS); 409 } 410 411 /*@C 412 PetscLogDefaultBegin - Turns on logging of objects and events using the default logging functions `PetscLogEventBeginDefault()` and `PetscLogEventEndDefault()`. This logs flop 413 rates and object creation and should not slow programs down too much. 414 This routine may be called more than once. 415 416 Logically Collective over `PETSC_COMM_WORLD` 417 418 Options Database Key: 419 . -log_view [viewertype:filename:viewerformat] - Prints summary of flop and timing information to the 420 screen (for code configured with --with-log=1 (which is the default)) 421 422 Example Usage: 423 .vb 424 PetscInitialize(...); 425 PetscLogDefaultBegin(); 426 ... code ... 427 PetscLogView(viewer); or PetscLogDump(); 428 PetscFinalize(); 429 .ve 430 431 Level: advanced 432 433 Note: 434 `PetscLogView()` or `PetscLogDump()` actually cause the printing of 435 the logging information. 436 437 .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogAllBegin()`, `PetscLogView()`, `PetscLogTraceBegin()` 438 @*/ 439 PetscErrorCode PetscLogDefaultBegin(void) 440 { 441 PetscFunctionBegin; 442 PetscCall(PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault)); 443 PetscFunctionReturn(PETSC_SUCCESS); 444 } 445 446 /*@C 447 PetscLogAllBegin - Turns on extensive logging of objects and events. Logs 448 all events. This creates large log files and slows the program down. 449 450 Logically Collective on `PETSC_COMM_WORLD` 451 452 Options Database Key: 453 . -log_all - Prints extensive log information 454 455 Example Usage: 456 .vb 457 PetscInitialize(...); 458 PetscLogAllBegin(); 459 ... code ... 460 PetscLogDump(filename); 461 PetscFinalize(); 462 .ve 463 464 Level: advanced 465 466 Note: 467 A related routine is `PetscLogDefaultBegin()` (with the options key -log_view), which is 468 intended for production runs since it logs only flop rates and object 469 creation (and shouldn't significantly slow the programs). 470 471 .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogDefaultBegin()`, `PetscLogTraceBegin()` 472 @*/ 473 PetscErrorCode PetscLogAllBegin(void) 474 { 475 PetscFunctionBegin; 476 PetscCall(PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete)); 477 PetscFunctionReturn(PETSC_SUCCESS); 478 } 479 480 /*@C 481 PetscLogTraceBegin - Activates trace logging. Every time a PETSc event 482 begins or ends, the event name is printed. 483 484 Logically Collective on `PETSC_COMM_WORLD` 485 486 Input Parameter: 487 . file - The file to print trace in (e.g. stdout) 488 489 Options Database Key: 490 . -log_trace [filename] - Activates `PetscLogTraceBegin()` 491 492 Level: intermediate 493 494 Notes: 495 `PetscLogTraceBegin()` prints the processor number, the execution time (sec), 496 then "Event begin:" or "Event end:" followed by the event name. 497 498 `PetscLogTraceBegin()` allows tracing of all PETSc calls, which is useful 499 to determine where a program is hanging without running in the 500 debugger. Can be used in conjunction with the -info option. 501 502 .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogAllBegin()`, `PetscLogView()`, `PetscLogDefaultBegin()` 503 @*/ 504 PetscErrorCode PetscLogTraceBegin(FILE *file) 505 { 506 PetscFunctionBegin; 507 petsc_tracefile = file; 508 509 PetscCall(PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace)); 510 PetscFunctionReturn(PETSC_SUCCESS); 511 } 512 513 /*@C 514 PetscLogLegacyCallbacksBegin - Create and start a log handler from callbacks 515 matching the now deprecated function pointers `PetscLogPLB`, `PetscLogPLE`, 516 `PetscLogPHC`, `PetscLogPHD`. 517 518 Logically Collective over `PETSC_COMM_WORLD` 519 520 Input Parameters: 521 + PetscLogPLB - A callback that will be executed by `PetscLogEventBegin()` (or `NULL`) 522 . PetscLogPLE - A callback that will be executed by `PetscLogEventEnd()` (or `NULL`) 523 . PetscLogPHC - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`) 524 - PetscLogPHD - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`) 525 526 Calling sequence of `PetscLogPLB`: 527 + e - a `PetscLogEvent` that is beginning 528 . _i - deprecated, unused 529 . o1 - a `PetscObject` associated with `e` (or `NULL`) 530 . o2 - a `PetscObject` associated with `e` (or `NULL`) 531 . o3 - a `PetscObject` associated with `e` (or `NULL`) 532 - o4 - a `PetscObject` associated with `e` (or `NULL`) 533 534 Calling sequence of `PetscLogPLE`: 535 + e - a `PetscLogEvent` that is beginning 536 . _i - deprecated, unused 537 . o1 - a `PetscObject` associated with `e` (or `NULL`) 538 . o2 - a `PetscObject` associated with `e` (or `NULL`) 539 . o3 - a `PetscObject` associated with `e` (or `NULL`) 540 - o4 - a `PetscObject` associated with `e` (or `NULL`) 541 542 Calling sequence of `PetscLogPHC`: 543 . o - a `PetscObject` that has just been created 544 545 Calling sequence of `PetscLogPHD`: 546 . o - a `PetscObject` that is about to be destroyed 547 548 Level: advanced 549 550 Notes: 551 This is for transitioning from the deprecated function `PetscLogSet()` and should not be used in new code. 552 553 This should help migrate external log handlers to use `PetscLogHandler`, but 554 callbacks that depend on the deprecated `PetscLogStage` datatype will have to be 555 updated. 556 557 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerStart()`, `PetscLogState` 558 @*/ 559 PetscErrorCode PetscLogLegacyCallbacksBegin(PetscErrorCode (*PetscLogPLB)(PetscLogEvent e, int _i, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4), PetscErrorCode (*PetscLogPLE)(PetscLogEvent e, int _i, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4), PetscErrorCode (*PetscLogPHC)(PetscObject o), PetscErrorCode (*PetscLogPHD)(PetscObject o)) 560 { 561 PetscLogHandler handler; 562 563 PetscFunctionBegin; 564 PetscCall(PetscLogHandlerCreateLegacy(PETSC_COMM_WORLD, PetscLogPLB, PetscLogPLE, PetscLogPHC, PetscLogPHD, &handler)); 565 PetscCall(PetscLogHandlerStart(handler)); 566 PetscCall(PetscLogHandlerDestroy(&handler)); 567 PetscFunctionReturn(PETSC_SUCCESS); 568 } 569 570 #if defined(PETSC_HAVE_MPE) 571 #include <mpe.h> 572 573 PETSC_INTERN PetscErrorCode PetscLogHandlerCreate_MPE(MPI_Comm, PetscLogHandler *); 574 575 static PetscBool PetscBeganMPE = PETSC_FALSE; 576 577 PETSC_INTERN PetscErrorCode PetscLogEventBeginMPE(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject); 578 PETSC_INTERN PetscErrorCode PetscLogEventEndMPE(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject); 579 #endif 580 581 /*@C 582 PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files and slows the 583 program down. 584 585 Collective over `PETSC_COMM_WORLD` 586 587 Options Database Key: 588 . -log_mpe - Prints extensive log information 589 590 Level: advanced 591 592 Note: 593 A related routine is `PetscLogDefaultBegin()` (with the options key `-log_view`), which is 594 intended for production runs since it logs only flop rates and object creation (and should 595 not significantly slow the programs). 596 597 .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogDefaultBegin()`, `PetscLogAllBegin()`, `PetscLogEventActivate()`, 598 `PetscLogEventDeactivate()` 599 @*/ 600 PetscErrorCode PetscLogMPEBegin(void) 601 { 602 PetscFunctionBegin; 603 #if defined(PETSC_HAVE_MPE) 604 /* Do MPE initialization */ 605 if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */ 606 PetscCall(PetscInfo(0, "Initializing MPE.\n")); 607 PetscCall(MPE_Init_log()); 608 609 PetscBeganMPE = PETSC_TRUE; 610 } else { 611 PetscCall(PetscInfo(0, "MPE already initialized. Not attempting to reinitialize.\n")); 612 } 613 PetscCall(PetscLogSet(PetscLogEventBeginMPE, PetscLogEventEndMPE)); 614 #else 615 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe"); 616 #endif 617 PetscFunctionReturn(PETSC_SUCCESS); 618 } 619 620 #if defined(PETSC_HAVE_TAU_PERFSTUBS) 621 #include <../src/sys/perfstubs/timer.h> 622 #endif 623 624 /*@C 625 PetscLogPerfstubsBegin - Turns on logging of events using the perfstubs interface. 626 627 Collective over `PETSC_COMM_WORLD` 628 629 Options Database Key: 630 . -log_perfstubs - use an external log handler through the perfstubs interface 631 632 Level: advanced 633 634 .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogEventActivate()` 635 @*/ 636 PetscErrorCode PetscLogPerfstubsBegin(void) 637 { 638 PetscFunctionBegin; 639 #if defined(PETSC_HAVE_TAU_PERFSTUBS) 640 PetscCall(PetscLogTypeBegin(PETSC_LOG_HANDLER_PERFSTUBS)); 641 #else 642 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without perfstubs support, reconfigure with --with-tau-perfstubs"); 643 #endif 644 PetscFunctionReturn(PETSC_SUCCESS); 645 } 646 647 /*@ 648 PetscLogActions - Determines whether actions are logged for the graphical viewer. 649 650 Not Collective 651 652 Input Parameter: 653 . flag - `PETSC_TRUE` if actions are to be logged 654 655 Options Database Key: 656 . -log_exclude_actions - Turns off actions logging 657 658 Level: intermediate 659 660 Note: 661 Logging of actions continues to consume more memory as the program 662 runs. Long running programs should consider turning this feature off. 663 664 .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()` 665 @*/ 666 PetscErrorCode PetscLogActions(PetscBool flag) 667 { 668 PetscFunctionBegin; 669 petsc_logActions = flag; 670 PetscFunctionReturn(PETSC_SUCCESS); 671 } 672 673 /*@ 674 PetscLogObjects - Determines whether objects are logged for the graphical viewer. 675 676 Not Collective 677 678 Input Parameter: 679 . flag - `PETSC_TRUE` if objects are to be logged 680 681 Options Database Key: 682 . -log_exclude_objects - Turns off objects logging 683 684 Level: intermediate 685 686 Note: 687 Logging of objects continues to consume more memory as the program 688 runs. Long running programs should consider turning this feature off. 689 690 .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()` 691 @*/ 692 PetscErrorCode PetscLogObjects(PetscBool flag) 693 { 694 PetscFunctionBegin; 695 petsc_logObjects = flag; 696 PetscFunctionReturn(PETSC_SUCCESS); 697 } 698 699 /*------------------------------------------------ Stage Functions --------------------------------------------------*/ 700 /*@C 701 PetscLogStageRegister - Attaches a character string name to a logging stage. 702 703 Not Collective 704 705 Input Parameter: 706 . sname - The name to associate with that stage 707 708 Output Parameter: 709 . stage - The stage number 710 711 Level: intermediate 712 713 .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()` 714 @*/ 715 PetscErrorCode PetscLogStageRegister(const char sname[], PetscLogStage *stage) 716 { 717 PetscStageLog stageLog; 718 PetscLogEvent event; 719 720 PetscFunctionBegin; 721 PetscCall(PetscLogGetStageLog(&stageLog)); 722 PetscCall(PetscStageLogRegister(stageLog, sname, stage)); 723 /* Copy events already changed in the main stage, this sucks */ 724 PetscCall(PetscEventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents)); 725 for (event = 0; event < stageLog->eventLog->numEvents; event++) PetscCall(PetscEventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event], &stageLog->stageInfo[*stage].eventLog->eventInfo[event])); 726 PetscCall(PetscClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses)); 727 #if defined(PETSC_HAVE_TAU_PERFSTUBS) 728 if (perfstubs_initialized == PERFSTUBS_SUCCESS) PetscStackCallExternalVoid("ps_timer_create_", stageLog->stageInfo[*stage].timer = ps_timer_create_(sname)); 729 #endif 730 PetscFunctionReturn(PETSC_SUCCESS); 731 } 732 733 /*@C 734 PetscLogStagePush - This function pushes a stage on the logging stack. Events started and stopped until `PetscLogStagePop()` will be associated with the stage 735 736 Not Collective 737 738 Input Parameter: 739 . stage - The stage on which to log 740 741 Example Usage: 742 If the option -log_view is used to run the program containing the 743 following code, then 2 sets of summary data will be printed during 744 PetscFinalize(). 745 .vb 746 PetscInitialize(int *argc,char ***args,0,0); 747 [stage 0 of code] 748 PetscLogStagePush(1); 749 [stage 1 of code] 750 PetscLogStagePop(); 751 PetscBarrier(...); 752 [more stage 0 of code] 753 PetscFinalize(); 754 .ve 755 756 Level: intermediate 757 758 Note: 759 Use `PetscLogStageRegister()` to register a stage. 760 761 .seealso: [](ch_profiling), `PetscLogStagePop()`, `PetscLogStageRegister()`, `PetscBarrier()` 762 @*/ 763 PetscErrorCode PetscLogStagePush(PetscLogStage stage) 764 { 765 PetscStageLog stageLog; 766 767 PetscFunctionBegin; 768 PetscCall(PetscLogGetStageLog(&stageLog)); 769 PetscCall(PetscStageLogPush(stageLog, stage)); 770 #if defined(PETSC_HAVE_TAU_PERFSTUBS) 771 if (perfstubs_initialized == PERFSTUBS_SUCCESS && stageLog->stageInfo[stage].timer != NULL) PetscStackCallExternalVoid("ps_timer_start_", ps_timer_start_(stageLog->stageInfo[stage].timer)); 772 #endif 773 PetscFunctionReturn(PETSC_SUCCESS); 774 } 775 776 /*@C 777 PetscLogStagePop - This function pops a stage from the logging stack that was pushed with `PetscLogStagePush()` 778 779 Not Collective 780 781 Example Usage: 782 If the option -log_view is used to run the program containing the 783 following code, then 2 sets of summary data will be printed during 784 PetscFinalize(). 785 .vb 786 PetscInitialize(int *argc,char ***args,0,0); 787 [stage 0 of code] 788 PetscLogStagePush(1); 789 [stage 1 of code] 790 PetscLogStagePop(); 791 PetscBarrier(...); 792 [more stage 0 of code] 793 PetscFinalize(); 794 .ve 795 796 Level: intermediate 797 798 .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStageRegister()`, `PetscBarrier()` 799 @*/ 800 PetscErrorCode PetscLogStagePop(void) 801 { 802 PetscStageLog stageLog; 803 804 PetscFunctionBegin; 805 PetscCall(PetscLogGetStageLog(&stageLog)); 806 #if defined(PETSC_HAVE_TAU_PERFSTUBS) 807 if (perfstubs_initialized == PERFSTUBS_SUCCESS && stageLog->stageInfo[stageLog->curStage].timer != NULL) PetscStackCallExternalVoid("ps_timer_stop_", ps_timer_stop_(stageLog->stageInfo[stageLog->curStage].timer)); 808 #endif 809 PetscCall(PetscStageLogPop(stageLog)); 810 PetscFunctionReturn(PETSC_SUCCESS); 811 } 812 813 /*@ 814 PetscLogStageSetActive - Sets if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`. 815 816 Not Collective 817 818 Input Parameters: 819 + stage - The stage 820 - isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`) 821 822 Level: intermediate 823 824 Note: 825 If this is set to `PETSC_FALSE` the logging acts as if the stage did not exist 826 827 .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()` 828 @*/ 829 PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive) 830 { 831 PetscStageLog stageLog; 832 833 PetscFunctionBegin; 834 PetscCall(PetscLogGetStageLog(&stageLog)); 835 PetscCall(PetscStageLogSetActive(stageLog, stage, isActive)); 836 PetscFunctionReturn(PETSC_SUCCESS); 837 } 838 839 /*@ 840 PetscLogStageGetActive - Checks if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`. 841 842 Not Collective 843 844 Input Parameter: 845 . stage - The stage 846 847 Output Parameter: 848 . isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`) 849 850 Level: intermediate 851 852 .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()` 853 @*/ 854 PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscBool *isActive) 855 { 856 PetscStageLog stageLog; 857 858 PetscFunctionBegin; 859 PetscCall(PetscLogGetStageLog(&stageLog)); 860 PetscCall(PetscStageLogGetActive(stageLog, stage, isActive)); 861 PetscFunctionReturn(PETSC_SUCCESS); 862 } 863 864 /*@ 865 PetscLogStageSetVisible - Determines stage visibility in `PetscLogView()` 866 867 Not Collective 868 869 Input Parameters: 870 + stage - The stage 871 - isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`) 872 873 Level: intermediate 874 875 Developer Notes: 876 What does visible mean, needs to be documented. 877 878 .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()` 879 @*/ 880 PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible) 881 { 882 PetscStageLog stageLog; 883 884 PetscFunctionBegin; 885 PetscCall(PetscLogGetStageLog(&stageLog)); 886 PetscCall(PetscStageLogSetVisible(stageLog, stage, isVisible)); 887 PetscFunctionReturn(PETSC_SUCCESS); 888 } 889 890 /*@ 891 PetscLogStageGetVisible - Returns stage visibility in `PetscLogView()` 892 893 Not Collective 894 895 Input Parameter: 896 . stage - The stage 897 898 Output Parameter: 899 . isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`) 900 901 Level: intermediate 902 903 .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()` 904 @*/ 905 PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscBool *isVisible) 906 { 907 PetscStageLog stageLog; 908 909 PetscFunctionBegin; 910 PetscCall(PetscLogGetStageLog(&stageLog)); 911 PetscCall(PetscStageLogGetVisible(stageLog, stage, isVisible)); 912 PetscFunctionReturn(PETSC_SUCCESS); 913 } 914 915 /*@C 916 PetscLogStageGetId - Returns the stage id when given the stage name. 917 918 Not Collective 919 920 Input Parameter: 921 . name - The stage name 922 923 Output Parameter: 924 . stage - The stage, , or -1 if no stage with that name exists 925 926 Level: intermediate 927 928 .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()` 929 @*/ 930 PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage) 931 { 932 PetscStageLog stageLog; 933 934 PetscFunctionBegin; 935 PetscCall(PetscLogGetStageLog(&stageLog)); 936 PetscCall(PetscStageLogGetStage(stageLog, name, stage)); 937 PetscFunctionReturn(PETSC_SUCCESS); 938 } 939 940 /*@C 941 PetscLogStageGetName - Returns the stage name when given the stage id. 942 943 Not Collective 944 945 Input Parameter: 946 . stage - The stage 947 948 Output Parameter: 949 . name - The stage name 950 951 Level: intermediate 952 953 .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()` 954 @*/ 955 PetscErrorCode PetscLogStageGetName(PetscLogStage stage, const char **name) 956 { 957 PetscLogStageInfo stage_info; 958 PetscLogState state; 959 960 PetscFunctionBegin; 961 PetscCall(PetscLogGetState(&state)); 962 PetscCall(PetscLogStateStageGetInfo(state, stage, &stage_info)); 963 *name = stage_info.name; 964 PetscFunctionReturn(PETSC_SUCCESS); 965 } 966 967 /*------------------------------------------------ Event Functions --------------------------------------------------*/ 968 969 /*@C 970 PetscLogEventRegister - Registers an event name for logging operations 971 972 Not Collective 973 974 Input Parameters: 975 + name - The name associated with the event 976 - classid - The classid associated to the class for this event, obtain either with 977 `PetscClassIdRegister()` or use a predefined one such as `KSP_CLASSID`, `SNES_CLASSID`, the predefined ones 978 are only available in C code 979 980 Output Parameter: 981 . event - The event id for use with `PetscLogEventBegin()` and `PetscLogEventEnd()`. 982 983 Example Usage: 984 .vb 985 PetscLogEvent USER_EVENT; 986 PetscClassId classid; 987 PetscLogDouble user_event_flops; 988 PetscClassIdRegister("class name",&classid); 989 PetscLogEventRegister("User event name",classid,&USER_EVENT); 990 PetscLogEventBegin(USER_EVENT,0,0,0,0); 991 [code segment to monitor] 992 PetscLogFlops(user_event_flops); 993 PetscLogEventEnd(USER_EVENT,0,0,0,0); 994 .ve 995 996 Level: intermediate 997 998 Notes: 999 PETSc automatically logs library events if the code has been 1000 configured with --with-log (which is the default) and 1001 -log_view or -log_all is specified. `PetscLogEventRegister()` is 1002 intended for logging user events to supplement this PETSc 1003 information. 1004 1005 PETSc can gather data for use with the utilities Jumpshot 1006 (part of the MPICH distribution). If PETSc has been compiled 1007 with flag -DPETSC_HAVE_MPE (MPE is an additional utility within 1008 MPICH), the user can employ another command line option, -log_mpe, 1009 to create a logfile, "mpe.log", which can be visualized 1010 Jumpshot. 1011 1012 The classid is associated with each event so that classes of events 1013 can be disabled simultaneously, such as all matrix events. The user 1014 can either use an existing classid, such as `MAT_CLASSID`, or create 1015 their own as shown in the example. 1016 1017 If an existing event with the same name exists, its event handle is 1018 returned instead of creating a new event. 1019 1020 .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogFlops()`, 1021 `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscClassIdRegister()` 1022 @*/ 1023 PetscErrorCode PetscLogEventRegister(const char name[], PetscClassId classid, PetscLogEvent *event) 1024 { 1025 PetscStageLog stageLog; 1026 int stage; 1027 1028 PetscFunctionBegin; 1029 *event = PETSC_DECIDE; 1030 PetscCall(PetscLogGetStageLog(&stageLog)); 1031 PetscCall(PetscEventRegLogGetEvent(stageLog->eventLog, name, event)); 1032 if (*event > 0) PetscFunctionReturn(PETSC_SUCCESS); 1033 PetscCall(PetscEventRegLogRegister(stageLog->eventLog, name, classid, event)); 1034 for (stage = 0; stage < stageLog->numStages; stage++) { 1035 PetscCall(PetscEventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents)); 1036 PetscCall(PetscClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses)); 1037 } 1038 PetscFunctionReturn(PETSC_SUCCESS); 1039 } 1040 1041 /*@ 1042 PetscLogEventSetCollective - Indicates that a particular event is collective. 1043 1044 Not Collective 1045 1046 Input Parameters: 1047 + event - The event id 1048 - collective - Boolean flag indicating whether a particular event is collective 1049 1050 Level: developer 1051 1052 Notes: 1053 New events returned from `PetscLogEventRegister()` are collective by default. 1054 1055 Collective events are handled specially if the -log_sync is used. In that case the logging saves information about 1056 two parts of the event; the time for all the MPI ranks to synchronize and then the time for the actual computation/communication 1057 to be performed. This option is useful to debug imbalance within the computations or communications 1058 1059 .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventRegister()` 1060 @*/ 1061 PetscErrorCode PetscLogEventSetCollective(PetscLogEvent event, PetscBool collective) 1062 { 1063 PetscStageLog stageLog; 1064 PetscEventRegLog eventRegLog; 1065 1066 PetscFunctionBegin; 1067 PetscCall(PetscLogGetStageLog(&stageLog)); 1068 PetscCall(PetscStageLogGetEventRegLog(stageLog, &eventRegLog)); 1069 PetscCheck(event >= 0 && event <= eventRegLog->numEvents, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid event id"); 1070 eventRegLog->eventInfo[event].collective = collective; 1071 PetscFunctionReturn(PETSC_SUCCESS); 1072 } 1073 1074 /*@ 1075 PetscLogEventIncludeClass - Activates event logging for a PETSc object class in every stage. 1076 1077 Not Collective 1078 1079 Input Parameter: 1080 . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc. 1081 1082 Level: developer 1083 1084 .seealso: [](ch_profiling), `PetscLogEventActivateClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()` 1085 @*/ 1086 PetscErrorCode PetscLogEventIncludeClass(PetscClassId classid) 1087 { 1088 PetscStageLog stageLog; 1089 int stage; 1090 1091 PetscFunctionBegin; 1092 PetscCall(PetscLogGetStageLog(&stageLog)); 1093 for (stage = 0; stage < stageLog->numStages; stage++) PetscCall(PetscEventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid)); 1094 PetscFunctionReturn(PETSC_SUCCESS); 1095 } 1096 1097 /*@ 1098 PetscLogEventExcludeClass - Deactivates event logging for a PETSc object class in every stage. 1099 1100 Not Collective 1101 1102 Input Parameter: 1103 . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc. 1104 1105 Level: developer 1106 1107 Note: 1108 If a class is excluded then events associated with that class are not logged. 1109 1110 .seealso: [](ch_profiling), `PetscLogEventDeactivateClass()`, `PetscLogEventActivateClass()`, `PetscLogEventDeactivate()`, `PetscLogEventActivate()` 1111 @*/ 1112 PetscErrorCode PetscLogEventExcludeClass(PetscClassId classid) 1113 { 1114 PetscStageLog stageLog; 1115 int stage; 1116 1117 PetscFunctionBegin; 1118 PetscCall(PetscLogGetStageLog(&stageLog)); 1119 for (stage = 0; stage < stageLog->numStages; stage++) PetscCall(PetscEventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid)); 1120 PetscFunctionReturn(PETSC_SUCCESS); 1121 } 1122 1123 /*@ 1124 PetscLogEventActivate - Indicates that a particular event should be logged. 1125 1126 Not Collective 1127 1128 Input Parameter: 1129 . event - The event id 1130 1131 Example Usage: 1132 .vb 1133 PetscLogEventDeactivate(VEC_SetValues); 1134 [code where you do not want to log VecSetValues()] 1135 PetscLogEventActivate(VEC_SetValues); 1136 [code where you do want to log VecSetValues()] 1137 .ve 1138 1139 Level: advanced 1140 1141 Note: 1142 The event may be either a pre-defined PETSc event (found in include/petsclog.h) 1143 or an event number obtained with `PetscLogEventRegister()`. 1144 1145 .seealso: [](ch_profiling), `PlogEventDeactivate()`, `PlogEventDeactivatePush()`, `PetscLogEventDeactivatePop()` 1146 @*/ 1147 PetscErrorCode PetscLogEventActivate(PetscLogEvent event) 1148 { 1149 PetscStageLog stageLog; 1150 int stage; 1151 1152 PetscFunctionBegin; 1153 PetscCall(PetscLogGetStageLog(&stageLog)); 1154 PetscCall(PetscStageLogGetCurrent(stageLog, &stage)); 1155 PetscCall(PetscEventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event)); 1156 PetscFunctionReturn(PETSC_SUCCESS); 1157 } 1158 1159 /*@ 1160 PetscLogEventDeactivate - Indicates that a particular event should not be logged. 1161 1162 Not Collective 1163 1164 Input Parameter: 1165 . event - The event id 1166 1167 Example Usage: 1168 .vb 1169 PetscLogEventDeactivate(VEC_SetValues); 1170 [code where you do not want to log VecSetValues()] 1171 PetscLogEventActivate(VEC_SetValues); 1172 [code where you do want to log VecSetValues()] 1173 .ve 1174 1175 Level: advanced 1176 1177 Note: 1178 The event may be either a pre-defined PETSc event (found in 1179 include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`). 1180 1181 .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()` 1182 @*/ 1183 PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event) 1184 { 1185 PetscStageLog stageLog; 1186 int stage; 1187 1188 PetscFunctionBegin; 1189 PetscCall(PetscLogGetStageLog(&stageLog)); 1190 PetscCall(PetscStageLogGetCurrent(stageLog, &stage)); 1191 PetscCall(PetscEventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event)); 1192 PetscFunctionReturn(PETSC_SUCCESS); 1193 } 1194 1195 /*@ 1196 PetscLogEventDeactivatePush - Indicates that a particular event should not be logged until `PetscLogEventDeactivatePop()` is called 1197 1198 Not Collective 1199 1200 Input Parameter: 1201 . event - The event id 1202 1203 Example Usage: 1204 .vb 1205 PetscLogEventDeactivatePush(VEC_SetValues); 1206 [code where you do not want to log VecSetValues()] 1207 PetscLogEventDeactivatePop(VEC_SetValues); 1208 [code where you do want to log VecSetValues()] 1209 .ve 1210 1211 Level: advanced 1212 1213 Note: 1214 The event may be either a pre-defined PETSc event (found in 1215 include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`). 1216 1217 .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePop()`, `PetscLogEventDeactivate()` 1218 @*/ 1219 PetscErrorCode PetscLogEventDeactivatePush(PetscLogEvent event) 1220 { 1221 PetscStageLog stageLog; 1222 int stage; 1223 1224 PetscFunctionBegin; 1225 PetscCall(PetscLogGetStageLog(&stageLog)); 1226 PetscCall(PetscStageLogGetCurrent(stageLog, &stage)); 1227 PetscCall(PetscEventPerfLogDeactivatePush(stageLog->stageInfo[stage].eventLog, event)); 1228 PetscFunctionReturn(PETSC_SUCCESS); 1229 } 1230 1231 /*@ 1232 PetscLogEventDeactivatePop - Indicates that a particular event should again be logged after the logging was turned off with `PetscLogEventDeactivatePush()` 1233 1234 Not Collective 1235 1236 Input Parameter: 1237 . event - The event id 1238 1239 Example Usage: 1240 .vb 1241 PetscLogEventDeactivatePush(VEC_SetValues); 1242 [code where you do not want to log VecSetValues()] 1243 PetscLogEventDeactivatePop(VEC_SetValues); 1244 [code where you do want to log VecSetValues()] 1245 .ve 1246 1247 Level: advanced 1248 1249 Note: 1250 The event may be either a pre-defined PETSc event (found in 1251 include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`). 1252 1253 .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()` 1254 @*/ 1255 PetscErrorCode PetscLogEventDeactivatePop(PetscLogEvent event) 1256 { 1257 PetscStageLog stageLog; 1258 int stage; 1259 1260 PetscFunctionBegin; 1261 PetscCall(PetscLogGetStageLog(&stageLog)); 1262 PetscCall(PetscStageLogGetCurrent(stageLog, &stage)); 1263 PetscCall(PetscEventPerfLogDeactivatePop(stageLog->stageInfo[stage].eventLog, event)); 1264 PetscFunctionReturn(PETSC_SUCCESS); 1265 } 1266 1267 /*@ 1268 PetscLogEventSetActiveAll - Turns on logging of all events 1269 1270 Not Collective 1271 1272 Input Parameters: 1273 + event - The event id 1274 - isActive - The activity flag determining whether the event is logged 1275 1276 Level: advanced 1277 1278 .seealso: [](ch_profiling), `PlogEventActivate()`, `PlogEventDeactivate()` 1279 @*/ 1280 PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive) 1281 { 1282 PetscStageLog stageLog; 1283 int stage; 1284 1285 PetscFunctionBegin; 1286 PetscCall(PetscLogGetStageLog(&stageLog)); 1287 for (stage = 0; stage < stageLog->numStages; stage++) { 1288 if (isActive) { 1289 PetscCall(PetscEventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event)); 1290 } else { 1291 PetscCall(PetscEventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event)); 1292 } 1293 } 1294 PetscFunctionReturn(PETSC_SUCCESS); 1295 } 1296 1297 /*@ 1298 PetscLogEventActivateClass - Activates event logging for a PETSc object class for the current stage 1299 1300 Not Collective 1301 1302 Input Parameter: 1303 . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc. 1304 1305 Level: developer 1306 1307 .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()` 1308 @*/ 1309 PetscErrorCode PetscLogEventActivateClass(PetscClassId classid) 1310 { 1311 PetscStageLog stageLog; 1312 int stage; 1313 1314 PetscFunctionBegin; 1315 PetscCall(PetscLogGetStageLog(&stageLog)); 1316 PetscCall(PetscStageLogGetCurrent(stageLog, &stage)); 1317 PetscCall(PetscEventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid)); 1318 PetscFunctionReturn(PETSC_SUCCESS); 1319 } 1320 1321 /*@ 1322 PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class for the current stage 1323 1324 Not Collective 1325 1326 Input Parameter: 1327 . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc. 1328 1329 Level: developer 1330 1331 .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventActivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()` 1332 @*/ 1333 PetscErrorCode PetscLogEventDeactivateClass(PetscClassId classid) 1334 { 1335 PetscStageLog stageLog; 1336 int stage; 1337 1338 PetscFunctionBegin; 1339 PetscCall(PetscLogGetStageLog(&stageLog)); 1340 PetscCall(PetscStageLogGetCurrent(stageLog, &stage)); 1341 PetscCall(PetscEventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid)); 1342 PetscFunctionReturn(PETSC_SUCCESS); 1343 } 1344 1345 /*MC 1346 PetscLogEventSync - Synchronizes the beginning of a user event. 1347 1348 Synopsis: 1349 #include <petsclog.h> 1350 PetscErrorCode PetscLogEventSync(int e, MPI_Comm comm) 1351 1352 Collective 1353 1354 Input Parameters: 1355 + e - integer associated with the event obtained from PetscLogEventRegister() 1356 - comm - an MPI communicator 1357 1358 Example Usage: 1359 .vb 1360 PetscLogEvent USER_EVENT; 1361 1362 PetscLogEventRegister("User event", 0, &USER_EVENT); 1363 PetscLogEventSync(USER_EVENT, PETSC_COMM_WORLD); 1364 PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0); 1365 [code segment to monitor] 1366 PetscLogEventEnd(USER_EVENT, 0, 0, 0 , 0); 1367 .ve 1368 1369 Level: developer 1370 1371 Note: 1372 This routine should be called only if there is not a `PetscObject` available to pass to 1373 `PetscLogEventBegin()`. 1374 1375 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()` 1376 M*/ 1377 1378 /*MC 1379 PetscLogEventBegin - Logs the beginning of a user event. 1380 1381 Synopsis: 1382 #include <petsclog.h> 1383 PetscErrorCode PetscLogEventBegin(int e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) 1384 1385 Not Collective 1386 1387 Input Parameters: 1388 + e - integer associated with the event obtained from PetscLogEventRegister() 1389 - o1,o2,o3,o4 - objects associated with the event, or 0 1390 1391 Fortran Synopsis: 1392 void PetscLogEventBegin(int e, PetscErrorCode ierr) 1393 1394 Example Usage: 1395 .vb 1396 PetscLogEvent USER_EVENT; 1397 1398 PetscLogDouble user_event_flops; 1399 PetscLogEventRegister("User event",0, &USER_EVENT); 1400 PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0); 1401 [code segment to monitor] 1402 PetscLogFlops(user_event_flops); 1403 PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0); 1404 .ve 1405 1406 Level: intermediate 1407 1408 Developer Note: 1409 `PetscLogEventBegin()` and `PetscLogEventBegin()` return error codes instead of explicitly 1410 handling the errors that occur in the macro directly because other packages that use this 1411 macros have used them in their own functions or methods that do not return error codes and it 1412 would be disruptive to change the current behavior. 1413 1414 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventEnd()`, `PetscLogFlops()` 1415 M*/ 1416 1417 /*MC 1418 PetscLogEventEnd - Log the end of a user event. 1419 1420 Synopsis: 1421 #include <petsclog.h> 1422 PetscErrorCode PetscLogEventEnd(int e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) 1423 1424 Not Collective 1425 1426 Input Parameters: 1427 + e - integer associated with the event obtained with PetscLogEventRegister() 1428 - o1,o2,o3,o4 - objects associated with the event, or 0 1429 1430 Fortran Synopsis: 1431 void PetscLogEventEnd(int e, PetscErrorCode ierr) 1432 1433 Example Usage: 1434 .vb 1435 PetscLogEvent USER_EVENT; 1436 1437 PetscLogDouble user_event_flops; 1438 PetscLogEventRegister("User event", 0, &USER_EVENT); 1439 PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0); 1440 [code segment to monitor] 1441 PetscLogFlops(user_event_flops); 1442 PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0); 1443 .ve 1444 1445 Level: intermediate 1446 1447 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogFlops()` 1448 M*/ 1449 1450 /*@C 1451 PetscLogEventGetId - Returns the event id when given the event name. 1452 1453 Not Collective 1454 1455 Input Parameter: 1456 . name - The event name 1457 1458 Output Parameter: 1459 . event - The event, or -1 if no event with that name exists 1460 1461 Level: intermediate 1462 1463 .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()` 1464 @*/ 1465 PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event) 1466 { 1467 PetscStageLog stageLog; 1468 1469 PetscFunctionBegin; 1470 PetscCall(PetscLogGetStageLog(&stageLog)); 1471 PetscCall(PetscEventRegLogGetEvent(stageLog->eventLog, name, event)); 1472 PetscFunctionReturn(PETSC_SUCCESS); 1473 } 1474 1475 /*@C 1476 PetscLogEventGetName - Returns the event name when given the event id. 1477 1478 Not Collective 1479 1480 Input Parameter: 1481 . event - The event 1482 1483 Output Parameter: 1484 . name - The event name 1485 1486 Level: intermediate 1487 1488 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()` 1489 @*/ 1490 PetscErrorCode PetscLogEventGetName(PetscLogEvent event, const char **name) 1491 { 1492 PetscLogEventInfo event_info; 1493 PetscLogState state; 1494 1495 PetscFunctionBegin; 1496 PetscCall(PetscLogGetState(&state)); 1497 PetscCall(PetscLogStateEventGetInfo(state, event, &event_info)); 1498 *name = event_info.name; 1499 PetscFunctionReturn(PETSC_SUCCESS); 1500 } 1501 1502 /*@ 1503 PetscLogEventsPause - Put event logging into "paused" mode: timers and counters for in-progress events are paused, and any events that happen before logging is resumed with `PetscLogEventsResume()` are logged in the "Main Stage" of execution. 1504 1505 Not collective 1506 1507 Level: advanced 1508 1509 Notes: 1510 When an external library or runtime has is initialized it can involve lots of setup time that skews the statistics of any unrelated running events: this function is intended to isolate such calls in the default log summary (`PetscLogDefaultBegin()`, `PetscLogView()`). 1511 1512 Other log handlers (such as the nested handler, `PetscLogNestedBegin()`) will ignore this function. 1513 1514 .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsResume()` 1515 @*/ 1516 PetscErrorCode PetscLogEventsPause(void) 1517 { 1518 PetscLogHandler handler; 1519 1520 PetscFunctionBegin; 1521 PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler)); 1522 if (handler) PetscCall(PetscLogHandlerDefaultEventsPause(handler)); 1523 PetscFunctionReturn(PETSC_SUCCESS); 1524 } 1525 1526 /*@ 1527 PetscLogEventsResume - Return logging to normal behavior after it was paused with `PetscLogEventsPause()`. 1528 1529 Not collective 1530 1531 Level: advanced 1532 1533 .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsPause()` 1534 @*/ 1535 PetscErrorCode PetscLogEventsResume(void) 1536 { 1537 PetscLogHandler handler; 1538 1539 PetscFunctionBegin; 1540 PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler)); 1541 if (handler) PetscCall(PetscLogHandlerDefaultEventsResume(handler)); 1542 PetscFunctionReturn(PETSC_SUCCESS); 1543 } 1544 1545 PetscErrorCode PetscLogPushCurrentEvent_Internal(PetscLogEvent event) 1546 { 1547 PetscFunctionBegin; 1548 if (!PetscDefined(HAVE_THREADSAFETY)) PetscCall(PetscIntStackPush(current_log_event_stack, event)); 1549 PetscFunctionReturn(PETSC_SUCCESS); 1550 } 1551 1552 PetscErrorCode PetscLogPopCurrentEvent_Internal(void) 1553 { 1554 PetscFunctionBegin; 1555 if (!PetscDefined(HAVE_THREADSAFETY)) PetscCall(PetscIntStackPop(current_log_event_stack, NULL)); 1556 PetscFunctionReturn(PETSC_SUCCESS); 1557 } 1558 1559 PetscErrorCode PetscLogGetCurrentEvent_Internal(PetscLogEvent *event) 1560 { 1561 PetscBool empty; 1562 1563 PetscFunctionBegin; 1564 PetscAssertPointer(event, 1); 1565 *event = PETSC_DECIDE; 1566 PetscCall(PetscIntStackEmpty(current_log_event_stack, &empty)); 1567 if (!empty) PetscCall(PetscIntStackTop(current_log_event_stack, event)); 1568 PetscFunctionReturn(PETSC_SUCCESS); 1569 } 1570 1571 PetscErrorCode PetscLogEventPause_Internal(PetscLogEvent event) 1572 { 1573 PetscFunctionBegin; 1574 if (event != PETSC_DECIDE) PetscCall(PetscLogEventEnd(event, NULL, NULL, NULL, NULL)); 1575 PetscFunctionReturn(PETSC_SUCCESS); 1576 } 1577 1578 PetscErrorCode PetscLogEventResume_Internal(PetscLogEvent event) 1579 { 1580 PetscStageLog stageLog; 1581 PetscEventPerfLog eventLog; 1582 int stage; 1583 1584 PetscFunctionBegin; 1585 if (event == PETSC_DECIDE) PetscFunctionReturn(PETSC_SUCCESS); 1586 PetscCall(PetscLogEventBegin(event, NULL, NULL, NULL, NULL)); 1587 PetscCall(PetscLogGetStageLog(&stageLog)); 1588 PetscCall(PetscStageLogGetCurrent(stageLog, &stage)); 1589 PetscCall(PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog)); 1590 eventLog->eventInfo[event].count--; 1591 PetscFunctionReturn(PETSC_SUCCESS); 1592 } 1593 1594 /*------------------------------------------------ Class Functions --------------------------------------------------*/ 1595 1596 /*MC 1597 PetscLogObjectCreate - Log the creation of a `PetscObject` 1598 1599 Synopsis: 1600 #include <petsclog.h> 1601 PetscErrorCode PetscLogObjectCreate(PetscObject h) 1602 1603 Not Collective 1604 1605 Input Parameters: 1606 . h - A `PetscObject` 1607 1608 Level: developer 1609 1610 Developer Note: 1611 Called internally by PETSc when creating objects: users do not need to call this directly. 1612 1613 .seealso: [](ch_profiling), `PetscLogObjectDestroy()` 1614 M*/ 1615 1616 /*MC 1617 PetscLogObjectDestroy - Logs the destruction of a `PetscObject` 1618 1619 Synopsis: 1620 #include <petsclog.h> 1621 PetscErrorCode PetscLogObjectDestroy(PetscObject h) 1622 1623 Not Collective 1624 1625 Input Parameters: 1626 . h - A `PetscObject` 1627 1628 Level: developer 1629 1630 Developer Note: 1631 Called internally by PETSc when destroying objects: users do not need to call this directly. 1632 1633 .seealso: [](ch_profiling), `PetscLogObjectCreate()` 1634 M*/ 1635 1636 /*@C 1637 PetscLogClassGetClassId - Returns the `PetscClassId` when given the class name. 1638 1639 Not Collective 1640 1641 Input Parameter: 1642 . name - The class name 1643 1644 Output Parameter: 1645 . classid - The `PetscClassId` id, or -1 if no class with that name exists 1646 1647 Level: intermediate 1648 1649 .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()` 1650 @*/ 1651 PetscErrorCode PetscLogClassGetClassId(const char name[], PetscClassId *classid) 1652 { 1653 PetscLogClass log_class; 1654 PetscLogClassInfo class_info; 1655 PetscLogState state; 1656 1657 PetscFunctionBegin; 1658 PetscCall(PetscLogGetState(&state)); 1659 PetscCall(PetscLogStateGetClassFromName(state, name, &log_class)); 1660 if (log_class < 0) { 1661 *classid = -1; 1662 PetscFunctionReturn(PETSC_SUCCESS); 1663 } 1664 PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info)); 1665 *classid = class_info.classid; 1666 PetscFunctionReturn(PETSC_SUCCESS); 1667 } 1668 1669 /*@C 1670 PetscLogClassIdGetName - Returns a `PetscClassId`'s name. 1671 1672 Not Collective 1673 1674 Input Parameter: 1675 . classid - A `PetscClassId` 1676 1677 Output Parameter: 1678 . name - The class name 1679 1680 Level: intermediate 1681 1682 .seealso: [](ch_profiling), `PetscLogClassRegister()`, `PetscLogClassBegin()`, `PetscLogClassEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadClass()` 1683 @*/ 1684 PetscErrorCode PetscLogClassIdGetName(PetscClassId classid, const char **name) 1685 { 1686 PetscLogClass log_class; 1687 PetscLogClassInfo class_info; 1688 PetscLogState state; 1689 1690 PetscFunctionBegin; 1691 PetscCall(PetscLogGetState(&state)); 1692 PetscCall(PetscLogStateGetClassFromClassId(state, classid, &log_class)); 1693 PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info)); 1694 *name = class_info.name; 1695 PetscFunctionReturn(PETSC_SUCCESS); 1696 } 1697 1698 /*------------------------------------------------ Output Functions -------------------------------------------------*/ 1699 /*@C 1700 PetscLogDump - Dumps logs of objects to a file. This file is intended to 1701 be read by bin/petscview. This program no longer exists. 1702 1703 Collective on `PETSC_COMM_WORLD` 1704 1705 Input Parameter: 1706 . sname - an optional file name 1707 1708 Example Usage: 1709 .vb 1710 PetscInitialize(...); 1711 PetscLogDefaultBegin(); or PetscLogAllBegin(); 1712 ... code ... 1713 PetscLogDump(filename); 1714 PetscFinalize(); 1715 .ve 1716 1717 Level: advanced 1718 1719 Note: 1720 The default file name is Log.<rank> where <rank> is the MPI process rank. If no name is specified, 1721 this file will be used. 1722 1723 .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogAllBegin()`, `PetscLogView()` 1724 @*/ 1725 PetscErrorCode PetscLogDump(const char sname[]) 1726 { 1727 PetscStageLog stageLog; 1728 PetscEventPerfInfo *eventInfo; 1729 FILE *fd; 1730 char file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN]; 1731 PetscLogDouble flops, _TotalTime; 1732 PetscMPIInt rank; 1733 int action, object, curStage; 1734 PetscLogEvent event; 1735 1736 PetscFunctionBegin; 1737 /* Calculate the total elapsed time */ 1738 PetscCall(PetscTime(&_TotalTime)); 1739 _TotalTime -= petsc_BaseTime; 1740 /* Open log file */ 1741 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 1742 PetscCall(PetscSNPrintf(file, PETSC_STATIC_ARRAY_LENGTH(file), "%s.%d", sname && sname[0] ? sname : "Log", rank)); 1743 PetscCall(PetscFixFilename(file, fname)); 1744 PetscCall(PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd)); 1745 PetscCheck(!(rank == 0) || !(!fd), PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname); 1746 /* Output totals */ 1747 PetscCall(PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flop %14e %16.8e\n", petsc_TotalFlops, _TotalTime)); 1748 PetscCall(PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0)); 1749 /* Output actions */ 1750 if (petsc_logActions) { 1751 PetscCall(PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", petsc_numActions)); 1752 for (action = 0; action < petsc_numActions; action++) { 1753 PetscCall(PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n", petsc_actions[action].time, petsc_actions[action].action, (int)petsc_actions[action].event, (int)petsc_actions[action].classid, petsc_actions[action].id1, 1754 petsc_actions[action].id2, petsc_actions[action].id3, petsc_actions[action].flops, petsc_actions[action].mem, petsc_actions[action].maxmem)); 1755 } 1756 } 1757 /* Output objects */ 1758 if (petsc_logObjects) { 1759 PetscCall(PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", petsc_numObjects, petsc_numObjectsDestroyed)); 1760 for (object = 0; object < petsc_numObjects; object++) { 1761 PetscCall(PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", petsc_objects[object].parent, (int)petsc_objects[object].mem)); 1762 if (!petsc_objects[object].name[0]) { 1763 PetscCall(PetscFPrintf(PETSC_COMM_WORLD, fd, "No Name\n")); 1764 } else { 1765 PetscCall(PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", petsc_objects[object].name)); 1766 } 1767 if (petsc_objects[object].info[0] != 0) { 1768 PetscCall(PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n")); 1769 } else { 1770 PetscCall(PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", petsc_objects[object].info)); 1771 } 1772 } 1773 } 1774 /* Output events */ 1775 PetscCall(PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:\n")); 1776 PetscCall(PetscLogGetStageLog(&stageLog)); 1777 PetscCall(PetscIntStackTop(stageLog->stack, &curStage)); 1778 eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo; 1779 for (event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) { 1780 if (eventInfo[event].time != 0.0) flops = eventInfo[event].flops / eventInfo[event].time; 1781 else flops = 0.0; 1782 PetscCall(PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16g\n", event, eventInfo[event].count, eventInfo[event].flops, eventInfo[event].time, flops)); 1783 } 1784 PetscCall(PetscFClose(PETSC_COMM_WORLD, fd)); 1785 PetscFunctionReturn(PETSC_SUCCESS); 1786 } 1787 1788 /* 1789 PetscLogView_Detailed - Each process prints the times for its own events 1790 1791 */ 1792 static PetscErrorCode PetscLogView_Detailed(PetscViewer viewer) 1793 { 1794 PetscStageLog stageLog; 1795 PetscEventPerfInfo *eventInfo = NULL, *stageInfo = NULL; 1796 PetscLogDouble locTotalTime, numRed, maxMem; 1797 int numStages, numEvents, stage, event; 1798 MPI_Comm comm = PetscObjectComm((PetscObject)viewer); 1799 PetscMPIInt rank, size; 1800 1801 PetscFunctionBegin; 1802 PetscCallMPI(MPI_Comm_size(comm, &size)); 1803 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1804 /* Must preserve reduction count before we go on */ 1805 numRed = petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct; 1806 /* Get the total elapsed time */ 1807 PetscCall(PetscTime(&locTotalTime)); 1808 locTotalTime -= petsc_BaseTime; 1809 PetscCall(PetscViewerASCIIPrintf(viewer, "size = %d\n", size)); 1810 PetscCall(PetscViewerASCIIPrintf(viewer, "LocalTimes = {}\n")); 1811 PetscCall(PetscViewerASCIIPrintf(viewer, "LocalMessages = {}\n")); 1812 PetscCall(PetscViewerASCIIPrintf(viewer, "LocalMessageLens = {}\n")); 1813 PetscCall(PetscViewerASCIIPrintf(viewer, "LocalReductions = {}\n")); 1814 PetscCall(PetscViewerASCIIPrintf(viewer, "LocalFlop = {}\n")); 1815 PetscCall(PetscViewerASCIIPrintf(viewer, "LocalObjects = {}\n")); 1816 PetscCall(PetscViewerASCIIPrintf(viewer, "LocalMemory = {}\n")); 1817 PetscCall(PetscLogGetStageLog(&stageLog)); 1818 PetscCallMPI(MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm)); 1819 PetscCall(PetscViewerASCIIPrintf(viewer, "Stages = {}\n")); 1820 for (stage = 0; stage < numStages; stage++) { 1821 PetscCall(PetscViewerASCIIPrintf(viewer, "Stages[\"%s\"] = {}\n", stageLog->stageInfo[stage].name)); 1822 PetscCall(PetscViewerASCIIPrintf(viewer, "Stages[\"%s\"][\"summary\"] = {}\n", stageLog->stageInfo[stage].name)); 1823 PetscCallMPI(MPI_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm)); 1824 for (event = 0; event < numEvents; event++) PetscCall(PetscViewerASCIIPrintf(viewer, "Stages[\"%s\"][\"%s\"] = {}\n", stageLog->stageInfo[stage].name, stageLog->eventLog->eventInfo[event].name)); 1825 } 1826 PetscCall(PetscMallocGetMaximumUsage(&maxMem)); 1827 PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 1828 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "LocalTimes[%d] = %g\n", rank, locTotalTime)); 1829 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "LocalMessages[%d] = %g\n", rank, (petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct))); 1830 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "LocalMessageLens[%d] = %g\n", rank, (petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len))); 1831 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "LocalReductions[%d] = %g\n", rank, numRed)); 1832 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "LocalFlop[%d] = %g\n", rank, petsc_TotalFlops)); 1833 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "LocalObjects[%d] = %d\n", rank, petsc_numObjects)); 1834 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "LocalMemory[%d] = %g\n", rank, maxMem)); 1835 PetscCall(PetscViewerFlush(viewer)); 1836 for (stage = 0; stage < numStages; stage++) { 1837 stageInfo = &stageLog->stageInfo[stage].perfInfo; 1838 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "Stages[\"%s\"][\"summary\"][%d] = {\"time\" : %g, \"numMessages\" : %g, \"messageLength\" : %g, \"numReductions\" : %g, \"flop\" : %g}\n", stageLog->stageInfo[stage].name, rank, stageInfo->time, 1839 stageInfo->numMessages, stageInfo->messageLength, stageInfo->numReductions, stageInfo->flops)); 1840 PetscCallMPI(MPI_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm)); 1841 for (event = 0; event < numEvents; event++) { 1842 eventInfo = &stageLog->stageInfo[stage].eventLog->eventInfo[event]; 1843 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "Stages[\"%s\"][\"%s\"][%d] = {\"count\" : %d, \"time\" : %g, \"syncTime\" : %g, \"numMessages\" : %g, \"messageLength\" : %g, \"numReductions\" : %g, \"flop\" : %g", 1844 stageLog->stageInfo[stage].name, stageLog->eventLog->eventInfo[event].name, rank, eventInfo->count, eventInfo->time, eventInfo->syncTime, eventInfo->numMessages, eventInfo->messageLength, eventInfo->numReductions, 1845 eventInfo->flops)); 1846 if (eventInfo->dof[0] >= 0.) { 1847 PetscInt d, e; 1848 1849 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, ", \"dof\" : [")); 1850 for (d = 0; d < 8; ++d) { 1851 if (d > 0) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, ", ")); 1852 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%g", eventInfo->dof[d])); 1853 } 1854 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "]")); 1855 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, ", \"error\" : [")); 1856 for (e = 0; e < 8; ++e) { 1857 if (e > 0) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, ", ")); 1858 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%g", eventInfo->errors[e])); 1859 } 1860 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "]")); 1861 } 1862 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "}\n")); 1863 } 1864 } 1865 PetscCall(PetscViewerFlush(viewer)); 1866 PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 1867 PetscFunctionReturn(PETSC_SUCCESS); 1868 } 1869 1870 /* 1871 PetscLogView_CSV - Each process prints the times for its own events in Comma-Separated Value Format 1872 */ 1873 static PetscErrorCode PetscLogView_CSV(PetscViewer viewer) 1874 { 1875 PetscStageLog stageLog; 1876 PetscEventPerfInfo *eventInfo = NULL; 1877 PetscLogDouble locTotalTime, maxMem; 1878 int numStages, numEvents, stage, event; 1879 MPI_Comm comm = PetscObjectComm((PetscObject)viewer); 1880 PetscMPIInt rank, size; 1881 1882 PetscFunctionBegin; 1883 PetscCallMPI(MPI_Comm_size(comm, &size)); 1884 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1885 /* Must preserve reduction count before we go on */ 1886 /* Get the total elapsed time */ 1887 PetscCall(PetscTime(&locTotalTime)); 1888 locTotalTime -= petsc_BaseTime; 1889 PetscCall(PetscLogGetStageLog(&stageLog)); 1890 PetscCallMPI(MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm)); 1891 PetscCall(PetscMallocGetMaximumUsage(&maxMem)); 1892 PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 1893 PetscCall(PetscViewerASCIIPrintf(viewer, "Stage Name,Event Name,Rank,Count,Time,Num Messages,Message Length,Num Reductions,FLOP,dof0,dof1,dof2,dof3,dof4,dof5,dof6,dof7,e0,e1,e2,e3,e4,e5,e6,e7,%d\n", size)); 1894 PetscCall(PetscViewerFlush(viewer)); 1895 for (stage = 0; stage < numStages; stage++) { 1896 PetscEventPerfInfo *stageInfo = &stageLog->stageInfo[stage].perfInfo; 1897 1898 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%s,summary,%d,1,%g,%g,%g,%g,%g\n", stageLog->stageInfo[stage].name, rank, stageInfo->time, stageInfo->numMessages, stageInfo->messageLength, stageInfo->numReductions, stageInfo->flops)); 1899 PetscCallMPI(MPI_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm)); 1900 for (event = 0; event < numEvents; event++) { 1901 eventInfo = &stageLog->stageInfo[stage].eventLog->eventInfo[event]; 1902 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%s,%s,%d,%d,%g,%g,%g,%g,%g", stageLog->stageInfo[stage].name, stageLog->eventLog->eventInfo[event].name, rank, eventInfo->count, eventInfo->time, eventInfo->numMessages, eventInfo->messageLength, 1903 eventInfo->numReductions, eventInfo->flops)); 1904 if (eventInfo->dof[0] >= 0.) { 1905 PetscInt d, e; 1906 1907 for (d = 0; d < 8; ++d) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, ",%g", eventInfo->dof[d])); 1908 for (e = 0; e < 8; ++e) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, ",%g", eventInfo->errors[e])); 1909 } 1910 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n")); 1911 } 1912 } 1913 PetscCall(PetscViewerFlush(viewer)); 1914 PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 1915 PetscFunctionReturn(PETSC_SUCCESS); 1916 } 1917 1918 static PetscErrorCode PetscLogViewWarnSync(MPI_Comm comm, FILE *fd) 1919 { 1920 PetscFunctionBegin; 1921 if (!PetscLogSyncOn) PetscFunctionReturn(PETSC_SUCCESS); 1922 PetscCall(PetscFPrintf(comm, fd, "\n\n")); 1923 PetscCall(PetscFPrintf(comm, fd, " ##########################################################\n")); 1924 PetscCall(PetscFPrintf(comm, fd, " # #\n")); 1925 PetscCall(PetscFPrintf(comm, fd, " # WARNING!!! #\n")); 1926 PetscCall(PetscFPrintf(comm, fd, " # #\n")); 1927 PetscCall(PetscFPrintf(comm, fd, " # This program was run with logging synchronization. #\n")); 1928 PetscCall(PetscFPrintf(comm, fd, " # This option provides more meaningful imbalance #\n")); 1929 PetscCall(PetscFPrintf(comm, fd, " # figures at the expense of slowing things down and #\n")); 1930 PetscCall(PetscFPrintf(comm, fd, " # providing a distorted view of the overall runtime. #\n")); 1931 PetscCall(PetscFPrintf(comm, fd, " # #\n")); 1932 PetscCall(PetscFPrintf(comm, fd, " ##########################################################\n\n\n")); 1933 PetscFunctionReturn(PETSC_SUCCESS); 1934 } 1935 1936 static PetscErrorCode PetscLogViewWarnDebugging(MPI_Comm comm, FILE *fd) 1937 { 1938 PetscFunctionBegin; 1939 if (PetscDefined(USE_DEBUG)) { 1940 PetscCall(PetscFPrintf(comm, fd, "\n\n")); 1941 PetscCall(PetscFPrintf(comm, fd, " ##########################################################\n")); 1942 PetscCall(PetscFPrintf(comm, fd, " # #\n")); 1943 PetscCall(PetscFPrintf(comm, fd, " # WARNING!!! #\n")); 1944 PetscCall(PetscFPrintf(comm, fd, " # #\n")); 1945 PetscCall(PetscFPrintf(comm, fd, " # This code was compiled with a debugging option. #\n")); 1946 PetscCall(PetscFPrintf(comm, fd, " # To get timing results run ./configure #\n")); 1947 PetscCall(PetscFPrintf(comm, fd, " # using --with-debugging=no, the performance will #\n")); 1948 PetscCall(PetscFPrintf(comm, fd, " # be generally two or three times faster. #\n")); 1949 PetscCall(PetscFPrintf(comm, fd, " # #\n")); 1950 PetscCall(PetscFPrintf(comm, fd, " ##########################################################\n\n\n")); 1951 } 1952 PetscFunctionReturn(PETSC_SUCCESS); 1953 } 1954 1955 static PetscErrorCode PetscLogViewWarnNoGpuAwareMpi(MPI_Comm comm, FILE *fd) 1956 { 1957 #if defined(PETSC_HAVE_DEVICE) 1958 PetscMPIInt size; 1959 PetscBool deviceInitialized = PETSC_FALSE; 1960 1961 PetscFunctionBegin; 1962 PetscCallMPI(MPI_Comm_size(comm, &size)); 1963 for (int i = PETSC_DEVICE_HOST + 1; i < PETSC_DEVICE_MAX; ++i) { 1964 const PetscDeviceType dtype = PetscDeviceTypeCast(i); 1965 if (PetscDeviceInitialized(dtype)) { /* a non-host device was initialized */ 1966 deviceInitialized = PETSC_TRUE; 1967 break; 1968 } 1969 } 1970 /* the last condition says petsc is configured with device but it is a pure CPU run, so don't print misleading warnings */ 1971 if (use_gpu_aware_mpi || size == 1 || !deviceInitialized) PetscFunctionReturn(PETSC_SUCCESS); 1972 PetscCall(PetscFPrintf(comm, fd, "\n\n")); 1973 PetscCall(PetscFPrintf(comm, fd, " ##########################################################\n")); 1974 PetscCall(PetscFPrintf(comm, fd, " # #\n")); 1975 PetscCall(PetscFPrintf(comm, fd, " # WARNING!!! #\n")); 1976 PetscCall(PetscFPrintf(comm, fd, " # #\n")); 1977 PetscCall(PetscFPrintf(comm, fd, " # This code was compiled with GPU support and you've #\n")); 1978 PetscCall(PetscFPrintf(comm, fd, " # created PETSc/GPU objects, but you intentionally #\n")); 1979 PetscCall(PetscFPrintf(comm, fd, " # used -use_gpu_aware_mpi 0, requiring PETSc to copy #\n")); 1980 PetscCall(PetscFPrintf(comm, fd, " # additional data between the GPU and CPU. To obtain #\n")); 1981 PetscCall(PetscFPrintf(comm, fd, " # meaningful timing results on multi-rank runs, use #\n")); 1982 PetscCall(PetscFPrintf(comm, fd, " # GPU-aware MPI instead. #\n")); 1983 PetscCall(PetscFPrintf(comm, fd, " # #\n")); 1984 PetscCall(PetscFPrintf(comm, fd, " ##########################################################\n\n\n")); 1985 PetscFunctionReturn(PETSC_SUCCESS); 1986 #else 1987 (void)comm; 1988 (void)fd; 1989 return PETSC_SUCCESS; 1990 #endif 1991 } 1992 1993 static PetscErrorCode PetscLogViewWarnGpuTime(MPI_Comm comm, FILE *fd) 1994 { 1995 #if defined(PETSC_HAVE_DEVICE) 1996 1997 PetscFunctionBegin; 1998 if (!PetscLogGpuTimeFlag || petsc_gflops == 0) PetscFunctionReturn(PETSC_SUCCESS); 1999 PetscCall(PetscFPrintf(comm, fd, "\n\n")); 2000 PetscCall(PetscFPrintf(comm, fd, " ##########################################################\n")); 2001 PetscCall(PetscFPrintf(comm, fd, " # #\n")); 2002 PetscCall(PetscFPrintf(comm, fd, " # WARNING!!! #\n")); 2003 PetscCall(PetscFPrintf(comm, fd, " # #\n")); 2004 PetscCall(PetscFPrintf(comm, fd, " # This code was run with -log_view_gpu_time #\n")); 2005 PetscCall(PetscFPrintf(comm, fd, " # This provides accurate timing within the GPU kernels #\n")); 2006 PetscCall(PetscFPrintf(comm, fd, " # but can slow down the entire computation by a #\n")); 2007 PetscCall(PetscFPrintf(comm, fd, " # measurable amount. For fastest runs we recommend #\n")); 2008 PetscCall(PetscFPrintf(comm, fd, " # not using this option. #\n")); 2009 PetscCall(PetscFPrintf(comm, fd, " # #\n")); 2010 PetscCall(PetscFPrintf(comm, fd, " ##########################################################\n\n\n")); 2011 PetscFunctionReturn(PETSC_SUCCESS); 2012 #else 2013 (void)comm; 2014 (void)fd; 2015 return PETSC_SUCCESS; 2016 #endif 2017 } 2018 2019 static PetscErrorCode PetscLogView_Default(PetscViewer viewer) 2020 { 2021 FILE *fd; 2022 PetscLogDouble zero = 0.0; 2023 PetscStageLog stageLog; 2024 PetscStageInfo *stageInfo = NULL; 2025 PetscEventPerfInfo *eventInfo = NULL; 2026 PetscClassPerfInfo *classInfo; 2027 char arch[128], hostname[128], username[128], pname[PETSC_MAX_PATH_LEN], date[128]; 2028 const char *name; 2029 PetscLogDouble locTotalTime, TotalTime, TotalFlops; 2030 PetscLogDouble numMessages, messageLength, avgMessLen, numReductions; 2031 PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red; 2032 PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed; 2033 PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed; 2034 PetscLogDouble min, max, tot, ratio, avg, x, y; 2035 PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratC, totm, totml, totr, mal, malmax, emalmax; 2036 #if defined(PETSC_HAVE_DEVICE) 2037 PetscLogEvent KSP_Solve, SNES_Solve, TS_Step, TAO_Solve; /* These need to be fixed to be some events registered with certain objects */ 2038 PetscLogDouble cct, gct, csz, gsz, gmaxt, gflops, gflopr, fracgflops; 2039 #endif 2040 PetscMPIInt minC, maxC; 2041 PetscMPIInt size, rank; 2042 PetscBool *localStageUsed, *stageUsed; 2043 PetscBool *localStageVisible, *stageVisible; 2044 int numStages, localNumEvents, numEvents; 2045 int stage, oclass; 2046 PetscLogEvent event; 2047 char version[256]; 2048 MPI_Comm comm; 2049 #if defined(PETSC_HAVE_DEVICE) 2050 PetscLogEvent eventid; 2051 PetscInt64 nas = 0x7FF0000000000002; 2052 #endif 2053 2054 PetscFunctionBegin; 2055 PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 2056 PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm)); 2057 PetscCall(PetscViewerASCIIGetPointer(viewer, &fd)); 2058 PetscCallMPI(MPI_Comm_size(comm, &size)); 2059 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 2060 /* Get the total elapsed time */ 2061 PetscCall(PetscTime(&locTotalTime)); 2062 locTotalTime -= petsc_BaseTime; 2063 2064 PetscCall(PetscFPrintf(comm, fd, "****************************************************************************************************************************************************************\n")); 2065 PetscCall(PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 160 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***\n")); 2066 PetscCall(PetscFPrintf(comm, fd, "****************************************************************************************************************************************************************\n")); 2067 PetscCall(PetscFPrintf(comm, fd, "\n------------------------------------------------------------------ PETSc Performance Summary: ------------------------------------------------------------------\n\n")); 2068 PetscCall(PetscLogViewWarnSync(comm, fd)); 2069 PetscCall(PetscLogViewWarnDebugging(comm, fd)); 2070 PetscCall(PetscLogViewWarnNoGpuAwareMpi(comm, fd)); 2071 PetscCall(PetscLogViewWarnGpuTime(comm, fd)); 2072 PetscCall(PetscGetArchType(arch, sizeof(arch))); 2073 PetscCall(PetscGetHostName(hostname, sizeof(hostname))); 2074 PetscCall(PetscGetUserName(username, sizeof(username))); 2075 PetscCall(PetscGetProgramName(pname, sizeof(pname))); 2076 PetscCall(PetscGetDate(date, sizeof(date))); 2077 PetscCall(PetscGetVersion(version, sizeof(version))); 2078 if (size == 1) { 2079 PetscCall(PetscFPrintf(comm, fd, "%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date)); 2080 } else { 2081 PetscCall(PetscFPrintf(comm, fd, "%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date)); 2082 } 2083 #if defined(PETSC_HAVE_OPENMP) 2084 PetscCall(PetscFPrintf(comm, fd, "Using %" PetscInt_FMT " OpenMP threads\n", PetscNumOMPThreads)); 2085 #endif 2086 PetscCall(PetscFPrintf(comm, fd, "Using %s\n", version)); 2087 2088 /* Must preserve reduction count before we go on */ 2089 red = petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct; 2090 2091 /* Calculate summary information */ 2092 PetscCall(PetscFPrintf(comm, fd, "\n Max Max/Min Avg Total\n")); 2093 /* Time */ 2094 PetscCall(MPIU_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm)); 2095 PetscCall(MPIU_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm)); 2096 PetscCall(MPIU_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2097 avg = tot / ((PetscLogDouble)size); 2098 if (min != 0.0) ratio = max / min; 2099 else ratio = 0.0; 2100 PetscCall(PetscFPrintf(comm, fd, "Time (sec): %5.3e %7.3f %5.3e\n", max, ratio, avg)); 2101 TotalTime = tot; 2102 /* Objects */ 2103 avg = (PetscLogDouble)petsc_numObjects; 2104 PetscCall(MPIU_Allreduce(&avg, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm)); 2105 PetscCall(MPIU_Allreduce(&avg, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm)); 2106 PetscCall(MPIU_Allreduce(&avg, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2107 avg = tot / ((PetscLogDouble)size); 2108 if (min != 0.0) ratio = max / min; 2109 else ratio = 0.0; 2110 PetscCall(PetscFPrintf(comm, fd, "Objects: %5.3e %7.3f %5.3e\n", max, ratio, avg)); 2111 /* Flops */ 2112 PetscCall(MPIU_Allreduce(&petsc_TotalFlops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm)); 2113 PetscCall(MPIU_Allreduce(&petsc_TotalFlops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm)); 2114 PetscCall(MPIU_Allreduce(&petsc_TotalFlops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2115 avg = tot / ((PetscLogDouble)size); 2116 if (min != 0.0) ratio = max / min; 2117 else ratio = 0.0; 2118 PetscCall(PetscFPrintf(comm, fd, "Flops: %5.3e %7.3f %5.3e %5.3e\n", max, ratio, avg, tot)); 2119 TotalFlops = tot; 2120 /* Flops/sec -- Must talk to Barry here */ 2121 if (locTotalTime != 0.0) flops = petsc_TotalFlops / locTotalTime; 2122 else flops = 0.0; 2123 PetscCall(MPIU_Allreduce(&flops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm)); 2124 PetscCall(MPIU_Allreduce(&flops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm)); 2125 PetscCall(MPIU_Allreduce(&flops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2126 avg = tot / ((PetscLogDouble)size); 2127 if (min != 0.0) ratio = max / min; 2128 else ratio = 0.0; 2129 PetscCall(PetscFPrintf(comm, fd, "Flops/sec: %5.3e %7.3f %5.3e %5.3e\n", max, ratio, avg, tot)); 2130 /* Memory */ 2131 PetscCall(PetscMallocGetMaximumUsage(&mem)); 2132 if (mem > 0.0) { 2133 PetscCall(MPIU_Allreduce(&mem, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm)); 2134 PetscCall(MPIU_Allreduce(&mem, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm)); 2135 PetscCall(MPIU_Allreduce(&mem, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2136 avg = tot / ((PetscLogDouble)size); 2137 if (min != 0.0) ratio = max / min; 2138 else ratio = 0.0; 2139 PetscCall(PetscFPrintf(comm, fd, "Memory (bytes): %5.3e %7.3f %5.3e %5.3e\n", max, ratio, avg, tot)); 2140 } 2141 /* Messages */ 2142 mess = 0.5 * (petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct); 2143 PetscCall(MPIU_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm)); 2144 PetscCall(MPIU_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm)); 2145 PetscCall(MPIU_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2146 avg = tot / ((PetscLogDouble)size); 2147 if (min != 0.0) ratio = max / min; 2148 else ratio = 0.0; 2149 PetscCall(PetscFPrintf(comm, fd, "MPI Msg Count: %5.3e %7.3f %5.3e %5.3e\n", max, ratio, avg, tot)); 2150 numMessages = tot; 2151 /* Message Lengths */ 2152 mess = 0.5 * (petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len); 2153 PetscCall(MPIU_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm)); 2154 PetscCall(MPIU_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm)); 2155 PetscCall(MPIU_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2156 if (numMessages != 0) avg = tot / numMessages; 2157 else avg = 0.0; 2158 if (min != 0.0) ratio = max / min; 2159 else ratio = 0.0; 2160 PetscCall(PetscFPrintf(comm, fd, "MPI Msg Len (bytes): %5.3e %7.3f %5.3e %5.3e\n", max, ratio, avg, tot)); 2161 messageLength = tot; 2162 /* Reductions */ 2163 PetscCall(MPIU_Allreduce(&red, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm)); 2164 PetscCall(MPIU_Allreduce(&red, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm)); 2165 PetscCall(MPIU_Allreduce(&red, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2166 if (min != 0.0) ratio = max / min; 2167 else ratio = 0.0; 2168 PetscCall(PetscFPrintf(comm, fd, "MPI Reductions: %5.3e %7.3f\n", max, ratio)); 2169 numReductions = red; /* wrong because uses count from process zero */ 2170 PetscCall(PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n")); 2171 PetscCall(PetscFPrintf(comm, fd, " e.g., VecAXPY() for real vectors of length N --> 2N flops\n")); 2172 PetscCall(PetscFPrintf(comm, fd, " and VecAXPY() for complex vectors of length N --> 8N flops\n")); 2173 2174 /* Get total number of stages -- 2175 Currently, a single processor can register more stages than another, but stages must all be registered in order. 2176 We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID. 2177 This seems best accomplished by assoicating a communicator with each stage. 2178 */ 2179 PetscCall(PetscLogGetStageLog(&stageLog)); 2180 PetscCallMPI(MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm)); 2181 PetscCall(PetscMalloc1(numStages, &localStageUsed)); 2182 PetscCall(PetscMalloc1(numStages, &stageUsed)); 2183 PetscCall(PetscMalloc1(numStages, &localStageVisible)); 2184 PetscCall(PetscMalloc1(numStages, &stageVisible)); 2185 if (numStages > 0) { 2186 stageInfo = stageLog->stageInfo; 2187 for (stage = 0; stage < numStages; stage++) { 2188 if (stage < stageLog->numStages) { 2189 localStageUsed[stage] = stageInfo[stage].used; 2190 localStageVisible[stage] = stageInfo[stage].perfInfo.visible; 2191 } else { 2192 localStageUsed[stage] = PETSC_FALSE; 2193 localStageVisible[stage] = PETSC_TRUE; 2194 } 2195 } 2196 PetscCall(MPIU_Allreduce(localStageUsed, stageUsed, numStages, MPIU_BOOL, MPI_LOR, comm)); 2197 PetscCall(MPIU_Allreduce(localStageVisible, stageVisible, numStages, MPIU_BOOL, MPI_LAND, comm)); 2198 for (stage = 0; stage < numStages; stage++) { 2199 if (stageUsed[stage]) { 2200 PetscCall(PetscFPrintf(comm, fd, "\nSummary of Stages: ----- Time ------ ----- Flop ------ --- Messages --- -- Message Lengths -- -- Reductions --\n")); 2201 PetscCall(PetscFPrintf(comm, fd, " Avg %%Total Avg %%Total Count %%Total Avg %%Total Count %%Total\n")); 2202 break; 2203 } 2204 } 2205 for (stage = 0; stage < numStages; stage++) { 2206 if (!stageUsed[stage]) continue; 2207 /* CANNOT use MPI_Allreduce() since it might fail the line number check */ 2208 if (localStageUsed[stage]) { 2209 PetscCall(MPIU_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2210 PetscCall(MPIU_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2211 PetscCall(MPIU_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2212 PetscCall(MPIU_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2213 PetscCall(MPIU_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2214 name = stageInfo[stage].name; 2215 } else { 2216 PetscCall(MPIU_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2217 PetscCall(MPIU_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2218 PetscCall(MPIU_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2219 PetscCall(MPIU_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2220 PetscCall(MPIU_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2221 name = ""; 2222 } 2223 mess *= 0.5; 2224 messLen *= 0.5; 2225 red /= size; 2226 if (TotalTime != 0.0) fracTime = stageTime / TotalTime; 2227 else fracTime = 0.0; 2228 if (TotalFlops != 0.0) fracFlops = flops / TotalFlops; 2229 else fracFlops = 0.0; 2230 /* Talk to Barry if (stageTime != 0.0) flops = (size*flops)/stageTime; else flops = 0.0; */ 2231 if (numMessages != 0.0) fracMessages = mess / numMessages; 2232 else fracMessages = 0.0; 2233 if (mess != 0.0) avgMessLen = messLen / mess; 2234 else avgMessLen = 0.0; 2235 if (messageLength != 0.0) fracLength = messLen / messageLength; 2236 else fracLength = 0.0; 2237 if (numReductions != 0.0) fracReductions = red / numReductions; 2238 else fracReductions = 0.0; 2239 PetscCall(PetscFPrintf(comm, fd, "%2d: %15s: %6.4e %5.1f%% %6.4e %5.1f%% %5.3e %5.1f%% %5.3e %5.1f%% %5.3e %5.1f%%\n", stage, name, stageTime / size, 100.0 * fracTime, flops, 100.0 * fracFlops, mess, 100.0 * fracMessages, avgMessLen, 100.0 * fracLength, red, 100.0 * fracReductions)); 2240 } 2241 } 2242 2243 PetscCall(PetscFPrintf(comm, fd, "\n------------------------------------------------------------------------------------------------------------------------\n")); 2244 PetscCall(PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n")); 2245 PetscCall(PetscFPrintf(comm, fd, "Phase summary info:\n")); 2246 PetscCall(PetscFPrintf(comm, fd, " Count: number of times phase was executed\n")); 2247 PetscCall(PetscFPrintf(comm, fd, " Time and Flop: Max - maximum over all processors\n")); 2248 PetscCall(PetscFPrintf(comm, fd, " Ratio - ratio of maximum to minimum over all processors\n")); 2249 PetscCall(PetscFPrintf(comm, fd, " Mess: number of messages sent\n")); 2250 PetscCall(PetscFPrintf(comm, fd, " AvgLen: average message length (bytes)\n")); 2251 PetscCall(PetscFPrintf(comm, fd, " Reduct: number of global reductions\n")); 2252 PetscCall(PetscFPrintf(comm, fd, " Global: entire computation\n")); 2253 PetscCall(PetscFPrintf(comm, fd, " Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n")); 2254 PetscCall(PetscFPrintf(comm, fd, " %%T - percent time in this phase %%F - percent flop in this phase\n")); 2255 PetscCall(PetscFPrintf(comm, fd, " %%M - percent messages in this phase %%L - percent message lengths in this phase\n")); 2256 PetscCall(PetscFPrintf(comm, fd, " %%R - percent reductions in this phase\n")); 2257 PetscCall(PetscFPrintf(comm, fd, " Total Mflop/s: 10e-6 * (sum of flop over all processors)/(max time over all processors)\n")); 2258 if (PetscLogMemory) { 2259 PetscCall(PetscFPrintf(comm, fd, " Memory usage is summed over all MPI processes, it is given in mega-bytes\n")); 2260 PetscCall(PetscFPrintf(comm, fd, " Malloc Mbytes: Memory allocated and kept during event (sum over all calls to event). May be negative\n")); 2261 PetscCall(PetscFPrintf(comm, fd, " EMalloc Mbytes: extra memory allocated during event and then freed (maximum over all calls to events). Never negative\n")); 2262 PetscCall(PetscFPrintf(comm, fd, " MMalloc Mbytes: Increase in high water mark of allocated memory (sum over all calls to event). Never negative\n")); 2263 PetscCall(PetscFPrintf(comm, fd, " RMI Mbytes: Increase in resident memory (sum over all calls to event)\n")); 2264 } 2265 #if defined(PETSC_HAVE_DEVICE) 2266 PetscCall(PetscFPrintf(comm, fd, " GPU Mflop/s: 10e-6 * (sum of flop on GPU over all processors)/(max GPU time over all processors)\n")); 2267 PetscCall(PetscFPrintf(comm, fd, " CpuToGpu Count: total number of CPU to GPU copies per processor\n")); 2268 PetscCall(PetscFPrintf(comm, fd, " CpuToGpu Size (Mbytes): 10e-6 * (total size of CPU to GPU copies per processor)\n")); 2269 PetscCall(PetscFPrintf(comm, fd, " GpuToCpu Count: total number of GPU to CPU copies per processor\n")); 2270 PetscCall(PetscFPrintf(comm, fd, " GpuToCpu Size (Mbytes): 10e-6 * (total size of GPU to CPU copies per processor)\n")); 2271 PetscCall(PetscFPrintf(comm, fd, " GPU %%F: percent flops on GPU in this event\n")); 2272 #endif 2273 PetscCall(PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------\n")); 2274 2275 PetscCall(PetscLogViewWarnDebugging(comm, fd)); 2276 2277 /* Report events */ 2278 PetscCall(PetscFPrintf(comm, fd, "Event Count Time (sec) Flop --- Global --- --- Stage ---- Total")); 2279 if (PetscLogMemory) PetscCall(PetscFPrintf(comm, fd, " Malloc EMalloc MMalloc RMI")); 2280 #if defined(PETSC_HAVE_DEVICE) 2281 PetscCall(PetscFPrintf(comm, fd, " GPU - CpuToGpu - - GpuToCpu - GPU")); 2282 #endif 2283 PetscCall(PetscFPrintf(comm, fd, "\n")); 2284 PetscCall(PetscFPrintf(comm, fd, " Max Ratio Max Ratio Max Ratio Mess AvgLen Reduct %%T %%F %%M %%L %%R %%T %%F %%M %%L %%R Mflop/s")); 2285 if (PetscLogMemory) PetscCall(PetscFPrintf(comm, fd, " Mbytes Mbytes Mbytes Mbytes")); 2286 #if defined(PETSC_HAVE_DEVICE) 2287 PetscCall(PetscFPrintf(comm, fd, " Mflop/s Count Size Count Size %%F")); 2288 #endif 2289 PetscCall(PetscFPrintf(comm, fd, "\n")); 2290 PetscCall(PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------")); 2291 if (PetscLogMemory) PetscCall(PetscFPrintf(comm, fd, "-----------------------------")); 2292 #if defined(PETSC_HAVE_DEVICE) 2293 PetscCall(PetscFPrintf(comm, fd, "---------------------------------------")); 2294 #endif 2295 PetscCall(PetscFPrintf(comm, fd, "\n")); 2296 2297 #if defined(PETSC_HAVE_DEVICE) 2298 /* this indirect way of accessing these values is needed when PETSc is build with multiple libraries since the symbols are not in libpetscsys */ 2299 PetscCall(PetscEventRegLogGetEvent(stageLog->eventLog, "TAOSolve", &TAO_Solve)); 2300 PetscCall(PetscEventRegLogGetEvent(stageLog->eventLog, "TSStep", &TS_Step)); 2301 PetscCall(PetscEventRegLogGetEvent(stageLog->eventLog, "SNESSolve", &SNES_Solve)); 2302 PetscCall(PetscEventRegLogGetEvent(stageLog->eventLog, "KSPSolve", &KSP_Solve)); 2303 #endif 2304 2305 /* Problem: The stage name will not show up unless the stage executed on proc 1 */ 2306 for (stage = 0; stage < numStages; stage++) { 2307 if (!stageVisible[stage]) continue; 2308 /* CANNOT use MPI_Allreduce() since it might fail the line number check */ 2309 if (localStageUsed[stage]) { 2310 PetscCall(PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name)); 2311 PetscCall(MPIU_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2312 PetscCall(MPIU_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2313 PetscCall(MPIU_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2314 PetscCall(MPIU_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2315 PetscCall(MPIU_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2316 } else { 2317 PetscCall(PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage)); 2318 PetscCall(MPIU_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2319 PetscCall(MPIU_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2320 PetscCall(MPIU_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2321 PetscCall(MPIU_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2322 PetscCall(MPIU_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2323 } 2324 mess *= 0.5; 2325 messLen *= 0.5; 2326 red /= size; 2327 2328 /* Get total number of events in this stage -- 2329 Currently, a single processor can register more events than another, but events must all be registered in order, 2330 just like stages. We can removed this requirement if necessary by having a global event numbering and indirection 2331 on the event ID. This seems best accomplished by associating a communicator with each stage. 2332 2333 Problem: If the event did not happen on proc 1, its name will not be available. 2334 Problem: Event visibility is not implemented 2335 */ 2336 if (localStageUsed[stage]) { 2337 eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo; 2338 localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents; 2339 } else localNumEvents = 0; 2340 PetscCallMPI(MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm)); 2341 for (event = 0; event < numEvents; event++) { 2342 /* CANNOT use MPI_Allreduce() since it might fail the line number check */ 2343 if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) { 2344 if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) flopr = eventInfo[event].flops; 2345 else flopr = 0.0; 2346 PetscCall(MPIU_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm)); 2347 PetscCall(MPIU_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm)); 2348 PetscCall(MPIU_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2349 PetscCall(MPIU_Allreduce(&eventInfo[event].time, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm)); 2350 PetscCall(MPIU_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm)); 2351 PetscCall(MPIU_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2352 PetscCall(MPIU_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2353 PetscCall(MPIU_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2354 PetscCall(MPIU_Allreduce(&eventInfo[event].numReductions, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2355 PetscCallMPI(MPI_Allreduce(&eventInfo[event].count, &minC, 1, MPI_INT, MPI_MIN, comm)); 2356 PetscCallMPI(MPI_Allreduce(&eventInfo[event].count, &maxC, 1, MPI_INT, MPI_MAX, comm)); 2357 if (PetscLogMemory) { 2358 PetscCall(MPIU_Allreduce(&eventInfo[event].memIncrease, &mem, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2359 PetscCall(MPIU_Allreduce(&eventInfo[event].mallocSpace, &mal, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2360 PetscCall(MPIU_Allreduce(&eventInfo[event].mallocIncrease, &malmax, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2361 PetscCall(MPIU_Allreduce(&eventInfo[event].mallocIncreaseEvent, &emalmax, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2362 } 2363 #if defined(PETSC_HAVE_DEVICE) 2364 PetscCall(MPIU_Allreduce(&eventInfo[event].CpuToGpuCount, &cct, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2365 PetscCall(MPIU_Allreduce(&eventInfo[event].GpuToCpuCount, &gct, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2366 PetscCall(MPIU_Allreduce(&eventInfo[event].CpuToGpuSize, &csz, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2367 PetscCall(MPIU_Allreduce(&eventInfo[event].GpuToCpuSize, &gsz, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2368 PetscCall(MPIU_Allreduce(&eventInfo[event].GpuFlops, &gflops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2369 PetscCall(MPIU_Allreduce(&eventInfo[event].GpuTime, &gmaxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm)); 2370 #endif 2371 name = stageLog->eventLog->eventInfo[event].name; 2372 } else { 2373 int ierr = 0; 2374 2375 flopr = 0.0; 2376 PetscCall(MPIU_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm)); 2377 PetscCall(MPIU_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm)); 2378 PetscCall(MPIU_Allreduce(&zero, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2379 PetscCall(MPIU_Allreduce(&zero, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm)); 2380 PetscCall(MPIU_Allreduce(&zero, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm)); 2381 PetscCall(MPIU_Allreduce(&zero, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2382 PetscCall(MPIU_Allreduce(&zero, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2383 PetscCall(MPIU_Allreduce(&zero, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2384 PetscCall(MPIU_Allreduce(&zero, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2385 PetscCallMPI(MPI_Allreduce(&ierr, &minC, 1, MPI_INT, MPI_MIN, comm)); 2386 PetscCallMPI(MPI_Allreduce(&ierr, &maxC, 1, MPI_INT, MPI_MAX, comm)); 2387 if (PetscLogMemory) { 2388 PetscCall(MPIU_Allreduce(&zero, &mem, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2389 PetscCall(MPIU_Allreduce(&zero, &mal, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2390 PetscCall(MPIU_Allreduce(&zero, &malmax, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2391 PetscCall(MPIU_Allreduce(&zero, &emalmax, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2392 } 2393 #if defined(PETSC_HAVE_DEVICE) 2394 PetscCall(MPIU_Allreduce(&zero, &cct, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2395 PetscCall(MPIU_Allreduce(&zero, &gct, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2396 PetscCall(MPIU_Allreduce(&zero, &csz, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2397 PetscCall(MPIU_Allreduce(&zero, &gsz, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2398 PetscCall(MPIU_Allreduce(&zero, &gflops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm)); 2399 PetscCall(MPIU_Allreduce(&zero, &gmaxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm)); 2400 #endif 2401 name = ""; 2402 } 2403 if (mint < 0.0) { 2404 PetscCall(PetscFPrintf(comm, fd, "WARNING!!! Minimum time %g over all processors for %s is negative! This happens\n on some machines whose times cannot handle too rapid calls.!\n artificially changing minimum to zero.\n", mint, name)); 2405 mint = 0; 2406 } 2407 PetscCheck(minf >= 0.0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Minimum flop %g over all processors for %s is negative! Not possible!", minf, name); 2408 /* Put NaN into the time for all events that may not be time accurately since they may happen asynchronously on the GPU */ 2409 #if defined(PETSC_HAVE_DEVICE) 2410 if (!PetscLogGpuTimeFlag && petsc_gflops > 0) { 2411 memcpy(&gmaxt, &nas, sizeof(PetscLogDouble)); 2412 PetscCall(PetscEventRegLogGetEvent(stageLog->eventLog, name, &eventid)); 2413 if (eventid != SNES_Solve && eventid != KSP_Solve && eventid != TS_Step && eventid != TAO_Solve) { 2414 memcpy(&mint, &nas, sizeof(PetscLogDouble)); 2415 memcpy(&maxt, &nas, sizeof(PetscLogDouble)); 2416 } 2417 } 2418 #endif 2419 totm *= 0.5; 2420 totml *= 0.5; 2421 totr /= size; 2422 2423 if (maxC != 0) { 2424 if (minC != 0) ratC = ((PetscLogDouble)maxC) / minC; 2425 else ratC = 0.0; 2426 if (mint != 0.0) ratt = maxt / mint; 2427 else ratt = 0.0; 2428 if (minf != 0.0) ratf = maxf / minf; 2429 else ratf = 0.0; 2430 if (TotalTime != 0.0) fracTime = tott / TotalTime; 2431 else fracTime = 0.0; 2432 if (TotalFlops != 0.0) fracFlops = totf / TotalFlops; 2433 else fracFlops = 0.0; 2434 if (stageTime != 0.0) fracStageTime = tott / stageTime; 2435 else fracStageTime = 0.0; 2436 if (flops != 0.0) fracStageFlops = totf / flops; 2437 else fracStageFlops = 0.0; 2438 if (numMessages != 0.0) fracMess = totm / numMessages; 2439 else fracMess = 0.0; 2440 if (messageLength != 0.0) fracMessLen = totml / messageLength; 2441 else fracMessLen = 0.0; 2442 if (numReductions != 0.0) fracRed = totr / numReductions; 2443 else fracRed = 0.0; 2444 if (mess != 0.0) fracStageMess = totm / mess; 2445 else fracStageMess = 0.0; 2446 if (messLen != 0.0) fracStageMessLen = totml / messLen; 2447 else fracStageMessLen = 0.0; 2448 if (red != 0.0) fracStageRed = totr / red; 2449 else fracStageRed = 0.0; 2450 if (totm != 0.0) totml /= totm; 2451 else totml = 0.0; 2452 if (maxt != 0.0) flopr = totf / maxt; 2453 else flopr = 0.0; 2454 if (fracStageTime > 1.0 || fracStageFlops > 1.0 || fracStageMess > 1.0 || fracStageMessLen > 1.0 || fracStageRed > 1.0) 2455 PetscCall(PetscFPrintf(comm, fd, "%-16s %7d %3.1f %5.4e %3.1f %3.2e %3.1f %2.1e %2.1e %2.1e %2.0f %2.0f %2.0f %2.0f %2.0f Multiple stages %5.0f", name, maxC, ratC, maxt, ratt, maxf, ratf, totm, totml, totr, 100.0 * fracTime, 100.0 * fracFlops, 100.0 * fracMess, 100.0 * fracMessLen, 100.0 * fracRed, PetscAbs(flopr) / 1.0e6)); 2456 else 2457 PetscCall(PetscFPrintf(comm, fd, "%-16s %7d %3.1f %5.4e %3.1f %3.2e %3.1f %2.1e %2.1e %2.1e %2.0f %2.0f %2.0f %2.0f %2.0f %3.0f %2.0f %2.0f %2.0f %2.0f %5.0f", name, maxC, ratC, maxt, ratt, maxf, ratf, totm, totml, totr, 100.0 * fracTime, 100.0 * fracFlops, 100.0 * fracMess, 100.0 * fracMessLen, 100.0 * fracRed, 100.0 * fracStageTime, 100.0 * fracStageFlops, 100.0 * fracStageMess, 100.0 * fracStageMessLen, 100.0 * fracStageRed, PetscAbs(flopr) / 1.0e6)); 2458 if (PetscLogMemory) PetscCall(PetscFPrintf(comm, fd, " %5.0f %5.0f %5.0f %5.0f", mal / 1.0e6, emalmax / 1.0e6, malmax / 1.0e6, mem / 1.0e6)); 2459 #if defined(PETSC_HAVE_DEVICE) 2460 if (totf != 0.0) fracgflops = gflops / totf; 2461 else fracgflops = 0.0; 2462 if (gmaxt != 0.0) gflopr = gflops / gmaxt; 2463 else gflopr = 0.0; 2464 PetscCall(PetscFPrintf(comm, fd, " %5.0f %4.0f %3.2e %4.0f %3.2e % 2.0f", PetscAbs(gflopr) / 1.0e6, cct / size, csz / (1.0e6 * size), gct / size, gsz / (1.0e6 * size), 100.0 * fracgflops)); 2465 #endif 2466 PetscCall(PetscFPrintf(comm, fd, "\n")); 2467 } 2468 } 2469 } 2470 2471 /* Memory usage and object creation */ 2472 PetscCall(PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------")); 2473 if (PetscLogMemory) PetscCall(PetscFPrintf(comm, fd, "-----------------------------")); 2474 #if defined(PETSC_HAVE_DEVICE) 2475 PetscCall(PetscFPrintf(comm, fd, "---------------------------------------")); 2476 #endif 2477 PetscCall(PetscFPrintf(comm, fd, "\n")); 2478 PetscCall(PetscFPrintf(comm, fd, "\n")); 2479 2480 /* Right now, only stages on the first processor are reported here, meaning only objects associated with 2481 the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then 2482 stats for stages local to processor sets. 2483 */ 2484 /* We should figure out the longest object name here (now 20 characters) */ 2485 PetscCall(PetscFPrintf(comm, fd, "Object Type Creations Destructions. Reports information only for process 0.\n")); 2486 for (stage = 0; stage < numStages; stage++) { 2487 if (localStageUsed[stage]) { 2488 classInfo = stageLog->stageInfo[stage].classLog->classInfo; 2489 PetscCall(PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name)); 2490 for (oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) { 2491 if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) { 2492 PetscCall(PetscFPrintf(comm, fd, "%20s %5d %5d\n", stageLog->classLog->classInfo[oclass].name, classInfo[oclass].creations, classInfo[oclass].destructions)); 2493 } 2494 } 2495 } else { 2496 if (!localStageVisible[stage]) continue; 2497 PetscCall(PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage)); 2498 } 2499 } 2500 2501 PetscCall(PetscFree(localStageUsed)); 2502 PetscCall(PetscFree(stageUsed)); 2503 PetscCall(PetscFree(localStageVisible)); 2504 PetscCall(PetscFree(stageVisible)); 2505 2506 /* Information unrelated to this particular run */ 2507 PetscCall(PetscFPrintf(comm, fd, "========================================================================================================================\n")); 2508 PetscCall(PetscTime(&y)); 2509 PetscCall(PetscTime(&x)); 2510 PetscCall(PetscTime(&y)); 2511 PetscCall(PetscTime(&y)); 2512 PetscCall(PetscTime(&y)); 2513 PetscCall(PetscTime(&y)); 2514 PetscCall(PetscTime(&y)); 2515 PetscCall(PetscTime(&y)); 2516 PetscCall(PetscTime(&y)); 2517 PetscCall(PetscTime(&y)); 2518 PetscCall(PetscTime(&y)); 2519 PetscCall(PetscTime(&y)); 2520 PetscCall(PetscFPrintf(comm, fd, "Average time to get PetscTime(): %g\n", (y - x) / 10.0)); 2521 /* MPI information */ 2522 if (size > 1) { 2523 MPI_Status status; 2524 PetscMPIInt tag; 2525 MPI_Comm newcomm; 2526 2527 PetscCallMPI(MPI_Barrier(comm)); 2528 PetscCall(PetscTime(&x)); 2529 PetscCallMPI(MPI_Barrier(comm)); 2530 PetscCallMPI(MPI_Barrier(comm)); 2531 PetscCallMPI(MPI_Barrier(comm)); 2532 PetscCallMPI(MPI_Barrier(comm)); 2533 PetscCallMPI(MPI_Barrier(comm)); 2534 PetscCall(PetscTime(&y)); 2535 PetscCall(PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y - x) / 5.0)); 2536 PetscCall(PetscCommDuplicate(comm, &newcomm, &tag)); 2537 PetscCallMPI(MPI_Barrier(comm)); 2538 if (rank) { 2539 PetscCallMPI(MPI_Recv(NULL, 0, MPI_INT, rank - 1, tag, newcomm, &status)); 2540 PetscCallMPI(MPI_Send(NULL, 0, MPI_INT, (rank + 1) % size, tag, newcomm)); 2541 } else { 2542 PetscCall(PetscTime(&x)); 2543 PetscCallMPI(MPI_Send(NULL, 0, MPI_INT, 1, tag, newcomm)); 2544 PetscCallMPI(MPI_Recv(NULL, 0, MPI_INT, size - 1, tag, newcomm, &status)); 2545 PetscCall(PetscTime(&y)); 2546 PetscCall(PetscFPrintf(comm, fd, "Average time for zero size MPI_Send(): %g\n", (y - x) / size)); 2547 } 2548 PetscCall(PetscCommDestroy(&newcomm)); 2549 } 2550 PetscCall(PetscOptionsView(NULL, viewer)); 2551 2552 /* Machine and compile information */ 2553 #if defined(PETSC_USE_FORTRAN_KERNELS) 2554 PetscCall(PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n")); 2555 #else 2556 PetscCall(PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n")); 2557 #endif 2558 #if defined(PETSC_USE_64BIT_INDICES) 2559 PetscCall(PetscFPrintf(comm, fd, "Compiled with 64-bit PetscInt\n")); 2560 #elif defined(PETSC_USE___FLOAT128) 2561 PetscCall(PetscFPrintf(comm, fd, "Compiled with 32-bit PetscInt\n")); 2562 #endif 2563 #if defined(PETSC_USE_REAL_SINGLE) 2564 PetscCall(PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n")); 2565 #elif defined(PETSC_USE___FLOAT128) 2566 PetscCall(PetscFPrintf(comm, fd, "Compiled with 128 bit precision PetscScalar and PetscReal\n")); 2567 #endif 2568 #if defined(PETSC_USE_REAL_MAT_SINGLE) 2569 PetscCall(PetscFPrintf(comm, fd, "Compiled with single precision matrices\n")); 2570 #else 2571 PetscCall(PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n")); 2572 #endif 2573 PetscCall(PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d sizeof(PetscInt) %d\n", (int)sizeof(short), (int)sizeof(int), (int)sizeof(long), (int)sizeof(void *), (int)sizeof(PetscScalar), (int)sizeof(PetscInt))); 2574 2575 PetscCall(PetscFPrintf(comm, fd, "Configure options: %s", petscconfigureoptions)); 2576 PetscCall(PetscFPrintf(comm, fd, "%s", petscmachineinfo)); 2577 PetscCall(PetscFPrintf(comm, fd, "%s", petsccompilerinfo)); 2578 PetscCall(PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo)); 2579 PetscCall(PetscFPrintf(comm, fd, "%s", petsclinkerinfo)); 2580 2581 /* Cleanup */ 2582 PetscCall(PetscFPrintf(comm, fd, "\n")); 2583 PetscCall(PetscLogViewWarnNoGpuAwareMpi(comm, fd)); 2584 PetscCall(PetscLogViewWarnDebugging(comm, fd)); 2585 PetscCall(PetscFPTrapPop()); 2586 PetscFunctionReturn(PETSC_SUCCESS); 2587 } 2588 2589 /*@C 2590 PetscLogView - Prints a summary of the logging. 2591 2592 Collective over MPI_Comm 2593 2594 Input Parameter: 2595 . viewer - an ASCII viewer 2596 2597 Options Database Keys: 2598 + -log_view [:filename] - Prints summary of log information 2599 . -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file 2600 . -log_view :filename.xml:ascii_xml - Saves a summary of the logging information in a nested format (see below for how to view it) 2601 . -log_view :filename.txt:ascii_flamegraph - Saves logging information in a format suitable for visualising as a Flame Graph (see below for how to view it) 2602 . -log_view_memory - Also display memory usage in each event 2603 . -log_view_gpu_time - Also display time in each event for GPU kernels (Note this may slow the computation) 2604 . -log_all - Saves a file Log.rank for each MPI rank with details of each step of the computation 2605 - -log_trace [filename] - Displays a trace of what each process is doing 2606 2607 Level: beginner 2608 2609 Notes: 2610 It is possible to control the logging programmatically but we recommend using the options database approach whenever possible 2611 By default the summary is printed to stdout. 2612 2613 Before calling this routine you must have called either PetscLogDefaultBegin() or PetscLogNestedBegin() 2614 2615 If PETSc is configured with --with-logging=0 then this functionality is not available 2616 2617 To view the nested XML format filename.xml first copy ${PETSC_DIR}/share/petsc/xml/performance_xml2html.xsl to the current 2618 directory then open filename.xml with your browser. Specific notes for certain browsers 2619 $ Firefox and Internet explorer - simply open the file 2620 $ Google Chrome - you must start up Chrome with the option --allow-file-access-from-files 2621 $ Safari - see https://ccm.net/faq/36342-safari-how-to-enable-local-file-access 2622 or one can use the package http://xmlsoft.org/XSLT/xsltproc2.html to translate the xml file to html and then open it with 2623 your browser. 2624 Alternatively, use the script ${PETSC_DIR}/lib/petsc/bin/petsc-performance-view to automatically open a new browser 2625 window and render the XML log file contents. 2626 2627 The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij MARITIME RESEARCH INSTITUTE NETHERLANDS 2628 2629 The Flame Graph output can be visualised using either the original Flame Graph script (https://github.com/brendangregg/FlameGraph) 2630 or using speedscope (https://www.speedscope.app). 2631 Old XML profiles may be converted into this format using the script ${PETSC_DIR}/lib/petsc/bin/xml2flamegraph.py. 2632 2633 .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogDump()` 2634 @*/ 2635 PetscErrorCode PetscLogView(PetscViewer viewer) 2636 { 2637 PetscBool isascii; 2638 PetscViewerFormat format; 2639 int stage, lastStage; 2640 PetscStageLog stageLog; 2641 2642 PetscFunctionBegin; 2643 PetscCheck(PetscLogPLB, PETSC_COMM_SELF, PETSC_ERR_SUP, "Must use -log_view or PetscLogDefaultBegin() before calling this routine"); 2644 /* Pop off any stages the user forgot to remove */ 2645 lastStage = 0; 2646 PetscCall(PetscLogGetStageLog(&stageLog)); 2647 PetscCall(PetscStageLogGetCurrent(stageLog, &stage)); 2648 while (stage >= 0) { 2649 lastStage = stage; 2650 PetscCall(PetscStageLogPop(stageLog)); 2651 PetscCall(PetscStageLogGetCurrent(stageLog, &stage)); 2652 } 2653 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 2654 PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Currently can only view logging to ASCII"); 2655 PetscCall(PetscViewerGetFormat(viewer, &format)); 2656 if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO) { 2657 PetscCall(PetscLogView_Default(viewer)); 2658 } else if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 2659 PetscCall(PetscLogView_Detailed(viewer)); 2660 } else if (format == PETSC_VIEWER_ASCII_CSV) { 2661 PetscCall(PetscLogView_CSV(viewer)); 2662 } else if (format == PETSC_VIEWER_ASCII_XML) { 2663 PetscCall(PetscLogView_Nested(viewer)); 2664 } else if (format == PETSC_VIEWER_ASCII_FLAMEGRAPH) { 2665 PetscCall(PetscLogView_Flamegraph(viewer)); 2666 } 2667 PetscCall(PetscStageLogPush(stageLog, lastStage)); 2668 PetscFunctionReturn(PETSC_SUCCESS); 2669 } 2670 2671 /*@C 2672 PetscLogViewFromOptions - Processes command line options to determine if/how a `PetscLog` is to be viewed. 2673 2674 Collective on `PETSC_COMM_WORLD` 2675 2676 Level: developer 2677 2678 .seealso: [](ch_profiling), `PetscLogView()` 2679 @*/ 2680 PetscErrorCode PetscLogViewFromOptions(void) 2681 { 2682 PetscViewer viewer; 2683 PetscBool flg; 2684 PetscViewerFormat format; 2685 2686 PetscFunctionBegin; 2687 PetscCall(PetscOptionsGetViewer(PETSC_COMM_WORLD, NULL, NULL, "-log_view", &viewer, &format, &flg)); 2688 if (flg) { 2689 PetscCall(PetscViewerPushFormat(viewer, format)); 2690 PetscCall(PetscLogView(viewer)); 2691 PetscCall(PetscViewerPopFormat(viewer)); 2692 PetscCall(PetscViewerDestroy(&viewer)); 2693 } 2694 PetscFunctionReturn(PETSC_SUCCESS); 2695 } 2696 2697 /*----------------------------------------------- Counter Functions -------------------------------------------------*/ 2698 /*@C 2699 PetscGetFlops - Returns the number of flops used on this processor 2700 since the program began. 2701 2702 Not Collective 2703 2704 Output Parameter: 2705 . flops - number of floating point operations 2706 2707 Level: intermediate 2708 2709 Notes: 2710 A global counter logs all PETSc flop counts. The user can use 2711 `PetscLogFlops()` to increment this counter to include flops for the 2712 application code. 2713 2714 A separate counter `PetscLogGPUFlops()` logs the flops that occur on any GPU associated with this MPI rank 2715 2716 .seealso: [](ch_profiling), `PetscLogGPUFlops()`, `PetscTime()`, `PetscLogFlops()` 2717 @*/ 2718 PetscErrorCode PetscGetFlops(PetscLogDouble *flops) 2719 { 2720 PetscFunctionBegin; 2721 *flops = petsc_TotalFlops; 2722 PetscFunctionReturn(PETSC_SUCCESS); 2723 } 2724 2725 /*@C 2726 PetscLogObjectState - Record information about an object with the default log handler 2727 2728 Not Collective 2729 2730 Input Parameters: 2731 + obj - the `PetscObject` 2732 . format - a printf-style format string 2733 - ... - printf arguments to format 2734 2735 Level: developer 2736 2737 .seealso: [](ch_profiling), `PetscLogObjectCreate()`, `PetscLogObjectDestroy()` 2738 @*/ 2739 PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...) 2740 { 2741 size_t fullLength; 2742 va_list Argp; 2743 2744 PetscFunctionBegin; 2745 if (!petsc_logObjects) PetscFunctionReturn(PETSC_SUCCESS); 2746 va_start(Argp, format); 2747 PetscCall(PetscVSNPrintf(petsc_objects[obj->id].info, 64, format, &fullLength, Argp)); 2748 va_end(Argp); 2749 PetscFunctionReturn(PETSC_SUCCESS); 2750 } 2751 2752 /*MC 2753 PetscLogFlops - Adds floating point operations to the global counter. 2754 2755 Synopsis: 2756 #include <petsclog.h> 2757 PetscErrorCode PetscLogFlops(PetscLogDouble f) 2758 2759 Not Collective 2760 2761 Input Parameter: 2762 . f - flop counter 2763 2764 Example Usage: 2765 .vb 2766 PetscLogEvent USER_EVENT; 2767 2768 PetscLogEventRegister("User event", 0, &USER_EVENT); 2769 PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0); 2770 [code segment to monitor] 2771 PetscLogFlops(user_flops) 2772 PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0); 2773 .ve 2774 2775 Level: intermediate 2776 2777 Note: 2778 A global counter logs all PETSc flop counts. The user can use PetscLogFlops() to increment 2779 this counter to include flops for the application code. 2780 2781 .seealso: [](ch_profiling), `PetscLogGPUFlops()`, `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscGetFlops()` 2782 M*/ 2783 2784 /*MC 2785 PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice) to get accurate 2786 timings 2787 2788 Synopsis: 2789 #include <petsclog.h> 2790 void PetscPreLoadBegin(PetscBool flag, char *name); 2791 2792 Not Collective 2793 2794 Input Parameters: 2795 + flag - `PETSC_TRUE` to run twice, `PETSC_FALSE` to run once, may be overridden with command 2796 line option `-preload true|false` 2797 - name - name of first stage (lines of code timed separately with `-log_view`) to be preloaded 2798 2799 Example Usage: 2800 .vb 2801 PetscPreLoadBegin(PETSC_TRUE, "first stage"); 2802 // lines of code 2803 PetscPreLoadStage("second stage"); 2804 // lines of code 2805 PetscPreLoadEnd(); 2806 .ve 2807 2808 Level: intermediate 2809 2810 Note: 2811 Only works in C/C++, not Fortran 2812 2813 Flags available within the macro\: 2814 + PetscPreLoadingUsed - `PETSC_TRUE` if we are or have done preloading 2815 . PetscPreLoadingOn - `PETSC_TRUE` if it is CURRENTLY doing preload 2816 . PetscPreLoadIt - `0` for the first computation (with preloading turned off it is only 2817 `0`) `1` for the second 2818 - PetscPreLoadMax - number of times it will do the computation, only one when preloading is 2819 turned on 2820 2821 The first two variables are available throughout the program, the second two only between the 2822 `PetscPreLoadBegin()` and `PetscPreLoadEnd()` 2823 2824 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()` 2825 M*/ 2826 2827 /*MC 2828 PetscPreLoadEnd - End a segment of code that may be preloaded (run twice) to get accurate 2829 timings 2830 2831 Synopsis: 2832 #include <petsclog.h> 2833 void PetscPreLoadEnd(void); 2834 2835 Not Collective 2836 2837 Example Usage: 2838 .vb 2839 PetscPreLoadBegin(PETSC_TRUE, "first stage"); 2840 // lines of code 2841 PetscPreLoadStage("second stage"); 2842 // lines of code 2843 PetscPreLoadEnd(); 2844 .ve 2845 2846 Level: intermediate 2847 2848 Note: 2849 Only works in C/C++ not fortran 2850 2851 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadStage()` 2852 M*/ 2853 2854 /*MC 2855 PetscPreLoadStage - Start a new segment of code to be timed separately to get accurate timings 2856 2857 Synopsis: 2858 #include <petsclog.h> 2859 void PetscPreLoadStage(char *name); 2860 2861 Not Collective 2862 2863 Example Usage: 2864 .vb 2865 PetscPreLoadBegin(PETSC_TRUE,"first stage"); 2866 // lines of code 2867 PetscPreLoadStage("second stage"); 2868 // lines of code 2869 PetscPreLoadEnd(); 2870 .ve 2871 2872 Level: intermediate 2873 2874 Note: 2875 Only works in C/C++ not fortran 2876 2877 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()` 2878 M*/ 2879 2880 #if PetscDefined(HAVE_DEVICE) 2881 #include <petsc/private/deviceimpl.h> 2882 2883 /* 2884 This cannot be called by users between PetscInitialize() and PetscFinalize() at any random location in the code 2885 because it will result in timing results that cannot be interpreted. 2886 */ 2887 static PetscErrorCode PetscLogGpuTime_Off(void) 2888 { 2889 PetscLogGpuTimeFlag = PETSC_FALSE; 2890 return PETSC_SUCCESS; 2891 } 2892 2893 /*@C 2894 PetscLogGpuTime - turn on the logging of GPU time for GPU kernels 2895 2896 Options Database Key: 2897 . -log_view_gpu_time - provide the GPU times in the `-log_view` output 2898 2899 Level: advanced 2900 2901 Notes: 2902 Turning on the timing of the GPU kernels can slow down the entire computation and should only 2903 be used when studying the performance of operations on GPU such as vector operations and 2904 matrix-vector operations. 2905 2906 This routine should only be called once near the beginning of the program. Once it is started 2907 it cannot be turned off. 2908 2909 .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTimeBegin()` 2910 @*/ 2911 PetscErrorCode PetscLogGpuTime(void) 2912 { 2913 if (!PetscLogGpuTimeFlag) PetscCall(PetscRegisterFinalize(PetscLogGpuTime_Off)); 2914 PetscLogGpuTimeFlag = PETSC_TRUE; 2915 return PETSC_SUCCESS; 2916 } 2917 2918 /*@C 2919 PetscLogGpuTimeBegin - Start timer for device 2920 2921 Level: intermediate 2922 2923 Notes: 2924 When CUDA or HIP is enabled, the timer is run on the GPU, it is a separate logging of time 2925 devoted to GPU computations (excluding kernel launch times). 2926 2927 When CUDA or HIP is not available, the timer is run on the CPU, it is a separate logging of 2928 time devoted to GPU computations (including kernel launch times). 2929 2930 There is no need to call WaitForCUDA() or WaitForHIP() between `PetscLogGpuTimeBegin()` and 2931 `PetscLogGpuTimeEnd()` 2932 2933 This timer should NOT include times for data transfers between the GPU and CPU, nor setup 2934 actions such as allocating space. 2935 2936 The regular logging captures the time for data transfers and any CPU activities during the 2937 event. It is used to compute the flop rate on the GPU as it is actively engaged in running a 2938 kernel. 2939 2940 Developer Notes: 2941 The GPU event timer captures the execution time of all the kernels launched in the default 2942 stream by the CPU between `PetscLogGpuTimeBegin()` and `PetsLogGpuTimeEnd()`. 2943 2944 `PetscLogGpuTimeBegin()` and `PetsLogGpuTimeEnd()` insert the begin and end events into the 2945 default stream (stream 0). The device will record a time stamp for the event when it reaches 2946 that event in the stream. The function xxxEventSynchronize() is called in 2947 `PetsLogGpuTimeEnd()` to block CPU execution, but not continued GPU execution, until the 2948 timer event is recorded. 2949 2950 .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTime()` 2951 @*/ 2952 PetscErrorCode PetscLogGpuTimeBegin(void) 2953 { 2954 PetscFunctionBegin; 2955 if (!PetscLogPLB || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS); 2956 if (PetscDefined(HAVE_DEVICE)) { 2957 PetscDeviceContext dctx; 2958 2959 PetscCall(PetscDeviceContextGetCurrentContext(&dctx)); 2960 PetscCall(PetscDeviceContextBeginTimer_Internal(dctx)); 2961 } else { 2962 PetscCall(PetscTimeSubtract(&petsc_gtime)); 2963 } 2964 PetscFunctionReturn(PETSC_SUCCESS); 2965 } 2966 2967 /*@C 2968 PetscLogGpuTimeEnd - Stop timer for device 2969 2970 Level: intermediate 2971 2972 .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeBegin()` 2973 @*/ 2974 PetscErrorCode PetscLogGpuTimeEnd(void) 2975 { 2976 PetscFunctionBegin; 2977 if (!PetscLogPLE || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS); 2978 if (PetscDefined(HAVE_DEVICE)) { 2979 PetscDeviceContext dctx; 2980 PetscLogDouble elapsed; 2981 2982 PetscCall(PetscDeviceContextGetCurrentContext(&dctx)); 2983 PetscCall(PetscDeviceContextEndTimer_Internal(dctx, &elapsed)); 2984 petsc_gtime += (elapsed / 1000.0); 2985 } else { 2986 PetscCall(PetscTimeAdd(&petsc_gtime)); 2987 } 2988 PetscFunctionReturn(PETSC_SUCCESS); 2989 } 2990 2991 #endif /* end of PETSC_HAVE_DEVICE */ 2992 2993 #endif /* PETSC_USE_LOG*/ 2994 2995 PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID; 2996 PetscClassId PETSC_OBJECT_CLASSID = 0; 2997 2998 /* Logging functions */ 2999 PetscErrorCode (*PetscLogPHC)(PetscObject) = NULL; 3000 PetscErrorCode (*PetscLogPHD)(PetscObject) = NULL; 3001 PetscErrorCode (*PetscLogPLB)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = NULL; 3002 PetscErrorCode (*PetscLogPLE)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = NULL; 3003 3004 /* Tracing event logging variables */ 3005 FILE *petsc_tracefile = NULL; 3006 int petsc_tracelevel = 0; 3007 const char *petsc_traceblanks = " "; 3008 char petsc_tracespace[128] = " "; 3009 PetscLogDouble petsc_tracetime = 0.0; 3010 static PetscBool PetscLogInitializeCalled = PETSC_FALSE; 3011 3012 static PetscIntStack current_log_event_stack = NULL; 3013 3014 PETSC_INTERN PetscErrorCode PetscLogInitialize(void) 3015 { 3016 int stage; 3017 PetscBool opt; 3018 3019 PetscFunctionBegin; 3020 if (PetscLogInitializeCalled) PetscFunctionReturn(PETSC_SUCCESS); 3021 PetscLogInitializeCalled = PETSC_TRUE; 3022 if (PetscDefined(USE_LOG)) { 3023 PetscCall(PetscIntStackCreate(¤t_log_event_stack)); 3024 PetscCall(PetscOptionsHasName(NULL, NULL, "-log_exclude_actions", &opt)); 3025 if (opt) petsc_logActions = PETSC_FALSE; 3026 PetscCall(PetscOptionsHasName(NULL, NULL, "-log_exclude_objects", &opt)); 3027 if (opt) petsc_logObjects = PETSC_FALSE; 3028 if (petsc_logActions) PetscCall(PetscMalloc1(petsc_maxActions, &petsc_actions)); 3029 if (petsc_logObjects) PetscCall(PetscMalloc1(petsc_maxObjects, &petsc_objects)); 3030 PetscLogPHC = PetscLogObjCreateDefault; 3031 PetscLogPHD = PetscLogObjDestroyDefault; 3032 /* Setup default logging structures */ 3033 PetscCall(PetscLogStateCreate(&petsc_log_state)); 3034 for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) { 3035 if (PetscLogHandlers[i].handler) PetscCall(PetscLogHandlerSetState(PetscLogHandlers[i].handler, petsc_log_state)); 3036 } 3037 PetscCall(PetscLogStateStageRegister(petsc_log_state, "Main Stage", &stage)); 3038 PetscCall(PetscStageLogCreate(&petsc_stageLog)); 3039 PetscCall(PetscStageLogRegister(petsc_stageLog, "Main Stage", &stage)); 3040 3041 PetscCall(PetscSpinlockCreate(&PetscLogSpinLock)); 3042 #if defined(PETSC_HAVE_THREADSAFETY) 3043 petsc_log_tid = 0; 3044 petsc_log_gid = 0; 3045 PetscCall(PetscHMapEventCreate(&eventInfoMap_th)); 3046 #endif 3047 3048 /* All processors sync here for more consistent logging */ 3049 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD)); 3050 PetscCall(PetscTime(&petsc_BaseTime)); 3051 PetscCall(PetscLogStagePush(stage)); 3052 #if defined(PETSC_HAVE_TAU_PERFSTUBS) 3053 PetscStackCallExternalVoid("ps_initialize_", ps_initialize_()); 3054 #endif 3055 } 3056 PetscFunctionReturn(PETSC_SUCCESS); 3057 } 3058 3059 PETSC_INTERN PetscErrorCode PetscLogFinalize(void) 3060 { 3061 PetscStageLog stageLog; 3062 3063 PetscFunctionBegin; 3064 if (PetscDefined(USE_LOG)) { 3065 for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) PetscCall(PetscLogHandlerDestroy(&PetscLogHandlers[i].handler)); 3066 PetscCall(PetscArrayzero(PetscLogHandlers, PETSC_LOG_HANDLER_MAX)); 3067 PetscCall(PetscLogStateDestroy(&petsc_log_state)); 3068 #if defined(PETSC_HAVE_THREADSAFETY) 3069 if (eventInfoMap_th) { 3070 PetscEventPerfInfo **array; 3071 PetscInt n, off = 0; 3072 3073 PetscCall(PetscHMapEventGetSize(eventInfoMap_th, &n)); 3074 PetscCall(PetscMalloc1(n, &array)); 3075 PetscCall(PetscHMapEventGetVals(eventInfoMap_th, &off, array)); 3076 for (PetscInt i = 0; i < n; i++) PetscCall(PetscFree(array[i])); 3077 PetscCall(PetscFree(array)); 3078 PetscCall(PetscHMapEventDestroy(&eventInfoMap_th)); 3079 } 3080 #endif 3081 PetscCall(PetscFree(petsc_actions)); 3082 PetscCall(PetscFree(petsc_objects)); 3083 PetscCall(PetscLogNestedEnd()); 3084 PetscCall(PetscLogSet(NULL, NULL)); 3085 3086 /* Resetting phase */ 3087 PetscCall(PetscLogGetStageLog(&stageLog)); 3088 PetscCall(PetscStageLogDestroy(stageLog)); 3089 PetscCall(PetscIntStackDestroy(current_log_event_stack)); 3090 current_log_event_stack = NULL; 3091 3092 petsc_TotalFlops = 0.0; 3093 petsc_numActions = 0; 3094 petsc_numObjects = 0; 3095 petsc_numObjectsDestroyed = 0; 3096 petsc_maxActions = 100; 3097 petsc_maxObjects = 100; 3098 petsc_actions = NULL; 3099 petsc_objects = NULL; 3100 petsc_logActions = PETSC_FALSE; 3101 petsc_logObjects = PETSC_FALSE; 3102 petsc_BaseTime = 0.0; 3103 petsc_TotalFlops = 0.0; 3104 petsc_send_ct = 0.0; 3105 petsc_recv_ct = 0.0; 3106 petsc_send_len = 0.0; 3107 petsc_recv_len = 0.0; 3108 petsc_isend_ct = 0.0; 3109 petsc_irecv_ct = 0.0; 3110 petsc_isend_len = 0.0; 3111 petsc_irecv_len = 0.0; 3112 petsc_wait_ct = 0.0; 3113 petsc_wait_any_ct = 0.0; 3114 petsc_wait_all_ct = 0.0; 3115 petsc_sum_of_waits_ct = 0.0; 3116 petsc_allreduce_ct = 0.0; 3117 petsc_gather_ct = 0.0; 3118 petsc_scatter_ct = 0.0; 3119 petsc_TotalFlops_th = 0.0; 3120 petsc_send_ct_th = 0.0; 3121 petsc_recv_ct_th = 0.0; 3122 petsc_send_len_th = 0.0; 3123 petsc_recv_len_th = 0.0; 3124 petsc_isend_ct_th = 0.0; 3125 petsc_irecv_ct_th = 0.0; 3126 petsc_isend_len_th = 0.0; 3127 petsc_irecv_len_th = 0.0; 3128 petsc_wait_ct_th = 0.0; 3129 petsc_wait_any_ct_th = 0.0; 3130 petsc_wait_all_ct_th = 0.0; 3131 petsc_sum_of_waits_ct_th = 0.0; 3132 petsc_allreduce_ct_th = 0.0; 3133 petsc_gather_ct_th = 0.0; 3134 petsc_scatter_ct_th = 0.0; 3135 3136 petsc_ctog_ct = 0.0; 3137 petsc_gtoc_ct = 0.0; 3138 petsc_ctog_sz = 0.0; 3139 petsc_gtoc_sz = 0.0; 3140 petsc_gflops = 0.0; 3141 petsc_gtime = 0.0; 3142 petsc_ctog_ct_th = 0.0; 3143 petsc_gtoc_ct_th = 0.0; 3144 petsc_ctog_sz_th = 0.0; 3145 petsc_gtoc_sz_th = 0.0; 3146 petsc_gflops_th = 0.0; 3147 petsc_gtime_th = 0.0; 3148 3149 PETSC_LARGEST_EVENT = PETSC_EVENT; 3150 PetscLogPHC = NULL; 3151 PetscLogPHD = NULL; 3152 petsc_tracefile = NULL; 3153 petsc_tracelevel = 0; 3154 petsc_traceblanks = " "; 3155 petsc_tracespace[0] = ' '; 3156 petsc_tracespace[1] = 0; 3157 petsc_tracetime = 0.0; 3158 petsc_stageLog = NULL; 3159 } 3160 PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID; 3161 PETSC_OBJECT_CLASSID = 0; 3162 PetscLogInitializeCalled = PETSC_FALSE; 3163 PetscFunctionReturn(PETSC_SUCCESS); 3164 } 3165 3166 /*@C 3167 PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code. 3168 3169 Not Collective 3170 3171 Input Parameter: 3172 . name - The class name 3173 3174 Output Parameter: 3175 . oclass - The class id or classid 3176 3177 Level: developer 3178 3179 .seealso: [](ch_profiling), `PetscLogEventRegister()` 3180 @*/ 3181 PetscErrorCode PetscClassIdRegister(const char name[], PetscClassId *oclass) 3182 { 3183 #if defined(PETSC_USE_LOG) 3184 PetscStageLog stageLog; 3185 PetscInt stage; 3186 #endif 3187 3188 PetscFunctionBegin; 3189 *oclass = ++PETSC_LARGEST_CLASSID; 3190 #if defined(PETSC_USE_LOG) 3191 PetscCall(PetscLogGetStageLog(&stageLog)); 3192 PetscCall(PetscClassRegLogRegister(stageLog->classLog, name, *oclass)); 3193 for (stage = 0; stage < stageLog->numStages; stage++) PetscCall(PetscClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses)); 3194 #endif 3195 PetscFunctionReturn(PETSC_SUCCESS); 3196 } 3197 3198 #if defined(PETSC_USE_LOG) && defined(PETSC_HAVE_MPE) 3199 #include <mpe.h> 3200 3201 /*@C 3202 PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot. 3203 3204 Input Parameter: 3205 . sname - The filename to dump to 3206 3207 Collective over `PETSC_COMM_WORLD` 3208 3209 Level: advanced 3210 3211 .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogAllBegin()`, `PetscLogMPEBegin()` 3212 @*/ 3213 PetscErrorCode PetscLogMPEDump(const char sname[]) 3214 { 3215 char name[PETSC_MAX_PATH_LEN]; 3216 3217 PetscFunctionBegin; 3218 if (PetscBeganMPE) { 3219 PetscCall(PetscInfo(0, "Finalizing MPE.\n")); 3220 if (sname) { 3221 PetscCall(PetscStrncpy(name, sname, sizeof(name))); 3222 } else { 3223 PetscCall(PetscGetProgramName(name, sizeof(name))); 3224 } 3225 PetscCall(MPE_Finish_log(name)); 3226 } else { 3227 PetscCall(PetscInfo(0, "Not finalizing MPE (not started by PETSc).\n")); 3228 } 3229 PetscFunctionReturn(PETSC_SUCCESS); 3230 } 3231 3232 #define PETSC_RGB_COLORS_MAX 39 3233 static const char *PetscLogMPERGBColors[PETSC_RGB_COLORS_MAX] = {"OliveDrab: ", "BlueViolet: ", "CadetBlue: ", "CornflowerBlue: ", "DarkGoldenrod: ", "DarkGreen: ", "DarkKhaki: ", "DarkOliveGreen: ", 3234 "DarkOrange: ", "DarkOrchid: ", "DarkSeaGreen: ", "DarkSlateGray: ", "DarkTurquoise: ", "DeepPink: ", "DarkKhaki: ", "DimGray: ", 3235 "DodgerBlue: ", "GreenYellow: ", "HotPink: ", "IndianRed: ", "LavenderBlush: ", "LawnGreen: ", "LemonChiffon: ", "LightCoral: ", 3236 "LightCyan: ", "LightPink: ", "LightSalmon: ", "LightSlateGray: ", "LightYellow: ", "LimeGreen: ", "MediumPurple: ", "MediumSeaGreen: ", 3237 "MediumSlateBlue:", "MidnightBlue: ", "MintCream: ", "MistyRose: ", "NavajoWhite: ", "NavyBlue: ", "OliveDrab: "}; 3238 3239 /*@C 3240 PetscLogMPEGetRGBColor - This routine returns a rgb color useable with `PetscLogEventRegister()` 3241 3242 Not collective. Maybe it should be? 3243 3244 Output Parameter: 3245 . str - character string representing the color 3246 3247 Level: developer 3248 3249 .seealso: [](ch_profiling), `PetscLogEventRegister()` 3250 @*/ 3251 PetscErrorCode PetscLogMPEGetRGBColor(const char *str[]) 3252 { 3253 static int idx = 0; 3254 3255 PetscFunctionBegin; 3256 *str = PetscLogMPERGBColors[idx]; 3257 idx = (idx + 1) % PETSC_RGB_COLORS_MAX; 3258 PetscFunctionReturn(PETSC_SUCCESS); 3259 } 3260 3261 #endif /* PETSC_USE_LOG && PETSC_HAVE_MPE */ 3262