Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
comm/test/Time/cxx_main.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #include "Teuchos_ConfigDefs.hpp"
43 #include "Teuchos_TimeMonitor.hpp"
44 #include "Teuchos_ScalarTraits.hpp"
45 #include "Teuchos_Version.hpp"
46 #include "Teuchos_as.hpp"
47 
48 #ifdef HAVE_MPI
49 #include <mpi.h>
50 #endif
51 
52 using std::string;
54 using Teuchos::Time;
55 using Teuchos::RCP;
57 using Teuchos::as;
58 
59 /* Test of Teuchos timing classes */
60 
61 
62 /* create timers for several functions */
63 static Time& sqrtTimer() {static RCP<Time> t = TimeMonitor::getNewTimer("square roots"); return *t;}
64 
65 static Time& factTimer() {static RCP<Time> t = TimeMonitor::getNewTimer("factorials"); return *t;}
66 
67 static Time& exceptTimer() {static RCP<Time> t = TimeMonitor::getNewTimer("func with std::exception"); return *t;}
68 
69 static Time& localTimer() {static RCP<Time> t = TimeMonitor::getNewTimer("a function that is not called on all procs"); return *t;}
70 
71 static Time& anotherTimer() {static RCP<Time> t = TimeMonitor::getNewTimer("another func"); return *t;}
72 
73 static Time& yetAnotherTimer() {static RCP<Time> t = TimeMonitor::getNewTimer("yet another func"); return *t;}
74 
75 static Time& yetOneMoreTimer() {static RCP<Time> t = TimeMonitor::getNewTimer("yet one more func"); return *t;}
76 
77 
78 // Prototypes of the functions we will time below.
79 double sqrtFunc();
80 double factFunc(int x);
81 double exceptFunc();
82 double localFunc();
83 double anotherFunc();
84 double yetAnotherFunc();
85 double yetOneMoreFunc();
86 
87 
88 int main(int argc, char* argv[])
89 {
90  bool verbose = 0;
91  int procRank = 0;
92  int FailedTests = 1; // This will be set to 0, if the std::exception is caught!
93 
94 #ifdef HAVE_MPI
95  /* initialize MPI if we are running in parallel */
96  MPI_Init(&argc, &argv);
97  MPI_Comm_rank( MPI_COMM_WORLD, &procRank );
98 #endif
99 
100  // Check for verbose flag.
101  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;
102 
103  if (verbose && procRank==0)
104  std::cout << Teuchos::Teuchos_Version() << std::endl << std::endl;
105 
106  try {
107  // time a simple function
108  for (int i=0; i<100; i++)
109  {
110  double x = 0.0;
111  x = sqrtFunc ();
112  (void) x; // forestall "variable set but not used" compiler warning
113  }
114 
115  // time a reentrant function
116  for (int i = 0; i < 100; ++i) {
117  factFunc (100);
118  }
119 
120  /* time a couple of silly functions */
121  for (int i = 0; i < 100; ++i) {
122  anotherFunc ();
123  yetAnotherFunc ();
124  yetOneMoreFunc ();
125  }
126 
127  /* Time a function that will be called only on the root proc. This
128  * checks that the TimeMonitor will work properly when different
129  * processors have different sets of timers. */
130  if (procRank == 0) {
131  for (int i = 0; i < 100; ++i) {
132  double x = 0.0;
133  x = localFunc ();
134  (void) x; // forestall "variable set but not used" compiler warning
135  }
136  }
137 
138  // time a function that throws an exception
139  for (int i = 0; i < 100; ++i) {
140  double x = 0.0;
141  x = exceptFunc ();
142  (void) x; // forestall "variable set but not used" compiler warning
143  }
144  }
145  catch (std::exception& e) {
146  // This _should_ only catch the one exception thrown above by the
147  // first call to exceptFunc().
148  if (verbose && procRank==0) {
149  std::cerr << "Caught std::exception [expected]: " << e.what() << std::endl;
150  }
151  // Return 0 since we caught the std::exception
152  FailedTests = 0;
153  }
154 
155  // Summarize timings. This must be done before finalizing MPI.
156  TimeMonitor::format ().setRowsBetweenLines (3);
157  if (verbose) {
158  TimeMonitor::summarize ();
159  }
160 
161 #ifdef HAVE_MPI
162  /* clean up MPI if we are running in parallel*/
163  MPI_Finalize ();
164 #endif // HAVE_MPI
165 
166  if (FailedTests != 0) {
167  std::cout << "End Result: TEST FAILED" << std::endl;
168  return 1;
169  }
170 
171  std::cout << "End Result: TEST PASSED" << std::endl;
172  return FailedTests;
173 }
174 
175 
176 /* sum std::sqrt(x), x=[0, 10000). */
177 double sqrtFunc()
178 {
179  /* construct a time monitor. This starts the timer. It will stop when leaving scope */
180  TimeMonitor timer(sqrtTimer());
181 
182  double sum = 0.0;
183 
184  for (int i=0; i<10000; i++)
185  {
186  TEUCHOS_TEST_FOR_EXCEPTION(ScalarTraits<double>::squareroot(as<double>(i)) > 1000.0, std::runtime_error,
187  "throw an std::exception");
188  sum += ScalarTraits<double>::squareroot(as<double>(i));
189  }
190 
191  return sum;
192 }
193 
194 
195 /* compute log(factorial(x)) */
196 double factFunc(int x)
197 {
198  /* construct a time monitor. This starts the timer. It will stop when leaving scope */
199  TimeMonitor timer(factTimer());
200 
201  if (x==0) return 0;
202  if (x==1) return 1;
203  return std::log(as<double>(x)) + factFunc(x-1);
204 }
205 
206 
207 /* sum std::sqrt(x), x=[0, 10000). */
208 double exceptFunc()
209 {
210  /* construct a time monitor. This starts the timer. It will stop when leaving scope */
211  TimeMonitor timer(exceptTimer());
212 
213  double sum = 0.0;
214  for (int i=0; i<10000; i++)
215  {
217  ScalarTraits<double>::squareroot(as<double>(i)) > 60.0, std::runtime_error,
218  "throw an std::exception");
219  sum += ScalarTraits<double>::squareroot(as<double>(i));
220  }
221  return sum;
222 }
223 
224 
225 /* sum x, x=[0, 10000). */
226 double localFunc()
227 {
228  /* construct a time monitor. This starts the timer. It will stop when leaving scope */
229  TimeMonitor timer(localTimer());
230 
231  double sum = 0.0;
232 
233  for (int i=0; i<10000; i++)
234  {
235  sum += i;
236  }
237 
238  return sum;
239 }
240 
241 
242 /* sum x^2, x=[0, 10000). */
243 double anotherFunc()
244 {
245  /* construct a time monitor. This starts the timer. It will stop when leaving scope */
246  TimeMonitor timer(anotherTimer());
247 
248  double sum = 0.0;
249 
250  for (int i=0; i<10000; i++)
251  {
252  sum += i*i;
253  }
254 
255  return sum;
256 }
257 
258 
259 /* sum x^3, x=[0, 10000). */
261 {
262  /* construct a time monitor. This starts the timer. It will stop when leaving scope */
263  TimeMonitor timer(yetAnotherTimer());
264 
265  double sum = 0.0;
266 
267  for (int i=0; i<10000; i++)
268  {
269  sum += i*i*i;
270  }
271 
272  return sum;
273 }
274 
275 
276 /* sum x+1, x=[0, 10000). */
278 {
279  /* construct a time monitor. This starts the timer. It will stop when leaving scope */
280  TimeMonitor timer(yetOneMoreTimer());
281 
282  double sum = 0.0;
283 
284  for (int i=0; i<10000; i++)
285  {
286  sum += i+1;
287  }
288 
289  return sum;
290 }
double anotherFunc()
static Time & yetAnotherTimer()
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
Teuchos header file which uses auto-configuration information to include necessary C++ headers...
This structure defines some basic traits for a scalar field type.
static Time & anotherTimer()
double exceptFunc()
static Time & factTimer()
Wall-clock timer.
double yetOneMoreFunc()
static Time & yetOneMoreTimer()
static Time & exceptTimer()
std::string Teuchos_Version()
static Time & localTimer()
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
static Time & sqrtTimer()
int main(int argc, char *argv[])
double sqrtFunc()
double factFunc(int x)
double localFunc()
Defines basic traits for the scalar field type.
Scope guard for Teuchos::Time, with MPI collective timer reporting.
Smart reference counting pointer class for automatic garbage collection.
double yetAnotherFunc()
Definition of Teuchos::as, for conversions between types.
Scope guard for Time, that can compute MPI collective timer statistics.