Actual source code: stageLog.c

petsc-3.3-p7 2013-05-11
  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> /*I    "petscsys.h"   I*/

 10: PetscStageLog  petsc_stageLog = 0;

 14: /*@C
 15:   PetscStageInfoDestroy - This destroys a PetscStageInfo object.

 17:   Not collective

 19:   Input Paramter:
 20: . stageInfo - The PetscStageInfo

 22:   Level: developer

 24: .keywords: log, stage, destroy
 25: .seealso: PetscStageLogCreate()
 26: @*/
 27: PetscErrorCode  PetscStageInfoDestroy(PetscStageInfo *stageInfo)
 28: {

 32:   PetscFree(stageInfo->name);
 33:   EventPerfLogDestroy(stageInfo->eventLog);
 34:   ClassPerfLogDestroy(stageInfo->classLog);
 35:   return(0);
 36: }

 40: /*@C
 41:   PetscStageLogDestroy - This destroys a PetscStageLog object.

 43:   Not collective

 45:   Input Paramter:
 46: . stageLog - The PetscStageLog

 48:   Level: developer

 50: .keywords: log, stage, destroy
 51: .seealso: PetscStageLogCreate()
 52: @*/
 53: PetscErrorCode  PetscStageLogDestroy(PetscStageLog stageLog)
 54: {
 55:   int            stage;

 59:   if (!stageLog) return(0);
 60:   PetscIntStackDestroy(stageLog->stack);
 61:   EventRegLogDestroy(stageLog->eventLog);
 62:   PetscClassRegLogDestroy(stageLog->classLog);
 63:   for(stage = 0; stage < stageLog->numStages; stage++) {
 64:     PetscStageInfoDestroy(&stageLog->stageInfo[stage]);
 65:   }
 66:   PetscFree(stageLog->stageInfo);
 67:   PetscFree(stageLog);
 68:   return(0);
 69: }

 73: /*@C
 74:   PetscStageLogRegister - Registers a stage name for logging operations in an application code.

 76:   Not Collective

 78:   Input Parameter:
 79: + stageLog - The PetscStageLog
 80: - sname    - the name to associate with that stage

 82:   Output Parameter:
 83: . stage    - The stage index

 85:   Level: developer

 87: .keywords: log, stage, register
 88: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscStageLogCreate()
 89: @*/
 90: PetscErrorCode  PetscStageLogRegister(PetscStageLog stageLog, const char sname[], int *stage)
 91: {
 92:   PetscStageInfo      *stageInfo;
 93:   char           *str;
 94:   int            s, st;

100:   for(st = 0; st < stageLog->numStages; ++st) {
101:     PetscBool  same;

103:     PetscStrcmp(stageLog->stageInfo[st].name, sname, &same);
104:     if (same) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Duplicate stage name given: %s", sname);
105:   }
106:   s = stageLog->numStages++;
107:   if (stageLog->numStages > stageLog->maxStages) {
108:     PetscMalloc(stageLog->maxStages*2 * sizeof(PetscStageInfo), &stageInfo);
109:     PetscMemcpy(stageInfo, stageLog->stageInfo, stageLog->maxStages * sizeof(PetscStageInfo));
110:     PetscFree(stageLog->stageInfo);
111:     stageLog->stageInfo  = stageInfo;
112:     stageLog->maxStages *= 2;
113:   }
114:   /* Setup stage */
115:   PetscStrallocpy(sname, &str);
116:   stageLog->stageInfo[s].name                   = str;
117:   stageLog->stageInfo[s].used                   = PETSC_FALSE;
118:   stageLog->stageInfo[s].perfInfo.active        = PETSC_TRUE;
119:   stageLog->stageInfo[s].perfInfo.visible       = PETSC_TRUE;
120:   stageLog->stageInfo[s].perfInfo.count         = 0;
121:   stageLog->stageInfo[s].perfInfo.flops         = 0.0;
122:   stageLog->stageInfo[s].perfInfo.time          = 0.0;
123:   stageLog->stageInfo[s].perfInfo.numMessages   = 0.0;
124:   stageLog->stageInfo[s].perfInfo.messageLength = 0.0;
125:   stageLog->stageInfo[s].perfInfo.numReductions = 0.0;
126:   EventPerfLogCreate(&stageLog->stageInfo[s].eventLog);
127:   ClassPerfLogCreate(&stageLog->stageInfo[s].classLog);
128:   *stage = s;
129:   return(0);
130: }

134: /*@C
135:   PetscStageLogPush - This function pushes a stage on the stack.

137:   Not Collective

139:   Input Parameters:
140: + stageLog   - The PetscStageLog
141: - stage - The stage to log

143:   Database Options:
144: . -log_summary - Activates logging

146:   Usage:
147:   If the option -log_sumary is used to run the program containing the 
148:   following code, then 2 sets of summary data will be printed during
149:   PetscFinalize().
150: .vb
151:       PetscInitialize(int *argc,char ***args,0,0);
152:       [stage 0 of code]   
153:       PetscStageLogPush(stageLog,1);
154:       [stage 1 of code]
155:       PetscStageLogPop(stageLog);
156:       PetscBarrier(...);
157:       [more stage 0 of code]   
158:       PetscFinalize();
159: .ve

161:   Notes:
162:   Use PetscLogStageRegister() to register a stage. All previous stages are
163:   accumulating time and flops, but events will only be logged in this stage.

165:   Level: developer

167: .keywords: log, push, stage
168: .seealso: PetscStageLogPop(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
169: @*/
170: PetscErrorCode  PetscStageLogPush(PetscStageLog stageLog, int stage)
171: {
172:   int            curStage = 0;
173:   PetscBool      empty;

177:   if ((stage < 0) || (stage >= stageLog->numStages)) {
178:     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
179:   }

181:   /* Record flops/time of previous stage */
182:   PetscIntStackEmpty(stageLog->stack, &empty);
183:   if (!empty) {
184:     PetscIntStackTop(stageLog->stack, &curStage);
185:     if (stageLog->stageInfo[curStage].perfInfo.active) {
186:       PetscTimeAdd(stageLog->stageInfo[curStage].perfInfo.time);
187:       stageLog->stageInfo[curStage].perfInfo.flops         += petsc_TotalFlops;
188:       stageLog->stageInfo[curStage].perfInfo.numMessages   += petsc_irecv_ct  + petsc_isend_ct  + petsc_recv_ct  + petsc_send_ct;
189:       stageLog->stageInfo[curStage].perfInfo.messageLength += petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
190:       stageLog->stageInfo[curStage].perfInfo.numReductions += petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
191:     }
192:   }
193:   /* Activate the stage */
194:   PetscIntStackPush(stageLog->stack, stage);
195:   stageLog->stageInfo[stage].used = PETSC_TRUE;
196:   stageLog->stageInfo[stage].perfInfo.count++;
197:   stageLog->curStage = stage;
198:   /* Subtract current quantities so that we obtain the difference when we pop */
199:   if (stageLog->stageInfo[stage].perfInfo.active) {
200:     PetscTimeSubtract(stageLog->stageInfo[stage].perfInfo.time);
201:     stageLog->stageInfo[stage].perfInfo.flops         -= petsc_TotalFlops;
202:     stageLog->stageInfo[stage].perfInfo.numMessages   -= petsc_irecv_ct  + petsc_isend_ct  + petsc_recv_ct  + petsc_send_ct;
203:     stageLog->stageInfo[stage].perfInfo.messageLength -= petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
204:     stageLog->stageInfo[stage].perfInfo.numReductions -= petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
205:   }
206:   return(0);
207: }

211: /*@C
212:   PetscStageLogPop - This function pops a stage from the stack.

214:   Not Collective

216:   Input Parameter:
217: . stageLog - The PetscStageLog

219:   Usage:
220:   If the option -log_sumary is used to run the program containing the 
221:   following code, then 2 sets of summary data will be printed during
222:   PetscFinalize().
223: .vb
224:       PetscInitialize(int *argc,char ***args,0,0);
225:       [stage 0 of code]   
226:       PetscStageLogPush(stageLog,1);
227:       [stage 1 of code]
228:       PetscStageLogPop(stageLog);
229:       PetscBarrier(...);
230:       [more stage 0 of code]   
231:       PetscFinalize();
232: .ve

234:   Notes:
235:   Use PetscStageLogRegister() to register a stage.

237:   Level: developer

239: .keywords: log, pop, stage
240: .seealso: PetscStageLogPush(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
241: @*/
242: PetscErrorCode  PetscStageLogPop(PetscStageLog stageLog)
243: {
244:   int             curStage;
245:   PetscBool       empty;

249:   /* Record flops/time of current stage */
250:   PetscIntStackPop(stageLog->stack, &curStage);
251:   if (stageLog->stageInfo[curStage].perfInfo.active) {
252:     PetscTimeAdd(stageLog->stageInfo[curStage].perfInfo.time);
253:     stageLog->stageInfo[curStage].perfInfo.flops         += petsc_TotalFlops;
254:     stageLog->stageInfo[curStage].perfInfo.numMessages   += petsc_irecv_ct  + petsc_isend_ct  + petsc_recv_ct  + petsc_send_ct;
255:     stageLog->stageInfo[curStage].perfInfo.messageLength += petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
256:     stageLog->stageInfo[curStage].perfInfo.numReductions += petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
257:   }
258:   PetscIntStackEmpty(stageLog->stack, &empty);
259:   if (!empty) {
260:     /* Subtract current quantities so that we obtain the difference when we pop */
261:     PetscIntStackTop(stageLog->stack, &curStage);
262:     if (stageLog->stageInfo[curStage].perfInfo.active) {
263:       PetscTimeSubtract(stageLog->stageInfo[curStage].perfInfo.time);
264:       stageLog->stageInfo[curStage].perfInfo.flops         -= petsc_TotalFlops;
265:       stageLog->stageInfo[curStage].perfInfo.numMessages   -= petsc_irecv_ct  + petsc_isend_ct  + petsc_recv_ct  + petsc_send_ct;
266:       stageLog->stageInfo[curStage].perfInfo.messageLength -= petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
267:       stageLog->stageInfo[curStage].perfInfo.numReductions -= petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
268:     }
269:     stageLog->curStage                           = curStage;
270:   } else {
271:     stageLog->curStage                           = -1;
272:   }
273:   return(0);
274: }


279: /*@C
280:   PetscStageLogGetClassRegLog - This function returns the PetscClassRegLog for the given stage.

282:   Not Collective

284:   Input Parameters:
285: . stageLog - The PetscStageLog

287:   Output Parameter:
288: . classLog - The PetscClassRegLog

290:   Level: developer

292: .keywords: log, stage
293: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
294: @*/
295: PetscErrorCode  PetscStageLogGetClassRegLog(PetscStageLog stageLog, PetscClassRegLog *classLog)
296: {
299:   *classLog = stageLog->classLog;
300:   return(0);
301: }

305: /*@C
306:   PetscStageLogGetEventRegLog - This function returns the PetscEventRegLog.

308:   Not Collective

310:   Input Parameters:
311: . stageLog - The PetscStageLog

313:   Output Parameter:
314: . eventLog - The PetscEventRegLog

316:   Level: developer

318: .keywords: log, stage
319: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
320: @*/
321: PetscErrorCode  PetscStageLogGetEventRegLog(PetscStageLog stageLog, PetscEventRegLog *eventLog)
322: {
325:   *eventLog = stageLog->eventLog;
326:   return(0);
327: }

331: /*@C
332:   PetscStageLogGetClassPerfLog - This function returns the ClassPerfLog for the given stage.

334:   Not Collective

336:   Input Parameters:
337: + stageLog - The PetscStageLog
338: - stage    - The stage

340:   Output Parameter:
341: . classLog - The ClassPerfLog

343:   Level: developer

345: .keywords: log, stage
346: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
347: @*/
348: PetscErrorCode  PetscStageLogGetClassPerfLog(PetscStageLog stageLog, int stage, PetscClassPerfLog *classLog)
349: {
352:   if ((stage < 0) || (stage >= stageLog->numStages)) {
353:     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
354:   }
355:   *classLog = stageLog->stageInfo[stage].classLog;
356:   return(0);
357: }


362: /*@C
363:   PetscStageLogSetActive - This function determines whether events will be logged during this state.

365:   Not Collective

367:   Input Parameters:
368: + stageLog - The PetscStageLog
369: . stage    - The stage to log
370: - isActive - The activity flag, PETSC_TRUE for logging, otherwise PETSC_FALSE (default is PETSC_TRUE)

372:   Level: developer

374: .keywords: log, active, stage
375: .seealso: PetscStageLogGetActive(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
376: @*/
377: PetscErrorCode  PetscStageLogSetActive(PetscStageLog stageLog, int stage, PetscBool  isActive)
378: {
380:   if ((stage < 0) || (stage >= stageLog->numStages)) {
381:     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
382:   }
383:   stageLog->stageInfo[stage].perfInfo.active = isActive;
384:   return(0);
385: }

389: /*@C
390:   PetscStageLogGetActive - This function returns whether events will be logged suring this stage.

392:   Not Collective

394:   Input Parameters:
395: + stageLog - The PetscStageLog
396: - stage    - The stage to log

398:   Output Parameter:
399: . isActive - The activity flag, PETSC_TRUE for logging, otherwise PETSC_FALSE (default is PETSC_TRUE)

401:   Level: developer

403: .keywords: log, visible, stage
404: .seealso: PetscStageLogSetActive(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
405: @*/
406: PetscErrorCode  PetscStageLogGetActive(PetscStageLog stageLog, int stage, PetscBool  *isActive)
407: {
409:   if ((stage < 0) || (stage >= stageLog->numStages)) {
410:     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
411:   }
413:   *isActive = stageLog->stageInfo[stage].perfInfo.active;
414:   return(0);
415: }

419: /*@C
420:   PetscStageLogSetVisible - This function determines whether a stage is printed during PetscLogView()

422:   Not Collective

424:   Input Parameters:
425: + stageLog  - The PetscStageLog
426: . stage     - The stage to log
427: - isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)

429:   Database Options:
430: . -log_summary - Activates log summary

432:   Level: developer

434: .keywords: log, visible, stage
435: .seealso: PetscStageLogGetVisible(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
436: @*/
437: PetscErrorCode  PetscStageLogSetVisible(PetscStageLog stageLog, int stage, PetscBool  isVisible)
438: {
440:   if ((stage < 0) || (stage >= stageLog->numStages)) {
441:     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
442:   }
443:   stageLog->stageInfo[stage].perfInfo.visible = isVisible;
444:   return(0);
445: }

449: /*@C
450:   PetscStageLogGetVisible - This function returns whether a stage is printed during PetscLogView()

452:   Not Collective

454:   Input Parameters:
455: + stageLog  - The PetscStageLog
456: - stage     - The stage to log

458:   Output Parameter:
459: . isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)

461:   Database Options:
462: . -log_summary - Activates log summary

464:   Level: developer

466: .keywords: log, visible, stage
467: .seealso: PetscStageLogSetVisible(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
468: @*/
469: PetscErrorCode  PetscStageLogGetVisible(PetscStageLog stageLog, int stage, PetscBool  *isVisible)
470: {
472:   if ((stage < 0) || (stage >= stageLog->numStages)) {
473:     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
474:   }
476:   *isVisible = stageLog->stageInfo[stage].perfInfo.visible;
477:   return(0);
478: }

482: /*@C
483:   PetscStageLogGetStage - This function returns the stage id given the stage name.

485:   Not Collective

487:   Input Parameters:
488: + stageLog - The PetscStageLog
489: - name     - The stage name

491:   Output Parameter:
492: . stage    - The stage id

494:   Level: developer 

496: .keywords: log, stage
497: .seealso: PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
498: @*/
499: PetscErrorCode  PetscStageLogGetStage(PetscStageLog stageLog, const char name[], int *stage)
500: {
501:   PetscBool      match;
502:   int            s;

508:   *stage = -1;
509:   for(s = 0; s < stageLog->numStages; s++) {
510:     PetscStrcasecmp(stageLog->stageInfo[s].name, name, &match);
511:     if (match) break;
512:   }
513:   if (s == stageLog->numStages) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "No stage named %s", name);
514:   *stage = s;
515:   return(0);
516: }

520: /*@C
521:   PetscStageLogCreate - This creates a PetscStageLog object.

523:   Not collective

525:   Input Parameter:
526: . stageLog - The PetscStageLog

528:   Level: developer

530: .keywords: log, stage, create
531: .seealso: PetscStageLogCreate()
532: @*/
533: PetscErrorCode  PetscStageLogCreate(PetscStageLog *stageLog)
534: {
535:   PetscStageLog       l;

539:   PetscNew(struct _n_PetscStageLog, &l);
540:   l->numStages = 0;
541:   l->maxStages = 10;
542:   l->curStage  = -1;
543:   PetscIntStackCreate(&l->stack);
544:   PetscMalloc(l->maxStages * sizeof(PetscStageInfo), &l->stageInfo);
545:   EventRegLogCreate(&l->eventLog);
546:   PetscClassRegLogCreate(&l->classLog);
547:   *stageLog = l;
548:   return(0);
549: }