Actual source code: classLog.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*/

 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;

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

 41: /*@C
 42:   PetscClassRegLogDestroy - This destroys a PetscClassRegLog object.

 44:   Not collective

 46:   Input Paramter:
 47: . classLog - The PetscClassRegLog

 49:   Level: developer

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

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

 70: /*@C
 71:   PetscClassRegInfoDestroy - This destroys a PetscClassRegInfo object.

 73:   Not collective

 75:   Input Parameter:
 76: . c - The PetscClassRegInfo

 78:   Level: developer

 80: .keywords: log, class, destroy
 81: .seealso: PetscStageLogDestroy(), EventLogDestroy()
 82: @*/
 83: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
 84: {

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

 94: /*@C
 95:   ClassPerfLogCreate - This creates a PetscClassPerfLog object.

 97:   Not collective

 99:   Input Parameter:
100: . classLog - The PetscClassPerfLog

102:   Level: developer

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

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

123: /*@C
124:   ClassPerfLogDestroy - This destroys a PetscClassPerfLog object.

126:   Not collective

128:   Input Paramter:
129: . classLog - The PetscClassPerfLog

131:   Level: developer

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

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

146: /*------------------------------------------------ General Functions -------------------------------------------------*/
149: /*@C
150:   ClassPerfInfoClear - This clears a PetscClassPerfInfo object.

152:   Not collective

154:   Input Paramter:
155: . classInfo - The PetscClassPerfInfo

157:   Level: developer

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

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

178:   Not collective

180:   Input Paramters:
181: + classLog - The PetscClassPerfLog
182: - size     - The size

184:   Level: developer

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

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

208: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
211: /*@C
212:   PetscClassRegLogRegister - Registers a class for logging operations in an application code.

214:   Not Collective

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

220:   Output Parameter:
221: .  classid   - The classid

223:   Level: developer

225: .keywords: log, class, register
226: .seealso: PetscClassIdRegister()
227: @*/
228: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
229: {
230:   PetscClassRegInfo   *classInfo;
231:   char           *str;
232:   int            c;

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

251: /*------------------------------------------------ Query Functions --------------------------------------------------*/
254: /*@C
255:   PetscClassRegLogGetClass - This function returns the class corresponding to a given classid.

257:   Not Collective

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

266:   Level: developer

268: .keywords: log, class, register
269: .seealso: PetscClassIdRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
270: @*/
271: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
272: {
273:   int c;

277:   for(c = 0; c < classLog->numClasses; c++) {
278:     /* Could do bisection here */
279:     if (classLog->classInfo[c].classid == classid) break;
280:   }
281:   if (c >= classLog->numClasses) {
282:     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);
283:   }
284:   *oclass = c;
285:   return(0);
286: }

288: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
289: /* Default object create logger */
292: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
293: {
294:   PetscStageLog       stageLog;
295:   PetscClassRegLog    classRegLog;
296:   PetscClassPerfLog   classPerfLog;
297:   Action        *tmpAction;
298:   Object        *tmpObjects;
299:   PetscLogDouble start, end;
300:   int            oclass = 0;
301:   int            stage;

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

324:   petsc_numObjects = obj->id;
325:   /* Record the creation action */
326:   if (petsc_logActions) {
327:     PetscTime(petsc_actions[petsc_numActions].time);
328:     petsc_actions[petsc_numActions].time  -= petsc_BaseTime;
329:     petsc_actions[petsc_numActions].action = CREATE;
330:     petsc_actions[petsc_numActions].classid = obj->classid;
331:     petsc_actions[petsc_numActions].id1    = petsc_numObjects;
332:     petsc_actions[petsc_numActions].id2    = -1;
333:     petsc_actions[petsc_numActions].id3    = -1;
334:     petsc_actions[petsc_numActions].flops  = petsc_TotalFlops;
335:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
336:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
337:     petsc_numActions++;
338:   }
339:   /* Record the object */
340:   if (petsc_logObjects) {
341:     petsc_objects[petsc_numObjects].parent = -1;
342:     petsc_objects[petsc_numObjects].obj    = obj;
343:     PetscMemzero(petsc_objects[petsc_numObjects].name, 64 * sizeof(char));
344:     PetscMemzero(petsc_objects[petsc_numObjects].info, 64 * sizeof(char));

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

361: /* Default object destroy logger */
364: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
365: {
366:   PetscStageLog       stageLog;
367:   PetscClassRegLog    classRegLog;
368:   PetscClassPerfLog   classPerfLog;
369:   Action        *tmpAction;
370:   PetscLogDouble start, end;
371:   int            oclass = 0;
372:   int            stage;

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