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 */ 1695c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscMallocAlign(size_t,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**); 1995c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscTrMallocDefault(size_t,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 55*e3ed9ee7SBarry 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; 62*e3ed9ee7SBarry Smith static int NumTRMaxMems = 0; 63*e3ed9ee7SBarry Smith static size_t TRMaxMems[MAXTRMAXMEMS]; 64*e3ed9ee7SBarry 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; 73*e3ed9ee7SBarry 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; 80*e3ed9ee7SBarry Smith if (PetscSetUseTrMallocCalled) PetscFunctionReturn(0); 81*e3ed9ee7SBarry 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 */ 173efca3c55SSatish Balay PetscErrorCode PetscTrMallocDefault(size_t a,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); 189efca3c55SSatish Balay ierr = PetscMallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),lineno,function,filename,(void**)&inew);CHKERRQ(ierr); 190e5c89e4eSSatish Balay 191*e3ed9ee7SBarry Smith if (PetscLogMemory) { 192*e3ed9ee7SBarry Smith /* zero the memory to force the value of PetscMemoryGetCurrentUsage() to accurately reflect allocated memory */ 193*e3ed9ee7SBarry Smith ierr = PetscMemzero(inew,nsize+sizeof(TrSPACE)+sizeof(PetscClassId));CHKERRQ(ierr); 194*e3ed9ee7SBarry Smith } 195*e3ed9ee7SBarry Smith 196e5c89e4eSSatish Balay head = (TRSPACE*)inew; 197e5c89e4eSSatish Balay inew += sizeof(TrSPACE); 198e5c89e4eSSatish Balay 199e5c89e4eSSatish Balay if (TRhead) TRhead->prev = head; 200e5c89e4eSSatish Balay head->next = TRhead; 201e5c89e4eSSatish Balay TRhead = head; 202f0ba7cfcSLisandro Dalcin head->prev = NULL; 203e5c89e4eSSatish Balay head->size = nsize; 204e5c89e4eSSatish Balay head->id = TRid; 205e5c89e4eSSatish Balay head->lineno = lineno; 206e5c89e4eSSatish Balay 207e5c89e4eSSatish Balay head->filename = filename; 208e5c89e4eSSatish Balay head->functionname = function; 2090700a824SBarry Smith head->classid = CLASSID_VALUE; 2100700a824SBarry Smith *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 211e5c89e4eSSatish Balay 212e5c89e4eSSatish Balay TRallocated += nsize; 213a297a907SKarl Rupp if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 214*e3ed9ee7SBarry Smith if (PetscLogMemory) { 215*e3ed9ee7SBarry Smith PetscInt i; 216*e3ed9ee7SBarry Smith for (i=0; i<NumTRMaxMems; i++) { 217*e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 218*e3ed9ee7SBarry Smith } 219*e3ed9ee7SBarry Smith } 220e5c89e4eSSatish Balay TRfrags++; 221e5c89e4eSSatish Balay 2228bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 22376386721SLisandro Dalcin if (PetscStackActive()) { 2245c25fcd7SBarry Smith ierr = PetscStackCopy(petscstack,&head->stack);CHKERRQ(ierr); 2252c9581d2SBarry Smith /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 2262c9581d2SBarry Smith head->stack.line[head->stack.currentsize-2] = lineno; 2279de0f6ecSBarry Smith } else { 2289de0f6ecSBarry Smith head->stack.currentsize = 0; 22976386721SLisandro Dalcin } 230e5c89e4eSSatish Balay #endif 231e5c89e4eSSatish Balay 232e5c89e4eSSatish Balay /* 233e5c89e4eSSatish Balay Allow logging of all mallocs made 234e5c89e4eSSatish Balay */ 235574034a9SJed Brown if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && a >= PetscLogMallocThreshold) { 236e5c89e4eSSatish Balay if (!PetscLogMalloc) { 237e5c89e4eSSatish Balay PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 238e32f2f54SBarry Smith if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 239a297a907SKarl Rupp 240a2ea699eSBarry Smith PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 241e32f2f54SBarry Smith if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 242a297a907SKarl Rupp 243a2ea699eSBarry Smith PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 244e32f2f54SBarry Smith if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 245e5c89e4eSSatish Balay } 246e5c89e4eSSatish Balay PetscLogMallocLength[PetscLogMalloc] = nsize; 247e5c89e4eSSatish Balay PetscLogMallocFile[PetscLogMalloc] = filename; 248e5c89e4eSSatish Balay PetscLogMallocFunction[PetscLogMalloc++] = function; 249e5c89e4eSSatish Balay } 250e5c89e4eSSatish Balay *result = (void*)inew; 251e5c89e4eSSatish Balay PetscFunctionReturn(0); 252e5c89e4eSSatish Balay } 253e5c89e4eSSatish Balay 254e5c89e4eSSatish Balay 255e5c89e4eSSatish Balay /* 256e5c89e4eSSatish Balay PetscTrFreeDefault - Free with tracing. 257e5c89e4eSSatish Balay 258e5c89e4eSSatish Balay Input Parameters: 259e5c89e4eSSatish Balay . a - pointer to a block allocated with PetscTrMalloc 260e5c89e4eSSatish Balay . lineno - line number where used. Use __LINE__ for this 261e5c89e4eSSatish Balay . file - file name where used. Use __FILE__ for this 262e5c89e4eSSatish Balay */ 263efca3c55SSatish Balay PetscErrorCode PetscTrFreeDefault(void *aa,int line,const char function[],const char file[]) 264e5c89e4eSSatish Balay { 265e5c89e4eSSatish Balay char *a = (char*)aa; 266e5c89e4eSSatish Balay TRSPACE *head; 267e5c89e4eSSatish Balay char *ahead; 268e5c89e4eSSatish Balay PetscErrorCode ierr; 2690700a824SBarry Smith PetscClassId *nend; 270e5c89e4eSSatish Balay 271e5c89e4eSSatish Balay PetscFunctionBegin; 272e5c89e4eSSatish Balay /* Do not try to handle empty blocks */ 27349d7da52SJed Brown if (!a) PetscFunctionReturn(0); 274e5c89e4eSSatish Balay 275e5c89e4eSSatish Balay if (TRdebugLevel) { 276efca3c55SSatish Balay ierr = PetscMallocValidate(line,function,file);CHKERRQ(ierr); 277e5c89e4eSSatish Balay } 278e5c89e4eSSatish Balay 279e5c89e4eSSatish Balay ahead = a; 280e5c89e4eSSatish Balay a = a - sizeof(TrSPACE); 281e5c89e4eSSatish Balay head = (TRSPACE*)a; 282e5c89e4eSSatish Balay 2830700a824SBarry Smith if (head->classid != CLASSID_VALUE) { 284efca3c55SSatish Balay (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); 285e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 286e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); 287e5c89e4eSSatish Balay } 2880700a824SBarry Smith nend = (PetscClassId*)(ahead + head->size); 2890700a824SBarry Smith if (*nend != CLASSID_VALUE) { 290e5c89e4eSSatish Balay if (*nend == ALREADY_FREED) { 291efca3c55SSatish Balay (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); 292e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 293e5c89e4eSSatish Balay if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 294efca3c55SSatish Balay (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 295e5c89e4eSSatish Balay } else { 296efca3c55SSatish Balay (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename); 297e5c89e4eSSatish Balay } 298e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); 299e5c89e4eSSatish Balay } else { 300e5c89e4eSSatish Balay /* Damaged tail */ 301efca3c55SSatish Balay (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); 302e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 303efca3c55SSatish Balay (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 304e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); 305e5c89e4eSSatish Balay } 306e5c89e4eSSatish Balay } 307e5c89e4eSSatish Balay /* Mark the location freed */ 308e5c89e4eSSatish Balay *nend = ALREADY_FREED; 309e5c89e4eSSatish Balay /* Save location where freed. If we suspect the line number, mark as allocated location */ 310e5c89e4eSSatish Balay if (line > 0 && line < 50000) { 311e5c89e4eSSatish Balay head->lineno = line; 312e5c89e4eSSatish Balay head->filename = file; 313e5c89e4eSSatish Balay head->functionname = function; 314e5c89e4eSSatish Balay } else { 315e5c89e4eSSatish Balay head->lineno = -head->lineno; 316e5c89e4eSSatish Balay } 317e5c89e4eSSatish Balay /* zero out memory - helps to find some reuse of already freed memory */ 318e5c89e4eSSatish Balay ierr = PetscMemzero(aa,head->size);CHKERRQ(ierr); 319e5c89e4eSSatish Balay 320*e3ed9ee7SBarry Smith if (TRallocated < head->size) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"TRallocate is smaller than memory just freed"); 321e5c89e4eSSatish Balay TRallocated -= head->size; 322e5c89e4eSSatish Balay TRfrags--; 323e5c89e4eSSatish Balay if (head->prev) head->prev->next = head->next; 324e5c89e4eSSatish Balay else TRhead = head->next; 325e5c89e4eSSatish Balay 326e5c89e4eSSatish Balay if (head->next) head->next->prev = head->prev; 327efca3c55SSatish Balay ierr = PetscFreeAlign(a,line,function,file);CHKERRQ(ierr); 328e5c89e4eSSatish Balay PetscFunctionReturn(0); 329e5c89e4eSSatish Balay } 330e5c89e4eSSatish Balay 331e5c89e4eSSatish Balay 3323221ece2SMatthew G. Knepley 3333221ece2SMatthew G. Knepley /* 3343221ece2SMatthew G. Knepley PetscTrReallocDefault - Realloc with tracing. 3353221ece2SMatthew G. Knepley 3363221ece2SMatthew G. Knepley Input Parameters: 3373221ece2SMatthew G. Knepley + len - number of bytes to allocate 3383221ece2SMatthew G. Knepley . lineno - line number where used. Use __LINE__ for this 3393221ece2SMatthew G. Knepley . filename - file name where used. Use __FILE__ for this 3403221ece2SMatthew G. Knepley - result - double aligned pointer to initial storage. 3413221ece2SMatthew G. Knepley 3423221ece2SMatthew G. Knepley Output Parameter: 3433221ece2SMatthew G. Knepley . result - double aligned pointer to requested storage, or null if not available. 3443221ece2SMatthew G. Knepley 3453221ece2SMatthew G. Knepley Level: developer 3463221ece2SMatthew G. Knepley 3473221ece2SMatthew G. Knepley .seealso: PetscTrMallocDefault(), PetscTrFreeDefault() 3483221ece2SMatthew G. Knepley */ 3493221ece2SMatthew G. Knepley PetscErrorCode PetscTrReallocDefault(size_t len, int lineno, const char function[], const char filename[], void **result) 3503221ece2SMatthew G. Knepley { 3513221ece2SMatthew G. Knepley char *a = (char *) *result; 3523221ece2SMatthew G. Knepley TRSPACE *head; 3533221ece2SMatthew G. Knepley char *ahead, *inew; 3543221ece2SMatthew G. Knepley PetscClassId *nend; 3553221ece2SMatthew G. Knepley size_t nsize; 3563221ece2SMatthew G. Knepley PetscErrorCode ierr; 3573221ece2SMatthew G. Knepley 3583221ece2SMatthew G. Knepley PetscFunctionBegin; 359c22f1541SToby Isaac /* Realloc to zero = free */ 360c22f1541SToby Isaac if (!len) { 361c22f1541SToby Isaac ierr = PetscTrFreeDefault(*result,lineno,function,filename);CHKERRQ(ierr); 362c22f1541SToby Isaac *result = NULL; 363c22f1541SToby Isaac PetscFunctionReturn(0); 364c22f1541SToby Isaac } 365f590eff4SLisandro Dalcin /* Realloc with NULL = malloc */ 366f590eff4SLisandro Dalcin if (!*result) { 367f590eff4SLisandro Dalcin ierr = PetscTrMallocDefault(len,lineno,function,filename,result);CHKERRQ(ierr); 368f590eff4SLisandro Dalcin PetscFunctionReturn(0); 369f590eff4SLisandro Dalcin } 3703221ece2SMatthew G. Knepley 3713221ece2SMatthew G. Knepley if (TRdebugLevel) {ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr);} 3723221ece2SMatthew G. Knepley 3733221ece2SMatthew G. Knepley ahead = a; 3743221ece2SMatthew G. Knepley a = a - sizeof(TrSPACE); 3753221ece2SMatthew G. Knepley head = (TRSPACE *) a; 3763221ece2SMatthew G. Knepley inew = a; 3773221ece2SMatthew G. Knepley 3783221ece2SMatthew G. Knepley if (head->classid != CLASSID_VALUE) { 3793221ece2SMatthew G. Knepley (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename); 3803221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 3813221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); 3823221ece2SMatthew G. Knepley } 3833221ece2SMatthew G. Knepley nend = (PetscClassId *)(ahead + head->size); 3843221ece2SMatthew G. Knepley if (*nend != CLASSID_VALUE) { 3853221ece2SMatthew G. Knepley if (*nend == ALREADY_FREED) { 3863221ece2SMatthew G. Knepley (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename); 3873221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 3883221ece2SMatthew G. Knepley if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 3893221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 3903221ece2SMatthew G. Knepley } else { 3913221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename); 3923221ece2SMatthew G. Knepley } 3933221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); 3943221ece2SMatthew G. Knepley } else { 3953221ece2SMatthew G. Knepley /* Damaged tail */ 3963221ece2SMatthew G. Knepley (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename); 3973221ece2SMatthew 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); 3983221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 3993221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); 4003221ece2SMatthew G. Knepley } 4013221ece2SMatthew G. Knepley } 4023221ece2SMatthew G. Knepley 4033221ece2SMatthew G. Knepley TRallocated -= head->size; 4043221ece2SMatthew G. Knepley TRfrags--; 4053221ece2SMatthew G. Knepley if (head->prev) head->prev->next = head->next; 4063221ece2SMatthew G. Knepley else TRhead = head->next; 4073221ece2SMatthew G. Knepley if (head->next) head->next->prev = head->prev; 4083221ece2SMatthew G. Knepley 4093221ece2SMatthew G. Knepley nsize = (len + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1); 4103221ece2SMatthew G. Knepley ierr = PetscReallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),lineno,function,filename,(void**)&inew);CHKERRQ(ierr); 4113221ece2SMatthew G. Knepley 4123221ece2SMatthew G. Knepley head = (TRSPACE*)inew; 4133221ece2SMatthew G. Knepley inew += sizeof(TrSPACE); 4143221ece2SMatthew G. Knepley 4153221ece2SMatthew G. Knepley if (TRhead) TRhead->prev = head; 4163221ece2SMatthew G. Knepley head->next = TRhead; 4173221ece2SMatthew G. Knepley TRhead = head; 4183221ece2SMatthew G. Knepley head->prev = NULL; 4193221ece2SMatthew G. Knepley head->size = nsize; 4203221ece2SMatthew G. Knepley head->id = TRid; 4213221ece2SMatthew G. Knepley head->lineno = lineno; 4223221ece2SMatthew G. Knepley 4233221ece2SMatthew G. Knepley head->filename = filename; 4243221ece2SMatthew G. Knepley head->functionname = function; 4253221ece2SMatthew G. Knepley head->classid = CLASSID_VALUE; 4263221ece2SMatthew G. Knepley *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 4273221ece2SMatthew G. Knepley 4283221ece2SMatthew G. Knepley TRallocated += nsize; 4293221ece2SMatthew G. Knepley if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 430*e3ed9ee7SBarry Smith if (PetscLogMemory) { 431*e3ed9ee7SBarry Smith PetscInt i; 432*e3ed9ee7SBarry Smith for (i=0; i<NumTRMaxMems; i++) { 433*e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 434*e3ed9ee7SBarry Smith } 435*e3ed9ee7SBarry Smith } 4363221ece2SMatthew G. Knepley TRfrags++; 4373221ece2SMatthew G. Knepley 4383221ece2SMatthew G. Knepley #if defined(PETSC_USE_DEBUG) 4393221ece2SMatthew G. Knepley if (PetscStackActive()) { 4403221ece2SMatthew G. Knepley ierr = PetscStackCopy(petscstack,&head->stack);CHKERRQ(ierr); 4413221ece2SMatthew G. Knepley /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 4423221ece2SMatthew G. Knepley head->stack.line[head->stack.currentsize-2] = lineno; 4433221ece2SMatthew G. Knepley } else { 4443221ece2SMatthew G. Knepley head->stack.currentsize = 0; 4453221ece2SMatthew G. Knepley } 4463221ece2SMatthew G. Knepley #endif 4473221ece2SMatthew G. Knepley 4483221ece2SMatthew G. Knepley /* 4493221ece2SMatthew G. Knepley Allow logging of all mallocs made 4503221ece2SMatthew G. Knepley */ 4513221ece2SMatthew G. Knepley if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && len >= PetscLogMallocThreshold) { 4523221ece2SMatthew G. Knepley if (!PetscLogMalloc) { 4533221ece2SMatthew G. Knepley PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 4543221ece2SMatthew G. Knepley if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4553221ece2SMatthew G. Knepley 4563221ece2SMatthew G. Knepley PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 4573221ece2SMatthew G. Knepley if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4583221ece2SMatthew G. Knepley 4593221ece2SMatthew G. Knepley PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 4603221ece2SMatthew G. Knepley if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4613221ece2SMatthew G. Knepley } 4623221ece2SMatthew G. Knepley PetscLogMallocLength[PetscLogMalloc] = nsize; 4633221ece2SMatthew G. Knepley PetscLogMallocFile[PetscLogMalloc] = filename; 4643221ece2SMatthew G. Knepley PetscLogMallocFunction[PetscLogMalloc++] = function; 4653221ece2SMatthew G. Knepley } 4663221ece2SMatthew G. Knepley *result = (void*)inew; 4673221ece2SMatthew G. Knepley PetscFunctionReturn(0); 4683221ece2SMatthew G. Knepley } 4693221ece2SMatthew G. Knepley 4703221ece2SMatthew G. Knepley 471fe7fb379SMatthew Knepley /*@C 4720841954dSBarry Smith PetscMemoryView - Shows the amount of memory currently being used 473e5c89e4eSSatish Balay in a communicator. 474e5c89e4eSSatish Balay 475e5c89e4eSSatish Balay Collective on PetscViewer 476e5c89e4eSSatish Balay 477e5c89e4eSSatish Balay Input Parameter: 478e5c89e4eSSatish Balay + viewer - the viewer that defines the communicator 479e5c89e4eSSatish Balay - message - string printed before values 480e5c89e4eSSatish Balay 4810841954dSBarry Smith Options Database: 4820841954dSBarry Smith + -malloc - have PETSc track how much memory it has allocated 4830841954dSBarry Smith - -memory_view - during PetscFinalize() have this routine called 4840841954dSBarry Smith 485e5c89e4eSSatish Balay Level: intermediate 486e5c89e4eSSatish Balay 487e5c89e4eSSatish Balay Concepts: memory usage 488e5c89e4eSSatish Balay 4890841954dSBarry Smith .seealso: PetscMallocDump(), PetscMemoryGetCurrentUsage(), PetscMemorySetGetMaximumUsage() 490e5c89e4eSSatish Balay @*/ 4910841954dSBarry Smith PetscErrorCode PetscMemoryView(PetscViewer viewer,const char message[]) 492e5c89e4eSSatish Balay { 4930841954dSBarry Smith PetscLogDouble allocated,allocatedmax,resident,residentmax,gallocated,gallocatedmax,gresident,gresidentmax,maxgallocated,maxgallocatedmax,maxgresident,maxgresidentmax; 4940841954dSBarry Smith PetscLogDouble mingallocated,mingallocatedmax,mingresident,mingresidentmax; 495e5c89e4eSSatish Balay PetscErrorCode ierr; 496e5c89e4eSSatish Balay MPI_Comm comm; 497e5c89e4eSSatish Balay 498e5c89e4eSSatish Balay PetscFunctionBegin; 499e5c89e4eSSatish Balay if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD; 500e5c89e4eSSatish Balay ierr = PetscMallocGetCurrentUsage(&allocated);CHKERRQ(ierr); 5010841954dSBarry Smith ierr = PetscMallocGetMaximumUsage(&allocatedmax);CHKERRQ(ierr); 502e5c89e4eSSatish Balay ierr = PetscMemoryGetCurrentUsage(&resident);CHKERRQ(ierr); 503e5c89e4eSSatish Balay ierr = PetscMemoryGetMaximumUsage(&residentmax);CHKERRQ(ierr); 504e5c89e4eSSatish Balay if (residentmax > 0) residentmax = PetscMax(resident,residentmax); 505e5c89e4eSSatish Balay ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 506e5c89e4eSSatish Balay ierr = PetscViewerASCIIPrintf(viewer,message);CHKERRQ(ierr); 507e5c89e4eSSatish Balay if (resident && residentmax && allocated) { 5080841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5090841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5100841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5110841954dSBarry 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); 5120841954dSBarry Smith ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5130841954dSBarry Smith ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5140841954dSBarry Smith ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5150841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr); 5160841954dSBarry Smith ierr = MPI_Reduce(&allocatedmax,&gallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5170841954dSBarry Smith ierr = MPI_Reduce(&allocatedmax,&maxgallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5180841954dSBarry Smith ierr = MPI_Reduce(&allocatedmax,&mingallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5190841954dSBarry 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); 5200841954dSBarry Smith ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5210841954dSBarry Smith ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5220841954dSBarry Smith ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5230841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr); 524e5c89e4eSSatish Balay } else if (resident && residentmax) { 5250841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5260841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5270841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5280841954dSBarry 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); 5290841954dSBarry Smith ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5300841954dSBarry Smith ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5310841954dSBarry Smith ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5320841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr); 533e5c89e4eSSatish Balay } else if (resident && allocated) { 5340841954dSBarry Smith ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5350841954dSBarry Smith ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5360841954dSBarry Smith ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5370841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr); 5380841954dSBarry Smith ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5390841954dSBarry Smith ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5400841954dSBarry Smith ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5410841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr); 5420841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n");CHKERRQ(ierr); 543e5c89e4eSSatish Balay } else if (allocated) { 5440841954dSBarry Smith ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5450841954dSBarry Smith ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5460841954dSBarry Smith ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5470841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr); 5480841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n");CHKERRQ(ierr); 5490841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"OS cannot compute process memory\n");CHKERRQ(ierr); 550e5c89e4eSSatish Balay } else { 551e5c89e4eSSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"Run with -malloc to get statistics on PetscMalloc() calls\nOS cannot compute process memory\n");CHKERRQ(ierr); 552e5c89e4eSSatish Balay } 553e5c89e4eSSatish Balay ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 554e5c89e4eSSatish Balay PetscFunctionReturn(0); 555e5c89e4eSSatish Balay } 556e5c89e4eSSatish Balay 55746eb3923SBarry Smith /*@ 558e5c89e4eSSatish Balay PetscMallocGetCurrentUsage - gets the current amount of memory used that was PetscMalloc()ed 559e5c89e4eSSatish Balay 560e5c89e4eSSatish Balay Not Collective 561e5c89e4eSSatish Balay 562e5c89e4eSSatish Balay Output Parameters: 563e5c89e4eSSatish Balay . space - number of bytes currently allocated 564e5c89e4eSSatish Balay 565e5c89e4eSSatish Balay Level: intermediate 566e5c89e4eSSatish Balay 567e5c89e4eSSatish Balay Concepts: memory usage 568e5c89e4eSSatish Balay 569e5c89e4eSSatish Balay .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 570e5c89e4eSSatish Balay PetscMemoryGetMaximumUsage() 571e5c89e4eSSatish Balay @*/ 5727087cfbeSBarry Smith PetscErrorCode PetscMallocGetCurrentUsage(PetscLogDouble *space) 573e5c89e4eSSatish Balay { 574e5c89e4eSSatish Balay PetscFunctionBegin; 575e5c89e4eSSatish Balay *space = (PetscLogDouble) TRallocated; 576e5c89e4eSSatish Balay PetscFunctionReturn(0); 577e5c89e4eSSatish Balay } 578e5c89e4eSSatish Balay 579dc37d89fSBarry Smith /*@ 580e5c89e4eSSatish Balay PetscMallocGetMaximumUsage - gets the maximum amount of memory used that was PetscMalloc()ed at any time 581e5c89e4eSSatish Balay during this run. 582e5c89e4eSSatish Balay 583e5c89e4eSSatish Balay Not Collective 584e5c89e4eSSatish Balay 585e5c89e4eSSatish Balay Output Parameters: 586e5c89e4eSSatish Balay . space - maximum number of bytes ever allocated at one time 587e5c89e4eSSatish Balay 588e5c89e4eSSatish Balay Level: intermediate 589e5c89e4eSSatish Balay 590e5c89e4eSSatish Balay Concepts: memory usage 591e5c89e4eSSatish Balay 592e5c89e4eSSatish Balay .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 593*e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage() 594e5c89e4eSSatish Balay @*/ 5957087cfbeSBarry Smith PetscErrorCode PetscMallocGetMaximumUsage(PetscLogDouble *space) 596e5c89e4eSSatish Balay { 597e5c89e4eSSatish Balay PetscFunctionBegin; 598e5c89e4eSSatish Balay *space = (PetscLogDouble) TRMaxMem; 599e5c89e4eSSatish Balay PetscFunctionReturn(0); 600e5c89e4eSSatish Balay } 601e5c89e4eSSatish Balay 602*e3ed9ee7SBarry Smith /*@ 603*e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage - Adds another event to collect the maximum memory usage over an event 604*e3ed9ee7SBarry Smith 605*e3ed9ee7SBarry Smith Not Collective 606*e3ed9ee7SBarry Smith 607*e3ed9ee7SBarry Smith Input Parameter: 608*e3ed9ee7SBarry Smith . event - an event id; this is just for error checking 609*e3ed9ee7SBarry Smith 610*e3ed9ee7SBarry Smith Level: developer 611*e3ed9ee7SBarry Smith 612*e3ed9ee7SBarry Smith Concepts: memory usage 613*e3ed9ee7SBarry Smith 614*e3ed9ee7SBarry Smith .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 615*e3ed9ee7SBarry Smith PetscMallocPopMaximumUsage() 616*e3ed9ee7SBarry Smith @*/ 617*e3ed9ee7SBarry Smith PetscErrorCode PetscMallocPushMaximumUsage(int event) 618*e3ed9ee7SBarry Smith { 619*e3ed9ee7SBarry Smith PetscFunctionBegin; 620*e3ed9ee7SBarry Smith if (++NumTRMaxMems > MAXTRMAXMEMS) PetscFunctionReturn(0); 621*e3ed9ee7SBarry Smith TRMaxMems[NumTRMaxMems-1] = TRallocated; 622*e3ed9ee7SBarry Smith TRMaxMemsEvents[NumTRMaxMems-1] = event; 623*e3ed9ee7SBarry Smith PetscFunctionReturn(0); 624*e3ed9ee7SBarry Smith } 625*e3ed9ee7SBarry Smith 626*e3ed9ee7SBarry Smith /*@ 627*e3ed9ee7SBarry Smith PetscMallocPopMaximumUsage - collect the maximum memory usage over an event 628*e3ed9ee7SBarry Smith 629*e3ed9ee7SBarry Smith Not Collective 630*e3ed9ee7SBarry Smith 631*e3ed9ee7SBarry Smith Input Parameter: 632*e3ed9ee7SBarry Smith . event - an event id; this is just for error checking 633*e3ed9ee7SBarry Smith 634*e3ed9ee7SBarry Smith Output Parameter: 635*e3ed9ee7SBarry Smith . mu - maximum amount of memory malloced during this event; high water mark relative to the beginning of the event 636*e3ed9ee7SBarry Smith 637*e3ed9ee7SBarry Smith Level: developer 638*e3ed9ee7SBarry Smith 639*e3ed9ee7SBarry Smith Concepts: memory usage 640*e3ed9ee7SBarry Smith 641*e3ed9ee7SBarry Smith .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 642*e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage() 643*e3ed9ee7SBarry Smith @*/ 644*e3ed9ee7SBarry Smith PetscErrorCode PetscMallocPopMaximumUsage(int event,PetscLogDouble *mu) 645*e3ed9ee7SBarry Smith { 646*e3ed9ee7SBarry Smith PetscFunctionBegin; 647*e3ed9ee7SBarry Smith *mu = 0; 648*e3ed9ee7SBarry Smith if (NumTRMaxMems-- > MAXTRMAXMEMS) PetscFunctionReturn(0); 649*e3ed9ee7SBarry Smith if (TRMaxMemsEvents[NumTRMaxMems] != event) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"PetscMallocPush/PopMaximumUsage() are not nested"); 650*e3ed9ee7SBarry Smith *mu = TRMaxMems[NumTRMaxMems]; 651*e3ed9ee7SBarry Smith PetscFunctionReturn(0); 652*e3ed9ee7SBarry Smith } 653*e3ed9ee7SBarry Smith 654a64a8e02SBarry Smith #if defined(PETSC_USE_DEBUG) 655a64a8e02SBarry Smith /*@C 656a64a8e02SBarry Smith PetscMallocGetStack - returns a pointer to the stack for the location in the program a call to PetscMalloc() was used to obtain that memory 657a64a8e02SBarry Smith 658a64a8e02SBarry Smith Collective on PETSC_COMM_WORLD 659a64a8e02SBarry Smith 660a64a8e02SBarry Smith Input Parameter: 661a64a8e02SBarry Smith . ptr - the memory location 662a64a8e02SBarry Smith 663a64a8e02SBarry Smith Output Paramter: 664a64a8e02SBarry Smith . stack - the stack indicating where the program allocated this memory 665a64a8e02SBarry Smith 666a64a8e02SBarry Smith Level: intermediate 667a64a8e02SBarry Smith 668a64a8e02SBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocDumpLog() 669a64a8e02SBarry Smith @*/ 670a64a8e02SBarry Smith PetscErrorCode PetscMallocGetStack(void *ptr,PetscStack **stack) 671a64a8e02SBarry Smith { 672a64a8e02SBarry Smith TRSPACE *head; 673a64a8e02SBarry Smith 674a64a8e02SBarry Smith PetscFunctionBegin; 675a64a8e02SBarry Smith head = (TRSPACE*) (((char*)ptr) - HEADER_BYTES); 676a64a8e02SBarry Smith *stack = &head->stack; 677a64a8e02SBarry Smith PetscFunctionReturn(0); 678a64a8e02SBarry Smith } 67976386721SLisandro Dalcin #else 68076386721SLisandro Dalcin PetscErrorCode PetscMallocGetStack(void *ptr,void **stack) 68176386721SLisandro Dalcin { 68276386721SLisandro Dalcin PetscFunctionBegin; 683f0ba7cfcSLisandro Dalcin *stack = NULL; 68476386721SLisandro Dalcin PetscFunctionReturn(0); 68576386721SLisandro Dalcin } 686a64a8e02SBarry Smith #endif 687a64a8e02SBarry Smith 688e5c89e4eSSatish Balay /*@C 689e5c89e4eSSatish Balay PetscMallocDump - Dumps the allocated memory blocks to a file. The information 690e5c89e4eSSatish Balay printed is: size of space (in bytes), address of space, id of space, 691e5c89e4eSSatish Balay file in which space was allocated, and line number at which it was 692e5c89e4eSSatish Balay allocated. 693e5c89e4eSSatish Balay 694e5c89e4eSSatish Balay Collective on PETSC_COMM_WORLD 695e5c89e4eSSatish Balay 696e5c89e4eSSatish Balay Input Parameter: 697e5c89e4eSSatish Balay . fp - file pointer. If fp is NULL, stdout is assumed. 698e5c89e4eSSatish Balay 699e5c89e4eSSatish Balay Options Database Key: 700e5c89e4eSSatish Balay . -malloc_dump - Dumps unfreed memory during call to PetscFinalize() 701e5c89e4eSSatish Balay 702e5c89e4eSSatish Balay Level: intermediate 703e5c89e4eSSatish Balay 704e5c89e4eSSatish Balay Fortran Note: 705e5c89e4eSSatish Balay The calling sequence in Fortran is PetscMallocDump(integer ierr) 706e5c89e4eSSatish Balay The fp defaults to stdout. 707e5c89e4eSSatish Balay 70895452b02SPatrick Sanan Notes: 70995452b02SPatrick Sanan uses MPI_COMM_WORLD, because this may be called in PetscFinalize() after PETSC_COMM_WORLD 710e5c89e4eSSatish Balay has been freed. 711e5c89e4eSSatish Balay 712e5c89e4eSSatish Balay Concepts: memory usage 713e5c89e4eSSatish Balay Concepts: memory bleeding 714e5c89e4eSSatish Balay Concepts: bleeding memory 715e5c89e4eSSatish Balay 7169e9a1f8fSvictor .seealso: PetscMallocGetCurrentUsage(), PetscMallocDumpLog() 717e5c89e4eSSatish Balay @*/ 7187087cfbeSBarry Smith PetscErrorCode PetscMallocDump(FILE *fp) 719e5c89e4eSSatish Balay { 720e5c89e4eSSatish Balay TRSPACE *head; 721*e3ed9ee7SBarry Smith size_t libAlloc = 0; 722e5c89e4eSSatish Balay PetscErrorCode ierr; 723e5c89e4eSSatish Balay PetscMPIInt rank; 724e5c89e4eSSatish Balay 725e5c89e4eSSatish Balay PetscFunctionBegin; 726e5c89e4eSSatish Balay ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr); 727da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 728e5c89e4eSSatish Balay head = TRhead; 729e5c89e4eSSatish Balay while (head) { 7305486ca60SMatthew G. Knepley libAlloc += head->size; 7315486ca60SMatthew G. Knepley head = head->next; 7325486ca60SMatthew G. Knepley } 7335486ca60SMatthew G. Knepley if (TRallocated - libAlloc > 0) fprintf(fp,"[%d]Total space allocated %.0f bytes\n",rank,(PetscLogDouble)TRallocated); 7345486ca60SMatthew G. Knepley head = TRhead; 7355486ca60SMatthew G. Knepley while (head) { 7365486ca60SMatthew G. Knepley PetscBool isLib; 7375486ca60SMatthew G. Knepley 7385486ca60SMatthew G. Knepley ierr = PetscStrcmp(head->functionname, "PetscDLLibraryOpen", &isLib);CHKERRQ(ierr); 7395486ca60SMatthew G. Knepley if (!isLib) { 740efca3c55SSatish Balay fprintf(fp,"[%2d]%.0f bytes %s() line %d in %s\n",rank,(PetscLogDouble)head->size,head->functionname,head->lineno,head->filename); 7418bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 742e5c89e4eSSatish Balay ierr = PetscStackPrint(&head->stack,fp);CHKERRQ(ierr); 743e5c89e4eSSatish Balay #endif 7445486ca60SMatthew G. Knepley } 745e5c89e4eSSatish Balay head = head->next; 746e5c89e4eSSatish Balay } 747e5c89e4eSSatish Balay PetscFunctionReturn(0); 748e5c89e4eSSatish Balay } 749e5c89e4eSSatish Balay 750e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------- */ 751e5c89e4eSSatish Balay 752dc37d89fSBarry Smith /*@ 753e5c89e4eSSatish Balay PetscMallocSetDumpLog - Activates logging of all calls to PetscMalloc(). 754e5c89e4eSSatish Balay 755e5c89e4eSSatish Balay Not Collective 756e5c89e4eSSatish Balay 757e5c89e4eSSatish Balay Options Database Key: 758574034a9SJed Brown + -malloc_log <filename> - Activates PetscMallocDumpLog() 759574034a9SJed Brown - -malloc_log_threshold <min> - Activates logging and sets a minimum size 760e5c89e4eSSatish Balay 761e5c89e4eSSatish Balay Level: advanced 762e5c89e4eSSatish Balay 763574034a9SJed Brown .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocSetDumpLogThreshold() 764e5c89e4eSSatish Balay @*/ 7657087cfbeSBarry Smith PetscErrorCode PetscMallocSetDumpLog(void) 766e5c89e4eSSatish Balay { 76721b680ceSJed Brown PetscErrorCode ierr; 76821b680ceSJed Brown 769e5c89e4eSSatish Balay PetscFunctionBegin; 770e5c89e4eSSatish Balay PetscLogMalloc = 0; 771a297a907SKarl Rupp 77221b680ceSJed Brown ierr = PetscMemorySetGetMaximumUsage();CHKERRQ(ierr); 773e5c89e4eSSatish Balay PetscFunctionReturn(0); 774e5c89e4eSSatish Balay } 775e5c89e4eSSatish Balay 776dc37d89fSBarry Smith /*@ 777574034a9SJed Brown PetscMallocSetDumpLogThreshold - Activates logging of all calls to PetscMalloc(). 778574034a9SJed Brown 779574034a9SJed Brown Not Collective 780574034a9SJed Brown 781574034a9SJed Brown Input Arguments: 782574034a9SJed Brown . logmin - minimum allocation size to log, or PETSC_DEFAULT 783574034a9SJed Brown 784574034a9SJed Brown Options Database Key: 785574034a9SJed Brown + -malloc_log <filename> - Activates PetscMallocDumpLog() 786574034a9SJed Brown - -malloc_log_threshold <min> - Activates logging and sets a minimum size 787574034a9SJed Brown 788574034a9SJed Brown Level: advanced 789574034a9SJed Brown 790574034a9SJed Brown .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocSetDumpLog() 791574034a9SJed Brown @*/ 792574034a9SJed Brown PetscErrorCode PetscMallocSetDumpLogThreshold(PetscLogDouble logmin) 793574034a9SJed Brown { 794574034a9SJed Brown PetscErrorCode ierr; 795574034a9SJed Brown 796574034a9SJed Brown PetscFunctionBegin; 797574034a9SJed Brown ierr = PetscMallocSetDumpLog();CHKERRQ(ierr); 798574034a9SJed Brown if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */ 799574034a9SJed Brown PetscLogMallocThreshold = (size_t)logmin; 800574034a9SJed Brown PetscFunctionReturn(0); 801574034a9SJed Brown } 802574034a9SJed Brown 803dc37d89fSBarry Smith /*@ 80418a2528dSJed Brown PetscMallocGetDumpLog - Determine whether all calls to PetscMalloc() are being logged 80518a2528dSJed Brown 80618a2528dSJed Brown Not Collective 80718a2528dSJed Brown 80818a2528dSJed Brown Output Arguments 80918a2528dSJed Brown . logging - PETSC_TRUE if logging is active 81018a2528dSJed Brown 81118a2528dSJed Brown Options Database Key: 81218a2528dSJed Brown . -malloc_log - Activates PetscMallocDumpLog() 81318a2528dSJed Brown 81418a2528dSJed Brown Level: advanced 81518a2528dSJed Brown 81618a2528dSJed Brown .seealso: PetscMallocDump(), PetscMallocDumpLog() 81718a2528dSJed Brown @*/ 81818a2528dSJed Brown PetscErrorCode PetscMallocGetDumpLog(PetscBool *logging) 81918a2528dSJed Brown { 82018a2528dSJed Brown 82118a2528dSJed Brown PetscFunctionBegin; 82218a2528dSJed Brown *logging = (PetscBool)(PetscLogMalloc >= 0); 82318a2528dSJed Brown PetscFunctionReturn(0); 82418a2528dSJed Brown } 82518a2528dSJed Brown 826e5c89e4eSSatish Balay /*@C 827e5c89e4eSSatish Balay PetscMallocDumpLog - Dumps the log of all calls to PetscMalloc(); also calls 82821b680ceSJed Brown PetscMemoryGetMaximumUsage() 829e5c89e4eSSatish Balay 830e5c89e4eSSatish Balay Collective on PETSC_COMM_WORLD 831e5c89e4eSSatish Balay 832e5c89e4eSSatish Balay Input Parameter: 8330298fd71SBarry Smith . fp - file pointer; or NULL 834e5c89e4eSSatish Balay 835e5c89e4eSSatish Balay Options Database Key: 836e5c89e4eSSatish Balay . -malloc_log - Activates PetscMallocDumpLog() 837e5c89e4eSSatish Balay 838e5c89e4eSSatish Balay Level: advanced 839e5c89e4eSSatish Balay 840e5c89e4eSSatish Balay Fortran Note: 841e5c89e4eSSatish Balay The calling sequence in Fortran is PetscMallocDumpLog(integer ierr) 842e5c89e4eSSatish Balay The fp defaults to stdout. 843e5c89e4eSSatish Balay 844e5c89e4eSSatish Balay .seealso: PetscMallocGetCurrentUsage(), PetscMallocDump(), PetscMallocSetDumpLog() 845e5c89e4eSSatish Balay @*/ 8467087cfbeSBarry Smith PetscErrorCode PetscMallocDumpLog(FILE *fp) 847e5c89e4eSSatish Balay { 848e5c89e4eSSatish Balay PetscInt i,j,n,dummy,*perm; 849e5c89e4eSSatish Balay size_t *shortlength; 850f56c2debSBarry Smith int *shortcount,err; 851e5c89e4eSSatish Balay PetscMPIInt rank,size,tag = 1212 /* very bad programming */; 852ace3abfcSBarry Smith PetscBool match; 853e5c89e4eSSatish Balay const char **shortfunction; 854e5c89e4eSSatish Balay PetscLogDouble rss; 855e5c89e4eSSatish Balay MPI_Status status; 856e5c89e4eSSatish Balay PetscErrorCode ierr; 857e5c89e4eSSatish Balay 858e5c89e4eSSatish Balay PetscFunctionBegin; 859e5c89e4eSSatish Balay ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr); 860e5c89e4eSSatish Balay ierr = MPI_Comm_size(MPI_COMM_WORLD,&size);CHKERRQ(ierr); 861e5c89e4eSSatish Balay /* 862e5c89e4eSSatish Balay Try to get the data printed in order by processor. This will only sometimes work 863e5c89e4eSSatish Balay */ 864f56c2debSBarry Smith err = fflush(fp); 865e32f2f54SBarry Smith if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 866f56c2debSBarry Smith 867e5c89e4eSSatish Balay ierr = MPI_Barrier(MPI_COMM_WORLD);CHKERRQ(ierr); 868e5c89e4eSSatish Balay if (rank) { 869e5c89e4eSSatish Balay ierr = MPI_Recv(&dummy,1,MPIU_INT,rank-1,tag,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 870e5c89e4eSSatish Balay } 871e5c89e4eSSatish Balay 872768aa557SSatish 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()"); 873768aa557SSatish Balay 874da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 875f3d65365SJed Brown ierr = PetscMemoryGetMaximumUsage(&rss);CHKERRQ(ierr); 876e5c89e4eSSatish Balay if (rss) { 877f3d65365SJed 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); 878e5c89e4eSSatish Balay } else { 879e5c89e4eSSatish 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); 880e5c89e4eSSatish Balay } 881e32f2f54SBarry Smith shortcount = (int*)malloc(PetscLogMalloc*sizeof(int));if (!shortcount) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 882e32f2f54SBarry Smith shortlength = (size_t*)malloc(PetscLogMalloc*sizeof(size_t));if (!shortlength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 883e32f2f54SBarry Smith shortfunction = (const char**)malloc(PetscLogMalloc*sizeof(char*));if (!shortfunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 88497b9d747SJed Brown for (i=0,n=0; i<PetscLogMalloc; i++) { 885e5c89e4eSSatish Balay for (j=0; j<n; j++) { 886e5c89e4eSSatish Balay ierr = PetscStrcmp(shortfunction[j],PetscLogMallocFunction[i],&match);CHKERRQ(ierr); 887e5c89e4eSSatish Balay if (match) { 888e5c89e4eSSatish Balay shortlength[j] += PetscLogMallocLength[i]; 88959ffdab8SBarry Smith shortcount[j]++; 890e5c89e4eSSatish Balay goto foundit; 891e5c89e4eSSatish Balay } 892e5c89e4eSSatish Balay } 893e5c89e4eSSatish Balay shortfunction[n] = PetscLogMallocFunction[i]; 894e5c89e4eSSatish Balay shortlength[n] = PetscLogMallocLength[i]; 89559ffdab8SBarry Smith shortcount[n] = 1; 896e5c89e4eSSatish Balay n++; 897e5c89e4eSSatish Balay foundit:; 898e5c89e4eSSatish Balay } 899e5c89e4eSSatish Balay 900e32f2f54SBarry Smith perm = (PetscInt*)malloc(n*sizeof(PetscInt));if (!perm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 901e5c89e4eSSatish Balay for (i=0; i<n; i++) perm[i] = i; 902e5c89e4eSSatish Balay ierr = PetscSortStrWithPermutation(n,(const char**)shortfunction,perm);CHKERRQ(ierr); 903e5c89e4eSSatish Balay 904e5c89e4eSSatish Balay ierr = PetscFPrintf(MPI_COMM_WORLD,fp,"[%d] Memory usage sorted by function\n",rank);CHKERRQ(ierr); 905e5c89e4eSSatish Balay for (i=0; i<n; i++) { 90659ffdab8SBarry 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); 907e5c89e4eSSatish Balay } 908e5c89e4eSSatish Balay free(perm); 909e5c89e4eSSatish Balay free(shortlength); 91059ffdab8SBarry Smith free(shortcount); 911e5c89e4eSSatish Balay free((char**)shortfunction); 912f56c2debSBarry Smith err = fflush(fp); 913e32f2f54SBarry Smith if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 914e5c89e4eSSatish Balay if (rank != size-1) { 915e5c89e4eSSatish Balay ierr = MPI_Send(&dummy,1,MPIU_INT,rank+1,tag,MPI_COMM_WORLD);CHKERRQ(ierr); 916e5c89e4eSSatish Balay } 917e5c89e4eSSatish Balay PetscFunctionReturn(0); 918e5c89e4eSSatish Balay } 919e5c89e4eSSatish Balay 920e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------- */ 921e5c89e4eSSatish Balay 922dc37d89fSBarry Smith /*@ 923e5c89e4eSSatish Balay PetscMallocDebug - Turns on/off debugging for the memory management routines. 924e5c89e4eSSatish Balay 925e5c89e4eSSatish Balay Not Collective 926e5c89e4eSSatish Balay 927e5c89e4eSSatish Balay Input Parameter: 928e5c89e4eSSatish Balay . level - PETSC_TRUE or PETSC_FALSE 929e5c89e4eSSatish Balay 930e5c89e4eSSatish Balay Level: intermediate 931e5c89e4eSSatish Balay 932e5c89e4eSSatish Balay .seealso: CHKMEMQ(), PetscMallocValidate() 933e5c89e4eSSatish Balay @*/ 9347087cfbeSBarry Smith PetscErrorCode PetscMallocDebug(PetscBool level) 935e5c89e4eSSatish Balay { 936e5c89e4eSSatish Balay PetscFunctionBegin; 937e5c89e4eSSatish Balay TRdebugLevel = level; 938e5c89e4eSSatish Balay PetscFunctionReturn(0); 939e5c89e4eSSatish Balay } 9400acecf5bSBarry Smith 941dc37d89fSBarry Smith /*@ 9420acecf5bSBarry Smith PetscMallocGetDebug - Indicates if any PETSc is doing ANY memory debugging. 9430acecf5bSBarry Smith 9440acecf5bSBarry Smith Not Collective 9450acecf5bSBarry Smith 9460acecf5bSBarry Smith Output Parameter: 9470acecf5bSBarry Smith . flg - PETSC_TRUE if any debugger 9480acecf5bSBarry Smith 9490acecf5bSBarry Smith Level: intermediate 9500acecf5bSBarry Smith 9510acecf5bSBarry Smith Note that by default, the debug version always does some debugging unless you run with -malloc no 9520acecf5bSBarry Smith 9530acecf5bSBarry Smith 9540acecf5bSBarry Smith .seealso: CHKMEMQ(), PetscMallocValidate() 9550acecf5bSBarry Smith @*/ 9560acecf5bSBarry Smith PetscErrorCode PetscMallocGetDebug(PetscBool *flg) 9570acecf5bSBarry Smith { 9580acecf5bSBarry Smith PetscFunctionBegin; 9590acecf5bSBarry Smith if (PetscTrMalloc == PetscTrMallocDefault) *flg = PETSC_TRUE; 9600acecf5bSBarry Smith else *flg = PETSC_FALSE; 9610acecf5bSBarry Smith PetscFunctionReturn(0); 9620acecf5bSBarry Smith } 963