C ++:使用MPI的gatherv来连接不同长度的向量 [英] C++: Using MPI's gatherv to concatenate vectors of differing lengths
问题描述
我有以下代码,它不会返回我的预期,驱使我疯狂,并进一步下降线。
代码是这里(缩写):
//预先汇总所有numfrags以使_numFrag
// numfrags是局部大小_fragLoc
// _ numFrag是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] 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:
X numFrag = 2
outVector(0)= 0
outVector(1)= 0
但我预计个人fragLoc的一起放在outVector,这不会发生。任何建议?当我完成调试时,我会清除障碍。
据我所知,如预期。
#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);打破;
case 2:break;
case 3:_fragLoc.push_back(37);打破;
}
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 $ b b 0:3:1
X numFrag = 2
outVector(0)= 12
outVector(1)= 37
so I'm trying to copy over vectors of different lengths between MPI processes in C++, namely taking vectors on all of the nodes and concatenating them into a new vector on node 0.
I have the following code, which does not return what I expected, driving me crazy, and causing trouble further down the line.
The code is this (abbreviated):
//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;
}
Giving a simple example, I have a four-node run. Here are the variable inputs as pseudocode:
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;
The output is:
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
But I expected the individual fragLoc's to be put together into outVector and this isn't happening. Any advice? I'll clean up the barriers when I'm done debugging.
As far as I can tell, the code above works as expected.
#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;
}
Running gives
$ 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
这篇关于C ++:使用MPI的gatherv来连接不同长度的向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!