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 */ 527104ee2SJacob Faibussowitsch #include <petsc/private/petscimpl.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; 1146c093d5bSvictor head = TRhead; lasthead = NULL; 1152cba8197SMatthew G. Knepley if (head && head->prev) { 116ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscMallocValidate: error detected in %s() at %s:%d\n",function,file,line); 1172cba8197SMatthew G. Knepley (*PetscErrorPrintf)("Root memory header %p has invalid back pointer %p\n",head,head->prev); 1184ed0ab5bSBarry Smith return PETSC_ERR_MEMC; 1192cba8197SMatthew G. Knepley } 120e5c89e4eSSatish Balay while (head) { 1210700a824SBarry Smith if (head->classid != CLASSID_VALUE) { 122ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscMallocValidate: error detected in %s() at %s:%d\n",function,file,line); 123e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory at address %p is corrupted\n",head); 1244ed0ab5bSBarry Smith (*PetscErrorPrintf)("Probably write before beginning of or past end of array\n"); 125e269983cSBarry Smith if (lasthead) { 126e269983cSBarry Smith a = (char*)(((TrSPACE*)head) + 1); 127ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Last intact block [id=%d(%.0f)] at address %p allocated in %s() at %s:%d\n",lasthead->id,(PetscLogDouble)lasthead->size,a,lasthead->functionname,lasthead->filename,lasthead->lineno); 128e269983cSBarry Smith } 129e269983cSBarry Smith abort(); 1304ed0ab5bSBarry Smith return PETSC_ERR_MEMC; 131e5c89e4eSSatish Balay } 132e5c89e4eSSatish Balay a = (char*)(((TrSPACE*)head) + 1); 1330700a824SBarry Smith nend = (PetscClassId*)(a + head->size); 1340700a824SBarry Smith if (*nend != CLASSID_VALUE) { 135ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscMallocValidate: error detected in %s() at %s:%d\n",function,file,line); 136e5c89e4eSSatish Balay if (*nend == ALREADY_FREED) { 137e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p already freed\n",head->id,(PetscLogDouble)head->size,a); 1384ed0ab5bSBarry Smith return PETSC_ERR_MEMC; 139e5c89e4eSSatish Balay } else { 140e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 141ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Memory originally allocated in %s() at %s:%d\n",head->functionname,head->filename,head->lineno); 1424ed0ab5bSBarry Smith return PETSC_ERR_MEMC; 143e5c89e4eSSatish Balay } 144e5c89e4eSSatish Balay } 1452cba8197SMatthew G. Knepley if (head->prev && head->prev != lasthead) { 146ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscMallocValidate: error detected in %s() at %s:%d\n",function,file,line); 1472cba8197SMatthew G. Knepley (*PetscErrorPrintf)("Backpointer %p is invalid, should be %p\n",head->prev,lasthead); 148ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Previous memory originally allocated in %s() at %s:%d\n",lasthead->functionname,lasthead->filename,lasthead->lineno); 149ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Memory originally allocated in %s() at %s:%d\n",head->functionname,head->filename,head->lineno); 1504ed0ab5bSBarry Smith return PETSC_ERR_MEMC; 1512cba8197SMatthew G. Knepley } 1526c093d5bSvictor lasthead = head; 153e5c89e4eSSatish Balay head = head->next; 154e5c89e4eSSatish Balay } 1554ed0ab5bSBarry Smith return 0; 156e5c89e4eSSatish Balay } 157e5c89e4eSSatish Balay 158e5c89e4eSSatish Balay /* 159e5c89e4eSSatish Balay PetscTrMallocDefault - Malloc with tracing. 160e5c89e4eSSatish Balay 161e5c89e4eSSatish Balay Input Parameters: 162e5c89e4eSSatish Balay + a - number of bytes to allocate 163e5c89e4eSSatish Balay . lineno - line number where used. Use __LINE__ for this 164efca3c55SSatish Balay - filename - file name where used. Use __FILE__ for this 165e5c89e4eSSatish Balay 166e5c89e4eSSatish Balay Returns: 16792f119d6SBarry Smith double aligned pointer to requested storage, or null if not available. 168e5c89e4eSSatish Balay */ 169071fcb05SBarry Smith PetscErrorCode PetscTrMallocDefault(size_t a,PetscBool clear,int lineno,const char function[],const char filename[],void **result) 170e5c89e4eSSatish Balay { 171e5c89e4eSSatish Balay TRSPACE *head; 172e5c89e4eSSatish Balay char *inew; 173e5c89e4eSSatish Balay size_t nsize; 174e5c89e4eSSatish Balay PetscErrorCode ierr; 175e5c89e4eSSatish Balay 176e5c89e4eSSatish Balay PetscFunctionBegin; 177f0ba7cfcSLisandro Dalcin /* Do not try to handle empty blocks */ 178f0ba7cfcSLisandro Dalcin if (!a) { *result = NULL; PetscFunctionReturn(0); } 179f0ba7cfcSLisandro Dalcin 180efca3c55SSatish Balay ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr); 181e5c89e4eSSatish Balay 18225b53cc9SJed Brown nsize = (a + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1); 1835f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),clear,lineno,function,filename,(void**)&inew)); 184e3ed9ee7SBarry Smith 185e5c89e4eSSatish Balay head = (TRSPACE*)inew; 186e5c89e4eSSatish Balay inew += sizeof(TrSPACE); 187e5c89e4eSSatish Balay 188e5c89e4eSSatish Balay if (TRhead) TRhead->prev = head; 189e5c89e4eSSatish Balay head->next = TRhead; 190e5c89e4eSSatish Balay TRhead = head; 191f0ba7cfcSLisandro Dalcin head->prev = NULL; 192e5c89e4eSSatish Balay head->size = nsize; 193608c71bfSMatthew G. Knepley head->rsize = a; 194e269983cSBarry Smith head->id = TRid++; 195e5c89e4eSSatish Balay head->lineno = lineno; 196e5c89e4eSSatish Balay 197e5c89e4eSSatish Balay head->filename = filename; 198e5c89e4eSSatish Balay head->functionname = function; 1990700a824SBarry Smith head->classid = CLASSID_VALUE; 2000700a824SBarry Smith *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 201e5c89e4eSSatish Balay 202608c71bfSMatthew G. Knepley TRallocated += TRrequestedSize ? head->rsize : head->size; 203a297a907SKarl Rupp if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 204e3ed9ee7SBarry Smith if (PetscLogMemory) { 205e3ed9ee7SBarry Smith PetscInt i; 206e3ed9ee7SBarry Smith for (i=0; i<NumTRMaxMems; i++) { 207e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 208e3ed9ee7SBarry Smith } 209e3ed9ee7SBarry Smith } 210e5c89e4eSSatish Balay TRfrags++; 211e5c89e4eSSatish Balay 2128bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 2135f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStackCopy(&petscstack,&head->stack)); 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; 21692f119d6SBarry Smith #if defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL_DOUBLE) 2172d4ee042Sprj- if (!clear && TRdebugIinitializenan) { 21892f119d6SBarry Smith size_t i, n = a/sizeof(PetscReal); 21992f119d6SBarry Smith PetscReal *s = (PetscReal*) inew; 22092f119d6SBarry Smith /* from https://www.doc.ic.ac.uk/~eedwards/compsys/float/nan.html */ 22192f119d6SBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 222df282883SBarry Smith int nas = 0x7F800002; 22392f119d6SBarry Smith #else 22492f119d6SBarry Smith PetscInt64 nas = 0x7FF0000000000002; 22592f119d6SBarry Smith #endif 22692f119d6SBarry Smith for (i=0; i<n; i++) { 22792f119d6SBarry Smith memcpy(s+i,&nas,sizeof(PetscReal)); 22892f119d6SBarry Smith } 22992f119d6SBarry Smith } 23092f119d6SBarry Smith #endif 231e5c89e4eSSatish Balay #endif 232e5c89e4eSSatish Balay 233e5c89e4eSSatish Balay /* 23492f119d6SBarry Smith Allow logging of all mallocs made. 23592f119d6SBarry Smith TODO: Currently this memory is never freed, it should be freed during PetscFinalize() 236e5c89e4eSSatish Balay */ 237574034a9SJed Brown if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && a >= PetscLogMallocThreshold) { 238e5c89e4eSSatish Balay if (!PetscLogMalloc) { 239e5c89e4eSSatish Balay PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 240*28b400f6SJacob Faibussowitsch PetscCheck(PetscLogMallocLength,PETSC_COMM_SELF,PETSC_ERR_MEM," "); 241a297a907SKarl Rupp 242a2ea699eSBarry Smith PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 243*28b400f6SJacob Faibussowitsch PetscCheck(PetscLogMallocFile,PETSC_COMM_SELF,PETSC_ERR_MEM," "); 244a297a907SKarl Rupp 245a2ea699eSBarry Smith PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 246*28b400f6SJacob Faibussowitsch PetscCheck(PetscLogMallocFunction,PETSC_COMM_SELF,PETSC_ERR_MEM," "); 247e5c89e4eSSatish Balay } 248e5c89e4eSSatish Balay PetscLogMallocLength[PetscLogMalloc] = nsize; 249e5c89e4eSSatish Balay PetscLogMallocFile[PetscLogMalloc] = filename; 250e5c89e4eSSatish Balay PetscLogMallocFunction[PetscLogMalloc++] = function; 251e5c89e4eSSatish Balay } 252608c71bfSMatthew G. Knepley if (PetscLogMallocTrace > -1 && a >= PetscLogMallocTraceThreshold) { 2535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(PetscLogMallocTraceViewer,"Alloc %zu %s:%d (%s)\n", a, filename ? filename : "null", lineno, function ? function : "null")); 254608c71bfSMatthew G. Knepley } 255e5c89e4eSSatish Balay *result = (void*)inew; 256e5c89e4eSSatish Balay PetscFunctionReturn(0); 257e5c89e4eSSatish Balay } 258e5c89e4eSSatish Balay 259e5c89e4eSSatish Balay /* 260e5c89e4eSSatish Balay PetscTrFreeDefault - Free with tracing. 261e5c89e4eSSatish Balay 262e5c89e4eSSatish Balay Input Parameters: 263e5c89e4eSSatish Balay . a - pointer to a block allocated with PetscTrMalloc 264e5c89e4eSSatish Balay . lineno - line number where used. Use __LINE__ for this 265608c71bfSMatthew G. Knepley . filename - file name where used. Use __FILE__ for this 266e5c89e4eSSatish Balay */ 267608c71bfSMatthew G. Knepley PetscErrorCode PetscTrFreeDefault(void *aa,int lineno,const char function[],const char filename[]) 268e5c89e4eSSatish Balay { 269e5c89e4eSSatish Balay char *a = (char*)aa; 270e5c89e4eSSatish Balay TRSPACE *head; 271e5c89e4eSSatish Balay char *ahead; 272608c71bfSMatthew G. Knepley size_t asize; 2730700a824SBarry Smith PetscClassId *nend; 274e5c89e4eSSatish Balay 275e5c89e4eSSatish Balay PetscFunctionBegin; 276e5c89e4eSSatish Balay /* Do not try to handle empty blocks */ 27749d7da52SJed Brown if (!a) PetscFunctionReturn(0); 278e5c89e4eSSatish Balay 2795f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMallocValidate(lineno,function,filename)); 280e5c89e4eSSatish Balay 281e5c89e4eSSatish Balay ahead = a; 282e5c89e4eSSatish Balay a = a - sizeof(TrSPACE); 283e5c89e4eSSatish Balay head = (TRSPACE*)a; 284e5c89e4eSSatish Balay 2850700a824SBarry Smith if (head->classid != CLASSID_VALUE) { 286ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() at %s:%d\n",function,filename,lineno); 287e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 288e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); 289e5c89e4eSSatish Balay } 2900700a824SBarry Smith nend = (PetscClassId*)(ahead + head->size); 2910700a824SBarry Smith if (*nend != CLASSID_VALUE) { 292e5c89e4eSSatish Balay if (*nend == ALREADY_FREED) { 293ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() at %s:%d\n",function,filename,lineno); 294e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 295e5c89e4eSSatish Balay if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 296ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Block freed in %s() at %s:%d\n",head->functionname,head->filename,head->lineno); 297e5c89e4eSSatish Balay } else { 298ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Block allocated in %s() at %s:%d\n",head->functionname,head->filename,-head->lineno); 299e5c89e4eSSatish Balay } 300e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); 301e5c89e4eSSatish Balay } else { 302e5c89e4eSSatish Balay /* Damaged tail */ 303ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() at %s:%d\n",function,filename,lineno); 304e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 305ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Block allocated in %s() at %s:%d\n",head->functionname,head->filename,head->lineno); 306e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); 307e5c89e4eSSatish Balay } 308e5c89e4eSSatish Balay } 309608c71bfSMatthew G. Knepley if (PetscLogMallocTrace > -1 && head->rsize >= PetscLogMallocTraceThreshold) { 3105f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(PetscLogMallocTraceViewer, "Free %zu %s:%d (%s)\n", head->rsize, filename ? filename : "null", lineno, function ? function : "null")); 311608c71bfSMatthew G. Knepley } 312e5c89e4eSSatish Balay /* Mark the location freed */ 313e5c89e4eSSatish Balay *nend = ALREADY_FREED; 314e5c89e4eSSatish Balay /* Save location where freed. If we suspect the line number, mark as allocated location */ 315608c71bfSMatthew G. Knepley if (lineno > 0 && lineno < 50000) { 316608c71bfSMatthew G. Knepley head->lineno = lineno; 317608c71bfSMatthew G. Knepley head->filename = filename; 318e5c89e4eSSatish Balay head->functionname = function; 319e5c89e4eSSatish Balay } else { 320e5c89e4eSSatish Balay head->lineno = -head->lineno; 321e5c89e4eSSatish Balay } 322608c71bfSMatthew G. Knepley asize = TRrequestedSize ? head->rsize : head->size; 3232c71b3e2SJacob Faibussowitsch PetscCheckFalse(TRallocated < asize,PETSC_COMM_SELF,PETSC_ERR_MEMC,"TRallocate is smaller than memory just freed"); 324608c71bfSMatthew G. Knepley TRallocated -= asize; 325e5c89e4eSSatish Balay TRfrags--; 326e5c89e4eSSatish Balay if (head->prev) head->prev->next = head->next; 327e5c89e4eSSatish Balay else TRhead = head->next; 328e5c89e4eSSatish Balay 329e5c89e4eSSatish Balay if (head->next) head->next->prev = head->prev; 3305f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFreeAlign(a,lineno,function,filename)); 331e5c89e4eSSatish Balay PetscFunctionReturn(0); 332e5c89e4eSSatish Balay } 333e5c89e4eSSatish Balay 3343221ece2SMatthew G. Knepley /* 3353221ece2SMatthew G. Knepley PetscTrReallocDefault - Realloc with tracing. 3363221ece2SMatthew G. Knepley 3373221ece2SMatthew G. Knepley Input Parameters: 3383221ece2SMatthew G. Knepley + len - number of bytes to allocate 3393221ece2SMatthew G. Knepley . lineno - line number where used. Use __LINE__ for this 3403221ece2SMatthew G. Knepley . filename - file name where used. Use __FILE__ for this 34192f119d6SBarry Smith - result - original memory 3423221ece2SMatthew G. Knepley 3433221ece2SMatthew G. Knepley Output Parameter: 3443221ece2SMatthew G. Knepley . result - double aligned pointer to requested storage, or null if not available. 3453221ece2SMatthew G. Knepley 3463221ece2SMatthew G. Knepley Level: developer 3473221ece2SMatthew G. Knepley 3483221ece2SMatthew G. Knepley .seealso: PetscTrMallocDefault(), PetscTrFreeDefault() 3493221ece2SMatthew G. Knepley */ 3503221ece2SMatthew G. Knepley PetscErrorCode PetscTrReallocDefault(size_t len, int lineno, const char function[], const char filename[], void **result) 3513221ece2SMatthew G. Knepley { 3523221ece2SMatthew G. Knepley char *a = (char *) *result; 3533221ece2SMatthew G. Knepley TRSPACE *head; 3543221ece2SMatthew G. Knepley char *ahead, *inew; 3553221ece2SMatthew G. Knepley PetscClassId *nend; 3563221ece2SMatthew G. Knepley size_t nsize; 3573221ece2SMatthew G. Knepley PetscErrorCode ierr; 3583221ece2SMatthew G. Knepley 3593221ece2SMatthew G. Knepley PetscFunctionBegin; 36092f119d6SBarry Smith /* Realloc requests zero space so just free the current space */ 361c22f1541SToby Isaac if (!len) { 3625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTrFreeDefault(*result,lineno,function,filename)); 363c22f1541SToby Isaac *result = NULL; 364c22f1541SToby Isaac PetscFunctionReturn(0); 365c22f1541SToby Isaac } 36692f119d6SBarry Smith /* If the orginal space was NULL just use the regular malloc() */ 367f590eff4SLisandro Dalcin if (!*result) { 3685f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTrMallocDefault(len,PETSC_FALSE,lineno,function,filename,result)); 369f590eff4SLisandro Dalcin PetscFunctionReturn(0); 370f590eff4SLisandro Dalcin } 3713221ece2SMatthew G. Knepley 37238548759SBarry Smith ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr); 3733221ece2SMatthew G. Knepley 3743221ece2SMatthew G. Knepley ahead = a; 3753221ece2SMatthew G. Knepley a = a - sizeof(TrSPACE); 3763221ece2SMatthew G. Knepley head = (TRSPACE *) a; 3773221ece2SMatthew G. Knepley inew = a; 3783221ece2SMatthew G. Knepley 3793221ece2SMatthew G. Knepley if (head->classid != CLASSID_VALUE) { 380ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() at %s:%d\n",function,filename,lineno); 3813221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 3823221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); 3833221ece2SMatthew G. Knepley } 3843221ece2SMatthew G. Knepley nend = (PetscClassId *)(ahead + head->size); 3853221ece2SMatthew G. Knepley if (*nend != CLASSID_VALUE) { 3863221ece2SMatthew G. Knepley if (*nend == ALREADY_FREED) { 387ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() at %s:%d\n",function,filename,lineno); 3883221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 3893221ece2SMatthew G. Knepley if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 390ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Block freed in %s() at %s:%d\n",head->functionname,head->filename,head->lineno); 3913221ece2SMatthew G. Knepley } else { 392ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Block allocated in %s() at %s:%d\n",head->functionname,head->filename,-head->lineno); 3933221ece2SMatthew G. Knepley } 3943221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); 3953221ece2SMatthew G. Knepley } else { 3963221ece2SMatthew G. Knepley /* Damaged tail */ 397ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() at %s:%d\n",function,filename,lineno); 3983221ece2SMatthew 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); 399ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Block allocated in %s() at %s:%d\n",head->functionname,head->filename,head->lineno); 4003221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); 4013221ece2SMatthew G. Knepley } 4023221ece2SMatthew G. Knepley } 4033221ece2SMatthew G. Knepley 40492f119d6SBarry Smith /* remove original reference to the memory allocated from the PETSc debugging heap */ 405608c71bfSMatthew G. Knepley TRallocated -= TRrequestedSize ? head->rsize : head->size; 4063221ece2SMatthew G. Knepley TRfrags--; 4073221ece2SMatthew G. Knepley if (head->prev) head->prev->next = head->next; 4083221ece2SMatthew G. Knepley else TRhead = head->next; 4093221ece2SMatthew G. Knepley if (head->next) head->next->prev = head->prev; 4103221ece2SMatthew G. Knepley 4113221ece2SMatthew G. Knepley nsize = (len + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1); 4125f80ce2aSJacob Faibussowitsch CHKERRQ(PetscReallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),lineno,function,filename,(void**)&inew)); 4133221ece2SMatthew G. Knepley 4143221ece2SMatthew G. Knepley head = (TRSPACE*)inew; 4153221ece2SMatthew G. Knepley inew += sizeof(TrSPACE); 4163221ece2SMatthew G. Knepley 4173221ece2SMatthew G. Knepley if (TRhead) TRhead->prev = head; 4183221ece2SMatthew G. Knepley head->next = TRhead; 4193221ece2SMatthew G. Knepley TRhead = head; 4203221ece2SMatthew G. Knepley head->prev = NULL; 4213221ece2SMatthew G. Knepley head->size = nsize; 422608c71bfSMatthew G. Knepley head->rsize = len; 423e269983cSBarry Smith head->id = TRid++; 4243221ece2SMatthew G. Knepley head->lineno = lineno; 4253221ece2SMatthew G. Knepley 4263221ece2SMatthew G. Knepley head->filename = filename; 4273221ece2SMatthew G. Knepley head->functionname = function; 4283221ece2SMatthew G. Knepley head->classid = CLASSID_VALUE; 4293221ece2SMatthew G. Knepley *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 4303221ece2SMatthew G. Knepley 431608c71bfSMatthew G. Knepley TRallocated += TRrequestedSize ? head->rsize : head->size; 4323221ece2SMatthew G. Knepley if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 433e3ed9ee7SBarry Smith if (PetscLogMemory) { 434e3ed9ee7SBarry Smith PetscInt i; 435e3ed9ee7SBarry Smith for (i=0; i<NumTRMaxMems; i++) { 436e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 437e3ed9ee7SBarry Smith } 438e3ed9ee7SBarry Smith } 4393221ece2SMatthew G. Knepley TRfrags++; 4403221ece2SMatthew G. Knepley 4413221ece2SMatthew G. Knepley #if defined(PETSC_USE_DEBUG) 4425f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStackCopy(&petscstack,&head->stack)); 4433221ece2SMatthew G. Knepley /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 4443221ece2SMatthew G. Knepley head->stack.line[head->stack.currentsize-2] = lineno; 4453221ece2SMatthew G. Knepley #endif 4463221ece2SMatthew G. Knepley 4473221ece2SMatthew G. Knepley /* 44892f119d6SBarry Smith Allow logging of all mallocs made. This adds a new entry to the list of allocated memory 44992f119d6SBarry Smith and does not remove the previous entry to the list hence this memory is "double counted" in PetscMallocView() 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)); 454*28b400f6SJacob Faibussowitsch PetscCheck(PetscLogMallocLength,PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4553221ece2SMatthew G. Knepley 4563221ece2SMatthew G. Knepley PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 457*28b400f6SJacob Faibussowitsch PetscCheck(PetscLogMallocFile,PETSC_COMM_SELF,PETSC_ERR_MEM," "); 4583221ece2SMatthew G. Knepley 4593221ece2SMatthew G. Knepley PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 460*28b400f6SJacob Faibussowitsch PetscCheck(PetscLogMallocFunction,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 470fe7fb379SMatthew Knepley /*@C 47192f119d6SBarry Smith PetscMemoryView - Shows the amount of memory currently being used in a communicator. 472e5c89e4eSSatish Balay 473e5c89e4eSSatish Balay Collective on PetscViewer 474e5c89e4eSSatish Balay 475d8d19677SJose E. Roman Input Parameters: 476e5c89e4eSSatish Balay + viewer - the viewer that defines the communicator 477e5c89e4eSSatish Balay - message - string printed before values 478e5c89e4eSSatish Balay 4790841954dSBarry Smith Options Database: 48092f119d6SBarry Smith + -malloc_debug - have PETSc track how much memory it has allocated 4810841954dSBarry Smith - -memory_view - during PetscFinalize() have this routine called 4820841954dSBarry Smith 483e5c89e4eSSatish Balay Level: intermediate 484e5c89e4eSSatish Balay 48592f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMemoryGetCurrentUsage(), PetscMemorySetGetMaximumUsage(), PetscMallocView() 486e5c89e4eSSatish Balay @*/ 4870841954dSBarry Smith PetscErrorCode PetscMemoryView(PetscViewer viewer,const char message[]) 488e5c89e4eSSatish Balay { 4890841954dSBarry Smith PetscLogDouble allocated,allocatedmax,resident,residentmax,gallocated,gallocatedmax,gresident,gresidentmax,maxgallocated,maxgallocatedmax,maxgresident,maxgresidentmax; 4900841954dSBarry Smith PetscLogDouble mingallocated,mingallocatedmax,mingresident,mingresidentmax; 491e5c89e4eSSatish Balay MPI_Comm comm; 492e5c89e4eSSatish Balay 493e5c89e4eSSatish Balay PetscFunctionBegin; 494e5c89e4eSSatish Balay if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD; 4955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMallocGetCurrentUsage(&allocated)); 4965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMallocGetMaximumUsage(&allocatedmax)); 4975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemoryGetCurrentUsage(&resident)); 4985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemoryGetMaximumUsage(&residentmax)); 499e5c89e4eSSatish Balay if (residentmax > 0) residentmax = PetscMax(resident,residentmax); 5005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectGetComm((PetscObject)viewer,&comm)); 5015f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"%s",message)); 502e5c89e4eSSatish Balay if (resident && residentmax && allocated) { 5035f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 5045f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 5055f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 5065f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"Maximum (over computational time) process memory: total %5.4e max %5.4e min %5.4e\n",gresidentmax,maxgresidentmax,mingresidentmax)); 5075f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 5085f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 5095f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 5105f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident)); 5115f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&allocatedmax,&gallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 5125f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&allocatedmax,&maxgallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 5135f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&allocatedmax,&mingallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 5145f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"Maximum (over computational time) space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocatedmax,maxgallocatedmax,mingallocatedmax)); 5155f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 5165f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 5175f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 5185f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated)); 519e5c89e4eSSatish Balay } else if (resident && residentmax) { 5205f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 5215f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 5225f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 5235f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"Maximum (over computational time) process memory: total %5.4e max %5.4e min %5.4e\n",gresidentmax,maxgresidentmax,mingresidentmax)); 5245f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 5255f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 5265f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 5275f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident)); 528e5c89e4eSSatish Balay } else if (resident && allocated) { 5295f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 5305f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 5315f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 5325f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident)); 5335f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 5345f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 5355f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 5365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated)); 5375f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n")); 538e5c89e4eSSatish Balay } else if (allocated) { 5395f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 5405f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 5415f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 5425f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated)); 5435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n")); 5445f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"OS cannot compute process memory\n")); 545e5c89e4eSSatish Balay } else { 5465f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"Run with -malloc_debug to get statistics on PetscMalloc() calls\nOS cannot compute process memory\n")); 547e5c89e4eSSatish Balay } 5485f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerFlush(viewer)); 549e5c89e4eSSatish Balay PetscFunctionReturn(0); 550e5c89e4eSSatish Balay } 551e5c89e4eSSatish Balay 55246eb3923SBarry Smith /*@ 553e5c89e4eSSatish Balay PetscMallocGetCurrentUsage - gets the current amount of memory used that was PetscMalloc()ed 554e5c89e4eSSatish Balay 555e5c89e4eSSatish Balay Not Collective 556e5c89e4eSSatish Balay 557e5c89e4eSSatish Balay Output Parameters: 558e5c89e4eSSatish Balay . space - number of bytes currently allocated 559e5c89e4eSSatish Balay 560e5c89e4eSSatish Balay Level: intermediate 561e5c89e4eSSatish Balay 562540e20f2SPierre Jolivet .seealso: PetscMallocDump(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 563e5c89e4eSSatish Balay PetscMemoryGetMaximumUsage() 564e5c89e4eSSatish Balay @*/ 5657087cfbeSBarry Smith PetscErrorCode PetscMallocGetCurrentUsage(PetscLogDouble *space) 566e5c89e4eSSatish Balay { 567e5c89e4eSSatish Balay PetscFunctionBegin; 568e5c89e4eSSatish Balay *space = (PetscLogDouble) TRallocated; 569e5c89e4eSSatish Balay PetscFunctionReturn(0); 570e5c89e4eSSatish Balay } 571e5c89e4eSSatish Balay 572dc37d89fSBarry Smith /*@ 573e5c89e4eSSatish Balay PetscMallocGetMaximumUsage - gets the maximum amount of memory used that was PetscMalloc()ed at any time 574e5c89e4eSSatish Balay during this run. 575e5c89e4eSSatish Balay 576e5c89e4eSSatish Balay Not Collective 577e5c89e4eSSatish Balay 578e5c89e4eSSatish Balay Output Parameters: 579e5c89e4eSSatish Balay . space - maximum number of bytes ever allocated at one time 580e5c89e4eSSatish Balay 581e5c89e4eSSatish Balay Level: intermediate 582e5c89e4eSSatish Balay 58392f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 584e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage() 585e5c89e4eSSatish Balay @*/ 5867087cfbeSBarry Smith PetscErrorCode PetscMallocGetMaximumUsage(PetscLogDouble *space) 587e5c89e4eSSatish Balay { 588e5c89e4eSSatish Balay PetscFunctionBegin; 589e5c89e4eSSatish Balay *space = (PetscLogDouble) TRMaxMem; 590e5c89e4eSSatish Balay PetscFunctionReturn(0); 591e5c89e4eSSatish Balay } 592e5c89e4eSSatish Balay 593e3ed9ee7SBarry Smith /*@ 594e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage - Adds another event to collect the maximum memory usage over an event 595e3ed9ee7SBarry Smith 596e3ed9ee7SBarry Smith Not Collective 597e3ed9ee7SBarry Smith 598e3ed9ee7SBarry Smith Input Parameter: 599e3ed9ee7SBarry Smith . event - an event id; this is just for error checking 600e3ed9ee7SBarry Smith 601e3ed9ee7SBarry Smith Level: developer 602e3ed9ee7SBarry Smith 60392f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 604e3ed9ee7SBarry Smith PetscMallocPopMaximumUsage() 605e3ed9ee7SBarry Smith @*/ 606e3ed9ee7SBarry Smith PetscErrorCode PetscMallocPushMaximumUsage(int event) 607e3ed9ee7SBarry Smith { 608e3ed9ee7SBarry Smith PetscFunctionBegin; 609e3ed9ee7SBarry Smith if (++NumTRMaxMems > MAXTRMAXMEMS) PetscFunctionReturn(0); 610e3ed9ee7SBarry Smith TRMaxMems[NumTRMaxMems-1] = TRallocated; 611e3ed9ee7SBarry Smith TRMaxMemsEvents[NumTRMaxMems-1] = event; 612e3ed9ee7SBarry Smith PetscFunctionReturn(0); 613e3ed9ee7SBarry Smith } 614e3ed9ee7SBarry Smith 615e3ed9ee7SBarry Smith /*@ 616e3ed9ee7SBarry Smith PetscMallocPopMaximumUsage - collect the maximum memory usage over an event 617e3ed9ee7SBarry Smith 618e3ed9ee7SBarry Smith Not Collective 619e3ed9ee7SBarry Smith 620e3ed9ee7SBarry Smith Input Parameter: 621e3ed9ee7SBarry Smith . event - an event id; this is just for error checking 622e3ed9ee7SBarry Smith 623e3ed9ee7SBarry Smith Output Parameter: 624e3ed9ee7SBarry Smith . mu - maximum amount of memory malloced during this event; high water mark relative to the beginning of the event 625e3ed9ee7SBarry Smith 626e3ed9ee7SBarry Smith Level: developer 627e3ed9ee7SBarry Smith 62892f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 629e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage() 630e3ed9ee7SBarry Smith @*/ 631e3ed9ee7SBarry Smith PetscErrorCode PetscMallocPopMaximumUsage(int event,PetscLogDouble *mu) 632e3ed9ee7SBarry Smith { 633e3ed9ee7SBarry Smith PetscFunctionBegin; 634e3ed9ee7SBarry Smith *mu = 0; 635e3ed9ee7SBarry Smith if (NumTRMaxMems-- > MAXTRMAXMEMS) PetscFunctionReturn(0); 6362c71b3e2SJacob Faibussowitsch PetscCheckFalse(TRMaxMemsEvents[NumTRMaxMems] != event,PETSC_COMM_SELF,PETSC_ERR_MEMC,"PetscMallocPush/PopMaximumUsage() are not nested"); 637e3ed9ee7SBarry Smith *mu = TRMaxMems[NumTRMaxMems]; 638e3ed9ee7SBarry Smith PetscFunctionReturn(0); 639e3ed9ee7SBarry Smith } 640e3ed9ee7SBarry Smith 641a64a8e02SBarry Smith #if defined(PETSC_USE_DEBUG) 642a64a8e02SBarry Smith /*@C 643a64a8e02SBarry Smith PetscMallocGetStack - returns a pointer to the stack for the location in the program a call to PetscMalloc() was used to obtain that memory 644a64a8e02SBarry Smith 645a64a8e02SBarry Smith Collective on PETSC_COMM_WORLD 646a64a8e02SBarry Smith 647a64a8e02SBarry Smith Input Parameter: 648a64a8e02SBarry Smith . ptr - the memory location 649a64a8e02SBarry Smith 650fd292e60Sprj- Output Parameter: 651a64a8e02SBarry Smith . stack - the stack indicating where the program allocated this memory 652a64a8e02SBarry Smith 653a64a8e02SBarry Smith Level: intermediate 654a64a8e02SBarry Smith 65592f119d6SBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocView() 656a64a8e02SBarry Smith @*/ 657a64a8e02SBarry Smith PetscErrorCode PetscMallocGetStack(void *ptr,PetscStack **stack) 658a64a8e02SBarry Smith { 659a64a8e02SBarry Smith TRSPACE *head; 660a64a8e02SBarry Smith 661a64a8e02SBarry Smith PetscFunctionBegin; 662a64a8e02SBarry Smith head = (TRSPACE*) (((char*)ptr) - HEADER_BYTES); 663a64a8e02SBarry Smith *stack = &head->stack; 664a64a8e02SBarry Smith PetscFunctionReturn(0); 665a64a8e02SBarry Smith } 66676386721SLisandro Dalcin #else 66776386721SLisandro Dalcin PetscErrorCode PetscMallocGetStack(void *ptr,void **stack) 66876386721SLisandro Dalcin { 66976386721SLisandro Dalcin PetscFunctionBegin; 670f0ba7cfcSLisandro Dalcin *stack = NULL; 67176386721SLisandro Dalcin PetscFunctionReturn(0); 67276386721SLisandro Dalcin } 673a64a8e02SBarry Smith #endif 674a64a8e02SBarry Smith 675e5c89e4eSSatish Balay /*@C 67692f119d6SBarry Smith PetscMallocDump - Dumps the currently allocated memory blocks to a file. The information 677e5c89e4eSSatish Balay printed is: size of space (in bytes), address of space, id of space, 678e5c89e4eSSatish Balay file in which space was allocated, and line number at which it was 679e5c89e4eSSatish Balay allocated. 680e5c89e4eSSatish Balay 68192f119d6SBarry Smith Not Collective 682e5c89e4eSSatish Balay 683e5c89e4eSSatish Balay Input Parameter: 684e5c89e4eSSatish Balay . fp - file pointer. If fp is NULL, stdout is assumed. 685e5c89e4eSSatish Balay 686e5c89e4eSSatish Balay Options Database Key: 68792f119d6SBarry Smith . -malloc_dump <optional filename> - Dumps unfreed memory during call to PetscFinalize() 688e5c89e4eSSatish Balay 689e5c89e4eSSatish Balay Level: intermediate 690e5c89e4eSSatish Balay 691e5c89e4eSSatish Balay Fortran Note: 692e5c89e4eSSatish Balay The calling sequence in Fortran is PetscMallocDump(integer ierr) 693e5c89e4eSSatish Balay The fp defaults to stdout. 694e5c89e4eSSatish Balay 69595452b02SPatrick Sanan Notes: 69692f119d6SBarry Smith Uses MPI_COMM_WORLD to display rank, because this may be called in PetscFinalize() after PETSC_COMM_WORLD has been freed. 697e5c89e4eSSatish Balay 69892f119d6SBarry Smith When called in PetscFinalize() dumps only the allocations that have not been properly freed 69992f119d6SBarry Smith 70092f119d6SBarry Smith PetscMallocView() prints a list of all memory ever allocated 70192f119d6SBarry Smith 702f0b7f91aSBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocView(), PetscMallocViewSet(), PetscMallocValidate() 703e5c89e4eSSatish Balay @*/ 7047087cfbeSBarry Smith PetscErrorCode PetscMallocDump(FILE *fp) 705e5c89e4eSSatish Balay { 706e5c89e4eSSatish Balay TRSPACE *head; 707e3ed9ee7SBarry Smith size_t libAlloc = 0; 708e5c89e4eSSatish Balay PetscMPIInt rank; 709e5c89e4eSSatish Balay 710e5c89e4eSSatish Balay PetscFunctionBegin; 7115f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Comm_rank(MPI_COMM_WORLD,&rank)); 712da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 713e5c89e4eSSatish Balay head = TRhead; 714e5c89e4eSSatish Balay while (head) { 715608c71bfSMatthew G. Knepley libAlloc += TRrequestedSize ? head->rsize : head->size; 7165486ca60SMatthew G. Knepley head = head->next; 7175486ca60SMatthew G. Knepley } 7185486ca60SMatthew G. Knepley if (TRallocated - libAlloc > 0) fprintf(fp,"[%d]Total space allocated %.0f bytes\n",rank,(PetscLogDouble)TRallocated); 7195486ca60SMatthew G. Knepley head = TRhead; 7205486ca60SMatthew G. Knepley while (head) { 7215486ca60SMatthew G. Knepley PetscBool isLib; 7225486ca60SMatthew G. Knepley 7235f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStrcmp(head->functionname, "PetscDLLibraryOpen", &isLib)); 7245486ca60SMatthew G. Knepley if (!isLib) { 725ccd65f63SJunchao Zhang fprintf(fp,"[%2d] %.0f bytes %s() at %s:%d\n",rank,(PetscLogDouble) (TRrequestedSize ? head->rsize : head->size),head->functionname,head->filename,head->lineno); 7268bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 7275f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStackPrint(&head->stack,fp)); 728e5c89e4eSSatish Balay #endif 7295486ca60SMatthew G. Knepley } 730e5c89e4eSSatish Balay head = head->next; 731e5c89e4eSSatish Balay } 732e5c89e4eSSatish Balay PetscFunctionReturn(0); 733e5c89e4eSSatish Balay } 734e5c89e4eSSatish Balay 735dc37d89fSBarry Smith /*@ 73692f119d6SBarry Smith PetscMallocViewSet - Activates logging of all calls to PetscMalloc() with a minimum size to view 737574034a9SJed Brown 738574034a9SJed Brown Not Collective 739574034a9SJed Brown 7404165533cSJose E. Roman Input Parameter: 741574034a9SJed Brown . logmin - minimum allocation size to log, or PETSC_DEFAULT 742574034a9SJed Brown 743574034a9SJed Brown Options Database Key: 74492f119d6SBarry Smith + -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize() 7458b254c29SBarry Smith . -malloc_view_threshold <min> - Sets a minimum size if -malloc_view is used 7468b254c29SBarry Smith - -log_view_memory - view the memory usage also with the -log_view option 747574034a9SJed Brown 748574034a9SJed Brown Level: advanced 749574034a9SJed Brown 75092f119d6SBarry Smith Notes: Must be called after PetscMallocSetDebug() 75192f119d6SBarry Smith 75292f119d6SBarry Smith Uses MPI_COMM_WORLD to determine rank because PETSc communicators may not be available 75392f119d6SBarry Smith 754f0b7f91aSBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocViewSet(), PetscMallocTraceSet(), PetscMallocValidate() 755574034a9SJed Brown @*/ 75692f119d6SBarry Smith PetscErrorCode PetscMallocViewSet(PetscLogDouble logmin) 757574034a9SJed Brown { 758574034a9SJed Brown PetscFunctionBegin; 75992f119d6SBarry Smith PetscLogMalloc = 0; 7605f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemorySetGetMaximumUsage()); 761574034a9SJed Brown if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */ 762574034a9SJed Brown PetscLogMallocThreshold = (size_t)logmin; 763574034a9SJed Brown PetscFunctionReturn(0); 764574034a9SJed Brown } 765574034a9SJed Brown 766dc37d89fSBarry Smith /*@ 76792f119d6SBarry Smith PetscMallocViewGet - Determine whether all calls to PetscMalloc() are being logged 76818a2528dSJed Brown 76918a2528dSJed Brown Not Collective 77018a2528dSJed Brown 7714165533cSJose E. Roman Output Parameter 77218a2528dSJed Brown . logging - PETSC_TRUE if logging is active 77318a2528dSJed Brown 77418a2528dSJed Brown Options Database Key: 77592f119d6SBarry Smith . -malloc_view <optional filename> - Activates PetscMallocView() 77618a2528dSJed Brown 77718a2528dSJed Brown Level: advanced 77818a2528dSJed Brown 779608c71bfSMatthew G. Knepley .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocTraceGet() 78018a2528dSJed Brown @*/ 78192f119d6SBarry Smith PetscErrorCode PetscMallocViewGet(PetscBool *logging) 78218a2528dSJed Brown { 78318a2528dSJed Brown PetscFunctionBegin; 78418a2528dSJed Brown *logging = (PetscBool)(PetscLogMalloc >= 0); 78518a2528dSJed Brown PetscFunctionReturn(0); 78618a2528dSJed Brown } 78718a2528dSJed Brown 788608c71bfSMatthew G. Knepley /*@ 789608c71bfSMatthew G. Knepley PetscMallocTraceSet - Trace all calls to PetscMalloc() 790608c71bfSMatthew G. Knepley 791608c71bfSMatthew G. Knepley Not Collective 792608c71bfSMatthew G. Knepley 7934165533cSJose E. Roman Input Parameters: 794608c71bfSMatthew G. Knepley + viewer - The viewer to use for tracing, or NULL to use stdout 795608c71bfSMatthew G. Knepley . active - Flag to activate or deactivate tracing 796608c71bfSMatthew G. Knepley - logmin - The smallest memory size that will be logged 797608c71bfSMatthew G. Knepley 798608c71bfSMatthew G. Knepley Note: 799608c71bfSMatthew G. Knepley The viewer should not be collective. 800608c71bfSMatthew G. Knepley 801608c71bfSMatthew G. Knepley Level: advanced 802608c71bfSMatthew G. Knepley 803608c71bfSMatthew G. Knepley .seealso: PetscMallocTraceGet(), PetscMallocViewGet(), PetscMallocDump(), PetscMallocView() 804608c71bfSMatthew G. Knepley @*/ 805608c71bfSMatthew G. Knepley PetscErrorCode PetscMallocTraceSet(PetscViewer viewer, PetscBool active, PetscLogDouble logmin) 806608c71bfSMatthew G. Knepley { 807608c71bfSMatthew G. Knepley PetscFunctionBegin; 808608c71bfSMatthew G. Knepley if (!active) {PetscLogMallocTrace = -1; PetscFunctionReturn(0);} 809608c71bfSMatthew G. Knepley PetscLogMallocTraceViewer = !viewer ? PETSC_VIEWER_STDOUT_SELF : viewer; 810608c71bfSMatthew G. Knepley PetscLogMallocTrace = 0; 8115f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemorySetGetMaximumUsage()); 812608c71bfSMatthew G. Knepley if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */ 813608c71bfSMatthew G. Knepley PetscLogMallocTraceThreshold = (size_t) logmin; 814608c71bfSMatthew G. Knepley PetscFunctionReturn(0); 815608c71bfSMatthew G. Knepley } 816608c71bfSMatthew G. Knepley 817608c71bfSMatthew G. Knepley /*@ 818608c71bfSMatthew G. Knepley PetscMallocTraceGet - Determine whether all calls to PetscMalloc() are being traced 819608c71bfSMatthew G. Knepley 820608c71bfSMatthew G. Knepley Not Collective 821608c71bfSMatthew G. Knepley 8224165533cSJose E. Roman Output Parameter: 823608c71bfSMatthew G. Knepley . logging - PETSC_TRUE if logging is active 824608c71bfSMatthew G. Knepley 825608c71bfSMatthew G. Knepley Options Database Key: 826608c71bfSMatthew G. Knepley . -malloc_view <optional filename> - Activates PetscMallocView() 827608c71bfSMatthew G. Knepley 828608c71bfSMatthew G. Knepley Level: advanced 829608c71bfSMatthew G. Knepley 830608c71bfSMatthew G. Knepley .seealso: PetscMallocTraceSet(), PetscMallocViewGet(), PetscMallocDump(), PetscMallocView() 831608c71bfSMatthew G. Knepley @*/ 832608c71bfSMatthew G. Knepley PetscErrorCode PetscMallocTraceGet(PetscBool *logging) 833608c71bfSMatthew G. Knepley { 834608c71bfSMatthew G. Knepley PetscFunctionBegin; 835608c71bfSMatthew G. Knepley *logging = (PetscBool) (PetscLogMallocTrace >= 0); 836608c71bfSMatthew G. Knepley PetscFunctionReturn(0); 837608c71bfSMatthew G. Knepley } 838608c71bfSMatthew G. Knepley 839e5c89e4eSSatish Balay /*@C 84092f119d6SBarry Smith PetscMallocView - Saves the log of all calls to PetscMalloc(); also calls 84121b680ceSJed Brown PetscMemoryGetMaximumUsage() 842e5c89e4eSSatish Balay 84392f119d6SBarry Smith Not Collective 844e5c89e4eSSatish Balay 845e5c89e4eSSatish Balay Input Parameter: 8460298fd71SBarry Smith . fp - file pointer; or NULL 847e5c89e4eSSatish Balay 848e5c89e4eSSatish Balay Options Database Key: 84992f119d6SBarry Smith . -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize() 850e5c89e4eSSatish Balay 851e5c89e4eSSatish Balay Level: advanced 852e5c89e4eSSatish Balay 853e5c89e4eSSatish Balay Fortran Note: 85492f119d6SBarry Smith The calling sequence in Fortran is PetscMallocView(integer ierr) 855e5c89e4eSSatish Balay The fp defaults to stdout. 856e5c89e4eSSatish Balay 85792f119d6SBarry Smith Notes: 85892f119d6SBarry Smith PetscMallocDump() dumps only the currently unfreed memory, this dumps all memory ever allocated 85992f119d6SBarry Smith 86092f119d6SBarry Smith PetscMemoryView() gives a brief summary of current memory usage 86192f119d6SBarry Smith 86292f119d6SBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocDump(), PetscMallocViewSet(), PetscMemoryView() 863e5c89e4eSSatish Balay @*/ 86492f119d6SBarry Smith PetscErrorCode PetscMallocView(FILE *fp) 865e5c89e4eSSatish Balay { 86692f119d6SBarry Smith PetscInt i,j,n,*perm; 867e5c89e4eSSatish Balay size_t *shortlength; 868f56c2debSBarry Smith int *shortcount,err; 86992f119d6SBarry Smith PetscMPIInt rank; 870ace3abfcSBarry Smith PetscBool match; 871e5c89e4eSSatish Balay const char **shortfunction; 872e5c89e4eSSatish Balay PetscLogDouble rss; 873e5c89e4eSSatish Balay 874e5c89e4eSSatish Balay PetscFunctionBegin; 8755f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Comm_rank(MPI_COMM_WORLD,&rank)); 876f56c2debSBarry Smith err = fflush(fp); 877*28b400f6SJacob Faibussowitsch PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 878f56c2debSBarry Smith 8792c71b3e2SJacob Faibussowitsch PetscCheckFalse(PetscLogMalloc < 0,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()"); 880768aa557SSatish Balay 881da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 8825f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemoryGetMaximumUsage(&rss)); 883e5c89e4eSSatish Balay if (rss) { 88492f119d6SBarry Smith (void) fprintf(fp,"[%d] Maximum memory PetscMalloc()ed %.0f maximum size of entire process %.0f\n",rank,(PetscLogDouble)TRMaxMem,rss); 885e5c89e4eSSatish Balay } else { 88692f119d6SBarry Smith (void) fprintf(fp,"[%d] Maximum memory PetscMalloc()ed %.0f OS cannot compute size of entire process\n",rank,(PetscLogDouble)TRMaxMem); 887e5c89e4eSSatish Balay } 888*28b400f6SJacob Faibussowitsch shortcount = (int*)malloc(PetscLogMalloc*sizeof(int));PetscCheck(shortcount,PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 889*28b400f6SJacob Faibussowitsch shortlength = (size_t*)malloc(PetscLogMalloc*sizeof(size_t));PetscCheck(shortlength,PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 890*28b400f6SJacob Faibussowitsch shortfunction = (const char**)malloc(PetscLogMalloc*sizeof(char*));PetscCheck(shortfunction,PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 89197b9d747SJed Brown for (i=0,n=0; i<PetscLogMalloc; i++) { 892e5c89e4eSSatish Balay for (j=0; j<n; j++) { 8935f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStrcmp(shortfunction[j],PetscLogMallocFunction[i],&match)); 894e5c89e4eSSatish Balay if (match) { 895e5c89e4eSSatish Balay shortlength[j] += PetscLogMallocLength[i]; 89659ffdab8SBarry Smith shortcount[j]++; 897e5c89e4eSSatish Balay goto foundit; 898e5c89e4eSSatish Balay } 899e5c89e4eSSatish Balay } 900e5c89e4eSSatish Balay shortfunction[n] = PetscLogMallocFunction[i]; 901e5c89e4eSSatish Balay shortlength[n] = PetscLogMallocLength[i]; 90259ffdab8SBarry Smith shortcount[n] = 1; 903e5c89e4eSSatish Balay n++; 904e5c89e4eSSatish Balay foundit:; 905e5c89e4eSSatish Balay } 906e5c89e4eSSatish Balay 907*28b400f6SJacob Faibussowitsch perm = (PetscInt*)malloc(n*sizeof(PetscInt));PetscCheck(perm,PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 908e5c89e4eSSatish Balay for (i=0; i<n; i++) perm[i] = i; 9095f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSortStrWithPermutation(n,(const char**)shortfunction,perm)); 910e5c89e4eSSatish Balay 91192f119d6SBarry Smith (void) fprintf(fp,"[%d] Memory usage sorted by function\n",rank); 912e5c89e4eSSatish Balay for (i=0; i<n; i++) { 91392f119d6SBarry Smith (void) fprintf(fp,"[%d] %d %.0f %s()\n",rank,shortcount[perm[i]],(PetscLogDouble)shortlength[perm[i]],shortfunction[perm[i]]); 914e5c89e4eSSatish Balay } 915e5c89e4eSSatish Balay free(perm); 916e5c89e4eSSatish Balay free(shortlength); 91759ffdab8SBarry Smith free(shortcount); 918e5c89e4eSSatish Balay free((char**)shortfunction); 919f56c2debSBarry Smith err = fflush(fp); 920*28b400f6SJacob Faibussowitsch PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 921e5c89e4eSSatish Balay PetscFunctionReturn(0); 922e5c89e4eSSatish Balay } 923e5c89e4eSSatish Balay 924e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------- */ 925e5c89e4eSSatish Balay 926dc37d89fSBarry Smith /*@ 92792f119d6SBarry Smith PetscMallocSetDebug - Set's PETSc memory debugging 928e5c89e4eSSatish Balay 929e5c89e4eSSatish Balay Not Collective 930e5c89e4eSSatish Balay 931d8d19677SJose E. Roman Input Parameters: 93292f119d6SBarry Smith + eachcall - checks the entire heap of allocated memory for issues on each call to PetscMalloc() and PetscFree() 9332d4ee042Sprj- - initializenan - initializes all memory with NaN to catch use of uninitialized floating point arrays 934e5c89e4eSSatish Balay 93592f119d6SBarry Smith Options Database: 93679dccf82SBarry Smith + -malloc_debug <true or false> - turns on or off debugging 93792f119d6SBarry Smith . -malloc_test - turns on all debugging if PETSc was configured with debugging including -malloc_dump, otherwise ignored 93879dccf82SBarry Smith . -malloc_view_threshold t - log only allocations larger than t 93992f119d6SBarry Smith . -malloc_dump <filename> - print a list of all memory that has not been freed 94079dccf82SBarry Smith . -malloc no - (deprecated) same as -malloc_debug no 94179dccf82SBarry Smith - -malloc_log - (deprecated) same as -malloc_view 942e5c89e4eSSatish Balay 94392f119d6SBarry Smith Level: developer 94492f119d6SBarry Smith 94592f119d6SBarry Smith Notes: This is called in PetscInitialize() and should not be called elsewhere 94692f119d6SBarry Smith 94792f119d6SBarry Smith .seealso: CHKMEMQ(), PetscMallocValidate(), PetscMallocGetDebug() 948e5c89e4eSSatish Balay @*/ 94992f119d6SBarry Smith PetscErrorCode PetscMallocSetDebug(PetscBool eachcall, PetscBool initializenan) 950e5c89e4eSSatish Balay { 951e5c89e4eSSatish Balay PetscFunctionBegin; 9522c71b3e2SJacob Faibussowitsch PetscCheckFalse(PetscTrMalloc == PetscTrMallocDefault,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot call this routine more than once, it can only be called in PetscInitialize()"); 9535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMallocSet(PetscTrMallocDefault,PetscTrFreeDefault,PetscTrReallocDefault)); 95492f119d6SBarry Smith 95592f119d6SBarry Smith TRallocated = 0; 95692f119d6SBarry Smith TRfrags = 0; 95792f119d6SBarry Smith TRhead = NULL; 95892f119d6SBarry Smith TRid = 0; 95992f119d6SBarry Smith TRdebugLevel = eachcall; 96092f119d6SBarry Smith TRMaxMem = 0; 96192f119d6SBarry Smith PetscLogMallocMax = 10000; 96292f119d6SBarry Smith PetscLogMalloc = -1; 9632d4ee042Sprj- TRdebugIinitializenan = initializenan; 964e5c89e4eSSatish Balay PetscFunctionReturn(0); 965e5c89e4eSSatish Balay } 9660acecf5bSBarry Smith 967dc37d89fSBarry Smith /*@ 96892f119d6SBarry Smith PetscMallocGetDebug - Indicates what PETSc memory debugging it is doing. 9690acecf5bSBarry Smith 9700acecf5bSBarry Smith Not Collective 9710acecf5bSBarry Smith 97292f119d6SBarry Smith Output Parameters: 97392f119d6SBarry Smith + basic - doing basic debugging 97492f119d6SBarry Smith . eachcall - checks the entire memory heap at each PetscMalloc()/PetscFree() 97579dccf82SBarry Smith - initializenan - initializes memory with NaN 9760acecf5bSBarry Smith 9770acecf5bSBarry Smith Level: intermediate 9780acecf5bSBarry Smith 97992f119d6SBarry Smith Notes: 98079dccf82SBarry Smith By default, the debug version always does some debugging unless you run with -malloc_debug no 9810acecf5bSBarry Smith 98292f119d6SBarry Smith .seealso: CHKMEMQ(), PetscMallocValidate(), PetscMallocSetDebug() 9830acecf5bSBarry Smith @*/ 98492f119d6SBarry Smith PetscErrorCode PetscMallocGetDebug(PetscBool *basic, PetscBool *eachcall, PetscBool *initializenan) 9850acecf5bSBarry Smith { 9860acecf5bSBarry Smith PetscFunctionBegin; 98779dccf82SBarry Smith if (basic) *basic = (PetscTrMalloc == PetscTrMallocDefault) ? PETSC_TRUE : PETSC_FALSE; 98879dccf82SBarry Smith if (eachcall) *eachcall = TRdebugLevel; 9892d4ee042Sprj- if (initializenan) *initializenan = TRdebugIinitializenan; 9900acecf5bSBarry Smith PetscFunctionReturn(0); 9910acecf5bSBarry Smith } 992608c71bfSMatthew G. Knepley 993608c71bfSMatthew G. Knepley /*@ 994608c71bfSMatthew G. Knepley PetscMallocLogRequestedSizeSet - Whether to log the requested or aligned memory size 995608c71bfSMatthew G. Knepley 996608c71bfSMatthew G. Knepley Not Collective 997608c71bfSMatthew G. Knepley 998608c71bfSMatthew G. Knepley Input Parameter: 999608c71bfSMatthew G. Knepley . flg - PETSC_TRUE to log the requested memory size 1000608c71bfSMatthew G. Knepley 1001608c71bfSMatthew G. Knepley Options Database: 1002608c71bfSMatthew G. Knepley . -malloc_requested_size <bool> - Sets this flag 1003608c71bfSMatthew G. Knepley 1004608c71bfSMatthew G. Knepley Level: developer 1005608c71bfSMatthew G. Knepley 1006608c71bfSMatthew G. Knepley .seealso: PetscMallocLogRequestedSizeGet(), PetscMallocViewSet() 1007608c71bfSMatthew G. Knepley @*/ 1008608c71bfSMatthew G. Knepley PetscErrorCode PetscMallocLogRequestedSizeSet(PetscBool flg) 1009608c71bfSMatthew G. Knepley { 1010608c71bfSMatthew G. Knepley PetscFunctionBegin; 1011608c71bfSMatthew G. Knepley TRrequestedSize = flg; 1012608c71bfSMatthew G. Knepley PetscFunctionReturn(0); 1013608c71bfSMatthew G. Knepley } 1014608c71bfSMatthew G. Knepley 1015608c71bfSMatthew G. Knepley /*@ 1016608c71bfSMatthew G. Knepley PetscMallocLogRequestedSizeGet - Whether to log the requested or aligned memory size 1017608c71bfSMatthew G. Knepley 1018608c71bfSMatthew G. Knepley Not Collective 1019608c71bfSMatthew G. Knepley 1020608c71bfSMatthew G. Knepley Output Parameter: 1021608c71bfSMatthew G. Knepley . flg - PETSC_TRUE if we log the requested memory size 1022608c71bfSMatthew G. Knepley 1023608c71bfSMatthew G. Knepley Level: developer 1024608c71bfSMatthew G. Knepley 1025608c71bfSMatthew G. Knepley .seealso: PetscMallocLogRequestedSizeSetinalSizeSet(), PetscMallocViewSet() 1026608c71bfSMatthew G. Knepley @*/ 1027608c71bfSMatthew G. Knepley PetscErrorCode PetscMallocLogRequestedSizeGet(PetscBool *flg) 1028608c71bfSMatthew G. Knepley { 1029608c71bfSMatthew G. Knepley PetscFunctionBegin; 1030608c71bfSMatthew G. Knepley *flg = TRrequestedSize; 1031608c71bfSMatthew G. Knepley PetscFunctionReturn(0); 1032608c71bfSMatthew G. Knepley } 1033