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