test_benchmarks.cpp

00001 /*--------------------------------------------------------------------*/
00002 /*    Copyright 2005 Sandia Corporation.                              */
00003 /*    Under the terms of Contract DE-AC04-94AL85000, there is a       */
00004 /*    non-exclusive license for use of this work by or on behalf      */
00005 /*    of the U.S. Government.  Export of this program may require     */
00006 /*    a license from the United States Government.                    */
00007 /*--------------------------------------------------------------------*/
00008 
00009 #include <fei_macros.hpp>
00010 #include <fei_utils.hpp>
00011 #include <test_utils/fei_test_utils.hpp>
00012 #include <test_utils/test_benchmarks.hpp>
00013 #include <snl_fei_Utils.hpp>
00014 #include <fei_ctg_set.hpp>
00015 #include <snl_fei_RaggedTable.hpp>
00016 #include <snl_fei_RaggedTable_specialize.hpp>
00017 #include <test_utils/HexBeam.hpp>
00018 
00019 #undef fei_file
00020 #define fei_file "test_benchmarks.cpp"
00021 
00022 #include <fei_ErrMacros.hpp>
00023 
00024 test_benchmarks::test_benchmarks(MPI_Comm comm)
00025   : tester(comm)
00026 {
00027 }
00028 
00029 test_benchmarks::~test_benchmarks()
00030 {
00031 }
00032 
00033 template<typename MAP_TYPE, typename SET_TYPE>
00034 double time_raggedtable_insert(int len)
00035 {
00036   double start_time = fei::utils::cpu_time();
00037 
00038   HexBeam hexcube(10, len, 1, HexBeam::OneD, 1, 0);
00039 
00040   snl_fei::RaggedTable<MAP_TYPE,SET_TYPE> table(0, hexcube.numLocalNodes());
00041 
00042   int numIndices = hexcube.numNodesPerElem();
00043 
00044   int* indices = new int[numIndices];
00045 
00046   int first = hexcube.firstLocalElem();
00047 
00048   for(int n=0; n<hexcube.numLocalElems(); ++n) {
00049     int elem = first+n;
00050 
00051     hexcube.getElemConnectivity(elem, indices);
00052 
00053     table.addIndices(numIndices, indices, numIndices, indices);
00054   }
00055 
00056   delete [] indices;
00057 
00058   double elapsed_time = fei::utils::cpu_time() - start_time;
00059   return(elapsed_time);
00060 }
00061 
00062 template<typename MAP_TYPE, typename SET_TYPE>
00063 double benchmark_raggedtable()
00064 {
00065   int len = 80;
00066 
00067   //first find a len such that time_taken is at least 1 second
00068   double time_taken = time_raggedtable_insert<MAP_TYPE,SET_TYPE>(len);
00069   while(time_taken < 1.0) {
00070     len *= 2;
00071     time_taken = time_raggedtable_insert<MAP_TYPE,SET_TYPE>(len);
00072   }
00073 
00074   //now repeat until time_taken passes 5 seconds
00075   time_taken = 0.0;
00076   int i=0;
00077   while(time_taken<5.0) {
00078     time_taken += time_raggedtable_insert<MAP_TYPE,SET_TYPE>(len);
00079     ++i;
00080   }
00081 
00082   return((double)(i*len)/time_taken);
00083 }
00084 
00085 void print_benchmark_banner()
00086 {
00087 
00088   FEI_COUT.width(38);
00089   FEI_COUT << " Benchmark name         ";
00090   FEI_COUT.width(10);
00091   FEI_COUT << "Value  ";
00092   FEI_COUT.width(12);
00093   FEI_COUT << "gold-copy";
00094   FEI_COUT.width(10);
00095   FEI_COUT <<" Result "<<FEI_ENDL;
00096 
00097   FEI_COUT.width(38);
00098   FEI_COUT << " -----------------------";
00099   FEI_COUT.width(10);
00100   FEI_COUT << "-----  ";
00101   FEI_COUT.width(12);
00102   FEI_COUT << "---------";
00103   FEI_COUT.width(10);
00104   FEI_COUT <<" ------ "<<FEI_ENDL;
00105 }
00106 
00107 void print_benchmark_line(const char* name,
00108         double value,
00109         double goldvalue,
00110         const char* passfail)
00111 {
00112   FEI_COUT.setf(IOS_FIXED, IOS_FLOATFIELD);
00113   FEI_COUT.precision(1);
00114 
00115   FEI_COUT.width(38);
00116   FEI_COUT << name;
00117   FEI_COUT.width(10);
00118   FEI_COUT << value;
00119   FEI_COUT.width(12);
00120   if (goldvalue < 0.0) FEI_COUT << "n/a";
00121   else FEI_COUT << goldvalue;
00122   FEI_COUT.width(10);
00123   FEI_COUT << passfail << FEI_ENDL;
00124 }
00125 
00126 std::string add_macro_values(const char* name)
00127 {
00128   FEI_OSTRINGSTREAM osstr;
00129   osstr << name;
00130 
00131 #if defined(FEI_PLATFORM) && defined(FEI_OPT_LEVEL)
00132   osstr << "_" << FEI_PLATFORM << "_" << FEI_OPT_LEVEL;
00133 #else
00134   osstr << "_unknown_unknown";
00135 #endif
00136 
00137   return(osstr.str());
00138 }
00139 
00140 int test_benchmarks::runtests()
00141 {
00142   if (numProcs_ > 1) return(0);
00143 
00144   //CHK_ERR( test3() );
00145 
00146   FEI_COUT << FEI_ENDL
00147      << "  ***** Benchmarks pass if within 10% of 'gold-copy' *****"
00148      <<FEI_ENDL<<FEI_ENDL;
00149 
00150 #if defined(FEI_PLATFORM) && defined(FEI_OPT_LEVEL)
00151   FEI_COUT << "  FEI_PLATFORM: "<<FEI_PLATFORM
00152      <<", FEI_OPT_LEVEL: "<<FEI_OPT_LEVEL
00153      <<FEI_ENDL<<FEI_ENDL;
00154   FEI_COUT << "  'gold-copy' benchmark values will be searched for in ./fei_utest_timings.txt"<<FEI_ENDL;
00155   FEI_COUT <<FEI_ENDL;
00156 #else
00157   FEI_COUT << "  preprocessor macros FEI_PLATFORM and FEI_OPT_LEVEL aren't defined, so"<<FEI_ENDL;
00158   FEI_COUT << "  ./fei_utest_timings.txt will not be searched for 'gold-copy' benchmark values"<<FEI_ENDL<<FEI_ENDL;
00159 #endif
00160 
00161   CHK_ERR( test1() );
00162   CHK_ERR( test2() );
00163   CHK_ERR( test4() );
00164   CHK_ERR( test5() );
00165   CHK_ERR( test6() );
00166   CHK_ERR( test7() );
00167   CHK_ERR( test8() );
00168 
00169   return(0);
00170 }
00171 
00172 int test_benchmarks::test1()
00173 {
00174   FEI_COUT << "Following group of benchmarks inserts integers into ragged tables"
00175      << " (simulating"<<FEI_ENDL
00176      << "matrix-graph construction) using various data structures."<<FEI_ENDL
00177      << "A higher number is better, indicating more insertions"
00178      << " in fixed amount of time." << FEI_ENDL<<FEI_ENDL;
00179 
00180   print_benchmark_banner();
00181 
00182   int returnValue = 0;
00183   double value, goldvalue;
00184   std::string passfail;
00185   std::string testname;
00186 
00187   value = benchmark_raggedtable<std::map<int,std::set<int>*>,std::set<int> >();
00188   goldvalue = -1.0;
00189   passfail = " ";
00190   print_benchmark_line("std::map<std::set>", value, goldvalue, passfail.c_str());
00191 
00192   testname = add_macro_values("std::map<fei::ctg_set>");
00193   value = benchmark_raggedtable<std::map<int,fei::ctg_set<int>*>,fei::ctg_set<int> >();
00194   try {
00195     goldvalue = fei_test_utils::get_file_benchmark("./fei_utest_timings.txt",
00196               testname.c_str());
00197     passfail = fei_test_utils::check_test_result(value, goldvalue, 10);
00198     if (passfail != "passed") returnValue = -1;
00199   }
00200   catch(...) {
00201     goldvalue = -1.0;
00202     passfail = " ";
00203   }
00204 
00205   print_benchmark_line("std::map<fei::ctg_set>", value, goldvalue, passfail.c_str());
00206 
00207 
00208 
00209   testname = add_macro_values("snl_fei::MapContig<fei::ctg_set>");
00210   value = benchmark_raggedtable<snl_fei::MapContig<fei::ctg_set<int>*>,fei::ctg_set<int> >();
00211   try {
00212     goldvalue = fei_test_utils::get_file_benchmark("./fei_utest_timings.txt",
00213               testname.c_str());
00214     passfail = fei_test_utils::check_test_result(value, goldvalue, 10);
00215     if (passfail != "passed") returnValue = -1;
00216   }
00217   catch(...) {
00218     goldvalue = -1.0;
00219     passfail = " ";
00220   }
00221 
00222   print_benchmark_line("snl_fei::MapContig<fei::ctg_set>", value, goldvalue, passfail.c_str());
00223 
00224 
00225 
00226 #ifdef FEI_HASH_MAP
00227   value = benchmark_raggedtable<FEI_HASH_MAP<int,FEI_HASH_SET<int>*>,FEI_HASH_SET<int> >();
00228   goldvalue = -1.0;
00229   passfail = " ";
00230   print_benchmark_line("hash_map<hash_set>", value, goldvalue, passfail.c_str());
00231 
00232 
00233 #endif
00234 
00235 
00236   FEI_COUT << FEI_ENDL;
00237   if (returnValue != 0) {
00238     FEI_COUT << "at least 1 benchmark failed."<< FEI_ENDL << FEI_ENDL;
00239   }
00240   return(returnValue);
00241 }
00242 
00243 template<typename SET_TYPE>
00244 double time_set_insert(int len)
00245 {
00246   double start_time = fei::utils::cpu_time();
00247 
00248   SET_TYPE* set_objs = new SET_TYPE[len];
00249 
00250   int inner = 24;
00251   int outer = 8;
00252 
00253   int first = 9000;
00254   int inner_2 = inner/2;
00255 
00256   for(int n=0; n<len; ++n) {
00257     int col_n = first+n;
00258     SET_TYPE& set_ref = set_objs[n];
00259 
00260     for(int i=0; i<outer; ++i) {
00261       int col_i = col_n+i*outer;
00262 
00263       for(int j=0; j<inner_2; ++j) {
00264   set_ref.insert(col_i+j);
00265   set_ref.insert(col_i+j+inner_2);
00266       }
00267     }
00268   }
00269 
00270   delete [] set_objs;
00271 
00272   double elapsed_time = fei::utils::cpu_time() - start_time;
00273   return(elapsed_time);
00274 }
00275 
00276 template<typename SET_TYPE>
00277 double time_set_insert2(int len)
00278 {
00279   double start_time = fei::utils::cpu_time();
00280 
00281   SET_TYPE* set_objs = new SET_TYPE[len];
00282 
00283   int inner = 24;
00284   int outer = 8;
00285 
00286   int first = 9000;
00287 
00288   for(int n=0; n<len; ++n) {
00289     int col_n = first+n;
00290     SET_TYPE& set_ref = set_objs[n];
00291 
00292     for(int i=0; i<outer; ++i) {
00293       int col_i = col_n+i*outer;
00294 
00295       for(int j=0; j<inner/2; ++j) {
00296   set_ref.insert2(col_i+j);
00297   set_ref.insert2(col_i+j+inner/2);
00298       }
00299     }
00300   }
00301 
00302   delete [] set_objs;
00303 
00304   double elapsed_time = fei::utils::cpu_time() - start_time;
00305   return(elapsed_time);
00306 }
00307 
00308 template<typename SET_TYPE>
00309 double benchmark_set()
00310 {
00311   int len = 1200;
00312 
00313   //first find a len such that time_taken is at least 1 second
00314   double time_taken = time_set_insert<SET_TYPE>(len);
00315   while(time_taken < 1.0) {
00316     len *= 2;
00317     time_taken = time_set_insert<SET_TYPE>(len);
00318   }
00319 
00320   //now repeat until time_taken passes 5 seconds
00321   time_taken = 0.0;
00322   int i=0;
00323   while(time_taken<5.0) {
00324     time_taken += time_set_insert<SET_TYPE>(len);
00325     ++i;
00326   }
00327 
00328   return((double)(i*len)/time_taken);
00329 }
00330 
00331 template<typename SET_TYPE>
00332 double benchmark_set2()
00333 {
00334   int len = 1200;
00335 
00336   //first find a len such that time_taken is at least 1 second
00337   double time_taken = time_set_insert2<SET_TYPE>(len);
00338   while(time_taken < 1.0) {
00339     len *= 2;
00340     time_taken = time_set_insert2<SET_TYPE>(len);
00341   }
00342 
00343   //now repeat until time_taken passes 5 seconds
00344   time_taken = 0.0;
00345   int i=0;
00346   while(time_taken<5.0) {
00347     time_taken += time_set_insert2<SET_TYPE>(len);
00348     ++i;
00349   }
00350 
00351   return((double)(i*len)/time_taken);
00352 }
00353 
00354 
00355 int test_benchmarks::test2()
00356 {
00357   int returnValue = 0;
00358 
00359   FEI_COUT<<FEI_ENDL;
00360   FEI_COUT << "Following group of benchmarks inserts integers into sorted lists"
00361      << " (actually"<<FEI_ENDL
00362      << "sets), which is a sub-task of the ragged-table benchmarks..."<<FEI_ENDL
00363      << "A higher number is better."<<FEI_ENDL<<FEI_ENDL;
00364 
00365   print_benchmark_banner();
00366 
00367   double value, goldvalue;
00368   std::string passfail;
00369   std::string testname;
00370 
00371 
00372   value = benchmark_set<fei::ctg_set<int> >();
00373   testname = add_macro_values("fei::ctg_set");
00374   try {
00375     goldvalue = fei_test_utils::get_file_benchmark("./fei_utest_timings.txt",
00376               testname.c_str());
00377     passfail = fei_test_utils::check_test_result(value, goldvalue, 10);
00378     if (passfail != "passed") returnValue = -1;
00379   }
00380   catch(...) {
00381     goldvalue = -1.0;
00382     passfail = " ";
00383   }
00384 
00385   print_benchmark_line("fei::ctg_set::insert", value, goldvalue, passfail.c_str());
00386 
00387 
00388 #ifndef FEI_NO_STL_SET
00389 
00390   value = benchmark_set<std::set<int> >();
00391   goldvalue = -1.0;
00392   passfail = " ";
00393   print_benchmark_line("std::set::insert", value, goldvalue, passfail.c_str());
00394 
00395 #endif
00396 
00397 #ifdef FEI_HASH_SET
00398 
00399   value = benchmark_set<FEI_HASH_SET<int> >();
00400   goldvalue = -1.0;
00401   passfail = " ";
00402   print_benchmark_line("hash_set::insert", value, goldvalue, passfail.c_str());
00403 
00404 #endif
00405   FEI_COUT << FEI_ENDL;
00406   FEI_COUT << "More list/set insertions..." << FEI_ENDL << FEI_ENDL;
00407 
00408   print_benchmark_banner();
00409 
00410 
00411   value = benchmark_set2<fei::ctg_set<int> >();
00412   testname = add_macro_values("fei::ctg_set2");
00413   try {
00414     goldvalue = fei_test_utils::get_file_benchmark("./fei_utest_timings.txt",
00415               testname.c_str());
00416     passfail = fei_test_utils::check_test_result(value, goldvalue, 10);
00417     if (passfail != "passed") returnValue = -1;
00418   }
00419   catch(...) {
00420     goldvalue = -1.0;
00421     passfail = " ";
00422   }
00423 
00424   print_benchmark_line("fei::ctg_set::insert2", value, goldvalue, passfail.c_str());
00425 
00426   FEI_COUT << FEI_ENDL;
00427   if (returnValue != 0) {
00428     FEI_COUT << "at least 1 benchmark failed."<< FEI_ENDL << FEI_ENDL;
00429   }
00430 
00431   return(returnValue);
00432 }
00433 
00434 int test_benchmarks::test3()
00435 {
00436   int len = 100000;
00437   int   n = 100000;
00438 
00439   std::vector<int> stdvector(len);
00440 
00441   std::vector<int> stdv_dest;
00442 
00443   int* stdvptr = &(stdvector[0]);
00444 
00445   for(int i=0; i<len; ++i) {
00446     stdvptr[i] = i*2;
00447   }
00448 
00449   FEI_COUT << FEI_ENDL << "time to perform " << n
00450            << " binary-searches and inserts on an std::vector" << FEI_ENDL
00451      << " of length " << len << ": " << FEI_ENDL;
00452 
00453   double start_time = fei::utils::cpu_time();
00454 
00455   stdvector.reserve(n*2);
00456 
00457   std::vector<int>::iterator
00458     v_iter,
00459     v_beg = stdvector.begin(),
00460     v_end = stdvector.end();
00461 
00462   for(int k=0; k<n; ++k) {
00463     v_iter = std::lower_bound(v_beg, v_end, k*2);
00464     stdvector.insert(v_iter, k*2-1);
00465     v_beg = stdvector.begin();
00466     v_end = stdvector.end();
00467   }
00468 
00469   double elapsed_time = fei::utils::cpu_time() - start_time;
00470 
00471   FEI_COUT << elapsed_time << FEI_ENDL;
00472 
00473   return(0);
00474 }
00475 
00476 int test_benchmarks::test4()
00477 {
00478   return(0);
00479 }
00480 
00481 int test_benchmarks::test5()
00482 {
00483   return(0);
00484 }
00485 
00486 int test_benchmarks::test6()
00487 {
00488   return(0);
00489 }
00490 
00491 int test_benchmarks::test7()
00492 {
00493   return(0);
00494 }
00495 
00496 int test_benchmarks::test8()
00497 {
00498   return(0);
00499 }
00500 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends
Generated on Wed Apr 13 10:08:25 2011 for FEI by  doxygen 1.6.3