xref: /petsc/src/sys/logging/plog.c (revision d5c9c0c4eebc2f2a01a1bd0c86fca87e2acd2a03)
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   PetscErrorCode ierr;
1329 
1330   PetscFunctionBegin;
1331   if (PetscDefined(USE_DEBUG)) {
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   }
1344   PetscFunctionReturn(0);
1345 }
1346 
1347 static PetscErrorCode PetscLogViewWarnNoGpuAwareMpi(MPI_Comm comm,FILE *fd)
1348 {
1349 #if defined(PETSC_HAVE_CUDA)
1350   PetscErrorCode ierr;
1351 
1352   PetscFunctionBegin;
1353   if (use_gpu_aware_mpi) PetscFunctionReturn(0);
1354   ierr = PetscFPrintf(comm, fd, "\n\n");CHKERRQ(ierr);
1355   ierr = PetscFPrintf(comm, fd, "      ##########################################################\n");CHKERRQ(ierr);
1356   ierr = PetscFPrintf(comm, fd, "      #                                                        #\n");CHKERRQ(ierr);
1357   ierr = PetscFPrintf(comm, fd, "      #                       WARNING!!!                       #\n");CHKERRQ(ierr);
1358   ierr = PetscFPrintf(comm, fd, "      #                                                        #\n");CHKERRQ(ierr);
1359   ierr = PetscFPrintf(comm, fd, "      #   This code was compiled with GPU support but you used #\n");CHKERRQ(ierr);
1360   ierr = PetscFPrintf(comm, fd, "      #   an MPI that's not GPU-aware, such Petsc had to copy  #\n");CHKERRQ(ierr);
1361   ierr = PetscFPrintf(comm, fd, "      #   data from GPU to CPU for MPI communication. To get   #\n");CHKERRQ(ierr);
1362   ierr = PetscFPrintf(comm, fd, "      #   meaningfull timing results, please use a GPU-aware   #\n");CHKERRQ(ierr);
1363   ierr = PetscFPrintf(comm, fd, "      #   MPI instead.                                         #\n");CHKERRQ(ierr);
1364   ierr = PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");CHKERRQ(ierr);
1365   PetscFunctionReturn(0);
1366 #else
1367   return 0;
1368 #endif
1369 }
1370 
1371 #if defined(PETSC_HAVE_OPENMP)
1372 extern PetscInt PetscNumOMPThreads;
1373 #endif
1374 
1375 PetscErrorCode  PetscLogView_Default(PetscViewer viewer)
1376 {
1377   FILE               *fd;
1378   PetscLogDouble     zero       = 0.0;
1379   PetscStageLog      stageLog;
1380   PetscStageInfo     *stageInfo = NULL;
1381   PetscEventPerfInfo *eventInfo = NULL;
1382   PetscClassPerfInfo *classInfo;
1383   char               arch[128],hostname[128],username[128],pname[PETSC_MAX_PATH_LEN],date[128];
1384   const char         *name;
1385   PetscLogDouble     locTotalTime, TotalTime, TotalFlops;
1386   PetscLogDouble     numMessages, messageLength, avgMessLen, numReductions;
1387   PetscLogDouble     stageTime, flops, flopr, mem, mess, messLen, red;
1388   PetscLogDouble     fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1389   PetscLogDouble     fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1390   PetscLogDouble     min, max, tot, ratio, avg, x, y;
1391   PetscLogDouble     minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratC, totm, totml, totr, mal, malmax, emalmax;
1392   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1393   PetscLogDouble     cct, gct, csz, gsz, gmaxt, gflops, gflopr, fracgflops;
1394   #endif
1395   PetscMPIInt        minC, maxC;
1396   PetscMPIInt        size, rank;
1397   PetscBool          *localStageUsed,    *stageUsed;
1398   PetscBool          *localStageVisible, *stageVisible;
1399   int                numStages, localNumEvents, numEvents;
1400   int                stage, oclass;
1401   PetscLogEvent      event;
1402   PetscErrorCode     ierr;
1403   char               version[256];
1404   MPI_Comm           comm;
1405 
1406   PetscFunctionBegin;
1407   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
1408   ierr = PetscViewerASCIIGetPointer(viewer,&fd);CHKERRQ(ierr);
1409   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
1410   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
1411   /* Get the total elapsed time */
1412   PetscTime(&locTotalTime);  locTotalTime -= petsc_BaseTime;
1413 
1414   ierr = PetscFPrintf(comm, fd, "************************************************************************************************************************\n");CHKERRQ(ierr);
1415   ierr = PetscFPrintf(comm, fd, "***             WIDEN YOUR WINDOW TO 120 CHARACTERS.  Use 'enscript -r -fCourier9' to print this document            ***\n");CHKERRQ(ierr);
1416   ierr = PetscFPrintf(comm, fd, "************************************************************************************************************************\n");CHKERRQ(ierr);
1417   ierr = PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");CHKERRQ(ierr);
1418   ierr = PetscLogViewWarnSync(comm,fd);CHKERRQ(ierr);
1419   ierr = PetscLogViewWarnDebugging(comm,fd);CHKERRQ(ierr);
1420   ierr = PetscLogViewWarnNoGpuAwareMpi(comm,fd);CHKERRQ(ierr);
1421   ierr = PetscGetArchType(arch,sizeof(arch));CHKERRQ(ierr);
1422   ierr = PetscGetHostName(hostname,sizeof(hostname));CHKERRQ(ierr);
1423   ierr = PetscGetUserName(username,sizeof(username));CHKERRQ(ierr);
1424   ierr = PetscGetProgramName(pname,sizeof(pname));CHKERRQ(ierr);
1425   ierr = PetscGetDate(date,sizeof(date));CHKERRQ(ierr);
1426   ierr = PetscGetVersion(version,sizeof(version));CHKERRQ(ierr);
1427   if (size == 1) {
1428     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);
1429   } else {
1430     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);
1431   }
1432 #if defined(PETSC_HAVE_OPENMP)
1433   ierr = PetscFPrintf(comm,fd,"Using %D OpenMP threads\n", PetscNumOMPThreads);CHKERRQ(ierr);
1434 #endif
1435   ierr = PetscFPrintf(comm, fd, "Using %s\n", version);CHKERRQ(ierr);
1436 
1437   /* Must preserve reduction count before we go on */
1438   red = petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
1439 
1440   /* Calculate summary information */
1441   ierr = PetscFPrintf(comm, fd, "\n                         Max       Max/Min     Avg       Total \n");CHKERRQ(ierr);
1442   /*   Time */
1443   ierr = MPIU_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1444   ierr = MPIU_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1445   ierr = MPIU_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1446   avg  = tot/((PetscLogDouble) size);
1447   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1448   ierr = PetscFPrintf(comm, fd, "Time (sec):           %5.3e   %7.3f   %5.3e\n", max, ratio, avg);CHKERRQ(ierr);
1449   TotalTime = tot;
1450   /*   Objects */
1451   avg  = (PetscLogDouble) petsc_numObjects;
1452   ierr = MPIU_Allreduce(&avg,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1453   ierr = MPIU_Allreduce(&avg,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1454   ierr = MPIU_Allreduce(&avg,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1455   avg  = tot/((PetscLogDouble) size);
1456   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1457   ierr = PetscFPrintf(comm, fd, "Objects:              %5.3e   %7.3f   %5.3e\n", max, ratio, avg);CHKERRQ(ierr);
1458   /*   Flops */
1459   ierr = MPIU_Allreduce(&petsc_TotalFlops,  &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1460   ierr = MPIU_Allreduce(&petsc_TotalFlops,  &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1461   ierr = MPIU_Allreduce(&petsc_TotalFlops,  &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1462   avg  = tot/((PetscLogDouble) size);
1463   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1464   ierr = PetscFPrintf(comm, fd, "Flop:                 %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);CHKERRQ(ierr);
1465   TotalFlops = tot;
1466   /*   Flops/sec -- Must talk to Barry here */
1467   if (locTotalTime != 0.0) flops = petsc_TotalFlops/locTotalTime; else flops = 0.0;
1468   ierr = MPIU_Allreduce(&flops,        &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1469   ierr = MPIU_Allreduce(&flops,        &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1470   ierr = MPIU_Allreduce(&flops,        &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1471   avg  = tot/((PetscLogDouble) size);
1472   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1473   ierr = PetscFPrintf(comm, fd, "Flop/sec:             %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);CHKERRQ(ierr);
1474   /*   Memory */
1475   ierr = PetscMallocGetMaximumUsage(&mem);CHKERRQ(ierr);
1476   if (mem > 0.0) {
1477     ierr = MPIU_Allreduce(&mem,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1478     ierr = MPIU_Allreduce(&mem,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1479     ierr = MPIU_Allreduce(&mem,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1480     avg  = tot/((PetscLogDouble) size);
1481     if (min != 0.0) ratio = max/min; else ratio = 0.0;
1482     ierr = PetscFPrintf(comm, fd, "Memory:               %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);CHKERRQ(ierr);
1483   }
1484   /*   Messages */
1485   mess = 0.5*(petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct);
1486   ierr = MPIU_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1487   ierr = MPIU_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1488   ierr = MPIU_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1489   avg  = tot/((PetscLogDouble) size);
1490   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1491   ierr = PetscFPrintf(comm, fd, "MPI Messages:         %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);CHKERRQ(ierr);
1492   numMessages = tot;
1493   /*   Message Lengths */
1494   mess = 0.5*(petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len);
1495   ierr = MPIU_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1496   ierr = MPIU_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1497   ierr = MPIU_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1498   if (numMessages != 0) avg = tot/numMessages; else avg = 0.0;
1499   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1500   ierr = PetscFPrintf(comm, fd, "MPI Message Lengths:  %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);CHKERRQ(ierr);
1501   messageLength = tot;
1502   /*   Reductions */
1503   ierr = MPIU_Allreduce(&red,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1504   ierr = MPIU_Allreduce(&red,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1505   ierr = MPIU_Allreduce(&red,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1506   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1507   ierr = PetscFPrintf(comm, fd, "MPI Reductions:       %5.3e   %7.3f\n", max, ratio);CHKERRQ(ierr);
1508   numReductions = red; /* wrong because uses count from process zero */
1509   ierr = PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");CHKERRQ(ierr);
1510   ierr = PetscFPrintf(comm, fd, "                            e.g., VecAXPY() for real vectors of length N --> 2N flop\n");CHKERRQ(ierr);
1511   ierr = PetscFPrintf(comm, fd, "                            and VecAXPY() for complex vectors of length N --> 8N flop\n");CHKERRQ(ierr);
1512 
1513   /* Get total number of stages --
1514        Currently, a single processor can register more stages than another, but stages must all be registered in order.
1515        We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1516        This seems best accomplished by assoicating a communicator with each stage.
1517   */
1518   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
1519   ierr = MPIU_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);CHKERRQ(ierr);
1520   ierr = PetscMalloc1(numStages, &localStageUsed);CHKERRQ(ierr);
1521   ierr = PetscMalloc1(numStages, &stageUsed);CHKERRQ(ierr);
1522   ierr = PetscMalloc1(numStages, &localStageVisible);CHKERRQ(ierr);
1523   ierr = PetscMalloc1(numStages, &stageVisible);CHKERRQ(ierr);
1524   if (numStages > 0) {
1525     stageInfo = stageLog->stageInfo;
1526     for (stage = 0; stage < numStages; stage++) {
1527       if (stage < stageLog->numStages) {
1528         localStageUsed[stage]    = stageInfo[stage].used;
1529         localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1530       } else {
1531         localStageUsed[stage]    = PETSC_FALSE;
1532         localStageVisible[stage] = PETSC_TRUE;
1533       }
1534     }
1535     ierr = MPIU_Allreduce(localStageUsed,    stageUsed,    numStages, MPIU_BOOL, MPI_LOR,  comm);CHKERRQ(ierr);
1536     ierr = MPIU_Allreduce(localStageVisible, stageVisible, numStages, MPIU_BOOL, MPI_LAND, comm);CHKERRQ(ierr);
1537     for (stage = 0; stage < numStages; stage++) {
1538       if (stageUsed[stage]) {
1539         ierr = PetscFPrintf(comm, fd, "\nSummary of Stages:   ----- Time ------  ----- Flop ------  --- Messages ---  -- Message Lengths --  -- Reductions --\n");CHKERRQ(ierr);
1540         ierr = PetscFPrintf(comm, fd, "                        Avg     %%Total     Avg     %%Total    Count   %%Total     Avg         %%Total    Count   %%Total \n");CHKERRQ(ierr);
1541         break;
1542       }
1543     }
1544     for (stage = 0; stage < numStages; stage++) {
1545       if (!stageUsed[stage]) continue;
1546       /* CANNOT use MPIU_Allreduce() since it might fail the line number check */
1547       if (localStageUsed[stage]) {
1548         ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1549         ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1550         ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1551         ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1552         ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1553         name = stageInfo[stage].name;
1554       } else {
1555         ierr = MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1556         ierr = MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1557         ierr = MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1558         ierr = MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1559         ierr = MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1560         name = "";
1561       }
1562       mess *= 0.5; messLen *= 0.5; red /= size;
1563       if (TotalTime     != 0.0) fracTime       = stageTime/TotalTime;    else fracTime       = 0.0;
1564       if (TotalFlops    != 0.0) fracFlops      = flops/TotalFlops;       else fracFlops      = 0.0;
1565       /* Talk to Barry if (stageTime     != 0.0) flops          = (size*flops)/stageTime; else flops          = 0.0; */
1566       if (numMessages   != 0.0) fracMessages   = mess/numMessages;       else fracMessages   = 0.0;
1567       if (mess          != 0.0) avgMessLen     = messLen/mess;           else avgMessLen     = 0.0;
1568       if (messageLength != 0.0) fracLength     = messLen/messageLength;  else fracLength     = 0.0;
1569       if (numReductions != 0.0) fracReductions = red/numReductions;      else fracReductions = 0.0;
1570       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",
1571                           stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1572                           mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);CHKERRQ(ierr);
1573     }
1574   }
1575 
1576   ierr = PetscFPrintf(comm, fd,"\n------------------------------------------------------------------------------------------------------------------------\n");CHKERRQ(ierr);
1577   ierr = PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");CHKERRQ(ierr);
1578   ierr = PetscFPrintf(comm, fd, "Phase summary info:\n");CHKERRQ(ierr);
1579   ierr = PetscFPrintf(comm, fd, "   Count: number of times phase was executed\n");CHKERRQ(ierr);
1580   ierr = PetscFPrintf(comm, fd, "   Time and Flop: Max - maximum over all processors\n");CHKERRQ(ierr);
1581   ierr = PetscFPrintf(comm, fd, "                  Ratio - ratio of maximum to minimum over all processors\n");CHKERRQ(ierr);
1582   ierr = PetscFPrintf(comm, fd, "   Mess: number of messages sent\n");CHKERRQ(ierr);
1583   ierr = PetscFPrintf(comm, fd, "   AvgLen: average message length (bytes)\n");CHKERRQ(ierr);
1584   ierr = PetscFPrintf(comm, fd, "   Reduct: number of global reductions\n");CHKERRQ(ierr);
1585   ierr = PetscFPrintf(comm, fd, "   Global: entire computation\n");CHKERRQ(ierr);
1586   ierr = PetscFPrintf(comm, fd, "   Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");CHKERRQ(ierr);
1587   ierr = PetscFPrintf(comm, fd, "      %%T - percent time in this phase         %%F - percent flop in this phase\n");CHKERRQ(ierr);
1588   ierr = PetscFPrintf(comm, fd, "      %%M - percent messages in this phase     %%L - percent message lengths in this phase\n");CHKERRQ(ierr);
1589   ierr = PetscFPrintf(comm, fd, "      %%R - percent reductions in this phase\n");CHKERRQ(ierr);
1590   ierr = PetscFPrintf(comm, fd, "   Total Mflop/s: 10e-6 * (sum of flop over all processors)/(max time over all processors)\n");CHKERRQ(ierr);
1591   if (PetscLogMemory) {
1592     ierr = PetscFPrintf(comm, fd, "   Malloc Mbytes: Memory allocated and kept during event (sum over all calls to event)\n");CHKERRQ(ierr);
1593     ierr = PetscFPrintf(comm, fd, "   EMalloc Mbytes: extra memory allocated during event and then freed (maximum over all calls to events)\n");CHKERRQ(ierr);
1594     ierr = PetscFPrintf(comm, fd, "   MMalloc Mbytes: Increase in high water mark of allocated memory (sum over all calls to event)\n");CHKERRQ(ierr);
1595     ierr = PetscFPrintf(comm, fd, "   RMI Mbytes: Increase in resident memory (sum over all calls to event)\n");CHKERRQ(ierr);
1596   }
1597   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1598   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);
1599   ierr = PetscFPrintf(comm, fd, "   CpuToGpu Count: total number of CPU to GPU copies per processor\n");CHKERRQ(ierr);
1600   ierr = PetscFPrintf(comm, fd, "   CpuToGpu Size (Mbytes): 10e-6 * (total size of CPU to GPU copies per processor)\n");CHKERRQ(ierr);
1601   ierr = PetscFPrintf(comm, fd, "   GpuToCpu Count: total number of GPU to CPU copies per processor\n");CHKERRQ(ierr);
1602   ierr = PetscFPrintf(comm, fd, "   GpuToCpu Size (Mbytes): 10e-6 * (total size of GPU to CPU copies per processor)\n");CHKERRQ(ierr);
1603   ierr = PetscFPrintf(comm, fd, "   GPU %%F: percent flops on GPU in this event\n");CHKERRQ(ierr);
1604   #endif
1605   ierr = PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------\n");CHKERRQ(ierr);
1606 
1607   ierr = PetscLogViewWarnDebugging(comm,fd);CHKERRQ(ierr);
1608 
1609   /* Report events */
1610   ierr = PetscFPrintf(comm, fd,"Event                Count      Time (sec)     Flop                              --- Global ---  --- Stage ----  Total");CHKERRQ(ierr);
1611   if (PetscLogMemory) {
1612     ierr = PetscFPrintf(comm, fd,"  Malloc EMalloc MMalloc RMI");CHKERRQ(ierr);
1613   }
1614   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1615   ierr = PetscFPrintf(comm, fd,"   GPU    - CpuToGpu -   - GpuToCpu - GPU");CHKERRQ(ierr);
1616   #endif
1617   ierr = PetscFPrintf(comm, fd,"\n");CHKERRQ(ierr);
1618   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);
1619   if (PetscLogMemory) {
1620     ierr = PetscFPrintf(comm, fd," Mbytes Mbytes Mbytes Mbytes");CHKERRQ(ierr);
1621   }
1622   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1623   ierr = PetscFPrintf(comm, fd," Mflop/s Count   Size   Count   Size  %%F");CHKERRQ(ierr);
1624   #endif
1625   ierr = PetscFPrintf(comm, fd,"\n");CHKERRQ(ierr);
1626   ierr = PetscFPrintf(comm, fd,"------------------------------------------------------------------------------------------------------------------------");CHKERRQ(ierr);
1627   if (PetscLogMemory) {
1628     ierr = PetscFPrintf(comm, fd,"-----------------------------");CHKERRQ(ierr);
1629   }
1630   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1631   ierr = PetscFPrintf(comm, fd,"---------------------------------------");CHKERRQ(ierr);
1632   #endif
1633   ierr = PetscFPrintf(comm, fd,"\n");CHKERRQ(ierr);
1634 
1635   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1636   for (stage = 0; stage < numStages; stage++) {
1637     if (!stageVisible[stage]) continue;
1638     /* CANNOT use MPIU_Allreduce() since it might fail the line number check */
1639     if (localStageUsed[stage]) {
1640       ierr = PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);CHKERRQ(ierr);
1641       ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1642       ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1643       ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1644       ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1645       ierr = MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1646     } else {
1647       ierr = PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);CHKERRQ(ierr);
1648       ierr = MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1649       ierr = MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1650       ierr = MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1651       ierr = MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1652       ierr = MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1653     }
1654     mess *= 0.5; messLen *= 0.5; red /= size;
1655 
1656     /* Get total number of events in this stage --
1657        Currently, a single processor can register more events than another, but events must all be registered in order,
1658        just like stages. We can removed this requirement if necessary by having a global event numbering and indirection
1659        on the event ID. This seems best accomplished by associating a communicator with each stage.
1660 
1661        Problem: If the event did not happen on proc 1, its name will not be available.
1662        Problem: Event visibility is not implemented
1663     */
1664     if (localStageUsed[stage]) {
1665       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1666       localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1667     } else localNumEvents = 0;
1668     ierr = MPIU_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);CHKERRQ(ierr);
1669     for (event = 0; event < numEvents; event++) {
1670       /* CANNOT use MPIU_Allreduce() since it might fail the line number check */
1671       if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) {
1672         if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) flopr = eventInfo[event].flops; else flopr = 0.0;
1673         ierr = MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1674         ierr = MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1675         ierr = MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1676         ierr = MPI_Allreduce(&eventInfo[event].time,          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1677         ierr = MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1678         ierr = MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1679         ierr = MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1680         ierr = MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1681         ierr = MPI_Allreduce(&eventInfo[event].numReductions, &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1682         ierr = MPI_Allreduce(&eventInfo[event].count,         &minC,  1, MPI_INT,             MPI_MIN, comm);CHKERRQ(ierr);
1683         ierr = MPI_Allreduce(&eventInfo[event].count,         &maxC,  1, MPI_INT,             MPI_MAX, comm);CHKERRQ(ierr);
1684         if (PetscLogMemory) {
1685           ierr  = MPI_Allreduce(&eventInfo[event].memIncrease,    &mem,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1686           ierr  = MPI_Allreduce(&eventInfo[event].mallocSpace,    &mal,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1687           ierr  = MPI_Allreduce(&eventInfo[event].mallocIncrease, &malmax,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1688           ierr  = MPI_Allreduce(&eventInfo[event].mallocIncreaseEvent, &emalmax,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1689         }
1690         #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1691         ierr  = MPI_Allreduce(&eventInfo[event].CpuToGpuCount,    &cct,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1692         ierr  = MPI_Allreduce(&eventInfo[event].GpuToCpuCount,    &gct,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1693         ierr  = MPI_Allreduce(&eventInfo[event].CpuToGpuSize,     &csz,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1694         ierr  = MPI_Allreduce(&eventInfo[event].GpuToCpuSize,     &gsz,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1695         ierr  = MPI_Allreduce(&eventInfo[event].GpuFlops,         &gflops,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1696         ierr  = MPI_Allreduce(&eventInfo[event].GpuTime,          &gmaxt ,1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1697         #endif
1698         name = stageLog->eventLog->eventInfo[event].name;
1699       } else {
1700         flopr = 0.0;
1701         ierr  = MPI_Allreduce(&flopr,                         &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1702         ierr  = MPI_Allreduce(&flopr,                         &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1703         ierr  = MPI_Allreduce(&zero,                          &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1704         ierr  = MPI_Allreduce(&zero,                          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);CHKERRQ(ierr);
1705         ierr  = MPI_Allreduce(&zero,                          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1706         ierr  = MPI_Allreduce(&zero,                          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1707         ierr  = MPI_Allreduce(&zero,                          &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1708         ierr  = MPI_Allreduce(&zero,                          &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1709         ierr  = MPI_Allreduce(&zero,                          &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1710         ierr  = MPI_Allreduce(&ierr,                          &minC,  1, MPI_INT,             MPI_MIN, comm);CHKERRQ(ierr);
1711         ierr  = MPI_Allreduce(&ierr,                          &maxC,  1, MPI_INT,             MPI_MAX, comm);CHKERRQ(ierr);
1712         if (PetscLogMemory) {
1713           ierr  = MPI_Allreduce(&zero,                        &mem,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1714           ierr  = MPI_Allreduce(&zero,                        &mal,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1715           ierr  = MPI_Allreduce(&zero,                        &malmax, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1716           ierr  = MPI_Allreduce(&zero,                        &emalmax,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1717         }
1718         #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1719         ierr  = MPI_Allreduce(&zero,                          &cct,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1720         ierr  = MPI_Allreduce(&zero,                          &gct,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1721         ierr  = MPI_Allreduce(&zero,                          &csz,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1722         ierr  = MPI_Allreduce(&zero,                          &gsz,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1723         ierr  = MPI_Allreduce(&zero,                          &gflops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);CHKERRQ(ierr);
1724         ierr  = MPI_Allreduce(&zero,                          &gmaxt , 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);CHKERRQ(ierr);
1725         #endif
1726         name  = "";
1727       }
1728       if (mint < 0.0) {
1729         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);
1730         mint = 0;
1731       }
1732       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);
1733       totm *= 0.5; totml *= 0.5; totr /= size;
1734 
1735       if (maxC != 0) {
1736         if (minC          != 0)   ratC             = ((PetscLogDouble)maxC)/minC;else ratC             = 0.0;
1737         if (mint          != 0.0) ratt             = maxt/mint;                  else ratt             = 0.0;
1738         if (minf          != 0.0) ratf             = maxf/minf;                  else ratf             = 0.0;
1739         if (TotalTime     != 0.0) fracTime         = tott/TotalTime;             else fracTime         = 0.0;
1740         if (TotalFlops    != 0.0) fracFlops        = totf/TotalFlops;            else fracFlops        = 0.0;
1741         if (stageTime     != 0.0) fracStageTime    = tott/stageTime;             else fracStageTime    = 0.0;
1742         if (flops         != 0.0) fracStageFlops   = totf/flops;                 else fracStageFlops   = 0.0;
1743         if (numMessages   != 0.0) fracMess         = totm/numMessages;           else fracMess         = 0.0;
1744         if (messageLength != 0.0) fracMessLen      = totml/messageLength;        else fracMessLen      = 0.0;
1745         if (numReductions != 0.0) fracRed          = totr/numReductions;         else fracRed          = 0.0;
1746         if (mess          != 0.0) fracStageMess    = totm/mess;                  else fracStageMess    = 0.0;
1747         if (messLen       != 0.0) fracStageMessLen = totml/messLen;              else fracStageMessLen = 0.0;
1748         if (red           != 0.0) fracStageRed     = totr/red;                   else fracStageRed     = 0.0;
1749         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1750         if (maxt          != 0.0) flopr            = totf/maxt;                  else flopr            = 0.0;
1751         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);
1752         ierr = PetscFPrintf(comm, fd,
1753                             "%-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",
1754                             name, maxC, ratC, maxt, ratt, maxf, ratf, totm, totml, totr,
1755                             100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1756                             100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1757                             PetscAbs(flopr)/1.0e6);CHKERRQ(ierr);
1758         if (PetscLogMemory) {
1759           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);
1760         }
1761         #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1762         if (totf  != 0.0) fracgflops = gflops/totf;  else fracgflops = 0.0;
1763         if (gmaxt != 0.0) gflopr     = gflops/gmaxt; else gflopr     = 0.0;
1764         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);
1765         #endif
1766         ierr = PetscFPrintf(comm, fd,"\n");CHKERRQ(ierr);
1767       }
1768     }
1769   }
1770 
1771   /* Memory usage and object creation */
1772   ierr = PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------");CHKERRQ(ierr);
1773   if (PetscLogMemory) {
1774     ierr = PetscFPrintf(comm, fd, "-----------------------------");CHKERRQ(ierr);
1775   }
1776   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1777   ierr = PetscFPrintf(comm, fd, "---------------------------------------");CHKERRQ(ierr);
1778   #endif
1779   ierr = PetscFPrintf(comm, fd, "\n");CHKERRQ(ierr);
1780   ierr = PetscFPrintf(comm, fd, "\n");CHKERRQ(ierr);
1781   ierr = PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");CHKERRQ(ierr);
1782 
1783   /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1784      the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1785      stats for stages local to processor sets.
1786   */
1787   /* We should figure out the longest object name here (now 20 characters) */
1788   ierr = PetscFPrintf(comm, fd, "Object Type          Creations   Destructions     Memory  Descendants' Mem.\n");CHKERRQ(ierr);
1789   ierr = PetscFPrintf(comm, fd, "Reports information only for process 0.\n");CHKERRQ(ierr);
1790   for (stage = 0; stage < numStages; stage++) {
1791     if (localStageUsed[stage]) {
1792       classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1793       ierr = PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);CHKERRQ(ierr);
1794       for (oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1795         if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1796           ierr = PetscFPrintf(comm, fd, "%20s %5d          %5d  %11.0f     %g\n", stageLog->classLog->classInfo[oclass].name,
1797                               classInfo[oclass].creations, classInfo[oclass].destructions, classInfo[oclass].mem,
1798                               classInfo[oclass].descMem);CHKERRQ(ierr);
1799         }
1800       }
1801     } else {
1802       if (!localStageVisible[stage]) continue;
1803       ierr = PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);CHKERRQ(ierr);
1804     }
1805   }
1806 
1807   ierr = PetscFree(localStageUsed);CHKERRQ(ierr);
1808   ierr = PetscFree(stageUsed);CHKERRQ(ierr);
1809   ierr = PetscFree(localStageVisible);CHKERRQ(ierr);
1810   ierr = PetscFree(stageVisible);CHKERRQ(ierr);
1811 
1812   /* Information unrelated to this particular run */
1813   ierr = PetscFPrintf(comm, fd, "========================================================================================================================\n");CHKERRQ(ierr);
1814   PetscTime(&y);
1815   PetscTime(&x);
1816   PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1817   PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1818   ierr = PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);CHKERRQ(ierr);
1819   /* MPI information */
1820   if (size > 1) {
1821     MPI_Status  status;
1822     PetscMPIInt tag;
1823     MPI_Comm    newcomm;
1824 
1825     ierr = MPI_Barrier(comm);CHKERRQ(ierr);
1826     PetscTime(&x);
1827     ierr = MPI_Barrier(comm);CHKERRQ(ierr);
1828     ierr = MPI_Barrier(comm);CHKERRQ(ierr);
1829     ierr = MPI_Barrier(comm);CHKERRQ(ierr);
1830     ierr = MPI_Barrier(comm);CHKERRQ(ierr);
1831     ierr = MPI_Barrier(comm);CHKERRQ(ierr);
1832     PetscTime(&y);
1833     ierr = PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);CHKERRQ(ierr);
1834     ierr = PetscCommDuplicate(comm,&newcomm, &tag);CHKERRQ(ierr);
1835     ierr = MPI_Barrier(comm);CHKERRQ(ierr);
1836     if (rank) {
1837       ierr = MPI_Recv(NULL, 0, MPI_INT, rank-1,            tag, newcomm, &status);CHKERRQ(ierr);
1838       ierr = MPI_Send(NULL, 0, MPI_INT, (rank+1)%size, tag, newcomm);CHKERRQ(ierr);
1839     } else {
1840       PetscTime(&x);
1841       ierr = MPI_Send(NULL, 0, MPI_INT, 1,          tag, newcomm);CHKERRQ(ierr);
1842       ierr = MPI_Recv(NULL, 0, MPI_INT, size-1, tag, newcomm, &status);CHKERRQ(ierr);
1843       PetscTime(&y);
1844       ierr = PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);CHKERRQ(ierr);
1845     }
1846     ierr = PetscCommDestroy(&newcomm);CHKERRQ(ierr);
1847   }
1848   ierr = PetscOptionsView(NULL,viewer);CHKERRQ(ierr);
1849 
1850   /* Machine and compile information */
1851 #if defined(PETSC_USE_FORTRAN_KERNELS)
1852   ierr = PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");CHKERRQ(ierr);
1853 #else
1854   ierr = PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");CHKERRQ(ierr);
1855 #endif
1856 #if defined(PETSC_USE_64BIT_INDICES)
1857   ierr = PetscFPrintf(comm, fd, "Compiled with 64 bit PetscInt\n");CHKERRQ(ierr);
1858 #elif defined(PETSC_USE___FLOAT128)
1859   ierr = PetscFPrintf(comm, fd, "Compiled with 32 bit PetscInt\n");CHKERRQ(ierr);
1860 #endif
1861 #if defined(PETSC_USE_REAL_SINGLE)
1862   ierr = PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");CHKERRQ(ierr);
1863 #elif defined(PETSC_USE___FLOAT128)
1864   ierr = PetscFPrintf(comm, fd, "Compiled with 128 bit precision PetscScalar and PetscReal\n");CHKERRQ(ierr);
1865 #endif
1866 #if defined(PETSC_USE_REAL_MAT_SINGLE)
1867   ierr = PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");CHKERRQ(ierr);
1868 #else
1869   ierr = PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");CHKERRQ(ierr);
1870 #endif
1871   ierr = PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d sizeof(PetscInt) %d\n",
1872                       (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar),(int) sizeof(PetscInt));CHKERRQ(ierr);
1873 
1874   ierr = PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);CHKERRQ(ierr);
1875   ierr = PetscFPrintf(comm, fd, "%s", petscmachineinfo);CHKERRQ(ierr);
1876   ierr = PetscFPrintf(comm, fd, "%s", petsccompilerinfo);CHKERRQ(ierr);
1877   ierr = PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);CHKERRQ(ierr);
1878   ierr = PetscFPrintf(comm, fd, "%s", petsclinkerinfo);CHKERRQ(ierr);
1879 
1880   /* Cleanup */
1881   ierr = PetscFPrintf(comm, fd, "\n");CHKERRQ(ierr);
1882   ierr = PetscLogViewWarnNoGpuAwareMpi(comm,fd);CHKERRQ(ierr);
1883   ierr = PetscLogViewWarnDebugging(comm,fd);CHKERRQ(ierr);
1884   PetscFunctionReturn(0);
1885 }
1886 
1887 /*@C
1888   PetscLogView - Prints a summary of the logging.
1889 
1890   Collective over MPI_Comm
1891 
1892   Input Parameter:
1893 .  viewer - an ASCII viewer
1894 
1895   Options Database Keys:
1896 +  -log_view [:filename] - Prints summary of log information
1897 .  -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
1898 .  -log_view :filename.xml:ascii_xml - Saves a summary of the logging information in a nested format (see below for how to view it)
1899 .  -log_all - Saves a file Log.rank for each MPI process with details of each step of the computation
1900 -  -log_trace [filename] - Displays a trace of what each process is doing
1901 
1902   Notes:
1903   It is possible to control the logging programatically but we recommend using the options database approach whenever possible
1904   By default the summary is printed to stdout.
1905 
1906   Before calling this routine you must have called either PetscLogDefaultBegin() or PetscLogNestedBegin()
1907 
1908   If PETSc is configured with --with-logging=0 then this functionality is not available
1909 
1910   To view the nested XML format filename.xml first copy  ${PETSC_DIR}/share/petsc/xml/performance_xml2html.xsl to the current
1911   directory then open filename.xml with your browser. Specific notes for certain browsers
1912 $    Firefox and Internet explorer - simply open the file
1913 $    Google Chrome - you must start up Chrome with the option --allow-file-access-from-files
1914 $    Safari - see https://ccm.net/faq/36342-safari-how-to-enable-local-file-access
1915   or one can use the package http://xmlsoft.org/XSLT/xsltproc2.html to translate the xml file to html and then open it with
1916   your browser.
1917   Alternatively, use the script ${PETSC_DIR}/lib/petsc/bin/petsc-performance-view to automatically open a new browser
1918   window and render the XML log file contents.
1919 
1920   The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij  MARITIME  RESEARCH  INSTITUTE  NETHERLANDS
1921 
1922   Level: beginner
1923 
1924 .seealso: PetscLogDefaultBegin(), PetscLogDump()
1925 @*/
1926 PetscErrorCode  PetscLogView(PetscViewer viewer)
1927 {
1928   PetscErrorCode    ierr;
1929   PetscBool         isascii;
1930   PetscViewerFormat format;
1931   int               stage, lastStage;
1932   PetscStageLog     stageLog;
1933 
1934   PetscFunctionBegin;
1935   if (!PetscLogPLB) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Must use -log_view or PetscLogDefaultBegin() before calling this routine");
1936   /* Pop off any stages the user forgot to remove */
1937   lastStage = 0;
1938   ierr      = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
1939   ierr      = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr);
1940   while (stage >= 0) {
1941     lastStage = stage;
1942     ierr      = PetscStageLogPop(stageLog);CHKERRQ(ierr);
1943     ierr      = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr);
1944   }
1945   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
1946   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Currently can only view logging to ASCII");
1947   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1948   if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO) {
1949     ierr = PetscLogView_Default(viewer);CHKERRQ(ierr);
1950   } else if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1951     ierr = PetscLogView_Detailed(viewer);CHKERRQ(ierr);
1952   } else if (format == PETSC_VIEWER_ASCII_CSV) {
1953     ierr = PetscLogView_CSV(viewer);CHKERRQ(ierr);
1954   } else if (format == PETSC_VIEWER_ASCII_XML) {
1955     ierr = PetscLogView_Nested(viewer);CHKERRQ(ierr);
1956   }
1957   ierr = PetscStageLogPush(stageLog, lastStage);CHKERRQ(ierr);
1958   PetscFunctionReturn(0);
1959 }
1960 
1961 /*@C
1962   PetscLogViewFromOptions - Processes command line options to determine if/how a PetscLog is to be viewed.
1963 
1964   Collective on PETSC_COMM_WORLD
1965 
1966   Not normally called by user
1967 
1968   Level: intermediate
1969 
1970 @*/
1971 PetscErrorCode PetscLogViewFromOptions(void)
1972 {
1973   PetscErrorCode    ierr;
1974   PetscViewer       viewer;
1975   PetscBool         flg;
1976   PetscViewerFormat format;
1977 
1978   PetscFunctionBegin;
1979   ierr   = PetscOptionsGetViewer(PETSC_COMM_WORLD,NULL,NULL,"-log_view",&viewer,&format,&flg);CHKERRQ(ierr);
1980   if (flg) {
1981     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
1982     ierr = PetscLogView(viewer);CHKERRQ(ierr);
1983     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
1984     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1985   }
1986   PetscFunctionReturn(0);
1987 }
1988 
1989 
1990 
1991 /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1992 /*@C
1993    PetscGetFlops - Returns the number of flops used on this processor
1994    since the program began.
1995 
1996    Not Collective
1997 
1998    Output Parameter:
1999    flops - number of floating point operations
2000 
2001    Notes:
2002    A global counter logs all PETSc flop counts.  The user can use
2003    PetscLogFlops() to increment this counter to include flops for the
2004    application code.
2005 
2006    Level: intermediate
2007 
2008 .seealso: PetscTime(), PetscLogFlops()
2009 @*/
2010 PetscErrorCode  PetscGetFlops(PetscLogDouble *flops)
2011 {
2012   PetscFunctionBegin;
2013   *flops = petsc_TotalFlops;
2014   PetscFunctionReturn(0);
2015 }
2016 
2017 PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
2018 {
2019   PetscErrorCode ierr;
2020   size_t         fullLength;
2021   va_list        Argp;
2022 
2023   PetscFunctionBegin;
2024   if (!petsc_logObjects) PetscFunctionReturn(0);
2025   va_start(Argp, format);
2026   ierr = PetscVSNPrintf(petsc_objects[obj->id].info, 64,format,&fullLength, Argp);CHKERRQ(ierr);
2027   va_end(Argp);
2028   PetscFunctionReturn(0);
2029 }
2030 
2031 
2032 /*MC
2033    PetscLogFlops - Adds floating point operations to the global counter.
2034 
2035    Synopsis:
2036    #include <petsclog.h>
2037    PetscErrorCode PetscLogFlops(PetscLogDouble f)
2038 
2039    Not Collective
2040 
2041    Input Parameter:
2042 .  f - flop counter
2043 
2044 
2045    Usage:
2046 .vb
2047      PetscLogEvent USER_EVENT;
2048      PetscLogEventRegister("User event",0,&USER_EVENT);
2049      PetscLogEventBegin(USER_EVENT,0,0,0,0);
2050         [code segment to monitor]
2051         PetscLogFlops(user_flops)
2052      PetscLogEventEnd(USER_EVENT,0,0,0,0);
2053 .ve
2054 
2055    Notes:
2056    A global counter logs all PETSc flop counts.  The user can use
2057    PetscLogFlops() to increment this counter to include flops for the
2058    application code.
2059 
2060    Level: intermediate
2061 
2062 .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()
2063 
2064 M*/
2065 
2066 /*MC
2067    PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice)
2068     to get accurate timings
2069 
2070    Synopsis:
2071    #include <petsclog.h>
2072    void PetscPreLoadBegin(PetscBool  flag,char *name);
2073 
2074    Not Collective
2075 
2076    Input Parameter:
2077 +   flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
2078            with command line option -preload true or -preload false
2079 -   name - name of first stage (lines of code timed separately with -log_view) to
2080            be preloaded
2081 
2082    Usage:
2083 .vb
2084      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2085        lines of code
2086        PetscPreLoadStage("second stage");
2087        lines of code
2088      PetscPreLoadEnd();
2089 .ve
2090 
2091    Notes:
2092     Only works in C/C++, not Fortran
2093 
2094      Flags available within the macro.
2095 +    PetscPreLoadingUsed - true if we are or have done preloading
2096 .    PetscPreLoadingOn - true if it is CURRENTLY doing preload
2097 .    PetscPreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
2098 -    PetscPreLoadMax - number of times it will do the computation, only one when preloading is turned on
2099      The first two variables are available throughout the program, the second two only between the PetscPreLoadBegin()
2100      and PetscPreLoadEnd()
2101 
2102    Level: intermediate
2103 
2104 .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadEnd(), PetscPreLoadStage()
2105 
2106 
2107 M*/
2108 
2109 /*MC
2110    PetscPreLoadEnd - End a segment of code that may be preloaded (run twice)
2111     to get accurate timings
2112 
2113    Synopsis:
2114    #include <petsclog.h>
2115    void PetscPreLoadEnd(void);
2116 
2117    Not Collective
2118 
2119    Usage:
2120 .vb
2121      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2122        lines of code
2123        PetscPreLoadStage("second stage");
2124        lines of code
2125      PetscPreLoadEnd();
2126 .ve
2127 
2128    Notes:
2129     only works in C/C++ not fortran
2130 
2131    Level: intermediate
2132 
2133 .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadStage()
2134 
2135 M*/
2136 
2137 /*MC
2138    PetscPreLoadStage - Start a new segment of code to be timed separately.
2139     to get accurate timings
2140 
2141    Synopsis:
2142    #include <petsclog.h>
2143    void PetscPreLoadStage(char *name);
2144 
2145    Not Collective
2146 
2147    Usage:
2148 .vb
2149      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2150        lines of code
2151        PetscPreLoadStage("second stage");
2152        lines of code
2153      PetscPreLoadEnd();
2154 .ve
2155 
2156    Notes:
2157     only works in C/C++ not fortran
2158 
2159    Level: intermediate
2160 
2161 .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd()
2162 
2163 M*/
2164 
2165 
2166 #else /* end of -DPETSC_USE_LOG section */
2167 
2168 PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
2169 {
2170   PetscFunctionBegin;
2171   PetscFunctionReturn(0);
2172 }
2173 
2174 #endif /* PETSC_USE_LOG*/
2175 
2176 
2177 PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2178 PetscClassId PETSC_OBJECT_CLASSID  = 0;
2179 
2180 /*@C
2181   PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code.
2182 
2183   Not Collective
2184 
2185   Input Parameter:
2186 . name   - The class name
2187 
2188   Output Parameter:
2189 . oclass - The class id or classid
2190 
2191   Level: developer
2192 
2193 @*/
2194 PetscErrorCode  PetscClassIdRegister(const char name[],PetscClassId *oclass)
2195 {
2196 #if defined(PETSC_USE_LOG)
2197   PetscStageLog  stageLog;
2198   PetscInt       stage;
2199   PetscErrorCode ierr;
2200 #endif
2201 
2202   PetscFunctionBegin;
2203   *oclass = ++PETSC_LARGEST_CLASSID;
2204 #if defined(PETSC_USE_LOG)
2205   ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr);
2206   ierr = PetscClassRegLogRegister(stageLog->classLog, name, *oclass);CHKERRQ(ierr);
2207   for (stage = 0; stage < stageLog->numStages; stage++) {
2208     ierr = PetscClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);CHKERRQ(ierr);
2209   }
2210 #endif
2211   PetscFunctionReturn(0);
2212 }
2213 
2214 #if defined(PETSC_USE_LOG) && defined(PETSC_HAVE_MPE)
2215 #include <mpe.h>
2216 
2217 PetscBool PetscBeganMPE = PETSC_FALSE;
2218 
2219 PETSC_INTERN PetscErrorCode PetscLogEventBeginMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
2220 PETSC_INTERN PetscErrorCode PetscLogEventEndMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
2221 
2222 /*@C
2223    PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files
2224    and slows the program down.
2225 
2226    Collective over PETSC_COMM_WORLD
2227 
2228    Options Database Keys:
2229 . -log_mpe - Prints extensive log information
2230 
2231    Notes:
2232    A related routine is PetscLogDefaultBegin() (with the options key -log_view), which is
2233    intended for production runs since it logs only flop rates and object
2234    creation (and should not significantly slow the programs).
2235 
2236    Level: advanced
2237 
2238 
2239 .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogEventActivate(),
2240           PetscLogEventDeactivate()
2241 @*/
2242 PetscErrorCode  PetscLogMPEBegin(void)
2243 {
2244   PetscErrorCode ierr;
2245 
2246   PetscFunctionBegin;
2247   /* Do MPE initialization */
2248   if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
2249     ierr = PetscInfo(0,"Initializing MPE.\n");CHKERRQ(ierr);
2250     ierr = MPE_Init_log();CHKERRQ(ierr);
2251 
2252     PetscBeganMPE = PETSC_TRUE;
2253   } else {
2254     ierr = PetscInfo(0,"MPE already initialized. Not attempting to reinitialize.\n");CHKERRQ(ierr);
2255   }
2256   ierr = PetscLogSet(PetscLogEventBeginMPE, PetscLogEventEndMPE);CHKERRQ(ierr);
2257   PetscFunctionReturn(0);
2258 }
2259 
2260 /*@C
2261    PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.
2262 
2263    Collective over PETSC_COMM_WORLD
2264 
2265    Level: advanced
2266 
2267 .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogMPEBegin()
2268 @*/
2269 PetscErrorCode  PetscLogMPEDump(const char sname[])
2270 {
2271   char           name[PETSC_MAX_PATH_LEN];
2272   PetscErrorCode ierr;
2273 
2274   PetscFunctionBegin;
2275   if (PetscBeganMPE) {
2276     ierr = PetscInfo(0,"Finalizing MPE.\n");CHKERRQ(ierr);
2277     if (sname) {
2278       ierr = PetscStrcpy(name,sname);CHKERRQ(ierr);
2279     } else {
2280       ierr = PetscGetProgramName(name,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
2281     }
2282     ierr = MPE_Finish_log(name);CHKERRQ(ierr);
2283   } else {
2284     ierr = PetscInfo(0,"Not finalizing MPE (not started by PETSc).\n");CHKERRQ(ierr);
2285   }
2286   PetscFunctionReturn(0);
2287 }
2288 
2289 #define PETSC_RGB_COLORS_MAX 39
2290 static const char *PetscLogMPERGBColors[PETSC_RGB_COLORS_MAX] = {
2291   "OliveDrab:      ",
2292   "BlueViolet:     ",
2293   "CadetBlue:      ",
2294   "CornflowerBlue: ",
2295   "DarkGoldenrod:  ",
2296   "DarkGreen:      ",
2297   "DarkKhaki:      ",
2298   "DarkOliveGreen: ",
2299   "DarkOrange:     ",
2300   "DarkOrchid:     ",
2301   "DarkSeaGreen:   ",
2302   "DarkSlateGray:  ",
2303   "DarkTurquoise:  ",
2304   "DeepPink:       ",
2305   "DarkKhaki:      ",
2306   "DimGray:        ",
2307   "DodgerBlue:     ",
2308   "GreenYellow:    ",
2309   "HotPink:        ",
2310   "IndianRed:      ",
2311   "LavenderBlush:  ",
2312   "LawnGreen:      ",
2313   "LemonChiffon:   ",
2314   "LightCoral:     ",
2315   "LightCyan:      ",
2316   "LightPink:      ",
2317   "LightSalmon:    ",
2318   "LightSlateGray: ",
2319   "LightYellow:    ",
2320   "LimeGreen:      ",
2321   "MediumPurple:   ",
2322   "MediumSeaGreen: ",
2323   "MediumSlateBlue:",
2324   "MidnightBlue:   ",
2325   "MintCream:      ",
2326   "MistyRose:      ",
2327   "NavajoWhite:    ",
2328   "NavyBlue:       ",
2329   "OliveDrab:      "
2330 };
2331 
2332 /*@C
2333   PetscLogMPEGetRGBColor - This routine returns a rgb color useable with PetscLogEventRegister()
2334 
2335   Not collective. Maybe it should be?
2336 
2337   Output Parameter:
2338 . str - character string representing the color
2339 
2340   Level: developer
2341 
2342 .seealso: PetscLogEventRegister
2343 @*/
2344 PetscErrorCode  PetscLogMPEGetRGBColor(const char *str[])
2345 {
2346   static int idx = 0;
2347 
2348   PetscFunctionBegin;
2349   *str = PetscLogMPERGBColors[idx];
2350   idx  = (idx + 1)% PETSC_RGB_COLORS_MAX;
2351   PetscFunctionReturn(0);
2352 }
2353 
2354 #endif /* PETSC_USE_LOG && PETSC_HAVE_MPE */
2355