Actual source code: plog.c
1: /*
2: PETSc code to log object creation and destruction and PETSc events.
3: */
4: #include petsc.h
5: #include "petscmachineinfo.h"
6: #if defined(PETSC_HAVE_MPE)
7: #include "mpe.h"
8: #endif
9: #include <stdarg.h>
10: #include <sys/types.h>
11: #include petscsys.h
12: #if defined(PETSC_HAVE_STDLIB_H)
13: #include <stdlib.h>
14: #endif
15: #if defined(PETSC_HAVE_MALLOC_H) && !defined(__cplusplus)
16: #include <malloc.h>
17: #endif
18: #include "petscfix.h"
19: #include src/sys/src/plog/ptime.h
20: #include plog.h
22: PetscCookie PETSC_LARGEST_COOKIE = PETSC_COOKIE;
23: PetscEvent PETSC_LARGEST_EVENT = PETSC_EVENT;
25: #if defined(PETSC_USE_LOG)
27: /* used in the MPI_XXX() count macros in petsclog.h */
28: int PETSC_DUMMY = 0,PETSC_DUMMY_SIZE = 0, PETSC_DUMMY_COUNT = 0;
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 send_ct = 0.0; /* The number of sends */
43: PetscLogDouble recv_ct = 0.0; /* The number of receives */
44: PetscLogDouble send_len = 0.0; /* The total length of all sent messages */
45: PetscLogDouble recv_len = 0.0; /* The total length of all received messages */
46: PetscLogDouble isend_ct = 0.0; /* The number of immediate sends */
47: PetscLogDouble irecv_ct = 0.0; /* The number of immediate receives */
48: PetscLogDouble isend_len = 0.0; /* The total length of all immediate send messages */
49: PetscLogDouble irecv_len = 0.0; /* The total length of all immediate receive messages */
50: PetscLogDouble wait_ct = 0.0; /* The number of waits */
51: PetscLogDouble wait_any_ct = 0.0; /* The number of anywaits */
52: PetscLogDouble wait_all_ct = 0.0; /* The number of waitalls */
53: PetscLogDouble sum_of_waits_ct = 0.0; /* The total number of waits */
54: PetscLogDouble allreduce_ct = 0.0; /* The number of reductions */
56: /* Logging functions */
57: PetscErrorCode (*_PetscLogPHC)(PetscObject) = PETSC_NULL;
58: PetscErrorCode (*_PetscLogPHD)(PetscObject) = PETSC_NULL;
59: PetscErrorCode (*_PetscLogPLB)(PetscEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
60: PetscErrorCode (*_PetscLogPLE)(PetscEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
62: /* Tracing event logging variables */
63: FILE *tracefile = PETSC_NULL;
64: int tracelevel = 0;
65: const char *traceblanks = " ";
66: char tracespace[128] = " ";
67: PetscLogDouble tracetime = 0.0;
69: /*---------------------------------------------- General Functions --------------------------------------------------*/
72: /*@C
73: PetscLogDestroy - Destroys the object and event logging data and resets the global counters.
75: Not Collective
77: Notes:
78: This routine should not usually be used by programmers. Instead employ
79: PetscLogStagePush() and PetscLogStagePop().
81: Level: developer
83: .keywords: log, destroy
84: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogStagePush(), PlogStagePop()
85: @*/
86: PetscErrorCode PetscLogDestroy(void)
87: {
88: StageLog stageLog;
92: if (actions) {
93: PetscFree(actions);
94: actions = PETSC_NULL;
95: }
96: if (objects) {
97: PetscFree(objects);
98: objects = PETSC_NULL;
99: }
100: PetscLogSet(PETSC_NULL, PETSC_NULL);
102: /* Resetting phase */
103: PetscLogGetStageLog(&stageLog);
104: StageLogDestroy(stageLog);
105: _TotalFlops = 0.0;
106: numActions = 0;
107: numObjects = 0;
108: numObjectsDestroyed = 0;
109: return(0);
110: }
114: /*@C
115: PetscLogSet - Sets the logging functions called at the beginning and ending of every event.
117: Not Collective
119: Input Parameters:
120: + b - The function called at beginning of event
121: - e - The function called at end of event
123: Level: developer
125: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
126: @*/
127: PetscErrorCode PetscLogSet(PetscErrorCode (*b)(PetscEvent, int, PetscObject, PetscObject, PetscObject, PetscObject),
128: PetscErrorCode (*e)(PetscEvent, int, PetscObject, PetscObject, PetscObject, PetscObject))
129: {
131: _PetscLogPLB = b;
132: _PetscLogPLE = e;
133: return(0);
134: }
136: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
139: PetscErrorCode PetscLogBegin_Private(void)
140: {
141: static PetscTruth initialized = PETSC_FALSE;
142: int stage;
143: PetscTruth opt;
144: PetscErrorCode ierr;
147: if (initialized) return(0);
148: initialized = PETSC_TRUE;
149: PetscOptionsHasName(PETSC_NULL, "-log_exclude_actions", &opt);
150: if (opt == PETSC_TRUE) {
151: logActions = PETSC_FALSE;
152: }
153: PetscOptionsHasName(PETSC_NULL, "-log_exclude_objects", &opt);
154: if (opt == PETSC_TRUE) {
155: logObjects = PETSC_FALSE;
156: }
157: if (logActions == PETSC_TRUE) {
158: PetscMalloc(maxActions * sizeof(Action), &actions);
159: }
160: if (logObjects == PETSC_TRUE) {
161: PetscMalloc(maxObjects * sizeof(Object), &objects);
162: }
163: _PetscLogPHC = PetscLogObjCreateDefault;
164: _PetscLogPHD = PetscLogObjDestroyDefault;
165: /* Setup default logging structures */
166: StageLogCreate(&_stageLog);
167: StageLogRegister(_stageLog, "Main Stage", &stage);
168: /* All processors sync here for more consistent logging */
169: MPI_Barrier(PETSC_COMM_WORLD);
170: PetscTime(BaseTime);
171: PetscLogStagePush(stage);
172: return(0);
173: }
177: /*@C
178: PetscLogBegin - Turns on logging of objects and events. This logs flop
179: rates and object creation and should not slow programs down too much.
180: This routine may be called more than once.
182: Collective over PETSC_COMM_WORLD
184: Options Database Keys:
185: + -log_summary - Prints summary of flop and timing information to the
186: screen (for code compiled with PETSC_USE_LOG)
187: - -log - Prints detailed log information (for code compiled with PETSC_USE_LOG)
189: Usage:
190: .vb
191: PetscInitialize(...);
192: PetscLogBegin();
193: ... code ...
194: PetscLogPrintSummary(MPI_Comm,filename); or PetscLogDump();
195: PetscFinalize();
196: .ve
198: Notes:
199: PetscLogPrintSummary(MPI_Comm,filename) or PetscLogDump() actually cause the printing of
200: the logging information.
202: Level: advanced
204: .keywords: log, begin
205: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogTraceBegin()
206: @*/
207: PetscErrorCode PetscLogBegin(void)
208: {
212: PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
213: PetscLogBegin_Private();
214: return(0);
215: }
219: /*@C
220: PetscLogAllBegin - Turns on extensive logging of objects and events. Logs
221: all events. This creates large log files and slows the program down.
223: Collective on PETSC_COMM_WORLD
225: Options Database Keys:
226: . -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
228: Usage:
229: .vb
230: PetscInitialize(...);
231: PetscLogAllBegin();
232: ... code ...
233: PetscLogDump(filename);
234: PetscFinalize();
235: .ve
237: Notes:
238: A related routine is PetscLogBegin (with the options key -log), which is
239: intended for production runs since it logs only flop rates and object
240: creation (and shouldn't significantly slow the programs).
242: Level: advanced
244: .keywords: log, all, begin
245: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogTraceBegin()
246: @*/
247: PetscErrorCode PetscLogAllBegin(void)
248: {
252: PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
253: PetscLogBegin_Private();
254: return(0);
255: }
259: /*@
260: PetscLogTraceBegin - Activates trace logging. Every time a PETSc event
261: begins or ends, the event name is printed.
263: Collective on PETSC_COMM_WORLD
265: Input Parameter:
266: . file - The file to print trace in (e.g. stdout)
268: Options Database Key:
269: . -log_trace [filename] - Activates PetscLogTraceBegin()
271: Notes:
272: PetscLogTraceBegin() prints the processor number, the execution time (sec),
273: then "Event begin:" or "Event end:" followed by the event name.
275: PetscLogTraceBegin() allows tracing of all PETSc calls, which is useful
276: to determine where a program is hanging without running in the
277: debugger. Can be used in conjunction with the -log_info option.
279: Level: intermediate
281: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogBegin()
282: @*/
283: PetscErrorCode PetscLogTraceBegin(FILE *file)
284: {
288: tracefile = file;
289: PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
290: PetscLogBegin_Private();
291: return(0);
292: }
296: /*@
297: PetscLogActions - Determines whether actions are logged for the graphical viewer.
299: Not Collective
301: Input Parameter:
302: . flag - PETSC_TRUE if actions are to be logged
304: Level: intermediate
306: Note: Logging of actions continues to consume more memory as the program
307: runs. Long running programs should consider turning this feature off.
309: Options Database Keys:
310: . -log_exclude_actions - Turns off actions logging
312: .keywords: log, stage, register
313: .seealso: PetscLogStagePush(), PetscLogStagePop()
314: @*/
315: PetscErrorCode PetscLogActions(PetscTruth flag)
316: {
318: logActions = flag;
319: return(0);
320: }
324: /*@
325: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
327: Not Collective
329: Input Parameter:
330: . flag - PETSC_TRUE if objects are to be logged
332: Level: intermediate
334: Note: Logging of objects continues to consume more memory as the program
335: runs. Long running programs should consider turning this feature off.
337: Options Database Keys:
338: . -log_exclude_objects - Turns off objects logging
340: .keywords: log, stage, register
341: .seealso: PetscLogStagePush(), PetscLogStagePop()
342: @*/
343: PetscErrorCode PetscLogObjects(PetscTruth flag)
344: {
346: logObjects = flag;
347: return(0);
348: }
350: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
353: /*@C
354: PetscLogStageRegister - Attaches a charactor string name to a logging stage.
356: Not Collective
358: Input Parameter:
359: . sname - The name to associate with that stage
361: Output Parameter:
362: . stage - The stage number
364: Level: intermediate
366: .keywords: log, stage, register
367: .seealso: PetscLogStagePush(), PetscLogStagePop()
368: @*/
369: PetscErrorCode PetscLogStageRegister(int *stage, const char sname[])
370: {
371: StageLog stageLog;
372: PetscEvent event;
376: PetscLogGetStageLog(&stageLog);
377: StageLogRegister(stageLog, sname, stage);
378: /* Copy events already changed in the main stage, this sucks */
379: EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
380: for(event = 0; event < stageLog->eventLog->numEvents; event++) {
381: EventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],
382: &stageLog->stageInfo[*stage].eventLog->eventInfo[event]);
383: }
384: ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
385: return(0);
386: }
390: /*@C
391: PetscLogStagePush - This function pushes a stage on the stack.
393: Not Collective
395: Input Parameter:
396: . stage - The stage on which to log
398: Usage:
399: If the option -log_sumary is used to run the program containing the
400: following code, then 2 sets of summary data will be printed during
401: PetscFinalize().
402: .vb
403: PetscInitialize(int *argc,char ***args,0,0);
404: [stage 0 of code]
405: PetscLogStagePush(1);
406: [stage 1 of code]
407: PetscLogStagePop();
408: PetscBarrier(...);
409: [more stage 0 of code]
410: PetscFinalize();
411: .ve
412:
413: Notes:
414: Use PetscLogStageRegister() to register a stage.
416: Level: intermediate
418: .keywords: log, push, stage
419: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
420: @*/
421: PetscErrorCode PetscLogStagePush(int stage)
422: {
423: StageLog stageLog;
427: PetscLogGetStageLog(&stageLog);
428: StageLogPush(stageLog, stage);
429: return(0);
430: }
434: /*@C
435: PetscLogStagePop - This function pops a stage from the stack.
437: Not Collective
439: Usage:
440: If the option -log_sumary is used to run the program containing the
441: following code, then 2 sets of summary data will be printed during
442: PetscFinalize().
443: .vb
444: PetscInitialize(int *argc,char ***args,0,0);
445: [stage 0 of code]
446: PetscLogStagePush(1);
447: [stage 1 of code]
448: PetscLogStagePop();
449: PetscBarrier(...);
450: [more stage 0 of code]
451: PetscFinalize();
452: .ve
454: Notes:
455: Use PetscLogStageRegister() to register a stage.
457: Level: intermediate
459: .keywords: log, pop, stage
460: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
461: @*/
462: PetscErrorCode PetscLogStagePop(void)
463: {
464: StageLog stageLog;
468: PetscLogGetStageLog(&stageLog);
469: StageLogPop(stageLog);
470: return(0);
471: }
475: /*@
476: PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().
478: Not Collective
480: Input Parameters:
481: + stage - The stage
482: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
484: Level: intermediate
486: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
487: @*/
488: PetscErrorCode PetscLogStageSetActive(int stage, PetscTruth isActive)
489: {
490: StageLog stageLog;
494: PetscLogGetStageLog(&stageLog);
495: StageLogSetActive(stageLog, stage, isActive);
496: return(0);
497: }
501: /*@
502: PetscLogStageGetActive - Returns stage activity for PetscLogEventBegin() and PetscLogEventEnd().
504: Not Collective
506: Input Parameter:
507: . stage - The stage
509: Output Parameter:
510: . isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
512: Level: intermediate
514: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
515: @*/
516: PetscErrorCode PetscLogStageGetActive(int stage, PetscTruth *isActive) \
517: {
518: StageLog stageLog;
522: PetscLogGetStageLog(&stageLog);
523: StageLogGetActive(stageLog, stage, isActive);
524: return(0);
525: }
529: /*@
530: PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()
532: Not Collective
534: Input Parameters:
535: + stage - The stage
536: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
538: Level: intermediate
540: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
541: @*/
542: PetscErrorCode PetscLogStageSetVisible(int stage, PetscTruth isVisible)
543: {
544: StageLog stageLog;
548: PetscLogGetStageLog(&stageLog);
549: StageLogSetVisible(stageLog, stage, isVisible);
550: return(0);
551: }
555: /*@
556: PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()
558: Not Collective
560: Input Parameter:
561: . stage - The stage
563: Output Parameter:
564: . isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
566: Level: intermediate
568: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
569: @*/
570: PetscErrorCode PetscLogStageGetVisible(int stage, PetscTruth *isVisible)
571: {
572: StageLog stageLog;
576: PetscLogGetStageLog(&stageLog);
577: StageLogGetVisible(stageLog, stage, isVisible);
578: return(0);
579: }
583: /*@
584: PetscLogStageGetId - Returns the stage id when given the stage name.
586: Not Collective
588: Input Parameter:
589: . name - The stage name
591: Output Parameter:
592: . stage - The stage
594: Level: intermediate
596: .seealso: PetscLogStagePush(), PetscLogStagePop(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
597: @*/
598: PetscErrorCode PetscLogStageGetId(const char name[], int *stage)
599: {
600: StageLog stageLog;
604: PetscLogGetStageLog(&stageLog);
605: StageLogGetStage(stageLog, name, stage);
606: return(0);
607: }
609: /*------------------------------------------------ Event Functions --------------------------------------------------*/
612: /*@C
613: PetscLogEventRegister - Registers an event name for logging operations in an application code.
615: Not Collective
617: Input Parameter:
618: + name - The name associated with the event
619: - cookie - The cookie associated to the class for this event
620:
621: Output Parameter:
622: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().
624: Example of Usage:
625: .vb
626: int USER_EVENT;
627: int user_event_flops;
628: PetscLogEventRegister(&USER_EVENT,"User event name");
629: PetscLogEventBegin(USER_EVENT,0,0,0,0);
630: [code segment to monitor]
631: PetscLogFlops(user_event_flops);
632: PetscLogEventEnd(USER_EVENT,0,0,0,0);
633: .ve
635: Notes:
636: PETSc automatically logs library events if the code has been
637: compiled with -DPETSC_USE_LOG (which is the default) and -log,
638: -log_summary, or -log_all are specified. PetscLogEventRegister() is
639: intended for logging user events to supplement this PETSc
640: information.
642: PETSc can gather data for use with the utilities Upshot/Nupshot
643: (part of the MPICH distribution). If PETSc has been compiled
644: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
645: MPICH), the user can employ another command line option, -log_mpe,
646: to create a logfile, "mpe.log", which can be visualized
647: Upshot/Nupshot.
649: Level: intermediate
651: .keywords: log, event, register
652: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
653: PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
654: PetscLogEventActivate(), PetscLogEventDeactivate()
655: @*/
656: PetscErrorCode PetscLogEventRegister(PetscEvent *event, const char name[],PetscCookie cookie)
657: {
658: StageLog stageLog;
659: int stage;
663: *event = PETSC_DECIDE;
664: PetscLogGetStageLog(&stageLog);
665: EventRegLogRegister(stageLog->eventLog, name, cookie, event);
666: for(stage = 0; stage < stageLog->numStages; stage++) {
667: EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
668: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
669: }
670: return(0);
671: }
675: /*@
676: PetscLogEventActivate - Indicates that a particular event should be logged.
678: Not Collective
680: Input Parameter:
681: . event - The event id
683: Usage:
684: .vb
685: PetscLogEventDeactivate(VEC_SetValues);
686: [code where you do not want to log VecSetValues()]
687: PetscLogEventActivate(VEC_SetValues);
688: [code where you do want to log VecSetValues()]
689: .ve
691: Note:
692: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
693: or an event number obtained with PetscLogEventRegister().
695: Level: advanced
697: .keywords: log, event, activate
698: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
699: @*/
700: PetscErrorCode PetscLogEventActivate(PetscEvent event)
701: {
702: StageLog stageLog;
703: int stage;
707: PetscLogGetStageLog(&stageLog);
708: StageLogGetCurrent(stageLog, &stage);
709: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
710: return(0);
711: }
715: /*@
716: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
718: Not Collective
720: Input Parameter:
721: . event - The event id
723: Usage:
724: .vb
725: PetscLogEventDeactivate(VEC_SetValues);
726: [code where you do not want to log VecSetValues()]
727: PetscLogEventActivate(VEC_SetValues);
728: [code where you do want to log VecSetValues()]
729: .ve
731: Note:
732: The event may be either a pre-defined PETSc event (found in
733: include/petsclog.h) or an event number obtained with PetscLogEventRegister()).
735: Level: advanced
737: .keywords: log, event, deactivate
738: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
739: @*/
740: PetscErrorCode PetscLogEventDeactivate(PetscEvent event)
741: {
742: StageLog stageLog;
743: int stage;
747: PetscLogGetStageLog(&stageLog);
748: StageLogGetCurrent(stageLog, &stage);
749: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
750: return(0);
751: }
755: /*@
756: PetscLogEventSetActiveAll - Sets the event activity in every stage.
758: Not Collective
760: Input Parameters:
761: + event - The event id
762: - isActive - The activity flag determining whether the event is logged
764: Level: advanced
766: .keywords: log, event, activate
767: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
768: @*/
769: PetscErrorCode PetscLogEventSetActiveAll(PetscEvent event, PetscTruth isActive)
770: {
771: StageLog stageLog;
772: int stage;
776: PetscLogGetStageLog(&stageLog);
777: for(stage = 0; stage < stageLog->numStages; stage++) {
778: if (isActive == PETSC_TRUE) {
779: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
780: } else {
781: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
782: }
783: }
784: return(0);
785: }
789: /*@
790: PetscLogEventActivateClass - Activates event logging for a PETSc object class.
792: Not Collective
794: Input Parameter:
795: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
797: Level: developer
799: .keywords: log, event, activate, class
800: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
801: @*/
802: PetscErrorCode PetscLogEventActivateClass(PetscCookie cookie)
803: {
804: StageLog stageLog;
805: int stage;
809: PetscLogGetStageLog(&stageLog);
810: StageLogGetCurrent(stageLog, &stage);
811: EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
812: return(0);
813: }
817: /*@
818: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.
820: Not Collective
822: Input Parameter:
823: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
825: Level: developer
827: .keywords: log, event, deactivate, class
828: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
829: @*/
830: PetscErrorCode PetscLogEventDeactivateClass(PetscCookie cookie)
831: {
832: StageLog stageLog;
833: int stage;
837: PetscLogGetStageLog(&stageLog);
838: StageLogGetCurrent(stageLog, &stage);
839: EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
840: return(0);
841: }
843: /*MC
844: PetscLogEventBegin - Logs the beginning of a user event.
846: Input Parameters:
847: + e - integer associated with the event obtained from PetscLogEventRegister()
848: - o1,o2,o3,o4 - objects associated with the event, or 0
850: Synopsis:
851: void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
852: PetscObject o4)
854: Fortran Synopsis:
855: void PetscLogEventEnd(int e,PetscErrorCode ierr)
857: Usage:
858: .vb
859: int USER_EVENT;
860: int user_event_flops;
861: PetscLogEventRegister(&USER_EVENT,"User event");
862: PetscLogEventBegin(USER_EVENT,0,0,0,0);
863: [code segment to monitor]
864: PetscLogFlops(user_event_flops);
865: PetscLogEventEnd(USER_EVENT,0,0,0,0);
866: .ve
868: Notes:
869: You need to register each integer event with the command
870: PetscLogEventRegister(). The source code must be compiled with
871: -DPETSC_USE_LOG, which is the default.
873: PETSc automatically logs library events if the code has been
874: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
875: specified. PetscLogEventBegin() is intended for logging user events
876: to supplement this PETSc information.
878: Level: intermediate
880: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops()
882: .keywords: log, event, begin
883: M*/
885: /*MC
886: PetscLogEventEnd - Log the end of a user event.
888: Input Parameters:
889: + e - integer associated with the event obtained with PetscLogEventRegister()
890: - o1,o2,o3,o4 - objects associated with the event, or 0
892: Synopsis:
893: void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
894: PetscObject o4)
896: Fortran Synopsis:
897: void PetscLogEventEnd(int e,PetscErrorCode ierr)
899: Usage:
900: .vb
901: int USER_EVENT;
902: int user_event_flops;
903: PetscLogEventRegister(&USER_EVENT,"User event");
904: PetscLogEventBegin(USER_EVENT,0,0,0,0);
905: [code segment to monitor]
906: PetscLogFlops(user_event_flops);
907: PetscLogEventEnd(USER_EVENT,0,0,0,0);
908: .ve
910: Notes:
911: You should also register each additional integer event with the command
912: PetscLogEventRegister(). Source code must be compiled with
913: -DPETSC_USE_LOG, which is the default.
915: PETSc automatically logs library events if the code has been
916: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
917: specified. PetscLogEventEnd() is intended for logging user events
918: to supplement this PETSc information.
920: Level: intermediate
922: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogFlops()
924: .keywords: log, event, end
925: M*/
927: /*MC
928: PetscLogEventBarrierBegin - Logs the time in a barrier before an event.
930: Input Parameters:
931: . e - integer associated with the event obtained from PetscLogEventRegister()
932: . o1,o2,o3,o4 - objects associated with the event, or 0
933: . comm - communicator the barrier takes place over
935: Synopsis:
936: void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
937: PetscObject o4,MPI_Comm comm)
939: Usage:
940: .vb
941: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
942: MPI_Allreduce()
943: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
944: .ve
946: Notes:
947: This is for logging the amount of time spent in a barrier for an event
948: that requires synchronization.
950: Additional Notes:
951: Synchronization events always come in pairs; for example, VEC_NormBarrier and
952: VEC_NormComm = VEC_NormBarrier + 1
954: Level: advanced
956: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
957: PetscLogEventBarrierEnd()
959: .keywords: log, event, begin, barrier
960: M*/
962: /*MC
963: PetscLogEventBarrierEnd - Logs the time in a barrier before an event.
965: Input Parameters:
966: . e - integer associated with the event obtained from PetscLogEventRegister()
967: . o1,o2,o3,o4 - objects associated with the event, or 0
968: . comm - communicator the barrier takes place over
970: Synopsis:
971: void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
972: PetscObject o4,MPI_Comm comm)
974: Usage:
975: .vb
976: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
977: MPI_Allreduce()
978: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
979: .ve
981: Notes:
982: This is for logging the amount of time spent in a barrier for an event
983: that requires synchronization.
985: Additional Notes:
986: Synchronization events always come in pairs; for example, VEC_NormBarrier and
987: VEC_NormComm = VEC_NormBarrier + 1
989: Level: advanced
991: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
992: PetscLogEventBarrierBegin()
994: .keywords: log, event, begin, barrier
995: M*/
997: /*------------------------------------------------ Class Functions --------------------------------------------------*/
1000: /*@C
1001: PetscLogClassRegister - Registers a class name for logging operations in an application code.
1003: Not Collective
1005: Input Parameter:
1006: . name - The class name
1007:
1008: Output Parameter:
1009: . oclass - The class id or cookie
1011: Level: developer
1013: .keywords: log, class, register
1014: .seealso: ClassLogRegister()
1015: @*/
1016: PetscErrorCode PetscLogClassRegister(PetscCookie *oclass, const char name[])
1017: {
1018: StageLog stageLog;
1019: int stage;
1023: *oclass = PETSC_DECIDE;
1024: PetscLogGetStageLog(&stageLog);
1025: ClassRegLogRegister(stageLog->classLog, name, oclass);
1026: for(stage = 0; stage < stageLog->numStages; stage++) {
1027: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
1028: }
1029: return(0);
1030: }
1032: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1035: /*@C
1036: PetscLogDump - Dumps logs of objects to a file. This file is intended to
1037: be read by petsc/bin/petscview.
1039: Collective on PETSC_COMM_WORLD
1041: Input Parameter:
1042: . name - an optional file name
1044: Options Database Keys:
1045: + -log - Prints basic log information (for code compiled with PETSC_USE_LOG)
1046: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
1047:
1048: Usage:
1049: .vb
1050: PetscInitialize(...);
1051: PetscLogBegin(); or PetscLogAllBegin();
1052: ... code ...
1053: PetscLogDump(filename);
1054: PetscFinalize();
1055: .ve
1057: Notes:
1058: The default file name is
1059: $ Log.<rank>
1060: where <rank> is the processor number. If no name is specified,
1061: this file will be used.
1063: Level: advanced
1065: .keywords: log, dump
1066: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
1067: @*/
1068: PetscErrorCode PetscLogDump(const char sname[])
1069: {
1070: StageLog stageLog;
1071: EventPerfInfo *eventInfo;
1072: FILE *fd;
1073: char file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1074: PetscLogDouble flops, _TotalTime;
1075: PetscMPIInt rank;
1076: int action, object, curStage;
1077: PetscEvent event;
1079:
1081: /* Calculate the total elapsed time */
1082: PetscTime(_TotalTime);
1083: _TotalTime -= BaseTime;
1084: /* Open log file */
1085: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1086: if (sname) {
1087: sprintf(file, "%s.%d", sname, rank);
1088: } else {
1089: sprintf(file, "Log.%d", rank);
1090: }
1091: PetscFixFilename(file, fname);
1092: PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1093: if ((!rank) && (!fd)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1094: /* Output totals */
1095: PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8e\n", _TotalFlops, _TotalTime);
1096: PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0);
1097: /* Output actions */
1098: PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", numActions);
1099: for(action = 0; action < numActions; action++) {
1100: PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n",
1101: actions[action].time, actions[action].action, (int)actions[action].event, (int)actions[action].cookie, actions[action].id1,
1102: actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
1103: }
1104: /* Output objects */
1105: PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", numObjects, numObjectsDestroyed);
1106: for(object = 0; object < numObjects; object++) {
1107: PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", objects[object].parent, (int) objects[object].mem);
1108: if (!objects[object].name[0]) {
1109: PetscFPrintf(PETSC_COMM_WORLD, fd,"No Name\n");
1110: } else {
1111: PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", objects[object].name);
1112: }
1113: if (objects[object].info[0] != 0) {
1114: PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n");
1115: } else {
1116: PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", objects[object].info);
1117: }
1118: }
1119: /* Output events */
1120: PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:\n");
1121: PetscLogGetStageLog(&stageLog);
1122: StackTop(stageLog->stack, &curStage);
1123: eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1124: for(event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1125: if (eventInfo[event].time != 0.0) {
1126: flops = eventInfo[event].flops/eventInfo[event].time;
1127: } else {
1128: flops = 0.0;
1129: }
1130: PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16g\n", event, eventInfo[event].count,
1131: eventInfo[event].flops, eventInfo[event].time, flops);
1132: }
1133: PetscFClose(PETSC_COMM_WORLD, fd);
1134: return(0);
1135: }
1139: /*@C
1140: PetscLogPrintSummary - Prints a summary of the logging.
1142: Collective over MPI_Comm
1144: Input Parameter:
1145: + comm - The MPI communicator (only one processor prints output)
1146: - file - [Optional] The output file name
1148: Options Database Keys:
1149: . -log_summary - Prints summary of log information (for code compiled with PETSC_USE_LOG)
1151: Usage:
1152: .vb
1153: PetscInitialize(...);
1154: PetscLogBegin();
1155: ... code ...
1156: PetscLogPrintSummary(MPI_Comm,filename);
1157: PetscFinalize(...);
1158: .ve
1160: Notes:
1161: By default the summary is printed to stdout.
1162: More extensive examination of the log information can be done with
1163: PetscLogDump(), which is activated by the option -log or -log_all, in
1164: combination with petsc/bin/petscview.
1166: Level: beginner
1167:
1168: .keywords: log, dump, print
1169: .seealso: PetscLogBegin(), PetscLogDump()
1170: @*/
1171: PetscErrorCode PetscLogPrintSummary(MPI_Comm comm, const char filename[])
1172: {
1173: FILE *fd = stdout;
1174: PetscScalar zero = 0.0;
1175: StageLog stageLog;
1176: StageInfo *stageInfo = PETSC_NULL;
1177: EventPerfInfo *eventInfo = PETSC_NULL;
1178: ClassPerfInfo *classInfo;
1179: char arch[10], hostname[64], username[16], pname[PETSC_MAX_PATH_LEN], date[64];
1180: const char *name;
1181: PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1182: PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1183: PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1184: PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1185: PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1186: PetscLogDouble min, max, tot, ratio, avg, x, y;
1187: PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1188: int minCt, maxCt;
1189: PetscMPIInt size, rank;
1190: PetscTruth *localStageUsed, *stageUsed;
1191: PetscTruth *localStageVisible, *stageVisible;
1192: int numStages, localNumEvents, numEvents;
1193: int stage, oclass;
1194: PetscEvent event;
1196: char version[256];
1199: MPI_Comm_size(comm, &size);
1200: MPI_Comm_rank(comm, &rank);
1201: /* Pop off any stages the user forgot to remove */
1202: PetscLogGetStageLog(&stageLog);
1203: StageLogGetCurrent(stageLog, &stage);
1204: while (stage >= 0) {
1205: StageLogPop(stageLog);
1206: StageLogGetCurrent(stageLog, &stage);
1207: }
1208: /* Get the total elapsed time */
1209: PetscTime(locTotalTime); locTotalTime -= BaseTime;
1210: /* Open the summary file */
1211: if (filename) {
1212: PetscFOpen(comm, filename, "w", &fd);
1213: }
1215: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1216: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***\n");
1217: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1218: PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1219: PetscGetArchType(arch, 10);
1220: PetscGetHostName(hostname, 64);
1221: PetscGetUserName(username, 16);
1222: PetscGetProgramName(pname, PETSC_MAX_PATH_LEN);
1223: PetscGetDate(date, 64);
1224: PetscGetVersion(&version);
1225: if (size == 1) {
1226: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1227:
1228: } else {
1229: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1230:
1231: }
1232: PetscFPrintf(comm, fd, "Using %s\n", version);
1234: /* Must preserve reduction count before we go on */
1235: red = allreduce_ct/((PetscLogDouble) size);
1237: /* Calculate summary information */
1238: PetscFPrintf(comm, fd, "\n Max Max/Min Avg Total \n");
1239: /* Time */
1240: MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1241: MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1242: MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1243: avg = (tot)/((PetscLogDouble) size);
1244: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1245: PetscFPrintf(comm, fd, "Time (sec): %5.3e %10.5f %5.3e\n", max, ratio, avg);
1246: TotalTime = tot;
1247: /* Objects */
1248: avg = (PetscLogDouble) numObjects;
1249: MPI_Allreduce(&avg, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1250: MPI_Allreduce(&avg, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1251: MPI_Allreduce(&avg, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1252: avg = (tot)/((PetscLogDouble) size);
1253: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1254: PetscFPrintf(comm, fd, "Objects: %5.3e %10.5f %5.3e\n", max, ratio, avg);
1255: /* Flops */
1256: MPI_Allreduce(&_TotalFlops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1257: MPI_Allreduce(&_TotalFlops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1258: MPI_Allreduce(&_TotalFlops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1259: avg = (tot)/((PetscLogDouble) size);
1260: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1261: PetscFPrintf(comm, fd, "Flops: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1262: TotalFlops = tot;
1263: /* Flops/sec -- Must talk to Barry here */
1264: if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1265: MPI_Allreduce(&flops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1266: MPI_Allreduce(&flops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1267: MPI_Allreduce(&flops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1268: avg = (tot)/((PetscLogDouble) size);
1269: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1270: PetscFPrintf(comm, fd, "Flops/sec: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1271: /* Memory */
1272: PetscTrSpace(PETSC_NULL, PETSC_NULL, &mem);
1273: if (mem > 0.0) {
1274: MPI_Allreduce(&mem, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1275: MPI_Allreduce(&mem, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1276: MPI_Allreduce(&mem, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1277: avg = (tot)/((PetscLogDouble) size);
1278: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1279: PetscFPrintf(comm, fd, "Memory: %5.3e %10.5f %5.3e\n", max, ratio, tot);
1280: }
1281: /* Messages */
1282: mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1283: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1284: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1285: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1286: avg = (tot)/((PetscLogDouble) size);
1287: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1288: PetscFPrintf(comm, fd, "MPI Messages: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1289: numMessages = tot;
1290: /* Message Lengths */
1291: mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1292: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1293: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1294: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1295: if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1296: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1297: PetscFPrintf(comm, fd, "MPI Message Lengths: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1298: messageLength = tot;
1299: /* Reductions */
1300: MPI_Allreduce(&red, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1301: MPI_Allreduce(&red, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1302: MPI_Allreduce(&red, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1303: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1304: PetscFPrintf(comm, fd, "MPI Reductions: %5.3e %10.5f\n", max, ratio);
1305: numReductions = tot;
1306: PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");
1307: PetscFPrintf(comm, fd, " e.g., VecAXPY() for real vectors of length N --> 2N flops\n");
1308: PetscFPrintf(comm, fd, " and VecAXPY() for complex vectors of length N --> 8N flops\n");
1310: /* Get total number of stages --
1311: Currently, a single processor can register more stages than another, but stages must all be registered in order.
1312: We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1313: This seems best accomplished by assoicating a communicator with each stage.
1314: */
1315: MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1316: PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1317: PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1318: PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1319: PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1320: if (numStages > 0) {
1321: stageInfo = stageLog->stageInfo;
1322: for(stage = 0; stage < numStages; stage++) {
1323: if (stage < stageLog->numStages) {
1324: localStageUsed[stage] = stageInfo[stage].used;
1325: localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1326: } else {
1327: localStageUsed[stage] = PETSC_FALSE;
1328: localStageVisible[stage] = PETSC_TRUE;
1329: }
1330: }
1331: MPI_Allreduce(localStageUsed, stageUsed, numStages, MPI_INT, MPI_LOR, comm);
1332: MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1333: for(stage = 0; stage < numStages; stage++) {
1334: if (stageUsed[stage] == PETSC_TRUE) {
1335: PetscFPrintf(comm, fd, "\nSummary of Stages: ----- Time ------ ----- Flops ----- --- Messages --- -- Message Lengths -- -- Reductions --\n");
1336: PetscFPrintf(comm, fd, " Avg %%Total Avg %%Total counts %%Total Avg %%Total counts %%Total \n");
1337: break;
1338: }
1339: }
1340: for(stage = 0; stage < numStages; stage++) {
1341: if (stageUsed[stage] == PETSC_FALSE) continue;
1342: if (localStageUsed[stage] == PETSC_TRUE) {
1343: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1344: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1345: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1346: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1347: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1348: name = stageInfo[stage].name;
1349: } else {
1350: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1351: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1352: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1353: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1354: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1355: name = "";
1356: }
1357: mess *= 0.5; messLen *= 0.5; red /= size;
1358: if (TotalTime != 0.0) fracTime = stageTime/TotalTime; else fracTime = 0.0;
1359: if (TotalFlops != 0.0) fracFlops = flops/TotalFlops; else fracFlops = 0.0;
1360: /* Talk to Barry if (stageTime != 0.0) flops = (size*flops)/stageTime; else flops = 0.0; */
1361: if (numMessages != 0.0) fracMessages = mess/numMessages; else fracMessages = 0.0;
1362: if (numMessages != 0.0) avgMessLen = messLen/numMessages; else avgMessLen = 0.0;
1363: if (messageLength != 0.0) fracLength = messLen/messageLength; else fracLength = 0.0;
1364: if (numReductions != 0.0) fracReductions = red/numReductions; else fracReductions = 0.0;
1365: 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",
1366: stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1367: mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1368:
1369: }
1370: }
1372: PetscFPrintf(comm, fd,
1373: "\n------------------------------------------------------------------------------------------------------------------------\n");
1374:
1375: PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1376: PetscFPrintf(comm, fd, "Phase summary info:\n");
1377: PetscFPrintf(comm, fd, " Count: number of times phase was executed\n");
1378: PetscFPrintf(comm, fd, " Time and Flops/sec: Max - maximum over all processors\n");
1379: PetscFPrintf(comm, fd, " Ratio - ratio of maximum to minimum over all processors\n");
1380: PetscFPrintf(comm, fd, " Mess: number of messages sent\n");
1381: PetscFPrintf(comm, fd, " Avg. len: average message length\n");
1382: PetscFPrintf(comm, fd, " Reduct: number of global reductions\n");
1383: PetscFPrintf(comm, fd, " Global: entire computation\n");
1384: PetscFPrintf(comm, fd, " Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");
1385: PetscFPrintf(comm, fd, " %%T - percent time in this phase %%F - percent flops in this phase\n");
1386: PetscFPrintf(comm, fd, " %%M - percent messages in this phase %%L - percent message lengths in this phase\n");
1387: PetscFPrintf(comm, fd, " %%R - percent reductions in this phase\n");
1388: PetscFPrintf(comm, fd, " Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)\n");
1389: PetscFPrintf(comm, fd,
1390: "------------------------------------------------------------------------------------------------------------------------\n");
1391:
1393: #if defined(PETSC_USE_BOPT_g)
1394: PetscFPrintf(comm, fd, "\n\n");
1395: PetscFPrintf(comm, fd, " ##########################################################\n");
1396: PetscFPrintf(comm, fd, " # #\n");
1397: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1398: PetscFPrintf(comm, fd, " # #\n");
1399: PetscFPrintf(comm, fd, " # This code was compiled with a debugging option, #\n");
1400: PetscFPrintf(comm, fd, " # BOPT=<g,g_c++,g_complex>. To get timing results #\n");
1401: PetscFPrintf(comm, fd, " # ALWAYS compile your code with an optimized version, #\n");
1402: PetscFPrintf(comm, fd, " # BOPT=<O,O_c++,O_complex>; 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 the flag -DPETSC_USE_FORTRAN_KERNELS #\n");
1417: PetscFPrintf(comm, fd, " # in base_variables and recompile the PETSc libraries. #\n");
1418: PetscFPrintf(comm, fd, " # #\n");
1419: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1420: #endif
1422: if (!PetscPreLoadingUsed) {
1423: PetscFPrintf(comm,fd,"\n\n");
1424: PetscFPrintf(comm,fd," ##########################################################\n");
1425: PetscFPrintf(comm,fd," # #\n");
1426: PetscFPrintf(comm,fd," # WARNING!!! #\n");
1427: PetscFPrintf(comm,fd," # #\n");
1428: PetscFPrintf(comm,fd," # This code was run without the PreLoadBegin() #\n");
1429: PetscFPrintf(comm,fd," # macros. To get timing results we always recommend #\n");
1430: PetscFPrintf(comm,fd," # preloading. otherwise timing numbers may be #\n");
1431: PetscFPrintf(comm,fd," # meaningless. #\n");
1432: PetscFPrintf(comm,fd," ##########################################################\n\n\n");
1433: }
1435: /* Report events */
1436: PetscFPrintf(comm, fd,
1437: "Event Count Time (sec) Flops/sec --- Global --- --- Stage --- Total\n");
1438:
1439: PetscFPrintf(comm, fd,
1440: " Max Ratio Max Ratio Max Ratio Mess Avg len Reduct %%T %%F %%M %%L %%R %%T %%F %%M %%L %%R Mflop/s\n");
1441:
1442: PetscFPrintf(comm,fd,
1443: "------------------------------------------------------------------------------------------------------------------------\n");
1445:
1446: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1447: for(stage = 0; stage < numStages; stage++) {
1448: if (stageVisible[stage] == PETSC_FALSE) continue;
1449: if (localStageUsed[stage] == PETSC_TRUE) {
1450: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1451: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1452: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1453: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1454: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1455: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1456: } else {
1457: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1458: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1459: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1460: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1461: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1462: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1463: }
1464: mess *= 0.5; messLen *= 0.5; red /= size;
1466: /* Get total number of events in this stage --
1467: Currently, a single processor can register more events than another, but events must all be registered in order,
1468: just like stages. We can removed this requirement if necessary by having a global event numbering and indirection
1469: on the event ID. This seems best accomplished by assoicating a communicator with each stage.
1471: Problem: If the event did not happen on proc 1, its name will not be available.
1472: Problem: Event visibility is not implemented
1473: */
1474: if (localStageUsed[stage] == PETSC_TRUE) {
1475: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1476: localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1477: } else {
1478: localNumEvents = 0;
1479: }
1480: MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1481: for(event = 0; event < numEvents; event++) {
1482: if ((localStageUsed[stage] == PETSC_TRUE) && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1483: if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1484: flopr = eventInfo[event].flops/eventInfo[event].time;
1485: } else {
1486: flopr = 0.0;
1487: }
1488: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1489: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1490: MPI_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1491: MPI_Allreduce(&eventInfo[event].time, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1492: MPI_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1493: MPI_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1494: MPI_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1495: MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1496: MPI_Allreduce(&eventInfo[event].numReductions, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1497: MPI_Allreduce(&eventInfo[event].count, &minCt, 1, MPI_INT, MPI_MIN, comm);
1498: MPI_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1499: name = stageLog->eventLog->eventInfo[event].name;
1500: } else {
1501: flopr = 0.0;
1502: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1503: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1504: MPI_Allreduce(&zero, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1505: MPI_Allreduce(&zero, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1506: MPI_Allreduce(&zero, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1507: MPI_Allreduce(&zero, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1508: MPI_Allreduce(&zero, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1509: MPI_Allreduce(&zero, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1510: MPI_Allreduce(&zero, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1511: MPI_Allreduce(&ierr, &minCt, 1, MPI_INT, MPI_MIN, comm);
1512: MPI_Allreduce(&ierr, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1513: name = "";
1514: }
1515: totm *= 0.5; totml *= 0.5; totr /= size;
1516:
1517: if (maxCt != 0) {
1518: if (minCt != 0) ratCt = ((PetscLogDouble) maxCt)/minCt; else ratCt = 0.0;
1519: if (mint != 0.0) ratt = maxt/mint; else ratt = 0.0;
1520: if (minf != 0.0) ratf = maxf/minf; else ratf = 0.0;
1521: if (TotalTime != 0.0) fracTime = tott/TotalTime; else fracTime = 0.0;
1522: if (TotalFlops != 0.0) fracFlops = totf/TotalFlops; else fracFlops = 0.0;
1523: if (stageTime != 0.0) fracStageTime = tott/stageTime; else fracStageTime = 0.0;
1524: if (flops != 0.0) fracStageFlops = totf/flops; else fracStageFlops = 0.0;
1525: if (numMessages != 0.0) fracMess = totm/numMessages; else fracMess = 0.0;
1526: if (messageLength != 0.0) fracMessLen = totml/messageLength; else fracMessLen = 0.0;
1527: if (numReductions != 0.0) fracRed = totr/numReductions; else fracRed = 0.0;
1528: if (mess != 0.0) fracStageMess = totm/mess; else fracStageMess = 0.0;
1529: if (messLen != 0.0) fracStageMessLen = totml/messLen; else fracStageMessLen = 0.0;
1530: if (red != 0.0) fracStageRed = totr/red; else fracStageRed = 0.0;
1531: if (totm != 0.0) totml /= totm; else totml = 0.0;
1532: if (maxt != 0.0) flopr = totf/maxt; else flopr = 0.0;
1533: PetscFPrintf(comm, fd,
1534: "%-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",
1535: name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1536: 100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1537: 100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1538: flopr/1.0e6);
1539:
1540: }
1541: }
1542: }
1544: /* Memory usage and object creation */
1545: PetscFPrintf(comm, fd,
1546: "------------------------------------------------------------------------------------------------------------------------\n");
1547:
1548: PetscFPrintf(comm, fd, "\n");
1549: PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");
1551: /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1552: the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1553: stats for stages local to processor sets.
1554: */
1555: /* We should figure out the longest object name here (now 20 characters) */
1556: PetscFPrintf(comm, fd, "Object Type Creations Destructions Memory Descendants' Mem.\n");
1557: for(stage = 0; stage < numStages; stage++) {
1558: if (localStageUsed[stage] == PETSC_TRUE) {
1559: classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1560: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1561: for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1562: if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1563: PetscFPrintf(comm, fd, "%20s %5d %5d %9d %g\n", stageLog->classLog->classInfo[oclass].name,
1564: classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1565: classInfo[oclass].descMem);
1566:
1567: }
1568: }
1569: } else {
1570: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1571: }
1572: }
1574: PetscFree(localStageUsed);
1575: PetscFree(stageUsed);
1576: PetscFree(localStageVisible);
1577: PetscFree(stageVisible);
1579: /* Information unrelated to this particular run */
1580: PetscFPrintf(comm, fd,
1581: "========================================================================================================================\n");
1582:
1583: PetscTime(y);
1584: PetscTime(x);
1585: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1586: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1587: PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1588: /* MPI information */
1589: if (size > 1) {
1590: MPI_Status status;
1591: int tag;
1593: MPI_Barrier(comm);
1594: PetscTime(x);
1595: MPI_Barrier(comm);
1596: MPI_Barrier(comm);
1597: MPI_Barrier(comm);
1598: MPI_Barrier(comm);
1599: MPI_Barrier(comm);
1600: PetscTime(y);
1601: PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1602: PetscCommGetNewTag(comm, &tag);
1603: MPI_Barrier(comm);
1604: if (rank) {
1605: MPI_Recv(0, 0, MPI_INT, rank-1, tag, comm, &status);
1606: MPI_Send(0, 0, MPI_INT, (rank+1)%size, tag, comm);
1607: } else {
1608: PetscTime(x);
1609: MPI_Send(0, 0, MPI_INT, 1, tag, comm);
1610: MPI_Recv(0, 0, MPI_INT, size-1, tag, comm, &status);
1611: PetscTime(y);
1612: PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1613: }
1614: }
1615: /* Machine and compile information */
1616: #if defined(PETSC_USE_FORTRAN_KERNELS)
1617: PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1618: #else
1619: PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1620: #endif
1621: #if defined(PETSC_USE_MAT_SINGLE)
1622: PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1623: #else
1624: PetscFPrintf(comm, fd, "Compiled with double precision matrices (default)\n");
1625: #endif
1626: PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d",
1627: (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*));
1628:
1630: PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1631: PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1632: PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1633: PetscFPrintf(comm, fd, "%s", petsclinkerinfo);
1635: /* Cleanup */
1636: PetscFPrintf(comm, fd, "\n");
1637: PetscFClose(comm, fd);
1638: return(0);
1639: }
1641: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1644: /*@C
1645: PetscGetFlops - Returns the number of flops used on this processor
1646: since the program began.
1648: Not Collective
1650: Output Parameter:
1651: flops - number of floating point operations
1653: Notes:
1654: A global counter logs all PETSc flop counts. The user can use
1655: PetscLogFlops() to increment this counter to include flops for the
1656: application code.
1658: PETSc automatically logs library events if the code has been
1659: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1660: -log_summary, or -log_all are specified. PetscLogFlops() is
1661: intended for logging user flops to supplement this PETSc
1662: information.
1664: Level: intermediate
1666: .keywords: log, flops, floating point operations
1668: .seealso: PetscGetTime(), PetscLogFlops()
1669: @*/
1670: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
1671: {
1673: *flops = _TotalFlops;
1674: return(0);
1675: }
1679: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
1680: {
1682: va_list Argp;
1685: if (!logObjects) return(0);
1686: va_start(Argp, format);
1687: PetscVSNPrintf(objects[obj->id].info, 64,format, Argp);
1688: va_end(Argp);
1689: return(0);
1690: }
1692: #else /* end of -DPETSC_USE_LOG section */
1696: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
1697: {
1699: return(0);
1700: }
1702: #endif /* PETSC_USE_LOG*/
1706: /*@
1707: PetscGetTime - Returns the current time of day in seconds. This
1708: returns wall-clock time.
1710: Not Collective
1712: Output Parameter:
1713: . v - time counter
1715: Usage:
1716: .vb
1717: PetscLogDouble v1,v2,elapsed_time;
1718: PetscGetTime(&v1);CHKERR(ierr);
1719: .... perform some calculation ...
1720: PetscGetTime(&v2);CHKERR(ierr);
1721: elapsed_time = v2 - v1;
1722: .ve
1724: Notes:
1725: Since the PETSc libraries incorporate timing of phases and operations,
1726: PetscGetTime() is intended only for timing of application codes.
1727: The options database commands -log, -log_summary, and -log_all activate
1728: PETSc library timing. See the users manual for further details.
1730: Level: intermediate
1732: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStagePush(),
1733: PetscLogStagePop(), PetscLogStageRegister(), PetscGetFlops()
1735: .keywords: get, time
1736: @*/
1737: PetscErrorCode PetscGetTime(PetscLogDouble *t)
1738: {
1740: PetscTime(*t);
1741: return(0);
1742: }
1746: /*@
1747: PetscLogGetStageLog - This function returns the default stage logging object.
1749: Not collective
1751: Output Parameter:
1752: . stageLog - The default StageLog
1754: Level: beginner
1756: .keywords: log, stage
1757: .seealso: StageLogCreate()
1758: @*/
1759: PetscErrorCode PetscLogGetStageLog(StageLog *stageLog)
1760: {
1763: *stageLog = _stageLog;
1764: return(0);
1765: }
1767: /*MC
1768: PetscLogFlops - Adds floating point operations to the global counter.
1770: Input Parameter:
1771: . f - flop counter
1773: Synopsis:
1774: void PetscLogFlops(int f)
1776: Usage:
1777: .vb
1778: int USER_EVENT;
1779: PetscLogEventRegister(&USER_EVENT,"User event");
1780: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1781: [code segment to monitor]
1782: PetscLogFlops(user_flops)
1783: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1784: .ve
1786: Notes:
1787: A global counter logs all PETSc flop counts. The user can use
1788: PetscLogFlops() to increment this counter to include flops for the
1789: application code.
1791: PETSc automatically logs library events if the code has been
1792: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1793: -log_summary, or -log_all are specified. PetscLogFlops() is
1794: intended for logging user flops to supplement this PETSc
1795: information.
1797: Level: intermediate
1799: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()
1801: .keywords: log, flops, floating point operations
1802: M*/
1804: PetscTruth PetscPreLoadingUsed = PETSC_FALSE;
1805: PetscTruth PetscPreLoadingOn = PETSC_FALSE;
1807: /*MC
1808: PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1809: to get accurate timings
1811: Input Parameter:
1812: + flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1813: with command line option -preload true or -preload false
1814: - name - name of first stage (lines of code timed seperately with -log_summary) to
1815: be preloaded
1817: Synopsis:
1818: void PreLoadBegin(PetscTruth flag,char *name);
1820: Usage:
1821: .vb
1822: PreLoadBegin(PETSC_TRUE,"first stage);
1823: lines of code
1824: PreLoadStage("second stage");
1825: lines of code
1826: PreLoadEnd();
1827: .ve
1829: Notes: Flags available within the macro.
1830: + PetscPreLoadingUsed - true if we are or have done preloading
1831: . PetscPreLoadingOn - true if it is CURRENTLY doing preload
1832: . PreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
1833: - PreLoadMax - number of times it will do the computation, only one when preloading is turned on
1834: The first two variables are available throughout the program, the second two only between the PreLoadBegin()
1835: and PreLoadEnd()
1837: Level: intermediate
1839: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadEnd(), PreLoadStage()
1841: Concepts: preloading
1842: Concepts: timing^accurate
1843: Concepts: paging^eliminating effects of
1846: M*/
1848: /*MC
1849: PreLoadEnd - End a segment of code that may be preloaded (run twice)
1850: to get accurate timings
1852: Synopsis:
1853: void PreLoadEnd(void);
1855: Usage:
1856: .vb
1857: PreLoadBegin(PETSC_TRUE,"first stage);
1858: lines of code
1859: PreLoadStage("second stage");
1860: lines of code
1861: PreLoadEnd();
1862: .ve
1864: Level: intermediate
1866: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadStage()
1868: M*/
1870: /*MC
1871: PreLoadStage - Start a new segment of code to be timed seperately.
1872: to get accurate timings
1874: Synopsis:
1875: void PreLoadStage(char *name);
1877: Usage:
1878: .vb
1879: PreLoadBegin(PETSC_TRUE,"first stage);
1880: lines of code
1881: PreLoadStage("second stage");
1882: lines of code
1883: PreLoadEnd();
1884: .ve
1886: Level: intermediate
1888: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd()
1890: M*/
1892: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1895: /*@C
1896: StackDestroy - This function destroys a stack.
1898: Not Collective
1900: Input Parameter:
1901: . stack - The stack
1903: Level: beginner
1905: .keywords: log, stack, destroy
1906: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
1907: @*/
1908: PetscErrorCode StackDestroy(IntStack stack)
1909: {
1913: PetscFree(stack->stack);
1914: PetscFree(stack);
1915: return(0);
1916: }
1920: /*@C
1921: StackEmpty - This function determines whether any items have been pushed.
1923: Not Collective
1925: Input Parameter:
1926: . stack - The stack
1928: Output Parameter:
1929: . empty - PETSC_TRUE if the stack is empty
1931: Level: intermediate
1933: .keywords: log, stack, empty
1934: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
1935: @*/
1936: PetscErrorCode StackEmpty(IntStack stack, PetscTruth *empty)
1937: {
1940: if (stack->top == -1) {
1941: *empty = PETSC_TRUE;
1942: } else {
1943: *empty = PETSC_FALSE;
1944: }
1945: return(0);
1946: }
1950: /*@C
1951: StackTop - This function returns the top of the stack.
1953: Not Collective
1955: Input Parameter:
1956: . stack - The stack
1958: Output Parameter:
1959: . top - The integer on top of the stack
1961: Level: intermediate
1963: .keywords: log, stack, top
1964: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
1965: @*/
1966: PetscErrorCode StackTop(IntStack stack, int *top)
1967: {
1970: *top = stack->stack[stack->top];
1971: return(0);
1972: }
1976: /*@C
1977: StackPush - This function pushes an integer on the stack.
1979: Not Collective
1981: Input Parameters:
1982: + stack - The stack
1983: - item - The integer to push
1985: Level: intermediate
1987: .keywords: log, stack, push
1988: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
1989: @*/
1990: PetscErrorCode StackPush(IntStack stack, int item)
1991: {
1992: int *array;
1996: stack->top++;
1997: if (stack->top >= stack->max) {
1998: PetscMalloc(stack->max*2 * sizeof(int), &array);
1999: PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
2000: PetscFree(stack->stack);
2001: stack->stack = array;
2002: stack->max *= 2;
2003: }
2004: stack->stack[stack->top] = item;
2005: return(0);
2006: }
2010: /*@C
2011: StackPop - This function pops an integer from the stack.
2013: Not Collective
2015: Input Parameter:
2016: . stack - The stack
2018: Output Parameter:
2019: . item - The integer popped
2021: Level: intermediate
2023: .keywords: log, stack, pop
2024: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
2025: @*/
2026: PetscErrorCode StackPop(IntStack stack, int *item)
2027: {
2030: if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
2031: *item = stack->stack[stack->top--];
2032: return(0);
2033: }
2037: /*@C
2038: StackCreate - This function creates a stack.
2040: Not Collective
2042: Output Parameter:
2043: . stack - The stack
2045: Level: beginner
2047: .keywords: log, stack, pop
2048: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
2049: @*/
2050: PetscErrorCode StackCreate(IntStack *stack)
2051: {
2052: IntStack s;
2057: PetscNew(struct _IntStack, &s);
2058: s->top = -1;
2059: s->max = 128;
2060: PetscMalloc(s->max * sizeof(int), &s->stack);
2061: PetscMemzero(s->stack, s->max * sizeof(int));
2062: *stack = s;
2063: return(0);
2064: }