1 2 /* 3 Interface to malloc() and free(). This code allows for logging of memory usage and some error checking 4 */ 5 #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 6 #include <petscviewer.h> 7 #if defined(PETSC_HAVE_MALLOC_H) 8 #include <malloc.h> 9 #endif 10 11 /* 12 These are defined in mal.c and ensure that malloced space is PetscScalar aligned 13 */ 14 PETSC_EXTERN PetscErrorCode PetscMallocAlign(size_t,PetscBool,int,const char[],const char[],void**); 15 PETSC_EXTERN PetscErrorCode PetscFreeAlign(void*,int,const char[],const char[]); 16 PETSC_EXTERN PetscErrorCode PetscReallocAlign(size_t,int,const char[],const char[],void**); 17 18 #define CLASSID_VALUE ((PetscClassId) 0xf0e0d0c9) 19 #define ALREADY_FREED ((PetscClassId) 0x0f0e0d9c) 20 21 /* this is the header put at the beginning of each malloc() using for tracking allocated space and checking of allocated space heap */ 22 typedef struct _trSPACE { 23 size_t size, rsize; /* Aligned size and requested size */ 24 int id; 25 int lineno; 26 const char *filename; 27 const char *functionname; 28 PetscClassId classid; 29 #if defined(PETSC_USE_DEBUG) 30 PetscStack stack; 31 #endif 32 struct _trSPACE *next,*prev; 33 } TRSPACE; 34 35 /* HEADER_BYTES is the number of bytes in a PetscMalloc() header. 36 It is sizeof(trSPACE) padded to be a multiple of PETSC_MEMALIGN. 37 */ 38 #define HEADER_BYTES ((sizeof(TRSPACE)+(PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1)) 39 40 /* This union is used to insure that the block passed to the user retains 41 a minimum alignment of PETSC_MEMALIGN. 42 */ 43 typedef union { 44 TRSPACE sp; 45 char v[HEADER_BYTES]; 46 } TrSPACE; 47 48 #define MAXTRMAXMEMS 50 49 static size_t TRallocated = 0; 50 static int TRfrags = 0; 51 static TRSPACE *TRhead = NULL; 52 static int TRid = 0; 53 static PetscBool TRdebugLevel = PETSC_FALSE; 54 static PetscBool TRdebugIinitializenan= PETSC_FALSE; 55 static PetscBool TRrequestedSize = PETSC_FALSE; 56 static size_t TRMaxMem = 0; 57 static int NumTRMaxMems = 0; 58 static size_t TRMaxMems[MAXTRMAXMEMS]; 59 static int TRMaxMemsEvents[MAXTRMAXMEMS]; 60 /* 61 Arrays to log information on mallocs for PetscMallocView() 62 */ 63 static int PetscLogMallocMax = 10000; 64 static int PetscLogMalloc = -1; 65 static size_t PetscLogMallocThreshold = 0; 66 static size_t *PetscLogMallocLength; 67 static const char **PetscLogMallocFile,**PetscLogMallocFunction; 68 static int PetscLogMallocTrace = -1; 69 static size_t PetscLogMallocTraceThreshold = 0; 70 static PetscViewer PetscLogMallocTraceViewer = NULL; 71 72 /*@C 73 PetscMallocValidate - Test the memory for corruption. This can be called at any time between PetscInitialize() and PetscFinalize() 74 75 Input Parameters: 76 + line - line number where call originated. 77 . function - name of function calling 78 - file - file where function is 79 80 Return value: 81 The number of errors detected. 82 83 Options Database:. 84 + -malloc_test - turns this feature on when PETSc was not configured with --with-debugging=0 85 - -malloc_debug - turns this feature on anytime 86 87 Output Effect: 88 Error messages are written to stdout. 89 90 Level: advanced 91 92 Notes: 93 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) 94 95 You should generally use CHKMEMQ as a short cut for calling this routine. 96 97 The Fortran calling sequence is simply PetscMallocValidate(ierr) 98 99 No output is generated if there are no problems detected. 100 101 Developers Note: 102 Uses the flg TRdebugLevel (set as the first argument to PetscMallocSetDebug()) to determine if it should run 103 104 .seealso: CHKMEMQ 105 106 @*/ 107 PetscErrorCode PetscMallocValidate(int line,const char function[],const char file[]) 108 { 109 TRSPACE *head,*lasthead; 110 char *a; 111 PetscClassId *nend; 112 113 if (!TRdebugLevel) return 0; 114 head = TRhead; lasthead = NULL; 115 if (head && head->prev) { 116 (*PetscErrorPrintf)("PetscMallocValidate: error detected in %s() at %s:%d\n",function,file,line); 117 (*PetscErrorPrintf)("Root memory header %p has invalid back pointer %p\n",head,head->prev); 118 return PETSC_ERR_MEMC; 119 } 120 while (head) { 121 if (head->classid != CLASSID_VALUE) { 122 (*PetscErrorPrintf)("PetscMallocValidate: error detected in %s() at %s:%d\n",function,file,line); 123 (*PetscErrorPrintf)("Memory at address %p is corrupted\n",head); 124 (*PetscErrorPrintf)("Probably write before beginning of or past end of array\n"); 125 if (lasthead) { 126 a = (char*)(((TrSPACE*)head) + 1); 127 (*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); 128 } 129 abort(); 130 return PETSC_ERR_MEMC; 131 } 132 a = (char*)(((TrSPACE*)head) + 1); 133 nend = (PetscClassId*)(a + head->size); 134 if (*nend != CLASSID_VALUE) { 135 (*PetscErrorPrintf)("PetscMallocValidate: error detected in %s() at %s:%d\n",function,file,line); 136 if (*nend == ALREADY_FREED) { 137 (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p already freed\n",head->id,(PetscLogDouble)head->size,a); 138 return PETSC_ERR_MEMC; 139 } else { 140 (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 141 (*PetscErrorPrintf)("Memory originally allocated in %s() at %s:%d\n",head->functionname,head->filename,head->lineno); 142 return PETSC_ERR_MEMC; 143 } 144 } 145 if (head->prev && head->prev != lasthead) { 146 (*PetscErrorPrintf)("PetscMallocValidate: error detected in %s() at %s:%d\n",function,file,line); 147 (*PetscErrorPrintf)("Backpointer %p is invalid, should be %p\n",head->prev,lasthead); 148 (*PetscErrorPrintf)("Previous memory originally allocated in %s() at %s:%d\n",lasthead->functionname,lasthead->filename,lasthead->lineno); 149 (*PetscErrorPrintf)("Memory originally allocated in %s() at %s:%d\n",head->functionname,head->filename,head->lineno); 150 return PETSC_ERR_MEMC; 151 } 152 lasthead = head; 153 head = head->next; 154 } 155 return 0; 156 } 157 158 /* 159 PetscTrMallocDefault - Malloc with tracing. 160 161 Input Parameters: 162 + a - number of bytes to allocate 163 . lineno - line number where used. Use __LINE__ for this 164 - filename - file name where used. Use __FILE__ for this 165 166 Returns: 167 double aligned pointer to requested storage, or null if not available. 168 */ 169 PetscErrorCode PetscTrMallocDefault(size_t a,PetscBool clear,int lineno,const char function[],const char filename[],void **result) 170 { 171 TRSPACE *head; 172 char *inew; 173 size_t nsize; 174 PetscErrorCode ierr; 175 176 PetscFunctionBegin; 177 /* Do not try to handle empty blocks */ 178 if (!a) { *result = NULL; PetscFunctionReturn(0); } 179 180 ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr); 181 182 nsize = (a + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1); 183 PetscCall(PetscMallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),clear,lineno,function,filename,(void**)&inew)); 184 185 head = (TRSPACE*)inew; 186 inew += sizeof(TrSPACE); 187 188 if (TRhead) TRhead->prev = head; 189 head->next = TRhead; 190 TRhead = head; 191 head->prev = NULL; 192 head->size = nsize; 193 head->rsize = a; 194 head->id = TRid++; 195 head->lineno = lineno; 196 197 head->filename = filename; 198 head->functionname = function; 199 head->classid = CLASSID_VALUE; 200 *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 201 202 TRallocated += TRrequestedSize ? head->rsize : head->size; 203 if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 204 if (PetscLogMemory) { 205 PetscInt i; 206 for (i=0; i<NumTRMaxMems; i++) { 207 if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 208 } 209 } 210 TRfrags++; 211 212 #if defined(PETSC_USE_DEBUG) 213 PetscCall(PetscStackCopy(&petscstack,&head->stack)); 214 /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 215 head->stack.line[head->stack.currentsize-2] = lineno; 216 #if defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL_DOUBLE) 217 if (!clear && TRdebugIinitializenan) { 218 size_t i, n = a/sizeof(PetscReal); 219 PetscReal *s = (PetscReal*) inew; 220 /* from https://www.doc.ic.ac.uk/~eedwards/compsys/float/nan.html */ 221 #if defined(PETSC_USE_REAL_SINGLE) 222 int nas = 0x7F800002; 223 #else 224 PetscInt64 nas = 0x7FF0000000000002; 225 #endif 226 for (i=0; i<n; i++) { 227 memcpy(s+i,&nas,sizeof(PetscReal)); 228 } 229 } 230 #endif 231 #endif 232 233 /* 234 Allow logging of all mallocs made. 235 TODO: Currently this memory is never freed, it should be freed during PetscFinalize() 236 */ 237 if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && a >= PetscLogMallocThreshold) { 238 if (!PetscLogMalloc) { 239 PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 240 PetscCheck(PetscLogMallocLength,PETSC_COMM_SELF,PETSC_ERR_MEM," "); 241 242 PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 243 PetscCheck(PetscLogMallocFile,PETSC_COMM_SELF,PETSC_ERR_MEM," "); 244 245 PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 246 PetscCheck(PetscLogMallocFunction,PETSC_COMM_SELF,PETSC_ERR_MEM," "); 247 } 248 PetscLogMallocLength[PetscLogMalloc] = nsize; 249 PetscLogMallocFile[PetscLogMalloc] = filename; 250 PetscLogMallocFunction[PetscLogMalloc++] = function; 251 } 252 if (PetscLogMallocTrace > -1 && a >= PetscLogMallocTraceThreshold) { 253 PetscCall(PetscViewerASCIIPrintf(PetscLogMallocTraceViewer,"Alloc %zu %s:%d (%s)\n", a, filename ? filename : "null", lineno, function ? function : "null")); 254 } 255 *result = (void*)inew; 256 PetscFunctionReturn(0); 257 } 258 259 /* 260 PetscTrFreeDefault - Free with tracing. 261 262 Input Parameters: 263 . a - pointer to a block allocated with PetscTrMalloc 264 . lineno - line number where used. Use __LINE__ for this 265 . filename - file name where used. Use __FILE__ for this 266 */ 267 PetscErrorCode PetscTrFreeDefault(void *aa,int lineno,const char function[],const char filename[]) 268 { 269 char *a = (char*)aa; 270 TRSPACE *head; 271 char *ahead; 272 size_t asize; 273 PetscClassId *nend; 274 275 PetscFunctionBegin; 276 /* Do not try to handle empty blocks */ 277 if (!a) PetscFunctionReturn(0); 278 279 PetscCall(PetscMallocValidate(lineno,function,filename)); 280 281 ahead = a; 282 a = a - sizeof(TrSPACE); 283 head = (TRSPACE*)a; 284 285 if (head->classid != CLASSID_VALUE) { 286 (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() at %s:%d\n",function,filename,lineno); 287 (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 288 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); 289 } 290 nend = (PetscClassId*)(ahead + head->size); 291 if (*nend != CLASSID_VALUE) { 292 if (*nend == ALREADY_FREED) { 293 (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() at %s:%d\n",function,filename,lineno); 294 (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 295 if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 296 (*PetscErrorPrintf)("Block freed in %s() at %s:%d\n",head->functionname,head->filename,head->lineno); 297 } else { 298 (*PetscErrorPrintf)("Block allocated in %s() at %s:%d\n",head->functionname,head->filename,-head->lineno); 299 } 300 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); 301 } else { 302 /* Damaged tail */ 303 (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() at %s:%d\n",function,filename,lineno); 304 (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 305 (*PetscErrorPrintf)("Block allocated in %s() at %s:%d\n",head->functionname,head->filename,head->lineno); 306 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); 307 } 308 } 309 if (PetscLogMallocTrace > -1 && head->rsize >= PetscLogMallocTraceThreshold) { 310 PetscCall(PetscViewerASCIIPrintf(PetscLogMallocTraceViewer, "Free %zu %s:%d (%s)\n", head->rsize, filename ? filename : "null", lineno, function ? function : "null")); 311 } 312 /* Mark the location freed */ 313 *nend = ALREADY_FREED; 314 /* Save location where freed. If we suspect the line number, mark as allocated location */ 315 if (lineno > 0 && lineno < 50000) { 316 head->lineno = lineno; 317 head->filename = filename; 318 head->functionname = function; 319 } else { 320 head->lineno = -head->lineno; 321 } 322 asize = TRrequestedSize ? head->rsize : head->size; 323 PetscCheck(TRallocated >= asize,PETSC_COMM_SELF,PETSC_ERR_MEMC,"TRallocate is smaller than memory just freed"); 324 TRallocated -= asize; 325 TRfrags--; 326 if (head->prev) head->prev->next = head->next; 327 else TRhead = head->next; 328 329 if (head->next) head->next->prev = head->prev; 330 PetscCall(PetscFreeAlign(a,lineno,function,filename)); 331 PetscFunctionReturn(0); 332 } 333 334 /* 335 PetscTrReallocDefault - Realloc with tracing. 336 337 Input Parameters: 338 + len - number of bytes to allocate 339 . lineno - line number where used. Use __LINE__ for this 340 . filename - file name where used. Use __FILE__ for this 341 - result - original memory 342 343 Output Parameter: 344 . result - double aligned pointer to requested storage, or null if not available. 345 346 Level: developer 347 348 .seealso: PetscTrMallocDefault(), PetscTrFreeDefault() 349 */ 350 PetscErrorCode PetscTrReallocDefault(size_t len, int lineno, const char function[], const char filename[], void **result) 351 { 352 char *a = (char *) *result; 353 TRSPACE *head; 354 char *ahead, *inew; 355 PetscClassId *nend; 356 size_t nsize; 357 PetscErrorCode ierr; 358 359 PetscFunctionBegin; 360 /* Realloc requests zero space so just free the current space */ 361 if (!len) { 362 PetscCall(PetscTrFreeDefault(*result,lineno,function,filename)); 363 *result = NULL; 364 PetscFunctionReturn(0); 365 } 366 /* If the orginal space was NULL just use the regular malloc() */ 367 if (!*result) { 368 PetscCall(PetscTrMallocDefault(len,PETSC_FALSE,lineno,function,filename,result)); 369 PetscFunctionReturn(0); 370 } 371 372 ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr); 373 374 ahead = a; 375 a = a - sizeof(TrSPACE); 376 head = (TRSPACE *) a; 377 inew = a; 378 379 if (head->classid != CLASSID_VALUE) { 380 (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() at %s:%d\n",function,filename,lineno); 381 (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 382 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); 383 } 384 nend = (PetscClassId *)(ahead + head->size); 385 if (*nend != CLASSID_VALUE) { 386 if (*nend == ALREADY_FREED) { 387 (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() at %s:%d\n",function,filename,lineno); 388 (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 389 if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 390 (*PetscErrorPrintf)("Block freed in %s() at %s:%d\n",head->functionname,head->filename,head->lineno); 391 } else { 392 (*PetscErrorPrintf)("Block allocated in %s() at %s:%d\n",head->functionname,head->filename,-head->lineno); 393 } 394 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); 395 } else { 396 /* Damaged tail */ 397 (*PetscErrorPrintf)("PetscTrReallocDefault() called from %s() at %s:%d\n",function,filename,lineno); 398 (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 399 (*PetscErrorPrintf)("Block allocated in %s() at %s:%d\n",head->functionname,head->filename,head->lineno); 400 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); 401 } 402 } 403 404 /* remove original reference to the memory allocated from the PETSc debugging heap */ 405 TRallocated -= TRrequestedSize ? head->rsize : head->size; 406 TRfrags--; 407 if (head->prev) head->prev->next = head->next; 408 else TRhead = head->next; 409 if (head->next) head->next->prev = head->prev; 410 411 nsize = (len + (PETSC_MEMALIGN-1)) & ~(PETSC_MEMALIGN-1); 412 PetscCall(PetscReallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscClassId),lineno,function,filename,(void**)&inew)); 413 414 head = (TRSPACE*)inew; 415 inew += sizeof(TrSPACE); 416 417 if (TRhead) TRhead->prev = head; 418 head->next = TRhead; 419 TRhead = head; 420 head->prev = NULL; 421 head->size = nsize; 422 head->rsize = len; 423 head->id = TRid++; 424 head->lineno = lineno; 425 426 head->filename = filename; 427 head->functionname = function; 428 head->classid = CLASSID_VALUE; 429 *(PetscClassId*)(inew + nsize) = CLASSID_VALUE; 430 431 TRallocated += TRrequestedSize ? head->rsize : head->size; 432 if (TRallocated > TRMaxMem) TRMaxMem = TRallocated; 433 if (PetscLogMemory) { 434 PetscInt i; 435 for (i=0; i<NumTRMaxMems; i++) { 436 if (TRallocated > TRMaxMems[i]) TRMaxMems[i] = TRallocated; 437 } 438 } 439 TRfrags++; 440 441 #if defined(PETSC_USE_DEBUG) 442 PetscCall(PetscStackCopy(&petscstack,&head->stack)); 443 /* fix the line number to where the malloc() was called, not the PetscFunctionBegin; */ 444 head->stack.line[head->stack.currentsize-2] = lineno; 445 #endif 446 447 /* 448 Allow logging of all mallocs made. This adds a new entry to the list of allocated memory 449 and does not remove the previous entry to the list hence this memory is "double counted" in PetscMallocView() 450 */ 451 if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax && len >= PetscLogMallocThreshold) { 452 if (!PetscLogMalloc) { 453 PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 454 PetscCheck(PetscLogMallocLength,PETSC_COMM_SELF,PETSC_ERR_MEM," "); 455 456 PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 457 PetscCheck(PetscLogMallocFile,PETSC_COMM_SELF,PETSC_ERR_MEM," "); 458 459 PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char*)); 460 PetscCheck(PetscLogMallocFunction,PETSC_COMM_SELF,PETSC_ERR_MEM," "); 461 } 462 PetscLogMallocLength[PetscLogMalloc] = nsize; 463 PetscLogMallocFile[PetscLogMalloc] = filename; 464 PetscLogMallocFunction[PetscLogMalloc++] = function; 465 } 466 *result = (void*)inew; 467 PetscFunctionReturn(0); 468 } 469 470 /*@C 471 PetscMemoryView - Shows the amount of memory currently being used in a communicator. 472 473 Collective on PetscViewer 474 475 Input Parameters: 476 + viewer - the viewer that defines the communicator 477 - message - string printed before values 478 479 Options Database: 480 + -malloc_debug - have PETSc track how much memory it has allocated 481 - -memory_view - during PetscFinalize() have this routine called 482 483 Level: intermediate 484 485 .seealso: PetscMallocDump(), PetscMemoryGetCurrentUsage(), PetscMemorySetGetMaximumUsage(), PetscMallocView() 486 @*/ 487 PetscErrorCode PetscMemoryView(PetscViewer viewer,const char message[]) 488 { 489 PetscLogDouble allocated,allocatedmax,resident,residentmax,gallocated,gallocatedmax,gresident,gresidentmax,maxgallocated,maxgallocatedmax,maxgresident,maxgresidentmax; 490 PetscLogDouble mingallocated,mingallocatedmax,mingresident,mingresidentmax; 491 MPI_Comm comm; 492 493 PetscFunctionBegin; 494 if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD; 495 PetscCall(PetscMallocGetCurrentUsage(&allocated)); 496 PetscCall(PetscMallocGetMaximumUsage(&allocatedmax)); 497 PetscCall(PetscMemoryGetCurrentUsage(&resident)); 498 PetscCall(PetscMemoryGetMaximumUsage(&residentmax)); 499 if (residentmax > 0) residentmax = PetscMax(resident,residentmax); 500 PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm)); 501 PetscCall(PetscViewerASCIIPrintf(viewer,"%s",message)); 502 if (resident && residentmax && allocated) { 503 PetscCallMPI(MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 504 PetscCallMPI(MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 505 PetscCallMPI(MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 506 PetscCall(PetscViewerASCIIPrintf(viewer,"Maximum (over computational time) process memory: total %5.4e max %5.4e min %5.4e\n",gresidentmax,maxgresidentmax,mingresidentmax)); 507 PetscCallMPI(MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 508 PetscCallMPI(MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 509 PetscCallMPI(MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 510 PetscCall(PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident)); 511 PetscCallMPI(MPI_Reduce(&allocatedmax,&gallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 512 PetscCallMPI(MPI_Reduce(&allocatedmax,&maxgallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 513 PetscCallMPI(MPI_Reduce(&allocatedmax,&mingallocatedmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 514 PetscCall(PetscViewerASCIIPrintf(viewer,"Maximum (over computational time) space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocatedmax,maxgallocatedmax,mingallocatedmax)); 515 PetscCallMPI(MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 516 PetscCallMPI(MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 517 PetscCallMPI(MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 518 PetscCall(PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated)); 519 } else if (resident && residentmax) { 520 PetscCallMPI(MPI_Reduce(&residentmax,&gresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 521 PetscCallMPI(MPI_Reduce(&residentmax,&maxgresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 522 PetscCallMPI(MPI_Reduce(&residentmax,&mingresidentmax,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 523 PetscCall(PetscViewerASCIIPrintf(viewer,"Maximum (over computational time) process memory: total %5.4e max %5.4e min %5.4e\n",gresidentmax,maxgresidentmax,mingresidentmax)); 524 PetscCallMPI(MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 525 PetscCallMPI(MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 526 PetscCallMPI(MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 527 PetscCall(PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident)); 528 } else if (resident && allocated) { 529 PetscCallMPI(MPI_Reduce(&resident,&gresident,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 530 PetscCallMPI(MPI_Reduce(&resident,&maxgresident,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 531 PetscCallMPI(MPI_Reduce(&resident,&mingresident,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 532 PetscCall(PetscViewerASCIIPrintf(viewer,"Current process memory: total %5.4e max %5.4e min %5.4e\n",gresident,maxgresident,mingresident)); 533 PetscCallMPI(MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 534 PetscCallMPI(MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 535 PetscCallMPI(MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 536 PetscCall(PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated)); 537 PetscCall(PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n")); 538 } else if (allocated) { 539 PetscCallMPI(MPI_Reduce(&allocated,&gallocated,1,MPIU_PETSCLOGDOUBLE,MPI_SUM,0,comm)); 540 PetscCallMPI(MPI_Reduce(&allocated,&maxgallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MAX,0,comm)); 541 PetscCallMPI(MPI_Reduce(&allocated,&mingallocated,1,MPIU_PETSCLOGDOUBLE,MPI_MIN,0,comm)); 542 PetscCall(PetscViewerASCIIPrintf(viewer,"Current space PetscMalloc()ed: total %5.4e max %5.4e min %5.4e\n",gallocated,maxgallocated,mingallocated)); 543 PetscCall(PetscViewerASCIIPrintf(viewer,"Run with -memory_view to get maximum memory usage\n")); 544 PetscCall(PetscViewerASCIIPrintf(viewer,"OS cannot compute process memory\n")); 545 } else { 546 PetscCall(PetscViewerASCIIPrintf(viewer,"Run with -malloc_debug to get statistics on PetscMalloc() calls\nOS cannot compute process memory\n")); 547 } 548 PetscCall(PetscViewerFlush(viewer)); 549 PetscFunctionReturn(0); 550 } 551 552 /*@ 553 PetscMallocGetCurrentUsage - gets the current amount of memory used that was PetscMalloc()ed 554 555 Not Collective 556 557 Output Parameters: 558 . space - number of bytes currently allocated 559 560 Level: intermediate 561 562 .seealso: PetscMallocDump(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 563 PetscMemoryGetMaximumUsage() 564 @*/ 565 PetscErrorCode PetscMallocGetCurrentUsage(PetscLogDouble *space) 566 { 567 PetscFunctionBegin; 568 *space = (PetscLogDouble) TRallocated; 569 PetscFunctionReturn(0); 570 } 571 572 /*@ 573 PetscMallocGetMaximumUsage - gets the maximum amount of memory used that was PetscMalloc()ed at any time 574 during this run. 575 576 Not Collective 577 578 Output Parameters: 579 . space - maximum number of bytes ever allocated at one time 580 581 Level: intermediate 582 583 .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 584 PetscMallocPushMaximumUsage() 585 @*/ 586 PetscErrorCode PetscMallocGetMaximumUsage(PetscLogDouble *space) 587 { 588 PetscFunctionBegin; 589 *space = (PetscLogDouble) TRMaxMem; 590 PetscFunctionReturn(0); 591 } 592 593 /*@ 594 PetscMallocPushMaximumUsage - Adds another event to collect the maximum memory usage over an event 595 596 Not Collective 597 598 Input Parameter: 599 . event - an event id; this is just for error checking 600 601 Level: developer 602 603 .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 604 PetscMallocPopMaximumUsage() 605 @*/ 606 PetscErrorCode PetscMallocPushMaximumUsage(int event) 607 { 608 PetscFunctionBegin; 609 if (++NumTRMaxMems > MAXTRMAXMEMS) PetscFunctionReturn(0); 610 TRMaxMems[NumTRMaxMems-1] = TRallocated; 611 TRMaxMemsEvents[NumTRMaxMems-1] = event; 612 PetscFunctionReturn(0); 613 } 614 615 /*@ 616 PetscMallocPopMaximumUsage - collect the maximum memory usage over an event 617 618 Not Collective 619 620 Input Parameter: 621 . event - an event id; this is just for error checking 622 623 Output Parameter: 624 . mu - maximum amount of memory malloced during this event; high water mark relative to the beginning of the event 625 626 Level: developer 627 628 .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 629 PetscMallocPushMaximumUsage() 630 @*/ 631 PetscErrorCode PetscMallocPopMaximumUsage(int event,PetscLogDouble *mu) 632 { 633 PetscFunctionBegin; 634 *mu = 0; 635 if (NumTRMaxMems-- > MAXTRMAXMEMS) PetscFunctionReturn(0); 636 PetscCheck(TRMaxMemsEvents[NumTRMaxMems] == event,PETSC_COMM_SELF,PETSC_ERR_MEMC,"PetscMallocPush/PopMaximumUsage() are not nested"); 637 *mu = TRMaxMems[NumTRMaxMems]; 638 PetscFunctionReturn(0); 639 } 640 641 #if defined(PETSC_USE_DEBUG) 642 /*@C 643 PetscMallocGetStack - returns a pointer to the stack for the location in the program a call to PetscMalloc() was used to obtain that memory 644 645 Collective on PETSC_COMM_WORLD 646 647 Input Parameter: 648 . ptr - the memory location 649 650 Output Parameter: 651 . stack - the stack indicating where the program allocated this memory 652 653 Level: intermediate 654 655 .seealso: PetscMallocGetCurrentUsage(), PetscMallocView() 656 @*/ 657 PetscErrorCode PetscMallocGetStack(void *ptr,PetscStack **stack) 658 { 659 TRSPACE *head; 660 661 PetscFunctionBegin; 662 head = (TRSPACE*) (((char*)ptr) - HEADER_BYTES); 663 *stack = &head->stack; 664 PetscFunctionReturn(0); 665 } 666 #else 667 PetscErrorCode PetscMallocGetStack(void *ptr,void **stack) 668 { 669 PetscFunctionBegin; 670 *stack = NULL; 671 PetscFunctionReturn(0); 672 } 673 #endif 674 675 /*@C 676 PetscMallocDump - Dumps the currently allocated memory blocks to a file. The information 677 printed is: size of space (in bytes), address of space, id of space, 678 file in which space was allocated, and line number at which it was 679 allocated. 680 681 Not Collective 682 683 Input Parameter: 684 . fp - file pointer. If fp is NULL, stdout is assumed. 685 686 Options Database Key: 687 . -malloc_dump <optional filename> - Dumps unfreed memory during call to PetscFinalize() 688 689 Level: intermediate 690 691 Fortran Note: 692 The calling sequence in Fortran is PetscMallocDump(integer ierr) 693 The fp defaults to stdout. 694 695 Notes: 696 Uses MPI_COMM_WORLD to display rank, because this may be called in PetscFinalize() after PETSC_COMM_WORLD has been freed. 697 698 When called in PetscFinalize() dumps only the allocations that have not been properly freed 699 700 PetscMallocView() prints a list of all memory ever allocated 701 702 .seealso: PetscMallocGetCurrentUsage(), PetscMallocView(), PetscMallocViewSet(), PetscMallocValidate() 703 @*/ 704 PetscErrorCode PetscMallocDump(FILE *fp) 705 { 706 TRSPACE *head; 707 size_t libAlloc = 0; 708 PetscMPIInt rank; 709 710 PetscFunctionBegin; 711 PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD,&rank)); 712 if (!fp) fp = PETSC_STDOUT; 713 head = TRhead; 714 while (head) { 715 libAlloc += TRrequestedSize ? head->rsize : head->size; 716 head = head->next; 717 } 718 if (TRallocated - libAlloc > 0) fprintf(fp,"[%d]Total space allocated %.0f bytes\n",rank,(PetscLogDouble)TRallocated); 719 head = TRhead; 720 while (head) { 721 PetscBool isLib; 722 723 PetscCall(PetscStrcmp(head->functionname, "PetscDLLibraryOpen", &isLib)); 724 if (!isLib) { 725 fprintf(fp,"[%2d] %.0f bytes %s() at %s:%d\n",rank,(PetscLogDouble) (TRrequestedSize ? head->rsize : head->size),head->functionname,head->filename,head->lineno); 726 #if defined(PETSC_USE_DEBUG) 727 PetscCall(PetscStackPrint(&head->stack,fp)); 728 #endif 729 } 730 head = head->next; 731 } 732 PetscFunctionReturn(0); 733 } 734 735 /*@ 736 PetscMallocViewSet - Activates logging of all calls to PetscMalloc() with a minimum size to view 737 738 Not Collective 739 740 Input Parameter: 741 . logmin - minimum allocation size to log, or PETSC_DEFAULT 742 743 Options Database Key: 744 + -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize() 745 . -malloc_view_threshold <min> - Sets a minimum size if -malloc_view is used 746 - -log_view_memory - view the memory usage also with the -log_view option 747 748 Level: advanced 749 750 Notes: Must be called after PetscMallocSetDebug() 751 752 Uses MPI_COMM_WORLD to determine rank because PETSc communicators may not be available 753 754 .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocViewSet(), PetscMallocTraceSet(), PetscMallocValidate() 755 @*/ 756 PetscErrorCode PetscMallocViewSet(PetscLogDouble logmin) 757 { 758 PetscFunctionBegin; 759 PetscLogMalloc = 0; 760 PetscCall(PetscMemorySetGetMaximumUsage()); 761 if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */ 762 PetscLogMallocThreshold = (size_t)logmin; 763 PetscFunctionReturn(0); 764 } 765 766 /*@ 767 PetscMallocViewGet - Determine whether all calls to PetscMalloc() are being logged 768 769 Not Collective 770 771 Output Parameter 772 . logging - PETSC_TRUE if logging is active 773 774 Options Database Key: 775 . -malloc_view <optional filename> - Activates PetscMallocView() 776 777 Level: advanced 778 779 .seealso: PetscMallocDump(), PetscMallocView(), PetscMallocTraceGet() 780 @*/ 781 PetscErrorCode PetscMallocViewGet(PetscBool *logging) 782 { 783 PetscFunctionBegin; 784 *logging = (PetscBool)(PetscLogMalloc >= 0); 785 PetscFunctionReturn(0); 786 } 787 788 /*@ 789 PetscMallocTraceSet - Trace all calls to PetscMalloc() 790 791 Not Collective 792 793 Input Parameters: 794 + viewer - The viewer to use for tracing, or NULL to use stdout 795 . active - Flag to activate or deactivate tracing 796 - logmin - The smallest memory size that will be logged 797 798 Note: 799 The viewer should not be collective. 800 801 Level: advanced 802 803 .seealso: PetscMallocTraceGet(), PetscMallocViewGet(), PetscMallocDump(), PetscMallocView() 804 @*/ 805 PetscErrorCode PetscMallocTraceSet(PetscViewer viewer, PetscBool active, PetscLogDouble logmin) 806 { 807 PetscFunctionBegin; 808 if (!active) {PetscLogMallocTrace = -1; PetscFunctionReturn(0);} 809 PetscLogMallocTraceViewer = !viewer ? PETSC_VIEWER_STDOUT_SELF : viewer; 810 PetscLogMallocTrace = 0; 811 PetscCall(PetscMemorySetGetMaximumUsage()); 812 if (logmin < 0) logmin = 0.0; /* PETSC_DEFAULT or PETSC_DECIDE */ 813 PetscLogMallocTraceThreshold = (size_t) logmin; 814 PetscFunctionReturn(0); 815 } 816 817 /*@ 818 PetscMallocTraceGet - Determine whether all calls to PetscMalloc() are being traced 819 820 Not Collective 821 822 Output Parameter: 823 . logging - PETSC_TRUE if logging is active 824 825 Options Database Key: 826 . -malloc_view <optional filename> - Activates PetscMallocView() 827 828 Level: advanced 829 830 .seealso: PetscMallocTraceSet(), PetscMallocViewGet(), PetscMallocDump(), PetscMallocView() 831 @*/ 832 PetscErrorCode PetscMallocTraceGet(PetscBool *logging) 833 { 834 PetscFunctionBegin; 835 *logging = (PetscBool) (PetscLogMallocTrace >= 0); 836 PetscFunctionReturn(0); 837 } 838 839 /*@C 840 PetscMallocView - Saves the log of all calls to PetscMalloc(); also calls 841 PetscMemoryGetMaximumUsage() 842 843 Not Collective 844 845 Input Parameter: 846 . fp - file pointer; or NULL 847 848 Options Database Key: 849 . -malloc_view <optional filename> - Activates PetscMallocView() in PetscFinalize() 850 851 Level: advanced 852 853 Fortran Note: 854 The calling sequence in Fortran is PetscMallocView(integer ierr) 855 The fp defaults to stdout. 856 857 Notes: 858 PetscMallocDump() dumps only the currently unfreed memory, this dumps all memory ever allocated 859 860 PetscMemoryView() gives a brief summary of current memory usage 861 862 .seealso: PetscMallocGetCurrentUsage(), PetscMallocDump(), PetscMallocViewSet(), PetscMemoryView() 863 @*/ 864 PetscErrorCode PetscMallocView(FILE *fp) 865 { 866 PetscInt i,j,n,*perm; 867 size_t *shortlength; 868 int *shortcount,err; 869 PetscMPIInt rank; 870 PetscBool match; 871 const char **shortfunction; 872 PetscLogDouble rss; 873 874 PetscFunctionBegin; 875 PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD,&rank)); 876 err = fflush(fp); 877 PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 878 879 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()"); 880 881 if (!fp) fp = PETSC_STDOUT; 882 PetscCall(PetscMemoryGetMaximumUsage(&rss)); 883 if (rss) { 884 (void) fprintf(fp,"[%d] Maximum memory PetscMalloc()ed %.0f maximum size of entire process %.0f\n",rank,(PetscLogDouble)TRMaxMem,rss); 885 } else { 886 (void) fprintf(fp,"[%d] Maximum memory PetscMalloc()ed %.0f OS cannot compute size of entire process\n",rank,(PetscLogDouble)TRMaxMem); 887 } 888 shortcount = (int*)malloc(PetscLogMalloc*sizeof(int));PetscCheck(shortcount,PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 889 shortlength = (size_t*)malloc(PetscLogMalloc*sizeof(size_t));PetscCheck(shortlength,PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 890 shortfunction = (const char**)malloc(PetscLogMalloc*sizeof(char*));PetscCheck(shortfunction,PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 891 for (i=0,n=0; i<PetscLogMalloc; i++) { 892 for (j=0; j<n; j++) { 893 PetscCall(PetscStrcmp(shortfunction[j],PetscLogMallocFunction[i],&match)); 894 if (match) { 895 shortlength[j] += PetscLogMallocLength[i]; 896 shortcount[j]++; 897 goto foundit; 898 } 899 } 900 shortfunction[n] = PetscLogMallocFunction[i]; 901 shortlength[n] = PetscLogMallocLength[i]; 902 shortcount[n] = 1; 903 n++; 904 foundit:; 905 } 906 907 perm = (PetscInt*)malloc(n*sizeof(PetscInt));PetscCheck(perm,PETSC_COMM_SELF,PETSC_ERR_MEM,"Out of memory"); 908 for (i=0; i<n; i++) perm[i] = i; 909 PetscCall(PetscSortStrWithPermutation(n,(const char**)shortfunction,perm)); 910 911 (void) fprintf(fp,"[%d] Memory usage sorted by function\n",rank); 912 for (i=0; i<n; i++) { 913 (void) fprintf(fp,"[%d] %d %.0f %s()\n",rank,shortcount[perm[i]],(PetscLogDouble)shortlength[perm[i]],shortfunction[perm[i]]); 914 } 915 free(perm); 916 free(shortlength); 917 free(shortcount); 918 free((char**)shortfunction); 919 err = fflush(fp); 920 PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 921 PetscFunctionReturn(0); 922 } 923 924 /* ---------------------------------------------------------------------------- */ 925 926 /*@ 927 PetscMallocSetDebug - Set's PETSc memory debugging 928 929 Not Collective 930 931 Input Parameters: 932 + eachcall - checks the entire heap of allocated memory for issues on each call to PetscMalloc() and PetscFree() 933 - initializenan - initializes all memory with NaN to catch use of uninitialized floating point arrays 934 935 Options Database: 936 + -malloc_debug <true or false> - turns on or off debugging 937 . -malloc_test - turns on all debugging if PETSc was configured with debugging including -malloc_dump, otherwise ignored 938 . -malloc_view_threshold t - log only allocations larger than t 939 . -malloc_dump <filename> - print a list of all memory that has not been freed 940 . -malloc no - (deprecated) same as -malloc_debug no 941 - -malloc_log - (deprecated) same as -malloc_view 942 943 Level: developer 944 945 Notes: This is called in PetscInitialize() and should not be called elsewhere 946 947 .seealso: CHKMEMQ(), PetscMallocValidate(), PetscMallocGetDebug() 948 @*/ 949 PetscErrorCode PetscMallocSetDebug(PetscBool eachcall, PetscBool initializenan) 950 { 951 PetscFunctionBegin; 952 PetscCheck(PetscTrMalloc != PetscTrMallocDefault,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot call this routine more than once, it can only be called in PetscInitialize()"); 953 PetscCall(PetscMallocSet(PetscTrMallocDefault,PetscTrFreeDefault,PetscTrReallocDefault)); 954 955 TRallocated = 0; 956 TRfrags = 0; 957 TRhead = NULL; 958 TRid = 0; 959 TRdebugLevel = eachcall; 960 TRMaxMem = 0; 961 PetscLogMallocMax = 10000; 962 PetscLogMalloc = -1; 963 TRdebugIinitializenan = initializenan; 964 PetscFunctionReturn(0); 965 } 966 967 /*@ 968 PetscMallocGetDebug - Indicates what PETSc memory debugging it is doing. 969 970 Not Collective 971 972 Output Parameters: 973 + basic - doing basic debugging 974 . eachcall - checks the entire memory heap at each PetscMalloc()/PetscFree() 975 - initializenan - initializes memory with NaN 976 977 Level: intermediate 978 979 Notes: 980 By default, the debug version always does some debugging unless you run with -malloc_debug no 981 982 .seealso: CHKMEMQ(), PetscMallocValidate(), PetscMallocSetDebug() 983 @*/ 984 PetscErrorCode PetscMallocGetDebug(PetscBool *basic, PetscBool *eachcall, PetscBool *initializenan) 985 { 986 PetscFunctionBegin; 987 if (basic) *basic = (PetscTrMalloc == PetscTrMallocDefault) ? PETSC_TRUE : PETSC_FALSE; 988 if (eachcall) *eachcall = TRdebugLevel; 989 if (initializenan) *initializenan = TRdebugIinitializenan; 990 PetscFunctionReturn(0); 991 } 992 993 /*@ 994 PetscMallocLogRequestedSizeSet - Whether to log the requested or aligned memory size 995 996 Not Collective 997 998 Input Parameter: 999 . flg - PETSC_TRUE to log the requested memory size 1000 1001 Options Database: 1002 . -malloc_requested_size <bool> - Sets this flag 1003 1004 Level: developer 1005 1006 .seealso: PetscMallocLogRequestedSizeGet(), PetscMallocViewSet() 1007 @*/ 1008 PetscErrorCode PetscMallocLogRequestedSizeSet(PetscBool flg) 1009 { 1010 PetscFunctionBegin; 1011 TRrequestedSize = flg; 1012 PetscFunctionReturn(0); 1013 } 1014 1015 /*@ 1016 PetscMallocLogRequestedSizeGet - Whether to log the requested or aligned memory size 1017 1018 Not Collective 1019 1020 Output Parameter: 1021 . flg - PETSC_TRUE if we log the requested memory size 1022 1023 Level: developer 1024 1025 .seealso: PetscMallocLogRequestedSizeSetinalSizeSet(), PetscMallocViewSet() 1026 @*/ 1027 PetscErrorCode PetscMallocLogRequestedSizeGet(PetscBool *flg) 1028 { 1029 PetscFunctionBegin; 1030 *flg = TRrequestedSize; 1031 PetscFunctionReturn(0); 1032 } 1033