MPI 中套接字编程的 select() 是什么?
What is equivalent of socket programming's select() in MPI?
在套接字编程中,我们有select()函数可以让我们同时检查多个套接字。我想知道 MPI 库中是否也有这样的功能?
在以下代码的第一个 for 循环中,我将多个非阻塞发送和接收请求从一个节点发送到每个其他节点。在第二个 for 循环中,我不想按顺序等待每个节点,而是想开始处理首先发送其数据的节点的数据。我想知道有什么办法吗?
for(id=0; id<numtasks; id++){
if(id == taskid) continue;
if(sendCount[id] != 0) MPI_Isend(sendBuffer[id], N*sendCount[id], MPI_DOUBLE, id, tag, MPI_COMM_WORLD, &reqs[id]);
if(recvCount[id] != 0) MPI_Irecv(recvBuffer[id], N*recvCount[id], MPI_DOUBLE, id, tag, MPI_COMM_WORLD, &reqs[id]);
}
for(id=0; id<numtasks; id++){
if(id == taskid) continue;
if(recvCount[id] != 0){
MPI_Wait(&reqs[id], &status);
for(i=0; i<recvCount[id]; i++)
splitData(N, recvBuffer[id] + N*i, U[toRecv[id][i]]);
}
}
根据给定的答案,我尝试修改我的代码,但在 运行 时间内我仍然遇到分段错误。请帮我找出错误。
for(id=0; id<numtasks; id++){
if(id == taskid) continue;
if(sendCount[id] != 0) MPI_Isend(sendBuffer[id], N*sendCount[id], MPI_DOUBLE, id, tag, MPI_COMM_WORLD, &reqs[id]);
if(recvCount[id] != 0) MPI_Irecv(recvBuffer[id], N*recvCount[id], MPI_DOUBLE, id, tag, MPI_COMM_WORLD, &reqs[id]);
}
reqs[taskid] = reqs[numtasks-1];
for(i=0; i<numtasks-1; i++){
MPI_Waitany(numtasks-1, reqs, &id, &status);
if(id == taskid) id = numtasks-1;
for(i=0; i<recvCount[id]; i++)
splitData(N, recvBuffer[id] + N*i, U[toRecv[id][i]]);
}
最接近的等效项是 MPI_Waitsome
,您提供一个请求列表,它会在至少一个请求完成后立即 returns。但是,没有像 select
中那样的超时。还有MPI_Waitany
、MPI_Waitall
以及MPI_Testany
、MPI_Testall
、MPI_Testsome
。
any
和 some
变体的主要区别在于界面通知您一个或多个已完成请求的方式。
编辑:您需要为每个操作使用单独的请求,特别是发送和接收操作。
在套接字编程中,我们有select()函数可以让我们同时检查多个套接字。我想知道 MPI 库中是否也有这样的功能?
在以下代码的第一个 for 循环中,我将多个非阻塞发送和接收请求从一个节点发送到每个其他节点。在第二个 for 循环中,我不想按顺序等待每个节点,而是想开始处理首先发送其数据的节点的数据。我想知道有什么办法吗?
for(id=0; id<numtasks; id++){
if(id == taskid) continue;
if(sendCount[id] != 0) MPI_Isend(sendBuffer[id], N*sendCount[id], MPI_DOUBLE, id, tag, MPI_COMM_WORLD, &reqs[id]);
if(recvCount[id] != 0) MPI_Irecv(recvBuffer[id], N*recvCount[id], MPI_DOUBLE, id, tag, MPI_COMM_WORLD, &reqs[id]);
}
for(id=0; id<numtasks; id++){
if(id == taskid) continue;
if(recvCount[id] != 0){
MPI_Wait(&reqs[id], &status);
for(i=0; i<recvCount[id]; i++)
splitData(N, recvBuffer[id] + N*i, U[toRecv[id][i]]);
}
}
根据给定的答案,我尝试修改我的代码,但在 运行 时间内我仍然遇到分段错误。请帮我找出错误。
for(id=0; id<numtasks; id++){
if(id == taskid) continue;
if(sendCount[id] != 0) MPI_Isend(sendBuffer[id], N*sendCount[id], MPI_DOUBLE, id, tag, MPI_COMM_WORLD, &reqs[id]);
if(recvCount[id] != 0) MPI_Irecv(recvBuffer[id], N*recvCount[id], MPI_DOUBLE, id, tag, MPI_COMM_WORLD, &reqs[id]);
}
reqs[taskid] = reqs[numtasks-1];
for(i=0; i<numtasks-1; i++){
MPI_Waitany(numtasks-1, reqs, &id, &status);
if(id == taskid) id = numtasks-1;
for(i=0; i<recvCount[id]; i++)
splitData(N, recvBuffer[id] + N*i, U[toRecv[id][i]]);
}
最接近的等效项是 MPI_Waitsome
,您提供一个请求列表,它会在至少一个请求完成后立即 returns。但是,没有像 select
中那样的超时。还有MPI_Waitany
、MPI_Waitall
以及MPI_Testany
、MPI_Testall
、MPI_Testsome
。
any
和 some
变体的主要区别在于界面通知您一个或多个已完成请求的方式。
编辑:您需要为每个操作使用单独的请求,特别是发送和接收操作。