MPI4PY:与neighbor_alltoallw进行环形通信

问题描述

请帮助!

我正在python中使用MPI(=消息传递接口)进行环形通信,这意味着每个等级都在相互发送和接收。我知道一种实现此目的的方法是使用例如MPI.COMM_WORLD.issend()MPI.COMM_WORLD.recv(),这是行之有效的。

现在,我想通过使用MPI.Topocomm.Neighbor_alltoallw以不同的方式实现相同的输出,但这不起作用。我写了一个C代码并在那儿工作,因此使用此函数可以达到相同的输出,但是当我在python中实现此功能时,它无法工作。请在下面找到C代码和Python代码

函数的定义说(Python的mpi4py包):

Neighbor_alltoallw(...) Topocomm.Neighbor_alltoallw(self,sendbuf,recvbuf)

Neighbor All-to-All Generalized

我不理解以下内容

  1. 为什么recbuf不是返回值?这里似乎是一个论点
  2. 如何在Python中实现环形通信?

感谢您的时间和支持

我的工作C代码


#include <stdio.h>
#include <mpi.h>

#define to_right 201
#define max_dims 1 


int main (int argc,char *argv[])
{
  int my_rank,size;
  int snd_buf,rcv_buf;
  int right,left;
  int sum,i;

  MPI_Comm    new_comm;
  int         dims[max_dims],periods[max_dims],reorder;

  MPI_Aint    snd_displs[2],rcv_displs[2];
  int         snd_counts[2],rcv_counts[2]; 
  MPI_Datatype snd_types[2],rcv_types[2]; 

  MPI_Status  status;
  MPI_Request request;


  MPI_Init(&argc,&argv);

  /* Get process info. */
  MPI_Comm_size(MPI_COMM_WORLD,&size);

  /* Set cartesian topology. */
  dims[0] = size;
  periods[0] = 1;
  reorder = 1;
 
  MPI_Cart_create(MPI_COMM_WORLD,max_dims,dims,periods,reorder,&new_comm);

  /* Get coords */
  MPI_Comm_rank(new_comm,&my_rank);
  /* MPI_Cart_coords(new_comm,my_rank,my_coords); */ 

  /* Get nearest neighbour rank. */
  MPI_Cart_shift(new_comm,1,&left,&right);

  /* Compute global sum. */
 
  sum = 0;
  snd_buf = my_rank;
  rcv_buf = -1000; /* unused value,should be overwritten by first MPI_Recv; only for test purpose */

  rcv_counts[0] = 1;  MPI_Get_address(&rcv_buf,&rcv_displs[0]); snd_types[0] = MPI_INT;
  rcv_counts[1] = 0;  rcv_displs[1] = 0 /*unused*/;              snd_types[1] = MPI_INT;
  snd_counts[0] = 0;  snd_displs[0] = 0 /*unused*/;              rcv_types[0] = MPI_INT;
  snd_counts[1] = 1;  MPI_Get_address(&snd_buf,&snd_displs[1]); rcv_types[1] = MPI_INT;

  for( i = 0; i < size; i++) 
  {
    /* Substituted by MPI_Neighbor_alltoallw() :
    MPI_Issend(&snd_buf,MPI_INT,right,to_right,new_comm,&request);
    MPI_Recv(&rcv_buf,left,&status);
    MPI_Wait(&request,&status);
    */    

    MPI_Neighbor_alltoallw(MPI_BottOM,snd_counts,snd_displs,snd_types,MPI_BottOM,rcv_counts,rcv_displs,rcv_types,new_comm);

    snd_buf = rcv_buf;
    sum += rcv_buf;
  }

  printf ("PE%i:\tSum = %i\n",sum);

  MPI_Finalize();
}

我无法正常工作的Python代码

from mpi4py import MPI

size = MPI.COMM_WORLD.Get_size()
my_rank = MPI.COMM_WORLD.Get_rank()
to_right =201
max_dims=1

dims = [max_dims]
periods=[max_dims]
dims[0]=size
periods[0]=1
reorder = True

new_comm=MPI.Intracomm.Create_cart(MPI.COMM_WORLD,True)
my_rank= new_comm.Get_rank()
left_right= MPI.Cartcomm.Shift(new_comm,1)

left=left_right[0]
right=left_right[1]

sum=0
snd_buf=my_rank
rcv_buf=-1000 #unused value,should be overwritten,only for test purpose

for counter in range(0,size):
    MPI.Topocomm.Neighbor_alltoallw(new_comm,snd_buf,rcv_buf)
    snd_buf=rcv_buf
    sum=sum+rcv_buf

print('PE ','sum=',sum)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)