【问题标题】:mpi send and recv all processes to one anothermpi 相互发送和接收所有进程
【发布时间】:2021-09-27 23:22:54
【问题描述】:

我正在尝试在每个进程上都有一个数组的所有进程之间发送数据,例如

int local_data[] = {0*rank,1*rank,2*rank,3*rank};

我有一个相应的标志数组,其中该数组中的每个值都指向我应该发送该值的进程,例如:

int part[] = {0,1,3,2};

所以这意味着 local_data[0] 应该以等级 0 进行处理 local_data[2] 应该以等级 3 进行处理,依此类推。 标志 arr 中的值从一个进程更改为另一个进程(均在 0-P-1 范围内,其中 P 是可用进程的总数)。

使用这个,我目前正在做的是:

for(int i=0; i<local_len; i++){
        if(part[i] != rank){
            MPI_Send(&local_data[i], 1,MPI_INT, part[i], 0, MPI_COMM_WORLD);
            MPI_Recv(&temp,1, MPI_INT, rank, 0, MPI_COMM_WORLD, &status );
            recvbuf[j] = temp;
            j++;
        }
        else{
            recvbuf[j] = local_data[i];
            j++;
        }
    }

如果part[i] != rank,我只发送和接收数据,以避免从同一进程发送和接收

recvbuf 是我接收每个进程的值的数组。它可以比初始 local_data 长度更长。

我也试过

MPI_Sendrecv(&local_data[i], 1,MPI_INT, part[i], 0, &temp, 1, MPI_INT, rank, 0, MPI_COMM_WORLD, &status);

程序在两种情况下都卡住了

我该如何解决这个问题?

All-to-All 集体是通往这里的路吗?

【问题讨论】:

  • 一个给定的rank 发送到part[i] 但从rank 接收(例如它自己)所以这将挂起。请注意,您的模式假定每个等级恰好将一个元素发送到所有其他等级。根据通信的排序方式,无论如何它可能会陷入僵局。 MPI_Alltoallv() 看起来像去这里的路。

标签: c mpi


【解决方案1】:

您的基本问题是您的发送调用转到一个动态确定的目标,但是没有相应的逻辑来确定哪些进程需要进行接收,如果需要,从哪里接收。

如果你的应用逻辑暗示每个人都会发送给每个人,那么你可以使用MPI_Alltoall

如果每个人都向某些人发送消息,但您知道您将收到四条消息,那么您可以将发送消息的MPI_Isend 和来自ANY_SOURCEMPI_Recv 组合起来。请注意,您需要Isend,因为严格来说,您的代码会死锁。如果您的 MPI 对小消息有“急切模式”,它可能会起作用。

如果发送次数和目标完全是随机的,那么您需要像 MPI_Ibarrier 这样的东西来检测一切都结束了。

但我怀疑您在这里遗漏了主要信息。为什么local_data的长度是4? part 数组是排列吗?等等。

【讨论】:

  • 是的,您遗漏了一些信息是对的。所以 local_data 的长度是动态的(可以是任何长度),part 数组只是我用来“分区”的数组(part 的值从 0 到 P-1,其中 P 是进程数)这样的数据我可以将每个元素从local_data 发送到part 中的相应进程值。我能够使用 MPI_AlltoAllv 来解决这个问题
【解决方案2】:

按照@GillesGouaillardet 的建议,我使用了MPI_AlltoAllv

解决这个问题。

【讨论】:

    猜你喜欢
    • 2012-04-22
    • 2017-01-20
    • 2013-04-15
    • 2018-03-12
    • 2013-12-20
    • 2016-06-15
    • 2012-03-13
    • 1970-01-01
    • 2011-07-04
    相关资源
    最近更新 更多