Actual source code: classLog.c

  1: /* $Id: classLog.c,v 1.3 2001/01/27 21:42:08 knepley Exp $ */

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

  7: /*----------------------------------------------- Creation Functions -------------------------------------------------*/
  8: /*@C
  9:   ClassRegLogCreate - This creates a ClassRegLog object.

 11:   Not collective

 13:   Input Parameter:
 14: . classLog - The ClassRegLog

 16:   Level: beginner

 18: .keywords: log, class, create
 19: .seealso: ClassRegLogDestroy(), StageLogCreate()
 20: @*/
 21: int ClassRegLogCreate(ClassRegLog *classLog) {
 22:   ClassRegLog l;
 23:   int         ierr;

 26:   PetscNew(struct _ClassRegLog, &l);
 27:   l->numClasses = 0;
 28:   l->maxClasses = 100;
 29:   PetscMalloc(l->maxClasses * sizeof(ClassRegInfo), &l->classInfo);
 30:   *classLog = l;
 31:   return(0);
 32: }

 34: /*@C
 35:   ClassRegLogDestroy - This destroys a ClassRegLog object.

 37:   Not collective

 39:   Input Paramter:
 40: . classLog - The ClassRegLog

 42:   Level: beginner

 44: .keywords: log, event, destroy
 45: .seealso: ClassRegLogCreate()
 46: @*/
 47: int ClassRegLogDestroy(ClassRegLog classLog) {
 48:   int c;

 52:   for(c = 0; c < classLog->numClasses; c++) {
 53:     ClassRegInfoDestroy(&classLog->classInfo[c]);
 54:   }
 55:   PetscFree(classLog->classInfo);
 56:   PetscFree(classLog);
 57:   return(0);
 58: }

 60: /*@C
 61:   ClassRegInfoDestroy - This destroys a ClassRegInfo object.

 63:   Not collective

 65:   Input Parameter:
 66: . c - The ClassRegInfo

 68:   Level: beginner

 70: .keywords: log, class, destroy
 71: .seealso: StageLogDestroy(), EventLogDestroy()
 72: @*/
 73: int ClassRegInfoDestroy(ClassRegInfo *c) {

 77:   if (c->name != PETSC_NULL) {
 78:     PetscFree(c->name);
 79:   }
 80:   return(0);
 81: }

 83: /*@C
 84:   ClassPerfLogCreate - This creates a ClassPerfLog object.

 86:   Not collective

 88:   Input Parameter:
 89: . classLog - The ClassPerfLog

 91:   Level: beginner

 93: .keywords: log, class, create
 94: .seealso: ClassPerfLogDestroy(), StageLogCreate()
 95: @*/
 96: int ClassPerfLogCreate(ClassPerfLog *classLog) {
 97:   ClassPerfLog l;
 98:   int          ierr;

101:   PetscNew(struct _ClassPerfLog, &l);
102:   l->numClasses = 0;
103:   l->maxClasses = 100;
104:   PetscMalloc(l->maxClasses * sizeof(ClassPerfInfo), &l->classInfo);
105:   *classLog = l;
106:   return(0);
107: }

109: /*@C
110:   ClassPerfLogDestroy - This destroys a ClassPerfLog object.

112:   Not collective

114:   Input Paramter:
115: . classLog - The ClassPerfLog

117:   Level: beginner

119: .keywords: log, event, destroy
120: .seealso: ClassPerfLogCreate()
121: @*/
122: int ClassPerfLogDestroy(ClassPerfLog classLog) {

126:   PetscFree(classLog->classInfo);
127:   PetscFree(classLog);
128:   return(0);
129: }

131: /*------------------------------------------------ General Functions -------------------------------------------------*/
132: /*@C
133:   ClassPerfInfoClear - This clears a ClassPerfInfo object.

135:   Not collective

137:   Input Paramter:
138: . classInfo - The ClassPerfInfo

140:   Level: beginner

142: .keywords: log, class, destroy
143: .seealso: ClassPerfLogCreate()
144: @*/
145: int ClassPerfInfoClear(ClassPerfInfo *classInfo) {
147:   classInfo->id           = -1;
148:   classInfo->creations    = 0;
149:   classInfo->destructions = 0;
150:   classInfo->mem          = 0.0;
151:   classInfo->descMem      = 0.0;
152:   return(0);
153: }

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

158:   Not collective

160:   Input Paramters:
161: + classLog - The ClassPerfLog
162: - size     - The size

164:   Level: intermediate

166: .keywords: log, class, size, ensure
167: .seealso: ClassPerfLogCreate()
168: @*/
169: int ClassPerfLogEnsureSize(ClassPerfLog classLog, int size) {
170:   ClassPerfInfo *classInfo;
171:   int            ierr;

174:   while(size > classLog->maxClasses) {
175:     PetscMalloc(classLog->maxClasses*2 * sizeof(ClassPerfInfo), &classInfo);
176:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassPerfInfo));
177:     PetscFree(classLog->classInfo);
178:     classLog->classInfo   = classInfo;
179:     classLog->maxClasses *= 2;
180:   }
181:   while(classLog->numClasses < size) {
182:     ClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
183:   }
184:   return(0);
185: }

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

194:   Not Collective

196:   Input Parameters:
197: + classLog - The ClassLog
198: . cname    - The name associated with the class
199: - cookie   - The prefered cookie (or PETSC_DECIDE), and the actual cookie on output

201:   Level: developer

203: .keywords: log, class, register
204: .seealso: PetscLogClassRegister()
205: @*/
206: int ClassRegLogRegister(ClassRegLog classLog, const char cname[], int *cookie) {
207:   ClassRegInfo *classInfo;
208:   char         *str;
209:   int           c;
210:   int           ierr;

215:   c = classLog->numClasses++;
216:   if (classLog->numClasses > classLog->maxClasses) {
217:     PetscMalloc(classLog->maxClasses*2 * sizeof(ClassRegInfo), &classInfo);
218:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassRegInfo));
219:     PetscFree(classLog->classInfo);
220:     classLog->classInfo   = classInfo;
221:     classLog->maxClasses *= 2;
222:   }
223:   PetscStrallocpy(cname, &str);
224:   classLog->classInfo[c].name     = str;
225:   if (*cookie == PETSC_DECIDE) {
226:     classLog->classInfo[c].cookie = ++PETSC_LARGEST_COOKIE;
227:   } else if (*cookie >= 0) {
228:     classLog->classInfo[c].cookie = *cookie;
229:     /* Need to check here for montonicity and insert if necessary */
230:   } else {
231:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Invalid suggested cookie %d", *cookie);
232:   }
233:   *cookie = classLog->classInfo[c].cookie;
234:   return(0);
235: }

237: /*------------------------------------------------ Query Functions --------------------------------------------------*/
238: /*@C
239:   ClassRegLogGetClass - This function returns the class corresponding to a given cookie.

241:   Not Collective

243:   Input Parameters:
244: + classLog - The ClassRegLog
245: - cookie   - The cookie
246:             
247:   Output Parameter:
248: . oclass   - The class id

250:   Level: developer

252: .keywords: log, class, register
253: .seealso: PetscLogClassRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
254: @*/
255: int ClassRegLogGetClass(ClassRegLog classLog, int cookie, int *oclass) {
256:   int c;

260:   for(c = 0; c < classLog->numClasses; c++) {
261:     /* Could do bisection here */
262:     if (classLog->classInfo[c].cookie == cookie) break;
263:   }
264:   if (c >= classLog->numClasses) SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid object cookie %d", cookie);
265:   *oclass = c;
266:   return(0);
267: }

269: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
270: /* Default object create logger */
271: int PetscLogObjCreateDefault(PetscObject obj) {
272:   StageLog       stageLog;
273:   ClassRegLog    classRegLog;
274:   ClassPerfLog   classPerfLog;
275:   Action        *tmpAction;
276:   Object        *tmpObjects;
277:   PetscLogDouble start, end;
278:   int            oclass;
279:   int            stage;
280:   int            ierr;

283:   /* Record stage info */
284:   PetscLogGetStageLog(&stageLog);
285:   StageLogGetCurrent(stageLog, &stage);
286:   StageLogGetClassRegLog(stageLog, &classRegLog);
287:   StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
288:   ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
289:   classPerfLog->classInfo[oclass].creations++;
290:   /* Dynamically enlarge logging structures */
291:   if (numActions >= maxActions) {
292:     PetscTime(start);
293:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
294:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
295:     PetscFree(actions);
296:     actions     = tmpAction;
297:     maxActions *= 2;
298:     PetscTime(end);
299:     BaseTime += (end - start);
300:   }
301:   /* Record the creation action */
302:   if (logActions == PETSC_TRUE) {
303:     PetscTime(actions[numActions].time);
304:     actions[numActions].time  -= BaseTime;
305:     actions[numActions].action = CREATE;
306:     actions[numActions].event  = obj->type;
307:     actions[numActions].cookie = obj->cookie;
308:     actions[numActions].id1    = numObjects;
309:     actions[numActions].id2    = -1;
310:     actions[numActions].id3    = -1;
311:     actions[numActions].flops  = _TotalFlops;
312:     PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &actions[numActions].maxmem);
313:     numActions++;
314:   }
315:   /* Record the object */
316:   if (logObjects == PETSC_TRUE) {
317:     objects[numObjects].parent = -1;
318:     objects[numObjects].obj    = obj;
319:     PetscMemzero(objects[numObjects].name, 64 * sizeof(char));
320:     PetscMemzero(objects[numObjects].info, 64 * sizeof(char));
321:     numObjects++;
322:   }
323:   obj->id = numObjects;
324:   /* Dynamically enlarge logging structures */
325:   if (numObjects >= maxObjects) {
326:     PetscTime(start);
327:     PetscMalloc(maxObjects*2 * sizeof(Object), &tmpObjects);
328:     PetscMemcpy(tmpObjects, objects, maxObjects * sizeof(Object));
329:     PetscFree(objects);
330:     objects     = tmpObjects;
331:     maxObjects *= 2;
332:     PetscTime(end);
333:     BaseTime += (end - start);
334:   }
335:   return(0);
336: }

338: /* Default object destroy logger */
339: int PetscLogObjDestroyDefault(PetscObject obj) {
340:   StageLog       stageLog;
341:   ClassRegLog    classRegLog;
342:   ClassPerfLog   classPerfLog;
343:   Action        *tmpAction;
344:   PetscLogDouble start, end;
345:   int            oclass, pclass;
346:   PetscObject    parent;
347:   PetscTruth     exists;
348:   int            stage;
349:   int            ierr;

352:   /* Record stage info */
353:   PetscLogGetStageLog(&stageLog);
354:   StageLogGetCurrent(stageLog, &stage);
355:   StageLogGetClassRegLog(stageLog, &classRegLog);
356:   StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
357:   ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
358:   classPerfLog->classInfo[oclass].destructions++;
359:   classPerfLog->classInfo[oclass].mem += obj->mem;
360:   /* Credit all ancestors with your memory */
361:   parent = obj->parent;
362:   while (parent != PETSC_NULL) {
363:     PetscObjectExists(parent, &exists);
364:     if (exists == PETSC_FALSE) break;
365:     ClassRegLogGetClass(classRegLog, parent->cookie, &pclass);
366:     classPerfLog->classInfo[pclass].descMem += obj->mem;
367:     parent = parent->parent;
368:   }
369:   numObjectsDestroyed++;
370:   /* Dynamically enlarge logging structures */
371:   if (numActions >= maxActions) {
372:     PetscTime(start);
373:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
374:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
375:     PetscFree(actions);
376:     actions     = tmpAction;
377:     maxActions *= 2;
378:     PetscTime(end);
379:     BaseTime += (end - start);
380:   }
381:   /* Record the destruction action */
382:   if (logActions == PETSC_TRUE) {
383:     PetscTime(actions[numActions].time);
384:     actions[numActions].time  -= BaseTime;
385:     actions[numActions].action = DESTROY;
386:     actions[numActions].event  = obj->type;
387:     actions[numActions].cookie = obj->cookie;
388:     actions[numActions].id1    = obj->id;
389:     actions[numActions].id2    = -1;
390:     actions[numActions].id3    = -1;
391:     actions[numActions].flops  = _TotalFlops;
392:     PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &actions[numActions].maxmem);
393:     numActions++;
394:   }
395:   if (logObjects == PETSC_TRUE) {
396:     if (obj->parent != PETSC_NULL) {
397:       PetscObjectExists(obj->parent, &exists);
398:       if (exists == PETSC_TRUE) {
399:         objects[obj->id].parent = obj->parent->id;
400:       } else {
401:         objects[obj->id].parent = -1;
402:       }
403:     } else {
404:       objects[obj->id].parent   = -1;
405:     }
406:     if (obj->name != PETSC_NULL) {
407:       PetscStrncpy(objects[obj->id].name, obj->name, 64);
408:     }
409:     objects[obj->id].obj      = PETSC_NULL;
410:     objects[obj->id].mem      = obj->mem;
411:   }
412:   return(0);
413: }