所以我试图在C ++中的MPI进程之间复制不同长度的向量,即在所有节点上获取向量并将它们连接到节点0上的新向量。
我有以下代码,这些代码没有返回我的预期,让我发疯,导致进一步陷入困境。
代码是这(缩写):
//previously summed all of numfrags to make _numFrag
//numfrags is a vector of the local sizes of _fragLoc
//_numFrag is the total of numfrags
MPI::COMM_WORLD.Barrier();
cout << _myid << "local numFrag = " << _fragLoc.size() << endl;
MPI::COMM_WORLD.Barrier();
for (unsigned i = 0; i < _fragLoc.size(); ++i) cout << "fragloc(" << i << ") = " << _fragLoc[i] << endl;
MPI::COMM_WORLD.Barrier();
vector<int> outVector (_numFrag);
int displ[_numprocs];
if (_myid == 0) {
double sum = 0;
for (int i = 0; i < _numprocs; ++i) {
displ[i] = sum;
cout << _myid << " : " << i << " : " << sum << endl;
sum += numfrags[i];
}
}
MPI::COMM_WORLD.Barrier(); MPI::COMM_WORLD.Gatherv(&_fragLoc[0], numfrags[_myid], MPI::INT, &outVector[0], &numfrags[0], &displ[0], MPI::INT,0);
MPI::COMM_WORLD.Barrier();
if (_myid == 0) {
cout << "X numFrag = " << _numFrag << endl;
for (unsigned i = 0; i < _numFrag; ++i) cout << "outVector(" << i << ") = " << outVector[i] << endl;
}
举一个简单的例子,我有一个四节点运行。以下是伪代码的变量输入:
int _numprocs = 4;
vector<int> numfrags = {0,1,0,1};
vector<int> _fragLoc <node 0> = {};
vector<int> _fragLoc <node 1> = {12};
vector<int> _fragLoc <node 2> = {};
vector<int> _fragLoc <node 3> = {37};
int _numFrag = 2;
输出结果为:
2local numFrag = 0
3local numFrag = 1
0local numFrag = 0
1local numFrag = 1
fragloc(0) = 12
fragloc(0) = 37
0 : 0 : 0
0 : 1 : 0
0 : 2 : 1
0 : 3 : 1
0: after stage 2
X numFrag = 2
outVector(0) = 0
outVector(1) = 0
但是我希望将各个fragLoc放在一起进入outVector,而这种情况并没有发生。有什么建议?我在完成调试后会清理障碍。
答案 0 :(得分:4)
据我所知,上面的代码按预期工作。
#include <iostream>
#include <mpi.h>
#include <vector>
using namespace std;
int main(int argc, char **argv) {
MPI::Init(argc, argv);
int _myid = MPI::COMM_WORLD.Get_rank();
int _numprocs = MPI::COMM_WORLD.Get_size();
vector<int> _fragLoc;
switch(_myid) {
case 0: break;
case 1: _fragLoc.push_back(12); break;
case 2: break;
case 3: _fragLoc.push_back(37); break;
}
int locNumFrag = _fragLoc.size();
cout << _myid << "local numFrag = " << locNumFrag << endl;
MPI::COMM_WORLD.Barrier(); // for printing
vector<int> numfrags(_numprocs);
MPI::COMM_WORLD.Allgather(&locNumFrag, 1, MPI::INT, &numfrags[0], 1, MPI::INT);
int _numFrag = 0;
for (int i=0; i<_numprocs; i++)
_numFrag += numfrags[i];
for (unsigned i = 0; i < _fragLoc.size(); ++i)
cout << "fragloc(" << i << ") = " << _fragLoc[i] << endl;
MPI::COMM_WORLD.Barrier(); // for printing
vector<int> outVector (_numFrag);
int displ[_numprocs];
if (_myid == 0) {
double sum = 0;
for (int i = 0; i < _numprocs; ++i) {
displ[i] = sum;
cout << _myid << " : " << i << " : " << sum << endl;
sum += numfrags[i];
}
}
MPI::COMM_WORLD.Gatherv(&_fragLoc[0], numfrags[_myid], MPI::INT, &outVector[0], &numfrags[0], &displ[0], MPI::INT,0);
if (_myid == 0) {
cout << "X numFrag = " << _numFrag << endl;
for (unsigned i = 0; i < _numFrag; ++i) cout << "outVector(" << i << ") = " << outVector[i] << endl;
}
MPI::Finalize();
return 0;
}
跑步给出
$ mpirun -np 4 ./gatherv
0local numFrag = 0
1local numFrag = 1
fragloc(0) = 12
2local numFrag = 0
3local numFrag = 1
fragloc(0) = 37
0 : 0 : 0
0 : 1 : 0
0 : 2 : 1
0 : 3 : 1
X numFrag = 2
outVector(0) = 12
outVector(1) = 37