You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MPI_Irecv与MPI_ANY_SOURCE通信时source返回-1的原因

问题成因

你遇到的MPI_Status.source返回-1的核心原因是对已完成且被释放的MPI请求调用了MPI_Request_get_status,拿到的是无效状态值,具体逻辑如下:

  • MPI_Wait(&R2[i], &status)调用成功后,会自动将请求R2[i]设置为MPI_REQUEST_NULL,并释放该请求对应的资源
  • 后续调用MPI_Request_get_status(R2[i], &flag, &status)时,传入的已经是无效的空请求,MPI实现会将status字段的所有值初始化为默认无效值,因此MPI_SOURCE返回-1
  • 你实际已经在MPI_Wait的出参status里拿到了有效的源进程号,完全不需要再调用MPI_Request_get_status获取状态
其他潜在问题

另外你的代码还有两个容易引发异常的隐患:

  1. 没有校验MPI_Init_thread返回的线程支持级别是否真的是MPI_THREAD_MULTIPLE,部分MPI实现默认不开启多线程并发调用MPI接口的支持,可能会引发未定义行为
  2. 你用2个OpenMP线程在同一个进程内同时调用MPI收发接口,即使MPI_THREAD_MULTIPLE支持正常,也要确保没有请求号、缓冲区的竞争,当前代码里的缓冲区是函数内局部变量暂时没有竞争,但后续扩容容易踩坑
修复方案

直接删掉MPI_Request_get_status这一行即可,用MPI_Wait返回的status值获取源进程号,修改后的fun1循环部分代码如下:

for (int i=0; i<L; ++i) {
    statusflag = MPI_Irecv(&buffer[i], 1, MPI_INT, MPI_ANY_SOURCE, 2501, MPI_COMM_WORLD, &R2[i]);
    MPI_Status status; 
    // Wait调用成功后status里已经有所有需要的信息
    MPI_Wait(&R2[i], &status);
    int q = status.MPI_SOURCE;
    printf("Flag was 1, source was %d, the error was %d, and statusflag was %d\n\n\n", q, status.MPI_ERROR, statusflag);
    std::cout<<std::flush;
    answers[i] = i*5;
    MPI_Ssend(&answers[i], 1, MPI_INT, q, i, MPI_COMM_WORLD);
}

修改后重新编译运行即可解决source返回-1以及后续段错误的问题。

内容的提问来源于stack exchange,提问作者Gaston

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 13:24:03