GPU allocation for CPX Unit Tests using PCI bus id (#1403)

* mapping devices wrt pci

* Gpu allocation by using pci mapping

* Passing gpuPriorityOrder in as an argument rather than making the functions non-static.

* Removing redundant testBed instance calling

[ROCm/rccl commit: 69b2b712ab]
This commit is contained in:
saurabhAMD
2024-11-04 10:51:00 -06:00
committed by GitHub
parent ad1384bea1
commit 69d976532b
9 changed files with 119 additions and 19 deletions
+80
View File
@@ -123,6 +123,73 @@ namespace RcclUnitTesting
return 0;
}
ncclResult_t busIdToInt64(const char* busId, int64_t* id) {
char hexStr[17]; // Longest possible int64 hex string + null terminator.
int hexOffset = 0;
for (int i = 0; hexOffset < sizeof(hexStr) - 1; i++) {
char c = busId[i];
if (c == ':') continue;
if (c == '.') break; //ignore everything after . as they belong to same physical pci
if ((c >= '0' && c <= '9') ||
(c >= 'A' && c <= 'F') ||
(c >= 'a' && c <= 'f')) {
hexStr[hexOffset++] = busId[i];
} else break;
}
hexStr[hexOffset] = '\0';
*id = strtol(hexStr, NULL, 16);
return ncclSuccess;
}
int getDevicePriority (std::vector<int> *gpuPriorityOrder){
// Prepare parent->child pipe
int pipefd[2];
if (pipe(pipefd) == -1) {
ERROR("Unable to create parent->child pipe for getting the device priority vector.\n");
return TEST_FAIL;
}
pid_t pid = fork();
if (0 == pid) {
std::vector<int> result;
try {
int numDev;
hipGetDeviceCount(&numDev);
std::unordered_map<int64_t, std::vector<int>> uniqueIdToGpuIndexes;
for(int dev=0;dev<numDev;dev++){
char busIdStr[] = "00000000:00:00.0";
int64_t busId;
hipDeviceGetPCIBusId(busIdStr, sizeof(busIdStr), dev);
busIdToInt64(busIdStr, &busId);
uniqueIdToGpuIndexes[busId].push_back(dev);
}
std::vector<std::pair<int64_t, std::vector<int>>> sortedIds(uniqueIdToGpuIndexes.begin(), uniqueIdToGpuIndexes.end());
std::sort(sortedIds.begin(), sortedIds.end(), [](const auto& a, const auto& b) {
return a.second.size() > b.second.size();
});
for (const auto& pair : sortedIds) {
result.insert(result.end(), pair.second.begin(), pair.second.end());
}
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
if (write(pipefd[1], result.data(), gpuPriorityOrder->size() * sizeof(int)) != gpuPriorityOrder->size() * sizeof(int)) return TEST_FAIL;
close(pipefd[0]);
close(pipefd[1]);
exit(EXIT_SUCCESS);
}
else {
int status;
if (read(pipefd[0], gpuPriorityOrder->data(), gpuPriorityOrder->size() * sizeof(int)) != gpuPriorityOrder->size() * sizeof(int)) return TEST_FAIL;
waitpid(pid, &status, 0);
assert(!status);
close(pipefd[0]);
close(pipefd[1]);
}
return TEST_SUCCESS;
return 0;
}
EnvVars::EnvVars()
{
@@ -151,10 +218,18 @@ namespace RcclUnitTesting
// Total number of reduction ops
int numOps = ncclNumOps;
gpuPriorityOrder.resize(numDetectedGpus);
for(int i=0;i<numDetectedGpus;i++){
gpuPriorityOrder[i] = i;
}
bool isCpxMode = false;
if(isGfx94) {
getDeviceMode(&isCpxMode);
if(isCpxMode) {
getDevicePriority(&gpuPriorityOrder);
}
}
// Test only pow2 number of GPUs for cpx mode to reduce the runtime for UT
onlyPow2Gpus = GetEnvVar("UT_POW2_GPUS" , isCpxMode); // Default value set based on whether system is in CPX mode. UT_POW2_GPUS set by user overrides it.
@@ -235,6 +310,11 @@ namespace RcclUnitTesting
return numGpusList;
}
std::vector<int> const& EnvVars::GetGpuPriorityOrder()
{
return gpuPriorityOrder;
}
std::vector<int> const& EnvVars::GetIsMultiProcessList()
{
return isMultiProcessList;