我是否需要为 MPI::Isend 提供相应的 MPI::Irecv? [英] Do I need to have a corresponding MPI::Irecv for an MPI::Isend?

查看:75
本文介绍了我是否需要为 MPI::Isend 提供相应的 MPI::Irecv?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个看似愚蠢的问题,但我似乎无法以一种或另一种方式找到明确的答案.

A seemingly silly question but I can't seem to find a definitive answer one way or the other.

基本问题是我是否需要为 MPI::Isend 提供相应的 MPI::Irecv?

The basic questions is do I need to have a corresponding MPI::Irecv for an MPI::Isend?

也就是说,即使消息发送是非阻塞的,只要我在重用发送缓冲区之前等待发送完成,我是否需要使用非阻塞接收 &等待接收发送的缓冲区?

That is, even though the message sending is non-blocking, as long as I wait on the sends to complete before reusing the send buffers, do I need to use non-blocking receives & waits to receive the sent buffers?

我的观点是,我想在发送消息时使用非阻塞发送来做其他事情",但接收器进程将立即使用缓冲区,因此我希望它们阻塞,直到真正收到缓冲区为止.

My point is, I want to use non-blocking sends to "do other stuff" while the message is being sent but the receiver process will use the buffers immediately so I want them to block until the buffer is truly received.

似乎我应该能够接收带有 MPI::Recv 的消息,即使它们是通过 MPI::Isend 发送的,但我想知道我是否遗漏了什么?

It seems like I should be able to receive messages with MPI::Recv even though they were sent with MPI::Isend but I am wondering if I am missing something?

一些简单的伪代码

  if( rank == 0 ){
   int r;
   for ( int i = 0; i < n; i++ ){

     // DO SOME STUFF HERE...

     request.Wait(status);
     request2.Wait(status);
     request3.Wait(status);

     r = i;
     memcpy( key, fromKey(i), ...);
     memcpy( trace, fromTrace(i), ...);

     request  = MPI::COMM_WORLD.Isend( &r, 1, MPI::INT, node, tag );
     request2 = MPI::COMM_WORLD.Isend( key, 10, MPI::INT, node, tag );
     request3 = MPI::COMM_WORLD.Isend( trace, nBytesTotal, MPI::BYTE, node, tag );

     // DO SOME MORE STUFF HERE.

   }
   r = -1;
   request  = MPI::COMM_WORLD.Isend( &r, 1, MPI::INT, node, tag );

   // Carry on ...

  } else {

   int r = -1;
   MPI::COMM_WORLD.Recv( &r, 1, MPI::INT, 0, tag, status );
   while( r >= 0 ){

     MPI::COMM_WORLD.Recv( &key, 10, MPI::INT, 0, tag, status );
     memcpy( saveKey, key, ...);

     MPI::COMM_WORLD.Recv( &trace, nBytesTotal, MPI::BYTE, 0, tag, status );
     memcpy( saveTrace, trace, ...);

     MPI::COMM_WORLD.Recv( &r, 1, MPI::INT, 0, tag, status );
  }

推荐答案

不,您可以在通信两端自由混合阻塞和非阻塞 MPI 操作.阻塞与 MPI 调用何时将控制权返回给您的代码有关,而与正在传输的消息的内容无关.

No, you can freely mix blocking and non-blocking MPI operations on both ends of the communication. Blocking is related to when the MPI call returns control to your code and not to the content of the message(s) being transmitted.

每个 MPI 消息都带有一个带有自身的信封",其中包含其源、目的地、标签和通信者.要成功接收消息,您的接收操作应该只匹配其信封.信封绝不指定消息是如何发送的——它是通过阻塞,是通过非阻塞操作,是同步发送(MPI_Ssend)还是缓冲发送(MPI_Ssend)>MPI_Bsend).唯一的例外是所谓的就绪模式"发送,它由 MPI_Rsend()MPI_Irsend() 启动,它要求匹配的接收操作已经发布或消息将不会被传递.

Every MPI message carries an "envelope" with itself, that contains its source, destination, tag, and communicator. To successfully receive a message your receive operation should only match its envelope. The envelope in no way specifies how exactly was the message sent - was it via a blocking, was it via a non-blocking operation, was it a synchronous send (MPI_Ssend) or a buffered one (MPI_Bsend). The only exception is the so-called "ready mode" send that is initiated with MPI_Rsend() or MPI_Irsend() which requires that the matching receive operation has already been posted or the message will not be delivered.

这就是为什么在整个 MPI 标准中使用术语匹配接收操作"而不是对应的接收函数".

That's why the term "matching receive operation" is used throughout the MPI standard and not something like "corresponding receive function".

这篇关于我是否需要为 MPI::Isend 提供相应的 MPI::Irecv?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆