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