Actual source code: classLog.c

  1: #define PETSC_DLL

 3:  #include petsc.h
 4:  #include petsctime.h
 5:  #include src/sys/plog/plog.h

  7: /*----------------------------------------------- Creation Functions -------------------------------------------------*/
  8: /* Note: these functions do not have prototypes in a public directory, so they are considered "internal" and not exported. */
 11: /*@C
 12:   ClassRegLogCreate - This creates a ClassRegLog object.

 14:   Not collective

 16:   Input Parameter:
 17: . classLog - The ClassRegLog

 19:   Level: beginner

 21: .keywords: log, class, create
 22: .seealso: ClassRegLogDestroy(), StageLogCreate()
 23: @*/
 24: PetscErrorCode ClassRegLogCreate(ClassRegLog *classLog)
 25: {
 26:   ClassRegLog l;

 30:   PetscNew(struct _n_ClassRegLog, &l);
 31:   l->numClasses = 0;
 32:   l->maxClasses = 100;
 33:   PetscMalloc(l->maxClasses * sizeof(ClassRegInfo), &l->classInfo);
 34:   *classLog = l;
 35:   return(0);
 36: }

 40: /*@C
 41:   ClassRegLogDestroy - This destroys a ClassRegLog object.

 43:   Not collective

 45:   Input Paramter:
 46: . classLog - The ClassRegLog

 48:   Level: beginner

 50: .keywords: log, event, destroy
 51: .seealso: ClassRegLogCreate()
 52: @*/
 53: PetscErrorCode ClassRegLogDestroy(ClassRegLog classLog)\
 54: {
 55:   int c;

 59:   for(c = 0; c < classLog->numClasses; c++) {
 60:     ClassRegInfoDestroy(&classLog->classInfo[c]);
 61:   }
 62:   PetscFree(classLog->classInfo);
 63:   PetscFree(classLog);
 64:   return(0);
 65: }

 69: /*@C
 70:   ClassRegInfoDestroy - This destroys a ClassRegInfo object.

 72:   Not collective

 74:   Input Parameter:
 75: . c - The ClassRegInfo

 77:   Level: beginner

 79: .keywords: log, class, destroy
 80: .seealso: StageLogDestroy(), EventLogDestroy()
 81: @*/
 82: PetscErrorCode ClassRegInfoDestroy(ClassRegInfo *c)
 83: {

 87:   PetscFree(c->name);
 88:   return(0);
 89: }

 93: /*@C
 94:   ClassPerfLogCreate - This creates a ClassPerfLog object.

 96:   Not collective

 98:   Input Parameter:
 99: . classLog - The ClassPerfLog

101:   Level: beginner

103: .keywords: log, class, create
104: .seealso: ClassPerfLogDestroy(), StageLogCreate()
105: @*/
106: PetscErrorCode ClassPerfLogCreate(ClassPerfLog *classLog)
107: {
108:   ClassPerfLog l;

112:   PetscNew(struct _n_ClassPerfLog, &l);
113:   l->numClasses = 0;
114:   l->maxClasses = 100;
115:   PetscMalloc(l->maxClasses * sizeof(ClassPerfInfo), &l->classInfo);
116:   *classLog = l;
117:   return(0);
118: }

122: /*@C
123:   ClassPerfLogDestroy - This destroys a ClassPerfLog object.

125:   Not collective

127:   Input Paramter:
128: . classLog - The ClassPerfLog

130:   Level: beginner

132: .keywords: log, event, destroy
133: .seealso: ClassPerfLogCreate()
134: @*/
135: PetscErrorCode ClassPerfLogDestroy(ClassPerfLog classLog)
136: {

140:   PetscFree(classLog->classInfo);
141:   PetscFree(classLog);
142:   return(0);
143: }

145: /*------------------------------------------------ General Functions -------------------------------------------------*/
148: /*@C
149:   ClassPerfInfoClear - This clears a ClassPerfInfo object.

151:   Not collective

153:   Input Paramter:
154: . classInfo - The ClassPerfInfo

156:   Level: beginner

158: .keywords: log, class, destroy
159: .seealso: ClassPerfLogCreate()
160: @*/
161: PetscErrorCode ClassPerfInfoClear(ClassPerfInfo *classInfo)
162: {
164:   classInfo->id           = -1;
165:   classInfo->creations    = 0;
166:   classInfo->destructions = 0;
167:   classInfo->mem          = 0.0;
168:   classInfo->descMem      = 0.0;
169:   return(0);
170: }

174: /*@C
175:   ClassPerfLogEnsureSize - This ensures that a ClassPerfLog is at least of a certain size.

177:   Not collective

179:   Input Paramters:
180: + classLog - The ClassPerfLog
181: - size     - The size

183:   Level: intermediate

185: .keywords: log, class, size, ensure
186: .seealso: ClassPerfLogCreate()
187: @*/
188: PetscErrorCode ClassPerfLogEnsureSize(ClassPerfLog classLog, int size)
189: {
190:   ClassPerfInfo *classInfo;

194:   while(size > classLog->maxClasses) {
195:     PetscMalloc(classLog->maxClasses*2 * sizeof(ClassPerfInfo), &classInfo);
196:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassPerfInfo));
197:     PetscFree(classLog->classInfo);
198:     classLog->classInfo   = classInfo;
199:     classLog->maxClasses *= 2;
200:   }
201:   while(classLog->numClasses < size) {
202:     ClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
203:   }
204:   return(0);
205: }

207: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
210: /*@C
211:   ClassRegLogRegister - Registers a class for logging operations in an application code.

213:   Not Collective

215:   Input Parameters:
216: + classLog - The ClassLog
217: - cname    - The name associated with the class

219:   Output Parameter:
220: .  cookie   - The cookie

222:   Level: developer

224: .keywords: log, class, register
225: .seealso: PetscLogClassRegister()
226: @*/
227: PetscErrorCode ClassRegLogRegister(ClassRegLog classLog, const char cname[], PetscCookie *cookie)
228: {
229:   ClassRegInfo *classInfo;
230:   char         *str;
231:   int           c;

237:   c = classLog->numClasses++;
238:   if (classLog->numClasses > classLog->maxClasses) {
239:     PetscMalloc(classLog->maxClasses*2 * sizeof(ClassRegInfo), &classInfo);
240:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassRegInfo));
241:     PetscFree(classLog->classInfo);
242:     classLog->classInfo   = classInfo;
243:     classLog->maxClasses *= 2;
244:   }
245:   PetscStrallocpy(cname, &str);
246:   classLog->classInfo[c].name     = str;
247:   PetscCookieRegister(cookie);
248:   classLog->classInfo[c].cookie = *cookie;
249:   return(0);
250: }

252: /*------------------------------------------------ Query Functions --------------------------------------------------*/
255: /*@C
256:   ClassRegLogGetClass - This function returns the class corresponding to a given cookie.

258:   Not Collective

260:   Input Parameters:
261: + classLog - The ClassRegLog
262: - cookie   - The cookie
263:             
264:   Output Parameter:
265: . oclass   - The class id

267:   Level: developer

269: .keywords: log, class, register
270: .seealso: PetscLogClassRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
271: @*/
272: PetscErrorCode ClassRegLogGetClass(ClassRegLog classLog, PetscCookie cookie, int *oclass)
273: {
274:   int c;

278:   for(c = 0; c < classLog->numClasses; c++) {
279:     /* Could do bisection here */
280:     if (classLog->classInfo[c].cookie == cookie) break;
281:   }
282:   if (c >= classLog->numClasses) {
283:     SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid object cookie %d\nThis often happens if you compile with PETSC_USE_DYNAMIC_LIBRARIES, but link with static libraries.", cookie);
284:   }
285:   *oclass = c;
286:   return(0);
287: }

289: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
290: /* Default object create logger */
293: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
294: {
295:   StageLog       stageLog;
296:   ClassRegLog    classRegLog;
297:   ClassPerfLog   classPerfLog;
298:   Action        *tmpAction;
299:   Object        *tmpObjects;
300:   PetscLogDouble start, end;
301:   int            oclass;
302:   int            stage;

306:   /* Record stage info */
307:   PetscLogGetStageLog(&stageLog);
308:   StageLogGetCurrent(stageLog, &stage);
309:   StageLogGetClassRegLog(stageLog, &classRegLog);
310:   StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
311:   ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
312:   classPerfLog->classInfo[oclass].creations++;
313:   /* Dynamically enlarge logging structures */
314:   if (numActions >= maxActions) {
315:     PetscTime(start);
316:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
317:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
318:     PetscFree(actions);
319:     actions     = tmpAction;
320:     maxActions *= 2;
321:     PetscTime(end);
322:     BaseTime += (end - start);
323:   }

325:   numObjects = obj->id;
326:   /* Record the creation action */
327:   if (logActions) {
328:     PetscTime(actions[numActions].time);
329:     actions[numActions].time  -= BaseTime;
330:     actions[numActions].action = CREATE;
331:     actions[numActions].cookie = obj->cookie;
332:     actions[numActions].id1    = numObjects;
333:     actions[numActions].id2    = -1;
334:     actions[numActions].id3    = -1;
335:     actions[numActions].flops  = _TotalFlops;
336:     PetscMallocGetCurrentUsage(&actions[numActions].mem);
337:     PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
338:     numActions++;
339:   }
340:   /* Record the object */
341:   if (logObjects) {
342:     objects[numObjects].parent = -1;
343:     objects[numObjects].obj    = obj;
344:     PetscMemzero(objects[numObjects].name, 64 * sizeof(char));
345:     PetscMemzero(objects[numObjects].info, 64 * sizeof(char));

347:   /* Dynamically enlarge logging structures */
348:     if (numObjects >= maxObjects) {
349:       PetscTime(start);
350:       PetscMalloc(maxObjects*2 * sizeof(Object), &tmpObjects);
351:       PetscMemcpy(tmpObjects, objects, maxObjects * sizeof(Object));
352:       PetscFree(objects);
353:       objects     = tmpObjects;
354:       maxObjects *= 2;
355:       PetscTime(end);
356:       BaseTime += (end - start);
357:     }
358:   }
359:   return(0);
360: }

362: /* Default object destroy logger */
365: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
366: {
367:   StageLog       stageLog;
368:   ClassRegLog    classRegLog;
369:   ClassPerfLog   classPerfLog;
370:   Action        *tmpAction;
371:   PetscLogDouble start, end;
372:   int            oclass;
373:   int            stage;

377:   /* Record stage info */
378:   PetscLogGetStageLog(&stageLog);
379:   StageLogGetCurrent(stageLog, &stage);
380:   if (stage != -1) {
381:     /* That can happen if the log summary is output before some things are destroyed */
382:     StageLogGetClassRegLog(stageLog, &classRegLog);
383:     StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
384:     ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
385:     classPerfLog->classInfo[oclass].destructions++;
386:     classPerfLog->classInfo[oclass].mem += obj->mem;
387:   }
388:   /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
389:   numObjectsDestroyed++;
390:   /* Dynamically enlarge logging structures */
391:   if (numActions >= maxActions) {
392:     PetscTime(start);
393:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
394:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
395:     PetscFree(actions);
396:     actions     = tmpAction;
397:     maxActions *= 2;
398:     PetscTime(end);
399:     BaseTime += (end - start);
400:   }
401:   /* Record the destruction action */
402:   if (logActions) {
403:     PetscTime(actions[numActions].time);
404:     actions[numActions].time  -= BaseTime;
405:     actions[numActions].action = DESTROY;
406:     actions[numActions].cookie = obj->cookie;
407:     actions[numActions].id1    = obj->id;
408:     actions[numActions].id2    = -1;
409:     actions[numActions].id3    = -1;
410:     actions[numActions].flops  = _TotalFlops;
411:     PetscMallocGetCurrentUsage(&actions[numActions].mem);
412:     PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
413:     numActions++;
414:   }
415:   if (logObjects) {
416:     if (obj->name) {
417:       PetscStrncpy(objects[obj->id].name, obj->name, 64);
418:     }
419:     objects[obj->id].obj      = PETSC_NULL;
420:     objects[obj->id].mem      = obj->mem;
421:   }
422:   return(0);
423: }