我一直在做一个大学项目,需要同时使用 OpenMp 和 MPI 审视 .csv
档案 的100万行)并提取一些统计数据。
我已经成功地编写并测试了一个程序,在我的机器上运行得很好,所以我开了一个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] {'\0'};
// 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 IO)。
读取文件时我没有收到任何错误,只有当我重新引入MPI_Bcast函数时才会出现。
我确保AWS EC2实例有足够的RAM(16Gb),所以我不明白为什么这一点。segmentation fault
会发生,而我对一切都很陌生(除了 c++
编程)所以我还没有工具来调试这样的错误。任何见解都是感激的
for(i = 0; i < LINES; ++i)
data[i] = new char[MAX_LINE_LENGHT] {'\0'};
你已经在不同的地址上分配了一大堆单独的字符串。
MPI_Bcast(&data[0][0], LINES * MAX_LINE_LENGHT, MPI_CHAR, 0, MPI_COMM_WORLD);
但你告诉我 MPI_Bcast
发送一个大小为 LINES * MAX_LINE_LENGHT
. 你没有在任何地方创建一个这样的对象。
你需要在一个地址上分配一个对象,其中包含所有你想发送的数据,因为那是 MPI_Bcast
期待。