我无法将MPI_Isend发送到随机目的地。如果我硬编码目的地,它工作正常,但如果我尝试生成一个随机的,它不会。以下是一些相关代码:
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
srand48(myid);
request=MPI_REQUEST_NULL;
if(myid == 0){
buffer=drand48();
do {
destination=lrand48() % numprocs;
} while (destination == 0); //Prevent sending to self
MPI_Isend(&buffer,1,MPI_DOUBLE,destination,1234,MPI_COMM_WORLD,&request);
}
else if (myid == destination) {
MPI_Irecv(&buffer,1,MPI_DOUBLE,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&request);
}
if(myid == 0){
printf("processor %d sent %lf to %d\n",myid,buffer,destination);
}
else {
printf("processor %d got %lf\n",myid,buffer);
}
我可以使用mpicc main.c
编译得很好当我使用mpirun -np 4 ./a.out
运行程序时输出为:
processor 0 sent 0.170828 to 2
processor 1 got 0.000000
processor 2 got 0.000000
processor 3 got 0.000000
例如,如果我将目标硬编码为2,那么我得到预期的输出:
processor 0 sent 0.170828
processor 1 got 0.000000
processor 2 got 0.170828
processor 3 got 0.000000
答案 0 :(得分:1)
MPI_Isend
和MPI_Irecv
启动相应的非阻止操作。在将返回的request
句柄传递给MPI_Wait
或MPI_Test
族的函数之前,无法保证它们完成(如果使用了测试函数,则完成状态为请求在布尔变量中传回,只要布尔标志保持为假,它就不完整。
但是您的代码存在概念性问题。 MPI是一种分布式内存范例 - 每个MPI级别实际上都位于其独立的地址空间中(虽然标准并非严格要求,但这几乎是所有MPI实现提供的)。因此,在等级0中设置destination
不会将其值神奇地转移到其他进程。您可以先广播该值,也可以向所有其他等级发送特殊的“空”消息,例如:
if (myid == 0) {
MPI_Request reqs[numprocs];
buffer=drand48();
do {
destination=lrand48() % numprocs;
} while (destination == 0); //Prevent sending to self
for (i = 1; i < numprocs; i++) {
if (i == destination)
MPI_Isend(&buffer,1,MPI_DOUBLE,i,1234,MPI_COMM_WORLD,&reqs[i]);
else
// Send an empty message with different tag
MPI_Isend(&buffer,0,MPI_DOUBLE,i,4321,MPI_COMM_WORLD,&reqs[i]);
}
reqs[0] = MPI_REQUEST_NULL;
MPI_Waitall(numprocs, reqs, MPI_STATUSES_IGNORE);
printf("processor %d sent %lf to %d\n",myid,buffer,destination);
}
else {
MPI_Status status;
MPI_Recv(&buffer,1,MPI_DOUBLE,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
if (status.MPI_TAG == 1234)
printf("processor %d got %lf\n",myid,buffer);
}
通过广播,代码看起来像:
request=MPI_REQUEST_NULL;
if (myid == 0) {
buffer=drand48();
do {
destination=lrand48() % numprocs;
} while (destination == 0); //Prevent sending to self
MPI_Bcast(&destination,1,MPI_INT,0,MPI_COMM_WORLD);
MPI_Isend(&buffer,1,MPI_DOUBLE,destination,1234,MPI_COMM_WORLD,&request);
}
else {
MPI_Bcast(&destination,1,MPI_INT,0,MPI_COMM_WORLD);
if (myid == destination) {
MPI_Irecv(&buffer,1,MPI_DOUBLE,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&request);
}
}
MPI_Wait(&request, MPI_STATUS_IGNORE);
if (myid == 0) {
printf("processor %d sent %lf to %d\n",myid,buffer,destination);
}
else {
printf("processor %d got %lf\n",myid,buffer);
}