xref: /petsc/src/sys/memory/mem.c (revision f23aa3dd738493dcb3a70a8c0c7f5454aa9150c2)
1e5c89e4eSSatish Balay 
2c6db04a5SJed Brown #include <petscsys.h>           /*I "petscsys.h" I*/
3e5c89e4eSSatish Balay #if defined(PETSC_HAVE_PWD_H)
4e5c89e4eSSatish Balay #include <pwd.h>
5e5c89e4eSSatish Balay #endif
6e5c89e4eSSatish Balay #include <ctype.h>
7e5c89e4eSSatish Balay #include <sys/types.h>
8e5c89e4eSSatish Balay #include <sys/stat.h>
9e5c89e4eSSatish Balay #if defined(PETSC_HAVE_UNISTD_H)
10e5c89e4eSSatish Balay #include <unistd.h>
11e5c89e4eSSatish Balay #endif
12e5c89e4eSSatish Balay #if defined(PETSC_HAVE_STDLIB_H)
13e5c89e4eSSatish Balay #include <stdlib.h>
14e5c89e4eSSatish Balay #endif
15e5c89e4eSSatish Balay #if defined(PETSC_HAVE_SYS_UTSNAME_H)
16e5c89e4eSSatish Balay #include <sys/utsname.h>
17e5c89e4eSSatish Balay #endif
18e5c89e4eSSatish Balay #include <fcntl.h>
19e5c89e4eSSatish Balay #include <time.h>
20e5c89e4eSSatish Balay #if defined(PETSC_HAVE_SYS_SYSTEMINFO_H)
21e5c89e4eSSatish Balay #include <sys/systeminfo.h>
22e5c89e4eSSatish Balay #endif
23e5c89e4eSSatish Balay 
24d6bc4c50SBarry Smith /* task_info seems to be buggy plus pgcc doesn't like including this file
25e5c89e4eSSatish Balay #if defined(PETSC_HAVE_TASK_INFO)
26e5c89e4eSSatish Balay #include <mach/mach.h>
27e5c89e4eSSatish Balay #endif
28d6bc4c50SBarry Smith */
29e5c89e4eSSatish Balay 
30e5c89e4eSSatish Balay #if defined(PETSC_HAVE_SYS_RESOURCE_H)
31e5c89e4eSSatish Balay #include <sys/resource.h>
32e5c89e4eSSatish Balay #endif
33e5c89e4eSSatish Balay #if defined(PETSC_HAVE_SYS_PROCFS_H)
34e5c89e4eSSatish Balay /* #include <sys/int_types.h> Required if using gcc on solaris 2.6 */
35e5c89e4eSSatish Balay #include <sys/procfs.h>
36e5c89e4eSSatish Balay #endif
37e5c89e4eSSatish Balay #if defined(PETSC_HAVE_FCNTL_H)
38e5c89e4eSSatish Balay #include <fcntl.h>
39e5c89e4eSSatish Balay #endif
40e5c89e4eSSatish Balay 
41e5c89e4eSSatish Balay #undef __FUNCT__
42e5c89e4eSSatish Balay #define __FUNCT__ "PetscMemoryGetCurrentUsage"
43e30d2299SSatish Balay /*@
44e5c89e4eSSatish Balay    PetscMemoryGetCurrentUsage - Returns the current resident set size (memory used)
45e5c89e4eSSatish Balay    for the program.
46e5c89e4eSSatish Balay 
47e5c89e4eSSatish Balay    Not Collective
48e5c89e4eSSatish Balay 
49e5c89e4eSSatish Balay    Output Parameter:
50e5c89e4eSSatish Balay .   mem - memory usage in bytes
51e5c89e4eSSatish Balay 
52e5c89e4eSSatish Balay    Options Database Key:
53e5c89e4eSSatish Balay .  -memory_info - Print memory usage at end of run
54e5c89e4eSSatish Balay .  -malloc_log - Activate logging of memory usage
55e5c89e4eSSatish Balay 
56e5c89e4eSSatish Balay    Level: intermediate
57e5c89e4eSSatish Balay 
58e5c89e4eSSatish Balay    Notes:
59e5c89e4eSSatish Balay    The memory usage reported here includes all Fortran arrays
60e5c89e4eSSatish Balay    (that may be used in application-defined sections of code).
61e5c89e4eSSatish Balay    This routine thus provides a more complete picture of memory
62e5c89e4eSSatish Balay    usage than PetscMallocGetCurrentUsage() for codes that employ Fortran with
63e5c89e4eSSatish Balay    hardwired arrays.
64e5c89e4eSSatish Balay 
65e5c89e4eSSatish Balay .seealso: PetscMallocGetMaximumUsage(), PetscMemoryGetMaximumUsage(), PetscMallocGetCurrentUsage()
66e5c89e4eSSatish Balay 
67e5c89e4eSSatish Balay    Concepts: resident set size
68e5c89e4eSSatish Balay    Concepts: memory usage
69e5c89e4eSSatish Balay 
70e5c89e4eSSatish Balay @*/
717087cfbeSBarry Smith PetscErrorCode  PetscMemoryGetCurrentUsage(PetscLogDouble *mem)
72e5c89e4eSSatish Balay {
73e5c89e4eSSatish Balay #if defined(PETSC_USE_PROCFS_FOR_SIZE)
74e5c89e4eSSatish Balay   FILE                   *file;
75e5c89e4eSSatish Balay   int                    fd;
76e5c89e4eSSatish Balay   char                   proc[PETSC_MAX_PATH_LEN];
77e5c89e4eSSatish Balay   prpsinfo_t             prusage;
78e5c89e4eSSatish Balay #elif defined(PETSC_USE_SBREAK_FOR_SIZE)
79e5c89e4eSSatish Balay   long                   *ii = sbreak(0);
80e5c89e4eSSatish Balay   int                    fd = ii - (long*)0;
81cb31d0b8SSatish Balay #elif defined(PETSC_USE_PROC_FOR_SIZE) && defined(PETSC_HAVE_GETPAGESIZE)
82e5c89e4eSSatish Balay   FILE                   *file;
83e5c89e4eSSatish Balay   char                   proc[PETSC_MAX_PATH_LEN];
84ed9cf6e9SBarry Smith   int                    mm,rss,err;
85e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_TASK_INFO)
8659ffdab8SBarry Smith   /*  task_basic_info_data_t ti;
8759ffdab8SBarry Smith       unsigned int           count; */
88e5c89e4eSSatish Balay   /*
89e5c89e4eSSatish Balay      The next line defined variables that are not used; but if they
90e5c89e4eSSatish Balay      are not included the code crashes. Something must be wrong
91e5c89e4eSSatish Balay      with either the task_info() command or compiler corrupting the
92e5c89e4eSSatish Balay      stack.
93e5c89e4eSSatish Balay   */
9459ffdab8SBarry Smith   /* kern_return_t          kerr; */
95e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_GETRUSAGE)
96e5c89e4eSSatish Balay   static struct rusage   temp;
97e5c89e4eSSatish Balay #endif
98e5c89e4eSSatish Balay 
99e5c89e4eSSatish Balay   PetscFunctionBegin;
100e5c89e4eSSatish Balay #if defined(PETSC_USE_PROCFS_FOR_SIZE)
101e5c89e4eSSatish Balay 
102e5c89e4eSSatish Balay   sprintf(proc,"/proc/%d",(int)getpid());
103*f23aa3ddSBarry Smith   if ((fd = open(proc,O_RDONLY)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to access system file %s to get memory usage data",file);
104*f23aa3ddSBarry Smith   if (ioctl(fd,PIOCPSINFO,&prusage) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Unable to access system file %s to get memory usage data",file);
1054097fa8bSSatish Balay   *mem = (PetscLogDouble)prusage.pr_byrssize;
106e5c89e4eSSatish Balay   close(fd);
107e5c89e4eSSatish Balay 
108e5c89e4eSSatish Balay #elif defined(PETSC_USE_SBREAK_FOR_SIZE)
109e5c89e4eSSatish Balay 
110e5c89e4eSSatish Balay   *mem = (PetscLogDouble)(8*fd - 4294967296); /* 2^32 - upper bits */
111e5c89e4eSSatish Balay 
112e5c89e4eSSatish Balay #elif defined(PETSC_USE_PROC_FOR_SIZE) && defined(PETSC_HAVE_GETPAGESIZE)
113e5c89e4eSSatish Balay   sprintf(proc,"/proc/%d/statm",(int)getpid());
114*f23aa3ddSBarry Smith   if (!(file = fopen(proc,"r"))) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to access system file %s to get memory usage data",proc);
115167ada76SJed Brown   if (fscanf(file,"%d %d",&mm,&rss) != 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"Failed to read two integers (mm and rss) from %s",proc);
1164097fa8bSSatish Balay   *mem = ((PetscLogDouble)rss) * ((PetscLogDouble)getpagesize());
117ed9cf6e9SBarry Smith   err = fclose(file);
118e32f2f54SBarry Smith   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
119e5c89e4eSSatish Balay 
120e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_TASK_INFO)
12159ffdab8SBarry Smith   *mem = 0;
122e32f2f54SBarry Smith   /* if ((kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&ti,&count)) != KERN_SUCCESS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Mach system call failed: kern_return_t ",kerr);
12359ffdab8SBarry Smith    *mem = (PetscLogDouble) ti.resident_size; */
124e5c89e4eSSatish Balay 
125e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_GETRUSAGE)
126e5c89e4eSSatish Balay   getrusage(RUSAGE_SELF,&temp);
127e5c89e4eSSatish Balay #if defined(PETSC_USE_KBYTES_FOR_SIZE)
1284097fa8bSSatish Balay   *mem = 1024.0 * ((PetscLogDouble)temp.ru_maxrss);
129cb31d0b8SSatish Balay #elif defined(PETSC_HAVE_GETPAGESIZE)
1304097fa8bSSatish Balay   *mem = ((PetscLogDouble)getpagesize())*((PetscLogDouble)temp.ru_maxrss);
131cb31d0b8SSatish Balay #else
132cb31d0b8SSatish Balay   *mem = 0.0;
133e5c89e4eSSatish Balay #endif
134e5c89e4eSSatish Balay 
135e5c89e4eSSatish Balay #else
136e5c89e4eSSatish Balay   *mem = 0.0;
137e5c89e4eSSatish Balay #endif
138e5c89e4eSSatish Balay   PetscFunctionReturn(0);
139e5c89e4eSSatish Balay }
140e5c89e4eSSatish Balay 
141ace3abfcSBarry Smith PetscBool      PetscMemoryCollectMaximumUsage = PETSC_FALSE;
142e5c89e4eSSatish Balay PetscLogDouble PetscMemoryMaximumUsage = 0;
143e5c89e4eSSatish Balay 
144e5c89e4eSSatish Balay #undef __FUNCT__
145e5c89e4eSSatish Balay #define __FUNCT__ "PetscMemoryGetMaximumUsage"
146e30d2299SSatish Balay /*@
147e5c89e4eSSatish Balay    PetscMemoryGetMaximumUsage - Returns the maximum resident set size (memory used)
148e5c89e4eSSatish Balay    for the program.
149e5c89e4eSSatish Balay 
150e5c89e4eSSatish Balay    Not Collective
151e5c89e4eSSatish Balay 
152e5c89e4eSSatish Balay    Output Parameter:
153e5c89e4eSSatish Balay .   mem - memory usage in bytes
154e5c89e4eSSatish Balay 
155e5c89e4eSSatish Balay    Options Database Key:
156e5c89e4eSSatish Balay .  -memory_info - Print memory usage at end of run
157e5c89e4eSSatish Balay .  -malloc_log - Activate logging of memory usage
158e5c89e4eSSatish Balay 
159e5c89e4eSSatish Balay    Level: intermediate
160e5c89e4eSSatish Balay 
161e5c89e4eSSatish Balay    Notes:
162e5c89e4eSSatish Balay    The memory usage reported here includes all Fortran arrays
163e5c89e4eSSatish Balay    (that may be used in application-defined sections of code).
164e5c89e4eSSatish Balay    This routine thus provides a more complete picture of memory
165e5c89e4eSSatish Balay    usage than PetscMallocGetCurrentUsage() for codes that employ Fortran with
166e5c89e4eSSatish Balay    hardwired arrays.
167e5c89e4eSSatish Balay 
168e5c89e4eSSatish Balay .seealso: PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), PetscMallocGetCurrentUsage(),
169e5c89e4eSSatish Balay           PetscMemorySetGetMaximumUsage()
170e5c89e4eSSatish Balay 
171e5c89e4eSSatish Balay    Concepts: resident set size
172e5c89e4eSSatish Balay    Concepts: memory usage
173e5c89e4eSSatish Balay 
174e5c89e4eSSatish Balay @*/
1757087cfbeSBarry Smith PetscErrorCode  PetscMemoryGetMaximumUsage(PetscLogDouble *mem)
176e5c89e4eSSatish Balay {
177e5c89e4eSSatish Balay   PetscFunctionBegin;
178e32f2f54SBarry Smith   if (!PetscMemoryCollectMaximumUsage) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"To use this function you must first call PetscMemorySetGetMaximumUsage()");
179e5c89e4eSSatish Balay   *mem = PetscMemoryMaximumUsage;
180e5c89e4eSSatish Balay   PetscFunctionReturn(0);
181e5c89e4eSSatish Balay }
182e5c89e4eSSatish Balay 
183e5c89e4eSSatish Balay #undef __FUNCT__
184e5c89e4eSSatish Balay #define __FUNCT__ "PetscMemorySetGetMaximumUsage"
185e5c89e4eSSatish Balay /*@C
186e5c89e4eSSatish Balay    PetscMemorySetGetMaximumUsage - Tells PETSc to monitor the maximum memory usage so that
187e5c89e4eSSatish Balay        PetscMemoryGetMaximumUsage() will work.
188e5c89e4eSSatish Balay 
189e5c89e4eSSatish Balay    Not Collective
190e5c89e4eSSatish Balay 
191e5c89e4eSSatish Balay    Options Database Key:
192e5c89e4eSSatish Balay .  -memory_info - Print memory usage at end of run
193e5c89e4eSSatish Balay .  -malloc_log - Activate logging of memory usage
194e5c89e4eSSatish Balay 
195e5c89e4eSSatish Balay    Level: intermediate
196e5c89e4eSSatish Balay 
197e5c89e4eSSatish Balay .seealso: PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), PetscMallocGetCurrentUsage(),
198e5c89e4eSSatish Balay           PetscMemoryGetMaximumUsage()
199e5c89e4eSSatish Balay 
200e5c89e4eSSatish Balay    Concepts: resident set size
201e5c89e4eSSatish Balay    Concepts: memory usage
202e5c89e4eSSatish Balay 
203e5c89e4eSSatish Balay @*/
2047087cfbeSBarry Smith PetscErrorCode  PetscMemorySetGetMaximumUsage(void)
205e5c89e4eSSatish Balay {
206e5c89e4eSSatish Balay   PetscFunctionBegin;
207e5c89e4eSSatish Balay   PetscMemoryCollectMaximumUsage = PETSC_TRUE;
208e5c89e4eSSatish Balay   PetscFunctionReturn(0);
209e5c89e4eSSatish Balay }
210