Actual source code: mem.c
1: #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for getpagesize() with c89 */
2: #include <petscsys.h>
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
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
31: /*@
32: PetscMemoryGetCurrentUsage - Returns the current resident set size (memory used)
33: for the program.
35: Not Collective
37: Output Parameter:
38: . mem - memory usage in bytes
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()`
45: Level: intermediate
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.
54: This value generally never decreases during a run even if the application has freed much of its memory that it allocated
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
76: PetscFunctionBegin;
77: #if defined(PETSC_USE_PROCFS_FOR_SIZE)
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);
85: #elif defined(PETSC_USE_SBREAK_FOR_SIZE)
87: *mem = (PetscLogDouble)(8 * fd - 4294967296); /* 2^32 - upper bits */
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");
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
107: #else
108: *mem = 0.0;
109: #endif
110: PetscFunctionReturn(PETSC_SUCCESS);
111: }
113: PETSC_INTERN PetscBool PetscMemoryCollectMaximumUsage;
114: PETSC_INTERN PetscLogDouble PetscMemoryMaximumUsage;
116: PetscBool PetscMemoryCollectMaximumUsage = PETSC_FALSE;
117: PetscLogDouble PetscMemoryMaximumUsage = 0;
119: /*@
120: PetscMemoryGetMaximumUsage - Returns the maximum resident set size (memory used)
121: for the program since it started (the high water mark).
123: Not Collective
125: Output Parameter:
126: . mem - memory usage in bytes
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()`
133: Level: intermediate
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.
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: }
153: /*@
154: PetscMemorySetGetMaximumUsage - Tells PETSc to monitor the maximum memory usage so that
155: `PetscMemoryGetMaximumUsage()` will work.
157: Not Collective
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()`
164: Level: intermediate
166: .seealso: `PetscMallocGetMaximumUsage()`, `PetscMemoryGetCurrentUsage()`, `PetscMallocGetCurrentUsage()`,
167: `PetscMemoryGetMaximumUsage()`
168: @*/
169: PetscErrorCode PetscMemorySetGetMaximumUsage(void)
170: {
171: PetscFunctionBegin;
172: PetscMemoryCollectMaximumUsage = PETSC_TRUE;
173: PetscFunctionReturn(PETSC_SUCCESS);
174: }