无法通过 MPI_send 发送整个矢量
Cant send the whole vector through MPI_send
我一直在努力学习 MPI。当我尝试 运行 以下代码时,我得到了错误的输出。
if (world_rank == 0){
vector<vector<double> > n(4,vector<double>(4));
srand(time(NULL));
for(int i=0; i<4 ;i++){
for(int j=0;j<4;j++){
n[i][j] = (double)rand()/RAND_MAX;
cout << n[i][j] << " ";
}
cout << endl;
}
MPI_Send((void*)&n[0][0],16*sizeof(double),MPI_BYTE,1,0,MPI_COMM_WORLD);
}else{
MPI_Status status;
vector<vector<double> > n(4,vector<double>(4));
MPI_Probe(0,0,MPI_COMM_WORLD,&status);
int size;
MPI_Get_count(&status,MPI_BYTE,&size);
cout << endl << size << endl;
MPI_Recv((void*)&n[0][0],16*sizeof(n[0][0]),MPI_BYTE,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
cout.flush();
cout << endl;
for(int i=0; i<4 ;i++){
for(int j=0;j<4;j++){
cout << n[i][j] << " ";
}
cout << endl;
}
}
我得到了除最后 3 个之外的所有双精度值。
像这样。
0.824468 0.752417 0.757125 0.470763
0.251683 0.703306 0.157991 0.764423
0.815327 0.0402807 0.897109 0.313816
0.997203 0.796665 0.0522305 0.797733
128
0.824468 0.752417 0.757125 0.470763
0.251683 0.703306 0.157991 0.764423
0.815327 0.0402807 0.897109 0.313816
0.997203 0 0 0
谁能告诉我为什么会这样?
我 运行 相同的代码大约一百次,仍然得到相同的输出(当然具有不同的值)但最后三个总是 0.
但是当我将大小从 16 更改为 19 时,我得到了所有值。
我还有一个疑惑。
有时输出(来自节点 0 和 1 的值)会重叠。任何人都可以告诉我如何阻止它或至少解释为什么会发生这种情况。我的意思是即使 send 和 recv 是阻塞函数。如何在节点 0
之前打印节点 1 的输出
您将二维数据 n
定义为 vector<vector<double> >
使其在内存中不连续。因此,您不能简单地使用 MPI 传输它(有一些方法可以做到这一点,但您最好只让内存连续)。
为了让你的内存连续,你可以这样声明你的 n
(未测试):
vector<double> ndata(4*4); //contiguous storage of the actual data
vector<double*> n(4); //vector of pointers to access the actual data
for (int i=1; i<4; i++) //initialisation of the pointers to the data
n[i] = &ndata[4*i];
当然,在 C++ 中为多维数组定义连续存储有更好的方法,但这只是解决您当前问题的快速方法。参见例如 this answer 以获得更好的结构。
另外,您的 MPI_Send()
和 MPI_Recv()
调用应该使用 4*4
MPI_DOUBLE
而不是 4*4*sizeof(double)
MPI_BYTE
.
我一直在努力学习 MPI。当我尝试 运行 以下代码时,我得到了错误的输出。
if (world_rank == 0){
vector<vector<double> > n(4,vector<double>(4));
srand(time(NULL));
for(int i=0; i<4 ;i++){
for(int j=0;j<4;j++){
n[i][j] = (double)rand()/RAND_MAX;
cout << n[i][j] << " ";
}
cout << endl;
}
MPI_Send((void*)&n[0][0],16*sizeof(double),MPI_BYTE,1,0,MPI_COMM_WORLD);
}else{
MPI_Status status;
vector<vector<double> > n(4,vector<double>(4));
MPI_Probe(0,0,MPI_COMM_WORLD,&status);
int size;
MPI_Get_count(&status,MPI_BYTE,&size);
cout << endl << size << endl;
MPI_Recv((void*)&n[0][0],16*sizeof(n[0][0]),MPI_BYTE,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
cout.flush();
cout << endl;
for(int i=0; i<4 ;i++){
for(int j=0;j<4;j++){
cout << n[i][j] << " ";
}
cout << endl;
}
}
我得到了除最后 3 个之外的所有双精度值。 像这样。
0.824468 0.752417 0.757125 0.470763
0.251683 0.703306 0.157991 0.764423
0.815327 0.0402807 0.897109 0.313816
0.997203 0.796665 0.0522305 0.797733
128
0.824468 0.752417 0.757125 0.470763
0.251683 0.703306 0.157991 0.764423
0.815327 0.0402807 0.897109 0.313816
0.997203 0 0 0
谁能告诉我为什么会这样? 我 运行 相同的代码大约一百次,仍然得到相同的输出(当然具有不同的值)但最后三个总是 0.
但是当我将大小从 16 更改为 19 时,我得到了所有值。
我还有一个疑惑。 有时输出(来自节点 0 和 1 的值)会重叠。任何人都可以告诉我如何阻止它或至少解释为什么会发生这种情况。我的意思是即使 send 和 recv 是阻塞函数。如何在节点 0
之前打印节点 1 的输出您将二维数据 n
定义为 vector<vector<double> >
使其在内存中不连续。因此,您不能简单地使用 MPI 传输它(有一些方法可以做到这一点,但您最好只让内存连续)。
为了让你的内存连续,你可以这样声明你的 n
(未测试):
vector<double> ndata(4*4); //contiguous storage of the actual data
vector<double*> n(4); //vector of pointers to access the actual data
for (int i=1; i<4; i++) //initialisation of the pointers to the data
n[i] = &ndata[4*i];
当然,在 C++ 中为多维数组定义连续存储有更好的方法,但这只是解决您当前问题的快速方法。参见例如 this answer 以获得更好的结构。
另外,您的 MPI_Send()
和 MPI_Recv()
调用应该使用 4*4
MPI_DOUBLE
而不是 4*4*sizeof(double)
MPI_BYTE
.