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; 542d4ee042Sprj- static PetscBool TRdebugIinitializenan= 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: 8979dccf82SBarry 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; 112*2cba8197SMatthew G. Knepley if (head && head->prev) { 113*2cba8197SMatthew G. Knepley (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 114*2cba8197SMatthew G. Knepley (*PetscErrorPrintf)("Root memory header %p has invalid back pointer %p\n",head,head->prev); 115*2cba8197SMatthew G. Knepley } 116e5c89e4eSSatish Balay while (head) { 1170700a824SBarry Smith if (head->classid != CLASSID_VALUE) { 118efca3c55SSatish Balay (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 119e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory at address %p is corrupted\n",head); 120e5c89e4eSSatish Balay (*PetscErrorPrintf)("Probably write past beginning or end of array\n"); 121efca3c55SSatish Balay if (lasthead) (*PetscErrorPrintf)("Last intact block allocated in %s() line %d in %s\n",lasthead->functionname,lasthead->lineno,lasthead->filename); 122e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 123e5c89e4eSSatish Balay } 124e5c89e4eSSatish Balay a = (char*)(((TrSPACE*)head) + 1); 1250700a824SBarry Smith nend = (PetscClassId*)(a + head->size); 1260700a824SBarry Smith if (*nend != CLASSID_VALUE) { 127efca3c55SSatish Balay (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 128e5c89e4eSSatish Balay if (*nend == ALREADY_FREED) { 129e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p already freed\n",head->id,(PetscLogDouble)head->size,a); 130e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 131e5c89e4eSSatish Balay } else { 132e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 133efca3c55SSatish Balay (*PetscErrorPrintf)("Memory originally allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 134e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 135e5c89e4eSSatish Balay } 136e5c89e4eSSatish Balay } 137*2cba8197SMatthew G. Knepley if (head->prev && head->prev != lasthead) { 138*2cba8197SMatthew G. Knepley (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 139*2cba8197SMatthew G. Knepley (*PetscErrorPrintf)("Backpointer %p is invalid, should be %p\n",head->prev,lasthead); 140*2cba8197SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 141*2cba8197SMatthew G. Knepley } 142*2cba8197SMatthew G. Knepley if (head->next && head != head->next->prev) { 143*2cba8197SMatthew G. Knepley (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 144*2cba8197SMatthew G. Knepley (*PetscErrorPrintf)("Next memory header %p has invalid back pointer %p, should be %p\n",head->next,head->next->prev,head); 145*2cba8197SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 146*2cba8197SMatthew G. Knepley } 1476c093d5bSvictor lasthead = head; 148e5c89e4eSSatish Balay head = head->next; 149e5c89e4eSSatish Balay } 150e5c89e4eSSatish Balay PetscFunctionReturn(0); 151e5c89e4eSSatish Balay } 152e5c89e4eSSatish Balay 153e5c89e4eSSatish Balay /* 154e5c89e4eSSatish Balay PetscTrMallocDefault - Malloc with tracing. 155e5c89e4eSSatish Balay 156e5c89e4eSSatish Balay Input Parameters: 157e5c89e4eSSatish Balay + a - number of bytes to allocate 158e5c89e4eSSatish Balay . lineno - line number where used. Use __LINE__ for this 159efca3c55SSatish Balay - filename - file name where used. Use __FILE__ for this 160e5c89e4eSSatish Balay 161e5c89e4eSSatish Balay Returns: 16292f119d6SBarry Smith double aligned pointer to requested storage, or null if not available. 163e5c89e4eSSatish Balay */ 164071fcb05SBarry Smith PetscErrorCode PetscTrMallocDefault(size_t a,PetscBool clear,int lineno,const char function[],const char filename[],void **result) 165e5c89e4eSSatish Balay { 166e5c89e4eSSatish Balay TRSPACE *head; 167e5c89e4eSSatish Balay char *inew; 168e5c89e4eSSatish Balay size_t nsize; 169e5c89e4eSSatish Balay PetscErrorCode ierr; 170e5c89e4eSSatish Balay 171e5c89e4eSSatish Balay PetscFunctionBegin; 172f0ba7cfcSLisandro Dalcin /* Do not try to handle empty blocks */ 173f0ba7cfcSLisandro Dalcin if (!a) { *result = NULL; PetscFunctionReturn(0); } 174f0ba7cfcSLisandro Dalcin 175efca3c55SSatish Balay ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr); 176e5c89e4eSSatish Balay 17725b53cc9SJed Brown nsize = (a + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1); 178071fcb05SBarry Smith ierr = PetscMallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),clear,lineno,function,filename,(void**)&inew);CHKERRQ(ierr); 179e3ed9ee7SBarry Smith 180e5c89e4eSSatish Balay head = (TRSPACE*)inew; 181e5c89e4eSSatish Balay inew += sizeof(TrSPACE); 182e5c89e4eSSatish Balay 183e5c89e4eSSatish Balay if (TRhead) TRhead->prev = head; 184e5c89e4eSSatish Balay head->next = TRhead; 185e5c89e4eSSatish Balay TRhead = head; 186f0ba7cfcSLisandro Dalcin head->prev = NULL; 187e5c89e4eSSatish Balay head->size = nsize; 188e5c89e4eSSatish Balay head->id = TRid; 189e5c89e4eSSatish Balay head->lineno = lineno; 190e5c89e4eSSatish Balay 191e5c89e4eSSatish Balay head->filename = filename; 192e5c89e4eSSatish Balay head->functionname = function; 1930700a824SBarry Smith head->classid = CLASSID_VALUE; 1940700a824SBarry Smith *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 195e5c89e4eSSatish Balay 196e5c89e4eSSatish Balay TRallocated += nsize; 197a297a907SKarl Rupp if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 198e3ed9ee7SBarry Smith if (PetscLogMemory) { 199e3ed9ee7SBarry Smith PetscInt i; 200e3ed9ee7SBarry Smith for (i=0; i<NumTRMaxMems; i++) { 201e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 202e3ed9ee7SBarry Smith } 203e3ed9ee7SBarry Smith } 204e5c89e4eSSatish Balay TRfrags++; 205e5c89e4eSSatish Balay 2068bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 20776386721SLisandro Dalcin if (PetscStackActive()) { 2085c25fcd7SBarry Smith ierr = PetscStackCopy(petscstack,&head->stack);CHKERRQ(ierr); 2092c9581d2SBarry Smith /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 2102c9581d2SBarry Smith head->stack.line[head->stack.currentsize-2] = lineno; 2119de0f6ecSBarry Smith } else { 2129de0f6ecSBarry Smith head->stack.currentsize = 0; 21376386721SLisandro Dalcin } 21492f119d6SBarry Smith #if defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL_DOUBLE) 2152d4ee042Sprj- if (!clear && TRdebugIinitializenan) { 21692f119d6SBarry Smith size_t i, n = a/sizeof(PetscReal); 21792f119d6SBarry Smith PetscReal *s = (PetscReal*) inew; 21892f119d6SBarry Smith /* from https://www.doc.ic.ac.uk/~eedwards/compsys/float/nan.html */ 21992f119d6SBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 220df282883SBarry Smith int nas = 0x7F800002; 22192f119d6SBarry Smith #else 22292f119d6SBarry Smith PetscInt64 nas = 0x7FF0000000000002; 22392f119d6SBarry Smith #endif 22492f119d6SBarry Smith for (i=0; i<n; i++) { 22592f119d6SBarry Smith memcpy(s+i,&nas,sizeof(PetscReal)); 22692f119d6SBarry Smith } 22792f119d6SBarry Smith } 22892f119d6SBarry Smith #endif 229e5c89e4eSSatish Balay #endif 230e5c89e4eSSatish Balay 231e5c89e4eSSatish Balay /* 23292f119d6SBarry Smith Allow logging of all mallocs made. 23392f119d6SBarry Smith TODO: Currently this memory is never freed, it should be freed during PetscFinalize() 234e5c89e4eSSatish Balay */ 235574034a9SJed Brown if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && a >= PetscLogMallocThreshold) { 236e5c89e4eSSatish Balay if (!PetscLogMalloc) { 237e5c89e4eSSatish Balay PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 238e32f2f54SBarry Smith if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 239a297a907SKarl Rupp 240a2ea699eSBarry Smith PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 241e32f2f54SBarry Smith if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 242a297a907SKarl Rupp 243a2ea699eSBarry Smith PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 244e32f2f54SBarry Smith if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 245e5c89e4eSSatish Balay } 246e5c89e4eSSatish Balay PetscLogMallocLength[PetscLogMalloc] = nsize; 247e5c89e4eSSatish Balay PetscLogMallocFile[PetscLogMalloc] = filename; 248e5c89e4eSSatish Balay PetscLogMallocFunction[PetscLogMalloc++] = function; 249e5c89e4eSSatish Balay } 250e5c89e4eSSatish Balay *result = (void*)inew; 251e5c89e4eSSatish Balay PetscFunctionReturn(0); 252e5c89e4eSSatish Balay } 253e5c89e4eSSatish Balay 254e5c89e4eSSatish Balay /* 255e5c89e4eSSatish Balay PetscTrFreeDefault - Free with tracing. 256e5c89e4eSSatish Balay 257e5c89e4eSSatish Balay Input Parameters: 258e5c89e4eSSatish Balay . a - pointer to a block allocated with PetscTrMalloc 259e5c89e4eSSatish Balay . lineno - line number where used. Use __LINE__ for this 260e5c89e4eSSatish Balay . file - file name where used. Use __FILE__ for this 261e5c89e4eSSatish Balay */ 262efca3c55SSatish Balay PetscErrorCode PetscTrFreeDefault(void *aa,int line,const char function[],const char file[]) 263e5c89e4eSSatish Balay { 264e5c89e4eSSatish Balay char *a = (char*)aa; 265e5c89e4eSSatish Balay TRSPACE *head; 266e5c89e4eSSatish Balay char *ahead; 267e5c89e4eSSatish Balay PetscErrorCode ierr; 2680700a824SBarry Smith PetscClassId *nend; 269e5c89e4eSSatish Balay 270e5c89e4eSSatish Balay PetscFunctionBegin; 271e5c89e4eSSatish Balay /* Do not try to handle empty blocks */ 27249d7da52SJed Brown if (!a) PetscFunctionReturn(0); 273e5c89e4eSSatish Balay 274efca3c55SSatish Balay ierr = PetscMallocValidate(line,function,file);CHKERRQ(ierr); 275e5c89e4eSSatish Balay 276e5c89e4eSSatish Balay ahead = a; 277e5c89e4eSSatish Balay a = a - sizeof(TrSPACE); 278e5c89e4eSSatish Balay head = (TRSPACE*)a; 279e5c89e4eSSatish Balay 2800700a824SBarry Smith if (head->classid != CLASSID_VALUE) { 281efca3c55SSatish Balay (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); 282e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 283e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); 284e5c89e4eSSatish Balay } 2850700a824SBarry Smith nend = (PetscClassId*)(ahead + head->size); 2860700a824SBarry Smith if (*nend != CLASSID_VALUE) { 287e5c89e4eSSatish Balay if (*nend == ALREADY_FREED) { 288efca3c55SSatish Balay (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); 289e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 290e5c89e4eSSatish Balay if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 291efca3c55SSatish Balay (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 292e5c89e4eSSatish Balay } else { 293efca3c55SSatish Balay (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename); 294e5c89e4eSSatish Balay } 295e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); 296e5c89e4eSSatish Balay } else { 297e5c89e4eSSatish Balay /* Damaged tail */ 298efca3c55SSatish Balay (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); 299e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 300efca3c55SSatish Balay (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 301e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); 302e5c89e4eSSatish Balay } 303e5c89e4eSSatish Balay } 304e5c89e4eSSatish Balay /* Mark the location freed */ 305e5c89e4eSSatish Balay *nend = ALREADY_FREED; 306e5c89e4eSSatish Balay /* Save location where freed. If we suspect the line number, mark as allocated location */ 307e5c89e4eSSatish Balay if (line > 0 && line < 50000) { 308e5c89e4eSSatish Balay head->lineno = line; 309e5c89e4eSSatish Balay head->filename = file; 310e5c89e4eSSatish Balay head->functionname = function; 311e5c89e4eSSatish Balay } else { 312e5c89e4eSSatish Balay head->lineno = -head->lineno; 313e5c89e4eSSatish Balay } 314e3ed9ee7SBarry Smith if (TRallocated < head->size) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"TRallocate is smaller than memory just freed"); 315e5c89e4eSSatish Balay TRallocated -= head->size; 316e5c89e4eSSatish Balay TRfrags--; 317e5c89e4eSSatish Balay if (head->prev) head->prev->next = head->next; 318e5c89e4eSSatish Balay else TRhead = head->next; 319e5c89e4eSSatish Balay 320e5c89e4eSSatish Balay if (head->next) head->next->prev = head->prev; 321efca3c55SSatish Balay ierr = PetscFreeAlign(a,line,function,file);CHKERRQ(ierr); 322e5c89e4eSSatish Balay PetscFunctionReturn(0); 323e5c89e4eSSatish Balay } 324e5c89e4eSSatish Balay 3253221ece2SMatthew G. Knepley /* 3263221ece2SMatthew G. Knepley PetscTrReallocDefault - Realloc with tracing. 3273221ece2SMatthew G. Knepley 3283221ece2SMatthew G. Knepley Input Parameters: 3293221ece2SMatthew G. Knepley + len - number of bytes to allocate 3303221ece2SMatthew G. Knepley . lineno - line number where used. Use __LINE__ for this 3313221ece2SMatthew G. Knepley . filename - file name where used. Use __FILE__ for this 33292f119d6SBarry Smith - result - original memory 3333221ece2SMatthew G. Knepley 3343221ece2SMatthew G. Knepley Output Parameter: 3353221ece2SMatthew G. Knepley . result - double aligned pointer to requested storage, or null if not available. 3363221ece2SMatthew G. Knepley 3373221ece2SMatthew G. Knepley Level: developer 3383221ece2SMatthew G. Knepley 3393221ece2SMatthew G. Knepley .seealso: PetscTrMallocDefault(), PetscTrFreeDefault() 3403221ece2SMatthew G. Knepley */ 3413221ece2SMatthew G. Knepley PetscErrorCode PetscTrReallocDefault(size_t len, int lineno, const char function[], const char filename[], void **result) 3423221ece2SMatthew G. Knepley { 3433221ece2SMatthew G. Knepley char *a = (char *) *result; 3443221ece2SMatthew G. Knepley TRSPACE *head; 3453221ece2SMatthew G. Knepley char *ahead, *inew; 3463221ece2SMatthew G. Knepley PetscClassId *nend; 3473221ece2SMatthew G. Knepley size_t nsize; 3483221ece2SMatthew G. Knepley PetscErrorCode ierr; 3493221ece2SMatthew G. Knepley 3503221ece2SMatthew G. Knepley PetscFunctionBegin; 35192f119d6SBarry Smith /* Realloc requests zero space so just free the current space */ 352c22f1541SToby Isaac if (!len) { 353c22f1541SToby Isaac ierr = PetscTrFreeDefault(*result,lineno,function,filename);CHKERRQ(ierr); 354c22f1541SToby Isaac *result = NULL; 355c22f1541SToby Isaac PetscFunctionReturn(0); 356c22f1541SToby Isaac } 35792f119d6SBarry Smith /* If the orginal space was NULL just use the regular malloc() */ 358f590eff4SLisandro Dalcin if (!*result) { 359071fcb05SBarry Smith ierr = PetscTrMallocDefault(len,PETSC_FALSE,lineno,function,filename,result);CHKERRQ(ierr); 360f590eff4SLisandro Dalcin PetscFunctionReturn(0); 361f590eff4SLisandro Dalcin } 3623221ece2SMatthew G. Knepley 36338548759SBarry Smith ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr); 3643221ece2SMatthew G. Knepley 3653221ece2SMatthew G. Knepley ahead = a; 3663221ece2SMatthew G. Knepley a = a - sizeof(TrSPACE); 3673221ece2SMatthew G. Knepley head = (TRSPACE *) a; 3683221ece2SMatthew G. Knepley inew = a; 3693221ece2SMatthew G. Knepley 3703221ece2SMatthew G. Knepley if (head->classid != CLASSID_VALUE) { 3713221ece2SMatthew G. Knepley (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename); 3723221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 3733221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); 3743221ece2SMatthew G. Knepley } 3753221ece2SMatthew G. Knepley nend = (PetscClassId *)(ahead + head->size); 3763221ece2SMatthew G. Knepley if (*nend != CLASSID_VALUE) { 3773221ece2SMatthew G. Knepley if (*nend == ALREADY_FREED) { 3783221ece2SMatthew G. Knepley (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename); 3793221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 3803221ece2SMatthew G. Knepley if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 3813221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 3823221ece2SMatthew G. Knepley } else { 3833221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename); 3843221ece2SMatthew G. Knepley } 3853221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); 3863221ece2SMatthew G. Knepley } else { 3873221ece2SMatthew G. Knepley /* Damaged tail */ 3883221ece2SMatthew G. Knepley (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename); 3893221ece2SMatthew 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); 3903221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 3913221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); 3923221ece2SMatthew G. Knepley } 3933221ece2SMatthew G. Knepley } 3943221ece2SMatthew G. Knepley 39592f119d6SBarry Smith /* remove original reference to the memory allocated from the PETSc debugging heap */ 3963221ece2SMatthew G. Knepley TRallocated -= head->size; 3973221ece2SMatthew G. Knepley TRfrags--; 3983221ece2SMatthew G. Knepley if (head->prev) head->prev->next = head->next; 3993221ece2SMatthew G. Knepley else TRhead = head->next; 4003221ece2SMatthew G. Knepley if (head->next) head->next->prev = head->prev; 4013221ece2SMatthew G. Knepley 4023221ece2SMatthew G. Knepley nsize = (len + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1); 4033221ece2SMatthew G. Knepley ierr = PetscReallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),lineno,function,filename,(void**)&inew);CHKERRQ(ierr); 4043221ece2SMatthew G. Knepley 4053221ece2SMatthew G. Knepley head = (TRSPACE*)inew; 4063221ece2SMatthew G. Knepley inew += sizeof(TrSPACE); 4073221ece2SMatthew G. Knepley 4083221ece2SMatthew G. Knepley if (TRhead) TRhead->prev = head; 4093221ece2SMatthew G. Knepley head->next = TRhead; 4103221ece2SMatthew G. Knepley TRhead = head; 4113221ece2SMatthew G. Knepley head->prev = NULL; 4123221ece2SMatthew G. Knepley head->size = nsize; 4133221ece2SMatthew G. Knepley head->id = TRid; 4143221ece2SMatthew G. Knepley head->lineno = lineno; 4153221ece2SMatthew G. Knepley 4163221ece2SMatthew G. Knepley head->filename = filename; 4173221ece2SMatthew G. Knepley head->functionname = function; 4183221ece2SMatthew G. Knepley head->classid = CLASSID_VALUE; 4193221ece2SMatthew G. Knepley *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 4203221ece2SMatthew G. Knepley 4213221ece2SMatthew G. Knepley TRallocated += nsize; 4223221ece2SMatthew G. Knepley if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 423e3ed9ee7SBarry Smith if (PetscLogMemory) { 424e3ed9ee7SBarry Smith PetscInt i; 425e3ed9ee7SBarry Smith for (i=0; i<NumTRMaxMems; i++) { 426e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 427e3ed9ee7SBarry Smith } 428e3ed9ee7SBarry Smith } 4293221ece2SMatthew G. Knepley TRfrags++; 4303221ece2SMatthew G. Knepley 4313221ece2SMatthew G. Knepley #if defined(PETSC_USE_DEBUG) 4323221ece2SMatthew G. Knepley if (PetscStackActive()) { 4333221ece2SMatthew G. Knepley ierr = PetscStackCopy(petscstack,&head->stack);CHKERRQ(ierr); 4343221ece2SMatthew G. Knepley /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 4353221ece2SMatthew G. Knepley head->stack.line[head->stack.currentsize-2] = lineno; 4363221ece2SMatthew G. Knepley } else { 4373221ece2SMatthew G. Knepley head->stack.currentsize = 0; 4383221ece2SMatthew G. Knepley } 4393221ece2SMatthew G. Knepley #endif 4403221ece2SMatthew G. Knepley 4413221ece2SMatthew G. Knepley /* 44292f119d6SBarry Smith Allow logging of all mallocs made. This adds a new entry to the list of allocated memory 44392f119d6SBarry Smith and does not remove the previous entry to the list hence this memory is "double counted" in PetscMallocView() 4443221ece2SMatthew G. Knepley */ 4453221ece2SMatthew G. Knepley if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && len >= PetscLogMallocThreshold) { 4463221ece2SMatthew G. Knepley if (!PetscLogMalloc) { 4473221ece2SMatthew G. Knepley PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 4483221ece2SMatthew G. Knepley if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4493221ece2SMatthew G. Knepley 4503221ece2SMatthew G. Knepley PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 4513221ece2SMatthew G. Knepley if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4523221ece2SMatthew G. Knepley 4533221ece2SMatthew G. Knepley PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 4543221ece2SMatthew G. Knepley if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4553221ece2SMatthew G. Knepley } 4563221ece2SMatthew G. Knepley PetscLogMallocLength[PetscLogMalloc] = nsize; 4573221ece2SMatthew G. Knepley PetscLogMallocFile[PetscLogMalloc] = filename; 4583221ece2SMatthew G. Knepley PetscLogMallocFunction[PetscLogMalloc++] = function; 4593221ece2SMatthew G. Knepley } 4603221ece2SMatthew G. Knepley *result = (void*)inew; 4613221ece2SMatthew G. Knepley PetscFunctionReturn(0); 4623221ece2SMatthew G. Knepley } 4633221ece2SMatthew G. Knepley 464fe7fb379SMatthew Knepley /*@C 46592f119d6SBarry Smith PetscMemoryView - Shows the amount of memory currently being used in a communicator. 466e5c89e4eSSatish Balay 467e5c89e4eSSatish Balay Collective on PetscViewer 468e5c89e4eSSatish Balay 469e5c89e4eSSatish Balay Input Parameter: 470e5c89e4eSSatish Balay + viewer - the viewer that defines the communicator 471e5c89e4eSSatish Balay - message - string printed before values 472e5c89e4eSSatish Balay 4730841954dSBarry Smith Options Database: 47492f119d6SBarry Smith + -malloc_debug - have PETSc track how much memory it has allocated 4750841954dSBarry Smith - -memory_view - during PetscFinalize() have this routine called 4760841954dSBarry Smith 477e5c89e4eSSatish Balay Level: intermediate 478e5c89e4eSSatish Balay 47992f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMemoryGetCurrentUsage(), PetscMemorySetGetMaximumUsage(), PetscMallocView() 480e5c89e4eSSatish Balay @*/ 4810841954dSBarry Smith PetscErrorCode PetscMemoryView(PetscViewer viewer,const char message[]) 482e5c89e4eSSatish Balay { 4830841954dSBarry Smith PetscLogDouble allocated,allocatedmax,resident,residentmax,gallocated,gallocatedmax,gresident,gresidentmax,maxgallocated,maxgallocatedmax,maxgresident,maxgresidentmax; 4840841954dSBarry Smith PetscLogDouble mingallocated,mingallocatedmax,mingresident,mingresidentmax; 485e5c89e4eSSatish Balay PetscErrorCode ierr; 486e5c89e4eSSatish Balay MPI_Comm comm; 487e5c89e4eSSatish Balay 488e5c89e4eSSatish Balay PetscFunctionBegin; 489e5c89e4eSSatish Balay if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD; 490e5c89e4eSSatish Balay ierr = PetscMallocGetCurrentUsage(&allocated);CHKERRQ(ierr); 4910841954dSBarry Smith ierr = PetscMallocGetMaximumUsage(&allocatedmax);CHKERRQ(ierr); 492e5c89e4eSSatish Balay ierr = PetscMemoryGetCurrentUsage(&resident);CHKERRQ(ierr); 493e5c89e4eSSatish Balay ierr = PetscMemoryGetMaximumUsage(&residentmax);CHKERRQ(ierr); 494e5c89e4eSSatish Balay if (residentmax > 0) residentmax = PetscMax(resident,residentmax); 495e5c89e4eSSatish Balay ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 496e5c89e4eSSatish Balay ierr = PetscViewerASCIIPrintf(viewer,message);CHKERRQ(ierr); 497e5c89e4eSSatish Balay if (resident && residentmax && allocated) { 4980841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 4990841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5000841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5010841954dSBarry 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); 5020841954dSBarry Smith ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5030841954dSBarry Smith ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5040841954dSBarry Smith ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5050841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr); 5060841954dSBarry Smith ierr = MPI_Reduce(&allocatedmax,&gallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5070841954dSBarry Smith ierr = MPI_Reduce(&allocatedmax,&maxgallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5080841954dSBarry Smith ierr = MPI_Reduce(&allocatedmax,&mingallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5090841954dSBarry 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); 5100841954dSBarry Smith ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5110841954dSBarry Smith ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5120841954dSBarry Smith ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5130841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr); 514e5c89e4eSSatish Balay } else if (resident && residentmax) { 5150841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5160841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5170841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5180841954dSBarry 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); 5190841954dSBarry Smith ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5200841954dSBarry Smith ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5210841954dSBarry Smith ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5220841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr); 523e5c89e4eSSatish Balay } else if (resident && allocated) { 5240841954dSBarry Smith ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5250841954dSBarry Smith ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5260841954dSBarry Smith ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5270841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr); 5280841954dSBarry Smith ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5290841954dSBarry Smith ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5300841954dSBarry Smith ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5310841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr); 5320841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n");CHKERRQ(ierr); 533e5c89e4eSSatish Balay } else if (allocated) { 5340841954dSBarry Smith ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5350841954dSBarry Smith ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5360841954dSBarry Smith ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5370841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr); 5380841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n");CHKERRQ(ierr); 5390841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"OS cannot compute process memory\n");CHKERRQ(ierr); 540e5c89e4eSSatish Balay } else { 54192f119d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Run with -malloc_debug to get statistics on PetscMalloc() calls\nOS cannot compute process memory\n");CHKERRQ(ierr); 542e5c89e4eSSatish Balay } 543e5c89e4eSSatish Balay ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 544e5c89e4eSSatish Balay PetscFunctionReturn(0); 545e5c89e4eSSatish Balay } 546e5c89e4eSSatish Balay 54746eb3923SBarry Smith /*@ 548e5c89e4eSSatish Balay PetscMallocGetCurrentUsage - gets the current amount of memory used that was PetscMalloc()ed 549e5c89e4eSSatish Balay 550e5c89e4eSSatish Balay Not Collective 551e5c89e4eSSatish Balay 552e5c89e4eSSatish Balay Output Parameters: 553e5c89e4eSSatish Balay . space - number of bytes currently allocated 554e5c89e4eSSatish Balay 555e5c89e4eSSatish Balay Level: intermediate 556e5c89e4eSSatish Balay 557540e20f2SPierre Jolivet .seealso: PetscMallocDump(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 558e5c89e4eSSatish Balay PetscMemoryGetMaximumUsage() 559e5c89e4eSSatish Balay @*/ 5607087cfbeSBarry Smith PetscErrorCode PetscMallocGetCurrentUsage(PetscLogDouble *space) 561e5c89e4eSSatish Balay { 562e5c89e4eSSatish Balay PetscFunctionBegin; 563e5c89e4eSSatish Balay *space = (PetscLogDouble) TRallocated; 564e5c89e4eSSatish Balay PetscFunctionReturn(0); 565e5c89e4eSSatish Balay } 566e5c89e4eSSatish Balay 567dc37d89fSBarry Smith /*@ 568e5c89e4eSSatish Balay PetscMallocGetMaximumUsage - gets the maximum amount of memory used that was PetscMalloc()ed at any time 569e5c89e4eSSatish Balay during this run. 570e5c89e4eSSatish Balay 571e5c89e4eSSatish Balay Not Collective 572e5c89e4eSSatish Balay 573e5c89e4eSSatish Balay Output Parameters: 574e5c89e4eSSatish Balay . space - maximum number of bytes ever allocated at one time 575e5c89e4eSSatish Balay 576e5c89e4eSSatish Balay Level: intermediate 577e5c89e4eSSatish Balay 57892f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 579e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage() 580e5c89e4eSSatish Balay @*/ 5817087cfbeSBarry Smith PetscErrorCode PetscMallocGetMaximumUsage(PetscLogDouble *space) 582e5c89e4eSSatish Balay { 583e5c89e4eSSatish Balay PetscFunctionBegin; 584e5c89e4eSSatish Balay *space = (PetscLogDouble) TRMaxMem; 585e5c89e4eSSatish Balay PetscFunctionReturn(0); 586e5c89e4eSSatish Balay } 587e5c89e4eSSatish Balay 588e3ed9ee7SBarry Smith /*@ 589e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage - Adds another event to collect the maximum memory usage over an event 590e3ed9ee7SBarry Smith 591e3ed9ee7SBarry Smith Not Collective 592e3ed9ee7SBarry Smith 593e3ed9ee7SBarry Smith Input Parameter: 594e3ed9ee7SBarry Smith . event - an event id; this is just for error checking 595e3ed9ee7SBarry Smith 596e3ed9ee7SBarry Smith Level: developer 597e3ed9ee7SBarry Smith 59892f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 599e3ed9ee7SBarry Smith PetscMallocPopMaximumUsage() 600e3ed9ee7SBarry Smith @*/ 601e3ed9ee7SBarry Smith PetscErrorCode PetscMallocPushMaximumUsage(int event) 602e3ed9ee7SBarry Smith { 603e3ed9ee7SBarry Smith PetscFunctionBegin; 604e3ed9ee7SBarry Smith if (++NumTRMaxMems > MAXTRMAXMEMS) PetscFunctionReturn(0); 605e3ed9ee7SBarry Smith TRMaxMems[NumTRMaxMems-1] = TRallocated; 606e3ed9ee7SBarry Smith TRMaxMemsEvents[NumTRMaxMems-1] = event; 607e3ed9ee7SBarry Smith PetscFunctionReturn(0); 608e3ed9ee7SBarry Smith } 609e3ed9ee7SBarry Smith 610e3ed9ee7SBarry Smith /*@ 611e3ed9ee7SBarry Smith PetscMallocPopMaximumUsage - collect the maximum memory usage over an event 612e3ed9ee7SBarry Smith 613e3ed9ee7SBarry Smith Not Collective 614e3ed9ee7SBarry Smith 615e3ed9ee7SBarry Smith Input Parameter: 616e3ed9ee7SBarry Smith . event - an event id; this is just for error checking 617e3ed9ee7SBarry Smith 618e3ed9ee7SBarry Smith Output Parameter: 619e3ed9ee7SBarry Smith . mu - maximum amount of memory malloced during this event; high water mark relative to the beginning of the event 620e3ed9ee7SBarry Smith 621e3ed9ee7SBarry Smith Level: developer 622e3ed9ee7SBarry Smith 62392f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 624e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage() 625e3ed9ee7SBarry Smith @*/ 626e3ed9ee7SBarry Smith PetscErrorCode PetscMallocPopMaximumUsage(int event,PetscLogDouble *mu) 627e3ed9ee7SBarry Smith { 628e3ed9ee7SBarry Smith PetscFunctionBegin; 629e3ed9ee7SBarry Smith *mu = 0; 630e3ed9ee7SBarry Smith if (NumTRMaxMems-- > MAXTRMAXMEMS) PetscFunctionReturn(0); 631e3ed9ee7SBarry Smith if (TRMaxMemsEvents[NumTRMaxMems] != event) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"PetscMallocPush/PopMaximumUsage() are not nested"); 632e3ed9ee7SBarry Smith *mu = TRMaxMems[NumTRMaxMems]; 633e3ed9ee7SBarry Smith PetscFunctionReturn(0); 634e3ed9ee7SBarry Smith } 635e3ed9ee7SBarry Smith 636a64a8e02SBarry Smith #if defined(PETSC_USE_DEBUG) 637a64a8e02SBarry Smith /*@C 638a64a8e02SBarry Smith PetscMallocGetStack - returns a pointer to the stack for the location in the program a call to PetscMalloc() was used to obtain that memory 639a64a8e02SBarry Smith 640a64a8e02SBarry Smith Collective on PETSC_COMM_WORLD 641a64a8e02SBarry Smith 642a64a8e02SBarry Smith Input Parameter: 643a64a8e02SBarry Smith . ptr - the memory location 644a64a8e02SBarry Smith 645fd292e60Sprj- Output Parameter: 646a64a8e02SBarry Smith . stack - the stack indicating where the program allocated this memory 647a64a8e02SBarry Smith 648a64a8e02SBarry Smith Level: intermediate 649a64a8e02SBarry Smith 65092f119d6SBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocView() 651a64a8e02SBarry Smith @*/ 652a64a8e02SBarry Smith PetscErrorCode PetscMallocGetStack(void *ptr,PetscStack **stack) 653a64a8e02SBarry Smith { 654a64a8e02SBarry Smith TRSPACE *head; 655a64a8e02SBarry Smith 656a64a8e02SBarry Smith PetscFunctionBegin; 657a64a8e02SBarry Smith head = (TRSPACE*) (((char*)ptr) - HEADER_BYTES); 658a64a8e02SBarry Smith *stack = &head->stack; 659a64a8e02SBarry Smith PetscFunctionReturn(0); 660a64a8e02SBarry Smith } 66176386721SLisandro Dalcin #else 66276386721SLisandro Dalcin PetscErrorCode PetscMallocGetStack(void *ptr,void **stack) 66376386721SLisandro Dalcin { 66476386721SLisandro Dalcin PetscFunctionBegin; 665f0ba7cfcSLisandro Dalcin *stack = NULL; 66676386721SLisandro Dalcin PetscFunctionReturn(0); 66776386721SLisandro Dalcin } 668a64a8e02SBarry Smith #endif 669a64a8e02SBarry Smith 670e5c89e4eSSatish Balay /*@C 67192f119d6SBarry Smith PetscMallocDump - Dumps the currently allocated memory blocks to a file. The information 672e5c89e4eSSatish Balay printed is: size of space (in bytes), address of space, id of space, 673e5c89e4eSSatish Balay file in which space was allocated, and line number at which it was 674e5c89e4eSSatish Balay allocated. 675e5c89e4eSSatish Balay 67692f119d6SBarry Smith Not Collective 677e5c89e4eSSatish Balay 678e5c89e4eSSatish Balay Input Parameter: 679e5c89e4eSSatish Balay . fp - file pointer. If fp is NULL, stdout is assumed. 680e5c89e4eSSatish Balay 681e5c89e4eSSatish Balay Options Database Key: 68292f119d6SBarry Smith . -malloc_dump <optional filename> - Dumps unfreed memory during call to PetscFinalize() 683e5c89e4eSSatish Balay 684e5c89e4eSSatish Balay Level: intermediate 685e5c89e4eSSatish Balay 686e5c89e4eSSatish Balay Fortran Note: 687e5c89e4eSSatish Balay The calling sequence in Fortran is PetscMallocDump(integer ierr) 688e5c89e4eSSatish Balay The fp defaults to stdout. 689e5c89e4eSSatish Balay 69095452b02SPatrick Sanan Notes: 69192f119d6SBarry Smith Uses MPI_COMM_WORLD to display rank, because this may be called in PetscFinalize() after PETSC_COMM_WORLD has been freed. 692e5c89e4eSSatish Balay 69392f119d6SBarry Smith When called in PetscFinalize() dumps only the allocations that have not been properly freed 69492f119d6SBarry Smith 69592f119d6SBarry Smith PetscMallocView() prints a list of all memory ever allocated 69692f119d6SBarry Smith 69792f119d6SBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocView(), PetscMallocViewSet() 698e5c89e4eSSatish Balay @*/ 6997087cfbeSBarry Smith PetscErrorCode PetscMallocDump(FILE *fp) 700e5c89e4eSSatish Balay { 701e5c89e4eSSatish Balay TRSPACE *head; 702e3ed9ee7SBarry Smith size_t libAlloc = 0; 703e5c89e4eSSatish Balay PetscErrorCode ierr; 704e5c89e4eSSatish Balay PetscMPIInt rank; 705e5c89e4eSSatish Balay 706e5c89e4eSSatish Balay PetscFunctionBegin; 707e5c89e4eSSatish Balay ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr); 708da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 709e5c89e4eSSatish Balay head = TRhead; 710e5c89e4eSSatish Balay while (head) { 7115486ca60SMatthew G. Knepley libAlloc += head->size; 7125486ca60SMatthew G. Knepley head = head->next; 7135486ca60SMatthew G. Knepley } 7145486ca60SMatthew G. Knepley if (TRallocated - libAlloc > 0) fprintf(fp,"[%d]Total space allocated %.0f bytes\n",rank,(PetscLogDouble)TRallocated); 7155486ca60SMatthew G. Knepley head = TRhead; 7165486ca60SMatthew G. Knepley while (head) { 7175486ca60SMatthew G. Knepley PetscBool isLib; 7185486ca60SMatthew G. Knepley 7195486ca60SMatthew G. Knepley ierr = PetscStrcmp(head->functionname, "PetscDLLibraryOpen", &isLib);CHKERRQ(ierr); 7205486ca60SMatthew G. Knepley if (!isLib) { 721efca3c55SSatish Balay fprintf(fp,"[%2d]%.0f bytes %s() line %d in %s\n",rank,(PetscLogDouble)head->size,head->functionname,head->lineno,head->filename); 7228bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 723e5c89e4eSSatish Balay ierr = PetscStackPrint(&head->stack,fp);CHKERRQ(ierr); 724e5c89e4eSSatish Balay #endif 7255486ca60SMatthew G. Knepley } 726e5c89e4eSSatish Balay head = head->next; 727e5c89e4eSSatish Balay } 728e5c89e4eSSatish Balay PetscFunctionReturn(0); 729e5c89e4eSSatish Balay } 730e5c89e4eSSatish Balay 731dc37d89fSBarry Smith /*@ 73292f119d6SBarry Smith PetscMallocViewSet - Activates logging of all calls to PetscMalloc() with a minimum size to view 733574034a9SJed Brown 734574034a9SJed Brown Not Collective 735574034a9SJed Brown 736574034a9SJed Brown Input Arguments: 737574034a9SJed Brown . logmin - minimum allocation size to log, or PETSC_DEFAULT 738574034a9SJed Brown 739574034a9SJed Brown Options Database Key: 74092f119d6SBarry Smith + -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize() 7418b254c29SBarry Smith . -malloc_view_threshold <min> - Sets a minimum size if -malloc_view is used 7428b254c29SBarry Smith - -log_view_memory - view the memory usage also with the -log_view option 743574034a9SJed Brown 744574034a9SJed Brown Level: advanced 745574034a9SJed Brown 74692f119d6SBarry Smith Notes: Must be called after PetscMallocSetDebug() 74792f119d6SBarry Smith 74892f119d6SBarry Smith Uses MPI_COMM_WORLD to determine rank because PETSc communicators may not be available 74992f119d6SBarry Smith 75092f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocViewSet() 751574034a9SJed Brown @*/ 75292f119d6SBarry Smith PetscErrorCode PetscMallocViewSet(PetscLogDouble logmin) 753574034a9SJed Brown { 754574034a9SJed Brown PetscErrorCode ierr; 755574034a9SJed Brown 756574034a9SJed Brown PetscFunctionBegin; 75792f119d6SBarry Smith PetscLogMalloc = 0; 75892f119d6SBarry Smith ierr = PetscMemorySetGetMaximumUsage();CHKERRQ(ierr); 759574034a9SJed Brown if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */ 760574034a9SJed Brown PetscLogMallocThreshold = (size_t)logmin; 761574034a9SJed Brown PetscFunctionReturn(0); 762574034a9SJed Brown } 763574034a9SJed Brown 764dc37d89fSBarry Smith /*@ 76592f119d6SBarry Smith PetscMallocViewGet - Determine whether all calls to PetscMalloc() are being logged 76618a2528dSJed Brown 76718a2528dSJed Brown Not Collective 76818a2528dSJed Brown 76918a2528dSJed Brown Output Arguments 77018a2528dSJed Brown . logging - PETSC_TRUE if logging is active 77118a2528dSJed Brown 77218a2528dSJed Brown Options Database Key: 77392f119d6SBarry Smith . -malloc_view <optional filename> - Activates PetscMallocView() 77418a2528dSJed Brown 77518a2528dSJed Brown Level: advanced 77618a2528dSJed Brown 77792f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView() 77818a2528dSJed Brown @*/ 77992f119d6SBarry Smith PetscErrorCode PetscMallocViewGet(PetscBool *logging) 78018a2528dSJed Brown { 78118a2528dSJed Brown 78218a2528dSJed Brown PetscFunctionBegin; 78318a2528dSJed Brown *logging = (PetscBool)(PetscLogMalloc >= 0); 78418a2528dSJed Brown PetscFunctionReturn(0); 78518a2528dSJed Brown } 78618a2528dSJed Brown 787e5c89e4eSSatish Balay /*@C 78892f119d6SBarry Smith PetscMallocView - Saves the log of all calls to PetscMalloc(); also calls 78921b680ceSJed Brown PetscMemoryGetMaximumUsage() 790e5c89e4eSSatish Balay 79192f119d6SBarry Smith Not Collective 792e5c89e4eSSatish Balay 793e5c89e4eSSatish Balay Input Parameter: 7940298fd71SBarry Smith . fp - file pointer; or NULL 795e5c89e4eSSatish Balay 796e5c89e4eSSatish Balay Options Database Key: 79792f119d6SBarry Smith . -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize() 798e5c89e4eSSatish Balay 799e5c89e4eSSatish Balay Level: advanced 800e5c89e4eSSatish Balay 801e5c89e4eSSatish Balay Fortran Note: 80292f119d6SBarry Smith The calling sequence in Fortran is PetscMallocView(integer ierr) 803e5c89e4eSSatish Balay The fp defaults to stdout. 804e5c89e4eSSatish Balay 80592f119d6SBarry Smith Notes: 80692f119d6SBarry Smith PetscMallocDump() dumps only the currently unfreed memory, this dumps all memory ever allocated 80792f119d6SBarry Smith 80892f119d6SBarry Smith PetscMemoryView() gives a brief summary of current memory usage 80992f119d6SBarry Smith 81092f119d6SBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocDump(), PetscMallocViewSet(), PetscMemoryView() 811e5c89e4eSSatish Balay @*/ 81292f119d6SBarry Smith PetscErrorCode PetscMallocView(FILE *fp) 813e5c89e4eSSatish Balay { 81492f119d6SBarry Smith PetscInt i,j,n,*perm; 815e5c89e4eSSatish Balay size_t *shortlength; 816f56c2debSBarry Smith int *shortcount,err; 81792f119d6SBarry Smith PetscMPIInt rank; 818ace3abfcSBarry Smith PetscBool match; 819e5c89e4eSSatish Balay const char **shortfunction; 820e5c89e4eSSatish Balay PetscLogDouble rss; 821e5c89e4eSSatish Balay PetscErrorCode ierr; 822e5c89e4eSSatish Balay 823e5c89e4eSSatish Balay PetscFunctionBegin; 824e5c89e4eSSatish Balay ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr); 825f56c2debSBarry Smith err = fflush(fp); 826e32f2f54SBarry Smith if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 827f56c2debSBarry Smith 82879dccf82SBarry 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()"); 829768aa557SSatish Balay 830da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 831f3d65365SJed Brown ierr = PetscMemoryGetMaximumUsage(&rss);CHKERRQ(ierr); 832e5c89e4eSSatish Balay if (rss) { 83392f119d6SBarry Smith (void) fprintf(fp,"[%d] Maximum memory PetscMalloc()ed %.0f maximum size of entire process %.0f\n",rank,(PetscLogDouble)TRMaxMem,rss); 834e5c89e4eSSatish Balay } else { 83592f119d6SBarry Smith (void) fprintf(fp,"[%d] Maximum memory PetscMalloc()ed %.0f OS cannot compute size of entire process\n",rank,(PetscLogDouble)TRMaxMem); 836e5c89e4eSSatish Balay } 837e32f2f54SBarry Smith shortcount = (int*)malloc(PetscLogMalloc*sizeof(int));if (!shortcount) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 838e32f2f54SBarry Smith shortlength = (size_t*)malloc(PetscLogMalloc*sizeof(size_t));if (!shortlength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 839e32f2f54SBarry Smith shortfunction = (const char**)malloc(PetscLogMalloc*sizeof(char*));if (!shortfunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 84097b9d747SJed Brown for (i=0,n=0; i<PetscLogMalloc; i++) { 841e5c89e4eSSatish Balay for (j=0; j<n; j++) { 842e5c89e4eSSatish Balay ierr = PetscStrcmp(shortfunction[j],PetscLogMallocFunction[i],&match);CHKERRQ(ierr); 843e5c89e4eSSatish Balay if (match) { 844e5c89e4eSSatish Balay shortlength[j] += PetscLogMallocLength[i]; 84559ffdab8SBarry Smith shortcount[j]++; 846e5c89e4eSSatish Balay goto foundit; 847e5c89e4eSSatish Balay } 848e5c89e4eSSatish Balay } 849e5c89e4eSSatish Balay shortfunction[n] = PetscLogMallocFunction[i]; 850e5c89e4eSSatish Balay shortlength[n] = PetscLogMallocLength[i]; 85159ffdab8SBarry Smith shortcount[n] = 1; 852e5c89e4eSSatish Balay n++; 853e5c89e4eSSatish Balay foundit:; 854e5c89e4eSSatish Balay } 855e5c89e4eSSatish Balay 856e32f2f54SBarry Smith perm = (PetscInt*)malloc(n*sizeof(PetscInt));if (!perm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 857e5c89e4eSSatish Balay for (i=0; i<n; i++) perm[i] = i; 858e5c89e4eSSatish Balay ierr = PetscSortStrWithPermutation(n,(const char**)shortfunction,perm);CHKERRQ(ierr); 859e5c89e4eSSatish Balay 86092f119d6SBarry Smith (void) fprintf(fp,"[%d] Memory usage sorted by function\n",rank); 861e5c89e4eSSatish Balay for (i=0; i<n; i++) { 86292f119d6SBarry Smith (void) fprintf(fp,"[%d] %d %.0f %s()\n",rank,shortcount[perm[i]],(PetscLogDouble)shortlength[perm[i]],shortfunction[perm[i]]); 863e5c89e4eSSatish Balay } 864e5c89e4eSSatish Balay free(perm); 865e5c89e4eSSatish Balay free(shortlength); 86659ffdab8SBarry Smith free(shortcount); 867e5c89e4eSSatish Balay free((char**)shortfunction); 868f56c2debSBarry Smith err = fflush(fp); 869e32f2f54SBarry Smith if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 870e5c89e4eSSatish Balay PetscFunctionReturn(0); 871e5c89e4eSSatish Balay } 872e5c89e4eSSatish Balay 873e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------- */ 874e5c89e4eSSatish Balay 875dc37d89fSBarry Smith /*@ 87692f119d6SBarry Smith PetscMallocSetDebug - Set's PETSc memory debugging 877e5c89e4eSSatish Balay 878e5c89e4eSSatish Balay Not Collective 879e5c89e4eSSatish Balay 880e5c89e4eSSatish Balay Input Parameter: 88192f119d6SBarry Smith + eachcall - checks the entire heap of allocated memory for issues on each call to PetscMalloc() and PetscFree() 8822d4ee042Sprj- - initializenan - initializes all memory with NaN to catch use of uninitialized floating point arrays 883e5c89e4eSSatish Balay 88492f119d6SBarry Smith Options Database: 88579dccf82SBarry Smith + -malloc_debug <true or false> - turns on or off debugging 88692f119d6SBarry Smith . -malloc_test - turns on all debugging if PETSc was configured with debugging including -malloc_dump, otherwise ignored 88779dccf82SBarry Smith . -malloc_view_threshold t - log only allocations larger than t 88892f119d6SBarry Smith . -malloc_dump <filename> - print a list of all memory that has not been freed 88979dccf82SBarry Smith . -malloc no - (deprecated) same as -malloc_debug no 89079dccf82SBarry Smith - -malloc_log - (deprecated) same as -malloc_view 891e5c89e4eSSatish Balay 89292f119d6SBarry Smith Level: developer 89392f119d6SBarry Smith 89492f119d6SBarry Smith Notes: This is called in PetscInitialize() and should not be called elsewhere 89592f119d6SBarry Smith 89692f119d6SBarry Smith .seealso: CHKMEMQ(), PetscMallocValidate(), PetscMallocGetDebug() 897e5c89e4eSSatish Balay @*/ 89892f119d6SBarry Smith PetscErrorCode PetscMallocSetDebug(PetscBool eachcall, PetscBool initializenan) 899e5c89e4eSSatish Balay { 90092f119d6SBarry Smith PetscErrorCode ierr; 90192f119d6SBarry Smith 902e5c89e4eSSatish Balay PetscFunctionBegin; 90392f119d6SBarry 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()"); 90492f119d6SBarry Smith ierr = PetscMallocSet(PetscTrMallocDefault,PetscTrFreeDefault,PetscTrReallocDefault);CHKERRQ(ierr); 90592f119d6SBarry Smith 90692f119d6SBarry Smith TRallocated = 0; 90792f119d6SBarry Smith TRfrags = 0; 90892f119d6SBarry Smith TRhead = NULL; 90992f119d6SBarry Smith TRid = 0; 91092f119d6SBarry Smith TRdebugLevel = eachcall; 91192f119d6SBarry Smith TRMaxMem = 0; 91292f119d6SBarry Smith PetscLogMallocMax = 10000; 91392f119d6SBarry Smith PetscLogMalloc = -1; 9142d4ee042Sprj- TRdebugIinitializenan = initializenan; 915e5c89e4eSSatish Balay PetscFunctionReturn(0); 916e5c89e4eSSatish Balay } 9170acecf5bSBarry Smith 918dc37d89fSBarry Smith /*@ 91992f119d6SBarry Smith PetscMallocGetDebug - Indicates what PETSc memory debugging it is doing. 9200acecf5bSBarry Smith 9210acecf5bSBarry Smith Not Collective 9220acecf5bSBarry Smith 92392f119d6SBarry Smith Output Parameters: 92492f119d6SBarry Smith + basic - doing basic debugging 92592f119d6SBarry Smith . eachcall - checks the entire memory heap at each PetscMalloc()/PetscFree() 92679dccf82SBarry Smith - initializenan - initializes memory with NaN 9270acecf5bSBarry Smith 9280acecf5bSBarry Smith Level: intermediate 9290acecf5bSBarry Smith 93092f119d6SBarry Smith Notes: 93179dccf82SBarry Smith By default, the debug version always does some debugging unless you run with -malloc_debug no 9320acecf5bSBarry Smith 93392f119d6SBarry Smith .seealso: CHKMEMQ(), PetscMallocValidate(), PetscMallocSetDebug() 9340acecf5bSBarry Smith @*/ 93592f119d6SBarry Smith PetscErrorCode PetscMallocGetDebug(PetscBool *basic, PetscBool *eachcall, PetscBool *initializenan) 9360acecf5bSBarry Smith { 9370acecf5bSBarry Smith PetscFunctionBegin; 93879dccf82SBarry Smith if (basic) *basic = (PetscTrMalloc == PetscTrMallocDefault) ? PETSC_TRUE : PETSC_FALSE; 93979dccf82SBarry Smith if (eachcall) *eachcall = TRdebugLevel; 9402d4ee042Sprj- if (initializenan) *initializenan = TRdebugIinitializenan; 9410acecf5bSBarry Smith PetscFunctionReturn(0); 9420acecf5bSBarry Smith } 943