MPI_Test 尽管从未发送过,但仍为请求返回真标志?
MPI_Test returning true flags for requests despite never sending?
我有一些出于测试目的的代码,我删除了所有发送,只有非阻塞接收。你可以想象我在使用 MPI_Test
时感到惊讶,这些标志表明一些请求实际上已经完成。我在笛卡尔网格中设置了我的代码,下面有一个小副本,尽管这不会重现错误:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // for sleep
#include <mpi.h>
void test(int pos);
MPI_Comm comm_cart;
int main(int argc, char *argv[])
{
int i, j;
int rank, size;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
/* code for mpi cartesian gird topology */
int dim[1];
dim[0] = 2;
int periods[1];
periods[0] = 0;
int reorder = 1;
int coords[1];
MPI_Cart_create(MPI_COMM_WORLD, 1, dim, periods, 1, &comm_cart);
MPI_Cart_coords(comm_cart, rank, 2, coords);
test(coords[0]);
MPI_Finalize();
return (0);
}
void test(int pos)
{
float placeholder[4];
int other = (pos+1) % 2;
MPI_Request reqs[8];
int flags[4];
for(int iter = 0; iter < 20; iter++){
// Test requests from previous time cycle
for(int i=0;i<4;i++){
if(iter == 0) break;
MPI_Test(&reqs[0], &flags[0] , MPI_STATUS_IGNORE);
printf("Flag: %d\n", flags[0]);
}
MPI_Irecv(&placeholder[0], 1, MPI_FLOAT, other, 0, comm_cart, &reqs[0]);
}
}
如有任何帮助,我们将不胜感激。
问题出在 MPI_Test
和 MPI_PROC_NULL
上。在使用 MPI_Cart_shift
时,你经常会得到 MPI_PROC_NULL
s,就好像你在网格的边缘,在某些方向上根本不存在相邻的单元格。
我在任何地方都找不到这方面的任何文档,所以我不得不自己发现它,但是当你用 MPI_PROC_NULL
源做一个 MPI_Irecv
时,它会立即完成并经过测试使用 MPI_Test
,对于已完成的请求,标志将为 return true。示例代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
MPI_Init(&argc, &argv);
int t;
int flag;
MPI_Request req;
MPI_Irecv(&t, 1, MPI_INT, MPI_PROC_NULL, 0, MPI_COMM_WORLD, &req);
MPI_Test(&req, &flag, MPI_STATUS_IGNORE);
printf("Flag: %d\n", flag);
MPI_Finalize();
return (0);
}
当运行时return如下:
Flag: 1
Flag: 1
我有一些出于测试目的的代码,我删除了所有发送,只有非阻塞接收。你可以想象我在使用 MPI_Test
时感到惊讶,这些标志表明一些请求实际上已经完成。我在笛卡尔网格中设置了我的代码,下面有一个小副本,尽管这不会重现错误:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // for sleep
#include <mpi.h>
void test(int pos);
MPI_Comm comm_cart;
int main(int argc, char *argv[])
{
int i, j;
int rank, size;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
/* code for mpi cartesian gird topology */
int dim[1];
dim[0] = 2;
int periods[1];
periods[0] = 0;
int reorder = 1;
int coords[1];
MPI_Cart_create(MPI_COMM_WORLD, 1, dim, periods, 1, &comm_cart);
MPI_Cart_coords(comm_cart, rank, 2, coords);
test(coords[0]);
MPI_Finalize();
return (0);
}
void test(int pos)
{
float placeholder[4];
int other = (pos+1) % 2;
MPI_Request reqs[8];
int flags[4];
for(int iter = 0; iter < 20; iter++){
// Test requests from previous time cycle
for(int i=0;i<4;i++){
if(iter == 0) break;
MPI_Test(&reqs[0], &flags[0] , MPI_STATUS_IGNORE);
printf("Flag: %d\n", flags[0]);
}
MPI_Irecv(&placeholder[0], 1, MPI_FLOAT, other, 0, comm_cart, &reqs[0]);
}
}
如有任何帮助,我们将不胜感激。
问题出在 MPI_Test
和 MPI_PROC_NULL
上。在使用 MPI_Cart_shift
时,你经常会得到 MPI_PROC_NULL
s,就好像你在网格的边缘,在某些方向上根本不存在相邻的单元格。
我在任何地方都找不到这方面的任何文档,所以我不得不自己发现它,但是当你用 MPI_PROC_NULL
源做一个 MPI_Irecv
时,它会立即完成并经过测试使用 MPI_Test
,对于已完成的请求,标志将为 return true。示例代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
MPI_Init(&argc, &argv);
int t;
int flag;
MPI_Request req;
MPI_Irecv(&t, 1, MPI_INT, MPI_PROC_NULL, 0, MPI_COMM_WORLD, &req);
MPI_Test(&req, &flag, MPI_STATUS_IGNORE);
printf("Flag: %d\n", flag);
MPI_Finalize();
return (0);
}
当运行时return如下:
Flag: 1
Flag: 1