Actual source code: plog.c
petsc-dev 2014-02-02
2: /*
3: PETSc code to log object creation and destruction and PETSc events.
5: This provides the public API used by the rest of PETSc and by users.
7: These routines use a private API that is not used elsewhere in PETSc and is not
8: accessible to users. The private API is defined in logimpl.h and the utils directory.
10: */
11: #include <petsc-private/logimpl.h> /*I "petscsys.h" I*/
12: #include <petsctime.h>
13: #include <petscviewer.h>
14: #include <petscthreadcomm.h>
16: PetscErrorCode PetscLogObjectParent(PetscObject p,PetscObject c)
17: {
18: if (!c || !p) return 0;
19: c->parent = p;
20: c->parentid = p->id;
21: return 0;
22: }
24: PetscErrorCode PetscLogObjectMemory(PetscObject p,PetscLogDouble m)
25: {
26: p->mem += m;
27: return 0;
28: }
30: PetscLogEvent PETSC_LARGEST_EVENT = PETSC_EVENT;
32: #if defined(PETSC_USE_LOG)
33: #include <petscmachineinfo.h>
34: #include <petscconfiginfo.h>
36: /* used in the MPI_XXX() count macros in petsclog.h */
38: /* Action and object logging variables */
39: Action *petsc_actions = NULL;
40: Object *petsc_objects = NULL;
41: PetscBool petsc_logActions = PETSC_FALSE;
42: PetscBool petsc_logObjects = PETSC_FALSE;
43: int petsc_numActions = 0, petsc_maxActions = 100;
44: int petsc_numObjects = 0, petsc_maxObjects = 100;
45: int petsc_numObjectsDestroyed = 0;
47: /* Global counters */
48: PetscLogDouble petsc_BaseTime = 0.0;
49: PetscLogDouble petsc_TotalFlops = 0.0; /* The number of flops */
50: PetscLogDouble petsc_tmp_flops = 0.0; /* The incremental number of flops */
51: PetscLogDouble petsc_send_ct = 0.0; /* The number of sends */
52: PetscLogDouble petsc_recv_ct = 0.0; /* The number of receives */
53: PetscLogDouble petsc_send_len = 0.0; /* The total length of all sent messages */
54: PetscLogDouble petsc_recv_len = 0.0; /* The total length of all received messages */
55: PetscLogDouble petsc_isend_ct = 0.0; /* The number of immediate sends */
56: PetscLogDouble petsc_irecv_ct = 0.0; /* The number of immediate receives */
57: PetscLogDouble petsc_isend_len = 0.0; /* The total length of all immediate send messages */
58: PetscLogDouble petsc_irecv_len = 0.0; /* The total length of all immediate receive messages */
59: PetscLogDouble petsc_wait_ct = 0.0; /* The number of waits */
60: PetscLogDouble petsc_wait_any_ct = 0.0; /* The number of anywaits */
61: PetscLogDouble petsc_wait_all_ct = 0.0; /* The number of waitalls */
62: PetscLogDouble petsc_sum_of_waits_ct = 0.0; /* The total number of waits */
63: PetscLogDouble petsc_allreduce_ct = 0.0; /* The number of reductions */
64: PetscLogDouble petsc_gather_ct = 0.0; /* The number of gathers and gathervs */
65: PetscLogDouble petsc_scatter_ct = 0.0; /* The number of scatters and scattervs */
67: /* Logging functions */
68: PetscErrorCode (*PetscLogPHC)(PetscObject) = NULL;
69: PetscErrorCode (*PetscLogPHD)(PetscObject) = NULL;
70: PetscErrorCode (*PetscLogPLB)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = NULL;
71: PetscErrorCode (*PetscLogPLE)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = NULL;
73: /* Tracing event logging variables */
74: FILE *petsc_tracefile = NULL;
75: int petsc_tracelevel = 0;
76: const char *petsc_traceblanks = " ";
77: char petsc_tracespace[128] = " ";
78: PetscLogDouble petsc_tracetime = 0.0;
79: static PetscBool PetscLogBegin_PrivateCalled = PETSC_FALSE;
81: /*---------------------------------------------- General Functions --------------------------------------------------*/
84: /*@C
85: PetscLogDestroy - Destroys the object and event logging data and resets the global counters.
87: Not Collective
89: Notes:
90: This routine should not usually be used by programmers. Instead employ
91: PetscLogStagePush() and PetscLogStagePop().
93: Level: developer
95: .keywords: log, destroy
96: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogStagePush(), PlogStagePop()
97: @*/
98: PetscErrorCode PetscLogDestroy(void)
99: {
100: PetscStageLog stageLog;
104: PetscFree(petsc_actions);
105: PetscFree(petsc_objects);
106: PetscLogSet(NULL, NULL);
108: /* Resetting phase */
109: PetscLogGetStageLog(&stageLog);
110: PetscStageLogDestroy(stageLog);
112: petsc_TotalFlops = 0.0;
113: petsc_numActions = 0;
114: petsc_numObjects = 0;
115: petsc_numObjectsDestroyed = 0;
116: petsc_maxActions = 100;
117: petsc_maxObjects = 100;
118: petsc_actions = NULL;
119: petsc_objects = NULL;
120: petsc_logActions = PETSC_FALSE;
121: petsc_logObjects = PETSC_FALSE;
122: petsc_BaseTime = 0.0;
123: petsc_TotalFlops = 0.0;
124: petsc_tmp_flops = 0.0;
125: petsc_send_ct = 0.0;
126: petsc_recv_ct = 0.0;
127: petsc_send_len = 0.0;
128: petsc_recv_len = 0.0;
129: petsc_isend_ct = 0.0;
130: petsc_irecv_ct = 0.0;
131: petsc_isend_len = 0.0;
132: petsc_irecv_len = 0.0;
133: petsc_wait_ct = 0.0;
134: petsc_wait_any_ct = 0.0;
135: petsc_wait_all_ct = 0.0;
136: petsc_sum_of_waits_ct = 0.0;
137: petsc_allreduce_ct = 0.0;
138: petsc_gather_ct = 0.0;
139: petsc_scatter_ct = 0.0;
140: PETSC_LARGEST_EVENT = PETSC_EVENT;
141: PetscLogPHC = NULL;
142: PetscLogPHD = NULL;
143: petsc_tracefile = NULL;
144: petsc_tracelevel = 0;
145: petsc_traceblanks = " ";
146: petsc_tracespace[0] = ' '; petsc_tracespace[1] = 0;
147: petsc_tracetime = 0.0;
148: PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
149: PETSC_OBJECT_CLASSID = 0;
150: petsc_stageLog = 0;
151: PetscLogBegin_PrivateCalled = PETSC_FALSE;
152: return(0);
153: }
157: /*@C
158: PetscLogSet - Sets the logging functions called at the beginning and ending of every event.
160: Not Collective
162: Input Parameters:
163: + b - The function called at beginning of event
164: - e - The function called at end of event
166: Level: developer
168: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
169: @*/
170: PetscErrorCode PetscLogSet(PetscErrorCode (*b)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject),
171: PetscErrorCode (*e)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject))
172: {
174: PetscLogPLB = b;
175: PetscLogPLE = e;
176: return(0);
177: }
179: #if defined(PETSC_HAVE_CHUD)
180: #include <CHUD/CHUD.h>
181: #endif
182: #if defined(PETSC_HAVE_PAPI)
183: #include <papi.h>
184: int PAPIEventSet = PAPI_NULL;
185: #endif
187: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
190: PetscErrorCode PetscLogBegin_Private(void)
191: {
192: int stage;
193: PetscBool opt;
197: if (PetscLogBegin_PrivateCalled) return(0);
198: PetscLogBegin_PrivateCalled = PETSC_TRUE;
200: PetscOptionsHasName(NULL, "-log_exclude_actions", &opt);
201: if (opt) petsc_logActions = PETSC_FALSE;
202: PetscOptionsHasName(NULL, "-log_exclude_objects", &opt);
203: if (opt) petsc_logObjects = PETSC_FALSE;
204: if (petsc_logActions) {
205: PetscMalloc1(petsc_maxActions, &petsc_actions);
206: }
207: if (petsc_logObjects) {
208: PetscMalloc1(petsc_maxObjects, &petsc_objects);
209: }
210: PetscLogPHC = PetscLogObjCreateDefault;
211: PetscLogPHD = PetscLogObjDestroyDefault;
212: /* Setup default logging structures */
213: PetscStageLogCreate(&petsc_stageLog);
214: PetscStageLogRegister(petsc_stageLog, "Main Stage", &stage);
215: #if defined(PETSC_HAVE_CHUD)
216: chudInitialize();
217: chudAcquireSamplingFacility(CHUD_BLOCKING);
218: chudSetSamplingDevice(chudCPU1Dev);
219: chudSetStartDelay(0,chudNanoSeconds);
220: chudClearPMCMode(chudCPU1Dev,chudUnused);
221: chudClearPMCs();
222: /* chudSetPMCMuxPosition(chudCPU1Dev,0,0); */
223: printf("%s\n",chudGetEventName(chudCPU1Dev,PMC_1,193));
224: printf("%s\n",chudGetEventDescription(chudCPU1Dev,PMC_1,193));
225: printf("%s\n",chudGetEventNotes(chudCPU1Dev,PMC_1,193));
226: chudSetPMCEvent(chudCPU1Dev,PMC_1,193);
227: chudSetPMCMode(chudCPU1Dev,PMC_1,chudCounter);
228: chudSetPrivilegeFilter(chudCPU1Dev,PMC_1,chudCountUserEvents);
229: chudSetPMCEventMask(chudCPU1Dev,PMC_1,0xFE);
230: if (!chudIsEventValid(chudCPU1Dev,PMC_1,193)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Event is not valid %d",193);
231: chudStartPMCs();
232: #endif
233: #if defined(PETSC_HAVE_PAPI)
234: PAPI_library_init(PAPI_VER_CURRENT);
235: if (ierr != PAPI_VER_CURRENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot initialize PAPI");
236: PAPI_query_event(PAPI_FP_INS);
237: PAPI_create_eventset(&PAPIEventSet);
238: PAPI_add_event(PAPIEventSet,PAPI_FP_INS);
239: PAPI_start(PAPIEventSet);
240: #endif
242: /* All processors sync here for more consistent logging */
243: MPI_Barrier(PETSC_COMM_WORLD);
244: PetscTime(&petsc_BaseTime);
245: PetscLogStagePush(stage);
246: return(0);
247: }
251: /*@C
252: PetscLogBegin - Turns on logging of objects and events. This logs flop
253: rates and object creation and should not slow programs down too much.
254: This routine may be called more than once.
256: Logically Collective over PETSC_COMM_WORLD
258: Options Database Keys:
259: + -log_summary - Prints summary of flop and timing information to the
260: screen (for code compiled with PETSC_USE_LOG)
261: - -log - Prints detailed log information (for code compiled with PETSC_USE_LOG)
263: Usage:
264: .vb
265: PetscInitialize(...);
266: PetscLogBegin();
267: ... code ...
268: PetscLogView(viewer); or PetscLogDump();
269: PetscFinalize();
270: .ve
272: Notes:
273: PetscLogView(viewer) or PetscLogDump() actually cause the printing of
274: the logging information.
276: Level: advanced
278: .keywords: log, begin
279: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogTraceBegin()
280: @*/
281: PetscErrorCode PetscLogBegin(void)
282: {
286: PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
287: PetscLogBegin_Private();
288: return(0);
289: }
293: /*@C
294: PetscLogAllBegin - Turns on extensive logging of objects and events. Logs
295: all events. This creates large log files and slows the program down.
297: Logically Collective on PETSC_COMM_WORLD
299: Options Database Keys:
300: . -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
302: Usage:
303: .vb
304: PetscInitialize(...);
305: PetscLogAllBegin();
306: ... code ...
307: PetscLogDump(filename);
308: PetscFinalize();
309: .ve
311: Notes:
312: A related routine is PetscLogBegin() (with the options key -log), which is
313: intended for production runs since it logs only flop rates and object
314: creation (and shouldn't significantly slow the programs).
316: Level: advanced
318: .keywords: log, all, begin
319: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogTraceBegin()
320: @*/
321: PetscErrorCode PetscLogAllBegin(void)
322: {
326: PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
327: PetscLogBegin_Private();
328: return(0);
329: }
333: /*@
334: PetscLogTraceBegin - Activates trace logging. Every time a PETSc event
335: begins or ends, the event name is printed.
337: Logically Collective on PETSC_COMM_WORLD
339: Input Parameter:
340: . file - The file to print trace in (e.g. stdout)
342: Options Database Key:
343: . -log_trace [filename] - Activates PetscLogTraceBegin()
345: Notes:
346: PetscLogTraceBegin() prints the processor number, the execution time (sec),
347: then "Event begin:" or "Event end:" followed by the event name.
349: PetscLogTraceBegin() allows tracing of all PETSc calls, which is useful
350: to determine where a program is hanging without running in the
351: debugger. Can be used in conjunction with the -info option.
353: Level: intermediate
355: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogBegin()
356: @*/
357: PetscErrorCode PetscLogTraceBegin(FILE *file)
358: {
362: petsc_tracefile = file;
364: PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
365: PetscLogBegin_Private();
366: return(0);
367: }
371: /*@
372: PetscLogActions - Determines whether actions are logged for the graphical viewer.
374: Not Collective
376: Input Parameter:
377: . flag - PETSC_TRUE if actions are to be logged
379: Level: intermediate
381: Note: Logging of actions continues to consume more memory as the program
382: runs. Long running programs should consider turning this feature off.
384: Options Database Keys:
385: . -log_exclude_actions - Turns off actions logging
387: .keywords: log, stage, register
388: .seealso: PetscLogStagePush(), PetscLogStagePop()
389: @*/
390: PetscErrorCode PetscLogActions(PetscBool flag)
391: {
393: petsc_logActions = flag;
394: return(0);
395: }
399: /*@
400: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
402: Not Collective
404: Input Parameter:
405: . flag - PETSC_TRUE if objects are to be logged
407: Level: intermediate
409: Note: Logging of objects continues to consume more memory as the program
410: runs. Long running programs should consider turning this feature off.
412: Options Database Keys:
413: . -log_exclude_objects - Turns off objects logging
415: .keywords: log, stage, register
416: .seealso: PetscLogStagePush(), PetscLogStagePop()
417: @*/
418: PetscErrorCode PetscLogObjects(PetscBool flag)
419: {
421: petsc_logObjects = flag;
422: return(0);
423: }
425: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
428: /*@C
429: PetscLogStageRegister - Attaches a charactor string name to a logging stage.
431: Not Collective
433: Input Parameter:
434: . sname - The name to associate with that stage
436: Output Parameter:
437: . stage - The stage number
439: Level: intermediate
441: .keywords: log, stage, register
442: .seealso: PetscLogStagePush(), PetscLogStagePop()
443: @*/
444: PetscErrorCode PetscLogStageRegister(const char sname[],PetscLogStage *stage)
445: {
446: PetscStageLog stageLog;
447: PetscLogEvent event;
451: PetscLogGetStageLog(&stageLog);
452: PetscStageLogRegister(stageLog, sname, stage);
453: /* Copy events already changed in the main stage, this sucks */
454: EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
455: for (event = 0; event < stageLog->eventLog->numEvents; event++) {
456: EventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],&stageLog->stageInfo[*stage].eventLog->eventInfo[event]);
457: }
458: ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
459: return(0);
460: }
464: /*@C
465: PetscLogStagePush - This function pushes a stage on the stack.
467: Not Collective
469: Input Parameter:
470: . stage - The stage on which to log
472: Usage:
473: If the option -log_sumary is used to run the program containing the
474: following code, then 2 sets of summary data will be printed during
475: PetscFinalize().
476: .vb
477: PetscInitialize(int *argc,char ***args,0,0);
478: [stage 0 of code]
479: PetscLogStagePush(1);
480: [stage 1 of code]
481: PetscLogStagePop();
482: PetscBarrier(...);
483: [more stage 0 of code]
484: PetscFinalize();
485: .ve
487: Notes:
488: Use PetscLogStageRegister() to register a stage.
490: Level: intermediate
492: .keywords: log, push, stage
493: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
494: @*/
495: PetscErrorCode PetscLogStagePush(PetscLogStage stage)
496: {
497: PetscStageLog stageLog;
501: PetscLogGetStageLog(&stageLog);
502: PetscStageLogPush(stageLog, stage);
503: return(0);
504: }
508: /*@C
509: PetscLogStagePop - This function pops a stage from the stack.
511: Not Collective
513: Usage:
514: If the option -log_sumary is used to run the program containing the
515: following code, then 2 sets of summary data will be printed during
516: PetscFinalize().
517: .vb
518: PetscInitialize(int *argc,char ***args,0,0);
519: [stage 0 of code]
520: PetscLogStagePush(1);
521: [stage 1 of code]
522: PetscLogStagePop();
523: PetscBarrier(...);
524: [more stage 0 of code]
525: PetscFinalize();
526: .ve
528: Notes:
529: Use PetscLogStageRegister() to register a stage.
531: Level: intermediate
533: .keywords: log, pop, stage
534: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
535: @*/
536: PetscErrorCode PetscLogStagePop(void)
537: {
538: PetscStageLog stageLog;
542: PetscLogGetStageLog(&stageLog);
543: PetscStageLogPop(stageLog);
544: return(0);
545: }
549: /*@
550: PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().
552: Not Collective
554: Input Parameters:
555: + stage - The stage
556: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
558: Level: intermediate
560: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
561: @*/
562: PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
563: {
564: PetscStageLog stageLog;
568: PetscLogGetStageLog(&stageLog);
569: PetscStageLogSetActive(stageLog, stage, isActive);
570: return(0);
571: }
575: /*@
576: PetscLogStageGetActive - Returns stage activity for PetscLogEventBegin() and PetscLogEventEnd().
578: Not Collective
580: Input Parameter:
581: . stage - The stage
583: Output Parameter:
584: . isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
586: Level: intermediate
588: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
589: @*/
590: PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscBool *isActive)
591: {
592: PetscStageLog stageLog;
596: PetscLogGetStageLog(&stageLog);
597: PetscStageLogGetActive(stageLog, stage, isActive);
598: return(0);
599: }
603: /*@
604: PetscLogStageSetVisible - Determines stage visibility in PetscLogView()
606: Not Collective
608: Input Parameters:
609: + stage - The stage
610: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
612: Level: intermediate
614: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogView()
615: @*/
616: PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)
617: {
618: PetscStageLog stageLog;
622: PetscLogGetStageLog(&stageLog);
623: PetscStageLogSetVisible(stageLog, stage, isVisible);
624: return(0);
625: }
629: /*@
630: PetscLogStageGetVisible - Returns stage visibility in PetscLogView()
632: Not Collective
634: Input Parameter:
635: . stage - The stage
637: Output Parameter:
638: . isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
640: Level: intermediate
642: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogView()
643: @*/
644: PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscBool *isVisible)
645: {
646: PetscStageLog stageLog;
650: PetscLogGetStageLog(&stageLog);
651: PetscStageLogGetVisible(stageLog, stage, isVisible);
652: return(0);
653: }
657: /*@C
658: PetscLogStageGetId - Returns the stage id when given the stage name.
660: Not Collective
662: Input Parameter:
663: . name - The stage name
665: Output Parameter:
666: . stage - The stage
668: Level: intermediate
670: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
671: @*/
672: PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
673: {
674: PetscStageLog stageLog;
678: PetscLogGetStageLog(&stageLog);
679: PetscStageLogGetStage(stageLog, name, stage);
680: return(0);
681: }
683: /*------------------------------------------------ Event Functions --------------------------------------------------*/
686: /*@C
687: PetscLogEventRegister - Registers an event name for logging operations in an application code.
689: Not Collective
691: Input Parameter:
692: + name - The name associated with the event
693: - classid - The classid associated to the class for this event, obtain either with
694: PetscClassIdRegister() or use a predefined one such as KSP_CLASSID, SNES_CLASSID, the predefined ones
695: are only available in C code
697: Output Parameter:
698: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().
700: Example of Usage:
701: .vb
702: PetscLogEvent USER_EVENT;
703: PetscClassId classid;
704: PetscLogDouble user_event_flops;
705: PetscClassIdRegister("class name",&classid);
706: PetscLogEventRegister("User event name",classid,&USER_EVENT);
707: PetscLogEventBegin(USER_EVENT,0,0,0,0);
708: [code segment to monitor]
709: PetscLogFlops(user_event_flops);
710: PetscLogEventEnd(USER_EVENT,0,0,0,0);
711: .ve
713: Notes:
714: PETSc automatically logs library events if the code has been
715: compiled with -DPETSC_USE_LOG (which is the default) and -log,
716: -log_summary, or -log_all are specified. PetscLogEventRegister() is
717: intended for logging user events to supplement this PETSc
718: information.
720: PETSc can gather data for use with the utilities Jumpshot
721: (part of the MPICH distribution). If PETSc has been compiled
722: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
723: MPICH), the user can employ another command line option, -log_mpe,
724: to create a logfile, "mpe.log", which can be visualized
725: Jumpshot.
727: The classid is associated with each event so that classes of events
728: can be disabled simultaneously, such as all matrix events. The user
729: can either use an existing classid, such as MAT_CLASSID, or create
730: their own as shown in the example.
732: Level: intermediate
734: .keywords: log, event, register
735: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
736: PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
737: PetscLogEventActivate(), PetscLogEventDeactivate(), PetscClassIdRegister()
738: @*/
739: PetscErrorCode PetscLogEventRegister(const char name[],PetscClassId classid,PetscLogEvent *event)
740: {
741: PetscStageLog stageLog;
742: int stage;
746: *event = PETSC_DECIDE;
747: PetscLogGetStageLog(&stageLog);
748: EventRegLogRegister(stageLog->eventLog, name, classid, event);
749: for (stage = 0; stage < stageLog->numStages; stage++) {
750: EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
751: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
752: }
753: return(0);
754: }
758: /*@
759: PetscLogEventActivate - Indicates that a particular event should be logged.
761: Not Collective
763: Input Parameter:
764: . event - The event id
766: Usage:
767: .vb
768: PetscLogEventDeactivate(VEC_SetValues);
769: [code where you do not want to log VecSetValues()]
770: PetscLogEventActivate(VEC_SetValues);
771: [code where you do want to log VecSetValues()]
772: .ve
774: Note:
775: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
776: or an event number obtained with PetscLogEventRegister().
778: Level: advanced
780: .keywords: log, event, activate
781: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
782: @*/
783: PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
784: {
785: PetscStageLog stageLog;
786: int stage;
790: PetscLogGetStageLog(&stageLog);
791: PetscStageLogGetCurrent(stageLog, &stage);
792: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
793: return(0);
794: }
798: /*@
799: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
801: Not Collective
803: Input Parameter:
804: . event - The event id
806: Usage:
807: .vb
808: PetscLogEventDeactivate(VEC_SetValues);
809: [code where you do not want to log VecSetValues()]
810: PetscLogEventActivate(VEC_SetValues);
811: [code where you do want to log VecSetValues()]
812: .ve
814: Note:
815: The event may be either a pre-defined PETSc event (found in
816: include/petsclog.h) or an event number obtained with PetscLogEventRegister()).
818: Level: advanced
820: .keywords: log, event, deactivate
821: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
822: @*/
823: PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
824: {
825: PetscStageLog stageLog;
826: int stage;
830: PetscLogGetStageLog(&stageLog);
831: PetscStageLogGetCurrent(stageLog, &stage);
832: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
833: return(0);
834: }
838: /*@
839: PetscLogEventSetActiveAll - Sets the event activity in every stage.
841: Not Collective
843: Input Parameters:
844: + event - The event id
845: - isActive - The activity flag determining whether the event is logged
847: Level: advanced
849: .keywords: log, event, activate
850: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
851: @*/
852: PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
853: {
854: PetscStageLog stageLog;
855: int stage;
859: PetscLogGetStageLog(&stageLog);
860: for (stage = 0; stage < stageLog->numStages; stage++) {
861: if (isActive) {
862: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
863: } else {
864: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
865: }
866: }
867: return(0);
868: }
872: /*@
873: PetscLogEventActivateClass - Activates event logging for a PETSc object class.
875: Not Collective
877: Input Parameter:
878: . classid - The event class, for example MAT_CLASSID, SNES_CLASSID, etc.
880: Level: developer
882: .keywords: log, event, activate, class
883: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
884: @*/
885: PetscErrorCode PetscLogEventActivateClass(PetscClassId classid)
886: {
887: PetscStageLog stageLog;
888: int stage;
892: PetscLogGetStageLog(&stageLog);
893: PetscStageLogGetCurrent(stageLog, &stage);
894: EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
895: return(0);
896: }
900: /*@
901: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.
903: Not Collective
905: Input Parameter:
906: . classid - The event class, for example MAT_CLASSID, SNES_CLASSID, etc.
908: Level: developer
910: .keywords: log, event, deactivate, class
911: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
912: @*/
913: PetscErrorCode PetscLogEventDeactivateClass(PetscClassId classid)
914: {
915: PetscStageLog stageLog;
916: int stage;
920: PetscLogGetStageLog(&stageLog);
921: PetscStageLogGetCurrent(stageLog, &stage);
922: EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
923: return(0);
924: }
926: /*MC
927: PetscLogEventBegin - Logs the beginning of a user event.
929: Synopsis:
930: #include <petsclog.h>
931: PetscErrorCode PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)
933: Not Collective
935: Input Parameters:
936: + e - integer associated with the event obtained from PetscLogEventRegister()
937: - o1,o2,o3,o4 - objects associated with the event, or 0
940: Fortran Synopsis:
941: void PetscLogEventBegin(int e,PetscErrorCode ierr)
943: Usage:
944: .vb
945: PetscLogEvent USER_EVENT;
946: PetscLogDouble user_event_flops;
947: PetscLogEventRegister("User event",0,&USER_EVENT);
948: PetscLogEventBegin(USER_EVENT,0,0,0,0);
949: [code segment to monitor]
950: PetscLogFlops(user_event_flops);
951: PetscLogEventEnd(USER_EVENT,0,0,0,0);
952: .ve
954: Notes:
955: You need to register each integer event with the command
956: PetscLogEventRegister(). The source code must be compiled with
957: -DPETSC_USE_LOG, which is the default.
959: PETSc automatically logs library events if the code has been
960: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
961: specified. PetscLogEventBegin() is intended for logging user events
962: to supplement this PETSc information.
964: Level: intermediate
966: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops()
968: .keywords: log, event, begin
969: M*/
971: /*MC
972: PetscLogEventEnd - Log the end of a user event.
974: Synopsis:
975: #include <petsclog.h>
976: PetscErrorCode PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)
978: Not Collective
980: Input Parameters:
981: + e - integer associated with the event obtained with PetscLogEventRegister()
982: - o1,o2,o3,o4 - objects associated with the event, or 0
985: Fortran Synopsis:
986: void PetscLogEventEnd(int e,PetscErrorCode ierr)
988: Usage:
989: .vb
990: PetscLogEvent USER_EVENT;
991: PetscLogDouble user_event_flops;
992: PetscLogEventRegister("User event",0,&USER_EVENT,);
993: PetscLogEventBegin(USER_EVENT,0,0,0,0);
994: [code segment to monitor]
995: PetscLogFlops(user_event_flops);
996: PetscLogEventEnd(USER_EVENT,0,0,0,0);
997: .ve
999: Notes:
1000: You should also register each additional integer event with the command
1001: PetscLogEventRegister(). Source code must be compiled with
1002: -DPETSC_USE_LOG, which is the default.
1004: PETSc automatically logs library events if the code has been
1005: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
1006: specified. PetscLogEventEnd() is intended for logging user events
1007: to supplement this PETSc information.
1009: Level: intermediate
1011: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogFlops()
1013: .keywords: log, event, end
1014: M*/
1016: /*MC
1017: PetscLogEventBarrierBegin - Logs the time in a barrier before an event.
1019: Synopsis:
1020: #include <petsclog.h>
1021: PetscErrorCode PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4,MPI_Comm comm)
1023: Not Collective
1025: Input Parameters:
1026: . e - integer associated with the event obtained from PetscLogEventRegister()
1027: . o1,o2,o3,o4 - objects associated with the event, or 0
1028: . comm - communicator the barrier takes place over
1031: Usage:
1032: .vb
1033: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
1034: MPI_Allreduce()
1035: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
1036: .ve
1038: Notes:
1039: This is for logging the amount of time spent in a barrier for an event
1040: that requires synchronization.
1042: Additional Notes:
1043: Synchronization events always come in pairs; for example, VEC_NormBarrier and
1044: VEC_NormComm = VEC_NormBarrier + 1
1046: Level: advanced
1048: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
1049: PetscLogEventBarrierEnd()
1051: .keywords: log, event, begin, barrier
1052: M*/
1054: /*MC
1055: PetscLogEventBarrierEnd - Logs the time in a barrier before an event.
1057: Synopsis:
1058: #include <petsclog.h>
1059: PetscErrorCode PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4,MPI_Comm comm)
1061: Logically Collective on MPI_Comm
1063: Input Parameters:
1064: . e - integer associated with the event obtained from PetscLogEventRegister()
1065: . o1,o2,o3,o4 - objects associated with the event, or 0
1066: . comm - communicator the barrier takes place over
1069: Usage:
1070: .vb
1071: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
1072: MPI_Allreduce()
1073: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
1074: .ve
1076: Notes:
1077: This is for logging the amount of time spent in a barrier for an event
1078: that requires synchronization.
1080: Additional Notes:
1081: Synchronization events always come in pairs; for example, VEC_NormBarrier and
1082: VEC_NormComm = VEC_NormBarrier + 1
1084: Level: advanced
1086: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
1087: PetscLogEventBarrierBegin()
1089: .keywords: log, event, begin, barrier
1090: M*/
1094: /*@C
1095: PetscLogEventGetId - Returns the event id when given the event name.
1097: Not Collective
1099: Input Parameter:
1100: . name - The event name
1102: Output Parameter:
1103: . event - The event
1105: Level: intermediate
1107: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStageGetId()
1108: @*/
1109: PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1110: {
1111: PetscStageLog stageLog;
1115: PetscLogGetStageLog(&stageLog);
1116: EventRegLogGetEvent(stageLog->eventLog, name, event);
1117: return(0);
1118: }
1121: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1124: /*@C
1125: PetscLogDump - Dumps logs of objects to a file. This file is intended to
1126: be read by bin/petscview. This program no longer exists.
1128: Collective on PETSC_COMM_WORLD
1130: Input Parameter:
1131: . name - an optional file name
1133: Options Database Keys:
1134: + -log - Prints basic log information (for code compiled with PETSC_USE_LOG)
1135: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
1137: Usage:
1138: .vb
1139: PetscInitialize(...);
1140: PetscLogBegin(); or PetscLogAllBegin();
1141: ... code ...
1142: PetscLogDump(filename);
1143: PetscFinalize();
1144: .ve
1146: Notes:
1147: The default file name is
1148: $ Log.<rank>
1149: where <rank> is the processor number. If no name is specified,
1150: this file will be used.
1152: Level: advanced
1154: .keywords: log, dump
1155: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogView()
1156: @*/
1157: PetscErrorCode PetscLogDump(const char sname[])
1158: {
1159: PetscStageLog stageLog;
1160: PetscEventPerfInfo *eventInfo;
1161: FILE *fd;
1162: char file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1163: PetscLogDouble flops, _TotalTime;
1164: PetscMPIInt rank;
1165: int action, object, curStage;
1166: PetscLogEvent event;
1167: PetscErrorCode ierr;
1170: /* Calculate the total elapsed time */
1171: PetscTime(&_TotalTime);
1172: _TotalTime -= petsc_BaseTime;
1173: /* Open log file */
1174: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1175: if (sname) sprintf(file, "%s.%d", sname, rank);
1176: else sprintf(file, "Log.%d", rank);
1177: PetscFixFilename(file, fname);
1178: PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1179: if ((!rank) && (!fd)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1180: /* Output totals */
1181: PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8e\n", petsc_TotalFlops, _TotalTime);
1182: PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0);
1183: /* Output actions */
1184: if (petsc_logActions) {
1185: PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", petsc_numActions);
1186: for (action = 0; action < petsc_numActions; action++) {
1187: PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n",
1188: petsc_actions[action].time, petsc_actions[action].action, (int)petsc_actions[action].event, (int)petsc_actions[action].classid, petsc_actions[action].id1,
1189: petsc_actions[action].id2, petsc_actions[action].id3, petsc_actions[action].flops, petsc_actions[action].mem, petsc_actions[action].maxmem);
1190: }
1191: }
1192: /* Output objects */
1193: if (petsc_logObjects) {
1194: PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", petsc_numObjects, petsc_numObjectsDestroyed);
1195: for (object = 0; object < petsc_numObjects; object++) {
1196: PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", petsc_objects[object].parent, (int) petsc_objects[object].mem);
1197: if (!petsc_objects[object].name[0]) {
1198: PetscFPrintf(PETSC_COMM_WORLD, fd,"No Name\n");
1199: } else {
1200: PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", petsc_objects[object].name);
1201: }
1202: if (petsc_objects[object].info[0] != 0) {
1203: PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n");
1204: } else {
1205: PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", petsc_objects[object].info);
1206: }
1207: }
1208: }
1209: /* Output events */
1210: PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:\n");
1211: PetscLogGetStageLog(&stageLog);
1212: PetscIntStackTop(stageLog->stack, &curStage);
1213: eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1214: for (event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1215: if (eventInfo[event].time != 0.0) flops = eventInfo[event].flops/eventInfo[event].time;
1216: else flops = 0.0;
1217: PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16g\n", event, eventInfo[event].count,
1218: eventInfo[event].flops, eventInfo[event].time, flops);
1219: }
1220: PetscFClose(PETSC_COMM_WORLD, fd);
1221: return(0);
1222: }
1226: /*
1227: PetscLogView_Detailed - Each process prints the times for its own events
1229: */
1230: PetscErrorCode PetscLogView_Detailed(PetscViewer viewer)
1231: {
1232: PetscErrorCode ierr;
1233: PetscLogDouble locTotalTime;
1234: PetscMPIInt rank,size;
1235: PetscStageLog stageLog;
1236: int numStages, numEvents,stage,event;
1237: MPI_Comm comm = PetscObjectComm((PetscObject)viewer);
1238: PetscEventPerfInfo *eventInfo = NULL;
1241: MPI_Comm_size(comm, &size);
1242: MPI_Comm_rank(comm, &rank);
1243: /* Get the total elapsed time */
1244: PetscTime(&locTotalTime); locTotalTime -= petsc_BaseTime;
1245: PetscViewerASCIIPrintf(viewer,"numProces = %d\n",size);
1246: PetscViewerASCIIPrintf(viewer,"LocalTimes = {}\n");
1247: PetscViewerASCIIPrintf(viewer,"LocalFlops = {}\n");
1248: PetscViewerASCIIPrintf(viewer,"LocalMessageLens = {}\n");
1249: PetscViewerASCIIPrintf(viewer,"LocalMessages = {}\n");
1250: PetscViewerASCIIPrintf(viewer,"LocalReductions = {}\n");
1251: PetscLogGetStageLog(&stageLog);
1252: MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1253: PetscViewerASCIIPrintf(viewer,"Stages = {}\n");
1254: for (stage=0; stage<numStages; stage++) {
1255: PetscViewerASCIIPrintf(viewer,"Stages[\"%s\"] = {}\n",stageLog->stageInfo[stage].name);
1256: MPI_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1257: for (event = 0; event < numEvents; event++) {
1258: PetscViewerASCIIPrintf(viewer,"Stages[\"%s\"][\"%s\"] = {}\n",stageLog->stageInfo[stage].name,stageLog->eventLog->eventInfo[event].name);
1259: }
1260: }
1261: PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);
1262: PetscViewerASCIISynchronizedPrintf(viewer,"LocalTimes[%d] = %g\n",rank,locTotalTime);
1263: PetscViewerASCIISynchronizedPrintf(viewer,"LocalFlops[%d] = %g\n",rank,petsc_TotalFlops);
1264: PetscViewerASCIISynchronizedPrintf(viewer,"LocalMessageLens[%d] = %g\n",rank,(petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len));
1265: PetscViewerASCIISynchronizedPrintf(viewer,"LocalMessages[%d] = %g\n",rank,(petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct));
1266: PetscViewerASCIISynchronizedPrintf(viewer,"LocalReductions[%d] = %g\n",rank,petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct);
1267: PetscViewerFlush(viewer);
1268: for (stage=0; stage<numStages; stage++) {
1269: MPI_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1270: for (event = 0; event < numEvents; event++) {
1271: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1272: PetscViewerASCIISynchronizedPrintf(viewer,"Stages[\"%s\"][\"%s\"][%d] = {\"count\" : %D, \"time\" : %g, \"numMessages\" : %g, \"messageLength\" : %g, \"numReductions\" : %g, \"flops\" : %g}\n",stageLog->stageInfo[stage].name,stageLog->eventLog->eventInfo[event].name,rank,
1273: eventInfo[event].count, eventInfo[event].time,eventInfo[event].numMessages, eventInfo[event].messageLength,
1274: eventInfo[event].numReductions,eventInfo[event].flops);
1275: }
1276: }
1277: PetscViewerFlush(viewer);
1278: PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);
1279: return(0);
1280: }
1284: PetscErrorCode PetscLogView_Default(PetscViewer viewer)
1285: {
1286: FILE *fd;
1287: PetscLogDouble zero = 0.0;
1288: PetscStageLog stageLog;
1289: PetscStageInfo *stageInfo = NULL;
1290: PetscEventPerfInfo *eventInfo = NULL;
1291: PetscClassPerfInfo *classInfo;
1292: char arch[128],hostname[128],username[128],pname[PETSC_MAX_PATH_LEN],date[128];
1293: const char *name;
1294: PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1295: PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1296: PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1297: PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1298: PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1299: PetscLogDouble min, max, tot, ratio, avg, x, y;
1300: PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1301: PetscMPIInt minCt, maxCt;
1302: PetscMPIInt size, rank;
1303: PetscBool *localStageUsed, *stageUsed;
1304: PetscBool *localStageVisible, *stageVisible;
1305: int numStages, localNumEvents, numEvents;
1306: int stage, oclass;
1307: PetscLogEvent event;
1308: PetscErrorCode ierr;
1309: char version[256];
1310: MPI_Comm comm;
1311: PetscInt nthreads;
1314: PetscObjectGetComm((PetscObject)viewer,&comm);
1315: PetscViewerASCIIGetPointer(viewer,&fd);
1316: MPI_Comm_size(comm, &size);
1317: MPI_Comm_rank(comm, &rank);
1318: /* Get the total elapsed time */
1319: PetscTime(&locTotalTime); locTotalTime -= petsc_BaseTime;
1321: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1322: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***\n");
1323: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1324: PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1325: PetscGetArchType(arch,sizeof(arch));
1326: PetscGetHostName(hostname,sizeof(hostname));
1327: PetscGetUserName(username,sizeof(username));
1328: PetscGetProgramName(pname,sizeof(pname));
1329: PetscGetDate(date,sizeof(date));
1330: PetscGetVersion(version,sizeof(version));
1331: if (size == 1) {
1332: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1333: } else {
1334: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1335: }
1336: PetscThreadCommGetNThreads(PETSC_COMM_WORLD,&nthreads);
1337: if (nthreads > 1) {
1338: PetscFPrintf(comm,fd,"With %d threads per MPI_Comm\n", (int)nthreads);
1339: }
1341: PetscFPrintf(comm, fd, "Using %s\n", version);
1343: /* Must preserve reduction count before we go on */
1344: red = petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
1346: /* Calculate summary information */
1347: PetscFPrintf(comm, fd, "\n Max Max/Min Avg Total \n");
1348: /* Time */
1349: MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1350: MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1351: MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1352: avg = (tot)/((PetscLogDouble) size);
1353: if (min != 0.0) ratio = max/min;
1354: else ratio = 0.0;
1355: PetscFPrintf(comm, fd, "Time (sec): %5.3e %10.5f %5.3e\n", max, ratio, avg);
1356: TotalTime = tot;
1357: /* Objects */
1358: avg = (PetscLogDouble) petsc_numObjects;
1359: MPI_Allreduce(&avg, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1360: MPI_Allreduce(&avg, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1361: MPI_Allreduce(&avg, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1362: avg = (tot)/((PetscLogDouble) size);
1363: if (min != 0.0) ratio = max/min;
1364: else ratio = 0.0;
1365: PetscFPrintf(comm, fd, "Objects: %5.3e %10.5f %5.3e\n", max, ratio, avg);
1366: /* Flops */
1367: MPI_Allreduce(&petsc_TotalFlops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1368: MPI_Allreduce(&petsc_TotalFlops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1369: MPI_Allreduce(&petsc_TotalFlops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1370: avg = (tot)/((PetscLogDouble) size);
1371: if (min != 0.0) ratio = max/min;
1372: else ratio = 0.0;
1373: PetscFPrintf(comm, fd, "Flops: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1374: TotalFlops = tot;
1375: /* Flops/sec -- Must talk to Barry here */
1376: if (locTotalTime != 0.0) flops = petsc_TotalFlops/locTotalTime;
1377: else flops = 0.0;
1378: MPI_Allreduce(&flops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1379: MPI_Allreduce(&flops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1380: MPI_Allreduce(&flops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1381: avg = (tot)/((PetscLogDouble) size);
1382: if (min != 0.0) ratio = max/min;
1383: else ratio = 0.0;
1384: PetscFPrintf(comm, fd, "Flops/sec: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1385: /* Memory */
1386: PetscMallocGetMaximumUsage(&mem);
1387: if (mem > 0.0) {
1388: MPI_Allreduce(&mem, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1389: MPI_Allreduce(&mem, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1390: MPI_Allreduce(&mem, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1391: avg = (tot)/((PetscLogDouble) size);
1392: if (min != 0.0) ratio = max/min;
1393: else ratio = 0.0;
1394: PetscFPrintf(comm, fd, "Memory: %5.3e %10.5f %5.3e\n", max, ratio, tot);
1395: }
1396: /* Messages */
1397: mess = 0.5*(petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct);
1398: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1399: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1400: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1401: avg = (tot)/((PetscLogDouble) size);
1402: if (min != 0.0) ratio = max/min;
1403: else ratio = 0.0;
1404: PetscFPrintf(comm, fd, "MPI Messages: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1405: numMessages = tot;
1406: /* Message Lengths */
1407: mess = 0.5*(petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len);
1408: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1409: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1410: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1411: if (numMessages != 0) avg = (tot)/(numMessages);
1412: else avg = 0.0;
1413: if (min != 0.0) ratio = max/min;
1414: else ratio = 0.0;
1415: PetscFPrintf(comm, fd, "MPI Message Lengths: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1416: messageLength = tot;
1417: /* Reductions */
1418: MPI_Allreduce(&red, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1419: MPI_Allreduce(&red, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1420: MPI_Allreduce(&red, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1421: if (min != 0.0) ratio = max/min;
1422: else ratio = 0.0;
1423: PetscFPrintf(comm, fd, "MPI Reductions: %5.3e %10.5f\n", max, ratio);
1424: numReductions = red; /* wrong because uses count from process zero */
1425: PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");
1426: PetscFPrintf(comm, fd, " e.g., VecAXPY() for real vectors of length N --> 2N flops\n");
1427: PetscFPrintf(comm, fd, " and VecAXPY() for complex vectors of length N --> 8N flops\n");
1429: /* Get total number of stages --
1430: Currently, a single processor can register more stages than another, but stages must all be registered in order.
1431: We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1432: This seems best accomplished by assoicating a communicator with each stage.
1433: */
1434: PetscLogGetStageLog(&stageLog);
1435: MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1436: PetscMalloc1(numStages, &localStageUsed);
1437: PetscMalloc1(numStages, &stageUsed);
1438: PetscMalloc1(numStages, &localStageVisible);
1439: PetscMalloc1(numStages, &stageVisible);
1440: if (numStages > 0) {
1441: stageInfo = stageLog->stageInfo;
1442: for (stage = 0; stage < numStages; stage++) {
1443: if (stage < stageLog->numStages) {
1444: localStageUsed[stage] = stageInfo[stage].used;
1445: localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1446: } else {
1447: localStageUsed[stage] = PETSC_FALSE;
1448: localStageVisible[stage] = PETSC_TRUE;
1449: }
1450: }
1451: MPI_Allreduce(localStageUsed, stageUsed, numStages, MPIU_BOOL, MPI_LOR, comm);
1452: MPI_Allreduce(localStageVisible, stageVisible, numStages, MPIU_BOOL, MPI_LAND, comm);
1453: for (stage = 0; stage < numStages; stage++) {
1454: if (stageUsed[stage]) {
1455: PetscFPrintf(comm, fd, "\nSummary of Stages: ----- Time ------ ----- Flops ----- --- Messages --- -- Message Lengths -- -- Reductions --\n");
1456: PetscFPrintf(comm, fd, " Avg %%Total Avg %%Total counts %%Total Avg %%Total counts %%Total \n");
1457: break;
1458: }
1459: }
1460: for (stage = 0; stage < numStages; stage++) {
1461: if (!stageUsed[stage]) continue;
1462: if (localStageUsed[stage]) {
1463: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1464: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1465: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1466: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1467: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1468: name = stageInfo[stage].name;
1469: } else {
1470: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1471: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1472: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1473: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1474: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1475: name = "";
1476: }
1477: mess *= 0.5; messLen *= 0.5; red /= size;
1478: if (TotalTime != 0.0) fracTime = stageTime/TotalTime; else fracTime = 0.0;
1479: if (TotalFlops != 0.0) fracFlops = flops/TotalFlops; else fracFlops = 0.0;
1480: /* Talk to Barry if (stageTime != 0.0) flops = (size*flops)/stageTime; else flops = 0.0; */
1481: if (numMessages != 0.0) fracMessages = mess/numMessages; else fracMessages = 0.0;
1482: if (numMessages != 0.0) avgMessLen = messLen/numMessages; else avgMessLen = 0.0;
1483: if (messageLength != 0.0) fracLength = messLen/messageLength; else fracLength = 0.0;
1484: if (numReductions != 0.0) fracReductions = red/numReductions; else fracReductions = 0.0;
1485: 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",
1486: stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1487: mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1488: }
1489: }
1491: PetscFPrintf(comm, fd,"\n------------------------------------------------------------------------------------------------------------------------\n");
1492: PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1493: PetscFPrintf(comm, fd, "Phase summary info:\n");
1494: PetscFPrintf(comm, fd, " Count: number of times phase was executed\n");
1495: PetscFPrintf(comm, fd, " Time and Flops: Max - maximum over all processors\n");
1496: PetscFPrintf(comm, fd, " Ratio - ratio of maximum to minimum over all processors\n");
1497: PetscFPrintf(comm, fd, " Mess: number of messages sent\n");
1498: PetscFPrintf(comm, fd, " Avg. len: average message length (bytes)\n");
1499: PetscFPrintf(comm, fd, " Reduct: number of global reductions\n");
1500: PetscFPrintf(comm, fd, " Global: entire computation\n");
1501: PetscFPrintf(comm, fd, " Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");
1502: PetscFPrintf(comm, fd, " %%T - percent time in this phase %%F - percent flops in this phase\n");
1503: PetscFPrintf(comm, fd, " %%M - percent messages in this phase %%L - percent message lengths in this phase\n");
1504: PetscFPrintf(comm, fd, " %%R - percent reductions in this phase\n");
1505: PetscFPrintf(comm, fd, " Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)\n");
1506: PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------\n");
1508: #if defined(PETSC_USE_DEBUG)
1509: PetscFPrintf(comm, fd, "\n\n");
1510: PetscFPrintf(comm, fd, " ##########################################################\n");
1511: PetscFPrintf(comm, fd, " # #\n");
1512: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1513: PetscFPrintf(comm, fd, " # #\n");
1514: PetscFPrintf(comm, fd, " # This code was compiled with a debugging option, #\n");
1515: PetscFPrintf(comm, fd, " # To get timing results run ./configure #\n");
1516: PetscFPrintf(comm, fd, " # using --with-debugging=no, the performance will #\n");
1517: PetscFPrintf(comm, fd, " # be generally two or three times faster. #\n");
1518: PetscFPrintf(comm, fd, " # #\n");
1519: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1520: #endif
1521: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1522: PetscFPrintf(comm, fd, "\n\n");
1523: PetscFPrintf(comm, fd, " ##########################################################\n");
1524: PetscFPrintf(comm, fd, " # #\n");
1525: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1526: PetscFPrintf(comm, fd, " # #\n");
1527: PetscFPrintf(comm, fd, " # The code for various complex numbers numerical #\n");
1528: PetscFPrintf(comm, fd, " # kernels uses C++, which generally is not well #\n");
1529: PetscFPrintf(comm, fd, " # optimized. For performance that is about 4-5 times #\n");
1530: PetscFPrintf(comm, fd, " # faster, specify --with-fortran-kernels=1 #\n");
1531: PetscFPrintf(comm, fd, " # when running ./configure.py. #\n");
1532: PetscFPrintf(comm, fd, " # #\n");
1533: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1534: #endif
1536: /* Report events */
1537: PetscFPrintf(comm, fd,"Event Count Time (sec) Flops --- Global --- --- Stage --- Total\n");
1538: PetscFPrintf(comm, fd," Max Ratio Max Ratio Max Ratio Mess Avg len Reduct %%T %%F %%M %%L %%R %%T %%F %%M %%L %%R Mflop/s\n");
1539: PetscFPrintf(comm,fd,"------------------------------------------------------------------------------------------------------------------------\n");
1541: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1542: for (stage = 0; stage < numStages; stage++) {
1543: if (!stageVisible[stage]) continue;
1544: if (localStageUsed[stage]) {
1545: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1546: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1547: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1548: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1549: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1550: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1551: } else {
1552: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1553: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1554: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1555: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1556: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1557: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1558: }
1559: mess *= 0.5; messLen *= 0.5; red /= size;
1561: /* Get total number of events in this stage --
1562: Currently, a single processor can register more events than another, but events must all be registered in order,
1563: just like stages. We can removed this requirement if necessary by having a global event numbering and indirection
1564: on the event ID. This seems best accomplished by assoicating a communicator with each stage.
1566: Problem: If the event did not happen on proc 1, its name will not be available.
1567: Problem: Event visibility is not implemented
1568: */
1569: if (localStageUsed[stage]) {
1570: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1571: localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1572: } else localNumEvents = 0;
1573: MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1574: for (event = 0; event < numEvents; event++) {
1575: if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) {
1576: if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) flopr = eventInfo[event].flops;
1577: else flopr = 0.0;
1579: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1580: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1581: MPI_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1582: MPI_Allreduce(&eventInfo[event].time, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1583: MPI_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1584: MPI_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1585: MPI_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1586: MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1587: MPI_Allreduce(&eventInfo[event].numReductions, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1588: MPI_Allreduce(&eventInfo[event].count, &minCt, 1, MPI_INT, MPI_MIN, comm);
1589: MPI_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1590: name = stageLog->eventLog->eventInfo[event].name;
1591: } else {
1592: flopr = 0.0;
1593: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1594: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1595: MPI_Allreduce(&zero, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1596: MPI_Allreduce(&zero, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1597: MPI_Allreduce(&zero, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1598: MPI_Allreduce(&zero, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1599: MPI_Allreduce(&zero, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1600: MPI_Allreduce(&zero, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1601: MPI_Allreduce(&zero, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1602: MPI_Allreduce(&ierr, &minCt, 1, MPI_INT, MPI_MIN, comm);
1603: MPI_Allreduce(&ierr, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1604: name = "";
1605: }
1606: if (mint < 0.0) {
1607: PetscFPrintf(comm, fd, "WARNING!!! Minimum time %g over all processors for %s is negative! This happens\n on some machines whose times cannot handle too rapid calls.!\n artificially changing minimum to zero.\n",mint,name);
1608: mint = 0;
1609: }
1610: if (minf < 0.0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Minimum flops %g over all processors for %s is negative! Not possible!",minf,name);
1611: totm *= 0.5; totml *= 0.5; totr /= size;
1613: if (maxCt != 0) {
1614: if (minCt != 0) ratCt = ((PetscLogDouble) maxCt)/minCt; else ratCt = 0.0;
1615: if (mint != 0.0) ratt = maxt/mint; else ratt = 0.0;
1616: if (minf != 0.0) ratf = maxf/minf; else ratf = 0.0;
1617: if (TotalTime != 0.0) fracTime = tott/TotalTime; else fracTime = 0.0;
1618: if (TotalFlops != 0.0) fracFlops = totf/TotalFlops; else fracFlops = 0.0;
1619: if (stageTime != 0.0) fracStageTime = tott/stageTime; else fracStageTime = 0.0;
1620: if (flops != 0.0) fracStageFlops = totf/flops; else fracStageFlops = 0.0;
1621: if (numMessages != 0.0) fracMess = totm/numMessages; else fracMess = 0.0;
1622: if (messageLength != 0.0) fracMessLen = totml/messageLength; else fracMessLen = 0.0;
1623: if (numReductions != 0.0) fracRed = totr/numReductions; else fracRed = 0.0;
1624: if (mess != 0.0) fracStageMess = totm/mess; else fracStageMess = 0.0;
1625: if (messLen != 0.0) fracStageMessLen = totml/messLen; else fracStageMessLen = 0.0;
1626: if (red != 0.0) fracStageRed = totr/red; else fracStageRed = 0.0;
1627: if (totm != 0.0) totml /= totm; else totml = 0.0;
1628: if (maxt != 0.0) flopr = totf/maxt; else flopr = 0.0;
1629: if (fracStageTime > 1.00) PetscFPrintf(comm, fd,"Warning -- total time of even greater than time of entire stage -- something is wrong with the timer\n");
1630: PetscFPrintf(comm, fd,
1631: "%-16s %7d%4.1f %5.4e%4.1f %3.2e%4.1f %2.1e %2.1e %2.1e%3.0f%3.0f%3.0f%3.0f%3.0f %3.0f%3.0f%3.0f%3.0f%3.0f %5.0f\n",
1632: name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1633: 100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1634: 100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1635: PetscAbsReal(flopr/1.0e6));
1636: }
1637: }
1638: }
1640: /* Memory usage and object creation */
1641: PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------\n");
1642: PetscFPrintf(comm, fd, "\n");
1643: PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");
1645: /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1646: the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1647: stats for stages local to processor sets.
1648: */
1649: /* We should figure out the longest object name here (now 20 characters) */
1650: PetscFPrintf(comm, fd, "Object Type Creations Destructions Memory Descendants' Mem.\n");
1651: PetscFPrintf(comm, fd, "Reports information only for process 0.\n");
1652: for (stage = 0; stage < numStages; stage++) {
1653: if (localStageUsed[stage]) {
1654: classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1655: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1656: for (oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1657: if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1658: PetscFPrintf(comm, fd, "%20s %5d %5d %11.0f %g\n", stageLog->classLog->classInfo[oclass].name,
1659: classInfo[oclass].creations, classInfo[oclass].destructions, classInfo[oclass].mem,
1660: classInfo[oclass].descMem);
1661: }
1662: }
1663: } else {
1664: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1665: }
1666: }
1668: PetscFree(localStageUsed);
1669: PetscFree(stageUsed);
1670: PetscFree(localStageVisible);
1671: PetscFree(stageVisible);
1673: /* Information unrelated to this particular run */
1674: PetscFPrintf(comm, fd, "========================================================================================================================\n");
1675: PetscTime(&y);
1676: PetscTime(&x);
1677: PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1678: PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1679: PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1680: /* MPI information */
1681: if (size > 1) {
1682: MPI_Status status;
1683: PetscMPIInt tag;
1684: MPI_Comm newcomm;
1686: MPI_Barrier(comm);
1687: PetscTime(&x);
1688: MPI_Barrier(comm);
1689: MPI_Barrier(comm);
1690: MPI_Barrier(comm);
1691: MPI_Barrier(comm);
1692: MPI_Barrier(comm);
1693: PetscTime(&y);
1694: PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1695: PetscCommDuplicate(comm,&newcomm, &tag);
1696: MPI_Barrier(comm);
1697: if (rank) {
1698: MPI_Recv(0, 0, MPI_INT, rank-1, tag, newcomm, &status);
1699: MPI_Send(0, 0, MPI_INT, (rank+1)%size, tag, newcomm);
1700: } else {
1701: PetscTime(&x);
1702: MPI_Send(0, 0, MPI_INT, 1, tag, newcomm);
1703: MPI_Recv(0, 0, MPI_INT, size-1, tag, newcomm, &status);
1704: PetscTime(&y);
1705: PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1706: }
1707: PetscCommDestroy(&newcomm);
1708: }
1709: PetscOptionsView(viewer);
1711: /* Machine and compile information */
1712: #if defined(PETSC_USE_FORTRAN_KERNELS)
1713: PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1714: #else
1715: PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1716: #endif
1717: #if defined(PETSC_USE_REAL_SINGLE)
1718: PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");
1719: #elif defined(PETSC_USE_LONGDOUBLE)
1720: PetscFPrintf(comm, fd, "Compiled with long double precision PetscScalar and PetscReal\n");
1721: #endif
1723: #if defined(PETSC_USE_REAL_MAT_SINGLE)
1724: PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1725: #else
1726: PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");
1727: #endif
1728: PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d sizeof(PetscInt) %d\n",
1729: (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar),(int) sizeof(PetscInt));
1731: PetscFPrintf(comm, fd, "Configure run at: %s\n",petscconfigureruntime);
1732: PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);
1733: PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1734: PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1735: PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1736: PetscFPrintf(comm, fd, "%s", petsclinkerinfo);
1738: /* Cleanup */
1739: PetscFPrintf(comm, fd, "\n");
1740: return(0);
1741: }
1745: /*@C
1746: PetscLogViewer - Prints a summary of the logging.
1748: Collective over MPI_Comm
1750: Input Parameter:
1751: . viewer - an ASCII viewer
1753: Options Database Keys:
1754: . -log_view [viewertype[:filename[:format]]] - Prints summary of log information (for code compiled with PETSC_USE_LOG)
1756: Usage:
1757: .vb
1758: PetscInitialize(...);
1759: PetscLogBegin();
1760: ... code ...
1761: PetscLogView(PetscViewer);
1762: PetscFinalize(...);
1763: .ve
1765: Notes:
1766: By default the summary is printed to stdout.
1768: Level: beginner
1770: .keywords: log, dump, print
1771: .seealso: PetscLogBegin(), PetscLogDump()
1772: @*/
1773: PetscErrorCode PetscLogView(PetscViewer viewer)
1774: {
1775: PetscErrorCode ierr;
1776: PetscBool isascii;
1777: PetscViewerFormat format;
1778: int stage, lastStage;
1779: PetscStageLog stageLog;
1782: if (!PetscLogBegin_PrivateCalled) SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_ORDER, "No call to PetscLogBegin() before PetscLogView()");
1783: /* Pop off any stages the user forgot to remove */
1784: lastStage = 0;
1785: PetscLogGetStageLog(&stageLog);
1786: PetscStageLogGetCurrent(stageLog, &stage);
1787: while (stage >= 0) {
1788: lastStage = stage;
1789: PetscStageLogPop(stageLog);
1790: PetscStageLogGetCurrent(stageLog, &stage);
1791: }
1792: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
1793: if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Currently can only view logging to ASCII");
1794: PetscViewerGetFormat(viewer,&format);
1795: if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO) {
1796: PetscLogView_Default(viewer);
1797: } else if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1798: PetscLogView_Detailed(viewer);
1799: }
1800: PetscStageLogPush(stageLog, lastStage);
1801: return(0);
1802: }
1806: /*@C
1807: PetscLogViewFromOptions - Processes command line options to determine if/how a PetscLog is to be viewed.
1809: Collective on PETSC_COMM_WORLD
1811: Not normally called by user
1813: Level: intermediate
1815: @*/
1816: PetscErrorCode PetscLogViewFromOptions(void)
1817: {
1818: PetscErrorCode ierr;
1819: PetscViewer viewer;
1820: PetscBool flg;
1821: PetscViewerFormat format;
1824: PetscOptionsGetViewer(PETSC_COMM_WORLD,NULL,"-log_view",&viewer,&format,&flg);
1825: if (flg) {
1826: PetscViewerPushFormat(viewer,format);
1827: PetscLogView(viewer);
1828: PetscViewerPopFormat(viewer);
1829: PetscViewerDestroy(&viewer);
1830: }
1831: return(0);
1832: }
1836: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1839: /*@C
1840: PetscGetFlops - Returns the number of flops used on this processor
1841: since the program began.
1843: Not Collective
1845: Output Parameter:
1846: flops - number of floating point operations
1848: Notes:
1849: A global counter logs all PETSc flop counts. The user can use
1850: PetscLogFlops() to increment this counter to include flops for the
1851: application code.
1853: PETSc automatically logs library events if the code has been
1854: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1855: -log_summary, or -log_all are specified. PetscLogFlops() is
1856: intended for logging user flops to supplement this PETSc
1857: information.
1859: Level: intermediate
1861: .keywords: log, flops, floating point operations
1863: .seealso: PetscTime(), PetscLogFlops()
1864: @*/
1865: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
1866: {
1868: *flops = petsc_TotalFlops;
1869: return(0);
1870: }
1874: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
1875: {
1877: size_t fullLength;
1878: va_list Argp;
1881: if (!petsc_logObjects) return(0);
1882: va_start(Argp, format);
1883: PetscVSNPrintf(petsc_objects[obj->id].info, 64,format,&fullLength, Argp);
1884: va_end(Argp);
1885: return(0);
1886: }
1889: /*MC
1890: PetscLogFlops - Adds floating point operations to the global counter.
1892: Synopsis:
1893: #include <petsclog.h>
1894: PetscErrorCode PetscLogFlops(PetscLogDouble f)
1896: Not Collective
1898: Input Parameter:
1899: . f - flop counter
1902: Usage:
1903: .vb
1904: PetscLogEvent USER_EVENT;
1905: PetscLogEventRegister("User event",0,&USER_EVENT);
1906: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1907: [code segment to monitor]
1908: PetscLogFlops(user_flops)
1909: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1910: .ve
1912: Notes:
1913: A global counter logs all PETSc flop counts. The user can use
1914: PetscLogFlops() to increment this counter to include flops for the
1915: application code.
1917: PETSc automatically logs library events if the code has been
1918: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1919: -log_summary, or -log_all are specified. PetscLogFlops() is
1920: intended for logging user flops to supplement this PETSc
1921: information.
1923: Level: intermediate
1925: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()
1927: .keywords: log, flops, floating point operations
1928: M*/
1930: /*MC
1931: PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1932: to get accurate timings
1934: Synopsis:
1935: #include <petsclog.h>
1936: void PetscPreLoadBegin(PetscBool flag,char *name);
1938: Not Collective
1940: Input Parameter:
1941: + flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1942: with command line option -preload true or -preload false
1943: - name - name of first stage (lines of code timed separately with -log_summary) to
1944: be preloaded
1946: Usage:
1947: .vb
1948: PetscPreLoadBegin(PETSC_TRUE,"first stage);
1949: lines of code
1950: PetscPreLoadStage("second stage");
1951: lines of code
1952: PetscPreLoadEnd();
1953: .ve
1955: Notes: Only works in C/C++, not Fortran
1957: Flags available within the macro.
1958: + PetscPreLoadingUsed - true if we are or have done preloading
1959: . PetscPreLoadingOn - true if it is CURRENTLY doing preload
1960: . PetscPreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
1961: - PetscPreLoadMax - number of times it will do the computation, only one when preloading is turned on
1962: The first two variables are available throughout the program, the second two only between the PetscPreLoadBegin()
1963: and PetscPreLoadEnd()
1965: Level: intermediate
1967: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadEnd(), PetscPreLoadStage()
1969: Concepts: preloading
1970: Concepts: timing^accurate
1971: Concepts: paging^eliminating effects of
1974: M*/
1976: /*MC
1977: PetscPreLoadEnd - End a segment of code that may be preloaded (run twice)
1978: to get accurate timings
1980: Synopsis:
1981: #include <petsclog.h>
1982: void PetscPreLoadEnd(void);
1984: Not Collective
1986: Usage:
1987: .vb
1988: PetscPreLoadBegin(PETSC_TRUE,"first stage);
1989: lines of code
1990: PetscPreLoadStage("second stage");
1991: lines of code
1992: PetscPreLoadEnd();
1993: .ve
1995: Notes: only works in C/C++ not fortran
1997: Level: intermediate
1999: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadStage()
2001: M*/
2003: /*MC
2004: PetscPreLoadStage - Start a new segment of code to be timed separately.
2005: to get accurate timings
2007: Synopsis:
2008: #include <petsclog.h>
2009: void PetscPreLoadStage(char *name);
2011: Not Collective
2013: Usage:
2014: .vb
2015: PetscPreLoadBegin(PETSC_TRUE,"first stage);
2016: lines of code
2017: PetscPreLoadStage("second stage");
2018: lines of code
2019: PetscPreLoadEnd();
2020: .ve
2022: Notes: only works in C/C++ not fortran
2024: Level: intermediate
2026: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd()
2028: M*/
2031: #else /* end of -DPETSC_USE_LOG section */
2035: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2036: {
2038: return(0);
2039: }
2041: #endif /* PETSC_USE_LOG*/
2044: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2045: PetscClassId PETSC_OBJECT_CLASSID = 0;
2049: /*@C
2050: PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code.
2052: Not Collective
2054: Input Parameter:
2055: . name - The class name
2057: Output Parameter:
2058: . oclass - The class id or classid
2060: Level: developer
2062: .keywords: log, class, register
2064: @*/
2065: PetscErrorCode PetscClassIdRegister(const char name[],PetscClassId *oclass)
2066: {
2067: #if defined(PETSC_USE_LOG)
2068: PetscStageLog stageLog;
2069: PetscInt stage;
2071: #endif
2074: *oclass = ++PETSC_LARGEST_CLASSID;
2075: #if defined(PETSC_USE_LOG)
2076: PetscLogGetStageLog(&stageLog);
2077: PetscClassRegLogRegister(stageLog->classLog, name, *oclass);
2078: for (stage = 0; stage < stageLog->numStages; stage++) {
2079: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
2080: }
2081: #endif
2082: return(0);
2083: }
2085: #if defined(PETSC_USE_LOG) && defined(PETSC_HAVE_MPE)
2086: #include <mpe.h>
2088: PetscBool PetscBeganMPE = PETSC_FALSE;
2090: PETSC_INTERN PetscErrorCode PetscLogEventBeginMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
2091: PETSC_INTERN PetscErrorCode PetscLogEventEndMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
2095: /*@C
2096: PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files
2097: and slows the program down.
2099: Collective over PETSC_COMM_WORLD
2101: Options Database Keys:
2102: . -log_mpe - Prints extensive log information (for code compiled with PETSC_USE_LOG)
2104: Notes:
2105: A related routine is PetscLogBegin() (with the options key -log_summary), which is
2106: intended for production runs since it logs only flop rates and object
2107: creation (and should not significantly slow the programs).
2109: Level: advanced
2111: Concepts: logging^MPE
2112: Concepts: logging^message passing
2114: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogAllBegin(), PetscLogEventActivate(),
2115: PetscLogEventDeactivate()
2116: @*/
2117: PetscErrorCode PetscLogMPEBegin(void)
2118: {
2122: /* Do MPE initialization */
2123: if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
2124: PetscInfo(0,"Initializing MPE.\n");
2125: MPE_Init_log();
2127: PetscBeganMPE = PETSC_TRUE;
2128: } else {
2129: PetscInfo(0,"MPE already initialized. Not attempting to reinitialize.\n");
2130: }
2131: PetscLogSet(PetscLogEventBeginMPE, PetscLogEventEndMPE);
2132: return(0);
2133: }
2137: /*@C
2138: PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.
2140: Collective over PETSC_COMM_WORLD
2142: Level: advanced
2144: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogMPEBegin()
2145: @*/
2146: PetscErrorCode PetscLogMPEDump(const char sname[])
2147: {
2148: char name[PETSC_MAX_PATH_LEN];
2152: if (PetscBeganMPE) {
2153: PetscInfo(0,"Finalizing MPE.\n");
2154: if (sname) {
2155: PetscStrcpy(name,sname);
2156: } else {
2157: PetscGetProgramName(name,PETSC_MAX_PATH_LEN);
2158: }
2159: MPE_Finish_log(name);
2160: } else {
2161: PetscInfo(0,"Not finalizing MPE (not started by PETSc).\n");
2162: }
2163: return(0);
2164: }
2166: #define PETSC_RGB_COLORS_MAX 39
2167: static const char *PetscLogMPERGBColors[PETSC_RGB_COLORS_MAX] = {
2168: "OliveDrab: ",
2169: "BlueViolet: ",
2170: "CadetBlue: ",
2171: "CornflowerBlue: ",
2172: "DarkGoldenrod: ",
2173: "DarkGreen: ",
2174: "DarkKhaki: ",
2175: "DarkOliveGreen: ",
2176: "DarkOrange: ",
2177: "DarkOrchid: ",
2178: "DarkSeaGreen: ",
2179: "DarkSlateGray: ",
2180: "DarkTurquoise: ",
2181: "DeepPink: ",
2182: "DarkKhaki: ",
2183: "DimGray: ",
2184: "DodgerBlue: ",
2185: "GreenYellow: ",
2186: "HotPink: ",
2187: "IndianRed: ",
2188: "LavenderBlush: ",
2189: "LawnGreen: ",
2190: "LemonChiffon: ",
2191: "LightCoral: ",
2192: "LightCyan: ",
2193: "LightPink: ",
2194: "LightSalmon: ",
2195: "LightSlateGray: ",
2196: "LightYellow: ",
2197: "LimeGreen: ",
2198: "MediumPurple: ",
2199: "MediumSeaGreen: ",
2200: "MediumSlateBlue:",
2201: "MidnightBlue: ",
2202: "MintCream: ",
2203: "MistyRose: ",
2204: "NavajoWhite: ",
2205: "NavyBlue: ",
2206: "OliveDrab: "
2207: };
2211: /*@C
2212: PetscLogMPEGetRGBColor - This routine returns a rgb color useable with PetscLogEventRegister()
2214: Not collective. Maybe it should be?
2216: Output Parameter
2217: . str - character string representing the color
2219: Level: developer
2221: .keywords: log, mpe , color
2222: .seealso: PetscLogEventRegister
2223: @*/
2224: PetscErrorCode PetscLogMPEGetRGBColor(const char *str[])
2225: {
2226: static int idx = 0;
2229: *str = PetscLogMPERGBColors[idx];
2230: idx = (idx + 1)% PETSC_RGB_COLORS_MAX;
2231: return(0);
2232: }
2234: #endif /* PETSC_USE_LOG && PETSC_HAVE_MPE */