MPI_Bcast 导致分段错误

MPI_Bcast results in segmentation fault

上下文

我一直在做一个大学项目,该项目需要同时使用 OpenMpMPI 来检查 .csv file(一百万行)并提取一些统计数据。

我已经设法编写并测试了一个在我的机器上运行良好的程序,所以我开了一个 AWS 账户来测试程序在多个节点上 运行 时的实际并行性能。

问题

当我 运行 单个 AWS EC2 (Amazon Linux 2, t2.xlarge) 实例上的代码时,我得到一个 segmentation fault 这是由于 MPI_BCast 调用,即使代码在我的机器上运行良好。在将其执行扩展到其他节点之前,我真的很想了解这个问题。

我已将产生此错误的代码缩小为以下代码:


#define FIN_PATH R"(NYPD_Motor_Vehicle_Collisions.csv)"
#define LINES 955928
#define MAX_LINE_LENGHT 500

...

int main() {
    int RANK;
    int SIZE;
    int THREAD_SUPPORT;

    MPI_Init_thread(nullptr, nullptr, MPI_THREAD_FUNNELED, &THREAD_SUPPORT);

    MPI_Comm_size(MPI_COMM_WORLD, &SIZE);
    MPI_Comm_rank(MPI_COMM_WORLD, &RANK);

    int i;

    //Initialize empty dataset
    char ** data = new char*[LINES];

    for(i = 0; i < LINES; ++i)
        data[i] = new char[MAX_LINE_LENGHT] {'[=11=]'};


    // Populate dataset
    if (RANK == 0) {
        string line;
        ifstream fin(FIN_PATH, ios::in);

        getline(fin, line);

        for(i = 0; i < LINES; ++i) {
            getline(fin, line);
            normalize(&line);
            line.copy(data[i], line.size() + 1);
        }
        fin.close();
    }


    // Broadcast dataset to each process
    MPI_Bcast(&data[0][0], LINES * MAX_LINE_LENGHT, MPI_CHAR, 0, MPI_COMM_WORLD);


    MPI_Finalize();
    return 0;
}


如你所见,我正在读取文件并将每个 char 保存到一个二维数组中(因为 MPI 无法处理字符串),然后我将其广播到每个进程(不优雅,但它帮助我避免在路上遇到大麻烦,例如:实施 MPI I/O).

读取文件时我没有收到任何错误,只有当我重新引入MPI_Bcast函数时才会出现错误。

我确保 AWS EC2 实例有足够的 RAM (16Gb),所以我不明白为什么会发生这种 segmentation fault,而且我对一切都是陌生的(c++ 编程除外) 所以我还没有工具来调试这样的错误。感谢任何见解!

for(i = 0; i < LINES; ++i)
    data[i] = new char[MAX_LINE_LENGHT] {'[=10=]'};

您在不同的地址分配了一大堆单独的字符串。

MPI_Bcast(&data[0][0], LINES * MAX_LINE_LENGHT, MPI_CHAR, 0, MPI_COMM_WORLD);

但是您告诉 MPI_Bcast 发送一个大小为 LINES * MAX_LINE_LENGHT 的对象。您没有在任何地方创建过这样的对象。

您需要在包含您要发送的所有数据的单个地址分配单个对象,因为这是 MPI_Bcast 所期望的。