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 */ 16*071fcb05SBarry 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**); 19*071fcb05SBarry 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: 114e5c89e4eSSatish Balay You should generally use CHKMEMQ as a short cut for calling this 115e5c89e4eSSatish Balay routine. 116e5c89e4eSSatish Balay 117efca3c55SSatish Balay The line, function, file are given by the C preprocessor as 118e5c89e4eSSatish Balay 119e5c89e4eSSatish Balay The Fortran calling sequence is simply PetscMallocValidate(ierr) 120e5c89e4eSSatish Balay 121e5c89e4eSSatish Balay No output is generated if there are no problems detected. 122e5c89e4eSSatish Balay 123e5c89e4eSSatish Balay .seealso: CHKMEMQ 124e5c89e4eSSatish Balay 125e5c89e4eSSatish Balay @*/ 126efca3c55SSatish Balay PetscErrorCode PetscMallocValidate(int line,const char function[],const char file[]) 127e5c89e4eSSatish Balay { 1286c093d5bSvictor TRSPACE *head,*lasthead; 129e5c89e4eSSatish Balay char *a; 1300700a824SBarry Smith PetscClassId *nend; 131e5c89e4eSSatish Balay 132e5c89e4eSSatish Balay PetscFunctionBegin; 1336c093d5bSvictor head = TRhead; lasthead = NULL; 134e5c89e4eSSatish Balay while (head) { 1350700a824SBarry Smith if (head->classid != CLASSID_VALUE) { 136efca3c55SSatish Balay (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 137e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory at address %p is corrupted\n",head); 138e5c89e4eSSatish Balay (*PetscErrorPrintf)("Probably write past beginning or end of array\n"); 139efca3c55SSatish Balay if (lasthead) (*PetscErrorPrintf)("Last intact block allocated in %s() line %d in %s\n",lasthead->functionname,lasthead->lineno,lasthead->filename); 140e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 141e5c89e4eSSatish Balay } 142e5c89e4eSSatish Balay a = (char*)(((TrSPACE*)head) + 1); 1430700a824SBarry Smith nend = (PetscClassId*)(a + head->size); 1440700a824SBarry Smith if (*nend != CLASSID_VALUE) { 145efca3c55SSatish Balay (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 146e5c89e4eSSatish Balay if (*nend == ALREADY_FREED) { 147e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p already freed\n",head->id,(PetscLogDouble)head->size,a); 148e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 149e5c89e4eSSatish Balay } else { 150e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 151efca3c55SSatish Balay (*PetscErrorPrintf)("Memory originally allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 152e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 153e5c89e4eSSatish Balay } 154e5c89e4eSSatish Balay } 1556c093d5bSvictor lasthead = head; 156e5c89e4eSSatish Balay head = head->next; 157e5c89e4eSSatish Balay } 158e5c89e4eSSatish Balay PetscFunctionReturn(0); 159e5c89e4eSSatish Balay } 160e5c89e4eSSatish Balay 161e5c89e4eSSatish Balay /* 162e5c89e4eSSatish Balay PetscTrMallocDefault - Malloc with tracing. 163e5c89e4eSSatish Balay 164e5c89e4eSSatish Balay Input Parameters: 165e5c89e4eSSatish Balay + a - number of bytes to allocate 166e5c89e4eSSatish Balay . lineno - line number where used. Use __LINE__ for this 167efca3c55SSatish Balay - filename - file name where used. Use __FILE__ for this 168e5c89e4eSSatish Balay 169e5c89e4eSSatish Balay Returns: 170e5c89e4eSSatish Balay double aligned pointer to requested storage, or null if not 171e5c89e4eSSatish Balay available. 172e5c89e4eSSatish Balay */ 173*071fcb05SBarry Smith PetscErrorCode PetscTrMallocDefault(size_t a,PetscBool clear,int lineno,const char function[],const char filename[],void **result) 174e5c89e4eSSatish Balay { 175e5c89e4eSSatish Balay TRSPACE *head; 176e5c89e4eSSatish Balay char *inew; 177e5c89e4eSSatish Balay size_t nsize; 178e5c89e4eSSatish Balay PetscErrorCode ierr; 179e5c89e4eSSatish Balay 180e5c89e4eSSatish Balay PetscFunctionBegin; 181f0ba7cfcSLisandro Dalcin /* Do not try to handle empty blocks */ 182f0ba7cfcSLisandro Dalcin if (!a) { *result = NULL; PetscFunctionReturn(0); } 183f0ba7cfcSLisandro Dalcin 184e5c89e4eSSatish Balay if (TRdebugLevel) { 185efca3c55SSatish Balay ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr); 186e5c89e4eSSatish Balay } 187e5c89e4eSSatish Balay 18825b53cc9SJed Brown nsize = (a + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1); 189*071fcb05SBarry Smith ierr = PetscMallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),clear,lineno,function,filename,(void**)&inew);CHKERRQ(ierr); 190e3ed9ee7SBarry Smith 191e5c89e4eSSatish Balay head = (TRSPACE*)inew; 192e5c89e4eSSatish Balay inew += sizeof(TrSPACE); 193e5c89e4eSSatish Balay 194e5c89e4eSSatish Balay if (TRhead) TRhead->prev = head; 195e5c89e4eSSatish Balay head->next = TRhead; 196e5c89e4eSSatish Balay TRhead = head; 197f0ba7cfcSLisandro Dalcin head->prev = NULL; 198e5c89e4eSSatish Balay head->size = nsize; 199e5c89e4eSSatish Balay head->id = TRid; 200e5c89e4eSSatish Balay head->lineno = lineno; 201e5c89e4eSSatish Balay 202e5c89e4eSSatish Balay head->filename = filename; 203e5c89e4eSSatish Balay head->functionname = function; 2040700a824SBarry Smith head->classid = CLASSID_VALUE; 2050700a824SBarry Smith *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 206e5c89e4eSSatish Balay 207e5c89e4eSSatish Balay TRallocated += nsize; 208a297a907SKarl Rupp if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 209e3ed9ee7SBarry Smith if (PetscLogMemory) { 210e3ed9ee7SBarry Smith PetscInt i; 211e3ed9ee7SBarry Smith for (i=0; i<NumTRMaxMems; i++) { 212e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 213e3ed9ee7SBarry Smith } 214e3ed9ee7SBarry Smith } 215e5c89e4eSSatish Balay TRfrags++; 216e5c89e4eSSatish Balay 2178bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 21876386721SLisandro Dalcin if (PetscStackActive()) { 2195c25fcd7SBarry Smith ierr = PetscStackCopy(petscstack,&head->stack);CHKERRQ(ierr); 2202c9581d2SBarry Smith /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 2212c9581d2SBarry Smith head->stack.line[head->stack.currentsize-2] = lineno; 2229de0f6ecSBarry Smith } else { 2239de0f6ecSBarry Smith head->stack.currentsize = 0; 22476386721SLisandro Dalcin } 225e5c89e4eSSatish Balay #endif 226e5c89e4eSSatish Balay 227e5c89e4eSSatish Balay /* 228e5c89e4eSSatish Balay Allow logging of all mallocs made 229e5c89e4eSSatish Balay */ 230574034a9SJed Brown if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && a >= PetscLogMallocThreshold) { 231e5c89e4eSSatish Balay if (!PetscLogMalloc) { 232e5c89e4eSSatish Balay PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 233e32f2f54SBarry Smith if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 234a297a907SKarl Rupp 235a2ea699eSBarry Smith PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 236e32f2f54SBarry Smith if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 237a297a907SKarl Rupp 238a2ea699eSBarry Smith PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 239e32f2f54SBarry Smith if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 240e5c89e4eSSatish Balay } 241e5c89e4eSSatish Balay PetscLogMallocLength[PetscLogMalloc] = nsize; 242e5c89e4eSSatish Balay PetscLogMallocFile[PetscLogMalloc] = filename; 243e5c89e4eSSatish Balay PetscLogMallocFunction[PetscLogMalloc++] = function; 244e5c89e4eSSatish Balay } 245e5c89e4eSSatish Balay *result = (void*)inew; 246e5c89e4eSSatish Balay PetscFunctionReturn(0); 247e5c89e4eSSatish Balay } 248e5c89e4eSSatish Balay 249e5c89e4eSSatish Balay 250e5c89e4eSSatish Balay /* 251e5c89e4eSSatish Balay PetscTrFreeDefault - Free with tracing. 252e5c89e4eSSatish Balay 253e5c89e4eSSatish Balay Input Parameters: 254e5c89e4eSSatish Balay . a - pointer to a block allocated with PetscTrMalloc 255e5c89e4eSSatish Balay . lineno - line number where used. Use __LINE__ for this 256e5c89e4eSSatish Balay . file - file name where used. Use __FILE__ for this 257e5c89e4eSSatish Balay */ 258efca3c55SSatish Balay PetscErrorCode PetscTrFreeDefault(void *aa,int line,const char function[],const char file[]) 259e5c89e4eSSatish Balay { 260e5c89e4eSSatish Balay char *a = (char*)aa; 261e5c89e4eSSatish Balay TRSPACE *head; 262e5c89e4eSSatish Balay char *ahead; 263e5c89e4eSSatish Balay PetscErrorCode ierr; 2640700a824SBarry Smith PetscClassId *nend; 265e5c89e4eSSatish Balay 266e5c89e4eSSatish Balay PetscFunctionBegin; 267e5c89e4eSSatish Balay /* Do not try to handle empty blocks */ 26849d7da52SJed Brown if (!a) PetscFunctionReturn(0); 269e5c89e4eSSatish Balay 270e5c89e4eSSatish Balay if (TRdebugLevel) { 271efca3c55SSatish Balay ierr = PetscMallocValidate(line,function,file);CHKERRQ(ierr); 272e5c89e4eSSatish Balay } 273e5c89e4eSSatish Balay 274e5c89e4eSSatish Balay ahead = a; 275e5c89e4eSSatish Balay a = a - sizeof(TrSPACE); 276e5c89e4eSSatish Balay head = (TRSPACE*)a; 277e5c89e4eSSatish Balay 2780700a824SBarry Smith if (head->classid != CLASSID_VALUE) { 279efca3c55SSatish Balay (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); 280e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 281e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); 282e5c89e4eSSatish Balay } 2830700a824SBarry Smith nend = (PetscClassId*)(ahead + head->size); 2840700a824SBarry Smith if (*nend != CLASSID_VALUE) { 285e5c89e4eSSatish Balay if (*nend == ALREADY_FREED) { 286efca3c55SSatish Balay (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); 287e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 288e5c89e4eSSatish Balay if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 289efca3c55SSatish Balay (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 290e5c89e4eSSatish Balay } else { 291efca3c55SSatish Balay (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename); 292e5c89e4eSSatish Balay } 293e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); 294e5c89e4eSSatish Balay } else { 295e5c89e4eSSatish Balay /* Damaged tail */ 296efca3c55SSatish Balay (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); 297e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 298efca3c55SSatish Balay (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 299e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); 300e5c89e4eSSatish Balay } 301e5c89e4eSSatish Balay } 302e5c89e4eSSatish Balay /* Mark the location freed */ 303e5c89e4eSSatish Balay *nend = ALREADY_FREED; 304e5c89e4eSSatish Balay /* Save location where freed. If we suspect the line number, mark as allocated location */ 305e5c89e4eSSatish Balay if (line > 0 && line < 50000) { 306e5c89e4eSSatish Balay head->lineno = line; 307e5c89e4eSSatish Balay head->filename = file; 308e5c89e4eSSatish Balay head->functionname = function; 309e5c89e4eSSatish Balay } else { 310e5c89e4eSSatish Balay head->lineno = -head->lineno; 311e5c89e4eSSatish Balay } 312e3ed9ee7SBarry Smith if (TRallocated < head->size) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"TRallocate is smaller than memory just freed"); 313e5c89e4eSSatish Balay TRallocated -= head->size; 314e5c89e4eSSatish Balay TRfrags--; 315e5c89e4eSSatish Balay if (head->prev) head->prev->next = head->next; 316e5c89e4eSSatish Balay else TRhead = head->next; 317e5c89e4eSSatish Balay 318e5c89e4eSSatish Balay if (head->next) head->next->prev = head->prev; 319efca3c55SSatish Balay ierr = PetscFreeAlign(a,line,function,file);CHKERRQ(ierr); 320e5c89e4eSSatish Balay PetscFunctionReturn(0); 321e5c89e4eSSatish Balay } 322e5c89e4eSSatish Balay 323e5c89e4eSSatish Balay 3243221ece2SMatthew G. Knepley 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 3323221ece2SMatthew G. Knepley - result - double aligned pointer to initial storage. 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; 351c22f1541SToby Isaac /* Realloc to zero = free */ 352c22f1541SToby Isaac if (!len) { 353c22f1541SToby Isaac ierr = PetscTrFreeDefault(*result,lineno,function,filename);CHKERRQ(ierr); 354c22f1541SToby Isaac *result = NULL; 355c22f1541SToby Isaac PetscFunctionReturn(0); 356c22f1541SToby Isaac } 357f590eff4SLisandro Dalcin /* Realloc with NULL = malloc */ 358f590eff4SLisandro Dalcin if (!*result) { 359*071fcb05SBarry Smith ierr = PetscTrMallocDefault(len,PETSC_FALSE,lineno,function,filename,result);CHKERRQ(ierr); 360f590eff4SLisandro Dalcin PetscFunctionReturn(0); 361f590eff4SLisandro Dalcin } 3623221ece2SMatthew G. Knepley 3633221ece2SMatthew G. Knepley if (TRdebugLevel) {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 3953221ece2SMatthew G. Knepley TRallocated -= head->size; 3963221ece2SMatthew G. Knepley TRfrags--; 3973221ece2SMatthew G. Knepley if (head->prev) head->prev->next = head->next; 3983221ece2SMatthew G. Knepley else TRhead = head->next; 3993221ece2SMatthew G. Knepley if (head->next) head->next->prev = head->prev; 4003221ece2SMatthew G. Knepley 4013221ece2SMatthew G. Knepley nsize = (len + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1); 4023221ece2SMatthew G. Knepley ierr = PetscReallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),lineno,function,filename,(void**)&inew);CHKERRQ(ierr); 4033221ece2SMatthew G. Knepley 4043221ece2SMatthew G. Knepley head = (TRSPACE*)inew; 4053221ece2SMatthew G. Knepley inew += sizeof(TrSPACE); 4063221ece2SMatthew G. Knepley 4073221ece2SMatthew G. Knepley if (TRhead) TRhead->prev = head; 4083221ece2SMatthew G. Knepley head->next = TRhead; 4093221ece2SMatthew G. Knepley TRhead = head; 4103221ece2SMatthew G. Knepley head->prev = NULL; 4113221ece2SMatthew G. Knepley head->size = nsize; 4123221ece2SMatthew G. Knepley head->id = TRid; 4133221ece2SMatthew G. Knepley head->lineno = lineno; 4143221ece2SMatthew G. Knepley 4153221ece2SMatthew G. Knepley head->filename = filename; 4163221ece2SMatthew G. Knepley head->functionname = function; 4173221ece2SMatthew G. Knepley head->classid = CLASSID_VALUE; 4183221ece2SMatthew G. Knepley *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 4193221ece2SMatthew G. Knepley 4203221ece2SMatthew G. Knepley TRallocated += nsize; 4213221ece2SMatthew G. Knepley if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 422e3ed9ee7SBarry Smith if (PetscLogMemory) { 423e3ed9ee7SBarry Smith PetscInt i; 424e3ed9ee7SBarry Smith for (i=0; i<NumTRMaxMems; i++) { 425e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 426e3ed9ee7SBarry Smith } 427e3ed9ee7SBarry Smith } 4283221ece2SMatthew G. Knepley TRfrags++; 4293221ece2SMatthew G. Knepley 4303221ece2SMatthew G. Knepley #if defined(PETSC_USE_DEBUG) 4313221ece2SMatthew G. Knepley if (PetscStackActive()) { 4323221ece2SMatthew G. Knepley ierr = PetscStackCopy(petscstack,&head->stack);CHKERRQ(ierr); 4333221ece2SMatthew G. Knepley /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 4343221ece2SMatthew G. Knepley head->stack.line[head->stack.currentsize-2] = lineno; 4353221ece2SMatthew G. Knepley } else { 4363221ece2SMatthew G. Knepley head->stack.currentsize = 0; 4373221ece2SMatthew G. Knepley } 4383221ece2SMatthew G. Knepley #endif 4393221ece2SMatthew G. Knepley 4403221ece2SMatthew G. Knepley /* 4413221ece2SMatthew G. Knepley Allow logging of all mallocs made 4423221ece2SMatthew G. Knepley */ 4433221ece2SMatthew G. Knepley if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && len >= PetscLogMallocThreshold) { 4443221ece2SMatthew G. Knepley if (!PetscLogMalloc) { 4453221ece2SMatthew G. Knepley PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 4463221ece2SMatthew G. Knepley if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4473221ece2SMatthew G. Knepley 4483221ece2SMatthew G. Knepley PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 4493221ece2SMatthew G. Knepley if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4503221ece2SMatthew G. Knepley 4513221ece2SMatthew G. Knepley PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 4523221ece2SMatthew G. Knepley if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4533221ece2SMatthew G. Knepley } 4543221ece2SMatthew G. Knepley PetscLogMallocLength[PetscLogMalloc] = nsize; 4553221ece2SMatthew G. Knepley PetscLogMallocFile[PetscLogMalloc] = filename; 4563221ece2SMatthew G. Knepley PetscLogMallocFunction[PetscLogMalloc++] = function; 4573221ece2SMatthew G. Knepley } 4583221ece2SMatthew G. Knepley *result = (void*)inew; 4593221ece2SMatthew G. Knepley PetscFunctionReturn(0); 4603221ece2SMatthew G. Knepley } 4613221ece2SMatthew G. Knepley 4623221ece2SMatthew G. Knepley 463fe7fb379SMatthew Knepley /*@C 4640841954dSBarry Smith PetscMemoryView - Shows the amount of memory currently being used 465e5c89e4eSSatish Balay 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: 4740841954dSBarry Smith + -malloc - 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 4790841954dSBarry Smith .seealso: PetscMallocDump(), PetscMemoryGetCurrentUsage(), PetscMemorySetGetMaximumUsage() 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 { 541e5c89e4eSSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"Run with -malloc 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 557e5c89e4eSSatish Balay .seealso: PetscMallocDump(), PetscMallocDumpLog(), 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 578e5c89e4eSSatish Balay .seealso: PetscMallocDump(), PetscMallocDumpLog(), 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 598e3ed9ee7SBarry Smith .seealso: PetscMallocDump(), PetscMallocDumpLog(), 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 623e3ed9ee7SBarry Smith .seealso: PetscMallocDump(), PetscMallocDumpLog(), 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 645a64a8e02SBarry Smith Output Paramter: 646a64a8e02SBarry Smith . stack - the stack indicating where the program allocated this memory 647a64a8e02SBarry Smith 648a64a8e02SBarry Smith Level: intermediate 649a64a8e02SBarry Smith 650a64a8e02SBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocDumpLog() 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 671e5c89e4eSSatish Balay PetscMallocDump - Dumps the 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 676e5c89e4eSSatish Balay Collective on PETSC_COMM_WORLD 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: 682e5c89e4eSSatish Balay . -malloc_dump - 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: 69195452b02SPatrick Sanan uses MPI_COMM_WORLD, because this may be called in PetscFinalize() after PETSC_COMM_WORLD 692e5c89e4eSSatish Balay has been freed. 693e5c89e4eSSatish Balay 6949e9a1f8fSvictor .seealso: PetscMallocGetCurrentUsage(), PetscMallocDumpLog() 695e5c89e4eSSatish Balay @*/ 6967087cfbeSBarry Smith PetscErrorCode PetscMallocDump(FILE *fp) 697e5c89e4eSSatish Balay { 698e5c89e4eSSatish Balay TRSPACE *head; 699e3ed9ee7SBarry Smith size_t libAlloc = 0; 700e5c89e4eSSatish Balay PetscErrorCode ierr; 701e5c89e4eSSatish Balay PetscMPIInt rank; 702e5c89e4eSSatish Balay 703e5c89e4eSSatish Balay PetscFunctionBegin; 704e5c89e4eSSatish Balay ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr); 705da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 706e5c89e4eSSatish Balay head = TRhead; 707e5c89e4eSSatish Balay while (head) { 7085486ca60SMatthew G. Knepley libAlloc += head->size; 7095486ca60SMatthew G. Knepley head = head->next; 7105486ca60SMatthew G. Knepley } 7115486ca60SMatthew G. Knepley if (TRallocated - libAlloc > 0) fprintf(fp,"[%d]Total space allocated %.0f bytes\n",rank,(PetscLogDouble)TRallocated); 7125486ca60SMatthew G. Knepley head = TRhead; 7135486ca60SMatthew G. Knepley while (head) { 7145486ca60SMatthew G. Knepley PetscBool isLib; 7155486ca60SMatthew G. Knepley 7165486ca60SMatthew G. Knepley ierr = PetscStrcmp(head->functionname, "PetscDLLibraryOpen", &isLib);CHKERRQ(ierr); 7175486ca60SMatthew G. Knepley if (!isLib) { 718efca3c55SSatish Balay fprintf(fp,"[%2d]%.0f bytes %s() line %d in %s\n",rank,(PetscLogDouble)head->size,head->functionname,head->lineno,head->filename); 7198bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 720e5c89e4eSSatish Balay ierr = PetscStackPrint(&head->stack,fp);CHKERRQ(ierr); 721e5c89e4eSSatish Balay #endif 7225486ca60SMatthew G. Knepley } 723e5c89e4eSSatish Balay head = head->next; 724e5c89e4eSSatish Balay } 725e5c89e4eSSatish Balay PetscFunctionReturn(0); 726e5c89e4eSSatish Balay } 727e5c89e4eSSatish Balay 728e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------- */ 729e5c89e4eSSatish Balay 730dc37d89fSBarry Smith /*@ 731e5c89e4eSSatish Balay PetscMallocSetDumpLog - Activates logging of all calls to PetscMalloc(). 732e5c89e4eSSatish Balay 733e5c89e4eSSatish Balay Not Collective 734e5c89e4eSSatish Balay 735e5c89e4eSSatish Balay Options Database Key: 736574034a9SJed Brown + -malloc_log <filename> - Activates PetscMallocDumpLog() 737574034a9SJed Brown - -malloc_log_threshold <min> - Activates logging and sets a minimum size 738e5c89e4eSSatish Balay 739e5c89e4eSSatish Balay Level: advanced 740e5c89e4eSSatish Balay 741574034a9SJed Brown .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocSetDumpLogThreshold() 742e5c89e4eSSatish Balay @*/ 7437087cfbeSBarry Smith PetscErrorCode PetscMallocSetDumpLog(void) 744e5c89e4eSSatish Balay { 74521b680ceSJed Brown PetscErrorCode ierr; 74621b680ceSJed Brown 747e5c89e4eSSatish Balay PetscFunctionBegin; 748e5c89e4eSSatish Balay PetscLogMalloc = 0; 749a297a907SKarl Rupp 75021b680ceSJed Brown ierr = PetscMemorySetGetMaximumUsage();CHKERRQ(ierr); 751e5c89e4eSSatish Balay PetscFunctionReturn(0); 752e5c89e4eSSatish Balay } 753e5c89e4eSSatish Balay 754dc37d89fSBarry Smith /*@ 755574034a9SJed Brown PetscMallocSetDumpLogThreshold - Activates logging of all calls to PetscMalloc(). 756574034a9SJed Brown 757574034a9SJed Brown Not Collective 758574034a9SJed Brown 759574034a9SJed Brown Input Arguments: 760574034a9SJed Brown . logmin - minimum allocation size to log, or PETSC_DEFAULT 761574034a9SJed Brown 762574034a9SJed Brown Options Database Key: 763574034a9SJed Brown + -malloc_log <filename> - Activates PetscMallocDumpLog() 764574034a9SJed Brown - -malloc_log_threshold <min> - Activates logging and sets a minimum size 765574034a9SJed Brown 766574034a9SJed Brown Level: advanced 767574034a9SJed Brown 768574034a9SJed Brown .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocSetDumpLog() 769574034a9SJed Brown @*/ 770574034a9SJed Brown PetscErrorCode PetscMallocSetDumpLogThreshold(PetscLogDouble logmin) 771574034a9SJed Brown { 772574034a9SJed Brown PetscErrorCode ierr; 773574034a9SJed Brown 774574034a9SJed Brown PetscFunctionBegin; 775574034a9SJed Brown ierr = PetscMallocSetDumpLog();CHKERRQ(ierr); 776574034a9SJed Brown if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */ 777574034a9SJed Brown PetscLogMallocThreshold = (size_t)logmin; 778574034a9SJed Brown PetscFunctionReturn(0); 779574034a9SJed Brown } 780574034a9SJed Brown 781dc37d89fSBarry Smith /*@ 78218a2528dSJed Brown PetscMallocGetDumpLog - Determine whether all calls to PetscMalloc() are being logged 78318a2528dSJed Brown 78418a2528dSJed Brown Not Collective 78518a2528dSJed Brown 78618a2528dSJed Brown Output Arguments 78718a2528dSJed Brown . logging - PETSC_TRUE if logging is active 78818a2528dSJed Brown 78918a2528dSJed Brown Options Database Key: 79018a2528dSJed Brown . -malloc_log - Activates PetscMallocDumpLog() 79118a2528dSJed Brown 79218a2528dSJed Brown Level: advanced 79318a2528dSJed Brown 79418a2528dSJed Brown .seealso: PetscMallocDump(), PetscMallocDumpLog() 79518a2528dSJed Brown @*/ 79618a2528dSJed Brown PetscErrorCode PetscMallocGetDumpLog(PetscBool *logging) 79718a2528dSJed Brown { 79818a2528dSJed Brown 79918a2528dSJed Brown PetscFunctionBegin; 80018a2528dSJed Brown *logging = (PetscBool)(PetscLogMalloc >= 0); 80118a2528dSJed Brown PetscFunctionReturn(0); 80218a2528dSJed Brown } 80318a2528dSJed Brown 804e5c89e4eSSatish Balay /*@C 805e5c89e4eSSatish Balay PetscMallocDumpLog - Dumps the log of all calls to PetscMalloc(); also calls 80621b680ceSJed Brown PetscMemoryGetMaximumUsage() 807e5c89e4eSSatish Balay 808e5c89e4eSSatish Balay Collective on PETSC_COMM_WORLD 809e5c89e4eSSatish Balay 810e5c89e4eSSatish Balay Input Parameter: 8110298fd71SBarry Smith . fp - file pointer; or NULL 812e5c89e4eSSatish Balay 813e5c89e4eSSatish Balay Options Database Key: 814e5c89e4eSSatish Balay . -malloc_log - Activates PetscMallocDumpLog() 815e5c89e4eSSatish Balay 816e5c89e4eSSatish Balay Level: advanced 817e5c89e4eSSatish Balay 818e5c89e4eSSatish Balay Fortran Note: 819e5c89e4eSSatish Balay The calling sequence in Fortran is PetscMallocDumpLog(integer ierr) 820e5c89e4eSSatish Balay The fp defaults to stdout. 821e5c89e4eSSatish Balay 822e5c89e4eSSatish Balay .seealso: PetscMallocGetCurrentUsage(), PetscMallocDump(), PetscMallocSetDumpLog() 823e5c89e4eSSatish Balay @*/ 8247087cfbeSBarry Smith PetscErrorCode PetscMallocDumpLog(FILE *fp) 825e5c89e4eSSatish Balay { 826e5c89e4eSSatish Balay PetscInt i,j,n,dummy,*perm; 827e5c89e4eSSatish Balay size_t *shortlength; 828f56c2debSBarry Smith int *shortcount,err; 829e5c89e4eSSatish Balay PetscMPIInt rank,size,tag = 1212 /* very bad programming */; 830ace3abfcSBarry Smith PetscBool match; 831e5c89e4eSSatish Balay const char **shortfunction; 832e5c89e4eSSatish Balay PetscLogDouble rss; 833e5c89e4eSSatish Balay MPI_Status status; 834e5c89e4eSSatish Balay PetscErrorCode ierr; 835e5c89e4eSSatish Balay 836e5c89e4eSSatish Balay PetscFunctionBegin; 837e5c89e4eSSatish Balay ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr); 838e5c89e4eSSatish Balay ierr = MPI_Comm_size(MPI_COMM_WORLD,&size);CHKERRQ(ierr); 839e5c89e4eSSatish Balay /* 840e5c89e4eSSatish Balay Try to get the data printed in order by processor. This will only sometimes work 841e5c89e4eSSatish Balay */ 842f56c2debSBarry Smith err = fflush(fp); 843e32f2f54SBarry Smith if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 844f56c2debSBarry Smith 845e5c89e4eSSatish Balay ierr = MPI_Barrier(MPI_COMM_WORLD);CHKERRQ(ierr); 846e5c89e4eSSatish Balay if (rank) { 847e5c89e4eSSatish Balay ierr = MPI_Recv(&dummy,1,MPIU_INT,rank-1,tag,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 848e5c89e4eSSatish Balay } 849e5c89e4eSSatish Balay 850768aa557SSatish 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()"); 851768aa557SSatish Balay 852da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 853f3d65365SJed Brown ierr = PetscMemoryGetMaximumUsage(&rss);CHKERRQ(ierr); 854e5c89e4eSSatish Balay if (rss) { 855f3d65365SJed 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); 856e5c89e4eSSatish Balay } else { 857e5c89e4eSSatish 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); 858e5c89e4eSSatish Balay } 859e32f2f54SBarry Smith shortcount = (int*)malloc(PetscLogMalloc*sizeof(int));if (!shortcount) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 860e32f2f54SBarry Smith shortlength = (size_t*)malloc(PetscLogMalloc*sizeof(size_t));if (!shortlength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 861e32f2f54SBarry Smith shortfunction = (const char**)malloc(PetscLogMalloc*sizeof(char*));if (!shortfunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 86297b9d747SJed Brown for (i=0,n=0; i<PetscLogMalloc; i++) { 863e5c89e4eSSatish Balay for (j=0; j<n; j++) { 864e5c89e4eSSatish Balay ierr = PetscStrcmp(shortfunction[j],PetscLogMallocFunction[i],&match);CHKERRQ(ierr); 865e5c89e4eSSatish Balay if (match) { 866e5c89e4eSSatish Balay shortlength[j] += PetscLogMallocLength[i]; 86759ffdab8SBarry Smith shortcount[j]++; 868e5c89e4eSSatish Balay goto foundit; 869e5c89e4eSSatish Balay } 870e5c89e4eSSatish Balay } 871e5c89e4eSSatish Balay shortfunction[n] = PetscLogMallocFunction[i]; 872e5c89e4eSSatish Balay shortlength[n] = PetscLogMallocLength[i]; 87359ffdab8SBarry Smith shortcount[n] = 1; 874e5c89e4eSSatish Balay n++; 875e5c89e4eSSatish Balay foundit:; 876e5c89e4eSSatish Balay } 877e5c89e4eSSatish Balay 878e32f2f54SBarry Smith perm = (PetscInt*)malloc(n*sizeof(PetscInt));if (!perm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 879e5c89e4eSSatish Balay for (i=0; i<n; i++) perm[i] = i; 880e5c89e4eSSatish Balay ierr = PetscSortStrWithPermutation(n,(const char**)shortfunction,perm);CHKERRQ(ierr); 881e5c89e4eSSatish Balay 882e5c89e4eSSatish Balay ierr = PetscFPrintf(MPI_COMM_WORLD,fp,"[%d] Memory usage sorted by function\n",rank);CHKERRQ(ierr); 883e5c89e4eSSatish Balay for (i=0; i<n; i++) { 88459ffdab8SBarry 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); 885e5c89e4eSSatish Balay } 886e5c89e4eSSatish Balay free(perm); 887e5c89e4eSSatish Balay free(shortlength); 88859ffdab8SBarry Smith free(shortcount); 889e5c89e4eSSatish Balay free((char**)shortfunction); 890f56c2debSBarry Smith err = fflush(fp); 891e32f2f54SBarry Smith if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 892e5c89e4eSSatish Balay if (rank != size-1) { 893e5c89e4eSSatish Balay ierr = MPI_Send(&dummy,1,MPIU_INT,rank+1,tag,MPI_COMM_WORLD);CHKERRQ(ierr); 894e5c89e4eSSatish Balay } 895e5c89e4eSSatish Balay PetscFunctionReturn(0); 896e5c89e4eSSatish Balay } 897e5c89e4eSSatish Balay 898e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------- */ 899e5c89e4eSSatish Balay 900dc37d89fSBarry Smith /*@ 901e5c89e4eSSatish Balay PetscMallocDebug - Turns on/off debugging for the memory management routines. 902e5c89e4eSSatish Balay 903e5c89e4eSSatish Balay Not Collective 904e5c89e4eSSatish Balay 905e5c89e4eSSatish Balay Input Parameter: 906e5c89e4eSSatish Balay . level - PETSC_TRUE or PETSC_FALSE 907e5c89e4eSSatish Balay 908e5c89e4eSSatish Balay Level: intermediate 909e5c89e4eSSatish Balay 910e5c89e4eSSatish Balay .seealso: CHKMEMQ(), PetscMallocValidate() 911e5c89e4eSSatish Balay @*/ 9127087cfbeSBarry Smith PetscErrorCode PetscMallocDebug(PetscBool level) 913e5c89e4eSSatish Balay { 914e5c89e4eSSatish Balay PetscFunctionBegin; 915e5c89e4eSSatish Balay TRdebugLevel = level; 916e5c89e4eSSatish Balay PetscFunctionReturn(0); 917e5c89e4eSSatish Balay } 9180acecf5bSBarry Smith 919dc37d89fSBarry Smith /*@ 9200acecf5bSBarry Smith PetscMallocGetDebug - Indicates if any PETSc is doing ANY memory debugging. 9210acecf5bSBarry Smith 9220acecf5bSBarry Smith Not Collective 9230acecf5bSBarry Smith 9240acecf5bSBarry Smith Output Parameter: 9250acecf5bSBarry Smith . flg - PETSC_TRUE if any debugger 9260acecf5bSBarry Smith 9270acecf5bSBarry Smith Level: intermediate 9280acecf5bSBarry Smith 9290acecf5bSBarry Smith Note that by default, the debug version always does some debugging unless you run with -malloc no 9300acecf5bSBarry Smith 9310acecf5bSBarry Smith 9320acecf5bSBarry Smith .seealso: CHKMEMQ(), PetscMallocValidate() 9330acecf5bSBarry Smith @*/ 9340acecf5bSBarry Smith PetscErrorCode PetscMallocGetDebug(PetscBool *flg) 9350acecf5bSBarry Smith { 9360acecf5bSBarry Smith PetscFunctionBegin; 9370acecf5bSBarry Smith if (PetscTrMalloc == PetscTrMallocDefault) *flg = PETSC_TRUE; 9380acecf5bSBarry Smith else *flg = PETSC_FALSE; 9390acecf5bSBarry Smith PetscFunctionReturn(0); 9400acecf5bSBarry Smith } 941