performanceData.h 4.51 KB
Newer Older
Benjamin Huber's avatar
Benjamin Huber committed
1
// Xerus - A General Purpose Tensor Library
2
// Copyright (C) 2014-2017 Benjamin Huber and Sebastian Wolf. 
Benjamin Huber's avatar
Benjamin Huber committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// 
// Xerus is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
// 
// Xerus is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
// 
// You should have received a copy of the GNU Affero General Public License
// along with Xerus. If not, see <http://www.gnu.org/licenses/>.
//
// For further information on Xerus visit https://libXerus.org 
// or contact us at contact@libXerus.org.

/**
21 22 23
* @file
* @brief Header file for the PerformanceData class.
*/
Benjamin Huber's avatar
Benjamin Huber committed
24 25

#pragma once
26

Benjamin Huber's avatar
Benjamin Huber committed
27
#include <string>
28 29
#include <vector>

Benjamin Huber's avatar
Benjamin Huber committed
30
#include "misc/timeMeasure.h"
31
#include "misc/histogram.h"
Benjamin Huber's avatar
Benjamin Huber committed
32

33 34
#include "basic.h"
#include "tensorNetwork.h"
Benjamin Huber's avatar
Benjamin Huber committed
35

36 37 38 39 40 41
namespace xerus {
	template<bool isOperator> class TTNetwork;
	
	typedef TTNetwork<false> TTTensor;
	typedef TTNetwork<true> TTOperator;
	
Sebastian Wolf's avatar
Sebastian Wolf committed
42 43 44 45 46 47 48
	/// @brief Storage class for the performance data collected during an algorithm (typically iteration count, time and residual)
	class PerformanceData {
	public:
		struct DataPoint {
			size_t iterationCount;
			size_t elapsedTime;
			double residual;
49
			double error;
Sebastian Wolf's avatar
Sebastian Wolf committed
50 51
			TensorNetwork::RankTuple ranks;
			size_t flags;
Sebastian Wolf's avatar
Sebastian Wolf committed
52
			
53 54
			DataPoint(const size_t _itrCount, const size_t _time, const value_t _residual, const value_t _error, const TensorNetwork::RankTuple _ranks, const size_t _flags) 
				: iterationCount(_itrCount), elapsedTime(_time), residual(_residual), error(_error), ranks(_ranks), flags(_flags) {}
Sebastian Wolf's avatar
Sebastian Wolf committed
55
		};
56
		
Sebastian Wolf's avatar
Sebastian Wolf committed
57 58 59 60
		const bool active;
		
		bool printProgress;
		
61 62
		using ErrorFunction = std::function<double(const TTTensor&)>;
		ErrorFunction errorFunction;
63
		
Sebastian Wolf's avatar
Sebastian Wolf committed
64 65
		size_t startTime;
		size_t stopTime;
Sebastian Wolf's avatar
Sebastian Wolf committed
66 67 68 69
		std::vector<DataPoint> data;
		
		std::string additionalInformation;
		
Sebastian Wolf's avatar
Sebastian Wolf committed
70
		
71 72 73
		explicit PerformanceData(const bool _printProgress = false, const bool _active = true) : 
			active(_active), printProgress(_printProgress), startTime(~0ul), stopTime(~0ul) {}
		
74
		explicit PerformanceData(const ErrorFunction& _errorFunction, const bool _printProgress = false, const bool _active = true) : 
75
			active(_active), printProgress(_printProgress), errorFunction(_errorFunction), startTime(~0ul), stopTime(~0ul) {}
Sebastian Wolf's avatar
Sebastian Wolf committed
76 77
		
		void start() {
78
			using ::xerus::misc::operator<<;
Sebastian Wolf's avatar
Sebastian Wolf committed
79
			if (active) {
Ben Huber's avatar
Ben Huber committed
80
				if(printProgress) {
Benjamin Huber's avatar
Benjamin Huber committed
81 82 83 84
					std::stringstream ss(additionalInformation);
					while (ss) {
						std::string line;
						std::getline(ss, line);
85
						XERUS_LOG_SHORT(PerformanceData, line);
Benjamin Huber's avatar
Benjamin Huber committed
86
					}
Ben Huber's avatar
Ben Huber committed
87
				}
Sebastian Wolf's avatar
Sebastian Wolf committed
88 89
				startTime = misc::uTime();
			}
90
		}
Sebastian Wolf's avatar
Sebastian Wolf committed
91 92
		
		void stop_timer() {
Sebastian Wolf's avatar
Sebastian Wolf committed
93 94 95
			if (active) {
				stopTime = misc::uTime();
			}
Sebastian Wolf's avatar
Sebastian Wolf committed
96 97 98
		}
		
		void continue_timer() {
Sebastian Wolf's avatar
Sebastian Wolf committed
99 100 101 102 103
			if (active) {
				size_t currtime = misc::uTime();
				startTime += currtime - stopTime;
				stopTime = ~0ul;
			}
104
		}
Sebastian Wolf's avatar
Sebastian Wolf committed
105 106
		
		void reset() {
Sebastian Wolf's avatar
Sebastian Wolf committed
107 108 109 110 111 112
			if (active) {
				data.clear();
				additionalInformation.clear();
				startTime = ~0ul;
				stopTime = ~0ul;
			}
Sebastian Wolf's avatar
Sebastian Wolf committed
113 114
		}
		
Sebastian Wolf's avatar
Sebastian Wolf committed
115 116 117 118
		size_t get_elapsed_time() const {
			return misc::uTime() - startTime;
		}
		
Sebastian Wolf's avatar
Sebastian Wolf committed
119 120 121 122 123 124 125 126
		size_t get_runtime() const {
			if (stopTime != ~0ul) {
				return stopTime - startTime;
			} else {
				return misc::uTime() - startTime;
			}
		}
		
Sebastian Wolf's avatar
Sebastian Wolf committed
127
		void add(const size_t _itrCount, const value_t _residual, const TensorNetwork::RankTuple _ranks = TensorNetwork::RankTuple(), const size_t _flags = 0);
Sebastian Wolf's avatar
Sebastian Wolf committed
128
		
129
		void add(const size_t _itrCount, const value_t _residual, const TTTensor& _x, const size_t _flags = 0);
130
		
Sebastian Wolf's avatar
Sebastian Wolf committed
131
		void add(const value_t _residual, const TensorNetwork::RankTuple _ranks = TensorNetwork::RankTuple(), const size_t _flags = 0);
Sebastian Wolf's avatar
Sebastian Wolf committed
132
		
Ben Huber's avatar
Ben Huber committed
133 134
		void add(const value_t _residual, const TTTensor& _x, const size_t _flags = 0);
		
Sebastian Wolf's avatar
Sebastian Wolf committed
135
		operator bool() const {
Sebastian Wolf's avatar
Sebastian Wolf committed
136
			return active;
Sebastian Wolf's avatar
Sebastian Wolf committed
137 138 139 140
		}
		
		/// @brief The pipe operator allows to add everything that can be converted to string to the additional information in the header. 
		template<class T>
141
		PerformanceData& operator<<(const T &_info) {
142
			using ::xerus::misc::operator<<;
Sebastian Wolf's avatar
Sebastian Wolf committed
143
			if (active) {
Ben Huber's avatar
Ben Huber committed
144
				additionalInformation += misc::to_string(_info);
Sebastian Wolf's avatar
???  
Sebastian Wolf committed
145
				if(printProgress) {
146
					XERUS_LOG_SHORT(PerformanceData, _info);
Sebastian Wolf's avatar
???  
Sebastian Wolf committed
147
				}
Sebastian Wolf's avatar
Sebastian Wolf committed
148 149 150 151 152 153
			}
			return *this;
		}
		
		void dump_to_file(const std::string &_fileName) const;
		
Benjamin Huber's avatar
Benjamin Huber committed
154
		misc::LogHistogram get_histogram(const value_t _base, bool _assumeConvergence = false) const;
Sebastian Wolf's avatar
Sebastian Wolf committed
155
	};
Benjamin Huber's avatar
Benjamin Huber committed
156

Sebastian Wolf's avatar
Sebastian Wolf committed
157
	extern PerformanceData NoPerfData;
158
}