Peano 4
Loading...
Searching...
No Matches
Statistics.cpp
Go to the documentation of this file.
1#include "Statistics.h"
2#include "tarch/Assertions.h"
4#include "tarch/mpi/Rank.h"
5
7
8#include <fstream>
9
10
12tarch::logging::Log tarch::logging::Statistics::_log( "tarch::logging::Statistics" );
14
15
20
21
22
24 _maxCountInBetweenTwoMeasurements(1000),
25 _maxTimeInBetweenTwoMeasurements(1.0),
26 _globalWatch( "tarch::logging::Statistics", "Statistics", false) {
27}
28
29
30
32 _watch("tarch::logging::Statistics", "Statistics", false),
33 _counter(0) {
34}
35
36
38 _watch("tarch::logging::Statistics", "Statistics", false),
39 _counter(0) {
40 _data.push_back( std::make_tuple(time,0.0,0.0,0.0,0) );
41}
42
43
45 double lastValueFromPreviousSnapshot = std::get<1>( _data.back() );
46 _data.push_back( std::make_tuple(
47 time,
48 lastValueFromPreviousSnapshot,
49 lastValueFromPreviousSnapshot,
50 lastValueFromPreviousSnapshot,
51 0
52 ));
53}
54
55
59
60
61bool tarch::logging::Statistics::acceptNewData(const std::string& identifier, bool disableSampling) {
62 _dataSetMap[identifier]._counter++;
63 _dataSetMap[identifier]._watch.stop();
64
65 bool result = false;
66
67 if (
68 disableSampling
69 ) {
70 result = true;
71 }
72 else if (
73 _dataSetMap[identifier]._data.size()>1
74 and
75 std::get<1>( _dataSetMap[identifier]._data[_dataSetMap[identifier]._data.size()-1] ) == std::get<1>( _dataSetMap[identifier]._data[_dataSetMap[identifier]._data.size()-2] )
76 ) {
77 result = false;
78 }
79 else if (
81 or
82 _dataSetMap[identifier]._watch.getCalendarTime() > _maxTimeInBetweenTwoMeasurements
83 ) {
84 result = true;
85 }
86
87 if (result) {
88 _dataSetMap[identifier]._counter = 0;
89 _dataSetMap[identifier]._watch.start();
90 return true;
91 }
92 else return false;
93}
94
95
96void tarch::logging::Statistics::initData(const std::string& identifier) {
97 if ( _dataSetMap.count( identifier )==0 ) {
99 double t = _globalWatch.getCalendarTime();
100
101 _dataSetMap.insert( std::pair<std::string,DataSet>( identifier, DataSet(t) ));
102 }
103}
104
105
106void tarch::logging::Statistics::updateDataSnapshot(const std::string& identifier, double value) {
107 assertion( _dataSetMap.count( identifier )==1 );
108 std::get<1>( _dataSetMap[identifier]._data.back() ) = value;
109 std::get<2>( _dataSetMap[identifier]._data.back() ) = std::min(std::get<2>( _dataSetMap[identifier]._data.back() ), value);
110 std::get<3>( _dataSetMap[identifier]._data.back() ) = std::max(std::get<3>( _dataSetMap[identifier]._data.back() ), value);
111 std::get<4>( _dataSetMap[identifier]._data.back() ) = 1 + std::get<4>( _dataSetMap[identifier]._data.back() );
112}
113
114
115#ifdef TrackStatistics
116void tarch::logging::Statistics::log( const std::string& identifier, const std::string& value ) {
118 if ( _logMessageMap.count( identifier )==0 ) {
119 _logMessageMap.insert( std::pair< std::string, LogMessage >( identifier, LogMessage() ) );
120 }
121
123 double t = _globalWatch.getCalendarTime();
124
125 _logMessageMap[identifier]._data.push_back( std::tuple<double,std::string>(t,value) );
126}
127
128
129void tarch::logging::Statistics::log( const std::string& identifier, double value, bool disableSampling ) {
131 initData(identifier);
132 updateDataSnapshot(identifier,value);
133 if ( acceptNewData(identifier, disableSampling) ) {
135 double t = _globalWatch.getCalendarTime();
136 logDebug( "log(string,double)", identifier << "=" << value );
137 _dataSetMap[identifier].createNewSnapshot(t);
138 }
139}
140
141
142void tarch::logging::Statistics::inc( const std::string& identifier, double value, bool disableSampling ) {
144 initData( identifier );
145
146 double newValue = std::get<1>( _dataSetMap[identifier]._data.back() ) + value;
147 updateDataSnapshot(identifier,newValue);
148
149 if ( acceptNewData(identifier, disableSampling) ) {
151 double t = _globalWatch.getCalendarTime();
152 _dataSetMap[identifier].createNewSnapshot(t);
153 }
154}
155#endif
156
157
158void tarch::logging::Statistics::writeToCSV( [[maybe_unused]] std::string filename ) {
159#ifdef TrackStatistics
160 logDebug( "writeToCSV(string)", "start to dump statistics into file " << filename );
161
162 if (tarch::mpi::Rank::getInstance().getNumberOfRanks()>0 ) {
163 filename += "-rank-" + std::to_string( tarch::mpi::Rank::getInstance().getRank() );
164 }
165
166 filename += ".csv";
167
168 // only for stats
169 int totalNumberOfEntries = 0;
170 for (auto& p: _dataSetMap) {
171 totalNumberOfEntries += p.second._data.size();
172 }
173 for (auto& p: _logMessageMap) {
174 totalNumberOfEntries += p.second._data.size();
175 }
176 logInfo( "writeToCSV(string)", "write statistics to file " << filename << " (total no of entries=" << totalNumberOfEntries << ")" );
177
178 std::ofstream file( filename );
179 file << "t";
180 for (auto& p: _dataSetMap) {
181 file << ", " << p.first;
182 }
183 for (auto& p: _logMessageMap) {
184 file << ", " << p.first;
185 }
186 file << std::endl;
187
188 double t = 0.0;
189 while (t<std::numeric_limits<double>::max()) {
190 // find minimum time stamp over both types of logs
191 t = std::numeric_limits<double>::max();
192
193 auto computeT = [&](double currentT) {
194 t = std::min( t, currentT );
195 };
196
197 for (auto& p: _dataSetMap) {
198 if (not p.second._data.empty()) {
199 computeT( std::get<0>(p.second._data.front()) );
200 }
201 }
202 for (auto& p: _logMessageMap) {
203 if (not p.second._data.empty()) {
204 computeT( std::get<0>(p.second._data.front()) );
205 }
206 }
207
208 // plot data. If an entry is a fit, remove it from sequence
209 if (t<std::numeric_limits<double>::max()) {
210 file << t;
211 for (auto& p: _dataSetMap) {
212 if (
213 not p.second._data.empty()
214 and
215 tarch::la::smallerEquals( std::get<0>(p.second._data.front()), t )
216 ) {
217 file << ", (" << std::get<1>(p.second._data.front())
218 << "/" << std::get<2>(p.second._data.front())
219 << "/" << std::get<3>(p.second._data.front())
220 << "/#" << std::get<4>(p.second._data.front())
221 << ")";
222 p.second._data.erase(p.second._data.begin());
223 }
224 else {
225 file << ", ";
226 }
227 }
228 for (auto& pp: _logMessageMap) {
229 if (
230 not pp.second._data.empty()
231 and
232 tarch::la::smallerEquals( std::get<0>(pp.second._data.front()), t )
233 ) {
234 file << ", \"" << std::get<1>(pp.second._data.front()) << "\" ";
235 pp.second._data.erase(pp.second._data.begin());
236 file << ", ";
237 }
238 else {
239 file << ", ";
240 }
241 }
242 }
243 file << std::endl;
244 }
245
246 // clear maps. Within this clear, I get seg faults on some computers when the program terminates
247 _dataSetMap.clear();
248 _logMessageMap.clear();
249
250 // close output file
251 file.close();
252 #else
253 logWarning( "writeToCSV(string)", "no statistics available. Recompile with -DTrackStatistics for runtime sampling" );
254 #endif
255}
#define assertion(expr)
#define logDebug(methodName, logMacroMessageStream)
Definition Log.h:50
#define logWarning(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:440
#define logInfo(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:411
Log Device.
Definition Log.h:516
Global statistics interface.
Definition Statistics.h:72
void inc(const std::string &identifier, double value=1.0, bool disableSampling=false)
Definition Statistics.h:92
tarch::timing::Watch _globalWatch
Definition Statistics.h:141
void log(const std::string &identifier, double value, bool disableSampling=false)
Log one particular value.
Definition Statistics.h:90
std::map< std::string, LogMessage > _logMessageMap
Definition Statistics.h:178
void updateDataSnapshot(const std::string &identifier, double value)
Updates snapshot.
void initData(const std::string &identifier)
Ensures that dataset is there.
void writeToCSV(std::string filename="statistics")
Write data to csv file.
std::map< std::string, DataSet > _dataSetMap
Mapping from identifier who wrote stats (key) onto DataSet.
Definition Statistics.h:177
static tarch::multicore::BooleanSemaphore _semaphore
Definition Statistics.h:136
static Statistics _singleton
Definition Statistics.h:132
bool acceptNewData(const std::string &identifier, bool disableSampling)
Not const, as it also updates the internal counters.
static Statistics & getInstance()
This is not the canonical realisation of singletons as I use it usually for stats in Peano.
static Rank & getInstance()
This operation returns the singleton instance.
Definition Rank.cpp:538
Create a lock around a boolean semaphore region.
Definition Lock.h:19
double getCalendarTime()
This method returns the elapsed calendar time between the start and stop command of the timer,...
Definition Watch.cpp:74
void stop()
Stop timer.
Definition Watch.cpp:55
bool smallerEquals(double lhs, double rhs, double tolerance=NUMERICAL_ZERO_DIFFERENCE)
One data set for one type (identifier) of statistics.
Definition Statistics.h:153
DataSet()
As we hold data sets within a map, we need a default constructor.
std::vector< std::tuple< double, double, double, double, int > > _data
Definition Statistics.h:159