NAMD
memusage.C
Go to the documentation of this file.
1 
7 #include "memusage.h"
8 #include "converse.h"
9 #ifndef WIN32
10 #include <stdio.h>
11 #include <sys/types.h>
12 #include <unistd.h>
13 #else
14 namespace {
15  int sbrk(int) { return 0; }
16 }
17 #endif
18 
19 int memusageinit::initialized;
20 unsigned long memusageinit::sbrkval;
21 
23  if ( initialized == 0 ) {
24  sbrkval = (unsigned long) sbrk(0);
25  initialized = 1;
26  }
27 }
28 
29 unsigned long memusageinit::memusage_sbrk() {
30  unsigned long newval = (unsigned long) sbrk(0);
31  return ( newval - memusageinit::sbrkval );
32 }
33 
34 
35 #ifdef WIN32
36 #define MEMUSAGE_USE_SBRK
37 #endif
38 
39 #ifdef _NO_MALLOC_H
40 #define NO_MALLINFO
41 #endif
42 
43 #ifdef MEMUSAGE_USE_SBRK
44 #define NO_MALLINFO
45 #define NO_PS
46 #endif
47 
48 
49 #ifdef MEMUSAGE_USE_MSTATS
50 
51 #include <malloc/malloc.h>
52 
53 unsigned long memusage_mstats() {
54  struct mstats ms = mstats();
55  unsigned long memtotal = ms.bytes_used;
56  return memtotal;
57 }
58 
59 #else
60 inline unsigned long memusage_mstats() { return 0; }
61 #endif
62 
63 
64 #ifndef NO_MALLINFO
65 
66 #include <malloc.h>
67 
68 unsigned long memusage_mallinfo() {
69  struct mallinfo mi = mallinfo();
70  // unsigned long memtotal = mi.usmblks + mi.uordblks + mi.hblkhd;
71  unsigned long memtotal = (unsigned int) mi.uordblks;
72  unsigned long memtotal2 = (unsigned int) mi.usmblks;
73  memtotal2 += (unsigned int) mi.hblkhd;
74  if ( memtotal2 > memtotal ) memtotal = memtotal2;
75 
76  // printf("mallinfo %d %d %d\n", mi.usmblks, mi.uordblks, mi.hblkhd);
77 
78  return memtotal;
79 }
80 
81 #else
82 inline unsigned long memusage_mallinfo() { return 0; }
83 #endif
84 
85 
86 inline unsigned long memusage_ps() {
87 #ifdef NO_PS
88  return 0;
89 #else
90  char pscmd[100];
91 #if defined(NAMD_CUDA) || defined(NAMD_MIC)
92  sprintf(pscmd, "/bin/ps -o rss= -p %d", getpid());
93 #else
94  sprintf(pscmd, "/bin/ps -o vsz= -p %d", getpid());
95 #endif
96  unsigned long vsz = 0;
97  FILE *p = popen(pscmd, "r");
98  if ( p ) {
99  fscanf(p, "%ld", &vsz);
100  pclose(p);
101  }
102  return ( vsz * (unsigned long) 1024 );
103 #endif
104 }
105 
106 #if CMK_BLUEGENEQ
107 /* Report the memusage according to
108  * https://wiki.alcf.anl.gov/parts/index.php/Blue_Gene/Q#CNK_Memory_Information
109  */
110 #include <spi/include/kernel/memory.h>
111 inline long long memusage_bgq(){
112  uint64_t heap;
113  Kernel_GetMemorySize(KERNEL_MEMSIZE_HEAP, &heap);
114  return heap;
115 }
116 #endif
117 
118 #if CMK_BLUEGENEP
119 /* Report the memusage according to
120  * http://www.alcf.anl.gov/resource-guides/determining-memory-use
121  */
122 #include <malloc.h>
123 inline long long memusage_bgp(){
124  struct mallinfo m = mallinfo();
125  long long hblkhd = (unsigned int) m.hblkhd;
126  long long uordblks = (unsigned int) m.uordblks;
127  return hblkhd + uordblks;
128 }
129 #endif
130 
131 inline unsigned long memusage_proc_self_stat() {
132 #ifdef NO_PS
133  return 0;
134 #else
135  static int failed_once = 0;
136  if ( failed_once ) return 0; // no point in retrying
137 
138  FILE *f = fopen("/proc/self/stat","r");
139  if ( ! f ) { failed_once = 1; return 0; }
140  for ( int i=0; i<22; ++i ) fscanf(f,"%*s");
141 #if defined(NAMD_CUDA) || defined(NAMD_MIC)
142  // skip vss, next value is rss in pages
143  fscanf(f,"%*s");
144 #endif
145  unsigned long vsz = 0; // should remain 0 on failure
146  fscanf(f,"%lu",&vsz);
147  fclose(f);
148 #if defined(NAMD_CUDA) || defined(NAMD_MIC)
149  vsz *= sysconf(_SC_PAGESIZE);
150 #endif
151  if ( ! vsz ) failed_once = 1;
152  // printf("/proc/self/stat reports %d MB\n", vsz/(1024*1024));
153  return vsz;
154 #endif
155 }
156 
157 
158 unsigned long memusage(const char **source) {
159 
160  unsigned long memtotal = 0;
161  const char* s = "ERROR";
162 
163  if ( ! CmiMemoryIs(CMI_MEMORY_IS_OS) ) {
164  memtotal = CmiMemoryUsage(); s = "CmiMemoryUsage";
165  }
166 
167 #if CMK_BLUEGENEQ
168  if( ! memtotal) { memtotal = memusage_bgq(); s="Kernel_GetMemorySize on BG/Q"; }
169 #endif
170 
171 #if CMK_BLUEGENEP
172  if( ! memtotal) { memtotal = memusage_bgp(); s="mallinfo on BG/P"; }
173 #endif
174 
175 #if defined(WIN32) && !defined(__CYGWIN__)
176  if ( ! memtotal ) {
177  memtotal = CmiMemoryUsage(); s = "GetProcessMemoryInfo";
178  }
179 #endif
180 
181  if ( ! memtotal ) {
182  memtotal = memusage_proc_self_stat(); s = "/proc/self/stat";
183  }
184 
185  if ( ! memtotal ) { memtotal = memusage_mstats(); s = "mstats"; }
186 
187  if ( ! memtotal ) { memtotal = memusage_mallinfo(); s = "mallinfo"; }
188 
189  if ( ! memtotal ) { memtotal = memusageinit::memusage_sbrk(); s = "sbrk"; }
190 
191  if ( ! memtotal ) { memtotal = memusage_ps(); s = "ps"; }
192 
193  if ( ! memtotal ) { memtotal = CmiMemoryUsage(); s = "CmiMemoryUsage"; }
194 
195  if ( ! memtotal ) s = "nothing";
196 
197  if ( source ) *source = s;
198 
199  return memtotal;
200 
201 }
202 
unsigned long memusage_mallinfo()
Definition: memusage.C:68
if(ComputeNonbondedUtil::goMethod==2)
unsigned long memusage_ps()
Definition: memusage.C:86
unsigned long memusage_proc_self_stat()
Definition: memusage.C:131
memusageinit()
Definition: memusage.C:22
unsigned long memusage(const char **source)
Definition: memusage.C:158
unsigned long memusage_mstats()
Definition: memusage.C:60