【问题详细描述】
1.测试两个进程调用HCCL-AllReduce性能,用profile抓取timeline发现有耗时较高的wait,这个是什么原因呢?
2.profile
【问题相关文件】
代码:代码实现是参考这里https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/800alpha001/devguide/hccl/hcclug/hcclug_000021.html
编译方式:g++ -I "${ATB_HOME_PATH}/include" -I "${ASCEND_HOME_PATH}/include" -L "${ATB_HOME_PATH}/lib" -L "${ASCEND_HOME_PATH}/lib64" al.cpp -l atb -l ascendcl -o demo
#include <iostream>
#include <vector>
#include <memory>
#include <thread>
#include <chrono>
#include "hccl/hccl.h"
#include "hccl/hccl_types.h"
#include "mpi.h"
#include <unistd.h>
#include <chrono>
#define ACLCHECK(ret) do {\
if(ret != ACL_SUCCESS)\
{\
printf("acl interface return err %s:%d, retcode: %d \n", __FILE__, __LINE__, ret);\
return ret;\
}\
} while(0)\
#define HCCLCHECK(ret) do {\
if(ret != HCCL_SUCCESS)\
{\
printf("hccl interface return errreturn err %s:%d, retcode: %d \n", __FILE__, __LINE__, ret);\
return ret;\
}\
} while(0)
struct ThreadContext {
HcclComm comm;
int32_t device;
};
int Sample(void *arg)
{
ThreadContext* ctx = (ThreadContext *)arg;
void* host_buf = nullptr;
void* send_buff = nullptr;
void* recv_buff = nullptr;
uint64_t count = 130*3072/2;
int malloc_kSize = count * sizeof(float);
aclrtEvent start_event, end_event;
aclrtStream stream;
ACLCHECK(aclrtCreateStream(&stream));
ACLCHECK(aclrtCreateEvent(&start_event));
ACLCHECK(aclrtCreateEvent(&end_event));
ACLCHECK(aclrtMalloc((void**)&send_buff, malloc_kSize, ACL_MEM_MALLOC_HUGE_FIRST));
ACLCHECK(aclrtMalloc((void**)&recv_buff, malloc_kSize, ACL_MEM_MALLOC_HUGE_FIRST));
ACLCHECK(aclrtMallocHost((void**)&host_buf, malloc_kSize));
ACLCHECK(aclrtMemcpy((void*)send_buff, malloc_kSize, (void*)host_buf, malloc_kSize, ACL_MEMCPY_HOST_TO_DEVICE));
HCCLCHECK(HcclAllReduce((void *)send_buff, (void*)recv_buff, count, HCCL_DATA_TYPE_FP32, HCCL_REDUCE_SUM, ctx->comm, stream));
ACLCHECK(aclrtSynchronizeStream(stream));
sleep(2);
auto start = std::chrono::steady_clock::now();
for (int i=0; i<61;i++) {
HCCLCHECK(HcclAllReduce((void *)send_buff, (void*)recv_buff, count, HCCL_DATA_TYPE_FP32, HCCL_REDUCE_SUM, ctx->comm, stream));
}
ACLCHECK(aclrtSynchronizeStream(stream));
auto end = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "device " << ctx->device << " Elapsed time: " << duration.count() << " ms" << std::endl;
if (ctx->device < 8) {
void* resultBuff;
ACLCHECK(aclrtMallocHost((void**)&resultBuff, malloc_kSize));
ACLCHECK(aclrtMemcpy((void*)resultBuff, malloc_kSize, (void*)recv_buff, malloc_kSize, ACL_MEMCPY_DEVICE_TO_HOST));
float* tmpResBuff = static_cast<float*>(resultBuff);
// for (uint32_t i = 0; i < count; ++i) {
// std::cout << "rankId:" << ctx->device << ",i" << i << " " << tmpResBuff[i] << std::endl;
// }
ACLCHECK(aclrtFreeHost(resultBuff));
}
ACLCHECK(aclrtFree(send_buff));
ACLCHECK(aclrtFree(recv_buff));
ACLCHECK(aclrtFreeHost(host_buf));
//销毁任务流
ACLCHECK(aclrtDestroyStream(stream));
ACLCHECK(aclrtDestroyEvent(start_event));
ACLCHECK(aclrtDestroyEvent(end_event));
std::cout << "device " << ctx->device <<" finish!" << std::endl;
return 0;
}
int main(int argc, char*argv[])
{
MPI_Init(&argc, &argv);
int procSize = 0;
int procRank = 0;
// 获取当前进程在所属进程组的编号
MPI_Comm_size(MPI_COMM_WORLD, &procSize);
MPI_Comm_rank(MPI_COMM_WORLD, &procRank);
int devId = procRank;
int devCount = procSize;
//设备资源初始化
ACLCHECK(aclInit(NULL));
// 指定集合通信操作使用的设备
ACLCHECK(aclrtSetDevice(devId));
// 在 rootRank 获取 rootInfo
HcclRootInfo rootInfo;
int32_t rootRank = 0;
if(devId == rootRank) {
HCCLCHECK(HcclGetRootInfo(&rootInfo));
}
// 将root_info广播到通信域内的其他rank
MPI_Bcast(&rootInfo, HCCL_ROOT_INFO_BYTES, MPI_CHAR, rootRank, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
// 初始化集合通信域
HcclComm hcclComm;
HCCLCHECK(HcclCommInitRootInfo(devCount, &rootInfo, devId, &hcclComm));
// 创建任务stream
struct ThreadContext args;
args.comm = hcclComm;
args.device = devId;
Sample((void *)&args);
sleep(2);
//销毁集合通信域
HCCLCHECK(HcclCommDestroy(hcclComm));
//重置设备
ACLCHECK(aclrtResetDevice(devId));
//设备去初始化
ACLCHECK(aclFinalize());
return 0;
} 【昇腾产品型号】:A800T
【版本信息】:
- CANN版本: 8.0.T16
- Python版本:Python 3.10.13
- 系统版本: Linux version 5.15.0-25-generic (gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0, GNU ld (GNU Binutils for Ubuntu) 2.38)
【开发需求】
- 功能需求(必填): 模型开发,算子性能测试
【问题详细描述】
1.测试两个进程调用HCCL-AllReduce性能,用profile抓取timeline发现有耗时较高的wait,这个是什么原因呢?
2.profile
代码:代码实现是参考这里https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/800alpha001/devguide/hccl/hcclug/hcclug_000021.html
编译方式:g++ -I "${ATB_HOME_PATH}/include" -I "${ASCEND_HOME_PATH}/include" -L "${ATB_HOME_PATH}/lib" -L "${ASCEND_HOME_PATH}/lib64" al.cpp -l atb -l ascendcl -o demo
#include <iostream> #include <vector> #include <memory> #include <thread> #include <chrono> #include "hccl/hccl.h" #include "hccl/hccl_types.h" #include "mpi.h" #include <unistd.h> #include <chrono> #define ACLCHECK(ret) do {\ if(ret != ACL_SUCCESS)\ {\ printf("acl interface return err %s:%d, retcode: %d \n", __FILE__, __LINE__, ret);\ return ret;\ }\ } while(0)\ #define HCCLCHECK(ret) do {\ if(ret != HCCL_SUCCESS)\ {\ printf("hccl interface return errreturn err %s:%d, retcode: %d \n", __FILE__, __LINE__, ret);\ return ret;\ }\ } while(0) struct ThreadContext { HcclComm comm; int32_t device; }; int Sample(void *arg) { ThreadContext* ctx = (ThreadContext *)arg; void* host_buf = nullptr; void* send_buff = nullptr; void* recv_buff = nullptr; uint64_t count = 130*3072/2; int malloc_kSize = count * sizeof(float); aclrtEvent start_event, end_event; aclrtStream stream; ACLCHECK(aclrtCreateStream(&stream)); ACLCHECK(aclrtCreateEvent(&start_event)); ACLCHECK(aclrtCreateEvent(&end_event)); ACLCHECK(aclrtMalloc((void**)&send_buff, malloc_kSize, ACL_MEM_MALLOC_HUGE_FIRST)); ACLCHECK(aclrtMalloc((void**)&recv_buff, malloc_kSize, ACL_MEM_MALLOC_HUGE_FIRST)); ACLCHECK(aclrtMallocHost((void**)&host_buf, malloc_kSize)); ACLCHECK(aclrtMemcpy((void*)send_buff, malloc_kSize, (void*)host_buf, malloc_kSize, ACL_MEMCPY_HOST_TO_DEVICE)); HCCLCHECK(HcclAllReduce((void *)send_buff, (void*)recv_buff, count, HCCL_DATA_TYPE_FP32, HCCL_REDUCE_SUM, ctx->comm, stream)); ACLCHECK(aclrtSynchronizeStream(stream)); sleep(2); auto start = std::chrono::steady_clock::now(); for (int i=0; i<61;i++) { HCCLCHECK(HcclAllReduce((void *)send_buff, (void*)recv_buff, count, HCCL_DATA_TYPE_FP32, HCCL_REDUCE_SUM, ctx->comm, stream)); } ACLCHECK(aclrtSynchronizeStream(stream)); auto end = std::chrono::steady_clock::now(); auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start); std::cout << "device " << ctx->device << " Elapsed time: " << duration.count() << " ms" << std::endl; if (ctx->device < 8) { void* resultBuff; ACLCHECK(aclrtMallocHost((void**)&resultBuff, malloc_kSize)); ACLCHECK(aclrtMemcpy((void*)resultBuff, malloc_kSize, (void*)recv_buff, malloc_kSize, ACL_MEMCPY_DEVICE_TO_HOST)); float* tmpResBuff = static_cast<float*>(resultBuff); // for (uint32_t i = 0; i < count; ++i) { // std::cout << "rankId:" << ctx->device << ",i" << i << " " << tmpResBuff[i] << std::endl; // } ACLCHECK(aclrtFreeHost(resultBuff)); } ACLCHECK(aclrtFree(send_buff)); ACLCHECK(aclrtFree(recv_buff)); ACLCHECK(aclrtFreeHost(host_buf)); //销毁任务流 ACLCHECK(aclrtDestroyStream(stream)); ACLCHECK(aclrtDestroyEvent(start_event)); ACLCHECK(aclrtDestroyEvent(end_event)); std::cout << "device " << ctx->device <<" finish!" << std::endl; return 0; } int main(int argc, char*argv[]) { MPI_Init(&argc, &argv); int procSize = 0; int procRank = 0; // 获取当前进程在所属进程组的编号 MPI_Comm_size(MPI_COMM_WORLD, &procSize); MPI_Comm_rank(MPI_COMM_WORLD, &procRank); int devId = procRank; int devCount = procSize; //设备资源初始化 ACLCHECK(aclInit(NULL)); // 指定集合通信操作使用的设备 ACLCHECK(aclrtSetDevice(devId)); // 在 rootRank 获取 rootInfo HcclRootInfo rootInfo; int32_t rootRank = 0; if(devId == rootRank) { HCCLCHECK(HcclGetRootInfo(&rootInfo)); } // 将root_info广播到通信域内的其他rank MPI_Bcast(&rootInfo, HCCL_ROOT_INFO_BYTES, MPI_CHAR, rootRank, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); // 初始化集合通信域 HcclComm hcclComm; HCCLCHECK(HcclCommInitRootInfo(devCount, &rootInfo, devId, &hcclComm)); // 创建任务stream struct ThreadContext args; args.comm = hcclComm; args.device = devId; Sample((void *)&args); sleep(2); //销毁集合通信域 HCCLCHECK(HcclCommDestroy(hcclComm)); //重置设备 ACLCHECK(aclrtResetDevice(devId)); //设备去初始化 ACLCHECK(aclFinalize()); return 0; }【昇腾产品型号】:A800T
【版本信息】:
- CANN版本: 8.0.T16
- Python版本:Python 3.10.13
- 系统版本: Linux version 5.15.0-25-generic (gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0, GNU ld (GNU Binutils for Ubuntu) 2.38)
【开发需求】
- 功能需求(必填): 模型开发,算子性能测试