如何获取使用MPI_ANY_SOURCE的非阻塞MPI_Irecv的实际发送源?
获取MPI_ANY_SOURCE对应的实际发送进程源的方法
当调用MPI_Irecv时指定MPI_ANY_SOURCE(即值为-2),只有在该非阻塞接收操作完成后,才能获取到实际的发送进程ID——因为发起调用时,MPI还不知道哪个进程会向该缓冲区发送数据。
针对基于MPICH的MPI应用,你可以通过以下几种方式获取实际发送源:
封装
MPI_Wait/MPI_Test等完成类函数,在操作完成后读取MPI_Status结构体中的MPI_SOURCE字段
你可以在现有的LD_PRELOAD封装代码中,新增对MPI_Wait的封装,示例代码如下:int MPI_Wait(MPI_Request *request, MPI_Status *status) { int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); // 调用原始的MPI_Wait int ret = PMPI_Wait(request, status); // 若状态指针有效,打印实际发送源 if (status != MPI_STATUS_IGNORE) { printf("MPI_Wait完成:进程%d,实际发送源=%d\n", rank, status->MPI_SOURCE); } return ret; }同理,你也可以用同样的逻辑封装
MPI_Test、MPI_Waitall等其他完成非阻塞操作的函数,在操作完成后提取实际发送源。使用
MPI_Request_get_status查询已完成请求的状态
如果你需要主动检查某个请求是否完成,并在完成后获取发送源,可以调用该函数:int flag; MPI_Status status; // 检查请求是否完成 MPI_Request_get_status(request, &flag, &status); if (flag) { printf("请求已完成,实际发送源=%d\n", status->MPI_SOURCE); }(可选)给请求关联自定义标记
如果你需要区分不同的MPI_Irecv请求,可以在发起调用时,将请求与自定义的元数据(比如原始调用的buffer地址、tag等)关联起来(比如用结构体包装MPI_Request),这样在完成时可以精准对应到具体的接收操作,更方便调试。
需要注意:只有当非阻塞接收操作完成后,MPI_Status中的MPI_SOURCE才会存储有效的实际发送进程ID,发起MPI_Irecv时的MPI_ANY_SOURCE只是一个通配符,不代表实际源。
内容的提问来源于stack exchange,提问作者Mariem
相关产品推荐
相关产品推荐

