Actual source code: stagelog.c
petsc-3.13.6 2020-09-29
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: #ifdef PETSC_USE_DEBUG
73: if (*stage != stageLog->curStage) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Inconsistency in stage log: stage %d should be %d", *stage, stageLog->curStage);
74: #endif
75: return(0);
76: }
78: /*@C
79: PetscStageLogGetEventPerfLog - This function returns the PetscEventPerfLog for the given stage.
81: Not Collective
83: Input Parameters:
84: + stageLog - The PetscStageLog
85: - stage - The stage
87: Output Parameter:
88: . eventLog - The PetscEventPerfLog
90: Level: developer
92: Developer Notes:
93: Inline since called for EACH PetscEventLogBeginDefault() and PetscEventLogEndDefault()
95: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
96: @*/
97: PetscErrorCode PetscStageLogGetEventPerfLog(PetscStageLog stageLog, int stage, PetscEventPerfLog *eventLog)
98: {
101: 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);
102: *eventLog = stageLog->stageInfo[stage].eventLog;
103: return(0);
104: }
106: /*@C
107: PetscStageInfoDestroy - This destroys a PetscStageInfo object.
109: Not collective
111: Input Parameter:
112: . stageInfo - The PetscStageInfo
114: Level: developer
116: .seealso: PetscStageLogCreate()
117: @*/
118: PetscErrorCode PetscStageInfoDestroy(PetscStageInfo *stageInfo)
119: {
123: PetscFree(stageInfo->name);
124: PetscEventPerfLogDestroy(stageInfo->eventLog);
125: PetscClassPerfLogDestroy(stageInfo->classLog);
126: return(0);
127: }
129: /*@C
130: PetscStageLogDestroy - This destroys a PetscStageLog object.
132: Not collective
134: Input Parameter:
135: . stageLog - The PetscStageLog
137: Level: developer
139: .seealso: PetscStageLogCreate()
140: @*/
141: PetscErrorCode PetscStageLogDestroy(PetscStageLog stageLog)
142: {
143: int stage;
147: if (!stageLog) return(0);
148: PetscIntStackDestroy(stageLog->stack);
149: PetscEventRegLogDestroy(stageLog->eventLog);
150: PetscClassRegLogDestroy(stageLog->classLog);
151: for (stage = 0; stage < stageLog->numStages; stage++) {
152: PetscStageInfoDestroy(&stageLog->stageInfo[stage]);
153: }
154: PetscFree(stageLog->stageInfo);
155: PetscFree(stageLog);
156: return(0);
157: }
159: /*@C
160: PetscStageLogRegister - Registers a stage name for logging operations in an Section 1.5 Writing Application Codes with PETSc code.
162: Not Collective
164: Input Parameter:
165: + stageLog - The PetscStageLog
166: - sname - the name to associate with that stage
168: Output Parameter:
169: . stage - The stage index
171: Level: developer
173: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscStageLogCreate()
174: @*/
175: PetscErrorCode PetscStageLogRegister(PetscStageLog stageLog, const char sname[], int *stage)
176: {
177: PetscStageInfo *stageInfo;
178: int s;
184: /* Check stage already registered */
185: for (s = 0; s < stageLog->numStages; ++s) {
186: PetscBool same;
188: PetscStrcmp(stageLog->stageInfo[s].name, sname, &same);
189: if (same) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Duplicate stage name given: %s", sname);
190: }
191: /* Create new stage */
192: s = stageLog->numStages++;
193: if (stageLog->numStages > stageLog->maxStages) {
194: PetscMalloc1(stageLog->maxStages*2, &stageInfo);
195: PetscArraycpy(stageInfo, stageLog->stageInfo, stageLog->maxStages);
196: PetscFree(stageLog->stageInfo);
197: stageLog->stageInfo = stageInfo;
198: stageLog->maxStages *= 2;
199: }
200: /* Setup new stage info */
201: stageInfo = &stageLog->stageInfo[s];
202: PetscMemzero(stageInfo,sizeof(PetscStageInfo));
203: PetscStrallocpy(sname,&stageInfo->name);
204: stageInfo->used = PETSC_FALSE;
205: stageInfo->perfInfo.active = PETSC_TRUE;
206: stageInfo->perfInfo.visible = PETSC_TRUE;
207: PetscEventPerfLogCreate(&stageInfo->eventLog);
208: PetscClassPerfLogCreate(&stageInfo->classLog);
209: *stage = s;
210: return(0);
211: }
213: /*@C
214: PetscStageLogPush - This function pushes a stage on the stack.
216: Not Collective
218: Input Parameters:
219: + stageLog - The PetscStageLog
220: - stage - The stage to log
222: Database Options:
223: . -log_view - Activates logging
225: Usage:
226: If the option -log_sumary is used to run the program containing the
227: following code, then 2 sets of summary data will be printed during
228: PetscFinalize().
229: .vb
230: PetscInitialize(int *argc,char ***args,0,0);
231: [stage 0 of code]
232: PetscStageLogPush(stageLog,1);
233: [stage 1 of code]
234: PetscStageLogPop(stageLog);
235: PetscBarrier(...);
236: [more stage 0 of code]
237: PetscFinalize();
238: .ve
240: Notes:
241: Use PetscLogStageRegister() to register a stage. All previous stages are
242: accumulating time and flops, but events will only be logged in this stage.
244: Level: developer
246: .seealso: PetscStageLogPop(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
247: @*/
248: PetscErrorCode PetscStageLogPush(PetscStageLog stageLog, int stage)
249: {
250: int curStage = 0;
251: PetscBool empty;
255: 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);
257: /* Record flops/time of previous stage */
258: PetscIntStackEmpty(stageLog->stack, &empty);
259: if (!empty) {
260: PetscIntStackTop(stageLog->stack, &curStage);
261: if (stageLog->stageInfo[curStage].perfInfo.active) {
262: PetscTimeAdd(&stageLog->stageInfo[curStage].perfInfo.time);
263: stageLog->stageInfo[curStage].perfInfo.flops += petsc_TotalFlops;
264: stageLog->stageInfo[curStage].perfInfo.numMessages += petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
265: stageLog->stageInfo[curStage].perfInfo.messageLength += petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
266: stageLog->stageInfo[curStage].perfInfo.numReductions += petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
267: }
268: }
269: /* Activate the stage */
270: PetscIntStackPush(stageLog->stack, stage);
272: stageLog->stageInfo[stage].used = PETSC_TRUE;
273: stageLog->stageInfo[stage].perfInfo.count++;
274: stageLog->curStage = stage;
275: /* Subtract current quantities so that we obtain the difference when we pop */
276: if (stageLog->stageInfo[stage].perfInfo.active) {
277: PetscTimeSubtract(&stageLog->stageInfo[stage].perfInfo.time);
278: stageLog->stageInfo[stage].perfInfo.flops -= petsc_TotalFlops;
279: stageLog->stageInfo[stage].perfInfo.numMessages -= petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
280: stageLog->stageInfo[stage].perfInfo.messageLength -= petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
281: stageLog->stageInfo[stage].perfInfo.numReductions -= petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
282: }
283: return(0);
284: }
286: /*@C
287: PetscStageLogPop - This function pops a stage from the stack.
289: Not Collective
291: Input Parameter:
292: . stageLog - The PetscStageLog
294: Usage:
295: If the option -log_sumary is used to run the program containing the
296: following code, then 2 sets of summary data will be printed during
297: PetscFinalize().
298: .vb
299: PetscInitialize(int *argc,char ***args,0,0);
300: [stage 0 of code]
301: PetscStageLogPush(stageLog,1);
302: [stage 1 of code]
303: PetscStageLogPop(stageLog);
304: PetscBarrier(...);
305: [more stage 0 of code]
306: PetscFinalize();
307: .ve
309: Notes:
310: Use PetscStageLogRegister() to register a stage.
312: Level: developer
314: .seealso: PetscStageLogPush(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
315: @*/
316: PetscErrorCode PetscStageLogPop(PetscStageLog stageLog)
317: {
318: int curStage;
319: PetscBool empty;
323: /* Record flops/time of current stage */
324: PetscIntStackPop(stageLog->stack, &curStage);
325: if (stageLog->stageInfo[curStage].perfInfo.active) {
326: PetscTimeAdd(&stageLog->stageInfo[curStage].perfInfo.time);
327: stageLog->stageInfo[curStage].perfInfo.flops += petsc_TotalFlops;
328: stageLog->stageInfo[curStage].perfInfo.numMessages += petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
329: stageLog->stageInfo[curStage].perfInfo.messageLength += petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
330: stageLog->stageInfo[curStage].perfInfo.numReductions += petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
331: }
332: PetscIntStackEmpty(stageLog->stack, &empty);
333: if (!empty) {
334: /* Subtract current quantities so that we obtain the difference when we pop */
335: PetscIntStackTop(stageLog->stack, &curStage);
336: if (stageLog->stageInfo[curStage].perfInfo.active) {
337: PetscTimeSubtract(&stageLog->stageInfo[curStage].perfInfo.time);
338: stageLog->stageInfo[curStage].perfInfo.flops -= petsc_TotalFlops;
339: stageLog->stageInfo[curStage].perfInfo.numMessages -= petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
340: stageLog->stageInfo[curStage].perfInfo.messageLength -= petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
341: stageLog->stageInfo[curStage].perfInfo.numReductions -= petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
342: }
343: stageLog->curStage = curStage;
344: } else stageLog->curStage = -1;
345: return(0);
346: }
349: /*@C
350: PetscStageLogGetClassRegLog - This function returns the PetscClassRegLog for the given stage.
352: Not Collective
354: Input Parameters:
355: . stageLog - The PetscStageLog
357: Output Parameter:
358: . classLog - The PetscClassRegLog
360: Level: developer
362: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
363: @*/
364: PetscErrorCode PetscStageLogGetClassRegLog(PetscStageLog stageLog, PetscClassRegLog *classLog)
365: {
368: *classLog = stageLog->classLog;
369: return(0);
370: }
372: /*@C
373: PetscStageLogGetEventRegLog - This function returns the PetscEventRegLog.
375: Not Collective
377: Input Parameters:
378: . stageLog - The PetscStageLog
380: Output Parameter:
381: . eventLog - The PetscEventRegLog
383: Level: developer
385: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
386: @*/
387: PetscErrorCode PetscStageLogGetEventRegLog(PetscStageLog stageLog, PetscEventRegLog *eventLog)
388: {
391: *eventLog = stageLog->eventLog;
392: return(0);
393: }
395: /*@C
396: PetscStageLogGetClassPerfLog - This function returns the PetscClassPerfLog for the given stage.
398: Not Collective
400: Input Parameters:
401: + stageLog - The PetscStageLog
402: - stage - The stage
404: Output Parameter:
405: . classLog - The PetscClassPerfLog
407: Level: developer
409: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
410: @*/
411: PetscErrorCode PetscStageLogGetClassPerfLog(PetscStageLog stageLog, int stage, PetscClassPerfLog *classLog)
412: {
415: 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);
416: *classLog = stageLog->stageInfo[stage].classLog;
417: return(0);
418: }
421: /*@C
422: PetscStageLogSetActive - This function determines whether events will be logged during this state.
424: Not Collective
426: Input Parameters:
427: + stageLog - The PetscStageLog
428: . stage - The stage to log
429: - isActive - The activity flag, PETSC_TRUE for logging, otherwise PETSC_FALSE (default is PETSC_TRUE)
431: Level: developer
433: .seealso: PetscStageLogGetActive(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
434: @*/
435: PetscErrorCode PetscStageLogSetActive(PetscStageLog stageLog, int stage, PetscBool isActive)
436: {
438: 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);
439: stageLog->stageInfo[stage].perfInfo.active = isActive;
440: return(0);
441: }
443: /*@C
444: PetscStageLogGetActive - This function returns whether events will be logged suring this stage.
446: Not Collective
448: Input Parameters:
449: + stageLog - The PetscStageLog
450: - stage - The stage to log
452: Output Parameter:
453: . isActive - The activity flag, PETSC_TRUE for logging, otherwise PETSC_FALSE (default is PETSC_TRUE)
455: Level: developer
457: .seealso: PetscStageLogSetActive(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
458: @*/
459: PetscErrorCode PetscStageLogGetActive(PetscStageLog stageLog, int stage, PetscBool *isActive)
460: {
462: 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);
464: *isActive = stageLog->stageInfo[stage].perfInfo.active;
465: return(0);
466: }
468: /*@C
469: PetscStageLogSetVisible - This function determines whether a stage is printed during PetscLogView()
471: Not Collective
473: Input Parameters:
474: + stageLog - The PetscStageLog
475: . stage - The stage to log
476: - isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)
478: Database Options:
479: . -log_view - Activates log summary
481: Level: developer
483: .seealso: PetscStageLogGetVisible(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
484: @*/
485: PetscErrorCode PetscStageLogSetVisible(PetscStageLog stageLog, int stage, PetscBool isVisible)
486: {
488: 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);
489: stageLog->stageInfo[stage].perfInfo.visible = isVisible;
490: return(0);
491: }
493: /*@C
494: PetscStageLogGetVisible - This function returns whether a stage is printed during PetscLogView()
496: Not Collective
498: Input Parameters:
499: + stageLog - The PetscStageLog
500: - stage - The stage to log
502: Output Parameter:
503: . isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)
505: Database Options:
506: . -log_view - Activates log summary
508: Level: developer
510: .seealso: PetscStageLogSetVisible(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
511: @*/
512: PetscErrorCode PetscStageLogGetVisible(PetscStageLog stageLog, int stage, PetscBool *isVisible)
513: {
515: 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);
517: *isVisible = stageLog->stageInfo[stage].perfInfo.visible;
518: return(0);
519: }
521: /*@C
522: PetscStageLogGetStage - This function returns the stage id given the stage name.
524: Not Collective
526: Input Parameters:
527: + stageLog - The PetscStageLog
528: - name - The stage name
530: Output Parameter:
531: . stage - The stage id, or -1 if it does not exist
533: Level: developer
535: .seealso: PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
536: @*/
537: PetscErrorCode PetscStageLogGetStage(PetscStageLog stageLog, const char name[], PetscLogStage *stage)
538: {
539: PetscBool match;
540: int s;
546: *stage = -1;
547: for (s = 0; s < stageLog->numStages; s++) {
548: PetscStrcasecmp(stageLog->stageInfo[s].name, name, &match);
549: if (match) {
550: *stage = s;
551: break;
552: }
553: }
554: return(0);
555: }
557: /*@C
558: PetscStageLogCreate - This creates a PetscStageLog object.
560: Not collective
562: Input Parameter:
563: . stageLog - The PetscStageLog
565: Level: developer
567: .seealso: PetscStageLogCreate()
568: @*/
569: PetscErrorCode PetscStageLogCreate(PetscStageLog *stageLog)
570: {
571: PetscStageLog l;
575: PetscNew(&l);
577: l->numStages = 0;
578: l->maxStages = 10;
579: l->curStage = -1;
581: PetscIntStackCreate(&l->stack);
582: PetscMalloc1(l->maxStages, &l->stageInfo);
583: PetscEventRegLogCreate(&l->eventLog);
584: PetscClassRegLogCreate(&l->classLog);
586: *stageLog = l;
587: return(0);
588: }