xref: /petsc/src/sys/memory/mtr.c (revision 79dccf82ad67fbc2ef5f84ff58416d96c239ff80) !
17d0a6c19SBarry Smith 
2e5c89e4eSSatish Balay /*
392f119d6SBarry Smith      Interface to malloc() and free(). This code allows for logging of memory usage and some error checking
4e5c89e4eSSatish Balay */
5c6db04a5SJed Brown #include <petscsys.h>           /*I "petscsys.h" I*/
6665c2dedSJed Brown #include <petscviewer.h>
7e5c89e4eSSatish Balay #if defined(PETSC_HAVE_MALLOC_H)
8e5c89e4eSSatish Balay #include <malloc.h>
9e5c89e4eSSatish Balay #endif
10e5c89e4eSSatish Balay 
11e5c89e4eSSatish Balay /*
12e5c89e4eSSatish Balay      These are defined in mal.c and ensure that malloced space is PetscScalar aligned
13e5c89e4eSSatish Balay */
14071fcb05SBarry Smith PETSC_EXTERN PetscErrorCode PetscMallocAlign(size_t,PetscBool,int,const char[],const char[],void**);
1595c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscFreeAlign(void*,int,const char[],const char[]);
1695c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscReallocAlign(size_t,int,const char[],const char[],void**);
17e5c89e4eSSatish Balay 
180700a824SBarry Smith #define CLASSID_VALUE  ((PetscClassId) 0xf0e0d0c9)
190700a824SBarry Smith #define ALREADY_FREED  ((PetscClassId) 0x0f0e0d9c)
20e5c89e4eSSatish Balay 
2192f119d6SBarry Smith /*  this is the header put at the beginning of each malloc() using for tracking allocated space and checking of allocated space heap */
22e5c89e4eSSatish Balay typedef struct _trSPACE {
23e5c89e4eSSatish Balay   size_t          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;
5492f119d6SBarry Smith static PetscBool TRdebugIintializenan = PETSC_FALSE;
55e5c89e4eSSatish Balay static size_t    TRMaxMem             = 0;
56e3ed9ee7SBarry Smith static int       NumTRMaxMems         = 0;
57e3ed9ee7SBarry Smith static size_t    TRMaxMems[MAXTRMAXMEMS];
58e3ed9ee7SBarry Smith static int       TRMaxMemsEvents[MAXTRMAXMEMS];
59e5c89e4eSSatish Balay /*
6092f119d6SBarry Smith       Arrays to log information on mallocs for PetscMallocView()
61e5c89e4eSSatish Balay */
62f0ba7cfcSLisandro Dalcin static int        PetscLogMallocMax       = 10000;
63f0ba7cfcSLisandro Dalcin static int        PetscLogMalloc          = -1;
64574034a9SJed Brown static size_t     PetscLogMallocThreshold = 0;
65e5c89e4eSSatish Balay static size_t     *PetscLogMallocLength;
66efca3c55SSatish Balay static const char **PetscLogMallocFile,**PetscLogMallocFunction;
67b022a5c1SBarry Smith 
68e5c89e4eSSatish Balay /*@C
6992f119d6SBarry Smith    PetscMallocValidate - Test the memory for corruption.  This can be called at any time between PetscInitialize() and PetscFinalize()
70e5c89e4eSSatish Balay 
7192f119d6SBarry Smith    Input Parameters:
72e5c89e4eSSatish Balay +  line - line number where call originated.
73e5c89e4eSSatish Balay .  function - name of function calling
74efca3c55SSatish Balay -  file - file where function is
75e5c89e4eSSatish Balay 
76e5c89e4eSSatish Balay    Return value:
77e5c89e4eSSatish Balay    The number of errors detected.
78e5c89e4eSSatish Balay 
7992f119d6SBarry Smith    Options Database:.
8092f119d6SBarry Smith +  -malloc_test - turns this feature on when PETSc was not configured with --with-debugging=0
8192f119d6SBarry Smith -  -malloc_debug - turns this feature on anytime
8292f119d6SBarry Smith 
83e5c89e4eSSatish Balay    Output Effect:
84e5c89e4eSSatish Balay    Error messages are written to stdout.
85e5c89e4eSSatish Balay 
86e5c89e4eSSatish Balay    Level: advanced
87e5c89e4eSSatish Balay 
88e5c89e4eSSatish Balay    Notes:
89*79dccf82SBarry 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)
9038548759SBarry Smith 
9192f119d6SBarry Smith     You should generally use CHKMEMQ as a short cut for calling this  routine.
92e5c89e4eSSatish Balay 
93e5c89e4eSSatish Balay     The Fortran calling sequence is simply PetscMallocValidate(ierr)
94e5c89e4eSSatish Balay 
95e5c89e4eSSatish Balay    No output is generated if there are no problems detected.
96e5c89e4eSSatish Balay 
9792f119d6SBarry Smith    Developers Note:
9892f119d6SBarry Smith      Uses the flg TRdebugLevel (set as the first argument to PetscMallocSetDebug()) to determine if it should run
9992f119d6SBarry Smith 
100e5c89e4eSSatish Balay .seealso: CHKMEMQ
101e5c89e4eSSatish Balay 
102e5c89e4eSSatish Balay @*/
103efca3c55SSatish Balay PetscErrorCode  PetscMallocValidate(int line,const char function[],const char file[])
104e5c89e4eSSatish Balay {
1056c093d5bSvictor   TRSPACE      *head,*lasthead;
106e5c89e4eSSatish Balay   char         *a;
1070700a824SBarry Smith   PetscClassId *nend;
108e5c89e4eSSatish Balay 
10938548759SBarry Smith   if (!TRdebugLevel) return 0;
110e5c89e4eSSatish Balay   PetscFunctionBegin;
1116c093d5bSvictor   head = TRhead; lasthead = NULL;
112e5c89e4eSSatish Balay   while (head) {
1130700a824SBarry Smith     if (head->classid != CLASSID_VALUE) {
114efca3c55SSatish Balay       (*PetscErrorPrintf)("PetscMallocValidate: error detected at  %s() line %d in %s\n",function,line,file);
115e5c89e4eSSatish Balay       (*PetscErrorPrintf)("Memory at address %p is corrupted\n",head);
116e5c89e4eSSatish Balay       (*PetscErrorPrintf)("Probably write past beginning or end of array\n");
117efca3c55SSatish Balay       if (lasthead) (*PetscErrorPrintf)("Last intact block allocated in %s() line %d in %s\n",lasthead->functionname,lasthead->lineno,lasthead->filename);
118e32f2f54SBarry Smith       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," ");
119e5c89e4eSSatish Balay     }
120e5c89e4eSSatish Balay     a    = (char*)(((TrSPACE*)head) + 1);
1210700a824SBarry Smith     nend = (PetscClassId*)(a + head->size);
1220700a824SBarry Smith     if (*nend != CLASSID_VALUE) {
123efca3c55SSatish Balay       (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s\n",function,line,file);
124e5c89e4eSSatish Balay       if (*nend == ALREADY_FREED) {
125e5c89e4eSSatish Balay         (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p already freed\n",head->id,(PetscLogDouble)head->size,a);
126e32f2f54SBarry Smith         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," ");
127e5c89e4eSSatish Balay       } else {
128e5c89e4eSSatish Balay         (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a);
129efca3c55SSatish Balay         (*PetscErrorPrintf)("Memory originally allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename);
130e32f2f54SBarry Smith         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC," ");
131e5c89e4eSSatish Balay       }
132e5c89e4eSSatish Balay     }
1336c093d5bSvictor     lasthead = head;
134e5c89e4eSSatish Balay     head     = head->next;
135e5c89e4eSSatish Balay   }
136e5c89e4eSSatish Balay   PetscFunctionReturn(0);
137e5c89e4eSSatish Balay }
138e5c89e4eSSatish Balay 
139e5c89e4eSSatish Balay /*
140e5c89e4eSSatish Balay     PetscTrMallocDefault - Malloc with tracing.
141e5c89e4eSSatish Balay 
142e5c89e4eSSatish Balay     Input Parameters:
143e5c89e4eSSatish Balay +   a   - number of bytes to allocate
144e5c89e4eSSatish Balay .   lineno - line number where used.  Use __LINE__ for this
145efca3c55SSatish Balay -   filename  - file name where used.  Use __FILE__ for this
146e5c89e4eSSatish Balay 
147e5c89e4eSSatish Balay     Returns:
14892f119d6SBarry Smith     double aligned pointer to requested storage, or null if not  available.
149e5c89e4eSSatish Balay  */
150071fcb05SBarry Smith PetscErrorCode  PetscTrMallocDefault(size_t a,PetscBool clear,int lineno,const char function[],const char filename[],void **result)
151e5c89e4eSSatish Balay {
152e5c89e4eSSatish Balay   TRSPACE        *head;
153e5c89e4eSSatish Balay   char           *inew;
154e5c89e4eSSatish Balay   size_t         nsize;
155e5c89e4eSSatish Balay   PetscErrorCode ierr;
156e5c89e4eSSatish Balay 
157e5c89e4eSSatish Balay   PetscFunctionBegin;
158f0ba7cfcSLisandro Dalcin   /* Do not try to handle empty blocks */
159f0ba7cfcSLisandro Dalcin   if (!a) { *result = NULL; PetscFunctionReturn(0); }
160f0ba7cfcSLisandro Dalcin 
161efca3c55SSatish Balay   ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr);
162e5c89e4eSSatish Balay 
16325b53cc9SJed Brown   nsize = (a + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1);
164071fcb05SBarry Smith   ierr  = PetscMallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),clear,lineno,function,filename,(void**)&inew);CHKERRQ(ierr);
165e3ed9ee7SBarry Smith 
166e5c89e4eSSatish Balay   head  = (TRSPACE*)inew;
167e5c89e4eSSatish Balay   inew += sizeof(TrSPACE);
168e5c89e4eSSatish Balay 
169e5c89e4eSSatish Balay   if (TRhead) TRhead->prev = head;
170e5c89e4eSSatish Balay   head->next   = TRhead;
171e5c89e4eSSatish Balay   TRhead       = head;
172f0ba7cfcSLisandro Dalcin   head->prev   = NULL;
173e5c89e4eSSatish Balay   head->size   = nsize;
174e5c89e4eSSatish Balay   head->id     = TRid;
175e5c89e4eSSatish Balay   head->lineno = lineno;
176e5c89e4eSSatish Balay 
177e5c89e4eSSatish Balay   head->filename                 = filename;
178e5c89e4eSSatish Balay   head->functionname             = function;
1790700a824SBarry Smith   head->classid                  = CLASSID_VALUE;
1800700a824SBarry Smith   *(PetscClassId*)(inew + nsize) = CLASSID_VALUE;
181e5c89e4eSSatish Balay 
182e5c89e4eSSatish Balay   TRallocated += nsize;
183a297a907SKarl Rupp   if (TRallocated > TRMaxMem) TRMaxMem = TRallocated;
184e3ed9ee7SBarry Smith   if (PetscLogMemory) {
185e3ed9ee7SBarry Smith     PetscInt i;
186e3ed9ee7SBarry Smith     for (i=0; i<NumTRMaxMems; i++) {
187e3ed9ee7SBarry Smith       if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated;
188e3ed9ee7SBarry Smith     }
189e3ed9ee7SBarry Smith   }
190e5c89e4eSSatish Balay   TRfrags++;
191e5c89e4eSSatish Balay 
1928bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG)
19376386721SLisandro Dalcin   if (PetscStackActive()) {
1945c25fcd7SBarry Smith     ierr = PetscStackCopy(petscstack,&head->stack);CHKERRQ(ierr);
1952c9581d2SBarry Smith     /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */
1962c9581d2SBarry Smith     head->stack.line[head->stack.currentsize-2] = lineno;
1979de0f6ecSBarry Smith   } else {
1989de0f6ecSBarry Smith     head->stack.currentsize = 0;
19976386721SLisandro Dalcin   }
20092f119d6SBarry Smith #if defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL_DOUBLE)
20192f119d6SBarry Smith   if (!clear && TRdebugIintializenan) {
20292f119d6SBarry Smith     size_t     i, n = a/sizeof(PetscReal);
20392f119d6SBarry Smith     PetscReal *s = (PetscReal*) inew;
20492f119d6SBarry Smith     /* from https://www.doc.ic.ac.uk/~eedwards/compsys/float/nan.html */
20592f119d6SBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
206df282883SBarry Smith     int        nas = 0x7F800002;
20792f119d6SBarry Smith #else
20892f119d6SBarry Smith     PetscInt64 nas = 0x7FF0000000000002;
20992f119d6SBarry Smith #endif
21092f119d6SBarry Smith     for (i=0; i<n; i++) {
21192f119d6SBarry Smith       memcpy(s+i,&nas,sizeof(PetscReal));
21292f119d6SBarry Smith     }
21392f119d6SBarry Smith   }
21492f119d6SBarry Smith #endif
215e5c89e4eSSatish Balay #endif
216e5c89e4eSSatish Balay 
217e5c89e4eSSatish Balay   /*
21892f119d6SBarry Smith          Allow logging of all mallocs made.
21992f119d6SBarry Smith          TODO: Currently this memory is never freed, it should be freed during PetscFinalize()
220e5c89e4eSSatish Balay   */
221574034a9SJed Brown   if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && a >= PetscLogMallocThreshold) {
222e5c89e4eSSatish Balay     if (!PetscLogMalloc) {
223e5c89e4eSSatish Balay       PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t));
224e32f2f54SBarry Smith       if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," ");
225a297a907SKarl Rupp 
226a2ea699eSBarry Smith       PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*));
227e32f2f54SBarry Smith       if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," ");
228a297a907SKarl Rupp 
229a2ea699eSBarry Smith       PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*));
230e32f2f54SBarry Smith       if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," ");
231e5c89e4eSSatish Balay     }
232e5c89e4eSSatish Balay     PetscLogMallocLength[PetscLogMalloc]     = nsize;
233e5c89e4eSSatish Balay     PetscLogMallocFile[PetscLogMalloc]       = filename;
234e5c89e4eSSatish Balay     PetscLogMallocFunction[PetscLogMalloc++] = function;
235e5c89e4eSSatish Balay   }
236e5c89e4eSSatish Balay   *result = (void*)inew;
237e5c89e4eSSatish Balay   PetscFunctionReturn(0);
238e5c89e4eSSatish Balay }
239e5c89e4eSSatish Balay 
240e5c89e4eSSatish Balay /*
241e5c89e4eSSatish Balay    PetscTrFreeDefault - Free with tracing.
242e5c89e4eSSatish Balay 
243e5c89e4eSSatish Balay    Input Parameters:
244e5c89e4eSSatish Balay .   a    - pointer to a block allocated with PetscTrMalloc
245e5c89e4eSSatish Balay .   lineno - line number where used.  Use __LINE__ for this
246e5c89e4eSSatish Balay .   file  - file name where used.  Use __FILE__ for this
247e5c89e4eSSatish Balay  */
248efca3c55SSatish Balay PetscErrorCode  PetscTrFreeDefault(void *aa,int line,const char function[],const char file[])
249e5c89e4eSSatish Balay {
250e5c89e4eSSatish Balay   char           *a = (char*)aa;
251e5c89e4eSSatish Balay   TRSPACE        *head;
252e5c89e4eSSatish Balay   char           *ahead;
253e5c89e4eSSatish Balay   PetscErrorCode ierr;
2540700a824SBarry Smith   PetscClassId   *nend;
255e5c89e4eSSatish Balay 
256e5c89e4eSSatish Balay   PetscFunctionBegin;
257e5c89e4eSSatish Balay   /* Do not try to handle empty blocks */
25849d7da52SJed Brown   if (!a) PetscFunctionReturn(0);
259e5c89e4eSSatish Balay 
260efca3c55SSatish Balay   ierr = PetscMallocValidate(line,function,file);CHKERRQ(ierr);
261e5c89e4eSSatish Balay 
262e5c89e4eSSatish Balay   ahead = a;
263e5c89e4eSSatish Balay   a     = a - sizeof(TrSPACE);
264e5c89e4eSSatish Balay   head  = (TRSPACE*)a;
265e5c89e4eSSatish Balay 
2660700a824SBarry Smith   if (head->classid != CLASSID_VALUE) {
267efca3c55SSatish Balay     (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file);
268e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a);
269e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory");
270e5c89e4eSSatish Balay   }
2710700a824SBarry Smith   nend = (PetscClassId*)(ahead + head->size);
2720700a824SBarry Smith   if (*nend != CLASSID_VALUE) {
273e5c89e4eSSatish Balay     if (*nend == ALREADY_FREED) {
274efca3c55SSatish Balay       (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file);
275e5c89e4eSSatish Balay       (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE));
276e5c89e4eSSatish Balay       if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) {
277efca3c55SSatish Balay         (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename);
278e5c89e4eSSatish Balay       } else {
279efca3c55SSatish Balay         (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename);
280e5c89e4eSSatish Balay       }
281e32f2f54SBarry Smith       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed");
282e5c89e4eSSatish Balay     } else {
283e5c89e4eSSatish Balay       /* Damaged tail */
284efca3c55SSatish Balay       (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file);
285e5c89e4eSSatish Balay       (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a);
286efca3c55SSatish Balay       (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename);
287e32f2f54SBarry Smith       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory");
288e5c89e4eSSatish Balay     }
289e5c89e4eSSatish Balay   }
290e5c89e4eSSatish Balay   /* Mark the location freed */
291e5c89e4eSSatish Balay   *nend = ALREADY_FREED;
292e5c89e4eSSatish Balay   /* Save location where freed.  If we suspect the line number, mark as  allocated location */
293e5c89e4eSSatish Balay   if (line > 0 && line < 50000) {
294e5c89e4eSSatish Balay     head->lineno       = line;
295e5c89e4eSSatish Balay     head->filename     = file;
296e5c89e4eSSatish Balay     head->functionname = function;
297e5c89e4eSSatish Balay   } else {
298e5c89e4eSSatish Balay     head->lineno = -head->lineno;
299e5c89e4eSSatish Balay   }
300e3ed9ee7SBarry Smith   if (TRallocated < head->size) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"TRallocate is smaller than memory just freed");
301e5c89e4eSSatish Balay   TRallocated -= head->size;
302e5c89e4eSSatish Balay   TRfrags--;
303e5c89e4eSSatish Balay   if (head->prev) head->prev->next = head->next;
304e5c89e4eSSatish Balay   else TRhead = head->next;
305e5c89e4eSSatish Balay 
306e5c89e4eSSatish Balay   if (head->next) head->next->prev = head->prev;
307efca3c55SSatish Balay   ierr = PetscFreeAlign(a,line,function,file);CHKERRQ(ierr);
308e5c89e4eSSatish Balay   PetscFunctionReturn(0);
309e5c89e4eSSatish Balay }
310e5c89e4eSSatish Balay 
3113221ece2SMatthew G. Knepley /*
3123221ece2SMatthew G. Knepley   PetscTrReallocDefault - Realloc with tracing.
3133221ece2SMatthew G. Knepley 
3143221ece2SMatthew G. Knepley   Input Parameters:
3153221ece2SMatthew G. Knepley + len      - number of bytes to allocate
3163221ece2SMatthew G. Knepley . lineno   - line number where used.  Use __LINE__ for this
3173221ece2SMatthew G. Knepley . filename - file name where used.  Use __FILE__ for this
31892f119d6SBarry Smith - result - original memory
3193221ece2SMatthew G. Knepley 
3203221ece2SMatthew G. Knepley   Output Parameter:
3213221ece2SMatthew G. Knepley . result - double aligned pointer to requested storage, or null if not available.
3223221ece2SMatthew G. Knepley 
3233221ece2SMatthew G. Knepley   Level: developer
3243221ece2SMatthew G. Knepley 
3253221ece2SMatthew G. Knepley .seealso: PetscTrMallocDefault(), PetscTrFreeDefault()
3263221ece2SMatthew G. Knepley */
3273221ece2SMatthew G. Knepley PetscErrorCode PetscTrReallocDefault(size_t len, int lineno, const char function[], const char filename[], void **result)
3283221ece2SMatthew G. Knepley {
3293221ece2SMatthew G. Knepley   char           *a = (char *) *result;
3303221ece2SMatthew G. Knepley   TRSPACE        *head;
3313221ece2SMatthew G. Knepley   char           *ahead, *inew;
3323221ece2SMatthew G. Knepley   PetscClassId   *nend;
3333221ece2SMatthew G. Knepley   size_t         nsize;
3343221ece2SMatthew G. Knepley   PetscErrorCode ierr;
3353221ece2SMatthew G. Knepley 
3363221ece2SMatthew G. Knepley   PetscFunctionBegin;
33792f119d6SBarry Smith   /* Realloc requests zero space so just free the current space */
338c22f1541SToby Isaac   if (!len) {
339c22f1541SToby Isaac     ierr = PetscTrFreeDefault(*result,lineno,function,filename);CHKERRQ(ierr);
340c22f1541SToby Isaac     *result = NULL;
341c22f1541SToby Isaac     PetscFunctionReturn(0);
342c22f1541SToby Isaac   }
34392f119d6SBarry Smith   /* If the orginal space was NULL just use the regular malloc() */
344f590eff4SLisandro Dalcin   if (!*result) {
345071fcb05SBarry Smith     ierr = PetscTrMallocDefault(len,PETSC_FALSE,lineno,function,filename,result);CHKERRQ(ierr);
346f590eff4SLisandro Dalcin     PetscFunctionReturn(0);
347f590eff4SLisandro Dalcin   }
3483221ece2SMatthew G. Knepley 
34938548759SBarry Smith   ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr);
3503221ece2SMatthew G. Knepley 
3513221ece2SMatthew G. Knepley   ahead = a;
3523221ece2SMatthew G. Knepley   a     = a - sizeof(TrSPACE);
3533221ece2SMatthew G. Knepley   head  = (TRSPACE *) a;
3543221ece2SMatthew G. Knepley   inew  = a;
3553221ece2SMatthew G. Knepley 
3563221ece2SMatthew G. Knepley   if (head->classid != CLASSID_VALUE) {
3573221ece2SMatthew G. Knepley     (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename);
3583221ece2SMatthew G. Knepley     (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a);
3593221ece2SMatthew G. Knepley     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory");
3603221ece2SMatthew G. Knepley   }
3613221ece2SMatthew G. Knepley   nend = (PetscClassId *)(ahead + head->size);
3623221ece2SMatthew G. Knepley   if (*nend != CLASSID_VALUE) {
3633221ece2SMatthew G. Knepley     if (*nend == ALREADY_FREED) {
3643221ece2SMatthew G. Knepley       (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename);
3653221ece2SMatthew G. Knepley       (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE));
3663221ece2SMatthew G. Knepley       if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) {
3673221ece2SMatthew G. Knepley         (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename);
3683221ece2SMatthew G. Knepley       } else {
3693221ece2SMatthew G. Knepley         (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename);
3703221ece2SMatthew G. Knepley       }
3713221ece2SMatthew G. Knepley       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed");
3723221ece2SMatthew G. Knepley     } else {
3733221ece2SMatthew G. Knepley       /* Damaged tail */
3743221ece2SMatthew G. Knepley       (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() line %d in %s\n",function,lineno,filename);
3753221ece2SMatthew 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);
3763221ece2SMatthew G. Knepley       (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename);
3773221ece2SMatthew G. Knepley       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory");
3783221ece2SMatthew G. Knepley     }
3793221ece2SMatthew G. Knepley   }
3803221ece2SMatthew G. Knepley 
38192f119d6SBarry Smith   /* remove original reference to the memory allocated from the PETSc debugging heap */
3823221ece2SMatthew G. Knepley   TRallocated -= head->size;
3833221ece2SMatthew G. Knepley   TRfrags--;
3843221ece2SMatthew G. Knepley   if (head->prev) head->prev->next = head->next;
3853221ece2SMatthew G. Knepley   else TRhead = head->next;
3863221ece2SMatthew G. Knepley   if (head->next) head->next->prev = head->prev;
3873221ece2SMatthew G. Knepley 
3883221ece2SMatthew G. Knepley   nsize = (len + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1);
3893221ece2SMatthew G. Knepley   ierr  = PetscReallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),lineno,function,filename,(void**)&inew);CHKERRQ(ierr);
3903221ece2SMatthew G. Knepley 
3913221ece2SMatthew G. Knepley   head  = (TRSPACE*)inew;
3923221ece2SMatthew G. Knepley   inew += sizeof(TrSPACE);
3933221ece2SMatthew G. Knepley 
3943221ece2SMatthew G. Knepley   if (TRhead) TRhead->prev = head;
3953221ece2SMatthew G. Knepley   head->next   = TRhead;
3963221ece2SMatthew G. Knepley   TRhead       = head;
3973221ece2SMatthew G. Knepley   head->prev   = NULL;
3983221ece2SMatthew G. Knepley   head->size   = nsize;
3993221ece2SMatthew G. Knepley   head->id     = TRid;
4003221ece2SMatthew G. Knepley   head->lineno = lineno;
4013221ece2SMatthew G. Knepley 
4023221ece2SMatthew G. Knepley   head->filename                 = filename;
4033221ece2SMatthew G. Knepley   head->functionname             = function;
4043221ece2SMatthew G. Knepley   head->classid                  = CLASSID_VALUE;
4053221ece2SMatthew G. Knepley   *(PetscClassId*)(inew + nsize) = CLASSID_VALUE;
4063221ece2SMatthew G. Knepley 
4073221ece2SMatthew G. Knepley   TRallocated += nsize;
4083221ece2SMatthew G. Knepley   if (TRallocated > TRMaxMem) TRMaxMem = TRallocated;
409e3ed9ee7SBarry Smith   if (PetscLogMemory) {
410e3ed9ee7SBarry Smith     PetscInt i;
411e3ed9ee7SBarry Smith     for (i=0; i<NumTRMaxMems; i++) {
412e3ed9ee7SBarry Smith       if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated;
413e3ed9ee7SBarry Smith     }
414e3ed9ee7SBarry Smith   }
4153221ece2SMatthew G. Knepley   TRfrags++;
4163221ece2SMatthew G. Knepley 
4173221ece2SMatthew G. Knepley #if defined(PETSC_USE_DEBUG)
4183221ece2SMatthew G. Knepley   if (PetscStackActive()) {
4193221ece2SMatthew G. Knepley     ierr = PetscStackCopy(petscstack,&head->stack);CHKERRQ(ierr);
4203221ece2SMatthew G. Knepley     /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */
4213221ece2SMatthew G. Knepley     head->stack.line[head->stack.currentsize-2] = lineno;
4223221ece2SMatthew G. Knepley   } else {
4233221ece2SMatthew G. Knepley     head->stack.currentsize = 0;
4243221ece2SMatthew G. Knepley   }
4253221ece2SMatthew G. Knepley #endif
4263221ece2SMatthew G. Knepley 
4273221ece2SMatthew G. Knepley   /*
42892f119d6SBarry Smith          Allow logging of all mallocs made. This adds a new entry to the list of allocated memory
42992f119d6SBarry Smith          and does not remove the previous entry to the list hence this memory is "double counted" in PetscMallocView()
4303221ece2SMatthew G. Knepley   */
4313221ece2SMatthew G. Knepley   if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && len >= PetscLogMallocThreshold) {
4323221ece2SMatthew G. Knepley     if (!PetscLogMalloc) {
4333221ece2SMatthew G. Knepley       PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t));
4343221ece2SMatthew G. Knepley       if (!PetscLogMallocLength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," ");
4353221ece2SMatthew G. Knepley 
4363221ece2SMatthew G. Knepley       PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*));
4373221ece2SMatthew G. Knepley       if (!PetscLogMallocFile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," ");
4383221ece2SMatthew G. Knepley 
4393221ece2SMatthew G. Knepley       PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*));
4403221ece2SMatthew G. Knepley       if (!PetscLogMallocFunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM," ");
4413221ece2SMatthew G. Knepley     }
4423221ece2SMatthew G. Knepley     PetscLogMallocLength[PetscLogMalloc]     = nsize;
4433221ece2SMatthew G. Knepley     PetscLogMallocFile[PetscLogMalloc]       = filename;
4443221ece2SMatthew G. Knepley     PetscLogMallocFunction[PetscLogMalloc++] = function;
4453221ece2SMatthew G. Knepley   }
4463221ece2SMatthew G. Knepley   *result = (void*)inew;
4473221ece2SMatthew G. Knepley   PetscFunctionReturn(0);
4483221ece2SMatthew G. Knepley }
4493221ece2SMatthew G. Knepley 
450fe7fb379SMatthew Knepley /*@C
45192f119d6SBarry Smith     PetscMemoryView - Shows the amount of memory currently being used in a communicator.
452e5c89e4eSSatish Balay 
453e5c89e4eSSatish Balay     Collective on PetscViewer
454e5c89e4eSSatish Balay 
455e5c89e4eSSatish Balay     Input Parameter:
456e5c89e4eSSatish Balay +    viewer - the viewer that defines the communicator
457e5c89e4eSSatish Balay -    message - string printed before values
458e5c89e4eSSatish Balay 
4590841954dSBarry Smith     Options Database:
46092f119d6SBarry Smith +    -malloc_debug - have PETSc track how much memory it has allocated
4610841954dSBarry Smith -    -memory_view - during PetscFinalize() have this routine called
4620841954dSBarry Smith 
463e5c89e4eSSatish Balay     Level: intermediate
464e5c89e4eSSatish Balay 
46592f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMemoryGetCurrentUsage(), PetscMemorySetGetMaximumUsage(), PetscMallocView()
466e5c89e4eSSatish Balay  @*/
4670841954dSBarry Smith PetscErrorCode  PetscMemoryView(PetscViewer viewer,const char message[])
468e5c89e4eSSatish Balay {
4690841954dSBarry Smith   PetscLogDouble allocated,allocatedmax,resident,residentmax,gallocated,gallocatedmax,gresident,gresidentmax,maxgallocated,maxgallocatedmax,maxgresident,maxgresidentmax;
4700841954dSBarry Smith   PetscLogDouble mingallocated,mingallocatedmax,mingresident,mingresidentmax;
471e5c89e4eSSatish Balay   PetscErrorCode ierr;
472e5c89e4eSSatish Balay   MPI_Comm       comm;
473e5c89e4eSSatish Balay 
474e5c89e4eSSatish Balay   PetscFunctionBegin;
475e5c89e4eSSatish Balay   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
476e5c89e4eSSatish Balay   ierr = PetscMallocGetCurrentUsage(&allocated);CHKERRQ(ierr);
4770841954dSBarry Smith   ierr = PetscMallocGetMaximumUsage(&allocatedmax);CHKERRQ(ierr);
478e5c89e4eSSatish Balay   ierr = PetscMemoryGetCurrentUsage(&resident);CHKERRQ(ierr);
479e5c89e4eSSatish Balay   ierr = PetscMemoryGetMaximumUsage(&residentmax);CHKERRQ(ierr);
480e5c89e4eSSatish Balay   if (residentmax > 0) residentmax = PetscMax(resident,residentmax);
481e5c89e4eSSatish Balay   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
482e5c89e4eSSatish Balay   ierr = PetscViewerASCIIPrintf(viewer,message);CHKERRQ(ierr);
483e5c89e4eSSatish Balay   if (resident && residentmax && allocated) {
4840841954dSBarry Smith     ierr = MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr);
4850841954dSBarry Smith     ierr = MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr);
4860841954dSBarry Smith     ierr = MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr);
4870841954dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Maximum (over computational time) process memory:        total %5.4e max %5.4e min %5.4e\n",gresidentmax,maxgresidentmax,mingresidentmax);CHKERRQ(ierr);
4880841954dSBarry Smith     ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr);
4890841954dSBarry Smith     ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr);
4900841954dSBarry Smith     ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr);
4910841954dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Current process memory:                                  total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr);
4920841954dSBarry Smith     ierr = MPI_Reduce(&allocatedmax,&gallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr);
4930841954dSBarry Smith     ierr = MPI_Reduce(&allocatedmax,&maxgallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr);
4940841954dSBarry Smith     ierr = MPI_Reduce(&allocatedmax,&mingallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr);
4950841954dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Maximum (over computational time) space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocatedmax,maxgallocatedmax,mingallocatedmax);CHKERRQ(ierr);
4960841954dSBarry Smith     ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr);
4970841954dSBarry Smith     ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr);
4980841954dSBarry Smith     ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr);
4990841954dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed:                           total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr);
500e5c89e4eSSatish Balay   } else if (resident && residentmax) {
5010841954dSBarry Smith     ierr = MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr);
5020841954dSBarry Smith     ierr = MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr);
5030841954dSBarry Smith     ierr = MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr);
5040841954dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Maximum (over computational time) process memory:        total %5.4e max %5.4e min %5.4e\n",gresidentmax,maxgresidentmax,mingresidentmax);CHKERRQ(ierr);
5050841954dSBarry Smith     ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr);
5060841954dSBarry Smith     ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr);
5070841954dSBarry Smith     ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr);
5080841954dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Current process memory:                                  total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr);
509e5c89e4eSSatish Balay   } else if (resident && allocated) {
5100841954dSBarry Smith     ierr = MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr);
5110841954dSBarry Smith     ierr = MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr);
5120841954dSBarry Smith     ierr = MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr);
5130841954dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Current process memory:                                  total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident);CHKERRQ(ierr);
5140841954dSBarry Smith     ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr);
5150841954dSBarry Smith     ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr);
5160841954dSBarry Smith     ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr);
5170841954dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed:                           total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr);
5180841954dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n");CHKERRQ(ierr);
519e5c89e4eSSatish Balay   } else if (allocated) {
5200841954dSBarry Smith     ierr = MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm);CHKERRQ(ierr);
5210841954dSBarry Smith     ierr = MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm);CHKERRQ(ierr);
5220841954dSBarry Smith     ierr = MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm);CHKERRQ(ierr);
5230841954dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed:                           total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated);CHKERRQ(ierr);
5240841954dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n");CHKERRQ(ierr);
5250841954dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"OS cannot compute process memory\n");CHKERRQ(ierr);
526e5c89e4eSSatish Balay   } else {
52792f119d6SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Run with -malloc_debug to get statistics on PetscMalloc() calls\nOS cannot compute process memory\n");CHKERRQ(ierr);
528e5c89e4eSSatish Balay   }
529e5c89e4eSSatish Balay   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
530e5c89e4eSSatish Balay   PetscFunctionReturn(0);
531e5c89e4eSSatish Balay }
532e5c89e4eSSatish Balay 
53346eb3923SBarry Smith /*@
534e5c89e4eSSatish Balay     PetscMallocGetCurrentUsage - gets the current amount of memory used that was PetscMalloc()ed
535e5c89e4eSSatish Balay 
536e5c89e4eSSatish Balay     Not Collective
537e5c89e4eSSatish Balay 
538e5c89e4eSSatish Balay     Output Parameters:
539e5c89e4eSSatish Balay .   space - number of bytes currently allocated
540e5c89e4eSSatish Balay 
541e5c89e4eSSatish Balay     Level: intermediate
542e5c89e4eSSatish Balay 
54392f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocLog(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(),
544e5c89e4eSSatish Balay           PetscMemoryGetMaximumUsage()
545e5c89e4eSSatish Balay  @*/
5467087cfbeSBarry Smith PetscErrorCode  PetscMallocGetCurrentUsage(PetscLogDouble *space)
547e5c89e4eSSatish Balay {
548e5c89e4eSSatish Balay   PetscFunctionBegin;
549e5c89e4eSSatish Balay   *space = (PetscLogDouble) TRallocated;
550e5c89e4eSSatish Balay   PetscFunctionReturn(0);
551e5c89e4eSSatish Balay }
552e5c89e4eSSatish Balay 
553dc37d89fSBarry Smith /*@
554e5c89e4eSSatish Balay     PetscMallocGetMaximumUsage - gets the maximum amount of memory used that was PetscMalloc()ed at any time
555e5c89e4eSSatish Balay         during this run.
556e5c89e4eSSatish Balay 
557e5c89e4eSSatish Balay     Not Collective
558e5c89e4eSSatish Balay 
559e5c89e4eSSatish Balay     Output Parameters:
560e5c89e4eSSatish Balay .   space - maximum number of bytes ever allocated at one time
561e5c89e4eSSatish Balay 
562e5c89e4eSSatish Balay     Level: intermediate
563e5c89e4eSSatish Balay 
56492f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(),
565e3ed9ee7SBarry Smith           PetscMallocPushMaximumUsage()
566e5c89e4eSSatish Balay  @*/
5677087cfbeSBarry Smith PetscErrorCode  PetscMallocGetMaximumUsage(PetscLogDouble *space)
568e5c89e4eSSatish Balay {
569e5c89e4eSSatish Balay   PetscFunctionBegin;
570e5c89e4eSSatish Balay   *space = (PetscLogDouble) TRMaxMem;
571e5c89e4eSSatish Balay   PetscFunctionReturn(0);
572e5c89e4eSSatish Balay }
573e5c89e4eSSatish Balay 
574e3ed9ee7SBarry Smith /*@
575e3ed9ee7SBarry Smith     PetscMallocPushMaximumUsage - Adds another event to collect the maximum memory usage over an event
576e3ed9ee7SBarry Smith 
577e3ed9ee7SBarry Smith     Not Collective
578e3ed9ee7SBarry Smith 
579e3ed9ee7SBarry Smith     Input Parameter:
580e3ed9ee7SBarry Smith .   event - an event id; this is just for error checking
581e3ed9ee7SBarry Smith 
582e3ed9ee7SBarry Smith     Level: developer
583e3ed9ee7SBarry Smith 
58492f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(),
585e3ed9ee7SBarry Smith           PetscMallocPopMaximumUsage()
586e3ed9ee7SBarry Smith  @*/
587e3ed9ee7SBarry Smith PetscErrorCode  PetscMallocPushMaximumUsage(int event)
588e3ed9ee7SBarry Smith {
589e3ed9ee7SBarry Smith   PetscFunctionBegin;
590e3ed9ee7SBarry Smith   if (++NumTRMaxMems > MAXTRMAXMEMS) PetscFunctionReturn(0);
591e3ed9ee7SBarry Smith   TRMaxMems[NumTRMaxMems-1]       = TRallocated;
592e3ed9ee7SBarry Smith   TRMaxMemsEvents[NumTRMaxMems-1] = event;
593e3ed9ee7SBarry Smith   PetscFunctionReturn(0);
594e3ed9ee7SBarry Smith }
595e3ed9ee7SBarry Smith 
596e3ed9ee7SBarry Smith /*@
597e3ed9ee7SBarry Smith     PetscMallocPopMaximumUsage - collect the maximum memory usage over an event
598e3ed9ee7SBarry Smith 
599e3ed9ee7SBarry Smith     Not Collective
600e3ed9ee7SBarry Smith 
601e3ed9ee7SBarry Smith     Input Parameter:
602e3ed9ee7SBarry Smith .   event - an event id; this is just for error checking
603e3ed9ee7SBarry Smith 
604e3ed9ee7SBarry Smith     Output Parameter:
605e3ed9ee7SBarry Smith .   mu - maximum amount of memory malloced during this event; high water mark relative to the beginning of the event
606e3ed9ee7SBarry Smith 
607e3ed9ee7SBarry Smith     Level: developer
608e3ed9ee7SBarry Smith 
60992f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(),
610e3ed9ee7SBarry Smith           PetscMallocPushMaximumUsage()
611e3ed9ee7SBarry Smith  @*/
612e3ed9ee7SBarry Smith PetscErrorCode  PetscMallocPopMaximumUsage(int event,PetscLogDouble *mu)
613e3ed9ee7SBarry Smith {
614e3ed9ee7SBarry Smith   PetscFunctionBegin;
615e3ed9ee7SBarry Smith   *mu = 0;
616e3ed9ee7SBarry Smith   if (NumTRMaxMems-- > MAXTRMAXMEMS) PetscFunctionReturn(0);
617e3ed9ee7SBarry Smith   if (TRMaxMemsEvents[NumTRMaxMems] != event) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"PetscMallocPush/PopMaximumUsage() are not nested");
618e3ed9ee7SBarry Smith   *mu = TRMaxMems[NumTRMaxMems];
619e3ed9ee7SBarry Smith   PetscFunctionReturn(0);
620e3ed9ee7SBarry Smith }
621e3ed9ee7SBarry Smith 
622a64a8e02SBarry Smith #if defined(PETSC_USE_DEBUG)
623a64a8e02SBarry Smith /*@C
624a64a8e02SBarry Smith    PetscMallocGetStack - returns a pointer to the stack for the location in the program a call to PetscMalloc() was used to obtain that memory
625a64a8e02SBarry Smith 
626a64a8e02SBarry Smith    Collective on PETSC_COMM_WORLD
627a64a8e02SBarry Smith 
628a64a8e02SBarry Smith    Input Parameter:
629a64a8e02SBarry Smith .    ptr - the memory location
630a64a8e02SBarry Smith 
631a64a8e02SBarry Smith    Output Paramter:
632a64a8e02SBarry Smith .    stack - the stack indicating where the program allocated this memory
633a64a8e02SBarry Smith 
634a64a8e02SBarry Smith    Level: intermediate
635a64a8e02SBarry Smith 
63692f119d6SBarry Smith .seealso:  PetscMallocGetCurrentUsage(), PetscMallocView()
637a64a8e02SBarry Smith @*/
638a64a8e02SBarry Smith PetscErrorCode  PetscMallocGetStack(void *ptr,PetscStack **stack)
639a64a8e02SBarry Smith {
640a64a8e02SBarry Smith   TRSPACE *head;
641a64a8e02SBarry Smith 
642a64a8e02SBarry Smith   PetscFunctionBegin;
643a64a8e02SBarry Smith   head   = (TRSPACE*) (((char*)ptr) - HEADER_BYTES);
644a64a8e02SBarry Smith   *stack = &head->stack;
645a64a8e02SBarry Smith   PetscFunctionReturn(0);
646a64a8e02SBarry Smith }
64776386721SLisandro Dalcin #else
64876386721SLisandro Dalcin PetscErrorCode  PetscMallocGetStack(void *ptr,void **stack)
64976386721SLisandro Dalcin {
65076386721SLisandro Dalcin   PetscFunctionBegin;
651f0ba7cfcSLisandro Dalcin   *stack = NULL;
65276386721SLisandro Dalcin   PetscFunctionReturn(0);
65376386721SLisandro Dalcin }
654a64a8e02SBarry Smith #endif
655a64a8e02SBarry Smith 
656e5c89e4eSSatish Balay /*@C
65792f119d6SBarry Smith    PetscMallocDump - Dumps the currently allocated memory blocks to a file. The information
658e5c89e4eSSatish Balay    printed is: size of space (in bytes), address of space, id of space,
659e5c89e4eSSatish Balay    file in which space was allocated, and line number at which it was
660e5c89e4eSSatish Balay    allocated.
661e5c89e4eSSatish Balay 
66292f119d6SBarry Smith    Not Collective
663e5c89e4eSSatish Balay 
664e5c89e4eSSatish Balay    Input Parameter:
665e5c89e4eSSatish Balay .  fp  - file pointer.  If fp is NULL, stdout is assumed.
666e5c89e4eSSatish Balay 
667e5c89e4eSSatish Balay    Options Database Key:
66892f119d6SBarry Smith .  -malloc_dump <optional filename> - Dumps unfreed memory during call to PetscFinalize()
669e5c89e4eSSatish Balay 
670e5c89e4eSSatish Balay    Level: intermediate
671e5c89e4eSSatish Balay 
672e5c89e4eSSatish Balay    Fortran Note:
673e5c89e4eSSatish Balay    The calling sequence in Fortran is PetscMallocDump(integer ierr)
674e5c89e4eSSatish Balay    The fp defaults to stdout.
675e5c89e4eSSatish Balay 
67695452b02SPatrick Sanan    Notes:
67792f119d6SBarry Smith      Uses MPI_COMM_WORLD to display rank, because this may be called in PetscFinalize() after PETSC_COMM_WORLD has been freed.
678e5c89e4eSSatish Balay 
67992f119d6SBarry Smith      When called in PetscFinalize() dumps only the allocations that have not been properly freed
68092f119d6SBarry Smith 
68192f119d6SBarry Smith      PetscMallocView() prints a list of all memory ever allocated
68292f119d6SBarry Smith 
68392f119d6SBarry Smith .seealso:  PetscMallocGetCurrentUsage(), PetscMallocView(), PetscMallocViewSet()
684e5c89e4eSSatish Balay @*/
6857087cfbeSBarry Smith PetscErrorCode  PetscMallocDump(FILE *fp)
686e5c89e4eSSatish Balay {
687e5c89e4eSSatish Balay   TRSPACE        *head;
688e3ed9ee7SBarry Smith   size_t         libAlloc = 0;
689e5c89e4eSSatish Balay   PetscErrorCode ierr;
690e5c89e4eSSatish Balay   PetscMPIInt    rank;
691e5c89e4eSSatish Balay 
692e5c89e4eSSatish Balay   PetscFunctionBegin;
693e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr);
694da9f1d6bSBarry Smith   if (!fp) fp = PETSC_STDOUT;
695e5c89e4eSSatish Balay   head = TRhead;
696e5c89e4eSSatish Balay   while (head) {
6975486ca60SMatthew G. Knepley     libAlloc += head->size;
6985486ca60SMatthew G. Knepley     head = head->next;
6995486ca60SMatthew G. Knepley   }
7005486ca60SMatthew G. Knepley   if (TRallocated - libAlloc > 0) fprintf(fp,"[%d]Total space allocated %.0f bytes\n",rank,(PetscLogDouble)TRallocated);
7015486ca60SMatthew G. Knepley   head = TRhead;
7025486ca60SMatthew G. Knepley   while (head) {
7035486ca60SMatthew G. Knepley     PetscBool isLib;
7045486ca60SMatthew G. Knepley 
7055486ca60SMatthew G. Knepley     ierr = PetscStrcmp(head->functionname, "PetscDLLibraryOpen", &isLib);CHKERRQ(ierr);
7065486ca60SMatthew G. Knepley     if (!isLib) {
707efca3c55SSatish Balay       fprintf(fp,"[%2d]%.0f bytes %s() line %d in %s\n",rank,(PetscLogDouble)head->size,head->functionname,head->lineno,head->filename);
7088bf1f09cSShri Abhyankar #if defined(PETSC_USE_DEBUG)
709e5c89e4eSSatish Balay       ierr = PetscStackPrint(&head->stack,fp);CHKERRQ(ierr);
710e5c89e4eSSatish Balay #endif
7115486ca60SMatthew G. Knepley     }
712e5c89e4eSSatish Balay     head = head->next;
713e5c89e4eSSatish Balay   }
714e5c89e4eSSatish Balay   PetscFunctionReturn(0);
715e5c89e4eSSatish Balay }
716e5c89e4eSSatish Balay 
717dc37d89fSBarry Smith /*@
71892f119d6SBarry Smith     PetscMallocViewSet - Activates logging of all calls to PetscMalloc() with a minimum size to view
719574034a9SJed Brown 
720574034a9SJed Brown     Not Collective
721574034a9SJed Brown 
722574034a9SJed Brown     Input Arguments:
723574034a9SJed Brown .   logmin - minimum allocation size to log, or PETSC_DEFAULT
724574034a9SJed Brown 
725574034a9SJed Brown     Options Database Key:
72692f119d6SBarry Smith +  -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize()
72792f119d6SBarry Smith -  -malloc_view_threshold <min> - Sets a minimum size if -malloc_view is used
728574034a9SJed Brown 
729574034a9SJed Brown     Level: advanced
730574034a9SJed Brown 
73192f119d6SBarry Smith     Notes: Must be called after PetscMallocSetDebug()
73292f119d6SBarry Smith 
73392f119d6SBarry Smith     Uses MPI_COMM_WORLD to determine rank because PETSc communicators may not be available
73492f119d6SBarry Smith 
73592f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocViewSet()
736574034a9SJed Brown @*/
73792f119d6SBarry Smith PetscErrorCode PetscMallocViewSet(PetscLogDouble logmin)
738574034a9SJed Brown {
739574034a9SJed Brown   PetscErrorCode ierr;
740574034a9SJed Brown 
741574034a9SJed Brown   PetscFunctionBegin;
74292f119d6SBarry Smith   PetscLogMalloc = 0;
74392f119d6SBarry Smith   ierr = PetscMemorySetGetMaximumUsage();CHKERRQ(ierr);
744574034a9SJed Brown   if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */
745574034a9SJed Brown   PetscLogMallocThreshold = (size_t)logmin;
746574034a9SJed Brown   PetscFunctionReturn(0);
747574034a9SJed Brown }
748574034a9SJed Brown 
749dc37d89fSBarry Smith /*@
75092f119d6SBarry Smith     PetscMallocViewGet - Determine whether all calls to PetscMalloc() are being logged
75118a2528dSJed Brown 
75218a2528dSJed Brown     Not Collective
75318a2528dSJed Brown 
75418a2528dSJed Brown     Output Arguments
75518a2528dSJed Brown .   logging - PETSC_TRUE if logging is active
75618a2528dSJed Brown 
75718a2528dSJed Brown     Options Database Key:
75892f119d6SBarry Smith .  -malloc_view <optional filename> - Activates PetscMallocView()
75918a2528dSJed Brown 
76018a2528dSJed Brown     Level: advanced
76118a2528dSJed Brown 
76292f119d6SBarry Smith .seealso: PetscMallocDump(), PetscMallocView()
76318a2528dSJed Brown @*/
76492f119d6SBarry Smith PetscErrorCode PetscMallocViewGet(PetscBool *logging)
76518a2528dSJed Brown {
76618a2528dSJed Brown 
76718a2528dSJed Brown   PetscFunctionBegin;
76818a2528dSJed Brown   *logging = (PetscBool)(PetscLogMalloc >= 0);
76918a2528dSJed Brown   PetscFunctionReturn(0);
77018a2528dSJed Brown }
77118a2528dSJed Brown 
772e5c89e4eSSatish Balay /*@C
77392f119d6SBarry Smith     PetscMallocView - Saves the log of all calls to PetscMalloc(); also calls
77421b680ceSJed Brown        PetscMemoryGetMaximumUsage()
775e5c89e4eSSatish Balay 
77692f119d6SBarry Smith     Not Collective
777e5c89e4eSSatish Balay 
778e5c89e4eSSatish Balay     Input Parameter:
7790298fd71SBarry Smith .   fp - file pointer; or NULL
780e5c89e4eSSatish Balay 
781e5c89e4eSSatish Balay     Options Database Key:
78292f119d6SBarry Smith .  -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize()
783e5c89e4eSSatish Balay 
784e5c89e4eSSatish Balay     Level: advanced
785e5c89e4eSSatish Balay 
786e5c89e4eSSatish Balay    Fortran Note:
78792f119d6SBarry Smith    The calling sequence in Fortran is PetscMallocView(integer ierr)
788e5c89e4eSSatish Balay    The fp defaults to stdout.
789e5c89e4eSSatish Balay 
79092f119d6SBarry Smith    Notes:
79192f119d6SBarry Smith      PetscMallocDump() dumps only the currently unfreed memory, this dumps all memory ever allocated
79292f119d6SBarry Smith 
79392f119d6SBarry Smith      PetscMemoryView() gives a brief summary of current memory usage
79492f119d6SBarry Smith 
79592f119d6SBarry Smith .seealso: PetscMallocGetCurrentUsage(), PetscMallocDump(), PetscMallocViewSet(), PetscMemoryView()
796e5c89e4eSSatish Balay @*/
79792f119d6SBarry Smith PetscErrorCode  PetscMallocView(FILE *fp)
798e5c89e4eSSatish Balay {
79992f119d6SBarry Smith   PetscInt       i,j,n,*perm;
800e5c89e4eSSatish Balay   size_t         *shortlength;
801f56c2debSBarry Smith   int            *shortcount,err;
80292f119d6SBarry Smith   PetscMPIInt    rank;
803ace3abfcSBarry Smith   PetscBool      match;
804e5c89e4eSSatish Balay   const char     **shortfunction;
805e5c89e4eSSatish Balay   PetscLogDouble rss;
806e5c89e4eSSatish Balay   PetscErrorCode ierr;
807e5c89e4eSSatish Balay 
808e5c89e4eSSatish Balay   PetscFunctionBegin;
809e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr);
810f56c2debSBarry Smith   err = fflush(fp);
811e32f2f54SBarry Smith   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
812f56c2debSBarry Smith 
813*79dccf82SBarry Smith   if (PetscLogMalloc < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"PetscMallocView() called without call to PetscMallocViewSet() this is often due to\n                      setting the option -malloc_view AFTER PetscInitialize() with PetscOptionsInsert() or PetscOptionsInsertFile()");
814768aa557SSatish Balay 
815da9f1d6bSBarry Smith   if (!fp) fp = PETSC_STDOUT;
816f3d65365SJed Brown   ierr = PetscMemoryGetMaximumUsage(&rss);CHKERRQ(ierr);
817e5c89e4eSSatish Balay   if (rss) {
81892f119d6SBarry Smith     (void) fprintf(fp,"[%d] Maximum memory PetscMalloc()ed %.0f maximum size of entire process %.0f\n",rank,(PetscLogDouble)TRMaxMem,rss);
819e5c89e4eSSatish Balay   } else {
82092f119d6SBarry Smith     (void) fprintf(fp,"[%d] Maximum memory PetscMalloc()ed %.0f OS cannot compute size of entire process\n",rank,(PetscLogDouble)TRMaxMem);
821e5c89e4eSSatish Balay   }
822e32f2f54SBarry Smith   shortcount    = (int*)malloc(PetscLogMalloc*sizeof(int));if (!shortcount) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory");
823e32f2f54SBarry Smith   shortlength   = (size_t*)malloc(PetscLogMalloc*sizeof(size_t));if (!shortlength) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory");
824e32f2f54SBarry Smith   shortfunction = (const char**)malloc(PetscLogMalloc*sizeof(char*));if (!shortfunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory");
82597b9d747SJed Brown   for (i=0,n=0; i<PetscLogMalloc; i++) {
826e5c89e4eSSatish Balay     for (j=0; j<n; j++) {
827e5c89e4eSSatish Balay       ierr = PetscStrcmp(shortfunction[j],PetscLogMallocFunction[i],&match);CHKERRQ(ierr);
828e5c89e4eSSatish Balay       if (match) {
829e5c89e4eSSatish Balay         shortlength[j] += PetscLogMallocLength[i];
83059ffdab8SBarry Smith         shortcount[j]++;
831e5c89e4eSSatish Balay         goto foundit;
832e5c89e4eSSatish Balay       }
833e5c89e4eSSatish Balay     }
834e5c89e4eSSatish Balay     shortfunction[n] = PetscLogMallocFunction[i];
835e5c89e4eSSatish Balay     shortlength[n]   = PetscLogMallocLength[i];
83659ffdab8SBarry Smith     shortcount[n]    = 1;
837e5c89e4eSSatish Balay     n++;
838e5c89e4eSSatish Balay foundit:;
839e5c89e4eSSatish Balay   }
840e5c89e4eSSatish Balay 
841e32f2f54SBarry Smith   perm = (PetscInt*)malloc(n*sizeof(PetscInt));if (!perm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory");
842e5c89e4eSSatish Balay   for (i=0; i<n; i++) perm[i] = i;
843e5c89e4eSSatish Balay   ierr = PetscSortStrWithPermutation(n,(const char**)shortfunction,perm);CHKERRQ(ierr);
844e5c89e4eSSatish Balay 
84592f119d6SBarry Smith   (void) fprintf(fp,"[%d] Memory usage sorted by function\n",rank);
846e5c89e4eSSatish Balay   for (i=0; i<n; i++) {
84792f119d6SBarry Smith     (void) fprintf(fp,"[%d] %d %.0f %s()\n",rank,shortcount[perm[i]],(PetscLogDouble)shortlength[perm[i]],shortfunction[perm[i]]);
848e5c89e4eSSatish Balay   }
849e5c89e4eSSatish Balay   free(perm);
850e5c89e4eSSatish Balay   free(shortlength);
85159ffdab8SBarry Smith   free(shortcount);
852e5c89e4eSSatish Balay   free((char**)shortfunction);
853f56c2debSBarry Smith   err = fflush(fp);
854e32f2f54SBarry Smith   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
855e5c89e4eSSatish Balay   PetscFunctionReturn(0);
856e5c89e4eSSatish Balay }
857e5c89e4eSSatish Balay 
858e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------- */
859e5c89e4eSSatish Balay 
860dc37d89fSBarry Smith /*@
86192f119d6SBarry Smith     PetscMallocSetDebug - Set's PETSc memory debugging
862e5c89e4eSSatish Balay 
863e5c89e4eSSatish Balay     Not Collective
864e5c89e4eSSatish Balay 
865e5c89e4eSSatish Balay     Input Parameter:
86692f119d6SBarry Smith +   eachcall - checks the entire heap of allocated memory for issues on each call to PetscMalloc() and PetscFree()
867*79dccf82SBarry Smith -   intializenan - initializes all memory with NaN to catch use of unintialized floating point arrays
868e5c89e4eSSatish Balay 
86992f119d6SBarry Smith     Options Database:
870*79dccf82SBarry Smith +   -malloc_debug <true or false> - turns on or off debugging
87192f119d6SBarry Smith .   -malloc_test - turns on all debugging if PETSc was configured with debugging including -malloc_dump, otherwise ignored
872*79dccf82SBarry Smith .   -malloc_view_threshold t - log only allocations larger than t
87392f119d6SBarry Smith .   -malloc_dump <filename> - print a list of all memory that has not been freed
874*79dccf82SBarry Smith .   -malloc no - (deprecated) same as -malloc_debug no
875*79dccf82SBarry Smith -   -malloc_log - (deprecated) same as -malloc_view
876e5c89e4eSSatish Balay 
87792f119d6SBarry Smith    Level: developer
87892f119d6SBarry Smith 
87992f119d6SBarry Smith     Notes: This is called in PetscInitialize() and should not be called elsewhere
88092f119d6SBarry Smith 
88192f119d6SBarry Smith .seealso: CHKMEMQ(), PetscMallocValidate(), PetscMallocGetDebug()
882e5c89e4eSSatish Balay @*/
88392f119d6SBarry Smith PetscErrorCode PetscMallocSetDebug(PetscBool eachcall, PetscBool initializenan)
884e5c89e4eSSatish Balay {
88592f119d6SBarry Smith   PetscErrorCode ierr;
88692f119d6SBarry Smith 
887e5c89e4eSSatish Balay   PetscFunctionBegin;
88892f119d6SBarry Smith   if (PetscTrMalloc == PetscTrMallocDefault) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot call this routine more than once, it can only be called in PetscInitialize()");
88992f119d6SBarry Smith   ierr = PetscMallocSet(PetscTrMallocDefault,PetscTrFreeDefault,PetscTrReallocDefault);CHKERRQ(ierr);
89092f119d6SBarry Smith 
89192f119d6SBarry Smith   TRallocated         = 0;
89292f119d6SBarry Smith   TRfrags             = 0;
89392f119d6SBarry Smith   TRhead              = NULL;
89492f119d6SBarry Smith   TRid                = 0;
89592f119d6SBarry Smith   TRdebugLevel        = eachcall;
89692f119d6SBarry Smith   TRMaxMem            = 0;
89792f119d6SBarry Smith   PetscLogMallocMax   = 10000;
89892f119d6SBarry Smith   PetscLogMalloc      = -1;
89992f119d6SBarry Smith   TRdebugIintializenan = initializenan;
900e5c89e4eSSatish Balay   PetscFunctionReturn(0);
901e5c89e4eSSatish Balay }
9020acecf5bSBarry Smith 
903dc37d89fSBarry Smith /*@
90492f119d6SBarry Smith     PetscMallocGetDebug - Indicates what PETSc memory debugging it is doing.
9050acecf5bSBarry Smith 
9060acecf5bSBarry Smith     Not Collective
9070acecf5bSBarry Smith 
90892f119d6SBarry Smith     Output Parameters:
90992f119d6SBarry Smith +    basic - doing basic debugging
91092f119d6SBarry Smith .    eachcall - checks the entire memory heap at each PetscMalloc()/PetscFree()
911*79dccf82SBarry Smith -    initializenan - initializes memory with NaN
9120acecf5bSBarry Smith 
9130acecf5bSBarry Smith    Level: intermediate
9140acecf5bSBarry Smith 
91592f119d6SBarry Smith    Notes:
916*79dccf82SBarry Smith      By default, the debug version always does some debugging unless you run with -malloc_debug no
9170acecf5bSBarry Smith 
91892f119d6SBarry Smith .seealso: CHKMEMQ(), PetscMallocValidate(), PetscMallocSetDebug()
9190acecf5bSBarry Smith @*/
92092f119d6SBarry Smith PetscErrorCode PetscMallocGetDebug(PetscBool *basic, PetscBool *eachcall, PetscBool *initializenan)
9210acecf5bSBarry Smith {
9220acecf5bSBarry Smith   PetscFunctionBegin;
923*79dccf82SBarry Smith   if (basic) *basic = (PetscTrMalloc == PetscTrMallocDefault) ? PETSC_TRUE : PETSC_FALSE;
924*79dccf82SBarry Smith   if (eachcall) *eachcall           = TRdebugLevel;
925*79dccf82SBarry Smith   if (initializenan) *initializenan = TRdebugIintializenan;
9260acecf5bSBarry Smith   PetscFunctionReturn(0);
9270acecf5bSBarry Smith }
928