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