17d0a6c19SBarry Smith 2e5c89e4eSSatish Balay /* 392f119d6SBarry Smith Interface to malloc() and free(). This code allows for logging of memory usage and some error checking 4e5c89e4eSSatish Balay */ 5c6db04a5SJed Brown #include <petscsys.h> /*I "petscsys.h" I*/ 6665c2dedSJed Brown #include <petscviewer.h> 7e5c89e4eSSatish Balay #if defined(PETSC_HAVE_MALLOC_H) 8e5c89e4eSSatish Balay #include <malloc.h> 9e5c89e4eSSatish Balay #endif 10e5c89e4eSSatish Balay 11e5c89e4eSSatish Balay /* 12e5c89e4eSSatish Balay These are defined in mal.c and ensure that malloced space is PetscScalar aligned 13e5c89e4eSSatish Balay */ 14071fcb05SBarry Smith PETSC_EXTERN PetscErrorCode PetscMallocAlign(size_t,PetscBool,int,const char[],const char[],void**); 1595c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscFreeAlign(void*,int,const char[],const char[]); 1695c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscReallocAlign(size_t,int,const char[],const char[],void**); 17e5c89e4eSSatish Balay 180700a824SBarry Smith #define CLASSID_VALUE ((PetscClassId) 0xf0e0d0c9) 190700a824SBarry Smith #define ALREADY_FREED ((PetscClassId) 0x0f0e0d9c) 20e5c89e4eSSatish Balay 2192f119d6SBarry Smith /* this is the header put at the beginning of each malloc() using for tracking allocated space and checking of allocated space heap */ 22e5c89e4eSSatish Balay typedef struct _trSPACE { 23608c71bfSMatthew G. Knepley size_t size, rsize; /* Aligned size and requested size */ 24e5c89e4eSSatish Balay int id; 25e5c89e4eSSatish Balay int lineno; 26e5c89e4eSSatish Balay const char *filename; 27e5c89e4eSSatish Balay const char *functionname; 280700a824SBarry Smith PetscClassId classid; 298bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 30e5c89e4eSSatish Balay PetscStack stack; 31e5c89e4eSSatish Balay #endif 32e5c89e4eSSatish Balay struct _trSPACE *next,*prev; 33e5c89e4eSSatish Balay } TRSPACE; 34e5c89e4eSSatish Balay 3525b53cc9SJed Brown /* HEADER_BYTES is the number of bytes in a PetscMalloc() header. 3692f119d6SBarry Smith It is sizeof(trSPACE) padded to be a multiple of PETSC_MEMALIGN. 3725b53cc9SJed Brown */ 38a64a8e02SBarry Smith #define HEADER_BYTES ((sizeof(TRSPACE)+(PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1)) 39e5c89e4eSSatish Balay 4025b53cc9SJed Brown /* This union is used to insure that the block passed to the user retains 4125b53cc9SJed Brown a minimum alignment of PETSC_MEMALIGN. 4225b53cc9SJed Brown */ 43e5c89e4eSSatish Balay typedef union { 44e5c89e4eSSatish Balay TRSPACE sp; 4525b53cc9SJed Brown char v[HEADER_BYTES]; 46e5c89e4eSSatish Balay } TrSPACE; 47e5c89e4eSSatish Balay 48e3ed9ee7SBarry Smith #define MAXTRMAXMEMS 50 49e5c89e4eSSatish Balay static size_t TRallocated = 0; 50e5c89e4eSSatish Balay static int TRfrags = 0; 51f0ba7cfcSLisandro Dalcin static TRSPACE *TRhead = NULL; 52e5c89e4eSSatish Balay static int TRid = 0; 53ace3abfcSBarry Smith static PetscBool TRdebugLevel = PETSC_FALSE; 542d4ee042Sprj- static PetscBool TRdebugIinitializenan= PETSC_FALSE; 55608c71bfSMatthew G. Knepley static PetscBool TRrequestedSize = PETSC_FALSE; 56e5c89e4eSSatish Balay static size_t TRMaxMem = 0; 57e3ed9ee7SBarry Smith static int NumTRMaxMems = 0; 58e3ed9ee7SBarry Smith static size_t TRMaxMems[MAXTRMAXMEMS]; 59e3ed9ee7SBarry Smith static int TRMaxMemsEvents[MAXTRMAXMEMS]; 60e5c89e4eSSatish Balay /* 6192f119d6SBarry Smith Arrays to log information on mallocs for PetscMallocView() 62e5c89e4eSSatish Balay */ 63f0ba7cfcSLisandro Dalcin static int PetscLogMallocMax = 10000; 64f0ba7cfcSLisandro Dalcin static int PetscLogMalloc = -1; 65574034a9SJed Brown static size_t PetscLogMallocThreshold = 0; 66e5c89e4eSSatish Balay static size_t *PetscLogMallocLength; 67efca3c55SSatish Balay static const char **PetscLogMallocFile,**PetscLogMallocFunction; 68608c71bfSMatthew G. Knepley static int PetscLogMallocTrace = -1; 69608c71bfSMatthew G. Knepley static size_t PetscLogMallocTraceThreshold = 0; 70608c71bfSMatthew G. Knepley static PetscViewer PetscLogMallocTraceViewer = NULL; 71b022a5c1SBarry Smith 72e5c89e4eSSatish Balay /*@C 7392f119d6SBarry Smith PetscMallocValidate - Test the memory for corruption. This can be called at any time between PetscInitialize() and PetscFinalize() 74e5c89e4eSSatish Balay 7592f119d6SBarry Smith Input Parameters: 76e5c89e4eSSatish Balay + line - line number where call originated. 77e5c89e4eSSatish Balay . function - name of function calling 78efca3c55SSatish Balay - file - file where function is 79e5c89e4eSSatish Balay 80e5c89e4eSSatish Balay Return value: 81e5c89e4eSSatish Balay The number of errors detected. 82e5c89e4eSSatish Balay 8392f119d6SBarry Smith Options Database:. 8492f119d6SBarry Smith + -malloc_test - turns this feature on when PETSc was not configured with --with-debugging=0 8592f119d6SBarry Smith - -malloc_debug - turns this feature on anytime 8692f119d6SBarry Smith 87e5c89e4eSSatish Balay Output Effect: 88e5c89e4eSSatish Balay Error messages are written to stdout. 89e5c89e4eSSatish Balay 90e5c89e4eSSatish Balay Level: advanced 91e5c89e4eSSatish Balay 92e5c89e4eSSatish Balay Notes: 9379dccf82SBarry Smith This is only run if PetscMallocSetDebug() has been called which is set by -malloc_test (if debugging is turned on) or -malloc_debug (any time) 9438548759SBarry Smith 9592f119d6SBarry Smith You should generally use CHKMEMQ as a short cut for calling this routine. 96e5c89e4eSSatish Balay 97e5c89e4eSSatish Balay The Fortran calling sequence is simply PetscMallocValidate(ierr) 98e5c89e4eSSatish Balay 99e5c89e4eSSatish Balay No output is generated if there are no problems detected. 100e5c89e4eSSatish Balay 10192f119d6SBarry Smith Developers Note: 10292f119d6SBarry Smith Uses the flg TRdebugLevel (set as the first argument to PetscMallocSetDebug()) to determine if it should run 10392f119d6SBarry Smith 104e5c89e4eSSatish Balay .seealso: CHKMEMQ 105e5c89e4eSSatish Balay 106e5c89e4eSSatish Balay @*/ 107efca3c55SSatish Balay PetscErrorCode PetscMallocValidate(int line,const char function[],const char file[]) 108e5c89e4eSSatish Balay { 1096c093d5bSvictor TRSPACE *head,*lasthead; 110e5c89e4eSSatish Balay char *a; 1110700a824SBarry Smith PetscClassId *nend; 112e5c89e4eSSatish Balay 11338548759SBarry Smith if (!TRdebugLevel) return 0; 114e5c89e4eSSatish Balay PetscFunctionBegin; 1156c093d5bSvictor head = TRhead; lasthead = NULL; 1162cba8197SMatthew G. Knepley if (head && head->prev) { 1172cba8197SMatthew G. Knepley (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 1182cba8197SMatthew G. Knepley (*PetscErrorPrintf)("Root memory header %p has invalid back pointer %p\n",head,head->prev); 1192cba8197SMatthew G. Knepley } 120e5c89e4eSSatish Balay while (head) { 1210700a824SBarry Smith if (head->classid != CLASSID_VALUE) { 122efca3c55SSatish Balay (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 123e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory at address %p is corrupted\n",head); 124e5c89e4eSSatish Balay (*PetscErrorPrintf)("Probably write past beginning or end of array\n"); 125efca3c55SSatish Balay if (lasthead) (*PetscErrorPrintf)("Last intact block allocated in %s() line %d in %s\n",lasthead->functionname,lasthead->lineno,lasthead->filename); 126e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 127e5c89e4eSSatish Balay } 128e5c89e4eSSatish Balay a = (char*)(((TrSPACE*)head) + 1); 1290700a824SBarry Smith nend = (PetscClassId*)(a + head->size); 1300700a824SBarry Smith if (*nend != CLASSID_VALUE) { 131efca3c55SSatish Balay (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 132e5c89e4eSSatish Balay if (*nend == ALREADY_FREED) { 133e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p already freed\n",head->id,(PetscLogDouble)head->size,a); 134e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 135e5c89e4eSSatish Balay } else { 136e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 137efca3c55SSatish Balay (*PetscErrorPrintf)("Memory originally allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 138e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 139e5c89e4eSSatish Balay } 140e5c89e4eSSatish Balay } 1412cba8197SMatthew G. Knepley if (head->prev && head->prev != lasthead) { 1422cba8197SMatthew G. Knepley (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 1432cba8197SMatthew G. Knepley (*PetscErrorPrintf)("Backpointer %p is invalid, should be %p\n",head->prev,lasthead); 1442cba8197SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 1452cba8197SMatthew G. Knepley } 1462cba8197SMatthew G. Knepley if (head->next && head != head->next->prev) { 1472cba8197SMatthew G. Knepley (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file); 1482cba8197SMatthew G. Knepley (*PetscErrorPrintf)("Next memory header %p has invalid back pointer %p, should be %p\n",head->next,head->next->prev,head); 1492cba8197SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," "); 1502cba8197SMatthew G. Knepley } 1516c093d5bSvictor lasthead = head; 152e5c89e4eSSatish Balay head = head->next; 153e5c89e4eSSatish Balay } 154e5c89e4eSSatish Balay PetscFunctionReturn(0); 155e5c89e4eSSatish Balay } 156e5c89e4eSSatish Balay 157e5c89e4eSSatish Balay /* 158e5c89e4eSSatish Balay PetscTrMallocDefault - Malloc with tracing. 159e5c89e4eSSatish Balay 160e5c89e4eSSatish Balay Input Parameters: 161e5c89e4eSSatish Balay + a - number of bytes to allocate 162e5c89e4eSSatish Balay . lineno - line number where used. Use __LINE__ for this 163efca3c55SSatish Balay - filename - file name where used. Use __FILE__ for this 164e5c89e4eSSatish Balay 165e5c89e4eSSatish Balay Returns: 16692f119d6SBarry Smith double aligned pointer to requested storage, or null if not available. 167e5c89e4eSSatish Balay */ 168071fcb05SBarry Smith PetscErrorCode PetscTrMallocDefault(size_t a,PetscBool clear,int lineno,const char function[],const char filename[],void **result) 169e5c89e4eSSatish Balay { 170e5c89e4eSSatish Balay TRSPACE *head; 171e5c89e4eSSatish Balay char *inew; 172e5c89e4eSSatish Balay size_t nsize; 173e5c89e4eSSatish Balay PetscErrorCode ierr; 174e5c89e4eSSatish Balay 175e5c89e4eSSatish Balay PetscFunctionBegin; 176f0ba7cfcSLisandro Dalcin /* Do not try to handle empty blocks */ 177f0ba7cfcSLisandro Dalcin if (!a) { *result = NULL; PetscFunctionReturn(0); } 178f0ba7cfcSLisandro Dalcin 179efca3c55SSatish Balay ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr); 180e5c89e4eSSatish Balay 18125b53cc9SJed Brown nsize = (a + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1); 182071fcb05SBarry Smith ierr = PetscMallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),clear,lineno,function,filename,(void**)&inew);CHKERRQ(ierr); 183e3ed9ee7SBarry Smith 184e5c89e4eSSatish Balay head = (TRSPACE*)inew; 185e5c89e4eSSatish Balay inew += sizeof(TrSPACE); 186e5c89e4eSSatish Balay 187e5c89e4eSSatish Balay if (TRhead) TRhead->prev = head; 188e5c89e4eSSatish Balay head->next = TRhead; 189e5c89e4eSSatish Balay TRhead = head; 190f0ba7cfcSLisandro Dalcin head->prev = NULL; 191e5c89e4eSSatish Balay head->size = nsize; 192608c71bfSMatthew G. Knepley head->rsize = a; 193e5c89e4eSSatish Balay head->id = TRid; 194e5c89e4eSSatish Balay head->lineno = lineno; 195e5c89e4eSSatish Balay 196e5c89e4eSSatish Balay head->filename = filename; 197e5c89e4eSSatish Balay head->functionname = function; 1980700a824SBarry Smith head->classid = CLASSID_VALUE; 1990700a824SBarry Smith *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 200e5c89e4eSSatish Balay 201608c71bfSMatthew G. Knepley TRallocated += TRrequestedSize ? head->rsize : head->size; 202a297a907SKarl Rupp if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 203e3ed9ee7SBarry Smith if (PetscLogMemory) { 204e3ed9ee7SBarry Smith PetscInt i; 205e3ed9ee7SBarry Smith for (i=0; i<NumTRMaxMems; i++) { 206e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 207e3ed9ee7SBarry Smith } 208e3ed9ee7SBarry Smith } 209e5c89e4eSSatish Balay TRfrags++; 210e5c89e4eSSatish Balay 2118bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 21276386721SLisandro Dalcin if (PetscStackActive()) { 2135c25fcd7SBarry Smith ierr = PetscStackCopy(petscstack,&head->stack);CHKERRQ(ierr); 2142c9581d2SBarry Smith /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 2152c9581d2SBarry Smith head->stack.line[head->stack.currentsize-2] = lineno; 2169de0f6ecSBarry Smith } else { 2179de0f6ecSBarry Smith head->stack.currentsize = 0; 21876386721SLisandro Dalcin } 21992f119d6SBarry Smith #if defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL_DOUBLE) 2202d4ee042Sprj- if (!clear && TRdebugIinitializenan) { 22192f119d6SBarry Smith size_t i, n = a/sizeof(PetscReal); 22292f119d6SBarry Smith PetscReal *s = (PetscReal*) inew; 22392f119d6SBarry Smith /* from https://www.doc.ic.ac.uk/~eedwards/compsys/float/nan.html */ 22492f119d6SBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 225df282883SBarry Smith int nas = 0x7F800002; 22692f119d6SBarry Smith #else 22792f119d6SBarry Smith PetscInt64 nas = 0x7FF0000000000002; 22892f119d6SBarry Smith #endif 22992f119d6SBarry Smith for (i=0; i<n; i++) { 23092f119d6SBarry Smith memcpy(s+i,&nas,sizeof(PetscReal)); 23192f119d6SBarry Smith } 23292f119d6SBarry Smith } 23392f119d6SBarry Smith #endif 234e5c89e4eSSatish Balay #endif 235e5c89e4eSSatish Balay 236e5c89e4eSSatish Balay /* 23792f119d6SBarry Smith Allow logging of all mallocs made. 23892f119d6SBarry Smith TODO: Currently this memory is never freed, it should be freed during PetscFinalize() 239e5c89e4eSSatish Balay */ 240574034a9SJed Brown if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && a >= PetscLogMallocThreshold) { 241e5c89e4eSSatish Balay if (!PetscLogMalloc) { 242e5c89e4eSSatish Balay PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 243e32f2f54SBarry Smith if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 244a297a907SKarl Rupp 245a2ea699eSBarry Smith PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 246e32f2f54SBarry Smith if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 247a297a907SKarl Rupp 248a2ea699eSBarry Smith PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 249e32f2f54SBarry Smith if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 250e5c89e4eSSatish Balay } 251e5c89e4eSSatish Balay PetscLogMallocLength[PetscLogMalloc] = nsize; 252e5c89e4eSSatish Balay PetscLogMallocFile[PetscLogMalloc] = filename; 253e5c89e4eSSatish Balay PetscLogMallocFunction[PetscLogMalloc++] = function; 254e5c89e4eSSatish Balay } 255608c71bfSMatthew G. Knepley if (PetscLogMallocTrace > -1 && a >= PetscLogMallocTraceThreshold) { 256608c71bfSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(PetscLogMallocTraceViewer,"Alloc %zu %s:%d (%s)\n", a, filename ? filename : "null", lineno, function ? function : "null");CHKERRQ(ierr); 257608c71bfSMatthew G. Knepley } 258e5c89e4eSSatish Balay *result = (void*)inew; 259e5c89e4eSSatish Balay PetscFunctionReturn(0); 260e5c89e4eSSatish Balay } 261e5c89e4eSSatish Balay 262e5c89e4eSSatish Balay /* 263e5c89e4eSSatish Balay PetscTrFreeDefault - Free with tracing. 264e5c89e4eSSatish Balay 265e5c89e4eSSatish Balay Input Parameters: 266e5c89e4eSSatish Balay . a - pointer to a block allocated with PetscTrMalloc 267e5c89e4eSSatish Balay . lineno - line number where used. Use __LINE__ for this 268608c71bfSMatthew G. Knepley . filename - file name where used. Use __FILE__ for this 269e5c89e4eSSatish Balay */ 270608c71bfSMatthew G. Knepley PetscErrorCode PetscTrFreeDefault(void *aa,int lineno,const char function[],const char filename[]) 271e5c89e4eSSatish Balay { 272e5c89e4eSSatish Balay char *a = (char*)aa; 273e5c89e4eSSatish Balay TRSPACE *head; 274e5c89e4eSSatish Balay char *ahead; 275608c71bfSMatthew G. Knepley size_t asize; 276e5c89e4eSSatish Balay PetscErrorCode ierr; 2770700a824SBarry Smith PetscClassId *nend; 278e5c89e4eSSatish Balay 279e5c89e4eSSatish Balay PetscFunctionBegin; 280e5c89e4eSSatish Balay /* Do not try to handle empty blocks */ 28149d7da52SJed Brown if (!a) PetscFunctionReturn(0); 282e5c89e4eSSatish Balay 283608c71bfSMatthew G. Knepley ierr = PetscMallocValidate(lineno,function,filename);CHKERRQ(ierr); 284e5c89e4eSSatish Balay 285e5c89e4eSSatish Balay ahead = a; 286e5c89e4eSSatish Balay a = a - sizeof(TrSPACE); 287e5c89e4eSSatish Balay head = (TRSPACE*)a; 288e5c89e4eSSatish Balay 2890700a824SBarry Smith if (head->classid != CLASSID_VALUE) { 290608c71bfSMatthew G. Knepley (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,lineno,filename); 291e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 292e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); 293e5c89e4eSSatish Balay } 2940700a824SBarry Smith nend = (PetscClassId*)(ahead + head->size); 2950700a824SBarry Smith if (*nend != CLASSID_VALUE) { 296e5c89e4eSSatish Balay if (*nend == ALREADY_FREED) { 297608c71bfSMatthew G. Knepley (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,lineno,filename); 298e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 299e5c89e4eSSatish Balay if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 300efca3c55SSatish Balay (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 301e5c89e4eSSatish Balay } else { 302efca3c55SSatish Balay (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename); 303e5c89e4eSSatish Balay } 304e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); 305e5c89e4eSSatish Balay } else { 306e5c89e4eSSatish Balay /* Damaged tail */ 307608c71bfSMatthew G. Knepley (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,lineno,filename); 308e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 309efca3c55SSatish Balay (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 310e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); 311e5c89e4eSSatish Balay } 312e5c89e4eSSatish Balay } 313608c71bfSMatthew G. Knepley if (PetscLogMallocTrace > -1 && head->rsize >= PetscLogMallocTraceThreshold) { 314608c71bfSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(PetscLogMallocTraceViewer, "Free %zu %s:%d (%s)\n", head->rsize, filename ? filename : "null", lineno, function ? function : "null");CHKERRQ(ierr); 315608c71bfSMatthew G. Knepley } 316e5c89e4eSSatish Balay /* Mark the location freed */ 317e5c89e4eSSatish Balay *nend = ALREADY_FREED; 318e5c89e4eSSatish Balay /* Save location where freed. If we suspect the line number, mark as allocated location */ 319608c71bfSMatthew G. Knepley if (lineno > 0 && lineno < 50000) { 320608c71bfSMatthew G. Knepley head->lineno = lineno; 321608c71bfSMatthew G. Knepley head->filename = filename; 322e5c89e4eSSatish Balay head->functionname = function; 323e5c89e4eSSatish Balay } else { 324e5c89e4eSSatish Balay head->lineno = -head->lineno; 325e5c89e4eSSatish Balay } 326608c71bfSMatthew G. Knepley asize = TRrequestedSize ? head->rsize : head->size; 327608c71bfSMatthew G. Knepley if (TRallocated < asize) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"TRallocate is smaller than memory just freed"); 328608c71bfSMatthew G. Knepley TRallocated -= asize; 329e5c89e4eSSatish Balay TRfrags--; 330e5c89e4eSSatish Balay if (head->prev) head->prev->next = head->next; 331e5c89e4eSSatish Balay else TRhead = head->next; 332e5c89e4eSSatish Balay 333e5c89e4eSSatish Balay if (head->next) head->next->prev = head->prev; 334608c71bfSMatthew G. Knepley ierr = PetscFreeAlign(a,lineno,function,filename);CHKERRQ(ierr); 335e5c89e4eSSatish Balay PetscFunctionReturn(0); 336e5c89e4eSSatish Balay } 337e5c89e4eSSatish Balay 3383221ece2SMatthew G. Knepley /* 3393221ece2SMatthew G. Knepley PetscTrReallocDefault - Realloc with tracing. 3403221ece2SMatthew G. Knepley 3413221ece2SMatthew G. Knepley Input Parameters: 3423221ece2SMatthew G. Knepley + len - number of bytes to allocate 3433221ece2SMatthew G. Knepley . lineno - line number where used. Use __LINE__ for this 3443221ece2SMatthew G. Knepley . filename - file name where used. Use __FILE__ for this 34592f119d6SBarry Smith - result - original memory 3463221ece2SMatthew G. Knepley 3473221ece2SMatthew G. Knepley Output Parameter: 3483221ece2SMatthew G. Knepley . result - double aligned pointer to requested storage, or null if not available. 3493221ece2SMatthew G. Knepley 3503221ece2SMatthew G. Knepley Level: developer 3513221ece2SMatthew G. Knepley 3523221ece2SMatthew G. Knepley .seealso: PetscTrMallocDefault(), PetscTrFreeDefault() 3533221ece2SMatthew G. Knepley */ 3543221ece2SMatthew G. Knepley PetscErrorCode PetscTrReallocDefault(size_t len, int lineno, const char function[], const char filename[], void **result) 3553221ece2SMatthew G. Knepley { 3563221ece2SMatthew G. Knepley char *a = (char *) *result; 3573221ece2SMatthew G. Knepley TRSPACE *head; 3583221ece2SMatthew G. Knepley char *ahead, *inew; 3593221ece2SMatthew G. Knepley PetscClassId *nend; 3603221ece2SMatthew G. Knepley size_t nsize; 3613221ece2SMatthew G. Knepley PetscErrorCode ierr; 3623221ece2SMatthew G. Knepley 3633221ece2SMatthew G. Knepley PetscFunctionBegin; 36492f119d6SBarry Smith /* Realloc requests zero space so just free the current space */ 365c22f1541SToby Isaac if (!len) { 366c22f1541SToby Isaac ierr = PetscTrFreeDefault(*result,lineno,function,filename);CHKERRQ(ierr); 367c22f1541SToby Isaac *result = NULL; 368c22f1541SToby Isaac PetscFunctionReturn(0); 369c22f1541SToby Isaac } 37092f119d6SBarry Smith /* If the orginal space was NULL just use the regular malloc() */ 371f590eff4SLisandro Dalcin if (!*result) { 372071fcb05SBarry Smith ierr = PetscTrMallocDefault(len,PETSC_FALSE,lineno,function,filename,result);CHKERRQ(ierr); 373f590eff4SLisandro Dalcin PetscFunctionReturn(0); 374f590eff4SLisandro Dalcin } 3753221ece2SMatthew G. Knepley 37638548759SBarry Smith ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr); 3773221ece2SMatthew G. Knepley 3783221ece2SMatthew G. Knepley ahead = a; 3793221ece2SMatthew G. Knepley a = a - sizeof(TrSPACE); 3803221ece2SMatthew G. Knepley head = (TRSPACE *) a; 3813221ece2SMatthew G. Knepley inew = a; 3823221ece2SMatthew G. Knepley 3833221ece2SMatthew G. Knepley if (head->classid != CLASSID_VALUE) { 3843221ece2SMatthew G. Knepley (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename); 3853221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 3863221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); 3873221ece2SMatthew G. Knepley } 3883221ece2SMatthew G. Knepley nend = (PetscClassId *)(ahead + head->size); 3893221ece2SMatthew G. Knepley if (*nend != CLASSID_VALUE) { 3903221ece2SMatthew G. Knepley if (*nend == ALREADY_FREED) { 3913221ece2SMatthew G. Knepley (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename); 3923221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 3933221ece2SMatthew G. Knepley if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 3943221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 3953221ece2SMatthew G. Knepley } else { 3963221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename); 3973221ece2SMatthew G. Knepley } 3983221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); 3993221ece2SMatthew G. Knepley } else { 4003221ece2SMatthew G. Knepley /* Damaged tail */ 4013221ece2SMatthew G. Knepley (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename); 4023221ece2SMatthew 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); 4033221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); 4043221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); 4053221ece2SMatthew G. Knepley } 4063221ece2SMatthew G. Knepley } 4073221ece2SMatthew G. Knepley 40892f119d6SBarry Smith /* remove original reference to the memory allocated from the PETSc debugging heap */ 409608c71bfSMatthew G. Knepley TRallocated -= TRrequestedSize ? head->rsize : head->size; 4103221ece2SMatthew G. Knepley TRfrags--; 4113221ece2SMatthew G. Knepley if (head->prev) head->prev->next = head->next; 4123221ece2SMatthew G. Knepley else TRhead = head->next; 4133221ece2SMatthew G. Knepley if (head->next) head->next->prev = head->prev; 4143221ece2SMatthew G. Knepley 4153221ece2SMatthew G. Knepley nsize = (len + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1); 4163221ece2SMatthew G. Knepley ierr = PetscReallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),lineno,function,filename,(void**)&inew);CHKERRQ(ierr); 4173221ece2SMatthew G. Knepley 4183221ece2SMatthew G. Knepley head = (TRSPACE*)inew; 4193221ece2SMatthew G. Knepley inew += sizeof(TrSPACE); 4203221ece2SMatthew G. Knepley 4213221ece2SMatthew G. Knepley if (TRhead) TRhead->prev = head; 4223221ece2SMatthew G. Knepley head->next = TRhead; 4233221ece2SMatthew G. Knepley TRhead = head; 4243221ece2SMatthew G. Knepley head->prev = NULL; 4253221ece2SMatthew G. Knepley head->size = nsize; 426608c71bfSMatthew G. Knepley head->rsize = len; 4273221ece2SMatthew G. Knepley head->id = TRid; 4283221ece2SMatthew G. Knepley head->lineno = lineno; 4293221ece2SMatthew G. Knepley 4303221ece2SMatthew G. Knepley head->filename = filename; 4313221ece2SMatthew G. Knepley head->functionname = function; 4323221ece2SMatthew G. Knepley head->classid = CLASSID_VALUE; 4333221ece2SMatthew G. Knepley *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 4343221ece2SMatthew G. Knepley 435608c71bfSMatthew G. Knepley TRallocated += TRrequestedSize ? head->rsize : head->size; 4363221ece2SMatthew G. Knepley if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 437e3ed9ee7SBarry Smith if (PetscLogMemory) { 438e3ed9ee7SBarry Smith PetscInt i; 439e3ed9ee7SBarry Smith for (i=0; i<NumTRMaxMems; i++) { 440e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 441e3ed9ee7SBarry Smith } 442e3ed9ee7SBarry Smith } 4433221ece2SMatthew G. Knepley TRfrags++; 4443221ece2SMatthew G. Knepley 4453221ece2SMatthew G. Knepley #if defined(PETSC_USE_DEBUG) 4463221ece2SMatthew G. Knepley if (PetscStackActive()) { 4473221ece2SMatthew G. Knepley ierr = PetscStackCopy(petscstack,&head->stack);CHKERRQ(ierr); 4483221ece2SMatthew G. Knepley /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 4493221ece2SMatthew G. Knepley head->stack.line[head->stack.currentsize-2] = lineno; 4503221ece2SMatthew G. Knepley } else { 4513221ece2SMatthew G. Knepley head->stack.currentsize = 0; 4523221ece2SMatthew G. Knepley } 4533221ece2SMatthew G. Knepley #endif 4543221ece2SMatthew G. Knepley 4553221ece2SMatthew G. Knepley /* 45692f119d6SBarry Smith Allow logging of all mallocs made. This adds a new entry to the list of allocated memory 45792f119d6SBarry Smith and does not remove the previous entry to the list hence this memory is "double counted" in PetscMallocView() 4583221ece2SMatthew G. Knepley */ 4593221ece2SMatthew G. Knepley if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && len >= PetscLogMallocThreshold) { 4603221ece2SMatthew G. Knepley if (!PetscLogMalloc) { 4613221ece2SMatthew G. Knepley PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 4623221ece2SMatthew G. Knepley if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4633221ece2SMatthew G. Knepley 4643221ece2SMatthew G. Knepley PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 4653221ece2SMatthew G. Knepley if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4663221ece2SMatthew G. Knepley 4673221ece2SMatthew G. Knepley PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 4683221ece2SMatthew G. Knepley if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4693221ece2SMatthew G. Knepley } 4703221ece2SMatthew G. Knepley PetscLogMallocLength[PetscLogMalloc] = nsize; 4713221ece2SMatthew G. Knepley PetscLogMallocFile[PetscLogMalloc] = filename; 4723221ece2SMatthew G. Knepley PetscLogMallocFunction[PetscLogMalloc++] = function; 4733221ece2SMatthew G. Knepley } 4743221ece2SMatthew G. Knepley *result = (void*)inew; 4753221ece2SMatthew G. Knepley PetscFunctionReturn(0); 4763221ece2SMatthew G. Knepley } 4773221ece2SMatthew G. Knepley 478fe7fb379SMatthew Knepley /*@C 47992f119d6SBarry Smith PetscMemoryView - Shows the amount of memory currently being used in a communicator. 480e5c89e4eSSatish Balay 481e5c89e4eSSatish Balay Collective on PetscViewer 482e5c89e4eSSatish Balay 483e5c89e4eSSatish Balay Input Parameter: 484e5c89e4eSSatish Balay + viewer - the viewer that defines the communicator 485e5c89e4eSSatish Balay - message - string printed before values 486e5c89e4eSSatish Balay 4870841954dSBarry Smith Options Database: 48892f119d6SBarry Smith + -malloc_debug - have PETSc track how much memory it has allocated 4890841954dSBarry Smith - -memory_view - during PetscFinalize() have this routine called 4900841954dSBarry Smith 491e5c89e4eSSatish Balay Level: intermediate 492e5c89e4eSSatish Balay 49392f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMemoryGetCurrentUsage(), PetscMemorySetGetMaximumUsage(), PetscMallocView() 494e5c89e4eSSatish Balay @*/ 4950841954dSBarry Smith PetscErrorCode PetscMemoryView(PetscViewer viewer,const char message[]) 496e5c89e4eSSatish Balay { 4970841954dSBarry Smith PetscLogDouble allocated,allocatedmax,resident,residentmax,gallocated,gallocatedmax,gresident,gresidentmax,maxgallocated,maxgallocatedmax,maxgresident,maxgresidentmax; 4980841954dSBarry Smith PetscLogDouble mingallocated,mingallocatedmax,mingresident,mingresidentmax; 499e5c89e4eSSatish Balay PetscErrorCode ierr; 500e5c89e4eSSatish Balay MPI_Comm comm; 501e5c89e4eSSatish Balay 502e5c89e4eSSatish Balay PetscFunctionBegin; 503e5c89e4eSSatish Balay if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD; 504e5c89e4eSSatish Balay ierr = PetscMallocGetCurrentUsage(&allocated);CHKERRQ(ierr); 5050841954dSBarry Smith ierr = PetscMallocGetMaximumUsage(&allocatedmax);CHKERRQ(ierr); 506e5c89e4eSSatish Balay ierr = PetscMemoryGetCurrentUsage(&resident);CHKERRQ(ierr); 507e5c89e4eSSatish Balay ierr = PetscMemoryGetMaximumUsage(&residentmax);CHKERRQ(ierr); 508e5c89e4eSSatish Balay if (residentmax > 0) residentmax = PetscMax(resident,residentmax); 509e5c89e4eSSatish Balay ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 510e5c89e4eSSatish Balay ierr = PetscViewerASCIIPrintf(viewer,message);CHKERRQ(ierr); 511e5c89e4eSSatish Balay if (resident && residentmax && allocated) { 5120841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5130841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5140841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5150841954dSBarry 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); 5160841954dSBarry Smith ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5170841954dSBarry Smith ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5180841954dSBarry Smith ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5190841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr); 5200841954dSBarry Smith ierr = MPI_Reduce(&allocatedmax,&gallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5210841954dSBarry Smith ierr = MPI_Reduce(&allocatedmax,&maxgallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5220841954dSBarry Smith ierr = MPI_Reduce(&allocatedmax,&mingallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5230841954dSBarry 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); 5240841954dSBarry Smith ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5250841954dSBarry Smith ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5260841954dSBarry Smith ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5270841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr); 528e5c89e4eSSatish Balay } else if (resident && residentmax) { 5290841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5300841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5310841954dSBarry Smith ierr = MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5320841954dSBarry 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); 5330841954dSBarry Smith ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5340841954dSBarry Smith ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5350841954dSBarry Smith ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5360841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr); 537e5c89e4eSSatish Balay } else if (resident && allocated) { 5380841954dSBarry Smith ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5390841954dSBarry Smith ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5400841954dSBarry Smith ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5410841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr); 5420841954dSBarry Smith ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5430841954dSBarry Smith ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5440841954dSBarry Smith ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5450841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr); 5460841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n");CHKERRQ(ierr); 547e5c89e4eSSatish Balay } else if (allocated) { 5480841954dSBarry Smith ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr); 5490841954dSBarry Smith ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr); 5500841954dSBarry Smith ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr); 5510841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr); 5520841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n");CHKERRQ(ierr); 5530841954dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"OS cannot compute process memory\n");CHKERRQ(ierr); 554e5c89e4eSSatish Balay } else { 55592f119d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Run with -malloc_debug to get statistics on PetscMalloc() calls\nOS cannot compute process memory\n");CHKERRQ(ierr); 556e5c89e4eSSatish Balay } 557e5c89e4eSSatish Balay ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 558e5c89e4eSSatish Balay PetscFunctionReturn(0); 559e5c89e4eSSatish Balay } 560e5c89e4eSSatish Balay 56146eb3923SBarry Smith /*@ 562e5c89e4eSSatish Balay PetscMallocGetCurrentUsage - gets the current amount of memory used that was PetscMalloc()ed 563e5c89e4eSSatish Balay 564e5c89e4eSSatish Balay Not Collective 565e5c89e4eSSatish Balay 566e5c89e4eSSatish Balay Output Parameters: 567e5c89e4eSSatish Balay . space - number of bytes currently allocated 568e5c89e4eSSatish Balay 569e5c89e4eSSatish Balay Level: intermediate 570e5c89e4eSSatish Balay 571540e20f2SPierre Jolivet .seealso: PetscMallocDump(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 572e5c89e4eSSatish Balay PetscMemoryGetMaximumUsage() 573e5c89e4eSSatish Balay @*/ 5747087cfbeSBarry Smith PetscErrorCode PetscMallocGetCurrentUsage(PetscLogDouble *space) 575e5c89e4eSSatish Balay { 576e5c89e4eSSatish Balay PetscFunctionBegin; 577e5c89e4eSSatish Balay *space = (PetscLogDouble) TRallocated; 578e5c89e4eSSatish Balay PetscFunctionReturn(0); 579e5c89e4eSSatish Balay } 580e5c89e4eSSatish Balay 581dc37d89fSBarry Smith /*@ 582e5c89e4eSSatish Balay PetscMallocGetMaximumUsage - gets the maximum amount of memory used that was PetscMalloc()ed at any time 583e5c89e4eSSatish Balay during this run. 584e5c89e4eSSatish Balay 585e5c89e4eSSatish Balay Not Collective 586e5c89e4eSSatish Balay 587e5c89e4eSSatish Balay Output Parameters: 588e5c89e4eSSatish Balay . space - maximum number of bytes ever allocated at one time 589e5c89e4eSSatish Balay 590e5c89e4eSSatish Balay Level: intermediate 591e5c89e4eSSatish Balay 59292f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 593e3ed9ee7SBarry 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 602e3ed9ee7SBarry Smith /*@ 603e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage - Adds another event to collect the maximum memory usage over an event 604e3ed9ee7SBarry Smith 605e3ed9ee7SBarry Smith Not Collective 606e3ed9ee7SBarry Smith 607e3ed9ee7SBarry Smith Input Parameter: 608e3ed9ee7SBarry Smith . event - an event id; this is just for error checking 609e3ed9ee7SBarry Smith 610e3ed9ee7SBarry Smith Level: developer 611e3ed9ee7SBarry Smith 61292f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 613e3ed9ee7SBarry Smith PetscMallocPopMaximumUsage() 614e3ed9ee7SBarry Smith @*/ 615e3ed9ee7SBarry Smith PetscErrorCode PetscMallocPushMaximumUsage(int event) 616e3ed9ee7SBarry Smith { 617e3ed9ee7SBarry Smith PetscFunctionBegin; 618e3ed9ee7SBarry Smith if (++NumTRMaxMems > MAXTRMAXMEMS) PetscFunctionReturn(0); 619e3ed9ee7SBarry Smith TRMaxMems[NumTRMaxMems-1] = TRallocated; 620e3ed9ee7SBarry Smith TRMaxMemsEvents[NumTRMaxMems-1] = event; 621e3ed9ee7SBarry Smith PetscFunctionReturn(0); 622e3ed9ee7SBarry Smith } 623e3ed9ee7SBarry Smith 624e3ed9ee7SBarry Smith /*@ 625e3ed9ee7SBarry Smith PetscMallocPopMaximumUsage - collect the maximum memory usage over an event 626e3ed9ee7SBarry Smith 627e3ed9ee7SBarry Smith Not Collective 628e3ed9ee7SBarry Smith 629e3ed9ee7SBarry Smith Input Parameter: 630e3ed9ee7SBarry Smith . event - an event id; this is just for error checking 631e3ed9ee7SBarry Smith 632e3ed9ee7SBarry Smith Output Parameter: 633e3ed9ee7SBarry Smith . mu - maximum amount of memory malloced during this event; high water mark relative to the beginning of the event 634e3ed9ee7SBarry Smith 635e3ed9ee7SBarry Smith Level: developer 636e3ed9ee7SBarry Smith 63792f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 638e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage() 639e3ed9ee7SBarry Smith @*/ 640e3ed9ee7SBarry Smith PetscErrorCode PetscMallocPopMaximumUsage(int event,PetscLogDouble *mu) 641e3ed9ee7SBarry Smith { 642e3ed9ee7SBarry Smith PetscFunctionBegin; 643e3ed9ee7SBarry Smith *mu = 0; 644e3ed9ee7SBarry Smith if (NumTRMaxMems-- > MAXTRMAXMEMS) PetscFunctionReturn(0); 645e3ed9ee7SBarry Smith if (TRMaxMemsEvents[NumTRMaxMems] != event) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"PetscMallocPush/PopMaximumUsage() are not nested"); 646e3ed9ee7SBarry Smith *mu = TRMaxMems[NumTRMaxMems]; 647e3ed9ee7SBarry Smith PetscFunctionReturn(0); 648e3ed9ee7SBarry Smith } 649e3ed9ee7SBarry Smith 650a64a8e02SBarry Smith #if defined(PETSC_USE_DEBUG) 651a64a8e02SBarry Smith /*@C 652a64a8e02SBarry Smith PetscMallocGetStack - returns a pointer to the stack for the location in the program a call to PetscMalloc() was used to obtain that memory 653a64a8e02SBarry Smith 654a64a8e02SBarry Smith Collective on PETSC_COMM_WORLD 655a64a8e02SBarry Smith 656a64a8e02SBarry Smith Input Parameter: 657a64a8e02SBarry Smith . ptr - the memory location 658a64a8e02SBarry Smith 659fd292e60Sprj- Output Parameter: 660a64a8e02SBarry Smith . stack - the stack indicating where the program allocated this memory 661a64a8e02SBarry Smith 662a64a8e02SBarry Smith Level: intermediate 663a64a8e02SBarry Smith 66492f119d6SBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocView() 665a64a8e02SBarry Smith @*/ 666a64a8e02SBarry Smith PetscErrorCode PetscMallocGetStack(void *ptr,PetscStack **stack) 667a64a8e02SBarry Smith { 668a64a8e02SBarry Smith TRSPACE *head; 669a64a8e02SBarry Smith 670a64a8e02SBarry Smith PetscFunctionBegin; 671a64a8e02SBarry Smith head = (TRSPACE*) (((char*)ptr) - HEADER_BYTES); 672a64a8e02SBarry Smith *stack = &head->stack; 673a64a8e02SBarry Smith PetscFunctionReturn(0); 674a64a8e02SBarry Smith } 67576386721SLisandro Dalcin #else 67676386721SLisandro Dalcin PetscErrorCode PetscMallocGetStack(void *ptr,void **stack) 67776386721SLisandro Dalcin { 67876386721SLisandro Dalcin PetscFunctionBegin; 679f0ba7cfcSLisandro Dalcin *stack = NULL; 68076386721SLisandro Dalcin PetscFunctionReturn(0); 68176386721SLisandro Dalcin } 682a64a8e02SBarry Smith #endif 683a64a8e02SBarry Smith 684e5c89e4eSSatish Balay /*@C 68592f119d6SBarry Smith PetscMallocDump - Dumps the currently allocated memory blocks to a file. The information 686e5c89e4eSSatish Balay printed is: size of space (in bytes), address of space, id of space, 687e5c89e4eSSatish Balay file in which space was allocated, and line number at which it was 688e5c89e4eSSatish Balay allocated. 689e5c89e4eSSatish Balay 69092f119d6SBarry Smith Not Collective 691e5c89e4eSSatish Balay 692e5c89e4eSSatish Balay Input Parameter: 693e5c89e4eSSatish Balay . fp - file pointer. If fp is NULL, stdout is assumed. 694e5c89e4eSSatish Balay 695e5c89e4eSSatish Balay Options Database Key: 69692f119d6SBarry Smith . -malloc_dump <optional filename> - Dumps unfreed memory during call to PetscFinalize() 697e5c89e4eSSatish Balay 698e5c89e4eSSatish Balay Level: intermediate 699e5c89e4eSSatish Balay 700e5c89e4eSSatish Balay Fortran Note: 701e5c89e4eSSatish Balay The calling sequence in Fortran is PetscMallocDump(integer ierr) 702e5c89e4eSSatish Balay The fp defaults to stdout. 703e5c89e4eSSatish Balay 70495452b02SPatrick Sanan Notes: 70592f119d6SBarry Smith Uses MPI_COMM_WORLD to display rank, because this may be called in PetscFinalize() after PETSC_COMM_WORLD has been freed. 706e5c89e4eSSatish Balay 70792f119d6SBarry Smith When called in PetscFinalize() dumps only the allocations that have not been properly freed 70892f119d6SBarry Smith 70992f119d6SBarry Smith PetscMallocView() prints a list of all memory ever allocated 71092f119d6SBarry Smith 711*f0b7f91aSBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocView(), PetscMallocViewSet(), PetscMallocValidate() 712e5c89e4eSSatish Balay @*/ 7137087cfbeSBarry Smith PetscErrorCode PetscMallocDump(FILE *fp) 714e5c89e4eSSatish Balay { 715e5c89e4eSSatish Balay TRSPACE *head; 716e3ed9ee7SBarry Smith size_t libAlloc = 0; 717e5c89e4eSSatish Balay PetscErrorCode ierr; 718e5c89e4eSSatish Balay PetscMPIInt rank; 719e5c89e4eSSatish Balay 720e5c89e4eSSatish Balay PetscFunctionBegin; 721e5c89e4eSSatish Balay ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr); 722da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 723e5c89e4eSSatish Balay head = TRhead; 724e5c89e4eSSatish Balay while (head) { 725608c71bfSMatthew G. Knepley libAlloc += TRrequestedSize ? head->rsize : head->size; 7265486ca60SMatthew G. Knepley head = head->next; 7275486ca60SMatthew G. Knepley } 7285486ca60SMatthew G. Knepley if (TRallocated - libAlloc > 0) fprintf(fp,"[%d]Total space allocated %.0f bytes\n",rank,(PetscLogDouble)TRallocated); 7295486ca60SMatthew G. Knepley head = TRhead; 7305486ca60SMatthew G. Knepley while (head) { 7315486ca60SMatthew G. Knepley PetscBool isLib; 7325486ca60SMatthew G. Knepley 7335486ca60SMatthew G. Knepley ierr = PetscStrcmp(head->functionname, "PetscDLLibraryOpen", &isLib);CHKERRQ(ierr); 7345486ca60SMatthew G. Knepley if (!isLib) { 735608c71bfSMatthew G. Knepley fprintf(fp,"[%2d]%.0f bytes %s() line %d in %s\n",rank,(PetscLogDouble) (TRrequestedSize ? head->rsize : head->size),head->functionname,head->lineno,head->filename); 7368bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 737e5c89e4eSSatish Balay ierr = PetscStackPrint(&head->stack,fp);CHKERRQ(ierr); 738e5c89e4eSSatish Balay #endif 7395486ca60SMatthew G. Knepley } 740e5c89e4eSSatish Balay head = head->next; 741e5c89e4eSSatish Balay } 742e5c89e4eSSatish Balay PetscFunctionReturn(0); 743e5c89e4eSSatish Balay } 744e5c89e4eSSatish Balay 745dc37d89fSBarry Smith /*@ 74692f119d6SBarry Smith PetscMallocViewSet - Activates logging of all calls to PetscMalloc() with a minimum size to view 747574034a9SJed Brown 748574034a9SJed Brown Not Collective 749574034a9SJed Brown 750574034a9SJed Brown Input Arguments: 751574034a9SJed Brown . logmin - minimum allocation size to log, or PETSC_DEFAULT 752574034a9SJed Brown 753574034a9SJed Brown Options Database Key: 75492f119d6SBarry Smith + -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize() 7558b254c29SBarry Smith . -malloc_view_threshold <min> - Sets a minimum size if -malloc_view is used 7568b254c29SBarry Smith - -log_view_memory - view the memory usage also with the -log_view option 757574034a9SJed Brown 758574034a9SJed Brown Level: advanced 759574034a9SJed Brown 76092f119d6SBarry Smith Notes: Must be called after PetscMallocSetDebug() 76192f119d6SBarry Smith 76292f119d6SBarry Smith Uses MPI_COMM_WORLD to determine rank because PETSc communicators may not be available 76392f119d6SBarry Smith 764*f0b7f91aSBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocViewSet(), PetscMallocTraceSet(), PetscMallocValidate() 765574034a9SJed Brown @*/ 76692f119d6SBarry Smith PetscErrorCode PetscMallocViewSet(PetscLogDouble logmin) 767574034a9SJed Brown { 768574034a9SJed Brown PetscErrorCode ierr; 769574034a9SJed Brown 770574034a9SJed Brown PetscFunctionBegin; 77192f119d6SBarry Smith PetscLogMalloc = 0; 77292f119d6SBarry Smith ierr = PetscMemorySetGetMaximumUsage();CHKERRQ(ierr); 773574034a9SJed Brown if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */ 774574034a9SJed Brown PetscLogMallocThreshold = (size_t)logmin; 775574034a9SJed Brown PetscFunctionReturn(0); 776574034a9SJed Brown } 777574034a9SJed Brown 778dc37d89fSBarry Smith /*@ 77992f119d6SBarry Smith PetscMallocViewGet - Determine whether all calls to PetscMalloc() are being logged 78018a2528dSJed Brown 78118a2528dSJed Brown Not Collective 78218a2528dSJed Brown 78318a2528dSJed Brown Output Arguments 78418a2528dSJed Brown . logging - PETSC_TRUE if logging is active 78518a2528dSJed Brown 78618a2528dSJed Brown Options Database Key: 78792f119d6SBarry Smith . -malloc_view <optional filename> - Activates PetscMallocView() 78818a2528dSJed Brown 78918a2528dSJed Brown Level: advanced 79018a2528dSJed Brown 791608c71bfSMatthew G. Knepley .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocTraceGet() 79218a2528dSJed Brown @*/ 79392f119d6SBarry Smith PetscErrorCode PetscMallocViewGet(PetscBool *logging) 79418a2528dSJed Brown { 79518a2528dSJed Brown 79618a2528dSJed Brown PetscFunctionBegin; 79718a2528dSJed Brown *logging = (PetscBool)(PetscLogMalloc >= 0); 79818a2528dSJed Brown PetscFunctionReturn(0); 79918a2528dSJed Brown } 80018a2528dSJed Brown 801608c71bfSMatthew G. Knepley /*@ 802608c71bfSMatthew G. Knepley PetscMallocTraceSet - Trace all calls to PetscMalloc() 803608c71bfSMatthew G. Knepley 804608c71bfSMatthew G. Knepley Not Collective 805608c71bfSMatthew G. Knepley 806608c71bfSMatthew G. Knepley Input Arguments: 807608c71bfSMatthew G. Knepley + viewer - The viewer to use for tracing, or NULL to use stdout 808608c71bfSMatthew G. Knepley . active - Flag to activate or deactivate tracing 809608c71bfSMatthew G. Knepley - logmin - The smallest memory size that will be logged 810608c71bfSMatthew G. Knepley 811608c71bfSMatthew G. Knepley Note: 812608c71bfSMatthew G. Knepley The viewer should not be collective. 813608c71bfSMatthew G. Knepley 814608c71bfSMatthew G. Knepley Level: advanced 815608c71bfSMatthew G. Knepley 816608c71bfSMatthew G. Knepley .seealso: PetscMallocTraceGet(), PetscMallocViewGet(), PetscMallocDump(), PetscMallocView() 817608c71bfSMatthew G. Knepley @*/ 818608c71bfSMatthew G. Knepley PetscErrorCode PetscMallocTraceSet(PetscViewer viewer, PetscBool active, PetscLogDouble logmin) 819608c71bfSMatthew G. Knepley { 820608c71bfSMatthew G. Knepley PetscErrorCode ierr; 821608c71bfSMatthew G. Knepley 822608c71bfSMatthew G. Knepley PetscFunctionBegin; 823608c71bfSMatthew G. Knepley if (!active) {PetscLogMallocTrace = -1; PetscFunctionReturn(0);} 824608c71bfSMatthew G. Knepley PetscLogMallocTraceViewer = !viewer ? PETSC_VIEWER_STDOUT_SELF : viewer; 825608c71bfSMatthew G. Knepley PetscLogMallocTrace = 0; 826608c71bfSMatthew G. Knepley ierr = PetscMemorySetGetMaximumUsage();CHKERRQ(ierr); 827608c71bfSMatthew G. Knepley if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */ 828608c71bfSMatthew G. Knepley PetscLogMallocTraceThreshold = (size_t) logmin; 829608c71bfSMatthew G. Knepley PetscFunctionReturn(0); 830608c71bfSMatthew G. Knepley } 831608c71bfSMatthew G. Knepley 832608c71bfSMatthew G. Knepley /*@ 833608c71bfSMatthew G. Knepley PetscMallocTraceGet - Determine whether all calls to PetscMalloc() are being traced 834608c71bfSMatthew G. Knepley 835608c71bfSMatthew G. Knepley Not Collective 836608c71bfSMatthew G. Knepley 837608c71bfSMatthew G. Knepley Output Argument: 838608c71bfSMatthew G. Knepley . logging - PETSC_TRUE if logging is active 839608c71bfSMatthew G. Knepley 840608c71bfSMatthew G. Knepley Options Database Key: 841608c71bfSMatthew G. Knepley . -malloc_view <optional filename> - Activates PetscMallocView() 842608c71bfSMatthew G. Knepley 843608c71bfSMatthew G. Knepley Level: advanced 844608c71bfSMatthew G. Knepley 845608c71bfSMatthew G. Knepley .seealso: PetscMallocTraceSet(), PetscMallocViewGet(), PetscMallocDump(), PetscMallocView() 846608c71bfSMatthew G. Knepley @*/ 847608c71bfSMatthew G. Knepley PetscErrorCode PetscMallocTraceGet(PetscBool *logging) 848608c71bfSMatthew G. Knepley { 849608c71bfSMatthew G. Knepley 850608c71bfSMatthew G. Knepley PetscFunctionBegin; 851608c71bfSMatthew G. Knepley *logging = (PetscBool) (PetscLogMallocTrace >= 0); 852608c71bfSMatthew G. Knepley PetscFunctionReturn(0); 853608c71bfSMatthew G. Knepley } 854608c71bfSMatthew G. Knepley 855e5c89e4eSSatish Balay /*@C 85692f119d6SBarry Smith PetscMallocView - Saves the log of all calls to PetscMalloc(); also calls 85721b680ceSJed Brown PetscMemoryGetMaximumUsage() 858e5c89e4eSSatish Balay 85992f119d6SBarry Smith Not Collective 860e5c89e4eSSatish Balay 861e5c89e4eSSatish Balay Input Parameter: 8620298fd71SBarry Smith . fp - file pointer; or NULL 863e5c89e4eSSatish Balay 864e5c89e4eSSatish Balay Options Database Key: 86592f119d6SBarry Smith . -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize() 866e5c89e4eSSatish Balay 867e5c89e4eSSatish Balay Level: advanced 868e5c89e4eSSatish Balay 869e5c89e4eSSatish Balay Fortran Note: 87092f119d6SBarry Smith The calling sequence in Fortran is PetscMallocView(integer ierr) 871e5c89e4eSSatish Balay The fp defaults to stdout. 872e5c89e4eSSatish Balay 87392f119d6SBarry Smith Notes: 87492f119d6SBarry Smith PetscMallocDump() dumps only the currently unfreed memory, this dumps all memory ever allocated 87592f119d6SBarry Smith 87692f119d6SBarry Smith PetscMemoryView() gives a brief summary of current memory usage 87792f119d6SBarry Smith 87892f119d6SBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocDump(), PetscMallocViewSet(), PetscMemoryView() 879e5c89e4eSSatish Balay @*/ 88092f119d6SBarry Smith PetscErrorCode PetscMallocView(FILE *fp) 881e5c89e4eSSatish Balay { 88292f119d6SBarry Smith PetscInt i,j,n,*perm; 883e5c89e4eSSatish Balay size_t *shortlength; 884f56c2debSBarry Smith int *shortcount,err; 88592f119d6SBarry Smith PetscMPIInt rank; 886ace3abfcSBarry Smith PetscBool match; 887e5c89e4eSSatish Balay const char **shortfunction; 888e5c89e4eSSatish Balay PetscLogDouble rss; 889e5c89e4eSSatish Balay PetscErrorCode ierr; 890e5c89e4eSSatish Balay 891e5c89e4eSSatish Balay PetscFunctionBegin; 892e5c89e4eSSatish Balay ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr); 893f56c2debSBarry Smith err = fflush(fp); 894e32f2f54SBarry Smith if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 895f56c2debSBarry Smith 89679dccf82SBarry Smith if (PetscLogMalloc < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"PetscMallocView() called without call to PetscMallocViewSet() this is often due to\n setting the option -malloc_view AFTER PetscInitialize() with PetscOptionsInsert() or PetscOptionsInsertFile()"); 897768aa557SSatish Balay 898da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 899f3d65365SJed Brown ierr = PetscMemoryGetMaximumUsage(&rss);CHKERRQ(ierr); 900e5c89e4eSSatish Balay if (rss) { 90192f119d6SBarry Smith (void) fprintf(fp,"[%d] Maximum memory PetscMalloc()ed %.0f maximum size of entire process %.0f\n",rank,(PetscLogDouble)TRMaxMem,rss); 902e5c89e4eSSatish Balay } else { 90392f119d6SBarry Smith (void) fprintf(fp,"[%d] Maximum memory PetscMalloc()ed %.0f OS cannot compute size of entire process\n",rank,(PetscLogDouble)TRMaxMem); 904e5c89e4eSSatish Balay } 905e32f2f54SBarry Smith shortcount = (int*)malloc(PetscLogMalloc*sizeof(int));if (!shortcount) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 906e32f2f54SBarry Smith shortlength = (size_t*)malloc(PetscLogMalloc*sizeof(size_t));if (!shortlength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 907e32f2f54SBarry Smith shortfunction = (const char**)malloc(PetscLogMalloc*sizeof(char*));if (!shortfunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 90897b9d747SJed Brown for (i=0,n=0; i<PetscLogMalloc; i++) { 909e5c89e4eSSatish Balay for (j=0; j<n; j++) { 910e5c89e4eSSatish Balay ierr = PetscStrcmp(shortfunction[j],PetscLogMallocFunction[i],&match);CHKERRQ(ierr); 911e5c89e4eSSatish Balay if (match) { 912e5c89e4eSSatish Balay shortlength[j] += PetscLogMallocLength[i]; 91359ffdab8SBarry Smith shortcount[j]++; 914e5c89e4eSSatish Balay goto foundit; 915e5c89e4eSSatish Balay } 916e5c89e4eSSatish Balay } 917e5c89e4eSSatish Balay shortfunction[n] = PetscLogMallocFunction[i]; 918e5c89e4eSSatish Balay shortlength[n] = PetscLogMallocLength[i]; 91959ffdab8SBarry Smith shortcount[n] = 1; 920e5c89e4eSSatish Balay n++; 921e5c89e4eSSatish Balay foundit:; 922e5c89e4eSSatish Balay } 923e5c89e4eSSatish Balay 924e32f2f54SBarry Smith perm = (PetscInt*)malloc(n*sizeof(PetscInt));if (!perm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 925e5c89e4eSSatish Balay for (i=0; i<n; i++) perm[i] = i; 926e5c89e4eSSatish Balay ierr = PetscSortStrWithPermutation(n,(const char**)shortfunction,perm);CHKERRQ(ierr); 927e5c89e4eSSatish Balay 92892f119d6SBarry Smith (void) fprintf(fp,"[%d] Memory usage sorted by function\n",rank); 929e5c89e4eSSatish Balay for (i=0; i<n; i++) { 93092f119d6SBarry Smith (void) fprintf(fp,"[%d] %d %.0f %s()\n",rank,shortcount[perm[i]],(PetscLogDouble)shortlength[perm[i]],shortfunction[perm[i]]); 931e5c89e4eSSatish Balay } 932e5c89e4eSSatish Balay free(perm); 933e5c89e4eSSatish Balay free(shortlength); 93459ffdab8SBarry Smith free(shortcount); 935e5c89e4eSSatish Balay free((char**)shortfunction); 936f56c2debSBarry Smith err = fflush(fp); 937e32f2f54SBarry Smith if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 938e5c89e4eSSatish Balay PetscFunctionReturn(0); 939e5c89e4eSSatish Balay } 940e5c89e4eSSatish Balay 941e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------- */ 942e5c89e4eSSatish Balay 943dc37d89fSBarry Smith /*@ 94492f119d6SBarry Smith PetscMallocSetDebug - Set's PETSc memory debugging 945e5c89e4eSSatish Balay 946e5c89e4eSSatish Balay Not Collective 947e5c89e4eSSatish Balay 948e5c89e4eSSatish Balay Input Parameter: 94992f119d6SBarry Smith + eachcall - checks the entire heap of allocated memory for issues on each call to PetscMalloc() and PetscFree() 9502d4ee042Sprj- - initializenan - initializes all memory with NaN to catch use of uninitialized floating point arrays 951e5c89e4eSSatish Balay 95292f119d6SBarry Smith Options Database: 95379dccf82SBarry Smith + -malloc_debug <true or false> - turns on or off debugging 95492f119d6SBarry Smith . -malloc_test - turns on all debugging if PETSc was configured with debugging including -malloc_dump, otherwise ignored 95579dccf82SBarry Smith . -malloc_view_threshold t - log only allocations larger than t 95692f119d6SBarry Smith . -malloc_dump <filename> - print a list of all memory that has not been freed 95779dccf82SBarry Smith . -malloc no - (deprecated) same as -malloc_debug no 95879dccf82SBarry Smith - -malloc_log - (deprecated) same as -malloc_view 959e5c89e4eSSatish Balay 96092f119d6SBarry Smith Level: developer 96192f119d6SBarry Smith 96292f119d6SBarry Smith Notes: This is called in PetscInitialize() and should not be called elsewhere 96392f119d6SBarry Smith 96492f119d6SBarry Smith .seealso: CHKMEMQ(), PetscMallocValidate(), PetscMallocGetDebug() 965e5c89e4eSSatish Balay @*/ 96692f119d6SBarry Smith PetscErrorCode PetscMallocSetDebug(PetscBool eachcall, PetscBool initializenan) 967e5c89e4eSSatish Balay { 96892f119d6SBarry Smith PetscErrorCode ierr; 96992f119d6SBarry Smith 970e5c89e4eSSatish Balay PetscFunctionBegin; 97192f119d6SBarry Smith if (PetscTrMalloc == PetscTrMallocDefault) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot call this routine more than once, it can only be called in PetscInitialize()"); 97292f119d6SBarry Smith ierr = PetscMallocSet(PetscTrMallocDefault,PetscTrFreeDefault,PetscTrReallocDefault);CHKERRQ(ierr); 97392f119d6SBarry Smith 97492f119d6SBarry Smith TRallocated = 0; 97592f119d6SBarry Smith TRfrags = 0; 97692f119d6SBarry Smith TRhead = NULL; 97792f119d6SBarry Smith TRid = 0; 97892f119d6SBarry Smith TRdebugLevel = eachcall; 97992f119d6SBarry Smith TRMaxMem = 0; 98092f119d6SBarry Smith PetscLogMallocMax = 10000; 98192f119d6SBarry Smith PetscLogMalloc = -1; 9822d4ee042Sprj- TRdebugIinitializenan = initializenan; 983e5c89e4eSSatish Balay PetscFunctionReturn(0); 984e5c89e4eSSatish Balay } 9850acecf5bSBarry Smith 986dc37d89fSBarry Smith /*@ 98792f119d6SBarry Smith PetscMallocGetDebug - Indicates what PETSc memory debugging it is doing. 9880acecf5bSBarry Smith 9890acecf5bSBarry Smith Not Collective 9900acecf5bSBarry Smith 99192f119d6SBarry Smith Output Parameters: 99292f119d6SBarry Smith + basic - doing basic debugging 99392f119d6SBarry Smith . eachcall - checks the entire memory heap at each PetscMalloc()/PetscFree() 99479dccf82SBarry Smith - initializenan - initializes memory with NaN 9950acecf5bSBarry Smith 9960acecf5bSBarry Smith Level: intermediate 9970acecf5bSBarry Smith 99892f119d6SBarry Smith Notes: 99979dccf82SBarry Smith By default, the debug version always does some debugging unless you run with -malloc_debug no 10000acecf5bSBarry Smith 100192f119d6SBarry Smith .seealso: CHKMEMQ(), PetscMallocValidate(), PetscMallocSetDebug() 10020acecf5bSBarry Smith @*/ 100392f119d6SBarry Smith PetscErrorCode PetscMallocGetDebug(PetscBool *basic, PetscBool *eachcall, PetscBool *initializenan) 10040acecf5bSBarry Smith { 10050acecf5bSBarry Smith PetscFunctionBegin; 100679dccf82SBarry Smith if (basic) *basic = (PetscTrMalloc == PetscTrMallocDefault) ? PETSC_TRUE : PETSC_FALSE; 100779dccf82SBarry Smith if (eachcall) *eachcall = TRdebugLevel; 10082d4ee042Sprj- if (initializenan) *initializenan = TRdebugIinitializenan; 10090acecf5bSBarry Smith PetscFunctionReturn(0); 10100acecf5bSBarry Smith } 1011608c71bfSMatthew G. Knepley 1012608c71bfSMatthew G. Knepley /*@ 1013608c71bfSMatthew G. Knepley PetscMallocLogRequestedSizeSet - Whether to log the requested or aligned memory size 1014608c71bfSMatthew G. Knepley 1015608c71bfSMatthew G. Knepley Not Collective 1016608c71bfSMatthew G. Knepley 1017608c71bfSMatthew G. Knepley Input Parameter: 1018608c71bfSMatthew G. Knepley . flg - PETSC_TRUE to log the requested memory size 1019608c71bfSMatthew G. Knepley 1020608c71bfSMatthew G. Knepley Options Database: 1021608c71bfSMatthew G. Knepley . -malloc_requested_size <bool> - Sets this flag 1022608c71bfSMatthew G. Knepley 1023608c71bfSMatthew G. Knepley Level: developer 1024608c71bfSMatthew G. Knepley 1025608c71bfSMatthew G. Knepley .seealso: PetscMallocLogRequestedSizeGet(), PetscMallocViewSet() 1026608c71bfSMatthew G. Knepley @*/ 1027608c71bfSMatthew G. Knepley PetscErrorCode PetscMallocLogRequestedSizeSet(PetscBool flg) 1028608c71bfSMatthew G. Knepley { 1029608c71bfSMatthew G. Knepley PetscFunctionBegin; 1030608c71bfSMatthew G. Knepley TRrequestedSize = flg; 1031608c71bfSMatthew G. Knepley PetscFunctionReturn(0); 1032608c71bfSMatthew G. Knepley } 1033608c71bfSMatthew G. Knepley 1034608c71bfSMatthew G. Knepley /*@ 1035608c71bfSMatthew G. Knepley PetscMallocLogRequestedSizeGet - Whether to log the requested or aligned memory size 1036608c71bfSMatthew G. Knepley 1037608c71bfSMatthew G. Knepley Not Collective 1038608c71bfSMatthew G. Knepley 1039608c71bfSMatthew G. Knepley Output Parameter: 1040608c71bfSMatthew G. Knepley . flg - PETSC_TRUE if we log the requested memory size 1041608c71bfSMatthew G. Knepley 1042608c71bfSMatthew G. Knepley Level: developer 1043608c71bfSMatthew G. Knepley 1044608c71bfSMatthew G. Knepley .seealso: PetscMallocLogRequestedSizeSetinalSizeSet(), PetscMallocViewSet() 1045608c71bfSMatthew G. Knepley @*/ 1046608c71bfSMatthew G. Knepley PetscErrorCode PetscMallocLogRequestedSizeGet(PetscBool *flg) 1047608c71bfSMatthew G. Knepley { 1048608c71bfSMatthew G. Knepley PetscFunctionBegin; 1049608c71bfSMatthew G. Knepley *flg = TRrequestedSize; 1050608c71bfSMatthew G. Knepley PetscFunctionReturn(0); 1051608c71bfSMatthew G. Knepley } 1052