17d0a6c19SBarry Smith 2e5c89e4eSSatish Balay /* 3e5c89e4eSSatish Balay Interface to malloc() and free(). This code allows for 4e5c89e4eSSatish Balay logging of memory usage and some error checking 5e5c89e4eSSatish Balay */ 6c6db04a5SJed Brown #include <petscsys.h> /*I "petscsys.h" I*/ 7665c2dedSJed Brown #include <petscviewer.h> 8e5c89e4eSSatish Balay #if defined(PETSC_HAVE_MALLOC_H) 9e5c89e4eSSatish Balay #include <malloc.h> 10e5c89e4eSSatish Balay #endif 11e5c89e4eSSatish Balay 12e5c89e4eSSatish Balay 13e5c89e4eSSatish Balay /* 14e5c89e4eSSatish Balay These are defined in mal.c and ensure that malloced space is PetscScalar aligned 15e5c89e4eSSatish Balay */ 16071fcb05SBarry Smith PETSC_EXTERN PetscErrorCode PetscMallocAlign(size_t,PetscBool,int,const char[],const char[],void**); 1795c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscFreeAlign(void*,int,const char[],const char[]); 1895c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscReallocAlign(size_t,int,const char[],const char[],void**); 19071fcb05SBarry Smith PETSC_EXTERN PetscErrorCode PetscTrMallocDefault(size_t,PetscBool,int,const char[],const char[],void**); 2095c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscTrFreeDefault(void*,int,const char[],const char[]); 2195c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscTrReallocDefault(size_t,int,const char[],const char[],void**); 22e5c89e4eSSatish Balay 23e5c89e4eSSatish Balay 240700a824SBarry Smith #define CLASSID_VALUE ((PetscClassId) 0xf0e0d0c9) 250700a824SBarry Smith #define ALREADY_FREED ((PetscClassId) 0x0f0e0d9c) 26e5c89e4eSSatish Balay 27e5c89e4eSSatish Balay typedef struct _trSPACE { 28e5c89e4eSSatish Balay size_t size; 29e5c89e4eSSatish Balay int id; 30e5c89e4eSSatish Balay int lineno; 31e5c89e4eSSatish Balay const char *filename; 32e5c89e4eSSatish Balay const char *functionname; 330700a824SBarry Smith PetscClassId classid; 348bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 35e5c89e4eSSatish Balay PetscStack stack; 36e5c89e4eSSatish Balay #endif 37e5c89e4eSSatish Balay struct _trSPACE *next,*prev; 38e5c89e4eSSatish Balay } TRSPACE; 39e5c89e4eSSatish Balay 4025b53cc9SJed Brown /* HEADER_BYTES is the number of bytes in a PetscMalloc() header. 4125b53cc9SJed Brown It is sizeof(TRSPACE) padded to be a multiple of PETSC_MEMALIGN. 4225b53cc9SJed Brown */ 43e5c89e4eSSatish Balay 44a64a8e02SBarry Smith #define HEADER_BYTES ((sizeof(TRSPACE)+(PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1)) 45e5c89e4eSSatish Balay 46e5c89e4eSSatish Balay 4725b53cc9SJed Brown /* This union is used to insure that the block passed to the user retains 4825b53cc9SJed Brown a minimum alignment of PETSC_MEMALIGN. 4925b53cc9SJed Brown */ 50e5c89e4eSSatish Balay typedef union { 51e5c89e4eSSatish Balay TRSPACE sp; 5225b53cc9SJed Brown char v[HEADER_BYTES]; 53e5c89e4eSSatish Balay } TrSPACE; 54e5c89e4eSSatish Balay 55e3ed9ee7SBarry Smith #define MAXTRMAXMEMS 50 56e5c89e4eSSatish Balay static size_t TRallocated = 0; 57e5c89e4eSSatish Balay static int TRfrags = 0; 58f0ba7cfcSLisandro Dalcin static TRSPACE *TRhead = NULL; 59e5c89e4eSSatish Balay static int TRid = 0; 60ace3abfcSBarry Smith static PetscBool TRdebugLevel = PETSC_FALSE; 61e5c89e4eSSatish Balay static size_t TRMaxMem = 0; 62e3ed9ee7SBarry Smith static int NumTRMaxMems = 0; 63e3ed9ee7SBarry Smith static size_t TRMaxMems[MAXTRMAXMEMS]; 64e3ed9ee7SBarry Smith static int TRMaxMemsEvents[MAXTRMAXMEMS]; 65e5c89e4eSSatish Balay /* 66e5c89e4eSSatish Balay Arrays to log information on all Mallocs 67e5c89e4eSSatish Balay */ 68f0ba7cfcSLisandro Dalcin static int PetscLogMallocMax = 10000; 69f0ba7cfcSLisandro Dalcin static int PetscLogMalloc = -1; 70574034a9SJed Brown static size_t PetscLogMallocThreshold = 0; 71e5c89e4eSSatish Balay static size_t *PetscLogMallocLength; 72efca3c55SSatish Balay static const char **PetscLogMallocFile,**PetscLogMallocFunction; 73e3ed9ee7SBarry Smith static PetscBool PetscSetUseTrMallocCalled = PETSC_FALSE; 74e5c89e4eSSatish Balay 7595c0884eSLisandro Dalcin PETSC_INTERN PetscErrorCode PetscSetUseTrMalloc_Private(void) 76b022a5c1SBarry Smith { 77b022a5c1SBarry Smith PetscErrorCode ierr; 78b022a5c1SBarry Smith 79b022a5c1SBarry Smith PetscFunctionBegin; 80e3ed9ee7SBarry Smith if (PetscSetUseTrMallocCalled) PetscFunctionReturn(0); 81e3ed9ee7SBarry Smith PetscSetUseTrMallocCalled = PETSC_TRUE; 82b022a5c1SBarry Smith ierr = PetscMallocSet(PetscTrMallocDefault,PetscTrFreeDefault);CHKERRQ(ierr); 833221ece2SMatthew G. Knepley PetscTrRealloc = PetscTrReallocDefault; 84a297a907SKarl Rupp 85b022a5c1SBarry Smith TRallocated = 0; 86b022a5c1SBarry Smith TRfrags = 0; 87f0ba7cfcSLisandro Dalcin TRhead = NULL; 88b022a5c1SBarry Smith TRid = 0; 89b022a5c1SBarry Smith TRdebugLevel = PETSC_FALSE; 90b022a5c1SBarry Smith TRMaxMem = 0; 91b022a5c1SBarry Smith PetscLogMallocMax = 10000; 92b022a5c1SBarry Smith PetscLogMalloc = -1; 93b022a5c1SBarry Smith PetscFunctionReturn(0); 94b022a5c1SBarry Smith } 95b022a5c1SBarry Smith 96e5c89e4eSSatish Balay /*@C 97e5c89e4eSSatish Balay PetscMallocValidate - Test the memory for corruption. This can be used to 98e5c89e4eSSatish Balay check for memory overwrites. 99e5c89e4eSSatish Balay 100e5c89e4eSSatish Balay Input Parameter: 101e5c89e4eSSatish Balay + line - line number where call originated. 102e5c89e4eSSatish Balay . function - name of function calling 103efca3c55SSatish Balay - file - file where function is 104e5c89e4eSSatish Balay 105e5c89e4eSSatish Balay Return value: 106e5c89e4eSSatish Balay The number of errors detected. 107e5c89e4eSSatish Balay 108e5c89e4eSSatish Balay Output Effect: 109e5c89e4eSSatish Balay Error messages are written to stdout. 110e5c89e4eSSatish Balay 111e5c89e4eSSatish Balay Level: advanced 112e5c89e4eSSatish Balay 113e5c89e4eSSatish Balay Notes: 114*38548759SBarry Smith This is only run if PetscMallocDebug() has been called which is set by -malloc_test (if debugging is turned on) or -malloc_debug (any time) 115*38548759SBarry Smith 116e5c89e4eSSatish Balay You should generally use CHKMEMQ as a short cut for calling this 117e5c89e4eSSatish Balay routine. 118e5c89e4eSSatish Balay 119efca3c55SSatish Balay The line, function, file are given by the C preprocessor as 120e5c89e4eSSatish Balay 121e5c89e4eSSatish Balay The Fortran calling sequence is simply PetscMallocValidate(ierr) 122e5c89e4eSSatish Balay 123e5c89e4eSSatish Balay No output is generated if there are no problems detected. 124e5c89e4eSSatish Balay 125e5c89e4eSSatish Balay .seealso: CHKMEMQ 126e5c89e4eSSatish Balay 127e5c89e4eSSatish Balay @*/ 128efca3c55SSatish Balay PetscErrorCode PetscMallocValidate(int line,const char function[],const char file[]) 129e5c89e4eSSatish Balay { 1306c093d5bSvictor TRSPACE *head,*lasthead; 131e5c89e4eSSatish Balay char *a; 1320700a824SBarry Smith PetscClassId *nend; 133e5c89e4eSSatish Balay 134*38548759SBarry Smith if (!TRdebugLevel) return 0; 135e5c89e4eSSatish Balay PetscFunctionBegin; 1366c093d5bSvictor head = TRhead; lasthead = NULL; 137e5c89e4eSSatish Balay while (head) { 1380700a824SBarry Smith if (head->classid != CLASSID_VALUE) { 139efca3c55SSatish Balay (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 140e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory at address %p is corrupted\n",head); 141e5c89e4eSSatish Balay (*PetscErrorPrintf)("Probably write past beginning or end of array\n"); 142efca3c55SSatish Balay if (lasthead) (*PetscErrorPrintf)("Last intact block allocated in %s() line %d in %s\n",lasthead->functionname,lasthead->lineno,lasthead->filename); 143e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 144e5c89e4eSSatish Balay } 145e5c89e4eSSatish Balay a = (char*)(((TrSPACE*)head) + 1); 1460700a824SBarry Smith nend = (PetscClassId*)(a + head->size); 1470700a824SBarry Smith if (*nend != CLASSID_VALUE) { 148efca3c55SSatish Balay (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 149e5c89e4eSSatish Balay if (*nend == ALREADY_FREED) { 150e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p already freed\n",head->id,(PetscLogDouble)head->size,a); 151e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 152e5c89e4eSSatish Balay } else { 153e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 154efca3c55SSatish Balay (*PetscErrorPrintf)("Memory originally allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 155e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 156e5c89e4eSSatish Balay } 157e5c89e4eSSatish Balay } 1586c093d5bSvictor lasthead = head; 159e5c89e4eSSatish Balay head = head->next; 160e5c89e4eSSatish Balay } 161e5c89e4eSSatish Balay PetscFunctionReturn(0); 162e5c89e4eSSatish Balay } 163e5c89e4eSSatish Balay 164e5c89e4eSSatish Balay /* 165e5c89e4eSSatish Balay PetscTrMallocDefault - Malloc with tracing. 166e5c89e4eSSatish Balay 167e5c89e4eSSatish Balay Input Parameters: 168e5c89e4eSSatish Balay + a - number of bytes to allocate 169e5c89e4eSSatish Balay . lineno - line number where used. Use __LINE__ for this 170efca3c55SSatish Balay - filename - file name where used. Use __FILE__ for this 171e5c89e4eSSatish Balay 172e5c89e4eSSatish Balay Returns: 173e5c89e4eSSatish Balay double aligned pointer to requested storage, or null if not 174e5c89e4eSSatish Balay available. 175e5c89e4eSSatish Balay */ 176071fcb05SBarry Smith PetscErrorCode PetscTrMallocDefault(size_t a,PetscBool clear,int lineno,const char function[],const char filename[],void **result) 177e5c89e4eSSatish Balay { 178e5c89e4eSSatish Balay TRSPACE *head; 179e5c89e4eSSatish Balay char *inew; 180e5c89e4eSSatish Balay size_t nsize; 181e5c89e4eSSatish Balay PetscErrorCode ierr; 182e5c89e4eSSatish Balay 183e5c89e4eSSatish Balay PetscFunctionBegin; 184f0ba7cfcSLisandro Dalcin /* Do not try to handle empty blocks */ 185f0ba7cfcSLisandro Dalcin if (!a) { *result = NULL; PetscFunctionReturn(0); } 186f0ba7cfcSLisandro Dalcin 187efca3c55SSatish Balay ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr); 188e5c89e4eSSatish Balay 18925b53cc9SJed Brown nsize = (a + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1); 190071fcb05SBarry Smith ierr = PetscMallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),clear,lineno,function,filename,(void**)&inew);CHKERRQ(ierr); 191e3ed9ee7SBarry Smith 192e5c89e4eSSatish Balay head = (TRSPACE*)inew; 193e5c89e4eSSatish Balay inew += sizeof(TrSPACE); 194e5c89e4eSSatish Balay 195e5c89e4eSSatish Balay if (TRhead) TRhead->prev = head; 196e5c89e4eSSatish Balay head->next = TRhead; 197e5c89e4eSSatish Balay TRhead = head; 198f0ba7cfcSLisandro Dalcin head->prev = NULL; 199e5c89e4eSSatish Balay head->size = nsize; 200e5c89e4eSSatish Balay head->id = TRid; 201e5c89e4eSSatish Balay head->lineno = lineno; 202e5c89e4eSSatish Balay 203e5c89e4eSSatish Balay head->filename = filename; 204e5c89e4eSSatish Balay head->functionname = function; 2050700a824SBarry Smith head->classid = CLASSID_VALUE; 2060700a824SBarry Smith *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 207e5c89e4eSSatish Balay 208e5c89e4eSSatish Balay TRallocated += nsize; 209a297a907SKarl Rupp if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 210e3ed9ee7SBarry Smith if (PetscLogMemory) { 211e3ed9ee7SBarry Smith PetscInt i; 212e3ed9ee7SBarry Smith for (i=0; i<NumTRMaxMems; i++) { 213e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 214e3ed9ee7SBarry Smith } 215e3ed9ee7SBarry Smith } 216e5c89e4eSSatish Balay TRfrags++; 217e5c89e4eSSatish Balay 2188bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 21976386721SLisandro Dalcin if (PetscStackActive()) { 2205c25fcd7SBarry Smith ierr = PetscStackCopy(petscstack,&head->stack);CHKERRQ(ierr); 2212c9581d2SBarry Smith /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 2222c9581d2SBarry Smith head->stack.line[head->stack.currentsize-2] = lineno; 2239de0f6ecSBarry Smith } else { 2249de0f6ecSBarry Smith head->stack.currentsize = 0; 22576386721SLisandro Dalcin } 226e5c89e4eSSatish Balay #endif 227e5c89e4eSSatish Balay 228e5c89e4eSSatish Balay /* 229e5c89e4eSSatish Balay Allow logging of all mallocs made 230e5c89e4eSSatish Balay */ 231574034a9SJed Brown if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && a >= PetscLogMallocThreshold) { 232e5c89e4eSSatish Balay if (!PetscLogMalloc) { 233e5c89e4eSSatish Balay PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 234e32f2f54SBarry Smith if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 235a297a907SKarl Rupp 236a2ea699eSBarry Smith PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 237e32f2f54SBarry Smith if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 238a297a907SKarl Rupp 239a2ea699eSBarry Smith PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 240e32f2f54SBarry Smith if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 241e5c89e4eSSatish Balay } 242e5c89e4eSSatish Balay PetscLogMallocLength[PetscLogMalloc] = nsize; 243e5c89e4eSSatish Balay PetscLogMallocFile[PetscLogMalloc] = filename; 244e5c89e4eSSatish Balay PetscLogMallocFunction[PetscLogMalloc++] = function; 245e5c89e4eSSatish Balay } 246e5c89e4eSSatish Balay *result = (void*)inew; 247e5c89e4eSSatish Balay PetscFunctionReturn(0); 248e5c89e4eSSatish Balay } 249e5c89e4eSSatish Balay 250e5c89e4eSSatish Balay 251e5c89e4eSSatish Balay /* 252e5c89e4eSSatish Balay PetscTrFreeDefault - Free with tracing. 253e5c89e4eSSatish Balay 254e5c89e4eSSatish Balay Input Parameters: 255e5c89e4eSSatish Balay . a - pointer to a block allocated with PetscTrMalloc 256e5c89e4eSSatish Balay . lineno - line number where used. Use __LINE__ for this 257e5c89e4eSSatish Balay . file - file name where used. Use __FILE__ for this 258e5c89e4eSSatish Balay */ 259efca3c55SSatish Balay PetscErrorCode PetscTrFreeDefault(void *aa,int line,const char function[],const char file[]) 260e5c89e4eSSatish Balay { 261e5c89e4eSSatish Balay char *a = (char*)aa; 262e5c89e4eSSatish Balay TRSPACE *head; 263e5c89e4eSSatish Balay char *ahead; 264e5c89e4eSSatish Balay PetscErrorCode ierr; 2650700a824SBarry Smith PetscClassId *nend; 266e5c89e4eSSatish Balay 267e5c89e4eSSatish Balay PetscFunctionBegin; 268e5c89e4eSSatish Balay /* Do not try to handle empty blocks */ 26949d7da52SJed Brown if (!a) PetscFunctionReturn(0); 270e5c89e4eSSatish Balay 271efca3c55SSatish Balay ierr = PetscMallocValidate(line,function,file);CHKERRQ(ierr); 272e5c89e4eSSatish Balay 273e5c89e4eSSatish Balay ahead = a; 274e5c89e4eSSatish Balay a = a - sizeof(TrSPACE); 275e5c89e4eSSatish Balay head = (TRSPACE*)a; 276e5c89e4eSSatish Balay 2770700a824SBarry Smith if (head->classid != CLASSID_VALUE) { 278efca3c55SSatish Balay (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); 279e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 280e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); 281e5c89e4eSSatish Balay } 2820700a824SBarry Smith nend = (PetscClassId*)(ahead + head->size); 2830700a824SBarry Smith if (*nend != CLASSID_VALUE) { 284e5c89e4eSSatish Balay if (*nend == ALREADY_FREED) { 285efca3c55SSatish Balay (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); 286e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 287e5c89e4eSSatish Balay if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 288efca3c55SSatish Balay (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 289e5c89e4eSSatish Balay } else { 290efca3c55SSatish Balay (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename); 291e5c89e4eSSatish Balay } 292e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); 293e5c89e4eSSatish Balay } else { 294e5c89e4eSSatish Balay /* Damaged tail */ 295efca3c55SSatish Balay (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); 296e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 297efca3c55SSatish Balay (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 298e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); 299e5c89e4eSSatish Balay } 300e5c89e4eSSatish Balay } 301e5c89e4eSSatish Balay /* Mark the location freed */ 302e5c89e4eSSatish Balay *nend = ALREADY_FREED; 303e5c89e4eSSatish Balay /* Save location where freed. If we suspect the line number, mark as allocated location */ 304e5c89e4eSSatish Balay if (line > 0 && line < 50000) { 305e5c89e4eSSatish Balay head->lineno = line; 306e5c89e4eSSatish Balay head->filename = file; 307e5c89e4eSSatish Balay head->functionname = function; 308e5c89e4eSSatish Balay } else { 309e5c89e4eSSatish Balay head->lineno = -head->lineno; 310e5c89e4eSSatish Balay } 311e3ed9ee7SBarry Smith if (TRallocated < head->size) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"TRallocate is smaller than memory just freed"); 312e5c89e4eSSatish Balay TRallocated -= head->size; 313e5c89e4eSSatish Balay TRfrags--; 314e5c89e4eSSatish Balay if (head->prev) head->prev->next = head->next; 315e5c89e4eSSatish Balay else TRhead = head->next; 316e5c89e4eSSatish Balay 317e5c89e4eSSatish Balay if (head->next) head->next->prev = head->prev; 318efca3c55SSatish Balay ierr = PetscFreeAlign(a,line,function,file);CHKERRQ(ierr); 319e5c89e4eSSatish Balay PetscFunctionReturn(0); 320e5c89e4eSSatish Balay } 321e5c89e4eSSatish Balay 322e5c89e4eSSatish Balay 3233221ece2SMatthew G. Knepley 3243221ece2SMatthew G. Knepley /* 3253221ece2SMatthew G. Knepley PetscTrReallocDefault - Realloc with tracing. 3263221ece2SMatthew G. Knepley 3273221ece2SMatthew G. Knepley Input Parameters: 3283221ece2SMatthew G. Knepley + len - number of bytes to allocate 3293221ece2SMatthew G. Knepley . lineno - line number where used. Use __LINE__ for this 3303221ece2SMatthew G. Knepley . filename - file name where used. Use __FILE__ for this 3313221ece2SMatthew G. Knepley - result - double aligned pointer to initial storage. 3323221ece2SMatthew G. Knepley 3333221ece2SMatthew G. Knepley Output Parameter: 3343221ece2SMatthew G. Knepley . result - double aligned pointer to requested storage, or null if not available. 3353221ece2SMatthew G. Knepley 3363221ece2SMatthew G. Knepley Level: developer 3373221ece2SMatthew G. Knepley 3383221ece2SMatthew G. Knepley .seealso: PetscTrMallocDefault(), PetscTrFreeDefault() 3393221ece2SMatthew G. Knepley */ 3403221ece2SMatthew G. Knepley PetscErrorCode PetscTrReallocDefault(size_t len, int lineno, const char function[], const char filename[], void **result) 3413221ece2SMatthew G. Knepley { 3423221ece2SMatthew G. Knepley char *a = (char *) *result; 3433221ece2SMatthew G. Knepley TRSPACE *head; 3443221ece2SMatthew G. Knepley char *ahead, *inew; 3453221ece2SMatthew G. Knepley PetscClassId *nend; 3463221ece2SMatthew G. Knepley size_t nsize; 3473221ece2SMatthew G. Knepley PetscErrorCode ierr; 3483221ece2SMatthew G. Knepley 3493221ece2SMatthew G. Knepley PetscFunctionBegin; 350c22f1541SToby Isaac /* Realloc to zero = free */ 351c22f1541SToby Isaac if (!len) { 352c22f1541SToby Isaac ierr = PetscTrFreeDefault(*result,lineno,function,filename);CHKERRQ(ierr); 353c22f1541SToby Isaac *result = NULL; 354c22f1541SToby Isaac PetscFunctionReturn(0); 355c22f1541SToby Isaac } 356f590eff4SLisandro Dalcin /* Realloc with NULL = malloc */ 357f590eff4SLisandro Dalcin if (!*result) { 358071fcb05SBarry Smith ierr = PetscTrMallocDefault(len,PETSC_FALSE,lineno,function,filename,result);CHKERRQ(ierr); 359f590eff4SLisandro Dalcin PetscFunctionReturn(0); 360f590eff4SLisandro Dalcin } 3613221ece2SMatthew G. Knepley 362*38548759SBarry Smith ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr); 3633221ece2SMatthew G. Knepley 3643221ece2SMatthew G. Knepley ahead = a; 3653221ece2SMatthew G. Knepley a = a - sizeof(TrSPACE); 3663221ece2SMatthew G. Knepley head = (TRSPACE *) a; 3673221ece2SMatthew G. Knepley inew = a; 3683221ece2SMatthew G. Knepley 3693221ece2SMatthew G. Knepley if (head->classid != CLASSID_VALUE) { 3703221ece2SMatthew G. Knepley (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename); 3713221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 3723221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); 3733221ece2SMatthew G. Knepley } 3743221ece2SMatthew G. Knepley nend = (PetscClassId *)(ahead + head->size); 3753221ece2SMatthew G. Knepley if (*nend != CLASSID_VALUE) { 3763221ece2SMatthew G. Knepley if (*nend == ALREADY_FREED) { 3773221ece2SMatthew G. Knepley (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename); 3783221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 3793221ece2SMatthew G. Knepley if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 3803221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 3813221ece2SMatthew G. Knepley } else { 3823221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename); 3833221ece2SMatthew G. Knepley } 3843221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); 3853221ece2SMatthew G. Knepley } else { 3863221ece2SMatthew G. Knepley /* Damaged tail */ 3873221ece2SMatthew G. Knepley (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename); 3883221ece2SMatthew 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); 3893221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 3903221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); 3913221ece2SMatthew G. Knepley } 3923221ece2SMatthew G. Knepley } 3933221ece2SMatthew G. Knepley 3943221ece2SMatthew G. Knepley TRallocated -= head->size; 3953221ece2SMatthew G. Knepley TRfrags--; 3963221ece2SMatthew G. Knepley if (head->prev) head->prev->next = head->next; 3973221ece2SMatthew G. Knepley else TRhead = head->next; 3983221ece2SMatthew G. Knepley if (head->next) head->next->prev = head->prev; 3993221ece2SMatthew G. Knepley 4003221ece2SMatthew G. Knepley nsize = (len + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1); 4013221ece2SMatthew G. Knepley ierr = PetscReallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),lineno,function,filename,(void**)&inew);CHKERRQ(ierr); 4023221ece2SMatthew G. Knepley 4033221ece2SMatthew G. Knepley head = (TRSPACE*)inew; 4043221ece2SMatthew G. Knepley inew += sizeof(TrSPACE); 4053221ece2SMatthew G. Knepley 4063221ece2SMatthew G. Knepley if (TRhead) TRhead->prev = head; 4073221ece2SMatthew G. Knepley head->next = TRhead; 4083221ece2SMatthew G. Knepley TRhead = head; 4093221ece2SMatthew G. Knepley head->prev = NULL; 4103221ece2SMatthew G. Knepley head->size = nsize; 4113221ece2SMatthew G. Knepley head->id = TRid; 4123221ece2SMatthew G. Knepley head->lineno = lineno; 4133221ece2SMatthew G. Knepley 4143221ece2SMatthew G. Knepley head->filename = filename; 4153221ece2SMatthew G. Knepley head->functionname = function; 4163221ece2SMatthew G. Knepley head->classid = CLASSID_VALUE; 4173221ece2SMatthew G. Knepley *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 4183221ece2SMatthew G. Knepley 4193221ece2SMatthew G. Knepley TRallocated += nsize; 4203221ece2SMatthew G. Knepley if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 421e3ed9ee7SBarry Smith if (PetscLogMemory) { 422e3ed9ee7SBarry Smith PetscInt i; 423e3ed9ee7SBarry Smith for (i=0; i<NumTRMaxMems; i++) { 424e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 425e3ed9ee7SBarry Smith } 426e3ed9ee7SBarry Smith } 4273221ece2SMatthew G. Knepley TRfrags++; 4283221ece2SMatthew G. Knepley 4293221ece2SMatthew G. Knepley #if defined(PETSC_USE_DEBUG) 4303221ece2SMatthew G. Knepley if (PetscStackActive()) { 4313221ece2SMatthew G. Knepley ierr = PetscStackCopy(petscstack,&head->stack);CHKERRQ(ierr); 4323221ece2SMatthew G. Knepley /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 4333221ece2SMatthew G. Knepley head->stack.line[head->stack.currentsize-2] = lineno; 4343221ece2SMatthew G. Knepley } else { 4353221ece2SMatthew G. Knepley head->stack.currentsize = 0; 4363221ece2SMatthew G. Knepley } 4373221ece2SMatthew G. Knepley #endif 4383221ece2SMatthew G. Knepley 4393221ece2SMatthew G. Knepley /* 4403221ece2SMatthew G. Knepley Allow logging of all mallocs made 4413221ece2SMatthew G. Knepley */ 4423221ece2SMatthew G. Knepley if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && len >= PetscLogMallocThreshold) { 4433221ece2SMatthew G. Knepley if (!PetscLogMalloc) { 4443221ece2SMatthew G. Knepley PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 4453221ece2SMatthew G. Knepley if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4463221ece2SMatthew G. Knepley 4473221ece2SMatthew G. Knepley PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 4483221ece2SMatthew G. Knepley if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4493221ece2SMatthew G. Knepley 4503221ece2SMatthew G. Knepley PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 4513221ece2SMatthew G. Knepley if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4523221ece2SMatthew G. Knepley } 4533221ece2SMatthew G. Knepley PetscLogMallocLength[PetscLogMalloc] = nsize; 4543221ece2SMatthew G. Knepley PetscLogMallocFile[PetscLogMalloc] = filename; 4553221ece2SMatthew G. Knepley PetscLogMallocFunction[PetscLogMalloc++] = function; 4563221ece2SMatthew G. Knepley } 4573221ece2SMatthew G. Knepley *result = (void*)inew; 4583221ece2SMatthew G. Knepley PetscFunctionReturn(0); 4593221ece2SMatthew G. Knepley } 4603221ece2SMatthew G. Knepley 4613221ece2SMatthew G. Knepley 462fe7fb379SMatthew Knepley /*@C 4630841954dSBarry Smith PetscMemoryView - Shows the amount of memory currently being used 464e5c89e4eSSatish Balay in a communicator. 465e5c89e4eSSatish Balay 466e5c89e4eSSatish Balay Collective on PetscViewer 467e5c89e4eSSatish Balay 468e5c89e4eSSatish Balay Input Parameter: 469e5c89e4eSSatish Balay + viewer - the viewer that defines the communicator 470e5c89e4eSSatish Balay - message - string printed before values 471e5c89e4eSSatish Balay 4720841954dSBarry Smith Options Database: 4730841954dSBarry Smith + -malloc - have PETSc track how much memory it has allocated 4740841954dSBarry Smith - -memory_view - during PetscFinalize() have this routine called 4750841954dSBarry Smith 476e5c89e4eSSatish Balay Level: intermediate 477e5c89e4eSSatish Balay 4780841954dSBarry Smith .seealso: PetscMallocDump(), PetscMemoryGetCurrentUsage(), PetscMemorySetGetMaximumUsage() 479e5c89e4eSSatish Balay @*/ 4800841954dSBarry Smith PetscErrorCode PetscMemoryView(PetscViewer viewer,const char message[]) 481e5c89e4eSSatish Balay { 4820841954dSBarry Smith PetscLogDouble allocated,allocatedmax,resident,residentmax,gallocated,gallocatedmax,gresident,gresidentmax,maxgallocated,maxgallocatedmax,maxgresident,maxgresidentmax; 4830841954dSBarry Smith PetscLogDouble mingallocated,mingallocatedmax,mingresident,mingresidentmax; 484e5c89e4eSSatish Balay PetscErrorCode ierr; 485e5c89e4eSSatish Balay MPI_Comm comm; 486e5c89e4eSSatish Balay 487e5c89e4eSSatish Balay PetscFunctionBegin; 488e5c89e4eSSatish Balay if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD; 489e5c89e4eSSatish Balay ierr = PetscMallocGetCurrentUsage(&allocated);CHKERRQ(ierr); 4900841954dSBarry Smith ierr = PetscMallocGetMaximumUsage(&allocatedmax);CHKERRQ(ierr); 491e5c89e4eSSatish Balay ierr = PetscMemoryGetCurrentUsage(&resident);CHKERRQ(ierr); 492e5c89e4eSSatish Balay ierr = PetscMemoryGetMaximumUsage(&residentmax);CHKERRQ(ierr); 493e5c89e4eSSatish Balay if (residentmax > 0) residentmax = PetscMax(resident,residentmax); 494e5c89e4eSSatish Balay ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 495e5c89e4eSSatish Balay ierr = PetscViewerASCIIPrintf(viewer,message);CHKERRQ(ierr); 496e5c89e4eSSatish Balay if (resident && residentmax && allocated) { 4970841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 4980841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 4990841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5000841954dSBarry 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); 5010841954dSBarry Smith ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5020841954dSBarry Smith ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5030841954dSBarry Smith ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5040841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr); 5050841954dSBarry Smith ierr = MPI_Reduce(&allocatedmax,&gallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5060841954dSBarry Smith ierr = MPI_Reduce(&allocatedmax,&maxgallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5070841954dSBarry Smith ierr = MPI_Reduce(&allocatedmax,&mingallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5080841954dSBarry 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); 5090841954dSBarry Smith ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5100841954dSBarry Smith ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5110841954dSBarry Smith ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5120841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr); 513e5c89e4eSSatish Balay } else if (resident && residentmax) { 5140841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5150841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5160841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5170841954dSBarry 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); 5180841954dSBarry Smith ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5190841954dSBarry Smith ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5200841954dSBarry Smith ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5210841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr); 522e5c89e4eSSatish Balay } else if (resident && allocated) { 5230841954dSBarry Smith ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5240841954dSBarry Smith ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5250841954dSBarry Smith ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5260841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr); 5270841954dSBarry Smith ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5280841954dSBarry Smith ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5290841954dSBarry Smith ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5300841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr); 5310841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n");CHKERRQ(ierr); 532e5c89e4eSSatish Balay } else if (allocated) { 5330841954dSBarry Smith ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5340841954dSBarry Smith ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5350841954dSBarry Smith ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5360841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr); 5370841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n");CHKERRQ(ierr); 5380841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"OS cannot compute process memory\n");CHKERRQ(ierr); 539e5c89e4eSSatish Balay } else { 540e5c89e4eSSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"Run with -malloc to get statistics on PetscMalloc() calls\nOS cannot compute process memory\n");CHKERRQ(ierr); 541e5c89e4eSSatish Balay } 542e5c89e4eSSatish Balay ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 543e5c89e4eSSatish Balay PetscFunctionReturn(0); 544e5c89e4eSSatish Balay } 545e5c89e4eSSatish Balay 54646eb3923SBarry Smith /*@ 547e5c89e4eSSatish Balay PetscMallocGetCurrentUsage - gets the current amount of memory used that was PetscMalloc()ed 548e5c89e4eSSatish Balay 549e5c89e4eSSatish Balay Not Collective 550e5c89e4eSSatish Balay 551e5c89e4eSSatish Balay Output Parameters: 552e5c89e4eSSatish Balay . space - number of bytes currently allocated 553e5c89e4eSSatish Balay 554e5c89e4eSSatish Balay Level: intermediate 555e5c89e4eSSatish Balay 556e5c89e4eSSatish Balay .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 557e5c89e4eSSatish Balay PetscMemoryGetMaximumUsage() 558e5c89e4eSSatish Balay @*/ 5597087cfbeSBarry Smith PetscErrorCode PetscMallocGetCurrentUsage(PetscLogDouble *space) 560e5c89e4eSSatish Balay { 561e5c89e4eSSatish Balay PetscFunctionBegin; 562e5c89e4eSSatish Balay *space = (PetscLogDouble) TRallocated; 563e5c89e4eSSatish Balay PetscFunctionReturn(0); 564e5c89e4eSSatish Balay } 565e5c89e4eSSatish Balay 566dc37d89fSBarry Smith /*@ 567e5c89e4eSSatish Balay PetscMallocGetMaximumUsage - gets the maximum amount of memory used that was PetscMalloc()ed at any time 568e5c89e4eSSatish Balay during this run. 569e5c89e4eSSatish Balay 570e5c89e4eSSatish Balay Not Collective 571e5c89e4eSSatish Balay 572e5c89e4eSSatish Balay Output Parameters: 573e5c89e4eSSatish Balay . space - maximum number of bytes ever allocated at one time 574e5c89e4eSSatish Balay 575e5c89e4eSSatish Balay Level: intermediate 576e5c89e4eSSatish Balay 577e5c89e4eSSatish Balay .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 578e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage() 579e5c89e4eSSatish Balay @*/ 5807087cfbeSBarry Smith PetscErrorCode PetscMallocGetMaximumUsage(PetscLogDouble *space) 581e5c89e4eSSatish Balay { 582e5c89e4eSSatish Balay PetscFunctionBegin; 583e5c89e4eSSatish Balay *space = (PetscLogDouble) TRMaxMem; 584e5c89e4eSSatish Balay PetscFunctionReturn(0); 585e5c89e4eSSatish Balay } 586e5c89e4eSSatish Balay 587e3ed9ee7SBarry Smith /*@ 588e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage - Adds another event to collect the maximum memory usage over an event 589e3ed9ee7SBarry Smith 590e3ed9ee7SBarry Smith Not Collective 591e3ed9ee7SBarry Smith 592e3ed9ee7SBarry Smith Input Parameter: 593e3ed9ee7SBarry Smith . event - an event id; this is just for error checking 594e3ed9ee7SBarry Smith 595e3ed9ee7SBarry Smith Level: developer 596e3ed9ee7SBarry Smith 597e3ed9ee7SBarry Smith .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 598e3ed9ee7SBarry Smith PetscMallocPopMaximumUsage() 599e3ed9ee7SBarry Smith @*/ 600e3ed9ee7SBarry Smith PetscErrorCode PetscMallocPushMaximumUsage(int event) 601e3ed9ee7SBarry Smith { 602e3ed9ee7SBarry Smith PetscFunctionBegin; 603e3ed9ee7SBarry Smith if (++NumTRMaxMems > MAXTRMAXMEMS) PetscFunctionReturn(0); 604e3ed9ee7SBarry Smith TRMaxMems[NumTRMaxMems-1] = TRallocated; 605e3ed9ee7SBarry Smith TRMaxMemsEvents[NumTRMaxMems-1] = event; 606e3ed9ee7SBarry Smith PetscFunctionReturn(0); 607e3ed9ee7SBarry Smith } 608e3ed9ee7SBarry Smith 609e3ed9ee7SBarry Smith /*@ 610e3ed9ee7SBarry Smith PetscMallocPopMaximumUsage - collect the maximum memory usage over an event 611e3ed9ee7SBarry Smith 612e3ed9ee7SBarry Smith Not Collective 613e3ed9ee7SBarry Smith 614e3ed9ee7SBarry Smith Input Parameter: 615e3ed9ee7SBarry Smith . event - an event id; this is just for error checking 616e3ed9ee7SBarry Smith 617e3ed9ee7SBarry Smith Output Parameter: 618e3ed9ee7SBarry Smith . mu - maximum amount of memory malloced during this event; high water mark relative to the beginning of the event 619e3ed9ee7SBarry Smith 620e3ed9ee7SBarry Smith Level: developer 621e3ed9ee7SBarry Smith 622e3ed9ee7SBarry Smith .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 623e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage() 624e3ed9ee7SBarry Smith @*/ 625e3ed9ee7SBarry Smith PetscErrorCode PetscMallocPopMaximumUsage(int event,PetscLogDouble *mu) 626e3ed9ee7SBarry Smith { 627e3ed9ee7SBarry Smith PetscFunctionBegin; 628e3ed9ee7SBarry Smith *mu = 0; 629e3ed9ee7SBarry Smith if (NumTRMaxMems-- > MAXTRMAXMEMS) PetscFunctionReturn(0); 630e3ed9ee7SBarry Smith if (TRMaxMemsEvents[NumTRMaxMems] != event) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"PetscMallocPush/PopMaximumUsage() are not nested"); 631e3ed9ee7SBarry Smith *mu = TRMaxMems[NumTRMaxMems]; 632e3ed9ee7SBarry Smith PetscFunctionReturn(0); 633e3ed9ee7SBarry Smith } 634e3ed9ee7SBarry Smith 635a64a8e02SBarry Smith #if defined(PETSC_USE_DEBUG) 636a64a8e02SBarry Smith /*@C 637a64a8e02SBarry Smith PetscMallocGetStack - returns a pointer to the stack for the location in the program a call to PetscMalloc() was used to obtain that memory 638a64a8e02SBarry Smith 639a64a8e02SBarry Smith Collective on PETSC_COMM_WORLD 640a64a8e02SBarry Smith 641a64a8e02SBarry Smith Input Parameter: 642a64a8e02SBarry Smith . ptr - the memory location 643a64a8e02SBarry Smith 644a64a8e02SBarry Smith Output Paramter: 645a64a8e02SBarry Smith . stack - the stack indicating where the program allocated this memory 646a64a8e02SBarry Smith 647a64a8e02SBarry Smith Level: intermediate 648a64a8e02SBarry Smith 649a64a8e02SBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocDumpLog() 650a64a8e02SBarry Smith @*/ 651a64a8e02SBarry Smith PetscErrorCode PetscMallocGetStack(void *ptr,PetscStack **stack) 652a64a8e02SBarry Smith { 653a64a8e02SBarry Smith TRSPACE *head; 654a64a8e02SBarry Smith 655a64a8e02SBarry Smith PetscFunctionBegin; 656a64a8e02SBarry Smith head = (TRSPACE*) (((char*)ptr) - HEADER_BYTES); 657a64a8e02SBarry Smith *stack = &head->stack; 658a64a8e02SBarry Smith PetscFunctionReturn(0); 659a64a8e02SBarry Smith } 66076386721SLisandro Dalcin #else 66176386721SLisandro Dalcin PetscErrorCode PetscMallocGetStack(void *ptr,void **stack) 66276386721SLisandro Dalcin { 66376386721SLisandro Dalcin PetscFunctionBegin; 664f0ba7cfcSLisandro Dalcin *stack = NULL; 66576386721SLisandro Dalcin PetscFunctionReturn(0); 66676386721SLisandro Dalcin } 667a64a8e02SBarry Smith #endif 668a64a8e02SBarry Smith 669e5c89e4eSSatish Balay /*@C 670e5c89e4eSSatish Balay PetscMallocDump - Dumps the allocated memory blocks to a file. The information 671e5c89e4eSSatish Balay printed is: size of space (in bytes), address of space, id of space, 672e5c89e4eSSatish Balay file in which space was allocated, and line number at which it was 673e5c89e4eSSatish Balay allocated. 674e5c89e4eSSatish Balay 675e5c89e4eSSatish Balay Collective on PETSC_COMM_WORLD 676e5c89e4eSSatish Balay 677e5c89e4eSSatish Balay Input Parameter: 678e5c89e4eSSatish Balay . fp - file pointer. If fp is NULL, stdout is assumed. 679e5c89e4eSSatish Balay 680e5c89e4eSSatish Balay Options Database Key: 681e5c89e4eSSatish Balay . -malloc_dump - Dumps unfreed memory during call to PetscFinalize() 682e5c89e4eSSatish Balay 683e5c89e4eSSatish Balay Level: intermediate 684e5c89e4eSSatish Balay 685e5c89e4eSSatish Balay Fortran Note: 686e5c89e4eSSatish Balay The calling sequence in Fortran is PetscMallocDump(integer ierr) 687e5c89e4eSSatish Balay The fp defaults to stdout. 688e5c89e4eSSatish Balay 68995452b02SPatrick Sanan Notes: 69095452b02SPatrick Sanan uses MPI_COMM_WORLD, because this may be called in PetscFinalize() after PETSC_COMM_WORLD 691e5c89e4eSSatish Balay has been freed. 692e5c89e4eSSatish Balay 6939e9a1f8fSvictor .seealso: PetscMallocGetCurrentUsage(), PetscMallocDumpLog() 694e5c89e4eSSatish Balay @*/ 6957087cfbeSBarry Smith PetscErrorCode PetscMallocDump(FILE *fp) 696e5c89e4eSSatish Balay { 697e5c89e4eSSatish Balay TRSPACE *head; 698e3ed9ee7SBarry Smith size_t libAlloc = 0; 699e5c89e4eSSatish Balay PetscErrorCode ierr; 700e5c89e4eSSatish Balay PetscMPIInt rank; 701e5c89e4eSSatish Balay 702e5c89e4eSSatish Balay PetscFunctionBegin; 703e5c89e4eSSatish Balay ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr); 704da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 705e5c89e4eSSatish Balay head = TRhead; 706e5c89e4eSSatish Balay while (head) { 7075486ca60SMatthew G. Knepley libAlloc += head->size; 7085486ca60SMatthew G. Knepley head = head->next; 7095486ca60SMatthew G. Knepley } 7105486ca60SMatthew G. Knepley if (TRallocated - libAlloc > 0) fprintf(fp,"[%d]Total space allocated %.0f bytes\n",rank,(PetscLogDouble)TRallocated); 7115486ca60SMatthew G. Knepley head = TRhead; 7125486ca60SMatthew G. Knepley while (head) { 7135486ca60SMatthew G. Knepley PetscBool isLib; 7145486ca60SMatthew G. Knepley 7155486ca60SMatthew G. Knepley ierr = PetscStrcmp(head->functionname, "PetscDLLibraryOpen", &isLib);CHKERRQ(ierr); 7165486ca60SMatthew G. Knepley if (!isLib) { 717efca3c55SSatish Balay fprintf(fp,"[%2d]%.0f bytes %s() line %d in %s\n",rank,(PetscLogDouble)head->size,head->functionname,head->lineno,head->filename); 7188bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 719e5c89e4eSSatish Balay ierr = PetscStackPrint(&head->stack,fp);CHKERRQ(ierr); 720e5c89e4eSSatish Balay #endif 7215486ca60SMatthew G. Knepley } 722e5c89e4eSSatish Balay head = head->next; 723e5c89e4eSSatish Balay } 724e5c89e4eSSatish Balay PetscFunctionReturn(0); 725e5c89e4eSSatish Balay } 726e5c89e4eSSatish Balay 727e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------- */ 728e5c89e4eSSatish Balay 729dc37d89fSBarry Smith /*@ 730e5c89e4eSSatish Balay PetscMallocSetDumpLog - Activates logging of all calls to PetscMalloc(). 731e5c89e4eSSatish Balay 732e5c89e4eSSatish Balay Not Collective 733e5c89e4eSSatish Balay 734e5c89e4eSSatish Balay Options Database Key: 735574034a9SJed Brown + -malloc_log <filename> - Activates PetscMallocDumpLog() 736574034a9SJed Brown - -malloc_log_threshold <min> - Activates logging and sets a minimum size 737e5c89e4eSSatish Balay 738e5c89e4eSSatish Balay Level: advanced 739e5c89e4eSSatish Balay 740574034a9SJed Brown .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocSetDumpLogThreshold() 741e5c89e4eSSatish Balay @*/ 7427087cfbeSBarry Smith PetscErrorCode PetscMallocSetDumpLog(void) 743e5c89e4eSSatish Balay { 74421b680ceSJed Brown PetscErrorCode ierr; 74521b680ceSJed Brown 746e5c89e4eSSatish Balay PetscFunctionBegin; 747e5c89e4eSSatish Balay PetscLogMalloc = 0; 748a297a907SKarl Rupp 74921b680ceSJed Brown ierr = PetscMemorySetGetMaximumUsage();CHKERRQ(ierr); 750e5c89e4eSSatish Balay PetscFunctionReturn(0); 751e5c89e4eSSatish Balay } 752e5c89e4eSSatish Balay 753dc37d89fSBarry Smith /*@ 754574034a9SJed Brown PetscMallocSetDumpLogThreshold - Activates logging of all calls to PetscMalloc(). 755574034a9SJed Brown 756574034a9SJed Brown Not Collective 757574034a9SJed Brown 758574034a9SJed Brown Input Arguments: 759574034a9SJed Brown . logmin - minimum allocation size to log, or PETSC_DEFAULT 760574034a9SJed Brown 761574034a9SJed Brown Options Database Key: 762574034a9SJed Brown + -malloc_log <filename> - Activates PetscMallocDumpLog() 763574034a9SJed Brown - -malloc_log_threshold <min> - Activates logging and sets a minimum size 764574034a9SJed Brown 765574034a9SJed Brown Level: advanced 766574034a9SJed Brown 767574034a9SJed Brown .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocSetDumpLog() 768574034a9SJed Brown @*/ 769574034a9SJed Brown PetscErrorCode PetscMallocSetDumpLogThreshold(PetscLogDouble logmin) 770574034a9SJed Brown { 771574034a9SJed Brown PetscErrorCode ierr; 772574034a9SJed Brown 773574034a9SJed Brown PetscFunctionBegin; 774574034a9SJed Brown ierr = PetscMallocSetDumpLog();CHKERRQ(ierr); 775574034a9SJed Brown if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */ 776574034a9SJed Brown PetscLogMallocThreshold = (size_t)logmin; 777574034a9SJed Brown PetscFunctionReturn(0); 778574034a9SJed Brown } 779574034a9SJed Brown 780dc37d89fSBarry Smith /*@ 78118a2528dSJed Brown PetscMallocGetDumpLog - Determine whether all calls to PetscMalloc() are being logged 78218a2528dSJed Brown 78318a2528dSJed Brown Not Collective 78418a2528dSJed Brown 78518a2528dSJed Brown Output Arguments 78618a2528dSJed Brown . logging - PETSC_TRUE if logging is active 78718a2528dSJed Brown 78818a2528dSJed Brown Options Database Key: 78918a2528dSJed Brown . -malloc_log - Activates PetscMallocDumpLog() 79018a2528dSJed Brown 79118a2528dSJed Brown Level: advanced 79218a2528dSJed Brown 79318a2528dSJed Brown .seealso: PetscMallocDump(), PetscMallocDumpLog() 79418a2528dSJed Brown @*/ 79518a2528dSJed Brown PetscErrorCode PetscMallocGetDumpLog(PetscBool *logging) 79618a2528dSJed Brown { 79718a2528dSJed Brown 79818a2528dSJed Brown PetscFunctionBegin; 79918a2528dSJed Brown *logging = (PetscBool)(PetscLogMalloc >= 0); 80018a2528dSJed Brown PetscFunctionReturn(0); 80118a2528dSJed Brown } 80218a2528dSJed Brown 803e5c89e4eSSatish Balay /*@C 804e5c89e4eSSatish Balay PetscMallocDumpLog - Dumps the log of all calls to PetscMalloc(); also calls 80521b680ceSJed Brown PetscMemoryGetMaximumUsage() 806e5c89e4eSSatish Balay 807e5c89e4eSSatish Balay Collective on PETSC_COMM_WORLD 808e5c89e4eSSatish Balay 809e5c89e4eSSatish Balay Input Parameter: 8100298fd71SBarry Smith . fp - file pointer; or NULL 811e5c89e4eSSatish Balay 812e5c89e4eSSatish Balay Options Database Key: 813e5c89e4eSSatish Balay . -malloc_log - Activates PetscMallocDumpLog() 814e5c89e4eSSatish Balay 815e5c89e4eSSatish Balay Level: advanced 816e5c89e4eSSatish Balay 817e5c89e4eSSatish Balay Fortran Note: 818e5c89e4eSSatish Balay The calling sequence in Fortran is PetscMallocDumpLog(integer ierr) 819e5c89e4eSSatish Balay The fp defaults to stdout. 820e5c89e4eSSatish Balay 821e5c89e4eSSatish Balay .seealso: PetscMallocGetCurrentUsage(), PetscMallocDump(), PetscMallocSetDumpLog() 822e5c89e4eSSatish Balay @*/ 8237087cfbeSBarry Smith PetscErrorCode PetscMallocDumpLog(FILE *fp) 824e5c89e4eSSatish Balay { 825e5c89e4eSSatish Balay PetscInt i,j,n,dummy,*perm; 826e5c89e4eSSatish Balay size_t *shortlength; 827f56c2debSBarry Smith int *shortcount,err; 828e5c89e4eSSatish Balay PetscMPIInt rank,size,tag = 1212 /* very bad programming */; 829ace3abfcSBarry Smith PetscBool match; 830e5c89e4eSSatish Balay const char **shortfunction; 831e5c89e4eSSatish Balay PetscLogDouble rss; 832e5c89e4eSSatish Balay MPI_Status status; 833e5c89e4eSSatish Balay PetscErrorCode ierr; 834e5c89e4eSSatish Balay 835e5c89e4eSSatish Balay PetscFunctionBegin; 836e5c89e4eSSatish Balay ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr); 837e5c89e4eSSatish Balay ierr = MPI_Comm_size(MPI_COMM_WORLD,&size);CHKERRQ(ierr); 838e5c89e4eSSatish Balay /* 839e5c89e4eSSatish Balay Try to get the data printed in order by processor. This will only sometimes work 840e5c89e4eSSatish Balay */ 841f56c2debSBarry Smith err = fflush(fp); 842e32f2f54SBarry Smith if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 843f56c2debSBarry Smith 844e5c89e4eSSatish Balay ierr = MPI_Barrier(MPI_COMM_WORLD);CHKERRQ(ierr); 845e5c89e4eSSatish Balay if (rank) { 846e5c89e4eSSatish Balay ierr = MPI_Recv(&dummy,1,MPIU_INT,rank-1,tag,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 847e5c89e4eSSatish Balay } 848e5c89e4eSSatish Balay 849768aa557SSatish Balay if (PetscLogMalloc < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"PetscMallocDumpLog() called without call to PetscMallocSetDumpLog() this is often due to\n setting the option -malloc_log AFTER PetscInitialize() with PetscOptionsInsert() or PetscOptionsInsertFile()"); 850768aa557SSatish Balay 851da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 852f3d65365SJed Brown ierr = PetscMemoryGetMaximumUsage(&rss);CHKERRQ(ierr); 853e5c89e4eSSatish Balay if (rss) { 854f3d65365SJed Brown ierr = PetscFPrintf(MPI_COMM_WORLD,fp,"[%d] Maximum memory PetscMalloc()ed %.0f maximum size of entire process %.0f\n",rank,(PetscLogDouble)TRMaxMem,rss);CHKERRQ(ierr); 855e5c89e4eSSatish Balay } else { 856e5c89e4eSSatish Balay ierr = PetscFPrintf(MPI_COMM_WORLD,fp,"[%d] Maximum memory PetscMalloc()ed %.0f OS cannot compute size of entire process\n",rank,(PetscLogDouble)TRMaxMem);CHKERRQ(ierr); 857e5c89e4eSSatish Balay } 858e32f2f54SBarry Smith shortcount = (int*)malloc(PetscLogMalloc*sizeof(int));if (!shortcount) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 859e32f2f54SBarry Smith shortlength = (size_t*)malloc(PetscLogMalloc*sizeof(size_t));if (!shortlength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 860e32f2f54SBarry Smith shortfunction = (const char**)malloc(PetscLogMalloc*sizeof(char*));if (!shortfunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 86197b9d747SJed Brown for (i=0,n=0; i<PetscLogMalloc; i++) { 862e5c89e4eSSatish Balay for (j=0; j<n; j++) { 863e5c89e4eSSatish Balay ierr = PetscStrcmp(shortfunction[j],PetscLogMallocFunction[i],&match);CHKERRQ(ierr); 864e5c89e4eSSatish Balay if (match) { 865e5c89e4eSSatish Balay shortlength[j] += PetscLogMallocLength[i]; 86659ffdab8SBarry Smith shortcount[j]++; 867e5c89e4eSSatish Balay goto foundit; 868e5c89e4eSSatish Balay } 869e5c89e4eSSatish Balay } 870e5c89e4eSSatish Balay shortfunction[n] = PetscLogMallocFunction[i]; 871e5c89e4eSSatish Balay shortlength[n] = PetscLogMallocLength[i]; 87259ffdab8SBarry Smith shortcount[n] = 1; 873e5c89e4eSSatish Balay n++; 874e5c89e4eSSatish Balay foundit:; 875e5c89e4eSSatish Balay } 876e5c89e4eSSatish Balay 877e32f2f54SBarry Smith perm = (PetscInt*)malloc(n*sizeof(PetscInt));if (!perm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 878e5c89e4eSSatish Balay for (i=0; i<n; i++) perm[i] = i; 879e5c89e4eSSatish Balay ierr = PetscSortStrWithPermutation(n,(const char**)shortfunction,perm);CHKERRQ(ierr); 880e5c89e4eSSatish Balay 881e5c89e4eSSatish Balay ierr = PetscFPrintf(MPI_COMM_WORLD,fp,"[%d] Memory usage sorted by function\n",rank);CHKERRQ(ierr); 882e5c89e4eSSatish Balay for (i=0; i<n; i++) { 88359ffdab8SBarry Smith ierr = PetscFPrintf(MPI_COMM_WORLD,fp,"[%d] %d %.0f %s()\n",rank,shortcount[perm[i]],(PetscLogDouble)shortlength[perm[i]],shortfunction[perm[i]]);CHKERRQ(ierr); 884e5c89e4eSSatish Balay } 885e5c89e4eSSatish Balay free(perm); 886e5c89e4eSSatish Balay free(shortlength); 88759ffdab8SBarry Smith free(shortcount); 888e5c89e4eSSatish Balay free((char**)shortfunction); 889f56c2debSBarry Smith err = fflush(fp); 890e32f2f54SBarry Smith if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 891e5c89e4eSSatish Balay if (rank != size-1) { 892e5c89e4eSSatish Balay ierr = MPI_Send(&dummy,1,MPIU_INT,rank+1,tag,MPI_COMM_WORLD);CHKERRQ(ierr); 893e5c89e4eSSatish Balay } 894e5c89e4eSSatish Balay PetscFunctionReturn(0); 895e5c89e4eSSatish Balay } 896e5c89e4eSSatish Balay 897e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------- */ 898e5c89e4eSSatish Balay 899dc37d89fSBarry Smith /*@ 900e5c89e4eSSatish Balay PetscMallocDebug - Turns on/off debugging for the memory management routines. 901e5c89e4eSSatish Balay 902e5c89e4eSSatish Balay Not Collective 903e5c89e4eSSatish Balay 904e5c89e4eSSatish Balay Input Parameter: 905e5c89e4eSSatish Balay . level - PETSC_TRUE or PETSC_FALSE 906e5c89e4eSSatish Balay 907e5c89e4eSSatish Balay Level: intermediate 908e5c89e4eSSatish Balay 909e5c89e4eSSatish Balay .seealso: CHKMEMQ(), PetscMallocValidate() 910e5c89e4eSSatish Balay @*/ 9117087cfbeSBarry Smith PetscErrorCode PetscMallocDebug(PetscBool level) 912e5c89e4eSSatish Balay { 913e5c89e4eSSatish Balay PetscFunctionBegin; 914e5c89e4eSSatish Balay TRdebugLevel = level; 915e5c89e4eSSatish Balay PetscFunctionReturn(0); 916e5c89e4eSSatish Balay } 9170acecf5bSBarry Smith 918dc37d89fSBarry Smith /*@ 9190acecf5bSBarry Smith PetscMallocGetDebug - Indicates if any PETSc is doing ANY memory debugging. 9200acecf5bSBarry Smith 9210acecf5bSBarry Smith Not Collective 9220acecf5bSBarry Smith 9230acecf5bSBarry Smith Output Parameter: 9240acecf5bSBarry Smith . flg - PETSC_TRUE if any debugger 9250acecf5bSBarry Smith 9260acecf5bSBarry Smith Level: intermediate 9270acecf5bSBarry Smith 9280acecf5bSBarry Smith Note that by default, the debug version always does some debugging unless you run with -malloc no 9290acecf5bSBarry Smith 9300acecf5bSBarry Smith 9310acecf5bSBarry Smith .seealso: CHKMEMQ(), PetscMallocValidate() 9320acecf5bSBarry Smith @*/ 9330acecf5bSBarry Smith PetscErrorCode PetscMallocGetDebug(PetscBool *flg) 9340acecf5bSBarry Smith { 9350acecf5bSBarry Smith PetscFunctionBegin; 9360acecf5bSBarry Smith if (PetscTrMalloc == PetscTrMallocDefault) *flg = PETSC_TRUE; 9370acecf5bSBarry Smith else *flg = PETSC_FALSE; 9380acecf5bSBarry Smith PetscFunctionReturn(0); 9390acecf5bSBarry Smith } 940