MPI_Bcast 导致分段错误
MPI_Bcast results in segmentation fault
上下文
我一直在做一个大学项目,该项目需要同时使用 OpenMp 和 MPI 来检查 .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
所期望的。
上下文
我一直在做一个大学项目,该项目需要同时使用 OpenMp 和 MPI 来检查 .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
所期望的。