Actual source code: plog.c
1: #define PETSC_DLL
2: /*
3: PETSc code to log object creation and destruction and PETSc events.
4: */
5: #include petsc.h
6: #include petsctime.h
7: #if defined(PETSC_HAVE_MPE)
8: #include "mpe.h"
9: #endif
10: #include <stdarg.h>
11: #include <sys/types.h>
12: #include petscsys.h
13: #if defined(PETSC_HAVE_STDLIB_H)
14: #include <stdlib.h>
15: #endif
16: #if defined(PETSC_HAVE_MALLOC_H)
17: #include <malloc.h>
18: #endif
19: #include "petscfix.h"
20: #include plog.h
22: PetscLogEvent PETSC_LARGEST_EVENT = PETSC_EVENT;
24: #if defined(PETSC_USE_LOG)
25: #include "petscmachineinfo.h"
26: #include "petscconfiginfo.h"
28: /* used in the MPI_XXX() count macros in petsclog.h */
29: int PETSC_DUMMY_SIZE = 0;
30: int PETSC_DUMMY_COUNT = 0;
32: /* Action and object logging variables */
33: Action *actions = PETSC_NULL;
34: Object *objects = PETSC_NULL;
35: PetscTruth logActions = PETSC_FALSE;
36: PetscTruth logObjects = PETSC_FALSE;
37: int numActions = 0, maxActions = 100;
38: int numObjects = 0, maxObjects = 100;
39: int numObjectsDestroyed = 0;
41: /* Global counters */
42: PetscLogDouble BaseTime = 0.0;
43: PetscLogDouble _TotalFlops = 0.0; /* The number of flops */
44: PetscLogDouble petsc_tmp_flops = 0.0; /* The incremental number of flops */
45: PetscLogDouble send_ct = 0.0; /* The number of sends */
46: PetscLogDouble recv_ct = 0.0; /* The number of receives */
47: PetscLogDouble send_len = 0.0; /* The total length of all sent messages */
48: PetscLogDouble recv_len = 0.0; /* The total length of all received messages */
49: PetscLogDouble isend_ct = 0.0; /* The number of immediate sends */
50: PetscLogDouble irecv_ct = 0.0; /* The number of immediate receives */
51: PetscLogDouble isend_len = 0.0; /* The total length of all immediate send messages */
52: PetscLogDouble irecv_len = 0.0; /* The total length of all immediate receive messages */
53: PetscLogDouble wait_ct = 0.0; /* The number of waits */
54: PetscLogDouble wait_any_ct = 0.0; /* The number of anywaits */
55: PetscLogDouble wait_all_ct = 0.0; /* The number of waitalls */
56: PetscLogDouble sum_of_waits_ct = 0.0; /* The total number of waits */
57: PetscLogDouble allreduce_ct = 0.0; /* The number of reductions */
58: PetscLogDouble gather_ct = 0.0; /* The number of gathers and gathervs */
59: PetscLogDouble scatter_ct = 0.0; /* The number of scatters and scattervs */
61: /* Logging functions */
62: PetscErrorCode (*_PetscLogPHC)(PetscObject) = PETSC_NULL;
63: PetscErrorCode (*_PetscLogPHD)(PetscObject) = PETSC_NULL;
64: PetscErrorCode (*_PetscLogPLB)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
65: PetscErrorCode (*_PetscLogPLE)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
67: /* Tracing event logging variables */
68: FILE *tracefile = PETSC_NULL;
69: int tracelevel = 0;
70: const char *traceblanks = " ";
71: char tracespace[128] = " ";
72: PetscLogDouble tracetime = 0.0;
74: /*---------------------------------------------- General Functions --------------------------------------------------*/
77: /*@C
78: PetscLogDestroy - Destroys the object and event logging data and resets the global counters.
80: Not Collective
82: Notes:
83: This routine should not usually be used by programmers. Instead employ
84: PetscLogStagePush() and PetscLogStagePop().
86: Level: developer
88: .keywords: log, destroy
89: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogStagePush(), PlogStagePop()
90: @*/
91: PetscErrorCode PetscLogDestroy(void)
92: {
93: StageLog stageLog;
97: PetscFree(actions);
98: actions = PETSC_NULL;
99: PetscFree(objects);
100: objects = PETSC_NULL;
101: PetscLogSet(PETSC_NULL, PETSC_NULL);
103: /* Resetting phase */
104: PetscLogGetStageLog(&stageLog);
105: StageLogDestroy(stageLog);
106: _TotalFlops = 0.0;
107: numActions = 0;
108: numObjects = 0;
109: numObjectsDestroyed = 0;
110: return(0);
111: }
115: /*@C
116: PetscLogSet - Sets the logging functions called at the beginning and ending of every event.
118: Not Collective
120: Input Parameters:
121: + b - The function called at beginning of event
122: - e - The function called at end of event
124: Level: developer
126: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
127: @*/
128: PetscErrorCode PetscLogSet(PetscErrorCode (*b)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject),
129: PetscErrorCode (*e)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject))
130: {
132: _PetscLogPLB = b;
133: _PetscLogPLE = e;
134: return(0);
135: }
137: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
140: PetscErrorCode PetscLogBegin_Private(void)
141: {
142: static PetscTruth initialized = PETSC_FALSE;
143: int stage;
144: PetscTruth opt;
145: PetscErrorCode ierr;
148: if (initialized) return(0);
149: initialized = PETSC_TRUE;
150: PetscOptionsHasName(PETSC_NULL, "-log_exclude_actions", &opt);
151: if (opt) {
152: logActions = PETSC_FALSE;
153: }
154: PetscOptionsHasName(PETSC_NULL, "-log_exclude_objects", &opt);
155: if (opt) {
156: logObjects = PETSC_FALSE;
157: }
158: if (logActions) {
159: PetscMalloc(maxActions * sizeof(Action), &actions);
160: }
161: if (logObjects) {
162: PetscMalloc(maxObjects * sizeof(Object), &objects);
163: }
164: _PetscLogPHC = PetscLogObjCreateDefault;
165: _PetscLogPHD = PetscLogObjDestroyDefault;
166: /* Setup default logging structures */
167: StageLogCreate(&_stageLog);
168: StageLogRegister(_stageLog, "Main Stage", &stage);
169: /* All processors sync here for more consistent logging */
170: MPI_Barrier(PETSC_COMM_WORLD);
171: PetscTime(BaseTime);
172: PetscLogStagePush(stage);
173: return(0);
174: }
178: /*@C
179: PetscLogBegin - Turns on logging of objects and events. This logs flop
180: rates and object creation and should not slow programs down too much.
181: This routine may be called more than once.
183: Collective over PETSC_COMM_WORLD
185: Options Database Keys:
186: + -log_summary - Prints summary of flop and timing information to the
187: screen (for code compiled with PETSC_USE_LOG)
188: - -log - Prints detailed log information (for code compiled with PETSC_USE_LOG)
190: Usage:
191: .vb
192: PetscInitialize(...);
193: PetscLogBegin();
194: ... code ...
195: PetscLogPrintSummary(MPI_Comm,filename); or PetscLogDump();
196: PetscFinalize();
197: .ve
199: Notes:
200: PetscLogPrintSummary(MPI_Comm,filename) or PetscLogDump() actually cause the printing of
201: the logging information.
203: Level: advanced
205: .keywords: log, begin
206: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogTraceBegin()
207: @*/
208: PetscErrorCode PetscLogBegin(void)
209: {
213: PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
214: PetscLogBegin_Private();
215: return(0);
216: }
220: /*@C
221: PetscLogAllBegin - Turns on extensive logging of objects and events. Logs
222: all events. This creates large log files and slows the program down.
224: Collective on PETSC_COMM_WORLD
226: Options Database Keys:
227: . -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
229: Usage:
230: .vb
231: PetscInitialize(...);
232: PetscLogAllBegin();
233: ... code ...
234: PetscLogDump(filename);
235: PetscFinalize();
236: .ve
238: Notes:
239: A related routine is PetscLogBegin (with the options key -log), which is
240: intended for production runs since it logs only flop rates and object
241: creation (and shouldn't significantly slow the programs).
243: Level: advanced
245: .keywords: log, all, begin
246: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogTraceBegin()
247: @*/
248: PetscErrorCode PetscLogAllBegin(void)
249: {
253: PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
254: PetscLogBegin_Private();
255: return(0);
256: }
260: /*@
261: PetscLogTraceBegin - Activates trace logging. Every time a PETSc event
262: begins or ends, the event name is printed.
264: Collective on PETSC_COMM_WORLD
266: Input Parameter:
267: . file - The file to print trace in (e.g. stdout)
269: Options Database Key:
270: . -log_trace [filename] - Activates PetscLogTraceBegin()
272: Notes:
273: PetscLogTraceBegin() prints the processor number, the execution time (sec),
274: then "Event begin:" or "Event end:" followed by the event name.
276: PetscLogTraceBegin() allows tracing of all PETSc calls, which is useful
277: to determine where a program is hanging without running in the
278: debugger. Can be used in conjunction with the -info option.
280: Level: intermediate
282: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogBegin()
283: @*/
284: PetscErrorCode PetscLogTraceBegin(FILE *file)
285: {
289: tracefile = file;
290: PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
291: PetscLogBegin_Private();
292: return(0);
293: }
297: /*@
298: PetscLogActions - Determines whether actions are logged for the graphical viewer.
300: Not Collective
302: Input Parameter:
303: . flag - PETSC_TRUE if actions are to be logged
305: Level: intermediate
307: Note: Logging of actions continues to consume more memory as the program
308: runs. Long running programs should consider turning this feature off.
310: Options Database Keys:
311: . -log_exclude_actions - Turns off actions logging
313: .keywords: log, stage, register
314: .seealso: PetscLogStagePush(), PetscLogStagePop()
315: @*/
316: PetscErrorCode PetscLogActions(PetscTruth flag)
317: {
319: logActions = flag;
320: return(0);
321: }
325: /*@
326: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
328: Not Collective
330: Input Parameter:
331: . flag - PETSC_TRUE if objects are to be logged
333: Level: intermediate
335: Note: Logging of objects continues to consume more memory as the program
336: runs. Long running programs should consider turning this feature off.
338: Options Database Keys:
339: . -log_exclude_objects - Turns off objects logging
341: .keywords: log, stage, register
342: .seealso: PetscLogStagePush(), PetscLogStagePop()
343: @*/
344: PetscErrorCode PetscLogObjects(PetscTruth flag)
345: {
347: logObjects = flag;
348: return(0);
349: }
351: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
354: /*@C
355: PetscLogStageRegister - Attaches a charactor string name to a logging stage.
357: Not Collective
359: Input Parameter:
360: . sname - The name to associate with that stage
362: Output Parameter:
363: . stage - The stage number
365: Level: intermediate
367: .keywords: log, stage, register
368: .seealso: PetscLogStagePush(), PetscLogStagePop()
369: @*/
370: PetscErrorCode PetscLogStageRegister(const char sname[],PetscLogStage *stage)
371: {
372: StageLog stageLog;
373: PetscLogEvent event;
377: PetscLogGetStageLog(&stageLog);
378: StageLogRegister(stageLog, sname, stage);
379: /* Copy events already changed in the main stage, this sucks */
380: EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
381: for(event = 0; event < stageLog->eventLog->numEvents; event++) {
382: EventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],
383: &stageLog->stageInfo[*stage].eventLog->eventInfo[event]);
384: }
385: ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
386: return(0);
387: }
391: /*@C
392: PetscLogStagePush - This function pushes a stage on the stack.
394: Not Collective
396: Input Parameter:
397: . stage - The stage on which to log
399: Usage:
400: If the option -log_sumary is used to run the program containing the
401: following code, then 2 sets of summary data will be printed during
402: PetscFinalize().
403: .vb
404: PetscInitialize(int *argc,char ***args,0,0);
405: [stage 0 of code]
406: PetscLogStagePush(1);
407: [stage 1 of code]
408: PetscLogStagePop();
409: PetscBarrier(...);
410: [more stage 0 of code]
411: PetscFinalize();
412: .ve
413:
414: Notes:
415: Use PetscLogStageRegister() to register a stage.
417: Level: intermediate
419: .keywords: log, push, stage
420: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
421: @*/
422: PetscErrorCode PetscLogStagePush(PetscLogStage stage)
423: {
424: StageLog stageLog;
428: PetscLogGetStageLog(&stageLog);
429: StageLogPush(stageLog, stage);
430: return(0);
431: }
435: /*@C
436: PetscLogStagePop - This function pops a stage from the stack.
438: Not Collective
440: Usage:
441: If the option -log_sumary is used to run the program containing the
442: following code, then 2 sets of summary data will be printed during
443: PetscFinalize().
444: .vb
445: PetscInitialize(int *argc,char ***args,0,0);
446: [stage 0 of code]
447: PetscLogStagePush(1);
448: [stage 1 of code]
449: PetscLogStagePop();
450: PetscBarrier(...);
451: [more stage 0 of code]
452: PetscFinalize();
453: .ve
455: Notes:
456: Use PetscLogStageRegister() to register a stage.
458: Level: intermediate
460: .keywords: log, pop, stage
461: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
462: @*/
463: PetscErrorCode PetscLogStagePop(void)
464: {
465: StageLog stageLog;
469: PetscLogGetStageLog(&stageLog);
470: StageLogPop(stageLog);
471: return(0);
472: }
476: /*@
477: PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().
479: Not Collective
481: Input Parameters:
482: + stage - The stage
483: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
485: Level: intermediate
487: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
488: @*/
489: PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscTruth isActive)
490: {
491: StageLog stageLog;
495: PetscLogGetStageLog(&stageLog);
496: StageLogSetActive(stageLog, stage, isActive);
497: return(0);
498: }
502: /*@
503: PetscLogStageGetActive - Returns stage activity for PetscLogEventBegin() and PetscLogEventEnd().
505: Not Collective
507: Input Parameter:
508: . stage - The stage
510: Output Parameter:
511: . isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
513: Level: intermediate
515: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
516: @*/
517: PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscTruth *isActive)
518: {
519: StageLog stageLog;
523: PetscLogGetStageLog(&stageLog);
524: StageLogGetActive(stageLog, stage, isActive);
525: return(0);
526: }
530: /*@
531: PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()
533: Not Collective
535: Input Parameters:
536: + stage - The stage
537: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
539: Level: intermediate
541: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
542: @*/
543: PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscTruth isVisible)
544: {
545: StageLog stageLog;
549: PetscLogGetStageLog(&stageLog);
550: StageLogSetVisible(stageLog, stage, isVisible);
551: return(0);
552: }
556: /*@
557: PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()
559: Not Collective
561: Input Parameter:
562: . stage - The stage
564: Output Parameter:
565: . isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
567: Level: intermediate
569: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
570: @*/
571: PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscTruth *isVisible)
572: {
573: StageLog stageLog;
577: PetscLogGetStageLog(&stageLog);
578: StageLogGetVisible(stageLog, stage, isVisible);
579: return(0);
580: }
584: /*@
585: PetscLogStageGetId - Returns the stage id when given the stage name.
587: Not Collective
589: Input Parameter:
590: . name - The stage name
592: Output Parameter:
593: . stage - The stage
595: Level: intermediate
597: .seealso: PetscLogStagePush(), PetscLogStagePop(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
598: @*/
599: PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
600: {
601: StageLog stageLog;
605: PetscLogGetStageLog(&stageLog);
606: StageLogGetStage(stageLog, name, stage);
607: return(0);
608: }
610: /*------------------------------------------------ Event Functions --------------------------------------------------*/
613: /*@C
614: PetscLogEventRegister - Registers an event name for logging operations in an application code.
616: Not Collective
618: Input Parameter:
619: + name - The name associated with the event
620: - cookie - The cookie associated to the class for this event, obtain either with
621: PetscCookieRegister() or use a predefined one such as KSP_COOKIE, SNES_COOKIE
622:
623: Output Parameter:
624: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().
626: Example of Usage:
627: .vb
628: PetscLogEvent USER_EVENT;
629: PetscCookie cookie;
630: int user_event_flops;
631: PetscCookieRegister("class name",&cookie);
632: PetscLogEventRegister("User event name",cookie,&USER_EVENT);
633: PetscLogEventBegin(USER_EVENT,0,0,0,0);
634: [code segment to monitor]
635: PetscLogFlops(user_event_flops);
636: PetscLogEventEnd(USER_EVENT,0,0,0,0);
637: .ve
639: Notes:
640: PETSc automatically logs library events if the code has been
641: compiled with -DPETSC_USE_LOG (which is the default) and -log,
642: -log_summary, or -log_all are specified. PetscLogEventRegister() is
643: intended for logging user events to supplement this PETSc
644: information.
646: PETSc can gather data for use with the utilities Upshot/Nupshot
647: (part of the MPICH distribution). If PETSc has been compiled
648: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
649: MPICH), the user can employ another command line option, -log_mpe,
650: to create a logfile, "mpe.log", which can be visualized
651: Upshot/Nupshot.
653: The cookie is associated with each event so that classes of events
654: can be disabled simultaneously, such as all matrix events. The user
655: can either use an existing cookie, such as MAT_COOKIE, or create
656: their own as shown in the example.
658: Level: intermediate
660: .keywords: log, event, register
661: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
662: PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
663: PetscLogEventActivate(), PetscLogEventDeactivate(), PetscCookieRegister()
664: @*/
665: PetscErrorCode PetscLogEventRegister(const char name[],PetscCookie cookie,PetscLogEvent *event)
666: {
667: StageLog stageLog;
668: int stage;
672: *event = PETSC_DECIDE;
673: PetscLogGetStageLog(&stageLog);
674: EventRegLogRegister(stageLog->eventLog, name, cookie, event);
675: for(stage = 0; stage < stageLog->numStages; stage++) {
676: EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
677: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
678: }
679: return(0);
680: }
684: /*@
685: PetscLogEventActivate - Indicates that a particular event should be logged.
687: Not Collective
689: Input Parameter:
690: . event - The event id
692: Usage:
693: .vb
694: PetscLogEventDeactivate(VEC_SetValues);
695: [code where you do not want to log VecSetValues()]
696: PetscLogEventActivate(VEC_SetValues);
697: [code where you do want to log VecSetValues()]
698: .ve
700: Note:
701: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
702: or an event number obtained with PetscLogEventRegister().
704: Level: advanced
706: .keywords: log, event, activate
707: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
708: @*/
709: PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
710: {
711: StageLog stageLog;
712: int stage;
716: PetscLogGetStageLog(&stageLog);
717: StageLogGetCurrent(stageLog, &stage);
718: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
719: return(0);
720: }
724: /*@
725: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
727: Not Collective
729: Input Parameter:
730: . event - The event id
732: Usage:
733: .vb
734: PetscLogEventDeactivate(VEC_SetValues);
735: [code where you do not want to log VecSetValues()]
736: PetscLogEventActivate(VEC_SetValues);
737: [code where you do want to log VecSetValues()]
738: .ve
740: Note:
741: The event may be either a pre-defined PETSc event (found in
742: include/petsclog.h) or an event number obtained with PetscLogEventRegister()).
744: Level: advanced
746: .keywords: log, event, deactivate
747: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
748: @*/
749: PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
750: {
751: StageLog stageLog;
752: int stage;
756: PetscLogGetStageLog(&stageLog);
757: StageLogGetCurrent(stageLog, &stage);
758: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
759: return(0);
760: }
764: /*@
765: PetscLogEventSetActiveAll - Sets the event activity in every stage.
767: Not Collective
769: Input Parameters:
770: + event - The event id
771: - isActive - The activity flag determining whether the event is logged
773: Level: advanced
775: .keywords: log, event, activate
776: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
777: @*/
778: PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscTruth isActive)
779: {
780: StageLog stageLog;
781: int stage;
785: PetscLogGetStageLog(&stageLog);
786: for(stage = 0; stage < stageLog->numStages; stage++) {
787: if (isActive) {
788: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
789: } else {
790: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
791: }
792: }
793: return(0);
794: }
798: /*@
799: PetscLogEventActivateClass - Activates event logging for a PETSc object class.
801: Not Collective
803: Input Parameter:
804: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
806: Level: developer
808: .keywords: log, event, activate, class
809: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
810: @*/
811: PetscErrorCode PetscLogEventActivateClass(PetscCookie cookie)
812: {
813: StageLog stageLog;
814: int stage;
818: PetscLogGetStageLog(&stageLog);
819: StageLogGetCurrent(stageLog, &stage);
820: EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
821: return(0);
822: }
826: /*@
827: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.
829: Not Collective
831: Input Parameter:
832: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
834: Level: developer
836: .keywords: log, event, deactivate, class
837: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
838: @*/
839: PetscErrorCode PetscLogEventDeactivateClass(PetscCookie cookie)
840: {
841: StageLog stageLog;
842: int stage;
846: PetscLogGetStageLog(&stageLog);
847: StageLogGetCurrent(stageLog, &stage);
848: EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
849: return(0);
850: }
852: /*MC
853: PetscLogEventBegin - Logs the beginning of a user event.
855: Input Parameters:
856: + e - integer associated with the event obtained from PetscLogEventRegister()
857: - o1,o2,o3,o4 - objects associated with the event, or 0
859: Synopsis:
860: void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
861: PetscObject o4)
863: Fortran Synopsis:
864: void PetscLogEventEnd(int e,PetscErrorCode ierr)
866: Usage:
867: .vb
868: int USER_EVENT;
869: int user_event_flops;
870: PetscLogEventRegister("User event",0,&USER_EVENT);
871: PetscLogEventBegin(USER_EVENT,0,0,0,0);
872: [code segment to monitor]
873: PetscLogFlops(user_event_flops);
874: PetscLogEventEnd(USER_EVENT,0,0,0,0);
875: .ve
877: Notes:
878: You need to register each integer event with the command
879: PetscLogEventRegister(). The source code must be compiled with
880: -DPETSC_USE_LOG, which is the default.
882: PETSc automatically logs library events if the code has been
883: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
884: specified. PetscLogEventBegin() is intended for logging user events
885: to supplement this PETSc information.
887: Level: intermediate
889: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops()
891: .keywords: log, event, begin
892: M*/
894: /*MC
895: PetscLogEventEnd - Log the end of a user event.
897: Input Parameters:
898: + e - integer associated with the event obtained with PetscLogEventRegister()
899: - o1,o2,o3,o4 - objects associated with the event, or 0
901: Synopsis:
902: void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
903: PetscObject o4)
905: Fortran Synopsis:
906: void PetscLogEventEnd(int e,PetscErrorCode ierr)
908: Usage:
909: .vb
910: int USER_EVENT;
911: int user_event_flops;
912: PetscLogEventRegister("User event",0,&USER_EVENT,);
913: PetscLogEventBegin(USER_EVENT,0,0,0,0);
914: [code segment to monitor]
915: PetscLogFlops(user_event_flops);
916: PetscLogEventEnd(USER_EVENT,0,0,0,0);
917: .ve
919: Notes:
920: You should also register each additional integer event with the command
921: PetscLogEventRegister(). Source code must be compiled with
922: -DPETSC_USE_LOG, which is the default.
924: PETSc automatically logs library events if the code has been
925: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
926: specified. PetscLogEventEnd() is intended for logging user events
927: to supplement this PETSc information.
929: Level: intermediate
931: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogFlops()
933: .keywords: log, event, end
934: M*/
936: /*MC
937: PetscLogEventBarrierBegin - Logs the time in a barrier before an event.
939: Input Parameters:
940: . e - integer associated with the event obtained from PetscLogEventRegister()
941: . o1,o2,o3,o4 - objects associated with the event, or 0
942: . comm - communicator the barrier takes place over
944: Synopsis:
945: void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
946: PetscObject o4,MPI_Comm comm)
948: Usage:
949: .vb
950: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
951: MPI_Allreduce()
952: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
953: .ve
955: Notes:
956: This is for logging the amount of time spent in a barrier for an event
957: that requires synchronization.
959: Additional Notes:
960: Synchronization events always come in pairs; for example, VEC_NormBarrier and
961: VEC_NormComm = VEC_NormBarrier + 1
963: Level: advanced
965: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
966: PetscLogEventBarrierEnd()
968: .keywords: log, event, begin, barrier
969: M*/
971: /*MC
972: PetscLogEventBarrierEnd - Logs the time in a barrier before an event.
974: Input Parameters:
975: . e - integer associated with the event obtained from PetscLogEventRegister()
976: . o1,o2,o3,o4 - objects associated with the event, or 0
977: . comm - communicator the barrier takes place over
979: Synopsis:
980: void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
981: PetscObject o4,MPI_Comm comm)
983: Usage:
984: .vb
985: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
986: MPI_Allreduce()
987: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
988: .ve
990: Notes:
991: This is for logging the amount of time spent in a barrier for an event
992: that requires synchronization.
994: Additional Notes:
995: Synchronization events always come in pairs; for example, VEC_NormBarrier and
996: VEC_NormComm = VEC_NormBarrier + 1
998: Level: advanced
1000: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
1001: PetscLogEventBarrierBegin()
1003: .keywords: log, event, begin, barrier
1004: M*/
1007: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1010: /*@C
1011: PetscLogDump - Dumps logs of objects to a file. This file is intended to
1012: be read by petsc/bin/petscview.
1014: Collective on PETSC_COMM_WORLD
1016: Input Parameter:
1017: . name - an optional file name
1019: Options Database Keys:
1020: + -log - Prints basic log information (for code compiled with PETSC_USE_LOG)
1021: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
1022:
1023: Usage:
1024: .vb
1025: PetscInitialize(...);
1026: PetscLogBegin(); or PetscLogAllBegin();
1027: ... code ...
1028: PetscLogDump(filename);
1029: PetscFinalize();
1030: .ve
1032: Notes:
1033: The default file name is
1034: $ Log.<rank>
1035: where <rank> is the processor number. If no name is specified,
1036: this file will be used.
1038: Level: advanced
1040: .keywords: log, dump
1041: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
1042: @*/
1043: PetscErrorCode PetscLogDump(const char sname[])
1044: {
1045: StageLog stageLog;
1046: EventPerfInfo *eventInfo;
1047: FILE *fd;
1048: char file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1049: PetscLogDouble flops, _TotalTime;
1050: PetscMPIInt rank;
1051: int action, object, curStage;
1052: PetscLogEvent event;
1054:
1056: /* Calculate the total elapsed time */
1057: PetscTime(_TotalTime);
1058: _TotalTime -= BaseTime;
1059: /* Open log file */
1060: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1061: if (sname) {
1062: sprintf(file, "%s.%d", sname, rank);
1063: } else {
1064: sprintf(file, "Log.%d", rank);
1065: }
1066: PetscFixFilename(file, fname);
1067: PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1068: if ((!rank) && (!fd)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1069: /* Output totals */
1070: PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8e\n", _TotalFlops, _TotalTime);
1071: PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0);
1072: /* Output actions */
1073: if (logActions) {
1074: PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", numActions);
1075: for(action = 0; action < numActions; action++) {
1076: PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n",
1077: actions[action].time, actions[action].action, (int)actions[action].event, (int)actions[action].cookie, actions[action].id1,
1078: actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
1079: }
1080: }
1081: /* Output objects */
1082: if (logObjects) {
1083: PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", numObjects, numObjectsDestroyed);
1084: for(object = 0; object < numObjects; object++) {
1085: PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", objects[object].parent, (int) objects[object].mem);
1086: if (!objects[object].name[0]) {
1087: PetscFPrintf(PETSC_COMM_WORLD, fd,"No Name\n");
1088: } else {
1089: PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", objects[object].name);
1090: }
1091: if (objects[object].info[0] != 0) {
1092: PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n");
1093: } else {
1094: PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", objects[object].info);
1095: }
1096: }
1097: }
1098: /* Output events */
1099: PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:\n");
1100: PetscLogGetStageLog(&stageLog);
1101: StackTop(stageLog->stack, &curStage);
1102: eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1103: for(event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1104: if (eventInfo[event].time != 0.0) {
1105: flops = eventInfo[event].flops/eventInfo[event].time;
1106: } else {
1107: flops = 0.0;
1108: }
1109: PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16g\n", event, eventInfo[event].count,
1110: eventInfo[event].flops, eventInfo[event].time, flops);
1111: }
1112: PetscFClose(PETSC_COMM_WORLD, fd);
1113: return(0);
1114: }
1118: /*@C
1119: PetscLogPrintSummary - Prints a summary of the logging.
1121: Collective over MPI_Comm
1123: Input Parameter:
1124: + comm - The MPI communicator (only one processor prints output)
1125: - file - [Optional] The output file name
1127: Options Database Keys:
1128: . -log_summary - Prints summary of log information (for code compiled with PETSC_USE_LOG)
1130: Usage:
1131: .vb
1132: PetscInitialize(...);
1133: PetscLogBegin();
1134: ... code ...
1135: PetscLogPrintSummary(MPI_Comm,filename);
1136: PetscFinalize(...);
1137: .ve
1139: Notes:
1140: By default the summary is printed to stdout.
1142: Level: beginner
1143:
1144: .keywords: log, dump, print
1145: .seealso: PetscLogBegin(), PetscLogDump()
1146: @*/
1147: PetscErrorCode PetscLogPrintSummary(MPI_Comm comm, const char filename[])
1148: {
1149: FILE *fd = PETSC_STDOUT;
1150: PetscLogDouble zero = 0.0;
1151: StageLog stageLog;
1152: StageInfo *stageInfo = PETSC_NULL;
1153: EventPerfInfo *eventInfo = PETSC_NULL;
1154: ClassPerfInfo *classInfo;
1155: char arch[10], hostname[64], username[16], pname[PETSC_MAX_PATH_LEN], date[64];
1156: const char *name;
1157: PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1158: PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1159: PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1160: PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1161: PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1162: PetscLogDouble min, max, tot, ratio, avg, x, y;
1163: PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1164: PetscMPIInt minCt, maxCt;
1165: PetscMPIInt size, rank;
1166: PetscTruth *localStageUsed, *stageUsed;
1167: PetscTruth *localStageVisible, *stageVisible;
1168: int numStages, localNumEvents, numEvents;
1169: int stage, lastStage, oclass;
1170: PetscLogEvent event;
1172: char version[256];
1175: MPI_Comm_size(comm, &size);
1176: MPI_Comm_rank(comm, &rank);
1177: /* Pop off any stages the user forgot to remove */
1178: lastStage = 0;
1179: PetscLogGetStageLog(&stageLog);
1180: StageLogGetCurrent(stageLog, &stage);
1181: while (stage >= 0) {
1182: lastStage = stage;
1183: StageLogPop(stageLog);
1184: StageLogGetCurrent(stageLog, &stage);
1185: }
1186: /* Get the total elapsed time */
1187: PetscTime(locTotalTime); locTotalTime -= BaseTime;
1188: /* Open the summary file */
1189: if (filename) {
1190: PetscFOpen(comm, filename, "w", &fd);
1191: }
1193: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1194: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***\n");
1195: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1196: PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1197: PetscGetArchType(arch, 10);
1198: PetscGetHostName(hostname, 64);
1199: PetscGetUserName(username, 16);
1200: PetscGetProgramName(pname, PETSC_MAX_PATH_LEN);
1201: PetscGetDate(date, 64);
1202: PetscGetVersion(version,256);
1203: if (size == 1) {
1204: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1205: } else {
1206: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1207: }
1208: PetscFPrintf(comm, fd, "Using %s\n", version);
1210: /* Must preserve reduction count before we go on */
1211: red = (allreduce_ct + gather_ct + scatter_ct)/((PetscLogDouble) size);
1213: /* Calculate summary information */
1214: PetscFPrintf(comm, fd, "\n Max Max/Min Avg Total \n");
1215: /* Time */
1216: MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1217: MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1218: MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1219: avg = (tot)/((PetscLogDouble) size);
1220: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1221: PetscFPrintf(comm, fd, "Time (sec): %5.3e %10.5f %5.3e\n", max, ratio, avg);
1222: TotalTime = tot;
1223: /* Objects */
1224: avg = (PetscLogDouble) numObjects;
1225: MPI_Allreduce(&avg, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1226: MPI_Allreduce(&avg, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1227: MPI_Allreduce(&avg, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1228: avg = (tot)/((PetscLogDouble) size);
1229: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1230: PetscFPrintf(comm, fd, "Objects: %5.3e %10.5f %5.3e\n", max, ratio, avg);
1231: /* Flops */
1232: MPI_Allreduce(&_TotalFlops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1233: MPI_Allreduce(&_TotalFlops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1234: MPI_Allreduce(&_TotalFlops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1235: avg = (tot)/((PetscLogDouble) size);
1236: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1237: PetscFPrintf(comm, fd, "Flops: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1238: TotalFlops = tot;
1239: /* Flops/sec -- Must talk to Barry here */
1240: if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1241: MPI_Allreduce(&flops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1242: MPI_Allreduce(&flops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1243: MPI_Allreduce(&flops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1244: avg = (tot)/((PetscLogDouble) size);
1245: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1246: PetscFPrintf(comm, fd, "Flops/sec: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1247: /* Memory */
1248: PetscMallocGetMaximumUsage(&mem);
1249: if (mem > 0.0) {
1250: MPI_Allreduce(&mem, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1251: MPI_Allreduce(&mem, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1252: MPI_Allreduce(&mem, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1253: avg = (tot)/((PetscLogDouble) size);
1254: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1255: PetscFPrintf(comm, fd, "Memory: %5.3e %10.5f %5.3e\n", max, ratio, tot);
1256: }
1257: /* Messages */
1258: mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1259: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1260: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1261: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1262: avg = (tot)/((PetscLogDouble) size);
1263: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1264: PetscFPrintf(comm, fd, "MPI Messages: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1265: numMessages = tot;
1266: /* Message Lengths */
1267: mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1268: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1269: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1270: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1271: if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1272: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1273: PetscFPrintf(comm, fd, "MPI Message Lengths: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1274: messageLength = tot;
1275: /* Reductions */
1276: MPI_Allreduce(&red, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1277: MPI_Allreduce(&red, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1278: MPI_Allreduce(&red, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1279: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1280: PetscFPrintf(comm, fd, "MPI Reductions: %5.3e %10.5f\n", max, ratio);
1281: numReductions = tot;
1282: PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");
1283: PetscFPrintf(comm, fd, " e.g., VecAXPY() for real vectors of length N --> 2N flops\n");
1284: PetscFPrintf(comm, fd, " and VecAXPY() for complex vectors of length N --> 8N flops\n");
1286: /* Get total number of stages --
1287: Currently, a single processor can register more stages than another, but stages must all be registered in order.
1288: We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1289: This seems best accomplished by assoicating a communicator with each stage.
1290: */
1291: MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1292: PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1293: PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1294: PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1295: PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1296: if (numStages > 0) {
1297: stageInfo = stageLog->stageInfo;
1298: for(stage = 0; stage < numStages; stage++) {
1299: if (stage < stageLog->numStages) {
1300: localStageUsed[stage] = stageInfo[stage].used;
1301: localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1302: } else {
1303: localStageUsed[stage] = PETSC_FALSE;
1304: localStageVisible[stage] = PETSC_TRUE;
1305: }
1306: }
1307: MPI_Allreduce(localStageUsed, stageUsed, numStages, MPI_INT, MPI_LOR, comm);
1308: MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1309: for(stage = 0; stage < numStages; stage++) {
1310: if (stageUsed[stage]) {
1311: PetscFPrintf(comm, fd, "\nSummary of Stages: ----- Time ------ ----- Flops ----- --- Messages --- -- Message Lengths -- -- Reductions --\n");
1312: PetscFPrintf(comm, fd, " Avg %%Total Avg %%Total counts %%Total Avg %%Total counts %%Total \n");
1313: break;
1314: }
1315: }
1316: for(stage = 0; stage < numStages; stage++) {
1317: if (!stageUsed[stage]) continue;
1318: if (localStageUsed[stage]) {
1319: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1320: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1321: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1322: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1323: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1324: name = stageInfo[stage].name;
1325: } else {
1326: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1327: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1328: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1329: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1330: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1331: name = "";
1332: }
1333: mess *= 0.5; messLen *= 0.5; red /= size;
1334: if (TotalTime != 0.0) fracTime = stageTime/TotalTime; else fracTime = 0.0;
1335: if (TotalFlops != 0.0) fracFlops = flops/TotalFlops; else fracFlops = 0.0;
1336: /* Talk to Barry if (stageTime != 0.0) flops = (size*flops)/stageTime; else flops = 0.0; */
1337: if (numMessages != 0.0) fracMessages = mess/numMessages; else fracMessages = 0.0;
1338: if (numMessages != 0.0) avgMessLen = messLen/numMessages; else avgMessLen = 0.0;
1339: if (messageLength != 0.0) fracLength = messLen/messageLength; else fracLength = 0.0;
1340: if (numReductions != 0.0) fracReductions = red/numReductions; else fracReductions = 0.0;
1341: 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",
1342: stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1343: mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1344: }
1345: }
1347: PetscFPrintf(comm, fd,
1348: "\n------------------------------------------------------------------------------------------------------------------------\n");
1349:
1350: PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1351: PetscFPrintf(comm, fd, "Phase summary info:\n");
1352: PetscFPrintf(comm, fd, " Count: number of times phase was executed\n");
1353: PetscFPrintf(comm, fd, " Time and Flops: Max - maximum over all processors\n");
1354: PetscFPrintf(comm, fd, " Ratio - ratio of maximum to minimum over all processors\n");
1355: PetscFPrintf(comm, fd, " Mess: number of messages sent\n");
1356: PetscFPrintf(comm, fd, " Avg. len: average message length\n");
1357: PetscFPrintf(comm, fd, " Reduct: number of global reductions\n");
1358: PetscFPrintf(comm, fd, " Global: entire computation\n");
1359: PetscFPrintf(comm, fd, " Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");
1360: PetscFPrintf(comm, fd, " %%T - percent time in this phase %%F - percent flops in this phase\n");
1361: PetscFPrintf(comm, fd, " %%M - percent messages in this phase %%L - percent message lengths in this phase\n");
1362: PetscFPrintf(comm, fd, " %%R - percent reductions in this phase\n");
1363: PetscFPrintf(comm, fd, " Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)\n");
1364: PetscFPrintf(comm, fd,
1365: "------------------------------------------------------------------------------------------------------------------------\n");
1366:
1368: #if defined(PETSC_USE_DEBUG)
1369: PetscFPrintf(comm, fd, "\n\n");
1370: PetscFPrintf(comm, fd, " ##########################################################\n");
1371: PetscFPrintf(comm, fd, " # #\n");
1372: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1373: PetscFPrintf(comm, fd, " # #\n");
1374: PetscFPrintf(comm, fd, " # This code was compiled with a debugging option, #\n");
1375: PetscFPrintf(comm, fd, " # To get timing results run config/configure.py #\n");
1376: PetscFPrintf(comm, fd, " # using --with-debugging=no, the performance will #\n");
1377: PetscFPrintf(comm, fd, " # be generally two or three times faster. #\n");
1378: PetscFPrintf(comm, fd, " # #\n");
1379: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1380: #endif
1381: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1382: PetscFPrintf(comm, fd, "\n\n");
1383: PetscFPrintf(comm, fd, " ##########################################################\n");
1384: PetscFPrintf(comm, fd, " # #\n");
1385: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1386: PetscFPrintf(comm, fd, " # #\n");
1387: PetscFPrintf(comm, fd, " # The code for various complex numbers numerical #\n");
1388: PetscFPrintf(comm, fd, " # kernels uses C++, which generally is not well #\n");
1389: PetscFPrintf(comm, fd, " # optimized. For performance that is about 4-5 times #\n");
1390: PetscFPrintf(comm, fd, " # faster, specify --with-fortran-kernels=generic #\n");
1391: PetscFPrintf(comm, fd, " # when running config/configure.py. #\n");
1392: PetscFPrintf(comm, fd, " # #\n");
1393: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1394: #endif
1396: /* Report events */
1397: PetscFPrintf(comm, fd,
1398: "Event Count Time (sec) Flops --- Global --- --- Stage --- Total\n");
1399:
1400: PetscFPrintf(comm, fd,
1401: " Max Ratio Max Ratio Max Ratio Mess Avg len Reduct %%T %%F %%M %%L %%R %%T %%F %%M %%L %%R Mflop/s\n");
1402:
1403: PetscFPrintf(comm,fd,
1404: "------------------------------------------------------------------------------------------------------------------------\n");
1406:
1407: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1408: for(stage = 0; stage < numStages; stage++) {
1409: if (!stageVisible[stage]) continue;
1410: if (localStageUsed[stage]) {
1411: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1412: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1413: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1414: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1415: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1416: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1417: } else {
1418: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1419: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1420: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1421: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1422: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1423: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1424: }
1425: mess *= 0.5; messLen *= 0.5; red /= size;
1427: /* Get total number of events in this stage --
1428: Currently, a single processor can register more events than another, but events must all be registered in order,
1429: just like stages. We can removed this requirement if necessary by having a global event numbering and indirection
1430: on the event ID. This seems best accomplished by assoicating a communicator with each stage.
1432: Problem: If the event did not happen on proc 1, its name will not be available.
1433: Problem: Event visibility is not implemented
1434: */
1435: if (localStageUsed[stage]) {
1436: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1437: localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1438: } else {
1439: localNumEvents = 0;
1440: }
1441: MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1442: for(event = 0; event < numEvents; event++) {
1443: if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) {
1444: if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1445: flopr = eventInfo[event].flops;
1446: } else {
1447: flopr = 0.0;
1448: }
1449: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1450: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1451: MPI_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1452: MPI_Allreduce(&eventInfo[event].time, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1453: MPI_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1454: MPI_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1455: MPI_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1456: MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1457: MPI_Allreduce(&eventInfo[event].numReductions, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1458: MPI_Allreduce(&eventInfo[event].count, &minCt, 1, MPI_INT, MPI_MIN, comm);
1459: MPI_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1460: name = stageLog->eventLog->eventInfo[event].name;
1461: } else {
1462: flopr = 0.0;
1463: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1464: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1465: MPI_Allreduce(&zero, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1466: MPI_Allreduce(&zero, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1467: MPI_Allreduce(&zero, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1468: MPI_Allreduce(&zero, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1469: MPI_Allreduce(&zero, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1470: MPI_Allreduce(&zero, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1471: MPI_Allreduce(&zero, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1472: MPI_Allreduce(&ierr, &minCt, 1, MPI_INT, MPI_MIN, comm);
1473: MPI_Allreduce(&ierr, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1474: name = "";
1475: }
1476: if (mint < 0.0) {
1477: 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);
1478: mint = 0;
1479: }
1480: if (minf < 0.0) SETERRQ2(PETSC_ERR_PLIB,"Minimum flops %g over all processors for %s is negative! Not possible!",minf,name);
1481: totm *= 0.5; totml *= 0.5; totr /= size;
1482:
1483: if (maxCt != 0) {
1484: if (minCt != 0) ratCt = ((PetscLogDouble) maxCt)/minCt; else ratCt = 0.0;
1485: if (mint != 0.0) ratt = maxt/mint; else ratt = 0.0;
1486: if (minf != 0.0) ratf = maxf/minf; else ratf = 0.0;
1487: if (TotalTime != 0.0) fracTime = tott/TotalTime; else fracTime = 0.0;
1488: if (TotalFlops != 0.0) fracFlops = totf/TotalFlops; else fracFlops = 0.0;
1489: if (stageTime != 0.0) fracStageTime = tott/stageTime; else fracStageTime = 0.0;
1490: if (flops != 0.0) fracStageFlops = totf/flops; else fracStageFlops = 0.0;
1491: if (numMessages != 0.0) fracMess = totm/numMessages; else fracMess = 0.0;
1492: if (messageLength != 0.0) fracMessLen = totml/messageLength; else fracMessLen = 0.0;
1493: if (numReductions != 0.0) fracRed = totr/numReductions; else fracRed = 0.0;
1494: if (mess != 0.0) fracStageMess = totm/mess; else fracStageMess = 0.0;
1495: if (messLen != 0.0) fracStageMessLen = totml/messLen; else fracStageMessLen = 0.0;
1496: if (red != 0.0) fracStageRed = totr/red; else fracStageRed = 0.0;
1497: if (totm != 0.0) totml /= totm; else totml = 0.0;
1498: if (maxt != 0.0) flopr = totf/maxt; else flopr = 0.0;
1499: PetscFPrintf(comm, fd,
1500: "%-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",
1501: name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1502: 100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1503: 100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1504: flopr/1.0e6);
1505: }
1506: }
1507: }
1509: /* Memory usage and object creation */
1510: PetscFPrintf(comm, fd,
1511: "------------------------------------------------------------------------------------------------------------------------\n");
1512: PetscFPrintf(comm, fd, "\n");
1513: PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");
1515: /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1516: the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1517: stats for stages local to processor sets.
1518: */
1519: /* We should figure out the longest object name here (now 20 characters) */
1520: PetscFPrintf(comm, fd, "Object Type Creations Destructions Memory Descendants' Mem.\n");
1521: for(stage = 0; stage < numStages; stage++) {
1522: if (localStageUsed[stage]) {
1523: classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1524: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1525: for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1526: if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1527: PetscFPrintf(comm, fd, "%20s %5d %5d %9d %g\n", stageLog->classLog->classInfo[oclass].name,
1528: classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1529: classInfo[oclass].descMem);
1530: }
1531: }
1532: } else {
1533: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1534: }
1535: }
1537: PetscFree(localStageUsed);
1538: PetscFree(stageUsed);
1539: PetscFree(localStageVisible);
1540: PetscFree(stageVisible);
1542: /* Information unrelated to this particular run */
1543: PetscFPrintf(comm, fd,
1544: "========================================================================================================================\n");
1545: PetscTime(y);
1546: PetscTime(x);
1547: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1548: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1549: PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1550: /* MPI information */
1551: if (size > 1) {
1552: MPI_Status status;
1553: PetscMPIInt tag;
1554: MPI_Comm newcomm;
1556: MPI_Barrier(comm);
1557: PetscTime(x);
1558: MPI_Barrier(comm);
1559: MPI_Barrier(comm);
1560: MPI_Barrier(comm);
1561: MPI_Barrier(comm);
1562: MPI_Barrier(comm);
1563: PetscTime(y);
1564: PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1565: PetscCommDuplicate(comm,&newcomm, &tag);
1566: MPI_Barrier(comm);
1567: if (rank) {
1568: MPI_Recv(0, 0, MPI_INT, rank-1, tag, newcomm, &status);
1569: MPI_Send(0, 0, MPI_INT, (rank+1)%size, tag, newcomm);
1570: } else {
1571: PetscTime(x);
1572: MPI_Send(0, 0, MPI_INT, 1, tag, newcomm);
1573: MPI_Recv(0, 0, MPI_INT, size-1, tag, newcomm, &status);
1574: PetscTime(y);
1575: PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1576: }
1577: PetscCommDestroy(&newcomm);
1578: }
1579: if (!rank) {
1580: PetscOptionsPrint(fd);
1581: }
1582: /* Machine and compile information */
1583: #if defined(PETSC_USE_FORTRAN_KERNELS)
1584: PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1585: #else
1586: PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1587: #endif
1588: #if defined(PETSC_USE_SINGLE)
1589: PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");
1590: #elif defined(PETSC_USE_LONGDOUBLE)
1591: PetscFPrintf(comm, fd, "Compiled with long double precision PetscScalar and PetscReal\n");
1592: #elif defined(PETSC_USE_INT)
1593: PetscFPrintf(comm, fd, "Compiled with int PetscScalar and PetscReal\n");
1594: #endif
1596: #if defined(PETSC_USE_MAT_SINGLE)
1597: PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1598: #else
1599: PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");
1600: #endif
1601: PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d\n",
1602: (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar));
1604: PetscFPrintf(comm, fd, "Configure run at: %s\n",petscconfigureruntime);
1605: PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);
1606: PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1607: PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1608: PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1609: PetscFPrintf(comm, fd, "%s", petsclinkerinfo);
1611: /* Cleanup */
1612: PetscFPrintf(comm, fd, "\n");
1613: PetscFClose(comm, fd);
1614: StageLogPush(stageLog, lastStage);
1615: return(0);
1616: }
1620: /*@C
1621: PetscLogPrintDetailed - Each process prints the times for its own events
1623: Collective over MPI_Comm
1625: Input Parameter:
1626: + comm - The MPI communicator (only one processor prints output)
1627: - file - [Optional] The output file name
1629: Options Database Keys:
1630: . -log_summary_detailed - Prints summary of log information (for code compiled with PETSC_USE_LOG)
1632: Usage:
1633: .vb
1634: PetscInitialize(...);
1635: PetscLogBegin();
1636: ... code ...
1637: PetscLogPrintDetailed(MPI_Comm,filename);
1638: PetscFinalize(...);
1639: .ve
1641: Notes:
1642: By default the summary is printed to stdout.
1644: Level: beginner
1645:
1646: .keywords: log, dump, print
1647: .seealso: PetscLogBegin(), PetscLogDump(), PetscLogPrintSummary()
1648: @*/
1649: PetscErrorCode PetscLogPrintDetailed(MPI_Comm comm, const char filename[])
1650: {
1651: FILE *fd = PETSC_STDOUT;
1652: StageLog stageLog;
1653: StageInfo *stageInfo = PETSC_NULL;
1654: EventPerfInfo *eventInfo = PETSC_NULL;
1655: const char *name = PETSC_NULL;
1656: PetscLogDouble TotalTime;
1657: PetscLogDouble stageTime, flops, flopr, mess, messLen, red;
1658: PetscLogDouble maxf, totf, maxt, tott, totm, totml, totr = 0.0;
1659: PetscMPIInt maxCt;
1660: PetscMPIInt size, rank;
1661: PetscTruth *stageUsed;
1662: PetscTruth *stageVisible;
1663: int numStages, numEvents;
1664: int stage;
1665: PetscLogEvent event;
1669: MPI_Comm_size(comm, &size);
1670: MPI_Comm_rank(comm, &rank);
1671: /* Pop off any stages the user forgot to remove */
1672: PetscLogGetStageLog(&stageLog);
1673: StageLogGetCurrent(stageLog, &stage);
1674: while (stage >= 0) {
1675: StageLogPop(stageLog);
1676: StageLogGetCurrent(stageLog, &stage);
1677: }
1678: /* Get the total elapsed time */
1679: PetscTime(TotalTime); TotalTime -= BaseTime;
1680: /* Open the summary file */
1681: if (filename) {
1682: PetscFOpen(comm, filename, "w", &fd);
1683: }
1685: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1686: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***\n");
1687: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1690: numStages = stageLog->numStages;
1691: PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1692: PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1693: if (numStages > 0) {
1694: stageInfo = stageLog->stageInfo;
1695: for(stage = 0; stage < numStages; stage++) {
1696: if (stage < stageLog->numStages) {
1697: stageUsed[stage] = stageInfo[stage].used;
1698: stageVisible[stage] = stageInfo[stage].perfInfo.visible;
1699: } else {
1700: stageUsed[stage] = PETSC_FALSE;
1701: stageVisible[stage] = PETSC_TRUE;
1702: }
1703: }
1704: }
1706: /* Report events */
1707: PetscFPrintf(comm, fd,"Event Count Time (sec) Flops/sec \n");
1708: PetscFPrintf(comm, fd," Mess Avg len Reduct \n");
1709: PetscFPrintf(comm,fd,"-----------------------------------------------------------------------------------\n");
1710: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1711: for(stage = 0; stage < numStages; stage++) {
1712: if (!stageVisible[stage]) continue;
1713: if (stageUsed[stage]) {
1714: PetscSynchronizedFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1715: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1716: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1717: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1718: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1719: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1720: }
1721: mess *= 0.5; messLen *= 0.5;
1723: /* Get total number of events in this stage --
1724: */
1725: if (stageUsed[stage]) {
1726: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1727: numEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1728: } else {
1729: numEvents = 0;
1730: }
1731: for(event = 0; event < numEvents; event++) {
1732: if (stageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1733: if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1734: flopr = eventInfo[event].flops/eventInfo[event].time;
1735: } else {
1736: flopr = 0.0;
1737: }
1738: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, PETSC_COMM_SELF);
1739: MPI_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1740: MPI_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, PETSC_COMM_SELF);
1741: MPI_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1742: MPI_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1743: MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1744: totr = eventInfo[event].numReductions;
1745: MPI_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, PETSC_COMM_SELF);
1746: name = stageLog->eventLog->eventInfo[event].name;
1747: totm *= 0.5; totml *= 0.5;
1748: }
1749:
1750: if (maxCt != 0) {
1751: if (totm != 0.0) totml /= totm; else totml = 0.0;
1752: PetscSynchronizedFPrintf(comm, fd,"%-16s %7d %5.4e %3.2e %2.1e %2.1e %2.1e\n",name, maxCt, maxt, maxf, totm, totml, totr);
1753: }
1754: }
1755: }
1756: PetscSynchronizedFlush(comm);
1758: PetscFree(stageUsed);
1759: PetscFree(stageVisible);
1761: PetscFClose(comm, fd);
1762: return(0);
1763: }
1765: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1768: /*@C
1769: PetscGetFlops - Returns the number of flops used on this processor
1770: since the program began.
1772: Not Collective
1774: Output Parameter:
1775: flops - number of floating point operations
1777: Notes:
1778: A global counter logs all PETSc flop counts. The user can use
1779: PetscLogFlops() to increment this counter to include flops for the
1780: application code.
1782: PETSc automatically logs library events if the code has been
1783: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1784: -log_summary, or -log_all are specified. PetscLogFlops() is
1785: intended for logging user flops to supplement this PETSc
1786: information.
1788: Level: intermediate
1790: .keywords: log, flops, floating point operations
1792: .seealso: PetscGetTime(), PetscLogFlops()
1793: @*/
1794: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
1795: {
1797: *flops = _TotalFlops;
1798: return(0);
1799: }
1803: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
1804: {
1806: int fullLength;
1807: va_list Argp;
1810: if (!logObjects) return(0);
1811: va_start(Argp, format);
1812: PetscVSNPrintf(objects[obj->id].info, 64,format,&fullLength, Argp);
1813: va_end(Argp);
1814: return(0);
1815: }
1819: /*@
1820: PetscLogGetStageLog - This function returns the default stage logging object.
1822: Not collective
1824: Output Parameter:
1825: . stageLog - The default StageLog
1827: Level: beginner
1829: .keywords: log, stage
1830: .seealso: StageLogCreate()
1831: @*/
1832: PetscErrorCode PetscLogGetStageLog(StageLog *stageLog)
1833: {
1836: *stageLog = _stageLog;
1837: return(0);
1838: }
1840: /*MC
1841: PetscLogFlops - Adds floating point operations to the global counter.
1843: Input Parameter:
1844: . f - flop counter
1846: Synopsis:
1847: void PetscLogFlops(int f)
1849: Usage:
1850: .vb
1851: int USER_EVENT;
1852: PetscLogEventRegister("User event",0,&USER_EVENT);
1853: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1854: [code segment to monitor]
1855: PetscLogFlops(user_flops)
1856: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1857: .ve
1859: Notes:
1860: A global counter logs all PETSc flop counts. The user can use
1861: PetscLogFlops() to increment this counter to include flops for the
1862: application code.
1864: PETSc automatically logs library events if the code has been
1865: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1866: -log_summary, or -log_all are specified. PetscLogFlops() is
1867: intended for logging user flops to supplement this PETSc
1868: information.
1870: Level: intermediate
1872: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()
1874: .keywords: log, flops, floating point operations
1875: M*/
1877: /*MC
1878: PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1879: to get accurate timings
1881: Input Parameter:
1882: + flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1883: with command line option -preload true or -preload false
1884: - name - name of first stage (lines of code timed separately with -log_summary) to
1885: be preloaded
1887: Synopsis:
1888: void PreLoadBegin(PetscTruth flag,char *name);
1890: Usage:
1891: .vb
1892: PreLoadBegin(PETSC_TRUE,"first stage);
1893: lines of code
1894: PreLoadStage("second stage");
1895: lines of code
1896: PreLoadEnd();
1897: .ve
1899: Notes: Only works in C/C++, not Fortran
1901: Flags available within the macro.
1902: + PetscPreLoadingUsed - true if we are or have done preloading
1903: . PetscPreLoadingOn - true if it is CURRENTLY doing preload
1904: . PreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
1905: - PreLoadMax - number of times it will do the computation, only one when preloading is turned on
1906: The first two variables are available throughout the program, the second two only between the PreLoadBegin()
1907: and PreLoadEnd()
1909: Level: intermediate
1911: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadEnd(), PreLoadStage()
1913: Concepts: preloading
1914: Concepts: timing^accurate
1915: Concepts: paging^eliminating effects of
1918: M*/
1920: /*MC
1921: PreLoadEnd - End a segment of code that may be preloaded (run twice)
1922: to get accurate timings
1924: Synopsis:
1925: void PreLoadEnd(void);
1927: Usage:
1928: .vb
1929: PreLoadBegin(PETSC_TRUE,"first stage);
1930: lines of code
1931: PreLoadStage("second stage");
1932: lines of code
1933: PreLoadEnd();
1934: .ve
1936: Notes: only works in C/C++ not fortran
1938: Level: intermediate
1940: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadStage()
1942: M*/
1944: /*MC
1945: PreLoadStage - Start a new segment of code to be timed separately.
1946: to get accurate timings
1948: Synopsis:
1949: void PreLoadStage(char *name);
1951: Usage:
1952: .vb
1953: PreLoadBegin(PETSC_TRUE,"first stage);
1954: lines of code
1955: PreLoadStage("second stage");
1956: lines of code
1957: PreLoadEnd();
1958: .ve
1960: Notes: only works in C/C++ not fortran
1962: Level: intermediate
1964: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd()
1966: M*/
1968: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1971: /*@C
1972: StackDestroy - This function destroys a stack.
1974: Not Collective
1976: Input Parameter:
1977: . stack - The stack
1979: Level: beginner
1981: .keywords: log, stack, destroy
1982: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
1983: @*/
1984: PetscErrorCode StackDestroy(IntStack stack)
1985: {
1989: PetscFree(stack->stack);
1990: PetscFree(stack);
1991: return(0);
1992: }
1996: /*@C
1997: StackEmpty - This function determines whether any items have been pushed.
1999: Not Collective
2001: Input Parameter:
2002: . stack - The stack
2004: Output Parameter:
2005: . empty - PETSC_TRUE if the stack is empty
2007: Level: intermediate
2009: .keywords: log, stack, empty
2010: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
2011: @*/
2012: PetscErrorCode StackEmpty(IntStack stack, PetscTruth *empty)
2013: {
2016: if (stack->top == -1) {
2017: *empty = PETSC_TRUE;
2018: } else {
2019: *empty = PETSC_FALSE;
2020: }
2021: return(0);
2022: }
2026: /*@C
2027: StackTop - This function returns the top of the stack.
2029: Not Collective
2031: Input Parameter:
2032: . stack - The stack
2034: Output Parameter:
2035: . top - The integer on top of the stack
2037: Level: intermediate
2039: .keywords: log, stack, top
2040: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
2041: @*/
2042: PetscErrorCode StackTop(IntStack stack, int *top)
2043: {
2046: *top = stack->stack[stack->top];
2047: return(0);
2048: }
2052: /*@C
2053: StackPush - This function pushes an integer on the stack.
2055: Not Collective
2057: Input Parameters:
2058: + stack - The stack
2059: - item - The integer to push
2061: Level: intermediate
2063: .keywords: log, stack, push
2064: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
2065: @*/
2066: PetscErrorCode StackPush(IntStack stack, int item)
2067: {
2068: int *array;
2072: stack->top++;
2073: if (stack->top >= stack->max) {
2074: PetscMalloc(stack->max*2 * sizeof(int), &array);
2075: PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
2076: PetscFree(stack->stack);
2077: stack->stack = array;
2078: stack->max *= 2;
2079: }
2080: stack->stack[stack->top] = item;
2081: return(0);
2082: }
2086: /*@C
2087: StackPop - This function pops an integer from the stack.
2089: Not Collective
2091: Input Parameter:
2092: . stack - The stack
2094: Output Parameter:
2095: . item - The integer popped
2097: Level: intermediate
2099: .keywords: log, stack, pop
2100: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
2101: @*/
2102: PetscErrorCode StackPop(IntStack stack, int *item)
2103: {
2106: if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
2107: *item = stack->stack[stack->top--];
2108: return(0);
2109: }
2113: /*@C
2114: StackCreate - This function creates a stack.
2116: Not Collective
2118: Output Parameter:
2119: . stack - The stack
2121: Level: beginner
2123: .keywords: log, stack, pop
2124: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
2125: @*/
2126: PetscErrorCode StackCreate(IntStack *stack)
2127: {
2128: IntStack s;
2133: PetscNew(struct _n_IntStack, &s);
2134: s->top = -1;
2135: s->max = 128;
2136: PetscMalloc(s->max * sizeof(int), &s->stack);
2137: PetscMemzero(s->stack, s->max * sizeof(int));
2138: *stack = s;
2139: return(0);
2140: }
2142: #else /* end of -DPETSC_USE_LOG section */
2146: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2147: {
2149: return(0);
2150: }
2152: #endif /* PETSC_USE_LOG*/
2155: PetscCookie PETSC_LARGEST_COOKIE = PETSC_SMALLEST_COOKIE;
2156: PetscCookie PETSC_OBJECT_COOKIE = 0;
2160: /*@C
2161: PetscCookieRegister - Registers a new class name for objects and logging operations in an application code.
2163: Not Collective
2165: Input Parameter:
2166: . name - The class name
2167:
2168: Output Parameter:
2169: . oclass - The class id or cookie
2171: Level: developer
2173: .keywords: log, class, register
2175: @*/
2176: PetscErrorCode PetscCookieRegister(const char name[],PetscCookie *oclass )
2177: {
2178: #if defined(PETSC_USE_LOG)
2179: StageLog stageLog;
2180: PetscInt stage;
2182: #endif
2185: *oclass = ++PETSC_LARGEST_COOKIE;
2186: #if defined(PETSC_USE_LOG)
2187: PetscLogGetStageLog(&stageLog);
2188: ClassRegLogRegister(stageLog->classLog, name, *oclass);
2189: for(stage = 0; stage < stageLog->numStages; stage++) {
2190: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
2191: }
2192: #endif
2193: return(0);
2194: }