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