在其他通信器中收到的MPI消息 [英] MPI message received in different communicator

查看:91
本文介绍了在其他通信器中收到的MPI消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我了解,MPI传播者会限制传播范围,例如 从一个通信器发送的消息永远不会在另一通信器中接收.

It was my understanding that MPI communicators restrict the scope of communication, such that messages sent from one communicator should never be received in a different one.

但是,下面内联的程序似乎与此矛盾.

However, the program inlined below appears to contradict this.

我知道MPI_Send调用在发布匹配的接收之前返回,因为它在内部进行了内部缓冲(与MPI_Ssend相反).我还了解到MPI_Comm_free不会立即销毁通信器,而只是将其标记为可释放,并等待任何未完成的操作完成.我想我无与伦比的send操作将永远挂起,但是然后我想知道为什么相同的对象(整数值)会被第二个通信器重用!?

I understand that the MPI_Send call returns before a matching receive is posted because of the internal buffering it does under the hood (as opposed to MPI_Ssend). I also understand that MPI_Comm_free doesn't destroy the communicator right away, but merely marks it for deallocation and waits for any pending operations to finish. I suppose that my unmatched send operation will be forever pending, but then I wonder how come the same object (integer value) is reused for the second communicator!?

这是正常行为,还是MPI库实现中的错误,还是我的程序不正确?

Is this normal behaviour, a bug in the MPI library implementation, or is it that my program is just incorrect?

任何建议都将不胜感激!

Any suggestions are much appreciated!

#include "stdio.h"
#include "unistd.h"
#include "mpi.h"

int main(int argc, char* argv[]) {
    int  rank, size;
    MPI_Group group;
    MPI_Comm my_comm;

    MPI_Init(&argc, &argv);

    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_group(MPI_COMM_WORLD, &group);

    MPI_Comm_create(MPI_COMM_WORLD, group, &my_comm);
    if (rank == 0) printf("created communicator %d\n", my_comm);

    if (rank == 1) {
        int msg = 123;
        MPI_Send(&msg, 1, MPI_INT, 0, 0, my_comm);
        printf("rank 1: message sent\n");
    }

    sleep(1);
    if (rank == 0) printf("freeing communicator %d\n", my_comm);
    MPI_Comm_free(&my_comm);

    sleep(2);

    MPI_Comm_create(MPI_COMM_WORLD, group, &my_comm);
    if (rank == 0) printf("created communicator %d\n", my_comm);

    if (rank == 0) {
        int msg;
        MPI_Recv(&msg, 1, MPI_INT, 1, 0, my_comm, MPI_STATUS_IGNORE);
        printf("rank 0: message received\n");
    }

    sleep(1);
    if (rank == 0) printf("freeing communicator %d\n", my_comm);
    MPI_Comm_free(&my_comm);

    MPI_Finalize();
    return 0;
}

输出:

created communicator -2080374784
rank 1: message sent
freeing communicator -2080374784
created communicator -2080374784
rank 0: message received
freeing communicator -2080374784

推荐答案

您看到的数字只是通信程序的句柄.自从释放手柄以来,重用它是安全的.至于为什么能够发送消息,请查看如何创建通信器.使用MPI_Comm_group时,将得到一个包含与指定的传播者相关联的等级的组.在这种情况下,您将获得所有排名,因为您将获得MPI_COMM_WORLD的组.然后,您正在使用MPI_Comm_create基于一组等级创建一个通信器.您使用的是刚刚得到的同一组,其中包含所有等级.因此,您的新沟通者具有MPI_COMM_WORLD的所有职位.如果您希望沟通者仅包含等级的子集,则需要使用其他功能(或多个功能)来组成所需的组.我建议您通读MPI标准的第6章,其中包括您需要的所有功能.选择构建所需的通信器所需的东西.

The number you're seeing is simply a handle for the communicator. It's safe to reuse the handle since you've freed it. As to why you're able to send the message, look at how you're creating the communicator. When you use MPI_Comm_group, you're getting a group containing the ranks associated with the specified communicator. In this case, you get all of the ranks, since you are getting the group for MPI_COMM_WORLD. Then, you are using MPI_Comm_create to create a communicator based on a group of ranks. You are using the same group you just got, which will contain all of the ranks. So your new communicator has all of the ranks from MPI_COMM_WORLD. If you want your communicator to only contain a subset of ranks, you'll need to use a different function (or multiple functions) to make the desired group(s). I'd recommend reading through Chapter 6 of the MPI Standard, it includes all of the functions you'll need. Pick what you need to build the communicator you want.

这篇关于在其他通信器中收到的MPI消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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