17d0a6c19SBarry Smith 2e5c89e4eSSatish Balay /* 392f119d6SBarry Smith Interface to malloc() and free(). This code allows for logging of memory usage and some error checking 4e5c89e4eSSatish Balay */ 5c6db04a5SJed Brown #include <petscsys.h> /*I "petscsys.h" I*/ 6665c2dedSJed Brown #include <petscviewer.h> 7e5c89e4eSSatish Balay #if defined(PETSC_HAVE_MALLOC_H) 8e5c89e4eSSatish Balay #include <malloc.h> 9e5c89e4eSSatish Balay #endif 10e5c89e4eSSatish Balay 11e5c89e4eSSatish Balay /* 12e5c89e4eSSatish Balay These are defined in mal.c and ensure that malloced space is PetscScalar aligned 13e5c89e4eSSatish Balay */ 14071fcb05SBarry Smith PETSC_EXTERN PetscErrorCode PetscMallocAlign(size_t,PetscBool,int,const char[],const char[],void**); 1595c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscFreeAlign(void*,int,const char[],const char[]); 1695c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscReallocAlign(size_t,int,const char[],const char[],void**); 17e5c89e4eSSatish Balay 180700a824SBarry Smith #define CLASSID_VALUE ((PetscClassId) 0xf0e0d0c9) 190700a824SBarry Smith #define ALREADY_FREED ((PetscClassId) 0x0f0e0d9c) 20e5c89e4eSSatish Balay 2192f119d6SBarry Smith /* this is the header put at the beginning of each malloc() using for tracking allocated space and checking of allocated space heap */ 22e5c89e4eSSatish Balay typedef struct _trSPACE { 23e5c89e4eSSatish Balay size_t size; 24e5c89e4eSSatish Balay int id; 25e5c89e4eSSatish Balay int lineno; 26e5c89e4eSSatish Balay const char *filename; 27e5c89e4eSSatish Balay const char *functionname; 280700a824SBarry Smith PetscClassId classid; 298bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 30e5c89e4eSSatish Balay PetscStack stack; 31e5c89e4eSSatish Balay #endif 32e5c89e4eSSatish Balay struct _trSPACE *next,*prev; 33e5c89e4eSSatish Balay } TRSPACE; 34e5c89e4eSSatish Balay 3525b53cc9SJed Brown /* HEADER_BYTES is the number of bytes in a PetscMalloc() header. 3692f119d6SBarry Smith It is sizeof(trSPACE) padded to be a multiple of PETSC_MEMALIGN. 3725b53cc9SJed Brown */ 38a64a8e02SBarry Smith #define HEADER_BYTES ((sizeof(TRSPACE)+(PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1)) 39e5c89e4eSSatish Balay 4025b53cc9SJed Brown /* This union is used to insure that the block passed to the user retains 4125b53cc9SJed Brown a minimum alignment of PETSC_MEMALIGN. 4225b53cc9SJed Brown */ 43e5c89e4eSSatish Balay typedef union { 44e5c89e4eSSatish Balay TRSPACE sp; 4525b53cc9SJed Brown char v[HEADER_BYTES]; 46e5c89e4eSSatish Balay } TrSPACE; 47e5c89e4eSSatish Balay 48e3ed9ee7SBarry Smith #define MAXTRMAXMEMS 50 49e5c89e4eSSatish Balay static size_t TRallocated = 0; 50e5c89e4eSSatish Balay static int TRfrags = 0; 51f0ba7cfcSLisandro Dalcin static TRSPACE *TRhead = NULL; 52e5c89e4eSSatish Balay static int TRid = 0; 53ace3abfcSBarry Smith static PetscBool TRdebugLevel = PETSC_FALSE; 5492f119d6SBarry Smith static PetscBool TRdebugIintializenan = PETSC_FALSE; 55e5c89e4eSSatish Balay static size_t TRMaxMem = 0; 56e3ed9ee7SBarry Smith static int NumTRMaxMems = 0; 57e3ed9ee7SBarry Smith static size_t TRMaxMems[MAXTRMAXMEMS]; 58e3ed9ee7SBarry Smith static int TRMaxMemsEvents[MAXTRMAXMEMS]; 59e5c89e4eSSatish Balay /* 6092f119d6SBarry Smith Arrays to log information on mallocs for PetscMallocView() 61e5c89e4eSSatish Balay */ 62f0ba7cfcSLisandro Dalcin static int PetscLogMallocMax = 10000; 63f0ba7cfcSLisandro Dalcin static int PetscLogMalloc = -1; 64574034a9SJed Brown static size_t PetscLogMallocThreshold = 0; 65e5c89e4eSSatish Balay static size_t *PetscLogMallocLength; 66efca3c55SSatish Balay static const char **PetscLogMallocFile,**PetscLogMallocFunction; 67b022a5c1SBarry Smith 68e5c89e4eSSatish Balay /*@C 6992f119d6SBarry Smith PetscMallocValidate - Test the memory for corruption. This can be called at any time between PetscInitialize() and PetscFinalize() 70e5c89e4eSSatish Balay 7192f119d6SBarry Smith Input Parameters: 72e5c89e4eSSatish Balay + line - line number where call originated. 73e5c89e4eSSatish Balay . function - name of function calling 74efca3c55SSatish Balay - file - file where function is 75e5c89e4eSSatish Balay 76e5c89e4eSSatish Balay Return value: 77e5c89e4eSSatish Balay The number of errors detected. 78e5c89e4eSSatish Balay 7992f119d6SBarry Smith Options Database:. 8092f119d6SBarry Smith + -malloc_test - turns this feature on when PETSc was not configured with --with-debugging=0 8192f119d6SBarry Smith - -malloc_debug - turns this feature on anytime 8292f119d6SBarry Smith 83e5c89e4eSSatish Balay Output Effect: 84e5c89e4eSSatish Balay Error messages are written to stdout. 85e5c89e4eSSatish Balay 86e5c89e4eSSatish Balay Level: advanced 87e5c89e4eSSatish Balay 88e5c89e4eSSatish Balay Notes: 89*79dccf82SBarry Smith 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) 9038548759SBarry Smith 9192f119d6SBarry Smith You should generally use CHKMEMQ as a short cut for calling this routine. 92e5c89e4eSSatish Balay 93e5c89e4eSSatish Balay The Fortran calling sequence is simply PetscMallocValidate(ierr) 94e5c89e4eSSatish Balay 95e5c89e4eSSatish Balay No output is generated if there are no problems detected. 96e5c89e4eSSatish Balay 9792f119d6SBarry Smith Developers Note: 9892f119d6SBarry Smith Uses the flg TRdebugLevel (set as the first argument to PetscMallocSetDebug()) to determine if it should run 9992f119d6SBarry Smith 100e5c89e4eSSatish Balay .seealso: CHKMEMQ 101e5c89e4eSSatish Balay 102e5c89e4eSSatish Balay @*/ 103efca3c55SSatish Balay PetscErrorCode PetscMallocValidate(int line,const char function[],const char file[]) 104e5c89e4eSSatish Balay { 1056c093d5bSvictor TRSPACE *head,*lasthead; 106e5c89e4eSSatish Balay char *a; 1070700a824SBarry Smith PetscClassId *nend; 108e5c89e4eSSatish Balay 10938548759SBarry Smith if (!TRdebugLevel) return 0; 110e5c89e4eSSatish Balay PetscFunctionBegin; 1116c093d5bSvictor head = TRhead; lasthead = NULL; 112e5c89e4eSSatish Balay while (head) { 1130700a824SBarry Smith if (head->classid != CLASSID_VALUE) { 114efca3c55SSatish Balay (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 115e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory at address %p is corrupted\n",head); 116e5c89e4eSSatish Balay (*PetscErrorPrintf)("Probably write past beginning or end of array\n"); 117efca3c55SSatish Balay if (lasthead) (*PetscErrorPrintf)("Last intact block allocated in %s() line %d in %s\n",lasthead->functionname,lasthead->lineno,lasthead->filename); 118e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 119e5c89e4eSSatish Balay } 120e5c89e4eSSatish Balay a = (char*)(((TrSPACE*)head) + 1); 1210700a824SBarry Smith nend = (PetscClassId*)(a + head->size); 1220700a824SBarry Smith if (*nend != CLASSID_VALUE) { 123efca3c55SSatish Balay (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 124e5c89e4eSSatish Balay if (*nend == ALREADY_FREED) { 125e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p already freed\n",head->id,(PetscLogDouble)head->size,a); 126e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 127e5c89e4eSSatish Balay } else { 128e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 129efca3c55SSatish Balay (*PetscErrorPrintf)("Memory originally allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 130e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 131e5c89e4eSSatish Balay } 132e5c89e4eSSatish Balay } 1336c093d5bSvictor lasthead = head; 134e5c89e4eSSatish Balay head = head->next; 135e5c89e4eSSatish Balay } 136e5c89e4eSSatish Balay PetscFunctionReturn(0); 137e5c89e4eSSatish Balay } 138e5c89e4eSSatish Balay 139e5c89e4eSSatish Balay /* 140e5c89e4eSSatish Balay PetscTrMallocDefault - Malloc with tracing. 141e5c89e4eSSatish Balay 142e5c89e4eSSatish Balay Input Parameters: 143e5c89e4eSSatish Balay + a - number of bytes to allocate 144e5c89e4eSSatish Balay . lineno - line number where used. Use __LINE__ for this 145efca3c55SSatish Balay - filename - file name where used. Use __FILE__ for this 146e5c89e4eSSatish Balay 147e5c89e4eSSatish Balay Returns: 14892f119d6SBarry Smith double aligned pointer to requested storage, or null if not available. 149e5c89e4eSSatish Balay */ 150071fcb05SBarry Smith PetscErrorCode PetscTrMallocDefault(size_t a,PetscBool clear,int lineno,const char function[],const char filename[],void **result) 151e5c89e4eSSatish Balay { 152e5c89e4eSSatish Balay TRSPACE *head; 153e5c89e4eSSatish Balay char *inew; 154e5c89e4eSSatish Balay size_t nsize; 155e5c89e4eSSatish Balay PetscErrorCode ierr; 156e5c89e4eSSatish Balay 157e5c89e4eSSatish Balay PetscFunctionBegin; 158f0ba7cfcSLisandro Dalcin /* Do not try to handle empty blocks */ 159f0ba7cfcSLisandro Dalcin if (!a) { *result = NULL; PetscFunctionReturn(0); } 160f0ba7cfcSLisandro Dalcin 161efca3c55SSatish Balay ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr); 162e5c89e4eSSatish Balay 16325b53cc9SJed Brown nsize = (a + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1); 164071fcb05SBarry Smith ierr = PetscMallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),clear,lineno,function,filename,(void**)&inew);CHKERRQ(ierr); 165e3ed9ee7SBarry Smith 166e5c89e4eSSatish Balay head = (TRSPACE*)inew; 167e5c89e4eSSatish Balay inew += sizeof(TrSPACE); 168e5c89e4eSSatish Balay 169e5c89e4eSSatish Balay if (TRhead) TRhead->prev = head; 170e5c89e4eSSatish Balay head->next = TRhead; 171e5c89e4eSSatish Balay TRhead = head; 172f0ba7cfcSLisandro Dalcin head->prev = NULL; 173e5c89e4eSSatish Balay head->size = nsize; 174e5c89e4eSSatish Balay head->id = TRid; 175e5c89e4eSSatish Balay head->lineno = lineno; 176e5c89e4eSSatish Balay 177e5c89e4eSSatish Balay head->filename = filename; 178e5c89e4eSSatish Balay head->functionname = function; 1790700a824SBarry Smith head->classid = CLASSID_VALUE; 1800700a824SBarry Smith *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 181e5c89e4eSSatish Balay 182e5c89e4eSSatish Balay TRallocated += nsize; 183a297a907SKarl Rupp if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 184e3ed9ee7SBarry Smith if (PetscLogMemory) { 185e3ed9ee7SBarry Smith PetscInt i; 186e3ed9ee7SBarry Smith for (i=0; i<NumTRMaxMems; i++) { 187e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 188e3ed9ee7SBarry Smith } 189e3ed9ee7SBarry Smith } 190e5c89e4eSSatish Balay TRfrags++; 191e5c89e4eSSatish Balay 1928bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 19376386721SLisandro Dalcin if (PetscStackActive()) { 1945c25fcd7SBarry Smith ierr = PetscStackCopy(petscstack,&head->stack);CHKERRQ(ierr); 1952c9581d2SBarry Smith /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 1962c9581d2SBarry Smith head->stack.line[head->stack.currentsize-2] = lineno; 1979de0f6ecSBarry Smith } else { 1989de0f6ecSBarry Smith head->stack.currentsize = 0; 19976386721SLisandro Dalcin } 20092f119d6SBarry Smith #if defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL_DOUBLE) 20192f119d6SBarry Smith if (!clear && TRdebugIintializenan) { 20292f119d6SBarry Smith size_t i, n = a/sizeof(PetscReal); 20392f119d6SBarry Smith PetscReal *s = (PetscReal*) inew; 20492f119d6SBarry Smith /* from https://www.doc.ic.ac.uk/~eedwards/compsys/float/nan.html */ 20592f119d6SBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 206df282883SBarry Smith int nas = 0x7F800002; 20792f119d6SBarry Smith #else 20892f119d6SBarry Smith PetscInt64 nas = 0x7FF0000000000002; 20992f119d6SBarry Smith #endif 21092f119d6SBarry Smith for (i=0; i<n; i++) { 21192f119d6SBarry Smith memcpy(s+i,&nas,sizeof(PetscReal)); 21292f119d6SBarry Smith } 21392f119d6SBarry Smith } 21492f119d6SBarry Smith #endif 215e5c89e4eSSatish Balay #endif 216e5c89e4eSSatish Balay 217e5c89e4eSSatish Balay /* 21892f119d6SBarry Smith Allow logging of all mallocs made. 21992f119d6SBarry Smith TODO: Currently this memory is never freed, it should be freed during PetscFinalize() 220e5c89e4eSSatish Balay */ 221574034a9SJed Brown if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && a >= PetscLogMallocThreshold) { 222e5c89e4eSSatish Balay if (!PetscLogMalloc) { 223e5c89e4eSSatish Balay PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 224e32f2f54SBarry Smith if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 225a297a907SKarl Rupp 226a2ea699eSBarry Smith PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 227e32f2f54SBarry Smith if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 228a297a907SKarl Rupp 229a2ea699eSBarry Smith PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 230e32f2f54SBarry Smith if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 231e5c89e4eSSatish Balay } 232e5c89e4eSSatish Balay PetscLogMallocLength[PetscLogMalloc] = nsize; 233e5c89e4eSSatish Balay PetscLogMallocFile[PetscLogMalloc] = filename; 234e5c89e4eSSatish Balay PetscLogMallocFunction[PetscLogMalloc++] = function; 235e5c89e4eSSatish Balay } 236e5c89e4eSSatish Balay *result = (void*)inew; 237e5c89e4eSSatish Balay PetscFunctionReturn(0); 238e5c89e4eSSatish Balay } 239e5c89e4eSSatish Balay 240e5c89e4eSSatish Balay /* 241e5c89e4eSSatish Balay PetscTrFreeDefault - Free with tracing. 242e5c89e4eSSatish Balay 243e5c89e4eSSatish Balay Input Parameters: 244e5c89e4eSSatish Balay . a - pointer to a block allocated with PetscTrMalloc 245e5c89e4eSSatish Balay . lineno - line number where used. Use __LINE__ for this 246e5c89e4eSSatish Balay . file - file name where used. Use __FILE__ for this 247e5c89e4eSSatish Balay */ 248efca3c55SSatish Balay PetscErrorCode PetscTrFreeDefault(void *aa,int line,const char function[],const char file[]) 249e5c89e4eSSatish Balay { 250e5c89e4eSSatish Balay char *a = (char*)aa; 251e5c89e4eSSatish Balay TRSPACE *head; 252e5c89e4eSSatish Balay char *ahead; 253e5c89e4eSSatish Balay PetscErrorCode ierr; 2540700a824SBarry Smith PetscClassId *nend; 255e5c89e4eSSatish Balay 256e5c89e4eSSatish Balay PetscFunctionBegin; 257e5c89e4eSSatish Balay /* Do not try to handle empty blocks */ 25849d7da52SJed Brown if (!a) PetscFunctionReturn(0); 259e5c89e4eSSatish Balay 260efca3c55SSatish Balay ierr = PetscMallocValidate(line,function,file);CHKERRQ(ierr); 261e5c89e4eSSatish Balay 262e5c89e4eSSatish Balay ahead = a; 263e5c89e4eSSatish Balay a = a - sizeof(TrSPACE); 264e5c89e4eSSatish Balay head = (TRSPACE*)a; 265e5c89e4eSSatish Balay 2660700a824SBarry Smith if (head->classid != CLASSID_VALUE) { 267efca3c55SSatish Balay (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); 268e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 269e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); 270e5c89e4eSSatish Balay } 2710700a824SBarry Smith nend = (PetscClassId*)(ahead + head->size); 2720700a824SBarry Smith if (*nend != CLASSID_VALUE) { 273e5c89e4eSSatish Balay if (*nend == ALREADY_FREED) { 274efca3c55SSatish Balay (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); 275e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 276e5c89e4eSSatish Balay if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 277efca3c55SSatish Balay (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 278e5c89e4eSSatish Balay } else { 279efca3c55SSatish Balay (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename); 280e5c89e4eSSatish Balay } 281e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); 282e5c89e4eSSatish Balay } else { 283e5c89e4eSSatish Balay /* Damaged tail */ 284efca3c55SSatish Balay (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); 285e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 286efca3c55SSatish Balay (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 287e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); 288e5c89e4eSSatish Balay } 289e5c89e4eSSatish Balay } 290e5c89e4eSSatish Balay /* Mark the location freed */ 291e5c89e4eSSatish Balay *nend = ALREADY_FREED; 292e5c89e4eSSatish Balay /* Save location where freed. If we suspect the line number, mark as allocated location */ 293e5c89e4eSSatish Balay if (line > 0 && line < 50000) { 294e5c89e4eSSatish Balay head->lineno = line; 295e5c89e4eSSatish Balay head->filename = file; 296e5c89e4eSSatish Balay head->functionname = function; 297e5c89e4eSSatish Balay } else { 298e5c89e4eSSatish Balay head->lineno = -head->lineno; 299e5c89e4eSSatish Balay } 300e3ed9ee7SBarry Smith if (TRallocated < head->size) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"TRallocate is smaller than memory just freed"); 301e5c89e4eSSatish Balay TRallocated -= head->size; 302e5c89e4eSSatish Balay TRfrags--; 303e5c89e4eSSatish Balay if (head->prev) head->prev->next = head->next; 304e5c89e4eSSatish Balay else TRhead = head->next; 305e5c89e4eSSatish Balay 306e5c89e4eSSatish Balay if (head->next) head->next->prev = head->prev; 307efca3c55SSatish Balay ierr = PetscFreeAlign(a,line,function,file);CHKERRQ(ierr); 308e5c89e4eSSatish Balay PetscFunctionReturn(0); 309e5c89e4eSSatish Balay } 310e5c89e4eSSatish Balay 3113221ece2SMatthew G. Knepley /* 3123221ece2SMatthew G. Knepley PetscTrReallocDefault - Realloc with tracing. 3133221ece2SMatthew G. Knepley 3143221ece2SMatthew G. Knepley Input Parameters: 3153221ece2SMatthew G. Knepley + len - number of bytes to allocate 3163221ece2SMatthew G. Knepley . lineno - line number where used. Use __LINE__ for this 3173221ece2SMatthew G. Knepley . filename - file name where used. Use __FILE__ for this 31892f119d6SBarry Smith - result - original memory 3193221ece2SMatthew G. Knepley 3203221ece2SMatthew G. Knepley Output Parameter: 3213221ece2SMatthew G. Knepley . result - double aligned pointer to requested storage, or null if not available. 3223221ece2SMatthew G. Knepley 3233221ece2SMatthew G. Knepley Level: developer 3243221ece2SMatthew G. Knepley 3253221ece2SMatthew G. Knepley .seealso: PetscTrMallocDefault(), PetscTrFreeDefault() 3263221ece2SMatthew G. Knepley */ 3273221ece2SMatthew G. Knepley PetscErrorCode PetscTrReallocDefault(size_t len, int lineno, const char function[], const char filename[], void **result) 3283221ece2SMatthew G. Knepley { 3293221ece2SMatthew G. Knepley char *a = (char *) *result; 3303221ece2SMatthew G. Knepley TRSPACE *head; 3313221ece2SMatthew G. Knepley char *ahead, *inew; 3323221ece2SMatthew G. Knepley PetscClassId *nend; 3333221ece2SMatthew G. Knepley size_t nsize; 3343221ece2SMatthew G. Knepley PetscErrorCode ierr; 3353221ece2SMatthew G. Knepley 3363221ece2SMatthew G. Knepley PetscFunctionBegin; 33792f119d6SBarry Smith /* Realloc requests zero space so just free the current space */ 338c22f1541SToby Isaac if (!len) { 339c22f1541SToby Isaac ierr = PetscTrFreeDefault(*result,lineno,function,filename);CHKERRQ(ierr); 340c22f1541SToby Isaac *result = NULL; 341c22f1541SToby Isaac PetscFunctionReturn(0); 342c22f1541SToby Isaac } 34392f119d6SBarry Smith /* If the orginal space was NULL just use the regular malloc() */ 344f590eff4SLisandro Dalcin if (!*result) { 345071fcb05SBarry Smith ierr = PetscTrMallocDefault(len,PETSC_FALSE,lineno,function,filename,result);CHKERRQ(ierr); 346f590eff4SLisandro Dalcin PetscFunctionReturn(0); 347f590eff4SLisandro Dalcin } 3483221ece2SMatthew G. Knepley 34938548759SBarry Smith ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr); 3503221ece2SMatthew G. Knepley 3513221ece2SMatthew G. Knepley ahead = a; 3523221ece2SMatthew G. Knepley a = a - sizeof(TrSPACE); 3533221ece2SMatthew G. Knepley head = (TRSPACE *) a; 3543221ece2SMatthew G. Knepley inew = a; 3553221ece2SMatthew G. Knepley 3563221ece2SMatthew G. Knepley if (head->classid != CLASSID_VALUE) { 3573221ece2SMatthew G. Knepley (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename); 3583221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 3593221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); 3603221ece2SMatthew G. Knepley } 3613221ece2SMatthew G. Knepley nend = (PetscClassId *)(ahead + head->size); 3623221ece2SMatthew G. Knepley if (*nend != CLASSID_VALUE) { 3633221ece2SMatthew G. Knepley if (*nend == ALREADY_FREED) { 3643221ece2SMatthew G. Knepley (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename); 3653221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 3663221ece2SMatthew G. Knepley if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 3673221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 3683221ece2SMatthew G. Knepley } else { 3693221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename); 3703221ece2SMatthew G. Knepley } 3713221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); 3723221ece2SMatthew G. Knepley } else { 3733221ece2SMatthew G. Knepley /* Damaged tail */ 3743221ece2SMatthew G. Knepley (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename); 3753221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 3763221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 3773221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); 3783221ece2SMatthew G. Knepley } 3793221ece2SMatthew G. Knepley } 3803221ece2SMatthew G. Knepley 38192f119d6SBarry Smith /* remove original reference to the memory allocated from the PETSc debugging heap */ 3823221ece2SMatthew G. Knepley TRallocated -= head->size; 3833221ece2SMatthew G. Knepley TRfrags--; 3843221ece2SMatthew G. Knepley if (head->prev) head->prev->next = head->next; 3853221ece2SMatthew G. Knepley else TRhead = head->next; 3863221ece2SMatthew G. Knepley if (head->next) head->next->prev = head->prev; 3873221ece2SMatthew G. Knepley 3883221ece2SMatthew G. Knepley nsize = (len + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1); 3893221ece2SMatthew G. Knepley ierr = PetscReallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),lineno,function,filename,(void**)&inew);CHKERRQ(ierr); 3903221ece2SMatthew G. Knepley 3913221ece2SMatthew G. Knepley head = (TRSPACE*)inew; 3923221ece2SMatthew G. Knepley inew += sizeof(TrSPACE); 3933221ece2SMatthew G. Knepley 3943221ece2SMatthew G. Knepley if (TRhead) TRhead->prev = head; 3953221ece2SMatthew G. Knepley head->next = TRhead; 3963221ece2SMatthew G. Knepley TRhead = head; 3973221ece2SMatthew G. Knepley head->prev = NULL; 3983221ece2SMatthew G. Knepley head->size = nsize; 3993221ece2SMatthew G. Knepley head->id = TRid; 4003221ece2SMatthew G. Knepley head->lineno = lineno; 4013221ece2SMatthew G. Knepley 4023221ece2SMatthew G. Knepley head->filename = filename; 4033221ece2SMatthew G. Knepley head->functionname = function; 4043221ece2SMatthew G. Knepley head->classid = CLASSID_VALUE; 4053221ece2SMatthew G. Knepley *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 4063221ece2SMatthew G. Knepley 4073221ece2SMatthew G. Knepley TRallocated += nsize; 4083221ece2SMatthew G. Knepley if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 409e3ed9ee7SBarry Smith if (PetscLogMemory) { 410e3ed9ee7SBarry Smith PetscInt i; 411e3ed9ee7SBarry Smith for (i=0; i<NumTRMaxMems; i++) { 412e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 413e3ed9ee7SBarry Smith } 414e3ed9ee7SBarry Smith } 4153221ece2SMatthew G. Knepley TRfrags++; 4163221ece2SMatthew G. Knepley 4173221ece2SMatthew G. Knepley #if defined(PETSC_USE_DEBUG) 4183221ece2SMatthew G. Knepley if (PetscStackActive()) { 4193221ece2SMatthew G. Knepley ierr = PetscStackCopy(petscstack,&head->stack);CHKERRQ(ierr); 4203221ece2SMatthew G. Knepley /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 4213221ece2SMatthew G. Knepley head->stack.line[head->stack.currentsize-2] = lineno; 4223221ece2SMatthew G. Knepley } else { 4233221ece2SMatthew G. Knepley head->stack.currentsize = 0; 4243221ece2SMatthew G. Knepley } 4253221ece2SMatthew G. Knepley #endif 4263221ece2SMatthew G. Knepley 4273221ece2SMatthew G. Knepley /* 42892f119d6SBarry Smith Allow logging of all mallocs made. This adds a new entry to the list of allocated memory 42992f119d6SBarry Smith and does not remove the previous entry to the list hence this memory is "double counted" in PetscMallocView() 4303221ece2SMatthew G. Knepley */ 4313221ece2SMatthew G. Knepley if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && len >= PetscLogMallocThreshold) { 4323221ece2SMatthew G. Knepley if (!PetscLogMalloc) { 4333221ece2SMatthew G. Knepley PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 4343221ece2SMatthew G. Knepley if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4353221ece2SMatthew G. Knepley 4363221ece2SMatthew G. Knepley PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 4373221ece2SMatthew G. Knepley if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4383221ece2SMatthew G. Knepley 4393221ece2SMatthew G. Knepley PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 4403221ece2SMatthew G. Knepley if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4413221ece2SMatthew G. Knepley } 4423221ece2SMatthew G. Knepley PetscLogMallocLength[PetscLogMalloc] = nsize; 4433221ece2SMatthew G. Knepley PetscLogMallocFile[PetscLogMalloc] = filename; 4443221ece2SMatthew G. Knepley PetscLogMallocFunction[PetscLogMalloc++] = function; 4453221ece2SMatthew G. Knepley } 4463221ece2SMatthew G. Knepley *result = (void*)inew; 4473221ece2SMatthew G. Knepley PetscFunctionReturn(0); 4483221ece2SMatthew G. Knepley } 4493221ece2SMatthew G. Knepley 450fe7fb379SMatthew Knepley /*@C 45192f119d6SBarry Smith PetscMemoryView - Shows the amount of memory currently being used in a communicator. 452e5c89e4eSSatish Balay 453e5c89e4eSSatish Balay Collective on PetscViewer 454e5c89e4eSSatish Balay 455e5c89e4eSSatish Balay Input Parameter: 456e5c89e4eSSatish Balay + viewer - the viewer that defines the communicator 457e5c89e4eSSatish Balay - message - string printed before values 458e5c89e4eSSatish Balay 4590841954dSBarry Smith Options Database: 46092f119d6SBarry Smith + -malloc_debug - have PETSc track how much memory it has allocated 4610841954dSBarry Smith - -memory_view - during PetscFinalize() have this routine called 4620841954dSBarry Smith 463e5c89e4eSSatish Balay Level: intermediate 464e5c89e4eSSatish Balay 46592f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMemoryGetCurrentUsage(), PetscMemorySetGetMaximumUsage(), PetscMallocView() 466e5c89e4eSSatish Balay @*/ 4670841954dSBarry Smith PetscErrorCode PetscMemoryView(PetscViewer viewer,const char message[]) 468e5c89e4eSSatish Balay { 4690841954dSBarry Smith PetscLogDouble allocated,allocatedmax,resident,residentmax,gallocated,gallocatedmax,gresident,gresidentmax,maxgallocated,maxgallocatedmax,maxgresident,maxgresidentmax; 4700841954dSBarry Smith PetscLogDouble mingallocated,mingallocatedmax,mingresident,mingresidentmax; 471e5c89e4eSSatish Balay PetscErrorCode ierr; 472e5c89e4eSSatish Balay MPI_Comm comm; 473e5c89e4eSSatish Balay 474e5c89e4eSSatish Balay PetscFunctionBegin; 475e5c89e4eSSatish Balay if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD; 476e5c89e4eSSatish Balay ierr = PetscMallocGetCurrentUsage(&allocated);CHKERRQ(ierr); 4770841954dSBarry Smith ierr = PetscMallocGetMaximumUsage(&allocatedmax);CHKERRQ(ierr); 478e5c89e4eSSatish Balay ierr = PetscMemoryGetCurrentUsage(&resident);CHKERRQ(ierr); 479e5c89e4eSSatish Balay ierr = PetscMemoryGetMaximumUsage(&residentmax);CHKERRQ(ierr); 480e5c89e4eSSatish Balay if (residentmax > 0) residentmax = PetscMax(resident,residentmax); 481e5c89e4eSSatish Balay ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 482e5c89e4eSSatish Balay ierr = PetscViewerASCIIPrintf(viewer,message);CHKERRQ(ierr); 483e5c89e4eSSatish Balay if (resident && residentmax && allocated) { 4840841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 4850841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 4860841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 4870841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Maximum (over computational time) process memory: total %5.4e max %5.4e min %5.4e\n",gresidentmax,maxgresidentmax,mingresidentmax);CHKERRQ(ierr); 4880841954dSBarry Smith ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 4890841954dSBarry Smith ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 4900841954dSBarry Smith ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 4910841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr); 4920841954dSBarry Smith ierr = MPI_Reduce(&allocatedmax,&gallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 4930841954dSBarry Smith ierr = MPI_Reduce(&allocatedmax,&maxgallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 4940841954dSBarry Smith ierr = MPI_Reduce(&allocatedmax,&mingallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 4950841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Maximum (over computational time) space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocatedmax,maxgallocatedmax,mingallocatedmax);CHKERRQ(ierr); 4960841954dSBarry Smith ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 4970841954dSBarry Smith ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 4980841954dSBarry Smith ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 4990841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr); 500e5c89e4eSSatish Balay } else if (resident && residentmax) { 5010841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5020841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5030841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5040841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Maximum (over computational time) process memory: total %5.4e max %5.4e min %5.4e\n",gresidentmax,maxgresidentmax,mingresidentmax);CHKERRQ(ierr); 5050841954dSBarry Smith ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5060841954dSBarry Smith ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5070841954dSBarry Smith ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5080841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr); 509e5c89e4eSSatish Balay } else if (resident && allocated) { 5100841954dSBarry Smith ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5110841954dSBarry Smith ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5120841954dSBarry Smith ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5130841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr); 5140841954dSBarry Smith ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5150841954dSBarry Smith ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5160841954dSBarry Smith ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5170841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr); 5180841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n");CHKERRQ(ierr); 519e5c89e4eSSatish Balay } else if (allocated) { 5200841954dSBarry Smith ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5210841954dSBarry Smith ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5220841954dSBarry Smith ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5230841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr); 5240841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n");CHKERRQ(ierr); 5250841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"OS cannot compute process memory\n");CHKERRQ(ierr); 526e5c89e4eSSatish Balay } else { 52792f119d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Run with -malloc_debug to get statistics on PetscMalloc() calls\nOS cannot compute process memory\n");CHKERRQ(ierr); 528e5c89e4eSSatish Balay } 529e5c89e4eSSatish Balay ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 530e5c89e4eSSatish Balay PetscFunctionReturn(0); 531e5c89e4eSSatish Balay } 532e5c89e4eSSatish Balay 53346eb3923SBarry Smith /*@ 534e5c89e4eSSatish Balay PetscMallocGetCurrentUsage - gets the current amount of memory used that was PetscMalloc()ed 535e5c89e4eSSatish Balay 536e5c89e4eSSatish Balay Not Collective 537e5c89e4eSSatish Balay 538e5c89e4eSSatish Balay Output Parameters: 539e5c89e4eSSatish Balay . space - number of bytes currently allocated 540e5c89e4eSSatish Balay 541e5c89e4eSSatish Balay Level: intermediate 542e5c89e4eSSatish Balay 54392f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocLog(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 544e5c89e4eSSatish Balay PetscMemoryGetMaximumUsage() 545e5c89e4eSSatish Balay @*/ 5467087cfbeSBarry Smith PetscErrorCode PetscMallocGetCurrentUsage(PetscLogDouble *space) 547e5c89e4eSSatish Balay { 548e5c89e4eSSatish Balay PetscFunctionBegin; 549e5c89e4eSSatish Balay *space = (PetscLogDouble) TRallocated; 550e5c89e4eSSatish Balay PetscFunctionReturn(0); 551e5c89e4eSSatish Balay } 552e5c89e4eSSatish Balay 553dc37d89fSBarry Smith /*@ 554e5c89e4eSSatish Balay PetscMallocGetMaximumUsage - gets the maximum amount of memory used that was PetscMalloc()ed at any time 555e5c89e4eSSatish Balay during this run. 556e5c89e4eSSatish Balay 557e5c89e4eSSatish Balay Not Collective 558e5c89e4eSSatish Balay 559e5c89e4eSSatish Balay Output Parameters: 560e5c89e4eSSatish Balay . space - maximum number of bytes ever allocated at one time 561e5c89e4eSSatish Balay 562e5c89e4eSSatish Balay Level: intermediate 563e5c89e4eSSatish Balay 56492f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 565e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage() 566e5c89e4eSSatish Balay @*/ 5677087cfbeSBarry Smith PetscErrorCode PetscMallocGetMaximumUsage(PetscLogDouble *space) 568e5c89e4eSSatish Balay { 569e5c89e4eSSatish Balay PetscFunctionBegin; 570e5c89e4eSSatish Balay *space = (PetscLogDouble) TRMaxMem; 571e5c89e4eSSatish Balay PetscFunctionReturn(0); 572e5c89e4eSSatish Balay } 573e5c89e4eSSatish Balay 574e3ed9ee7SBarry Smith /*@ 575e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage - Adds another event to collect the maximum memory usage over an event 576e3ed9ee7SBarry Smith 577e3ed9ee7SBarry Smith Not Collective 578e3ed9ee7SBarry Smith 579e3ed9ee7SBarry Smith Input Parameter: 580e3ed9ee7SBarry Smith . event - an event id; this is just for error checking 581e3ed9ee7SBarry Smith 582e3ed9ee7SBarry Smith Level: developer 583e3ed9ee7SBarry Smith 58492f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 585e3ed9ee7SBarry Smith PetscMallocPopMaximumUsage() 586e3ed9ee7SBarry Smith @*/ 587e3ed9ee7SBarry Smith PetscErrorCode PetscMallocPushMaximumUsage(int event) 588e3ed9ee7SBarry Smith { 589e3ed9ee7SBarry Smith PetscFunctionBegin; 590e3ed9ee7SBarry Smith if (++NumTRMaxMems > MAXTRMAXMEMS) PetscFunctionReturn(0); 591e3ed9ee7SBarry Smith TRMaxMems[NumTRMaxMems-1] = TRallocated; 592e3ed9ee7SBarry Smith TRMaxMemsEvents[NumTRMaxMems-1] = event; 593e3ed9ee7SBarry Smith PetscFunctionReturn(0); 594e3ed9ee7SBarry Smith } 595e3ed9ee7SBarry Smith 596e3ed9ee7SBarry Smith /*@ 597e3ed9ee7SBarry Smith PetscMallocPopMaximumUsage - collect the maximum memory usage over an event 598e3ed9ee7SBarry Smith 599e3ed9ee7SBarry Smith Not Collective 600e3ed9ee7SBarry Smith 601e3ed9ee7SBarry Smith Input Parameter: 602e3ed9ee7SBarry Smith . event - an event id; this is just for error checking 603e3ed9ee7SBarry Smith 604e3ed9ee7SBarry Smith Output Parameter: 605e3ed9ee7SBarry Smith . mu - maximum amount of memory malloced during this event; high water mark relative to the beginning of the event 606e3ed9ee7SBarry Smith 607e3ed9ee7SBarry Smith Level: developer 608e3ed9ee7SBarry Smith 60992f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 610e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage() 611e3ed9ee7SBarry Smith @*/ 612e3ed9ee7SBarry Smith PetscErrorCode PetscMallocPopMaximumUsage(int event,PetscLogDouble *mu) 613e3ed9ee7SBarry Smith { 614e3ed9ee7SBarry Smith PetscFunctionBegin; 615e3ed9ee7SBarry Smith *mu = 0; 616e3ed9ee7SBarry Smith if (NumTRMaxMems-- > MAXTRMAXMEMS) PetscFunctionReturn(0); 617e3ed9ee7SBarry Smith if (TRMaxMemsEvents[NumTRMaxMems] != event) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"PetscMallocPush/PopMaximumUsage() are not nested"); 618e3ed9ee7SBarry Smith *mu = TRMaxMems[NumTRMaxMems]; 619e3ed9ee7SBarry Smith PetscFunctionReturn(0); 620e3ed9ee7SBarry Smith } 621e3ed9ee7SBarry Smith 622a64a8e02SBarry Smith #if defined(PETSC_USE_DEBUG) 623a64a8e02SBarry Smith /*@C 624a64a8e02SBarry Smith PetscMallocGetStack - returns a pointer to the stack for the location in the program a call to PetscMalloc() was used to obtain that memory 625a64a8e02SBarry Smith 626a64a8e02SBarry Smith Collective on PETSC_COMM_WORLD 627a64a8e02SBarry Smith 628a64a8e02SBarry Smith Input Parameter: 629a64a8e02SBarry Smith . ptr - the memory location 630a64a8e02SBarry Smith 631a64a8e02SBarry Smith Output Paramter: 632a64a8e02SBarry Smith . stack - the stack indicating where the program allocated this memory 633a64a8e02SBarry Smith 634a64a8e02SBarry Smith Level: intermediate 635a64a8e02SBarry Smith 63692f119d6SBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocView() 637a64a8e02SBarry Smith @*/ 638a64a8e02SBarry Smith PetscErrorCode PetscMallocGetStack(void *ptr,PetscStack **stack) 639a64a8e02SBarry Smith { 640a64a8e02SBarry Smith TRSPACE *head; 641a64a8e02SBarry Smith 642a64a8e02SBarry Smith PetscFunctionBegin; 643a64a8e02SBarry Smith head = (TRSPACE*) (((char*)ptr) - HEADER_BYTES); 644a64a8e02SBarry Smith *stack = &head->stack; 645a64a8e02SBarry Smith PetscFunctionReturn(0); 646a64a8e02SBarry Smith } 64776386721SLisandro Dalcin #else 64876386721SLisandro Dalcin PetscErrorCode PetscMallocGetStack(void *ptr,void **stack) 64976386721SLisandro Dalcin { 65076386721SLisandro Dalcin PetscFunctionBegin; 651f0ba7cfcSLisandro Dalcin *stack = NULL; 65276386721SLisandro Dalcin PetscFunctionReturn(0); 65376386721SLisandro Dalcin } 654a64a8e02SBarry Smith #endif 655a64a8e02SBarry Smith 656e5c89e4eSSatish Balay /*@C 65792f119d6SBarry Smith PetscMallocDump - Dumps the currently allocated memory blocks to a file. The information 658e5c89e4eSSatish Balay printed is: size of space (in bytes), address of space, id of space, 659e5c89e4eSSatish Balay file in which space was allocated, and line number at which it was 660e5c89e4eSSatish Balay allocated. 661e5c89e4eSSatish Balay 66292f119d6SBarry Smith Not Collective 663e5c89e4eSSatish Balay 664e5c89e4eSSatish Balay Input Parameter: 665e5c89e4eSSatish Balay . fp - file pointer. If fp is NULL, stdout is assumed. 666e5c89e4eSSatish Balay 667e5c89e4eSSatish Balay Options Database Key: 66892f119d6SBarry Smith . -malloc_dump <optional filename> - Dumps unfreed memory during call to PetscFinalize() 669e5c89e4eSSatish Balay 670e5c89e4eSSatish Balay Level: intermediate 671e5c89e4eSSatish Balay 672e5c89e4eSSatish Balay Fortran Note: 673e5c89e4eSSatish Balay The calling sequence in Fortran is PetscMallocDump(integer ierr) 674e5c89e4eSSatish Balay The fp defaults to stdout. 675e5c89e4eSSatish Balay 67695452b02SPatrick Sanan Notes: 67792f119d6SBarry Smith Uses MPI_COMM_WORLD to display rank, because this may be called in PetscFinalize() after PETSC_COMM_WORLD has been freed. 678e5c89e4eSSatish Balay 67992f119d6SBarry Smith When called in PetscFinalize() dumps only the allocations that have not been properly freed 68092f119d6SBarry Smith 68192f119d6SBarry Smith PetscMallocView() prints a list of all memory ever allocated 68292f119d6SBarry Smith 68392f119d6SBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocView(), PetscMallocViewSet() 684e5c89e4eSSatish Balay @*/ 6857087cfbeSBarry Smith PetscErrorCode PetscMallocDump(FILE *fp) 686e5c89e4eSSatish Balay { 687e5c89e4eSSatish Balay TRSPACE *head; 688e3ed9ee7SBarry Smith size_t libAlloc = 0; 689e5c89e4eSSatish Balay PetscErrorCode ierr; 690e5c89e4eSSatish Balay PetscMPIInt rank; 691e5c89e4eSSatish Balay 692e5c89e4eSSatish Balay PetscFunctionBegin; 693e5c89e4eSSatish Balay ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr); 694da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 695e5c89e4eSSatish Balay head = TRhead; 696e5c89e4eSSatish Balay while (head) { 6975486ca60SMatthew G. Knepley libAlloc += head->size; 6985486ca60SMatthew G. Knepley head = head->next; 6995486ca60SMatthew G. Knepley } 7005486ca60SMatthew G. Knepley if (TRallocated - libAlloc > 0) fprintf(fp,"[%d]Total space allocated %.0f bytes\n",rank,(PetscLogDouble)TRallocated); 7015486ca60SMatthew G. Knepley head = TRhead; 7025486ca60SMatthew G. Knepley while (head) { 7035486ca60SMatthew G. Knepley PetscBool isLib; 7045486ca60SMatthew G. Knepley 7055486ca60SMatthew G. Knepley ierr = PetscStrcmp(head->functionname, "PetscDLLibraryOpen", &isLib);CHKERRQ(ierr); 7065486ca60SMatthew G. Knepley if (!isLib) { 707efca3c55SSatish Balay fprintf(fp,"[%2d]%.0f bytes %s() line %d in %s\n",rank,(PetscLogDouble)head->size,head->functionname,head->lineno,head->filename); 7088bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 709e5c89e4eSSatish Balay ierr = PetscStackPrint(&head->stack,fp);CHKERRQ(ierr); 710e5c89e4eSSatish Balay #endif 7115486ca60SMatthew G. Knepley } 712e5c89e4eSSatish Balay head = head->next; 713e5c89e4eSSatish Balay } 714e5c89e4eSSatish Balay PetscFunctionReturn(0); 715e5c89e4eSSatish Balay } 716e5c89e4eSSatish Balay 717dc37d89fSBarry Smith /*@ 71892f119d6SBarry Smith PetscMallocViewSet - Activates logging of all calls to PetscMalloc() with a minimum size to view 719574034a9SJed Brown 720574034a9SJed Brown Not Collective 721574034a9SJed Brown 722574034a9SJed Brown Input Arguments: 723574034a9SJed Brown . logmin - minimum allocation size to log, or PETSC_DEFAULT 724574034a9SJed Brown 725574034a9SJed Brown Options Database Key: 72692f119d6SBarry Smith + -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize() 72792f119d6SBarry Smith - -malloc_view_threshold <min> - Sets a minimum size if -malloc_view is used 728574034a9SJed Brown 729574034a9SJed Brown Level: advanced 730574034a9SJed Brown 73192f119d6SBarry Smith Notes: Must be called after PetscMallocSetDebug() 73292f119d6SBarry Smith 73392f119d6SBarry Smith Uses MPI_COMM_WORLD to determine rank because PETSc communicators may not be available 73492f119d6SBarry Smith 73592f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocViewSet() 736574034a9SJed Brown @*/ 73792f119d6SBarry Smith PetscErrorCode PetscMallocViewSet(PetscLogDouble logmin) 738574034a9SJed Brown { 739574034a9SJed Brown PetscErrorCode ierr; 740574034a9SJed Brown 741574034a9SJed Brown PetscFunctionBegin; 74292f119d6SBarry Smith PetscLogMalloc = 0; 74392f119d6SBarry Smith ierr = PetscMemorySetGetMaximumUsage();CHKERRQ(ierr); 744574034a9SJed Brown if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */ 745574034a9SJed Brown PetscLogMallocThreshold = (size_t)logmin; 746574034a9SJed Brown PetscFunctionReturn(0); 747574034a9SJed Brown } 748574034a9SJed Brown 749dc37d89fSBarry Smith /*@ 75092f119d6SBarry Smith PetscMallocViewGet - Determine whether all calls to PetscMalloc() are being logged 75118a2528dSJed Brown 75218a2528dSJed Brown Not Collective 75318a2528dSJed Brown 75418a2528dSJed Brown Output Arguments 75518a2528dSJed Brown . logging - PETSC_TRUE if logging is active 75618a2528dSJed Brown 75718a2528dSJed Brown Options Database Key: 75892f119d6SBarry Smith . -malloc_view <optional filename> - Activates PetscMallocView() 75918a2528dSJed Brown 76018a2528dSJed Brown Level: advanced 76118a2528dSJed Brown 76292f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView() 76318a2528dSJed Brown @*/ 76492f119d6SBarry Smith PetscErrorCode PetscMallocViewGet(PetscBool *logging) 76518a2528dSJed Brown { 76618a2528dSJed Brown 76718a2528dSJed Brown PetscFunctionBegin; 76818a2528dSJed Brown *logging = (PetscBool)(PetscLogMalloc >= 0); 76918a2528dSJed Brown PetscFunctionReturn(0); 77018a2528dSJed Brown } 77118a2528dSJed Brown 772e5c89e4eSSatish Balay /*@C 77392f119d6SBarry Smith PetscMallocView - Saves the log of all calls to PetscMalloc(); also calls 77421b680ceSJed Brown PetscMemoryGetMaximumUsage() 775e5c89e4eSSatish Balay 77692f119d6SBarry Smith Not Collective 777e5c89e4eSSatish Balay 778e5c89e4eSSatish Balay Input Parameter: 7790298fd71SBarry Smith . fp - file pointer; or NULL 780e5c89e4eSSatish Balay 781e5c89e4eSSatish Balay Options Database Key: 78292f119d6SBarry Smith . -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize() 783e5c89e4eSSatish Balay 784e5c89e4eSSatish Balay Level: advanced 785e5c89e4eSSatish Balay 786e5c89e4eSSatish Balay Fortran Note: 78792f119d6SBarry Smith The calling sequence in Fortran is PetscMallocView(integer ierr) 788e5c89e4eSSatish Balay The fp defaults to stdout. 789e5c89e4eSSatish Balay 79092f119d6SBarry Smith Notes: 79192f119d6SBarry Smith PetscMallocDump() dumps only the currently unfreed memory, this dumps all memory ever allocated 79292f119d6SBarry Smith 79392f119d6SBarry Smith PetscMemoryView() gives a brief summary of current memory usage 79492f119d6SBarry Smith 79592f119d6SBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocDump(), PetscMallocViewSet(), PetscMemoryView() 796e5c89e4eSSatish Balay @*/ 79792f119d6SBarry Smith PetscErrorCode PetscMallocView(FILE *fp) 798e5c89e4eSSatish Balay { 79992f119d6SBarry Smith PetscInt i,j,n,*perm; 800e5c89e4eSSatish Balay size_t *shortlength; 801f56c2debSBarry Smith int *shortcount,err; 80292f119d6SBarry Smith PetscMPIInt rank; 803ace3abfcSBarry Smith PetscBool match; 804e5c89e4eSSatish Balay const char **shortfunction; 805e5c89e4eSSatish Balay PetscLogDouble rss; 806e5c89e4eSSatish Balay PetscErrorCode ierr; 807e5c89e4eSSatish Balay 808e5c89e4eSSatish Balay PetscFunctionBegin; 809e5c89e4eSSatish Balay ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr); 810f56c2debSBarry Smith err = fflush(fp); 811e32f2f54SBarry Smith if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 812f56c2debSBarry Smith 813*79dccf82SBarry Smith 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()"); 814768aa557SSatish Balay 815da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 816f3d65365SJed Brown ierr = PetscMemoryGetMaximumUsage(&rss);CHKERRQ(ierr); 817e5c89e4eSSatish Balay if (rss) { 81892f119d6SBarry Smith (void) fprintf(fp,"[%d] Maximum memory PetscMalloc()ed %.0f maximum size of entire process %.0f\n",rank,(PetscLogDouble)TRMaxMem,rss); 819e5c89e4eSSatish Balay } else { 82092f119d6SBarry Smith (void) fprintf(fp,"[%d] Maximum memory PetscMalloc()ed %.0f OS cannot compute size of entire process\n",rank,(PetscLogDouble)TRMaxMem); 821e5c89e4eSSatish Balay } 822e32f2f54SBarry Smith shortcount = (int*)malloc(PetscLogMalloc*sizeof(int));if (!shortcount) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 823e32f2f54SBarry Smith shortlength = (size_t*)malloc(PetscLogMalloc*sizeof(size_t));if (!shortlength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 824e32f2f54SBarry Smith shortfunction = (const char**)malloc(PetscLogMalloc*sizeof(char*));if (!shortfunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 82597b9d747SJed Brown for (i=0,n=0; i<PetscLogMalloc; i++) { 826e5c89e4eSSatish Balay for (j=0; j<n; j++) { 827e5c89e4eSSatish Balay ierr = PetscStrcmp(shortfunction[j],PetscLogMallocFunction[i],&match);CHKERRQ(ierr); 828e5c89e4eSSatish Balay if (match) { 829e5c89e4eSSatish Balay shortlength[j] += PetscLogMallocLength[i]; 83059ffdab8SBarry Smith shortcount[j]++; 831e5c89e4eSSatish Balay goto foundit; 832e5c89e4eSSatish Balay } 833e5c89e4eSSatish Balay } 834e5c89e4eSSatish Balay shortfunction[n] = PetscLogMallocFunction[i]; 835e5c89e4eSSatish Balay shortlength[n] = PetscLogMallocLength[i]; 83659ffdab8SBarry Smith shortcount[n] = 1; 837e5c89e4eSSatish Balay n++; 838e5c89e4eSSatish Balay foundit:; 839e5c89e4eSSatish Balay } 840e5c89e4eSSatish Balay 841e32f2f54SBarry Smith perm = (PetscInt*)malloc(n*sizeof(PetscInt));if (!perm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 842e5c89e4eSSatish Balay for (i=0; i<n; i++) perm[i] = i; 843e5c89e4eSSatish Balay ierr = PetscSortStrWithPermutation(n,(const char**)shortfunction,perm);CHKERRQ(ierr); 844e5c89e4eSSatish Balay 84592f119d6SBarry Smith (void) fprintf(fp,"[%d] Memory usage sorted by function\n",rank); 846e5c89e4eSSatish Balay for (i=0; i<n; i++) { 84792f119d6SBarry Smith (void) fprintf(fp,"[%d] %d %.0f %s()\n",rank,shortcount[perm[i]],(PetscLogDouble)shortlength[perm[i]],shortfunction[perm[i]]); 848e5c89e4eSSatish Balay } 849e5c89e4eSSatish Balay free(perm); 850e5c89e4eSSatish Balay free(shortlength); 85159ffdab8SBarry Smith free(shortcount); 852e5c89e4eSSatish Balay free((char**)shortfunction); 853f56c2debSBarry Smith err = fflush(fp); 854e32f2f54SBarry Smith if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 855e5c89e4eSSatish Balay PetscFunctionReturn(0); 856e5c89e4eSSatish Balay } 857e5c89e4eSSatish Balay 858e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------- */ 859e5c89e4eSSatish Balay 860dc37d89fSBarry Smith /*@ 86192f119d6SBarry Smith PetscMallocSetDebug - Set's PETSc memory debugging 862e5c89e4eSSatish Balay 863e5c89e4eSSatish Balay Not Collective 864e5c89e4eSSatish Balay 865e5c89e4eSSatish Balay Input Parameter: 86692f119d6SBarry Smith + eachcall - checks the entire heap of allocated memory for issues on each call to PetscMalloc() and PetscFree() 867*79dccf82SBarry Smith - intializenan - initializes all memory with NaN to catch use of unintialized floating point arrays 868e5c89e4eSSatish Balay 86992f119d6SBarry Smith Options Database: 870*79dccf82SBarry Smith + -malloc_debug <true or false> - turns on or off debugging 87192f119d6SBarry Smith . -malloc_test - turns on all debugging if PETSc was configured with debugging including -malloc_dump, otherwise ignored 872*79dccf82SBarry Smith . -malloc_view_threshold t - log only allocations larger than t 87392f119d6SBarry Smith . -malloc_dump <filename> - print a list of all memory that has not been freed 874*79dccf82SBarry Smith . -malloc no - (deprecated) same as -malloc_debug no 875*79dccf82SBarry Smith - -malloc_log - (deprecated) same as -malloc_view 876e5c89e4eSSatish Balay 87792f119d6SBarry Smith Level: developer 87892f119d6SBarry Smith 87992f119d6SBarry Smith Notes: This is called in PetscInitialize() and should not be called elsewhere 88092f119d6SBarry Smith 88192f119d6SBarry Smith .seealso: CHKMEMQ(), PetscMallocValidate(), PetscMallocGetDebug() 882e5c89e4eSSatish Balay @*/ 88392f119d6SBarry Smith PetscErrorCode PetscMallocSetDebug(PetscBool eachcall, PetscBool initializenan) 884e5c89e4eSSatish Balay { 88592f119d6SBarry Smith PetscErrorCode ierr; 88692f119d6SBarry Smith 887e5c89e4eSSatish Balay PetscFunctionBegin; 88892f119d6SBarry Smith 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()"); 88992f119d6SBarry Smith ierr = PetscMallocSet(PetscTrMallocDefault,PetscTrFreeDefault,PetscTrReallocDefault);CHKERRQ(ierr); 89092f119d6SBarry Smith 89192f119d6SBarry Smith TRallocated = 0; 89292f119d6SBarry Smith TRfrags = 0; 89392f119d6SBarry Smith TRhead = NULL; 89492f119d6SBarry Smith TRid = 0; 89592f119d6SBarry Smith TRdebugLevel = eachcall; 89692f119d6SBarry Smith TRMaxMem = 0; 89792f119d6SBarry Smith PetscLogMallocMax = 10000; 89892f119d6SBarry Smith PetscLogMalloc = -1; 89992f119d6SBarry Smith TRdebugIintializenan = initializenan; 900e5c89e4eSSatish Balay PetscFunctionReturn(0); 901e5c89e4eSSatish Balay } 9020acecf5bSBarry Smith 903dc37d89fSBarry Smith /*@ 90492f119d6SBarry Smith PetscMallocGetDebug - Indicates what PETSc memory debugging it is doing. 9050acecf5bSBarry Smith 9060acecf5bSBarry Smith Not Collective 9070acecf5bSBarry Smith 90892f119d6SBarry Smith Output Parameters: 90992f119d6SBarry Smith + basic - doing basic debugging 91092f119d6SBarry Smith . eachcall - checks the entire memory heap at each PetscMalloc()/PetscFree() 911*79dccf82SBarry Smith - initializenan - initializes memory with NaN 9120acecf5bSBarry Smith 9130acecf5bSBarry Smith Level: intermediate 9140acecf5bSBarry Smith 91592f119d6SBarry Smith Notes: 916*79dccf82SBarry Smith By default, the debug version always does some debugging unless you run with -malloc_debug no 9170acecf5bSBarry Smith 91892f119d6SBarry Smith .seealso: CHKMEMQ(), PetscMallocValidate(), PetscMallocSetDebug() 9190acecf5bSBarry Smith @*/ 92092f119d6SBarry Smith PetscErrorCode PetscMallocGetDebug(PetscBool *basic, PetscBool *eachcall, PetscBool *initializenan) 9210acecf5bSBarry Smith { 9220acecf5bSBarry Smith PetscFunctionBegin; 923*79dccf82SBarry Smith if (basic) *basic = (PetscTrMalloc == PetscTrMallocDefault) ? PETSC_TRUE : PETSC_FALSE; 924*79dccf82SBarry Smith if (eachcall) *eachcall = TRdebugLevel; 925*79dccf82SBarry Smith if (initializenan) *initializenan = TRdebugIintializenan; 9260acecf5bSBarry Smith PetscFunctionReturn(0); 9270acecf5bSBarry Smith } 928