summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2019-07-08 21:09:34 (GMT)
committerBrad King <brad.king@kitware.com>2019-10-02 13:33:54 (GMT)
commitc494b2973a1557c3373a2841ba39da6b8d4bdb5a (patch)
tree09a5508bf005d7518beed699db52c4dbd3a64d36
parentc8f48069430cb286ca593a967e0c3b8e5ea842c4 (diff)
downloadCMake-c494b2973a1557c3373a2841ba39da6b8d4bdb5a.zip
CMake-c494b2973a1557c3373a2841ba39da6b8d4bdb5a.tar.gz
CMake-c494b2973a1557c3373a2841ba39da6b8d4bdb5a.tar.bz2
CTest: Add cmCTestHardwareAllocator class
-rw-r--r--Source/CMakeLists.txt1
-rw-r--r--Source/CTest/cmCTestHardwareAllocator.cxx86
-rw-r--r--Source/CTest/cmCTestHardwareAllocator.h39
-rw-r--r--Tests/CMakeLib/CMakeLists.txt1
-rw-r--r--Tests/CMakeLib/testCTestHardwareAllocator.cxx426
5 files changed, 553 insertions, 0 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 8e38590..57229db 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -918,6 +918,7 @@ set(CTEST_SRCS cmCTest.cxx
CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
CTest/cmCTestGenericHandler.cxx
CTest/cmCTestHandlerCommand.cxx
+ CTest/cmCTestHardwareAllocator.cxx
CTest/cmCTestHardwareSpec.cxx
CTest/cmCTestLaunch.cxx
CTest/cmCTestMemCheckCommand.cxx
diff --git a/Source/CTest/cmCTestHardwareAllocator.cxx b/Source/CTest/cmCTestHardwareAllocator.cxx
new file mode 100644
index 0000000..2d1833d
--- /dev/null
+++ b/Source/CTest/cmCTestHardwareAllocator.cxx
@@ -0,0 +1,86 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmCTestHardwareAllocator.h"
+
+#include <utility>
+#include <vector>
+
+#include "cmCTestHardwareSpec.h"
+
+void cmCTestHardwareAllocator::InitializeFromHardwareSpec(
+ const cmCTestHardwareSpec& spec)
+{
+ this->Resources.clear();
+
+ for (auto const& it : spec.LocalSocket.Resources) {
+ auto& res = this->Resources[it.first];
+ for (auto const& specRes : it.second) {
+ res[specRes.Id].Total = specRes.Capacity;
+ res[specRes.Id].Locked = 0;
+ }
+ }
+}
+
+const std::map<std::string,
+ std::map<std::string, cmCTestHardwareAllocator::Resource>>&
+cmCTestHardwareAllocator::GetResources() const
+{
+ return this->Resources;
+}
+
+bool cmCTestHardwareAllocator::AllocateResource(const std::string& name,
+ const std::string& id,
+ unsigned int slots)
+{
+ auto it = this->Resources.find(name);
+ if (it == this->Resources.end()) {
+ return false;
+ }
+
+ auto resIt = it->second.find(id);
+ if (resIt == it->second.end()) {
+ return false;
+ }
+
+ if (resIt->second.Total < resIt->second.Locked + slots) {
+ return false;
+ }
+
+ resIt->second.Locked += slots;
+ return true;
+}
+
+bool cmCTestHardwareAllocator::DeallocateResource(const std::string& name,
+ const std::string& id,
+ unsigned int slots)
+{
+ auto it = this->Resources.find(name);
+ if (it == this->Resources.end()) {
+ return false;
+ }
+
+ auto resIt = it->second.find(id);
+ if (resIt == it->second.end()) {
+ return false;
+ }
+
+ if (resIt->second.Locked < slots) {
+ return false;
+ }
+
+ resIt->second.Locked -= slots;
+ return true;
+}
+
+bool cmCTestHardwareAllocator::Resource::operator==(
+ const Resource& other) const
+{
+ return this->Total == other.Total && this->Locked == other.Locked;
+}
+
+bool cmCTestHardwareAllocator::Resource::operator!=(
+ const Resource& other) const
+{
+ return !(*this == other);
+}
diff --git a/Source/CTest/cmCTestHardwareAllocator.h b/Source/CTest/cmCTestHardwareAllocator.h
new file mode 100644
index 0000000..441f84d
--- /dev/null
+++ b/Source/CTest/cmCTestHardwareAllocator.h
@@ -0,0 +1,39 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmCTestHardwareAllocator_h
+#define cmCTestHardwareAllocator_h
+
+#include <map>
+#include <string>
+
+class cmCTestHardwareSpec;
+
+class cmCTestHardwareAllocator
+{
+public:
+ struct Resource
+ {
+ unsigned int Total;
+ unsigned int Locked;
+
+ unsigned int Free() const { return this->Total - this->Locked; }
+
+ bool operator==(const Resource& other) const;
+ bool operator!=(const Resource& other) const;
+ };
+
+ void InitializeFromHardwareSpec(const cmCTestHardwareSpec& spec);
+
+ const std::map<std::string, std::map<std::string, Resource>>& GetResources()
+ const;
+
+ bool AllocateResource(const std::string& name, const std::string& id,
+ unsigned int slots);
+ bool DeallocateResource(const std::string& name, const std::string& id,
+ unsigned int slots);
+
+private:
+ std::map<std::string, std::map<std::string, Resource>> Resources;
+};
+
+#endif
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index 901f097..c24b64c 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -8,6 +8,7 @@ include_directories(
set(CMakeLib_TESTS
testArgumentParser.cxx
testCTestProcesses.cxx
+ testCTestHardwareAllocator.cxx
testCTestHardwareSpec.cxx
testGeneratedFileStream.cxx
testRST.cxx
diff --git a/Tests/CMakeLib/testCTestHardwareAllocator.cxx b/Tests/CMakeLib/testCTestHardwareAllocator.cxx
new file mode 100644
index 0000000..6f05d03
--- /dev/null
+++ b/Tests/CMakeLib/testCTestHardwareAllocator.cxx
@@ -0,0 +1,426 @@
+#include <iostream>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "cmCTestHardwareAllocator.h"
+#include "cmCTestHardwareSpec.h"
+
+static const cmCTestHardwareSpec spec{ { {
+ /* clang-format off */
+ { "gpus", { { "0", 4 }, { "1", 8 }, { "2", 0 }, { "3", 8 } } },
+ /* clang-format on */
+} } };
+
+bool testInitializeFromHardwareSpec()
+{
+ bool retval = true;
+
+ cmCTestHardwareAllocator allocator;
+ allocator.InitializeFromHardwareSpec(spec);
+
+ static const std::map<
+ std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
+ expected{
+ /* clang-format off */
+ { "gpus", {
+ { "0", { 4, 0 } },
+ { "1", { 8, 0 } },
+ { "2", { 0, 0 } },
+ { "3", { 8, 0 } },
+ } },
+ /* clang-format on */
+ };
+ if (allocator.GetResources() != expected) {
+ std::cout << "GetResources() did not return expected value\n";
+ retval = false;
+ }
+
+ return retval;
+}
+
+bool testAllocateResource()
+{
+ bool retval = true;
+
+ cmCTestHardwareAllocator allocator;
+ allocator.InitializeFromHardwareSpec(spec);
+
+ static const std::map<
+ std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
+ expected1{
+ /* clang-format off */
+ { "gpus", {
+ { "0", { 4, 2 } },
+ { "1", { 8, 0 } },
+ { "2", { 0, 0 } },
+ { "3", { 8, 0 } },
+ } },
+ /* clang-format on */
+ };
+ if (!allocator.AllocateResource("gpus", "0", 2)) {
+ std::cout
+ << "AllocateResource(\"gpus\", \"0\", 2) returned false, should be "
+ "true\n";
+ retval = false;
+ }
+ if (allocator.GetResources() != expected1) {
+ std::cout << "GetResources() did not return expected value\n";
+ retval = false;
+ }
+
+ static const std::map<
+ std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
+ expected2{
+ /* clang-format off */
+ { "gpus", {
+ { "0", { 4, 4 } },
+ { "1", { 8, 0 } },
+ { "2", { 0, 0 } },
+ { "3", { 8, 0 } },
+ } },
+ /* clang-format on */
+ };
+ if (!allocator.AllocateResource("gpus", "0", 2)) {
+ std::cout
+ << "AllocateResource(\"gpus\", \"0\", 2) returned false, should be "
+ "true\n";
+ retval = false;
+ }
+ if (allocator.GetResources() != expected2) {
+ std::cout << "GetResources() did not return expected value\n";
+ retval = false;
+ }
+
+ static const std::map<
+ std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
+ expected3{
+ /* clang-format off */
+ { "gpus", {
+ { "0", { 4, 4 } },
+ { "1", { 8, 0 } },
+ { "2", { 0, 0 } },
+ { "3", { 8, 0 } },
+ } },
+ /* clang-format on */
+ };
+ if (allocator.AllocateResource("gpus", "0", 1)) {
+ std::cout
+ << "AllocateResource(\"gpus\", \"0\", 1) returned true, should be "
+ "false\n";
+ retval = false;
+ }
+ if (allocator.GetResources() != expected3) {
+ std::cout << "GetResources() did not return expected value\n";
+ retval = false;
+ }
+
+ static const std::map<
+ std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
+ expected4{
+ /* clang-format off */
+ { "gpus", {
+ { "0", { 4, 4 } },
+ { "1", { 8, 7 } },
+ { "2", { 0, 0 } },
+ { "3", { 8, 0 } },
+ } },
+ /* clang-format on */
+ };
+ if (!allocator.AllocateResource("gpus", "1", 7)) {
+ std::cout
+ << "AllocateResource(\"gpus\", \"1\", 7) returned false, should be "
+ "true\n";
+ retval = false;
+ }
+ if (allocator.AllocateResource("gpus", "1", 2)) {
+ std::cout
+ << "AllocateResource(\"gpus\", \"1\", 2) returned true, should be "
+ "false\n";
+ retval = false;
+ }
+ if (allocator.GetResources() != expected4) {
+ std::cout << "GetResources() did not return expected value\n";
+ retval = false;
+ }
+
+ static const std::map<
+ std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
+ expected5{
+ /* clang-format off */
+ { "gpus", {
+ { "0", { 4, 4 } },
+ { "1", { 8, 7 } },
+ { "2", { 0, 0 } },
+ { "3", { 8, 0 } },
+ } },
+ /* clang-format on */
+ };
+ if (allocator.AllocateResource("gpus", "2", 1)) {
+ std::cout
+ << "AllocateResource(\"gpus\", \"2\", 1) returned true, should be "
+ "false\n";
+ retval = false;
+ }
+ if (allocator.GetResources() != expected5) {
+ std::cout << "GetResources() did not return expected value\n";
+ retval = false;
+ }
+
+ static const std::map<
+ std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
+ expected6{
+ /* clang-format off */
+ { "gpus", {
+ { "0", { 4, 4 } },
+ { "1", { 8, 7 } },
+ { "2", { 0, 0 } },
+ { "3", { 8, 0 } },
+ } },
+ /* clang-format on */
+ };
+ if (allocator.AllocateResource("gpus", "4", 1)) {
+ std::cout
+ << "AllocateResource(\"gpus\", \"4\", 1) returned true, should be "
+ "false\n";
+ retval = false;
+ }
+ if (allocator.GetResources() != expected6) {
+ std::cout << "GetResources() did not return expected value\n";
+ retval = false;
+ }
+
+ static const std::map<
+ std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
+ expected7{
+ /* clang-format off */
+ { "gpus", {
+ { "0", { 4, 4 } },
+ { "1", { 8, 7 } },
+ { "2", { 0, 0 } },
+ { "3", { 8, 0 } },
+ } },
+ /* clang-format on */
+ };
+ if (allocator.AllocateResource("threads", "0", 1)) {
+ std::cout
+ << "AllocateResource(\"threads\", \"0\", 1) returned true, should be"
+ " false\n";
+ retval = false;
+ }
+ if (allocator.GetResources() != expected7) {
+ std::cout << "GetResources() did not return expected value\n";
+ retval = false;
+ }
+
+ return retval;
+}
+
+bool testDeallocateResource()
+{
+ bool retval = true;
+
+ cmCTestHardwareAllocator allocator;
+ allocator.InitializeFromHardwareSpec(spec);
+
+ static const std::map<
+ std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
+ expected1{
+ /* clang-format off */
+ { "gpus", {
+ { "0", { 4, 1 } },
+ { "1", { 8, 0 } },
+ { "2", { 0, 0 } },
+ { "3", { 8, 0 } },
+ } },
+ /* clang-format on */
+ };
+ if (!allocator.AllocateResource("gpus", "0", 2)) {
+ std::cout
+ << "AllocateResource(\"gpus\", \"0\", 2) returned false, should be "
+ "true\n";
+ retval = false;
+ }
+ if (!allocator.DeallocateResource("gpus", "0", 1)) {
+ std::cout
+ << "DeallocateResource(\"gpus\", \"0\", 1) returned false, should be"
+ " true\n";
+ retval = false;
+ }
+ if (allocator.GetResources() != expected1) {
+ std::cout << "GetResources() did not return expected value\n";
+ retval = false;
+ }
+
+ static const std::map<
+ std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
+ expected2{
+ /* clang-format off */
+ { "gpus", {
+ { "0", { 4, 1 } },
+ { "1", { 8, 0 } },
+ { "2", { 0, 0 } },
+ { "3", { 8, 0 } },
+ } },
+ /* clang-format on */
+ };
+ if (allocator.DeallocateResource("gpus", "0", 2)) {
+ std::cout
+ << "DeallocateResource(\"gpus\", \"0\", 2) returned true, should be"
+ " false\n";
+ retval = false;
+ }
+ if (allocator.GetResources() != expected2) {
+ std::cout << "GetResources() did not return expected value\n";
+ retval = false;
+ }
+
+ static const std::map<
+ std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
+ expected3{
+ /* clang-format off */
+ { "gpus", {
+ { "0", { 4, 0 } },
+ { "1", { 8, 0 } },
+ { "2", { 0, 0 } },
+ { "3", { 8, 0 } },
+ } },
+ /* clang-format on */
+ };
+ if (!allocator.DeallocateResource("gpus", "0", 1)) {
+ std::cout
+ << "DeallocateResource(\"gpus\", \"0\", 1) returned false, should be"
+ " true\n";
+ retval = false;
+ }
+ if (allocator.GetResources() != expected3) {
+ std::cout << "GetResources() did not return expected value\n";
+ retval = false;
+ }
+
+ static const std::map<
+ std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
+ expected4{
+ /* clang-format off */
+ { "gpus", {
+ { "0", { 4, 0 } },
+ { "1", { 8, 0 } },
+ { "2", { 0, 0 } },
+ { "3", { 8, 0 } },
+ } },
+ /* clang-format on */
+ };
+ if (allocator.DeallocateResource("gpus", "0", 1)) {
+ std::cout
+ << "DeallocateResource(\"gpus\", \"0\", 1) returned true, should be"
+ " false\n";
+ retval = false;
+ }
+ if (allocator.GetResources() != expected4) {
+ std::cout << "GetResources() did not return expected value\n";
+ retval = false;
+ }
+
+ static const std::map<
+ std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
+ expected5{
+ /* clang-format off */
+ { "gpus", {
+ { "0", { 4, 0 } },
+ { "1", { 8, 0 } },
+ { "2", { 0, 0 } },
+ { "3", { 8, 0 } },
+ } },
+ /* clang-format on */
+ };
+ if (allocator.DeallocateResource("gpus", "4", 1)) {
+ std::cout
+ << "DeallocateResource(\"gpus\", \"4\", 1) returned true, should be"
+ " false\n";
+ retval = false;
+ }
+ if (allocator.GetResources() != expected5) {
+ std::cout << "GetResources() did not return expected value\n";
+ retval = false;
+ }
+
+ static const std::map<
+ std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
+ expected6{
+ /* clang-format off */
+ { "gpus", {
+ { "0", { 4, 0 } },
+ { "1", { 8, 0 } },
+ { "2", { 0, 0 } },
+ { "3", { 8, 0 } },
+ } },
+ /* clang-format on */
+ };
+ if (allocator.DeallocateResource("threads", "0", 1)) {
+ std::cout
+ << "DeallocateResource(\"threads\", \"0\", 1) returned true, should be"
+ " false\n";
+ retval = false;
+ }
+ if (allocator.GetResources() != expected6) {
+ std::cout << "GetResources() did not return expected value\n";
+ retval = false;
+ }
+
+ return retval;
+}
+
+bool testResourceFree()
+{
+ bool retval = true;
+
+ const cmCTestHardwareAllocator::Resource r1{ 5, 0 };
+ if (r1.Free() != 5) {
+ std::cout << "cmCTestHardwareAllocator::Resource::Free() did not return "
+ "expected value for { 5, 0 }\n";
+ retval = false;
+ }
+
+ const cmCTestHardwareAllocator::Resource r2{ 3, 2 };
+ if (r2.Free() != 1) {
+ std::cout << "cmCTestHardwareAllocator::Resource::Free() did not return "
+ "expected value for { 3, 2 }\n";
+ retval = false;
+ }
+
+ const cmCTestHardwareAllocator::Resource r3{ 4, 4 };
+ if (r3.Free() != 0) {
+ std::cout << "cmCTestHardwareAllocator::Resource::Free() did not return "
+ "expected value for { 4, 4 }\n";
+ retval = false;
+ }
+
+ return retval;
+}
+
+int testCTestHardwareAllocator(int, char** const)
+{
+ int retval = 0;
+
+ if (!testInitializeFromHardwareSpec()) {
+ std::cout << "in testInitializeFromHardwareSpec()\n";
+ retval = -1;
+ }
+
+ if (!testAllocateResource()) {
+ std::cout << "in testAllocateResource()\n";
+ retval = -1;
+ }
+
+ if (!testDeallocateResource()) {
+ std::cout << "in testDeallocateResource()\n";
+ retval = -1;
+ }
+
+ if (!testResourceFree()) {
+ std::cout << "in testResourceFree()\n";
+ retval = -1;
+ }
+
+ return retval;
+}