Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
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       (void)x; // Not used!
00114     }
00115 
00116     /* time a reentrant function */
00117     for (int i=0; i<100; i++)
00118     {
00119       factFunc(100);
00120     }
00121 
00122     /* time a couple of silly functions */
00123     for (int i=0; i<100; i++)
00124     {
00125       anotherFunc();
00126       yetAnotherFunc();
00127       yetOneMoreFunc();
00128     }
00129 
00130     /* Time a function that will be called only on the root proc. This 
00131      * checks that the TimeMonitor will work properly when different
00132      * processors have different sets of timers. */
00133     if (procRank==0)
00134     {
00135       for (int i=0; i<100; i++)
00136       {
00137         double x = 0.0;
00138         x = localFunc();
00139         (void)x; // Not used!
00140       }
00141     }
00142 
00143     /* time a function that throws an std::exception */
00144     for (int i=0; i<100; i++)
00145     {
00146       double x = 0.0;
00147       x = exceptFunc();
00148       (void)x; // Not used!
00149     }
00150 
00151       
00152   }
00153   catch(std::exception& e)
00154   {
00155     if (verbose && procRank==0)
00156       std::cerr << "Caught std::exception [expected]:  " << e.what() << std::endl;
00157 
00158     // Return 0 since we caught the std::exception
00159     FailedTests = 0;
00160   }
00161 
00162   /* Summarize timings. This must be done before finalizing MPI  */
00163   TimeMonitor::format().setRowsBetweenLines(3);
00164   if (verbose)
00165     TimeMonitor::summarize();
00166 
00167 #ifdef HAVE_MPI
00168   /* clean up MPI if we are running in parallel*/
00169   MPI_Finalize();
00170 #endif
00171 
00172   if (FailedTests != 0) {
00173     std::cout << "End Result: TEST FAILED" << std::endl;
00174     return 1;
00175   }
00176 
00177   std::cout << "End Result: TEST PASSED" << std::endl;
00178   return FailedTests;
00179 }
00180 
00181 
00182 /* sum std::sqrt(x), x=[0, 10000). */
00183 double sqrtFunc()
00184 {
00185   /* construct a time monitor. This starts the timer. It will stop when leaving scope */
00186   TimeMonitor timer(sqrtTimer());
00187 
00188   double sum = 0.0;
00189 
00190   for (int i=0; i<10000; i++) 
00191   {
00192     TEUCHOS_TEST_FOR_EXCEPTION(ScalarTraits<double>::squareroot(as<double>(i)) > 1000.0, std::runtime_error,
00193       "throw an std::exception");
00194     sum += ScalarTraits<double>::squareroot(as<double>(i));
00195   }
00196 
00197   return sum;
00198 }
00199 
00200 
00201 /* compute log(factorial(x)) */
00202 double factFunc(int x)
00203 {
00204   /* construct a time monitor. This starts the timer. It will stop when leaving scope */
00205   TimeMonitor timer(factTimer());
00206 
00207   if (x==0) return 0;
00208   if (x==1) return 1;
00209   return std::log(as<double>(x))  + factFunc(x-1);
00210 }
00211 
00212 
00213 /* sum std::sqrt(x), x=[0, 10000). */
00214 double exceptFunc()
00215 {
00216   /* construct a time monitor. This starts the timer. It will stop when leaving scope */
00217   TimeMonitor timer(exceptTimer());
00218 
00219   double sum = 0.0;
00220   for (int i=0; i<10000; i++)
00221   {
00222     TEUCHOS_TEST_FOR_EXCEPTION(
00223       ScalarTraits<double>::squareroot(as<double>(i)) > 60.0, std::runtime_error,
00224       "throw an std::exception");
00225     sum += ScalarTraits<double>::squareroot(as<double>(i));
00226   }
00227   return sum;
00228 }
00229 
00230 
00231 /* sum x, x=[0, 10000). */
00232 double localFunc()
00233 {
00234   /* construct a time monitor. This starts the timer. It will stop when leaving scope */
00235   TimeMonitor timer(localTimer());
00236 
00237   double sum = 0.0;
00238 
00239   for (int i=0; i<10000; i++) 
00240   {
00241     sum += i;
00242   }
00243 
00244   return sum;
00245 }
00246 
00247 
00248 /* sum x^2, x=[0, 10000). */
00249 double anotherFunc()
00250 {
00251   /* construct a time monitor. This starts the timer. It will stop when leaving scope */
00252   TimeMonitor timer(anotherTimer());
00253 
00254   double sum = 0.0;
00255 
00256   for (int i=0; i<10000; i++) 
00257   {
00258     sum += i*i;
00259   }
00260 
00261   return sum;
00262 }
00263 
00264 
00265 /* sum x^3, x=[0, 10000). */
00266 double yetAnotherFunc()
00267 {
00268   /* construct a time monitor. This starts the timer. It will stop when leaving scope */
00269   TimeMonitor timer(yetAnotherTimer());
00270 
00271   double sum = 0.0;
00272 
00273   for (int i=0; i<10000; i++) 
00274   {
00275     sum += i*i*i;
00276   }
00277 
00278   return sum;
00279 }
00280 
00281 
00282 /* sum x+1, x=[0, 10000). */
00283 double yetOneMoreFunc()
00284 {
00285   /* construct a time monitor. This starts the timer. It will stop when leaving scope */
00286   TimeMonitor timer(yetOneMoreTimer());
00287 
00288   double sum = 0.0;
00289 
00290   for (int i=0; i<10000; i++) 
00291   {
00292     sum += i+1;
00293   }
00294 
00295   return sum;
00296 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines