Date: 2022-03-04T17:37:12+00:00

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;
     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 Parameter:
     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 Parameter:
    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 Parameter:
    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 Parameters:
    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: }