OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
IpplMemoryUsage.cpp
Go to the documentation of this file.
1 //
2 // Class IpplMemoryUsage
3 // A simple singleton class which lets the user watch the memory consumption of a program.
4 // ATTENTION: We use following memory convention
5 //
6 // 8 bit = 1 byte = 1e-3 kB = 1e-6 MB
7 // = 1e-3 / 1.024 KiB (KibiByte)
8 // = 1e-3 / 1.024 / 1.024 MiB (MebiByte)
9 //
10 // instead of the usually taken but wrong relation 1024 kB = 1 MB.
11 //
12 // General usage
13 // 1) create the instance using IpplMemoryUsage::getInstance(unit, reset).
14 // The reset boolean indicates wether the memory at creation should be
15 // subtracted from the measurements later on.
16 // The class is based on t getrusage() that returns the memory
17 // consumption in kB (KiloByte). You can specify the return value of
18 // IpplMemoryUsage by the first argument.
19 // Although one can use those input parameters they are only applied
20 // at the first call. Additional calls with different input do NOT
21 // modify the instance.
22 // 2) At any point in the program you can call IpplMemoryUsage::sample()
23 // to collect the data.
24 //
25 // Copyright (c) 2017 - 2018, Matthias Frey, Paul Scherrer Institut, Villigen PSI, Switzerland
26 // All rights reserved
27 //
28 // Implemented as part of the PhD thesis
29 // "Precise Simulations of Multibunches in High Intensity Cyclotrons"
30 //
31 // This file is part of OPAL.
32 //
33 // OPAL is free software: you can redistribute it and/or modify
34 // it under the terms of the GNU General Public License as published by
35 // the Free Software Foundation, either version 3 of the License, or
36 // (at your option) any later version.
37 //
38 // You should have received a copy of the GNU General Public License
39 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
40 //
42 
43 #include "Message/GlobalComm.h"
44 #include "Utility/IpplInfo.h"
45 
48 { }
49 
50 
52  : who_m(RUSAGE_SELF)
53 {
54  globalMemPerCore_m = std::unique_ptr<double[]>(new double[Ippl::getNodes()]);
55 
56  switch ( unit ) {
57  case Unit::BIT:
58  conversion_factor_m = 8.0e3;
59  unit_m = "bit";
60  break;
61  case Unit::B:
62  conversion_factor_m = 1.0e3;
63  unit_m = "B";
64  break;
65  case Unit::KB:
66  conversion_factor_m = 1.0;
67  unit_m = "kB";
68  break;
69  case Unit::KiB:
70  conversion_factor_m = 1.0 / 1.024;
71  unit_m = "KiB";
72  break;
73  case Unit::MB:
74  conversion_factor_m = 1.0e-3;
75  unit_m = "MB";
76  break;
77  case Unit::MiB:
78  conversion_factor_m = 1.0 / (1.024 * 1024.0);
79  unit_m = "MiB";
80  break;
81  case Unit::GiB:
82  conversion_factor_m = 1.0 / (1.024 * 1024.0 * 1024.0);
83  unit_m = "GiB";
84  break;
85  case Unit::GB:
86  default:
87  conversion_factor_m = 1.0e-6;
88  unit_m = "GB";
89  break;
90  }
91 
92  initial_memory_m = 0.0;
93  if ( reset ) {
94  this->sample_m();
96  }
97 }
98 
99 
101  bool reset)
102 {
103  static IpplMemory_t instance_mp = IpplMemory_t(new IpplMemoryUsage(unit, reset));
104  return instance_mp.get();
105 }
106 
107 
108 double IpplMemoryUsage::getMemoryUsage(int core) const {
109  return globalMemPerCore_m[core];
110 }
111 
112 
114  // update max_rss_m
115  this->sample_m();
116 
117  for(int i = 0; i < Ippl::getNodes(); i++)
118  globalMemPerCore_m[i] = 0;
119 
120  double localMemPerCore = max_rss_m;
121 
122  gather(&localMemPerCore, &globalMemPerCore_m[0], 1);
123 }
124 
125 
126 const std::string& IpplMemoryUsage::getUnit() const {
127  return unit_m;
128 }
129 
130 
132  rusage usage;
133  if ( getrusage(who_m, &usage) == -1 )
134  throw std::runtime_error(
135  "IpplMemoryUsage::sample_m(): Error in collecting memory!");
136 
137  max_rss_m = usage.ru_maxrss * conversion_factor_m - initial_memory_m;
138 }
void gather(const T *input, T *output, int count, int root=0)
Definition: GlobalComm.hpp:449
static int getNodes()
Definition: IpplInfo.cpp:670
const std::string & getUnit() const
static IpplMemory_p getInstance(Unit unit=Unit::GB, bool reset=true)
static IpplMemory_t instance_mp
*this
double getMemoryUsage(int core) const
double max_rss_m
max. resident set size [GB] or [GiB]
double conversion_factor_m
to various units. getrusage() returns in kB
std::unique_ptr< double[]> globalMemPerCore_m
memory of all cores
std::unique_ptr< IpplMemoryUsage > IpplMemory_t
std::string unit_m
what's the unit of the memory
double who_m
RUSAGE_SELF, RUSAGE_CHILDREN (, RUSAGE_THREAD)
double initial_memory_m
memory usage at construction time [GB] or [GiB]