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: int numActions = 0, maxActions = 100;
35: int numObjects = 0, maxObjects = 100;
36: int numObjectsDestroyed = 0;
38: /* Global counters */
39: PetscLogDouble BaseTime;
40: PetscLogDouble _TotalFlops = 0.0; /* The number of flops */
41: PetscLogDouble send_ct = 0.0; /* The number of sends */
42: PetscLogDouble recv_ct = 0.0; /* The number of receives */
43: PetscLogDouble send_len = 0.0; /* The total length of all sent messages */
44: PetscLogDouble recv_len = 0.0; /* The total length of all received messages */
45: PetscLogDouble isend_ct = 0.0; /* The number of immediate sends */
46: PetscLogDouble irecv_ct = 0.0; /* The number of immediate receives */
47: PetscLogDouble isend_len = 0.0; /* The total length of all immediate send messages */
48: PetscLogDouble irecv_len = 0.0; /* The total length of all immediate receive messages */
49: PetscLogDouble wait_ct = 0.0; /* The number of waits */
50: PetscLogDouble wait_any_ct = 0.0; /* The number of anywaits */
51: PetscLogDouble wait_all_ct = 0.0; /* The number of waitalls */
52: PetscLogDouble sum_of_waits_ct = 0.0; /* The total number of waits */
53: PetscLogDouble allreduce_ct = 0.0; /* The number of reductions */
55: /* Logging functions */
56: int (*_PetscLogPHC)(PetscObject) = PETSC_NULL;
57: int (*_PetscLogPHD)(PetscObject) = PETSC_NULL;
58: int (*_PetscLogPLB)(int, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
59: int (*_PetscLogPLE)(int, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
61: /* Tracing event logging variables */
62: FILE *tracefile = PETSC_NULL;
63: int tracelevel = 0;
64: char *traceblanks = " ";
65: char tracespace[128];
66: PetscLogDouble tracetime = 0.0;
68: /*---------------------------------------------- General Functions --------------------------------------------------*/
69: /*@C
70: PetscLogDestroy - Destroys the object and event logging data and resets the global counters.
72: Not Collective
74: Notes:
75: This routine should not usually be used by programmers. Instead employ
76: PetscLogStagePush() and PetscLogStagePop().
78: Level: developer
80: .keywords: log, destroy
81: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogStagePush(), PlogStagePop()
82: @*/
83: int PetscLogDestroy(void) {
84: StageLog stageLog;
85: int ierr;
88: if (actions != PETSC_NULL) {
89: PetscFree(actions);
90: actions = PETSC_NULL;
91: }
92: if (objects != PETSC_NULL) {
93: PetscFree(objects);
94: objects = PETSC_NULL;
95: }
96: PetscLogSet(PETSC_NULL, PETSC_NULL);
98: /* Resetting phase */
99: PetscLogGetStageLog(&stageLog);
100: StageLogDestroy(stageLog);
101: _TotalFlops = 0.0;
102: numActions = 0;
103: numObjects = 0;
104: numObjectsDestroyed = 0;
105: return(0);
106: }
108: /*@C
109: PetscLogSet - Sets the logging functions called at the beginning and ending of every event.
111: Not Collective
113: Input Parameters:
114: + b - The function called at beginning of event
115: - e - The function called at end of event
117: Level: developer
119: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
120: @*/
121: int PetscLogSet(int (*b)(int, int, PetscObject, PetscObject, PetscObject, PetscObject),
122: int (*e)(int, int, PetscObject, PetscObject, PetscObject, PetscObject))
123: {
125: _PetscLogPLB = b;
126: _PetscLogPLE = e;
127: return(0);
128: }
130: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
131: int PetscLogBegin_Private(void) {
132: static int initialized = 0;
133: int stage;
134: PetscTruth opt;
135: int ierr;
138: if (initialized) return(0);
139: initialized = 1;
140: PetscOptionsHasName(PETSC_NULL, "-log_exclude_actions", &opt);
141: if (opt == PETSC_FALSE) {
142: PetscMalloc(maxActions * sizeof(Action), &actions);
143: }
144: PetscOptionsHasName(PETSC_NULL, "-log_exclude_objects", &opt);
145: if (opt == PETSC_FALSE) {
146: PetscMalloc(maxObjects * sizeof(Object), &objects);
147: }
148: _PetscLogPHC = PetscLogObjCreateDefault;
149: _PetscLogPHD = PetscLogObjDestroyDefault;
150: /* Setup default logging structures */
151: StageLogCreate(&_stageLog);
152: StageLogRegister(_stageLog, "Main Stage", &stage);
153: /* All processors sync here for more consistent logging */
154: MPI_Barrier(PETSC_COMM_WORLD);
155: PetscTime(BaseTime);
156: PetscLogStagePush(stage);
157: return(0);
158: }
160: /*@C
161: PetscLogBegin - Turns on logging of objects and events. This logs flop
162: rates and object creation and should not slow programs down too much.
163: This routine may be called more than once.
165: Collective over PETSC_COMM_WORLD
167: Options Database Keys:
168: + -log_summary - Prints summary of flop and timing information to the
169: screen (for code compiled with PETSC_USE_LOG)
170: - -log - Prints detailed log information (for code compiled with PETSC_USE_LOG)
172: Usage:
173: .vb
174: PetscInitialize(...);
175: PetscLogBegin();
176: ... code ...
177: PetscLogPrintSummary(MPI_Comm,filename); or PetscLogDump();
178: PetscFinalize();
179: .ve
181: Notes:
182: PetscLogPrintSummary(MPI_Comm,filename) or PetscLogDump() actually cause the printing of
183: the logging information.
185: Level: advanced
187: .keywords: log, begin
188: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogTraceBegin()
189: @*/
190: int PetscLogBegin(void)
191: {
195: PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
196: PetscLogBegin_Private();
197: return(0);
198: }
200: /*@C
201: PetscLogAllBegin - Turns on extensive logging of objects and events. Logs
202: all events. This creates large log files and slows the program down.
204: Collective on PETSC_COMM_WORLD
206: Options Database Keys:
207: . -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
209: Usage:
210: .vb
211: PetscInitialize(...);
212: PetscLogAllBegin();
213: ... code ...
214: PetscLogDump(filename);
215: PetscFinalize();
216: .ve
218: Notes:
219: A related routine is PetscLogBegin (with the options key -log), which is
220: intended for production runs since it logs only flop rates and object
221: creation (and shouldn't significantly slow the programs).
223: Level: advanced
225: .keywords: log, all, begin
226: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogTraceBegin()
227: @*/
228: int PetscLogAllBegin(void)
229: {
233: PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
234: PetscLogBegin_Private();
235: return(0);
236: }
238: /*@
239: PetscLogTraceBegin - Activates trace logging. Every time a PETSc event
240: begins or ends, the event name is printed.
242: Collective on PETSC_COMM_WORLD
244: Input Parameter:
245: . file - The file to print trace in (e.g. stdout)
247: Options Database Key:
248: . -log_trace [filename] - Activates PetscLogTraceBegin()
250: Notes:
251: PetscLogTraceBegin() prints the processor number, the execution time (sec),
252: then "Event begin:" or "Event end:" followed by the event name.
254: PetscLogTraceBegin() allows tracing of all PETSc calls, which is useful
255: to determine where a program is hanging without running in the
256: debugger. Can be used in conjunction with the -log_info option.
258: Level: intermediate
260: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogBegin()
261: @*/
262: int PetscLogTraceBegin(FILE *file)
263: {
267: tracefile = file;
268: PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
269: PetscLogBegin_Private();
270: return(0);
271: }
273: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
274: /*@C
275: PetscLogStageRegister - Attaches a charactor string name to a logging stage.
277: Not Collective
279: Input Parameter:
280: . sname - The name to associate with that stage
282: Output Parameter:
283: . stage - The stage number
285: Level: intermediate
287: .keywords: log, stage, register
288: .seealso: PetscLogStagePush(), PetscLogStagePop()
289: @*/
290: int PetscLogStageRegister(int *stage, const char sname[]) {
291: StageLog stageLog;
292: int ierr;
295: PetscLogGetStageLog(&stageLog);
296: StageLogRegister(stageLog, sname, stage);
297: EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
298: ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
299: return(0);
300: }
302: /*@C
303: PetscLogStagePush - This function pushes a stage on the stack.
305: Not Collective
307: Input Parameter:
308: . stage - The stage on which to log
310: Usage:
311: If the option -log_sumary is used to run the program containing the
312: following code, then 2 sets of summary data will be printed during
313: PetscFinalize().
314: .vb
315: PetscInitialize(int *argc,char ***args,0,0);
316: [stage 0 of code]
317: PetscLogStagePush(1);
318: [stage 1 of code]
319: PetscLogStagePop();
320: PetscBarrier(...);
321: [more stage 0 of code]
322: PetscFinalize();
323: .ve
324:
325: Notes:
326: Use PetscLogStageRegister() to register a stage.
328: Level: intermediate
330: .keywords: log, push, stage
331: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
332: @*/
333: int PetscLogStagePush(int stage)
334: {
335: StageLog stageLog;
336: int ierr;
339: PetscLogGetStageLog(&stageLog);
340: StageLogPush(stageLog, stage);
341: return(0);
342: }
344: /*@C
345: PetscLogStagePop - This function pops a stage from the stack.
347: Not Collective
349: Usage:
350: If the option -log_sumary is used to run the program containing the
351: following code, then 2 sets of summary data will be printed during
352: PetscFinalize().
353: .vb
354: PetscInitialize(int *argc,char ***args,0,0);
355: [stage 0 of code]
356: PetscLogStagePush(1);
357: [stage 1 of code]
358: PetscLogStagePop();
359: PetscBarrier(...);
360: [more stage 0 of code]
361: PetscFinalize();
362: .ve
364: Notes:
365: Use PetscLogStageRegister() to register a stage.
367: Level: intermediate
369: .keywords: log, pop, stage
370: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
371: @*/
372: int PetscLogStagePop(void)
373: {
374: StageLog stageLog;
375: int ierr;
378: PetscLogGetStageLog(&stageLog);
379: StageLogPop(stageLog);
380: return(0);
381: }
383: /*@C
384: PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().
386: Not Collective
388: Input Parameters:
389: + stage - The stage
390: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
392: Level: intermediate
394: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
395: @*/
396: int PetscLogStageSetActive(int stage, PetscTruth isActive) {
397: StageLog stageLog;
398: int ierr;
401: PetscLogGetStageLog(&stageLog);
402: StageLogSetActive(stageLog, stage, isActive);
403: return(0);
404: }
406: /*@C
407: PetscLogStageGetActive - Returns stage activity for PetscLogEventBegin() and PetscLogEventEnd().
409: Not Collective
411: Input Parameter:
412: . stage - The stage
414: Output Parameter:
415: . isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
417: Level: intermediate
419: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
420: @*/
421: int PetscLogStageGetActive(int stage, PetscTruth *isActive) {
422: StageLog stageLog;
423: int ierr;
426: PetscLogGetStageLog(&stageLog);
427: StageLogGetActive(stageLog, stage, isActive);
428: return(0);
429: }
431: /*@C
432: PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()
434: Not Collective
436: Input Parameters:
437: + stage - The stage
438: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
440: Level: intermediate
442: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
443: @*/
444: int PetscLogStageSetVisible(int stage, PetscTruth isVisible)
445: {
446: StageLog stageLog;
447: int ierr;
450: PetscLogGetStageLog(&stageLog);
451: StageLogSetVisible(stageLog, stage, isVisible);
452: return(0);
453: }
455: /*@C
456: PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()
458: Not Collective
460: Input Parameter:
461: . stage - The stage
463: Output Parameter:
464: . isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
466: Level: intermediate
468: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
469: @*/
470: int PetscLogStageGetVisible(int stage, PetscTruth *isVisible)
471: {
472: StageLog stageLog;
473: int ierr;
476: PetscLogGetStageLog(&stageLog);
477: StageLogGetVisible(stageLog, stage, isVisible);
478: return(0);
479: }
481: /*@C
482: PetscLogStageGetId - Returns the stage id when given the stage name.
484: Not Collective
486: Input Parameter:
487: . name - The stage name
489: Output Parameter:
490: . stage - The stage
492: Level: intermediate
494: .seealso: PetscLogStagePush(), PetscLogStagePop(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
495: @*/
496: int PetscLogStageGetId(const char name[], int *stage)
497: {
498: StageLog stageLog;
499: int ierr;
502: PetscLogGetStageLog(&stageLog);
503: StageLogGetStage(stageLog, name, stage);
504: return(0);
505: }
507: /*------------------------------------------------ Event Functions --------------------------------------------------*/
508: /*@C
509: PetscLogEventRegister - Registers an event name for logging operations in an application code.
511: Not Collective
513: Input Parameter:
514: + name - The name associated with the event
515: - cookie - The cookie associated to the class for this event
516:
517: Output Parameter:
518: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().
520: Example of Usage:
521: .vb
522: int USER_EVENT;
523: int user_event_flops;
524: PetscLogEventRegister(&USER_EVENT,"User event name");
525: PetscLogEventBegin(USER_EVENT,0,0,0,0);
526: [code segment to monitor]
527: PetscLogFlops(user_event_flops);
528: PetscLogEventEnd(USER_EVENT,0,0,0,0);
529: .ve
531: Notes:
532: PETSc automatically logs library events if the code has been
533: compiled with -DPETSC_USE_LOG (which is the default) and -log,
534: -log_summary, or -log_all are specified. PetscLogEventRegister() is
535: intended for logging user events to supplement this PETSc
536: information.
538: PETSc can gather data for use with the utilities Upshot/Nupshot
539: (part of the MPICH distribution). If PETSc has been compiled
540: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
541: MPICH), the user can employ another command line option, -log_mpe,
542: to create a logfile, "mpe.log", which can be visualized
543: Upshot/Nupshot.
545: Level: intermediate
547: .keywords: log, event, register
548: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
549: PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
550: PetscLogEventActivate(), PetscLogEventDeactivate()
551: @*/
552: int PetscLogEventRegister(int *event, const char name[],int cookie) {
553: StageLog stageLog;
554: int stage;
555: int ierr;
558: *event = PETSC_DECIDE;
559: PetscLogGetStageLog(&stageLog);
560: EventRegLogRegister(stageLog->eventLog, name, cookie, event);
561: for(stage = 0; stage < stageLog->numStages; stage++) {
562: EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
563: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
564: }
565: return(0);
566: }
568: /*@
569: PetscLogEventActivate - Indicates that a particular event should be logged.
571: Not Collective
573: Input Parameter:
574: . event - The event id
576: Usage:
577: .vb
578: PetscLogEventDeactivate(VEC_SetValues);
579: [code where you do not want to log VecSetValues()]
580: PetscLogEventActivate(VEC_SetValues);
581: [code where you do want to log VecSetValues()]
582: .ve
584: Note:
585: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
586: or an event number obtained with PetscLogEventRegister().
588: Level: advanced
590: .keywords: log, event, activate
591: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
592: @*/
593: int PetscLogEventActivate(int event) {
594: StageLog stageLog;
595: int stage;
596: int ierr;
599: PetscLogGetStageLog(&stageLog);
600: StageLogGetCurrent(stageLog, &stage);
601: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
602: return(0);
603: }
605: /*@
606: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
608: Not Collective
610: Input Parameter:
611: . event - The event id
613: Usage:
614: .vb
615: PetscLogEventDeactivate(VEC_SetValues);
616: [code where you do not want to log VecSetValues()]
617: PetscLogEventActivate(VEC_SetValues);
618: [code where you do want to log VecSetValues()]
619: .ve
621: Note:
622: The event may be either a pre-defined PETSc event (found in
623: include/petsclog.h) or an event number obtained with PetscLogEventRegister()).
625: Level: advanced
627: .keywords: log, event, deactivate
628: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
629: @*/
630: int PetscLogEventDeactivate(int event) {
631: StageLog stageLog;
632: int stage;
633: int ierr;
636: PetscLogGetStageLog(&stageLog);
637: StageLogGetCurrent(stageLog, &stage);
638: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
639: return(0);
640: }
642: /*@
643: PetscLogEventActivateClass - Activates event logging for a PETSc object class.
645: Not Collective
647: Input Parameter:
648: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
650: Level: developer
652: .keywords: log, event, activate, class
653: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
654: @*/
655: int PetscLogEventActivateClass(int cookie) {
656: StageLog stageLog;
657: int stage;
658: int ierr;
661: PetscLogGetStageLog(&stageLog);
662: StageLogGetCurrent(stageLog, &stage);
663: EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
664: return(0);
665: }
667: /*@
668: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.
670: Not Collective
672: Input Parameter:
673: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
675: Level: developer
677: .keywords: log, event, deactivate, class
678: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
679: @*/
680: int PetscLogEventDeactivateClass(int cookie) {
681: StageLog stageLog;
682: int stage;
683: int ierr;
686: PetscLogGetStageLog(&stageLog);
687: StageLogGetCurrent(stageLog, &stage);
688: EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
689: return(0);
690: }
692: /*MC
693: PetscLogEventBegin - Logs the beginning of a user event.
695: Input Parameters:
696: + e - integer associated with the event obtained from PetscLogEventRegister()
697: - o1,o2,o3,o4 - objects associated with the event, or 0
699: Synopsis:
700: void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
701: PetscObject o4)
703: Usage:
704: .vb
705: int USER_EVENT;
706: int user_event_flops;
707: PetscLogEventRegister(&USER_EVENT,"User event");
708: PetscLogEventBegin(USER_EVENT,0,0,0,0);
709: [code segment to monitor]
710: PetscLogFlops(user_event_flops);
711: PetscLogEventEnd(USER_EVENT,0,0,0,0);
712: .ve
714: Notes:
715: You should also register each integer event with the command
716: PetscLogEventRegister(). The source code must be compiled with
717: -DPETSC_USE_LOG, which is the default.
719: PETSc automatically logs library events if the code has been
720: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
721: specified. PetscLogEventBegin() is intended for logging user events
722: to supplement this PETSc information.
724: Level: intermediate
726: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops()
728: .keywords: log, event, begin
729: M*/
731: /*MC
732: PetscLogEventEnd - Log the end of a user event.
734: Input Parameters:
735: + e - integer associated with the event obtained with PetscLogEventRegister()
736: - o1,o2,o3,o4 - objects associated with the event, or 0
738: Synopsis:
739: void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
740: PetscObject o4)
742: Usage:
743: .vb
744: int USER_EVENT;
745: int user_event_flops;
746: PetscLogEventRegister(&USER_EVENT,"User event");
747: PetscLogEventBegin(USER_EVENT,0,0,0,0);
748: [code segment to monitor]
749: PetscLogFlops(user_event_flops);
750: PetscLogEventEnd(USER_EVENT,0,0,0,0);
751: .ve
753: Notes:
754: You should also register each additional integer event with the command
755: PetscLogEventRegister(). Source code must be compiled with
756: -DPETSC_USE_LOG, which is the default.
758: PETSc automatically logs library events if the code has been
759: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
760: specified. PetscLogEventEnd() is intended for logging user events
761: to supplement this PETSc information.
763: Level: intermediate
765: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogFlops()
767: .keywords: log, event, end
768: M*/
770: /*MC
771: PetscLogEventBarrierBegin - Logs the time in a barrier before an event.
773: Input Parameters:
774: . e - integer associated with the event obtained from PetscLogEventRegister()
775: . o1,o2,o3,o4 - objects associated with the event, or 0
776: . comm - communicator the barrier takes place over
778: Synopsis:
779: void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
780: PetscObject o4,MPI_Comm comm)
782: Usage:
783: .vb
784: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
785: MPI_Allreduce()
786: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
787: .ve
789: Notes:
790: This is for logging the amount of time spent in a barrier for an event
791: that requires synchronization.
793: Additional Notes:
794: Synchronization events always come in pairs; for example, VEC_NormBarrier and
795: VEC_NormComm = VEC_NormBarrier + 1
797: Level: advanced
799: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
800: PetscLogEventBarrierEnd()
802: .keywords: log, event, begin, barrier
803: M*/
805: /*MC
806: PetscLogEventBarrierEnd - Logs the time in a barrier before an event.
808: Input Parameters:
809: . e - integer associated with the event obtained from PetscLogEventRegister()
810: . o1,o2,o3,o4 - objects associated with the event, or 0
811: . comm - communicator the barrier takes place over
813: Synopsis:
814: void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
815: PetscObject o4,MPI_Comm comm)
817: Usage:
818: .vb
819: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
820: MPI_Allreduce()
821: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
822: .ve
824: Notes:
825: This is for logging the amount of time spent in a barrier for an event
826: that requires synchronization.
828: Additional Notes:
829: Synchronization events always come in pairs; for example, VEC_NormBarrier and
830: VEC_NormComm = VEC_NormBarrier + 1
832: Level: advanced
834: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
835: PetscLogEventBarrierBegin()
837: .keywords: log, event, begin, barrier
838: M*/
840: /*------------------------------------------------ Class Functions --------------------------------------------------*/
841: /*@C
842: PetscLogClassRegister - Registers a class name for logging operations in an application code.
844: Not Collective
846: Input Parameter:
847: . name - The class name
848:
849: Output Parameter:
850: . oclass - The class id or cookie
852: Level: developer
854: .keywords: log, class, register
855: .seealso: ClassLogRegister()
856: @*/
857: int PetscLogClassRegister(int *oclass, const char name[])
858: {
859: StageLog stageLog;
860: int ierr;
863: *oclass = PETSC_DECIDE;
864: PetscLogGetStageLog(&stageLog);
865: ClassRegLogRegister(stageLog->classLog, name, oclass);
866: return(0);
867: }
869: /*------------------------------------------------ Output Functions -------------------------------------------------*/
870: /*@C
871: PetscLogDump - Dumps logs of objects to a file. This file is intended to
872: be read by petsc/bin/petscview.
874: Collective on PETSC_COMM_WORLD
876: Input Parameter:
877: . name - an optional file name
879: Options Database Keys:
880: + -log - Prints basic log information (for code compiled with PETSC_USE_LOG)
881: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
882:
883: Usage:
884: .vb
885: PetscInitialize(...);
886: PetscLogBegin(); or PetscLogAllBegin();
887: ... code ...
888: PetscLogDump(filename);
889: PetscFinalize();
890: .ve
892: Notes:
893: The default file name is
894: $ Log.<rank>
895: where <rank> is the processor number. If no name is specified,
896: this file will be used.
898: Level: advanced
900: .keywords: log, dump
901: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
902: @*/
903: int PetscLogDump(const char sname[]) {
904: StageLog stageLog;
905: EventPerfInfo *eventInfo;
906: FILE *fd;
907: char file[64], fname[64];
908: PetscLogDouble flops, _TotalTime;
909: int rank, curStage;
910: int action, object, event;
911: int ierr;
912:
914: /* Calculate the total elapsed time */
915: PetscTime(_TotalTime);
916: _TotalTime -= BaseTime;
917: /* Open log file */
918: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
919: if (sname != PETSC_NULL) {
920: sprintf(file, "%s.%d", sname, rank);
921: } else {
922: sprintf(file, "Log.%d", rank);
923: }
924: PetscFixFilename(file, fname);
925: PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
926: if ((rank == 0) && (fd == PETSC_NULL)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
927: /* Output totals */
928: PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8en", _TotalFlops, _TotalTime);
929: PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %gn", 0.0);
930: /* Output actions */
931: PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %dn", numActions);
932: for(action = 0; action < numActions; action++) {
933: PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %gn",
934: actions[action].time, actions[action].action, actions[action].event, actions[action].cookie, actions[action].id1,
935: actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
936: }
937: /* Output objects */
938: PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %dn", numObjects, numObjectsDestroyed);
939: for(object = 0; object < numObjects; object++) {
940: PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %dn", objects[object].parent, (int) objects[object].mem);
941: if (!objects[object].name[0]) {
942: PetscFPrintf(PETSC_COMM_WORLD, fd,"No Namen");
943: } else {
944: PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %sn", objects[object].name);
945: }
946: if (objects[object].info[0] != 0) {
947: PetscFPrintf(PETSC_COMM_WORLD, fd, "No Infon");
948: } else {
949: PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %sn", objects[object].info);
950: }
951: }
952: /* Output events */
953: PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:n");
954: PetscLogGetStageLog(&stageLog);
955: StackTop(stageLog->stack, &curStage);
956: eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
957: for(event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
958: if (eventInfo[event].time != 0.0) {
959: flops = eventInfo[event].flops/eventInfo[event].time;
960: } else {
961: flops = 0.0;
962: }
963: PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16gn", event, eventInfo[event].count,
964: eventInfo[event].flops, eventInfo[event].time, flops);
965: }
966: PetscFClose(PETSC_COMM_WORLD, fd);
967: return(0);
968: }
970: /*@C
971: PetscLogPrintSummary - Prints a summary of the logging.
973: Collective over MPI_Comm
975: Input Parameter:
976: + comm - The MPI communicator (only one processor prints output)
977: - file - [Optional] The output file name
979: Options Database Keys:
980: . -log_summary - Prints summary of log information (for code compiled with PETSC_USE_LOG)
982: Usage:
983: .vb
984: PetscInitialize(...);
985: PetscLogBegin();
986: ... code ...
987: PetscLogPrintSummary(MPI_Comm,filename);
988: PetscFinalize(...);
989: .ve
991: Notes:
992: By default the summary is printed to stdout.
993: More extensive examination of the log information can be done with
994: PetscLogDump(), which is activated by the option -log or -log_all, in
995: combination with petsc/bin/petscview.
997: Level: beginner
998:
999: .keywords: log, dump, print
1000: .seealso: PetscLogBegin(), PetscLogDump()
1001: @*/
1002: int PetscLogPrintSummary(MPI_Comm comm, const char filename[]) {
1003: FILE *fd = stdout;
1004: PetscScalar zero = 0.0;
1005: StageLog stageLog;
1006: StageInfo *stageInfo = PETSC_NULL;
1007: EventPerfInfo *eventInfo = PETSC_NULL;
1008: ClassPerfInfo *classInfo;
1009: char arch[10], hostname[64], username[16], pname[256], date[64];
1010: char *name;
1011: PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1012: PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1013: PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1014: PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1015: PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1016: PetscLogDouble min, max, tot, ratio, avg, x, y;
1017: PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1018: int minCt, maxCt;
1019: int numProcs, rank;
1020: PetscTruth *localStageUsed, *stageUsed;
1021: PetscTruth *localStageVisible, *stageVisible;
1022: int numStages, localNumEvents, numEvents;
1023: int stage, event, oclass;
1024: int ierr;
1027: MPI_Comm_size(comm, &numProcs);
1028: MPI_Comm_rank(comm, &rank);
1029: /* Pop off any stages the user forgot to remove */
1030: PetscLogGetStageLog(&stageLog);
1031: StageLogGetCurrent(stageLog, &stage);
1032: while (stage >= 0) {
1033: StageLogPop(stageLog);
1034: StageLogGetCurrent(stageLog, &stage);
1035: }
1036: /* Get the total elapsed time */
1037: PetscTime(locTotalTime); locTotalTime -= BaseTime;
1038: /* Open the summary file */
1039: if (filename != PETSC_NULL) {
1040: PetscFOpen(comm, filename, "w", &fd);
1041: }
1043: PetscFPrintf(comm, fd, "************************************************************************************************************************n");
1044: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***n");
1045: PetscFPrintf(comm, fd, "************************************************************************************************************************n");
1046: PetscFPrintf(comm, fd, "n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------nn");
1047: PetscGetArchType(arch, 10);
1048: PetscGetHostName(hostname, 64);
1049: PetscGetUserName(username, 16);
1050: PetscGetProgramName(pname, 256);
1051: PetscGetDate(date, 64);
1052: if (numProcs == 1) {
1053: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %sn", pname, arch, hostname, numProcs, username, date);
1054:
1055: } else {
1056: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %sn", pname, arch, hostname, numProcs, username, date);
1057:
1058: }
1059: PetscFPrintf(comm, fd, "Using %sn", PETSC_VERSION_NUMBER);
1061: /* Must preserve reduction count before we go on */
1062: red = allreduce_ct/((PetscLogDouble) numProcs);
1064: /* Calculate summary information */
1065: PetscFPrintf(comm, fd, "n Max Max/Min Avg Total n");
1066: /* Time */
1067: MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1068: MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1069: MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1070: avg = (tot)/((PetscLogDouble) numProcs);
1071: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1072: PetscFPrintf(comm, fd, "Time (sec): %5.3e %10.5f %5.3en", max, ratio, avg);
1073: TotalTime = tot;
1074: /* Objects */
1075: avg = (PetscLogDouble) numObjects;
1076: MPI_Allreduce(&avg, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1077: MPI_Allreduce(&avg, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1078: MPI_Allreduce(&avg, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1079: avg = (tot)/((PetscLogDouble) numProcs);
1080: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1081: PetscFPrintf(comm, fd, "Objects: %5.3e %10.5f %5.3en", max, ratio, avg);
1082: /* Flops */
1083: MPI_Allreduce(&_TotalFlops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1084: MPI_Allreduce(&_TotalFlops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1085: MPI_Allreduce(&_TotalFlops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1086: avg = (tot)/((PetscLogDouble) numProcs);
1087: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1088: PetscFPrintf(comm, fd, "Flops: %5.3e %10.5f %5.3e %5.3en", max, ratio, avg, tot);
1089: TotalFlops = tot;
1090: /* Flops/sec -- Must talk to Barry here */
1091: if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1092: MPI_Allreduce(&flops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1093: MPI_Allreduce(&flops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1094: MPI_Allreduce(&flops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1095: avg = (tot)/((PetscLogDouble) numProcs);
1096: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1097: PetscFPrintf(comm, fd, "Flops/sec: %5.3e %10.5f %5.3e %5.3en", max, ratio, avg, tot);
1098: /* Memory */
1099: PetscTrSpace(PETSC_NULL, PETSC_NULL, &mem);
1100: if (mem > 0.0) {
1101: MPI_Allreduce(&mem, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1102: MPI_Allreduce(&mem, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1103: MPI_Allreduce(&mem, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1104: avg = (tot)/((PetscLogDouble) numProcs);
1105: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1106: PetscFPrintf(comm, fd, "Memory: %5.3e %10.5f %5.3en", max, ratio, tot);
1107: }
1108: /* Messages */
1109: mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1110: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1111: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1112: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1113: avg = (tot)/((PetscLogDouble) numProcs);
1114: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1115: PetscFPrintf(comm, fd, "MPI Messages: %5.3e %10.5f %5.3e %5.3en", max, ratio, avg, tot);
1116: numMessages = tot;
1117: /* Message Lengths */
1118: mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1119: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1120: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1121: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1122: if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1123: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1124: PetscFPrintf(comm, fd, "MPI Message Lengths: %5.3e %10.5f %5.3e %5.3en", max, ratio, avg, tot);
1125: messageLength = tot;
1126: /* Reductions */
1127: MPI_Allreduce(&red, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1128: MPI_Allreduce(&red, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1129: MPI_Allreduce(&red, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1130: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1131: PetscFPrintf(comm, fd, "MPI Reductions: %5.3e %10.5fn", max, ratio);
1132: numReductions = tot;
1133: PetscFPrintf(comm, fd, "nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)n");
1134: PetscFPrintf(comm, fd, " e.g., VecAXPY() for real vectors of length N --> 2N flopsn");
1135: PetscFPrintf(comm, fd, " and VecAXPY() for complex vectors of length N --> 8N flopsn");
1137: /* Get total number of stages --
1138: Currently, a single processor can register more stages than another, but stages must all be registered in order.
1139: We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1140: This seems best accomplished by assoicating a communicator with each stage.
1141: */
1142: MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1143: PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1144: PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1145: PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1146: PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1147: if (numStages > 0) {
1148: stageInfo = stageLog->stageInfo;
1149: for(stage = 0; stage < numStages; stage++) {
1150: if (stage < stageLog->numStages) {
1151: localStageUsed[stage] = stageInfo[stage].used;
1152: localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1153: } else {
1154: localStageUsed[stage] = PETSC_FALSE;
1155: localStageVisible[stage] = PETSC_TRUE;
1156: }
1157: }
1158: MPI_Allreduce(localStageUsed, stageUsed, numStages, MPI_INT, MPI_LOR, comm);
1159: MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1160: for(stage = 0; stage < numStages; stage++) {
1161: if (stageUsed[stage] == PETSC_TRUE) {
1162: PetscFPrintf(comm, fd, "nSummary of Stages: ----- Time ------ ----- Flops ----- --- Messages --- -- Message Lengths -- -- Reductions --n");
1163: PetscFPrintf(comm, fd, " Avg %%Total Avg %%Total counts %%Total Avg %%Total counts %%Total n");
1164: break;
1165: }
1166: }
1167: for(stage = 0; stage < numStages; stage++) {
1168: if (stageUsed[stage] == PETSC_FALSE) continue;
1169: if (localStageUsed[stage] == PETSC_TRUE) {
1170: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1171: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1172: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1173: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1174: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1175: name = stageInfo[stage].name;
1176: } else {
1177: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1178: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1179: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1180: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1181: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1182: name = "";
1183: }
1184: mess *= 0.5; messLen *= 0.5; red /= numProcs;
1185: if (TotalTime != 0.0) fracTime = stageTime/TotalTime; else fracTime = 0.0;
1186: if (TotalFlops != 0.0) fracFlops = flops/TotalFlops; else fracFlops = 0.0;
1187: /* Talk to Barry if (stageTime != 0.0) flops = (numProcs*flops)/stageTime; else flops = 0.0; */
1188: if (numMessages != 0.0) fracMessages = mess/numMessages; else fracMessages = 0.0;
1189: if (numMessages != 0.0) avgMessLen = messLen/numMessages; else avgMessLen = 0.0;
1190: if (messageLength != 0.0) fracLength = messLen/messageLength; else fracLength = 0.0;
1191: if (numReductions != 0.0) fracReductions = red/numReductions; else fracReductions = 0.0;
1192: 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",
1193: stage, name, stageTime/numProcs, 100.0*fracTime, flops, 100.0*fracFlops,
1194: mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1195:
1196: }
1197: }
1199: PetscFPrintf(comm, fd,
1200: "n------------------------------------------------------------------------------------------------------------------------n");
1201:
1202: PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.n");
1203: PetscFPrintf(comm, fd, "Phase summary info:n");
1204: PetscFPrintf(comm, fd, " Count: number of times phase was executedn");
1205: PetscFPrintf(comm, fd, " Time and Flops/sec: Max - maximum over all processorsn");
1206: PetscFPrintf(comm, fd, " Ratio - ratio of maximum to minimum over all processorsn");
1207: PetscFPrintf(comm, fd, " Mess: number of messages sentn");
1208: PetscFPrintf(comm, fd, " Avg. len: average message lengthn");
1209: PetscFPrintf(comm, fd, " Reduct: number of global reductionsn");
1210: PetscFPrintf(comm, fd, " Global: entire computationn");
1211: PetscFPrintf(comm, fd, " Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().n");
1212: PetscFPrintf(comm, fd, " %%T - percent time in this phase %%F - percent flops in this phasen");
1213: PetscFPrintf(comm, fd, " %%M - percent messages in this phase %%L - percent message lengths in this phasen");
1214: PetscFPrintf(comm, fd, " %%R - percent reductions in this phasen");
1215: PetscFPrintf(comm, fd, " Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)n");
1216: PetscFPrintf(comm, fd,
1217: "------------------------------------------------------------------------------------------------------------------------n");
1218:
1220: #if defined(PETSC_USE_BOPT_g)
1221: PetscFPrintf(comm, fd, "nn");
1222: PetscFPrintf(comm, fd, " ##########################################################n");
1223: PetscFPrintf(comm, fd, " # #n");
1224: PetscFPrintf(comm, fd, " # WARNING!!! #n");
1225: PetscFPrintf(comm, fd, " # #n");
1226: PetscFPrintf(comm, fd, " # This code was compiled with a debugging option, #n");
1227: PetscFPrintf(comm, fd, " # BOPT=<g,g_c++,g_complex>. To get timing results #n");
1228: PetscFPrintf(comm, fd, " # ALWAYS compile your code with an optimized version, #n");
1229: PetscFPrintf(comm, fd, " # BOPT=<O,O_c++,O_complex>; the performance will #n");
1230: PetscFPrintf(comm, fd, " # be generally two or three times faster. #n");
1231: PetscFPrintf(comm, fd, " # #n");
1232: PetscFPrintf(comm, fd, " ##########################################################nnn");
1233: #endif
1234: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1235: PetscFPrintf(comm, fd, "nn");
1236: PetscFPrintf(comm, fd, " ##########################################################n");
1237: PetscFPrintf(comm, fd, " # #n");
1238: PetscFPrintf(comm, fd, " # WARNING!!! #n");
1239: PetscFPrintf(comm, fd, " # #n");
1240: PetscFPrintf(comm, fd, " # The code for various complex numbers numerical #n");
1241: PetscFPrintf(comm, fd, " # kernels uses C++, which generally is not well #n");
1242: PetscFPrintf(comm, fd, " # optimized. For performance that is about 4-5 times #n");
1243: PetscFPrintf(comm, fd, " # faster, specify the flag -DPETSC_USE_FORTRAN_KERNELS #n");
1244: PetscFPrintf(comm, fd, " # in base_variables and recompile the PETSc libraries. #n");
1245: PetscFPrintf(comm, fd, " # #n");
1246: PetscFPrintf(comm, fd, " ##########################################################nnn");
1247: #endif
1249: if (!PetscPreLoadingUsed) {
1250: PetscFPrintf(comm,fd,"nn");
1251: PetscFPrintf(comm,fd," ##########################################################n");
1252: PetscFPrintf(comm,fd," # #n");
1253: PetscFPrintf(comm,fd," # WARNING!!! #n");
1254: PetscFPrintf(comm,fd," # #n");
1255: PetscFPrintf(comm,fd," # This code was run without the PreLoadinBegin() #n");
1256: PetscFPrintf(comm,fd," # macros. To get timing results we always recommend #n");
1257: PetscFPrintf(comm,fd," # preloading. otherwise timing numbers may be #n");
1258: PetscFPrintf(comm,fd," # meaningless. #n");
1259: PetscFPrintf(comm,fd," ##########################################################nnn");
1260: }
1262: /* Report events */
1263: PetscFPrintf(comm, fd,
1264: "Event Count Time (sec) Flops/sec --- Global --- --- Stage --- Totaln");
1265:
1266: PetscFPrintf(comm, fd,
1267: " Max Ratio Max Ratio Max Ratio Mess Avg len Reduct %%T %%F %%M %%L %%R %%T %%F %%M %%L %%R Mflop/sn");
1268:
1269: PetscFPrintf(comm,fd,
1270: "------------------------------------------------------------------------------------------------------------------------n");
1272:
1273: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1274: for(stage = 0; stage < numStages; stage++) {
1275: if (stageVisible[stage] == PETSC_FALSE) continue;
1276: if (localStageUsed[stage] == PETSC_TRUE) {
1277: PetscFPrintf(comm, fd, "n--- Event Stage %d: %snn", stage, stageInfo[stage].name);
1278: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1279: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1280: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1281: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1282: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1283: } else {
1284: PetscFPrintf(comm, fd, "n--- Event Stage %d: Unknownnn", stage);
1285: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1286: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1287: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1288: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1289: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1290: }
1291: mess *= 0.5; messLen *= 0.5; red /= numProcs;
1293: /* Get total number of events in this stage --
1294: Currently, a single processor can register more events than another, but events must all be registered in order,
1295: just like stages. We can removed this requirement if necessary by having a global event numbering and indirection
1296: on the event ID. This seems best accomplished by assoicating a communicator with each stage.
1298: Problem: If the event did not happen on proc 1, its name will not be available.
1299: Problem: Event visibility is not implemented
1300: */
1301: if (localStageUsed[stage] == PETSC_TRUE) {
1302: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1303: localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1304: } else {
1305: localNumEvents = 0;
1306: }
1307: MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1308: for(event = 0; event < numEvents; event++) {
1309: if ((localStageUsed[stage] == PETSC_TRUE) && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1310: if (eventInfo[event].count > 0) {
1311: flopr = eventInfo[event].flops/eventInfo[event].time;
1312: } else {
1313: flopr = 0.0;
1314: }
1315: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1316: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1317: MPI_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1318: MPI_Allreduce(&eventInfo[event].time, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1319: MPI_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1320: MPI_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1321: MPI_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1322: MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1323: MPI_Allreduce(&eventInfo[event].numReductions, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1324: MPI_Allreduce(&eventInfo[event].count, &minCt, 1, MPI_INT, MPI_MIN, comm);
1325: MPI_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1326: name = stageLog->eventLog->eventInfo[event].name;
1327: } else {
1328: flopr = 0.0;
1329: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1330: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1331: MPI_Allreduce(&zero, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1332: MPI_Allreduce(&zero, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1333: MPI_Allreduce(&zero, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1334: MPI_Allreduce(&zero, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1335: MPI_Allreduce(&zero, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1336: MPI_Allreduce(&zero, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1337: MPI_Allreduce(&zero, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1338: MPI_Allreduce(&ierr, &minCt, 1, MPI_INT, MPI_MIN, comm);
1339: MPI_Allreduce(&ierr, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1340: name = "";
1341: }
1342: totm *= 0.5; totml *= 0.5; totr /= numProcs;
1343:
1344: if (maxCt != 0) {
1345: if (minCt != 0) ratCt = ((PetscLogDouble) maxCt)/minCt; else ratCt = 0.0;
1346: if (mint != 0.0) ratt = maxt/mint; else ratt = 0.0;
1347: if (minf != 0.0) ratf = maxf/minf; else ratf = 0.0;
1348: if (TotalTime != 0.0) fracTime = tott/TotalTime; else fracTime = 0.0;
1349: if (TotalFlops != 0.0) fracFlops = totf/TotalFlops; else fracFlops = 0.0;
1350: if (stageTime != 0.0) fracStageTime = tott/stageTime; else fracStageTime = 0.0;
1351: if (flops != 0.0) fracStageFlops = totf/flops; else fracStageFlops = 0.0;
1352: if (numMessages != 0.0) fracMess = totm/numMessages; else fracMess = 0.0;
1353: if (messageLength != 0.0) fracMessLen = totml/messageLength; else fracMessLen = 0.0;
1354: if (numReductions != 0.0) fracRed = totr/numReductions; else fracRed = 0.0;
1355: if (mess != 0.0) fracStageMess = totm/mess; else fracStageMess = 0.0;
1356: if (messLen != 0.0) fracStageMessLen = totml/messLen; else fracStageMessLen = 0.0;
1357: if (red != 0.0) fracStageRed = totr/red; else fracStageRed = 0.0;
1358: if (totm != 0.0) totml /= totm; else totml = 0.0;
1359: if (maxt != 0.0) flopr = totf/maxt; else flopr = 0.0;
1360: PetscFPrintf(comm, fd,
1361: "%-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",
1362: name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1363: 100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1364: 100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1365: flopr/1.0e6);
1366:
1367: }
1368: }
1369: }
1371: /* Memory usage and object creation */
1372: PetscFPrintf(comm, fd,
1373: "------------------------------------------------------------------------------------------------------------------------n");
1374:
1375: PetscFPrintf(comm, fd, "n");
1376: PetscFPrintf(comm, fd, "Memory usage is given in bytes:nn");
1378: /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1379: the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1380: stats for stages local to processor sets.
1381: */
1382: /* We should figure out the longest object name here (now 20 characters) */
1383: PetscFPrintf(comm, fd, "Object Type Creations Destructions Memory Descendants' Mem.n");
1384: for(stage = 0; stage < numStages; stage++) {
1385: if (localStageUsed[stage] == PETSC_TRUE) {
1386: classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1387: PetscFPrintf(comm, fd, "n--- Event Stage %d: %snn", stage, stageInfo[stage].name);
1388: for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1389: if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1390: PetscFPrintf(comm, fd, "%20s %5d %5d %9d %gn", stageLog->classLog->classInfo[oclass].name,
1391: classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1392: classInfo[oclass].descMem);
1393:
1394: }
1395: }
1396: } else {
1397: PetscFPrintf(comm, fd, "n--- Event Stage %d: Unknownnn", stage);
1398: }
1399: }
1401: PetscFree(localStageUsed);
1402: PetscFree(stageUsed);
1403: PetscFree(localStageVisible);
1404: PetscFree(stageVisible);
1406: /* Information unrelated to this particular run */
1407: PetscFPrintf(comm, fd,
1408: "========================================================================================================================n");
1409:
1410: PetscTime(y);
1411: PetscTime(x);
1412: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1413: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1414: PetscFPrintf(comm,fd,"Average time to get PetscTime(): %gn", (y-x)/10.0);
1415: /* MPI information */
1416: if (numProcs > 1) {
1417: MPI_Status status;
1418: int tag;
1420: MPI_Barrier(comm);
1421: PetscTime(x);
1422: MPI_Barrier(comm);
1423: MPI_Barrier(comm);
1424: MPI_Barrier(comm);
1425: MPI_Barrier(comm);
1426: MPI_Barrier(comm);
1427: PetscTime(y);
1428: PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %gn", (y-x)/5.0);
1429: PetscCommGetNewTag(comm, &tag);
1430: MPI_Barrier(comm);
1431: if (rank) {
1432: MPI_Recv(0, 0, MPI_INT, rank-1, tag, comm, &status);
1433: MPI_Send(0, 0, MPI_INT, (rank+1)%numProcs, tag, comm);
1434: } else {
1435: PetscTime(x);
1436: MPI_Send(0, 0, MPI_INT, 1, tag, comm);
1437: MPI_Recv(0, 0, MPI_INT, numProcs-1, tag, comm, &status);
1438: PetscTime(y);
1439: PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %gn", (y-x)/numProcs);
1440: }
1441: }
1442: /* Machine and compile information */
1443: #if defined(PETSC_USE_FORTRAN_KERNELS)
1444: PetscFPrintf(comm, fd, "Compiled without FORTRAN kernelsn");
1445: #else
1446: PetscFPrintf(comm, fd, "Compiled without FORTRAN kernelsn");
1447: #endif
1448: #if defined(PETSC_USE_MAT_SINGLE)
1449: PetscFPrintf(comm, fd, "Compiled with single precision matricesn");
1450: #else
1451: PetscFPrintf(comm, fd, "Compiled with double precision matrices (default)n");
1452: #endif
1453: PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void *) %d",
1454: (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*));
1455:
1457: PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1458: PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1459: PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1460: PetscFPrintf(comm, fd, "%s", petsclinkerinfo);
1462: /* Cleanup */
1463: PetscFPrintf(comm, fd, "n");
1464: PetscFClose(comm, fd);
1465: return(0);
1466: }
1468: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1469: /*@C
1470: PetscGetFlops - Returns the number of flops used on this processor
1471: since the program began.
1473: Not Collective
1475: Output Parameter:
1476: flops - number of floating point operations
1478: Notes:
1479: A global counter logs all PETSc flop counts. The user can use
1480: PetscLogFlops() to increment this counter to include flops for the
1481: application code.
1483: PETSc automatically logs library events if the code has been
1484: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1485: -log_summary, or -log_all are specified. PetscLogFlops() is
1486: intended for logging user flops to supplement this PETSc
1487: information.
1489: Level: intermediate
1491: .keywords: log, flops, floating point operations
1493: .seealso: PetscGetTime(), PetscLogFlops()
1494: @*/
1495: int PetscGetFlops(PetscLogDouble *flops)
1496: {
1498: *flops = _TotalFlops;
1499: return(0);
1500: }
1502: int PetscLogObjectState(PetscObject obj, const char format[], ...)
1503: {
1504: va_list Argp;
1507: if (!objects) return(0);
1508: va_start(Argp, format);
1509: #if defined(PETSC_HAVE_VPRINTF_CHAR)
1510: vsprintf(objects[obj->id].info, format, (char *) Argp);
1511: #else
1512: vsprintf(objects[obj->id].info, format, Argp);
1513: #endif
1514: va_end(Argp);
1515: return(0);
1516: }
1518: #else /* end of -DPETSC_USE_LOG section */
1520: int PetscLogObjectState(PetscObject obj, const char format[], ...)
1521: {
1523: return(0);
1524: }
1526: #endif /* PETSC_USE_LOG*/
1528: /*@
1529: PetscGetTime - Returns the current time of day in seconds. This
1530: returns wall-clock time.
1532: Not Collective
1534: Output Parameter:
1535: . v - time counter
1537: Usage:
1538: .vb
1539: PetscLogDouble v1,v2,elapsed_time;
1540: PetscGetTime(&v1);CHKERR(ierr);
1541: .... perform some calculation ...
1542: PetscGetTime(&v2);CHKERR(ierr);
1543: elapsed_time = v2 - v1;
1544: .ve
1546: Notes:
1547: Since the PETSc libraries incorporate timing of phases and operations,
1548: PetscGetTime() is intended only for timing of application codes.
1549: The options database commands -log, -log_summary, and -log_all activate
1550: PETSc library timing. See the users manual for further details.
1552: Level: intermediate
1554: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStagePush(),
1555: PetscLogStagePop(), PetscLogStageRegister(), PetscGetFlops()
1557: .keywords: get, time
1558: @*/
1559: int PetscGetTime(PetscLogDouble *t)
1560: {
1562: PetscTime(*t);
1563: return(0);
1564: }
1566: /*
1567: PetscLogGetStageLog - This function returns the default stage logging object.
1569: Not collective
1571: Output Parameter:
1572: . stageLog - The default StageLog
1574: Level: beginner
1576: .keywords: log, stage
1577: .seealso: StageLogCreate()
1578: */
1579: int PetscLogGetStageLog(StageLog *stageLog)
1580: {
1583: *stageLog = _stageLog;
1584: return(0);
1585: }
1587: /*MC
1588: PetscLogFlops - Adds floating point operations to the global counter.
1590: Input Parameter:
1591: . f - flop counter
1593: Synopsis:
1594: void PetscLogFlops(int f)
1596: Usage:
1597: .vb
1598: int USER_EVENT;
1599: PetscLogEventRegister(&USER_EVENT,"User event");
1600: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1601: [code segment to monitor]
1602: PetscLogFlops(user_flops)
1603: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1604: .ve
1606: Notes:
1607: A global counter logs all PETSc flop counts. The user can use
1608: PetscLogFlops() to increment this counter to include flops for the
1609: application code.
1611: PETSc automatically logs library events if the code has been
1612: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1613: -log_summary, or -log_all are specified. PetscLogFlops() is
1614: intended for logging user flops to supplement this PETSc
1615: information.
1617: Level: intermediate
1619: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()
1621: .keywords: log, flops, floating point operations
1622: M*/
1624: PetscTruth PetscPreLoadingUsed = PETSC_FALSE;
1625: PetscTruth PetscPreLoadingOn = PETSC_FALSE;
1627: /*MC
1628: PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1629: to get accurate timings
1631: Input Parameter:
1632: + flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1633: with command line option -preload true or -preload false
1634: - name - name of first stage (lines of code timed seperately with -log_summary) to
1635: be preloaded
1637: Synopsis:
1638: void PreLoadBegin(PetscTruth flag,char *name);
1640: Usage:
1641: .vb
1642: PreLoadBegin(PETSC_TRUE,"first stage);
1643: lines of code
1644: PreLoadStage("second stage");
1645: lines of code
1646: PreLoadEnd();
1647: .ve
1649: Level: intermediate
1651: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadEnd(), PreLoadStage()
1653: Concepts: preloading
1654: Concepts: timing^accurate
1655: Concepts: paging^eliminating effects of
1658: M*/
1660: /*MC
1661: PreLoadEnd - End a segment of code that may be preloaded (run twice)
1662: to get accurate timings
1664: Synopsis:
1665: void PreLoadEnd(void);
1667: Usage:
1668: .vb
1669: PreLoadBegin(PETSC_TRUE,"first stage);
1670: lines of code
1671: PreLoadStage("second stage");
1672: lines of code
1673: PreLoadEnd();
1674: .ve
1676: Level: intermediate
1678: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadStage()
1680: M*/
1682: /*MC
1683: PreLoadStage - Start a new segment of code to be timed seperately.
1684: to get accurate timings
1686: Synopsis:
1687: void PreLoadStage(char *name);
1689: Usage:
1690: .vb
1691: PreLoadBegin(PETSC_TRUE,"first stage);
1692: lines of code
1693: PreLoadStage("second stage");
1694: lines of code
1695: PreLoadEnd();
1696: .ve
1698: Level: intermediate
1700: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd()
1702: M*/
1704: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1705: /*@C
1706: StackDestroy - This function destroys a stack.
1708: Not Collective
1710: Input Parameter:
1711: . stack - The stack
1713: Level: beginner
1715: .keywords: log, stack, destroy
1716: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
1717: @*/
1718: int StackDestroy(IntStack stack)
1719: {
1723: PetscFree(stack->stack);
1724: PetscFree(stack);
1725: return(0);
1726: }
1728: /*@C
1729: StackEmpty - This function determines whether any items have been pushed.
1731: Not Collective
1733: Input Parameter:
1734: . stack - The stack
1736: Output Parameter:
1737: . empty - PETSC_TRUE if the stack is empty
1739: Level: intermediate
1741: .keywords: log, stack, empty
1742: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
1743: @*/
1744: int StackEmpty(IntStack stack, PetscTruth *empty)
1745: {
1748: if (stack->top == -1) {
1749: *empty = PETSC_TRUE;
1750: } else {
1751: *empty = PETSC_FALSE;
1752: }
1753: return(0);
1754: }
1756: /*@C
1757: StackTop - This function returns the top of the stack.
1759: Not Collective
1761: Input Parameter:
1762: . stack - The stack
1764: Output Parameter:
1765: . top - The integer on top of the stack
1767: Level: intermediate
1769: .keywords: log, stack, top
1770: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
1771: @*/
1772: int StackTop(IntStack stack, int *top)
1773: {
1776: *top = stack->stack[stack->top];
1777: return(0);
1778: }
1780: /*@C
1781: StackPush - This function pushes an integer on the stack.
1783: Not Collective
1785: Input Parameters:
1786: + stack - The stack
1787: - item - The integer to push
1789: Level: intermediate
1791: .keywords: log, stack, push
1792: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
1793: @*/
1794: int StackPush(IntStack stack, int item)
1795: {
1796: int *array;
1797: int ierr;
1800: stack->top++;
1801: if (stack->top >= stack->max) {
1802: PetscMalloc(stack->max*2 * sizeof(int), &array);
1803: PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
1804: PetscFree(stack->stack);
1805: stack->stack = array;
1806: stack->max *= 2;
1807: }
1808: stack->stack[stack->top] = item;
1809: return(0);
1810: }
1812: /*@C
1813: StackPop - This function pops an integer from the stack.
1815: Not Collective
1817: Input Parameter:
1818: . stack - The stack
1820: Output Parameter:
1821: . item - The integer popped
1823: Level: intermediate
1825: .keywords: log, stack, pop
1826: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
1827: @*/
1828: int StackPop(IntStack stack, int *item)
1829: {
1832: if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
1833: *item = stack->stack[stack->top--];
1834: return(0);
1835: }
1837: /*@C
1838: StackCreate - This function creates a stack.
1840: Not Collective
1842: Output Parameter:
1843: . stack - The stack
1845: Level: beginner
1847: .keywords: log, stack, pop
1848: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
1849: @*/
1850: int StackCreate(IntStack *stack)
1851: {
1852: IntStack s;
1853: int ierr;
1857: PetscNew(struct _IntStack, &s);
1858: s->top = -1;
1859: s->max = 128;
1860: PetscMalloc(s->max * sizeof(int), &s->stack);
1861: PetscMemzero(s->stack, s->max * sizeof(int));
1862: *stack = s;
1863: return(0);
1864: }