Actual source code: stagelog.c

petsc-3.12.5 2020-03-29
Report Typos and Errors

  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 = 0;

 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:     MPI_Abort(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 Paramter:
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 Paramter:
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 application 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: }