xref: /petsc/src/sys/logging/plog.c (revision efa12513287cff49a2b9648ae83199dcbfaad71a)
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 = MPIU_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);CHKERRQ(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 = MPIU_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);CHKERRQ(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 = MPIU_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);CHKERRQ(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 = MPIU_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);CHKERRQ(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 = MPIU_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);CHKERRQ(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 = MPIU_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1520   ierr = MPIU_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1521   ierr = MPIU_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(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 = MPIU_Allreduce(&avg,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1529   ierr = MPIU_Allreduce(&avg,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1530   ierr = MPIU_Allreduce(&avg,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(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 = MPIU_Allreduce(&petsc_TotalFlops,  &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1536   ierr = MPIU_Allreduce(&petsc_TotalFlops,  &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1537   ierr = MPIU_Allreduce(&petsc_TotalFlops,  &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(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 = MPIU_Allreduce(&flops,        &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1545   ierr = MPIU_Allreduce(&flops,        &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1546   ierr = MPIU_Allreduce(&flops,        &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(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 = MPIU_Allreduce(&mem,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1554     ierr = MPIU_Allreduce(&mem,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1555     ierr = MPIU_Allreduce(&mem,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(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 = MPIU_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1563   ierr = MPIU_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1564   ierr = MPIU_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(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 = MPIU_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1572   ierr = MPIU_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1573   ierr = MPIU_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(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 = MPIU_Allreduce(&red,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1580   ierr = MPIU_Allreduce(&red,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1581   ierr = MPIU_Allreduce(&red,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(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 = MPIU_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);CHKERRQ(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 = MPIU_Allreduce(localStageUsed,    stageUsed,    numStages, MPIU_BOOL, MPI_LOR,  comm);CHKERRQ(ierr);
1612     ierr = MPIU_Allreduce(localStageVisible, stageVisible, numStages, MPIU_BOOL, MPI_LAND, comm);CHKERRQ(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 MPIU_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 MPIU_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 = MPIU_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);CHKERRQ(ierr);
1745     for (event = 0; event < numEvents; event++) {
1746       /* CANNOT use MPIU_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);CHKERRQ(ierr);
1762           ierr  = MPI_Allreduce(&eventInfo[event].mallocSpace,    &mal,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1763           ierr  = MPI_Allreduce(&eventInfo[event].mallocIncrease, &malmax,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1764           ierr  = MPI_Allreduce(&eventInfo[event].mallocIncreaseEvent, &emalmax,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1765         }
1766         #if defined(PETSC_HAVE_DEVICE)
1767         ierr  = MPI_Allreduce(&eventInfo[event].CpuToGpuCount,    &cct,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1768         ierr  = MPI_Allreduce(&eventInfo[event].GpuToCpuCount,    &gct,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1769         ierr  = MPI_Allreduce(&eventInfo[event].CpuToGpuSize,     &csz,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1770         ierr  = MPI_Allreduce(&eventInfo[event].GpuToCpuSize,     &gsz,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1771         ierr  = MPI_Allreduce(&eventInfo[event].GpuFlops,         &gflops,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1772         ierr  = MPI_Allreduce(&eventInfo[event].GpuTime,          &gmaxt ,1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(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);CHKERRQ(ierr);
1778         ierr  = MPI_Allreduce(&flopr,                         &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1779         ierr  = MPI_Allreduce(&zero,                          &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1780         ierr  = MPI_Allreduce(&zero,                          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1781         ierr  = MPI_Allreduce(&zero,                          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1782         ierr  = MPI_Allreduce(&zero,                          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1783         ierr  = MPI_Allreduce(&zero,                          &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1784         ierr  = MPI_Allreduce(&zero,                          &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1785         ierr  = MPI_Allreduce(&zero,                          &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1786         ierr  = MPI_Allreduce(&ierr,                          &minC,  1, MPI_INT,             MPI_MIN, comm);CHKERRQ(ierr);
1787         ierr  = MPI_Allreduce(&ierr,                          &maxC,  1, MPI_INT,             MPI_MAX, comm);CHKERRQ(ierr);
1788         if (PetscLogMemory) {
1789           ierr  = MPI_Allreduce(&zero,                        &mem,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1790           ierr  = MPI_Allreduce(&zero,                        &mal,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1791           ierr  = MPI_Allreduce(&zero,                        &malmax, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1792           ierr  = MPI_Allreduce(&zero,                        &emalmax,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1793         }
1794         #if defined(PETSC_HAVE_DEVICE)
1795         ierr  = MPI_Allreduce(&zero,                          &cct,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1796         ierr  = MPI_Allreduce(&zero,                          &gct,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1797         ierr  = MPI_Allreduce(&zero,                          &csz,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1798         ierr  = MPI_Allreduce(&zero,                          &gsz,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1799         ierr  = MPI_Allreduce(&zero,                          &gflops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1800         ierr  = MPI_Allreduce(&zero,                          &gmaxt , 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(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_all - Saves a file Log.rank for each MPI process with details of each step of the computation
1976 -  -log_trace [filename] - Displays a trace of what each process is doing
1977 
1978   Notes:
1979   It is possible to control the logging programatically but we recommend using the options database approach whenever possible
1980   By default the summary is printed to stdout.
1981 
1982   Before calling this routine you must have called either PetscLogDefaultBegin() or PetscLogNestedBegin()
1983 
1984   If PETSc is configured with --with-logging=0 then this functionality is not available
1985 
1986   To view the nested XML format filename.xml first copy  ${PETSC_DIR}/share/petsc/xml/performance_xml2html.xsl to the current
1987   directory then open filename.xml with your browser. Specific notes for certain browsers
1988 $    Firefox and Internet explorer - simply open the file
1989 $    Google Chrome - you must start up Chrome with the option --allow-file-access-from-files
1990 $    Safari - see https://ccm.net/faq/36342-safari-how-to-enable-local-file-access
1991   or one can use the package http://xmlsoft.org/XSLT/xsltproc2.html to translate the xml file to html and then open it with
1992   your browser.
1993   Alternatively, use the script ${PETSC_DIR}/lib/petsc/bin/petsc-performance-view to automatically open a new browser
1994   window and render the XML log file contents.
1995 
1996   The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij  MARITIME  RESEARCH  INSTITUTE  NETHERLANDS
1997 
1998   Level: beginner
1999 
2000 .seealso: PetscLogDefaultBegin(), PetscLogDump()
2001 @*/
2002 PetscErrorCode  PetscLogView(PetscViewer viewer)
2003 {
2004   PetscErrorCode    ierr;
2005   PetscBool         isascii;
2006   PetscViewerFormat format;
2007   int               stage, lastStage;
2008   PetscStageLog     stageLog;
2009 
2010   PetscFunctionBegin;
2011   if (!PetscLogPLB) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Must use -log_view or PetscLogDefaultBegin() before calling this routine");
2012   /* Pop off any stages the user forgot to remove */
2013   lastStage = 0;
2014   ierr      = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
2015   ierr      = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr);
2016   while (stage >= 0) {
2017     lastStage = stage;
2018     ierr      = PetscStageLogPop(stageLog);CHKERRQ(ierr);
2019     ierr      = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr);
2020   }
2021   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
2022   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Currently can only view logging to ASCII");
2023   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
2024   if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO) {
2025     ierr = PetscLogView_Default(viewer);CHKERRQ(ierr);
2026   } else if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
2027     ierr = PetscLogView_Detailed(viewer);CHKERRQ(ierr);
2028   } else if (format == PETSC_VIEWER_ASCII_CSV) {
2029     ierr = PetscLogView_CSV(viewer);CHKERRQ(ierr);
2030   } else if (format == PETSC_VIEWER_ASCII_XML) {
2031     ierr = PetscLogView_Nested(viewer);CHKERRQ(ierr);
2032   }
2033   ierr = PetscStageLogPush(stageLog, lastStage);CHKERRQ(ierr);
2034   PetscFunctionReturn(0);
2035 }
2036 
2037 /*@C
2038   PetscLogViewFromOptions - Processes command line options to determine if/how a PetscLog is to be viewed.
2039 
2040   Collective on PETSC_COMM_WORLD
2041 
2042   Not normally called by user
2043 
2044   Level: intermediate
2045 
2046 @*/
2047 PetscErrorCode PetscLogViewFromOptions(void)
2048 {
2049   PetscErrorCode    ierr;
2050   PetscViewer       viewer;
2051   PetscBool         flg;
2052   PetscViewerFormat format;
2053 
2054   PetscFunctionBegin;
2055   ierr   = PetscOptionsGetViewer(PETSC_COMM_WORLD,NULL,NULL,"-log_view",&viewer,&format,&flg);CHKERRQ(ierr);
2056   if (flg) {
2057     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
2058     ierr = PetscLogView(viewer);CHKERRQ(ierr);
2059     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
2060     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
2061   }
2062   PetscFunctionReturn(0);
2063 }
2064 
2065 
2066 
2067 /*----------------------------------------------- Counter Functions -------------------------------------------------*/
2068 /*@C
2069    PetscGetFlops - Returns the number of flops used on this processor
2070    since the program began.
2071 
2072    Not Collective
2073 
2074    Output Parameter:
2075    flops - number of floating point operations
2076 
2077    Notes:
2078    A global counter logs all PETSc flop counts.  The user can use
2079    PetscLogFlops() to increment this counter to include flops for the
2080    application code.
2081 
2082    Level: intermediate
2083 
2084 .seealso: PetscTime(), PetscLogFlops()
2085 @*/
2086 PetscErrorCode  PetscGetFlops(PetscLogDouble *flops)
2087 {
2088   PetscFunctionBegin;
2089   *flops = petsc_TotalFlops;
2090   PetscFunctionReturn(0);
2091 }
2092 
2093 PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
2094 {
2095   PetscErrorCode ierr;
2096   size_t         fullLength;
2097   va_list        Argp;
2098 
2099   PetscFunctionBegin;
2100   if (!petsc_logObjects) PetscFunctionReturn(0);
2101   va_start(Argp, format);
2102   ierr = PetscVSNPrintf(petsc_objects[obj->id].info, 64,format,&fullLength, Argp);CHKERRQ(ierr);
2103   va_end(Argp);
2104   PetscFunctionReturn(0);
2105 }
2106 
2107 
2108 /*MC
2109    PetscLogFlops - Adds floating point operations to the global counter.
2110 
2111    Synopsis:
2112    #include <petsclog.h>
2113    PetscErrorCode PetscLogFlops(PetscLogDouble f)
2114 
2115    Not Collective
2116 
2117    Input Parameter:
2118 .  f - flop counter
2119 
2120 
2121    Usage:
2122 .vb
2123      PetscLogEvent USER_EVENT;
2124      PetscLogEventRegister("User event",0,&USER_EVENT);
2125      PetscLogEventBegin(USER_EVENT,0,0,0,0);
2126         [code segment to monitor]
2127         PetscLogFlops(user_flops)
2128      PetscLogEventEnd(USER_EVENT,0,0,0,0);
2129 .ve
2130 
2131    Notes:
2132    A global counter logs all PETSc flop counts.  The user can use
2133    PetscLogFlops() to increment this counter to include flops for the
2134    application code.
2135 
2136    Level: intermediate
2137 
2138 .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()
2139 
2140 M*/
2141 
2142 /*MC
2143    PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice)
2144     to get accurate timings
2145 
2146    Synopsis:
2147    #include <petsclog.h>
2148    void PetscPreLoadBegin(PetscBool  flag,char *name);
2149 
2150    Not Collective
2151 
2152    Input Parameter:
2153 +   flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
2154            with command line option -preload true or -preload false
2155 -   name - name of first stage (lines of code timed separately with -log_view) to
2156            be preloaded
2157 
2158    Usage:
2159 .vb
2160      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2161        lines of code
2162        PetscPreLoadStage("second stage");
2163        lines of code
2164      PetscPreLoadEnd();
2165 .ve
2166 
2167    Notes:
2168     Only works in C/C++, not Fortran
2169 
2170      Flags available within the macro.
2171 +    PetscPreLoadingUsed - true if we are or have done preloading
2172 .    PetscPreLoadingOn - true if it is CURRENTLY doing preload
2173 .    PetscPreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
2174 -    PetscPreLoadMax - number of times it will do the computation, only one when preloading is turned on
2175      The first two variables are available throughout the program, the second two only between the PetscPreLoadBegin()
2176      and PetscPreLoadEnd()
2177 
2178    Level: intermediate
2179 
2180 .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadEnd(), PetscPreLoadStage()
2181 
2182 
2183 M*/
2184 
2185 /*MC
2186    PetscPreLoadEnd - End a segment of code that may be preloaded (run twice)
2187     to get accurate timings
2188 
2189    Synopsis:
2190    #include <petsclog.h>
2191    void PetscPreLoadEnd(void);
2192 
2193    Not Collective
2194 
2195    Usage:
2196 .vb
2197      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2198        lines of code
2199        PetscPreLoadStage("second stage");
2200        lines of code
2201      PetscPreLoadEnd();
2202 .ve
2203 
2204    Notes:
2205     only works in C/C++ not fortran
2206 
2207    Level: intermediate
2208 
2209 .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadStage()
2210 
2211 M*/
2212 
2213 /*MC
2214    PetscPreLoadStage - Start a new segment of code to be timed separately.
2215     to get accurate timings
2216 
2217    Synopsis:
2218    #include <petsclog.h>
2219    void PetscPreLoadStage(char *name);
2220 
2221    Not Collective
2222 
2223    Usage:
2224 .vb
2225      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2226        lines of code
2227        PetscPreLoadStage("second stage");
2228        lines of code
2229      PetscPreLoadEnd();
2230 .ve
2231 
2232    Notes:
2233     only works in C/C++ not fortran
2234 
2235    Level: intermediate
2236 
2237 .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd()
2238 
2239 M*/
2240 
2241 
2242 #else /* end of -DPETSC_USE_LOG section */
2243 
2244 PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
2245 {
2246   PetscFunctionBegin;
2247   PetscFunctionReturn(0);
2248 }
2249 
2250 #endif /* PETSC_USE_LOG*/
2251 
2252 
2253 PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2254 PetscClassId PETSC_OBJECT_CLASSID  = 0;
2255 
2256 /*@C
2257   PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code.
2258 
2259   Not Collective
2260 
2261   Input Parameter:
2262 . name   - The class name
2263 
2264   Output Parameter:
2265 . oclass - The class id or classid
2266 
2267   Level: developer
2268 
2269 @*/
2270 PetscErrorCode  PetscClassIdRegister(const char name[],PetscClassId *oclass)
2271 {
2272 #if defined(PETSC_USE_LOG)
2273   PetscStageLog  stageLog;
2274   PetscInt       stage;
2275   PetscErrorCode ierr;
2276 #endif
2277 
2278   PetscFunctionBegin;
2279   *oclass = ++PETSC_LARGEST_CLASSID;
2280 #if defined(PETSC_USE_LOG)
2281   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
2282   ierr = PetscClassRegLogRegister(stageLog->classLog, name, *oclass);CHKERRQ(ierr);
2283   for (stage = 0; stage < stageLog->numStages; stage++) {
2284     ierr = PetscClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);CHKERRQ(ierr);
2285   }
2286 #endif
2287   PetscFunctionReturn(0);
2288 }
2289 
2290 #if defined(PETSC_USE_LOG) && defined(PETSC_HAVE_MPE)
2291 #include <mpe.h>
2292 
2293 PetscBool PetscBeganMPE = PETSC_FALSE;
2294 
2295 PETSC_INTERN PetscErrorCode PetscLogEventBeginMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
2296 PETSC_INTERN PetscErrorCode PetscLogEventEndMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
2297 
2298 /*@C
2299    PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files
2300    and slows the program down.
2301 
2302    Collective over PETSC_COMM_WORLD
2303 
2304    Options Database Keys:
2305 . -log_mpe - Prints extensive log information
2306 
2307    Notes:
2308    A related routine is PetscLogDefaultBegin() (with the options key -log_view), which is
2309    intended for production runs since it logs only flop rates and object
2310    creation (and should not significantly slow the programs).
2311 
2312    Level: advanced
2313 
2314 
2315 .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogEventActivate(),
2316           PetscLogEventDeactivate()
2317 @*/
2318 PetscErrorCode  PetscLogMPEBegin(void)
2319 {
2320   PetscErrorCode ierr;
2321 
2322   PetscFunctionBegin;
2323   /* Do MPE initialization */
2324   if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
2325     ierr = PetscInfo(0,"Initializing MPE.\n");CHKERRQ(ierr);
2326     ierr = MPE_Init_log();CHKERRQ(ierr);
2327 
2328     PetscBeganMPE = PETSC_TRUE;
2329   } else {
2330     ierr = PetscInfo(0,"MPE already initialized. Not attempting to reinitialize.\n");CHKERRQ(ierr);
2331   }
2332   ierr = PetscLogSet(PetscLogEventBeginMPE, PetscLogEventEndMPE);CHKERRQ(ierr);
2333   PetscFunctionReturn(0);
2334 }
2335 
2336 /*@C
2337    PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.
2338 
2339    Collective over PETSC_COMM_WORLD
2340 
2341    Level: advanced
2342 
2343 .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogMPEBegin()
2344 @*/
2345 PetscErrorCode  PetscLogMPEDump(const char sname[])
2346 {
2347   char           name[PETSC_MAX_PATH_LEN];
2348   PetscErrorCode ierr;
2349 
2350   PetscFunctionBegin;
2351   if (PetscBeganMPE) {
2352     ierr = PetscInfo(0,"Finalizing MPE.\n");CHKERRQ(ierr);
2353     if (sname) {
2354       ierr = PetscStrcpy(name,sname);CHKERRQ(ierr);
2355     } else {
2356       ierr = PetscGetProgramName(name,sizeof(name));CHKERRQ(ierr);
2357     }
2358     ierr = MPE_Finish_log(name);CHKERRQ(ierr);
2359   } else {
2360     ierr = PetscInfo(0,"Not finalizing MPE (not started by PETSc).\n");CHKERRQ(ierr);
2361   }
2362   PetscFunctionReturn(0);
2363 }
2364 
2365 #define PETSC_RGB_COLORS_MAX 39
2366 static const char *PetscLogMPERGBColors[PETSC_RGB_COLORS_MAX] = {
2367   "OliveDrab:      ",
2368   "BlueViolet:     ",
2369   "CadetBlue:      ",
2370   "CornflowerBlue: ",
2371   "DarkGoldenrod:  ",
2372   "DarkGreen:      ",
2373   "DarkKhaki:      ",
2374   "DarkOliveGreen: ",
2375   "DarkOrange:     ",
2376   "DarkOrchid:     ",
2377   "DarkSeaGreen:   ",
2378   "DarkSlateGray:  ",
2379   "DarkTurquoise:  ",
2380   "DeepPink:       ",
2381   "DarkKhaki:      ",
2382   "DimGray:        ",
2383   "DodgerBlue:     ",
2384   "GreenYellow:    ",
2385   "HotPink:        ",
2386   "IndianRed:      ",
2387   "LavenderBlush:  ",
2388   "LawnGreen:      ",
2389   "LemonChiffon:   ",
2390   "LightCoral:     ",
2391   "LightCyan:      ",
2392   "LightPink:      ",
2393   "LightSalmon:    ",
2394   "LightSlateGray: ",
2395   "LightYellow:    ",
2396   "LimeGreen:      ",
2397   "MediumPurple:   ",
2398   "MediumSeaGreen: ",
2399   "MediumSlateBlue:",
2400   "MidnightBlue:   ",
2401   "MintCream:      ",
2402   "MistyRose:      ",
2403   "NavajoWhite:    ",
2404   "NavyBlue:       ",
2405   "OliveDrab:      "
2406 };
2407 
2408 /*@C
2409   PetscLogMPEGetRGBColor - This routine returns a rgb color useable with PetscLogEventRegister()
2410 
2411   Not collective. Maybe it should be?
2412 
2413   Output Parameter:
2414 . str - character string representing the color
2415 
2416   Level: developer
2417 
2418 .seealso: PetscLogEventRegister
2419 @*/
2420 PetscErrorCode  PetscLogMPEGetRGBColor(const char *str[])
2421 {
2422   static int idx = 0;
2423 
2424   PetscFunctionBegin;
2425   *str = PetscLogMPERGBColors[idx];
2426   idx  = (idx + 1)% PETSC_RGB_COLORS_MAX;
2427   PetscFunctionReturn(0);
2428 }
2429 
2430 #endif /* PETSC_USE_LOG && PETSC_HAVE_MPE */
2431