Home | History | Annotate | Download | only in generic_bench
      1 //=====================================================
      2 // File   :  btl.hh
      3 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      4 //=====================================================
      5 //
      6 // This program is free software; you can redistribute it and/or
      7 // modify it under the terms of the GNU General Public License
      8 // as published by the Free Software Foundation; either version 2
      9 // of the License, or (at your option) any later version.
     10 //
     11 // This program is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 // You should have received a copy of the GNU General Public License
     16 // along with this program; if not, write to the Free Software
     17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     18 //
     19 #ifndef BTL_HH
     20 #define BTL_HH
     21 
     22 #include "bench_parameter.hh"
     23 #include <iostream>
     24 #include <algorithm>
     25 #include <vector>
     26 #include <string>
     27 #include "utilities.h"
     28 
     29 #if (defined __GNUC__)
     30 #define BTL_ALWAYS_INLINE __attribute__((always_inline)) inline
     31 #else
     32 #define BTL_ALWAYS_INLINE inline
     33 #endif
     34 
     35 #if (defined __GNUC__)
     36 #define BTL_DONT_INLINE __attribute__((noinline))
     37 #else
     38 #define BTL_DONT_INLINE
     39 #endif
     40 
     41 #if (defined __GNUC__)
     42 #define BTL_ASM_COMMENT(X)  asm("#" X)
     43 #else
     44 #define BTL_ASM_COMMENT(X)
     45 #endif
     46 
     47 #ifdef __SSE__
     48 #include "xmmintrin.h"
     49 // This enables flush to zero (FTZ) and denormals are zero (DAZ) modes:
     50 #define BTL_DISABLE_SSE_EXCEPTIONS()  { _mm_setcsr(_mm_getcsr() | 0x8040); }
     51 #else
     52 #define BTL_DISABLE_SSE_EXCEPTIONS()
     53 #endif
     54 
     55 /** Enhanced std::string
     56 */
     57 class BtlString : public std::string
     58 {
     59 public:
     60     BtlString() : std::string() {}
     61     BtlString(const BtlString& str) : std::string(static_cast<const std::string&>(str)) {}
     62     BtlString(const std::string& str) : std::string(str) {}
     63     BtlString(const char* str) : std::string(str) {}
     64 
     65     operator const char* () const { return c_str(); }
     66 
     67     void trim( bool left = true, bool right = true )
     68     {
     69         int lspaces, rspaces, len = length(), i;
     70         lspaces = rspaces = 0;
     71 
     72         if ( left )
     73             for (i=0; i<len && (at(i)==' '||at(i)=='\t'||at(i)=='\r'||at(i)=='\n'); ++lspaces,++i);
     74 
     75         if ( right && lspaces < len )
     76             for(i=len-1; i>=0 && (at(i)==' '||at(i)=='\t'||at(i)=='\r'||at(i)=='\n'); rspaces++,i--);
     77 
     78         *this = substr(lspaces, len-lspaces-rspaces);
     79     }
     80 
     81     std::vector<BtlString> split( const BtlString& delims = "\t\n ") const
     82     {
     83         std::vector<BtlString> ret;
     84         unsigned int numSplits = 0;
     85         size_t start, pos;
     86         start = 0;
     87         do
     88         {
     89             pos = find_first_of(delims, start);
     90             if (pos == start)
     91             {
     92                 ret.push_back("");
     93                 start = pos + 1;
     94             }
     95             else if (pos == npos)
     96                 ret.push_back( substr(start) );
     97             else
     98             {
     99                 ret.push_back( substr(start, pos - start) );
    100                 start = pos + 1;
    101             }
    102             //start = find_first_not_of(delims, start);
    103             ++numSplits;
    104         } while (pos != npos);
    105         return ret;
    106     }
    107 
    108     bool endsWith(const BtlString& str) const
    109     {
    110         if(str.size()>this->size())
    111             return false;
    112         return this->substr(this->size()-str.size(),str.size()) == str;
    113     }
    114     bool contains(const BtlString& str) const
    115     {
    116         return this->find(str)<this->size();
    117     }
    118     bool beginsWith(const BtlString& str) const
    119     {
    120         if(str.size()>this->size())
    121             return false;
    122         return this->substr(0,str.size()) == str;
    123     }
    124 
    125     BtlString toLowerCase( void )
    126     {
    127         std::transform(begin(), end(), begin(), static_cast<int(*)(int)>(::tolower) );
    128         return *this;
    129     }
    130     BtlString toUpperCase( void )
    131     {
    132         std::transform(begin(), end(), begin(), static_cast<int(*)(int)>(::toupper) );
    133         return *this;
    134     }
    135 
    136     /** Case insensitive comparison.
    137     */
    138     bool isEquiv(const BtlString& str) const
    139     {
    140         BtlString str0 = *this;
    141         str0.toLowerCase();
    142         BtlString str1 = str;
    143         str1.toLowerCase();
    144         return str0 == str1;
    145     }
    146 
    147     /** Decompose the current string as a path and a file.
    148         For instance: "dir1/dir2/file.ext" leads to path="dir1/dir2/" and filename="file.ext"
    149     */
    150     void decomposePathAndFile(BtlString& path, BtlString& filename) const
    151     {
    152         std::vector<BtlString> elements = this->split("/\\");
    153         path = "";
    154         filename = elements.back();
    155         elements.pop_back();
    156         if (this->at(0)=='/')
    157             path = "/";
    158         for (unsigned int i=0 ; i<elements.size() ; ++i)
    159             path += elements[i] + "/";
    160     }
    161 };
    162 
    163 class BtlConfig
    164 {
    165 public:
    166   BtlConfig()
    167     : overwriteResults(false), checkResults(true), realclock(false), tries(DEFAULT_NB_TRIES)
    168   {
    169     char * _config;
    170     _config = getenv ("BTL_CONFIG");
    171     if (_config!=NULL)
    172     {
    173       std::vector<BtlString> config = BtlString(_config).split(" \t\n");
    174       for (unsigned int i = 0; i<config.size(); i++)
    175       {
    176         if (config[i].beginsWith("-a"))
    177         {
    178           if (i+1==config.size())
    179           {
    180             std::cerr << "error processing option: " << config[i] << "\n";
    181             exit(2);
    182           }
    183           Instance.m_selectedActionNames = config[i+1].split(":");
    184 
    185           i += 1;
    186         }
    187         else if (config[i].beginsWith("-t"))
    188         {
    189           if (i+1==config.size())
    190           {
    191             std::cerr << "error processing option: " << config[i] << "\n";
    192             exit(2);
    193           }
    194           Instance.tries = atoi(config[i+1].c_str());
    195 
    196           i += 1;
    197         }
    198         else if (config[i].beginsWith("--overwrite"))
    199         {
    200           Instance.overwriteResults = true;
    201         }
    202         else if (config[i].beginsWith("--nocheck"))
    203         {
    204           Instance.checkResults = false;
    205         }
    206         else if (config[i].beginsWith("--real"))
    207         {
    208           Instance.realclock = true;
    209         }
    210       }
    211     }
    212 
    213     BTL_DISABLE_SSE_EXCEPTIONS();
    214   }
    215 
    216   BTL_DONT_INLINE static bool skipAction(const std::string& _name)
    217   {
    218     if (Instance.m_selectedActionNames.empty())
    219       return false;
    220 
    221     BtlString name(_name);
    222     for (unsigned int i=0; i<Instance.m_selectedActionNames.size(); ++i)
    223       if (name.contains(Instance.m_selectedActionNames[i]))
    224         return false;
    225 
    226     return true;
    227   }
    228 
    229   static BtlConfig Instance;
    230   bool overwriteResults;
    231   bool checkResults;
    232   bool realclock;
    233   int tries;
    234 
    235 protected:
    236   std::vector<BtlString> m_selectedActionNames;
    237 };
    238 
    239 #define BTL_MAIN \
    240   BtlConfig BtlConfig::Instance
    241 
    242 #endif // BTL_HH
    243