Actual source code: classlog.c

      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;

     26:   PetscNew(&l);

     28:   l->numClasses = 0;
     29:   l->maxClasses = 100;

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

     33:   *classLog = l;
     34:   return 0;
     35: }

     37: /*@C
     38:   PetscClassRegLogDestroy - This destroys a PetscClassRegLog object.

     40:   Not collective

     42:   Input Parameter:
     43: . classLog - The PetscClassRegLog

     45:   Level: developer

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

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

     61: /*@C
     62:   PetscClassRegInfoDestroy - This destroys a PetscClassRegInfo object.

     64:   Not collective

     66:   Input Parameter:
     67: . c - The PetscClassRegInfo

     69:   Level: developer

     71: .seealso: PetscStageLogDestroy(), EventLogDestroy()
     72: @*/
     73: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
     74: {
     75:   PetscFree(c->name);
     76:   return 0;
     77: }

     79: /*@C
     80:   PetscClassPerfLogCreate - This creates a PetscClassPerfLog object.

     82:   Not collective

     84:   Input Parameter:
     85: . classLog - The PetscClassPerfLog

     87:   Level: developer

     89: .seealso: PetscClassPerfLogDestroy(), PetscStageLogCreate()
     90: @*/
     91: PetscErrorCode PetscClassPerfLogCreate(PetscClassPerfLog *classLog)
     92: {
     93:   PetscClassPerfLog l;

     95:   PetscNew(&l);

     97:   l->numClasses = 0;
     98:   l->maxClasses = 100;

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

    102:   *classLog = l;
    103:   return 0;
    104: }

    106: /*@C
    107:   PetscClassPerfLogDestroy - This destroys a PetscClassPerfLog object.

    109:   Not collective

    111:   Input Parameter:
    112: . classLog - The PetscClassPerfLog

    114:   Level: developer

    116: .seealso: PetscClassPerfLogCreate()
    117: @*/
    118: PetscErrorCode PetscClassPerfLogDestroy(PetscClassPerfLog classLog)
    119: {
    120:   PetscFree(classLog->classInfo);
    121:   PetscFree(classLog);
    122:   return 0;
    123: }

    125: /*------------------------------------------------ General Functions -------------------------------------------------*/
    126: /*@C
    127:   PetscClassPerfInfoClear - This clears a PetscClassPerfInfo object.

    129:   Not collective

    131:   Input Parameter:
    132: . classInfo - The PetscClassPerfInfo

    134:   Level: developer

    136: .seealso: PetscClassPerfLogCreate()
    137: @*/
    138: PetscErrorCode PetscClassPerfInfoClear(PetscClassPerfInfo *classInfo)
    139: {
    140:   classInfo->id           = -1;
    141:   classInfo->creations    = 0;
    142:   classInfo->destructions = 0;
    143:   classInfo->mem          = 0.0;
    144:   classInfo->descMem      = 0.0;
    145:   return 0;
    146: }

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

    151:   Not collective

    153:   Input Parameters:
    154: + classLog - The PetscClassPerfLog
    155: - size     - The size

    157:   Level: developer

    159: .seealso: PetscClassPerfLogCreate()
    160: @*/
    161: PetscErrorCode PetscClassPerfLogEnsureSize(PetscClassPerfLog classLog, int size)
    162: {
    163:   PetscClassPerfInfo *classInfo;

    165:   while (size > classLog->maxClasses) {
    166:     PetscMalloc1(classLog->maxClasses*2, &classInfo);
    167:     PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
    168:     PetscFree(classLog->classInfo);

    170:     classLog->classInfo   = classInfo;
    171:     classLog->maxClasses *= 2;
    172:   }
    173:   while (classLog->numClasses < size) {
    174:     PetscClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
    175:   }
    176:   return 0;
    177: }

    179: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
    180: /*@C
    181:   PetscClassRegLogRegister - Registers a class for logging operations in an application code.

    183:   Not Collective

    185:   Input Parameters:
    186: + classLog - The ClassLog
    187: - cname    - The name associated with the class

    189:   Output Parameter:
    190: .  classid   - The classid

    192:   Level: developer

    194: .seealso: PetscClassIdRegister()
    195: @*/
    196: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
    197: {
    198:   PetscClassRegInfo *classInfo;
    199:   char              *str;
    200:   int               c;

    203:   c = classLog->numClasses++;
    204:   if (classLog->numClasses > classLog->maxClasses) {
    205:     PetscMalloc1(classLog->maxClasses*2, &classInfo);
    206:     PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
    207:     PetscFree(classLog->classInfo);

    209:     classLog->classInfo   = classInfo;
    210:     classLog->maxClasses *= 2;
    211:   }
    212:   PetscStrallocpy(cname, &str);

    214:   classLog->classInfo[c].name    = str;
    215:   classLog->classInfo[c].classid = classid;
    216:   return 0;
    217: }

    219: /*------------------------------------------------ Query Functions --------------------------------------------------*/
    220: /*@C
    221:   PetscClassRegLogGetClass - This function returns the class corresponding to a given classid.

    223:   Not Collective

    225:   Input Parameters:
    226: + classLog - The PetscClassRegLog
    227: - classid  - The cookie

    229:   Output Parameter:
    230: . oclass   - The class id

    232:   Level: developer

    234: .seealso: PetscClassIdRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
    235: @*/
    236: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
    237: {
    238:   int c;

    241:   for (c = 0; c < classLog->numClasses; c++) {
    242:     /* Could do bisection here */
    243:     if (classLog->classInfo[c].classid == classid) break;
    244:   }
    246:   *oclass = c;
    247:   return 0;
    248: }

    250: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
    251: /* Default object create logger */
    252: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
    253: {
    254:   PetscStageLog     stageLog;
    255:   PetscClassRegLog  classRegLog;
    256:   PetscClassPerfLog classPerfLog;
    257:   Action            *tmpAction;
    258:   Object            *tmpObjects;
    259:   PetscLogDouble    start, end;
    260:   int               oclass = 0;
    261:   int               stage;

    263:   /* Record stage info */
    264:   PetscLogGetStageLog(&stageLog);
    265:   PetscStageLogGetCurrent(stageLog, &stage);
    266:   PetscStageLogGetClassRegLog(stageLog, &classRegLog);
    267:   PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
    268:   PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
    269:   classPerfLog->classInfo[oclass].creations++;
    270:   /* Dynamically enlarge logging structures */
    271:   if (petsc_numActions >= petsc_maxActions) {
    272:     PetscTime(&start);
    273:     PetscMalloc1(petsc_maxActions*2, &tmpAction);
    274:     PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
    275:     PetscFree(petsc_actions);

    277:     petsc_actions     = tmpAction;
    278:     petsc_maxActions *= 2;
    279:     PetscTime(&end);
    280:     petsc_BaseTime += (end - start);
    281:   }

    283:   petsc_numObjects = obj->id;
    284:   /* Record the creation action */
    285:   if (petsc_logActions) {
    286:     PetscTime(&petsc_actions[petsc_numActions].time);
    287:     petsc_actions[petsc_numActions].time   -= petsc_BaseTime;
    288:     petsc_actions[petsc_numActions].action  = CREATE;
    289:     petsc_actions[petsc_numActions].classid = obj->classid;
    290:     petsc_actions[petsc_numActions].id1     = petsc_numObjects;
    291:     petsc_actions[petsc_numActions].id2     = -1;
    292:     petsc_actions[petsc_numActions].id3     = -1;
    293:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

    295:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
    296:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
    297:     petsc_numActions++;
    298:   }
    299:   /* Record the object */
    300:   if (petsc_logObjects) {
    301:     petsc_objects[petsc_numObjects].parent = -1;
    302:     petsc_objects[petsc_numObjects].obj    = obj;

    304:     PetscMemzero(petsc_objects[petsc_numObjects].name, sizeof(petsc_objects[0].name));
    305:     PetscMemzero(petsc_objects[petsc_numObjects].info, sizeof(petsc_objects[0].info));

    307:     /* Dynamically enlarge logging structures */
    308:     if (petsc_numObjects >= petsc_maxObjects) {
    309:       PetscTime(&start);
    310:       PetscMalloc1(petsc_maxObjects*2, &tmpObjects);
    311:       PetscArraycpy(tmpObjects, petsc_objects, petsc_maxObjects);
    312:       PetscFree(petsc_objects);

    314:       petsc_objects     = tmpObjects;
    315:       petsc_maxObjects *= 2;
    316:       PetscTime(&end);
    317:       petsc_BaseTime += (end - start);
    318:     }
    319:   }
    320:   return 0;
    321: }

    323: /* Default object destroy logger */
    324: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
    325: {
    326:   PetscStageLog     stageLog;
    327:   PetscClassRegLog  classRegLog;
    328:   PetscClassPerfLog classPerfLog;
    329:   Action            *tmpAction;
    330:   PetscLogDouble    start, end;
    331:   int               oclass = 0;
    332:   int               stage;

    334:   /* Record stage info */
    335:   PetscLogGetStageLog(&stageLog);
    336:   PetscStageLogGetCurrent(stageLog, &stage);
    337:   if (stage != -1) {
    338:     /* That can happen if the log summary is output before some things are destroyed */
    339:     PetscStageLogGetClassRegLog(stageLog, &classRegLog);
    340:     PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
    341:     PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
    342:     classPerfLog->classInfo[oclass].destructions++;
    343:     classPerfLog->classInfo[oclass].mem += obj->mem;
    344:   }
    345:   /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
    346:   petsc_numObjectsDestroyed++;
    347:   /* Dynamically enlarge logging structures */
    348:   if (petsc_numActions >= petsc_maxActions) {
    349:     PetscTime(&start);
    350:     PetscMalloc1(petsc_maxActions*2, &tmpAction);
    351:     PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
    352:     PetscFree(petsc_actions);

    354:     petsc_actions     = tmpAction;
    355:     petsc_maxActions *= 2;
    356:     PetscTime(&end);
    357:     petsc_BaseTime += (end - start);
    358:   }
    359:   /* Record the destruction action */
    360:   if (petsc_logActions) {
    361:     PetscTime(&petsc_actions[petsc_numActions].time);
    362:     petsc_actions[petsc_numActions].time   -= petsc_BaseTime;
    363:     petsc_actions[petsc_numActions].action  = DESTROY;
    364:     petsc_actions[petsc_numActions].classid = obj->classid;
    365:     petsc_actions[petsc_numActions].id1     = obj->id;
    366:     petsc_actions[petsc_numActions].id2     = -1;
    367:     petsc_actions[petsc_numActions].id3     = -1;
    368:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

    370:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
    371:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
    372:     petsc_numActions++;
    373:   }
    374:   if (petsc_logObjects) {
    375:     if (obj->name) {
    376:       PetscStrncpy(petsc_objects[obj->id].name, obj->name, 64);
    377:     }
    378:     petsc_objects[obj->id].obj = NULL;
    379:     petsc_objects[obj->id].mem = obj->mem;
    380:   }
    381:   return 0;
    382: }