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 */
30: /* Action and object logging variables */
31: Action *actions = PETSC_NULL;
32: Object *objects = PETSC_NULL;
33: PetscTruth logActions = PETSC_FALSE;
34: PetscTruth logObjects = PETSC_FALSE;
35: int numActions = 0, maxActions = 100;
36: int numObjects = 0, maxObjects = 100;
37: int numObjectsDestroyed = 0;
39: /* Global counters */
40: PetscLogDouble BaseTime = 0.0;
41: PetscLogDouble _TotalFlops = 0.0; /* The number of flops */
42: PetscLogDouble petsc_tmp_flops = 0.0; /* The incremental number of flops */
43: PetscLogDouble send_ct = 0.0; /* The number of sends */
44: PetscLogDouble recv_ct = 0.0; /* The number of receives */
45: PetscLogDouble send_len = 0.0; /* The total length of all sent messages */
46: PetscLogDouble recv_len = 0.0; /* The total length of all received messages */
47: PetscLogDouble isend_ct = 0.0; /* The number of immediate sends */
48: PetscLogDouble irecv_ct = 0.0; /* The number of immediate receives */
49: PetscLogDouble isend_len = 0.0; /* The total length of all immediate send messages */
50: PetscLogDouble irecv_len = 0.0; /* The total length of all immediate receive messages */
51: PetscLogDouble wait_ct = 0.0; /* The number of waits */
52: PetscLogDouble wait_any_ct = 0.0; /* The number of anywaits */
53: PetscLogDouble wait_all_ct = 0.0; /* The number of waitalls */
54: PetscLogDouble sum_of_waits_ct = 0.0; /* The total number of waits */
55: PetscLogDouble allreduce_ct = 0.0; /* The number of reductions */
56: PetscLogDouble gather_ct = 0.0; /* The number of gathers and gathervs */
57: PetscLogDouble scatter_ct = 0.0; /* The number of scatters and scattervs */
59: /* Logging functions */
60: PetscErrorCode (*_PetscLogPHC)(PetscObject) = PETSC_NULL;
61: PetscErrorCode (*_PetscLogPHD)(PetscObject) = PETSC_NULL;
62: PetscErrorCode (*_PetscLogPLB)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
63: PetscErrorCode (*_PetscLogPLE)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
65: /* Tracing event logging variables */
66: FILE *tracefile = PETSC_NULL;
67: int tracelevel = 0;
68: const char *traceblanks = " ";
69: char tracespace[128] = " ";
70: PetscLogDouble tracetime = 0.0;
72: /*---------------------------------------------- General Functions --------------------------------------------------*/
75: /*@C
76: PetscLogDestroy - Destroys the object and event logging data and resets the global counters.
78: Not Collective
80: Notes:
81: This routine should not usually be used by programmers. Instead employ
82: PetscLogStagePush() and PetscLogStagePop().
84: Level: developer
86: .keywords: log, destroy
87: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogStagePush(), PlogStagePop()
88: @*/
89: PetscErrorCode PetscLogDestroy(void)
90: {
91: StageLog stageLog;
95: PetscFree(actions);
96: actions = PETSC_NULL;
97: PetscFree(objects);
98: objects = PETSC_NULL;
99: PetscLogSet(PETSC_NULL, PETSC_NULL);
101: /* Resetting phase */
102: PetscLogGetStageLog(&stageLog);
103: StageLogDestroy(stageLog);
104: _TotalFlops = 0.0;
105: numActions = 0;
106: numObjects = 0;
107: numObjectsDestroyed = 0;
108: return(0);
109: }
113: /*@C
114: PetscLogSet - Sets the logging functions called at the beginning and ending of every event.
116: Not Collective
118: Input Parameters:
119: + b - The function called at beginning of event
120: - e - The function called at end of event
122: Level: developer
124: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
125: @*/
126: PetscErrorCode PetscLogSet(PetscErrorCode (*b)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject),
127: PetscErrorCode (*e)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject))
128: {
130: _PetscLogPLB = b;
131: _PetscLogPLE = e;
132: return(0);
133: }
135: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
138: PetscErrorCode PetscLogBegin_Private(void)
139: {
140: static PetscTruth initialized = PETSC_FALSE;
141: int stage;
142: PetscTruth opt;
143: PetscErrorCode ierr;
146: if (initialized) return(0);
147: initialized = PETSC_TRUE;
148: PetscOptionsHasName(PETSC_NULL, "-log_exclude_actions", &opt);
149: if (opt) {
150: logActions = PETSC_FALSE;
151: }
152: PetscOptionsHasName(PETSC_NULL, "-log_exclude_objects", &opt);
153: if (opt) {
154: logObjects = PETSC_FALSE;
155: }
156: if (logActions) {
157: PetscMalloc(maxActions * sizeof(Action), &actions);
158: }
159: if (logObjects) {
160: PetscMalloc(maxObjects * sizeof(Object), &objects);
161: }
162: _PetscLogPHC = PetscLogObjCreateDefault;
163: _PetscLogPHD = PetscLogObjDestroyDefault;
164: /* Setup default logging structures */
165: StageLogCreate(&_stageLog);
166: StageLogRegister(_stageLog, "Main Stage", &stage);
167: /* All processors sync here for more consistent logging */
168: MPI_Barrier(PETSC_COMM_WORLD);
169: PetscTime(BaseTime);
170: PetscLogStagePush(stage);
171: return(0);
172: }
176: /*@C
177: PetscLogBegin - Turns on logging of objects and events. This logs flop
178: rates and object creation and should not slow programs down too much.
179: This routine may be called more than once.
181: Collective over PETSC_COMM_WORLD
183: Options Database Keys:
184: + -log_summary - Prints summary of flop and timing information to the
185: screen (for code compiled with PETSC_USE_LOG)
186: - -log - Prints detailed log information (for code compiled with PETSC_USE_LOG)
188: Usage:
189: .vb
190: PetscInitialize(...);
191: PetscLogBegin();
192: ... code ...
193: PetscLogPrintSummary(MPI_Comm,filename); or PetscLogDump();
194: PetscFinalize();
195: .ve
197: Notes:
198: PetscLogPrintSummary(MPI_Comm,filename) or PetscLogDump() actually cause the printing of
199: the logging information.
201: Level: advanced
203: .keywords: log, begin
204: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogTraceBegin()
205: @*/
206: PetscErrorCode PetscLogBegin(void)
207: {
211: PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
212: PetscLogBegin_Private();
213: return(0);
214: }
218: /*@C
219: PetscLogAllBegin - Turns on extensive logging of objects and events. Logs
220: all events. This creates large log files and slows the program down.
222: Collective on PETSC_COMM_WORLD
224: Options Database Keys:
225: . -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
227: Usage:
228: .vb
229: PetscInitialize(...);
230: PetscLogAllBegin();
231: ... code ...
232: PetscLogDump(filename);
233: PetscFinalize();
234: .ve
236: Notes:
237: A related routine is PetscLogBegin (with the options key -log), which is
238: intended for production runs since it logs only flop rates and object
239: creation (and shouldn't significantly slow the programs).
241: Level: advanced
243: .keywords: log, all, begin
244: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogTraceBegin()
245: @*/
246: PetscErrorCode PetscLogAllBegin(void)
247: {
251: PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
252: PetscLogBegin_Private();
253: return(0);
254: }
258: /*@
259: PetscLogTraceBegin - Activates trace logging. Every time a PETSc event
260: begins or ends, the event name is printed.
262: Collective on PETSC_COMM_WORLD
264: Input Parameter:
265: . file - The file to print trace in (e.g. stdout)
267: Options Database Key:
268: . -log_trace [filename] - Activates PetscLogTraceBegin()
270: Notes:
271: PetscLogTraceBegin() prints the processor number, the execution time (sec),
272: then "Event begin:" or "Event end:" followed by the event name.
274: PetscLogTraceBegin() allows tracing of all PETSc calls, which is useful
275: to determine where a program is hanging without running in the
276: debugger. Can be used in conjunction with the -info option.
278: Level: intermediate
280: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogBegin()
281: @*/
282: PetscErrorCode PetscLogTraceBegin(FILE *file)
283: {
287: tracefile = file;
288: PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
289: PetscLogBegin_Private();
290: return(0);
291: }
295: /*@
296: PetscLogActions - Determines whether actions are logged for the graphical viewer.
298: Not Collective
300: Input Parameter:
301: . flag - PETSC_TRUE if actions are to be logged
303: Level: intermediate
305: Note: Logging of actions continues to consume more memory as the program
306: runs. Long running programs should consider turning this feature off.
308: Options Database Keys:
309: . -log_exclude_actions - Turns off actions logging
311: .keywords: log, stage, register
312: .seealso: PetscLogStagePush(), PetscLogStagePop()
313: @*/
314: PetscErrorCode PetscLogActions(PetscTruth flag)
315: {
317: logActions = flag;
318: return(0);
319: }
323: /*@
324: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
326: Not Collective
328: Input Parameter:
329: . flag - PETSC_TRUE if objects are to be logged
331: Level: intermediate
333: Note: Logging of objects continues to consume more memory as the program
334: runs. Long running programs should consider turning this feature off.
336: Options Database Keys:
337: . -log_exclude_objects - Turns off objects logging
339: .keywords: log, stage, register
340: .seealso: PetscLogStagePush(), PetscLogStagePop()
341: @*/
342: PetscErrorCode PetscLogObjects(PetscTruth flag)
343: {
345: logObjects = flag;
346: return(0);
347: }
349: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
352: /*@C
353: PetscLogStageRegister - Attaches a charactor string name to a logging stage.
355: Not Collective
357: Input Parameter:
358: . sname - The name to associate with that stage
360: Output Parameter:
361: . stage - The stage number
363: Level: intermediate
365: .keywords: log, stage, register
366: .seealso: PetscLogStagePush(), PetscLogStagePop()
367: @*/
368: PetscErrorCode PetscLogStageRegister(const char sname[],PetscLogStage *stage)
369: {
370: StageLog stageLog;
371: PetscLogEvent event;
375: PetscLogGetStageLog(&stageLog);
376: StageLogRegister(stageLog, sname, stage);
377: /* Copy events already changed in the main stage, this sucks */
378: EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
379: for(event = 0; event < stageLog->eventLog->numEvents; event++) {
380: EventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],
381: &stageLog->stageInfo[*stage].eventLog->eventInfo[event]);
382: }
383: ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
384: return(0);
385: }
389: /*@C
390: PetscLogStagePush - This function pushes a stage on the stack.
392: Not Collective
394: Input Parameter:
395: . stage - The stage on which to log
397: Usage:
398: If the option -log_sumary is used to run the program containing the
399: following code, then 2 sets of summary data will be printed during
400: PetscFinalize().
401: .vb
402: PetscInitialize(int *argc,char ***args,0,0);
403: [stage 0 of code]
404: PetscLogStagePush(1);
405: [stage 1 of code]
406: PetscLogStagePop();
407: PetscBarrier(...);
408: [more stage 0 of code]
409: PetscFinalize();
410: .ve
411:
412: Notes:
413: Use PetscLogStageRegister() to register a stage.
415: Level: intermediate
417: .keywords: log, push, stage
418: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
419: @*/
420: PetscErrorCode PetscLogStagePush(PetscLogStage stage)
421: {
422: StageLog stageLog;
426: PetscLogGetStageLog(&stageLog);
427: StageLogPush(stageLog, stage);
428: return(0);
429: }
433: /*@C
434: PetscLogStagePop - This function pops a stage from the stack.
436: Not Collective
438: Usage:
439: If the option -log_sumary is used to run the program containing the
440: following code, then 2 sets of summary data will be printed during
441: PetscFinalize().
442: .vb
443: PetscInitialize(int *argc,char ***args,0,0);
444: [stage 0 of code]
445: PetscLogStagePush(1);
446: [stage 1 of code]
447: PetscLogStagePop();
448: PetscBarrier(...);
449: [more stage 0 of code]
450: PetscFinalize();
451: .ve
453: Notes:
454: Use PetscLogStageRegister() to register a stage.
456: Level: intermediate
458: .keywords: log, pop, stage
459: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
460: @*/
461: PetscErrorCode PetscLogStagePop(void)
462: {
463: StageLog stageLog;
467: PetscLogGetStageLog(&stageLog);
468: StageLogPop(stageLog);
469: return(0);
470: }
474: /*@
475: PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().
477: Not Collective
479: Input Parameters:
480: + stage - The stage
481: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
483: Level: intermediate
485: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
486: @*/
487: PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscTruth isActive)
488: {
489: StageLog stageLog;
493: PetscLogGetStageLog(&stageLog);
494: StageLogSetActive(stageLog, stage, isActive);
495: return(0);
496: }
500: /*@
501: PetscLogStageGetActive - Returns stage activity for PetscLogEventBegin() and PetscLogEventEnd().
503: Not Collective
505: Input Parameter:
506: . stage - The stage
508: Output Parameter:
509: . isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
511: Level: intermediate
513: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
514: @*/
515: PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscTruth *isActive)
516: {
517: StageLog stageLog;
521: PetscLogGetStageLog(&stageLog);
522: StageLogGetActive(stageLog, stage, isActive);
523: return(0);
524: }
528: /*@
529: PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()
531: Not Collective
533: Input Parameters:
534: + stage - The stage
535: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
537: Level: intermediate
539: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
540: @*/
541: PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscTruth isVisible)
542: {
543: StageLog stageLog;
547: PetscLogGetStageLog(&stageLog);
548: StageLogSetVisible(stageLog, stage, isVisible);
549: return(0);
550: }
554: /*@
555: PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()
557: Not Collective
559: Input Parameter:
560: . stage - The stage
562: Output Parameter:
563: . isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
565: Level: intermediate
567: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
568: @*/
569: PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscTruth *isVisible)
570: {
571: StageLog stageLog;
575: PetscLogGetStageLog(&stageLog);
576: StageLogGetVisible(stageLog, stage, isVisible);
577: return(0);
578: }
582: /*@C
583: PetscLogStageGetId - Returns the stage id when given the stage name.
585: Not Collective
587: Input Parameter:
588: . name - The stage name
590: Output Parameter:
591: . stage - The stage
593: Level: intermediate
595: .seealso: PetscLogStagePush(), PetscLogStagePop(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
596: @*/
597: PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
598: {
599: StageLog stageLog;
603: PetscLogGetStageLog(&stageLog);
604: StageLogGetStage(stageLog, name, stage);
605: return(0);
606: }
608: /*------------------------------------------------ Event Functions --------------------------------------------------*/
611: /*@C
612: PetscLogEventRegister - Registers an event name for logging operations in an application code.
614: Not Collective
616: Input Parameter:
617: + name - The name associated with the event
618: - cookie - The cookie associated to the class for this event, obtain either with
619: PetscCookieRegister() or use a predefined one such as KSP_COOKIE, SNES_COOKIE
620:
621: Output Parameter:
622: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().
624: Example of Usage:
625: .vb
626: PetscLogEvent USER_EVENT;
627: PetscCookie cookie;
628: int user_event_flops;
629: PetscCookieRegister("class name",&cookie);
630: PetscLogEventRegister("User event name",cookie,&USER_EVENT);
631: PetscLogEventBegin(USER_EVENT,0,0,0,0);
632: [code segment to monitor]
633: PetscLogFlops(user_event_flops);
634: PetscLogEventEnd(USER_EVENT,0,0,0,0);
635: .ve
637: Notes:
638: PETSc automatically logs library events if the code has been
639: compiled with -DPETSC_USE_LOG (which is the default) and -log,
640: -log_summary, or -log_all are specified. PetscLogEventRegister() is
641: intended for logging user events to supplement this PETSc
642: information.
644: PETSc can gather data for use with the utilities Upshot/Nupshot
645: (part of the MPICH distribution). If PETSc has been compiled
646: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
647: MPICH), the user can employ another command line option, -log_mpe,
648: to create a logfile, "mpe.log", which can be visualized
649: Upshot/Nupshot.
651: The cookie is associated with each event so that classes of events
652: can be disabled simultaneously, such as all matrix events. The user
653: can either use an existing cookie, such as MAT_COOKIE, or create
654: their own as shown in the example.
656: Level: intermediate
658: .keywords: log, event, register
659: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
660: PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
661: PetscLogEventActivate(), PetscLogEventDeactivate(), PetscCookieRegister()
662: @*/
663: PetscErrorCode PetscLogEventRegister(const char name[],PetscCookie cookie,PetscLogEvent *event)
664: {
665: StageLog stageLog;
666: int stage;
670: *event = PETSC_DECIDE;
671: PetscLogGetStageLog(&stageLog);
672: EventRegLogRegister(stageLog->eventLog, name, cookie, event);
673: for(stage = 0; stage < stageLog->numStages; stage++) {
674: EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
675: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
676: }
677: return(0);
678: }
682: /*@
683: PetscLogEventActivate - Indicates that a particular event should be logged.
685: Not Collective
687: Input Parameter:
688: . event - The event id
690: Usage:
691: .vb
692: PetscLogEventDeactivate(VEC_SetValues);
693: [code where you do not want to log VecSetValues()]
694: PetscLogEventActivate(VEC_SetValues);
695: [code where you do want to log VecSetValues()]
696: .ve
698: Note:
699: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
700: or an event number obtained with PetscLogEventRegister().
702: Level: advanced
704: .keywords: log, event, activate
705: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
706: @*/
707: PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
708: {
709: StageLog stageLog;
710: int stage;
714: PetscLogGetStageLog(&stageLog);
715: StageLogGetCurrent(stageLog, &stage);
716: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
717: return(0);
718: }
722: /*@
723: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
725: Not Collective
727: Input Parameter:
728: . event - The event id
730: Usage:
731: .vb
732: PetscLogEventDeactivate(VEC_SetValues);
733: [code where you do not want to log VecSetValues()]
734: PetscLogEventActivate(VEC_SetValues);
735: [code where you do want to log VecSetValues()]
736: .ve
738: Note:
739: The event may be either a pre-defined PETSc event (found in
740: include/petsclog.h) or an event number obtained with PetscLogEventRegister()).
742: Level: advanced
744: .keywords: log, event, deactivate
745: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
746: @*/
747: PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
748: {
749: StageLog stageLog;
750: int stage;
754: PetscLogGetStageLog(&stageLog);
755: StageLogGetCurrent(stageLog, &stage);
756: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
757: return(0);
758: }
762: /*@
763: PetscLogEventSetActiveAll - Sets the event activity in every stage.
765: Not Collective
767: Input Parameters:
768: + event - The event id
769: - isActive - The activity flag determining whether the event is logged
771: Level: advanced
773: .keywords: log, event, activate
774: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
775: @*/
776: PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscTruth isActive)
777: {
778: StageLog stageLog;
779: int stage;
783: PetscLogGetStageLog(&stageLog);
784: for(stage = 0; stage < stageLog->numStages; stage++) {
785: if (isActive) {
786: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
787: } else {
788: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
789: }
790: }
791: return(0);
792: }
796: /*@
797: PetscLogEventActivateClass - Activates event logging for a PETSc object class.
799: Not Collective
801: Input Parameter:
802: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
804: Level: developer
806: .keywords: log, event, activate, class
807: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
808: @*/
809: PetscErrorCode PetscLogEventActivateClass(PetscCookie cookie)
810: {
811: StageLog stageLog;
812: int stage;
816: PetscLogGetStageLog(&stageLog);
817: StageLogGetCurrent(stageLog, &stage);
818: EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
819: return(0);
820: }
824: /*@
825: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.
827: Not Collective
829: Input Parameter:
830: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
832: Level: developer
834: .keywords: log, event, deactivate, class
835: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
836: @*/
837: PetscErrorCode PetscLogEventDeactivateClass(PetscCookie cookie)
838: {
839: StageLog stageLog;
840: int stage;
844: PetscLogGetStageLog(&stageLog);
845: StageLogGetCurrent(stageLog, &stage);
846: EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
847: return(0);
848: }
850: /*MC
851: PetscLogEventBegin - Logs the beginning of a user event.
853: Input Parameters:
854: + e - integer associated with the event obtained from PetscLogEventRegister()
855: - o1,o2,o3,o4 - objects associated with the event, or 0
857: Synopsis:
858: void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
859: PetscObject o4)
861: Fortran Synopsis:
862: void PetscLogEventEnd(int e,PetscErrorCode ierr)
864: Usage:
865: .vb
866: int USER_EVENT;
867: int user_event_flops;
868: PetscLogEventRegister("User event",0,&USER_EVENT);
869: PetscLogEventBegin(USER_EVENT,0,0,0,0);
870: [code segment to monitor]
871: PetscLogFlops(user_event_flops);
872: PetscLogEventEnd(USER_EVENT,0,0,0,0);
873: .ve
875: Notes:
876: You need to register each integer event with the command
877: PetscLogEventRegister(). The source code must be compiled with
878: -DPETSC_USE_LOG, which is the default.
880: PETSc automatically logs library events if the code has been
881: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
882: specified. PetscLogEventBegin() is intended for logging user events
883: to supplement this PETSc information.
885: Level: intermediate
887: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops()
889: .keywords: log, event, begin
890: M*/
892: /*MC
893: PetscLogEventEnd - Log the end of a user event.
895: Input Parameters:
896: + e - integer associated with the event obtained with PetscLogEventRegister()
897: - o1,o2,o3,o4 - objects associated with the event, or 0
899: Synopsis:
900: void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
901: PetscObject o4)
903: Fortran Synopsis:
904: void PetscLogEventEnd(int e,PetscErrorCode ierr)
906: Usage:
907: .vb
908: int USER_EVENT;
909: int user_event_flops;
910: PetscLogEventRegister("User event",0,&USER_EVENT,);
911: PetscLogEventBegin(USER_EVENT,0,0,0,0);
912: [code segment to monitor]
913: PetscLogFlops(user_event_flops);
914: PetscLogEventEnd(USER_EVENT,0,0,0,0);
915: .ve
917: Notes:
918: You should also register each additional integer event with the command
919: PetscLogEventRegister(). Source code must be compiled with
920: -DPETSC_USE_LOG, which is the default.
922: PETSc automatically logs library events if the code has been
923: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
924: specified. PetscLogEventEnd() is intended for logging user events
925: to supplement this PETSc information.
927: Level: intermediate
929: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogFlops()
931: .keywords: log, event, end
932: M*/
934: /*MC
935: PetscLogEventBarrierBegin - Logs the time in a barrier before an event.
937: Input Parameters:
938: . e - integer associated with the event obtained from PetscLogEventRegister()
939: . o1,o2,o3,o4 - objects associated with the event, or 0
940: . comm - communicator the barrier takes place over
942: Synopsis:
943: void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
944: PetscObject o4,MPI_Comm comm)
946: Usage:
947: .vb
948: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
949: MPI_Allreduce()
950: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
951: .ve
953: Notes:
954: This is for logging the amount of time spent in a barrier for an event
955: that requires synchronization.
957: Additional Notes:
958: Synchronization events always come in pairs; for example, VEC_NormBarrier and
959: VEC_NormComm = VEC_NormBarrier + 1
961: Level: advanced
963: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
964: PetscLogEventBarrierEnd()
966: .keywords: log, event, begin, barrier
967: M*/
969: /*MC
970: PetscLogEventBarrierEnd - Logs the time in a barrier before an event.
972: Input Parameters:
973: . e - integer associated with the event obtained from PetscLogEventRegister()
974: . o1,o2,o3,o4 - objects associated with the event, or 0
975: . comm - communicator the barrier takes place over
977: Synopsis:
978: void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
979: PetscObject o4,MPI_Comm comm)
981: Usage:
982: .vb
983: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
984: MPI_Allreduce()
985: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
986: .ve
988: Notes:
989: This is for logging the amount of time spent in a barrier for an event
990: that requires synchronization.
992: Additional Notes:
993: Synchronization events always come in pairs; for example, VEC_NormBarrier and
994: VEC_NormComm = VEC_NormBarrier + 1
996: Level: advanced
998: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
999: PetscLogEventBarrierBegin()
1001: .keywords: log, event, begin, barrier
1002: M*/
1006: /*@C
1007: PetscLogEventGetId - Returns the event id when given the event name.
1009: Not Collective
1011: Input Parameter:
1012: . name - The event name
1014: Output Parameter:
1015: . event - The event
1017: Level: intermediate
1019: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStageGetId()
1020: @*/
1021: PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1022: {
1023: StageLog stageLog;
1027: PetscLogGetStageLog(&stageLog);
1028: EventRegLogGetEvent(stageLog->eventLog, name, event);
1029: return(0);
1030: }
1033: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1036: /*@C
1037: PetscLogDump - Dumps logs of objects to a file. This file is intended to
1038: be read by petsc/bin/petscview.
1040: Collective on PETSC_COMM_WORLD
1042: Input Parameter:
1043: . name - an optional file name
1045: Options Database Keys:
1046: + -log - Prints basic log information (for code compiled with PETSC_USE_LOG)
1047: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
1048:
1049: Usage:
1050: .vb
1051: PetscInitialize(...);
1052: PetscLogBegin(); or PetscLogAllBegin();
1053: ... code ...
1054: PetscLogDump(filename);
1055: PetscFinalize();
1056: .ve
1058: Notes:
1059: The default file name is
1060: $ Log.<rank>
1061: where <rank> is the processor number. If no name is specified,
1062: this file will be used.
1064: Level: advanced
1066: .keywords: log, dump
1067: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
1068: @*/
1069: PetscErrorCode PetscLogDump(const char sname[])
1070: {
1071: StageLog stageLog;
1072: EventPerfInfo *eventInfo;
1073: FILE *fd;
1074: char file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1075: PetscLogDouble flops, _TotalTime;
1076: PetscMPIInt rank;
1077: int action, object, curStage;
1078: PetscLogEvent event;
1080:
1082: /* Calculate the total elapsed time */
1083: PetscTime(_TotalTime);
1084: _TotalTime -= BaseTime;
1085: /* Open log file */
1086: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1087: if (sname) {
1088: sprintf(file, "%s.%d", sname, rank);
1089: } else {
1090: sprintf(file, "Log.%d", rank);
1091: }
1092: PetscFixFilename(file, fname);
1093: PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1094: if ((!rank) && (!fd)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1095: /* Output totals */
1096: PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8e\n", _TotalFlops, _TotalTime);
1097: PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0);
1098: /* Output actions */
1099: if (logActions) {
1100: PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", numActions);
1101: for(action = 0; action < numActions; action++) {
1102: PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n",
1103: actions[action].time, actions[action].action, (int)actions[action].event, (int)actions[action].cookie, actions[action].id1,
1104: actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
1105: }
1106: }
1107: /* Output objects */
1108: if (logObjects) {
1109: PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", numObjects, numObjectsDestroyed);
1110: for(object = 0; object < numObjects; object++) {
1111: PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", objects[object].parent, (int) objects[object].mem);
1112: if (!objects[object].name[0]) {
1113: PetscFPrintf(PETSC_COMM_WORLD, fd,"No Name\n");
1114: } else {
1115: PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", objects[object].name);
1116: }
1117: if (objects[object].info[0] != 0) {
1118: PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n");
1119: } else {
1120: PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", objects[object].info);
1121: }
1122: }
1123: }
1124: /* Output events */
1125: PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:\n");
1126: PetscLogGetStageLog(&stageLog);
1127: StackTop(stageLog->stack, &curStage);
1128: eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1129: for(event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1130: if (eventInfo[event].time != 0.0) {
1131: flops = eventInfo[event].flops/eventInfo[event].time;
1132: } else {
1133: flops = 0.0;
1134: }
1135: PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16g\n", event, eventInfo[event].count,
1136: eventInfo[event].flops, eventInfo[event].time, flops);
1137: }
1138: PetscFClose(PETSC_COMM_WORLD, fd);
1139: return(0);
1140: }
1144: /*@C
1145: PetscLogPrintSummary - Prints a summary of the logging.
1147: Collective over MPI_Comm
1149: Input Parameter:
1150: + comm - The MPI communicator (only one processor prints output)
1151: - file - [Optional] The output file name
1153: Options Database Keys:
1154: . -log_summary - Prints summary of log information (for code compiled with PETSC_USE_LOG)
1156: Usage:
1157: .vb
1158: PetscInitialize(...);
1159: PetscLogBegin();
1160: ... code ...
1161: PetscLogPrintSummary(MPI_Comm,filename);
1162: PetscFinalize(...);
1163: .ve
1165: Notes:
1166: By default the summary is printed to stdout.
1168: Level: beginner
1169:
1170: .keywords: log, dump, print
1171: .seealso: PetscLogBegin(), PetscLogDump()
1172: @*/
1173: PetscErrorCode PetscLogPrintSummary(MPI_Comm comm, const char filename[])
1174: {
1175: FILE *fd = PETSC_STDOUT;
1176: PetscLogDouble zero = 0.0;
1177: StageLog stageLog;
1178: StageInfo *stageInfo = PETSC_NULL;
1179: EventPerfInfo *eventInfo = PETSC_NULL;
1180: ClassPerfInfo *classInfo;
1181: char arch[10], hostname[64], username[16], pname[PETSC_MAX_PATH_LEN], date[64];
1182: const char *name;
1183: PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1184: PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1185: PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1186: PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1187: PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1188: PetscLogDouble min, max, tot, ratio, avg, x, y;
1189: PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1190: PetscMPIInt minCt, maxCt;
1191: PetscMPIInt size, rank;
1192: PetscTruth *localStageUsed, *stageUsed;
1193: PetscTruth *localStageVisible, *stageVisible;
1194: int numStages, localNumEvents, numEvents;
1195: int stage, lastStage, oclass;
1196: PetscLogEvent event;
1198: char version[256];
1201: MPI_Comm_size(comm, &size);
1202: MPI_Comm_rank(comm, &rank);
1203: /* Pop off any stages the user forgot to remove */
1204: lastStage = 0;
1205: PetscLogGetStageLog(&stageLog);
1206: StageLogGetCurrent(stageLog, &stage);
1207: while (stage >= 0) {
1208: lastStage = stage;
1209: StageLogPop(stageLog);
1210: StageLogGetCurrent(stageLog, &stage);
1211: }
1212: /* Get the total elapsed time */
1213: PetscTime(locTotalTime); locTotalTime -= BaseTime;
1214: /* Open the summary file */
1215: if (filename) {
1216: PetscFOpen(comm, filename, "w", &fd);
1217: }
1219: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1220: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***\n");
1221: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1222: PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1223: PetscGetArchType(arch, 10);
1224: PetscGetHostName(hostname, 64);
1225: PetscGetUserName(username, 16);
1226: PetscGetProgramName(pname, PETSC_MAX_PATH_LEN);
1227: PetscGetDate(date, 64);
1228: PetscGetVersion(version,256);
1229: if (size == 1) {
1230: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1231: } else {
1232: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1233: }
1234: PetscFPrintf(comm, fd, "Using %s\n", version);
1236: /* Must preserve reduction count before we go on */
1237: red = (allreduce_ct + gather_ct + scatter_ct)/((PetscLogDouble) size);
1239: /* Calculate summary information */
1240: PetscFPrintf(comm, fd, "\n Max Max/Min Avg Total \n");
1241: /* Time */
1242: MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1243: MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1244: MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1245: avg = (tot)/((PetscLogDouble) size);
1246: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1247: PetscFPrintf(comm, fd, "Time (sec): %5.3e %10.5f %5.3e\n", max, ratio, avg);
1248: TotalTime = tot;
1249: /* Objects */
1250: avg = (PetscLogDouble) numObjects;
1251: MPI_Allreduce(&avg, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1252: MPI_Allreduce(&avg, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1253: MPI_Allreduce(&avg, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1254: avg = (tot)/((PetscLogDouble) size);
1255: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1256: PetscFPrintf(comm, fd, "Objects: %5.3e %10.5f %5.3e\n", max, ratio, avg);
1257: /* Flops */
1258: MPI_Allreduce(&_TotalFlops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1259: MPI_Allreduce(&_TotalFlops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1260: MPI_Allreduce(&_TotalFlops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1261: avg = (tot)/((PetscLogDouble) size);
1262: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1263: PetscFPrintf(comm, fd, "Flops: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1264: TotalFlops = tot;
1265: /* Flops/sec -- Must talk to Barry here */
1266: if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1267: MPI_Allreduce(&flops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1268: MPI_Allreduce(&flops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1269: MPI_Allreduce(&flops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1270: avg = (tot)/((PetscLogDouble) size);
1271: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1272: PetscFPrintf(comm, fd, "Flops/sec: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1273: /* Memory */
1274: PetscMallocGetMaximumUsage(&mem);
1275: if (mem > 0.0) {
1276: MPI_Allreduce(&mem, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1277: MPI_Allreduce(&mem, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1278: MPI_Allreduce(&mem, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1279: avg = (tot)/((PetscLogDouble) size);
1280: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1281: PetscFPrintf(comm, fd, "Memory: %5.3e %10.5f %5.3e\n", max, ratio, tot);
1282: }
1283: /* Messages */
1284: mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1285: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1286: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1287: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1288: avg = (tot)/((PetscLogDouble) size);
1289: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1290: PetscFPrintf(comm, fd, "MPI Messages: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1291: numMessages = tot;
1292: /* Message Lengths */
1293: mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1294: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1295: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1296: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1297: if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1298: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1299: PetscFPrintf(comm, fd, "MPI Message Lengths: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1300: messageLength = tot;
1301: /* Reductions */
1302: MPI_Allreduce(&red, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1303: MPI_Allreduce(&red, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1304: MPI_Allreduce(&red, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1305: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1306: PetscFPrintf(comm, fd, "MPI Reductions: %5.3e %10.5f\n", max, ratio);
1307: numReductions = tot;
1308: PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");
1309: PetscFPrintf(comm, fd, " e.g., VecAXPY() for real vectors of length N --> 2N flops\n");
1310: PetscFPrintf(comm, fd, " and VecAXPY() for complex vectors of length N --> 8N flops\n");
1312: /* Get total number of stages --
1313: Currently, a single processor can register more stages than another, but stages must all be registered in order.
1314: We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1315: This seems best accomplished by assoicating a communicator with each stage.
1316: */
1317: MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1318: PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1319: PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1320: PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1321: PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1322: if (numStages > 0) {
1323: stageInfo = stageLog->stageInfo;
1324: for(stage = 0; stage < numStages; stage++) {
1325: if (stage < stageLog->numStages) {
1326: localStageUsed[stage] = stageInfo[stage].used;
1327: localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1328: } else {
1329: localStageUsed[stage] = PETSC_FALSE;
1330: localStageVisible[stage] = PETSC_TRUE;
1331: }
1332: }
1333: MPI_Allreduce(localStageUsed, stageUsed, numStages, MPI_INT, MPI_LOR, comm);
1334: MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1335: for(stage = 0; stage < numStages; stage++) {
1336: if (stageUsed[stage]) {
1337: PetscFPrintf(comm, fd, "\nSummary of Stages: ----- Time ------ ----- Flops ----- --- Messages --- -- Message Lengths -- -- Reductions --\n");
1338: PetscFPrintf(comm, fd, " Avg %%Total Avg %%Total counts %%Total Avg %%Total counts %%Total \n");
1339: break;
1340: }
1341: }
1342: for(stage = 0; stage < numStages; stage++) {
1343: if (!stageUsed[stage]) continue;
1344: if (localStageUsed[stage]) {
1345: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1346: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1347: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1348: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1349: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1350: name = stageInfo[stage].name;
1351: } else {
1352: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1353: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1354: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1355: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1356: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1357: name = "";
1358: }
1359: mess *= 0.5; messLen *= 0.5; red /= size;
1360: if (TotalTime != 0.0) fracTime = stageTime/TotalTime; else fracTime = 0.0;
1361: if (TotalFlops != 0.0) fracFlops = flops/TotalFlops; else fracFlops = 0.0;
1362: /* Talk to Barry if (stageTime != 0.0) flops = (size*flops)/stageTime; else flops = 0.0; */
1363: if (numMessages != 0.0) fracMessages = mess/numMessages; else fracMessages = 0.0;
1364: if (numMessages != 0.0) avgMessLen = messLen/numMessages; else avgMessLen = 0.0;
1365: if (messageLength != 0.0) fracLength = messLen/messageLength; else fracLength = 0.0;
1366: if (numReductions != 0.0) fracReductions = red/numReductions; else fracReductions = 0.0;
1367: 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",
1368: stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1369: mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1370: }
1371: }
1373: PetscFPrintf(comm, fd,
1374: "\n------------------------------------------------------------------------------------------------------------------------\n");
1375:
1376: PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1377: PetscFPrintf(comm, fd, "Phase summary info:\n");
1378: PetscFPrintf(comm, fd, " Count: number of times phase was executed\n");
1379: PetscFPrintf(comm, fd, " Time and Flops: Max - maximum over all processors\n");
1380: PetscFPrintf(comm, fd, " Ratio - ratio of maximum to minimum over all processors\n");
1381: PetscFPrintf(comm, fd, " Mess: number of messages sent\n");
1382: PetscFPrintf(comm, fd, " Avg. len: average message length\n");
1383: PetscFPrintf(comm, fd, " Reduct: number of global reductions\n");
1384: PetscFPrintf(comm, fd, " Global: entire computation\n");
1385: PetscFPrintf(comm, fd, " Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");
1386: PetscFPrintf(comm, fd, " %%T - percent time in this phase %%F - percent flops in this phase\n");
1387: PetscFPrintf(comm, fd, " %%M - percent messages in this phase %%L - percent message lengths in this phase\n");
1388: PetscFPrintf(comm, fd, " %%R - percent reductions in this phase\n");
1389: PetscFPrintf(comm, fd, " Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)\n");
1390: PetscFPrintf(comm, fd,
1391: "------------------------------------------------------------------------------------------------------------------------\n");
1392:
1394: #if defined(PETSC_USE_DEBUG)
1395: PetscFPrintf(comm, fd, "\n\n");
1396: PetscFPrintf(comm, fd, " ##########################################################\n");
1397: PetscFPrintf(comm, fd, " # #\n");
1398: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1399: PetscFPrintf(comm, fd, " # #\n");
1400: PetscFPrintf(comm, fd, " # This code was compiled with a debugging option, #\n");
1401: PetscFPrintf(comm, fd, " # To get timing results run config/configure.py #\n");
1402: PetscFPrintf(comm, fd, " # using --with-debugging=no, the performance will #\n");
1403: PetscFPrintf(comm, fd, " # be generally two or three times faster. #\n");
1404: PetscFPrintf(comm, fd, " # #\n");
1405: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1406: #endif
1407: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1408: PetscFPrintf(comm, fd, "\n\n");
1409: PetscFPrintf(comm, fd, " ##########################################################\n");
1410: PetscFPrintf(comm, fd, " # #\n");
1411: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1412: PetscFPrintf(comm, fd, " # #\n");
1413: PetscFPrintf(comm, fd, " # The code for various complex numbers numerical #\n");
1414: PetscFPrintf(comm, fd, " # kernels uses C++, which generally is not well #\n");
1415: PetscFPrintf(comm, fd, " # optimized. For performance that is about 4-5 times #\n");
1416: PetscFPrintf(comm, fd, " # faster, specify --with-fortran-kernels=generic #\n");
1417: PetscFPrintf(comm, fd, " # when running config/configure.py. #\n");
1418: PetscFPrintf(comm, fd, " # #\n");
1419: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1420: #endif
1422: /* Report events */
1423: PetscFPrintf(comm, fd,
1424: "Event Count Time (sec) Flops --- Global --- --- Stage --- Total\n");
1425:
1426: PetscFPrintf(comm, fd,
1427: " Max Ratio Max Ratio Max Ratio Mess Avg len Reduct %%T %%F %%M %%L %%R %%T %%F %%M %%L %%R Mflop/s\n");
1428:
1429: PetscFPrintf(comm,fd,
1430: "------------------------------------------------------------------------------------------------------------------------\n");
1432:
1433: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1434: for(stage = 0; stage < numStages; stage++) {
1435: if (!stageVisible[stage]) continue;
1436: if (localStageUsed[stage]) {
1437: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1438: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1439: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1440: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1441: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1442: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1443: } else {
1444: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1445: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1446: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1447: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1448: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1449: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1450: }
1451: mess *= 0.5; messLen *= 0.5; red /= size;
1453: /* Get total number of events in this stage --
1454: Currently, a single processor can register more events than another, but events must all be registered in order,
1455: just like stages. We can removed this requirement if necessary by having a global event numbering and indirection
1456: on the event ID. This seems best accomplished by assoicating a communicator with each stage.
1458: Problem: If the event did not happen on proc 1, its name will not be available.
1459: Problem: Event visibility is not implemented
1460: */
1461: if (localStageUsed[stage]) {
1462: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1463: localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1464: } else {
1465: localNumEvents = 0;
1466: }
1467: MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1468: for(event = 0; event < numEvents; event++) {
1469: if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) {
1470: if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1471: flopr = eventInfo[event].flops;
1472: } else {
1473: flopr = 0.0;
1474: }
1475: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1476: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1477: MPI_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1478: MPI_Allreduce(&eventInfo[event].time, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1479: MPI_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1480: MPI_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1481: MPI_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1482: MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1483: MPI_Allreduce(&eventInfo[event].numReductions, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1484: MPI_Allreduce(&eventInfo[event].count, &minCt, 1, MPI_INT, MPI_MIN, comm);
1485: MPI_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1486: name = stageLog->eventLog->eventInfo[event].name;
1487: } else {
1488: flopr = 0.0;
1489: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1490: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1491: MPI_Allreduce(&zero, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1492: MPI_Allreduce(&zero, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1493: MPI_Allreduce(&zero, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1494: MPI_Allreduce(&zero, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1495: MPI_Allreduce(&zero, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1496: MPI_Allreduce(&zero, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1497: MPI_Allreduce(&zero, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1498: MPI_Allreduce(&ierr, &minCt, 1, MPI_INT, MPI_MIN, comm);
1499: MPI_Allreduce(&ierr, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1500: name = "";
1501: }
1502: if (mint < 0.0) {
1503: 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);
1504: mint = 0;
1505: }
1506: if (minf < 0.0) SETERRQ2(PETSC_ERR_PLIB,"Minimum flops %g over all processors for %s is negative! Not possible!",minf,name);
1507: totm *= 0.5; totml *= 0.5; totr /= size;
1508:
1509: if (maxCt != 0) {
1510: if (minCt != 0) ratCt = ((PetscLogDouble) maxCt)/minCt; else ratCt = 0.0;
1511: if (mint != 0.0) ratt = maxt/mint; else ratt = 0.0;
1512: if (minf != 0.0) ratf = maxf/minf; else ratf = 0.0;
1513: if (TotalTime != 0.0) fracTime = tott/TotalTime; else fracTime = 0.0;
1514: if (TotalFlops != 0.0) fracFlops = totf/TotalFlops; else fracFlops = 0.0;
1515: if (stageTime != 0.0) fracStageTime = tott/stageTime; else fracStageTime = 0.0;
1516: if (flops != 0.0) fracStageFlops = totf/flops; else fracStageFlops = 0.0;
1517: if (numMessages != 0.0) fracMess = totm/numMessages; else fracMess = 0.0;
1518: if (messageLength != 0.0) fracMessLen = totml/messageLength; else fracMessLen = 0.0;
1519: if (numReductions != 0.0) fracRed = totr/numReductions; else fracRed = 0.0;
1520: if (mess != 0.0) fracStageMess = totm/mess; else fracStageMess = 0.0;
1521: if (messLen != 0.0) fracStageMessLen = totml/messLen; else fracStageMessLen = 0.0;
1522: if (red != 0.0) fracStageRed = totr/red; else fracStageRed = 0.0;
1523: if (totm != 0.0) totml /= totm; else totml = 0.0;
1524: if (maxt != 0.0) flopr = totf/maxt; else flopr = 0.0;
1525: PetscFPrintf(comm, fd,
1526: "%-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",
1527: name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1528: 100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1529: 100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1530: flopr/1.0e6);
1531: }
1532: }
1533: }
1535: /* Memory usage and object creation */
1536: PetscFPrintf(comm, fd,
1537: "------------------------------------------------------------------------------------------------------------------------\n");
1538: PetscFPrintf(comm, fd, "\n");
1539: PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");
1541: /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1542: the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1543: stats for stages local to processor sets.
1544: */
1545: /* We should figure out the longest object name here (now 20 characters) */
1546: PetscFPrintf(comm, fd, "Object Type Creations Destructions Memory Descendants' Mem.\n");
1547: for(stage = 0; stage < numStages; stage++) {
1548: if (localStageUsed[stage]) {
1549: classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1550: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1551: for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1552: if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1553: PetscFPrintf(comm, fd, "%20s %5d %5d %9d %g\n", stageLog->classLog->classInfo[oclass].name,
1554: classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1555: classInfo[oclass].descMem);
1556: }
1557: }
1558: } else {
1559: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1560: }
1561: }
1563: PetscFree(localStageUsed);
1564: PetscFree(stageUsed);
1565: PetscFree(localStageVisible);
1566: PetscFree(stageVisible);
1568: /* Information unrelated to this particular run */
1569: PetscFPrintf(comm, fd,
1570: "========================================================================================================================\n");
1571: PetscTime(y);
1572: PetscTime(x);
1573: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1574: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1575: PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1576: /* MPI information */
1577: if (size > 1) {
1578: MPI_Status status;
1579: PetscMPIInt tag;
1580: MPI_Comm newcomm;
1582: MPI_Barrier(comm);
1583: PetscTime(x);
1584: MPI_Barrier(comm);
1585: MPI_Barrier(comm);
1586: MPI_Barrier(comm);
1587: MPI_Barrier(comm);
1588: MPI_Barrier(comm);
1589: PetscTime(y);
1590: PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1591: PetscCommDuplicate(comm,&newcomm, &tag);
1592: MPI_Barrier(comm);
1593: if (rank) {
1594: MPI_Recv(0, 0, MPI_INT, rank-1, tag, newcomm, &status);
1595: MPI_Send(0, 0, MPI_INT, (rank+1)%size, tag, newcomm);
1596: } else {
1597: PetscTime(x);
1598: MPI_Send(0, 0, MPI_INT, 1, tag, newcomm);
1599: MPI_Recv(0, 0, MPI_INT, size-1, tag, newcomm, &status);
1600: PetscTime(y);
1601: PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1602: }
1603: PetscCommDestroy(&newcomm);
1604: }
1605: if (!rank) {
1606: PetscOptionsPrint(fd);
1607: }
1608: /* Machine and compile information */
1609: #if defined(PETSC_USE_FORTRAN_KERNELS)
1610: PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1611: #else
1612: PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1613: #endif
1614: #if defined(PETSC_USE_SINGLE)
1615: PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");
1616: #elif defined(PETSC_USE_LONGDOUBLE)
1617: PetscFPrintf(comm, fd, "Compiled with long double precision PetscScalar and PetscReal\n");
1618: #elif defined(PETSC_USE_INT)
1619: PetscFPrintf(comm, fd, "Compiled with int PetscScalar and PetscReal\n");
1620: #endif
1622: #if defined(PETSC_USE_MAT_SINGLE)
1623: PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1624: #else
1625: PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");
1626: #endif
1627: PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d\n",
1628: (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar));
1630: PetscFPrintf(comm, fd, "Configure run at: %s\n",petscconfigureruntime);
1631: PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);
1632: PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1633: PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1634: PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1635: PetscFPrintf(comm, fd, "%s", petsclinkerinfo);
1637: /* Cleanup */
1638: PetscFPrintf(comm, fd, "\n");
1639: PetscFClose(comm, fd);
1640: StageLogPush(stageLog, lastStage);
1641: return(0);
1642: }
1646: /*@C
1647: PetscLogPrintDetailed - Each process prints the times for its own events
1649: Collective over MPI_Comm
1651: Input Parameter:
1652: + comm - The MPI communicator (only one processor prints output)
1653: - file - [Optional] The output file name
1655: Options Database Keys:
1656: . -log_summary_detailed - Prints summary of log information (for code compiled with PETSC_USE_LOG)
1658: Usage:
1659: .vb
1660: PetscInitialize(...);
1661: PetscLogBegin();
1662: ... code ...
1663: PetscLogPrintDetailed(MPI_Comm,filename);
1664: PetscFinalize(...);
1665: .ve
1667: Notes:
1668: By default the summary is printed to stdout.
1670: Level: beginner
1671:
1672: .keywords: log, dump, print
1673: .seealso: PetscLogBegin(), PetscLogDump(), PetscLogPrintSummary()
1674: @*/
1675: PetscErrorCode PetscLogPrintDetailed(MPI_Comm comm, const char filename[])
1676: {
1677: FILE *fd = PETSC_STDOUT;
1678: StageLog stageLog;
1679: StageInfo *stageInfo = PETSC_NULL;
1680: EventPerfInfo *eventInfo = PETSC_NULL;
1681: const char *name = PETSC_NULL;
1682: PetscLogDouble TotalTime;
1683: PetscLogDouble stageTime, flops, flopr, mess, messLen, red;
1684: PetscLogDouble maxf, totf, maxt, tott, totm, totml, totr = 0.0;
1685: PetscMPIInt maxCt;
1686: PetscMPIInt size, rank;
1687: PetscTruth *stageUsed;
1688: PetscTruth *stageVisible;
1689: int numStages, numEvents;
1690: int stage;
1691: PetscLogEvent event;
1695: MPI_Comm_size(comm, &size);
1696: MPI_Comm_rank(comm, &rank);
1697: /* Pop off any stages the user forgot to remove */
1698: PetscLogGetStageLog(&stageLog);
1699: StageLogGetCurrent(stageLog, &stage);
1700: while (stage >= 0) {
1701: StageLogPop(stageLog);
1702: StageLogGetCurrent(stageLog, &stage);
1703: }
1704: /* Get the total elapsed time */
1705: PetscTime(TotalTime); TotalTime -= BaseTime;
1706: /* Open the summary file */
1707: if (filename) {
1708: PetscFOpen(comm, filename, "w", &fd);
1709: }
1711: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1712: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***\n");
1713: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1716: numStages = stageLog->numStages;
1717: PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1718: PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1719: if (numStages > 0) {
1720: stageInfo = stageLog->stageInfo;
1721: for(stage = 0; stage < numStages; stage++) {
1722: if (stage < stageLog->numStages) {
1723: stageUsed[stage] = stageInfo[stage].used;
1724: stageVisible[stage] = stageInfo[stage].perfInfo.visible;
1725: } else {
1726: stageUsed[stage] = PETSC_FALSE;
1727: stageVisible[stage] = PETSC_TRUE;
1728: }
1729: }
1730: }
1732: /* Report events */
1733: PetscFPrintf(comm, fd,"Event Count Time (sec) Flops/sec \n");
1734: PetscFPrintf(comm, fd," Mess Avg len Reduct \n");
1735: PetscFPrintf(comm,fd,"-----------------------------------------------------------------------------------\n");
1736: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1737: for(stage = 0; stage < numStages; stage++) {
1738: if (!stageVisible[stage]) continue;
1739: if (stageUsed[stage]) {
1740: PetscSynchronizedFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1741: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1742: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1743: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1744: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1745: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1746: }
1747: mess *= 0.5; messLen *= 0.5;
1749: /* Get total number of events in this stage --
1750: */
1751: if (stageUsed[stage]) {
1752: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1753: numEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1754: } else {
1755: numEvents = 0;
1756: }
1757: for(event = 0; event < numEvents; event++) {
1758: if (stageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1759: if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1760: flopr = eventInfo[event].flops/eventInfo[event].time;
1761: } else {
1762: flopr = 0.0;
1763: }
1764: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, PETSC_COMM_SELF);
1765: MPI_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1766: MPI_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, PETSC_COMM_SELF);
1767: MPI_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1768: MPI_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1769: MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1770: totr = eventInfo[event].numReductions;
1771: MPI_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, PETSC_COMM_SELF);
1772: name = stageLog->eventLog->eventInfo[event].name;
1773: totm *= 0.5; totml *= 0.5;
1774: }
1775:
1776: if (maxCt != 0) {
1777: if (totm != 0.0) totml /= totm; else totml = 0.0;
1778: PetscSynchronizedFPrintf(comm, fd,"%-16s %7d %5.4e %3.2e %2.1e %2.1e %2.1e\n",name, maxCt, maxt, maxf, totm, totml, totr);
1779: }
1780: }
1781: }
1782: PetscSynchronizedFlush(comm);
1784: PetscFree(stageUsed);
1785: PetscFree(stageVisible);
1787: PetscFClose(comm, fd);
1788: return(0);
1789: }
1791: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1794: /*@C
1795: PetscGetFlops - Returns the number of flops used on this processor
1796: since the program began.
1798: Not Collective
1800: Output Parameter:
1801: flops - number of floating point operations
1803: Notes:
1804: A global counter logs all PETSc flop counts. The user can use
1805: PetscLogFlops() to increment this counter to include flops for the
1806: application code.
1808: PETSc automatically logs library events if the code has been
1809: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1810: -log_summary, or -log_all are specified. PetscLogFlops() is
1811: intended for logging user flops to supplement this PETSc
1812: information.
1814: Level: intermediate
1816: .keywords: log, flops, floating point operations
1818: .seealso: PetscGetTime(), PetscLogFlops()
1819: @*/
1820: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
1821: {
1823: *flops = _TotalFlops;
1824: return(0);
1825: }
1829: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
1830: {
1832: int fullLength;
1833: va_list Argp;
1836: if (!logObjects) return(0);
1837: va_start(Argp, format);
1838: PetscVSNPrintf(objects[obj->id].info, 64,format,&fullLength, Argp);
1839: va_end(Argp);
1840: return(0);
1841: }
1845: /*@
1846: PetscLogGetStageLog - This function returns the default stage logging object.
1848: Not collective
1850: Output Parameter:
1851: . stageLog - The default StageLog
1853: Level: beginner
1855: .keywords: log, stage
1856: .seealso: StageLogCreate()
1857: @*/
1858: PetscErrorCode PetscLogGetStageLog(StageLog *stageLog)
1859: {
1862: *stageLog = _stageLog;
1863: return(0);
1864: }
1866: /*MC
1867: PetscLogFlops - Adds floating point operations to the global counter.
1869: Input Parameter:
1870: . f - flop counter
1872: Synopsis:
1873: void PetscLogFlops(int f)
1875: Usage:
1876: .vb
1877: int USER_EVENT;
1878: PetscLogEventRegister("User event",0,&USER_EVENT);
1879: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1880: [code segment to monitor]
1881: PetscLogFlops(user_flops)
1882: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1883: .ve
1885: Notes:
1886: A global counter logs all PETSc flop counts. The user can use
1887: PetscLogFlops() to increment this counter to include flops for the
1888: application code.
1890: PETSc automatically logs library events if the code has been
1891: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1892: -log_summary, or -log_all are specified. PetscLogFlops() is
1893: intended for logging user flops to supplement this PETSc
1894: information.
1896: Level: intermediate
1898: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()
1900: .keywords: log, flops, floating point operations
1901: M*/
1903: /*MC
1904: PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1905: to get accurate timings
1907: Input Parameter:
1908: + flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1909: with command line option -preload true or -preload false
1910: - name - name of first stage (lines of code timed separately with -log_summary) to
1911: be preloaded
1913: Synopsis:
1914: void PreLoadBegin(PetscTruth flag,char *name);
1916: Usage:
1917: .vb
1918: PreLoadBegin(PETSC_TRUE,"first stage);
1919: lines of code
1920: PreLoadStage("second stage");
1921: lines of code
1922: PreLoadEnd();
1923: .ve
1925: Notes: Only works in C/C++, not Fortran
1927: Flags available within the macro.
1928: + PetscPreLoadingUsed - true if we are or have done preloading
1929: . PetscPreLoadingOn - true if it is CURRENTLY doing preload
1930: . PreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
1931: - PreLoadMax - number of times it will do the computation, only one when preloading is turned on
1932: The first two variables are available throughout the program, the second two only between the PreLoadBegin()
1933: and PreLoadEnd()
1935: Level: intermediate
1937: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadEnd(), PreLoadStage()
1939: Concepts: preloading
1940: Concepts: timing^accurate
1941: Concepts: paging^eliminating effects of
1944: M*/
1946: /*MC
1947: PreLoadEnd - End a segment of code that may be preloaded (run twice)
1948: to get accurate timings
1950: Synopsis:
1951: void PreLoadEnd(void);
1953: Usage:
1954: .vb
1955: PreLoadBegin(PETSC_TRUE,"first stage);
1956: lines of code
1957: PreLoadStage("second stage");
1958: lines of code
1959: PreLoadEnd();
1960: .ve
1962: Notes: only works in C/C++ not fortran
1964: Level: intermediate
1966: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadStage()
1968: M*/
1970: /*MC
1971: PreLoadStage - Start a new segment of code to be timed separately.
1972: to get accurate timings
1974: Synopsis:
1975: void PreLoadStage(char *name);
1977: Usage:
1978: .vb
1979: PreLoadBegin(PETSC_TRUE,"first stage);
1980: lines of code
1981: PreLoadStage("second stage");
1982: lines of code
1983: PreLoadEnd();
1984: .ve
1986: Notes: only works in C/C++ not fortran
1988: Level: intermediate
1990: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd()
1992: M*/
1994: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1997: /*@C
1998: StackDestroy - This function destroys a stack.
2000: Not Collective
2002: Input Parameter:
2003: . stack - The stack
2005: Level: beginner
2007: .keywords: log, stack, destroy
2008: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
2009: @*/
2010: PetscErrorCode StackDestroy(IntStack stack)
2011: {
2015: PetscFree(stack->stack);
2016: PetscFree(stack);
2017: return(0);
2018: }
2022: /*@C
2023: StackEmpty - This function determines whether any items have been pushed.
2025: Not Collective
2027: Input Parameter:
2028: . stack - The stack
2030: Output Parameter:
2031: . empty - PETSC_TRUE if the stack is empty
2033: Level: intermediate
2035: .keywords: log, stack, empty
2036: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
2037: @*/
2038: PetscErrorCode StackEmpty(IntStack stack, PetscTruth *empty)
2039: {
2042: if (stack->top == -1) {
2043: *empty = PETSC_TRUE;
2044: } else {
2045: *empty = PETSC_FALSE;
2046: }
2047: return(0);
2048: }
2052: /*@C
2053: StackTop - This function returns the top of the stack.
2055: Not Collective
2057: Input Parameter:
2058: . stack - The stack
2060: Output Parameter:
2061: . top - The integer on top of the stack
2063: Level: intermediate
2065: .keywords: log, stack, top
2066: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
2067: @*/
2068: PetscErrorCode StackTop(IntStack stack, int *top)
2069: {
2072: *top = stack->stack[stack->top];
2073: return(0);
2074: }
2078: /*@C
2079: StackPush - This function pushes an integer on the stack.
2081: Not Collective
2083: Input Parameters:
2084: + stack - The stack
2085: - item - The integer to push
2087: Level: intermediate
2089: .keywords: log, stack, push
2090: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
2091: @*/
2092: PetscErrorCode StackPush(IntStack stack, int item)
2093: {
2094: int *array;
2098: stack->top++;
2099: if (stack->top >= stack->max) {
2100: PetscMalloc(stack->max*2 * sizeof(int), &array);
2101: PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
2102: PetscFree(stack->stack);
2103: stack->stack = array;
2104: stack->max *= 2;
2105: }
2106: stack->stack[stack->top] = item;
2107: return(0);
2108: }
2112: /*@C
2113: StackPop - This function pops an integer from the stack.
2115: Not Collective
2117: Input Parameter:
2118: . stack - The stack
2120: Output Parameter:
2121: . item - The integer popped
2123: Level: intermediate
2125: .keywords: log, stack, pop
2126: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
2127: @*/
2128: PetscErrorCode StackPop(IntStack stack, int *item)
2129: {
2132: if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
2133: *item = stack->stack[stack->top--];
2134: return(0);
2135: }
2139: /*@C
2140: StackCreate - This function creates a stack.
2142: Not Collective
2144: Output Parameter:
2145: . stack - The stack
2147: Level: beginner
2149: .keywords: log, stack, pop
2150: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
2151: @*/
2152: PetscErrorCode StackCreate(IntStack *stack)
2153: {
2154: IntStack s;
2159: PetscNew(struct _n_IntStack, &s);
2160: s->top = -1;
2161: s->max = 128;
2162: PetscMalloc(s->max * sizeof(int), &s->stack);
2163: PetscMemzero(s->stack, s->max * sizeof(int));
2164: *stack = s;
2165: return(0);
2166: }
2168: #else /* end of -DPETSC_USE_LOG section */
2172: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2173: {
2175: return(0);
2176: }
2178: #endif /* PETSC_USE_LOG*/
2181: PetscCookie PETSC_LARGEST_COOKIE = PETSC_SMALLEST_COOKIE;
2182: PetscCookie PETSC_OBJECT_COOKIE = 0;
2186: /*@C
2187: PetscCookieRegister - Registers a new class name for objects and logging operations in an application code.
2189: Not Collective
2191: Input Parameter:
2192: . name - The class name
2193:
2194: Output Parameter:
2195: . oclass - The class id or cookie
2197: Level: developer
2199: .keywords: log, class, register
2201: @*/
2202: PetscErrorCode PetscCookieRegister(const char name[],PetscCookie *oclass )
2203: {
2204: #if defined(PETSC_USE_LOG)
2205: StageLog stageLog;
2206: PetscInt stage;
2208: #endif
2211: *oclass = ++PETSC_LARGEST_COOKIE;
2212: #if defined(PETSC_USE_LOG)
2213: PetscLogGetStageLog(&stageLog);
2214: ClassRegLogRegister(stageLog->classLog, name, *oclass);
2215: for(stage = 0; stage < stageLog->numStages; stage++) {
2216: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
2217: }
2218: #endif
2219: return(0);
2220: }