#ifndef __TIMER_HPP__
#define __TIMER_HPP__
#include <sys/time.h>
#include <cstdlib>
#include <mpi.h>
#include <Datatypes.hpp>
#include <string>
#include <iomanip>
#include <map>
class Timer {
public:
Timer() : time_(0.0) {}
~Timer() { }
void start() {
gettimeofday(&start_, 0);
}
void stop() {
gettimeofday(&stop_, 0);
time_ += ((stop_.tv_sec*1000000+stop_.tv_usec)-(start_.tv_sec*1000000+start_.tv_usec))/1000000.00;
}
void reduce(const Subdomain& subdomain) {
MPI_Allreduce(&time_, &timeTotal_, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
MPI_Allreduce(&time_, &timeMin_, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD);
MPI_Allreduce(&time_, &timeMax_, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
timeTotal_ /= subdomain.numProcs;
}
double getTime() { return time_; }
friend std::ostream& operator<<(std::ostream& os, const Timer& t);
private:
double time_, timeTotal_, timeMin_, timeMax_;
timeval start_, stop_;
};
std::ostream& operator<<(std::ostream& os, const Timer& t) {
return os << std::scientific << std::setw(8) << std::setprecision(3)
<< t.timeTotal_ << " \t " << t.timeMin_ << " \t " << t.timeMax_;
}
class TimeMap {
public:
TimeMap() { }
~TimeMap() { }
void reduce(const Subdomain& subdomain) {
for(std::map<std::string, Timer>::iterator it = map_.begin(); it != map_.end(); ++it)
it->second.reduce(subdomain);
}
double getTotalTime() {
double ret = 0.0;
for(std::map<std::string, Timer>::iterator it = map_.begin(); it != map_.end(); ++it)
ret += it->second.getTime();
return ret;
}
Timer& operator[](const std::string& name) {
return map_[name];
}
friend std::ostream& operator<<(std::ostream& os, const TimeMap& t);
private:
std::map<std::string, Timer> map_;
};
std::ostream& operator<<(std::ostream& os, const TimeMap& t) {
for(std::map<std::string, Timer>::const_iterator it = t.map_.begin(); it != t.map_.end(); ++it) {
os << "--- " << std::setw(15) << std::left << it->first << "\t" << it->second << "\n";
}
return os << "--------------\n";
}
#endif // __TIMER_HPP__