所以,这是我的任务。我应该在主过程中读取K - 1三元组(K - 是进程数)。三元组由两个整数数字和一个 double 组成。我必须使用 MPI_Pack 和集体操作将此三元组发送到其他进程。但是当使用 MPI_Pack 时,我收到一个错误:无效的缓冲区指针。 这是我的代码:
int flag;
MPI_Initialized(&flag);
if (flag == 0)
return;
int rank, size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int* intbuf = new int[2];
double doublebuf;
byte* rbuf = new byte[(size - 1)*(2 * sizeof(int)+sizeof(double))];
if (rank == 0) {
int pos = 0;
for (int i = 0; i < size - 1; ++i){
pt >> intbuf[1] >> intbuf[2] >> doublebuf; //pt is from the special library and it's okay
MPI_Pack(intbuf, 2, MPI_INT, rbuf, sizeof(int)* 2, &pos, MPI_COMM_WORLD);
MPI_Pack(&doublebuf, 1, MPI_DOUBLE, rbuf, sizeof(double), &pos, MPI_COMM_WORLD);
}
}
MPI_Bcast(rbuf, sizeof(rbuf), MPI_PACKED, 0, MPI_COMM_WORLD);
if (rank != 0){
int pos = 0;
for (int i = 0; i < size - 1; ++i){
MPI_Unpack(rbuf, sizeof(int)* 2, &pos, intbuf, 2, MPI_INT, MPI_COMM_WORLD);
MPI_Unpack(rbuf, sizeof(double), &pos, &doublebuf, 1, MPI_DOUBLE, MPI_COMM_WORLD);
pt << intbuf[1] << intbuf[2] << doublebuf;
}
}
我在做什么?
答案 0 :(得分:3)
主要问题来自这一行:
MPI_Bcast(rbuf, sizeof(rbuf), MPI_PACKED, 0, MPI_COMM_WORLD);
更具体地说,它来自sizeof(rdbuf)
,应由pos
替换。实际上,sizeof(rdbuf)
是一个sizeof(byte*)
,根据您的操作系统可能是4或8,但这与您尝试传输的数据大小无关...这已修复,你的代码可能“有效”。
然而,这仍有很多问题:
MPI_Pack_size()
。MPI_Pack()
?此功能是PVM(即并行虚拟机)的一种遗留物,它是消息传递库预先存在的MPI。该功能的目的是简化从PVM到MPI的过渡,但肯定不能用于从头开发。为了解决您的问题,我建议您拨打2个不同的MPI_Bcast()
,一个使用2个整数,另一个使用双倍。这非常简单明了。
另一个(更好,如果可伸缩性很重要)可能性是创建一个包含你的int和double的结构,并使用MPI_Type_create_struct()
创建匹配的MPI结构类型。
无论如何,祝你的代码好运。
答案 1 :(得分:0)
所以我只是修复了我的错误。打包数据时发生了错误: MPI_Pack 的第5个分区并不意味着您打包了多少数据,这意味着您的缓冲区大小(在我的情况下,缓冲区是 rbuf < / em>), MPI_Unpack 的第二个参数具有相同的语义。 这是固定代码。它有效。
int* intbuf = new int[2];
double doublebuf;
int N = (size - 1)*(2 * sizeof(int)+sizeof(double));
byte* rbuf = new byte[N];
int pos = 0;
if (rank == 0) {
for (int i = 0; i < size - 1; ++i){
pt >> intbuf[0] >> intbuf[1] >> doublebuf;
MPI_Pack(intbuf, 2, MPI_INT, rbuf, N, &pos, MPI_COMM_WORLD);
MPI_Pack(&doublebuf, 1, MPI_DOUBLE, rbuf, N, &pos, MPI_COMM_WORLD);
}
}
MPI_Bcast(rbuf, N, MPI_PACKED, 0, MPI_COMM_WORLD);
if (rank != 0){
int pos = 0;
for (int i = 0; i < size - 1; ++i){
int* intbuf_out = new int[2];
double doublebuf_out;
MPI_Unpack(rbuf, N, &pos, intbuf_out, 2, MPI_INT, MPI_COMM_WORLD);
MPI_Unpack(rbuf, N, &pos, &doublebuf_out, 1, MPI_DOUBLE, MPI_COMM_WORLD);
pt << intbuf_out[0] << intbuf_out[1] << doublebuf_out;
delete(intbuf_out);
}
}