1 #define PETSC_DLL 2 /* 3 Interface to malloc() and free(). This code allows for 4 logging of memory usage and some error checking 5 */ 6 #include "petsc.h" /*I "petsc.h" I*/ 7 #include "petscsys.h" 8 #if defined(PETSC_HAVE_STDLIB_H) 9 #include <stdlib.h> 10 #endif 11 #if defined(PETSC_HAVE_MALLOC_H) 12 #include <malloc.h> 13 #endif 14 #include "petscfix.h" 15 16 17 /* 18 These are defined in mal.c and ensure that malloced space is PetscScalar aligned 19 */ 20 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscMallocAlign(size_t,int,const char[],const char[],const char[],void**); 21 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscFreeAlign(void*,int,const char[],const char[],const char[]); 22 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscTrMallocDefault(size_t,int,const char[],const char[],const char[],void**); 23 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscTrFreeDefault(void*,int,const char[],const char[],const char[]); 24 25 #undef __FUNCT__ 26 #define __FUNCT__ "PetscSetUseTrMalloc_Private" 27 PetscErrorCode PetscSetUseTrMalloc_Private(void) 28 { 29 PetscErrorCode ierr; 30 31 PetscFunctionBegin; 32 ierr = PetscSetMalloc(PetscTrMallocDefault,PetscTrFreeDefault);CHKERRQ(ierr); 33 PetscFunctionReturn(0); 34 } 35 36 #if (PETSC_SIZEOF_VOID_P == 8) 37 #define TR_ALIGN_BYTES 8 38 #define TR_ALIGN_MASK 0x7 39 #else 40 #define TR_ALIGN_BYTES 4 41 #define TR_ALIGN_MASK 0x3 42 #endif 43 44 #define COOKIE_VALUE 0xf0e0d0c9 45 #define ALREADY_FREED 0x0f0e0d9c 46 #define MAX_TR_STACK 20 47 #define TR_MALLOC 0x1 48 #define TR_FREE 0x2 49 50 typedef struct _trSPACE { 51 size_t size; 52 int id; 53 int lineno; 54 const char *filename; 55 const char *functionname; 56 const char *dirname; 57 unsigned long cookie; 58 #if defined(PETSC_USE_DEBUG) 59 PetscStack stack; 60 #endif 61 struct _trSPACE *next,*prev; 62 } TRSPACE; 63 64 /* HEADER_DOUBLES is the number of doubles in a PetscMalloc() header */ 65 /* We have to be careful about alignment rules here */ 66 67 #define HEADER_DOUBLES sizeof(TRSPACE)/sizeof(double)+1 68 69 70 /* This union is used to insure that the block passed to the user is 71 aligned on a double boundary */ 72 typedef union { 73 TRSPACE sp; 74 double v[HEADER_DOUBLES]; 75 } TrSPACE; 76 77 static size_t TRallocated = 0; 78 static int TRfrags = 0; 79 static TRSPACE *TRhead = 0; 80 static int TRid = 0; 81 static PetscTruth TRdebugLevel = PETSC_FALSE; 82 static size_t TRMaxMem = 0; 83 /* 84 Arrays to log information on all Mallocs 85 */ 86 static int PetscLogMallocMax = 10000,PetscLogMalloc = -1; 87 static size_t *PetscLogMallocLength; 88 static const char **PetscLogMallocDirectory,**PetscLogMallocFile,**PetscLogMallocFunction; 89 90 #undef __FUNCT__ 91 #define __FUNCT__ "PetscMallocValidate" 92 /*@C 93 PetscMallocValidate - Test the memory for corruption. This can be used to 94 check for memory overwrites. 95 96 Input Parameter: 97 + line - line number where call originated. 98 . function - name of function calling 99 . file - file where function is 100 - dir - directory where function is 101 102 Return value: 103 The number of errors detected. 104 105 Output Effect: 106 Error messages are written to stdout. 107 108 Level: advanced 109 110 Notes: 111 You should generally use CHKMEMQ as a short cut for calling this 112 routine. 113 114 The line, function, file and dir are given by the C preprocessor as 115 __LINE__, __FUNCT__, __FILE__, and __DIR__ 116 117 The Fortran calling sequence is simply PetscMallocValidate(ierr) 118 119 No output is generated if there are no problems detected. 120 121 .seealso: CHKMEMQ 122 123 @*/ 124 PetscErrorCode PETSC_DLLEXPORT PetscMallocValidate(int line,const char function[],const char file[],const char dir[]) 125 { 126 TRSPACE *head,*lasthead; 127 char *a; 128 unsigned long *nend; 129 130 PetscFunctionBegin; 131 head = TRhead; lasthead = NULL; 132 while (head) { 133 if (head->cookie != COOKIE_VALUE) { 134 (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s%s\n",function,line,dir,file); 135 (*PetscErrorPrintf)("Memory at address %p is corrupted\n",head); 136 (*PetscErrorPrintf)("Probably write past beginning or end of array\n"); 137 if (lasthead) 138 (*PetscErrorPrintf)("Last intact block allocated in %s() line %d in %s%s\n",lasthead->functionname,lasthead->lineno,lasthead->dirname,lasthead->filename); 139 SETERRQ(PETSC_ERR_MEMC," "); 140 } 141 a = (char *)(((TrSPACE*)head) + 1); 142 nend = (unsigned long *)(a + head->size); 143 if (*nend != COOKIE_VALUE) { 144 (*PetscErrorPrintf)("PetscMallocValidate: error detected at %s() line %d in %s%s\n",function,line,dir,file); 145 if (*nend == ALREADY_FREED) { 146 (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p already freed\n",head->id,(PetscLogDouble)head->size,a); 147 SETERRQ(PETSC_ERR_MEMC," "); 148 } else { 149 (*PetscErrorPrintf)("Memory [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 150 (*PetscErrorPrintf)("Memory originally allocated in %s() line %d in %s%s\n",head->functionname,head->lineno,head->dirname,head->filename); 151 SETERRQ(PETSC_ERR_MEMC," "); 152 } 153 } 154 lasthead = head; 155 head = head->next; 156 } 157 PetscFunctionReturn(0); 158 } 159 160 #undef __FUNCT__ 161 #define __FUNCT__ "PetscTrMallocDefault" 162 /* 163 PetscTrMallocDefault - Malloc with tracing. 164 165 Input Parameters: 166 + a - number of bytes to allocate 167 . lineno - line number where used. Use __LINE__ for this 168 . function - function calling routine. Use __FUNCT__ for this 169 . filename - file name where used. Use __FILE__ for this 170 - dir - directory where file is. Use __SDIR__ for this 171 172 Returns: 173 double aligned pointer to requested storage, or null if not 174 available. 175 */ 176 PetscErrorCode PETSC_DLLEXPORT PetscTrMallocDefault(size_t a,int lineno,const char function[],const char filename[],const char dir[],void**result) 177 { 178 TRSPACE *head; 179 char *inew; 180 size_t nsize; 181 PetscErrorCode ierr; 182 183 PetscFunctionBegin; 184 if (!a) { 185 SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Trying to malloc zero size array"); 186 } 187 188 if (TRdebugLevel) { 189 ierr = PetscMallocValidate(lineno,function,filename,dir); if (ierr) PetscFunctionReturn(ierr); 190 } 191 192 nsize = a; 193 if (nsize & TR_ALIGN_MASK) nsize += (TR_ALIGN_BYTES - (nsize & TR_ALIGN_MASK)); 194 ierr = PetscMallocAlign(nsize+sizeof(TrSPACE)+sizeof(PetscScalar),lineno,function,filename,dir,(void**)&inew);CHKERRQ(ierr); 195 196 head = (TRSPACE *)inew; 197 inew += sizeof(TrSPACE); 198 199 if (TRhead) TRhead->prev = head; 200 head->next = TRhead; 201 TRhead = head; 202 head->prev = 0; 203 head->size = nsize; 204 head->id = TRid; 205 head->lineno = lineno; 206 207 head->filename = filename; 208 head->functionname = function; 209 head->dirname = dir; 210 head->cookie = COOKIE_VALUE; 211 *(unsigned long *)(inew + nsize) = COOKIE_VALUE; 212 213 TRallocated += nsize; 214 if (TRallocated > TRMaxMem) { 215 TRMaxMem = TRallocated; 216 } 217 TRfrags++; 218 219 #if defined(PETSC_USE_DEBUG) 220 ierr = PetscStackCopy(petscstack,&head->stack);CHKERRQ(ierr); 221 #endif 222 223 /* 224 Allow logging of all mallocs made 225 */ 226 if (PetscLogMalloc > -1 && PetscLogMalloc < PetscLogMallocMax) { 227 if (!PetscLogMalloc) { 228 PetscLogMallocLength = (size_t*)malloc(PetscLogMallocMax*sizeof(size_t)); 229 if (!PetscLogMallocLength) SETERRQ(PETSC_ERR_MEM," "); 230 PetscLogMallocDirectory = (const char**)malloc(PetscLogMallocMax*sizeof(char**)); 231 if (!PetscLogMallocDirectory) SETERRQ(PETSC_ERR_MEM," "); 232 PetscLogMallocFile = (const char**)malloc(PetscLogMallocMax*sizeof(char**)); 233 if (!PetscLogMallocFile) SETERRQ(PETSC_ERR_MEM," "); 234 PetscLogMallocFunction = (const char**)malloc(PetscLogMallocMax*sizeof(char**)); 235 if (!PetscLogMallocFunction) SETERRQ(PETSC_ERR_MEM," "); 236 } 237 PetscLogMallocLength[PetscLogMalloc] = nsize; 238 PetscLogMallocDirectory[PetscLogMalloc] = dir; 239 PetscLogMallocFile[PetscLogMalloc] = filename; 240 PetscLogMallocFunction[PetscLogMalloc++] = function; 241 } 242 *result = (void*)inew; 243 PetscFunctionReturn(0); 244 } 245 246 247 #undef __FUNCT__ 248 #define __FUNCT__ "PetscTrFreeDefault" 249 /* 250 PetscTrFreeDefault - Free with tracing. 251 252 Input Parameters: 253 . a - pointer to a block allocated with PetscTrMalloc 254 . lineno - line number where used. Use __LINE__ for this 255 . function - function calling routine. Use __FUNCT__ for this 256 . file - file name where used. Use __FILE__ for this 257 . dir - directory where file is. Use __SDIR__ for this 258 */ 259 PetscErrorCode PETSC_DLLEXPORT PetscTrFreeDefault(void *aa,int line,const char function[],const char file[],const char dir[]) 260 { 261 char *a = (char*)aa; 262 TRSPACE *head; 263 char *ahead; 264 PetscErrorCode ierr; 265 unsigned long *nend; 266 267 PetscFunctionBegin; 268 /* Do not try to handle empty blocks */ 269 if (!a) { 270 (*PetscErrorPrintf)("PetscTrFreeDefault called from %s() line %d in %s%s\n",function,line,dir,file); 271 SETERRQ4(PETSC_ERR_ARG_OUTOFRANGE,"Trying to free null block: Free called from %s() line %d in %s%s\n",function,line,dir,file); 272 } 273 274 if (TRdebugLevel) { 275 ierr = PetscMallocValidate(line,function,file,dir);CHKERRQ(ierr); 276 } 277 278 ahead = a; 279 a = a - sizeof(TrSPACE); 280 head = (TRSPACE *)a; 281 282 if (head->cookie != COOKIE_VALUE) { 283 (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s%s\n",function,line,dir,file); 284 (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); 285 SETERRQ(PETSC_ERR_MEMC,"Bad location or corrupted memory"); 286 } 287 nend = (unsigned long *)(ahead + head->size); 288 if (*nend != COOKIE_VALUE) { 289 if (*nend == ALREADY_FREED) { 290 (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s%s\n",function,line,dir,file); 291 (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); 292 if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { 293 (*PetscErrorPrintf)("Block freed in %s() line %d in %s%s\n",head->functionname,head->lineno,head->dirname,head->filename); 294 } else { 295 (*PetscErrorPrintf)("Block allocated in %s() line %d in %s%s\n",head->functionname,-head->lineno,head->dirname,head->filename); 296 } 297 SETERRQ(PETSC_ERR_ARG_WRONG,"Memory already freed"); 298 } else { 299 /* Damaged tail */ 300 (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s%s\n",function,line,dir,file); 301 (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); 302 (*PetscErrorPrintf)("Block allocated in %s() line %d in %s%s\n",head->functionname,head->lineno,head->dirname,head->filename); 303 SETERRQ(PETSC_ERR_MEMC,"Corrupted memory"); 304 } 305 } 306 /* Mark the location freed */ 307 *nend = ALREADY_FREED; 308 /* Save location where freed. If we suspect the line number, mark as allocated location */ 309 if (line > 0 && line < 50000) { 310 head->lineno = line; 311 head->filename = file; 312 head->functionname = function; 313 head->dirname = dir; 314 } else { 315 head->lineno = - head->lineno; 316 } 317 /* zero out memory - helps to find some reuse of already freed memory */ 318 ierr = PetscMemzero(aa,head->size);CHKERRQ(ierr); 319 320 TRallocated -= head->size; 321 TRfrags --; 322 if (head->prev) head->prev->next = head->next; 323 else TRhead = head->next; 324 325 if (head->next) head->next->prev = head->prev; 326 ierr = PetscFreeAlign(a,line,function,file,dir);CHKERRQ(ierr); 327 PetscFunctionReturn(0); 328 } 329 330 331 #undef __FUNCT__ 332 #define __FUNCT__ "PetscMemoryShowUsage" 333 /*@C 334 PetscMemoryShowUsage - Shows the amount of memory currently being used 335 in a communicator. 336 337 Collective on PetscViewer 338 339 Input Parameter: 340 + viewer - the viewer that defines the communicator 341 - message - string printed before values 342 343 Level: intermediate 344 345 Concepts: memory usage 346 347 .seealso: PetscMallocDump(), PetscMemoryGetCurrentUsage() 348 @*/ 349 PetscErrorCode PETSC_DLLEXPORT PetscMemoryShowUsage(PetscViewer viewer,const char message[]) 350 { 351 PetscLogDouble allocated,maximum,resident,residentmax; 352 PetscErrorCode ierr; 353 PetscMPIInt rank; 354 MPI_Comm comm; 355 356 PetscFunctionBegin; 357 if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD; 358 ierr = PetscMallocGetCurrentUsage(&allocated);CHKERRQ(ierr); 359 ierr = PetscMallocGetMaximumUsage(&maximum);CHKERRQ(ierr); 360 ierr = PetscMemoryGetCurrentUsage(&resident);CHKERRQ(ierr); 361 ierr = PetscMemoryGetMaximumUsage(&residentmax);CHKERRQ(ierr); 362 if (residentmax > 0) residentmax = PetscMax(resident,residentmax); 363 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 364 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 365 ierr = PetscViewerASCIIPrintf(viewer,message);CHKERRQ(ierr); 366 if (resident && residentmax && allocated) { 367 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d]Current space PetscMalloc()ed %g, max space PetscMalloced() %g\n[%d]Current process memory %g max process memory %g\n",rank,allocated,maximum,rank,resident,residentmax);CHKERRQ(ierr); 368 } else if (resident && residentmax) { 369 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d]Run with -malloc to get statistics on PetscMalloc() calls\n[%d]Current process memory %g max process memory %g\n",rank,rank,resident,residentmax);CHKERRQ(ierr); 370 } else if (resident && allocated) { 371 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d]Current space PetscMalloc()ed %g, max space PetscMalloced() %g\n[%d]Current process memory %g, run with -memory_info to get max memory usage\n",rank,allocated,maximum,rank,resident);CHKERRQ(ierr); 372 } else if (allocated) { 373 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d]Current space PetscMalloc()ed %g, max space PetscMalloced() %g\n[%d]OS cannot compute process memory\n",rank,allocated,maximum,rank);CHKERRQ(ierr); 374 } else { 375 ierr = PetscViewerASCIIPrintf(viewer,"Run with -malloc to get statistics on PetscMalloc() calls\nOS cannot compute process memory\n");CHKERRQ(ierr); 376 } 377 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 378 PetscFunctionReturn(0); 379 } 380 381 #undef __FUNCT__ 382 #define __FUNCT__ "PetscMallocGetCurrentUsage" 383 /*@C 384 PetscMallocGetCurrentUsage - gets the current amount of memory used that was PetscMalloc()ed 385 386 Not Collective 387 388 Output Parameters: 389 . space - number of bytes currently allocated 390 391 Level: intermediate 392 393 Concepts: memory usage 394 395 .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 396 PetscMemoryGetMaximumUsage() 397 @*/ 398 PetscErrorCode PETSC_DLLEXPORT PetscMallocGetCurrentUsage(PetscLogDouble *space) 399 { 400 PetscFunctionBegin; 401 *space = (PetscLogDouble) TRallocated; 402 PetscFunctionReturn(0); 403 } 404 405 #undef __FUNCT__ 406 #define __FUNCT__ "PetscMallocGetMaximumUsage" 407 /*@C 408 PetscMallocGetMaximumUsage - gets the maximum amount of memory used that was PetscMalloc()ed at any time 409 during this run. 410 411 Not Collective 412 413 Output Parameters: 414 . space - maximum number of bytes ever allocated at one time 415 416 Level: intermediate 417 418 Concepts: memory usage 419 420 .seealso: PetscMallocDump(), PetscMallocDumpLog(), PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), 421 PetscMemoryGetCurrentUsage() 422 @*/ 423 PetscErrorCode PETSC_DLLEXPORT PetscMallocGetMaximumUsage(PetscLogDouble *space) 424 { 425 PetscFunctionBegin; 426 *space = (PetscLogDouble) TRMaxMem; 427 PetscFunctionReturn(0); 428 } 429 430 #undef __FUNCT__ 431 #define __FUNCT__ "PetscMallocDump" 432 /*@C 433 PetscMallocDump - Dumps the allocated memory blocks to a file. The information 434 printed is: size of space (in bytes), address of space, id of space, 435 file in which space was allocated, and line number at which it was 436 allocated. 437 438 Collective on PETSC_COMM_WORLD 439 440 Input Parameter: 441 . fp - file pointer. If fp is NULL, stdout is assumed. 442 443 Options Database Key: 444 . -malloc_dump - Dumps unfreed memory during call to PetscFinalize() 445 446 Level: intermediate 447 448 Fortran Note: 449 The calling sequence in Fortran is PetscMallocDump(integer ierr) 450 The fp defaults to stdout. 451 452 Notes: uses MPI_COMM_WORLD, because this may be called in PetscFinalize() after PETSC_COMM_WORLD 453 has been freed. 454 455 Concepts: memory usage 456 Concepts: memory bleeding 457 Concepts: bleeding memory 458 459 .seealso: PetscMallocGetCurrentSize(), PetscMallocDumpLog() 460 @*/ 461 PetscErrorCode PETSC_DLLEXPORT PetscMallocDump(FILE *fp) 462 { 463 TRSPACE *head; 464 PetscErrorCode ierr; 465 PetscMPIInt rank; 466 467 PetscFunctionBegin; 468 ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr); 469 if (!fp) fp = stdout; 470 if (TRallocated > 0) { 471 fprintf(fp,"[%d]Total space allocated %.0f bytes\n",rank,(PetscLogDouble)TRallocated); 472 } 473 head = TRhead; 474 while (head) { 475 fprintf(fp,"[%2d]%.0f bytes %s() line %d in %s%s\n",rank,(PetscLogDouble)head->size,head->functionname,head->lineno,head->dirname,head->filename); 476 #if defined(PETSC_USE_DEBUG) 477 ierr = PetscStackPrint(&head->stack,fp);CHKERRQ(ierr); 478 #endif 479 head = head->next; 480 } 481 PetscFunctionReturn(0); 482 } 483 484 /* ---------------------------------------------------------------------------- */ 485 486 #undef __FUNCT__ 487 #define __FUNCT__ "PetscMallocSetDumpLog" 488 /*@C 489 PetscMallocSetDumpLog - Activates logging of all calls to PetscMalloc(). 490 491 Not Collective 492 493 Options Database Key: 494 . -malloc_log - Activates PetscMallocDumpLog() 495 496 Level: advanced 497 498 .seealso: PetscMallocDump(), PetscMallocDumpLog() 499 @*/ 500 PetscErrorCode PETSC_DLLEXPORT PetscMallocSetDumpLog(void) 501 { 502 PetscFunctionBegin; 503 PetscLogMalloc = 0; 504 PetscFunctionReturn(0); 505 } 506 507 #undef __FUNCT__ 508 #define __FUNCT__ "PetscMallocDumpLog" 509 /*@C 510 PetscMallocDumpLog - Dumps the log of all calls to PetscMalloc(); also calls 511 PetscMemoryGetCurrentUsage() and PetscMemoryGetMaximumUsage() 512 513 Collective on PETSC_COMM_WORLD 514 515 Input Parameter: 516 . fp - file pointer; or PETSC_NULL 517 518 Options Database Key: 519 . -malloc_log - Activates PetscMallocDumpLog() 520 521 Level: advanced 522 523 Fortran Note: 524 The calling sequence in Fortran is PetscMallocDumpLog(integer ierr) 525 The fp defaults to stdout. 526 527 .seealso: PetscMallocGetCurrentUsage(), PetscMallocDump(), PetscMallocSetDumpLog() 528 @*/ 529 PetscErrorCode PETSC_DLLEXPORT PetscMallocDumpLog(FILE *fp) 530 { 531 PetscInt i,j,n,dummy,*perm; 532 size_t *shortlength; 533 int *shortcount; 534 PetscMPIInt rank,size,tag = 1212 /* very bad programming */; 535 PetscTruth match; 536 const char **shortfunction; 537 PetscLogDouble rss; 538 MPI_Status status; 539 PetscErrorCode ierr; 540 541 PetscFunctionBegin; 542 ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr); 543 ierr = MPI_Comm_size(MPI_COMM_WORLD,&size);CHKERRQ(ierr); 544 /* 545 Try to get the data printed in order by processor. This will only sometimes work 546 */ 547 fflush(fp); 548 ierr = MPI_Barrier(MPI_COMM_WORLD);CHKERRQ(ierr); 549 if (rank) { 550 ierr = MPI_Recv(&dummy,1,MPIU_INT,rank-1,tag,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 551 } 552 553 if (!fp) fp = stdout; 554 ierr = PetscMemoryGetCurrentUsage(&rss);CHKERRQ(ierr); 555 if (rss) { 556 ierr = PetscFPrintf(MPI_COMM_WORLD,fp,"[%d] Maximum memory PetscMalloc()ed %.0f maximum size of entire process %D\n",rank,(PetscLogDouble)TRMaxMem,rss);CHKERRQ(ierr); 557 } else { 558 ierr = PetscFPrintf(MPI_COMM_WORLD,fp,"[%d] Maximum memory PetscMalloc()ed %.0f OS cannot compute size of entire process\n",rank,(PetscLogDouble)TRMaxMem);CHKERRQ(ierr); 559 } 560 if (PetscLogMalloc < 0) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"PetscMallocDumpLog() called without call to PetscMallocSetDumpLog() this is often due to\n setting the option -malloc_log AFTER PetscInitialize() with PetscOptionsInsert() or PetscOptionsInsertFile()"); 561 shortcount = (int*)malloc(PetscLogMalloc*sizeof(int));if (!shortcount) SETERRQ(PETSC_ERR_MEM,"Out of memory"); 562 shortlength = (size_t*)malloc(PetscLogMalloc*sizeof(size_t));if (!shortlength) SETERRQ(PETSC_ERR_MEM,"Out of memory"); 563 shortfunction = (const char**)malloc(PetscLogMalloc*sizeof(char *));if (!shortfunction) SETERRQ(PETSC_ERR_MEM,"Out of memory"); 564 shortfunction[0] = PetscLogMallocFunction[0]; 565 shortlength[0] = PetscLogMallocLength[0]; 566 shortcount[0] = 0; 567 n = 1; 568 for (i=1; i<PetscLogMalloc; i++) { 569 for (j=0; j<n; j++) { 570 ierr = PetscStrcmp(shortfunction[j],PetscLogMallocFunction[i],&match);CHKERRQ(ierr); 571 if (match) { 572 shortlength[j] += PetscLogMallocLength[i]; 573 shortcount[j]++; 574 goto foundit; 575 } 576 } 577 shortfunction[n] = PetscLogMallocFunction[i]; 578 shortlength[n] = PetscLogMallocLength[i]; 579 shortcount[n] = 1; 580 n++; 581 foundit:; 582 } 583 584 perm = (PetscInt*)malloc(n*sizeof(PetscInt));if (!perm) SETERRQ(PETSC_ERR_MEM,"Out of memory"); 585 for (i=0; i<n; i++) perm[i] = i; 586 ierr = PetscSortStrWithPermutation(n,(const char **)shortfunction,perm);CHKERRQ(ierr); 587 588 ierr = PetscFPrintf(MPI_COMM_WORLD,fp,"[%d] Memory usage sorted by function\n",rank);CHKERRQ(ierr); 589 for (i=0; i<n; i++) { 590 ierr = PetscFPrintf(MPI_COMM_WORLD,fp,"[%d] %d %.0f %s()\n",rank,shortcount[perm[i]],(PetscLogDouble)shortlength[perm[i]],shortfunction[perm[i]]);CHKERRQ(ierr); 591 } 592 free(perm); 593 free(shortlength); 594 free(shortcount); 595 free((char **)shortfunction); 596 fflush(fp); 597 if (rank != size-1) { 598 ierr = MPI_Send(&dummy,1,MPIU_INT,rank+1,tag,MPI_COMM_WORLD);CHKERRQ(ierr); 599 } 600 PetscFunctionReturn(0); 601 } 602 603 /* ---------------------------------------------------------------------------- */ 604 605 #undef __FUNCT__ 606 #define __FUNCT__ "PetscMallocDebug" 607 /*@C 608 PetscMallocDebug - Turns on/off debugging for the memory management routines. 609 610 Not Collective 611 612 Input Parameter: 613 . level - PETSC_TRUE or PETSC_FALSE 614 615 Level: intermediate 616 617 .seealso: CHKMEMQ(), PetscMallocValidate() 618 @*/ 619 PetscErrorCode PETSC_DLLEXPORT PetscMallocDebug(PetscTruth level) 620 { 621 PetscFunctionBegin; 622 TRdebugLevel = level; 623 PetscFunctionReturn(0); 624 } 625