|
Teuchos Package Browser (Single Doxygen Collection)
Version of the Day
|
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 }
1.7.6.1