source: src/base/timer.cpp@ a40eea

Last change on this file since a40eea was ac6d04, checked in by Julian Iseringhausen <isering@…>, 14 years ago

Merge recent changes of the vmg library into ScaFaCos.

Includes a fix for the communication problems on Jugene.

git-svn-id: https://svn.version.fz-juelich.de/scafacos/trunk@1666 5161e1c8-67bf-11de-9fd5-51895aff932f

  • Property mode set to 100644
File size: 5.3 KB
RevLine 
[dfed1c]1/**
2 * @file timer.cpp
3 * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
4 * @date Tue Sep 6 16:17:40 2011
5 *
6 * @brief Class to measure timings.
7 *
8 */
9
10#ifdef HAVE_CONFIG_H
11#include <config.h>
12#endif
13
14#ifdef HAVE_MPI
15#include <mpi.h>
[ac6d04]16#ifdef HAVE_MARMOT
17#include <enhancempicalls.h>
18#include <sourceinfompicalls.h>
19#endif
[dfed1c]20#endif
21
22#include <iostream>
23#include <limits>
24#include <sstream>
25
26#include "base/helper.hpp"
27#include "base/timer.hpp"
28#include "comm/comm.hpp"
29#include "thirdparty/pugixml/pugixml.hpp"
30#include "mg.hpp"
31
32using namespace VMG;
33
34std::map<std::string, TimerData> Timer::td;
35
36void Timer::Start(std::string event)
37{
38#ifdef HAVE_MPI
39#ifdef DEBUG_MEASURE_TIME
40 std::map<std::string, TimerData>::iterator iter = td.find(event);
41 if (iter == td.end())
42 iter = td.insert(std::make_pair(event, TimerData())).first;
43
44 iter->second.time_start = MPI_Wtime();
45#endif
46#endif
47}
48
49void Timer::Stop(std::string event)
50{
51#ifdef HAVE_MPI
52#ifdef DEBUG_MEASURE_TIME
53 double time_end = MPI_Wtime();
54
55 std::map<std::string, TimerData>::iterator iter = td.find(event);
56
57 if (time_end - iter->second.time_start < std::numeric_limits<double>::min())
58 ++(iter->second.warning);
59
60 ++(iter->second.total);
61
62 iter->second.duration += time_end - iter->second.time_start;
63#endif
64#endif
65}
66
67void Timer::Clear()
68{
69 td.clear();
70}
71
72pugi::xml_node Timer::ToXMLNode()
73{
74 std::map<std::string, TimerData>::iterator iter;
75
[1610dc]76 pugi::xml_node node_process;
77 node_process.append_attribute("Rank").set_value(MG::GetComm()->GlobalRank());
[dfed1c]78
79 pugi::xml_node node_timings = node_process.append_child("Timings");
80
81 for (iter=Timer::td.begin(); iter!=Timer::td.end(); ++iter) {
82
83 pugi::xml_node node_entry = node_timings.append_child("Sample");
84 node_entry.append_attribute("Name").set_value(Helper::ToString(iter->first).c_str());
85
[1610dc]86 node_entry.append_child("Duration")
87 .append_child(pugi::node_pcdata)
88 .set_value(Helper::ToString(iter->second.duration).c_str());
[dfed1c]89
[1610dc]90 node_entry.append_child("Warnings")
91 .append_child(pugi::node_pcdata)
92 .set_value(Helper::ToString(iter->second.warning).c_str());
[dfed1c]93
[1610dc]94 node_entry.append_child("Total")
95 .append_child(pugi::node_pcdata)
96 .set_value(Helper::ToString(iter->second.total).c_str());
[dfed1c]97
98 }
99
100 return node_process;
101}
102
103std::string Timer::ToString()
104{
105 pugi::xml_node node = Timer::ToXMLNode();
106 std::stringstream str;
107 node.print(str);
108 return str.str();
109}
110
111void Timer::Print()
112{
113#ifdef DEBUG_MEASURE_TIME
114 std::map<std::string, TimerData>::const_iterator iter;
115 Comm& comm = *MG::GetComm();
116
117 if (comm.GlobalRank() == 0) {
118 comm.PrintStringOnce("Running times:");
119 for (iter=Timer::td.begin(); iter!=Timer::td.end(); ++iter)
[894a5f]120 comm.PrintStringOnce(" %s: %e s (%d)", iter->first.c_str(), iter->second.duration, iter->second.total);
[dfed1c]121 }
122#endif
123}
124
[894a5f]125template <class T>
126static T min(T* data, int num_data, int& at_rank)
127{
128 at_rank = 0;
129 T min = data[0];
130
131 for (int i=1; i<num_data; ++i)
132 if (data[i] < min) {
133 at_rank = i;
134 min = data[i];
135 }
136 return min;
137}
138
139template <class T>
140static T max(T* data, int num_data, int& at_rank)
141{
142 at_rank = 0;
143 T max = data[0];
144
145 for (int i=1; i<num_data; ++i)
146 if (data[i] > max) {
147 at_rank = i;
148 max = data[i];
149 }
150 return max;
151}
152
153template <class T>
154static vmg_float avg(T* data, int num_data)
155{
156 vmg_float average = 0.0;
157 vmg_float num_data_inv = 1.0 / static_cast<vmg_float>(num_data);
158 for (int i=0; i<num_data; ++i)
159 average += data[i] * num_data_inv;
160 return average;
161}
162
163void Timer::PrintGlobal()
164{
165#ifdef DEBUG_MEASURE_TIME
166 std::map<std::string, TimerData>::const_iterator iter;
167 Comm& comm = *MG::GetComm();
168 char name[80];
169 int rank, size;
170
171 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
172 MPI_Comm_size(MPI_COMM_WORLD, &size);
173
174 vmg_float times[size];
175 int calls[size];
176
177 comm.PrintStringOnce("Running times (global):");
178
179 for (iter=Timer::td.begin(); iter!=Timer::td.end(); ++iter) {
180 std::strcpy(name, iter->first.c_str());
181 MPI_Bcast(name, 80, MPI_CHAR, 0, MPI_COMM_WORLD);
182 MPI_Gather(&Timer::td[name].duration, 1, MPI_DOUBLE, times, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
183 MPI_Gather(&Timer::td[name].total, 1, MPI_INT, calls, 1, MPI_INT, 0, MPI_COMM_WORLD);
184
185 if (rank == 0) {
186 int min_calls, max_calls, avg_calls;
187 vmg_float min_duration, max_duration, avg_duration;
188 int rank_min_calls, rank_max_calls, rank_min_duration, rank_max_duration;
189
190 min_duration = min(times, size, rank_min_duration);
191 max_duration = max(times, size, rank_max_duration);
192 avg_duration = avg(times, size);
193 min_calls = min(calls, size, rank_min_calls);
194 max_calls = max(calls, size, rank_max_calls);
195 avg_calls = avg(calls, size);
196
197 comm.PrintStringOnce(" %s: %e s (%d)", iter->first.c_str(), iter->second.duration, iter->second.total);
198 comm.PrintStringOnce(" Min: %e s @ %d", min_duration, rank_min_duration);
199 comm.PrintStringOnce(" Max: %e s @ %d", max_duration, rank_max_duration);
200 comm.PrintStringOnce(" Avg: %e s", avg_duration);
201 comm.PrintStringOnce(" Min calls: %d @ %d", min_calls, rank_min_calls);
202 comm.PrintStringOnce(" Max calls: %d @ %d", max_calls, rank_max_calls);
203 comm.PrintStringOnce(" Avg calls: %f", avg_calls);
204 }
205 }
206
207#endif
208}
209
[dfed1c]210std::ostream& VMG::operator<<(std::ostream& out, const Timer&)
211{
212 return out << Timer::ToString();
213}
Note: See TracBrowser for help on using the repository browser.