xref: /petsc/src/sys/logging/plog.c (revision 4302210d98c281cf4e8bc0fee406cf222e373a4c)
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 <petsctime.h>
13 #include <petscviewer.h>
14 
15 PetscErrorCode PetscLogObjectParent(PetscObject p,PetscObject c)
16 {
17   if (!c || !p) return 0;
18   c->parent   = p;
19   c->parentid = p->id;
20   return 0;
21 }
22 
23 /*@C
24    PetscLogObjectMemory - Adds to an object a count of additional amount of memory that is used by the object.
25 
26    Not collective.
27 
28    Input Parameters:
29 +  obj  - the PETSc object
30 -  mem  - the amount of memory that is being added to the object
31 
32    Level: developer
33 
34    Developer Notes:
35     Currently we do not always do a good job of associating all memory allocations with an object.
36 
37 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscInitializeNoArguments()
38 
39 @*/
40 PetscErrorCode PetscLogObjectMemory(PetscObject p,PetscLogDouble m)
41 {
42   if (!p) return 0;
43   p->mem += m;
44   return 0;
45 }
46 
47 PetscLogEvent PETSC_LARGEST_EVENT = PETSC_EVENT;
48 
49 #if defined(PETSC_USE_LOG)
50 #include <petscmachineinfo.h>
51 #include <petscconfiginfo.h>
52 
53 /* used in the MPI_XXX() count macros in petsclog.h */
54 
55 /* Action and object logging variables */
56 Action    *petsc_actions            = NULL;
57 Object    *petsc_objects            = NULL;
58 PetscBool petsc_logActions          = PETSC_FALSE;
59 PetscBool petsc_logObjects          = PETSC_FALSE;
60 int       petsc_numActions          = 0, petsc_maxActions = 100;
61 int       petsc_numObjects          = 0, petsc_maxObjects = 100;
62 int       petsc_numObjectsDestroyed = 0;
63 
64 /* Global counters */
65 PetscLogDouble petsc_BaseTime        = 0.0;
66 PetscLogDouble petsc_TotalFlops      = 0.0;  /* The number of flops */
67 PetscLogDouble petsc_tmp_flops       = 0.0;  /* The incremental number of flops */
68 PetscLogDouble petsc_send_ct         = 0.0;  /* The number of sends */
69 PetscLogDouble petsc_recv_ct         = 0.0;  /* The number of receives */
70 PetscLogDouble petsc_send_len        = 0.0;  /* The total length of all sent messages */
71 PetscLogDouble petsc_recv_len        = 0.0;  /* The total length of all received messages */
72 PetscLogDouble petsc_isend_ct        = 0.0;  /* The number of immediate sends */
73 PetscLogDouble petsc_irecv_ct        = 0.0;  /* The number of immediate receives */
74 PetscLogDouble petsc_isend_len       = 0.0;  /* The total length of all immediate send messages */
75 PetscLogDouble petsc_irecv_len       = 0.0;  /* The total length of all immediate receive messages */
76 PetscLogDouble petsc_wait_ct         = 0.0;  /* The number of waits */
77 PetscLogDouble petsc_wait_any_ct     = 0.0;  /* The number of anywaits */
78 PetscLogDouble petsc_wait_all_ct     = 0.0;  /* The number of waitalls */
79 PetscLogDouble petsc_sum_of_waits_ct = 0.0;  /* The total number of waits */
80 PetscLogDouble petsc_allreduce_ct    = 0.0;  /* The number of reductions */
81 PetscLogDouble petsc_gather_ct       = 0.0;  /* The number of gathers and gathervs */
82 PetscLogDouble petsc_scatter_ct      = 0.0;  /* The number of scatters and scattervs */
83 #if defined(PETSC_HAVE_DEVICE)
84 PetscLogDouble petsc_ctog_ct         = 0.0;  /* The total number of CPU to GPU copies */
85 PetscLogDouble petsc_gtoc_ct         = 0.0;  /* The total number of GPU to CPU copies */
86 PetscLogDouble petsc_ctog_sz         = 0.0;  /* The total size of CPU to GPU copies */
87 PetscLogDouble petsc_gtoc_sz         = 0.0;  /* The total size of GPU to CPU copies */
88 PetscLogDouble petsc_gflops          = 0.0;  /* The flops done on a GPU */
89 PetscLogDouble petsc_gtime           = 0.0;  /* The time spent on a GPU */
90 #if defined(PETSC_USE_DEBUG)
91 PetscBool petsc_gtime_inuse = PETSC_FALSE;
92 #endif
93 #endif
94 
95 /* Logging functions */
96 PetscErrorCode (*PetscLogPHC)(PetscObject) = NULL;
97 PetscErrorCode (*PetscLogPHD)(PetscObject) = NULL;
98 PetscErrorCode (*PetscLogPLB)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = NULL;
99 PetscErrorCode (*PetscLogPLE)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = NULL;
100 
101 /* Tracing event logging variables */
102 FILE             *petsc_tracefile            = NULL;
103 int              petsc_tracelevel            = 0;
104 const char       *petsc_traceblanks          = "                                                                                                    ";
105 char             petsc_tracespace[128]       = " ";
106 PetscLogDouble   petsc_tracetime             = 0.0;
107 static PetscBool PetscLogInitializeCalled = PETSC_FALSE;
108 
109 PETSC_INTERN PetscErrorCode PetscLogInitialize(void)
110 {
111   int            stage;
112   PetscBool      opt;
113   PetscErrorCode ierr;
114 
115   PetscFunctionBegin;
116   if (PetscLogInitializeCalled) PetscFunctionReturn(0);
117   PetscLogInitializeCalled = PETSC_TRUE;
118 
119   ierr = PetscOptionsHasName(NULL,NULL, "-log_exclude_actions", &opt);CHKERRQ(ierr);
120   if (opt) petsc_logActions = PETSC_FALSE;
121   ierr = PetscOptionsHasName(NULL,NULL, "-log_exclude_objects", &opt);CHKERRQ(ierr);
122   if (opt) petsc_logObjects = PETSC_FALSE;
123   if (petsc_logActions) {
124     ierr = PetscMalloc1(petsc_maxActions, &petsc_actions);CHKERRQ(ierr);
125   }
126   if (petsc_logObjects) {
127     ierr = PetscMalloc1(petsc_maxObjects, &petsc_objects);CHKERRQ(ierr);
128   }
129   PetscLogPHC = PetscLogObjCreateDefault;
130   PetscLogPHD = PetscLogObjDestroyDefault;
131   /* Setup default logging structures */
132   ierr = PetscStageLogCreate(&petsc_stageLog);CHKERRQ(ierr);
133   ierr = PetscStageLogRegister(petsc_stageLog, "Main Stage", &stage);CHKERRQ(ierr);
134 
135   /* All processors sync here for more consistent logging */
136   ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRMPI(ierr);
137   PetscTime(&petsc_BaseTime);
138   ierr = PetscLogStagePush(stage);CHKERRQ(ierr);
139   PetscFunctionReturn(0);
140 }
141 
142 PETSC_INTERN PetscErrorCode PetscLogFinalize(void)
143 {
144   PetscStageLog  stageLog;
145   PetscErrorCode ierr;
146 
147   PetscFunctionBegin;
148   ierr = PetscFree(petsc_actions);CHKERRQ(ierr);
149   ierr = PetscFree(petsc_objects);CHKERRQ(ierr);
150   ierr = PetscLogNestedEnd();CHKERRQ(ierr);
151   ierr = PetscLogSet(NULL, NULL);CHKERRQ(ierr);
152 
153   /* Resetting phase */
154   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
155   ierr = PetscStageLogDestroy(stageLog);CHKERRQ(ierr);
156 
157   petsc_TotalFlops            = 0.0;
158   petsc_numActions            = 0;
159   petsc_numObjects            = 0;
160   petsc_numObjectsDestroyed   = 0;
161   petsc_maxActions            = 100;
162   petsc_maxObjects            = 100;
163   petsc_actions               = NULL;
164   petsc_objects               = NULL;
165   petsc_logActions            = PETSC_FALSE;
166   petsc_logObjects            = PETSC_FALSE;
167   petsc_BaseTime              = 0.0;
168   petsc_TotalFlops            = 0.0;
169   petsc_tmp_flops             = 0.0;
170   petsc_send_ct               = 0.0;
171   petsc_recv_ct               = 0.0;
172   petsc_send_len              = 0.0;
173   petsc_recv_len              = 0.0;
174   petsc_isend_ct              = 0.0;
175   petsc_irecv_ct              = 0.0;
176   petsc_isend_len             = 0.0;
177   petsc_irecv_len             = 0.0;
178   petsc_wait_ct               = 0.0;
179   petsc_wait_any_ct           = 0.0;
180   petsc_wait_all_ct           = 0.0;
181   petsc_sum_of_waits_ct       = 0.0;
182   petsc_allreduce_ct          = 0.0;
183   petsc_gather_ct             = 0.0;
184   petsc_scatter_ct            = 0.0;
185   #if defined(PETSC_HAVE_DEVICE)
186   petsc_ctog_ct               = 0.0;
187   petsc_gtoc_ct               = 0.0;
188   petsc_ctog_sz               = 0.0;
189   petsc_gtoc_sz               = 0.0;
190   petsc_gflops                = 0.0;
191   petsc_gtime                 = 0.0;
192   #endif
193   PETSC_LARGEST_EVENT         = PETSC_EVENT;
194   PetscLogPHC                 = NULL;
195   PetscLogPHD                 = NULL;
196   petsc_tracefile             = NULL;
197   petsc_tracelevel            = 0;
198   petsc_traceblanks           = "                                                                                                    ";
199   petsc_tracespace[0]         = ' '; petsc_tracespace[1] = 0;
200   petsc_tracetime             = 0.0;
201   PETSC_LARGEST_CLASSID       = PETSC_SMALLEST_CLASSID;
202   PETSC_OBJECT_CLASSID        = 0;
203   petsc_stageLog              = NULL;
204   PetscLogInitializeCalled    = PETSC_FALSE;
205   PetscFunctionReturn(0);
206 }
207 
208 /*@C
209   PetscLogSet - Sets the logging functions called at the beginning and ending of every event.
210 
211   Not Collective
212 
213   Input Parameters:
214 + b - The function called at beginning of event
215 - e - The function called at end of event
216 
217   Level: developer
218 
219 .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
220 @*/
221 PetscErrorCode  PetscLogSet(PetscErrorCode (*b)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject),
222                             PetscErrorCode (*e)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject))
223 {
224   PetscFunctionBegin;
225   PetscLogPLB = b;
226   PetscLogPLE = e;
227   PetscFunctionReturn(0);
228 }
229 
230 /*@C
231   PetscLogDefaultBegin - Turns on logging of objects and events. This logs flop
232   rates and object creation and should not slow programs down too much.
233   This routine may be called more than once.
234 
235   Logically Collective over PETSC_COMM_WORLD
236 
237   Options Database Keys:
238 . -log_view [viewertype:filename:viewerformat] - Prints summary of flop and timing information to the
239                   screen (for code configured with --with-log=1 (which is the default))
240 
241   Usage:
242 .vb
243       PetscInitialize(...);
244       PetscLogDefaultBegin();
245        ... code ...
246       PetscLogView(viewer); or PetscLogDump();
247       PetscFinalize();
248 .ve
249 
250   Notes:
251   PetscLogView(viewer) or PetscLogDump() actually cause the printing of
252   the logging information.
253 
254   Level: advanced
255 
256 .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogTraceBegin()
257 @*/
258 PetscErrorCode  PetscLogDefaultBegin(void)
259 {
260   PetscErrorCode ierr;
261 
262   PetscFunctionBegin;
263   ierr = PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);CHKERRQ(ierr);
264   PetscFunctionReturn(0);
265 }
266 
267 /*@C
268   PetscLogAllBegin - Turns on extensive logging of objects and events. Logs
269   all events. This creates large log files and slows the program down.
270 
271   Logically Collective on PETSC_COMM_WORLD
272 
273   Options Database Keys:
274 . -log_all - Prints extensive log information
275 
276   Usage:
277 .vb
278      PetscInitialize(...);
279      PetscLogAllBegin();
280      ... code ...
281      PetscLogDump(filename);
282      PetscFinalize();
283 .ve
284 
285   Notes:
286   A related routine is PetscLogDefaultBegin() (with the options key -log), which is
287   intended for production runs since it logs only flop rates and object
288   creation (and shouldn't significantly slow the programs).
289 
290   Level: advanced
291 
292 .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogTraceBegin()
293 @*/
294 PetscErrorCode  PetscLogAllBegin(void)
295 {
296   PetscErrorCode ierr;
297 
298   PetscFunctionBegin;
299   ierr = PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);CHKERRQ(ierr);
300   PetscFunctionReturn(0);
301 }
302 
303 /*@C
304   PetscLogTraceBegin - Activates trace logging.  Every time a PETSc event
305   begins or ends, the event name is printed.
306 
307   Logically Collective on PETSC_COMM_WORLD
308 
309   Input Parameter:
310 . file - The file to print trace in (e.g. stdout)
311 
312   Options Database Key:
313 . -log_trace [filename] - Activates PetscLogTraceBegin()
314 
315   Notes:
316   PetscLogTraceBegin() prints the processor number, the execution time (sec),
317   then "Event begin:" or "Event end:" followed by the event name.
318 
319   PetscLogTraceBegin() allows tracing of all PETSc calls, which is useful
320   to determine where a program is hanging without running in the
321   debugger.  Can be used in conjunction with the -info option.
322 
323   Level: intermediate
324 
325 .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogDefaultBegin()
326 @*/
327 PetscErrorCode  PetscLogTraceBegin(FILE *file)
328 {
329   PetscErrorCode ierr;
330 
331   PetscFunctionBegin;
332   petsc_tracefile = file;
333 
334   ierr = PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);CHKERRQ(ierr);
335   PetscFunctionReturn(0);
336 }
337 
338 /*@
339   PetscLogActions - Determines whether actions are logged for the graphical viewer.
340 
341   Not Collective
342 
343   Input Parameter:
344 . flag - PETSC_TRUE if actions are to be logged
345 
346   Level: intermediate
347 
348   Note: Logging of actions continues to consume more memory as the program
349   runs. Long running programs should consider turning this feature off.
350 
351   Options Database Keys:
352 . -log_exclude_actions - Turns off actions logging
353 
354 .seealso: PetscLogStagePush(), PetscLogStagePop()
355 @*/
356 PetscErrorCode  PetscLogActions(PetscBool flag)
357 {
358   PetscFunctionBegin;
359   petsc_logActions = flag;
360   PetscFunctionReturn(0);
361 }
362 
363 /*@
364   PetscLogObjects - Determines whether objects are logged for the graphical viewer.
365 
366   Not Collective
367 
368   Input Parameter:
369 . flag - PETSC_TRUE if objects are to be logged
370 
371   Level: intermediate
372 
373   Note: Logging of objects continues to consume more memory as the program
374   runs. Long running programs should consider turning this feature off.
375 
376   Options Database Keys:
377 . -log_exclude_objects - Turns off objects logging
378 
379 .seealso: PetscLogStagePush(), PetscLogStagePop()
380 @*/
381 PetscErrorCode  PetscLogObjects(PetscBool flag)
382 {
383   PetscFunctionBegin;
384   petsc_logObjects = flag;
385   PetscFunctionReturn(0);
386 }
387 
388 /*------------------------------------------------ Stage Functions --------------------------------------------------*/
389 /*@C
390   PetscLogStageRegister - Attaches a character string name to a logging stage.
391 
392   Not Collective
393 
394   Input Parameter:
395 . sname - The name to associate with that stage
396 
397   Output Parameter:
398 . stage - The stage number
399 
400   Level: intermediate
401 
402 .seealso: PetscLogStagePush(), PetscLogStagePop()
403 @*/
404 PetscErrorCode  PetscLogStageRegister(const char sname[],PetscLogStage *stage)
405 {
406   PetscStageLog  stageLog;
407   PetscLogEvent  event;
408   PetscErrorCode ierr;
409 
410   PetscFunctionBegin;
411   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
412   ierr = PetscStageLogRegister(stageLog, sname, stage);CHKERRQ(ierr);
413   /* Copy events already changed in the main stage, this sucks */
414   ierr = PetscEventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);CHKERRQ(ierr);
415   for (event = 0; event < stageLog->eventLog->numEvents; event++) {
416     ierr = PetscEventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],&stageLog->stageInfo[*stage].eventLog->eventInfo[event]);CHKERRQ(ierr);
417   }
418   ierr = PetscClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);CHKERRQ(ierr);
419   PetscFunctionReturn(0);
420 }
421 
422 /*@C
423   PetscLogStagePush - This function pushes a stage on the stack.
424 
425   Not Collective
426 
427   Input Parameter:
428 . stage - The stage on which to log
429 
430   Usage:
431   If the option -log_sumary is used to run the program containing the
432   following code, then 2 sets of summary data will be printed during
433   PetscFinalize().
434 .vb
435       PetscInitialize(int *argc,char ***args,0,0);
436       [stage 0 of code]
437       PetscLogStagePush(1);
438       [stage 1 of code]
439       PetscLogStagePop();
440       PetscBarrier(...);
441       [more stage 0 of code]
442       PetscFinalize();
443 .ve
444 
445   Notes:
446   Use PetscLogStageRegister() to register a stage.
447 
448   Level: intermediate
449 
450 .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
451 @*/
452 PetscErrorCode  PetscLogStagePush(PetscLogStage stage)
453 {
454   PetscStageLog  stageLog;
455   PetscErrorCode ierr;
456 
457   PetscFunctionBegin;
458   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
459   ierr = PetscStageLogPush(stageLog, stage);CHKERRQ(ierr);
460   PetscFunctionReturn(0);
461 }
462 
463 /*@C
464   PetscLogStagePop - This function pops a stage from the stack.
465 
466   Not Collective
467 
468   Usage:
469   If the option -log_sumary is used to run the program containing the
470   following code, then 2 sets of summary data will be printed during
471   PetscFinalize().
472 .vb
473       PetscInitialize(int *argc,char ***args,0,0);
474       [stage 0 of code]
475       PetscLogStagePush(1);
476       [stage 1 of code]
477       PetscLogStagePop();
478       PetscBarrier(...);
479       [more stage 0 of code]
480       PetscFinalize();
481 .ve
482 
483   Notes:
484   Use PetscLogStageRegister() to register a stage.
485 
486   Level: intermediate
487 
488 .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
489 @*/
490 PetscErrorCode  PetscLogStagePop(void)
491 {
492   PetscStageLog  stageLog;
493   PetscErrorCode ierr;
494 
495   PetscFunctionBegin;
496   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
497   ierr = PetscStageLogPop(stageLog);CHKERRQ(ierr);
498   PetscFunctionReturn(0);
499 }
500 
501 /*@
502   PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().
503 
504   Not Collective
505 
506   Input Parameters:
507 + stage    - The stage
508 - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
509 
510   Level: intermediate
511 
512 .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
513 @*/
514 PetscErrorCode  PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
515 {
516   PetscStageLog  stageLog;
517   PetscErrorCode ierr;
518 
519   PetscFunctionBegin;
520   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
521   ierr = PetscStageLogSetActive(stageLog, stage, isActive);CHKERRQ(ierr);
522   PetscFunctionReturn(0);
523 }
524 
525 /*@
526   PetscLogStageGetActive - Returns stage activity for PetscLogEventBegin() and PetscLogEventEnd().
527 
528   Not Collective
529 
530   Input Parameter:
531 . stage    - The stage
532 
533   Output Parameter:
534 . isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
535 
536   Level: intermediate
537 
538 .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
539 @*/
540 PetscErrorCode  PetscLogStageGetActive(PetscLogStage stage, PetscBool  *isActive)
541 {
542   PetscStageLog  stageLog;
543   PetscErrorCode ierr;
544 
545   PetscFunctionBegin;
546   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
547   ierr = PetscStageLogGetActive(stageLog, stage, isActive);CHKERRQ(ierr);
548   PetscFunctionReturn(0);
549 }
550 
551 /*@
552   PetscLogStageSetVisible - Determines stage visibility in PetscLogView()
553 
554   Not Collective
555 
556   Input Parameters:
557 + stage     - The stage
558 - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
559 
560   Level: intermediate
561 
562 .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogView()
563 @*/
564 PetscErrorCode  PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)
565 {
566   PetscStageLog  stageLog;
567   PetscErrorCode ierr;
568 
569   PetscFunctionBegin;
570   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
571   ierr = PetscStageLogSetVisible(stageLog, stage, isVisible);CHKERRQ(ierr);
572   PetscFunctionReturn(0);
573 }
574 
575 /*@
576   PetscLogStageGetVisible - Returns stage visibility in PetscLogView()
577 
578   Not Collective
579 
580   Input Parameter:
581 . stage     - The stage
582 
583   Output Parameter:
584 . isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
585 
586   Level: intermediate
587 
588 .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogView()
589 @*/
590 PetscErrorCode  PetscLogStageGetVisible(PetscLogStage stage, PetscBool  *isVisible)
591 {
592   PetscStageLog  stageLog;
593   PetscErrorCode ierr;
594 
595   PetscFunctionBegin;
596   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
597   ierr = PetscStageLogGetVisible(stageLog, stage, isVisible);CHKERRQ(ierr);
598   PetscFunctionReturn(0);
599 }
600 
601 /*@C
602   PetscLogStageGetId - Returns the stage id when given the stage name.
603 
604   Not Collective
605 
606   Input Parameter:
607 . name  - The stage name
608 
609   Output Parameter:
610 . stage - The stage, , or -1 if no stage with that name exists
611 
612   Level: intermediate
613 
614 .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
615 @*/
616 PetscErrorCode  PetscLogStageGetId(const char name[], PetscLogStage *stage)
617 {
618   PetscStageLog  stageLog;
619   PetscErrorCode ierr;
620 
621   PetscFunctionBegin;
622   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
623   ierr = PetscStageLogGetStage(stageLog, name, stage);CHKERRQ(ierr);
624   PetscFunctionReturn(0);
625 }
626 
627 /*------------------------------------------------ Event Functions --------------------------------------------------*/
628 /*@C
629   PetscLogEventRegister - Registers an event name for logging operations in an application code.
630 
631   Not Collective
632 
633   Input Parameter:
634 + name   - The name associated with the event
635 - classid - The classid associated to the class for this event, obtain either with
636            PetscClassIdRegister() or use a predefined one such as KSP_CLASSID, SNES_CLASSID, the predefined ones
637            are only available in C code
638 
639   Output Parameter:
640 . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().
641 
642   Example of Usage:
643 .vb
644       PetscLogEvent USER_EVENT;
645       PetscClassId classid;
646       PetscLogDouble user_event_flops;
647       PetscClassIdRegister("class name",&classid);
648       PetscLogEventRegister("User event name",classid,&USER_EVENT);
649       PetscLogEventBegin(USER_EVENT,0,0,0,0);
650          [code segment to monitor]
651          PetscLogFlops(user_event_flops);
652       PetscLogEventEnd(USER_EVENT,0,0,0,0);
653 .ve
654 
655   Notes:
656   PETSc automatically logs library events if the code has been
657   configured with --with-log (which is the default) and
658   -log_view or -log_all is specified.  PetscLogEventRegister() is
659   intended for logging user events to supplement this PETSc
660   information.
661 
662   PETSc can gather data for use with the utilities Jumpshot
663   (part of the MPICH distribution).  If PETSc has been compiled
664   with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
665   MPICH), the user can employ another command line option, -log_mpe,
666   to create a logfile, "mpe.log", which can be visualized
667   Jumpshot.
668 
669   The classid is associated with each event so that classes of events
670   can be disabled simultaneously, such as all matrix events. The user
671   can either use an existing classid, such as MAT_CLASSID, or create
672   their own as shown in the example.
673 
674   If an existing event with the same name exists, its event handle is
675   returned instead of creating a new event.
676 
677   Level: intermediate
678 
679 .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
680           PetscLogEventActivate(), PetscLogEventDeactivate(), PetscClassIdRegister()
681 @*/
682 PetscErrorCode  PetscLogEventRegister(const char name[],PetscClassId classid,PetscLogEvent *event)
683 {
684   PetscStageLog  stageLog;
685   int            stage;
686   PetscErrorCode ierr;
687 
688   PetscFunctionBegin;
689   *event = PETSC_DECIDE;
690   ierr   = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
691   ierr   = PetscEventRegLogGetEvent(stageLog->eventLog, name, event);CHKERRQ(ierr);
692   if (*event > 0) PetscFunctionReturn(0);
693   ierr   = PetscEventRegLogRegister(stageLog->eventLog, name, classid, event);CHKERRQ(ierr);
694   for (stage = 0; stage < stageLog->numStages; stage++) {
695     ierr = PetscEventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);CHKERRQ(ierr);
696     ierr = PetscClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);CHKERRQ(ierr);
697   }
698   PetscFunctionReturn(0);
699 }
700 
701 /*@
702   PetscLogEventSetCollective - Indicates that a particular event is collective.
703 
704   Not Collective
705 
706   Input Parameter:
707 + event - The event id
708 - collective - Bolean flag indicating whether a particular event is collective
709 
710   Note:
711   New events returned from PetscLogEventRegister() are collective by default.
712 
713   Level: developer
714 
715 .seealso: PetscLogEventRegister()
716 @*/
717 PetscErrorCode PetscLogEventSetCollective(PetscLogEvent event,PetscBool collective)
718 {
719   PetscStageLog    stageLog;
720   PetscEventRegLog eventRegLog;
721   PetscErrorCode   ierr;
722 
723   PetscFunctionBegin;
724   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
725   ierr = PetscStageLogGetEventRegLog(stageLog,&eventRegLog);CHKERRQ(ierr);
726   if (event < 0 || event > eventRegLog->numEvents) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid event id");
727   eventRegLog->eventInfo[event].collective = collective;
728   PetscFunctionReturn(0);
729 }
730 
731 /*@
732   PetscLogEventIncludeClass - Activates event logging for a PETSc object class in every stage.
733 
734   Not Collective
735 
736   Input Parameter:
737 . classid - The object class, for example MAT_CLASSID, SNES_CLASSID, etc.
738 
739   Level: developer
740 
741 .seealso: PetscLogEventActivateClass(),PetscLogEventDeactivateClass(),PetscLogEventActivate(),PetscLogEventDeactivate()
742 @*/
743 PetscErrorCode  PetscLogEventIncludeClass(PetscClassId classid)
744 {
745   PetscStageLog  stageLog;
746   int            stage;
747   PetscErrorCode ierr;
748 
749   PetscFunctionBegin;
750   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
751   for (stage = 0; stage < stageLog->numStages; stage++) {
752     ierr = PetscEventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);CHKERRQ(ierr);
753   }
754   PetscFunctionReturn(0);
755 }
756 
757 /*@
758   PetscLogEventExcludeClass - Deactivates event logging for a PETSc object class in every stage.
759 
760   Not Collective
761 
762   Input Parameter:
763 . classid - The object class, for example MAT_CLASSID, SNES_CLASSID, etc.
764 
765   Level: developer
766 
767 .seealso: PetscLogEventDeactivateClass(),PetscLogEventActivateClass(),PetscLogEventDeactivate(),PetscLogEventActivate()
768 @*/
769 PetscErrorCode  PetscLogEventExcludeClass(PetscClassId classid)
770 {
771   PetscStageLog  stageLog;
772   int            stage;
773   PetscErrorCode ierr;
774 
775   PetscFunctionBegin;
776   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
777   for (stage = 0; stage < stageLog->numStages; stage++) {
778     ierr = PetscEventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);CHKERRQ(ierr);
779   }
780   PetscFunctionReturn(0);
781 }
782 
783 /*@
784   PetscLogEventActivate - Indicates that a particular event should be logged.
785 
786   Not Collective
787 
788   Input Parameter:
789 . event - The event id
790 
791   Usage:
792 .vb
793       PetscLogEventDeactivate(VEC_SetValues);
794         [code where you do not want to log VecSetValues()]
795       PetscLogEventActivate(VEC_SetValues);
796         [code where you do want to log VecSetValues()]
797 .ve
798 
799   Note:
800   The event may be either a pre-defined PETSc event (found in include/petsclog.h)
801   or an event number obtained with PetscLogEventRegister().
802 
803   Level: advanced
804 
805 .seealso: PlogEventDeactivate(), PlogEventDeactivatePush(), PetscLogEventDeactivatePop()
806 @*/
807 PetscErrorCode  PetscLogEventActivate(PetscLogEvent event)
808 {
809   PetscStageLog  stageLog;
810   int            stage;
811   PetscErrorCode ierr;
812 
813   PetscFunctionBegin;
814   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
815   ierr = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr);
816   ierr = PetscEventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);CHKERRQ(ierr);
817   PetscFunctionReturn(0);
818 }
819 
820 /*@
821   PetscLogEventDeactivate - Indicates that a particular event should not be logged.
822 
823   Not Collective
824 
825   Input Parameter:
826 . event - The event id
827 
828   Usage:
829 .vb
830       PetscLogEventDeactivate(VEC_SetValues);
831         [code where you do not want to log VecSetValues()]
832       PetscLogEventActivate(VEC_SetValues);
833         [code where you do want to log VecSetValues()]
834 .ve
835 
836   Note:
837   The event may be either a pre-defined PETSc event (found in
838   include/petsclog.h) or an event number obtained with PetscLogEventRegister()).
839 
840   Level: advanced
841 
842 .seealso: PetscLogEventActivate(), PetscLogEventDeactivatePush(), PetscLogEventDeactivatePop()
843 @*/
844 PetscErrorCode  PetscLogEventDeactivate(PetscLogEvent event)
845 {
846   PetscStageLog  stageLog;
847   int            stage;
848   PetscErrorCode ierr;
849 
850   PetscFunctionBegin;
851   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
852   ierr = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr);
853   ierr = PetscEventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);CHKERRQ(ierr);
854   PetscFunctionReturn(0);
855 }
856 
857 /*@
858   PetscLogEventDeactivatePush - Indicates that a particular event should not be logged.
859 
860   Not Collective
861 
862   Input Parameter:
863 . event - The event id
864 
865   Usage:
866 .vb
867       PetscLogEventDeactivatePush(VEC_SetValues);
868         [code where you do not want to log VecSetValues()]
869       PetscLogEventDeactivatePop(VEC_SetValues);
870         [code where you do want to log VecSetValues()]
871 .ve
872 
873   Note:
874   The event may be either a pre-defined PETSc event (found in
875   include/petsclog.h) or an event number obtained with PetscLogEventRegister()).
876 
877   Level: advanced
878 
879 .seealso: PetscLogEventActivate(), PetscLogEventDeactivatePop()
880 @*/
881 PetscErrorCode  PetscLogEventDeactivatePush(PetscLogEvent event)
882 {
883   PetscStageLog  stageLog;
884   int            stage;
885   PetscErrorCode ierr;
886 
887   PetscFunctionBegin;
888   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
889   ierr = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr);
890   ierr = PetscEventPerfLogDeactivatePush(stageLog->stageInfo[stage].eventLog, event);CHKERRQ(ierr);
891   PetscFunctionReturn(0);
892 }
893 
894 /*@
895   PetscLogEventDeactivatePop - Indicates that a particular event shouldbe logged.
896 
897   Not Collective
898 
899   Input Parameter:
900 . event - The event id
901 
902   Usage:
903 .vb
904       PetscLogEventDeactivatePush(VEC_SetValues);
905         [code where you do not want to log VecSetValues()]
906       PetscLogEventDeactivatePop(VEC_SetValues);
907         [code where you do want to log VecSetValues()]
908 .ve
909 
910   Note:
911   The event may be either a pre-defined PETSc event (found in
912   include/petsclog.h) or an event number obtained with PetscLogEventRegister()).
913 
914   Level: advanced
915 
916 .seealso: PetscLogEventActivate(), PetscLogEventDeactivatePush()
917 @*/
918 PetscErrorCode  PetscLogEventDeactivatePop(PetscLogEvent event)
919 {
920   PetscStageLog  stageLog;
921   int            stage;
922   PetscErrorCode ierr;
923 
924   PetscFunctionBegin;
925   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
926   ierr = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr);
927   ierr = PetscEventPerfLogDeactivatePop(stageLog->stageInfo[stage].eventLog, event);CHKERRQ(ierr);
928   PetscFunctionReturn(0);
929 }
930 
931 /*@
932   PetscLogEventSetActiveAll - Sets the event activity in every stage.
933 
934   Not Collective
935 
936   Input Parameters:
937 + event    - The event id
938 - isActive - The activity flag determining whether the event is logged
939 
940   Level: advanced
941 
942 .seealso: PlogEventActivate(),PlogEventDeactivate()
943 @*/
944 PetscErrorCode  PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
945 {
946   PetscStageLog  stageLog;
947   int            stage;
948   PetscErrorCode ierr;
949 
950   PetscFunctionBegin;
951   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
952   for (stage = 0; stage < stageLog->numStages; stage++) {
953     if (isActive) {
954       ierr = PetscEventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);CHKERRQ(ierr);
955     } else {
956       ierr = PetscEventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);CHKERRQ(ierr);
957     }
958   }
959   PetscFunctionReturn(0);
960 }
961 
962 /*@
963   PetscLogEventActivateClass - Activates event logging for a PETSc object class.
964 
965   Not Collective
966 
967   Input Parameter:
968 . classid - The event class, for example MAT_CLASSID, SNES_CLASSID, etc.
969 
970   Level: developer
971 
972 .seealso: PetscLogEventDeactivateClass(),PetscLogEventActivate(),PetscLogEventDeactivate()
973 @*/
974 PetscErrorCode  PetscLogEventActivateClass(PetscClassId classid)
975 {
976   PetscStageLog  stageLog;
977   int            stage;
978   PetscErrorCode ierr;
979 
980   PetscFunctionBegin;
981   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
982   ierr = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr);
983   ierr = PetscEventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);CHKERRQ(ierr);
984   PetscFunctionReturn(0);
985 }
986 
987 /*@
988   PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.
989 
990   Not Collective
991 
992   Input Parameter:
993 . classid - The event class, for example MAT_CLASSID, SNES_CLASSID, etc.
994 
995   Level: developer
996 
997 .seealso: PetscLogEventActivateClass(),PetscLogEventActivate(),PetscLogEventDeactivate()
998 @*/
999 PetscErrorCode  PetscLogEventDeactivateClass(PetscClassId classid)
1000 {
1001   PetscStageLog  stageLog;
1002   int            stage;
1003   PetscErrorCode ierr;
1004 
1005   PetscFunctionBegin;
1006   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
1007   ierr = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr);
1008   ierr = PetscEventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);CHKERRQ(ierr);
1009   PetscFunctionReturn(0);
1010 }
1011 
1012 /*MC
1013    PetscLogEventSync - Synchronizes the beginning of a user event.
1014 
1015    Synopsis:
1016    #include <petsclog.h>
1017    PetscErrorCode PetscLogEventSync(int e,MPI_Comm comm)
1018 
1019    Collective
1020 
1021    Input Parameters:
1022 +  e - integer associated with the event obtained from PetscLogEventRegister()
1023 -  comm - an MPI communicator
1024 
1025    Usage:
1026 .vb
1027      PetscLogEvent USER_EVENT;
1028      PetscLogEventRegister("User event",0,&USER_EVENT);
1029      PetscLogEventSync(USER_EVENT,PETSC_COMM_WORLD);
1030      PetscLogEventBegin(USER_EVENT,0,0,0,0);
1031         [code segment to monitor]
1032      PetscLogEventEnd(USER_EVENT,0,0,0,0);
1033 .ve
1034 
1035    Notes:
1036    This routine should be called only if there is not a
1037    PetscObject available to pass to PetscLogEventBegin().
1038 
1039    Level: developer
1040 
1041 .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd()
1042 
1043 M*/
1044 
1045 /*MC
1046    PetscLogEventBegin - Logs the beginning of a user event.
1047 
1048    Synopsis:
1049    #include <petsclog.h>
1050    PetscErrorCode PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)
1051 
1052    Not Collective
1053 
1054    Input Parameters:
1055 +  e - integer associated with the event obtained from PetscLogEventRegister()
1056 -  o1,o2,o3,o4 - objects associated with the event, or 0
1057 
1058 
1059    Fortran Synopsis:
1060    void PetscLogEventBegin(int e,PetscErrorCode ierr)
1061 
1062    Usage:
1063 .vb
1064      PetscLogEvent USER_EVENT;
1065      PetscLogDouble user_event_flops;
1066      PetscLogEventRegister("User event",0,&USER_EVENT);
1067      PetscLogEventBegin(USER_EVENT,0,0,0,0);
1068         [code segment to monitor]
1069         PetscLogFlops(user_event_flops);
1070      PetscLogEventEnd(USER_EVENT,0,0,0,0);
1071 .ve
1072 
1073    Notes:
1074    You need to register each integer event with the command
1075    PetscLogEventRegister().
1076 
1077    Level: intermediate
1078 
1079 .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops()
1080 
1081 M*/
1082 
1083 /*MC
1084    PetscLogEventEnd - Log the end of a user event.
1085 
1086    Synopsis:
1087    #include <petsclog.h>
1088    PetscErrorCode PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)
1089 
1090    Not Collective
1091 
1092    Input Parameters:
1093 +  e - integer associated with the event obtained with PetscLogEventRegister()
1094 -  o1,o2,o3,o4 - objects associated with the event, or 0
1095 
1096 
1097    Fortran Synopsis:
1098    void PetscLogEventEnd(int e,PetscErrorCode ierr)
1099 
1100    Usage:
1101 .vb
1102      PetscLogEvent USER_EVENT;
1103      PetscLogDouble user_event_flops;
1104      PetscLogEventRegister("User event",0,&USER_EVENT,);
1105      PetscLogEventBegin(USER_EVENT,0,0,0,0);
1106         [code segment to monitor]
1107         PetscLogFlops(user_event_flops);
1108      PetscLogEventEnd(USER_EVENT,0,0,0,0);
1109 .ve
1110 
1111    Notes:
1112    You should also register each additional integer event with the command
1113    PetscLogEventRegister().
1114 
1115    Level: intermediate
1116 
1117 .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogFlops()
1118 
1119 M*/
1120 
1121 /*@C
1122   PetscLogEventGetId - Returns the event id when given the event name.
1123 
1124   Not Collective
1125 
1126   Input Parameter:
1127 . name  - The event name
1128 
1129   Output Parameter:
1130 . event - The event, or -1 if no event with that name exists
1131 
1132   Level: intermediate
1133 
1134 .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStageGetId()
1135 @*/
1136 PetscErrorCode  PetscLogEventGetId(const char name[], PetscLogEvent *event)
1137 {
1138   PetscStageLog  stageLog;
1139   PetscErrorCode ierr;
1140 
1141   PetscFunctionBegin;
1142   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
1143   ierr = PetscEventRegLogGetEvent(stageLog->eventLog, name, event);CHKERRQ(ierr);
1144   PetscFunctionReturn(0);
1145 }
1146 
1147 
1148 /*------------------------------------------------ Output Functions -------------------------------------------------*/
1149 /*@C
1150   PetscLogDump - Dumps logs of objects to a file. This file is intended to
1151   be read by bin/petscview. This program no longer exists.
1152 
1153   Collective on PETSC_COMM_WORLD
1154 
1155   Input Parameter:
1156 . name - an optional file name
1157 
1158   Usage:
1159 .vb
1160      PetscInitialize(...);
1161      PetscLogDefaultBegin(); or PetscLogAllBegin();
1162      ... code ...
1163      PetscLogDump(filename);
1164      PetscFinalize();
1165 .ve
1166 
1167   Notes:
1168   The default file name is
1169 $    Log.<rank>
1170   where <rank> is the processor number. If no name is specified,
1171   this file will be used.
1172 
1173   Level: advanced
1174 
1175 .seealso: PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogView()
1176 @*/
1177 PetscErrorCode  PetscLogDump(const char sname[])
1178 {
1179   PetscStageLog      stageLog;
1180   PetscEventPerfInfo *eventInfo;
1181   FILE               *fd;
1182   char               file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1183   PetscLogDouble     flops, _TotalTime;
1184   PetscMPIInt        rank;
1185   int                action, object, curStage;
1186   PetscLogEvent      event;
1187   PetscErrorCode     ierr;
1188 
1189   PetscFunctionBegin;
1190   /* Calculate the total elapsed time */
1191   PetscTime(&_TotalTime);
1192   _TotalTime -= petsc_BaseTime;
1193   /* Open log file */
1194   ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);CHKERRMPI(ierr);
1195   if (sname && sname[0]) sprintf(file, "%s.%d", sname, rank);
1196   else sprintf(file, "Log.%d", rank);
1197   ierr = PetscFixFilename(file, fname);CHKERRQ(ierr);
1198   ierr = PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);CHKERRQ(ierr);
1199   if ((!rank) && (!fd)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1200   /* Output totals */
1201   ierr = PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flop %14e %16.8e\n", petsc_TotalFlops, _TotalTime);CHKERRQ(ierr);
1202   ierr = PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0);CHKERRQ(ierr);
1203   /* Output actions */
1204   if (petsc_logActions) {
1205     ierr = PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", petsc_numActions);CHKERRQ(ierr);
1206     for (action = 0; action < petsc_numActions; action++) {
1207       ierr = PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n",
1208                           petsc_actions[action].time, petsc_actions[action].action, (int)petsc_actions[action].event, (int)petsc_actions[action].classid, petsc_actions[action].id1,
1209                           petsc_actions[action].id2, petsc_actions[action].id3, petsc_actions[action].flops, petsc_actions[action].mem, petsc_actions[action].maxmem);CHKERRQ(ierr);
1210     }
1211   }
1212   /* Output objects */
1213   if (petsc_logObjects) {
1214     ierr = PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", petsc_numObjects, petsc_numObjectsDestroyed);CHKERRQ(ierr);
1215     for (object = 0; object < petsc_numObjects; object++) {
1216       ierr = PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", petsc_objects[object].parent, (int) petsc_objects[object].mem);CHKERRQ(ierr);
1217       if (!petsc_objects[object].name[0]) {
1218         ierr = PetscFPrintf(PETSC_COMM_WORLD, fd,"No Name\n");CHKERRQ(ierr);
1219       } else {
1220         ierr = PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", petsc_objects[object].name);CHKERRQ(ierr);
1221       }
1222       if (petsc_objects[object].info[0] != 0) {
1223         ierr = PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n");CHKERRQ(ierr);
1224       } else {
1225         ierr = PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", petsc_objects[object].info);CHKERRQ(ierr);
1226       }
1227     }
1228   }
1229   /* Output events */
1230   ierr = PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:\n");CHKERRQ(ierr);
1231   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
1232   ierr = PetscIntStackTop(stageLog->stack, &curStage);CHKERRQ(ierr);
1233   eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1234   for (event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1235     if (eventInfo[event].time != 0.0) flops = eventInfo[event].flops/eventInfo[event].time;
1236     else flops = 0.0;
1237     ierr = PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16g\n", event, eventInfo[event].count,
1238                         eventInfo[event].flops, eventInfo[event].time, flops);CHKERRQ(ierr);
1239   }
1240   ierr = PetscFClose(PETSC_COMM_WORLD, fd);CHKERRQ(ierr);
1241   PetscFunctionReturn(0);
1242 }
1243 
1244 /*
1245   PetscLogView_Detailed - Each process prints the times for its own events
1246 
1247 */
1248 PetscErrorCode  PetscLogView_Detailed(PetscViewer viewer)
1249 {
1250   PetscStageLog      stageLog;
1251   PetscEventPerfInfo *eventInfo = NULL, *stageInfo = NULL;
1252   PetscLogDouble     locTotalTime, numRed, maxMem;
1253   int                numStages,numEvents,stage,event;
1254   MPI_Comm           comm = PetscObjectComm((PetscObject) viewer);
1255   PetscMPIInt        rank,size;
1256   PetscErrorCode     ierr;
1257 
1258   PetscFunctionBegin;
1259   ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr);
1260   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
1261   /* Must preserve reduction count before we go on */
1262   numRed = petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
1263   /* Get the total elapsed time */
1264   PetscTime(&locTotalTime);  locTotalTime -= petsc_BaseTime;
1265   ierr = PetscViewerASCIIPrintf(viewer,"size = %d\n",size);CHKERRQ(ierr);
1266   ierr = PetscViewerASCIIPrintf(viewer,"LocalTimes = {}\n");CHKERRQ(ierr);
1267   ierr = PetscViewerASCIIPrintf(viewer,"LocalMessages = {}\n");CHKERRQ(ierr);
1268   ierr = PetscViewerASCIIPrintf(viewer,"LocalMessageLens = {}\n");CHKERRQ(ierr);
1269   ierr = PetscViewerASCIIPrintf(viewer,"LocalReductions = {}\n");CHKERRQ(ierr);
1270   ierr = PetscViewerASCIIPrintf(viewer,"LocalFlop = {}\n");CHKERRQ(ierr);
1271   ierr = PetscViewerASCIIPrintf(viewer,"LocalObjects = {}\n");CHKERRQ(ierr);
1272   ierr = PetscViewerASCIIPrintf(viewer,"LocalMemory = {}\n");CHKERRQ(ierr);
1273   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
1274   ierr = MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);CHKERRMPI(ierr);
1275   ierr = PetscViewerASCIIPrintf(viewer,"Stages = {}\n");CHKERRQ(ierr);
1276   for (stage=0; stage<numStages; stage++) {
1277     ierr = PetscViewerASCIIPrintf(viewer,"Stages[\"%s\"] = {}\n",stageLog->stageInfo[stage].name);CHKERRQ(ierr);
1278     ierr = PetscViewerASCIIPrintf(viewer,"Stages[\"%s\"][\"summary\"] = {}\n",stageLog->stageInfo[stage].name);CHKERRQ(ierr);
1279     ierr = MPI_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);CHKERRMPI(ierr);
1280     for (event = 0; event < numEvents; event++) {
1281       ierr = PetscViewerASCIIPrintf(viewer,"Stages[\"%s\"][\"%s\"] = {}\n",stageLog->stageInfo[stage].name,stageLog->eventLog->eventInfo[event].name);CHKERRQ(ierr);
1282     }
1283   }
1284   ierr = PetscMallocGetMaximumUsage(&maxMem);CHKERRQ(ierr);
1285   ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
1286   ierr = PetscViewerASCIISynchronizedPrintf(viewer,"LocalTimes[%d] = %g\n",rank,locTotalTime);CHKERRQ(ierr);
1287   ierr = PetscViewerASCIISynchronizedPrintf(viewer,"LocalMessages[%d] = %g\n",rank,(petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct));CHKERRQ(ierr);
1288   ierr = PetscViewerASCIISynchronizedPrintf(viewer,"LocalMessageLens[%d] = %g\n",rank,(petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len));CHKERRQ(ierr);
1289   ierr = PetscViewerASCIISynchronizedPrintf(viewer,"LocalReductions[%d] = %g\n",rank,numRed);CHKERRQ(ierr);
1290   ierr = PetscViewerASCIISynchronizedPrintf(viewer,"LocalFlop[%d] = %g\n",rank,petsc_TotalFlops);CHKERRQ(ierr);
1291   ierr = PetscViewerASCIISynchronizedPrintf(viewer,"LocalObjects[%d] = %d\n",rank,petsc_numObjects);CHKERRQ(ierr);
1292   ierr = PetscViewerASCIISynchronizedPrintf(viewer,"LocalMemory[%d] = %g\n",rank,maxMem);CHKERRQ(ierr);
1293   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
1294   for (stage=0; stage<numStages; stage++) {
1295     stageInfo = &stageLog->stageInfo[stage].perfInfo;
1296     ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Stages[\"%s\"][\"summary\"][%d] = {\"time\" : %g, \"numMessages\" : %g, \"messageLength\" : %g, \"numReductions\" : %g, \"flop\" : %g}\n",
1297                                               stageLog->stageInfo[stage].name,rank,
1298                                               stageInfo->time,stageInfo->numMessages,stageInfo->messageLength,stageInfo->numReductions,stageInfo->flops);CHKERRQ(ierr);
1299     ierr = MPI_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);CHKERRMPI(ierr);
1300     for (event = 0; event < numEvents; event++) {
1301       eventInfo = &stageLog->stageInfo[stage].eventLog->eventInfo[event];
1302       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Stages[\"%s\"][\"%s\"][%d] = {\"count\" : %D, \"time\" : %g, \"syncTime\" : %g, \"numMessages\" : %g, \"messageLength\" : %g, \"numReductions\" : %g, \"flop\" : %g",
1303                                                 stageLog->stageInfo[stage].name,stageLog->eventLog->eventInfo[event].name,rank,
1304                                                 eventInfo->count,eventInfo->time,eventInfo->syncTime,eventInfo->numMessages,eventInfo->messageLength,eventInfo->numReductions,eventInfo->flops);CHKERRQ(ierr);
1305       if (eventInfo->dof[0] >= 0.) {
1306         PetscInt d, e;
1307 
1308         ierr = PetscViewerASCIISynchronizedPrintf(viewer, ", \"dof\" : [");CHKERRQ(ierr);
1309         for (d = 0; d < 8; ++d) {
1310           if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ", ");CHKERRQ(ierr);}
1311           ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", eventInfo->dof[d]);CHKERRQ(ierr);
1312         }
1313         ierr = PetscViewerASCIISynchronizedPrintf(viewer, "]");CHKERRQ(ierr);
1314         ierr = PetscViewerASCIISynchronizedPrintf(viewer, ", \"error\" : [");CHKERRQ(ierr);
1315         for (e = 0; e < 8; ++e) {
1316           if (e > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ", ");CHKERRQ(ierr);}
1317           ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", eventInfo->errors[e]);CHKERRQ(ierr);
1318         }
1319         ierr = PetscViewerASCIISynchronizedPrintf(viewer, "]");CHKERRQ(ierr);
1320       }
1321       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"}\n");CHKERRQ(ierr);
1322     }
1323   }
1324   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
1325   ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr);
1326   PetscFunctionReturn(0);
1327 }
1328 
1329 /*
1330   PetscLogView_CSV - Each process prints the times for its own events in Comma-Separated Value Format
1331 */
1332 PetscErrorCode  PetscLogView_CSV(PetscViewer viewer)
1333 {
1334   PetscStageLog      stageLog;
1335   PetscEventPerfInfo *eventInfo = NULL;
1336   PetscLogDouble     locTotalTime, maxMem;
1337   int                numStages,numEvents,stage,event;
1338   MPI_Comm           comm = PetscObjectComm((PetscObject) viewer);
1339   PetscMPIInt        rank,size;
1340   PetscErrorCode     ierr;
1341 
1342   PetscFunctionBegin;
1343   ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr);
1344   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
1345   /* Must preserve reduction count before we go on */
1346   /* Get the total elapsed time */
1347   PetscTime(&locTotalTime);  locTotalTime -= petsc_BaseTime;
1348   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
1349   ierr = MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);CHKERRMPI(ierr);
1350   ierr = PetscMallocGetMaximumUsage(&maxMem);CHKERRQ(ierr);
1351   ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
1352   ierr = PetscViewerASCIIPrintf(viewer,"Stage Name,Event Name,Rank,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);
1353   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
1354   for (stage=0; stage<numStages; stage++) {
1355     PetscEventPerfInfo *stageInfo = &stageLog->stageInfo[stage].perfInfo;
1356 
1357     ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%s,summary,%d,%g,%g,%g,%g,%g\n",
1358                                               stageLog->stageInfo[stage].name,rank,stageInfo->time,stageInfo->numMessages,stageInfo->messageLength,stageInfo->numReductions,stageInfo->flops);CHKERRQ(ierr);
1359     ierr = MPI_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);CHKERRMPI(ierr);
1360     for (event = 0; event < numEvents; event++) {
1361       eventInfo = &stageLog->stageInfo[stage].eventLog->eventInfo[event];
1362       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%s,%s,%d,%g,%g,%g,%g,%g",stageLog->stageInfo[stage].name,
1363                                                 stageLog->eventLog->eventInfo[event].name,rank,eventInfo->time,eventInfo->numMessages,
1364                                                 eventInfo->messageLength,eventInfo->numReductions,eventInfo->flops);CHKERRQ(ierr);
1365       if (eventInfo->dof[0] >= 0.) {
1366         PetscInt d, e;
1367 
1368         for (d = 0; d < 8; ++d) {
1369           ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",%g", eventInfo->dof[d]);CHKERRQ(ierr);
1370         }
1371         for (e = 0; e < 8; ++e) {
1372           ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",%g", eventInfo->errors[e]);CHKERRQ(ierr);
1373         }
1374       }
1375       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr);
1376     }
1377   }
1378   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
1379   ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr);
1380   PetscFunctionReturn(0);
1381 }
1382 
1383 static PetscErrorCode PetscLogViewWarnSync(MPI_Comm comm,FILE *fd)
1384 {
1385   PetscErrorCode ierr;
1386   PetscFunctionBegin;
1387   if (!PetscLogSyncOn) PetscFunctionReturn(0);
1388   ierr = PetscFPrintf(comm, fd, "\n\n");CHKERRQ(ierr);
1389   ierr = PetscFPrintf(comm, fd, "      ##########################################################\n");CHKERRQ(ierr);
1390   ierr = PetscFPrintf(comm, fd, "      #                                                        #\n");CHKERRQ(ierr);
1391   ierr = PetscFPrintf(comm, fd, "      #                       WARNING!!!                       #\n");CHKERRQ(ierr);
1392   ierr = PetscFPrintf(comm, fd, "      #                                                        #\n");CHKERRQ(ierr);
1393   ierr = PetscFPrintf(comm, fd, "      #   This program was run with logging synchronization.   #\n");CHKERRQ(ierr);
1394   ierr = PetscFPrintf(comm, fd, "      #   This option provides more meaningful imbalance       #\n");CHKERRQ(ierr);
1395   ierr = PetscFPrintf(comm, fd, "      #   figures at the expense of slowing things down and    #\n");CHKERRQ(ierr);
1396   ierr = PetscFPrintf(comm, fd, "      #   providing a distorted view of the overall runtime.   #\n");CHKERRQ(ierr);
1397   ierr = PetscFPrintf(comm, fd, "      #                                                        #\n");CHKERRQ(ierr);
1398   ierr = PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");CHKERRQ(ierr);
1399   PetscFunctionReturn(0);
1400 }
1401 
1402 static PetscErrorCode PetscLogViewWarnDebugging(MPI_Comm comm,FILE *fd)
1403 {
1404   PetscErrorCode ierr;
1405 
1406   PetscFunctionBegin;
1407   if (PetscDefined(USE_DEBUG)) {
1408     ierr = PetscFPrintf(comm, fd, "\n\n");CHKERRQ(ierr);
1409     ierr = PetscFPrintf(comm, fd, "      ##########################################################\n");CHKERRQ(ierr);
1410     ierr = PetscFPrintf(comm, fd, "      #                                                        #\n");CHKERRQ(ierr);
1411     ierr = PetscFPrintf(comm, fd, "      #                       WARNING!!!                       #\n");CHKERRQ(ierr);
1412     ierr = PetscFPrintf(comm, fd, "      #                                                        #\n");CHKERRQ(ierr);
1413     ierr = PetscFPrintf(comm, fd, "      #   This code was compiled with a debugging option.      #\n");CHKERRQ(ierr);
1414     ierr = PetscFPrintf(comm, fd, "      #   To get timing results run ./configure                #\n");CHKERRQ(ierr);
1415     ierr = PetscFPrintf(comm, fd, "      #   using --with-debugging=no, the performance will      #\n");CHKERRQ(ierr);
1416     ierr = PetscFPrintf(comm, fd, "      #   be generally two or three times faster.              #\n");CHKERRQ(ierr);
1417     ierr = PetscFPrintf(comm, fd, "      #                                                        #\n");CHKERRQ(ierr);
1418     ierr = PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");CHKERRQ(ierr);
1419   }
1420   PetscFunctionReturn(0);
1421 }
1422 
1423 static PetscErrorCode PetscLogViewWarnNoGpuAwareMpi(MPI_Comm comm,FILE *fd)
1424 {
1425 #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1426   PetscErrorCode ierr;
1427 
1428   PetscFunctionBegin;
1429   if (use_gpu_aware_mpi || !PetscCreatedGpuObjects) PetscFunctionReturn(0);
1430   ierr = PetscFPrintf(comm, fd, "\n\n");CHKERRQ(ierr);
1431   ierr = PetscFPrintf(comm, fd, "      ##########################################################\n");CHKERRQ(ierr);
1432   ierr = PetscFPrintf(comm, fd, "      #                                                        #\n");CHKERRQ(ierr);
1433   ierr = PetscFPrintf(comm, fd, "      #                       WARNING!!!                       #\n");CHKERRQ(ierr);
1434   ierr = PetscFPrintf(comm, fd, "      #                                                        #\n");CHKERRQ(ierr);
1435   ierr = PetscFPrintf(comm, fd, "      # This code was compiled with GPU support and you've     #\n");CHKERRQ(ierr);
1436   ierr = PetscFPrintf(comm, fd, "      # created PETSc/GPU objects, but you intentionally used  #\n");CHKERRQ(ierr);
1437   ierr = PetscFPrintf(comm, fd, "      # -use_gpu_aware_mpi 0, such that PETSc had to copy data #\n");CHKERRQ(ierr);
1438   ierr = PetscFPrintf(comm, fd, "      # from GPU to CPU for communication. To get meaningfull  #\n");CHKERRQ(ierr);
1439   ierr = PetscFPrintf(comm, fd, "      # timing results, please use GPU-aware MPI instead.      #\n");CHKERRQ(ierr);
1440   ierr = PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");CHKERRQ(ierr);
1441   PetscFunctionReturn(0);
1442 #else
1443   return 0;
1444 #endif
1445 }
1446 
1447 #if defined(PETSC_HAVE_OPENMP)
1448 extern PetscInt PetscNumOMPThreads;
1449 #endif
1450 
1451 PetscErrorCode  PetscLogView_Default(PetscViewer viewer)
1452 {
1453   FILE               *fd;
1454   PetscLogDouble     zero       = 0.0;
1455   PetscStageLog      stageLog;
1456   PetscStageInfo     *stageInfo = NULL;
1457   PetscEventPerfInfo *eventInfo = NULL;
1458   PetscClassPerfInfo *classInfo;
1459   char               arch[128],hostname[128],username[128],pname[PETSC_MAX_PATH_LEN],date[128];
1460   const char         *name;
1461   PetscLogDouble     locTotalTime, TotalTime, TotalFlops;
1462   PetscLogDouble     numMessages, messageLength, avgMessLen, numReductions;
1463   PetscLogDouble     stageTime, flops, flopr, mem, mess, messLen, red;
1464   PetscLogDouble     fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1465   PetscLogDouble     fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1466   PetscLogDouble     min, max, tot, ratio, avg, x, y;
1467   PetscLogDouble     minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratC, totm, totml, totr, mal, malmax, emalmax;
1468   #if defined(PETSC_HAVE_DEVICE)
1469   PetscLogDouble     cct, gct, csz, gsz, gmaxt, gflops, gflopr, fracgflops;
1470   #endif
1471   PetscMPIInt        minC, maxC;
1472   PetscMPIInt        size, rank;
1473   PetscBool          *localStageUsed,    *stageUsed;
1474   PetscBool          *localStageVisible, *stageVisible;
1475   int                numStages, localNumEvents, numEvents;
1476   int                stage, oclass;
1477   PetscLogEvent      event;
1478   PetscErrorCode     ierr;
1479   char               version[256];
1480   MPI_Comm           comm;
1481 
1482   PetscFunctionBegin;
1483   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
1484   ierr = PetscViewerASCIIGetPointer(viewer,&fd);CHKERRQ(ierr);
1485   ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr);
1486   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
1487   /* Get the total elapsed time */
1488   PetscTime(&locTotalTime);  locTotalTime -= petsc_BaseTime;
1489 
1490   ierr = PetscFPrintf(comm, fd, "************************************************************************************************************************\n");CHKERRQ(ierr);
1491   ierr = PetscFPrintf(comm, fd, "***             WIDEN YOUR WINDOW TO 120 CHARACTERS.  Use 'enscript -r -fCourier9' to print this document            ***\n");CHKERRQ(ierr);
1492   ierr = PetscFPrintf(comm, fd, "************************************************************************************************************************\n");CHKERRQ(ierr);
1493   ierr = PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");CHKERRQ(ierr);
1494   ierr = PetscLogViewWarnSync(comm,fd);CHKERRQ(ierr);
1495   ierr = PetscLogViewWarnDebugging(comm,fd);CHKERRQ(ierr);
1496   ierr = PetscLogViewWarnNoGpuAwareMpi(comm,fd);CHKERRQ(ierr);
1497   ierr = PetscGetArchType(arch,sizeof(arch));CHKERRQ(ierr);
1498   ierr = PetscGetHostName(hostname,sizeof(hostname));CHKERRQ(ierr);
1499   ierr = PetscGetUserName(username,sizeof(username));CHKERRQ(ierr);
1500   ierr = PetscGetProgramName(pname,sizeof(pname));CHKERRQ(ierr);
1501   ierr = PetscGetDate(date,sizeof(date));CHKERRQ(ierr);
1502   ierr = PetscGetVersion(version,sizeof(version));CHKERRQ(ierr);
1503   if (size == 1) {
1504     ierr = PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);CHKERRQ(ierr);
1505   } else {
1506     ierr = PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);CHKERRQ(ierr);
1507   }
1508 #if defined(PETSC_HAVE_OPENMP)
1509   ierr = PetscFPrintf(comm,fd,"Using %D OpenMP threads\n", PetscNumOMPThreads);CHKERRQ(ierr);
1510 #endif
1511   ierr = PetscFPrintf(comm, fd, "Using %s\n", version);CHKERRQ(ierr);
1512 
1513   /* Must preserve reduction count before we go on */
1514   red = petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
1515 
1516   /* Calculate summary information */
1517   ierr = PetscFPrintf(comm, fd, "\n                         Max       Max/Min     Avg       Total\n");CHKERRQ(ierr);
1518   /*   Time */
1519   ierr = MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRMPI(ierr);
1520   ierr = MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRMPI(ierr);
1521   ierr = MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1522   avg  = tot/((PetscLogDouble) size);
1523   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1524   ierr = PetscFPrintf(comm, fd, "Time (sec):           %5.3e   %7.3f   %5.3e\n", max, ratio, avg);CHKERRQ(ierr);
1525   TotalTime = tot;
1526   /*   Objects */
1527   avg  = (PetscLogDouble) petsc_numObjects;
1528   ierr = MPI_Allreduce(&avg,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRMPI(ierr);
1529   ierr = MPI_Allreduce(&avg,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRMPI(ierr);
1530   ierr = MPI_Allreduce(&avg,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1531   avg  = tot/((PetscLogDouble) size);
1532   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1533   ierr = PetscFPrintf(comm, fd, "Objects:              %5.3e   %7.3f   %5.3e\n", max, ratio, avg);CHKERRQ(ierr);
1534   /*   Flops */
1535   ierr = MPI_Allreduce(&petsc_TotalFlops,  &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRMPI(ierr);
1536   ierr = MPI_Allreduce(&petsc_TotalFlops,  &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRMPI(ierr);
1537   ierr = MPI_Allreduce(&petsc_TotalFlops,  &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1538   avg  = tot/((PetscLogDouble) size);
1539   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1540   ierr = PetscFPrintf(comm, fd, "Flop:                 %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);CHKERRQ(ierr);
1541   TotalFlops = tot;
1542   /*   Flops/sec -- Must talk to Barry here */
1543   if (locTotalTime != 0.0) flops = petsc_TotalFlops/locTotalTime; else flops = 0.0;
1544   ierr = MPI_Allreduce(&flops,        &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRMPI(ierr);
1545   ierr = MPI_Allreduce(&flops,        &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRMPI(ierr);
1546   ierr = MPI_Allreduce(&flops,        &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1547   avg  = tot/((PetscLogDouble) size);
1548   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1549   ierr = PetscFPrintf(comm, fd, "Flop/sec:             %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);CHKERRQ(ierr);
1550   /*   Memory */
1551   ierr = PetscMallocGetMaximumUsage(&mem);CHKERRQ(ierr);
1552   if (mem > 0.0) {
1553     ierr = MPI_Allreduce(&mem,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRMPI(ierr);
1554     ierr = MPI_Allreduce(&mem,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRMPI(ierr);
1555     ierr = MPI_Allreduce(&mem,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1556     avg  = tot/((PetscLogDouble) size);
1557     if (min != 0.0) ratio = max/min; else ratio = 0.0;
1558     ierr = PetscFPrintf(comm, fd, "Memory:               %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);CHKERRQ(ierr);
1559   }
1560   /*   Messages */
1561   mess = 0.5*(petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct);
1562   ierr = MPI_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRMPI(ierr);
1563   ierr = MPI_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRMPI(ierr);
1564   ierr = MPI_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1565   avg  = tot/((PetscLogDouble) size);
1566   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1567   ierr = PetscFPrintf(comm, fd, "MPI Messages:         %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);CHKERRQ(ierr);
1568   numMessages = tot;
1569   /*   Message Lengths */
1570   mess = 0.5*(petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len);
1571   ierr = MPI_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRMPI(ierr);
1572   ierr = MPI_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRMPI(ierr);
1573   ierr = MPI_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1574   if (numMessages != 0) avg = tot/numMessages; else avg = 0.0;
1575   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1576   ierr = PetscFPrintf(comm, fd, "MPI Message Lengths:  %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);CHKERRQ(ierr);
1577   messageLength = tot;
1578   /*   Reductions */
1579   ierr = MPI_Allreduce(&red,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRMPI(ierr);
1580   ierr = MPI_Allreduce(&red,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRMPI(ierr);
1581   ierr = MPI_Allreduce(&red,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1582   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1583   ierr = PetscFPrintf(comm, fd, "MPI Reductions:       %5.3e   %7.3f\n", max, ratio);CHKERRQ(ierr);
1584   numReductions = red; /* wrong because uses count from process zero */
1585   ierr = PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");CHKERRQ(ierr);
1586   ierr = PetscFPrintf(comm, fd, "                            e.g., VecAXPY() for real vectors of length N --> 2N flop\n");CHKERRQ(ierr);
1587   ierr = PetscFPrintf(comm, fd, "                            and VecAXPY() for complex vectors of length N --> 8N flop\n");CHKERRQ(ierr);
1588 
1589   /* Get total number of stages --
1590        Currently, a single processor can register more stages than another, but stages must all be registered in order.
1591        We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1592        This seems best accomplished by assoicating a communicator with each stage.
1593   */
1594   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
1595   ierr = MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);CHKERRMPI(ierr);
1596   ierr = PetscMalloc1(numStages, &localStageUsed);CHKERRQ(ierr);
1597   ierr = PetscMalloc1(numStages, &stageUsed);CHKERRQ(ierr);
1598   ierr = PetscMalloc1(numStages, &localStageVisible);CHKERRQ(ierr);
1599   ierr = PetscMalloc1(numStages, &stageVisible);CHKERRQ(ierr);
1600   if (numStages > 0) {
1601     stageInfo = stageLog->stageInfo;
1602     for (stage = 0; stage < numStages; stage++) {
1603       if (stage < stageLog->numStages) {
1604         localStageUsed[stage]    = stageInfo[stage].used;
1605         localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1606       } else {
1607         localStageUsed[stage]    = PETSC_FALSE;
1608         localStageVisible[stage] = PETSC_TRUE;
1609       }
1610     }
1611     ierr = MPI_Allreduce(localStageUsed,    stageUsed,    numStages, MPIU_BOOL, MPI_LOR,  comm);CHKERRMPI(ierr);
1612     ierr = MPI_Allreduce(localStageVisible, stageVisible, numStages, MPIU_BOOL, MPI_LAND, comm);CHKERRMPI(ierr);
1613     for (stage = 0; stage < numStages; stage++) {
1614       if (stageUsed[stage]) {
1615         ierr = PetscFPrintf(comm, fd, "\nSummary of Stages:   ----- Time ------  ----- Flop ------  --- Messages ---  -- Message Lengths --  -- Reductions --\n");CHKERRQ(ierr);
1616         ierr = PetscFPrintf(comm, fd, "                        Avg     %%Total     Avg     %%Total    Count   %%Total     Avg         %%Total    Count   %%Total\n");CHKERRQ(ierr);
1617         break;
1618       }
1619     }
1620     for (stage = 0; stage < numStages; stage++) {
1621       if (!stageUsed[stage]) continue;
1622       /* CANNOT use MPI_Allreduce() since it might fail the line number check */
1623       if (localStageUsed[stage]) {
1624         ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1625         ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1626         ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1627         ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1628         ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1629         name = stageInfo[stage].name;
1630       } else {
1631         ierr = MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1632         ierr = MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1633         ierr = MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1634         ierr = MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1635         ierr = MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1636         name = "";
1637       }
1638       mess *= 0.5; messLen *= 0.5; red /= size;
1639       if (TotalTime     != 0.0) fracTime       = stageTime/TotalTime;    else fracTime       = 0.0;
1640       if (TotalFlops    != 0.0) fracFlops      = flops/TotalFlops;       else fracFlops      = 0.0;
1641       /* Talk to Barry if (stageTime     != 0.0) flops          = (size*flops)/stageTime; else flops          = 0.0; */
1642       if (numMessages   != 0.0) fracMessages   = mess/numMessages;       else fracMessages   = 0.0;
1643       if (mess          != 0.0) avgMessLen     = messLen/mess;           else avgMessLen     = 0.0;
1644       if (messageLength != 0.0) fracLength     = messLen/messageLength;  else fracLength     = 0.0;
1645       if (numReductions != 0.0) fracReductions = red/numReductions;      else fracReductions = 0.0;
1646       ierr = 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",
1647                           stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1648                           mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);CHKERRQ(ierr);
1649     }
1650   }
1651 
1652   ierr = PetscFPrintf(comm, fd,"\n------------------------------------------------------------------------------------------------------------------------\n");CHKERRQ(ierr);
1653   ierr = PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");CHKERRQ(ierr);
1654   ierr = PetscFPrintf(comm, fd, "Phase summary info:\n");CHKERRQ(ierr);
1655   ierr = PetscFPrintf(comm, fd, "   Count: number of times phase was executed\n");CHKERRQ(ierr);
1656   ierr = PetscFPrintf(comm, fd, "   Time and Flop: Max - maximum over all processors\n");CHKERRQ(ierr);
1657   ierr = PetscFPrintf(comm, fd, "                  Ratio - ratio of maximum to minimum over all processors\n");CHKERRQ(ierr);
1658   ierr = PetscFPrintf(comm, fd, "   Mess: number of messages sent\n");CHKERRQ(ierr);
1659   ierr = PetscFPrintf(comm, fd, "   AvgLen: average message length (bytes)\n");CHKERRQ(ierr);
1660   ierr = PetscFPrintf(comm, fd, "   Reduct: number of global reductions\n");CHKERRQ(ierr);
1661   ierr = PetscFPrintf(comm, fd, "   Global: entire computation\n");CHKERRQ(ierr);
1662   ierr = PetscFPrintf(comm, fd, "   Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");CHKERRQ(ierr);
1663   ierr = PetscFPrintf(comm, fd, "      %%T - percent time in this phase         %%F - percent flop in this phase\n");CHKERRQ(ierr);
1664   ierr = PetscFPrintf(comm, fd, "      %%M - percent messages in this phase     %%L - percent message lengths in this phase\n");CHKERRQ(ierr);
1665   ierr = PetscFPrintf(comm, fd, "      %%R - percent reductions in this phase\n");CHKERRQ(ierr);
1666   ierr = PetscFPrintf(comm, fd, "   Total Mflop/s: 10e-6 * (sum of flop over all processors)/(max time over all processors)\n");CHKERRQ(ierr);
1667   if (PetscLogMemory) {
1668     ierr = PetscFPrintf(comm, fd, "   Malloc Mbytes: Memory allocated and kept during event (sum over all calls to event)\n");CHKERRQ(ierr);
1669     ierr = PetscFPrintf(comm, fd, "   EMalloc Mbytes: extra memory allocated during event and then freed (maximum over all calls to events)\n");CHKERRQ(ierr);
1670     ierr = PetscFPrintf(comm, fd, "   MMalloc Mbytes: Increase in high water mark of allocated memory (sum over all calls to event)\n");CHKERRQ(ierr);
1671     ierr = PetscFPrintf(comm, fd, "   RMI Mbytes: Increase in resident memory (sum over all calls to event)\n");CHKERRQ(ierr);
1672   }
1673   #if defined(PETSC_HAVE_DEVICE)
1674   ierr = PetscFPrintf(comm, fd, "   GPU Mflop/s: 10e-6 * (sum of flop on GPU over all processors)/(max GPU time over all processors)\n");CHKERRQ(ierr);
1675   ierr = PetscFPrintf(comm, fd, "   CpuToGpu Count: total number of CPU to GPU copies per processor\n");CHKERRQ(ierr);
1676   ierr = PetscFPrintf(comm, fd, "   CpuToGpu Size (Mbytes): 10e-6 * (total size of CPU to GPU copies per processor)\n");CHKERRQ(ierr);
1677   ierr = PetscFPrintf(comm, fd, "   GpuToCpu Count: total number of GPU to CPU copies per processor\n");CHKERRQ(ierr);
1678   ierr = PetscFPrintf(comm, fd, "   GpuToCpu Size (Mbytes): 10e-6 * (total size of GPU to CPU copies per processor)\n");CHKERRQ(ierr);
1679   ierr = PetscFPrintf(comm, fd, "   GPU %%F: percent flops on GPU in this event\n");CHKERRQ(ierr);
1680   #endif
1681   ierr = PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------\n");CHKERRQ(ierr);
1682 
1683   ierr = PetscLogViewWarnDebugging(comm,fd);CHKERRQ(ierr);
1684 
1685   /* Report events */
1686   ierr = PetscFPrintf(comm, fd,"Event                Count      Time (sec)     Flop                              --- Global ---  --- Stage ----  Total");CHKERRQ(ierr);
1687   if (PetscLogMemory) {
1688     ierr = PetscFPrintf(comm, fd,"  Malloc EMalloc MMalloc RMI");CHKERRQ(ierr);
1689   }
1690   #if defined(PETSC_HAVE_DEVICE)
1691   ierr = PetscFPrintf(comm, fd,"   GPU    - CpuToGpu -   - GpuToCpu - GPU");CHKERRQ(ierr);
1692   #endif
1693   ierr = PetscFPrintf(comm, fd,"\n");CHKERRQ(ierr);
1694   ierr = PetscFPrintf(comm, fd,"                   Max Ratio  Max     Ratio   Max  Ratio  Mess   AvgLen  Reduct  %%T %%F %%M %%L %%R  %%T %%F %%M %%L %%R Mflop/s");CHKERRQ(ierr);
1695   if (PetscLogMemory) {
1696     ierr = PetscFPrintf(comm, fd," Mbytes Mbytes Mbytes Mbytes");CHKERRQ(ierr);
1697   }
1698   #if defined(PETSC_HAVE_DEVICE)
1699   ierr = PetscFPrintf(comm, fd," Mflop/s Count   Size   Count   Size  %%F");CHKERRQ(ierr);
1700   #endif
1701   ierr = PetscFPrintf(comm, fd,"\n");CHKERRQ(ierr);
1702   ierr = PetscFPrintf(comm, fd,"------------------------------------------------------------------------------------------------------------------------");CHKERRQ(ierr);
1703   if (PetscLogMemory) {
1704     ierr = PetscFPrintf(comm, fd,"-----------------------------");CHKERRQ(ierr);
1705   }
1706   #if defined(PETSC_HAVE_DEVICE)
1707   ierr = PetscFPrintf(comm, fd,"---------------------------------------");CHKERRQ(ierr);
1708   #endif
1709   ierr = PetscFPrintf(comm, fd,"\n");CHKERRQ(ierr);
1710 
1711   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1712   for (stage = 0; stage < numStages; stage++) {
1713     if (!stageVisible[stage]) continue;
1714     /* CANNOT use MPI_Allreduce() since it might fail the line number check */
1715     if (localStageUsed[stage]) {
1716       ierr = PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);CHKERRQ(ierr);
1717       ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1718       ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1719       ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1720       ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1721       ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1722     } else {
1723       ierr = PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);CHKERRQ(ierr);
1724       ierr = MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1725       ierr = MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1726       ierr = MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1727       ierr = MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1728       ierr = MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1729     }
1730     mess *= 0.5; messLen *= 0.5; red /= size;
1731 
1732     /* Get total number of events in this stage --
1733        Currently, a single processor can register more events than another, but events must all be registered in order,
1734        just like stages. We can removed this requirement if necessary by having a global event numbering and indirection
1735        on the event ID. This seems best accomplished by associating a communicator with each stage.
1736 
1737        Problem: If the event did not happen on proc 1, its name will not be available.
1738        Problem: Event visibility is not implemented
1739     */
1740     if (localStageUsed[stage]) {
1741       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1742       localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1743     } else localNumEvents = 0;
1744     ierr = MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);CHKERRMPI(ierr);
1745     for (event = 0; event < numEvents; event++) {
1746       /* CANNOT use MPI_Allreduce() since it might fail the line number check */
1747       if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) {
1748         if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) flopr = eventInfo[event].flops; else flopr = 0.0;
1749         ierr = MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRMPI(ierr);
1750         ierr = MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRMPI(ierr);
1751         ierr = MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1752         ierr = MPI_Allreduce(&eventInfo[event].time,          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRMPI(ierr);
1753         ierr = MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRMPI(ierr);
1754         ierr = MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1755         ierr = MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1756         ierr = MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1757         ierr = MPI_Allreduce(&eventInfo[event].numReductions, &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1758         ierr = MPI_Allreduce(&eventInfo[event].count,         &minC,  1, MPI_INT,             MPI_MIN, comm);CHKERRMPI(ierr);
1759         ierr = MPI_Allreduce(&eventInfo[event].count,         &maxC,  1, MPI_INT,             MPI_MAX, comm);CHKERRMPI(ierr);
1760         if (PetscLogMemory) {
1761           ierr  = MPI_Allreduce(&eventInfo[event].memIncrease,    &mem,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1762           ierr  = MPI_Allreduce(&eventInfo[event].mallocSpace,    &mal,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1763           ierr  = MPI_Allreduce(&eventInfo[event].mallocIncrease, &malmax,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1764           ierr  = MPI_Allreduce(&eventInfo[event].mallocIncreaseEvent, &emalmax,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1765         }
1766         #if defined(PETSC_HAVE_DEVICE)
1767         ierr  = MPI_Allreduce(&eventInfo[event].CpuToGpuCount,    &cct,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1768         ierr  = MPI_Allreduce(&eventInfo[event].GpuToCpuCount,    &gct,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1769         ierr  = MPI_Allreduce(&eventInfo[event].CpuToGpuSize,     &csz,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1770         ierr  = MPI_Allreduce(&eventInfo[event].GpuToCpuSize,     &gsz,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1771         ierr  = MPI_Allreduce(&eventInfo[event].GpuFlops,         &gflops,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1772         ierr  = MPI_Allreduce(&eventInfo[event].GpuTime,          &gmaxt ,1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRMPI(ierr);
1773         #endif
1774         name = stageLog->eventLog->eventInfo[event].name;
1775       } else {
1776         flopr = 0.0;
1777         ierr  = MPI_Allreduce(&flopr,                         &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRMPI(ierr);
1778         ierr  = MPI_Allreduce(&flopr,                         &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRMPI(ierr);
1779         ierr  = MPI_Allreduce(&zero,                          &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1780         ierr  = MPI_Allreduce(&zero,                          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRMPI(ierr);
1781         ierr  = MPI_Allreduce(&zero,                          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRMPI(ierr);
1782         ierr  = MPI_Allreduce(&zero,                          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1783         ierr  = MPI_Allreduce(&zero,                          &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1784         ierr  = MPI_Allreduce(&zero,                          &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1785         ierr  = MPI_Allreduce(&zero,                          &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1786         ierr  = MPI_Allreduce(&ierr,                          &minC,  1, MPI_INT,             MPI_MIN, comm);CHKERRMPI(ierr);
1787         ierr  = MPI_Allreduce(&ierr,                          &maxC,  1, MPI_INT,             MPI_MAX, comm);CHKERRMPI(ierr);
1788         if (PetscLogMemory) {
1789           ierr  = MPI_Allreduce(&zero,                        &mem,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1790           ierr  = MPI_Allreduce(&zero,                        &mal,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1791           ierr  = MPI_Allreduce(&zero,                        &malmax, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1792           ierr  = MPI_Allreduce(&zero,                        &emalmax,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1793         }
1794         #if defined(PETSC_HAVE_DEVICE)
1795         ierr  = MPI_Allreduce(&zero,                          &cct,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1796         ierr  = MPI_Allreduce(&zero,                          &gct,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1797         ierr  = MPI_Allreduce(&zero,                          &csz,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1798         ierr  = MPI_Allreduce(&zero,                          &gsz,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1799         ierr  = MPI_Allreduce(&zero,                          &gflops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRMPI(ierr);
1800         ierr  = MPI_Allreduce(&zero,                          &gmaxt , 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRMPI(ierr);
1801         #endif
1802         name  = "";
1803       }
1804       if (mint < 0.0) {
1805         ierr = 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);
1806         mint = 0;
1807       }
1808       if (minf < 0.0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Minimum flop %g over all processors for %s is negative! Not possible!",minf,name);
1809       totm *= 0.5; totml *= 0.5; totr /= size;
1810 
1811       if (maxC != 0) {
1812         if (minC          != 0)   ratC             = ((PetscLogDouble)maxC)/minC;else ratC             = 0.0;
1813         if (mint          != 0.0) ratt             = maxt/mint;                  else ratt             = 0.0;
1814         if (minf          != 0.0) ratf             = maxf/minf;                  else ratf             = 0.0;
1815         if (TotalTime     != 0.0) fracTime         = tott/TotalTime;             else fracTime         = 0.0;
1816         if (TotalFlops    != 0.0) fracFlops        = totf/TotalFlops;            else fracFlops        = 0.0;
1817         if (stageTime     != 0.0) fracStageTime    = tott/stageTime;             else fracStageTime    = 0.0;
1818         if (flops         != 0.0) fracStageFlops   = totf/flops;                 else fracStageFlops   = 0.0;
1819         if (numMessages   != 0.0) fracMess         = totm/numMessages;           else fracMess         = 0.0;
1820         if (messageLength != 0.0) fracMessLen      = totml/messageLength;        else fracMessLen      = 0.0;
1821         if (numReductions != 0.0) fracRed          = totr/numReductions;         else fracRed          = 0.0;
1822         if (mess          != 0.0) fracStageMess    = totm/mess;                  else fracStageMess    = 0.0;
1823         if (messLen       != 0.0) fracStageMessLen = totml/messLen;              else fracStageMessLen = 0.0;
1824         if (red           != 0.0) fracStageRed     = totr/red;                   else fracStageRed     = 0.0;
1825         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1826         if (maxt          != 0.0) flopr            = totf/maxt;                  else flopr            = 0.0;
1827         if (fracStageTime > 1.00)  ierr = PetscFPrintf(comm, fd,"Warning -- total time of event greater than time of entire stage -- something is wrong with the timer\n");CHKERRQ(ierr);
1828         ierr = PetscFPrintf(comm, fd,
1829                             "%-16s %7d%4.1f %5.4e%4.1f %3.2e%4.1f %2.1e %2.1e %2.1e%3.0f%3.0f%3.0f%3.0f%3.0f %3.0f%3.0f%3.0f%3.0f%3.0f %5.0f",
1830                             name, maxC, ratC, maxt, ratt, maxf, ratf, totm, totml, totr,
1831                             100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1832                             100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1833                             PetscAbs(flopr)/1.0e6);CHKERRQ(ierr);
1834         if (PetscLogMemory) {
1835           ierr = PetscFPrintf(comm, fd," %5.0f   %5.0f   %5.0f   %5.0f",mal/1.0e6,emalmax/1.0e6,malmax/1.0e6,mem/1.0e6);CHKERRQ(ierr);
1836         }
1837         #if defined(PETSC_HAVE_DEVICE)
1838         if (totf  != 0.0) fracgflops = gflops/totf;  else fracgflops = 0.0;
1839         if (gmaxt != 0.0) gflopr     = gflops/gmaxt; else gflopr     = 0.0;
1840         ierr = PetscFPrintf(comm, fd,"   %5.0f   %4.0f %3.2e %4.0f %3.2e% 3.0f",PetscAbs(gflopr)/1.0e6,cct/size,csz/(1.0e6*size),gct/size,gsz/(1.0e6*size),100.0*fracgflops);CHKERRQ(ierr);
1841         #endif
1842         ierr = PetscFPrintf(comm, fd,"\n");CHKERRQ(ierr);
1843       }
1844     }
1845   }
1846 
1847   /* Memory usage and object creation */
1848   ierr = PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------");CHKERRQ(ierr);
1849   if (PetscLogMemory) {
1850     ierr = PetscFPrintf(comm, fd, "-----------------------------");CHKERRQ(ierr);
1851   }
1852   #if defined(PETSC_HAVE_DEVICE)
1853   ierr = PetscFPrintf(comm, fd, "---------------------------------------");CHKERRQ(ierr);
1854   #endif
1855   ierr = PetscFPrintf(comm, fd, "\n");CHKERRQ(ierr);
1856   ierr = PetscFPrintf(comm, fd, "\n");CHKERRQ(ierr);
1857   ierr = PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");CHKERRQ(ierr);
1858 
1859   /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1860      the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1861      stats for stages local to processor sets.
1862   */
1863   /* We should figure out the longest object name here (now 20 characters) */
1864   ierr = PetscFPrintf(comm, fd, "Object Type          Creations   Destructions     Memory  Descendants' Mem.\n");CHKERRQ(ierr);
1865   ierr = PetscFPrintf(comm, fd, "Reports information only for process 0.\n");CHKERRQ(ierr);
1866   for (stage = 0; stage < numStages; stage++) {
1867     if (localStageUsed[stage]) {
1868       classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1869       ierr = PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);CHKERRQ(ierr);
1870       for (oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1871         if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1872           ierr = PetscFPrintf(comm, fd, "%20s %5d          %5d  %11.0f     %g\n", stageLog->classLog->classInfo[oclass].name,
1873                               classInfo[oclass].creations, classInfo[oclass].destructions, classInfo[oclass].mem,
1874                               classInfo[oclass].descMem);CHKERRQ(ierr);
1875         }
1876       }
1877     } else {
1878       if (!localStageVisible[stage]) continue;
1879       ierr = PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);CHKERRQ(ierr);
1880     }
1881   }
1882 
1883   ierr = PetscFree(localStageUsed);CHKERRQ(ierr);
1884   ierr = PetscFree(stageUsed);CHKERRQ(ierr);
1885   ierr = PetscFree(localStageVisible);CHKERRQ(ierr);
1886   ierr = PetscFree(stageVisible);CHKERRQ(ierr);
1887 
1888   /* Information unrelated to this particular run */
1889   ierr = PetscFPrintf(comm, fd, "========================================================================================================================\n");CHKERRQ(ierr);
1890   PetscTime(&y);
1891   PetscTime(&x);
1892   PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1893   PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1894   ierr = PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);CHKERRQ(ierr);
1895   /* MPI information */
1896   if (size > 1) {
1897     MPI_Status  status;
1898     PetscMPIInt tag;
1899     MPI_Comm    newcomm;
1900 
1901     ierr = MPI_Barrier(comm);CHKERRMPI(ierr);
1902     PetscTime(&x);
1903     ierr = MPI_Barrier(comm);CHKERRMPI(ierr);
1904     ierr = MPI_Barrier(comm);CHKERRMPI(ierr);
1905     ierr = MPI_Barrier(comm);CHKERRMPI(ierr);
1906     ierr = MPI_Barrier(comm);CHKERRMPI(ierr);
1907     ierr = MPI_Barrier(comm);CHKERRMPI(ierr);
1908     PetscTime(&y);
1909     ierr = PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);CHKERRQ(ierr);
1910     ierr = PetscCommDuplicate(comm,&newcomm, &tag);CHKERRQ(ierr);
1911     ierr = MPI_Barrier(comm);CHKERRMPI(ierr);
1912     if (rank) {
1913       ierr = MPI_Recv(NULL, 0, MPI_INT, rank-1,            tag, newcomm, &status);CHKERRMPI(ierr);
1914       ierr = MPI_Send(NULL, 0, MPI_INT, (rank+1)%size, tag, newcomm);CHKERRMPI(ierr);
1915     } else {
1916       PetscTime(&x);
1917       ierr = MPI_Send(NULL, 0, MPI_INT, 1,          tag, newcomm);CHKERRMPI(ierr);
1918       ierr = MPI_Recv(NULL, 0, MPI_INT, size-1, tag, newcomm, &status);CHKERRMPI(ierr);
1919       PetscTime(&y);
1920       ierr = PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);CHKERRQ(ierr);
1921     }
1922     ierr = PetscCommDestroy(&newcomm);CHKERRQ(ierr);
1923   }
1924   ierr = PetscOptionsView(NULL,viewer);CHKERRQ(ierr);
1925 
1926   /* Machine and compile information */
1927 #if defined(PETSC_USE_FORTRAN_KERNELS)
1928   ierr = PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");CHKERRQ(ierr);
1929 #else
1930   ierr = PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");CHKERRQ(ierr);
1931 #endif
1932 #if defined(PETSC_USE_64BIT_INDICES)
1933   ierr = PetscFPrintf(comm, fd, "Compiled with 64 bit PetscInt\n");CHKERRQ(ierr);
1934 #elif defined(PETSC_USE___FLOAT128)
1935   ierr = PetscFPrintf(comm, fd, "Compiled with 32 bit PetscInt\n");CHKERRQ(ierr);
1936 #endif
1937 #if defined(PETSC_USE_REAL_SINGLE)
1938   ierr = PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");CHKERRQ(ierr);
1939 #elif defined(PETSC_USE___FLOAT128)
1940   ierr = PetscFPrintf(comm, fd, "Compiled with 128 bit precision PetscScalar and PetscReal\n");CHKERRQ(ierr);
1941 #endif
1942 #if defined(PETSC_USE_REAL_MAT_SINGLE)
1943   ierr = PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");CHKERRQ(ierr);
1944 #else
1945   ierr = PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");CHKERRQ(ierr);
1946 #endif
1947   ierr = PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d sizeof(PetscInt) %d\n",
1948                       (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar),(int) sizeof(PetscInt));CHKERRQ(ierr);
1949 
1950   ierr = PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);CHKERRQ(ierr);
1951   ierr = PetscFPrintf(comm, fd, "%s", petscmachineinfo);CHKERRQ(ierr);
1952   ierr = PetscFPrintf(comm, fd, "%s", petsccompilerinfo);CHKERRQ(ierr);
1953   ierr = PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);CHKERRQ(ierr);
1954   ierr = PetscFPrintf(comm, fd, "%s", petsclinkerinfo);CHKERRQ(ierr);
1955 
1956   /* Cleanup */
1957   ierr = PetscFPrintf(comm, fd, "\n");CHKERRQ(ierr);
1958   ierr = PetscLogViewWarnNoGpuAwareMpi(comm,fd);CHKERRQ(ierr);
1959   ierr = PetscLogViewWarnDebugging(comm,fd);CHKERRQ(ierr);
1960   PetscFunctionReturn(0);
1961 }
1962 
1963 /*@C
1964   PetscLogView - Prints a summary of the logging.
1965 
1966   Collective over MPI_Comm
1967 
1968   Input Parameter:
1969 .  viewer - an ASCII viewer
1970 
1971   Options Database Keys:
1972 +  -log_view [:filename] - Prints summary of log information
1973 .  -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
1974 .  -log_view :filename.xml:ascii_xml - Saves a summary of the logging information in a nested format (see below for how to view it)
1975 .  -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)
1976 .  -log_all - Saves a file Log.rank for each MPI process with details of each step of the computation
1977 -  -log_trace [filename] - Displays a trace of what each process is doing
1978 
1979   Notes:
1980   It is possible to control the logging programatically but we recommend using the options database approach whenever possible
1981   By default the summary is printed to stdout.
1982 
1983   Before calling this routine you must have called either PetscLogDefaultBegin() or PetscLogNestedBegin()
1984 
1985   If PETSc is configured with --with-logging=0 then this functionality is not available
1986 
1987   To view the nested XML format filename.xml first copy  ${PETSC_DIR}/share/petsc/xml/performance_xml2html.xsl to the current
1988   directory then open filename.xml with your browser. Specific notes for certain browsers
1989 $    Firefox and Internet explorer - simply open the file
1990 $    Google Chrome - you must start up Chrome with the option --allow-file-access-from-files
1991 $    Safari - see https://ccm.net/faq/36342-safari-how-to-enable-local-file-access
1992   or one can use the package http://xmlsoft.org/XSLT/xsltproc2.html to translate the xml file to html and then open it with
1993   your browser.
1994   Alternatively, use the script ${PETSC_DIR}/lib/petsc/bin/petsc-performance-view to automatically open a new browser
1995   window and render the XML log file contents.
1996 
1997   The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij  MARITIME  RESEARCH  INSTITUTE  NETHERLANDS
1998 
1999   The Flame Graph output can be visualised using either the original Flame Graph script (https://github.com/brendangregg/FlameGraph)
2000   or using speedscope (https://www.speedscope.app).
2001   Old XML profiles may be converted into this format using the script ${PETSC_DIR}/lib/petsc/bin/xml2flamegraph.py.
2002 
2003   Level: beginner
2004 
2005 .seealso: PetscLogDefaultBegin(), PetscLogDump()
2006 @*/
2007 PetscErrorCode  PetscLogView(PetscViewer viewer)
2008 {
2009   PetscErrorCode    ierr;
2010   PetscBool         isascii;
2011   PetscViewerFormat format;
2012   int               stage, lastStage;
2013   PetscStageLog     stageLog;
2014 
2015   PetscFunctionBegin;
2016   if (!PetscLogPLB) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Must use -log_view or PetscLogDefaultBegin() before calling this routine");
2017   /* Pop off any stages the user forgot to remove */
2018   lastStage = 0;
2019   ierr      = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
2020   ierr      = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr);
2021   while (stage >= 0) {
2022     lastStage = stage;
2023     ierr      = PetscStageLogPop(stageLog);CHKERRQ(ierr);
2024     ierr      = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr);
2025   }
2026   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
2027   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Currently can only view logging to ASCII");
2028   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
2029   if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO) {
2030     ierr = PetscLogView_Default(viewer);CHKERRQ(ierr);
2031   } else if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
2032     ierr = PetscLogView_Detailed(viewer);CHKERRQ(ierr);
2033   } else if (format == PETSC_VIEWER_ASCII_CSV) {
2034     ierr = PetscLogView_CSV(viewer);CHKERRQ(ierr);
2035   } else if (format == PETSC_VIEWER_ASCII_XML) {
2036     ierr = PetscLogView_Nested(viewer);CHKERRQ(ierr);
2037   } else if (format == PETSC_VIEWER_ASCII_FLAMEGRAPH) {
2038     ierr = PetscLogView_Flamegraph(viewer);CHKERRQ(ierr);
2039   }
2040   ierr = PetscStageLogPush(stageLog, lastStage);CHKERRQ(ierr);
2041   PetscFunctionReturn(0);
2042 }
2043 
2044 /*@C
2045   PetscLogViewFromOptions - Processes command line options to determine if/how a PetscLog is to be viewed.
2046 
2047   Collective on PETSC_COMM_WORLD
2048 
2049   Not normally called by user
2050 
2051   Level: intermediate
2052 
2053 @*/
2054 PetscErrorCode PetscLogViewFromOptions(void)
2055 {
2056   PetscErrorCode    ierr;
2057   PetscViewer       viewer;
2058   PetscBool         flg;
2059   PetscViewerFormat format;
2060 
2061   PetscFunctionBegin;
2062   ierr   = PetscOptionsGetViewer(PETSC_COMM_WORLD,NULL,NULL,"-log_view",&viewer,&format,&flg);CHKERRQ(ierr);
2063   if (flg) {
2064     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
2065     ierr = PetscLogView(viewer);CHKERRQ(ierr);
2066     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
2067     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
2068   }
2069   PetscFunctionReturn(0);
2070 }
2071 
2072 
2073 
2074 /*----------------------------------------------- Counter Functions -------------------------------------------------*/
2075 /*@C
2076    PetscGetFlops - Returns the number of flops used on this processor
2077    since the program began.
2078 
2079    Not Collective
2080 
2081    Output Parameter:
2082    flops - number of floating point operations
2083 
2084    Notes:
2085    A global counter logs all PETSc flop counts.  The user can use
2086    PetscLogFlops() to increment this counter to include flops for the
2087    application code.
2088 
2089    Level: intermediate
2090 
2091 .seealso: PetscTime(), PetscLogFlops()
2092 @*/
2093 PetscErrorCode  PetscGetFlops(PetscLogDouble *flops)
2094 {
2095   PetscFunctionBegin;
2096   *flops = petsc_TotalFlops;
2097   PetscFunctionReturn(0);
2098 }
2099 
2100 PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
2101 {
2102   PetscErrorCode ierr;
2103   size_t         fullLength;
2104   va_list        Argp;
2105 
2106   PetscFunctionBegin;
2107   if (!petsc_logObjects) PetscFunctionReturn(0);
2108   va_start(Argp, format);
2109   ierr = PetscVSNPrintf(petsc_objects[obj->id].info, 64,format,&fullLength, Argp);CHKERRQ(ierr);
2110   va_end(Argp);
2111   PetscFunctionReturn(0);
2112 }
2113 
2114 
2115 /*MC
2116    PetscLogFlops - Adds floating point operations to the global counter.
2117 
2118    Synopsis:
2119    #include <petsclog.h>
2120    PetscErrorCode PetscLogFlops(PetscLogDouble f)
2121 
2122    Not Collective
2123 
2124    Input Parameter:
2125 .  f - flop counter
2126 
2127 
2128    Usage:
2129 .vb
2130      PetscLogEvent USER_EVENT;
2131      PetscLogEventRegister("User event",0,&USER_EVENT);
2132      PetscLogEventBegin(USER_EVENT,0,0,0,0);
2133         [code segment to monitor]
2134         PetscLogFlops(user_flops)
2135      PetscLogEventEnd(USER_EVENT,0,0,0,0);
2136 .ve
2137 
2138    Notes:
2139    A global counter logs all PETSc flop counts.  The user can use
2140    PetscLogFlops() to increment this counter to include flops for the
2141    application code.
2142 
2143    Level: intermediate
2144 
2145 .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()
2146 
2147 M*/
2148 
2149 /*MC
2150    PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice)
2151     to get accurate timings
2152 
2153    Synopsis:
2154    #include <petsclog.h>
2155    void PetscPreLoadBegin(PetscBool  flag,char *name);
2156 
2157    Not Collective
2158 
2159    Input Parameter:
2160 +   flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
2161            with command line option -preload true or -preload false
2162 -   name - name of first stage (lines of code timed separately with -log_view) to
2163            be preloaded
2164 
2165    Usage:
2166 .vb
2167      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2168        lines of code
2169        PetscPreLoadStage("second stage");
2170        lines of code
2171      PetscPreLoadEnd();
2172 .ve
2173 
2174    Notes:
2175     Only works in C/C++, not Fortran
2176 
2177      Flags available within the macro.
2178 +    PetscPreLoadingUsed - true if we are or have done preloading
2179 .    PetscPreLoadingOn - true if it is CURRENTLY doing preload
2180 .    PetscPreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
2181 -    PetscPreLoadMax - number of times it will do the computation, only one when preloading is turned on
2182      The first two variables are available throughout the program, the second two only between the PetscPreLoadBegin()
2183      and PetscPreLoadEnd()
2184 
2185    Level: intermediate
2186 
2187 .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadEnd(), PetscPreLoadStage()
2188 
2189 
2190 M*/
2191 
2192 /*MC
2193    PetscPreLoadEnd - End a segment of code that may be preloaded (run twice)
2194     to get accurate timings
2195 
2196    Synopsis:
2197    #include <petsclog.h>
2198    void PetscPreLoadEnd(void);
2199 
2200    Not Collective
2201 
2202    Usage:
2203 .vb
2204      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2205        lines of code
2206        PetscPreLoadStage("second stage");
2207        lines of code
2208      PetscPreLoadEnd();
2209 .ve
2210 
2211    Notes:
2212     only works in C/C++ not fortran
2213 
2214    Level: intermediate
2215 
2216 .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadStage()
2217 
2218 M*/
2219 
2220 /*MC
2221    PetscPreLoadStage - Start a new segment of code to be timed separately.
2222     to get accurate timings
2223 
2224    Synopsis:
2225    #include <petsclog.h>
2226    void PetscPreLoadStage(char *name);
2227 
2228    Not Collective
2229 
2230    Usage:
2231 .vb
2232      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2233        lines of code
2234        PetscPreLoadStage("second stage");
2235        lines of code
2236      PetscPreLoadEnd();
2237 .ve
2238 
2239    Notes:
2240     only works in C/C++ not fortran
2241 
2242    Level: intermediate
2243 
2244 .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd()
2245 
2246 M*/
2247 
2248 
2249 #else /* end of -DPETSC_USE_LOG section */
2250 
2251 PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
2252 {
2253   PetscFunctionBegin;
2254   PetscFunctionReturn(0);
2255 }
2256 
2257 #endif /* PETSC_USE_LOG*/
2258 
2259 
2260 PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2261 PetscClassId PETSC_OBJECT_CLASSID  = 0;
2262 
2263 /*@C
2264   PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code.
2265 
2266   Not Collective
2267 
2268   Input Parameter:
2269 . name   - The class name
2270 
2271   Output Parameter:
2272 . oclass - The class id or classid
2273 
2274   Level: developer
2275 
2276 @*/
2277 PetscErrorCode  PetscClassIdRegister(const char name[],PetscClassId *oclass)
2278 {
2279 #if defined(PETSC_USE_LOG)
2280   PetscStageLog  stageLog;
2281   PetscInt       stage;
2282   PetscErrorCode ierr;
2283 #endif
2284 
2285   PetscFunctionBegin;
2286   *oclass = ++PETSC_LARGEST_CLASSID;
2287 #if defined(PETSC_USE_LOG)
2288   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
2289   ierr = PetscClassRegLogRegister(stageLog->classLog, name, *oclass);CHKERRQ(ierr);
2290   for (stage = 0; stage < stageLog->numStages; stage++) {
2291     ierr = PetscClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);CHKERRQ(ierr);
2292   }
2293 #endif
2294   PetscFunctionReturn(0);
2295 }
2296 
2297 #if defined(PETSC_USE_LOG) && defined(PETSC_HAVE_MPE)
2298 #include <mpe.h>
2299 
2300 PetscBool PetscBeganMPE = PETSC_FALSE;
2301 
2302 PETSC_INTERN PetscErrorCode PetscLogEventBeginMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
2303 PETSC_INTERN PetscErrorCode PetscLogEventEndMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
2304 
2305 /*@C
2306    PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files
2307    and slows the program down.
2308 
2309    Collective over PETSC_COMM_WORLD
2310 
2311    Options Database Keys:
2312 . -log_mpe - Prints extensive log information
2313 
2314    Notes:
2315    A related routine is PetscLogDefaultBegin() (with the options key -log_view), which is
2316    intended for production runs since it logs only flop rates and object
2317    creation (and should not significantly slow the programs).
2318 
2319    Level: advanced
2320 
2321 
2322 .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogEventActivate(),
2323           PetscLogEventDeactivate()
2324 @*/
2325 PetscErrorCode  PetscLogMPEBegin(void)
2326 {
2327   PetscErrorCode ierr;
2328 
2329   PetscFunctionBegin;
2330   /* Do MPE initialization */
2331   if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
2332     ierr = PetscInfo(0,"Initializing MPE.\n");CHKERRQ(ierr);
2333     ierr = MPE_Init_log();CHKERRQ(ierr);
2334 
2335     PetscBeganMPE = PETSC_TRUE;
2336   } else {
2337     ierr = PetscInfo(0,"MPE already initialized. Not attempting to reinitialize.\n");CHKERRQ(ierr);
2338   }
2339   ierr = PetscLogSet(PetscLogEventBeginMPE, PetscLogEventEndMPE);CHKERRQ(ierr);
2340   PetscFunctionReturn(0);
2341 }
2342 
2343 /*@C
2344    PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.
2345 
2346    Collective over PETSC_COMM_WORLD
2347 
2348    Level: advanced
2349 
2350 .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogMPEBegin()
2351 @*/
2352 PetscErrorCode  PetscLogMPEDump(const char sname[])
2353 {
2354   char           name[PETSC_MAX_PATH_LEN];
2355   PetscErrorCode ierr;
2356 
2357   PetscFunctionBegin;
2358   if (PetscBeganMPE) {
2359     ierr = PetscInfo(0,"Finalizing MPE.\n");CHKERRQ(ierr);
2360     if (sname) {
2361       ierr = PetscStrcpy(name,sname);CHKERRQ(ierr);
2362     } else {
2363       ierr = PetscGetProgramName(name,sizeof(name));CHKERRQ(ierr);
2364     }
2365     ierr = MPE_Finish_log(name);CHKERRQ(ierr);
2366   } else {
2367     ierr = PetscInfo(0,"Not finalizing MPE (not started by PETSc).\n");CHKERRQ(ierr);
2368   }
2369   PetscFunctionReturn(0);
2370 }
2371 
2372 #define PETSC_RGB_COLORS_MAX 39
2373 static const char *PetscLogMPERGBColors[PETSC_RGB_COLORS_MAX] = {
2374   "OliveDrab:      ",
2375   "BlueViolet:     ",
2376   "CadetBlue:      ",
2377   "CornflowerBlue: ",
2378   "DarkGoldenrod:  ",
2379   "DarkGreen:      ",
2380   "DarkKhaki:      ",
2381   "DarkOliveGreen: ",
2382   "DarkOrange:     ",
2383   "DarkOrchid:     ",
2384   "DarkSeaGreen:   ",
2385   "DarkSlateGray:  ",
2386   "DarkTurquoise:  ",
2387   "DeepPink:       ",
2388   "DarkKhaki:      ",
2389   "DimGray:        ",
2390   "DodgerBlue:     ",
2391   "GreenYellow:    ",
2392   "HotPink:        ",
2393   "IndianRed:      ",
2394   "LavenderBlush:  ",
2395   "LawnGreen:      ",
2396   "LemonChiffon:   ",
2397   "LightCoral:     ",
2398   "LightCyan:      ",
2399   "LightPink:      ",
2400   "LightSalmon:    ",
2401   "LightSlateGray: ",
2402   "LightYellow:    ",
2403   "LimeGreen:      ",
2404   "MediumPurple:   ",
2405   "MediumSeaGreen: ",
2406   "MediumSlateBlue:",
2407   "MidnightBlue:   ",
2408   "MintCream:      ",
2409   "MistyRose:      ",
2410   "NavajoWhite:    ",
2411   "NavyBlue:       ",
2412   "OliveDrab:      "
2413 };
2414 
2415 /*@C
2416   PetscLogMPEGetRGBColor - This routine returns a rgb color useable with PetscLogEventRegister()
2417 
2418   Not collective. Maybe it should be?
2419 
2420   Output Parameter:
2421 . str - character string representing the color
2422 
2423   Level: developer
2424 
2425 .seealso: PetscLogEventRegister
2426 @*/
2427 PetscErrorCode  PetscLogMPEGetRGBColor(const char *str[])
2428 {
2429   static int idx = 0;
2430 
2431   PetscFunctionBegin;
2432   *str = PetscLogMPERGBColors[idx];
2433   idx  = (idx + 1)% PETSC_RGB_COLORS_MAX;
2434   PetscFunctionReturn(0);
2435 }
2436 
2437 #endif /* PETSC_USE_LOG && PETSC_HAVE_MPE */
2438