Actual source code: plog.c
1: /*$Id: plog.c,v 1.262 2001/08/22 17:59:37 balay Exp $*/
2: /*
3: PETSc code to log object creation and destruction and PETSc events.
4: */
5: #include petsc.h
6: #include "petscmachineinfo.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) && !defined(__cplusplus)
17: #include <malloc.h>
18: #endif
19: #include "petscfix.h"
20: #include src/sys/src/plog/ptime.h
21: #include plog.h
23: int PETSC_LARGEST_COOKIE = PETSC_COOKIE;
24: int PETSC_LARGEST_EVENT = PETSC_EVENT;
26: #if defined(PETSC_USE_LOG)
28: /* used in the MPI_XXX() count macros in petsclog.h */
29: int PETSC_DUMMY,PETSC_DUMMY_SIZE;
31: /* Action and object logging variables */
32: Action *actions = PETSC_NULL;
33: Object *objects = PETSC_NULL;
34: PetscTruth logActions = PETSC_TRUE;
35: PetscTruth logObjects = PETSC_TRUE;
36: int numActions = 0, maxActions = 100;
37: int numObjects = 0, maxObjects = 100;
38: int numObjectsDestroyed = 0;
40: /* Global counters */
41: PetscLogDouble BaseTime;
42: PetscLogDouble _TotalFlops = 0.0; /* The 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 */
57: /* Logging functions */
58: int (*_PetscLogPHC)(PetscObject) = PETSC_NULL;
59: int (*_PetscLogPHD)(PetscObject) = PETSC_NULL;
60: int (*_PetscLogPLB)(int, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
61: int (*_PetscLogPLE)(int, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
63: /* Tracing event logging variables */
64: FILE *tracefile = PETSC_NULL;
65: int tracelevel = 0;
66: char *traceblanks = " ";
67: char tracespace[128];
68: PetscLogDouble tracetime = 0.0;
70: /*---------------------------------------------- General Functions --------------------------------------------------*/
71: /*@C
72: PetscLogDestroy - Destroys the object and event logging data and resets the global counters.
74: Not Collective
76: Notes:
77: This routine should not usually be used by programmers. Instead employ
78: PetscLogStagePush() and PetscLogStagePop().
80: Level: developer
82: .keywords: log, destroy
83: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogStagePush(), PlogStagePop()
84: @*/
85: int PetscLogDestroy(void) {
86: StageLog stageLog;
87: int ierr;
90: if (actions != PETSC_NULL) {
91: PetscFree(actions);
92: actions = PETSC_NULL;
93: }
94: if (objects != PETSC_NULL) {
95: PetscFree(objects);
96: objects = PETSC_NULL;
97: }
98: PetscLogSet(PETSC_NULL, PETSC_NULL);
100: /* Resetting phase */
101: PetscLogGetStageLog(&stageLog);
102: StageLogDestroy(stageLog);
103: _TotalFlops = 0.0;
104: numActions = 0;
105: numObjects = 0;
106: numObjectsDestroyed = 0;
107: return(0);
108: }
110: /*@C
111: PetscLogSet - Sets the logging functions called at the beginning and ending of every event.
113: Not Collective
115: Input Parameters:
116: + b - The function called at beginning of event
117: - e - The function called at end of event
119: Level: developer
121: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
122: @*/
123: int PetscLogSet(int (*b)(int, int, PetscObject, PetscObject, PetscObject, PetscObject),
124: int (*e)(int, int, PetscObject, PetscObject, PetscObject, PetscObject))
125: {
127: _PetscLogPLB = b;
128: _PetscLogPLE = e;
129: return(0);
130: }
132: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
133: int PetscLogBegin_Private(void) {
134: static int initialized = 0;
135: int stage;
136: PetscTruth opt;
137: int ierr;
140: if (initialized) return(0);
141: initialized = 1;
142: PetscOptionsHasName(PETSC_NULL, "-log_exclude_actions", &opt);
143: if (opt == PETSC_FALSE) {
144: PetscMalloc(maxActions * sizeof(Action), &actions);
145: } else {
146: logActions = PETSC_FALSE;
147: }
148: PetscOptionsHasName(PETSC_NULL, "-log_exclude_objects", &opt);
149: if (opt == PETSC_FALSE) {
150: PetscMalloc(maxObjects * sizeof(Object), &objects);
151: } else {
152: logObjects = PETSC_FALSE;
153: }
154: _PetscLogPHC = PetscLogObjCreateDefault;
155: _PetscLogPHD = PetscLogObjDestroyDefault;
156: /* Setup default logging structures */
157: StageLogCreate(&_stageLog);
158: StageLogRegister(_stageLog, "Main Stage", &stage);
159: /* All processors sync here for more consistent logging */
160: MPI_Barrier(PETSC_COMM_WORLD);
161: PetscTime(BaseTime);
162: PetscLogStagePush(stage);
163: return(0);
164: }
166: /*@C
167: PetscLogBegin - Turns on logging of objects and events. This logs flop
168: rates and object creation and should not slow programs down too much.
169: This routine may be called more than once.
171: Collective over PETSC_COMM_WORLD
173: Options Database Keys:
174: + -log_summary - Prints summary of flop and timing information to the
175: screen (for code compiled with PETSC_USE_LOG)
176: - -log - Prints detailed log information (for code compiled with PETSC_USE_LOG)
178: Usage:
179: .vb
180: PetscInitialize(...);
181: PetscLogBegin();
182: ... code ...
183: PetscLogPrintSummary(MPI_Comm,filename); or PetscLogDump();
184: PetscFinalize();
185: .ve
187: Notes:
188: PetscLogPrintSummary(MPI_Comm,filename) or PetscLogDump() actually cause the printing of
189: the logging information.
191: Level: advanced
193: .keywords: log, begin
194: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogTraceBegin()
195: @*/
196: int PetscLogBegin(void)
197: {
201: PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
202: PetscLogBegin_Private();
203: return(0);
204: }
206: /*@C
207: PetscLogAllBegin - Turns on extensive logging of objects and events. Logs
208: all events. This creates large log files and slows the program down.
210: Collective on PETSC_COMM_WORLD
212: Options Database Keys:
213: . -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
215: Usage:
216: .vb
217: PetscInitialize(...);
218: PetscLogAllBegin();
219: ... code ...
220: PetscLogDump(filename);
221: PetscFinalize();
222: .ve
224: Notes:
225: A related routine is PetscLogBegin (with the options key -log), which is
226: intended for production runs since it logs only flop rates and object
227: creation (and shouldn't significantly slow the programs).
229: Level: advanced
231: .keywords: log, all, begin
232: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogTraceBegin()
233: @*/
234: int PetscLogAllBegin(void)
235: {
239: PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
240: PetscLogBegin_Private();
241: return(0);
242: }
244: /*@
245: PetscLogTraceBegin - Activates trace logging. Every time a PETSc event
246: begins or ends, the event name is printed.
248: Collective on PETSC_COMM_WORLD
250: Input Parameter:
251: . file - The file to print trace in (e.g. stdout)
253: Options Database Key:
254: . -log_trace [filename] - Activates PetscLogTraceBegin()
256: Notes:
257: PetscLogTraceBegin() prints the processor number, the execution time (sec),
258: then "Event begin:" or "Event end:" followed by the event name.
260: PetscLogTraceBegin() allows tracing of all PETSc calls, which is useful
261: to determine where a program is hanging without running in the
262: debugger. Can be used in conjunction with the -log_info option.
264: Level: intermediate
266: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogBegin()
267: @*/
268: int PetscLogTraceBegin(FILE *file)
269: {
273: tracefile = file;
274: PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
275: PetscLogBegin_Private();
276: return(0);
277: }
279: /*@
280: PetscLogActions - Determines whether actions are logged for the graphical viewer.
282: Not Collective
284: Input Parameter:
285: . flag - PETSC_TRUE if actions are to be logged
287: Level: intermediate
289: Note: Logging of actions continues to consume more memory as the program
290: runs. Long running programs should consider turning this feature off.
292: Options Database Keys:
293: . -log_exclude_actions - Turns off actions logging
295: .keywords: log, stage, register
296: .seealso: PetscLogStagePush(), PetscLogStagePop()
297: @*/
298: int PetscLogActions(PetscTruth flag) {
300: logActions = flag;
301: return(0);
302: }
304: /*@
305: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
307: Not Collective
309: Input Parameter:
310: . flag - PETSC_TRUE if objects are to be logged
312: Level: intermediate
314: Note: Logging of objects continues to consume more memory as the program
315: runs. Long running programs should consider turning this feature off.
317: Options Database Keys:
318: . -log_exclude_objects - Turns off objects logging
320: .keywords: log, stage, register
321: .seealso: PetscLogStagePush(), PetscLogStagePop()
322: @*/
323: int PetscLogObjects(PetscTruth flag) {
325: logObjects = flag;
326: return(0);
327: }
329: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
330: /*@C
331: PetscLogStageRegister - Attaches a charactor string name to a logging stage.
333: Not Collective
335: Input Parameter:
336: . sname - The name to associate with that stage
338: Output Parameter:
339: . stage - The stage number
341: Level: intermediate
343: .keywords: log, stage, register
344: .seealso: PetscLogStagePush(), PetscLogStagePop()
345: @*/
346: int PetscLogStageRegister(int *stage, const char sname[]) {
347: StageLog stageLog;
348: int ierr;
351: PetscLogGetStageLog(&stageLog);
352: StageLogRegister(stageLog, sname, stage);
353: EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
354: ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
355: return(0);
356: }
358: /*@C
359: PetscLogStagePush - This function pushes a stage on the stack.
361: Not Collective
363: Input Parameter:
364: . stage - The stage on which to log
366: Usage:
367: If the option -log_sumary is used to run the program containing the
368: following code, then 2 sets of summary data will be printed during
369: PetscFinalize().
370: .vb
371: PetscInitialize(int *argc,char ***args,0,0);
372: [stage 0 of code]
373: PetscLogStagePush(1);
374: [stage 1 of code]
375: PetscLogStagePop();
376: PetscBarrier(...);
377: [more stage 0 of code]
378: PetscFinalize();
379: .ve
380:
381: Notes:
382: Use PetscLogStageRegister() to register a stage.
384: Level: intermediate
386: .keywords: log, push, stage
387: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
388: @*/
389: int PetscLogStagePush(int stage)
390: {
391: StageLog stageLog;
392: int ierr;
395: PetscLogGetStageLog(&stageLog);
396: StageLogPush(stageLog, stage);
397: return(0);
398: }
400: /*@C
401: PetscLogStagePop - This function pops a stage from the stack.
403: Not Collective
405: Usage:
406: If the option -log_sumary is used to run the program containing the
407: following code, then 2 sets of summary data will be printed during
408: PetscFinalize().
409: .vb
410: PetscInitialize(int *argc,char ***args,0,0);
411: [stage 0 of code]
412: PetscLogStagePush(1);
413: [stage 1 of code]
414: PetscLogStagePop();
415: PetscBarrier(...);
416: [more stage 0 of code]
417: PetscFinalize();
418: .ve
420: Notes:
421: Use PetscLogStageRegister() to register a stage.
423: Level: intermediate
425: .keywords: log, pop, stage
426: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
427: @*/
428: int PetscLogStagePop(void)
429: {
430: StageLog stageLog;
431: int ierr;
434: PetscLogGetStageLog(&stageLog);
435: StageLogPop(stageLog);
436: return(0);
437: }
439: /*@
440: PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().
442: Not Collective
444: Input Parameters:
445: + stage - The stage
446: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
448: Level: intermediate
450: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
451: @*/
452: int PetscLogStageSetActive(int stage, PetscTruth isActive) {
453: StageLog stageLog;
454: int ierr;
457: PetscLogGetStageLog(&stageLog);
458: StageLogSetActive(stageLog, stage, isActive);
459: return(0);
460: }
462: /*@
463: PetscLogStageGetActive - Returns stage activity for PetscLogEventBegin() and PetscLogEventEnd().
465: Not Collective
467: Input Parameter:
468: . stage - The stage
470: Output Parameter:
471: . isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
473: Level: intermediate
475: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
476: @*/
477: int PetscLogStageGetActive(int stage, PetscTruth *isActive) {
478: StageLog stageLog;
479: int ierr;
482: PetscLogGetStageLog(&stageLog);
483: StageLogGetActive(stageLog, stage, isActive);
484: return(0);
485: }
487: /*@
488: PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()
490: Not Collective
492: Input Parameters:
493: + stage - The stage
494: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
496: Level: intermediate
498: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
499: @*/
500: int PetscLogStageSetVisible(int stage, PetscTruth isVisible)
501: {
502: StageLog stageLog;
503: int ierr;
506: PetscLogGetStageLog(&stageLog);
507: StageLogSetVisible(stageLog, stage, isVisible);
508: return(0);
509: }
511: /*@
512: PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()
514: Not Collective
516: Input Parameter:
517: . stage - The stage
519: Output Parameter:
520: . isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
522: Level: intermediate
524: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
525: @*/
526: int PetscLogStageGetVisible(int stage, PetscTruth *isVisible)
527: {
528: StageLog stageLog;
529: int ierr;
532: PetscLogGetStageLog(&stageLog);
533: StageLogGetVisible(stageLog, stage, isVisible);
534: return(0);
535: }
537: /*@
538: PetscLogStageGetId - Returns the stage id when given the stage name.
540: Not Collective
542: Input Parameter:
543: . name - The stage name
545: Output Parameter:
546: . stage - The stage
548: Level: intermediate
550: .seealso: PetscLogStagePush(), PetscLogStagePop(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
551: @*/
552: int PetscLogStageGetId(const char name[], int *stage)
553: {
554: StageLog stageLog;
555: int ierr;
558: PetscLogGetStageLog(&stageLog);
559: StageLogGetStage(stageLog, name, stage);
560: return(0);
561: }
563: /*------------------------------------------------ Event Functions --------------------------------------------------*/
564: /*@C
565: PetscLogEventRegister - Registers an event name for logging operations in an application code.
567: Not Collective
569: Input Parameter:
570: + name - The name associated with the event
571: - cookie - The cookie associated to the class for this event
572:
573: Output Parameter:
574: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().
576: Example of Usage:
577: .vb
578: int USER_EVENT;
579: int user_event_flops;
580: PetscLogEventRegister(&USER_EVENT,"User event name");
581: PetscLogEventBegin(USER_EVENT,0,0,0,0);
582: [code segment to monitor]
583: PetscLogFlops(user_event_flops);
584: PetscLogEventEnd(USER_EVENT,0,0,0,0);
585: .ve
587: Notes:
588: PETSc automatically logs library events if the code has been
589: compiled with -DPETSC_USE_LOG (which is the default) and -log,
590: -log_summary, or -log_all are specified. PetscLogEventRegister() is
591: intended for logging user events to supplement this PETSc
592: information.
594: PETSc can gather data for use with the utilities Upshot/Nupshot
595: (part of the MPICH distribution). If PETSc has been compiled
596: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
597: MPICH), the user can employ another command line option, -log_mpe,
598: to create a logfile, "mpe.log", which can be visualized
599: Upshot/Nupshot.
601: Level: intermediate
603: .keywords: log, event, register
604: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
605: PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
606: PetscLogEventActivate(), PetscLogEventDeactivate()
607: @*/
608: int PetscLogEventRegister(int *event, const char name[],int cookie) {
609: StageLog stageLog;
610: int stage;
611: int ierr;
614: *event = PETSC_DECIDE;
615: PetscLogGetStageLog(&stageLog);
616: EventRegLogRegister(stageLog->eventLog, name, cookie, event);
617: for(stage = 0; stage < stageLog->numStages; stage++) {
618: EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
619: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
620: }
621: return(0);
622: }
624: /*@
625: PetscLogEventActivate - Indicates that a particular event should be logged.
627: Not Collective
629: Input Parameter:
630: . event - The event id
632: Usage:
633: .vb
634: PetscLogEventDeactivate(VEC_SetValues);
635: [code where you do not want to log VecSetValues()]
636: PetscLogEventActivate(VEC_SetValues);
637: [code where you do want to log VecSetValues()]
638: .ve
640: Note:
641: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
642: or an event number obtained with PetscLogEventRegister().
644: Level: advanced
646: .keywords: log, event, activate
647: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
648: @*/
649: int PetscLogEventActivate(int event) {
650: StageLog stageLog;
651: int stage;
652: int ierr;
655: PetscLogGetStageLog(&stageLog);
656: StageLogGetCurrent(stageLog, &stage);
657: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
658: return(0);
659: }
661: /*@
662: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
664: Not Collective
666: Input Parameter:
667: . event - The event id
669: Usage:
670: .vb
671: PetscLogEventDeactivate(VEC_SetValues);
672: [code where you do not want to log VecSetValues()]
673: PetscLogEventActivate(VEC_SetValues);
674: [code where you do want to log VecSetValues()]
675: .ve
677: Note:
678: The event may be either a pre-defined PETSc event (found in
679: include/petsclog.h) or an event number obtained with PetscLogEventRegister()).
681: Level: advanced
683: .keywords: log, event, deactivate
684: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
685: @*/
686: int PetscLogEventDeactivate(int event) {
687: StageLog stageLog;
688: int stage;
689: int ierr;
692: PetscLogGetStageLog(&stageLog);
693: StageLogGetCurrent(stageLog, &stage);
694: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
695: return(0);
696: }
698: /*@
699: PetscLogEventActivateClass - Activates event logging for a PETSc object class.
701: Not Collective
703: Input Parameter:
704: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
706: Level: developer
708: .keywords: log, event, activate, class
709: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
710: @*/
711: int PetscLogEventActivateClass(int cookie) {
712: StageLog stageLog;
713: int stage;
714: int ierr;
717: PetscLogGetStageLog(&stageLog);
718: StageLogGetCurrent(stageLog, &stage);
719: EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
720: return(0);
721: }
723: /*@
724: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.
726: Not Collective
728: Input Parameter:
729: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
731: Level: developer
733: .keywords: log, event, deactivate, class
734: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
735: @*/
736: int PetscLogEventDeactivateClass(int cookie) {
737: StageLog stageLog;
738: int stage;
739: int ierr;
742: PetscLogGetStageLog(&stageLog);
743: StageLogGetCurrent(stageLog, &stage);
744: EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
745: return(0);
746: }
748: /*MC
749: PetscLogEventBegin - Logs the beginning of a user event.
751: Input Parameters:
752: + e - integer associated with the event obtained from PetscLogEventRegister()
753: - o1,o2,o3,o4 - objects associated with the event, or 0
755: Synopsis:
756: void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
757: PetscObject o4)
759: Usage:
760: .vb
761: int USER_EVENT;
762: int user_event_flops;
763: PetscLogEventRegister(&USER_EVENT,"User event");
764: PetscLogEventBegin(USER_EVENT,0,0,0,0);
765: [code segment to monitor]
766: PetscLogFlops(user_event_flops);
767: PetscLogEventEnd(USER_EVENT,0,0,0,0);
768: .ve
770: Notes:
771: You should also register each integer event with the command
772: PetscLogEventRegister(). The source code must be compiled with
773: -DPETSC_USE_LOG, which is the default.
775: PETSc automatically logs library events if the code has been
776: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
777: specified. PetscLogEventBegin() is intended for logging user events
778: to supplement this PETSc information.
780: Level: intermediate
782: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops()
784: .keywords: log, event, begin
785: M*/
787: /*MC
788: PetscLogEventEnd - Log the end of a user event.
790: Input Parameters:
791: + e - integer associated with the event obtained with PetscLogEventRegister()
792: - o1,o2,o3,o4 - objects associated with the event, or 0
794: Synopsis:
795: void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
796: PetscObject o4)
798: Usage:
799: .vb
800: int USER_EVENT;
801: int user_event_flops;
802: PetscLogEventRegister(&USER_EVENT,"User event");
803: PetscLogEventBegin(USER_EVENT,0,0,0,0);
804: [code segment to monitor]
805: PetscLogFlops(user_event_flops);
806: PetscLogEventEnd(USER_EVENT,0,0,0,0);
807: .ve
809: Notes:
810: You should also register each additional integer event with the command
811: PetscLogEventRegister(). Source code must be compiled with
812: -DPETSC_USE_LOG, which is the default.
814: PETSc automatically logs library events if the code has been
815: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
816: specified. PetscLogEventEnd() is intended for logging user events
817: to supplement this PETSc information.
819: Level: intermediate
821: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogFlops()
823: .keywords: log, event, end
824: M*/
826: /*MC
827: PetscLogEventBarrierBegin - Logs the time in a barrier before an event.
829: Input Parameters:
830: . e - integer associated with the event obtained from PetscLogEventRegister()
831: . o1,o2,o3,o4 - objects associated with the event, or 0
832: . comm - communicator the barrier takes place over
834: Synopsis:
835: void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
836: PetscObject o4,MPI_Comm comm)
838: Usage:
839: .vb
840: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
841: MPI_Allreduce()
842: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
843: .ve
845: Notes:
846: This is for logging the amount of time spent in a barrier for an event
847: that requires synchronization.
849: Additional Notes:
850: Synchronization events always come in pairs; for example, VEC_NormBarrier and
851: VEC_NormComm = VEC_NormBarrier + 1
853: Level: advanced
855: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
856: PetscLogEventBarrierEnd()
858: .keywords: log, event, begin, barrier
859: M*/
861: /*MC
862: PetscLogEventBarrierEnd - Logs the time in a barrier before an event.
864: Input Parameters:
865: . e - integer associated with the event obtained from PetscLogEventRegister()
866: . o1,o2,o3,o4 - objects associated with the event, or 0
867: . comm - communicator the barrier takes place over
869: Synopsis:
870: void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
871: PetscObject o4,MPI_Comm comm)
873: Usage:
874: .vb
875: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
876: MPI_Allreduce()
877: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
878: .ve
880: Notes:
881: This is for logging the amount of time spent in a barrier for an event
882: that requires synchronization.
884: Additional Notes:
885: Synchronization events always come in pairs; for example, VEC_NormBarrier and
886: VEC_NormComm = VEC_NormBarrier + 1
888: Level: advanced
890: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
891: PetscLogEventBarrierBegin()
893: .keywords: log, event, begin, barrier
894: M*/
896: /*------------------------------------------------ Class Functions --------------------------------------------------*/
897: /*@C
898: PetscLogClassRegister - Registers a class name for logging operations in an application code.
900: Not Collective
902: Input Parameter:
903: . name - The class name
904:
905: Output Parameter:
906: . oclass - The class id or cookie
908: Level: developer
910: .keywords: log, class, register
911: .seealso: ClassLogRegister()
912: @*/
913: int PetscLogClassRegister(int *oclass, const char name[])
914: {
915: StageLog stageLog;
916: int ierr;
919: *oclass = PETSC_DECIDE;
920: PetscLogGetStageLog(&stageLog);
921: ClassRegLogRegister(stageLog->classLog, name, oclass);
922: return(0);
923: }
925: /*------------------------------------------------ Output Functions -------------------------------------------------*/
926: /*@C
927: PetscLogDump - Dumps logs of objects to a file. This file is intended to
928: be read by petsc/bin/petscview.
930: Collective on PETSC_COMM_WORLD
932: Input Parameter:
933: . name - an optional file name
935: Options Database Keys:
936: + -log - Prints basic log information (for code compiled with PETSC_USE_LOG)
937: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
938:
939: Usage:
940: .vb
941: PetscInitialize(...);
942: PetscLogBegin(); or PetscLogAllBegin();
943: ... code ...
944: PetscLogDump(filename);
945: PetscFinalize();
946: .ve
948: Notes:
949: The default file name is
950: $ Log.<rank>
951: where <rank> is the processor number. If no name is specified,
952: this file will be used.
954: Level: advanced
956: .keywords: log, dump
957: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
958: @*/
959: int PetscLogDump(const char sname[]) {
960: StageLog stageLog;
961: EventPerfInfo *eventInfo;
962: FILE *fd;
963: char file[64], fname[64];
964: PetscLogDouble flops, _TotalTime;
965: int rank, curStage;
966: int action, object, event;
967: int ierr;
968:
970: /* Calculate the total elapsed time */
971: PetscTime(_TotalTime);
972: _TotalTime -= BaseTime;
973: /* Open log file */
974: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
975: if (sname != PETSC_NULL) {
976: sprintf(file, "%s.%d", sname, rank);
977: } else {
978: sprintf(file, "Log.%d", rank);
979: }
980: PetscFixFilename(file, fname);
981: PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
982: if ((rank == 0) && (fd == PETSC_NULL)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
983: /* Output totals */
984: PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8en", _TotalFlops, _TotalTime);
985: PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %gn", 0.0);
986: /* Output actions */
987: PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %dn", numActions);
988: for(action = 0; action < numActions; action++) {
989: PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %gn",
990: actions[action].time, actions[action].action, actions[action].event, actions[action].cookie, actions[action].id1,
991: actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
992: }
993: /* Output objects */
994: PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %dn", numObjects, numObjectsDestroyed);
995: for(object = 0; object < numObjects; object++) {
996: PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %dn", objects[object].parent, (int) objects[object].mem);
997: if (!objects[object].name[0]) {
998: PetscFPrintf(PETSC_COMM_WORLD, fd,"No Namen");
999: } else {
1000: PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %sn", objects[object].name);
1001: }
1002: if (objects[object].info[0] != 0) {
1003: PetscFPrintf(PETSC_COMM_WORLD, fd, "No Infon");
1004: } else {
1005: PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %sn", objects[object].info);
1006: }
1007: }
1008: /* Output events */
1009: PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:n");
1010: PetscLogGetStageLog(&stageLog);
1011: StackTop(stageLog->stack, &curStage);
1012: eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1013: for(event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1014: if (eventInfo[event].time != 0.0) {
1015: flops = eventInfo[event].flops/eventInfo[event].time;
1016: } else {
1017: flops = 0.0;
1018: }
1019: PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16gn", event, eventInfo[event].count,
1020: eventInfo[event].flops, eventInfo[event].time, flops);
1021: }
1022: PetscFClose(PETSC_COMM_WORLD, fd);
1023: return(0);
1024: }
1026: /*@C
1027: PetscLogPrintSummary - Prints a summary of the logging.
1029: Collective over MPI_Comm
1031: Input Parameter:
1032: + comm - The MPI communicator (only one processor prints output)
1033: - file - [Optional] The output file name
1035: Options Database Keys:
1036: . -log_summary - Prints summary of log information (for code compiled with PETSC_USE_LOG)
1038: Usage:
1039: .vb
1040: PetscInitialize(...);
1041: PetscLogBegin();
1042: ... code ...
1043: PetscLogPrintSummary(MPI_Comm,filename);
1044: PetscFinalize(...);
1045: .ve
1047: Notes:
1048: By default the summary is printed to stdout.
1049: More extensive examination of the log information can be done with
1050: PetscLogDump(), which is activated by the option -log or -log_all, in
1051: combination with petsc/bin/petscview.
1053: Level: beginner
1054:
1055: .keywords: log, dump, print
1056: .seealso: PetscLogBegin(), PetscLogDump()
1057: @*/
1058: int PetscLogPrintSummary(MPI_Comm comm, const char filename[]) {
1059: FILE *fd = stdout;
1060: PetscScalar zero = 0.0;
1061: StageLog stageLog;
1062: StageInfo *stageInfo = PETSC_NULL;
1063: EventPerfInfo *eventInfo = PETSC_NULL;
1064: ClassPerfInfo *classInfo;
1065: char arch[10], hostname[64], username[16], pname[256], date[64];
1066: char *name;
1067: PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1068: PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1069: PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1070: PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1071: PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1072: PetscLogDouble min, max, tot, ratio, avg, x, y;
1073: PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1074: int minCt, maxCt;
1075: int numProcs, rank;
1076: PetscTruth *localStageUsed, *stageUsed;
1077: PetscTruth *localStageVisible, *stageVisible;
1078: int numStages, localNumEvents, numEvents;
1079: int stage, event, oclass;
1080: int ierr;
1081: char version[256];
1084: MPI_Comm_size(comm, &numProcs);
1085: MPI_Comm_rank(comm, &rank);
1086: /* Pop off any stages the user forgot to remove */
1087: PetscLogGetStageLog(&stageLog);
1088: StageLogGetCurrent(stageLog, &stage);
1089: while (stage >= 0) {
1090: StageLogPop(stageLog);
1091: StageLogGetCurrent(stageLog, &stage);
1092: }
1093: /* Get the total elapsed time */
1094: PetscTime(locTotalTime); locTotalTime -= BaseTime;
1095: /* Open the summary file */
1096: if (filename != PETSC_NULL) {
1097: PetscFOpen(comm, filename, "w", &fd);
1098: }
1100: PetscFPrintf(comm, fd, "************************************************************************************************************************n");
1101: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***n");
1102: PetscFPrintf(comm, fd, "************************************************************************************************************************n");
1103: PetscFPrintf(comm, fd, "n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------nn");
1104: PetscGetArchType(arch, 10);
1105: PetscGetHostName(hostname, 64);
1106: PetscGetUserName(username, 16);
1107: PetscGetProgramName(pname, 256);
1108: PetscGetDate(date, 64);
1109: PetscGetVersion(&version);
1110: if (numProcs == 1) {
1111: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %sn", pname, arch, hostname, numProcs, username, date);
1112:
1113: } else {
1114: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %sn", pname, arch, hostname, numProcs, username, date);
1115:
1116: }
1117: PetscFPrintf(comm, fd, "Using %sn", version);
1119: /* Must preserve reduction count before we go on */
1120: red = allreduce_ct/((PetscLogDouble) numProcs);
1122: /* Calculate summary information */
1123: PetscFPrintf(comm, fd, "n Max Max/Min Avg Total n");
1124: /* Time */
1125: MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1126: MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1127: MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1128: avg = (tot)/((PetscLogDouble) numProcs);
1129: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1130: PetscFPrintf(comm, fd, "Time (sec): %5.3e %10.5f %5.3en", max, ratio, avg);
1131: TotalTime = tot;
1132: /* Objects */
1133: avg = (PetscLogDouble) numObjects;
1134: MPI_Allreduce(&avg, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1135: MPI_Allreduce(&avg, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1136: MPI_Allreduce(&avg, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1137: avg = (tot)/((PetscLogDouble) numProcs);
1138: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1139: PetscFPrintf(comm, fd, "Objects: %5.3e %10.5f %5.3en", max, ratio, avg);
1140: /* Flops */
1141: MPI_Allreduce(&_TotalFlops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1142: MPI_Allreduce(&_TotalFlops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1143: MPI_Allreduce(&_TotalFlops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1144: avg = (tot)/((PetscLogDouble) numProcs);
1145: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1146: PetscFPrintf(comm, fd, "Flops: %5.3e %10.5f %5.3e %5.3en", max, ratio, avg, tot);
1147: TotalFlops = tot;
1148: /* Flops/sec -- Must talk to Barry here */
1149: if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1150: MPI_Allreduce(&flops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1151: MPI_Allreduce(&flops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1152: MPI_Allreduce(&flops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1153: avg = (tot)/((PetscLogDouble) numProcs);
1154: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1155: PetscFPrintf(comm, fd, "Flops/sec: %5.3e %10.5f %5.3e %5.3en", max, ratio, avg, tot);
1156: /* Memory */
1157: PetscTrSpace(PETSC_NULL, PETSC_NULL, &mem);
1158: if (mem > 0.0) {
1159: MPI_Allreduce(&mem, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1160: MPI_Allreduce(&mem, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1161: MPI_Allreduce(&mem, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1162: avg = (tot)/((PetscLogDouble) numProcs);
1163: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1164: PetscFPrintf(comm, fd, "Memory: %5.3e %10.5f %5.3en", max, ratio, tot);
1165: }
1166: /* Messages */
1167: mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1168: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1169: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1170: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1171: avg = (tot)/((PetscLogDouble) numProcs);
1172: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1173: PetscFPrintf(comm, fd, "MPI Messages: %5.3e %10.5f %5.3e %5.3en", max, ratio, avg, tot);
1174: numMessages = tot;
1175: /* Message Lengths */
1176: mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1177: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1178: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1179: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1180: if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1181: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1182: PetscFPrintf(comm, fd, "MPI Message Lengths: %5.3e %10.5f %5.3e %5.3en", max, ratio, avg, tot);
1183: messageLength = tot;
1184: /* Reductions */
1185: MPI_Allreduce(&red, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1186: MPI_Allreduce(&red, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1187: MPI_Allreduce(&red, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1188: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1189: PetscFPrintf(comm, fd, "MPI Reductions: %5.3e %10.5fn", max, ratio);
1190: numReductions = tot;
1191: PetscFPrintf(comm, fd, "nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)n");
1192: PetscFPrintf(comm, fd, " e.g., VecAXPY() for real vectors of length N --> 2N flopsn");
1193: PetscFPrintf(comm, fd, " and VecAXPY() for complex vectors of length N --> 8N flopsn");
1195: /* Get total number of stages --
1196: Currently, a single processor can register more stages than another, but stages must all be registered in order.
1197: We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1198: This seems best accomplished by assoicating a communicator with each stage.
1199: */
1200: MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1201: PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1202: PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1203: PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1204: PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1205: if (numStages > 0) {
1206: stageInfo = stageLog->stageInfo;
1207: for(stage = 0; stage < numStages; stage++) {
1208: if (stage < stageLog->numStages) {
1209: localStageUsed[stage] = stageInfo[stage].used;
1210: localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1211: } else {
1212: localStageUsed[stage] = PETSC_FALSE;
1213: localStageVisible[stage] = PETSC_TRUE;
1214: }
1215: }
1216: MPI_Allreduce(localStageUsed, stageUsed, numStages, MPI_INT, MPI_LOR, comm);
1217: MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1218: for(stage = 0; stage < numStages; stage++) {
1219: if (stageUsed[stage] == PETSC_TRUE) {
1220: PetscFPrintf(comm, fd, "nSummary of Stages: ----- Time ------ ----- Flops ----- --- Messages --- -- Message Lengths -- -- Reductions --n");
1221: PetscFPrintf(comm, fd, " Avg %%Total Avg %%Total counts %%Total Avg %%Total counts %%Total n");
1222: break;
1223: }
1224: }
1225: for(stage = 0; stage < numStages; stage++) {
1226: if (stageUsed[stage] == PETSC_FALSE) continue;
1227: if (localStageUsed[stage] == PETSC_TRUE) {
1228: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1229: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1230: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1231: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1232: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1233: name = stageInfo[stage].name;
1234: } else {
1235: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1236: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1237: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1238: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1239: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1240: name = "";
1241: }
1242: mess *= 0.5; messLen *= 0.5; red /= numProcs;
1243: if (TotalTime != 0.0) fracTime = stageTime/TotalTime; else fracTime = 0.0;
1244: if (TotalFlops != 0.0) fracFlops = flops/TotalFlops; else fracFlops = 0.0;
1245: /* Talk to Barry if (stageTime != 0.0) flops = (numProcs*flops)/stageTime; else flops = 0.0; */
1246: if (numMessages != 0.0) fracMessages = mess/numMessages; else fracMessages = 0.0;
1247: if (numMessages != 0.0) avgMessLen = messLen/numMessages; else avgMessLen = 0.0;
1248: if (messageLength != 0.0) fracLength = messLen/messageLength; else fracLength = 0.0;
1249: if (numReductions != 0.0) fracReductions = red/numReductions; else fracReductions = 0.0;
1250: 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",
1251: stage, name, stageTime/numProcs, 100.0*fracTime, flops, 100.0*fracFlops,
1252: mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1253:
1254: }
1255: }
1257: PetscFPrintf(comm, fd,
1258: "n------------------------------------------------------------------------------------------------------------------------n");
1259:
1260: PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.n");
1261: PetscFPrintf(comm, fd, "Phase summary info:n");
1262: PetscFPrintf(comm, fd, " Count: number of times phase was executedn");
1263: PetscFPrintf(comm, fd, " Time and Flops/sec: Max - maximum over all processorsn");
1264: PetscFPrintf(comm, fd, " Ratio - ratio of maximum to minimum over all processorsn");
1265: PetscFPrintf(comm, fd, " Mess: number of messages sentn");
1266: PetscFPrintf(comm, fd, " Avg. len: average message lengthn");
1267: PetscFPrintf(comm, fd, " Reduct: number of global reductionsn");
1268: PetscFPrintf(comm, fd, " Global: entire computationn");
1269: PetscFPrintf(comm, fd, " Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().n");
1270: PetscFPrintf(comm, fd, " %%T - percent time in this phase %%F - percent flops in this phasen");
1271: PetscFPrintf(comm, fd, " %%M - percent messages in this phase %%L - percent message lengths in this phasen");
1272: PetscFPrintf(comm, fd, " %%R - percent reductions in this phasen");
1273: PetscFPrintf(comm, fd, " Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)n");
1274: PetscFPrintf(comm, fd,
1275: "------------------------------------------------------------------------------------------------------------------------n");
1276:
1278: #if defined(PETSC_USE_BOPT_g)
1279: PetscFPrintf(comm, fd, "nn");
1280: PetscFPrintf(comm, fd, " ##########################################################n");
1281: PetscFPrintf(comm, fd, " # #n");
1282: PetscFPrintf(comm, fd, " # WARNING!!! #n");
1283: PetscFPrintf(comm, fd, " # #n");
1284: PetscFPrintf(comm, fd, " # This code was compiled with a debugging option, #n");
1285: PetscFPrintf(comm, fd, " # BOPT=<g,g_c++,g_complex>. To get timing results #n");
1286: PetscFPrintf(comm, fd, " # ALWAYS compile your code with an optimized version, #n");
1287: PetscFPrintf(comm, fd, " # BOPT=<O,O_c++,O_complex>; the performance will #n");
1288: PetscFPrintf(comm, fd, " # be generally two or three times faster. #n");
1289: PetscFPrintf(comm, fd, " # #n");
1290: PetscFPrintf(comm, fd, " ##########################################################nnn");
1291: #endif
1292: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1293: PetscFPrintf(comm, fd, "nn");
1294: PetscFPrintf(comm, fd, " ##########################################################n");
1295: PetscFPrintf(comm, fd, " # #n");
1296: PetscFPrintf(comm, fd, " # WARNING!!! #n");
1297: PetscFPrintf(comm, fd, " # #n");
1298: PetscFPrintf(comm, fd, " # The code for various complex numbers numerical #n");
1299: PetscFPrintf(comm, fd, " # kernels uses C++, which generally is not well #n");
1300: PetscFPrintf(comm, fd, " # optimized. For performance that is about 4-5 times #n");
1301: PetscFPrintf(comm, fd, " # faster, specify the flag -DPETSC_USE_FORTRAN_KERNELS #n");
1302: PetscFPrintf(comm, fd, " # in base_variables and recompile the PETSc libraries. #n");
1303: PetscFPrintf(comm, fd, " # #n");
1304: PetscFPrintf(comm, fd, " ##########################################################nnn");
1305: #endif
1307: if (!PetscPreLoadingUsed) {
1308: PetscFPrintf(comm,fd,"nn");
1309: PetscFPrintf(comm,fd," ##########################################################n");
1310: PetscFPrintf(comm,fd," # #n");
1311: PetscFPrintf(comm,fd," # WARNING!!! #n");
1312: PetscFPrintf(comm,fd," # #n");
1313: PetscFPrintf(comm,fd," # This code was run without the PreLoadinBegin() #n");
1314: PetscFPrintf(comm,fd," # macros. To get timing results we always recommend #n");
1315: PetscFPrintf(comm,fd," # preloading. otherwise timing numbers may be #n");
1316: PetscFPrintf(comm,fd," # meaningless. #n");
1317: PetscFPrintf(comm,fd," ##########################################################nnn");
1318: }
1320: /* Report events */
1321: PetscFPrintf(comm, fd,
1322: "Event Count Time (sec) Flops/sec --- Global --- --- Stage --- Totaln");
1323:
1324: PetscFPrintf(comm, fd,
1325: " Max Ratio Max Ratio Max Ratio Mess Avg len Reduct %%T %%F %%M %%L %%R %%T %%F %%M %%L %%R Mflop/sn");
1326:
1327: PetscFPrintf(comm,fd,
1328: "------------------------------------------------------------------------------------------------------------------------n");
1330:
1331: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1332: for(stage = 0; stage < numStages; stage++) {
1333: if (stageVisible[stage] == PETSC_FALSE) continue;
1334: if (localStageUsed[stage] == PETSC_TRUE) {
1335: PetscFPrintf(comm, fd, "n--- Event Stage %d: %snn", stage, stageInfo[stage].name);
1336: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1337: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1338: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1339: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1340: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1341: } else {
1342: PetscFPrintf(comm, fd, "n--- Event Stage %d: Unknownnn", stage);
1343: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1344: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1345: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1346: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1347: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1348: }
1349: mess *= 0.5; messLen *= 0.5; red /= numProcs;
1351: /* Get total number of events in this stage --
1352: Currently, a single processor can register more events than another, but events must all be registered in order,
1353: just like stages. We can removed this requirement if necessary by having a global event numbering and indirection
1354: on the event ID. This seems best accomplished by assoicating a communicator with each stage.
1356: Problem: If the event did not happen on proc 1, its name will not be available.
1357: Problem: Event visibility is not implemented
1358: */
1359: if (localStageUsed[stage] == PETSC_TRUE) {
1360: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1361: localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1362: } else {
1363: localNumEvents = 0;
1364: }
1365: MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1366: for(event = 0; event < numEvents; event++) {
1367: if ((localStageUsed[stage] == PETSC_TRUE) && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1368: if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1369: flopr = eventInfo[event].flops/eventInfo[event].time;
1370: } else {
1371: flopr = 0.0;
1372: }
1373: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1374: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1375: MPI_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1376: MPI_Allreduce(&eventInfo[event].time, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1377: MPI_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1378: MPI_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1379: MPI_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1380: MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1381: MPI_Allreduce(&eventInfo[event].numReductions, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1382: MPI_Allreduce(&eventInfo[event].count, &minCt, 1, MPI_INT, MPI_MIN, comm);
1383: MPI_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1384: name = stageLog->eventLog->eventInfo[event].name;
1385: } else {
1386: flopr = 0.0;
1387: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1388: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1389: MPI_Allreduce(&zero, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1390: MPI_Allreduce(&zero, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1391: MPI_Allreduce(&zero, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1392: MPI_Allreduce(&zero, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1393: MPI_Allreduce(&zero, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1394: MPI_Allreduce(&zero, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1395: MPI_Allreduce(&zero, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1396: MPI_Allreduce(&ierr, &minCt, 1, MPI_INT, MPI_MIN, comm);
1397: MPI_Allreduce(&ierr, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1398: name = "";
1399: }
1400: totm *= 0.5; totml *= 0.5; totr /= numProcs;
1401:
1402: if (maxCt != 0) {
1403: if (minCt != 0) ratCt = ((PetscLogDouble) maxCt)/minCt; else ratCt = 0.0;
1404: if (mint != 0.0) ratt = maxt/mint; else ratt = 0.0;
1405: if (minf != 0.0) ratf = maxf/minf; else ratf = 0.0;
1406: if (TotalTime != 0.0) fracTime = tott/TotalTime; else fracTime = 0.0;
1407: if (TotalFlops != 0.0) fracFlops = totf/TotalFlops; else fracFlops = 0.0;
1408: if (stageTime != 0.0) fracStageTime = tott/stageTime; else fracStageTime = 0.0;
1409: if (flops != 0.0) fracStageFlops = totf/flops; else fracStageFlops = 0.0;
1410: if (numMessages != 0.0) fracMess = totm/numMessages; else fracMess = 0.0;
1411: if (messageLength != 0.0) fracMessLen = totml/messageLength; else fracMessLen = 0.0;
1412: if (numReductions != 0.0) fracRed = totr/numReductions; else fracRed = 0.0;
1413: if (mess != 0.0) fracStageMess = totm/mess; else fracStageMess = 0.0;
1414: if (messLen != 0.0) fracStageMessLen = totml/messLen; else fracStageMessLen = 0.0;
1415: if (red != 0.0) fracStageRed = totr/red; else fracStageRed = 0.0;
1416: if (totm != 0.0) totml /= totm; else totml = 0.0;
1417: if (maxt != 0.0) flopr = totf/maxt; else flopr = 0.0;
1418: PetscFPrintf(comm, fd,
1419: "%-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.0fn",
1420: name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1421: 100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1422: 100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1423: flopr/1.0e6);
1424:
1425: }
1426: }
1427: }
1429: /* Memory usage and object creation */
1430: PetscFPrintf(comm, fd,
1431: "------------------------------------------------------------------------------------------------------------------------n");
1432:
1433: PetscFPrintf(comm, fd, "n");
1434: PetscFPrintf(comm, fd, "Memory usage is given in bytes:nn");
1436: /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1437: the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1438: stats for stages local to processor sets.
1439: */
1440: /* We should figure out the longest object name here (now 20 characters) */
1441: PetscFPrintf(comm, fd, "Object Type Creations Destructions Memory Descendants' Mem.n");
1442: for(stage = 0; stage < numStages; stage++) {
1443: if (localStageUsed[stage] == PETSC_TRUE) {
1444: classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1445: PetscFPrintf(comm, fd, "n--- Event Stage %d: %snn", stage, stageInfo[stage].name);
1446: for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1447: if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1448: PetscFPrintf(comm, fd, "%20s %5d %5d %9d %gn", stageLog->classLog->classInfo[oclass].name,
1449: classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1450: classInfo[oclass].descMem);
1451:
1452: }
1453: }
1454: } else {
1455: PetscFPrintf(comm, fd, "n--- Event Stage %d: Unknownnn", stage);
1456: }
1457: }
1459: PetscFree(localStageUsed);
1460: PetscFree(stageUsed);
1461: PetscFree(localStageVisible);
1462: PetscFree(stageVisible);
1464: /* Information unrelated to this particular run */
1465: PetscFPrintf(comm, fd,
1466: "========================================================================================================================n");
1467:
1468: PetscTime(y);
1469: PetscTime(x);
1470: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1471: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1472: PetscFPrintf(comm,fd,"Average time to get PetscTime(): %gn", (y-x)/10.0);
1473: /* MPI information */
1474: if (numProcs > 1) {
1475: MPI_Status status;
1476: int tag;
1478: MPI_Barrier(comm);
1479: PetscTime(x);
1480: MPI_Barrier(comm);
1481: MPI_Barrier(comm);
1482: MPI_Barrier(comm);
1483: MPI_Barrier(comm);
1484: MPI_Barrier(comm);
1485: PetscTime(y);
1486: PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %gn", (y-x)/5.0);
1487: PetscCommGetNewTag(comm, &tag);
1488: MPI_Barrier(comm);
1489: if (rank) {
1490: MPI_Recv(0, 0, MPI_INT, rank-1, tag, comm, &status);
1491: MPI_Send(0, 0, MPI_INT, (rank+1)%numProcs, tag, comm);
1492: } else {
1493: PetscTime(x);
1494: MPI_Send(0, 0, MPI_INT, 1, tag, comm);
1495: MPI_Recv(0, 0, MPI_INT, numProcs-1, tag, comm, &status);
1496: PetscTime(y);
1497: PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %gn", (y-x)/numProcs);
1498: }
1499: }
1500: /* Machine and compile information */
1501: #if defined(PETSC_USE_FORTRAN_KERNELS)
1502: PetscFPrintf(comm, fd, "Compiled with FORTRAN kernelsn");
1503: #else
1504: PetscFPrintf(comm, fd, "Compiled without FORTRAN kernelsn");
1505: #endif
1506: #if defined(PETSC_USE_MAT_SINGLE)
1507: PetscFPrintf(comm, fd, "Compiled with single precision matricesn");
1508: #else
1509: PetscFPrintf(comm, fd, "Compiled with double precision matrices (default)n");
1510: #endif
1511: PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void *) %d",
1512: (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*));
1513:
1515: PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1516: PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1517: PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1518: PetscFPrintf(comm, fd, "%s", petsclinkerinfo);
1520: /* Cleanup */
1521: PetscFPrintf(comm, fd, "n");
1522: PetscFClose(comm, fd);
1523: return(0);
1524: }
1526: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1527: /*@C
1528: PetscGetFlops - Returns the number of flops used on this processor
1529: since the program began.
1531: Not Collective
1533: Output Parameter:
1534: flops - number of floating point operations
1536: Notes:
1537: A global counter logs all PETSc flop counts. The user can use
1538: PetscLogFlops() to increment this counter to include flops for the
1539: application code.
1541: PETSc automatically logs library events if the code has been
1542: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1543: -log_summary, or -log_all are specified. PetscLogFlops() is
1544: intended for logging user flops to supplement this PETSc
1545: information.
1547: Level: intermediate
1549: .keywords: log, flops, floating point operations
1551: .seealso: PetscGetTime(), PetscLogFlops()
1552: @*/
1553: int PetscGetFlops(PetscLogDouble *flops)
1554: {
1556: *flops = _TotalFlops;
1557: return(0);
1558: }
1560: int PetscLogObjectState(PetscObject obj, const char format[], ...)
1561: {
1562: va_list Argp;
1565: if (logObjects == PETSC_FALSE) return(0);
1566: va_start(Argp, format);
1567: #if defined(PETSC_HAVE_VPRINTF_CHAR)
1568: vsprintf(objects[obj->id].info, format, (char *) Argp);
1569: #else
1570: vsprintf(objects[obj->id].info, format, Argp);
1571: #endif
1572: va_end(Argp);
1573: return(0);
1574: }
1576: #else /* end of -DPETSC_USE_LOG section */
1578: int PetscLogObjectState(PetscObject obj, const char format[], ...)
1579: {
1581: return(0);
1582: }
1584: #endif /* PETSC_USE_LOG*/
1586: /*@
1587: PetscGetTime - Returns the current time of day in seconds. This
1588: returns wall-clock time.
1590: Not Collective
1592: Output Parameter:
1593: . v - time counter
1595: Usage:
1596: .vb
1597: PetscLogDouble v1,v2,elapsed_time;
1598: PetscGetTime(&v1);CHKERR(ierr);
1599: .... perform some calculation ...
1600: PetscGetTime(&v2);CHKERR(ierr);
1601: elapsed_time = v2 - v1;
1602: .ve
1604: Notes:
1605: Since the PETSc libraries incorporate timing of phases and operations,
1606: PetscGetTime() is intended only for timing of application codes.
1607: The options database commands -log, -log_summary, and -log_all activate
1608: PETSc library timing. See the users manual for further details.
1610: Level: intermediate
1612: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStagePush(),
1613: PetscLogStagePop(), PetscLogStageRegister(), PetscGetFlops()
1615: .keywords: get, time
1616: @*/
1617: int PetscGetTime(PetscLogDouble *t)
1618: {
1620: PetscTime(*t);
1621: return(0);
1622: }
1624: /*@
1625: PetscLogGetStageLog - This function returns the default stage logging object.
1627: Not collective
1629: Output Parameter:
1630: . stageLog - The default StageLog
1632: Level: beginner
1634: .keywords: log, stage
1635: .seealso: StageLogCreate()
1636: @*/
1637: int PetscLogGetStageLog(StageLog *stageLog)
1638: {
1641: *stageLog = _stageLog;
1642: return(0);
1643: }
1645: /*MC
1646: PetscLogFlops - Adds floating point operations to the global counter.
1648: Input Parameter:
1649: . f - flop counter
1651: Synopsis:
1652: void PetscLogFlops(int f)
1654: Usage:
1655: .vb
1656: int USER_EVENT;
1657: PetscLogEventRegister(&USER_EVENT,"User event");
1658: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1659: [code segment to monitor]
1660: PetscLogFlops(user_flops)
1661: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1662: .ve
1664: Notes:
1665: A global counter logs all PETSc flop counts. The user can use
1666: PetscLogFlops() to increment this counter to include flops for the
1667: application code.
1669: PETSc automatically logs library events if the code has been
1670: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1671: -log_summary, or -log_all are specified. PetscLogFlops() is
1672: intended for logging user flops to supplement this PETSc
1673: information.
1675: Level: intermediate
1677: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()
1679: .keywords: log, flops, floating point operations
1680: M*/
1682: PetscTruth PetscPreLoadingUsed = PETSC_FALSE;
1683: PetscTruth PetscPreLoadingOn = PETSC_FALSE;
1685: /*MC
1686: PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1687: to get accurate timings
1689: Input Parameter:
1690: + flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1691: with command line option -preload true or -preload false
1692: - name - name of first stage (lines of code timed seperately with -log_summary) to
1693: be preloaded
1695: Synopsis:
1696: void PreLoadBegin(PetscTruth flag,char *name);
1698: Usage:
1699: .vb
1700: PreLoadBegin(PETSC_TRUE,"first stage);
1701: lines of code
1702: PreLoadStage("second stage");
1703: lines of code
1704: PreLoadEnd();
1705: .ve
1707: Level: intermediate
1709: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadEnd(), PreLoadStage()
1711: Concepts: preloading
1712: Concepts: timing^accurate
1713: Concepts: paging^eliminating effects of
1716: M*/
1718: /*MC
1719: PreLoadEnd - End a segment of code that may be preloaded (run twice)
1720: to get accurate timings
1722: Synopsis:
1723: void PreLoadEnd(void);
1725: Usage:
1726: .vb
1727: PreLoadBegin(PETSC_TRUE,"first stage);
1728: lines of code
1729: PreLoadStage("second stage");
1730: lines of code
1731: PreLoadEnd();
1732: .ve
1734: Level: intermediate
1736: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadStage()
1738: M*/
1740: /*MC
1741: PreLoadStage - Start a new segment of code to be timed seperately.
1742: to get accurate timings
1744: Synopsis:
1745: void PreLoadStage(char *name);
1747: Usage:
1748: .vb
1749: PreLoadBegin(PETSC_TRUE,"first stage);
1750: lines of code
1751: PreLoadStage("second stage");
1752: lines of code
1753: PreLoadEnd();
1754: .ve
1756: Level: intermediate
1758: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd()
1760: M*/
1762: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1763: /*@C
1764: StackDestroy - This function destroys a stack.
1766: Not Collective
1768: Input Parameter:
1769: . stack - The stack
1771: Level: beginner
1773: .keywords: log, stack, destroy
1774: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
1775: @*/
1776: int StackDestroy(IntStack stack)
1777: {
1781: PetscFree(stack->stack);
1782: PetscFree(stack);
1783: return(0);
1784: }
1786: /*@C
1787: StackEmpty - This function determines whether any items have been pushed.
1789: Not Collective
1791: Input Parameter:
1792: . stack - The stack
1794: Output Parameter:
1795: . empty - PETSC_TRUE if the stack is empty
1797: Level: intermediate
1799: .keywords: log, stack, empty
1800: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
1801: @*/
1802: int StackEmpty(IntStack stack, PetscTruth *empty)
1803: {
1806: if (stack->top == -1) {
1807: *empty = PETSC_TRUE;
1808: } else {
1809: *empty = PETSC_FALSE;
1810: }
1811: return(0);
1812: }
1814: /*@C
1815: StackTop - This function returns the top of the stack.
1817: Not Collective
1819: Input Parameter:
1820: . stack - The stack
1822: Output Parameter:
1823: . top - The integer on top of the stack
1825: Level: intermediate
1827: .keywords: log, stack, top
1828: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
1829: @*/
1830: int StackTop(IntStack stack, int *top)
1831: {
1834: *top = stack->stack[stack->top];
1835: return(0);
1836: }
1838: /*@C
1839: StackPush - This function pushes an integer on the stack.
1841: Not Collective
1843: Input Parameters:
1844: + stack - The stack
1845: - item - The integer to push
1847: Level: intermediate
1849: .keywords: log, stack, push
1850: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
1851: @*/
1852: int StackPush(IntStack stack, int item)
1853: {
1854: int *array;
1855: int ierr;
1858: stack->top++;
1859: if (stack->top >= stack->max) {
1860: PetscMalloc(stack->max*2 * sizeof(int), &array);
1861: PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
1862: PetscFree(stack->stack);
1863: stack->stack = array;
1864: stack->max *= 2;
1865: }
1866: stack->stack[stack->top] = item;
1867: return(0);
1868: }
1870: /*@C
1871: StackPop - This function pops an integer from the stack.
1873: Not Collective
1875: Input Parameter:
1876: . stack - The stack
1878: Output Parameter:
1879: . item - The integer popped
1881: Level: intermediate
1883: .keywords: log, stack, pop
1884: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
1885: @*/
1886: int StackPop(IntStack stack, int *item)
1887: {
1890: if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
1891: *item = stack->stack[stack->top--];
1892: return(0);
1893: }
1895: /*@C
1896: StackCreate - This function creates a stack.
1898: Not Collective
1900: Output Parameter:
1901: . stack - The stack
1903: Level: beginner
1905: .keywords: log, stack, pop
1906: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
1907: @*/
1908: int StackCreate(IntStack *stack)
1909: {
1910: IntStack s;
1911: int ierr;
1915: PetscNew(struct _IntStack, &s);
1916: s->top = -1;
1917: s->max = 128;
1918: PetscMalloc(s->max * sizeof(int), &s->stack);
1919: PetscMemzero(s->stack, s->max * sizeof(int));
1920: *stack = s;
1921: return(0);
1922: }