MPI_Bcast 中的分段错误
Segmentation fault in MPI_Bcast
我是 Open MPI 的新手,我正在尝试将其用于 运行 使用字典攻击的暴力密码破解程序(我实际上并不是在破解密码,这只是一个练习)。我使用的字典是 vector<char>
,其中单词由空终止符分隔。
使用 MPI_Barriers
,我确定错误发生在第二个 MPI_Bcast
(广播 dictionary
的 MPI_Bcast
)。我已验证缓冲区的内容(向量的大小)已成功广播。
我得到的错误是代码 "Address not mapped" 的分段错误 (11)。
由于某种原因,当 运行 有 > 2 个进程时,这总是发生在排名 2 的进程中。如果我 运行 只有 2 个进程,它会出现在排名 1 的进程中。
我不知道它是否总是由于偶然、由于调度而陷入 2 级进程,或者它是否实际上只是 2 级进程中的一个问题(我发现它最不可能发生在 2 个进程中) .
在其他类似的问题中,问题在于buffer是如何传递的。正常问题是用户在 c 程序中手动分配内存,将指针的地址而不是指针本身传递给数组。这不是这里的问题(我什至出于绝望尝试过,但它被捕获为编译器错误)。
我现在不知道问题出在哪里。它可能与传递缓冲区有关,或者完全与其他东西有关。如果需要更多代码,请告诉我。
相关代码:
void BroadCast_Receive(vector<char> &dictionary, vector<char> &passwords){
int buffer[2];
buffer[0] = dictionary.size();
buffer[1] = passwords.size();
MPI_Bcast(buffer,2,MPI_INT,0,MPI_COMM_WORLD);
dictionary.resize(buffer[0]);
passwords.resize(buffer[1]);
// seg faults here
MPI_Bcast(&dictionary[0],buffer[0],MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(&passwords[0],buffer[1],MPI_INT,0,MPI_COMM_WORLD);
}
你的问题是你的 MPI_Datatype
不匹配。您正在使用 MPI_INT
,而您的 dictionary
和 passwords
是类型 char
的 std::vector
。请改用 MPI_CHAR
。
此外,正如 PaulMcKenzie 指出的那样,如果向量的大小为 0
,&dictionary[0]
仍然会失败。对于干净的代码,您应该检查此条件或断言它。
以下代码应该适合您:
void BroadCast_Receive(vector<char> &dictionary, vector<char> &passwords){
int buffer[2];
buffer[0] = dictionary.size();
buffer[1] = passwords.size();
MPI_Bcast(buffer,2,MPI_INT,0,MPI_COMM_WORLD);
if (buffer[0] > 0) {
dictionary.resize(buffer[0]);
MPI_Bcast(&dictionary[0],buffer[0],MPI_CHAR,0,MPI_COMM_WORLD);
}
if (buffer[1] > 0) {
passwords.resize(buffer[1]);
MPI_Bcast(&passwords[0],buffer[1],MPI_CHAR,0,MPI_COMM_WORLD);
}
}
我是 Open MPI 的新手,我正在尝试将其用于 运行 使用字典攻击的暴力密码破解程序(我实际上并不是在破解密码,这只是一个练习)。我使用的字典是 vector<char>
,其中单词由空终止符分隔。
使用 MPI_Barriers
,我确定错误发生在第二个 MPI_Bcast
(广播 dictionary
的 MPI_Bcast
)。我已验证缓冲区的内容(向量的大小)已成功广播。
我得到的错误是代码 "Address not mapped" 的分段错误 (11)。
由于某种原因,当 运行 有 > 2 个进程时,这总是发生在排名 2 的进程中。如果我 运行 只有 2 个进程,它会出现在排名 1 的进程中。 我不知道它是否总是由于偶然、由于调度而陷入 2 级进程,或者它是否实际上只是 2 级进程中的一个问题(我发现它最不可能发生在 2 个进程中) .
在其他类似的问题中,问题在于buffer是如何传递的。正常问题是用户在 c 程序中手动分配内存,将指针的地址而不是指针本身传递给数组。这不是这里的问题(我什至出于绝望尝试过,但它被捕获为编译器错误)。
我现在不知道问题出在哪里。它可能与传递缓冲区有关,或者完全与其他东西有关。如果需要更多代码,请告诉我。
相关代码:
void BroadCast_Receive(vector<char> &dictionary, vector<char> &passwords){
int buffer[2];
buffer[0] = dictionary.size();
buffer[1] = passwords.size();
MPI_Bcast(buffer,2,MPI_INT,0,MPI_COMM_WORLD);
dictionary.resize(buffer[0]);
passwords.resize(buffer[1]);
// seg faults here
MPI_Bcast(&dictionary[0],buffer[0],MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(&passwords[0],buffer[1],MPI_INT,0,MPI_COMM_WORLD);
}
你的问题是你的 MPI_Datatype
不匹配。您正在使用 MPI_INT
,而您的 dictionary
和 passwords
是类型 char
的 std::vector
。请改用 MPI_CHAR
。
此外,正如 PaulMcKenzie 指出的那样,如果向量的大小为 0
,&dictionary[0]
仍然会失败。对于干净的代码,您应该检查此条件或断言它。
以下代码应该适合您:
void BroadCast_Receive(vector<char> &dictionary, vector<char> &passwords){
int buffer[2];
buffer[0] = dictionary.size();
buffer[1] = passwords.size();
MPI_Bcast(buffer,2,MPI_INT,0,MPI_COMM_WORLD);
if (buffer[0] > 0) {
dictionary.resize(buffer[0]);
MPI_Bcast(&dictionary[0],buffer[0],MPI_CHAR,0,MPI_COMM_WORLD);
}
if (buffer[1] > 0) {
passwords.resize(buffer[1]);
MPI_Bcast(&passwords[0],buffer[1],MPI_CHAR,0,MPI_COMM_WORLD);
}
}