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 */ 439371c9d4SSatish Balay typedef union 449371c9d4SSatish Balay { 45e5c89e4eSSatish Balay TRSPACE sp; 4625b53cc9SJed Brown char v[HEADER_BYTES]; 47e5c89e4eSSatish Balay } TrSPACE; 48e5c89e4eSSatish Balay 49e3ed9ee7SBarry Smith #define MAXTRMAXMEMS 50 50e5c89e4eSSatish Balay static size_t TRallocated = 0; 51e5c89e4eSSatish Balay static int TRfrags = 0; 52f0ba7cfcSLisandro Dalcin static TRSPACE *TRhead = NULL; 53e5c89e4eSSatish Balay static int TRid = 0; 54ace3abfcSBarry Smith static PetscBool TRdebugLevel = PETSC_FALSE; 552d4ee042Sprj- static PetscBool TRdebugIinitializenan = PETSC_FALSE; 56608c71bfSMatthew G. Knepley static PetscBool TRrequestedSize = PETSC_FALSE; 57e5c89e4eSSatish Balay static size_t TRMaxMem = 0; 58e3ed9ee7SBarry Smith static int NumTRMaxMems = 0; 59e3ed9ee7SBarry Smith static size_t TRMaxMems[MAXTRMAXMEMS]; 60e3ed9ee7SBarry Smith static int TRMaxMemsEvents[MAXTRMAXMEMS]; 61e5c89e4eSSatish Balay /* 6292f119d6SBarry Smith Arrays to log information on mallocs for PetscMallocView() 63e5c89e4eSSatish Balay */ 64f0ba7cfcSLisandro Dalcin static int PetscLogMallocMax = 10000; 65f0ba7cfcSLisandro Dalcin static int PetscLogMalloc = -1; 66574034a9SJed Brown static size_t PetscLogMallocThreshold = 0; 67e5c89e4eSSatish Balay static size_t *PetscLogMallocLength; 68efca3c55SSatish Balay static const char **PetscLogMallocFile, **PetscLogMallocFunction; 69608c71bfSMatthew G. Knepley static int PetscLogMallocTrace = -1; 70608c71bfSMatthew G. Knepley static size_t PetscLogMallocTraceThreshold = 0; 71608c71bfSMatthew G. Knepley static PetscViewer PetscLogMallocTraceViewer = NULL; 72b022a5c1SBarry Smith 73e5c89e4eSSatish Balay /*@C 7492f119d6SBarry Smith PetscMallocValidate - Test the memory for corruption. This can be called at any time between PetscInitialize() and PetscFinalize() 75e5c89e4eSSatish Balay 7692f119d6SBarry Smith Input Parameters: 77e5c89e4eSSatish Balay + line - line number where call originated. 78e5c89e4eSSatish Balay . function - name of function calling 79efca3c55SSatish Balay - file - file where function is 80e5c89e4eSSatish Balay 81e5c89e4eSSatish Balay Return value: 82e5c89e4eSSatish Balay The number of errors detected. 83e5c89e4eSSatish Balay 8492f119d6SBarry Smith Options Database:. 8592f119d6SBarry Smith + -malloc_test - turns this feature on when PETSc was not configured with --with-debugging=0 8692f119d6SBarry Smith - -malloc_debug - turns this feature on anytime 8792f119d6SBarry Smith 88e5c89e4eSSatish Balay Output Effect: 89e5c89e4eSSatish Balay Error messages are written to stdout. 90e5c89e4eSSatish Balay 91e5c89e4eSSatish Balay Level: advanced 92e5c89e4eSSatish Balay 93e5c89e4eSSatish Balay Notes: 9479dccf82SBarry 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) 9538548759SBarry Smith 9692f119d6SBarry Smith You should generally use CHKMEMQ as a short cut for calling this routine. 97e5c89e4eSSatish Balay 98e5c89e4eSSatish Balay The Fortran calling sequence is simply PetscMallocValidate(ierr) 99e5c89e4eSSatish Balay 100e5c89e4eSSatish Balay No output is generated if there are no problems detected. 101e5c89e4eSSatish Balay 10292f119d6SBarry Smith Developers Note: 10392f119d6SBarry Smith Uses the flg TRdebugLevel (set as the first argument to PetscMallocSetDebug()) to determine if it should run 10492f119d6SBarry Smith 105db781477SPatrick Sanan .seealso: `CHKMEMQ` 106e5c89e4eSSatish Balay 107e5c89e4eSSatish Balay @*/ 1089371c9d4SSatish Balay PetscErrorCode PetscMallocValidate(int line, const char function[], const char file[]) { 1096c093d5bSvictor TRSPACE *head, *lasthead; 110e5c89e4eSSatish Balay char *a; 1110700a824SBarry Smith PetscClassId *nend; 112e5c89e4eSSatish Balay 11338548759SBarry Smith if (!TRdebugLevel) return 0; 1149371c9d4SSatish Balay head = TRhead; 1159371c9d4SSatish Balay lasthead = NULL; 1162cba8197SMatthew G. Knepley if (head && head->prev) { 117ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscMallocValidate: error detected in %s() at %s:%d\n", function, file, line); 1182cba8197SMatthew G. Knepley (*PetscErrorPrintf)("Root memory header %p has invalid back pointer %p\n", head, head->prev); 1194ed0ab5bSBarry Smith return PETSC_ERR_MEMC; 1202cba8197SMatthew G. Knepley } 121e5c89e4eSSatish Balay while (head) { 1220700a824SBarry Smith if (head->classid != CLASSID_VALUE) { 123ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscMallocValidate: error detected in %s() at %s:%d\n", function, file, line); 124e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory at address %p is corrupted\n", head); 1254ed0ab5bSBarry Smith (*PetscErrorPrintf)("Probably write before beginning of or past end of array\n"); 126e269983cSBarry Smith if (lasthead) { 127e269983cSBarry Smith a = (char *)(((TrSPACE *)head) + 1); 128ccd65f63SJunchao 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); 129e269983cSBarry Smith } 130e269983cSBarry Smith abort(); 1314ed0ab5bSBarry Smith return PETSC_ERR_MEMC; 132e5c89e4eSSatish Balay } 133e5c89e4eSSatish Balay a = (char *)(((TrSPACE *)head) + 1); 1340700a824SBarry Smith nend = (PetscClassId *)(a + head->size); 1350700a824SBarry Smith if (*nend != CLASSID_VALUE) { 136ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscMallocValidate: error detected in %s() at %s:%d\n", function, file, line); 137e5c89e4eSSatish Balay if (*nend == ALREADY_FREED) { 138e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p already freed\n", head->id, (PetscLogDouble)head->size, a); 1394ed0ab5bSBarry Smith return PETSC_ERR_MEMC; 140e5c89e4eSSatish Balay } else { 141e5c89e4eSSatish Balay (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n", head->id, (PetscLogDouble)head->size, a); 142ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Memory originally allocated in %s() at %s:%d\n", head->functionname, head->filename, head->lineno); 1434ed0ab5bSBarry Smith return PETSC_ERR_MEMC; 144e5c89e4eSSatish Balay } 145e5c89e4eSSatish Balay } 1462cba8197SMatthew G. Knepley if (head->prev && head->prev != lasthead) { 147ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscMallocValidate: error detected in %s() at %s:%d\n", function, file, line); 1482cba8197SMatthew G. Knepley (*PetscErrorPrintf)("Backpointer %p is invalid, should be %p\n", head->prev, lasthead); 149ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Previous memory originally allocated in %s() at %s:%d\n", lasthead->functionname, lasthead->filename, lasthead->lineno); 150ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Memory originally allocated in %s() at %s:%d\n", head->functionname, head->filename, head->lineno); 1514ed0ab5bSBarry Smith return PETSC_ERR_MEMC; 1522cba8197SMatthew G. Knepley } 1536c093d5bSvictor lasthead = head; 154e5c89e4eSSatish Balay head = head->next; 155e5c89e4eSSatish Balay } 1564ed0ab5bSBarry Smith return 0; 157e5c89e4eSSatish Balay } 158e5c89e4eSSatish Balay 159e5c89e4eSSatish Balay /* 160e5c89e4eSSatish Balay PetscTrMallocDefault - Malloc with tracing. 161e5c89e4eSSatish Balay 162e5c89e4eSSatish Balay Input Parameters: 163e5c89e4eSSatish Balay + a - number of bytes to allocate 164e5c89e4eSSatish Balay . lineno - line number where used. Use __LINE__ for this 165efca3c55SSatish Balay - filename - file name where used. Use __FILE__ for this 166e5c89e4eSSatish Balay 167e5c89e4eSSatish Balay Returns: 16892f119d6SBarry Smith double aligned pointer to requested storage, or null if not available. 169e5c89e4eSSatish Balay */ 1709371c9d4SSatish Balay PetscErrorCode PetscTrMallocDefault(size_t a, PetscBool clear, int lineno, const char function[], const char filename[], void **result) { 171e5c89e4eSSatish Balay TRSPACE *head; 172e5c89e4eSSatish Balay char *inew; 173e5c89e4eSSatish Balay size_t nsize; 174e5c89e4eSSatish Balay 175e5c89e4eSSatish Balay PetscFunctionBegin; 176f0ba7cfcSLisandro Dalcin /* Do not try to handle empty blocks */ 1779371c9d4SSatish Balay if (!a) { 1789371c9d4SSatish Balay *result = NULL; 1799371c9d4SSatish Balay PetscFunctionReturn(0); 1809371c9d4SSatish Balay } 181f0ba7cfcSLisandro Dalcin 182*11cc89d2SBarry Smith PetscCall(PetscMallocValidate(lineno, function, filename)); 183e5c89e4eSSatish Balay 18425b53cc9SJed Brown nsize = (a + (PETSC_MEMALIGN - 1)) & ~(PETSC_MEMALIGN - 1); 1859566063dSJacob Faibussowitsch PetscCall(PetscMallocAlign(nsize + sizeof(TrSPACE) + sizeof(PetscClassId), clear, lineno, function, filename, (void **)&inew)); 186e3ed9ee7SBarry Smith 187e5c89e4eSSatish Balay head = (TRSPACE *)inew; 188e5c89e4eSSatish Balay inew += sizeof(TrSPACE); 189e5c89e4eSSatish Balay 190e5c89e4eSSatish Balay if (TRhead) TRhead->prev = head; 191e5c89e4eSSatish Balay head->next = TRhead; 192e5c89e4eSSatish Balay TRhead = head; 193f0ba7cfcSLisandro Dalcin head->prev = NULL; 194e5c89e4eSSatish Balay head->size = nsize; 195608c71bfSMatthew G. Knepley head->rsize = a; 196e269983cSBarry Smith head->id = TRid++; 197e5c89e4eSSatish Balay head->lineno = lineno; 198e5c89e4eSSatish Balay 199e5c89e4eSSatish Balay head->filename = filename; 200e5c89e4eSSatish Balay head->functionname = function; 2010700a824SBarry Smith head->classid = CLASSID_VALUE; 2020700a824SBarry Smith *(PetscClassId *)(inew + nsize) = CLASSID_VALUE; 203e5c89e4eSSatish Balay 204608c71bfSMatthew G. Knepley TRallocated += TRrequestedSize ? head->rsize : head->size; 205a297a907SKarl Rupp if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 206e3ed9ee7SBarry Smith if (PetscLogMemory) { 207e3ed9ee7SBarry Smith PetscInt i; 208e3ed9ee7SBarry Smith for (i = 0; i < NumTRMaxMems; i++) { 209e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 210e3ed9ee7SBarry Smith } 211e3ed9ee7SBarry Smith } 212e5c89e4eSSatish Balay TRfrags++; 213e5c89e4eSSatish Balay 2148bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 2159566063dSJacob Faibussowitsch PetscCall(PetscStackCopy(&petscstack, &head->stack)); 2162c9581d2SBarry Smith /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 2172c9581d2SBarry Smith head->stack.line[head->stack.currentsize - 2] = lineno; 21892f119d6SBarry Smith #if defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL_DOUBLE) 2192d4ee042Sprj- if (!clear && TRdebugIinitializenan) { 22092f119d6SBarry Smith size_t i, n = a / sizeof(PetscReal); 22192f119d6SBarry Smith PetscReal *s = (PetscReal *)inew; 22292f119d6SBarry Smith /* from https://www.doc.ic.ac.uk/~eedwards/compsys/float/nan.html */ 22392f119d6SBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 224df282883SBarry Smith int nas = 0x7F800002; 22592f119d6SBarry Smith #else 22692f119d6SBarry Smith PetscInt64 nas = 0x7FF0000000000002; 22792f119d6SBarry Smith #endif 228ad540459SPierre Jolivet for (i = 0; i < n; i++) memcpy(s + i, &nas, sizeof(PetscReal)); 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)); 24028b400f6SJacob Faibussowitsch PetscCheck(PetscLogMallocLength, PETSC_COMM_SELF, PETSC_ERR_MEM, " "); 241a297a907SKarl Rupp 242a2ea699eSBarry Smith PetscLogMallocFile = (const char **)malloc(PetscLogMallocMax * sizeof(char *)); 24328b400f6SJacob Faibussowitsch PetscCheck(PetscLogMallocFile, PETSC_COMM_SELF, PETSC_ERR_MEM, " "); 244a297a907SKarl Rupp 245a2ea699eSBarry Smith PetscLogMallocFunction = (const char **)malloc(PetscLogMallocMax * sizeof(char *)); 24628b400f6SJacob 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 } 25248a46eb9SPierre Jolivet if (PetscLogMallocTrace > -1 && a >= PetscLogMallocTraceThreshold) PetscCall(PetscViewerASCIIPrintf(PetscLogMallocTraceViewer, "Alloc %zu %s:%d (%s)\n", a, filename ? filename : "null", lineno, function ? function : "null")); 253e5c89e4eSSatish Balay *result = (void *)inew; 254e5c89e4eSSatish Balay PetscFunctionReturn(0); 255e5c89e4eSSatish Balay } 256e5c89e4eSSatish Balay 257e5c89e4eSSatish Balay /* 258e5c89e4eSSatish Balay PetscTrFreeDefault - Free with tracing. 259e5c89e4eSSatish Balay 260e5c89e4eSSatish Balay Input Parameters: 261e5c89e4eSSatish Balay . a - pointer to a block allocated with PetscTrMalloc 262e5c89e4eSSatish Balay . lineno - line number where used. Use __LINE__ for this 263608c71bfSMatthew G. Knepley . filename - file name where used. Use __FILE__ for this 264e5c89e4eSSatish Balay */ 2659371c9d4SSatish Balay PetscErrorCode PetscTrFreeDefault(void *aa, int lineno, const char function[], const char filename[]) { 266e5c89e4eSSatish Balay char *a = (char *)aa; 267e5c89e4eSSatish Balay TRSPACE *head; 268e5c89e4eSSatish Balay char *ahead; 269608c71bfSMatthew G. Knepley size_t asize; 2700700a824SBarry Smith PetscClassId *nend; 271e5c89e4eSSatish Balay 272e5c89e4eSSatish Balay PetscFunctionBegin; 273e5c89e4eSSatish Balay /* Do not try to handle empty blocks */ 27449d7da52SJed Brown if (!a) PetscFunctionReturn(0); 275e5c89e4eSSatish Balay 2769566063dSJacob Faibussowitsch PetscCall(PetscMallocValidate(lineno, function, filename)); 277e5c89e4eSSatish Balay 278e5c89e4eSSatish Balay ahead = a; 279e5c89e4eSSatish Balay a = a - sizeof(TrSPACE); 280e5c89e4eSSatish Balay head = (TRSPACE *)a; 281e5c89e4eSSatish Balay 2820700a824SBarry Smith if (head->classid != CLASSID_VALUE) { 283ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() at %s:%d\n", function, filename, lineno); 284e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n", a); 285e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_MEMC, "Bad location or corrupted memory"); 286e5c89e4eSSatish Balay } 2870700a824SBarry Smith nend = (PetscClassId *)(ahead + head->size); 2880700a824SBarry Smith if (*nend != CLASSID_VALUE) { 289e5c89e4eSSatish Balay if (*nend == ALREADY_FREED) { 290ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() at %s:%d\n", function, filename, lineno); 291e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n", head->id, (PetscLogDouble)head->size, a + sizeof(TrSPACE)); 292e5c89e4eSSatish Balay if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 293ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Block freed in %s() at %s:%d\n", head->functionname, head->filename, head->lineno); 294e5c89e4eSSatish Balay } else { 295ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Block allocated in %s() at %s:%d\n", head->functionname, head->filename, -head->lineno); 296e5c89e4eSSatish Balay } 297e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Memory already freed"); 298e5c89e4eSSatish Balay } else { 299e5c89e4eSSatish Balay /* Damaged tail */ 300ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() at %s:%d\n", function, filename, lineno); 301e5c89e4eSSatish Balay (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n", head->id, (PetscLogDouble)head->size, a); 302ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Block allocated in %s() at %s:%d\n", head->functionname, head->filename, head->lineno); 303e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_MEMC, "Corrupted memory"); 304e5c89e4eSSatish Balay } 305e5c89e4eSSatish Balay } 306608c71bfSMatthew G. Knepley if (PetscLogMallocTrace > -1 && head->rsize >= PetscLogMallocTraceThreshold) { 3079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(PetscLogMallocTraceViewer, "Free %zu %s:%d (%s)\n", head->rsize, filename ? filename : "null", lineno, function ? function : "null")); 308608c71bfSMatthew G. Knepley } 309e5c89e4eSSatish Balay /* Mark the location freed */ 310e5c89e4eSSatish Balay *nend = ALREADY_FREED; 311e5c89e4eSSatish Balay /* Save location where freed. If we suspect the line number, mark as allocated location */ 312608c71bfSMatthew G. Knepley if (lineno > 0 && lineno < 50000) { 313608c71bfSMatthew G. Knepley head->lineno = lineno; 314608c71bfSMatthew G. Knepley head->filename = filename; 315e5c89e4eSSatish Balay head->functionname = function; 316e5c89e4eSSatish Balay } else { 317e5c89e4eSSatish Balay head->lineno = -head->lineno; 318e5c89e4eSSatish Balay } 319608c71bfSMatthew G. Knepley asize = TRrequestedSize ? head->rsize : head->size; 32008401ef6SPierre Jolivet PetscCheck(TRallocated >= asize, PETSC_COMM_SELF, PETSC_ERR_MEMC, "TRallocate is smaller than memory just freed"); 321608c71bfSMatthew G. Knepley TRallocated -= asize; 322e5c89e4eSSatish Balay TRfrags--; 323e5c89e4eSSatish Balay if (head->prev) head->prev->next = head->next; 324e5c89e4eSSatish Balay else TRhead = head->next; 325e5c89e4eSSatish Balay 326e5c89e4eSSatish Balay if (head->next) head->next->prev = head->prev; 3279566063dSJacob Faibussowitsch PetscCall(PetscFreeAlign(a, lineno, function, filename)); 328e5c89e4eSSatish Balay PetscFunctionReturn(0); 329e5c89e4eSSatish Balay } 330e5c89e4eSSatish Balay 3313221ece2SMatthew G. Knepley /* 3323221ece2SMatthew G. Knepley PetscTrReallocDefault - Realloc with tracing. 3333221ece2SMatthew G. Knepley 3343221ece2SMatthew G. Knepley Input Parameters: 3353221ece2SMatthew G. Knepley + len - number of bytes to allocate 3363221ece2SMatthew G. Knepley . lineno - line number where used. Use __LINE__ for this 3373221ece2SMatthew G. Knepley . filename - file name where used. Use __FILE__ for this 33892f119d6SBarry Smith - result - original memory 3393221ece2SMatthew G. Knepley 3403221ece2SMatthew G. Knepley Output Parameter: 3413221ece2SMatthew G. Knepley . result - double aligned pointer to requested storage, or null if not available. 3423221ece2SMatthew G. Knepley 3433221ece2SMatthew G. Knepley Level: developer 3443221ece2SMatthew G. Knepley 345db781477SPatrick Sanan .seealso: `PetscTrMallocDefault()`, `PetscTrFreeDefault()` 3463221ece2SMatthew G. Knepley */ 3479371c9d4SSatish Balay PetscErrorCode PetscTrReallocDefault(size_t len, int lineno, const char function[], const char filename[], void **result) { 3483221ece2SMatthew G. Knepley char *a = (char *)*result; 3493221ece2SMatthew G. Knepley TRSPACE *head; 3503221ece2SMatthew G. Knepley char *ahead, *inew; 3513221ece2SMatthew G. Knepley PetscClassId *nend; 3523221ece2SMatthew G. Knepley size_t nsize; 3533221ece2SMatthew G. Knepley 3543221ece2SMatthew G. Knepley PetscFunctionBegin; 35592f119d6SBarry Smith /* Realloc requests zero space so just free the current space */ 356c22f1541SToby Isaac if (!len) { 3579566063dSJacob Faibussowitsch PetscCall(PetscTrFreeDefault(*result, lineno, function, filename)); 358c22f1541SToby Isaac *result = NULL; 359c22f1541SToby Isaac PetscFunctionReturn(0); 360c22f1541SToby Isaac } 36192f119d6SBarry Smith /* If the orginal space was NULL just use the regular malloc() */ 362f590eff4SLisandro Dalcin if (!*result) { 3639566063dSJacob Faibussowitsch PetscCall(PetscTrMallocDefault(len, PETSC_FALSE, lineno, function, filename, result)); 364f590eff4SLisandro Dalcin PetscFunctionReturn(0); 365f590eff4SLisandro Dalcin } 3663221ece2SMatthew G. Knepley 367*11cc89d2SBarry Smith PetscCall(PetscMallocValidate(lineno, function, filename)); 3683221ece2SMatthew G. Knepley 3693221ece2SMatthew G. Knepley ahead = a; 3703221ece2SMatthew G. Knepley a = a - sizeof(TrSPACE); 3713221ece2SMatthew G. Knepley head = (TRSPACE *)a; 3723221ece2SMatthew G. Knepley inew = a; 3733221ece2SMatthew G. Knepley 3743221ece2SMatthew G. Knepley if (head->classid != CLASSID_VALUE) { 375ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() at %s:%d\n", function, filename, lineno); 3763221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n", a); 3773221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_MEMC, "Bad location or corrupted memory"); 3783221ece2SMatthew G. Knepley } 3793221ece2SMatthew G. Knepley nend = (PetscClassId *)(ahead + head->size); 3803221ece2SMatthew G. Knepley if (*nend != CLASSID_VALUE) { 3813221ece2SMatthew G. Knepley if (*nend == ALREADY_FREED) { 382ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() at %s:%d\n", function, filename, lineno); 3833221ece2SMatthew G. Knepley (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n", head->id, (PetscLogDouble)head->size, a + sizeof(TrSPACE)); 3843221ece2SMatthew G. Knepley if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 385ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Block freed in %s() at %s:%d\n", head->functionname, head->filename, head->lineno); 3863221ece2SMatthew G. Knepley } else { 387ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Block allocated in %s() at %s:%d\n", head->functionname, head->filename, -head->lineno); 3883221ece2SMatthew G. Knepley } 3893221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Memory already freed"); 3903221ece2SMatthew G. Knepley } else { 3913221ece2SMatthew G. Knepley /* Damaged tail */ 392ccd65f63SJunchao Zhang (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() at %s:%d\n", function, filename, lineno); 3933221ece2SMatthew 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); 394ccd65f63SJunchao Zhang (*PetscErrorPrintf)("Block allocated in %s() at %s:%d\n", head->functionname, head->filename, head->lineno); 3953221ece2SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_MEMC, "Corrupted memory"); 3963221ece2SMatthew G. Knepley } 3973221ece2SMatthew G. Knepley } 3983221ece2SMatthew G. Knepley 39992f119d6SBarry Smith /* remove original reference to the memory allocated from the PETSc debugging heap */ 400608c71bfSMatthew G. Knepley TRallocated -= TRrequestedSize ? head->rsize : head->size; 4013221ece2SMatthew G. Knepley TRfrags--; 4023221ece2SMatthew G. Knepley if (head->prev) head->prev->next = head->next; 4033221ece2SMatthew G. Knepley else TRhead = head->next; 4043221ece2SMatthew G. Knepley if (head->next) head->next->prev = head->prev; 4053221ece2SMatthew G. Knepley 4063221ece2SMatthew G. Knepley nsize = (len + (PETSC_MEMALIGN - 1)) & ~(PETSC_MEMALIGN - 1); 4079566063dSJacob Faibussowitsch PetscCall(PetscReallocAlign(nsize + sizeof(TrSPACE) + sizeof(PetscClassId), lineno, function, filename, (void **)&inew)); 4083221ece2SMatthew G. Knepley 4093221ece2SMatthew G. Knepley head = (TRSPACE *)inew; 4103221ece2SMatthew G. Knepley inew += sizeof(TrSPACE); 4113221ece2SMatthew G. Knepley 4123221ece2SMatthew G. Knepley if (TRhead) TRhead->prev = head; 4133221ece2SMatthew G. Knepley head->next = TRhead; 4143221ece2SMatthew G. Knepley TRhead = head; 4153221ece2SMatthew G. Knepley head->prev = NULL; 4163221ece2SMatthew G. Knepley head->size = nsize; 417608c71bfSMatthew G. Knepley head->rsize = len; 418e269983cSBarry Smith head->id = TRid++; 4193221ece2SMatthew G. Knepley head->lineno = lineno; 4203221ece2SMatthew G. Knepley 4213221ece2SMatthew G. Knepley head->filename = filename; 4223221ece2SMatthew G. Knepley head->functionname = function; 4233221ece2SMatthew G. Knepley head->classid = CLASSID_VALUE; 4243221ece2SMatthew G. Knepley *(PetscClassId *)(inew + nsize) = CLASSID_VALUE; 4253221ece2SMatthew G. Knepley 426608c71bfSMatthew G. Knepley TRallocated += TRrequestedSize ? head->rsize : head->size; 4273221ece2SMatthew G. Knepley if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 428e3ed9ee7SBarry Smith if (PetscLogMemory) { 429e3ed9ee7SBarry Smith PetscInt i; 430e3ed9ee7SBarry Smith for (i = 0; i < NumTRMaxMems; i++) { 431e3ed9ee7SBarry Smith if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 432e3ed9ee7SBarry Smith } 433e3ed9ee7SBarry Smith } 4343221ece2SMatthew G. Knepley TRfrags++; 4353221ece2SMatthew G. Knepley 4363221ece2SMatthew G. Knepley #if defined(PETSC_USE_DEBUG) 4379566063dSJacob Faibussowitsch PetscCall(PetscStackCopy(&petscstack, &head->stack)); 4383221ece2SMatthew G. Knepley /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 4393221ece2SMatthew G. Knepley head->stack.line[head->stack.currentsize - 2] = lineno; 4403221ece2SMatthew G. Knepley #endif 4413221ece2SMatthew G. Knepley 4423221ece2SMatthew G. Knepley /* 44392f119d6SBarry Smith Allow logging of all mallocs made. This adds a new entry to the list of allocated memory 44492f119d6SBarry Smith and does not remove the previous entry to the list hence this memory is "double counted" in PetscMallocView() 4453221ece2SMatthew G. Knepley */ 4463221ece2SMatthew G. Knepley if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && len >= PetscLogMallocThreshold) { 4473221ece2SMatthew G. Knepley if (!PetscLogMalloc) { 4483221ece2SMatthew G. Knepley PetscLogMallocLength = (size_t *)malloc(PetscLogMallocMax * sizeof(size_t)); 44928b400f6SJacob Faibussowitsch PetscCheck(PetscLogMallocLength, PETSC_COMM_SELF, PETSC_ERR_MEM, " "); 4503221ece2SMatthew G. Knepley 4513221ece2SMatthew G. Knepley PetscLogMallocFile = (const char **)malloc(PetscLogMallocMax * sizeof(char *)); 45228b400f6SJacob Faibussowitsch PetscCheck(PetscLogMallocFile, PETSC_COMM_SELF, PETSC_ERR_MEM, " "); 4533221ece2SMatthew G. Knepley 4543221ece2SMatthew G. Knepley PetscLogMallocFunction = (const char **)malloc(PetscLogMallocMax * sizeof(char *)); 45528b400f6SJacob Faibussowitsch PetscCheck(PetscLogMallocFunction, PETSC_COMM_SELF, PETSC_ERR_MEM, " "); 4563221ece2SMatthew G. Knepley } 4573221ece2SMatthew G. Knepley PetscLogMallocLength[PetscLogMalloc] = nsize; 4583221ece2SMatthew G. Knepley PetscLogMallocFile[PetscLogMalloc] = filename; 4593221ece2SMatthew G. Knepley PetscLogMallocFunction[PetscLogMalloc++] = function; 4603221ece2SMatthew G. Knepley } 4613221ece2SMatthew G. Knepley *result = (void *)inew; 4623221ece2SMatthew G. Knepley PetscFunctionReturn(0); 4633221ece2SMatthew G. Knepley } 4643221ece2SMatthew G. Knepley 465fe7fb379SMatthew Knepley /*@C 46692f119d6SBarry Smith PetscMemoryView - Shows the amount of memory currently being used in a communicator. 467e5c89e4eSSatish Balay 468e5c89e4eSSatish Balay Collective on PetscViewer 469e5c89e4eSSatish Balay 470d8d19677SJose E. Roman Input Parameters: 471e5c89e4eSSatish Balay + viewer - the viewer that defines the communicator 472e5c89e4eSSatish Balay - message - string printed before values 473e5c89e4eSSatish Balay 4740841954dSBarry Smith Options Database: 47592f119d6SBarry Smith + -malloc_debug - have PETSc track how much memory it has allocated 4760841954dSBarry Smith - -memory_view - during PetscFinalize() have this routine called 4770841954dSBarry Smith 478e5c89e4eSSatish Balay Level: intermediate 479e5c89e4eSSatish Balay 480db781477SPatrick Sanan .seealso: `PetscMallocDump()`, `PetscMemoryGetCurrentUsage()`, `PetscMemorySetGetMaximumUsage()`, `PetscMallocView()` 481e5c89e4eSSatish Balay @*/ 4829371c9d4SSatish Balay PetscErrorCode PetscMemoryView(PetscViewer viewer, const char message[]) { 4830841954dSBarry Smith PetscLogDouble allocated, allocatedmax, resident, residentmax, gallocated, gallocatedmax, gresident, gresidentmax, maxgallocated, maxgallocatedmax, maxgresident, maxgresidentmax; 4840841954dSBarry Smith PetscLogDouble mingallocated, mingallocatedmax, mingresident, mingresidentmax; 485e5c89e4eSSatish Balay MPI_Comm comm; 486e5c89e4eSSatish Balay 487e5c89e4eSSatish Balay PetscFunctionBegin; 488e5c89e4eSSatish Balay if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD; 4899566063dSJacob Faibussowitsch PetscCall(PetscMallocGetCurrentUsage(&allocated)); 4909566063dSJacob Faibussowitsch PetscCall(PetscMallocGetMaximumUsage(&allocatedmax)); 4919566063dSJacob Faibussowitsch PetscCall(PetscMemoryGetCurrentUsage(&resident)); 4929566063dSJacob Faibussowitsch PetscCall(PetscMemoryGetMaximumUsage(&residentmax)); 493e5c89e4eSSatish Balay if (residentmax > 0) residentmax = PetscMax(resident, residentmax); 4949566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm)); 4959566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s", message)); 496e5c89e4eSSatish Balay if (resident && residentmax && allocated) { 4979566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&residentmax, &gresidentmax, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, 0, comm)); 4989566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&residentmax, &maxgresidentmax, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, 0, comm)); 4999566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&residentmax, &mingresidentmax, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, 0, comm)); 5009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Maximum (over computational time) process memory: total %5.4e max %5.4e min %5.4e\n", gresidentmax, maxgresidentmax, mingresidentmax)); 5019566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&resident, &gresident, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, 0, comm)); 5029566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&resident, &maxgresident, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, 0, comm)); 5039566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&resident, &mingresident, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, 0, comm)); 5049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Current process memory: total %5.4e max %5.4e min %5.4e\n", gresident, maxgresident, mingresident)); 5059566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&allocatedmax, &gallocatedmax, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, 0, comm)); 5069566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&allocatedmax, &maxgallocatedmax, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, 0, comm)); 5079566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&allocatedmax, &mingallocatedmax, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, 0, comm)); 5089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Maximum (over computational time) space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n", gallocatedmax, maxgallocatedmax, mingallocatedmax)); 5099566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&allocated, &gallocated, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, 0, comm)); 5109566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&allocated, &maxgallocated, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, 0, comm)); 5119566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&allocated, &mingallocated, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, 0, comm)); 5129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n", gallocated, maxgallocated, mingallocated)); 513e5c89e4eSSatish Balay } else if (resident && residentmax) { 5149566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&residentmax, &gresidentmax, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, 0, comm)); 5159566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&residentmax, &maxgresidentmax, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, 0, comm)); 5169566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&residentmax, &mingresidentmax, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, 0, comm)); 5179566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Maximum (over computational time) process memory: total %5.4e max %5.4e min %5.4e\n", gresidentmax, maxgresidentmax, mingresidentmax)); 5189566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&resident, &gresident, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, 0, comm)); 5199566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&resident, &maxgresident, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, 0, comm)); 5209566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&resident, &mingresident, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, 0, comm)); 5219566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Current process memory: total %5.4e max %5.4e min %5.4e\n", gresident, maxgresident, mingresident)); 522e5c89e4eSSatish Balay } else if (resident && allocated) { 5239566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&resident, &gresident, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, 0, comm)); 5249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&resident, &maxgresident, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, 0, comm)); 5259566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&resident, &mingresident, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, 0, comm)); 5269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Current process memory: total %5.4e max %5.4e min %5.4e\n", gresident, maxgresident, mingresident)); 5279566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&allocated, &gallocated, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, 0, comm)); 5289566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&allocated, &maxgallocated, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, 0, comm)); 5299566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&allocated, &mingallocated, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, 0, comm)); 5309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n", gallocated, maxgallocated, mingallocated)); 5319566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Run with -memory_view to get maximum memory usage\n")); 532e5c89e4eSSatish Balay } else if (allocated) { 5339566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&allocated, &gallocated, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, 0, comm)); 5349566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&allocated, &maxgallocated, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, 0, comm)); 5359566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&allocated, &mingallocated, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, 0, comm)); 5369566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n", gallocated, maxgallocated, mingallocated)); 5379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Run with -memory_view to get maximum memory usage\n")); 5389566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "OS cannot compute process memory\n")); 539e5c89e4eSSatish Balay } else { 5409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Run with -malloc_debug to get statistics on PetscMalloc() calls\nOS cannot compute process memory\n")); 541e5c89e4eSSatish Balay } 5429566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 543e5c89e4eSSatish Balay PetscFunctionReturn(0); 544e5c89e4eSSatish Balay } 545e5c89e4eSSatish Balay 54646eb3923SBarry Smith /*@ 547e5c89e4eSSatish Balay PetscMallocGetCurrentUsage - gets the current amount of memory used that was PetscMalloc()ed 548e5c89e4eSSatish Balay 549e5c89e4eSSatish Balay Not Collective 550e5c89e4eSSatish Balay 551e5c89e4eSSatish Balay Output Parameters: 552e5c89e4eSSatish Balay . space - number of bytes currently allocated 553e5c89e4eSSatish Balay 554e5c89e4eSSatish Balay Level: intermediate 555e5c89e4eSSatish Balay 556db781477SPatrick Sanan .seealso: `PetscMallocDump()`, `PetscMallocGetMaximumUsage()`, `PetscMemoryGetCurrentUsage()`, 557db781477SPatrick Sanan `PetscMemoryGetMaximumUsage()` 558e5c89e4eSSatish Balay @*/ 5599371c9d4SSatish Balay PetscErrorCode PetscMallocGetCurrentUsage(PetscLogDouble *space) { 560e5c89e4eSSatish Balay PetscFunctionBegin; 561e5c89e4eSSatish Balay *space = (PetscLogDouble)TRallocated; 562e5c89e4eSSatish Balay PetscFunctionReturn(0); 563e5c89e4eSSatish Balay } 564e5c89e4eSSatish Balay 565dc37d89fSBarry Smith /*@ 566e5c89e4eSSatish Balay PetscMallocGetMaximumUsage - gets the maximum amount of memory used that was PetscMalloc()ed at any time 567e5c89e4eSSatish Balay during this run. 568e5c89e4eSSatish Balay 569e5c89e4eSSatish Balay Not Collective 570e5c89e4eSSatish Balay 571e5c89e4eSSatish Balay Output Parameters: 572e5c89e4eSSatish Balay . space - maximum number of bytes ever allocated at one time 573e5c89e4eSSatish Balay 574e5c89e4eSSatish Balay Level: intermediate 575e5c89e4eSSatish Balay 576db781477SPatrick Sanan .seealso: `PetscMallocDump()`, `PetscMallocView()`, `PetscMallocGetMaximumUsage()`, `PetscMemoryGetCurrentUsage()`, 577db781477SPatrick Sanan `PetscMallocPushMaximumUsage()` 578e5c89e4eSSatish Balay @*/ 5799371c9d4SSatish Balay PetscErrorCode PetscMallocGetMaximumUsage(PetscLogDouble *space) { 580e5c89e4eSSatish Balay PetscFunctionBegin; 581e5c89e4eSSatish Balay *space = (PetscLogDouble)TRMaxMem; 582e5c89e4eSSatish Balay PetscFunctionReturn(0); 583e5c89e4eSSatish Balay } 584e5c89e4eSSatish Balay 585e3ed9ee7SBarry Smith /*@ 586e3ed9ee7SBarry Smith PetscMallocPushMaximumUsage - Adds another event to collect the maximum memory usage over an event 587e3ed9ee7SBarry Smith 588e3ed9ee7SBarry Smith Not Collective 589e3ed9ee7SBarry Smith 590e3ed9ee7SBarry Smith Input Parameter: 591e3ed9ee7SBarry Smith . event - an event id; this is just for error checking 592e3ed9ee7SBarry Smith 593e3ed9ee7SBarry Smith Level: developer 594e3ed9ee7SBarry Smith 595db781477SPatrick Sanan .seealso: `PetscMallocDump()`, `PetscMallocView()`, `PetscMallocGetMaximumUsage()`, `PetscMemoryGetCurrentUsage()`, 596db781477SPatrick Sanan `PetscMallocPopMaximumUsage()` 597e3ed9ee7SBarry Smith @*/ 5989371c9d4SSatish Balay PetscErrorCode PetscMallocPushMaximumUsage(int event) { 599e3ed9ee7SBarry Smith PetscFunctionBegin; 600e3ed9ee7SBarry Smith if (++NumTRMaxMems > MAXTRMAXMEMS) PetscFunctionReturn(0); 601e3ed9ee7SBarry Smith TRMaxMems[NumTRMaxMems - 1] = TRallocated; 602e3ed9ee7SBarry Smith TRMaxMemsEvents[NumTRMaxMems - 1] = event; 603e3ed9ee7SBarry Smith PetscFunctionReturn(0); 604e3ed9ee7SBarry Smith } 605e3ed9ee7SBarry Smith 606e3ed9ee7SBarry Smith /*@ 607e3ed9ee7SBarry Smith PetscMallocPopMaximumUsage - collect the maximum memory usage over an event 608e3ed9ee7SBarry Smith 609e3ed9ee7SBarry Smith Not Collective 610e3ed9ee7SBarry Smith 611e3ed9ee7SBarry Smith Input Parameter: 612e3ed9ee7SBarry Smith . event - an event id; this is just for error checking 613e3ed9ee7SBarry Smith 614e3ed9ee7SBarry Smith Output Parameter: 615e3ed9ee7SBarry Smith . mu - maximum amount of memory malloced during this event; high water mark relative to the beginning of the event 616e3ed9ee7SBarry Smith 617e3ed9ee7SBarry Smith Level: developer 618e3ed9ee7SBarry Smith 619db781477SPatrick Sanan .seealso: `PetscMallocDump()`, `PetscMallocView()`, `PetscMallocGetMaximumUsage()`, `PetscMemoryGetCurrentUsage()`, 620db781477SPatrick Sanan `PetscMallocPushMaximumUsage()` 621e3ed9ee7SBarry Smith @*/ 6229371c9d4SSatish Balay PetscErrorCode PetscMallocPopMaximumUsage(int event, PetscLogDouble *mu) { 623e3ed9ee7SBarry Smith PetscFunctionBegin; 624e3ed9ee7SBarry Smith *mu = 0; 625e3ed9ee7SBarry Smith if (NumTRMaxMems-- > MAXTRMAXMEMS) PetscFunctionReturn(0); 62608401ef6SPierre Jolivet PetscCheck(TRMaxMemsEvents[NumTRMaxMems] == event, PETSC_COMM_SELF, PETSC_ERR_MEMC, "PetscMallocPush/PopMaximumUsage() are not nested"); 627e3ed9ee7SBarry Smith *mu = TRMaxMems[NumTRMaxMems]; 628e3ed9ee7SBarry Smith PetscFunctionReturn(0); 629e3ed9ee7SBarry Smith } 630e3ed9ee7SBarry Smith 631a64a8e02SBarry Smith #if defined(PETSC_USE_DEBUG) 632a64a8e02SBarry Smith /*@C 633a64a8e02SBarry Smith PetscMallocGetStack - returns a pointer to the stack for the location in the program a call to PetscMalloc() was used to obtain that memory 634a64a8e02SBarry Smith 635a64a8e02SBarry Smith Collective on PETSC_COMM_WORLD 636a64a8e02SBarry Smith 637a64a8e02SBarry Smith Input Parameter: 638a64a8e02SBarry Smith . ptr - the memory location 639a64a8e02SBarry Smith 640fd292e60Sprj- Output Parameter: 641a64a8e02SBarry Smith . stack - the stack indicating where the program allocated this memory 642a64a8e02SBarry Smith 643a64a8e02SBarry Smith Level: intermediate 644a64a8e02SBarry Smith 645db781477SPatrick Sanan .seealso: `PetscMallocGetCurrentUsage()`, `PetscMallocView()` 646a64a8e02SBarry Smith @*/ 6479371c9d4SSatish Balay PetscErrorCode PetscMallocGetStack(void *ptr, PetscStack **stack) { 648a64a8e02SBarry Smith TRSPACE *head; 649a64a8e02SBarry Smith 650a64a8e02SBarry Smith PetscFunctionBegin; 651a64a8e02SBarry Smith head = (TRSPACE *)(((char *)ptr) - HEADER_BYTES); 652a64a8e02SBarry Smith *stack = &head->stack; 653a64a8e02SBarry Smith PetscFunctionReturn(0); 654a64a8e02SBarry Smith } 65576386721SLisandro Dalcin #else 6569371c9d4SSatish Balay PetscErrorCode PetscMallocGetStack(void *ptr, void **stack) { 65776386721SLisandro Dalcin PetscFunctionBegin; 658f0ba7cfcSLisandro Dalcin *stack = NULL; 65976386721SLisandro Dalcin PetscFunctionReturn(0); 66076386721SLisandro Dalcin } 661a64a8e02SBarry Smith #endif 662a64a8e02SBarry Smith 663e5c89e4eSSatish Balay /*@C 66492f119d6SBarry Smith PetscMallocDump - Dumps the currently allocated memory blocks to a file. The information 665e5c89e4eSSatish Balay printed is: size of space (in bytes), address of space, id of space, 666e5c89e4eSSatish Balay file in which space was allocated, and line number at which it was 667e5c89e4eSSatish Balay allocated. 668e5c89e4eSSatish Balay 66992f119d6SBarry Smith Not Collective 670e5c89e4eSSatish Balay 671e5c89e4eSSatish Balay Input Parameter: 672e5c89e4eSSatish Balay . fp - file pointer. If fp is NULL, stdout is assumed. 673e5c89e4eSSatish Balay 674e5c89e4eSSatish Balay Options Database Key: 67592f119d6SBarry Smith . -malloc_dump <optional filename> - Dumps unfreed memory during call to PetscFinalize() 676e5c89e4eSSatish Balay 677e5c89e4eSSatish Balay Level: intermediate 678e5c89e4eSSatish Balay 679e5c89e4eSSatish Balay Fortran Note: 680e5c89e4eSSatish Balay The calling sequence in Fortran is PetscMallocDump(integer ierr) 681e5c89e4eSSatish Balay The fp defaults to stdout. 682e5c89e4eSSatish Balay 68395452b02SPatrick Sanan Notes: 68492f119d6SBarry Smith Uses MPI_COMM_WORLD to display rank, because this may be called in PetscFinalize() after PETSC_COMM_WORLD has been freed. 685e5c89e4eSSatish Balay 68692f119d6SBarry Smith When called in PetscFinalize() dumps only the allocations that have not been properly freed 68792f119d6SBarry Smith 68892f119d6SBarry Smith PetscMallocView() prints a list of all memory ever allocated 68992f119d6SBarry Smith 690db781477SPatrick Sanan .seealso: `PetscMallocGetCurrentUsage()`, `PetscMallocView()`, `PetscMallocViewSet()`, `PetscMallocValidate()` 691e5c89e4eSSatish Balay @*/ 6929371c9d4SSatish Balay PetscErrorCode PetscMallocDump(FILE *fp) { 693e5c89e4eSSatish Balay TRSPACE *head; 694e3ed9ee7SBarry Smith size_t libAlloc = 0; 695e5c89e4eSSatish Balay PetscMPIInt rank; 696e5c89e4eSSatish Balay 697e5c89e4eSSatish Balay PetscFunctionBegin; 6989566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &rank)); 699da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 700e5c89e4eSSatish Balay head = TRhead; 701e5c89e4eSSatish Balay while (head) { 702608c71bfSMatthew G. Knepley libAlloc += TRrequestedSize ? head->rsize : head->size; 7035486ca60SMatthew G. Knepley head = head->next; 7045486ca60SMatthew G. Knepley } 7055486ca60SMatthew G. Knepley if (TRallocated - libAlloc > 0) fprintf(fp, "[%d]Total space allocated %.0f bytes\n", rank, (PetscLogDouble)TRallocated); 7065486ca60SMatthew G. Knepley head = TRhead; 7075486ca60SMatthew G. Knepley while (head) { 7085486ca60SMatthew G. Knepley PetscBool isLib; 7095486ca60SMatthew G. Knepley 7109566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(head->functionname, "PetscDLLibraryOpen", &isLib)); 7115486ca60SMatthew G. Knepley if (!isLib) { 712ccd65f63SJunchao Zhang fprintf(fp, "[%2d] %.0f bytes %s() at %s:%d\n", rank, (PetscLogDouble)(TRrequestedSize ? head->rsize : head->size), head->functionname, head->filename, head->lineno); 7138bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG) 7149566063dSJacob Faibussowitsch PetscCall(PetscStackPrint(&head->stack, fp)); 715e5c89e4eSSatish Balay #endif 7165486ca60SMatthew G. Knepley } 717e5c89e4eSSatish Balay head = head->next; 718e5c89e4eSSatish Balay } 719e5c89e4eSSatish Balay PetscFunctionReturn(0); 720e5c89e4eSSatish Balay } 721e5c89e4eSSatish Balay 722dc37d89fSBarry Smith /*@ 72392f119d6SBarry Smith PetscMallocViewSet - Activates logging of all calls to PetscMalloc() with a minimum size to view 724574034a9SJed Brown 725574034a9SJed Brown Not Collective 726574034a9SJed Brown 7274165533cSJose E. Roman Input Parameter: 728574034a9SJed Brown . logmin - minimum allocation size to log, or PETSC_DEFAULT 729574034a9SJed Brown 730574034a9SJed Brown Options Database Key: 73192f119d6SBarry Smith + -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize() 7328b254c29SBarry Smith . -malloc_view_threshold <min> - Sets a minimum size if -malloc_view is used 7338b254c29SBarry Smith - -log_view_memory - view the memory usage also with the -log_view option 734574034a9SJed Brown 735574034a9SJed Brown Level: advanced 736574034a9SJed Brown 73792f119d6SBarry Smith Notes: Must be called after PetscMallocSetDebug() 73892f119d6SBarry Smith 73992f119d6SBarry Smith Uses MPI_COMM_WORLD to determine rank because PETSc communicators may not be available 74092f119d6SBarry Smith 741db781477SPatrick Sanan .seealso: `PetscMallocDump()`, `PetscMallocView()`, `PetscMallocViewSet()`, `PetscMallocTraceSet()`, `PetscMallocValidate()` 742574034a9SJed Brown @*/ 7439371c9d4SSatish Balay PetscErrorCode PetscMallocViewSet(PetscLogDouble logmin) { 744574034a9SJed Brown PetscFunctionBegin; 74592f119d6SBarry Smith PetscLogMalloc = 0; 7469566063dSJacob Faibussowitsch PetscCall(PetscMemorySetGetMaximumUsage()); 747574034a9SJed Brown if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */ 748574034a9SJed Brown PetscLogMallocThreshold = (size_t)logmin; 749574034a9SJed Brown PetscFunctionReturn(0); 750574034a9SJed Brown } 751574034a9SJed Brown 752dc37d89fSBarry Smith /*@ 75392f119d6SBarry Smith PetscMallocViewGet - Determine whether all calls to PetscMalloc() are being logged 75418a2528dSJed Brown 75518a2528dSJed Brown Not Collective 75618a2528dSJed Brown 7574165533cSJose E. Roman Output Parameter 75818a2528dSJed Brown . logging - PETSC_TRUE if logging is active 75918a2528dSJed Brown 76018a2528dSJed Brown Options Database Key: 76192f119d6SBarry Smith . -malloc_view <optional filename> - Activates PetscMallocView() 76218a2528dSJed Brown 76318a2528dSJed Brown Level: advanced 76418a2528dSJed Brown 765db781477SPatrick Sanan .seealso: `PetscMallocDump()`, `PetscMallocView()`, `PetscMallocTraceGet()` 76618a2528dSJed Brown @*/ 7679371c9d4SSatish Balay PetscErrorCode PetscMallocViewGet(PetscBool *logging) { 76818a2528dSJed Brown PetscFunctionBegin; 76918a2528dSJed Brown *logging = (PetscBool)(PetscLogMalloc >= 0); 77018a2528dSJed Brown PetscFunctionReturn(0); 77118a2528dSJed Brown } 77218a2528dSJed Brown 773608c71bfSMatthew G. Knepley /*@ 774608c71bfSMatthew G. Knepley PetscMallocTraceSet - Trace all calls to PetscMalloc() 775608c71bfSMatthew G. Knepley 776608c71bfSMatthew G. Knepley Not Collective 777608c71bfSMatthew G. Knepley 7784165533cSJose E. Roman Input Parameters: 779608c71bfSMatthew G. Knepley + viewer - The viewer to use for tracing, or NULL to use stdout 780608c71bfSMatthew G. Knepley . active - Flag to activate or deactivate tracing 781608c71bfSMatthew G. Knepley - logmin - The smallest memory size that will be logged 782608c71bfSMatthew G. Knepley 783608c71bfSMatthew G. Knepley Note: 784608c71bfSMatthew G. Knepley The viewer should not be collective. 785608c71bfSMatthew G. Knepley 786608c71bfSMatthew G. Knepley Level: advanced 787608c71bfSMatthew G. Knepley 788db781477SPatrick Sanan .seealso: `PetscMallocTraceGet()`, `PetscMallocViewGet()`, `PetscMallocDump()`, `PetscMallocView()` 789608c71bfSMatthew G. Knepley @*/ 7909371c9d4SSatish Balay PetscErrorCode PetscMallocTraceSet(PetscViewer viewer, PetscBool active, PetscLogDouble logmin) { 791608c71bfSMatthew G. Knepley PetscFunctionBegin; 7929371c9d4SSatish Balay if (!active) { 7939371c9d4SSatish Balay PetscLogMallocTrace = -1; 7949371c9d4SSatish Balay PetscFunctionReturn(0); 7959371c9d4SSatish Balay } 796608c71bfSMatthew G. Knepley PetscLogMallocTraceViewer = !viewer ? PETSC_VIEWER_STDOUT_SELF : viewer; 797608c71bfSMatthew G. Knepley PetscLogMallocTrace = 0; 7989566063dSJacob Faibussowitsch PetscCall(PetscMemorySetGetMaximumUsage()); 799608c71bfSMatthew G. Knepley if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */ 800608c71bfSMatthew G. Knepley PetscLogMallocTraceThreshold = (size_t)logmin; 801608c71bfSMatthew G. Knepley PetscFunctionReturn(0); 802608c71bfSMatthew G. Knepley } 803608c71bfSMatthew G. Knepley 804608c71bfSMatthew G. Knepley /*@ 805608c71bfSMatthew G. Knepley PetscMallocTraceGet - Determine whether all calls to PetscMalloc() are being traced 806608c71bfSMatthew G. Knepley 807608c71bfSMatthew G. Knepley Not Collective 808608c71bfSMatthew G. Knepley 8094165533cSJose E. Roman Output Parameter: 810608c71bfSMatthew G. Knepley . logging - PETSC_TRUE if logging is active 811608c71bfSMatthew G. Knepley 812608c71bfSMatthew G. Knepley Options Database Key: 813608c71bfSMatthew G. Knepley . -malloc_view <optional filename> - Activates PetscMallocView() 814608c71bfSMatthew G. Knepley 815608c71bfSMatthew G. Knepley Level: advanced 816608c71bfSMatthew G. Knepley 817db781477SPatrick Sanan .seealso: `PetscMallocTraceSet()`, `PetscMallocViewGet()`, `PetscMallocDump()`, `PetscMallocView()` 818608c71bfSMatthew G. Knepley @*/ 8199371c9d4SSatish Balay PetscErrorCode PetscMallocTraceGet(PetscBool *logging) { 820608c71bfSMatthew G. Knepley PetscFunctionBegin; 821608c71bfSMatthew G. Knepley *logging = (PetscBool)(PetscLogMallocTrace >= 0); 822608c71bfSMatthew G. Knepley PetscFunctionReturn(0); 823608c71bfSMatthew G. Knepley } 824608c71bfSMatthew G. Knepley 825e5c89e4eSSatish Balay /*@C 82692f119d6SBarry Smith PetscMallocView - Saves the log of all calls to PetscMalloc(); also calls 82721b680ceSJed Brown PetscMemoryGetMaximumUsage() 828e5c89e4eSSatish Balay 82992f119d6SBarry Smith Not Collective 830e5c89e4eSSatish Balay 831e5c89e4eSSatish Balay Input Parameter: 8320298fd71SBarry Smith . fp - file pointer; or NULL 833e5c89e4eSSatish Balay 834e5c89e4eSSatish Balay Options Database Key: 83592f119d6SBarry Smith . -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize() 836e5c89e4eSSatish Balay 837e5c89e4eSSatish Balay Level: advanced 838e5c89e4eSSatish Balay 839e5c89e4eSSatish Balay Fortran Note: 84092f119d6SBarry Smith The calling sequence in Fortran is PetscMallocView(integer ierr) 841e5c89e4eSSatish Balay The fp defaults to stdout. 842e5c89e4eSSatish Balay 84392f119d6SBarry Smith Notes: 84492f119d6SBarry Smith PetscMallocDump() dumps only the currently unfreed memory, this dumps all memory ever allocated 84592f119d6SBarry Smith 84692f119d6SBarry Smith PetscMemoryView() gives a brief summary of current memory usage 84792f119d6SBarry Smith 848db781477SPatrick Sanan .seealso: `PetscMallocGetCurrentUsage()`, `PetscMallocDump()`, `PetscMallocViewSet()`, `PetscMemoryView()` 849e5c89e4eSSatish Balay @*/ 8509371c9d4SSatish Balay PetscErrorCode PetscMallocView(FILE *fp) { 85192f119d6SBarry Smith PetscInt i, j, n, *perm; 852e5c89e4eSSatish Balay size_t *shortlength; 853f56c2debSBarry Smith int *shortcount, err; 85492f119d6SBarry Smith PetscMPIInt rank; 855ace3abfcSBarry Smith PetscBool match; 856e5c89e4eSSatish Balay const char **shortfunction; 857e5c89e4eSSatish Balay PetscLogDouble rss; 858e5c89e4eSSatish Balay 859e5c89e4eSSatish Balay PetscFunctionBegin; 8609566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &rank)); 861f56c2debSBarry Smith err = fflush(fp); 86228b400f6SJacob Faibussowitsch PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file"); 863f56c2debSBarry Smith 86408401ef6SPierre Jolivet PetscCheck(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()"); 865768aa557SSatish Balay 866da9f1d6bSBarry Smith if (!fp) fp = PETSC_STDOUT; 8679566063dSJacob Faibussowitsch PetscCall(PetscMemoryGetMaximumUsage(&rss)); 868e5c89e4eSSatish Balay if (rss) { 86992f119d6SBarry Smith (void)fprintf(fp, "[%d] Maximum memory PetscMalloc()ed %.0f maximum size of entire process %.0f\n", rank, (PetscLogDouble)TRMaxMem, rss); 870e5c89e4eSSatish Balay } else { 87192f119d6SBarry Smith (void)fprintf(fp, "[%d] Maximum memory PetscMalloc()ed %.0f OS cannot compute size of entire process\n", rank, (PetscLogDouble)TRMaxMem); 872e5c89e4eSSatish Balay } 8739371c9d4SSatish Balay shortcount = (int *)malloc(PetscLogMalloc * sizeof(int)); 8749371c9d4SSatish Balay PetscCheck(shortcount, PETSC_COMM_SELF, PETSC_ERR_MEM, "Out of memory"); 8759371c9d4SSatish Balay shortlength = (size_t *)malloc(PetscLogMalloc * sizeof(size_t)); 8769371c9d4SSatish Balay PetscCheck(shortlength, PETSC_COMM_SELF, PETSC_ERR_MEM, "Out of memory"); 8779371c9d4SSatish Balay shortfunction = (const char **)malloc(PetscLogMalloc * sizeof(char *)); 8789371c9d4SSatish Balay PetscCheck(shortfunction, PETSC_COMM_SELF, PETSC_ERR_MEM, "Out of memory"); 87997b9d747SJed Brown for (i = 0, n = 0; i < PetscLogMalloc; i++) { 880e5c89e4eSSatish Balay for (j = 0; j < n; j++) { 8819566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(shortfunction[j], PetscLogMallocFunction[i], &match)); 882e5c89e4eSSatish Balay if (match) { 883e5c89e4eSSatish Balay shortlength[j] += PetscLogMallocLength[i]; 88459ffdab8SBarry Smith shortcount[j]++; 885e5c89e4eSSatish Balay goto foundit; 886e5c89e4eSSatish Balay } 887e5c89e4eSSatish Balay } 888e5c89e4eSSatish Balay shortfunction[n] = PetscLogMallocFunction[i]; 889e5c89e4eSSatish Balay shortlength[n] = PetscLogMallocLength[i]; 89059ffdab8SBarry Smith shortcount[n] = 1; 891e5c89e4eSSatish Balay n++; 892e5c89e4eSSatish Balay foundit:; 893e5c89e4eSSatish Balay } 894e5c89e4eSSatish Balay 8959371c9d4SSatish Balay perm = (PetscInt *)malloc(n * sizeof(PetscInt)); 8969371c9d4SSatish Balay PetscCheck(perm, PETSC_COMM_SELF, PETSC_ERR_MEM, "Out of memory"); 897e5c89e4eSSatish Balay for (i = 0; i < n; i++) perm[i] = i; 8989566063dSJacob Faibussowitsch PetscCall(PetscSortStrWithPermutation(n, (const char **)shortfunction, perm)); 899e5c89e4eSSatish Balay 90092f119d6SBarry Smith (void)fprintf(fp, "[%d] Memory usage sorted by function\n", rank); 901ad540459SPierre Jolivet for (i = 0; i < n; i++) (void)fprintf(fp, "[%d] %d %.0f %s()\n", rank, shortcount[perm[i]], (PetscLogDouble)shortlength[perm[i]], shortfunction[perm[i]]); 902e5c89e4eSSatish Balay free(perm); 903e5c89e4eSSatish Balay free(shortlength); 90459ffdab8SBarry Smith free(shortcount); 905e5c89e4eSSatish Balay free((char **)shortfunction); 906f56c2debSBarry Smith err = fflush(fp); 90728b400f6SJacob Faibussowitsch PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file"); 908e5c89e4eSSatish Balay PetscFunctionReturn(0); 909e5c89e4eSSatish Balay } 910e5c89e4eSSatish Balay 911e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------- */ 912e5c89e4eSSatish Balay 913dc37d89fSBarry Smith /*@ 91492f119d6SBarry Smith PetscMallocSetDebug - Set's PETSc memory debugging 915e5c89e4eSSatish Balay 916e5c89e4eSSatish Balay Not Collective 917e5c89e4eSSatish Balay 918d8d19677SJose E. Roman Input Parameters: 91992f119d6SBarry Smith + eachcall - checks the entire heap of allocated memory for issues on each call to PetscMalloc() and PetscFree() 9202d4ee042Sprj- - initializenan - initializes all memory with NaN to catch use of uninitialized floating point arrays 921e5c89e4eSSatish Balay 92292f119d6SBarry Smith Options Database: 92379dccf82SBarry Smith + -malloc_debug <true or false> - turns on or off debugging 92492f119d6SBarry Smith . -malloc_test - turns on all debugging if PETSc was configured with debugging including -malloc_dump, otherwise ignored 92579dccf82SBarry Smith . -malloc_view_threshold t - log only allocations larger than t 92692f119d6SBarry Smith . -malloc_dump <filename> - print a list of all memory that has not been freed 92779dccf82SBarry Smith . -malloc no - (deprecated) same as -malloc_debug no 92879dccf82SBarry Smith - -malloc_log - (deprecated) same as -malloc_view 929e5c89e4eSSatish Balay 93092f119d6SBarry Smith Level: developer 93192f119d6SBarry Smith 93292f119d6SBarry Smith Notes: This is called in PetscInitialize() and should not be called elsewhere 93392f119d6SBarry Smith 934db781477SPatrick Sanan .seealso: `CHKMEMQ()`, `PetscMallocValidate()`, `PetscMallocGetDebug()` 935e5c89e4eSSatish Balay @*/ 9369371c9d4SSatish Balay PetscErrorCode PetscMallocSetDebug(PetscBool eachcall, PetscBool initializenan) { 937e5c89e4eSSatish Balay PetscFunctionBegin; 93808401ef6SPierre Jolivet PetscCheck(PetscTrMalloc != PetscTrMallocDefault, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot call this routine more than once, it can only be called in PetscInitialize()"); 9399566063dSJacob Faibussowitsch PetscCall(PetscMallocSet(PetscTrMallocDefault, PetscTrFreeDefault, PetscTrReallocDefault)); 94092f119d6SBarry Smith 94192f119d6SBarry Smith TRallocated = 0; 94292f119d6SBarry Smith TRfrags = 0; 94392f119d6SBarry Smith TRhead = NULL; 94492f119d6SBarry Smith TRid = 0; 94592f119d6SBarry Smith TRdebugLevel = eachcall; 94692f119d6SBarry Smith TRMaxMem = 0; 94792f119d6SBarry Smith PetscLogMallocMax = 10000; 94892f119d6SBarry Smith PetscLogMalloc = -1; 9492d4ee042Sprj- TRdebugIinitializenan = initializenan; 950e5c89e4eSSatish Balay PetscFunctionReturn(0); 951e5c89e4eSSatish Balay } 9520acecf5bSBarry Smith 953dc37d89fSBarry Smith /*@ 95492f119d6SBarry Smith PetscMallocGetDebug - Indicates what PETSc memory debugging it is doing. 9550acecf5bSBarry Smith 9560acecf5bSBarry Smith Not Collective 9570acecf5bSBarry Smith 95892f119d6SBarry Smith Output Parameters: 95992f119d6SBarry Smith + basic - doing basic debugging 96092f119d6SBarry Smith . eachcall - checks the entire memory heap at each PetscMalloc()/PetscFree() 96179dccf82SBarry Smith - initializenan - initializes memory with NaN 9620acecf5bSBarry Smith 9630acecf5bSBarry Smith Level: intermediate 9640acecf5bSBarry Smith 96592f119d6SBarry Smith Notes: 96679dccf82SBarry Smith By default, the debug version always does some debugging unless you run with -malloc_debug no 9670acecf5bSBarry Smith 968db781477SPatrick Sanan .seealso: `CHKMEMQ()`, `PetscMallocValidate()`, `PetscMallocSetDebug()` 9690acecf5bSBarry Smith @*/ 9709371c9d4SSatish Balay PetscErrorCode PetscMallocGetDebug(PetscBool *basic, PetscBool *eachcall, PetscBool *initializenan) { 9710acecf5bSBarry Smith PetscFunctionBegin; 97279dccf82SBarry Smith if (basic) *basic = (PetscTrMalloc == PetscTrMallocDefault) ? PETSC_TRUE : PETSC_FALSE; 97379dccf82SBarry Smith if (eachcall) *eachcall = TRdebugLevel; 9742d4ee042Sprj- if (initializenan) *initializenan = TRdebugIinitializenan; 9750acecf5bSBarry Smith PetscFunctionReturn(0); 9760acecf5bSBarry Smith } 977608c71bfSMatthew G. Knepley 978608c71bfSMatthew G. Knepley /*@ 979608c71bfSMatthew G. Knepley PetscMallocLogRequestedSizeSet - Whether to log the requested or aligned memory size 980608c71bfSMatthew G. Knepley 981608c71bfSMatthew G. Knepley Not Collective 982608c71bfSMatthew G. Knepley 983608c71bfSMatthew G. Knepley Input Parameter: 984608c71bfSMatthew G. Knepley . flg - PETSC_TRUE to log the requested memory size 985608c71bfSMatthew G. Knepley 986608c71bfSMatthew G. Knepley Options Database: 987608c71bfSMatthew G. Knepley . -malloc_requested_size <bool> - Sets this flag 988608c71bfSMatthew G. Knepley 989608c71bfSMatthew G. Knepley Level: developer 990608c71bfSMatthew G. Knepley 991db781477SPatrick Sanan .seealso: `PetscMallocLogRequestedSizeGet()`, `PetscMallocViewSet()` 992608c71bfSMatthew G. Knepley @*/ 9939371c9d4SSatish Balay PetscErrorCode PetscMallocLogRequestedSizeSet(PetscBool flg) { 994608c71bfSMatthew G. Knepley PetscFunctionBegin; 995608c71bfSMatthew G. Knepley TRrequestedSize = flg; 996608c71bfSMatthew G. Knepley PetscFunctionReturn(0); 997608c71bfSMatthew G. Knepley } 998608c71bfSMatthew G. Knepley 999608c71bfSMatthew G. Knepley /*@ 1000608c71bfSMatthew G. Knepley PetscMallocLogRequestedSizeGet - Whether to log the requested or aligned memory size 1001608c71bfSMatthew G. Knepley 1002608c71bfSMatthew G. Knepley Not Collective 1003608c71bfSMatthew G. Knepley 1004608c71bfSMatthew G. Knepley Output Parameter: 1005608c71bfSMatthew G. Knepley . flg - PETSC_TRUE if we log the requested memory size 1006608c71bfSMatthew G. Knepley 1007608c71bfSMatthew G. Knepley Level: developer 1008608c71bfSMatthew G. Knepley 1009db781477SPatrick Sanan .seealso: `PetscMallocLogRequestedSizeSetinalSizeSet()`, `PetscMallocViewSet()` 1010608c71bfSMatthew G. Knepley @*/ 10119371c9d4SSatish Balay PetscErrorCode PetscMallocLogRequestedSizeGet(PetscBool *flg) { 1012608c71bfSMatthew G. Knepley PetscFunctionBegin; 1013608c71bfSMatthew G. Knepley *flg = TRrequestedSize; 1014608c71bfSMatthew G. Knepley PetscFunctionReturn(0); 1015608c71bfSMatthew G. Knepley } 1016