Update copyright date; remove old CVS keyword
[ctsim.git] / include / timer.h
1 /*****************************************************************************
2 ** FILE IDENTIFICATION
3 **
4 **      Name:         timer.h
5 **      Purpose:      Header file for Timer class
6 **      Author:       Kevin Rosenberg
7 **      Date Started: Sep 2000
8 **
9 **  This is part of the CTSim program
10 **  Copyright (c) 1983-2009 Kevin Rosenberg
11 **
12 **  This program is free software; you can redistribute it and/or modify
13 **  it under the terms of the GNU General Public License (version 2) as
14 **  published by the Free Software Foundation.
15 **
16 **  This program is distributed in the hope that it will be useful,
17 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 **  GNU General Public License for more details.
20 **
21 **  You should have received a copy of the GNU General Public License
22 **  along with this program; if not, write to the Free Software
23 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24 ******************************************************************************/
25
26 #ifndef _TIMER_H
27 #define _TIMER_H
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #ifdef HAVE_SYS_TIME_H
34 #include <sys/time.h>
35 #endif
36
37 #ifdef MSVC
38 #include <sys/timeb.h>
39 #endif
40
41 class Timer
42 {
43  public:
44     Timer (void)
45         { m_timeStart = ttime(); }
46
47     virtual ~Timer (void)
48         {}
49
50     virtual double timerEnd (void)
51       {
52         m_timeEnd = ttime();
53         m_timeElapsed = m_timeEnd - m_timeStart;
54
55         return (m_timeElapsed);
56       }
57
58     virtual void timerReport (const char* const msg) const
59       {
60                 std::cout << msg << ": " << m_timeElapsed << " seconds" << std::endl;
61       }
62
63     virtual double timerEndAndReport (const char* const msg)
64       {
65         double t = timerEnd ();
66         timerReport (msg);
67         return (t);
68       }
69
70     double getTimeElapsed (void) const
71         { return m_timeElapsed; }
72
73  protected:
74     double m_timeStart;
75     double m_timeEnd;
76     double m_timeElapsed;
77
78     double ttime(void) const
79         {
80 #ifdef HAVE_GETTIMEOFDAY
81             struct timeval now;
82             if (gettimeofday (&now, NULL))
83                 return 0;
84
85             return (now.tv_sec + static_cast<double>(now.tv_usec) / 1000000.);
86 #elif defined(MSVC)
87                 struct _timeb now;
88                 _ftime (&now);
89                 return (now.time + static_cast<double>(now.millitm) / 1000.);
90 #else
91             return 0;
92 #endif
93         }
94 };
95
96
97 #ifdef HAVE_MPI
98
99 #include "mpi++.h"
100
101 class TimerMPI : public Timer
102 {
103  public:
104     TimerMPI (MPI::Intracomm& comm)
105         : m_comm(comm)
106       {
107           m_timeStart = MPI::Wtime();
108       }
109
110     virtual ~TimerMPI (void)
111       {}
112
113     virtual double timerEnd (void)
114       {
115         m_timeEnd = MPI::Wtime();
116         m_timeElapsed = m_timeEnd - m_timeStart;
117
118         return (m_timeElapsed);
119       }
120
121     virtual void timerReport (const char* const msg)
122       {
123           if (m_comm.Get_rank() == 0)
124                   std::cout << msg << ": " << m_timeElapsed << " seconds" << std::endl;
125       }
126
127     virtual double timerEndAndReport (const char* const msg)
128       {
129         double t = timerEnd ();
130         timerReport (msg);
131         return (t);
132       }
133
134     virtual void timerReportAllProcesses (const char* const msg)
135       {
136           timerReport (msg);
137       }
138
139  protected:
140     MPI::Intracomm& m_comm;
141 };
142
143 class TimerCollectiveMPI : public TimerMPI
144 {
145  public:
146     TimerCollectiveMPI (MPI::Intracomm& comm)
147         : TimerMPI::TimerMPI (comm)
148       {
149         m_comm.Barrier();
150         m_timeStart = MPI::Wtime();
151       }
152
153     virtual ~TimerCollectiveMPI (void)
154       {}
155
156     virtual double timerEnd (void)
157       {
158         m_timeEnd = MPI::Wtime();
159         m_timeElapsed = m_timeEnd - m_timeStart;
160         m_comm.Reduce (&m_timeElapsed, &m_timeMin, 1, MPI::DOUBLE, MPI::MIN, 0);
161         m_comm.Reduce (&m_timeElapsed, &m_timeMax, 1, MPI::DOUBLE, MPI::MAX, 0);
162
163         return (m_timeElapsed);
164       }
165
166     virtual double timerEndAndReport (const char* const msg)
167       {
168         double t = timerEnd ();
169         timerReport (msg);
170         return (t);
171       }
172
173     virtual void timerReport (const char* const msg)
174       {
175         if (m_comm.Get_rank() == 0)
176                 std::cout << msg << " " << "Minimum=" << m_timeMin << ", Maximum=" << m_timeMax << " seconds" << std::endl;
177       }
178
179     virtual void timerReportAllProcesses (const char* const msg)
180       {
181                 std::cout << msg << ": " << "Minimum=" << m_timeMin << ", Maximum=" << m_timeMax << " seconds (Rank " << m_comm.Get_rank() << ")" << std::endl;
182       }
183
184  private:
185     double m_timeMin;
186     double m_timeMax;
187 };
188 #endif
189
190
191 #endif  // _TIMER_H
192
193