xerus
a general purpose tensor library
performanceData.cpp
Go to the documentation of this file.
1 // Xerus - A General Purpose Tensor Library
2 // Copyright (C) 2014-2017 Benjamin Huber and Sebastian Wolf.
3 //
4 // Xerus is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as published
6 // by the Free Software Foundation, either version 3 of the License,
7 // or (at your option) any later version.
8 //
9 // Xerus is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
13 //
14 // You should have received a copy of the GNU Affero General Public License
15 // along with Xerus. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // For further information on Xerus visit https://libXerus.org
18 // or contact us at contact@libXerus.org.
19 
25 #include <string>
26 #include <fstream>
27 #include <xerus/ttNetwork.h>
28 #include <xerus/performanceData.h>
29 #include <xerus/misc/internal.h>
30 
31 
32 namespace xerus {
33 
34  void PerformanceData::add(const size_t _itrCount, const xerus::value_t _residual, const std::vector<size_t> _ranks, const size_t _flags) {
35  if (active) {
36  if (startTime == ~0ul) {
37  start();
38  }
39  data.emplace_back(_itrCount, get_elapsed_time(), _residual, 0.0, _ranks, _flags);
40 
41  if(printProgress) {
42  LOG_SHORT(PerformanceData, "Iteration " << std::setw(4) << std::setfill(' ') << _itrCount
43  << " Time: " << std::right << std::setw(6) << std::setfill(' ') << std::fixed << std::setprecision(2) << double(data.back().elapsedTime)*1e-6
44  << "s Residual: " << std::setw(11) << std::setfill(' ') << std::scientific << std::setprecision(6) << data.back().residual
45  << " Flags: " << _flags << " Ranks: " << _ranks);
46  }
47  }
48  }
49 
50  void PerformanceData::add(const size_t _itrCount, const xerus::value_t _residual, const TTTensor& _x, const size_t _flags) {
51  if(!errorFunction) { add(_itrCount, _residual, _x.ranks(), _flags); return; }
52 
53  if (active) {
54  if (startTime == ~0ul) {
55  start();
56  }
57  stop_timer();
58 
59  data.emplace_back(_itrCount, get_elapsed_time(), _residual, errorFunction(_x), _x.ranks(), _flags);
60 
61  if (printProgress) {
62  LOG_SHORT(PerformanceData, "Iteration " << std::setw(4) << std::setfill(' ') << _itrCount
63  << " Time: " << std::right << std::setw(6) << std::setfill(' ') << std::fixed << std::setprecision(2) << double(data.back().elapsedTime)*1e-6
64  << "s Residual: " << std::setw(11) << std::setfill(' ') << std::scientific << std::setprecision(6) << data.back().residual
65  << " Error: " << std::setw(11) << std::setfill(' ') << std::scientific << std::setprecision(6) << data.back().error
66  << " Flags: " << _flags << " Ranks: " << _x.ranks()); // NOTE using data.back().ranks causes segmentation fault in gcc
67  }
69  }
70  }
71 
72  void PerformanceData::add(const xerus::value_t _residual, const TensorNetwork::RankTuple _ranks, const size_t _flags) {
73  if (active) {
74  if (data.empty()) {
75  add(0, _residual, _ranks, _flags);
76  } else {
77  add(data.back().iterationCount+1, _residual, _ranks, _flags);
78  }
79  }
80  }
81 
82  void PerformanceData::add(const value_t _residual, const TTTensor& _x, const size_t _flags) {
83  if (active) {
84  if (data.empty()) {
85  add(0, _residual, _x, _flags);
86  } else {
87  add(data.back().iterationCount+1, _residual, _x, _flags);
88  }
89  }
90  }
91 
92  void PerformanceData::dump_to_file(const std::string &_fileName) const {
93  std::string header;
94  header += "# ";
95  header += additionalInformation;
96  misc::replace(header, "\n", "\n# ");
97  header += "\n# \n#itr \ttime[us] \tresidual \terror \tflags \tranks...\n";
98  std::ofstream out(_fileName);
99  out << header;
100  for (const DataPoint &d : data) {
101  out << d.iterationCount << '\t' << d.elapsedTime << '\t' << d.residual << '\t' << d.error << '\t' << d.flags;
102  for (size_t r : d.ranks) {
103  out << '\t' << r;
104  }
105  out << '\n';
106  }
107  out.close();
108  }
109 
110  misc::LogHistogram PerformanceData::get_histogram(const xerus::value_t _base, bool _assumeConvergence) const {
111  misc::LogHistogram hist(_base);
112  std::vector<PerformanceData::DataPoint> convergenceData(data);
113  if (_assumeConvergence) {
114  value_t finalResidual = data.back().residual;
115  convergenceData.pop_back();
116  for (auto &p : convergenceData) {
117  p.residual -= finalResidual;
118  }
119  }
120 
121  for (size_t i = 1; i<convergenceData.size(); ++i) {
122  if (convergenceData[i].residual <= 0 || convergenceData[i-1].residual <= 0
123  || convergenceData[i].residual >= convergenceData[i-1].residual) {
124  continue;
125  }
126 
127  // assume x_2 = x_1 * 2^(-alpha * delta-t)
128  value_t relativeChange = convergenceData[i].residual/convergenceData[i-1].residual;
129  value_t exponent = log(relativeChange) / log(2);
130  size_t delta_t = convergenceData[i].elapsedTime - convergenceData[i-1].elapsedTime;
131  if (delta_t == 0) {
132  LOG(warning, "approximated 0us by 1us");
133  delta_t = 1;
134  }
135  value_t rate = - exponent / value_t(delta_t);
136  REQUIRE(std::isfinite(rate), "infinite rate? " << relativeChange << " " << exponent << " " << delta_t << " " << rate);
137  hist.add(rate, delta_t);
138  }
139  return hist;
140  }
141 
142  PerformanceData NoPerfData(false, false);
143 } // namespace xerus
size_t get_elapsed_time() const
Header file for the TTNetwork class (and thus TTTensor and TTOperator).
#define REQUIRE
Definition: internal.h:33
#define LOG
Definition: internal.h:38
The main namespace of xerus.
Definition: basic.h:37
std::string additionalInformation
Storage class for the performance data collected during an algorithm (typically iteration count...
std::vector< size_t > ranks() const
Gets the ranks of the TTNetwork.
Definition: ttNetwork.cpp:717
std::vector< DataPoint > data
Header file for comfort functions and macros that should not be exported in the library.
#define LOG_SHORT
Definition: internal.h:39
PerformanceData NoPerfData
double value_t
The type of values to be used by xerus.
Definition: basic.h:43
void dump_to_file(const std::string &_fileName) const
std::vector< size_t > RankTuple
: Represention of the ranks of a TensorNetwork.
Definition: tensorNetwork.h:45
A logarithmic histogram, i.e. the size of all buckets is given by a constant factor [x - x*base) ...
Definition: histogram.h:37
ErrorFunction errorFunction
void add(double _value, size_t _count=1)
Definition: histogram.cpp:42
Header file for the PerformanceData class.
misc::LogHistogram get_histogram(const value_t _base, bool _assumeConvergence=false) const
void replace(std::string &_string, const std::string &_search, const std::string &_replace)
: Replaces all occurences of _search in _string by _replace.
void add(const size_t _itrCount, const value_t _residual, const TensorNetwork::RankTuple _ranks=TensorNetwork::RankTuple(), const size_t _flags=0)