Date: 2021-03-03T22:25:41+00:00

Actual source code: mtr.c
petsc-3.14.5 2021-03-03
Report Typos and Errors

      2: /*
      3:      Interface to malloc() and free(). This code allows for logging of memory usage and some error checking
      4: */
      5: #include <petscsys.h>
      6: #include <petscviewer.h>
      7: #if defined(PETSC_HAVE_MALLOC_H)
      8: #include <malloc.h>
      9: #endif

     11: /*
     12:      These are defined in mal.c and ensure that malloced space is PetscScalar aligned
     13: */
     14: PETSC_EXTERN PetscErrorCode PetscMallocAlign(size_t,PetscBool,int,const char[],const char[],void**);
     15: PETSC_EXTERN PetscErrorCode PetscFreeAlign(void*,int,const char[],const char[]);
     16: PETSC_EXTERN PetscErrorCode PetscReallocAlign(size_t,int,const char[],const char[],void**);

     18: #define CLASSID_VALUE  ((PetscClassId) 0xf0e0d0c9)
     19: #define ALREADY_FREED  ((PetscClassId) 0x0f0e0d9c)

     21: /*  this is the header put at the beginning of each malloc() using for tracking allocated space and checking of allocated space heap */
     22: typedef struct _trSPACE {
     23:   size_t          size, rsize; /* Aligned size and requested size */
     24:   int             id;
     25:   int             lineno;
     26:   const char      *filename;
     27:   const char      *functionname;
     28:   PetscClassId    classid;
     29: #if defined(PETSC_USE_DEBUG)
     30:   PetscStack      stack;
     31: #endif
     32:   struct _trSPACE *next,*prev;
     33: } TRSPACE;

     35: /* HEADER_BYTES is the number of bytes in a PetscMalloc() header.
     36:    It is sizeof(trSPACE) padded to be a multiple of PETSC_MEMALIGN.
     37: */
     38: #define HEADER_BYTES  ((sizeof(TRSPACE)+(PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1))

     40: /* This union is used to insure that the block passed to the user retains
     41:    a minimum alignment of PETSC_MEMALIGN.
     42: */
     43: typedef union {
     44:   TRSPACE sp;
     45:   char    v[HEADER_BYTES];
     46: } TrSPACE;

     48: #define MAXTRMAXMEMS 50
     49: static size_t    TRallocated          = 0;
     50: static int       TRfrags              = 0;
     51: static TRSPACE   *TRhead              = NULL;
     52: static int       TRid                 = 0;
     53: static PetscBool TRdebugLevel         = PETSC_FALSE;
     54: static PetscBool TRdebugIinitializenan= PETSC_FALSE;
     55: static PetscBool TRrequestedSize      = PETSC_FALSE;
     56: static size_t    TRMaxMem             = 0;
     57: static int       NumTRMaxMems         = 0;
     58: static size_t    TRMaxMems[MAXTRMAXMEMS];
     59: static int       TRMaxMemsEvents[MAXTRMAXMEMS];
     60: /*
     61:       Arrays to log information on mallocs for PetscMallocView()
     62: */
     63: static int        PetscLogMallocMax       = 10000;
     64: static int        PetscLogMalloc          = -1;
     65: static size_t     PetscLogMallocThreshold = 0;
     66: static size_t     *PetscLogMallocLength;
     67: static const char **PetscLogMallocFile,**PetscLogMallocFunction;
     68: static int        PetscLogMallocTrace          = -1;
     69: static size_t     PetscLogMallocTraceThreshold = 0;
     70: static PetscViewer PetscLogMallocTraceViewer   = NULL;

     72: /*@C
     73:    PetscMallocValidate - Test the memory for corruption.  This can be called at any time between PetscInitialize() and PetscFinalize()

     75:    Input Parameters:
     76: +  line - line number where call originated.
     77: .  function - name of function calling
     78: -  file - file where function is

     80:    Return value:
     81:    The number of errors detected.

     83:    Options Database:.
     84: +  -malloc_test - turns this feature on when PETSc was not configured with --with-debugging=0
     85: -  -malloc_debug - turns this feature on anytime

     87:    Output Effect:
     88:    Error messages are written to stdout.

     90:    Level: advanced

     92:    Notes:
     93:     This is only run if PetscMallocSetDebug() has been called which is set by -malloc_test (if debugging is turned on) or -malloc_debug (any time)

     95:     You should generally use CHKMEMQ as a short cut for calling this  routine.

     97:     The Fortran calling sequence is simply PetscMallocValidate(ierr)

     99:    No output is generated if there are no problems detected.

    101:    Developers Note:
    102:      Uses the flg TRdebugLevel (set as the first argument to PetscMallocSetDebug()) to determine if it should run

    104: .seealso: CHKMEMQ

    106: @*/
    107: PetscErrorCode  PetscMallocValidate(int line,const char function[],const char file[])
    108: {
    109:   TRSPACE      *head,*lasthead;
    110:   char         *a;
    111:   PetscClassId *nend;

    113:   if (!TRdebugLevel) return 0;
    114:   head = TRhead; lasthead = NULL;
    115:   if (head && head->prev) {
    116:     (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file);
    117:     (*PetscErrorPrintf)("Root memory header %p has invalid back pointer %p\n",head,head->prev);
    118:     return PETSC_ERR_MEMC;
    119:   }
    120:   while (head) {
    121:     if (head->classid != CLASSID_VALUE) {
    122:       (*PetscErrorPrintf)("PetscMallocValidate: error detected at  %s() line %d in %s\n",function,line,file);
    123:       (*PetscErrorPrintf)("Memory at address %p is corrupted\n",head);
    124:       (*PetscErrorPrintf)("Probably write before beginning of or past end of array\n");
    125:       if (lasthead) (*PetscErrorPrintf)("Last intact block allocated in %s() line %d in %s\n",lasthead->functionname,lasthead->lineno,lasthead->filename);
    126:       return PETSC_ERR_MEMC;
    127:     }
    128:     a    = (char*)(((TrSPACE*)head) + 1);
    129:     nend = (PetscClassId*)(a + head->size);
    130:     if (*nend != CLASSID_VALUE) {
    131:       (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file);
    132:       if (*nend == ALREADY_FREED) {
    133:         (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p already freed\n",head->id,(PetscLogDouble)head->size,a);
    134:         return PETSC_ERR_MEMC;
    135:       } else {
    136:         (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a);
    137:         (*PetscErrorPrintf)("Memory originally allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename);
    138:         return PETSC_ERR_MEMC;
    139:       }
    140:     }
    141:     if (head->prev && head->prev != lasthead) {
    142:       (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file);
    143:       (*PetscErrorPrintf)("Backpointer %p is invalid, should be %p\n",head->prev,lasthead);
    144:       return PETSC_ERR_MEMC;
    145:     }
    146:     if (head->next && head != head->next->prev) {
    147:       (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file);
    148:       (*PetscErrorPrintf)("Next memory header %p has invalid back pointer %p, should be %p\n",head->next,head->next->prev,head);
    149:       return PETSC_ERR_MEMC;
    150:     }
    151:     lasthead = head;
    152:     head     = head->next;
    153:   }
    154:   return 0;
    155: }

    157: /*
    158:     PetscTrMallocDefault - Malloc with tracing.

    160:     Input Parameters:
    161: +   a   - number of bytes to allocate
    162: .   lineno - line number where used.  Use __LINE__ for this
    163: -   filename  - file name where used.  Use __FILE__ for this

    165:     Returns:
    166:     double aligned pointer to requested storage, or null if not  available.
    167:  */
    168: PetscErrorCode  PetscTrMallocDefault(size_t a,PetscBool clear,int lineno,const char function[],const char filename[],void **result)
    169: {
    170:   TRSPACE        *head;
    171:   char           *inew;
    172:   size_t         nsize;

    176:   /* Do not try to handle empty blocks */
    177:   if (!a) { *result = NULL; return(0); }

    179:   PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr);

    181:   nsize = (a + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1);
    182:   PetscMallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),clear,lineno,function,filename,(void**)&inew);

    184:   head  = (TRSPACE*)inew;
    185:   inew += sizeof(TrSPACE);

    187:   if (TRhead) TRhead->prev = head;
    188:   head->next   = TRhead;
    189:   TRhead       = head;
    190:   head->prev   = NULL;
    191:   head->size   = nsize;
    192:   head->rsize  = a;
    193:   head->id     = TRid;
    194:   head->lineno = lineno;

    196:   head->filename                 = filename;
    197:   head->functionname             = function;
    198:   head->classid                  = CLASSID_VALUE;
    199:   *(PetscClassId*)(inew + nsize) = CLASSID_VALUE;

    201:   TRallocated += TRrequestedSize ? head->rsize : head->size;
    202:   if (TRallocated > TRMaxMem) TRMaxMem = TRallocated;
    203:   if (PetscLogMemory) {
    204:     PetscInt i;
    205:     for (i=0; i<NumTRMaxMems; i++) {
    206:       if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated;
    207:     }
    208:   }
    209:   TRfrags++;

    211: #if defined(PETSC_USE_DEBUG)
    212:   if (PetscStackActive()) {
    213:     PetscStackCopy(petscstack,&head->stack);
    215:     head->stack.line[head->stack.currentsize-2] = lineno;
    216:   } else {
    217:     head->stack.currentsize = 0;
    218:   }
    219: #if defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL_DOUBLE)
    220:   if (!clear && TRdebugIinitializenan) {
    221:     size_t     i, n = a/sizeof(PetscReal);
    222:     PetscReal *s = (PetscReal*) inew;
    223:     /* from https://www.doc.ic.ac.uk/~eedwards/compsys/float/nan.html */
    224: #if defined(PETSC_USE_REAL_SINGLE)
    225:     int        nas = 0x7F800002;
    226: #else
    227:     PetscInt64 nas = 0x7FF0000000000002;
    228: #endif
    229:     for (i=0; i<n; i++) {
    230:       memcpy(s+i,&nas,sizeof(PetscReal));
    231:     }
    232:   }
    233: #endif
    234: #endif

    236:   /*
    237:          Allow logging of all mallocs made.
    238:          TODO: Currently this memory is never freed, it should be freed during PetscFinalize()
    239:   */
    240:   if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && a >= PetscLogMallocThreshold) {
    241:     if (!PetscLogMalloc) {
    242:       PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t));
    243:       if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," ");

    245:       PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*));
    246:       if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," ");

    248:       PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*));
    249:       if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," ");
    250:     }
    251:     PetscLogMallocLength[PetscLogMalloc]     = nsize;
    252:     PetscLogMallocFile[PetscLogMalloc]       = filename;
    253:     PetscLogMallocFunction[PetscLogMalloc++] = function;
    254:   }
    255:   if (PetscLogMallocTrace > -1 && a >= PetscLogMallocTraceThreshold) {
    256:     PetscViewerASCIIPrintf(PetscLogMallocTraceViewer,"Alloc %zu %s:%d (%s)\n", a, filename ? filename : "null", lineno, function ? function : "null");
    257:   }
    258:   *result = (void*)inew;
    259:   return(0);
    260: }

    262: /*
    263:    PetscTrFreeDefault - Free with tracing.

    265:    Input Parameters:
    266: .   a    - pointer to a block allocated with PetscTrMalloc
    267: .   lineno - line number where used.  Use __LINE__ for this
    268: .   filename  - file name where used.  Use __FILE__ for this
    269:  */
    270: PetscErrorCode  PetscTrFreeDefault(void *aa,int lineno,const char function[],const char filename[])
    271: {
    272:   char           *a = (char*)aa;
    273:   TRSPACE        *head;
    274:   char           *ahead;
    275:   size_t         asize;
    277:   PetscClassId   *nend;

    280:   /* Do not try to handle empty blocks */
    281:   if (!a) return(0);

    283:   PetscMallocValidate(lineno,function,filename);

    285:   ahead = a;
    286:   a     = a - sizeof(TrSPACE);
    287:   head  = (TRSPACE*)a;

    289:   if (head->classid != CLASSID_VALUE) {
    290:     (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,lineno,filename);
    291:     (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a);
    292:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory");
    293:   }
    294:   nend = (PetscClassId*)(ahead + head->size);
    295:   if (*nend != CLASSID_VALUE) {
    296:     if (*nend == ALREADY_FREED) {
    297:       (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,lineno,filename);
    298:       (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE));
    299:       if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) {
    300:         (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename);
    301:       } else {
    302:         (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename);
    303:       }
    304:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed");
    305:     } else {
    306:       /* Damaged tail */
    307:       (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,lineno,filename);
    308:       (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a);
    309:       (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename);
    310:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory");
    311:     }
    312:   }
    313:   if (PetscLogMallocTrace > -1 && head->rsize >= PetscLogMallocTraceThreshold) {
    314:     PetscViewerASCIIPrintf(PetscLogMallocTraceViewer, "Free  %zu %s:%d (%s)\n", head->rsize, filename ? filename : "null", lineno, function ? function : "null");
    315:   }
    316:   /* Mark the location freed */
    317:   *nend = ALREADY_FREED;
    318:   /* Save location where freed.  If we suspect the line number, mark as  allocated location */
    319:   if (lineno > 0 && lineno < 50000) {
    320:     head->lineno       = lineno;
    321:     head->filename     = filename;
    322:     head->functionname = function;
    323:   } else {
    324:     head->lineno = -head->lineno;
    325:   }
    326:   asize = TRrequestedSize ? head->rsize : head->size;
    327:   if (TRallocated < asize) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"TRallocate is smaller than memory just freed");
    328:   TRallocated -= asize;
    329:   TRfrags--;
    330:   if (head->prev) head->prev->next = head->next;
    331:   else TRhead = head->next;

    333:   if (head->next) head->next->prev = head->prev;
    334:   PetscFreeAlign(a,lineno,function,filename);
    335:   return(0);
    336: }

    338: /*
    339:   PetscTrReallocDefault - Realloc with tracing.

    341:   Input Parameters:
    342: + len      - number of bytes to allocate
    343: . lineno   - line number where used.  Use __LINE__ for this
    344: . filename - file name where used.  Use __FILE__ for this
    345: - result - original memory

    347:   Output Parameter:
    348: . result - double aligned pointer to requested storage, or null if not available.

    350:   Level: developer

    352: .seealso: PetscTrMallocDefault(), PetscTrFreeDefault()
    353: */
    354: PetscErrorCode PetscTrReallocDefault(size_t len, int lineno, const char function[], const char filename[], void **result)
    355: {
    356:   char           *a = (char *) *result;
    357:   TRSPACE        *head;
    358:   char           *ahead, *inew;
    359:   PetscClassId   *nend;
    360:   size_t         nsize;

    364:   /* Realloc requests zero space so just free the current space */
    365:   if (!len) {
    366:     PetscTrFreeDefault(*result,lineno,function,filename);
    367:     *result = NULL;
    368:     return(0);
    369:   }
    370:   /* If the orginal space was NULL just use the regular malloc() */
    371:   if (!*result) {
    372:     PetscTrMallocDefault(len,PETSC_FALSE,lineno,function,filename,result);
    373:     return(0);
    374:   }

    376:   PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr);

    378:   ahead = a;
    379:   a     = a - sizeof(TrSPACE);
    380:   head  = (TRSPACE *) a;
    381:   inew  = a;

    383:   if (head->classid != CLASSID_VALUE) {
    384:     (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename);
    385:     (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a);
    386:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory");
    387:   }
    388:   nend = (PetscClassId *)(ahead + head->size);
    389:   if (*nend != CLASSID_VALUE) {
    390:     if (*nend == ALREADY_FREED) {
    391:       (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename);
    392:       (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE));
    393:       if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) {
    394:         (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename);
    395:       } else {
    396:         (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename);
    397:       }
    398:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed");
    399:     } else {
    400:       /* Damaged tail */
    401:       (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename);
    402:       (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a);
    403:       (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename);
    404:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory");
    405:     }
    406:   }

    408:   /* remove original reference to the memory allocated from the PETSc debugging heap */
    409:   TRallocated -= TRrequestedSize ? head->rsize : head->size;
    410:   TRfrags--;
    411:   if (head->prev) head->prev->next = head->next;
    412:   else TRhead = head->next;
    413:   if (head->next) head->next->prev = head->prev;

    415:   nsize = (len + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1);
    416:   PetscReallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),lineno,function,filename,(void**)&inew);

    418:   head  = (TRSPACE*)inew;
    419:   inew += sizeof(TrSPACE);

    421:   if (TRhead) TRhead->prev = head;
    422:   head->next   = TRhead;
    423:   TRhead       = head;
    424:   head->prev   = NULL;
    425:   head->size   = nsize;
    426:   head->rsize  = len;
    427:   head->id     = TRid;
    428:   head->lineno = lineno;

    430:   head->filename                 = filename;
    431:   head->functionname             = function;
    432:   head->classid                  = CLASSID_VALUE;
    433:   *(PetscClassId*)(inew + nsize) = CLASSID_VALUE;

    435:   TRallocated += TRrequestedSize ? head->rsize : head->size;
    436:   if (TRallocated > TRMaxMem) TRMaxMem = TRallocated;
    437:   if (PetscLogMemory) {
    438:     PetscInt i;
    439:     for (i=0; i<NumTRMaxMems; i++) {
    440:       if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated;
    441:     }
    442:   }
    443:   TRfrags++;

    445: #if defined(PETSC_USE_DEBUG)
    446:   if (PetscStackActive()) {
    447:     PetscStackCopy(petscstack,&head->stack);
    449:     head->stack.line[head->stack.currentsize-2] = lineno;
    450:   } else {
    451:     head->stack.currentsize = 0;
    452:   }
    453: #endif

    455:   /*
    456:          Allow logging of all mallocs made. This adds a new entry to the list of allocated memory
    457:          and does not remove the previous entry to the list hence this memory is "double counted" in PetscMallocView()
    458:   */
    459:   if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && len >= PetscLogMallocThreshold) {
    460:     if (!PetscLogMalloc) {
    461:       PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t));
    462:       if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," ");

    464:       PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*));
    465:       if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," ");

    467:       PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*));
    468:       if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," ");
    469:     }
    470:     PetscLogMallocLength[PetscLogMalloc]     = nsize;
    471:     PetscLogMallocFile[PetscLogMalloc]       = filename;
    472:     PetscLogMallocFunction[PetscLogMalloc++] = function;
    473:   }
    474:   *result = (void*)inew;
    475:   return(0);
    476: }

    478: /*@C
    479:     PetscMemoryView - Shows the amount of memory currently being used in a communicator.

    481:     Collective on PetscViewer

    483:     Input Parameter:
    484: +    viewer - the viewer that defines the communicator
    485: -    message - string printed before values

    487:     Options Database:
    488: +    -malloc_debug - have PETSc track how much memory it has allocated
    489: -    -memory_view - during PetscFinalize() have this routine called

    491:     Level: intermediate

    493: .seealso: PetscMallocDump(), PetscMemoryGetCurrentUsage(), PetscMemorySetGetMaximumUsage(), PetscMallocView()
    494:  @*/
    495: PetscErrorCode  PetscMemoryView(PetscViewer viewer,const char message[])
    496: {
    497:   PetscLogDouble allocated,allocatedmax,resident,residentmax,gallocated,gallocatedmax,gresident,gresidentmax,maxgallocated,maxgallocatedmax,maxgresident,maxgresidentmax;
    498:   PetscLogDouble mingallocated,mingallocatedmax,mingresident,mingresidentmax;
    500:   MPI_Comm       comm;

    503:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
    504:   PetscMallocGetCurrentUsage(&allocated);
    505:   PetscMallocGetMaximumUsage(&allocatedmax);
    506:   PetscMemoryGetCurrentUsage(&resident);
    507:   PetscMemoryGetMaximumUsage(&residentmax);
    508:   if (residentmax > 0) residentmax = PetscMax(resident,residentmax);
    509:   PetscObjectGetComm((PetscObject)viewer,&comm);
    510:   PetscViewerASCIIPrintf(viewer,message);
    511:   if (resident && residentmax && allocated) {
    512:     MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);
    513:     MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);
    514:     MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);
    515:     PetscViewerASCIIPrintf(viewer,"Maximum (over computational time) process memory:        total %5.4e max %5.4e min %5.4e\n",gresidentmax,maxgresidentmax,mingresidentmax);
    516:     MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);
    517:     MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);
    518:     MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);
    519:     PetscViewerASCIIPrintf(viewer,"Current process memory:                                  total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);
    520:     MPI_Reduce(&allocatedmax,&gallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);
    521:     MPI_Reduce(&allocatedmax,&maxgallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);
    522:     MPI_Reduce(&allocatedmax,&mingallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);
    523:     PetscViewerASCIIPrintf(viewer,"Maximum (over computational time) space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocatedmax,maxgallocatedmax,mingallocatedmax);
    524:     MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);
    525:     MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);
    526:     MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);
    527:     PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed:                           total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);
    528:   } else if (resident && residentmax) {
    529:     MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);
    530:     MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);
    531:     MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);
    532:     PetscViewerASCIIPrintf(viewer,"Maximum (over computational time) process memory:        total %5.4e max %5.4e min %5.4e\n",gresidentmax,maxgresidentmax,mingresidentmax);
    533:     MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);
    534:     MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);
    535:     MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);
    536:     PetscViewerASCIIPrintf(viewer,"Current process memory:                                  total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);
    537:   } else if (resident && allocated) {
    538:     MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);
    539:     MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);
    540:     MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);
    541:     PetscViewerASCIIPrintf(viewer,"Current process memory:                                  total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);
    542:     MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);
    543:     MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);
    544:     MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);
    545:     PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed:                           total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);
    546:     PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n");
    547:   } else if (allocated) {
    548:     MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);
    549:     MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);
    550:     MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);
    551:     PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed:                           total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);
    552:     PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n");
    553:     PetscViewerASCIIPrintf(viewer,"OS cannot compute process memory\n");
    554:   } else {
    555:     PetscViewerASCIIPrintf(viewer,"Run with -malloc_debug to get statistics on PetscMalloc() calls\nOS cannot compute process memory\n");
    556:   }
    557:   PetscViewerFlush(viewer);
    558:   return(0);
    559: }

    561: /*@
    562:     PetscMallocGetCurrentUsage - gets the current amount of memory used that was PetscMalloc()ed

    564:     Not Collective

    566:     Output Parameters:
    567: .   space - number of bytes currently allocated

    569:     Level: intermediate

    571: .seealso: PetscMallocDump(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(),
    572:           PetscMemoryGetMaximumUsage()
    573:  @*/
    574: PetscErrorCode  PetscMallocGetCurrentUsage(PetscLogDouble *space)
    575: {
    577:   *space = (PetscLogDouble) TRallocated;
    578:   return(0);
    579: }

    581: /*@
    582:     PetscMallocGetMaximumUsage - gets the maximum amount of memory used that was PetscMalloc()ed at any time
    583:         during this run.

    585:     Not Collective

    587:     Output Parameters:
    588: .   space - maximum number of bytes ever allocated at one time

    590:     Level: intermediate

    592: .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(),
    593:           PetscMallocPushMaximumUsage()
    594:  @*/
    595: PetscErrorCode  PetscMallocGetMaximumUsage(PetscLogDouble *space)
    596: {
    598:   *space = (PetscLogDouble) TRMaxMem;
    599:   return(0);
    600: }

    602: /*@
    603:     PetscMallocPushMaximumUsage - Adds another event to collect the maximum memory usage over an event

    605:     Not Collective

    607:     Input Parameter:
    608: .   event - an event id; this is just for error checking

    610:     Level: developer

    612: .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(),
    613:           PetscMallocPopMaximumUsage()
    614:  @*/
    615: PetscErrorCode  PetscMallocPushMaximumUsage(int event)
    616: {
    618:   if (++NumTRMaxMems > MAXTRMAXMEMS) return(0);
    619:   TRMaxMems[NumTRMaxMems-1]       = TRallocated;
    620:   TRMaxMemsEvents[NumTRMaxMems-1] = event;
    621:   return(0);
    622: }

    624: /*@
    625:     PetscMallocPopMaximumUsage - collect the maximum memory usage over an event

    627:     Not Collective

    629:     Input Parameter:
    630: .   event - an event id; this is just for error checking

    632:     Output Parameter:
    633: .   mu - maximum amount of memory malloced during this event; high water mark relative to the beginning of the event

    635:     Level: developer

    637: .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(),
    638:           PetscMallocPushMaximumUsage()
    639:  @*/
    640: PetscErrorCode  PetscMallocPopMaximumUsage(int event,PetscLogDouble *mu)
    641: {
    643:   *mu = 0;
    644:   if (NumTRMaxMems-- > MAXTRMAXMEMS) return(0);
    645:   if (TRMaxMemsEvents[NumTRMaxMems] != event) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"PetscMallocPush/PopMaximumUsage() are not nested");
    646:   *mu = TRMaxMems[NumTRMaxMems];
    647:   return(0);
    648: }

    650: #if defined(PETSC_USE_DEBUG)
    651: /*@C
    652:    PetscMallocGetStack - returns a pointer to the stack for the location in the program a call to PetscMalloc() was used to obtain that memory

    654:    Collective on PETSC_COMM_WORLD

    656:    Input Parameter:
    657: .    ptr - the memory location

    659:    Output Parameter:
    660: .    stack - the stack indicating where the program allocated this memory

    662:    Level: intermediate

    664: .seealso:  PetscMallocGetCurrentUsage(), PetscMallocView()
    665: @*/
    666: PetscErrorCode  PetscMallocGetStack(void *ptr,PetscStack **stack)
    667: {
    668:   TRSPACE *head;

    671:   head   = (TRSPACE*) (((char*)ptr) - HEADER_BYTES);
    672:   *stack = &head->stack;
    673:   return(0);
    674: }
    675: #else
    676: PetscErrorCode  PetscMallocGetStack(void *ptr,void **stack)
    677: {
    679:   *stack = NULL;
    680:   return(0);
    681: }
    682: #endif

    684: /*@C
    685:    PetscMallocDump - Dumps the currently allocated memory blocks to a file. The information
    686:    printed is: size of space (in bytes), address of space, id of space,
    687:    file in which space was allocated, and line number at which it was
    688:    allocated.

    690:    Not Collective

    692:    Input Parameter:
    693: .  fp  - file pointer.  If fp is NULL, stdout is assumed.

    695:    Options Database Key:
    696: .  -malloc_dump <optional filename> - Dumps unfreed memory during call to PetscFinalize()

    698:    Level: intermediate

    700:    Fortran Note:
    701:    The calling sequence in Fortran is PetscMallocDump(integer ierr)
    702:    The fp defaults to stdout.

    704:    Notes:
    705:      Uses MPI_COMM_WORLD to display rank, because this may be called in PetscFinalize() after PETSC_COMM_WORLD has been freed.

    707:      When called in PetscFinalize() dumps only the allocations that have not been properly freed

    709:      PetscMallocView() prints a list of all memory ever allocated

    711: .seealso:  PetscMallocGetCurrentUsage(), PetscMallocView(), PetscMallocViewSet(), PetscMallocValidate()
    712: @*/
    713: PetscErrorCode  PetscMallocDump(FILE *fp)
    714: {
    715:   TRSPACE        *head;
    716:   size_t         libAlloc = 0;
    718:   PetscMPIInt    rank;

    721:   MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    722:   if (!fp) fp = PETSC_STDOUT;
    723:   head = TRhead;
    724:   while (head) {
    725:     libAlloc += TRrequestedSize ? head->rsize : head->size;
    726:     head = head->next;
    727:   }
    728:   if (TRallocated - libAlloc > 0) fprintf(fp,"[%d]Total space allocated %.0f bytes\n",rank,(PetscLogDouble)TRallocated);
    729:   head = TRhead;
    730:   while (head) {
    731:     PetscBool isLib;

    733:     PetscStrcmp(head->functionname, "PetscDLLibraryOpen", &isLib);
    734:     if (!isLib) {
    735:       fprintf(fp,"[%2d]%.0f bytes %s() line %d in %s\n",rank,(PetscLogDouble) (TRrequestedSize ? head->rsize : head->size),head->functionname,head->lineno,head->filename);
    736: #if defined(PETSC_USE_DEBUG)
    737:       PetscStackPrint(&head->stack,fp);
    738: #endif
    739:     }
    740:     head = head->next;
    741:   }
    742:   return(0);
    743: }

    745: /*@
    746:     PetscMallocViewSet - Activates logging of all calls to PetscMalloc() with a minimum size to view

    748:     Not Collective

    750:     Input Arguments:
    751: .   logmin - minimum allocation size to log, or PETSC_DEFAULT

    753:     Options Database Key:
    754: +  -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize()
    755: .  -malloc_view_threshold <min> - Sets a minimum size if -malloc_view is used
    756: -  -log_view_memory - view the memory usage also with the -log_view option

    758:     Level: advanced

    760:     Notes: Must be called after PetscMallocSetDebug()

    762:     Uses MPI_COMM_WORLD to determine rank because PETSc communicators may not be available

    764: .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocViewSet(), PetscMallocTraceSet(), PetscMallocValidate()
    765: @*/
    766: PetscErrorCode PetscMallocViewSet(PetscLogDouble logmin)
    767: {

    771:   PetscLogMalloc = 0;
    772:   PetscMemorySetGetMaximumUsage();
    773:   if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */
    774:   PetscLogMallocThreshold = (size_t)logmin;
    775:   return(0);
    776: }

    778: /*@
    779:     PetscMallocViewGet - Determine whether all calls to PetscMalloc() are being logged

    781:     Not Collective

    783:     Output Arguments
    784: .   logging - PETSC_TRUE if logging is active

    786:     Options Database Key:
    787: .  -malloc_view <optional filename> - Activates PetscMallocView()

    789:     Level: advanced

    791: .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocTraceGet()
    792: @*/
    793: PetscErrorCode PetscMallocViewGet(PetscBool *logging)
    794: {

    797:   *logging = (PetscBool)(PetscLogMalloc >= 0);
    798:   return(0);
    799: }

    801: /*@
    802:   PetscMallocTraceSet - Trace all calls to PetscMalloc()

    804:   Not Collective

    806:   Input Arguments:
    807: + viewer - The viewer to use for tracing, or NULL to use stdout
    808: . active - Flag to activate or deactivate tracing
    809: - logmin - The smallest memory size that will be logged

    811:   Note:
    812:   The viewer should not be collective.

    814:   Level: advanced

    816: .seealso: PetscMallocTraceGet(), PetscMallocViewGet(), PetscMallocDump(), PetscMallocView()
    817: @*/
    818: PetscErrorCode PetscMallocTraceSet(PetscViewer viewer, PetscBool active, PetscLogDouble logmin)
    819: {

    823:   if (!active) {PetscLogMallocTrace = -1; return(0);}
    824:   PetscLogMallocTraceViewer = !viewer ? PETSC_VIEWER_STDOUT_SELF : viewer;
    825:   PetscLogMallocTrace = 0;
    826:   PetscMemorySetGetMaximumUsage();
    827:   if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */
    828:   PetscLogMallocTraceThreshold = (size_t) logmin;
    829:   return(0);
    830: }

    832: /*@
    833:   PetscMallocTraceGet - Determine whether all calls to PetscMalloc() are being traced

    835:   Not Collective

    837:   Output Argument:
    838: . logging - PETSC_TRUE if logging is active

    840:   Options Database Key:
    841: . -malloc_view <optional filename> - Activates PetscMallocView()

    843:   Level: advanced

    845: .seealso: PetscMallocTraceSet(), PetscMallocViewGet(), PetscMallocDump(), PetscMallocView()
    846: @*/
    847: PetscErrorCode PetscMallocTraceGet(PetscBool *logging)
    848: {

    851:   *logging = (PetscBool) (PetscLogMallocTrace >= 0);
    852:   return(0);
    853: }

    855: /*@C
    856:     PetscMallocView - Saves the log of all calls to PetscMalloc(); also calls
    857:        PetscMemoryGetMaximumUsage()

    859:     Not Collective

    861:     Input Parameter:
    862: .   fp - file pointer; or NULL

    864:     Options Database Key:
    865: .  -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize()

    867:     Level: advanced

    869:    Fortran Note:
    870:    The calling sequence in Fortran is PetscMallocView(integer ierr)
    871:    The fp defaults to stdout.

    873:    Notes:
    874:      PetscMallocDump() dumps only the currently unfreed memory, this dumps all memory ever allocated

    876:      PetscMemoryView() gives a brief summary of current memory usage

    878: .seealso: PetscMallocGetCurrentUsage(), PetscMallocDump(), PetscMallocViewSet(), PetscMemoryView()
    879: @*/
    880: PetscErrorCode  PetscMallocView(FILE *fp)
    881: {
    882:   PetscInt       i,j,n,*perm;
    883:   size_t         *shortlength;
    884:   int            *shortcount,err;
    885:   PetscMPIInt    rank;
    886:   PetscBool      match;
    887:   const char     **shortfunction;
    888:   PetscLogDouble rss;

    892:   MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    893:   err = fflush(fp);
    894:   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");

    896:   if (PetscLogMalloc < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"PetscMallocView() called without call to PetscMallocViewSet() this is often due to\n                      setting the option -malloc_view AFTER PetscInitialize() with PetscOptionsInsert() or PetscOptionsInsertFile()");

    898:   if (!fp) fp = PETSC_STDOUT;
    899:   PetscMemoryGetMaximumUsage(&rss);
    900:   if (rss) {
    901:     (void) fprintf(fp,"[%d] Maximum memory PetscMalloc()ed %.0f maximum size of entire process %.0f\n",rank,(PetscLogDouble)TRMaxMem,rss);
    902:   } else {
    903:     (void) fprintf(fp,"[%d] Maximum memory PetscMalloc()ed %.0f OS cannot compute size of entire process\n",rank,(PetscLogDouble)TRMaxMem);
    904:   }
    905:   shortcount    = (int*)malloc(PetscLogMalloc*sizeof(int));if (!shortcount) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory");
    906:   shortlength   = (size_t*)malloc(PetscLogMalloc*sizeof(size_t));if (!shortlength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory");
    907:   shortfunction = (const char**)malloc(PetscLogMalloc*sizeof(char*));if (!shortfunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory");
    908:   for (i=0,n=0; i<PetscLogMalloc; i++) {
    909:     for (j=0; j<n; j++) {
    910:       PetscStrcmp(shortfunction[j],PetscLogMallocFunction[i],&match);
    911:       if (match) {
    912:         shortlength[j] += PetscLogMallocLength[i];
    913:         shortcount[j]++;
    914:         goto foundit;
    915:       }
    916:     }
    917:     shortfunction[n] = PetscLogMallocFunction[i];
    918:     shortlength[n]   = PetscLogMallocLength[i];
    919:     shortcount[n]    = 1;
    920:     n++;
    921: foundit:;
    922:   }

    924:   perm = (PetscInt*)malloc(n*sizeof(PetscInt));if (!perm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory");
    925:   for (i=0; i<n; i++) perm[i] = i;
    926:   PetscSortStrWithPermutation(n,(const char**)shortfunction,perm);

    928:   (void) fprintf(fp,"[%d] Memory usage sorted by function\n",rank);
    929:   for (i=0; i<n; i++) {
    930:     (void) fprintf(fp,"[%d] %d %.0f %s()\n",rank,shortcount[perm[i]],(PetscLogDouble)shortlength[perm[i]],shortfunction[perm[i]]);
    931:   }
    932:   free(perm);
    933:   free(shortlength);
    934:   free(shortcount);
    935:   free((char**)shortfunction);
    936:   err = fflush(fp);
    937:   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    938:   return(0);
    939: }

    941: /* ---------------------------------------------------------------------------- */

    943: /*@
    944:     PetscMallocSetDebug - Set's PETSc memory debugging

    946:     Not Collective

    948:     Input Parameter:
    949: +   eachcall - checks the entire heap of allocated memory for issues on each call to PetscMalloc() and PetscFree()
    950: -   initializenan - initializes all memory with NaN to catch use of uninitialized floating point arrays

    952:     Options Database:
    953: +   -malloc_debug <true or false> - turns on or off debugging
    954: .   -malloc_test - turns on all debugging if PETSc was configured with debugging including -malloc_dump, otherwise ignored
    955: .   -malloc_view_threshold t - log only allocations larger than t
    956: .   -malloc_dump <filename> - print a list of all memory that has not been freed
    957: .   -malloc no - (deprecated) same as -malloc_debug no
    958: -   -malloc_log - (deprecated) same as -malloc_view

    960:    Level: developer

    962:     Notes: This is called in PetscInitialize() and should not be called elsewhere

    964: .seealso: CHKMEMQ(), PetscMallocValidate(), PetscMallocGetDebug()
    965: @*/
    966: PetscErrorCode PetscMallocSetDebug(PetscBool eachcall, PetscBool initializenan)
    967: {

    971:   if (PetscTrMalloc == PetscTrMallocDefault) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot call this routine more than once, it can only be called in PetscInitialize()");
    972:   PetscMallocSet(PetscTrMallocDefault,PetscTrFreeDefault,PetscTrReallocDefault);

    974:   TRallocated         = 0;
    975:   TRfrags             = 0;
    976:   TRhead              = NULL;
    977:   TRid                = 0;
    978:   TRdebugLevel        = eachcall;
    979:   TRMaxMem            = 0;
    980:   PetscLogMallocMax   = 10000;
    981:   PetscLogMalloc      = -1;
    982:   TRdebugIinitializenan = initializenan;
    983:   return(0);
    984: }

    986: /*@
    987:     PetscMallocGetDebug - Indicates what PETSc memory debugging it is doing.

    989:     Not Collective

    991:     Output Parameters:
    992: +    basic - doing basic debugging
    993: .    eachcall - checks the entire memory heap at each PetscMalloc()/PetscFree()
    994: -    initializenan - initializes memory with NaN

    996:    Level: intermediate

    998:    Notes:
    999:      By default, the debug version always does some debugging unless you run with -malloc_debug no

    1001: .seealso: CHKMEMQ(), PetscMallocValidate(), PetscMallocSetDebug()
    1002: @*/
    1003: PetscErrorCode PetscMallocGetDebug(PetscBool *basic, PetscBool *eachcall, PetscBool *initializenan)
    1004: {
    1006:   if (basic) *basic = (PetscTrMalloc == PetscTrMallocDefault) ? PETSC_TRUE : PETSC_FALSE;
    1007:   if (eachcall) *eachcall           = TRdebugLevel;
    1008:   if (initializenan) *initializenan = TRdebugIinitializenan;
    1009:   return(0);
    1010: }

    1012: /*@
    1013:   PetscMallocLogRequestedSizeSet - Whether to log the requested or aligned memory size

    1015:   Not Collective

    1017:   Input Parameter:
    1018: . flg - PETSC_TRUE to log the requested memory size

    1020:   Options Database:
    1021: . -malloc_requested_size <bool> - Sets this flag

    1023:   Level: developer

    1025: .seealso: PetscMallocLogRequestedSizeGet(), PetscMallocViewSet()
    1026: @*/
    1027: PetscErrorCode PetscMallocLogRequestedSizeSet(PetscBool flg)
    1028: {
    1030:   TRrequestedSize = flg;
    1031:   return(0);
    1032: }

    1034: /*@
    1035:   PetscMallocLogRequestedSizeGet - Whether to log the requested or aligned memory size

    1037:   Not Collective

    1039:   Output Parameter:
    1040: . flg - PETSC_TRUE if we log the requested memory size

    1042:   Level: developer

    1044: .seealso: PetscMallocLogRequestedSizeSetinalSizeSet(), PetscMallocViewSet()
    1045: @*/
    1046: PetscErrorCode PetscMallocLogRequestedSizeGet(PetscBool *flg)
    1047: {
    1049:   *flg = TRrequestedSize;
    1050:   return(0);
    1051: }