1 //===================================================== 2 // File : btl.hh 3 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@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: BtlString()60 BtlString() : std::string() {} BtlString(const BtlString & str)61 BtlString(const BtlString& str) : std::string(static_cast<const std::string&>(str)) {} BtlString(const std::string & str)62 BtlString(const std::string& str) : std::string(str) {} BtlString(const char * str)63 BtlString(const char* str) : std::string(str) {} 64 operator const char*() const65 operator const char* () const { return c_str(); } 66 trim(bool left=true,bool right=true)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 split(const BtlString & delims="\\t\\n ") const81 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 endsWith(const BtlString & str) const108 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 } contains(const BtlString & str) const114 bool contains(const BtlString& str) const 115 { 116 return this->find(str)<this->size(); 117 } beginsWith(const BtlString & str) const118 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 toLowerCase(void)125 BtlString toLowerCase( void ) 126 { 127 std::transform(begin(), end(), begin(), static_cast<int(*)(int)>(::tolower) ); 128 return *this; 129 } toUpperCase(void)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 */ isEquiv(const BtlString & str) const138 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 */ decomposePathAndFile(BtlString & path,BtlString & filename) const150 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: BtlConfig()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 skipAction(const std::string & _name)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