Actual source code: classlog.c
petsc-3.7.1 2016-05-15
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> /*I    "petscsys.h"   I*/

     12: /*@C
     13:   PetscClassRegLogCreate - This creates a PetscClassRegLog object.

     15:   Not collective

     17:   Input Parameter:
     18: . classLog - The PetscClassRegLog

     20:   Level: developer

     22: .keywords: log, class, create
     23: .seealso: PetscClassRegLogDestroy(), PetscStageLogCreate()
     24: @*/
     25: PetscErrorCode PetscClassRegLogCreate(PetscClassRegLog *classLog)
     26: {
     27:   PetscClassRegLog l;
     28:   PetscErrorCode   ierr;

     31:   PetscNew(&l);

     33:   l->numClasses = 0;
     34:   l->maxClasses = 100;

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

     38:   *classLog = l;
     39:   return(0);
     40: }

     44: /*@C
     45:   PetscClassRegLogDestroy - This destroys a PetscClassRegLog object.

     47:   Not collective

     49:   Input Paramter:
     50: . classLog - The PetscClassRegLog

     52:   Level: developer

     54: .keywords: log, event, destroy
     55: .seealso: PetscClassRegLogCreate()
     56: @*/
     57: PetscErrorCode PetscClassRegLogDestroy(PetscClassRegLog classLog)
     58: {
     59:   int            c;

     63:   for (c = 0; c < classLog->numClasses; c++) {
     64:     PetscClassRegInfoDestroy(&classLog->classInfo[c]);
     65:   }
     66:   PetscFree(classLog->classInfo);
     67:   PetscFree(classLog);
     68:   return(0);
     69: }

     73: /*@C
     74:   PetscClassRegInfoDestroy - This destroys a PetscClassRegInfo object.

     76:   Not collective

     78:   Input Parameter:
     79: . c - The PetscClassRegInfo

     81:   Level: developer

     83: .keywords: log, class, destroy
     84: .seealso: PetscStageLogDestroy(), EventLogDestroy()
     85: @*/
     86: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
     87: {

     91:   PetscFree(c->name);
     92:   return(0);
     93: }

     97: /*@C
     98:   ClassPerfLogCreate - This creates a PetscClassPerfLog object.

    100:   Not collective

    102:   Input Parameter:
    103: . classLog - The PetscClassPerfLog

    105:   Level: developer

    107: .keywords: log, class, create
    108: .seealso: ClassPerfLogDestroy(), PetscStageLogCreate()
    109: @*/
    110: PetscErrorCode ClassPerfLogCreate(PetscClassPerfLog *classLog)
    111: {
    112:   PetscClassPerfLog l;
    113:   PetscErrorCode    ierr;

    116:   PetscNew(&l);

    118:   l->numClasses = 0;
    119:   l->maxClasses = 100;

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

    123:   *classLog = l;
    124:   return(0);
    125: }

    129: /*@C
    130:   ClassPerfLogDestroy - This destroys a PetscClassPerfLog object.

    132:   Not collective

    134:   Input Paramter:
    135: . classLog - The PetscClassPerfLog

    137:   Level: developer

    139: .keywords: log, event, destroy
    140: .seealso: ClassPerfLogCreate()
    141: @*/
    142: PetscErrorCode ClassPerfLogDestroy(PetscClassPerfLog classLog)
    143: {

    147:   PetscFree(classLog->classInfo);
    148:   PetscFree(classLog);
    149:   return(0);
    150: }

    152: /*------------------------------------------------ General Functions -------------------------------------------------*/
    155: /*@C
    156:   ClassPerfInfoClear - This clears a PetscClassPerfInfo object.

    158:   Not collective

    160:   Input Paramter:
    161: . classInfo - The PetscClassPerfInfo

    163:   Level: developer

    165: .keywords: log, class, destroy
    166: .seealso: ClassPerfLogCreate()
    167: @*/
    168: PetscErrorCode ClassPerfInfoClear(PetscClassPerfInfo *classInfo)
    169: {
    171:   classInfo->id           = -1;
    172:   classInfo->creations    = 0;
    173:   classInfo->destructions = 0;
    174:   classInfo->mem          = 0.0;
    175:   classInfo->descMem      = 0.0;
    176:   return(0);
    177: }

    181: /*@C
    182:   ClassPerfLogEnsureSize - This ensures that a PetscClassPerfLog is at least of a certain size.

    184:   Not collective

    186:   Input Paramters:
    187: + classLog - The PetscClassPerfLog
    188: - size     - The size

    190:   Level: developer

    192: .keywords: log, class, size, ensure
    193: .seealso: ClassPerfLogCreate()
    194: @*/
    195: PetscErrorCode ClassPerfLogEnsureSize(PetscClassPerfLog classLog, int size)
    196: {
    197:   PetscClassPerfInfo *classInfo;
    198:   PetscErrorCode     ierr;

    201:   while (size > classLog->maxClasses) {
    202:     PetscMalloc1(classLog->maxClasses*2, &classInfo);
    203:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(PetscClassPerfInfo));
    204:     PetscFree(classLog->classInfo);

    206:     classLog->classInfo   = classInfo;
    207:     classLog->maxClasses *= 2;
    208:   }
    209:   while (classLog->numClasses < size) {
    210:     ClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
    211:   }
    212:   return(0);
    213: }

    215: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
    218: /*@C
    219:   PetscClassRegLogRegister - Registers a class for logging operations in an application code.

    221:   Not Collective

    223:   Input Parameters:
    224: + classLog - The ClassLog
    225: - cname    - The name associated with the class

    227:   Output Parameter:
    228: .  classid   - The classid

    230:   Level: developer

    232: .keywords: log, class, register
    233: .seealso: PetscClassIdRegister()
    234: @*/
    235: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
    236: {
    237:   PetscClassRegInfo *classInfo;
    238:   char              *str;
    239:   int               c;
    240:   PetscErrorCode    ierr;

    244:   c = classLog->numClasses++;
    245:   if (classLog->numClasses > classLog->maxClasses) {
    246:     PetscMalloc1(classLog->maxClasses*2, &classInfo);
    247:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(PetscClassRegInfo));
    248:     PetscFree(classLog->classInfo);

    250:     classLog->classInfo   = classInfo;
    251:     classLog->maxClasses *= 2;
    252:   }
    253:   PetscStrallocpy(cname, &str);

    255:   classLog->classInfo[c].name    = str;
    256:   classLog->classInfo[c].classid = classid;
    257:   return(0);
    258: }

    260: /*------------------------------------------------ Query Functions --------------------------------------------------*/
    263: /*@C
    264:   PetscClassRegLogGetClass - This function returns the class corresponding to a given classid.

    266:   Not Collective

    268:   Input Parameters:
    269: + classLog - The PetscClassRegLog
    270: - cookie   - The cookie

    272:   Output Parameter:
    273: . oclass   - The class id

    275:   Level: developer

    277: .keywords: log, class, register
    278: .seealso: PetscClassIdRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
    279: @*/
    280: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
    281: {
    282:   int c;

    286:   for (c = 0; c < classLog->numClasses; c++) {
    287:     /* Could do bisection here */
    288:     if (classLog->classInfo[c].classid == classid) break;
    289:   }
    290:   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);
    291:   *oclass = c;
    292:   return(0);
    293: }

    295: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
    296: /* Default object create logger */
    299: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
    300: {
    301:   PetscStageLog     stageLog;
    302:   PetscClassRegLog  classRegLog;
    303:   PetscClassPerfLog classPerfLog;
    304:   Action            *tmpAction;
    305:   Object            *tmpObjects;
    306:   PetscLogDouble    start, end;
    307:   int               oclass = 0;
    308:   int               stage;
    309:   PetscErrorCode    ierr;

    312:   /* Record stage info */
    313:   PetscLogGetStageLog(&stageLog);
    314:   PetscStageLogGetCurrent(stageLog, &stage);
    315:   PetscStageLogGetClassRegLog(stageLog, &classRegLog);
    316:   PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
    317:   PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
    318:   classPerfLog->classInfo[oclass].creations++;
    319:   /* Dynamically enlarge logging structures */
    320:   if (petsc_numActions >= petsc_maxActions) {
    321:     PetscTime(&start);
    322:     PetscMalloc1(petsc_maxActions*2, &tmpAction);
    323:     PetscMemcpy(tmpAction, petsc_actions, petsc_maxActions * sizeof(Action));
    324:     PetscFree(petsc_actions);

    326:     petsc_actions     = tmpAction;
    327:     petsc_maxActions *= 2;
    328:     PetscTime(&end);
    329:     petsc_BaseTime += (end - start);
    330:   }

    332:   petsc_numObjects = obj->id;
    333:   /* Record the creation action */
    334:   if (petsc_logActions) {
    335:     PetscTime(&petsc_actions[petsc_numActions].time);
    336:     petsc_actions[petsc_numActions].time   -= petsc_BaseTime;
    337:     petsc_actions[petsc_numActions].action  = CREATE;
    338:     petsc_actions[petsc_numActions].classid = obj->classid;
    339:     petsc_actions[petsc_numActions].id1     = petsc_numObjects;
    340:     petsc_actions[petsc_numActions].id2     = -1;
    341:     petsc_actions[petsc_numActions].id3     = -1;
    342:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

    344:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
    345:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
    346:     petsc_numActions++;
    347:   }
    348:   /* Record the object */
    349:   if (petsc_logObjects) {
    350:     petsc_objects[petsc_numObjects].parent = -1;
    351:     petsc_objects[petsc_numObjects].obj    = obj;

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

    356:     /* Dynamically enlarge logging structures */
    357:     if (petsc_numObjects >= petsc_maxObjects) {
    358:       PetscTime(&start);
    359:       PetscMalloc1(petsc_maxObjects*2, &tmpObjects);
    360:       PetscMemcpy(tmpObjects, petsc_objects, petsc_maxObjects * sizeof(Object));
    361:       PetscFree(petsc_objects);

    363:       petsc_objects     = tmpObjects;
    364:       petsc_maxObjects *= 2;
    365:       PetscTime(&end);
    366:       petsc_BaseTime += (end - start);
    367:     }
    368:   }
    369:   return(0);
    370: }

    372: /* Default object destroy logger */
    375: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
    376: {
    377:   PetscStageLog     stageLog;
    378:   PetscClassRegLog  classRegLog;
    379:   PetscClassPerfLog classPerfLog;
    380:   Action            *tmpAction;
    381:   PetscLogDouble    start, end;
    382:   int               oclass = 0;
    383:   int               stage;
    384:   PetscErrorCode    ierr;

    387:   /* Record stage info */
    388:   PetscLogGetStageLog(&stageLog);
    389:   PetscStageLogGetCurrent(stageLog, &stage);
    390:   if (stage != -1) {
    391:     /* That can happen if the log summary is output before some things are destroyed */
    392:     PetscStageLogGetClassRegLog(stageLog, &classRegLog);
    393:     PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
    394:     PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
    395:     classPerfLog->classInfo[oclass].destructions++;
    396:     classPerfLog->classInfo[oclass].mem += obj->mem;
    397:   }
    398:   /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
    399:   petsc_numObjectsDestroyed++;
    400:   /* Dynamically enlarge logging structures */
    401:   if (petsc_numActions >= petsc_maxActions) {
    402:     PetscTime(&start);
    403:     PetscMalloc1(petsc_maxActions*2, &tmpAction);
    404:     PetscMemcpy(tmpAction, petsc_actions, petsc_maxActions * sizeof(Action));
    405:     PetscFree(petsc_actions);

    407:     petsc_actions     = tmpAction;
    408:     petsc_maxActions *= 2;
    409:     PetscTime(&end);
    410:     petsc_BaseTime += (end - start);
    411:   }
    412:   /* Record the destruction action */
    413:   if (petsc_logActions) {
    414:     PetscTime(&petsc_actions[petsc_numActions].time);
    415:     petsc_actions[petsc_numActions].time   -= petsc_BaseTime;
    416:     petsc_actions[petsc_numActions].action  = DESTROY;
    417:     petsc_actions[petsc_numActions].classid = obj->classid;
    418:     petsc_actions[petsc_numActions].id1     = obj->id;
    419:     petsc_actions[petsc_numActions].id2     = -1;
    420:     petsc_actions[petsc_numActions].id3     = -1;
    421:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

    423:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
    424:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
    425:     petsc_numActions++;
    426:   }
    427:   if (petsc_logObjects) {
    428:     if (obj->name) {
    429:       PetscStrncpy(petsc_objects[obj->id].name, obj->name, 64);
    430:     }
    431:     petsc_objects[obj->id].obj = NULL;
    432:     petsc_objects[obj->id].mem = obj->mem;
    433:   }
    434:   return(0);
    435: }