* Copyright (c) 2024 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#include "atb/comm.h"
#include <gtest/gtest.h>
#include <iostream>
namespace atb {
void TestCreateHcclComm(int rank, int rankRoot, int rankSize)
{
aclrtSetDevice(rank);
char commName[128] = "";
HcclComm hcclComm = nullptr;
hcclComm = atb::Comm::CreateHcclComm(rank, rankRoot, rankSize, commName);
std::cout << "commName: " << commName << std::endl;
EXPECT_NE(hcclComm, nullptr) << "HcclComm should not be null";
EXPECT_NE(commName, "") << "CommName should not be null";
auto ret = atb::Comm::DestoryHcclComm(hcclComm);
aclrtResetDevice(rank);
std::cout << "destoryHcclComm ret: " << ret << std::endl;
}
void TestCreateHcclCommByRankFile(int rank, int rankSize)
{
aclrtSetDevice(rank);
char commName[128] = "";
char *rankTableFile = "/home/zmq/ranktableFile.json";
HcclComm hcclComm = nullptr;
hcclComm = atb::Comm::CreateHcclCommByRankTableFile(rank, rankSize, rankTableFile, commName);
std::cout << "rankTableFile commName: " << commName << std::endl;
EXPECT_NE(hcclComm, nullptr) << "rankTableFile HcclComm should not be null";
EXPECT_NE(commName, "") << "rankTableFile CommName should not be null";
auto ret = atb::Comm::DestoryHcclComm(hcclComm);
aclrtResetDevice(rank);
std::cout << "destoryHcclComm ret: " << ret << std::endl;
}
void TestCreateHcclCrossMulitComm(int realRank, int subCommRankId, std::vector<uint32_t> rankIds, uint64_t subCommId)
{
std::cout << "realRank: " << realRank << std::endl;
aclrtSetDevice(realRank);
char *rankTableFile = "/data/ranktableFile.json";
uint32_t hcclBufferSize = 200;
char commName[129] = "";
HcclComm hcclComm = nullptr;
hcclComm = atb::Comm::CreateHcclCrossMulitComm(rankTableFile, subCommRankId, rankIds, subCommId, hcclBufferSize, commName);
std::cout << "commName: " << commName << std::endl;
EXPECT_NE(hcclComm, nullptr) << "HcclComm should not be null";
EXPECT_NE(commName, "") << "CommName should not be null";
auto ret = atb::Comm::DestoryHcclComm(hcclComm);
aclrtResetDevice(realRank);
std::cout << "destoryHcclComm ret: " << ret << std::endl;
}
}
void RunTestInProcess(int rank, int rankSize)
{
int rankRoot = 0;
atb::TestCreateHcclComm(rank, rankRoot, rankSize);
}
void RunCreateHcclCrossMulitComm()
{
const int processCount = 4;
pid_t pids[processCount];
std::vector<uint32_t> rankIds1 = {0, 1};
int subCommId1 = 1;
pids[0] = fork();
if (pids[0] < 0) {
std::cout << "fork failed ! " << pids[0] << std::endl;
} else if (pids[0] == 0) {
atb::TestCreateHcclCrossMulitComm(0, 0, rankIds1, subCommId1);
exit(0);
}
pids[1] = fork();
if (pids[1] < 0) {
std::cout << "fork failed ! " << pids[1] << std::endl;
} else if (pids[1] == 0) {
atb::TestCreateHcclCrossMulitComm(1, 1, rankIds1, subCommId1);
exit(0);
}
std::vector<uint32_t> rankIds2 = {2, 3};
int subCommId2 = 2;
pids[2] = fork();
if (pids[2] < 0) {
std::cout << "fork failed ! " << pids[2] << std::endl;
} else if (pids[2] == 0) {
atb::TestCreateHcclCrossMulitComm(2, 0, rankIds2, subCommId2);
exit(0);
}
pids[3] = fork();
if (pids[3] < 0) {
std::cout << "fork failed ! " << pids[3] << std::endl;
} else if (pids[3] == 0) {
atb::TestCreateHcclCrossMulitComm(3, 1, rankIds2, subCommId2);
exit(0);
}
for (int i = 0; i < processCount; ++i) {
waitpid(pids[i], NULL, 0);
}
}
TEST(CreateCommTest, CreateHcclCommMultiProcess)
{
const int processCount = 2;
pid_t pids[processCount];
for (int i = 0; i < processCount; ++i) {
pids[i] = fork();
if (pids[i] < 0) {
std::cout << "fork failed ! " << pids[i] << std::endl;
} else if (pids[i] == 0) {
RunTestInProcess(i, processCount);
exit(0);
}
}
for (int i = 0; i < processCount; ++i) {
waitpid(pids[i], NULL, 0);
}
}