Actual source code: classLog.c

  1: #define PETSC_DLL

 3:  #include petsc.h
 4:  #include src/sys/src/plog/ptime.h
 5:  #include 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 _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:   if (c->name) {
 88:     PetscFree(c->name);
 89:   }
 90:   return(0);
 91: }

 95: /*@C
 96:   ClassPerfLogCreate - This creates a ClassPerfLog object.

 98:   Not collective

100:   Input Parameter:
101: . classLog - The ClassPerfLog

103:   Level: beginner

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

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

124: /*@C
125:   ClassPerfLogDestroy - This destroys a ClassPerfLog object.

127:   Not collective

129:   Input Paramter:
130: . classLog - The ClassPerfLog

132:   Level: beginner

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

142:   PetscFree(classLog->classInfo);
143:   PetscFree(classLog);
144:   return(0);
145: }

147: /*------------------------------------------------ General Functions -------------------------------------------------*/
150: /*@C
151:   ClassPerfInfoClear - This clears a ClassPerfInfo object.

153:   Not collective

155:   Input Paramter:
156: . classInfo - The ClassPerfInfo

158:   Level: beginner

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

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

179:   Not collective

181:   Input Paramters:
182: + classLog - The ClassPerfLog
183: - size     - The size

185:   Level: intermediate

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

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

209: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
212: /*@C
213:   ClassRegLogRegister - Registers a class for logging operations in an application code.
214:   A prefered cookie is given on input, and the actual cookie is returned on output. If
215:   the user has no preference, PETSC_DECIDE will cause the cookie to be automatically
216:   assigned, and unique in this ClassLog.

218:   Not Collective

220:   Input Parameters:
221: + classLog - The ClassLog
222: . cname    - The name associated with the class
223: - cookie   - The prefered cookie (or PETSC_DECIDE), and the actual cookie on output

225:   Level: developer

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

240:   c = classLog->numClasses++;
241:   if (classLog->numClasses > classLog->maxClasses) {
242:     PetscMalloc(classLog->maxClasses*2 * sizeof(ClassRegInfo), &classInfo);
243:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassRegInfo));
244:     PetscFree(classLog->classInfo);
245:     classLog->classInfo   = classInfo;
246:     classLog->maxClasses *= 2;
247:   }
248:   PetscStrallocpy(cname, &str);
249:   classLog->classInfo[c].name     = str;
250:   if (*cookie == PETSC_DECIDE) {
251:     classLog->classInfo[c].cookie = ++PETSC_LARGEST_COOKIE;
252:   } else if (*cookie >= 0) {
253:     classLog->classInfo[c].cookie = *cookie;
254:     /* Need to check here for montonicity and insert if necessary */
255:   } else {
256:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Invalid suggested cookie %d", (int)*cookie);
257:   }
258:   *cookie = classLog->classInfo[c].cookie;
259:   return(0);
260: }

262: /*------------------------------------------------ Query Functions --------------------------------------------------*/
265: /*@C
266:   ClassRegLogGetClass - This function returns the class corresponding to a given cookie.

268:   Not Collective

270:   Input Parameters:
271: + classLog - The ClassRegLog
272: - cookie   - The cookie
273:             
274:   Output Parameter:
275: . oclass   - The class id

277:   Level: developer

279: .keywords: log, class, register
280: .seealso: PetscLogClassRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
281: @*/
282: PetscErrorCode ClassRegLogGetClass(ClassRegLog classLog, PetscCookie cookie, int *oclass)
283: {
284:   int c;

288:   for(c = 0; c < classLog->numClasses; c++) {
289:     /* Could do bisection here */
290:     if (classLog->classInfo[c].cookie == cookie) break;
291:   }
292:   if (c >= classLog->numClasses) {
293:     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);
294:   }
295:   *oclass = c;
296:   return(0);
297: }

299: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
300: /* Default object create logger */
303: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
304: {
305:   StageLog       stageLog;
306:   ClassRegLog    classRegLog;
307:   ClassPerfLog   classPerfLog;
308:   Action        *tmpAction;
309:   Object        *tmpObjects;
310:   PetscLogDouble start, end;
311:   int            oclass;
312:   int            stage;

316:   /* Record stage info */
317:   PetscLogGetStageLog(&stageLog);
318:   StageLogGetCurrent(stageLog, &stage);
319:   StageLogGetClassRegLog(stageLog, &classRegLog);
320:   StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
321:   ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
322:   classPerfLog->classInfo[oclass].creations++;
323:   /* Dynamically enlarge logging structures */
324:   if (numActions >= maxActions) {
325:     PetscTime(start);
326:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
327:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
328:     PetscFree(actions);
329:     actions     = tmpAction;
330:     maxActions *= 2;
331:     PetscTime(end);
332:     BaseTime += (end - start);
333:   }

335:   numObjects = obj->id;
336:   /* Record the creation action */
337:   if (logActions) {
338:     PetscTime(actions[numActions].time);
339:     actions[numActions].time  -= BaseTime;
340:     actions[numActions].action = CREATE;
341:     actions[numActions].cookie = obj->cookie;
342:     actions[numActions].id1    = numObjects;
343:     actions[numActions].id2    = -1;
344:     actions[numActions].id3    = -1;
345:     actions[numActions].flops  = _TotalFlops;
346:     PetscMallocGetCurrentUsage(&actions[numActions].mem);
347:     PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
348:     numActions++;
349:   }
350:   /* Record the object */
351:   if (logObjects) {
352:     objects[numObjects].parent = -1;
353:     objects[numObjects].obj    = obj;
354:     PetscMemzero(objects[numObjects].name, 64 * sizeof(char));
355:     PetscMemzero(objects[numObjects].info, 64 * sizeof(char));

357:   /* Dynamically enlarge logging structures */
358:     if (numObjects >= maxObjects) {
359:       PetscTime(start);
360:       PetscMalloc(maxObjects*2 * sizeof(Object), &tmpObjects);
361:       PetscMemcpy(tmpObjects, objects, maxObjects * sizeof(Object));
362:       PetscFree(objects);
363:       objects     = tmpObjects;
364:       maxObjects *= 2;
365:       PetscTime(end);
366:       BaseTime += (end - start);
367:     }
368:   }
369:   return(0);
370: }

372: /* Default object destroy logger */
375: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
376: {
377:   StageLog       stageLog;
378:   ClassRegLog    classRegLog;
379:   ClassPerfLog   classPerfLog;
380:   Action        *tmpAction;
381:   PetscLogDouble start, end;
382:   int            oclass;
383:   int            stage;

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