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

MPI程序故障排查:Bcast同步异常与Sendrecv传输失效

MPI管道式数据传递程序问题排查与代码迭代

任务描述

编写一个MPI程序,实现0号进程的数据通过管道传递给所有其他进程,具体要求如下:

  • 进程i必须从i-1进程接收数据,再将其发送给i+1进程,直至最后一个进程
  • 0号进程从用户处读取整数,直到输入负数为止
  • 必须使用MPI_Sendrecv完成数据交互

问题与代码迭代

编写程序后遇到以下问题:

  1. 初始版本中调用MPI_Bcast时,其他进程未等待0号进程生成数据就继续执行,导致逻辑错误
  2. 调整MPI_Bcast执行顺序后,MPI_Sendrecv仍然无法正常工作,程序出现冻结

初始代码

最初使用list存储数据,错误地在0号进程输入数据前就执行了MPI_Bcast,且直接传递list对象给MPI函数(MPI无法直接处理C++容器),导致广播无效。

#include <stdio.h>
#include <mpi.h>
#include <iostream>
#include <list>

using namespace std;

int proc_count, proc_this;
int input;
list <int> buf;
list <int> nlist = {};
int siz = 0;
int main(int argc, char** argv)
{
    int tag = 1;
    MPI_Status Stat;
    MPI_Request request;
    int prev, next;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &proc_count);
    MPI_Comm_rank(MPI_COMM_WORLD, &proc_this);

    prev = proc_this - 1;
    next = proc_this + 1;

    cout << "size before = " << siz << endl;

 
    MPI_Bcast(&siz, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&nlist, siz, MPI_INT, 0, MPI_COMM_WORLD);
    cout << "size = " << siz << endl;


    if (proc_this == 0) {

        cout << "Enter an integer and a non-negative number ";
        cin >> input;
        while (input >= 0) {
            nlist.push_back(input);

            cout << "Enter an integer and a non-negative number ";
            cin >> input;
        }
        cout << "Was entered negative value \n";

        siz = nlist.size();

    }
    else if (proc_this != 0 and proc_this != proc_count - 1) {
        
        
        MPI_Sendrecv(&nlist, siz, MPI_INT, next, tag, &buf, siz, MPI_INT, prev, tag, MPI_COMM_WORLD, &Stat);
        printf("Proc No-%d send data to proc No-%d\n", prev, next);

        cout << "size siz= " << siz << endl;
        for (auto it = nlist.begin(); it != nlist.end(); it++)
            printf("Proc No-%d my data %d\n", proc_this, *it);

    }
    else 
        printf("Last proc was reached!");


    MPI_Finalize();
    return 0;
}

更新1

将list替换为vector,但仍在0号进程输入数据前执行MPI_Bcast,广播顺序错误,且尝试广播vector对象本身而非底层数据指针。

#include <stdio.h>
#include <mpi.h>
#include <iostream>
#include <vector>

using namespace std;

int proc_count, proc_this;
int input;
vector <int> buf;
vector <int> nlist = {};
int siz;
int main(int argc, char** argv)
{
    int tag = 1;
    MPI_Status Stat;
    MPI_Request request;
    int prev, next;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &proc_count);
    MPI_Comm_rank(MPI_COMM_WORLD, &proc_this);

    prev = proc_this - 1;
    next = proc_this + 1;

    cout << "size before = " << siz << endl;

    MPI_Bcast(&siz, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&nlist, siz, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&buf, siz, MPI_INT, 0, MPI_COMM_WORLD);

    if (proc_this == 0) {

        cout << "Enter an integer and a non-negative number ";
        cin >> input;
        while (input >= 0) {
            nlist.push_back(input);

            cout << "Enter an integer and a non-negative number ";
            cin >> input;
        }
        cout << "Was entered negative value \n";

        siz = nlist.size();
        buf.resize(siz);
    }
    else if (proc_this != 0 and proc_this != proc_count - 1) {
        cout << "buf size = " << buf.size() << endl;
        cout << "size = " << siz << endl;

        MPI_Sendrecv(nlist.data(), siz, MPI_INT, next, tag, buf.data(), siz, MPI_INT, prev, tag, MPI_COMM_WORLD, &Stat);

        printf("Proc No-%d send data to proc No-%d\n", proc_this, next);
        cout << "size siz= " << siz << endl;

        for (auto it = nlist.begin(); it != nlist.end(); it++)
            printf("Proc No-%d my data %d\n", proc_this, *it);
    }
    else
        printf("Last proc was reached!");


    MPI_Finalize();
    return 0;
}

更新2

修复了MPI_Bcast的顺序(先让0号进程输入数据,再广播数据大小和内容),但MPI_Sendrecv的逻辑仍有问题,程序冻结。

#include <stdio.h>
#include <mpi.h>
#include <iostream>
#include <vector>

using namespace std;

int proc_count, proc_this;
int input;
vector <int> buf = {};
vector <int> nlist = {};
int siz;
int main(int argc, char** argv)
{
    int tag = 1;
    MPI_Status Stat;
    MPI_Request request;
    int prev, next;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &proc_count);
    MPI_Comm_rank(MPI_COMM_WORLD, &proc_this);

    prev = proc_this - 1;
    next = proc_this + 1;

    cout << "size before = " << siz << endl;


    if (proc_this == 0) {

        cout << "Enter an integer and a non-negative number ";
        cin >> input;
        while (input >= 0) {
            nlist.push_back(input);

            cout << "Enter an integer and a non-negative number ";
            cin >> input;
        }
        cout << "Was entered negative value \n";

        siz = nlist.size();
    }
  
    
    MPI_Bcast(&siz, 1, MPI_INT, 0, MPI_COMM_WORLD);
    nlist.resize(siz);
    MPI_Bcast(nlist.data(), siz, MPI_INT, 0, MPI_COMM_WORLD);
    buf.resize(siz);

    if (proc_this != 0 and proc_this != proc_count - 1) {

        cout << "buf size = " << buf.size() << endl;
        cout << "size nlist = " << nlist.size() << endl;

        MPI_Sendrecv(nlist.data(), siz, MPI_INT, next, tag, buf.data(), siz, MPI_INT, prev, tag, MPI_COMM_WORLD, &Stat);

        printf("Proc No-%d send data to proc No-%d\n", proc_this, next);
        cout << "size siz= " << siz << endl;

        for (int it: nlist)
            cout << "Proc No- " << proc_this << " my data " << it << endl;
    }
    if (proc_this == proc_count - 1)
        printf("Last proc was reached!");

    MPI_Finalize();
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 00:57:04