• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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