Teuchos Package Browser (Single Doxygen Collection) Version of the Day
test/Time/cxx_main.cpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #include "Teuchos_ConfigDefs.hpp"
00043 #include "Teuchos_TimeMonitor.hpp"
00044 #include "Teuchos_ScalarTraits.hpp"
00045 #include "Teuchos_Version.hpp"
00046 #include "Teuchos_as.hpp"
00047 
00048 #ifdef HAVE_MPI
00049 #include <mpi.h>
00050 #endif
00051 
00052 using std::string;
00053 using Teuchos::TimeMonitor;
00054 using Teuchos::Time;
00055 using Teuchos::RCP;
00056 using Teuchos::ScalarTraits;
00057 using Teuchos::as;
00058 
00059 /* Test of Teuchos timing classes */
00060 
00061 
00062 /* create timers for several functions */
00063 static Time& sqrtTimer() {static RCP<Time> t = TimeMonitor::getNewTimer("square roots"); return *t;}
00064 
00065 static Time& factTimer() {static RCP<Time> t = TimeMonitor::getNewTimer("factorials"); return *t;}
00066 
00067 static Time& exceptTimer() {static RCP<Time> t = TimeMonitor::getNewTimer("func with std::exception"); return *t;}
00068 
00069 static Time& localTimer() {static RCP<Time> t = TimeMonitor::getNewTimer("a function that is not called on all procs"); return *t;}
00070 
00071 static Time& anotherTimer() {static RCP<Time> t = TimeMonitor::getNewTimer("another func"); return *t;}
00072 
00073 static Time& yetAnotherTimer() {static RCP<Time> t = TimeMonitor::getNewTimer("yet another func"); return *t;}
00074 
00075 static Time& yetOneMoreTimer() {static RCP<Time> t = TimeMonitor::getNewTimer("yet one more func"); return *t;}
00076 
00077 
00078 int main(int argc, char* argv[])
00079 {
00080   bool verbose = 0;
00081   int procRank = 0;
00082   int FailedTests = 1; // This will be set to 0, if the std::exception is caught!
00083 
00084 #ifdef HAVE_MPI 
00085   /* initialize MPI if we are running in parallel */
00086   MPI_Init(&argc, &argv);
00087   MPI_Comm_rank( MPI_COMM_WORLD, &procRank );
00088 #endif      
00089   
00090   // Check for verbose flag.
00091   if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;
00092 
00093   if (verbose && procRank==0)
00094     std::cout << Teuchos::Teuchos_Version() << std::endl << std::endl;
00095 
00096   try
00097   {
00098 
00099     // Prototypes???
00100     double sqrtFunc();
00101     double factFunc(int x);
00102     double exceptFunc();
00103     double localFunc();
00104     double anotherFunc();
00105     double yetAnotherFunc();
00106     double yetOneMoreFunc();
00107       
00108     /* time a simple function */
00109     for (int i=0; i<100; i++)
00110     {
00111       double x = 0.0;
00112       x = sqrtFunc();
00113     }
00114 
00115     /* time a reentrant function */
00116     for (int i=0; i<100; i++)
00117     {
00118       factFunc(100);
00119     }
00120 
00121     /* time a couple of silly functions */
00122     for (int i=0; i<100; i++)
00123     {
00124       anotherFunc();
00125       yetAnotherFunc();
00126       yetOneMoreFunc();
00127     }
00128 
00129     /* Time a function that will be called only on the root proc. This 
00130      * checks that the TimeMonitor will work properly when different
00131      * processors have different sets of timers. */
00132     if (procRank==0)
00133     {
00134       for (int i=0; i<100; i++)
00135       {
00136         double x = 0.0;
00137         x = localFunc();
00138       }
00139     }
00140 
00141     /* time a function that throws an std::exception */
00142     for (int i=0; i<100; i++)
00143     {
00144       double x = 0.0;
00145       x = exceptFunc();
00146     }
00147 
00148       
00149   }
00150   catch(std::exception& e)
00151   {
00152     if (verbose && procRank==0)
00153       std::cerr << "Caught std::exception [expected]:  " << e.what() << std::endl;
00154 
00155     // Return 0 since we caught the std::exception
00156     FailedTests = 0;
00157   }
00158 
00159   /* Summarize timings. This must be done before finalizing MPI  */
00160   TimeMonitor::format().setRowsBetweenLines(3);
00161   if (verbose)
00162     TimeMonitor::summarize();
00163 
00164 #ifdef HAVE_MPI
00165   /* clean up MPI if we are running in parallel*/
00166   MPI_Finalize();
00167 #endif
00168 
00169   if (FailedTests != 0) {
00170     std::cout << "End Result: TEST FAILED" << std::endl;
00171     return 1;
00172   }
00173 
00174   std::cout << "End Result: TEST PASSED" << std::endl;
00175   return FailedTests;
00176 }
00177 
00178 
00179 /* sum std::sqrt(x), x=[0, 10000). */
00180 double sqrtFunc()
00181 {
00182   /* construct a time monitor. This starts the timer. It will stop when leaving scope */
00183   TimeMonitor timer(sqrtTimer());
00184 
00185   double sum = 0.0;
00186 
00187   for (int i=0; i<10000; i++) 
00188   {
00189     TEST_FOR_EXCEPTION(ScalarTraits<double>::squareroot(as<double>(i)) > 1000.0, std::runtime_error,
00190       "throw an std::exception");
00191     sum += ScalarTraits<double>::squareroot(as<double>(i));
00192   }
00193 
00194   return sum;
00195 }
00196 
00197 
00198 /* compute log(factorial(x)) */
00199 double factFunc(int x)
00200 {
00201   /* construct a time monitor. This starts the timer. It will stop when leaving scope */
00202   TimeMonitor timer(factTimer());
00203 
00204   if (x==0) return 0;
00205   if (x==1) return 1;
00206   return std::log(as<double>(x))  + factFunc(x-1);
00207 }
00208 
00209 
00210 /* sum std::sqrt(x), x=[0, 10000). */
00211 double exceptFunc()
00212 {
00213   /* construct a time monitor. This starts the timer. It will stop when leaving scope */
00214   TimeMonitor timer(exceptTimer());
00215 
00216   double sum = 0.0;
00217   for (int i=0; i<10000; i++)
00218   {
00219     TEST_FOR_EXCEPTION(
00220       ScalarTraits<double>::squareroot(as<double>(i)) > 60.0, std::runtime_error,
00221       "throw an std::exception");
00222     sum += ScalarTraits<double>::squareroot(as<double>(i));
00223   }
00224   return sum;
00225 }
00226 
00227 
00228 /* sum x, x=[0, 10000). */
00229 double localFunc()
00230 {
00231   /* construct a time monitor. This starts the timer. It will stop when leaving scope */
00232   TimeMonitor timer(localTimer());
00233 
00234   double sum = 0.0;
00235 
00236   for (int i=0; i<10000; i++) 
00237   {
00238     sum += i;
00239   }
00240 
00241   return sum;
00242 }
00243 
00244 
00245 /* sum x^2, x=[0, 10000). */
00246 double anotherFunc()
00247 {
00248   /* construct a time monitor. This starts the timer. It will stop when leaving scope */
00249   TimeMonitor timer(anotherTimer());
00250 
00251   double sum = 0.0;
00252 
00253   for (int i=0; i<10000; i++) 
00254   {
00255     sum += i*i;
00256   }
00257 
00258   return sum;
00259 }
00260 
00261 
00262 /* sum x^3, x=[0, 10000). */
00263 double yetAnotherFunc()
00264 {
00265   /* construct a time monitor. This starts the timer. It will stop when leaving scope */
00266   TimeMonitor timer(yetAnotherTimer());
00267 
00268   double sum = 0.0;
00269 
00270   for (int i=0; i<10000; i++) 
00271   {
00272     sum += i*i*i;
00273   }
00274 
00275   return sum;
00276 }
00277 
00278 
00279 /* sum x+1, x=[0, 10000). */
00280 double yetOneMoreFunc()
00281 {
00282   /* construct a time monitor. This starts the timer. It will stop when leaving scope */
00283   TimeMonitor timer(yetOneMoreTimer());
00284 
00285   double sum = 0.0;
00286 
00287   for (int i=0; i<10000; i++) 
00288   {
00289     sum += i+1;
00290   }
00291 
00292   return sum;
00293 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines