diff options
Diffstat (limited to 'btl/generic_bench')
24 files changed, 2349 insertions, 0 deletions
diff --git a/btl/generic_bench/bench.hh b/btl/generic_bench/bench.hh new file mode 100644 index 0000000..4004797 --- /dev/null +++ b/btl/generic_bench/bench.hh @@ -0,0 +1,103 @@ +//===================================================== +// File : bench.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:16 CEST 2002 +// Copyright (C) 2011 Andrea Arteaga <andyspiros@gmail.com> +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef BENCH_HH +#define BENCH_HH + +#include "btl.hh" +#include "bench_parameter.hh" +#include <iostream> +#include "utilities.h" +#include "size_lin_log.hh" +#include "xy_file.hh" +#include <vector> +#include <string> +#include "timers/portable_perf_analyzer.hh" + +#ifdef DISTRIBUTED +#include "timers/distributed_perf_analyzer_root.hh" +#include "timers/distributed_perf_analyzer_node.hh" +#endif + +// #include "timers/mixed_perf_analyzer.hh" +// #include "timers/x86_perf_analyzer.hh" +// #include "timers/STL_perf_analyzer.hh" +#ifdef HAVE_MKL +extern "C" void cblas_saxpy(const int, const float, const float*, const int, float *, const int); +#endif + +template <template<class> class Perf_Analyzer, class Action> +BTL_DONT_INLINE void bench( int size_min, int size_max, int nb_point, bool silent = false ) +{ + std::string filename = "bench_"+Action::name()+".dat"; + + if (!silent) { INFOS("starting " <<filename); } + + // utilities + + std::vector<double> tab_mflops(nb_point); + std::vector<int> tab_sizes(nb_point); + + // matrices and vector size calculations + size_lin_log(nb_point,size_min,size_max,tab_sizes); + + // loop on matrix size + Perf_Analyzer<Action> perf_action; + for (int i=nb_point-1; i>=0; i--) + { + if (!silent) + std::cout << " " << "size = " << tab_sizes[i] << " " << std::flush; + + BTL_DISABLE_SSE_EXCEPTIONS(); + + tab_mflops[i] = perf_action.eval_mflops(tab_sizes[i], silent); + if (!silent) + std::cout << tab_mflops[i] << " MFlops (" << nb_point-i << "/" << nb_point << ")" << std::endl; + } + + // dump the result in a file : + if (!silent) dump_xy_file(tab_sizes, tab_mflops, filename); + +} + +// default Perf Analyzer + +template <class Action> +BTL_DONT_INLINE void bench( int size_min, int size_max, int nb_point, bool silent = false) +{ + bench<Portable_Perf_Analyzer,Action>(size_min,size_max,nb_point,silent); +} + +#ifdef DISTRIBUTED +// distributed Perf Analyzer + +template <class Action> +BTL_DONT_INLINE void distr_bench( int size_min, int size_max, int nb_point, bool silent = false) +{ + int myid, nproc; + blacs_pinfo_(&myid, &nproc); + if (myid) + bench<Distributed_Perf_Analyzer_Node, Action>(size_min, size_max, nb_point, silent); + else + bench<Distributed_Perf_Analyzer_Root, Action>(size_min, size_max, nb_point, silent); +} +#endif + +#endif diff --git a/btl/generic_bench/bench_parameter.hh b/btl/generic_bench/bench_parameter.hh new file mode 100644 index 0000000..4c355cd --- /dev/null +++ b/btl/generic_bench/bench_parameter.hh @@ -0,0 +1,53 @@ +//===================================================== +// File : bench_parameter.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:16 CEST 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef BENCH_PARAMETER_HH +#define BENCH_PARAMETER_HH + +// minimal time for each measurement +#define REAL_TYPE float +// minimal time for each measurement +#define MIN_TIME 0.2 +// nb of point on bench curves +#define NB_POINT 100 +// min vector size for axpy bench +#define MIN_AXPY 5 +// max vector size for axpy bench +#define MAX_AXPY 1000000 +// min matrix size for matrix vector product bench +#define MIN_MV 5 +// max matrix size for matrix vector product bench +#define MAX_MV 3000 +// min matrix size for matrix matrix product bench +#define MIN_MM 5 +// max matrix size for matrix matrix product bench +#define MAX_MM MAX_MV +// min matrix size for LU bench +#define MIN_LU 5 +// max matrix size for LU bench +#define MAX_LU 3000 +// max size for tiny vector and matrix +#define TINY_MV_MAX_SIZE 16 +// default nb_sample for x86 timer +#define DEFAULT_NB_SAMPLE 1000 + +// how many times we run a single bench (keep the best perf) +#define DEFAULT_NB_TRIES 3 + +#endif diff --git a/btl/generic_bench/btl.hh b/btl/generic_bench/btl.hh new file mode 100644 index 0000000..17cd397 --- /dev/null +++ b/btl/generic_bench/btl.hh @@ -0,0 +1,247 @@ +//===================================================== +// File : btl.hh +// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef BTL_HH +#define BTL_HH + +#include "bench_parameter.hh" +#include <iostream> +#include <algorithm> +#include <vector> +#include <string> +#include "utilities.h" + +#if (defined __GNUC__) +#define BTL_ALWAYS_INLINE __attribute__((always_inline)) inline +#else +#define BTL_ALWAYS_INLINE inline +#endif + +#if (defined __GNUC__) +#define BTL_DONT_INLINE __attribute__((noinline)) +#else +#define BTL_DONT_INLINE +#endif + +#if (defined __GNUC__) +#define BTL_ASM_COMMENT(X) asm("#"X) +#else +#define BTL_ASM_COMMENT(X) +#endif + +#if (defined __GNUC__) && (!defined __INTEL_COMPILER) && !defined(__arm__) && !defined(__powerpc__) +#define BTL_DISABLE_SSE_EXCEPTIONS() { \ + int aux; \ + asm( \ + "stmxcsr %[aux] \n\t" \ + "orl $32832, %[aux] \n\t" \ + "ldmxcsr %[aux] \n\t" \ + : : [aux] "m" (aux)); \ +} +#else +#define BTL_DISABLE_SSE_EXCEPTIONS() +#endif + +/** Enhanced std::string +*/ +class BtlString : public std::string +{ +public: + BtlString() : std::string() {} + BtlString(const BtlString& str) : std::string(static_cast<const std::string&>(str)) {} + BtlString(const std::string& str) : std::string(str) {} + BtlString(const char* str) : std::string(str) {} + + operator const char* () const { return c_str(); } + + void trim( bool left = true, bool right = true ) + { + int lspaces, rspaces, len = length(), i; + lspaces = rspaces = 0; + + if ( left ) + for (i=0; i<len && (at(i)==' '||at(i)=='\t'||at(i)=='\r'||at(i)=='\n'); ++lspaces,++i); + + if ( right && lspaces < len ) + for(i=len-1; i>=0 && (at(i)==' '||at(i)=='\t'||at(i)=='\r'||at(i)=='\n'); rspaces++,i--); + + *this = substr(lspaces, len-lspaces-rspaces); + } + + std::vector<BtlString> split( const BtlString& delims = "\t\n ") const + { + std::vector<BtlString> ret; + unsigned int numSplits = 0; + size_t start, pos; + start = 0; + do + { + pos = find_first_of(delims, start); + if (pos == start) + { + ret.push_back(""); + start = pos + 1; + } + else if (pos == npos) + ret.push_back( substr(start) ); + else + { + ret.push_back( substr(start, pos - start) ); + start = pos + 1; + } + //start = find_first_not_of(delims, start); + ++numSplits; + } while (pos != npos); + return ret; + } + + bool endsWith(const BtlString& str) const + { + if(str.size()>this->size()) + return false; + return this->substr(this->size()-str.size(),str.size()) == str; + } + bool contains(const BtlString& str) const + { + return this->find(str)<this->size(); + } + bool beginsWith(const BtlString& str) const + { + if(str.size()>this->size()) + return false; + return this->substr(0,str.size()) == str; + } + + BtlString toLowerCase( void ) + { + std::transform(begin(), end(), begin(), static_cast<int(*)(int)>(::tolower) ); + return *this; + } + BtlString toUpperCase( void ) + { + std::transform(begin(), end(), begin(), static_cast<int(*)(int)>(::toupper) ); + return *this; + } + + /** Case insensitive comparison. + */ + bool isEquiv(const BtlString& str) const + { + BtlString str0 = *this; + str0.toLowerCase(); + BtlString str1 = str; + str1.toLowerCase(); + return str0 == str1; + } + + /** Decompose the current string as a path and a file. + For instance: "dir1/dir2/file.ext" leads to path="dir1/dir2/" and filename="file.ext" + */ + void decomposePathAndFile(BtlString& path, BtlString& filename) const + { + std::vector<BtlString> elements = this->split("/\\"); + path = ""; + filename = elements.back(); + elements.pop_back(); + if (this->at(0)=='/') + path = "/"; + for (unsigned int i=0 ; i<elements.size() ; ++i) + path += elements[i] + "/"; + } +}; + +class BtlConfig +{ +public: + BtlConfig() + : overwriteResults(false), checkResults(true), realclock(false), tries(DEFAULT_NB_TRIES) + { + char * _config; + _config = getenv ("BTL_CONFIG"); + if (_config!=NULL) + { + std::vector<BtlString> config = BtlString(_config).split(" \t\n"); + for (int i = 0; i<config.size(); i++) + { + if (config[i].beginsWith("-a")) + { + if (i+1==config.size()) + { + std::cerr << "error processing option: " << config[i] << "\n"; + exit(2); + } + Instance.m_selectedActionNames = config[i+1].split(":"); + + i += 1; + } + else if (config[i].beginsWith("-t")) + { + if (i+1==config.size()) + { + std::cerr << "error processing option: " << config[i] << "\n"; + exit(2); + } + Instance.tries = atoi(config[i+1].c_str()); + + i += 1; + } + else if (config[i].beginsWith("--overwrite")) + { + Instance.overwriteResults = true; + } + else if (config[i].beginsWith("--nocheck")) + { + Instance.checkResults = false; + } + else if (config[i].beginsWith("--real")) + { + Instance.realclock = true; + } + } + } + + BTL_DISABLE_SSE_EXCEPTIONS(); + } + + BTL_DONT_INLINE static bool skipAction(const std::string& _name) + { + if (Instance.m_selectedActionNames.empty()) + return false; + + BtlString name(_name); + for (int i=0; i<Instance.m_selectedActionNames.size(); ++i) + if (name.contains(Instance.m_selectedActionNames[i])) + return false; + + return true; + } + + static BtlConfig Instance; + bool overwriteResults; + bool checkResults; + bool realclock; + int tries; + +protected: + std::vector<BtlString> m_selectedActionNames; +}; + +#define BTL_MAIN \ + BtlConfig BtlConfig::Instance + +#endif // BTL_HH diff --git a/btl/generic_bench/init/init_function.hh b/btl/generic_bench/init/init_function.hh new file mode 100644 index 0000000..7b3bdba --- /dev/null +++ b/btl/generic_bench/init/init_function.hh @@ -0,0 +1,54 @@ +//===================================================== +// File : init_function.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:18 CEST 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef INIT_FUNCTION_HH +#define INIT_FUNCTION_HH + +double simple_function(int index) +{ + return index; +} + +double simple_function(int index_i, int index_j) +{ + return index_i+index_j; +} + +double pseudo_random(int index) +{ + return std::rand()/double(RAND_MAX); +} + +double pseudo_random(int index_i, int index_j) +{ + return std::rand()/double(RAND_MAX); +} + + +double null_function(int index) +{ + return 0.0; +} + +double null_function(int index_i, int index_j) +{ + return 0.0; +} + +#endif diff --git a/btl/generic_bench/init/init_matrix.hh b/btl/generic_bench/init/init_matrix.hh new file mode 100644 index 0000000..c598ffc --- /dev/null +++ b/btl/generic_bench/init/init_matrix.hh @@ -0,0 +1,93 @@ +//===================================================== +// File : init_matrix.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002 +// Copyright (C) 2011 Andrea Arteaga <andyspiros@gmail.com> +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef INIT_MATRIX_HH +#define INIT_MATRIX_HH + +#include "LinearCongruential.hh" + +// The Vector class must satisfy the following part of STL vector concept : +// resize() method +// [] operator for setting element +// value_type defined +template<double init_function(int,int), class Vector> +BTL_DONT_INLINE void init_row(Vector & X, int size, int row){ + + X.resize(size); + + for (int j=0;j<X.size();j++){ + X[j]=typename Vector::value_type(init_function(row,j)); + } +} + + +// Matrix is a Vector of Vector +// The Matrix class must satisfy the following part of STL vector concept : +// resize() method +// [] operator for setting rows +template<double init_function(int,int),class Vector> +BTL_DONT_INLINE void init_matrix(Vector & A, int size){ + A.resize(size); + for (int row=0; row<A.size() ; row++){ + init_row<init_function>(A[row],size,row); + } +} + +template<double init_function(int,int),class Matrix> +BTL_DONT_INLINE void init_matrix_symm(Matrix& A, int size){ + A.resize(size); + for (int row=0; row<A.size() ; row++) + A[row].resize(size); + for (int row=0; row<A.size() ; row++){ + A[row][row] = init_function(row,row); + for (int col=0; col<row ; col++){ + double x = init_function(row,col); + A[row][col] = A[col][row] = x; + } + } +} + +template<class Matrix> BTL_DONT_INLINE +void init_matrix(Matrix& A, const int& size, const unsigned& seed) +{ + typedef typename Matrix::value_type value_t; + A.resize(size*size); + LinearCongruential rng(seed); + for (typename Matrix::iterator i = A.begin(), end = A.end(); i != end; ++i) + *i = rng.get_01(); +} + +template<class Matrix> BTL_DONT_INLINE +void init_SPD_matrix(Matrix& A, const int& size, const unsigned& seed) +{ + typedef typename Matrix::value_type value_t; + A.resize(size*size); + LinearCongruential rng(seed); + for (int r = 0; r < size; ++r) { + A[r+size*r] = rng.get_01() + size; + for (int c = r+1; c < size; ++c) { + const value_t v = rng.get_01(); + A[r+size*c] = v; + A[c+size*r] = v; + } + } +} + +#endif diff --git a/btl/generic_bench/init/init_vector.hh b/btl/generic_bench/init/init_vector.hh new file mode 100644 index 0000000..efaf0c9 --- /dev/null +++ b/btl/generic_bench/init/init_vector.hh @@ -0,0 +1,37 @@ +//===================================================== +// File : init_vector.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:18 CEST 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef INIT_VECTOR_HH +#define INIT_VECTOR_HH + +// The Vector class must satisfy the following part of STL vector concept : +// resize() method +// [] operator for setting element +// value_type defined +template<double init_function(int), class Vector> +void init_vector(Vector & X, int size){ + + X.resize(size); + + for (int i=0;i<X.size();i++){ + X[i]=typename Vector::value_type(init_function(i)); + } +} + +#endif diff --git a/btl/generic_bench/static/bench_static.hh b/btl/generic_bench/static/bench_static.hh new file mode 100644 index 0000000..23b55ec --- /dev/null +++ b/btl/generic_bench/static/bench_static.hh @@ -0,0 +1,80 @@ +//===================================================== +// File : bench_static.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:16 CEST 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef BENCH_STATIC_HH +#define BENCH_STATIC_HH + +#include "btl.hh" +#include "bench_parameter.hh" +#include <iostream> +#include "utilities.h" +#include "xy_file.hh" +#include "static/static_size_generator.hh" +#include "timers/portable_perf_analyzer.hh" +// #include "timers/mixed_perf_analyzer.hh" +// #include "timers/x86_perf_analyzer.hh" + +using namespace std; + + +template <template<class> class Perf_Analyzer, template<class> class Action, template<class,int> class Interface> +BTL_DONT_INLINE void bench_static(void) +{ + if (BtlConfig::skipAction(Action<Interface<REAL_TYPE,10> >::name())) + return; + + string filename = "bench_" + Action<Interface<REAL_TYPE,10> >::name() + ".dat"; + + INFOS("starting " << filename); + + const int max_size = TINY_MV_MAX_SIZE; + + std::vector<double> tab_mflops; + std::vector<double> tab_sizes; + + static_size_generator<max_size,Perf_Analyzer,Action,Interface>::go(tab_sizes,tab_mflops); + + dump_xy_file(tab_sizes,tab_mflops,filename); +} + +// default Perf Analyzer +template <template<class> class Action, template<class,int> class Interface> +BTL_DONT_INLINE void bench_static(void) +{ + bench_static<Portable_Perf_Analyzer,Action,Interface>(); + //bench_static<Mixed_Perf_Analyzer,Action,Interface>(); + //bench_static<X86_Perf_Analyzer,Action,Interface>(); +} + +#endif + + + + + + + + + + + + + + + diff --git a/btl/generic_bench/static/intel_bench_fixed_size.hh b/btl/generic_bench/static/intel_bench_fixed_size.hh new file mode 100644 index 0000000..b4edcbc --- /dev/null +++ b/btl/generic_bench/static/intel_bench_fixed_size.hh @@ -0,0 +1,66 @@ +//===================================================== +// File : intel_bench_fixed_size.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar déc 3 18:59:37 CET 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef _BENCH_FIXED_SIZE_HH_ +#define _BENCH_FIXED_SIZE_HH_ + +#include "utilities.h" +#include "function_time.hh" + +template <class Action> +double bench_fixed_size(int size, unsigned long long & nb_calc,unsigned long long & nb_init) +{ + + Action action(size); + + double time_baseline=time_init(nb_init,action); + + while (time_baseline < MIN_TIME) { + + //INFOS("nb_init="<<nb_init); + //INFOS("time_baseline="<<time_baseline); + nb_init*=2; + time_baseline=time_init(nb_init,action); + } + + time_baseline=time_baseline/(double(nb_init)); + + double time_action=time_calculate(nb_calc,action); + + while (time_action < MIN_TIME) { + + nb_calc*=2; + time_action=time_calculate(nb_calc,action); + } + + INFOS("nb_init="<<nb_init); + INFOS("nb_calc="<<nb_calc); + + + time_action=time_action/(double(nb_calc)); + + action.check_result(); + + time_action=time_action-time_baseline; + + return action.nb_op_base()/(time_action*1000000.0); + +} + +#endif diff --git a/btl/generic_bench/static/static_size_generator.hh b/btl/generic_bench/static/static_size_generator.hh new file mode 100644 index 0000000..dd02df3 --- /dev/null +++ b/btl/generic_bench/static/static_size_generator.hh @@ -0,0 +1,57 @@ +//===================================================== +// File : static_size_generator.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar déc 3 18:59:36 CET 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef _STATIC_SIZE_GENERATOR_HH +#define _STATIC_SIZE_GENERATOR_HH +#include <vector> + +using namespace std; + +//recursive generation of statically defined matrix and vector sizes + +template <int SIZE,template<class> class Perf_Analyzer, template<class> class Action, template<class,int> class Interface> +struct static_size_generator{ + static void go(vector<double> & tab_sizes, vector<double> & tab_mflops) + { + tab_sizes.push_back(SIZE); + std::cout << tab_sizes.back() << " \t" << std::flush; + Perf_Analyzer<Action<Interface<REAL_TYPE,SIZE> > > perf_action; + tab_mflops.push_back(perf_action.eval_mflops(SIZE)); + std::cout << tab_mflops.back() << " MFlops" << std::endl; + static_size_generator<SIZE-1,Perf_Analyzer,Action,Interface>::go(tab_sizes,tab_mflops); + }; +}; + +//recursion end + +template <template<class> class Perf_Analyzer, template<class> class Action, template<class,int> class Interface> +struct static_size_generator<1,Perf_Analyzer,Action,Interface>{ + static void go(vector<double> & tab_sizes, vector<double> & tab_mflops) + { + tab_sizes.push_back(1); + Perf_Analyzer<Action<Interface<REAL_TYPE,1> > > perf_action; + tab_mflops.push_back(perf_action.eval_mflops(1)); + }; +}; + +#endif + + + + diff --git a/btl/generic_bench/timers/STL_perf_analyzer.hh b/btl/generic_bench/timers/STL_perf_analyzer.hh new file mode 100644 index 0000000..c9f894b --- /dev/null +++ b/btl/generic_bench/timers/STL_perf_analyzer.hh @@ -0,0 +1,82 @@ +//===================================================== +// File : STL_perf_analyzer.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar déc 3 18:59:35 CET 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef _STL_PERF_ANALYSER_HH +#define _STL_PERF_ANALYSER_HH + +#include "STL_timer.hh" +#include "bench_parameter.hh" + +template<class ACTION> +class STL_Perf_Analyzer{ +public: + STL_Perf_Analyzer(unsigned long long nb_sample=DEFAULT_NB_SAMPLE):_nb_sample(nb_sample),_chronos() + { + MESSAGE("STL_Perf_Analyzer Ctor"); + }; + STL_Perf_Analyzer( const STL_Perf_Analyzer & ){ + INFOS("Copy Ctor not implemented"); + exit(0); + }; + ~STL_Perf_Analyzer( void ){ + MESSAGE("STL_Perf_Analyzer Dtor"); + }; + + + inline double eval_mflops(int size) + { + + ACTION action(size); + + _chronos.start_baseline(_nb_sample); + + do { + + action.initialize(); + } while (_chronos.check()); + + double baseline_time=_chronos.get_time(); + + _chronos.start(_nb_sample); + do { + action.initialize(); + action.calculate(); + } while (_chronos.check()); + + double calculate_time=_chronos.get_time(); + + double corrected_time=calculate_time-baseline_time; + + // cout << size <<" "<<baseline_time<<" "<<calculate_time<<" "<<corrected_time<<" "<<action.nb_op_base() << endl; + + return action.nb_op_base()/(corrected_time*1000000.0); + //return action.nb_op_base()/(calculate_time*1000000.0); + + } +private: + + STL_Timer _chronos; + unsigned long long _nb_sample; + + +}; + + + +#endif diff --git a/btl/generic_bench/timers/STL_timer.hh b/btl/generic_bench/timers/STL_timer.hh new file mode 100644 index 0000000..19c54e9 --- /dev/null +++ b/btl/generic_bench/timers/STL_timer.hh @@ -0,0 +1,78 @@ +//===================================================== +// File : STL_Timer.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar déc 3 18:59:35 CET 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// STL Timer Class. Adapted (L.P.) from the timer class by Musser et Al +// described int the Book : STL Tutorial and reference guide. +// Define a timer class for analyzing algorithm performance. +#include <iostream> +#include <iomanip> +#include <vector> +#include <map> +#include <algorithm> +using namespace std; + +class STL_Timer { +public: + STL_Timer(){ baseline = false; }; // Default constructor + // Start a series of r trials: + void start(unsigned int r){ + reps = r; + count = 0; + iterations.clear(); + iterations.reserve(reps); + initial = time(0); + }; + // Start a series of r trials to determine baseline time: + void start_baseline(unsigned int r) + { + baseline = true; + start(r); + } + // Returns true if the trials have been completed, else false + bool check() + { + ++count; + final = time(0); + if (initial < final) { + iterations.push_back(count); + initial = final; + count = 0; + } + return (iterations.size() < reps); + }; + // Returns the results for external use + double get_time( void ) + { + sort(iterations.begin(), iterations.end()); + return 1.0/iterations[reps/2]; + }; +private: + unsigned int reps; // Number of trials + // For storing loop iterations of a trial + vector<long> iterations; + // For saving initial and final times of a trial + time_t initial, final; + // For counting loop iterations of a trial + unsigned long count; + // true if this is a baseline computation, false otherwise + bool baseline; + // For recording the baseline time + double baseline_time; +}; + diff --git a/btl/generic_bench/timers/distributed_perf_analyzer_node.hh b/btl/generic_bench/timers/distributed_perf_analyzer_node.hh new file mode 100644 index 0000000..924eb87 --- /dev/null +++ b/btl/generic_bench/timers/distributed_perf_analyzer_node.hh @@ -0,0 +1,95 @@ +//===================================================== +// Copyright (C) 2011 Andrea Arteaga <andyspiros@gmail.com> +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef _PORTABLE_PERF_ANALYZER_NODE_HH +#define _PORTABLE_PERF_ANALYZER_NODE_HH + +#include "utilities.h" +#include "timers/portable_timer.hh" +#include "blacs.h" + +template <class Action> +class Distributed_Perf_Analyzer_Node{ +public: + Distributed_Perf_Analyzer_Node( ):_nb_calc(0){ + MESSAGE("Distributed_Perf_Analyzer_Node Ctor"); + int temp, what = 0; + blacs_get_(&temp, &what, &context); + }; + Distributed_Perf_Analyzer_Node( const Distributed_Perf_Analyzer_Node& ){ + INFOS("Copy Ctor not implemented"); + exit(0); + }; + ~Distributed_Perf_Analyzer_Node(){ + MESSAGE("Distributed_Perf_Analyzer_Node Dtor"); + }; + + BTL_DONT_INLINE double eval_mflops(int size, bool silent = false) + { + Action action(size); + + /* Find best _nb_calc_ */ + int bcast_receive, iZERO = 0, iONE = 1; + igebr2d_(&context, "A", " ", &iONE, &iONE, &bcast_receive, &iONE, &iZERO, &iZERO); + while (bcast_receive > 0) { + _nb_calc = bcast_receive; + action.initialize(); + time_calculate(action); + igebr2d_(&context, "A", " ", &iONE, &iONE, &bcast_receive, &iONE, &iZERO, &iZERO); + } + int tries = -bcast_receive; + + /* Optimize */ + for (int i = 1; i < tries; ++i) { + Action _action(size); + _action.initialize(); + time_calculate(_action); + } + + /* Check */ + int do_check; + igebr2d_(&context, "A", " ", &iONE, &iONE, &do_check, &iONE, &iZERO, &iZERO); + if (do_check > 0) { + action.initialize(); + action.calculate(); + action.check_result(); + } + + /* Return a void value */ + return 0.; + } + + BTL_DONT_INLINE void time_calculate(Action & action) + { + // no need for time measurement + action.calculate(); + for (int i = 0; i < _nb_calc; ++i) + action.calculate(); + } + + unsigned long long get_nb_calc() + { + return _nb_calc; + } + + +private: + int context; + unsigned long long _nb_calc; +}; + +#endif //_PORTABLE_PERF_ANALYZER_NODE_HH diff --git a/btl/generic_bench/timers/distributed_perf_analyzer_root.hh b/btl/generic_bench/timers/distributed_perf_analyzer_root.hh new file mode 100644 index 0000000..bbab901 --- /dev/null +++ b/btl/generic_bench/timers/distributed_perf_analyzer_root.hh @@ -0,0 +1,116 @@ +//===================================================== +// Copyright (C) 2011 Andrea Arteaga <andyspiros@gmail.com> +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef _PORTABLE_PERF_ANALYZER_ROOT_HH +#define _PORTABLE_PERF_ANALYZER_ROOT_HH + +#include "utilities.h" +#include "timers/portable_timer.hh" +#include "blacs.h" + +template <class Action> +class Distributed_Perf_Analyzer_Root{ +public: + Distributed_Perf_Analyzer_Root( ):_nb_calc(0), m_time_action(0), _chronos(){ + MESSAGE("Distributed_Perf_Analyzer_Root Ctor"); + int temp, what = 0; + blacs_get_(&temp, &what, &context); + }; + Distributed_Perf_Analyzer_Root( const Distributed_Perf_Analyzer_Root & ){ + INFOS("Copy Ctor not implemented"); + exit(0); + }; + ~Distributed_Perf_Analyzer_Root(){ + MESSAGE("Distributed_Perf_Analyzer_Root Dtor"); + }; + + BTL_DONT_INLINE double eval_mflops(int size, bool silent = false) + { + Action action(size); + m_time_action = 0; + _nb_calc = 0; + + /* Find best _nb_calc_ */ + int bcast_send = _nb_calc; + int iONE = 1; + while (m_time_action < MIN_TIME) { + _nb_calc = _nb_calc ? 2*_nb_calc : 1; + bcast_send = _nb_calc; + igebs2d_(&context, "A", " ", &iONE, &iONE, &bcast_send, &iONE); + action.initialize(); + m_time_action = time_calculate(action); + } + int tries = BtlConfig::Instance.tries; + bcast_send = -tries; + igebs2d_(&context, "A", " ", &iONE, &iONE, &bcast_send, &iONE); + + /* Optimize */ + for (int i = 1; i < tries; ++i) { + Action _action(size); + if (!silent) + std::cout << " " << _action.nb_op_base()*_nb_calc/(m_time_action*1e6) << " " << std::flush; + _action.initialize(); + m_time_action = std::min(m_time_action, time_calculate(_action)); + } + double time_action = m_time_action / (double(_nb_calc)); + + /* Check */ + int do_check = (BtlConfig::Instance.checkResults && size<128) ? 1 : 1; + igebs2d_(&context, "A", " ", &iONE, &iONE, &do_check, &iONE); + if (do_check > 0) { + action.initialize(); + action.calculate(); + action.check_result(); + } + + return action.nb_op_base()/(time_action*1e6); + } + + BTL_DONT_INLINE double time_calculate(Action & action) + { + // time measurement + action.calculate(); + _chronos.start(); + for (int ii=0; ii<_nb_calc; ii++) + { + action.calculate(); + } + _chronos.stop(); + + double user_time = _chronos.user_time(); + if (user_time < 0) { + std::cout << " { error: nb=" << _nb_calc << ", time=" << user_time << " } " << std::flush; + } + return user_time; + } + + unsigned long long get_nb_calc() + { + return _nb_calc; + } + + +private: + int context; + unsigned long long _nb_calc; + double m_time_action; + Portable_Timer _chronos; + +}; + +#endif //_PORTABLE_PERF_ANALYZER_ROOT_HH + diff --git a/btl/generic_bench/timers/mixed_perf_analyzer.hh b/btl/generic_bench/timers/mixed_perf_analyzer.hh new file mode 100644 index 0000000..e190236 --- /dev/null +++ b/btl/generic_bench/timers/mixed_perf_analyzer.hh @@ -0,0 +1,73 @@ +//===================================================== +// File : mixed_perf_analyzer.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar déc 3 18:59:36 CET 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef _MIXED_PERF_ANALYSER_HH +#define _MIXED_PERF_ANALYSER_HH + +#include "x86_perf_analyzer.hh" +#include "portable_perf_analyzer.hh" + +// choose portable perf analyzer for long calculations and x86 analyser for short ones + + +template<class Action> +class Mixed_Perf_Analyzer{ + +public: + Mixed_Perf_Analyzer( void ):_x86pa(),_ppa(),_use_ppa(true) + { + MESSAGE("Mixed_Perf_Analyzer Ctor"); + }; + Mixed_Perf_Analyzer( const Mixed_Perf_Analyzer & ){ + INFOS("Copy Ctor not implemented"); + exit(0); + }; + ~Mixed_Perf_Analyzer( void ){ + MESSAGE("Mixed_Perf_Analyzer Dtor"); + }; + + + inline double eval_mflops(int size) + { + + double result=0.0; + if (_use_ppa){ + result=_ppa.eval_mflops(size); + if (_ppa.get_nb_calc()>DEFAULT_NB_SAMPLE){_use_ppa=false;} + } + else{ + result=_x86pa.eval_mflops(size); + } + + return result; + } + +private: + + Portable_Perf_Analyzer<Action> _ppa; + X86_Perf_Analyzer<Action> _x86pa; + bool _use_ppa; + +}; + +#endif + + + + diff --git a/btl/generic_bench/timers/portable_perf_analyzer.hh b/btl/generic_bench/timers/portable_perf_analyzer.hh new file mode 100644 index 0000000..b207bde --- /dev/null +++ b/btl/generic_bench/timers/portable_perf_analyzer.hh @@ -0,0 +1,110 @@ +//===================================================== +// File : portable_perf_analyzer.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar d�c 3 18:59:35 CET 2002 +// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> +// Copyright (C) 2011 Andrea Arteaga <andyspiros@gmail.com> +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef _PORTABLE_PERF_ANALYZER_HH +#define _PORTABLE_PERF_ANALYZER_HH + +#include "utilities.h" +#include "timers/portable_timer.hh" +#include <iomanip> + +template <class Action> +class Portable_Perf_Analyzer{ +public: + Portable_Perf_Analyzer( ):_nb_calc(0), m_time_action(0), _chronos(){ + MESSAGE("Portable_Perf_Analyzer Ctor"); + }; + Portable_Perf_Analyzer( const Portable_Perf_Analyzer & ){ + INFOS("Copy Ctor not implemented"); + exit(0); + }; + ~Portable_Perf_Analyzer(){ + MESSAGE("Portable_Perf_Analyzer Dtor"); + }; + + BTL_DONT_INLINE double eval_mflops(int size, bool silent = false) + { + Action action(size); + + while (m_time_action < MIN_TIME) { + _nb_calc = _nb_calc ? 2*_nb_calc : 1; + action.initialize(); + m_time_action = time_calculate(action); + } + + // optimize + for (int i=1; i<BtlConfig::Instance.tries; ++i) + { + Action _action(size); + if (!silent) { + if (_action.nb_op_base()*_nb_calc < 0) + std::cout << " { op*calc = " << _action.nb_op_base()*_nb_calc << " } " << std::flush; + std::cout << " " << _action.nb_op_base()*_nb_calc/(m_time_action*1e6) << " "; + } + _action.initialize(); + m_time_action = std::min(m_time_action, time_calculate(_action)); + } + + double time_action = m_time_action / (double(_nb_calc)); + + // check + if (BtlConfig::Instance.checkResults && size<128) + { + action.initialize(); + action.calculate(); + action.check_result(); + } + return action.nb_op_base()/(time_action*1e6); + } + + BTL_DONT_INLINE double time_calculate(Action & action) + { + // time measurement + action.calculate(); + _chronos.start(); + for (int ii=0; ii<_nb_calc; ii++) + { + action.calculate(); + } + _chronos.stop(); + + double user_time = _chronos.user_time(); + if (user_time < 0) { + std::cout << " { error: nb=" << _nb_calc << ", time=" << user_time << " } " << std::flush; + } + return user_time; + } + + unsigned long long get_nb_calc() + { + return _nb_calc; + } + + +private: + unsigned long long _nb_calc; + double m_time_action; + Portable_Timer _chronos; + +}; + +#endif //_PORTABLE_PERF_ANALYZER_HH + diff --git a/btl/generic_bench/timers/portable_perf_analyzer_old.hh b/btl/generic_bench/timers/portable_perf_analyzer_old.hh new file mode 100644 index 0000000..fce3781 --- /dev/null +++ b/btl/generic_bench/timers/portable_perf_analyzer_old.hh @@ -0,0 +1,134 @@ +//===================================================== +// File : portable_perf_analyzer.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar d�c 3 18:59:35 CET 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef _PORTABLE_PERF_ANALYZER_HH +#define _PORTABLE_PERF_ANALYZER_HH + +#include "utilities.h" +#include "timers/portable_timer.hh" + +template <class Action> +class Portable_Perf_Analyzer{ +public: + Portable_Perf_Analyzer( void ):_nb_calc(1),_nb_init(1),_chronos(){ + MESSAGE("Portable_Perf_Analyzer Ctor"); + }; + Portable_Perf_Analyzer( const Portable_Perf_Analyzer & ){ + INFOS("Copy Ctor not implemented"); + exit(0); + }; + ~Portable_Perf_Analyzer( void ){ + MESSAGE("Portable_Perf_Analyzer Dtor"); + }; + + + + inline double eval_mflops(int size) + { + + Action action(size); + +// double time_baseline = time_init(action); +// while (time_baseline < MIN_TIME_INIT) +// { +// _nb_init *= 2; +// time_baseline = time_init(action); +// } +// +// // optimize +// for (int i=1; i<NB_TRIES; ++i) +// time_baseline = std::min(time_baseline, time_init(action)); +// +// time_baseline = time_baseline/(double(_nb_init)); + + double time_action = time_calculate(action); + while (time_action < MIN_TIME) + { + _nb_calc *= 2; + time_action = time_calculate(action); + } + + // optimize + for (int i=1; i<NB_TRIES; ++i) + time_action = std::min(time_action, time_calculate(action)); + +// INFOS("size="<<size); +// INFOS("_nb_init="<<_nb_init); +// INFOS("_nb_calc="<<_nb_calc); + + time_action = time_action / (double(_nb_calc)); + + action.check_result(); + + + double time_baseline = time_init(action); + for (int i=1; i<NB_TRIES; ++i) + time_baseline = std::min(time_baseline, time_init(action)); + time_baseline = time_baseline/(double(_nb_init)); + + + +// INFOS("time_baseline="<<time_baseline); +// INFOS("time_action="<<time_action); + + time_action = time_action - time_baseline; + +// INFOS("time_corrected="<<time_action); + + return action.nb_op_base()/(time_action*1000000.0); + } + + inline double time_init(Action & action) + { + // time measurement + _chronos.start(); + for (int ii=0; ii<_nb_init; ii++) + action.initialize(); + _chronos.stop(); + return _chronos.user_time(); + } + + + inline double time_calculate(Action & action) + { + // time measurement + _chronos.start(); + for (int ii=0;ii<_nb_calc;ii++) + { + action.initialize(); + action.calculate(); + } + _chronos.stop(); + return _chronos.user_time(); + } + + unsigned long long get_nb_calc( void ) + { + return _nb_calc; + } + + +private: + unsigned long long _nb_calc; + unsigned long long _nb_init; + Portable_Timer _chronos; + +}; + +#endif //_PORTABLE_PERF_ANALYZER_HH diff --git a/btl/generic_bench/timers/portable_timer.hh b/btl/generic_bench/timers/portable_timer.hh new file mode 100755 index 0000000..e6ad309 --- /dev/null +++ b/btl/generic_bench/timers/portable_timer.hh @@ -0,0 +1,145 @@ +//===================================================== +// File : portable_timer.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> from boost lib +// Copyright (C) EDF R&D, lun sep 30 14:23:17 CEST 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// simple_time extracted from the boost library +// +#ifndef _PORTABLE_TIMER_HH +#define _PORTABLE_TIMER_HH + +#include <ctime> +#include <cstdlib> + +#include <time.h> + + +#define USEC_IN_SEC 1000000 + + +// timer -------------------------------------------------------------------// + +// A timer object measures CPU time. +#ifdef _MSC_VER + +#define NOMINMAX +#include <windows.h> + +/*#ifndef hr_timer +#include "hr_time.h" +#define hr_timer +#endif*/ + + class Portable_Timer + { + public: + + typedef struct { + LARGE_INTEGER start; + LARGE_INTEGER stop; + } stopWatch; + + + Portable_Timer() + { + startVal.QuadPart = 0; + stopVal.QuadPart = 0; + QueryPerformanceFrequency(&frequency); + } + + void start() { QueryPerformanceCounter(&startVal); } + + void stop() { QueryPerformanceCounter(&stopVal); } + + double elapsed() { + LARGE_INTEGER time; + time.QuadPart = stopVal.QuadPart - startVal.QuadPart; + return LIToSecs(time); + } + + double user_time() { return elapsed(); } + + + private: + + double LIToSecs(LARGE_INTEGER& L) { + return ((double)L.QuadPart /(double)frequency.QuadPart) ; + } + + LARGE_INTEGER startVal; + LARGE_INTEGER stopVal; + LARGE_INTEGER frequency; + + + }; // Portable_Timer + +#else + +#include <sys/time.h> +#include <sys/resource.h> +#include <unistd.h> +#include <sys/times.h> + +class Portable_Timer +{ + public: + + Portable_Timer() + { + m_clkid = BtlConfig::Instance.realclock ? CLOCK_REALTIME : CLOCK_PROCESS_CPUTIME_ID; + } + + Portable_Timer(int clkid) : m_clkid(clkid) + {} + + void start() + { + timespec ts; + clock_gettime(m_clkid, &ts); + m_start_time = double(ts.tv_sec) + 1e-9 * double(ts.tv_nsec); + + } + + void stop() + { + timespec ts; + clock_gettime(m_clkid, &ts); + m_stop_time = double(ts.tv_sec) + 1e-9 * double(ts.tv_nsec); + + } + + double elapsed() + { + return user_time(); + } + + double user_time() + { + return m_stop_time - m_start_time; + } + + +private: + + int m_clkid; + double m_stop_time, m_start_time; + +}; // Portable_Timer + +#endif + +#endif // PORTABLE_TIMER_HPP diff --git a/btl/generic_bench/timers/x86_perf_analyzer.hh b/btl/generic_bench/timers/x86_perf_analyzer.hh new file mode 100644 index 0000000..37ea21d --- /dev/null +++ b/btl/generic_bench/timers/x86_perf_analyzer.hh @@ -0,0 +1,108 @@ +//===================================================== +// File : x86_perf_analyzer.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar d�c 3 18:59:35 CET 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef _X86_PERF_ANALYSER_HH +#define _X86_PERF_ANALYSER_HH + +#include "x86_timer.hh" +#include "bench_parameter.hh" + +template<class ACTION> +class X86_Perf_Analyzer{ +public: + X86_Perf_Analyzer( unsigned long long nb_sample=DEFAULT_NB_SAMPLE):_nb_sample(nb_sample),_chronos() + { + MESSAGE("X86_Perf_Analyzer Ctor"); + _chronos.find_frequency(); + }; + X86_Perf_Analyzer( const X86_Perf_Analyzer & ){ + INFOS("Copy Ctor not implemented"); + exit(0); + }; + ~X86_Perf_Analyzer( void ){ + MESSAGE("X86_Perf_Analyzer Dtor"); + }; + + + inline double eval_mflops(int size) + { + + ACTION action(size); + + int nb_loop=5; + double calculate_time=0.0; + double baseline_time=0.0; + + for (int j=0 ; j < nb_loop ; j++){ + + _chronos.clear(); + + for(int i=0 ; i < _nb_sample ; i++) + { + _chronos.start(); + action.initialize(); + action.calculate(); + _chronos.stop(); + _chronos.add_get_click(); + } + + calculate_time += double(_chronos.get_shortest_clicks())/_chronos.frequency(); + + if (j==0) action.check_result(); + + _chronos.clear(); + + for(int i=0 ; i < _nb_sample ; i++) + { + _chronos.start(); + action.initialize(); + _chronos.stop(); + _chronos.add_get_click(); + + } + + baseline_time+=double(_chronos.get_shortest_clicks())/_chronos.frequency(); + + } + + double corrected_time = (calculate_time-baseline_time)/double(nb_loop); + + +// INFOS("_nb_sample="<<_nb_sample); +// INFOS("baseline_time="<<baseline_time); +// INFOS("calculate_time="<<calculate_time); +// INFOS("corrected_time="<<corrected_time); + +// cout << size <<" "<<baseline_time<<" "<<calculate_time<<" "<<corrected_time<<" "<<action.nb_op_base() << endl; + + return action.nb_op_base()/(corrected_time*1000000.0); + //return action.nb_op_base()/(calculate_time*1000000.0); + } + +private: + + X86_Timer _chronos; + unsigned long long _nb_sample; + + +}; + + + +#endif diff --git a/btl/generic_bench/timers/x86_timer.hh b/btl/generic_bench/timers/x86_timer.hh new file mode 100644 index 0000000..cfb5ee8 --- /dev/null +++ b/btl/generic_bench/timers/x86_timer.hh @@ -0,0 +1,246 @@ +//===================================================== +// File : x86_timer.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar d�c 3 18:59:35 CET 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef _X86_TIMER_HH +#define _X86_TIMER_HH + +#include <sys/time.h> +#include <sys/resource.h> +#include <unistd.h> +#include <sys/times.h> +//#include "system_time.h" +#define u32 unsigned int +#include <asm/msr.h> +#include "utilities.h" +#include <map> +#include <fstream> +#include <string> +#include <iostream> + +// frequence de la becanne en Hz +//#define FREQUENCY 648000000 +//#define FREQUENCY 1400000000 +#define FREQUENCY 1695000000 + +using namespace std; + + +class X86_Timer { + +public : + + X86_Timer( void ):_frequency(FREQUENCY),_nb_sample(0) + { + MESSAGE("X86_Timer Default Ctor"); + } + + inline void start( void ){ + + rdtsc(_click_start.n32[0],_click_start.n32[1]); + + } + + + inline void stop( void ){ + + rdtsc(_click_stop.n32[0],_click_stop.n32[1]); + + } + + + inline double frequency( void ){ + return _frequency; + } + + double get_elapsed_time_in_second( void ){ + + return (_click_stop.n64-_click_start.n64)/double(FREQUENCY); + + + } + + unsigned long long get_click( void ){ + + return (_click_stop.n64-_click_start.n64); + + } + + inline void find_frequency( void ){ + + time_t initial, final; + int dummy=2; + + initial = time(0); + start(); + do { + dummy+=2; + } + while(time(0)==initial); + // On est au debut d'un cycle d'une seconde !!! + initial = time(0); + start(); + do { + dummy+=2; + } + while(time(0)==initial); + final=time(0); + stop(); + // INFOS("fine grained time : "<< get_elapsed_time_in_second()); + // INFOS("coarse grained time : "<< final-initial); + _frequency=_frequency*get_elapsed_time_in_second()/double(final-initial); + /// INFOS("CPU frequency : "<< _frequency); + + } + + void add_get_click( void ){ + + _nb_sample++; + _counted_clicks[get_click()]++; + fill_history_clicks(); + + } + + void dump_statistics(string filemane){ + + ofstream outfile (filemane.c_str(),ios::out) ; + + std::map<unsigned long long , unsigned long long>::iterator itr; + for(itr=_counted_clicks.begin() ; itr!=_counted_clicks.end() ; itr++) + { + outfile << (*itr).first << " " << (*itr).second << endl ; + } + + outfile.close(); + + } + + void dump_history(string filemane){ + + ofstream outfile (filemane.c_str(),ios::out) ; + + + + for(int i=0 ; i<_history_mean_clicks.size() ; i++) + { + outfile << i << " " + << _history_mean_clicks[i] << " " + << _history_shortest_clicks[i] << " " + << _history_most_occured_clicks[i] << endl ; + } + + outfile.close(); + + } + + + + double get_mean_clicks( void ){ + + std::map<unsigned long long,unsigned long long>::iterator itr; + + unsigned long long mean_clicks=0; + + for(itr=_counted_clicks.begin() ; itr!=_counted_clicks.end() ; itr++) + { + + mean_clicks+=(*itr).second*(*itr).first; + } + + return mean_clicks/double(_nb_sample); + + } + + double get_shortest_clicks( void ){ + + return double((*_counted_clicks.begin()).first); + + } + + void fill_history_clicks( void ){ + + _history_mean_clicks.push_back(get_mean_clicks()); + _history_shortest_clicks.push_back(get_shortest_clicks()); + _history_most_occured_clicks.push_back(get_most_occured_clicks()); + + } + + + double get_most_occured_clicks( void ){ + + unsigned long long moc=0; + unsigned long long max_occurence=0; + + std::map<unsigned long long,unsigned long long>::iterator itr; + + for(itr=_counted_clicks.begin() ; itr!=_counted_clicks.end() ; itr++) + { + + if (max_occurence<=(*itr).second){ + max_occurence=(*itr).second; + moc=(*itr).first; + } + } + + return double(moc); + + } + + void clear( void ) + { + _counted_clicks.clear(); + + _history_mean_clicks.clear(); + _history_shortest_clicks.clear(); + _history_most_occured_clicks.clear(); + + _nb_sample=0; + } + + + +private : + + union + { + unsigned long int n32[2] ; + unsigned long long n64 ; + } _click_start; + + union + { + unsigned long int n32[2] ; + unsigned long long n64 ; + } _click_stop; + + double _frequency ; + + map<unsigned long long,unsigned long long> _counted_clicks; + + vector<double> _history_mean_clicks; + vector<double> _history_shortest_clicks; + vector<double> _history_most_occured_clicks; + + unsigned long long _nb_sample; + + + +}; + + +#endif diff --git a/btl/generic_bench/utils/LinearCongruential.hh b/btl/generic_bench/utils/LinearCongruential.hh new file mode 100644 index 0000000..3aa3716 --- /dev/null +++ b/btl/generic_bench/utils/LinearCongruential.hh @@ -0,0 +1,83 @@ +//===================================================== +// Copyright (C) 2011 Andrea Arteaga <andyspiros@gmail.com> +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef LINEARCONGRUENTIAL_HH_ +#define LINEARCONGRUENTIAL_HH_ + +#include <vector> + +class LinearCongruential +{ + typedef std::vector<unsigned> buffer_t; + typedef unsigned int_t; + +public: + LinearCongruential(const int_t& seed) : + a_(1664525u), c_(1013904223u), m_(getM()), i_(0) + { + buffer_.resize(4096/sizeof(unsigned)); + fillBuffer(seed); + } + + int_t a() const { return a_; } + int_t c() const { return c_; } + int_t m() const { return m_; } + + int_t get_int() { + if (i_ >= buffer_.size()) { + fillBuffer(); + i_ = 0; + } + return buffer_.at(i_++); + } + + double get_01() { + return static_cast<double>(get_int())/static_cast<double>(m_); + } + +private: + buffer_t buffer_; + const int_t a_, c_, m_; + std::size_t i_; + + void fillBuffer(const int_t& seed) + { + buffer_.front() = (seed*a_+c_) & m_; + for ( + typename buffer_t::iterator i = buffer_.begin()+1, end = buffer_.end(); + i != end; ++i) + *i = (*(i-1)*a_ + c_) & m_; + } + + void fillBuffer() + { + const int_t seed = buffer_.back(); + fillBuffer(seed); + } + + static int_t getM() + { + int_t _m = 1; + for (int i = 1; i < 32; ++i) { + _m <<= 1; + _m += 1; + } + return _m; + } +}; + +#endif /* LINEARCONGRUENTIAL_HH_ */ diff --git a/btl/generic_bench/utils/size_lin_log.hh b/btl/generic_bench/utils/size_lin_log.hh new file mode 100644 index 0000000..7c272c0 --- /dev/null +++ b/btl/generic_bench/utils/size_lin_log.hh @@ -0,0 +1,70 @@ +//===================================================== +// File : size_lin_log.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar déc 3 18:59:37 CET 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef SIZE_LIN_LOG +#define SIZE_LIN_LOG + +#include "size_log.hh" + +template<class Vector> +void size_lin_log(const int nb_point, const int size_min, const int size_max, Vector & X) +{ + int ten=10; + int nine=9; + + X.resize(nb_point); + + if (nb_point>ten){ + + for (int i=0;i<nine;i++){ + + X[i]=i+size_min; + + } + + Vector log_size; + size_log(nb_point-nine,nine+size_min,size_max,log_size); + + for (int i=0;i<nb_point-nine;i++){ + + X[i+nine]=log_size[i]; + + } + } + else{ + + for (int i=0;i<nb_point;i++){ + + X[i]=i+1; + + } + } + + // for (int i=0;i<nb_point;i++){ + +// INFOS("computed sizes : X["<<i<<"]="<<X[i]); + +// } + +} + +#endif + + + diff --git a/btl/generic_bench/utils/size_log.hh b/btl/generic_bench/utils/size_log.hh new file mode 100644 index 0000000..13a3da7 --- /dev/null +++ b/btl/generic_bench/utils/size_log.hh @@ -0,0 +1,54 @@ +//===================================================== +// File : size_log.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:17 CEST 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef SIZE_LOG +#define SIZE_LOG + +#include "math.h" +// The Vector class must satisfy the following part of STL vector concept : +// resize() method +// [] operator for seting element +// the vector element are int compatible. +template<class Vector> +void size_log(const int nb_point, const int size_min, const int size_max, Vector & X) +{ + X.resize(nb_point); + + float ls_min=log(float(size_min)); + float ls_max=log(float(size_max)); + + float ls=0.0; + + float delta_ls=(ls_max-ls_min)/(float(nb_point-1)); + + int size=0; + + for (int i=0;i<nb_point;i++){ + + ls = ls_min + float(i)*delta_ls ; + + size=int(exp(ls)); + + X[i]=size; + } + +} + + +#endif diff --git a/btl/generic_bench/utils/utilities.h b/btl/generic_bench/utils/utilities.h new file mode 100644 index 0000000..d2330d0 --- /dev/null +++ b/btl/generic_bench/utils/utilities.h @@ -0,0 +1,90 @@ +//============================================================================= +// File : utilities.h +// Created : mar jun 19 13:18:14 CEST 2001 +// Author : Antoine YESSAYAN, Paul RASCLE, EDF +// Project : SALOME +// Copyright : EDF 2001 +// $Header$ +//============================================================================= + +/* --- Definition macros file to print information if _DEBUG_ is defined --- */ + +# ifndef UTILITIES_H +# define UTILITIES_H + +# include <stdlib.h> +//# include <iostream> ok for gcc3.01 +# include <iostream> + +/* --- INFOS is always defined (without _DEBUG_): to be used for warnings, with release version --- */ + +# define HEREWEARE cout<<flush ; cerr << __FILE__ << " [" << __LINE__ << "] : " << flush ; +# define INFOS(chain) {HEREWEARE ; cerr << chain << endl ;} +# define PYSCRIPT(chain) {cout<<flush ; cerr << "---PYSCRIPT--- " << chain << endl ;} + +/* --- To print date and time of compilation of current source on stdout --- */ + +# if defined ( __GNUC__ ) +# define COMPILER "g++" ; +# elif defined ( __sun ) +# define COMPILER "CC" ; +# elif defined ( __KCC ) +# define COMPILER "KCC" ; +# elif defined ( __PGI ) +# define COMPILER "pgCC" ; +# else +# define COMPILER "undefined" ; +# endif + +# ifdef INFOS_COMPILATION +# error INFOS_COMPILATION already defined +# endif +# define INFOS_COMPILATION {\ + cerr << flush;\ + cout << __FILE__ ;\ + cout << " [" << __LINE__ << "] : " ;\ + cout << "COMPILED with " << COMPILER ;\ + cout << ", " << __DATE__ ; \ + cout << " at " << __TIME__ << endl ;\ + cout << "\n\n" ;\ + cout << flush ;\ + } + +# ifdef _DEBUG_ + +/* --- the following MACROS are useful at debug time --- */ + +# define HERE cout<<flush ; cerr << "- Trace " << __FILE__ << " [" << __LINE__ << "] : " << flush ; +# define SCRUTE(var) HERE ; cerr << #var << "=" << var << endl ; +# define MESSAGE(chain) {HERE ; cerr << chain << endl ;} +# define INTERRUPTION(code) HERE ; cerr << "INTERRUPTION return code= " << code << endl ; exit(code) ; + +# ifndef ASSERT +# define ASSERT(condition) if (!(condition)){ HERE ; cerr << "CONDITION " << #condition << " NOT VERIFIED"<< endl ; INTERRUPTION(1) ;} +# endif /* ASSERT */ + +#define REPERE cout<<flush ; cerr << " --------------" << endl << flush ; +#define BEGIN_OF(chain) {REPERE ; HERE ; cerr << "Begin of: " << chain << endl ; REPERE ; } +#define END_OF(chain) {REPERE ; HERE ; cerr << "Normal end of: " << chain << endl ; REPERE ; } + + + +# else /* ifdef _DEBUG_*/ + +# define HERE +# define SCRUTE(var) +# define MESSAGE(chain) +# define INTERRUPTION(code) + +# ifndef ASSERT +# define ASSERT(condition) +# endif /* ASSERT */ + +#define REPERE +#define BEGIN_OF(chain) +#define END_OF(chain) + + +# endif /* ifdef _DEBUG_*/ + +# endif /* ifndef UTILITIES_H */ diff --git a/btl/generic_bench/utils/xy_file.hh b/btl/generic_bench/utils/xy_file.hh new file mode 100644 index 0000000..4571bed --- /dev/null +++ b/btl/generic_bench/utils/xy_file.hh @@ -0,0 +1,75 @@ +//===================================================== +// File : dump_file_x_y.hh +// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:20 CEST 2002 +//===================================================== +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#ifndef XY_FILE_HH +#define XY_FILE_HH +#include <fstream> +#include <iostream> +#include <string> +#include <vector> +using namespace std; + +bool read_xy_file(const std::string & filename, std::vector<int> & tab_sizes, + std::vector<double> & tab_mflops, bool quiet = false) +{ + + std::ifstream input_file (filename.c_str(),std::ios::in); + + if (!input_file){ + if (!quiet) { + INFOS("!!! Error opening "<<filename); + } + return false; + } + + int nb_point=0; + int size=0; + double mflops=0; + + while (input_file >> size >> mflops ){ + nb_point++; + tab_sizes.push_back(size); + tab_mflops.push_back(mflops); + } + SCRUTE(nb_point); + + input_file.close(); + return true; +} + +// The Vector class must satisfy the following part of STL vector concept : +// resize() method +// [] operator for seting element +// the vector element must have the << operator define + +using namespace std; + +template<class Vector_A, class Vector_B> +void dump_xy_file(const Vector_A & X, const Vector_B & Y, const std::string & filename){ + + ofstream outfile (filename.c_str(),ios::out) ; + int size=X.size(); + + for (int i=0;i<size;i++) + outfile << X[i] << " " << Y[i] << endl; + + outfile.close(); +} + +#endif |