/** * @file timer.cpp * @author Julian Iseringhausen * @date Tue Sep 6 16:17:40 2011 * * @brief Class to measure timings. * */ #ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_MPI #include #endif #include #include #include #include "base/helper.hpp" #include "base/timer.hpp" #include "comm/comm.hpp" #include "thirdparty/pugixml/pugixml.hpp" #include "mg.hpp" using namespace VMG; std::map Timer::td; void Timer::Start(std::string event) { #ifdef HAVE_MPI #ifdef DEBUG_MEASURE_TIME std::map::iterator iter = td.find(event); if (iter == td.end()) iter = td.insert(std::make_pair(event, TimerData())).first; iter->second.time_start = MPI_Wtime(); #endif #endif } void Timer::Stop(std::string event) { #ifdef HAVE_MPI #ifdef DEBUG_MEASURE_TIME double time_end = MPI_Wtime(); std::map::iterator iter = td.find(event); if (time_end - iter->second.time_start < std::numeric_limits::min()) ++(iter->second.warning); ++(iter->second.total); iter->second.duration += time_end - iter->second.time_start; #endif #endif } void Timer::Clear() { td.clear(); } pugi::xml_node Timer::ToXMLNode() { std::map::iterator iter; pugi::xml_document doc; pugi::xml_node node_process = doc.append_child("Process"); pugi::xml_attribute att_rank = node_process.append_attribute("Rank"); att_rank.set_value(MG::GetComm()->GlobalRank()); pugi::xml_node node_timings = node_process.append_child("Timings"); for (iter=Timer::td.begin(); iter!=Timer::td.end(); ++iter) { pugi::xml_node node_entry = node_timings.append_child("Sample"); node_entry.append_attribute("Name").set_value(Helper::ToString(iter->first).c_str()); pugi::xml_node node_duration = node_entry.append_child("Duration"); pugi::xml_node node_duration_data = node_duration.append_child(pugi::node_pcdata); node_duration_data.set_value(Helper::ToString(iter->second.duration).c_str()); pugi::xml_node node_warnings = node_entry.append_child("Warnings"); pugi::xml_node node_warnings_data = node_warnings.append_child(pugi::node_pcdata); node_warnings_data.set_value(Helper::ToString(iter->second.warning).c_str()); pugi::xml_node node_total = node_entry.append_child("Total"); pugi::xml_node node_total_data = node_total.append_child(pugi::node_pcdata); node_total_data.set_value(Helper::ToString(iter->second.total).c_str()); } return node_process; } std::string Timer::ToString() { pugi::xml_node node = Timer::ToXMLNode(); std::stringstream str; node.print(str); return str.str(); } void Timer::Print() { #ifdef DEBUG_MEASURE_TIME std::map::const_iterator iter; Comm& comm = *MG::GetComm(); if (comm.GlobalRank() == 0) { comm.PrintStringOnce("Running times:"); for (iter=Timer::td.begin(); iter!=Timer::td.end(); ++iter) comm.PrintStringOnce(" %s: %es", iter->first.c_str(), iter->second.duration); } #endif } std::ostream& VMG::operator<<(std::ostream& out, const Timer&) { return out << Timer::ToString(); }