Rheolef  7.1
an efficient C++ finite element environment
dis_memory_usage.cc
Go to the documentation of this file.
1 /*
22  * inspirated from:
23  * https://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-run-time-in-c
24  */
25 
26 #if defined(_WIN32)
27 #include <windows.h>
28 #include <psapi.h>
29 
30 #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
31 #include <unistd.h>
32 #include <sys/resource.h>
33 
34 #if defined(__APPLE__) && defined(__MACH__)
35 #include <mach/mach.h>
36 
37 #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
38 #include <fcntl.h>
39 #include <procfs.h>
40 
41 #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
42 #include <stdio.h>
43 
44 #endif
45 
46 #else
47 #error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS."
48 #endif
49 
50 namespace rheolef {
58 {
59 #if defined(_WIN32)
60  /* Windows -------------------------------------------------- */
61  PROCESS_MEMORY_COUNTERS info;
62  GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
63  return (size_t)info.PeakWorkingSetSize;
64 
65 #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
66  /* AIX and Solaris ------------------------------------------ */
67  struct psinfo psinfo;
68  int fd = -1;
69  if ( (fd = open( "/proc/self/psinfo", O_RDONLY )) == -1 )
70  return (size_t)0L; /* Can't open? */
71  if ( read( fd, &psinfo, sizeof(psinfo) ) != sizeof(psinfo) )
72  {
73  close( fd );
74  return (size_t)0L; /* Can't read? */
75  }
76  close( fd );
77  return (size_t)(psinfo.pr_rssize * 1024L);
78 
79 #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
80  /* BSD, Linux, and OSX -------------------------------------- */
81  struct rusage rusage;
82  getrusage( RUSAGE_SELF, &rusage );
83 #if defined(__APPLE__) && defined(__MACH__)
84  return (size_t)rusage.ru_maxrss;
85 #else
86  return (size_t)(rusage.ru_maxrss * 1024L);
87 #endif
88 
89 #else
90  /* Unknown OS ----------------------------------------------- */
91  return (size_t)0L; /* Unsupported. */
92 #endif
93 }
94 
95 } // namespace rheolef
96 
102 namespace rheolef {
104 {
105 #if defined(_WIN32)
106  /* Windows -------------------------------------------------- */
107  PROCESS_MEMORY_COUNTERS info;
108  GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
109  return (size_t)info.WorkingSetSize;
110 
111 #elif defined(__APPLE__) && defined(__MACH__)
112  /* OSX ------------------------------------------------------ */
113  struct mach_task_basic_info info;
114  mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
115  if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO,
116  (task_info_t)&info, &infoCount ) != KERN_SUCCESS )
117  return (size_t)0L; /* Can't access? */
118  return (size_t)info.resident_size;
119 
120 #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
121  /* Linux ---------------------------------------------------- */
122  long rss = 0L;
123  FILE* fp = NULL;
124  if ( (fp = fopen( "/proc/self/statm", "r" )) == NULL )
125  return (size_t)0L; /* Can't open? */
126  if ( fscanf( fp, "%*s%ld", &rss ) != 1 )
127  {
128  fclose( fp );
129  return (size_t)0L; /* Can't read? */
130  }
131  fclose( fp );
132  return (size_t)rss * (size_t)sysconf( _SC_PAGESIZE);
133 
134 #else
135  /* AIX, BSD, Solaris, and Unknown OS ------------------------ */
136  return (size_t)0L; /* Unsupported. */
137 #endif
138 }
139 } // namespace rheolef
140 /*
141  * http://nadeausoftware.com/articles/2012/09/c_c_tip_how_get_physical_memory_size_system
142  *
143  * Author: David Robert Nadeau
144  * Site: http://NadeauSoftware.com/
145  * License: Creative Commons Attribution 3.0 Unported License
146  * http://creativecommons.org/licenses/by/3.0/deed.en_US
147  */
148 
149 #if defined(_WIN32)
150 #include <Windows.h>
151 
152 #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
153 #include <unistd.h>
154 #include <sys/types.h>
155 #include <sys/param.h>
156 #if defined(BSD)
157 #include <sys/sysctl.h>
158 #endif
159 
160 #else
161 #error "Unable to define getMemorySize( ) for an unknown OS."
162 #endif
163 
164 
165 
169 namespace rheolef {
170 size_t memory_size()
171 {
172 #if defined(_WIN32) && (defined(__CYGWIN__) || defined(__CYGWIN32__))
173  /* Cygwin under Windows. ------------------------------------ */
174  /* New 64-bit MEMORYSTATUSEX isn't available. Use old 32.bit */
175  MEMORYSTATUS status;
176  status.dwLength = sizeof(status);
177  GlobalMemoryStatus( &status );
178  return (size_t)status.dwTotalPhys;
179 
180 #elif defined(_WIN32)
181  /* Windows. ------------------------------------------------- */
182  /* Use new 64-bit MEMORYSTATUSEX, not old 32-bit MEMORYSTATUS */
183  MEMORYSTATUSEX status;
184  status.dwLength = sizeof(status);
185  GlobalMemoryStatusEx( &status );
186  return (size_t)status.ullTotalPhys;
187 
188 #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
189  /* UNIX variants. ------------------------------------------- */
190  /* Prefer sysctl() over sysconf() except sysctl() HW_REALMEM and HW_PHYSMEM */
191 
192 #if defined(CTL_HW) && (defined(HW_MEMSIZE) || defined(HW_PHYSMEM64))
193  int mib[2];
194  mib[0] = CTL_HW;
195 #if defined(HW_MEMSIZE)
196  mib[1] = HW_MEMSIZE; /* OSX. --------------------- */
197 #elif defined(HW_PHYSMEM64)
198  mib[1] = HW_PHYSMEM64; /* NetBSD, OpenBSD. --------- */
199 #endif
200  int64_t size = 0; /* 64-bit */
201  size_t len = sizeof( size );
202  if ( sysctl( mib, 2, &size, &len, NULL, 0 ) == 0 )
203  return (size_t)size;
204  return 0L; /* Failed? */
205 
206 #elif defined(_SC_AIX_REALMEM)
207  /* AIX. ----------------------------------------------------- */
208  return (size_t)sysconf( _SC_AIX_REALMEM ) * (size_t)1024L;
209 
210 #elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
211  /* FreeBSD, Linux, OpenBSD, and Solaris. -------------------- */
212  return (size_t)sysconf( _SC_PHYS_PAGES ) *
213  (size_t)sysconf( _SC_PAGESIZE );
214 
215 #elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGE_SIZE)
216  /* Legacy. -------------------------------------------------- */
217  return (size_t)sysconf( _SC_PHYS_PAGES ) *
218  (size_t)sysconf( _SC_PAGE_SIZE );
219 
220 #elif defined(CTL_HW) && (defined(HW_PHYSMEM) || defined(HW_REALMEM))
221  /* DragonFly BSD, FreeBSD, NetBSD, OpenBSD, and OSX. -------- */
222  int mib[2];
223  mib[0] = CTL_HW;
224 #if defined(HW_REALMEM)
225  mib[1] = HW_REALMEM; /* FreeBSD. ----------------- */
226 #elif defined(HW_PYSMEM)
227  mib[1] = HW_PHYSMEM; /* Others. ------------------ */
228 #endif
229  unsigned int size = 0; /* 32-bit */
230  size_t len = sizeof( size );
231  if ( sysctl( mib, 2, &size, &len, NULL, 0 ) == 0 )
232  return (size_t)size;
233  return 0L; /* Failed? */
234 #endif /* sysctl and sysconf variants */
235 
236 #else
237  return 0L; /* Unknown OS. */
238 #endif
239 }
240 } // namespace rheolef
241 
242 #include "rheolef/distributed.h"
243 
244 /*
245  * extends to distributed memory: sum all
246  * Author: Pierre.Saramito@imag.fr
247  * License: GPL
248  */
249 
250 namespace rheolef {
251 #ifndef _RHEOLEF_HAVE_MPI
252 size_t dis_memory_usage() { return seq_memory_usage(); }
253 size_t dis_peak_memory_usage() { return seq_peak_memory_usage(); }
254 #else // _RHEOLEF_HAVE_MPI
256  size_t local_mem = seq_memory_usage();
257  if (! (mpi::environment::initialized() && !mpi::environment::finalized())) {
258  return local_mem;
259  }
260  return rheolef::mpi::all_reduce (rheolef::communicator(), local_mem, std::plus<size_t>());
261 }
263  size_t local_mem = seq_peak_memory_usage();
264  if (! (mpi::environment::initialized() && !mpi::environment::finalized())) {
265  return local_mem;
266  }
267  return rheolef::mpi::all_reduce (rheolef::communicator(), local_mem, std::plus<size_t>());
268 }
269 #endif // _RHEOLEF_HAVE_MPI
270 } // namespace rheolef
rheolef::dis_peak_memory_usage
size_t dis_peak_memory_usage()
Definition: dis_memory_usage.cc:262
rheolef::seq_memory_usage
size_t seq_memory_usage()
Definition: dis_memory_usage.cc:103
rheolef::seq_peak_memory_usage
size_t seq_peak_memory_usage()
Definition: dis_memory_usage.cc:57
rheolef
This file is part of Rheolef.
Definition: compiler_eigen.h:37
mkgeo_obstacle.L
string L
Definition: mkgeo_obstacle.sh:133
rheolef::memory_size
size_t memory_size()
Definition: dis_memory_usage.cc:170
rheolef::dis_memory_usage
size_t dis_memory_usage()
Definition: dis_memory_usage.cc:255
mkgeo_contraction.status
status
Definition: mkgeo_contraction.sh:290