Actual source code: stagelog.c
2: /*
3: This defines part of the private API for logging performance information. It is intended to be used only by the
4: PETSc PetscLog...() interface and not elsewhere, nor by users. Hence the prototypes for these functions are NOT
5: in the public PETSc include files.
7: */
8: #include <petsc/private/logimpl.h>
10: PetscStageLog petsc_stageLog = NULL;
12: /*@C
13: PetscLogGetStageLog - This function returns the default stage logging object.
15: Not collective
17: Output Parameter:
18: . stageLog - The default PetscStageLog
20: Level: developer
22: Developer Notes:
23: Inline since called for EACH PetscEventLogBeginDefault() and PetscEventLogEndDefault()
25: .seealso: PetscStageLogCreate()
26: @*/
27: PetscErrorCode PetscLogGetStageLog(PetscStageLog *stageLog)
28: {
31: if (!petsc_stageLog) {
32: fprintf(stderr, "PETSC ERROR: Logging has not been enabled.\nYou might have forgotten to call PetscInitialize().\n");
33: PETSCABORT(MPI_COMM_WORLD, PETSC_ERR_SUP);
34: }
35: *stageLog = petsc_stageLog;
36: return(0);
37: }
39: /*@C
40: PetscStageLogGetCurrent - This function returns the stage from the top of the stack.
42: Not Collective
44: Input Parameter:
45: . stageLog - The PetscStageLog
47: Output Parameter:
48: . stage - The current stage
50: Notes:
51: If no stage is currently active, stage is set to -1.
53: Level: developer
55: Developer Notes:
56: Inline since called for EACH PetscEventLogBeginDefault() and PetscEventLogEndDefault()
58: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
59: @*/
60: PetscErrorCode PetscStageLogGetCurrent(PetscStageLog stageLog, int *stage)
61: {
62: PetscBool empty;
66: PetscIntStackEmpty(stageLog->stack, &empty);
67: if (empty) {
68: *stage = -1;
69: } else {
70: PetscIntStackTop(stageLog->stack, stage);
71: }
72: if (*stage != stageLog->curStage) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Inconsistency in stage log: stage %d should be %d", *stage, stageLog->curStage);
73: return(0);
74: }
76: /*@C
77: PetscStageLogGetEventPerfLog - This function returns the PetscEventPerfLog for the given stage.
79: Not Collective
81: Input Parameters:
82: + stageLog - The PetscStageLog
83: - stage - The stage
85: Output Parameter:
86: . eventLog - The PetscEventPerfLog
88: Level: developer
90: Developer Notes:
91: Inline since called for EACH PetscEventLogBeginDefault() and PetscEventLogEndDefault()
93: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
94: @*/
95: PetscErrorCode PetscStageLogGetEventPerfLog(PetscStageLog stageLog, int stage, PetscEventPerfLog *eventLog)
96: {
99: if ((stage < 0) || (stage >= stageLog->numStages)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
100: *eventLog = stageLog->stageInfo[stage].eventLog;
101: return(0);
102: }
104: /*@C
105: PetscStageInfoDestroy - This destroys a PetscStageInfo object.
107: Not collective
109: Input Parameter:
110: . stageInfo - The PetscStageInfo
112: Level: developer
114: .seealso: PetscStageLogCreate()
115: @*/
116: PetscErrorCode PetscStageInfoDestroy(PetscStageInfo *stageInfo)
117: {
121: PetscFree(stageInfo->name);
122: PetscEventPerfLogDestroy(stageInfo->eventLog);
123: PetscClassPerfLogDestroy(stageInfo->classLog);
124: return(0);
125: }
127: /*@C
128: PetscStageLogDestroy - This destroys a PetscStageLog object.
130: Not collective
132: Input Parameter:
133: . stageLog - The PetscStageLog
135: Level: developer
137: .seealso: PetscStageLogCreate()
138: @*/
139: PetscErrorCode PetscStageLogDestroy(PetscStageLog stageLog)
140: {
141: int stage;
145: if (!stageLog) return(0);
146: PetscIntStackDestroy(stageLog->stack);
147: PetscEventRegLogDestroy(stageLog->eventLog);
148: PetscClassRegLogDestroy(stageLog->classLog);
149: for (stage = 0; stage < stageLog->numStages; stage++) {
150: PetscStageInfoDestroy(&stageLog->stageInfo[stage]);
151: }
152: PetscFree(stageLog->stageInfo);
153: PetscFree(stageLog);
154: return(0);
155: }
157: /*@C
158: PetscStageLogRegister - Registers a stage name for logging operations in an application code.
160: Not Collective
162: Input Parameters:
163: + stageLog - The PetscStageLog
164: - sname - the name to associate with that stage
166: Output Parameter:
167: . stage - The stage index
169: Level: developer
171: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscStageLogCreate()
172: @*/
173: PetscErrorCode PetscStageLogRegister(PetscStageLog stageLog, const char sname[], int *stage)
174: {
175: PetscStageInfo *stageInfo;
176: int s;
182: /* Check stage already registered */
183: for (s = 0; s < stageLog->numStages; ++s) {
184: PetscBool same;
186: PetscStrcmp(stageLog->stageInfo[s].name, sname, &same);
187: if (same) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Duplicate stage name given: %s", sname);
188: }
189: /* Create new stage */
190: s = stageLog->numStages++;
191: if (stageLog->numStages > stageLog->maxStages) {
192: PetscMalloc1(stageLog->maxStages*2, &stageInfo);
193: PetscArraycpy(stageInfo, stageLog->stageInfo, stageLog->maxStages);
194: PetscFree(stageLog->stageInfo);
195: stageLog->stageInfo = stageInfo;
196: stageLog->maxStages *= 2;
197: }
198: /* Setup new stage info */
199: stageInfo = &stageLog->stageInfo[s];
200: PetscMemzero(stageInfo,sizeof(PetscStageInfo));
201: PetscStrallocpy(sname,&stageInfo->name);
202: stageInfo->used = PETSC_FALSE;
203: stageInfo->perfInfo.active = PETSC_TRUE;
204: stageInfo->perfInfo.visible = PETSC_TRUE;
205: PetscEventPerfLogCreate(&stageInfo->eventLog);
206: PetscClassPerfLogCreate(&stageInfo->classLog);
207: *stage = s;
208: return(0);
209: }
211: /*@C
212: PetscStageLogPush - This function pushes a stage on the stack.
214: Not Collective
216: Input Parameters:
217: + stageLog - The PetscStageLog
218: - stage - The stage to log
220: Database Options:
221: . -log_view - Activates logging
223: Usage:
224: If the option -log_sumary is used to run the program containing the
225: following code, then 2 sets of summary data will be printed during
226: PetscFinalize().
227: .vb
228: PetscInitialize(int *argc,char ***args,0,0);
229: [stage 0 of code]
230: PetscStageLogPush(stageLog,1);
231: [stage 1 of code]
232: PetscStageLogPop(stageLog);
233: PetscBarrier(...);
234: [more stage 0 of code]
235: PetscFinalize();
236: .ve
238: Notes:
239: Use PetscLogStageRegister() to register a stage. All previous stages are
240: accumulating time and flops, but events will only be logged in this stage.
242: Level: developer
244: .seealso: PetscStageLogPop(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
245: @*/
246: PetscErrorCode PetscStageLogPush(PetscStageLog stageLog, int stage)
247: {
248: int curStage = 0;
249: PetscBool empty;
253: if ((stage < 0) || (stage >= stageLog->numStages)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
255: /* Record flops/time of previous stage */
256: PetscIntStackEmpty(stageLog->stack, &empty);
257: if (!empty) {
258: PetscIntStackTop(stageLog->stack, &curStage);
259: if (stageLog->stageInfo[curStage].perfInfo.active) {
260: PetscTimeAdd(&stageLog->stageInfo[curStage].perfInfo.time);
261: stageLog->stageInfo[curStage].perfInfo.flops += petsc_TotalFlops;
262: stageLog->stageInfo[curStage].perfInfo.numMessages += petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
263: stageLog->stageInfo[curStage].perfInfo.messageLength += petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
264: stageLog->stageInfo[curStage].perfInfo.numReductions += petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
265: }
266: }
267: /* Activate the stage */
268: PetscIntStackPush(stageLog->stack, stage);
270: stageLog->stageInfo[stage].used = PETSC_TRUE;
271: stageLog->stageInfo[stage].perfInfo.count++;
272: stageLog->curStage = stage;
273: /* Subtract current quantities so that we obtain the difference when we pop */
274: if (stageLog->stageInfo[stage].perfInfo.active) {
275: PetscTimeSubtract(&stageLog->stageInfo[stage].perfInfo.time);
276: stageLog->stageInfo[stage].perfInfo.flops -= petsc_TotalFlops;
277: stageLog->stageInfo[stage].perfInfo.numMessages -= petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
278: stageLog->stageInfo[stage].perfInfo.messageLength -= petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
279: stageLog->stageInfo[stage].perfInfo.numReductions -= petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
280: }
281: return(0);
282: }
284: /*@C
285: PetscStageLogPop - This function pops a stage from the stack.
287: Not Collective
289: Input Parameter:
290: . stageLog - The PetscStageLog
292: Usage:
293: If the option -log_sumary is used to run the program containing the
294: following code, then 2 sets of summary data will be printed during
295: PetscFinalize().
296: .vb
297: PetscInitialize(int *argc,char ***args,0,0);
298: [stage 0 of code]
299: PetscStageLogPush(stageLog,1);
300: [stage 1 of code]
301: PetscStageLogPop(stageLog);
302: PetscBarrier(...);
303: [more stage 0 of code]
304: PetscFinalize();
305: .ve
307: Notes:
308: Use PetscStageLogRegister() to register a stage.
310: Level: developer
312: .seealso: PetscStageLogPush(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
313: @*/
314: PetscErrorCode PetscStageLogPop(PetscStageLog stageLog)
315: {
316: int curStage;
317: PetscBool empty;
321: /* Record flops/time of current stage */
322: PetscIntStackPop(stageLog->stack, &curStage);
323: if (stageLog->stageInfo[curStage].perfInfo.active) {
324: PetscTimeAdd(&stageLog->stageInfo[curStage].perfInfo.time);
325: stageLog->stageInfo[curStage].perfInfo.flops += petsc_TotalFlops;
326: stageLog->stageInfo[curStage].perfInfo.numMessages += petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
327: stageLog->stageInfo[curStage].perfInfo.messageLength += petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
328: stageLog->stageInfo[curStage].perfInfo.numReductions += petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
329: }
330: PetscIntStackEmpty(stageLog->stack, &empty);
331: if (!empty) {
332: /* Subtract current quantities so that we obtain the difference when we pop */
333: PetscIntStackTop(stageLog->stack, &curStage);
334: if (stageLog->stageInfo[curStage].perfInfo.active) {
335: PetscTimeSubtract(&stageLog->stageInfo[curStage].perfInfo.time);
336: stageLog->stageInfo[curStage].perfInfo.flops -= petsc_TotalFlops;
337: stageLog->stageInfo[curStage].perfInfo.numMessages -= petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
338: stageLog->stageInfo[curStage].perfInfo.messageLength -= petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
339: stageLog->stageInfo[curStage].perfInfo.numReductions -= petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
340: }
341: stageLog->curStage = curStage;
342: } else stageLog->curStage = -1;
343: return(0);
344: }
346: /*@C
347: PetscStageLogGetClassRegLog - This function returns the PetscClassRegLog for the given stage.
349: Not Collective
351: Input Parameters:
352: . stageLog - The PetscStageLog
354: Output Parameter:
355: . classLog - The PetscClassRegLog
357: Level: developer
359: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
360: @*/
361: PetscErrorCode PetscStageLogGetClassRegLog(PetscStageLog stageLog, PetscClassRegLog *classLog)
362: {
365: *classLog = stageLog->classLog;
366: return(0);
367: }
369: /*@C
370: PetscStageLogGetEventRegLog - This function returns the PetscEventRegLog.
372: Not Collective
374: Input Parameters:
375: . stageLog - The PetscStageLog
377: Output Parameter:
378: . eventLog - The PetscEventRegLog
380: Level: developer
382: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
383: @*/
384: PetscErrorCode PetscStageLogGetEventRegLog(PetscStageLog stageLog, PetscEventRegLog *eventLog)
385: {
388: *eventLog = stageLog->eventLog;
389: return(0);
390: }
392: /*@C
393: PetscStageLogGetClassPerfLog - This function returns the PetscClassPerfLog for the given stage.
395: Not Collective
397: Input Parameters:
398: + stageLog - The PetscStageLog
399: - stage - The stage
401: Output Parameter:
402: . classLog - The PetscClassPerfLog
404: Level: developer
406: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
407: @*/
408: PetscErrorCode PetscStageLogGetClassPerfLog(PetscStageLog stageLog, int stage, PetscClassPerfLog *classLog)
409: {
412: if ((stage < 0) || (stage >= stageLog->numStages)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
413: *classLog = stageLog->stageInfo[stage].classLog;
414: return(0);
415: }
417: /*@C
418: PetscStageLogSetActive - This function determines whether events will be logged during this state.
420: Not Collective
422: Input Parameters:
423: + stageLog - The PetscStageLog
424: . stage - The stage to log
425: - isActive - The activity flag, PETSC_TRUE for logging, otherwise PETSC_FALSE (default is PETSC_TRUE)
427: Level: developer
429: .seealso: PetscStageLogGetActive(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
430: @*/
431: PetscErrorCode PetscStageLogSetActive(PetscStageLog stageLog, int stage, PetscBool isActive)
432: {
434: if ((stage < 0) || (stage >= stageLog->numStages)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
435: stageLog->stageInfo[stage].perfInfo.active = isActive;
436: return(0);
437: }
439: /*@C
440: PetscStageLogGetActive - This function returns whether events will be logged suring this stage.
442: Not Collective
444: Input Parameters:
445: + stageLog - The PetscStageLog
446: - stage - The stage to log
448: Output Parameter:
449: . isActive - The activity flag, PETSC_TRUE for logging, otherwise PETSC_FALSE (default is PETSC_TRUE)
451: Level: developer
453: .seealso: PetscStageLogSetActive(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
454: @*/
455: PetscErrorCode PetscStageLogGetActive(PetscStageLog stageLog, int stage, PetscBool *isActive)
456: {
458: if ((stage < 0) || (stage >= stageLog->numStages)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
460: *isActive = stageLog->stageInfo[stage].perfInfo.active;
461: return(0);
462: }
464: /*@C
465: PetscStageLogSetVisible - This function determines whether a stage is printed during PetscLogView()
467: Not Collective
469: Input Parameters:
470: + stageLog - The PetscStageLog
471: . stage - The stage to log
472: - isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)
474: Database Options:
475: . -log_view - Activates log summary
477: Level: developer
479: .seealso: PetscStageLogGetVisible(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
480: @*/
481: PetscErrorCode PetscStageLogSetVisible(PetscStageLog stageLog, int stage, PetscBool isVisible)
482: {
484: if ((stage < 0) || (stage >= stageLog->numStages)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
485: stageLog->stageInfo[stage].perfInfo.visible = isVisible;
486: return(0);
487: }
489: /*@C
490: PetscStageLogGetVisible - This function returns whether a stage is printed during PetscLogView()
492: Not Collective
494: Input Parameters:
495: + stageLog - The PetscStageLog
496: - stage - The stage to log
498: Output Parameter:
499: . isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)
501: Database Options:
502: . -log_view - Activates log summary
504: Level: developer
506: .seealso: PetscStageLogSetVisible(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
507: @*/
508: PetscErrorCode PetscStageLogGetVisible(PetscStageLog stageLog, int stage, PetscBool *isVisible)
509: {
511: if ((stage < 0) || (stage >= stageLog->numStages)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
513: *isVisible = stageLog->stageInfo[stage].perfInfo.visible;
514: return(0);
515: }
517: /*@C
518: PetscStageLogGetStage - This function returns the stage id given the stage name.
520: Not Collective
522: Input Parameters:
523: + stageLog - The PetscStageLog
524: - name - The stage name
526: Output Parameter:
527: . stage - The stage id, or -1 if it does not exist
529: Level: developer
531: .seealso: PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
532: @*/
533: PetscErrorCode PetscStageLogGetStage(PetscStageLog stageLog, const char name[], PetscLogStage *stage)
534: {
535: PetscBool match;
536: int s;
542: *stage = -1;
543: for (s = 0; s < stageLog->numStages; s++) {
544: PetscStrcasecmp(stageLog->stageInfo[s].name, name, &match);
545: if (match) {
546: *stage = s;
547: break;
548: }
549: }
550: return(0);
551: }
553: /*@C
554: PetscStageLogCreate - This creates a PetscStageLog object.
556: Not collective
558: Input Parameter:
559: . stageLog - The PetscStageLog
561: Level: developer
563: .seealso: PetscStageLogCreate()
564: @*/
565: PetscErrorCode PetscStageLogCreate(PetscStageLog *stageLog)
566: {
567: PetscStageLog l;
571: PetscNew(&l);
573: l->numStages = 0;
574: l->maxStages = 10;
575: l->curStage = -1;
577: PetscIntStackCreate(&l->stack);
578: PetscMalloc1(l->maxStages, &l->stageInfo);
579: PetscEventRegLogCreate(&l->eventLog);
580: PetscClassRegLogCreate(&l->classLog);
582: *stageLog = l;
583: return(0);
584: }