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