#include #include #include #include #include #include #include #include #include #include #include #include "rib.h" #include "config.h" using namespace std; BenchParameterNumeric::BenchParameterNumeric(size_t _begin) { begin = _begin; end = _begin; step = 1; step_type = LINEAR; } BenchParameterString::BenchParameterString(string _value) { value = _value; } void BenchParameterNumeric::reset() { current = begin; } void BenchParameterString::reset() { } void BenchParameterNumeric::print(ostream &s) { s << "bp: " << begin << "-" << end << "/" << step << endl; } void BenchParameterString::print(ostream &s) { s << "bp: " << value; } void BenchParameterNumeric::print_current(ostream &s, bool units) { if (units && (current != 0) && (current % 1024 == 0)) { if (current % (1024*1024) == 0) { s << current / (1024*1024) << "M"; } else { s << current / 1024 << "k"; } } else { s << current; } } void BenchParameterString::print_current(ostream &s, bool units) { s << value; } bool BenchParameterNumeric::nextStepPossible() { if (step_type == LINEAR) { if (current + step <= end) { return true; } else { return false; } } else if (step_type == EXPONENTIAL) { if (current * step <= end) { return true; } else { return false; } } else { assert(false); } } bool BenchParameterNumeric::nextStep() { if (step_type == LINEAR) { if (current + step <= end) { current += step; return true; } else { return false; } } else if (step_type == EXPONENTIAL) { if (current * step <= end) { current *= step; return true; } else { return false; } } else { assert(false); } } bool BenchParameterString::nextStepPossible() { return false; } bool BenchParameterString::nextStep() { return false; } bool BenchParameterNumeric::resume_from(BenchParameter * res) { BenchParameterNumeric * bp = (BenchParameterNumeric *) res; if (bp->begin >= this->begin && bp->begin <= this->end) { this->current = bp->begin; return true; } else { return false; } } bool BenchParameterString::resume_from(BenchParameter * res) { BenchParameterString * bp = (BenchParameterString *) res; if (bp->value == this->value) { return true; } else { return false; } } static size_t checkUnits(istringstream &i) { char c; c = i.peek(); if (c == 'k'|| c == 'K') { i >> c; return 1024; } else if (c == 'm' || c == 'M') { i >> c; return 1024*1024; } else { return 1; } } inline string trim(const std::string& s) { if(s.length() == 0) { return s; } int b = s.find_first_not_of(" \t"); int e = s.find_last_not_of(" \t"); if(b == -1) { return ""; } return std::string(s, b, e - b + 1); } void skip_ws(std::istream& i) { for (ios::int_type p = i.peek(); p == ' ' || p == '\t'; p = i.peek()) { i.ignore(1); } } // copied from http://www.digitalpeer.com/id/simple vector tokenize (const string & str, const string & delimiters) { vector tokens; // skip delimiters at beginning. string::size_type lastPos = str.find_first_not_of(delimiters, 0); // find first "non-delimiter". string::size_type pos = str.find_first_of(delimiters, lastPos); while (string::npos != pos || string::npos != lastPos) { // found a token, add it to the vector. tokens.push_back(str.substr(lastPos, pos - lastPos)); // skip delimiters. Note the "not_of" lastPos = str.find_first_not_of(delimiters, pos); // find next "non-delimiter" pos = str.find_first_of(delimiters, lastPos); } return tokens; } void replace_chars (std::string & str, char from, char to) { for (string::size_type pos = str.find_first_of(from); pos != string::npos; pos = str.find_first_of(from, pos + 1)) { str[pos] = to; } } std::map > parse_ini(const char * ini_filename) { string s; string name; string value; ifstream ini_file(ini_filename); char c = 0; map > res; string mapname = "global"; map m; params_list l; if (!ini_file) { cerr << "error opening " << ini_filename << endl; } while (getline(ini_file, s)) { s = trim(s); if (s.empty() || s[0] == '#') { continue; } if (s.length() > 2 && s[0] == '[' && s[s.length() - 1] == ']') { res[mapname] = m; mapname = s.substr(1, s.length() - 2); m.clear(); } l.clear(); string::size_type p = s.find('=', 0); if (p != string::npos) { istringstream i(s); getline (i, name, '='); name = trim(name); // cout << "name='" << name << "', value='" << value << "'" << endl; skip_ws(i); while (!i.eof()) { BenchParameter * bp; size_t begin; i >> begin; if (i.fail()) { i.clear(); string val; getline(i, val, ','); val = trim(val); // cout << bp->str_param << endl; if (!s.length()) { bp = NULL; } else { bp = new BenchParameterString(val); } if (!i.eof()) { i.putback(','); } } else { BenchParameterNumeric * bpn = new BenchParameterNumeric(begin * checkUnits(i)); skip_ws(i); if (i.peek() == '-') { i >> c; i >> bpn->end; bpn->end *= checkUnits(i); skip_ws(i); if (i.peek() == '/' || i.peek() == '^') { i >> c; i >> bpn->step; bpn->step *= checkUnits(i); if (c == '^') { bpn->step_type = BenchParameterNumeric::EXPONENTIAL; } skip_ws(i); } } bp = bpn; } // bp->print(); l.push_back(bp); skip_ws(i); i >> c; if (c != ',') { break; } } m[name] = l; } } res[mapname] = m; // for (map >::iterator mit = res.begin(); mit != res.end(); mit++) { // // cout << "map name: " << mit->first << endl; // // for (map::iterator it = mit->second.begin(); it != mit->second.end(); it++) { // // cout << "\tparam name: " << it->first << endl; // // params_list &lo = it->second; // // for (params_list::iterator it2 = lo.begin(); it2 != lo.end(); it2++) { // // cout << "\t\t"; // // (*it2)->print(cout); // // cout << endl; // // } // // } // // } // // exit(0); return res; } void free_ini(std::map > & allparams) { // dealocate global and any leftover sections for (map >::iterator it1 = allparams.begin(); it1 != allparams.end(); it1++) { map & paramsToDelete = it1->second; for (map::iterator it2 = paramsToDelete.begin(); it2 != paramsToDelete.end(); it2++) { params_list & paramToDelete = it2->second; for (params_list::iterator it3 = paramToDelete.begin(); it3 != paramToDelete.end(); it3++) { delete *it3; } } } }