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