Actual source code: classlog.c

petsc-3.4.5 2014-06-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> /*I    "petscsys.h"   I*/

 12: /*@C
 13:   PetscClassRegLogCreate - This creates a PetscClassRegLog object.

 15:   Not collective

 17:   Input Parameter:
 18: . classLog - The PetscClassRegLog

 20:   Level: developer

 22: .keywords: log, class, create
 23: .seealso: PetscClassRegLogDestroy(), PetscStageLogCreate()
 24: @*/
 25: PetscErrorCode PetscClassRegLogCreate(PetscClassRegLog *classLog)
 26: {
 27:   PetscClassRegLog l;
 28:   PetscErrorCode   ierr;

 31:   PetscNew(struct _n_PetscClassRegLog, &l);

 33:   l->numClasses = 0;
 34:   l->maxClasses = 100;

 36:   PetscMalloc(l->maxClasses * sizeof(PetscClassRegInfo), &l->classInfo);

 38:   *classLog = l;
 39:   return(0);
 40: }

 44: /*@C
 45:   PetscClassRegLogDestroy - This destroys a PetscClassRegLog object.

 47:   Not collective

 49:   Input Paramter:
 50: . classLog - The PetscClassRegLog

 52:   Level: developer

 54: .keywords: log, event, destroy
 55: .seealso: PetscClassRegLogCreate()
 56: @*/
 57: PetscErrorCode PetscClassRegLogDestroy(PetscClassRegLog classLog)
 58: {
 59:   int            c;

 63:   for (c = 0; c < classLog->numClasses; c++) {
 64:     PetscClassRegInfoDestroy(&classLog->classInfo[c]);
 65:   }
 66:   PetscFree(classLog->classInfo);
 67:   PetscFree(classLog);
 68:   return(0);
 69: }

 73: /*@C
 74:   PetscClassRegInfoDestroy - This destroys a PetscClassRegInfo object.

 76:   Not collective

 78:   Input Parameter:
 79: . c - The PetscClassRegInfo

 81:   Level: developer

 83: .keywords: log, class, destroy
 84: .seealso: PetscStageLogDestroy(), EventLogDestroy()
 85: @*/
 86: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
 87: {

 91:   PetscFree(c->name);
 92:   return(0);
 93: }

 97: /*@C
 98:   ClassPerfLogCreate - This creates a PetscClassPerfLog object.

100:   Not collective

102:   Input Parameter:
103: . classLog - The PetscClassPerfLog

105:   Level: developer

107: .keywords: log, class, create
108: .seealso: ClassPerfLogDestroy(), PetscStageLogCreate()
109: @*/
110: PetscErrorCode ClassPerfLogCreate(PetscClassPerfLog *classLog)
111: {
112:   PetscClassPerfLog l;
113:   PetscErrorCode    ierr;

116:   PetscNew(struct _n_PetscClassPerfLog, &l);

118:   l->numClasses = 0;
119:   l->maxClasses = 100;

121:   PetscMalloc(l->maxClasses * sizeof(PetscClassPerfInfo), &l->classInfo);

123:   *classLog = l;
124:   return(0);
125: }

129: /*@C
130:   ClassPerfLogDestroy - This destroys a PetscClassPerfLog object.

132:   Not collective

134:   Input Paramter:
135: . classLog - The PetscClassPerfLog

137:   Level: developer

139: .keywords: log, event, destroy
140: .seealso: ClassPerfLogCreate()
141: @*/
142: PetscErrorCode ClassPerfLogDestroy(PetscClassPerfLog classLog)
143: {

147:   PetscFree(classLog->classInfo);
148:   PetscFree(classLog);
149:   return(0);
150: }

152: /*------------------------------------------------ General Functions -------------------------------------------------*/
155: /*@C
156:   ClassPerfInfoClear - This clears a PetscClassPerfInfo object.

158:   Not collective

160:   Input Paramter:
161: . classInfo - The PetscClassPerfInfo

163:   Level: developer

165: .keywords: log, class, destroy
166: .seealso: ClassPerfLogCreate()
167: @*/
168: PetscErrorCode ClassPerfInfoClear(PetscClassPerfInfo *classInfo)
169: {
171:   classInfo->id           = -1;
172:   classInfo->creations    = 0;
173:   classInfo->destructions = 0;
174:   classInfo->mem          = 0.0;
175:   classInfo->descMem      = 0.0;
176:   return(0);
177: }

181: /*@C
182:   ClassPerfLogEnsureSize - This ensures that a PetscClassPerfLog is at least of a certain size.

184:   Not collective

186:   Input Paramters:
187: + classLog - The PetscClassPerfLog
188: - size     - The size

190:   Level: developer

192: .keywords: log, class, size, ensure
193: .seealso: ClassPerfLogCreate()
194: @*/
195: PetscErrorCode ClassPerfLogEnsureSize(PetscClassPerfLog classLog, int size)
196: {
197:   PetscClassPerfInfo *classInfo;
198:   PetscErrorCode     ierr;

201:   while (size > classLog->maxClasses) {
202:     PetscMalloc(classLog->maxClasses*2 * sizeof(PetscClassPerfInfo), &classInfo);
203:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(PetscClassPerfInfo));
204:     PetscFree(classLog->classInfo);

206:     classLog->classInfo   = classInfo;
207:     classLog->maxClasses *= 2;
208:   }
209:   while (classLog->numClasses < size) {
210:     ClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
211:   }
212:   return(0);
213: }

215: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
218: /*@C
219:   PetscClassRegLogRegister - Registers a class for logging operations in an application code.

221:   Not Collective

223:   Input Parameters:
224: + classLog - The ClassLog
225: - cname    - The name associated with the class

227:   Output Parameter:
228: .  classid   - The classid

230:   Level: developer

232: .keywords: log, class, register
233: .seealso: PetscClassIdRegister()
234: @*/
235: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
236: {
237:   PetscClassRegInfo *classInfo;
238:   char              *str;
239:   int               c;
240:   PetscErrorCode    ierr;

244:   c = classLog->numClasses++;
245:   if (classLog->numClasses > classLog->maxClasses) {
246:     PetscMalloc(classLog->maxClasses*2 * sizeof(PetscClassRegInfo), &classInfo);
247:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(PetscClassRegInfo));
248:     PetscFree(classLog->classInfo);

250:     classLog->classInfo   = classInfo;
251:     classLog->maxClasses *= 2;
252:   }
253:   PetscStrallocpy(cname, &str);

255:   classLog->classInfo[c].name    = str;
256:   classLog->classInfo[c].classid = classid;
257:   return(0);
258: }

260: /*------------------------------------------------ Query Functions --------------------------------------------------*/
263: /*@C
264:   PetscClassRegLogGetClass - This function returns the class corresponding to a given classid.

266:   Not Collective

268:   Input Parameters:
269: + classLog - The PetscClassRegLog
270: - cookie   - The cookie

272:   Output Parameter:
273: . oclass   - The class id

275:   Level: developer

277: .keywords: log, class, register
278: .seealso: PetscClassIdRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
279: @*/
280: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
281: {
282:   int c;

286:   for (c = 0; c < classLog->numClasses; c++) {
287:     /* Could do bisection here */
288:     if (classLog->classInfo[c].classid == classid) break;
289:   }
290:   if (c >= classLog->numClasses) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid object classid %d\nThis often happens if you compile with PETSC_USE_DYNAMIC_LIBRARIES, but link with static libraries.", classid);
291:   *oclass = c;
292:   return(0);
293: }

295: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
296: /* Default object create logger */
299: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
300: {
301:   PetscStageLog     stageLog;
302:   PetscClassRegLog  classRegLog;
303:   PetscClassPerfLog classPerfLog;
304:   Action            *tmpAction;
305:   Object            *tmpObjects;
306:   PetscLogDouble    start, end;
307:   int               oclass = 0;
308:   int               stage;
309:   PetscErrorCode    ierr;

312:   /* Record stage info */
313:   PetscLogGetStageLog(&stageLog);
314:   PetscStageLogGetCurrent(stageLog, &stage);
315:   PetscStageLogGetClassRegLog(stageLog, &classRegLog);
316:   PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
317:   PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
318:   classPerfLog->classInfo[oclass].creations++;
319:   /* Dynamically enlarge logging structures */
320:   if (petsc_numActions >= petsc_maxActions) {
321:     PetscTime(&start);
322:     PetscMalloc(petsc_maxActions*2 * sizeof(Action), &tmpAction);
323:     PetscMemcpy(tmpAction, petsc_actions, petsc_maxActions * sizeof(Action));
324:     PetscFree(petsc_actions);

326:     petsc_actions     = tmpAction;
327:     petsc_maxActions *= 2;
328:     PetscTime(&end);
329:     petsc_BaseTime += (end - start);
330:   }

332:   petsc_numObjects = obj->id;
333:   /* Record the creation action */
334:   if (petsc_logActions) {
335:     PetscTime(&petsc_actions[petsc_numActions].time);
336:     petsc_actions[petsc_numActions].time   -= petsc_BaseTime;
337:     petsc_actions[petsc_numActions].action  = CREATE;
338:     petsc_actions[petsc_numActions].classid = obj->classid;
339:     petsc_actions[petsc_numActions].id1     = petsc_numObjects;
340:     petsc_actions[petsc_numActions].id2     = -1;
341:     petsc_actions[petsc_numActions].id3     = -1;
342:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

344:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
345:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
346:     petsc_numActions++;
347:   }
348:   /* Record the object */
349:   if (petsc_logObjects) {
350:     petsc_objects[petsc_numObjects].parent = -1;
351:     petsc_objects[petsc_numObjects].obj    = obj;

353:     PetscMemzero(petsc_objects[petsc_numObjects].name, 64 * sizeof(char));
354:     PetscMemzero(petsc_objects[petsc_numObjects].info, 64 * sizeof(char));

356:     /* Dynamically enlarge logging structures */
357:     if (petsc_numObjects >= petsc_maxObjects) {
358:       PetscTime(&start);
359:       PetscMalloc(petsc_maxObjects*2 * sizeof(Object), &tmpObjects);
360:       PetscMemcpy(tmpObjects, petsc_objects, petsc_maxObjects * sizeof(Object));
361:       PetscFree(petsc_objects);

363:       petsc_objects     = tmpObjects;
364:       petsc_maxObjects *= 2;
365:       PetscTime(&end);
366:       petsc_BaseTime += (end - start);
367:     }
368:   }
369:   return(0);
370: }

372: /* Default object destroy logger */
375: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
376: {
377:   PetscStageLog     stageLog;
378:   PetscClassRegLog  classRegLog;
379:   PetscClassPerfLog classPerfLog;
380:   Action            *tmpAction;
381:   PetscLogDouble    start, end;
382:   int               oclass = 0;
383:   int               stage;
384:   PetscErrorCode    ierr;

387:   /* Record stage info */
388:   PetscLogGetStageLog(&stageLog);
389:   PetscStageLogGetCurrent(stageLog, &stage);
390:   if (stage != -1) {
391:     /* That can happen if the log summary is output before some things are destroyed */
392:     PetscStageLogGetClassRegLog(stageLog, &classRegLog);
393:     PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
394:     PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
395:     classPerfLog->classInfo[oclass].destructions++;
396:     classPerfLog->classInfo[oclass].mem += obj->mem;
397:   }
398:   /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
399:   petsc_numObjectsDestroyed++;
400:   /* Dynamically enlarge logging structures */
401:   if (petsc_numActions >= petsc_maxActions) {
402:     PetscTime(&start);
403:     PetscMalloc(petsc_maxActions*2 * sizeof(Action), &tmpAction);
404:     PetscMemcpy(tmpAction, petsc_actions, petsc_maxActions * sizeof(Action));
405:     PetscFree(petsc_actions);

407:     petsc_actions     = tmpAction;
408:     petsc_maxActions *= 2;
409:     PetscTime(&end);
410:     petsc_BaseTime += (end - start);
411:   }
412:   /* Record the destruction action */
413:   if (petsc_logActions) {
414:     PetscTime(&petsc_actions[petsc_numActions].time);
415:     petsc_actions[petsc_numActions].time   -= petsc_BaseTime;
416:     petsc_actions[petsc_numActions].action  = DESTROY;
417:     petsc_actions[petsc_numActions].classid = obj->classid;
418:     petsc_actions[petsc_numActions].id1     = obj->id;
419:     petsc_actions[petsc_numActions].id2     = -1;
420:     petsc_actions[petsc_numActions].id3     = -1;
421:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

423:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
424:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
425:     petsc_numActions++;
426:   }
427:   if (petsc_logObjects) {
428:     if (obj->name) {
429:       PetscStrncpy(petsc_objects[obj->id].name, obj->name, 64);
430:     }
431:     petsc_objects[obj->id].obj = NULL;
432:     petsc_objects[obj->id].mem = obj->mem;
433:   }
434:   return(0);
435: }