Actual source code: classLog.c

      1: #define PETSC_DLL

     3:  #include petsc.h
     4:  #include src/sys/src/plog/ptime.h
     5:  #include plog.h

      7: /*----------------------------------------------- Creation Functions -------------------------------------------------*/
      8: /* Note: these functions do not have prototypes in a public directory, so they are considered "internal" and not exported. */
     11: /*@C
     12:   ClassRegLogCreate - This creates a ClassRegLog object.

     14:   Not collective

     16:   Input Parameter:
     17: . classLog - The ClassRegLog

     19:   Level: beginner

     21: .keywords: log, class, create
     22: .seealso: ClassRegLogDestroy(), StageLogCreate()
     23: @*/
     24: PetscErrorCode ClassRegLogCreate(ClassRegLog *classLog)
     25: {
     26:   ClassRegLog l;

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

     40: /*@C
     41:   ClassRegLogDestroy - This destroys a ClassRegLog object.

     43:   Not collective

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

     48:   Level: beginner

     50: .keywords: log, event, destroy
     51: .seealso: ClassRegLogCreate()
     52: @*/
     53: PetscErrorCode ClassRegLogDestroy(ClassRegLog classLog)\
     54: {
     55:   int c;

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

     69: /*@C
     70:   ClassRegInfoDestroy - This destroys a ClassRegInfo object.

     72:   Not collective

     74:   Input Parameter:
     75: . c - The ClassRegInfo

     77:   Level: beginner

     79: .keywords: log, class, destroy
     80: .seealso: StageLogDestroy(), EventLogDestroy()
     81: @*/
     82: PetscErrorCode ClassRegInfoDestroy(ClassRegInfo *c)
     83: {

     87:   if (c->name) {
     88:     PetscFree(c->name);
     89:   }
     90:   return(0);
     91: }

     95: /*@C
     96:   ClassPerfLogCreate - This creates a ClassPerfLog object.

     98:   Not collective

    100:   Input Parameter:
    101: . classLog - The ClassPerfLog

    103:   Level: beginner

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

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

    124: /*@C
    125:   ClassPerfLogDestroy - This destroys a ClassPerfLog object.

    127:   Not collective

    129:   Input Paramter:
    130: . classLog - The ClassPerfLog

    132:   Level: beginner

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

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

    147: /*------------------------------------------------ General Functions -------------------------------------------------*/
    150: /*@C
    151:   ClassPerfInfoClear - This clears a ClassPerfInfo object.

    153:   Not collective

    155:   Input Paramter:
    156: . classInfo - The ClassPerfInfo

    158:   Level: beginner

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

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

    179:   Not collective

    181:   Input Paramters:
    182: + classLog - The ClassPerfLog
    183: - size     - The size

    185:   Level: intermediate

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

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

    209: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
    212: /*@C
    213:   ClassRegLogRegister - Registers a class for logging operations in an application code.
    214:   A prefered cookie is given on input, and the actual cookie is returned on output. If
    215:   the user has no preference, PETSC_DECIDE will cause the cookie to be automatically
    216:   assigned, and unique in this ClassLog.

    218:   Not Collective

    220:   Input Parameters:
    221: + classLog - The ClassLog
    222: . cname    - The name associated with the class
    223: - cookie   - The prefered cookie (or PETSC_DECIDE), and the actual cookie on output

    225:   Level: developer

    227: .keywords: log, class, register
    228: .seealso: PetscLogClassRegister()
    229: @*/
    230: PetscErrorCode ClassRegLogRegister(ClassRegLog classLog, const char cname[], PetscCookie *cookie)
    231: {
    232:   ClassRegInfo *classInfo;
    233:   char         *str;
    234:   int           c;

    240:   c = classLog->numClasses++;
    241:   if (classLog->numClasses > classLog->maxClasses) {
    242:     PetscMalloc(classLog->maxClasses*2 * sizeof(ClassRegInfo), &classInfo);
    243:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassRegInfo));
    244:     PetscFree(classLog->classInfo);
    245:     classLog->classInfo   = classInfo;
    246:     classLog->maxClasses *= 2;
    247:   }
    248:   PetscStrallocpy(cname, &str);
    249:   classLog->classInfo[c].name     = str;
    250:   if (*cookie == PETSC_DECIDE) {
    251:     classLog->classInfo[c].cookie = ++PETSC_LARGEST_COOKIE;
    252:   } else if (*cookie >= 0) {
    253:     classLog->classInfo[c].cookie = *cookie;
    254:     /* Need to check here for montonicity and insert if necessary */
    255:   } else {
    256:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Invalid suggested cookie %d", (int)*cookie);
    257:   }
    258:   *cookie = classLog->classInfo[c].cookie;
    259:   return(0);
    260: }

    262: /*------------------------------------------------ Query Functions --------------------------------------------------*/
    265: /*@C
    266:   ClassRegLogGetClass - This function returns the class corresponding to a given cookie.

    268:   Not Collective

    270:   Input Parameters:
    271: + classLog - The ClassRegLog
    272: - cookie   - The cookie
    273:
    274:   Output Parameter:
    275: . oclass   - The class id

    277:   Level: developer

    279: .keywords: log, class, register
    280: .seealso: PetscLogClassRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
    281: @*/
    282: PetscErrorCode ClassRegLogGetClass(ClassRegLog classLog, PetscCookie cookie, int *oclass)
    283: {
    284:   int c;

    288:   for(c = 0; c < classLog->numClasses; c++) {
    289:     /* Could do bisection here */
    290:     if (classLog->classInfo[c].cookie == cookie) break;
    291:   }
    292:   if (c >= classLog->numClasses) {
    293:     SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid object cookie %d\nThis often happens if you compile with PETSC_USE_DYNAMIC_LIBRARIES, but link with static libraries.", cookie);
    294:   }
    295:   *oclass = c;
    296:   return(0);
    297: }

    299: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
    300: /* Default object create logger */
    303: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
    304: {
    305:   StageLog       stageLog;
    306:   ClassRegLog    classRegLog;
    307:   ClassPerfLog   classPerfLog;
    308:   Action        *tmpAction;
    309:   Object        *tmpObjects;
    310:   PetscLogDouble start, end;
    311:   int            oclass;
    312:   int            stage;

    316:   /* Record stage info */
    317:   PetscLogGetStageLog(&stageLog);
    318:   StageLogGetCurrent(stageLog, &stage);
    319:   StageLogGetClassRegLog(stageLog, &classRegLog);
    320:   StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
    321:   ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
    322:   classPerfLog->classInfo[oclass].creations++;
    323:   /* Dynamically enlarge logging structures */
    324:   if (numActions >= maxActions) {
    325:     PetscTime(start);
    326:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
    327:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
    328:     PetscFree(actions);
    329:     actions     = tmpAction;
    330:     maxActions *= 2;
    331:     PetscTime(end);
    332:     BaseTime += (end - start);
    333:   }

    335:   numObjects = obj->id;
    336:   /* Record the creation action */
    337:   if (logActions) {
    338:     PetscTime(actions[numActions].time);
    339:     actions[numActions].time  -= BaseTime;
    340:     actions[numActions].action = CREATE;
    341:     actions[numActions].cookie = obj->cookie;
    342:     actions[numActions].id1    = numObjects;
    343:     actions[numActions].id2    = -1;
    344:     actions[numActions].id3    = -1;
    345:     actions[numActions].flops  = _TotalFlops;
    346:     PetscMallocGetCurrentUsage(&actions[numActions].mem);
    347:     PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
    348:     numActions++;
    349:   }
    350:   /* Record the object */
    351:   if (logObjects) {
    352:     objects[numObjects].parent = -1;
    353:     objects[numObjects].obj    = obj;
    354:     PetscMemzero(objects[numObjects].name, 64 * sizeof(char));
    355:     PetscMemzero(objects[numObjects].info, 64 * sizeof(char));

    357:   /* Dynamically enlarge logging structures */
    358:     if (numObjects >= maxObjects) {
    359:       PetscTime(start);
    360:       PetscMalloc(maxObjects*2 * sizeof(Object), &tmpObjects);
    361:       PetscMemcpy(tmpObjects, objects, maxObjects * sizeof(Object));
    362:       PetscFree(objects);
    363:       objects     = tmpObjects;
    364:       maxObjects *= 2;
    365:       PetscTime(end);
    366:       BaseTime += (end - start);
    367:     }
    368:   }
    369:   return(0);
    370: }

    372: /* Default object destroy logger */
    375: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
    376: {
    377:   StageLog       stageLog;
    378:   ClassRegLog    classRegLog;
    379:   ClassPerfLog   classPerfLog;
    380:   Action        *tmpAction;
    381:   PetscLogDouble start, end;
    382:   int            oclass;
    383:   int            stage;

    387:   /* Record stage info */
    388:   PetscLogGetStageLog(&stageLog);
    389:   StageLogGetCurrent(stageLog, &stage);
    390:   StageLogGetClassRegLog(stageLog, &classRegLog);
    391:   StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
    392:   ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
    393:   classPerfLog->classInfo[oclass].destructions++;
    394:   classPerfLog->classInfo[oclass].mem += obj->mem;
    395:   /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
    396:   numObjectsDestroyed++;
    397:   /* Dynamically enlarge logging structures */
    398:   if (numActions >= maxActions) {
    399:     PetscTime(start);
    400:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
    401:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
    402:     PetscFree(actions);
    403:     actions     = tmpAction;
    404:     maxActions *= 2;
    405:     PetscTime(end);
    406:     BaseTime += (end - start);
    407:   }
    408:   /* Record the destruction action */
    409:   if (logActions) {
    410:     PetscTime(actions[numActions].time);
    411:     actions[numActions].time  -= BaseTime;
    412:     actions[numActions].action = DESTROY;
    413:     actions[numActions].cookie = obj->cookie;
    414:     actions[numActions].id1    = obj->id;
    415:     actions[numActions].id2    = -1;
    416:     actions[numActions].id3    = -1;
    417:     actions[numActions].flops  = _TotalFlops;
    418:     PetscMallocGetCurrentUsage(&actions[numActions].mem);
    419:     PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
    420:     numActions++;
    421:   }
    422:   if (logObjects) {
    423:     if (obj->name) {
    424:       PetscStrncpy(objects[obj->id].name, obj->name, 64);
    425:     }
    426:     objects[obj->id].obj      = PETSC_NULL;
    427:     objects[obj->id].mem      = obj->mem;
    428:   }
    429:   return(0);
    430: }