Actual source code: classlog.c

petsc-master 2019-07-16
Report Typos and Errors

  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>

 10: /*@C
 11:   PetscClassRegLogCreate - This creates a PetscClassRegLog object.

 13:   Not collective

 15:   Input Parameter:
 16: . classLog - The PetscClassRegLog

 18:   Level: developer

 20: .seealso: PetscClassRegLogDestroy(), PetscStageLogCreate()
 21: @*/
 22: PetscErrorCode PetscClassRegLogCreate(PetscClassRegLog *classLog)
 23: {
 24:   PetscClassRegLog l;
 25:   PetscErrorCode   ierr;

 28:   PetscNew(&l);

 30:   l->numClasses = 0;
 31:   l->maxClasses = 100;

 33:   PetscMalloc1(l->maxClasses, &l->classInfo);

 35:   *classLog = l;
 36:   return(0);
 37: }

 39: /*@C
 40:   PetscClassRegLogDestroy - This destroys a PetscClassRegLog object.

 42:   Not collective

 44:   Input Paramter:
 45: . classLog - The PetscClassRegLog

 47:   Level: developer

 49: .seealso: PetscClassRegLogCreate()
 50: @*/
 51: PetscErrorCode PetscClassRegLogDestroy(PetscClassRegLog classLog)
 52: {
 53:   int            c;

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

 65: /*@C
 66:   PetscClassRegInfoDestroy - This destroys a PetscClassRegInfo object.

 68:   Not collective

 70:   Input Parameter:
 71: . c - The PetscClassRegInfo

 73:   Level: developer

 75: .seealso: PetscStageLogDestroy(), EventLogDestroy()
 76: @*/
 77: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
 78: {

 82:   PetscFree(c->name);
 83:   return(0);
 84: }

 86: /*@C
 87:   PetscClassPerfLogCreate - This creates a PetscClassPerfLog object.

 89:   Not collective

 91:   Input Parameter:
 92: . classLog - The PetscClassPerfLog

 94:   Level: developer

 96: .seealso: PetscClassPerfLogDestroy(), PetscStageLogCreate()
 97: @*/
 98: PetscErrorCode PetscClassPerfLogCreate(PetscClassPerfLog *classLog)
 99: {
100:   PetscClassPerfLog l;
101:   PetscErrorCode    ierr;

104:   PetscNew(&l);

106:   l->numClasses = 0;
107:   l->maxClasses = 100;

109:   PetscMalloc1(l->maxClasses, &l->classInfo);

111:   *classLog = l;
112:   return(0);
113: }

115: /*@C
116:   PetscClassPerfLogDestroy - This destroys a PetscClassPerfLog object.

118:   Not collective

120:   Input Paramter:
121: . classLog - The PetscClassPerfLog

123:   Level: developer

125: .seealso: PetscClassPerfLogCreate()
126: @*/
127: PetscErrorCode PetscClassPerfLogDestroy(PetscClassPerfLog classLog)
128: {

132:   PetscFree(classLog->classInfo);
133:   PetscFree(classLog);
134:   return(0);
135: }

137: /*------------------------------------------------ General Functions -------------------------------------------------*/
138: /*@C
139:   PetscClassPerfInfoClear - This clears a PetscClassPerfInfo object.

141:   Not collective

143:   Input Paramter:
144: . classInfo - The PetscClassPerfInfo

146:   Level: developer

148: .seealso: PetscClassPerfLogCreate()
149: @*/
150: PetscErrorCode PetscClassPerfInfoClear(PetscClassPerfInfo *classInfo)
151: {
153:   classInfo->id           = -1;
154:   classInfo->creations    = 0;
155:   classInfo->destructions = 0;
156:   classInfo->mem          = 0.0;
157:   classInfo->descMem      = 0.0;
158:   return(0);
159: }

161: /*@C
162:   PetscClassPerfLogEnsureSize - This ensures that a PetscClassPerfLog is at least of a certain size.

164:   Not collective

166:   Input Paramters:
167: + classLog - The PetscClassPerfLog
168: - size     - The size

170:   Level: developer

172: .seealso: PetscClassPerfLogCreate()
173: @*/
174: PetscErrorCode PetscClassPerfLogEnsureSize(PetscClassPerfLog classLog, int size)
175: {
176:   PetscClassPerfInfo *classInfo;
177:   PetscErrorCode     ierr;

180:   while (size > classLog->maxClasses) {
181:     PetscMalloc1(classLog->maxClasses*2, &classInfo);
182:     PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
183:     PetscFree(classLog->classInfo);

185:     classLog->classInfo   = classInfo;
186:     classLog->maxClasses *= 2;
187:   }
188:   while (classLog->numClasses < size) {
189:     PetscClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
190:   }
191:   return(0);
192: }

194: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
195: /*@C
196:   PetscClassRegLogRegister - Registers a class for logging operations in an application code.

198:   Not Collective

200:   Input Parameters:
201: + classLog - The ClassLog
202: - cname    - The name associated with the class

204:   Output Parameter:
205: .  classid   - The classid

207:   Level: developer

209: .seealso: PetscClassIdRegister()
210: @*/
211: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
212: {
213:   PetscClassRegInfo *classInfo;
214:   char              *str;
215:   int               c;
216:   PetscErrorCode    ierr;

220:   c = classLog->numClasses++;
221:   if (classLog->numClasses > classLog->maxClasses) {
222:     PetscMalloc1(classLog->maxClasses*2, &classInfo);
223:     PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
224:     PetscFree(classLog->classInfo);

226:     classLog->classInfo   = classInfo;
227:     classLog->maxClasses *= 2;
228:   }
229:   PetscStrallocpy(cname, &str);

231:   classLog->classInfo[c].name    = str;
232:   classLog->classInfo[c].classid = classid;
233:   return(0);
234: }

236: /*------------------------------------------------ Query Functions --------------------------------------------------*/
237: /*@C
238:   PetscClassRegLogGetClass - This function returns the class corresponding to a given classid.

240:   Not Collective

242:   Input Parameters:
243: + classLog - The PetscClassRegLog
244: - classid  - The cookie

246:   Output Parameter:
247: . oclass   - The class id

249:   Level: developer

251: .seealso: PetscClassIdRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
252: @*/
253: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
254: {
255:   int c;

259:   for (c = 0; c < classLog->numClasses; c++) {
260:     /* Could do bisection here */
261:     if (classLog->classInfo[c].classid == classid) break;
262:   }
263:   if (c >= classLog->numClasses) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid object classid %d\nThis could happen if you compile with PETSC_HAVE_DYNAMIC_LIBRARIES, but link with static libraries.", classid);
264:   *oclass = c;
265:   return(0);
266: }

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

283:   /* Record stage info */
284:   PetscLogGetStageLog(&stageLog);
285:   PetscStageLogGetCurrent(stageLog, &stage);
286:   PetscStageLogGetClassRegLog(stageLog, &classRegLog);
287:   PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
288:   PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
289:   classPerfLog->classInfo[oclass].creations++;
290:   /* Dynamically enlarge logging structures */
291:   if (petsc_numActions >= petsc_maxActions) {
292:     PetscTime(&start);
293:     PetscMalloc1(petsc_maxActions*2, &tmpAction);
294:     PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
295:     PetscFree(petsc_actions);

297:     petsc_actions     = tmpAction;
298:     petsc_maxActions *= 2;
299:     PetscTime(&end);
300:     petsc_BaseTime += (end - start);
301:   }

303:   petsc_numObjects = obj->id;
304:   /* Record the creation action */
305:   if (petsc_logActions) {
306:     PetscTime(&petsc_actions[petsc_numActions].time);
307:     petsc_actions[petsc_numActions].time   -= petsc_BaseTime;
308:     petsc_actions[petsc_numActions].action  = CREATE;
309:     petsc_actions[petsc_numActions].classid = obj->classid;
310:     petsc_actions[petsc_numActions].id1     = petsc_numObjects;
311:     petsc_actions[petsc_numActions].id2     = -1;
312:     petsc_actions[petsc_numActions].id3     = -1;
313:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

315:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
316:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
317:     petsc_numActions++;
318:   }
319:   /* Record the object */
320:   if (petsc_logObjects) {
321:     petsc_objects[petsc_numObjects].parent = -1;
322:     petsc_objects[petsc_numObjects].obj    = obj;

324:     PetscMemzero(petsc_objects[petsc_numObjects].name, sizeof(petsc_objects[0].name));
325:     PetscMemzero(petsc_objects[petsc_numObjects].info, sizeof(petsc_objects[0].info));

327:     /* Dynamically enlarge logging structures */
328:     if (petsc_numObjects >= petsc_maxObjects) {
329:       PetscTime(&start);
330:       PetscMalloc1(petsc_maxObjects*2, &tmpObjects);
331:       PetscArraycpy(tmpObjects, petsc_objects, petsc_maxObjects);
332:       PetscFree(petsc_objects);

334:       petsc_objects     = tmpObjects;
335:       petsc_maxObjects *= 2;
336:       PetscTime(&end);
337:       petsc_BaseTime += (end - start);
338:     }
339:   }
340:   return(0);
341: }

343: /* Default object destroy logger */
344: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
345: {
346:   PetscStageLog     stageLog;
347:   PetscClassRegLog  classRegLog;
348:   PetscClassPerfLog classPerfLog;
349:   Action            *tmpAction;
350:   PetscLogDouble    start, end;
351:   int               oclass = 0;
352:   int               stage;
353:   PetscErrorCode    ierr;

356:   /* Record stage info */
357:   PetscLogGetStageLog(&stageLog);
358:   PetscStageLogGetCurrent(stageLog, &stage);
359:   if (stage != -1) {
360:     /* That can happen if the log summary is output before some things are destroyed */
361:     PetscStageLogGetClassRegLog(stageLog, &classRegLog);
362:     PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
363:     PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
364:     classPerfLog->classInfo[oclass].destructions++;
365:     classPerfLog->classInfo[oclass].mem += obj->mem;
366:   }
367:   /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
368:   petsc_numObjectsDestroyed++;
369:   /* Dynamically enlarge logging structures */
370:   if (petsc_numActions >= petsc_maxActions) {
371:     PetscTime(&start);
372:     PetscMalloc1(petsc_maxActions*2, &tmpAction);
373:     PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
374:     PetscFree(petsc_actions);

376:     petsc_actions     = tmpAction;
377:     petsc_maxActions *= 2;
378:     PetscTime(&end);
379:     petsc_BaseTime += (end - start);
380:   }
381:   /* Record the destruction action */
382:   if (petsc_logActions) {
383:     PetscTime(&petsc_actions[petsc_numActions].time);
384:     petsc_actions[petsc_numActions].time   -= petsc_BaseTime;
385:     petsc_actions[petsc_numActions].action  = DESTROY;
386:     petsc_actions[petsc_numActions].classid = obj->classid;
387:     petsc_actions[petsc_numActions].id1     = obj->id;
388:     petsc_actions[petsc_numActions].id2     = -1;
389:     petsc_actions[petsc_numActions].id3     = -1;
390:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

392:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
393:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
394:     petsc_numActions++;
395:   }
396:   if (petsc_logObjects) {
397:     if (obj->name) {
398:       PetscStrncpy(petsc_objects[obj->id].name, obj->name, 64);
399:     }
400:     petsc_objects[obj->id].obj = NULL;
401:     petsc_objects[obj->id].mem = obj->mem;
402:   }
403:   return(0);
404: }