#include #include #include "params.h" using namespace std; /******************************************************************/ /* PUBLIC METHODS */ /******************************************************************/ BenchParams::BenchParams() : advanced(false) { } BenchParams::~BenchParams() { // delete all instances of BenchParameter that we point to through iniDefs or unmanaged for (vector::iterator it1 = iniDefs.begin(); it1 != iniDefs.end(); it1++) { params_list & paramsToDelete = *it1; for (params_list::iterator it2 = paramsToDelete.begin(); it2 != paramsToDelete.end(); it2++) { delete *it2; } paramsToDelete.clear(); } iniDefs.clear(); for (map::iterator itt = unmanagedParams.begin(); itt != unmanagedParams.end(); itt++) { delete itt->second; } unmanagedParams.clear(); } void BenchParams::initialize (map & params, bool plot) { // try to read values (parameter lists) of all defined parameters from the ini file // and put them either to iniDefs or unmanaged // iterate over all parameter definitions for (int i = 0; i < countAll(); i++) { const param_def & paramDef = allDefs[i]; // obtain name of parameter from definition const string & paramName = paramDef.name; // see if the parameter is defined in rib.ini map::iterator it = params.find(paramName); if (it == params.end()) { // TODO: distinguish optional parameters? cerr << "missing parameter " << paramName << " in rib.ini" << endl; if (!plot) { exit(EXIT_FAILURE); } } else { // for managed parameters, store the list of values to iniDefs // and also the definition to defs if (paramDef.managed) { iniDefs.push_back(it->second); defs.push_back(paramDef); } else { // unmanaged parameters need to have only one instance, not list params_list unmanagedParamValues = it->second; assert(unmanagedParamValues.size() == 1); // get the parameter BenchParameter * unmanagedParam = it->second.front(); // reset the parameter to its first value unmanagedParam->reset(); // unmanaged parameters cannot be e.g. ranges of values assert(!unmanagedParam->nextStepPossible()); // put the value in unmanaged unmanagedParams[paramName] = unmanagedParam; } } params.erase(it); } int iniCount = count(); // prepare structures holding values and lookup structures currentIt.reserve(iniCount); current.reserve(iniCount); for (int i = 0; i < iniCount; i++) { if (defs[i].type == NUMERIC) { orderMapNumeric[defs[i].name] = i; } else if (defs[i].type == STRING) { orderMapString[defs[i].name] = i; } else { assert(false); } orderMapAll[defs[i].name] = i; if (defs[i].mult == MULT) { multParams.push_back(defs[i].name); } else if (defs[i].mult == DIV) { divParams.push_back(defs[i].name); } } orderCurrent = -1; } void BenchParams::resume (const map & params) { int cnt = countAll(); for (int i = 0; i < cnt; i++) { // unmanaged parameters are not stored nor needed in rib.resume if (!allDefs[i].managed) { continue; } map::const_iterator it = params.find(allDefs[i].name); if (it == params.end()) { cerr << "missing parameter " << allDefs[i].name << " in rib.resume" << endl; exit(1); } currentIt[i] = iniDefs[i].begin(); while (currentIt[i] != iniDefs[i].end()) { current[i] = *currentIt[i]; if (current[i]->resume_from(*it->second.begin())) { break; } else { currentIt[i]++; } } if (currentIt[i] == iniDefs[i].end()) { cerr << "invalid resume value for parameter " << allDefs[i].name << " in rib.resume" << endl; exit(1); } } orderCurrent = -2; } int BenchParams::getOrder (const std::string param_name) { map::const_iterator it = orderMapAll.find(param_name); if (it == orderMapAll.end()) { return -1; } else { return it->second; } } BenchParameter * BenchParams::currentParam (const std::string & param_name, std::map & orderMap) { BenchParameter * param = NULL; // first try to find the param as managed map::const_iterator it = orderMap.find(param_name); if (it != orderMap.end()) { param = current[it->second]; } else { // now try to find it as unmanaged param = getUnmanagedParam(param_name); if (param == NULL) { cerr << "currentParam() unknown param: " << param_name << endl; exit(EXIT_FAILURE); } } return param; } std::string BenchParams::currentValues (const std::string & delim, bool units, int skipOrder1, int skipOrder2) { ostringstream s; printValues(s, delim, units, skipOrder1, skipOrder2); return s.str(); } std::string BenchParams::tableSubtitle (int skipOrder1, int skipOrder2) { ostringstream s; bool first = true; // bool secondline = false; for (int i = 0; i < count(); i++) { if (i != skipOrder1 && i != skipOrder2) { if (!first) { s << ", "; // if (!secondline && (i > param_count() / 2)) { // s << "\n"; // secondline = true; // } else { // s << " "; // } } s << defs[i].name << "="; current[i]->print_current(s, true); first = false; } } return s.str(); } void BenchParams::resetOne (int order) { currentIt[order] = iniDefs[order].begin(); current[order] = *currentIt[order]; current[order]->reset(); } void BenchParams::setCurrentOrder (int order) { orderCurrent = order; } void BenchParams::resetAll () { while (++orderCurrent < count()) { resetOne(orderCurrent); } orderCurrent = count() - 1; } bool BenchParams::advanceOneCheck (int order) { if (current[order]->nextStep()) { return true; } else { params_list::const_iterator it = currentIt[order]; if (++it != iniDefs[order].end()) { return true; } else { return false; } } } bool BenchParams::advanceOne (int order) { if (current[order]->nextStep()) { return true; } else if (++currentIt[order] != iniDefs[order].end()) { current[order] = *currentIt[order]; current[order]->reset(); return true; } else { return false; } } bool BenchParams::advance (int skipOrder1, int skipOrder2) { if (count() == 0) { if (advanced == false) { advanced = true; return true; } else { return false; } } if (orderCurrent == -2) { orderCurrent = count() - 1; return true; } if (orderCurrent >= 0) { while (orderCurrent >= 0) { if (orderCurrent == skipOrder1 || orderCurrent == skipOrder2) { orderCurrent--; } else if (advanceOne(orderCurrent)) { break; } else { orderCurrent--; } } if (orderCurrent < 0) { return false; } } return true; } /******************************************************************/ /* PRINTING METHODS */ /******************************************************************/ void BenchParams::printNames (std::ostream & s, const std::string & delim) { for (int i = 0; i < count(); i++) { s << defs[i].name << delim; } } void BenchParams::printCurrentValue (std::ostream & s, int i, bool units) { current[i]->print_current(s, units); } void BenchParams::printValues (std::ostream & s, const std::string & delim, bool units, int skipOrder1, int skipOrder2) { bool first = true; for (int i = 0; i < count(); i++) { if (i != skipOrder1 && i != skipOrder2) { if (!first) { s << delim; } else { first = false; } current[i]->print_current(s, units); } } } void BenchParams::printNamesValues (std::ostream & s, const std::string & delim, bool units) { for (int i = 0; i < count(); i++) { s << defs[i].name << delim; current[i]->print_current(s, units); s << endl; } }