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