我无法让MPI_Gatherv
使用std :: vector。我编写了一个小程序,它应该填充一个秩为+1的整数的向量(当向量初始化为0时避免为0)。这只是一个使用2个MPI进程运行的示例程序,我意识到它的可扩展性不高。
#include <iostream>
#include <vector>
#include "mpi.h"
int main(int argc, char **argv)
{
int my_rank; //rank of process
int p; //number of MPI processes
int tag=50; //Tag for message
int X = 32;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &p);
std::vector<int> rcvvec(X);
std::vector<int> sndvec(X/p);
int rcounts[p];
int rdisp[p];
for(int i=0; i<p; ++i) {
rcounts[i] = X/p;
rdisp[i] = my_rank*(X/p);
}
for (int i = 0; i < X/p; ++i)
sndvec[i] = my_rank+1;
MPI_Gatherv(&sndvec.front(), rcounts[my_rank], MPI_INT, &rcvvec.front(), rcounts, rdisp, MPI_INT, 0, MPI_COMM_WORLD);
if (!my_rank) {
for (int i = 0; i < rcvvec.size(); ++i) {
std::cout<<rcvvec[i]<<" ";
} std::cout<<std::endl;
}
MPI_Finalize();
}
我希望rcvvec
包含1111111122222222
但我获得2222222200000000
因此,由于某种原因,它只在向量的前半部分插入进程1的整数。有谁知道这里发生了什么?我也尝试用普通的C风格数组实现它,我得到了相同的结果。但如果我用C而不是C ++编写它就可以了。这是我对C ++和MPI的理解失败吗?
感谢您的帮助!
答案 0 :(得分:2)
问题不在于std :: vector;你的代码中只有一个拼写错误来计算位移。这样:
for(int i=0; i<p; ++i) {
rcounts[i] = X/p;
rdisp[i] = my_rank*(X/p);
}
应该是这样的:
for(int i=0; i<p; ++i) {
rcounts[i] = X/p;
rdisp[i] = i*(X/p);
}
实际上,对于零级(在这种情况下是位移数组唯一重要的位置),所有位移都为零,所以所有内容都被写入数组的开头,而后半部分被写入阵列没有动过。