From a516040579bbcd101731f02afcc715480c8d301c Mon Sep 17 00:00:00 2001 From: Zach Mullen Date: Tue, 8 Sep 2009 17:10:35 -0400 Subject: [PATCH] ENH: ctest now writes time cost data to a file after a test set is run, and uses these time costs to schedule the processes the next time ctest is run in that build tree. --- Source/CTest/cmCTestMultiProcessHandler.cxx | 60 +++++++++++++++++++-- Source/CTest/cmCTestMultiProcessHandler.h | 6 ++- Source/CTest/cmCTestTestHandler.cxx | 4 +- 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 8002c057d..637c2d53d 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -30,11 +30,9 @@ cmCTestMultiProcessHandler::cmCTestMultiProcessHandler() // Set the tests void cmCTestMultiProcessHandler::SetTests(TestMap& tests, - TestCostMap& testCosts, PropertiesMap& properties) { this->Tests = tests; - this->TestCosts = testCosts; this->Properties = properties; this->Total = this->Tests.size(); // set test run map to false for all @@ -44,6 +42,8 @@ cmCTestMultiProcessHandler::SetTests(TestMap& tests, this->TestRunningMap[i->first] = false; this->TestFinishMap[i->first] = false; } + this->ReadCostData(); + this->CreateTestCostList(); } // Set the max number of tests that can be run at the same time. @@ -271,12 +271,63 @@ bool cmCTestMultiProcessHandler::CheckOutput() this->TestRunningMap[test] = false; this->RunningTests.erase(p); this->WriteCheckpoint(test); + this->WriteCostData(test, p->GetTestResults().ExecutionTime); this->RunningCount -= GetProcessorsUsed(test); delete p; } return true; } +//--------------------------------------------------------- +void cmCTestMultiProcessHandler::ReadCostData() +{ + std::string fname = this->CTest->GetBinaryDir() + + "/Testing/Temporary/CTestCostData.txt"; + + if(cmSystemTools::FileExists(fname.c_str(), true) + && this->ParallelLevel > 1) + { + std::ifstream fin; + fin.open(fname.c_str()); + std::string line; + while(std::getline(fin, line)) + { + std::vector parts = + cmSystemTools::SplitString(line.c_str(), ' '); + + int index = atoi(parts[0].c_str()); + float cost = atof(parts[1].c_str()); + if(this->Properties[index] && this->Properties[index]->Cost == 0) + { + this->Properties[index]->Cost = cost; + } + } + fin.close(); + } + cmSystemTools::RemoveFile(fname.c_str()); +} + +//--------------------------------------------------------- +void cmCTestMultiProcessHandler::CreateTestCostList() +{ + for(TestMap::iterator i = this->Tests.begin(); + i != this->Tests.end(); ++i) + { + this->TestCosts[this->Properties[i->first]->Cost].insert(i->first); + } +} + +//--------------------------------------------------------- +void cmCTestMultiProcessHandler::WriteCostData(int index, float cost) +{ + std::string fname = this->CTest->GetBinaryDir() + + "/Testing/Temporary/CTestCostData.txt"; + std::fstream fout; + fout.open(fname.c_str(), std::ios::app); + fout << index << " " << cost << "\n"; + fout.close(); +} + //--------------------------------------------------------- void cmCTestMultiProcessHandler::WriteCheckpoint(int index) { @@ -288,6 +339,7 @@ void cmCTestMultiProcessHandler::WriteCheckpoint(int index) fout.close(); } +//--------------------------------------------------------- void cmCTestMultiProcessHandler::MarkFinished() { std::string fname = this->CTest->GetBinaryDir() @@ -295,7 +347,7 @@ void cmCTestMultiProcessHandler::MarkFinished() cmSystemTools::RemoveFile(fname.c_str()); } -//--------------------------------------------------------------------- +//--------------------------------------------------------- //For ShowOnly mode void cmCTestMultiProcessHandler::PrintTestList() { @@ -330,7 +382,7 @@ void cmCTestMultiProcessHandler::PrintTestList() } } -//---------------------------------------------------------------- +//--------------------------------------------------------- void cmCTestMultiProcessHandler::CheckResume() { std::string fname = this->CTest->GetBinaryDir() diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h index 97af2f3ec..ff1141c89 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.h +++ b/Source/CTest/cmCTestMultiProcessHandler.h @@ -37,8 +37,7 @@ public: cmCTestMultiProcessHandler(); // Set the tests - void SetTests(TestMap& tests, TestCostMap& testCosts, - PropertiesMap& properties); + void SetTests(TestMap& tests, PropertiesMap& properties); // Set the max number of tests that can be run at the same time. void SetParallelLevel(size_t); void RunTests(); @@ -70,6 +69,9 @@ protected: bool StartTest(int test); // Mark the checkpoint for the given test void WriteCheckpoint(int index); + void WriteCostData(int index, float cost); + void ReadCostData(); + void CreateTestCostList(); // Removes the checkpoint file void MarkFinished(); void EraseTest(int index); diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 3cf2d124d..229f92a5f 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -1010,7 +1010,6 @@ void cmCTestTestHandler::ProcessDirectory(std::vector &passed, << std::endl; cmCTestMultiProcessHandler::TestMap tests; - cmCTestMultiProcessHandler::TestCostMap testCosts; cmCTestMultiProcessHandler::PropertiesMap properties; for (ListOfTests::iterator it = this->TestList.begin(); @@ -1037,9 +1036,8 @@ void cmCTestTestHandler::ProcessDirectory(std::vector &passed, } tests[it->Index] = depends; properties[it->Index] = &*it; - testCosts[p.Cost].insert(p.Index); } - parallel.SetTests(tests, testCosts, properties); + parallel.SetTests(tests, properties); parallel.SetPassFailVectors(&passed, &failed); this->TestResults.clear(); parallel.SetTestResults(&this->TestResults);