点对点通信
点对点通信可用于表达 rank 之间的任何通信模式。任何点对点通信都需要两个 MCCL 调用:一个 rank 上的 mcclSend() 调用和另一个 rank 上的相应 mcclRecv() 调用,两者具有相同的计数和数据类型。
除传统 Send/Recv 之外,MCCL 还提供了基于对称窗口的 RMA signal 系列接口:
这组接口更适合“写入对端窗口后通知对端”的单边同步模型,详细说明见 RMA Signal。
针对不同对等体的多个 mcclSend() 和 mcclRecv() 调用可以与 mcclGroupStart() 和 mcclGroupEnd() 结合使用,形成更复杂的通信模式,如一对一(散射)、多对一(收集)、多对多或与 N 维空间中的邻居通信 。
组内的点对点调用将阻塞,直到该组调用完成,但组内的调用可以被视为独立进行,因此永远不应相互阻塞。因此,合并需要同时进行的调用以避免死锁非常重要。
以下是一些并行应用程序使用的典型点对点通信模式的例子。MCCL 语义允许所有变体,每个 rank 具有不同的大小、数据类型和缓冲区。
发送接收
在 MPI 术语中,sendrecv 操作是指两个 rank 交换数据,同时发送和接收。这可以通过合并 mcclSend 和 mcclRecv 调用来实现:
mcclGroupStart();
mcclSend(sendbuff, sendcount, sendtype, peer, comm, stream);
mcclRecv(recvbuff, recvcount, recvtype, peer, comm, stream);
mcclGroupEnd();
一对一( 散射)
从 root rank 的一对一操作可以通过合并组中的所有发送和接收操作来表达:
mcclGroupStart();
if (rank == root) {
for (int r=0; r<nranks; r++)
mcclSend(sendbuff[r], size, type, r, comm, stream);
}
mcclRecv(recvbuff, size, type, root, comm, stream);
mcclGroupEnd();
多对一(收集)
类似地,向 root rank 的多对一操作将这样实现:
mcclGroupStart();
if (rank == root) {
for (int r=0; r<nranks; r++)
mcclRecv(recvbuff[r], size, type, r, comm, stream);
}
mcclSend(sendbuff, size, type, root, comm, stream);
mcclGroupEnd();
多对多
多对多操作将是合并的发送/接收操作循环,与所有对等体进行:
mcclGroupStart();
for (int r=0; r<nranks; r++) {
mcclSend(sendbuff[r], sendcount, sendtype, r, comm, stream);
mcclRecv(recvbuff[r], recvcount, recvtype, r, comm, stream);
}
mcclGroupEnd();
邻居交换
最后,在 N 维空间中与邻居交换数据可以这样做:
mcclGroupStart();
for (int d=0; d<ndims; d++) {
mcclSend(sendbuff[d], sendcount, sendtype, next[d], comm, stream);
mcclRecv(recvbuff[d], recvcount, recvtype, prev[d], comm, stream);
}
mcclGroupEnd();

