58 ValueTolerance::ValueTolerance() {
 
   66 ValueTolerance::ValueTolerance(
double val, 
double tol) {
 
   74 ValueTolerance::ValueTolerance(
double val, 
double low, 
double up) {
 
   79   use_tolerance = 
false;
 
   82 ValueTolerance::ValueTolerance(std::string str) {
 
   86 bool ValueTolerance::operator ==(ValueTolerance& rhs) {
 
   87   return (value == rhs.value) &&
 
   88          (tolerance == rhs.tolerance) &&
 
   89          (lower == rhs.lower) &&
 
   90          (upper == rhs.upper) &&
 
   91          (use_tolerance == rhs.use_tolerance);
 
   94 std::string ValueTolerance::as_string(){
 
   95   std::ostringstream strs;
 
   97     strs << value << 
" , " << tolerance;
 
   99     strs << value << 
" , " << lower << 
" , " << upper;
 
  103 void ValueTolerance::from_string(
const std::string& valtol_str) {
 
  104   std::string value_str = valtol_str.substr(0,valtol_str.find(
","));
 
  105   value = atof(value_str.c_str());
 
  106   std::string tol_str = valtol_str.substr(valtol_str.find(
",")+1);
 
  107   if(tol_str.find(
",")<=tol_str.length()) {
 
  108     use_tolerance = 
false;
 
  109     std::string lower_str = tol_str.substr(0,tol_str.find(
","));
 
  110     lower = atof(lower_str.c_str());
 
  111     std::string upper_str = tol_str.substr(tol_str.find(
",")+1);
 
  112     upper = atof(upper_str.c_str());
 
  114     use_tolerance = 
true;
 
  115     tolerance = atof(tol_str.c_str());
 
  119   XMLTestNode::XMLTestNode():XMLObject() {}
 
  121   XMLTestNode::XMLTestNode(
const std::string &tag):XMLObject(tag) {}
 
  123   XMLTestNode::XMLTestNode(XMLObjectImplem *ptr):XMLObject(ptr) {}
 
  125   XMLTestNode::XMLTestNode(XMLObject obj):XMLObject(obj) {}
 
  127   void  XMLTestNode::addDouble (
const std::string &name, 
double val) {
 
  128     addAttribute<double>(name,val);
 
  131   void  XMLTestNode::addInt (
const std::string &name, 
int val) {
 
  132     addAttribute<int>(name,val);
 
  135   void  XMLTestNode::addBool (
const std::string &name, 
bool val) {
 
  136     addAttribute<bool>(name,val);
 
  139   void XMLTestNode::addValueTolerance(
const std::string &name, ValueTolerance val){
 
  140     addAttribute<std::string>(name,val.as_string());
 
  143   void  XMLTestNode::addString (
const std::string &name, std::string val) {
 
  144     addAttribute<std::string>(name,val);
 
  147   bool XMLTestNode::hasChild(
const std::string &name)
 const {
 
  158   void XMLTestNode::appendContentLine(
const size_t& i, 
const std::string &str) {
 
  159     ptr_->appendContentLine(i,str);
 
  162   XMLTestNode XMLTestNode::getChild(
const std::string &name)
 const {
 
  171   XMLTestNode XMLTestNode::getChild(
const int &i)
 const {
 
  175   const XMLObject* XMLTestNode::xml_object()
 const {
 
  179   bool XMLTestNode::hasSameElements(XMLTestNode 
const & lhs)
 const {
 
  183        (
getTag().compare(lhs.getTag())!=0)) 
return false;
 
  187       if( (!lhs.hasChild(child.getTag())) ||
 
  188           (!child.hasSameElements(lhs.getChild(child.getTag()))) ) 
return false;
 
  192       if(
getContentLine(i).compare(lhs.getContentLine(i))!=0) 
return false;
 
  200   std::string cpuname(
"Undefined");
 
  201   unsigned int threads = 0;
 
  202   unsigned int cores_per_socket = 0;
 
  203   unsigned int highest_socketid = 0;
 
  206     std::ifstream cpuinfo(
"/proc/cpuinfo");
 
  208     if((cpuinfo.rdstate()&cpuinfo.failbit)) std::cout<<
"Failed to open filen\n";
 
  209     while (!cpuinfo.eof() && !(cpuinfo.rdstate()&cpuinfo.failbit)) {
 
  210       getline (cpuinfo,line);
 
  211       if (line.find(
"model name") < line.size()) {
 
  212         cpuname = line.substr(line.find(
":")+2);
 
  215       if (line.find(
"physical id") < line.size()) {
 
  216         unsigned int socketid = atoi(line.substr(line.find(
":")+2).c_str());
 
  217         highest_socketid = highest_socketid>socketid?highest_socketid:socketid;
 
  219       if (line.find(
"cpu cores") < line.size()) {
 
  220         cores_per_socket = atoi(line.substr(line.find(
":")+2).c_str());
 
  226   XMLTestNode machine_config(
"MachineConfiguration");
 
  228   machine_config.addString(
"Compiler", TEUCHOS_COMPILER_NAME);
 
  229   machine_config.addInt(
"Compiler_Version",  TEUCHOS_COMPILER_VERSION);
 
  230   machine_config.addString(
"CPU_Name", cpuname);
 
  231   machine_config.addInt(
"CPU_Sockets", highest_socketid+1);
 
  232   machine_config.addInt(
"CPU_Cores_Per_Socket", cores_per_socket);
 
  233   machine_config.addInt(
"CPU_Total_HyperThreads", threads);
 
  234   return machine_config;
 
  240                           const std::string filename,
 
  241                           const std::string ext_hostname)
 
  245   bool is_new_config = 
true;
 
  250   if (std::ifstream (filename.c_str ())) {
 
  256   memset (hostname, 0, 256);
 
  257   if (ext_hostname.empty ()) {
 
  258     gethostname (hostname, 255);
 
  260     strncat (hostname, ext_hostname.c_str (), 255);
 
  263   XMLTestNode new_test_entry = new_test.getChild (
"TestEntry");
 
  269   if (database.hasChild (hostname)) {
 
  270     XMLTestNode machine = database.getChild (hostname);
 
  276         configuration.
getTag ().compare (
"Configuration") != 0,
 
  277         std::runtime_error, 
"Unexpected Tag \"" << configuration.
getTag ()
 
  278         << 
"\"; only children with Tag = \"Configuration\" are allowed in a " 
  282         ! configuration.hasChild (
"MachineConfiguration") ||
 
  283         ! configuration.hasChild (
"Tests"),
 
  285         "A Configuration needs to have a child \"MachineConfiguration\" and a " 
  288       XMLTestNode machine_configuration = configuration.getChild (
"MachineConfiguration");
 
  289       XMLTestNode old_tests = configuration.getChild (
"Tests");
 
  291       if (machine_configuration.hasSameElements (machine_config)) {
 
  292         is_new_config = 
false;
 
  295         if (old_tests.hasChild (new_test.
getTag ())) {
 
  299           int new_test_config = -1;
 
  300           for (
int k = 0; k < old_test.
numChildren (); ++k) {
 
  301             XMLTestNode old_test_entry = old_test.getChild (k);
 
  304               ! old_test_entry.hasChild (
"TestConfiguration") ||
 
  305               ! new_test_entry.hasChild (
"TestResults"),
 
  306               std::runtime_error, 
"A TestEntry needs to have a child " 
  307               "\"TestConfiguration\" and a child \"TestResults\".");
 
  309             if (old_test_entry.getChild (
"TestConfiguration").hasSameElements (new_test_entry.getChild (
"TestConfiguration"))) {
 
  314           if (new_test_config < 0) {
 
  316             return_value = PerfTestNewTestConfiguration;
 
  318             bool deviation = 
false;
 
  319             XMLTestNode old_test_entry = old_test.getChild (new_test_config);
 
  320             XMLTestNode old_results = old_test_entry.getChild (
"TestResults");
 
  321             XMLTestNode new_results = new_test_entry.getChild (
"TestResults");
 
  324             for (
int old_r = 0; old_r < old_results.
numChildren (); ++old_r) {
 
  325               XMLTestNode result_entry = old_results.getChild (old_r);
 
  328               bool exists = new_results.hasChild (result_entry.
getTag ());
 
  334                 if((result_entry.
getTag().find(
"Time")==0) || (result_entry.
getTag().find(
"Result")==0)) {
 
  338                   if(old_valtol.use_tolerance) {
 
  339                     double diff = old_valtol.value - new_valtol.value;
 
  342                     double normalization = old_valtol.value;
 
  343                     normalization*=normalization;
 
  345                     if(normalization==0?diff>0:diff/normalization>old_valtol.tolerance*old_valtol.tolerance) {
 
  347                       std::cout << std::endl
 
  348                           << 
"DeviationA in Test: \"" << old_test.
getTag()
 
  349                           << 
"\" for entry \"" <<  result_entry.
getTag() << 
"\"" << std::endl;
 
  350                       std::cout << 
"  Existing Value: \"" << oldv_str << 
"\"" << std::endl;
 
  351                       std::cout << 
"  New Value:      \"" << new_results.getChild(result_entry.
getTag()).getContentLine(0) << 
"\"" << std::endl << std::endl;
 
  354                     if( (old_valtol.lower>new_valtol.value) || (old_valtol.upper<new_valtol.value)) {
 
  356                       std::cout << std::endl
 
  357                           << 
"DeviationB in Test: \"" << old_test.
getTag()
 
  358                           << 
"\" for entry \"" <<  result_entry.
getTag() << 
"\"" << std::endl;
 
  359                       std::cout << 
"  Existing Value: \"" << oldv_str << 
"\"" << std::endl;
 
  360                       std::cout << 
"  New Value:      \"" << new_results.getChild(result_entry.
getTag()).getContentLine(0) << 
"\"" << std::endl << std::endl;
 
  365                   if(oldv_str.compare(new_results.getChild(result_entry.
getTag()).getContentLine(0))!=0) {
 
  367                     std::cout << std::endl
 
  368                         << 
"DeviationC in Test: \"" << old_test.
getTag()
 
  369                         << 
"\" for entry \"" <<  result_entry.
getTag() << 
"\"" << std::endl;
 
  370                     std::cout << 
"  Existing Value: \"" << oldv_str << 
"\"" << std::endl;
 
  371                     std::cout << 
"  New Value:      \"" << new_results.getChild(result_entry.
getTag()).getContentLine(0) << 
"\"" << std::endl << std::endl;
 
  377                 std::cout << 
"Error New test has same name as an existing one, but one of the old entries is missing." << std::endl;
 
  382             if(deviation) { return_value = PerfTestFailed; }
 
  386                 for(
int new_r = 0; new_r < new_results.
numChildren() ; new_r++) {
 
  387                   if(!old_results.hasChild(new_results.getChild(new_r).
getTag())) {
 
  388                     old_results.
addChild(new_results.getChild(new_r));
 
  392                 return_value = PerfTestUpdatedTest;
 
  399           return_value = PerfTestNewTest;
 
  414       return_value = PerfTestNewConfiguration;
 
  429     return_value = PerfTestNewMachine;
 
  433   if(return_value>PerfTestPassed) {
 
  434     std::ofstream fout(filename.c_str());
 
  435     fout << database << std::endl;
 
const std::string & getTag() const 
Return the tag of the current node. 
 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging. 
 
void addChild(const XMLObject &child)
Add a child node to the node. 
 
bool isEmpty() const 
Find out if a node is empty. 
 
XMLObject()
Empty constructor. 
 
ValueTolerance is a struct to keep a tuple of value and a tolerance. The tolerance can be either expr...
 
Tools for an XML-based performance test archive. 
 
PerfTestResult
ReturnValues for PerfTest_CheckOrAdd_Test. 
 
int numChildren() const 
Return the number of child nodes owned by this node. 
 
Subclass of XMLObject used by the performance archive. 
 
int numContentLines() const 
Return the number of lines of character content stored in this node. 
 
const XMLObject & getChild(int i) const 
Return the i-th child node. 
 
const std::string & getContentLine(int i) const 
Return the i-th line of character content stored in this node. 
 
PerfTestResult PerfTest_CheckOrAdd_Test(XMLTestNode machine_config, XMLTestNode new_test, const std::string filename, const std::string ext_hostname)
Check whether a test is present and match an existing test in an archive. 
 
XMLTestNode PerfTest_MachineConfig()
PerfTest_MachineConfig generates a basic machine configuration XMLTestNode. 
 
An object representation of a subset of XML data.