Actual source code: classlog.c
petsc-3.10.5 2019-03-28
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: .keywords: log, class, create
     21: .seealso: PetscClassRegLogDestroy(), PetscStageLogCreate()
     22: @*/
     23: PetscErrorCode PetscClassRegLogCreate(PetscClassRegLog *classLog)
     24: {
     25:   PetscClassRegLog l;
     26:   PetscErrorCode   ierr;

     29:   PetscNew(&l);

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

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

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

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

     43:   Not collective

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

     48:   Level: developer

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

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

     67: /*@C
     68:   PetscClassRegInfoDestroy - This destroys a PetscClassRegInfo object.

     70:   Not collective

     72:   Input Parameter:
     73: . c - The PetscClassRegInfo

     75:   Level: developer

     77: .keywords: log, class, destroy
     78: .seealso: PetscStageLogDestroy(), EventLogDestroy()
     79: @*/
     80: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
     81: {

     85:   PetscFree(c->name);
     86:   return(0);
     87: }

     89: /*@C
     90:   PetscClassPerfLogCreate - This creates a PetscClassPerfLog object.

     92:   Not collective

     94:   Input Parameter:
     95: . classLog - The PetscClassPerfLog

     97:   Level: developer

     99: .keywords: log, class, create
    100: .seealso: PetscClassPerfLogDestroy(), PetscStageLogCreate()
    101: @*/
    102: PetscErrorCode PetscClassPerfLogCreate(PetscClassPerfLog *classLog)
    103: {
    104:   PetscClassPerfLog l;
    105:   PetscErrorCode    ierr;

    108:   PetscNew(&l);

    110:   l->numClasses = 0;
    111:   l->maxClasses = 100;

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

    115:   *classLog = l;
    116:   return(0);
    117: }

    119: /*@C
    120:   PetscClassPerfLogDestroy - This destroys a PetscClassPerfLog object.

    122:   Not collective

    124:   Input Paramter:
    125: . classLog - The PetscClassPerfLog

    127:   Level: developer

    129: .keywords: log, event, destroy
    130: .seealso: PetscClassPerfLogCreate()
    131: @*/
    132: PetscErrorCode PetscClassPerfLogDestroy(PetscClassPerfLog classLog)
    133: {

    137:   PetscFree(classLog->classInfo);
    138:   PetscFree(classLog);
    139:   return(0);
    140: }

    142: /*------------------------------------------------ General Functions -------------------------------------------------*/
    143: /*@C
    144:   PetscClassPerfInfoClear - This clears a PetscClassPerfInfo object.

    146:   Not collective

    148:   Input Paramter:
    149: . classInfo - The PetscClassPerfInfo

    151:   Level: developer

    153: .keywords: log, class, destroy
    154: .seealso: PetscClassPerfLogCreate()
    155: @*/
    156: PetscErrorCode PetscClassPerfInfoClear(PetscClassPerfInfo *classInfo)
    157: {
    159:   classInfo->id           = -1;
    160:   classInfo->creations    = 0;
    161:   classInfo->destructions = 0;
    162:   classInfo->mem          = 0.0;
    163:   classInfo->descMem      = 0.0;
    164:   return(0);
    165: }

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

    170:   Not collective

    172:   Input Paramters:
    173: + classLog - The PetscClassPerfLog
    174: - size     - The size

    176:   Level: developer

    178: .keywords: log, class, size, ensure
    179: .seealso: PetscClassPerfLogCreate()
    180: @*/
    181: PetscErrorCode PetscClassPerfLogEnsureSize(PetscClassPerfLog classLog, int size)
    182: {
    183:   PetscClassPerfInfo *classInfo;
    184:   PetscErrorCode     ierr;

    187:   while (size > classLog->maxClasses) {
    188:     PetscMalloc1(classLog->maxClasses*2, &classInfo);
    189:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(PetscClassPerfInfo));
    190:     PetscFree(classLog->classInfo);

    192:     classLog->classInfo   = classInfo;
    193:     classLog->maxClasses *= 2;
    194:   }
    195:   while (classLog->numClasses < size) {
    196:     PetscClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
    197:   }
    198:   return(0);
    199: }

    201: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
    202: /*@C
    203:   PetscClassRegLogRegister - Registers a class for logging operations in an application code.

    205:   Not Collective

    207:   Input Parameters:
    208: + classLog - The ClassLog
    209: - cname    - The name associated with the class

    211:   Output Parameter:
    212: .  classid   - The classid

    214:   Level: developer

    216: .keywords: log, class, register
    217: .seealso: PetscClassIdRegister()
    218: @*/
    219: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
    220: {
    221:   PetscClassRegInfo *classInfo;
    222:   char              *str;
    223:   int               c;
    224:   PetscErrorCode    ierr;

    228:   c = classLog->numClasses++;
    229:   if (classLog->numClasses > classLog->maxClasses) {
    230:     PetscMalloc1(classLog->maxClasses*2, &classInfo);
    231:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(PetscClassRegInfo));
    232:     PetscFree(classLog->classInfo);

    234:     classLog->classInfo   = classInfo;
    235:     classLog->maxClasses *= 2;
    236:   }
    237:   PetscStrallocpy(cname, &str);

    239:   classLog->classInfo[c].name    = str;
    240:   classLog->classInfo[c].classid = classid;
    241:   return(0);
    242: }

    244: /*------------------------------------------------ Query Functions --------------------------------------------------*/
    245: /*@C
    246:   PetscClassRegLogGetClass - This function returns the class corresponding to a given classid.

    248:   Not Collective

    250:   Input Parameters:
    251: + classLog - The PetscClassRegLog
    252: - classid  - The cookie

    254:   Output Parameter:
    255: . oclass   - The class id

    257:   Level: developer

    259: .keywords: log, class, register
    260: .seealso: PetscClassIdRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
    261: @*/
    262: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
    263: {
    264:   int c;

    268:   for (c = 0; c < classLog->numClasses; c++) {
    269:     /* Could do bisection here */
    270:     if (classLog->classInfo[c].classid == classid) break;
    271:   }
    272:   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);
    273:   *oclass = c;
    274:   return(0);
    275: }

    277: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
    278: /* Default object create logger */
    279: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
    280: {
    281:   PetscStageLog     stageLog;
    282:   PetscClassRegLog  classRegLog;
    283:   PetscClassPerfLog classPerfLog;
    284:   Action            *tmpAction;
    285:   Object            *tmpObjects;
    286:   PetscLogDouble    start, end;
    287:   int               oclass = 0;
    288:   int               stage;
    289:   PetscErrorCode    ierr;

    292:   /* Record stage info */
    293:   PetscLogGetStageLog(&stageLog);
    294:   PetscStageLogGetCurrent(stageLog, &stage);
    295:   PetscStageLogGetClassRegLog(stageLog, &classRegLog);
    296:   PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
    297:   PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
    298:   classPerfLog->classInfo[oclass].creations++;
    299:   /* Dynamically enlarge logging structures */
    300:   if (petsc_numActions >= petsc_maxActions) {
    301:     PetscTime(&start);
    302:     PetscMalloc1(petsc_maxActions*2, &tmpAction);
    303:     PetscMemcpy(tmpAction, petsc_actions, petsc_maxActions * sizeof(Action));
    304:     PetscFree(petsc_actions);

    306:     petsc_actions     = tmpAction;
    307:     petsc_maxActions *= 2;
    308:     PetscTime(&end);
    309:     petsc_BaseTime += (end - start);
    310:   }

    312:   petsc_numObjects = obj->id;
    313:   /* Record the creation action */
    314:   if (petsc_logActions) {
    315:     PetscTime(&petsc_actions[petsc_numActions].time);
    316:     petsc_actions[petsc_numActions].time   -= petsc_BaseTime;
    317:     petsc_actions[petsc_numActions].action  = CREATE;
    318:     petsc_actions[petsc_numActions].classid = obj->classid;
    319:     petsc_actions[petsc_numActions].id1     = petsc_numObjects;
    320:     petsc_actions[petsc_numActions].id2     = -1;
    321:     petsc_actions[petsc_numActions].id3     = -1;
    322:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

    324:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
    325:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
    326:     petsc_numActions++;
    327:   }
    328:   /* Record the object */
    329:   if (petsc_logObjects) {
    330:     petsc_objects[petsc_numObjects].parent = -1;
    331:     petsc_objects[petsc_numObjects].obj    = obj;

    333:     PetscMemzero(petsc_objects[petsc_numObjects].name, 64 * sizeof(char));
    334:     PetscMemzero(petsc_objects[petsc_numObjects].info, 64 * sizeof(char));

    336:     /* Dynamically enlarge logging structures */
    337:     if (petsc_numObjects >= petsc_maxObjects) {
    338:       PetscTime(&start);
    339:       PetscMalloc1(petsc_maxObjects*2, &tmpObjects);
    340:       PetscMemcpy(tmpObjects, petsc_objects, petsc_maxObjects * sizeof(Object));
    341:       PetscFree(petsc_objects);

    343:       petsc_objects     = tmpObjects;
    344:       petsc_maxObjects *= 2;
    345:       PetscTime(&end);
    346:       petsc_BaseTime += (end - start);
    347:     }
    348:   }
    349:   return(0);
    350: }

    352: /* Default object destroy logger */
    353: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
    354: {
    355:   PetscStageLog     stageLog;
    356:   PetscClassRegLog  classRegLog;
    357:   PetscClassPerfLog classPerfLog;
    358:   Action            *tmpAction;
    359:   PetscLogDouble    start, end;
    360:   int               oclass = 0;
    361:   int               stage;
    362:   PetscErrorCode    ierr;

    365:   /* Record stage info */
    366:   PetscLogGetStageLog(&stageLog);
    367:   PetscStageLogGetCurrent(stageLog, &stage);
    368:   if (stage != -1) {
    369:     /* That can happen if the log summary is output before some things are destroyed */
    370:     PetscStageLogGetClassRegLog(stageLog, &classRegLog);
    371:     PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
    372:     PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
    373:     classPerfLog->classInfo[oclass].destructions++;
    374:     classPerfLog->classInfo[oclass].mem += obj->mem;
    375:   }
    376:   /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
    377:   petsc_numObjectsDestroyed++;
    378:   /* Dynamically enlarge logging structures */
    379:   if (petsc_numActions >= petsc_maxActions) {
    380:     PetscTime(&start);
    381:     PetscMalloc1(petsc_maxActions*2, &tmpAction);
    382:     PetscMemcpy(tmpAction, petsc_actions, petsc_maxActions * sizeof(Action));
    383:     PetscFree(petsc_actions);

    385:     petsc_actions     = tmpAction;
    386:     petsc_maxActions *= 2;
    387:     PetscTime(&end);
    388:     petsc_BaseTime += (end - start);
    389:   }
    390:   /* Record the destruction action */
    391:   if (petsc_logActions) {
    392:     PetscTime(&petsc_actions[petsc_numActions].time);
    393:     petsc_actions[petsc_numActions].time   -= petsc_BaseTime;
    394:     petsc_actions[petsc_numActions].action  = DESTROY;
    395:     petsc_actions[petsc_numActions].classid = obj->classid;
    396:     petsc_actions[petsc_numActions].id1     = obj->id;
    397:     petsc_actions[petsc_numActions].id2     = -1;
    398:     petsc_actions[petsc_numActions].id3     = -1;
    399:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

    401:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
    402:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
    403:     petsc_numActions++;
    404:   }
    405:   if (petsc_logObjects) {
    406:     if (obj->name) {
    407:       PetscStrncpy(petsc_objects[obj->id].name, obj->name, 64);
    408:     }
    409:     petsc_objects[obj->id].obj = NULL;
    410:     petsc_objects[obj->id].mem = obj->mem;
    411:   }
    412:   return(0);
    413: }