1 #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for getpagesize() with c89 */ 2 #include <petscsys.h> /*I "petscsys.h" I*/ 3 #if defined(PETSC_HAVE_PWD_H) 4 #include <pwd.h> 5 #endif 6 #include <ctype.h> 7 #include <sys/stat.h> 8 #if defined(PETSC_HAVE_UNISTD_H) 9 #include <unistd.h> 10 #endif 11 #if defined(PETSC_HAVE_SYS_UTSNAME_H) 12 #include <sys/utsname.h> 13 #endif 14 #include <fcntl.h> 15 #include <time.h> 16 #if defined(PETSC_HAVE_SYS_SYSTEMINFO_H) 17 #include <sys/systeminfo.h> 18 #endif 19 20 #if defined(PETSC_HAVE_SYS_RESOURCE_H) 21 #include <sys/resource.h> 22 #endif 23 #if defined(PETSC_HAVE_SYS_PROCFS_H) 24 /* #include <sys/int_types.h> Required if using gcc on solaris 2.6 */ 25 #include <sys/procfs.h> 26 #endif 27 #if defined(PETSC_HAVE_FCNTL_H) 28 #include <fcntl.h> 29 #endif 30 31 /*@ 32 PetscMemoryGetCurrentUsage - Returns the current resident set size (memory used) 33 for the program. 34 35 Not Collective 36 37 Output Parameter: 38 . mem - memory usage in bytes 39 40 Options Database Key: 41 + -memory_view - Print memory usage at end of run 42 . -log_view_memory - Display memory information for each logged event 43 - -malloc_view - Print usage of `PetscMalloc()` in `PetscFinalize()` 44 45 Level: intermediate 46 47 Notes: 48 The memory usage reported here includes all Fortran arrays 49 (that may be used in application-defined sections of code). 50 This routine thus provides a more complete picture of memory 51 usage than `PetscMallocGetCurrentUsage()` for codes that employ Fortran with 52 hardwired arrays. 53 54 This value generally never decreases during a run even if the application has freed much of its memory that it allocated 55 56 .seealso: `PetscMallocGetMaximumUsage()`, `PetscMemoryGetMaximumUsage()`, `PetscMallocGetCurrentUsage()`, `PetscMemorySetGetMaximumUsage()`, `PetscMemoryView()` 57 @*/ 58 PetscErrorCode PetscMemoryGetCurrentUsage(PetscLogDouble *mem) 59 { 60 #if defined(PETSC_USE_PROCFS_FOR_SIZE) 61 FILE *file; 62 int fd; 63 char proc[PETSC_MAX_PATH_LEN]; 64 prpsinfo_t prusage; 65 #elif defined(PETSC_USE_SBREAK_FOR_SIZE) 66 long *ii = sbreak(0); 67 int fd = ii - (long *)0; 68 #elif defined(PETSC_USE_PROC_FOR_SIZE) && defined(PETSC_HAVE_GETPAGESIZE) 69 FILE *file; 70 char proc[PETSC_MAX_PATH_LEN]; 71 int mm, rss, err; 72 #elif defined(PETSC_HAVE_GETRUSAGE) 73 static struct rusage temp; 74 #endif 75 76 PetscFunctionBegin; 77 #if defined(PETSC_USE_PROCFS_FOR_SIZE) 78 79 PetscCall(PetscSNPrintf(proc, PETSC_STATIC_ARRAY_LENGTH(proc), "/proc/%d", (int)getpid())); 80 PetscCheck((fd = open(proc, O_RDONLY)) != -1, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to access system file %s to get memory usage data", file); 81 PetscCheck(ioctl(fd, PIOCPSINFO, &prusage) != -1, PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Unable to access system file %s to get memory usage data", file); 82 *mem = (PetscLogDouble)prusage.pr_byrssize; 83 close(fd); 84 85 #elif defined(PETSC_USE_SBREAK_FOR_SIZE) 86 87 *mem = (PetscLogDouble)(8 * fd - 4294967296); /* 2^32 - upper bits */ 88 89 #elif defined(PETSC_USE_PROC_FOR_SIZE) && defined(PETSC_HAVE_GETPAGESIZE) 90 PetscCall(PetscSNPrintf(proc, PETSC_STATIC_ARRAY_LENGTH(proc), "/proc/%d/statm", (int)getpid())); 91 PetscCheck((file = fopen(proc, "r")), PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to access system file %s to get memory usage data", proc); 92 PetscCheck(fscanf(file, "%d %d", &mm, &rss) == 2, PETSC_COMM_SELF, PETSC_ERR_SYS, "Failed to read two integers (mm and rss) from %s", proc); 93 *mem = ((PetscLogDouble)rss) * ((PetscLogDouble)getpagesize()); 94 err = fclose(file); 95 PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file"); 96 97 #elif defined(PETSC_HAVE_GETRUSAGE) 98 getrusage(RUSAGE_SELF, &temp); 99 #if defined(PETSC_USE_KBYTES_FOR_SIZE) 100 *mem = 1024.0 * ((PetscLogDouble)temp.ru_maxrss); 101 #elif defined(PETSC_USE_PAGES_FOR_SIZE) && defined(PETSC_HAVE_GETPAGESIZE) 102 *mem = ((PetscLogDouble)getpagesize()) * ((PetscLogDouble)temp.ru_maxrss); 103 #else 104 *mem = temp.ru_maxrss; 105 #endif 106 107 #else 108 *mem = 0.0; 109 #endif 110 PetscFunctionReturn(PETSC_SUCCESS); 111 } 112 113 PETSC_INTERN PetscBool PetscMemoryCollectMaximumUsage; 114 PETSC_INTERN PetscLogDouble PetscMemoryMaximumUsage; 115 116 PetscBool PetscMemoryCollectMaximumUsage = PETSC_FALSE; 117 PetscLogDouble PetscMemoryMaximumUsage = 0; 118 119 /*@ 120 PetscMemoryGetMaximumUsage - Returns the maximum resident set size (memory used) 121 for the program since it started (the high water mark). 122 123 Not Collective 124 125 Output Parameter: 126 . mem - memory usage in bytes 127 128 Options Database Key: 129 + -memory_view - Print memory usage at end of run 130 . -log_view_memory - Print memory information per event 131 - -malloc_view - Print usage of `PetscMalloc()` in `PetscFinalize()` 132 133 Level: intermediate 134 135 Note: 136 The memory usage reported here includes all Fortran arrays 137 (that may be used in application-defined sections of code). 138 This routine thus provides a more complete picture of memory 139 usage than `PetscMallocGetCurrentUsage()` for codes that employ Fortran with 140 hardwired arrays. 141 142 .seealso: `PetscMallocGetMaximumUsage()`, `PetscMemoryGetCurrentUsage()`, `PetscMallocGetCurrentUsage()`, 143 `PetscMemorySetGetMaximumUsage()` 144 @*/ 145 PetscErrorCode PetscMemoryGetMaximumUsage(PetscLogDouble *mem) 146 { 147 PetscFunctionBegin; 148 PetscCheck(PetscMemoryCollectMaximumUsage, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "To use this function you must first call PetscMemorySetGetMaximumUsage()"); 149 *mem = PetscMemoryMaximumUsage; 150 PetscFunctionReturn(PETSC_SUCCESS); 151 } 152 153 /*@ 154 PetscMemorySetGetMaximumUsage - Tells PETSc to monitor the maximum memory usage so that 155 `PetscMemoryGetMaximumUsage()` will work. 156 157 Not Collective 158 159 Options Database Key: 160 + -memory_view - Print memory usage at end of run 161 . -log_view_memory - Print memory information per event 162 - -malloc_view - Print usage of `PetscMalloc()` in `PetscFinalize()` 163 164 Level: intermediate 165 166 .seealso: `PetscMallocGetMaximumUsage()`, `PetscMemoryGetCurrentUsage()`, `PetscMallocGetCurrentUsage()`, 167 `PetscMemoryGetMaximumUsage()` 168 @*/ 169 PetscErrorCode PetscMemorySetGetMaximumUsage(void) 170 { 171 PetscFunctionBegin; 172 PetscMemoryCollectMaximumUsage = PETSC_TRUE; 173 PetscFunctionReturn(PETSC_SUCCESS); 174 } 175