8

我发现了一个名为 MPI_COMM_SELF 的 MPI 通信器。问题是,我不知道,它什么时候有用。在我看来,只是每个进程都“认为”自己是根。

你能解释一下它MPI_COMM_SELF到底是如何工作的,在什么情况下它有用吗?

我找到了这个幻灯片,但那里只是简单地提到了通讯器。


我已经尝试过这个“Hello, world”示例,所有进程都返回 0 作为它们的 PID。

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

int main() {
    MPI_Init(NULL, NULL);

    int world_rank;
    MPI_Comm_rank(MPI_COMM_SELF, &world_rank);

    printf("Hello, my PID is %d!\n",
            world_rank);

    MPI_Finalize();
    return 0;
}
4

2 回答 2

4

MPI 通信器是两条信息:进程集合和该集合的上下文。默认的通信器是 MPI_COMM_WORLD - 每个进程 - 和 MPI_COMM_SELF - 只有一个进程。

你可以让更多的沟通者与所有、一个或一些进程。

为什么上下文很重要?想想图书馆。使用 MPI 的库可能会与该库的客户端发生冲突,除非库会复制通信器,从而创建一个库可以通信的上下文,而无需担心客户端在做什么。

MPI_COMM_SELF 是单个进程。如果调用集体例程,则通信器中的所有进程都必须参与。

MPI_COMM_SELF 对于 MPI-IO 例程特别有用,但前提是您想要“每个进程的文件”。如果您要与多个 MPI 进程共享文件(并且您可能应该这样做),请使用包含这些 MPI 进程的通信器。

于 2015-05-28T20:14:45.260 回答
3

除了 IO 相关的使用外MPI_COMM_SELF,MPI 标准中还描述了两个。

一种特殊用途MPI_COMM_SELF是在 MPI 库的最终确定期间调用用户函数,这与 C 中的机制非常相似atexit()。事实上,atexit()在 MPI 程序中不能可靠地使用该机制,因为 MPI 实现不需要从MPI_Finalize()except in rank 0,因此需要另一种机制(此外,Fortran 没有等效的atexit()完全)。幸运的是,MPI 提供了一种缓存机制,允许将任意属性与某些 MPI 对象(即通信器、窗口和数据类型)进行可移植关联,这主要在编写可移植库时很有用。每个属性都有一组复制和删除回调,每次发生特定事件时都会调用这些回调,例如,当一个属性由于通信器的复制而被复制时。该标准不保证所有 MPI 对象在期间被销毁的顺序,MPI_Finalize()但它保证这MPI_COMM_SELF是第一个被销毁的对象。因此,将带有删除回调的属性附加到MPI_COMM_SELF将在调用后立即触发回调MPI_Finalize()

另一个用途MPI_COMM_SELF是与 MPI 的客户端/服务器机制一起使用。如果您有 MPI 作业并希望其中一个队列从单独的 MPI 作业接收客户端连接,则必须使用MPI_COMM_SELFsinceMPI_Comm_accept()是集体调用。

于 2015-05-29T11:36:27.880 回答