结合MPI_Allgather和openmp并行

结合MPI_Allgather和openmp并行,mpi,openmp,Mpi,Openmp,我正在尝试在openmp线程中使用MPI_Allgather类型的功能。也就是说,所有线程都将共同拥有一个数据副本(但每个线程只生成其中的一部分) 事实上,通过在MPI_SEND和MPI_RECV的“tag”字段中使用线程id,openmp线程之间的通信是可能的。但MPI_Allgather似乎不是这样工作的 例子 我有2个MPI进程。每个进程有2个openmp线程。现在,这4个线程中的每一个都计算部分数据。我想使用MPI_Allgather,以便所有线程组合它们的数据并拥有组合数据的副本。但似

我正在尝试在openmp线程中使用MPI_Allgather类型的功能。也就是说,所有线程都将共同拥有一个数据副本(但每个线程只生成其中的一部分)

事实上,通过在MPI_SEND和MPI_RECV的“tag”字段中使用线程id,openmp线程之间的通信是可能的。但MPI_Allgather似乎不是这样工作的

例子 我有2个MPI进程。每个进程有2个openmp线程。现在,这4个线程中的每一个都计算部分数据。我想使用MPI_Allgather,以便所有线程组合它们的数据并拥有组合数据的副本。但似乎MPI_Allgather只在MPI进程的粒度中起作用

如果您能给我一些建议,我将不胜感激


谢谢

所有MPI通信调用都会寻址称为列组的实体。目前,所有MPI实现都遵循秩等于操作系统进程的解释,即不共享内存空间的实体。原则上,您可以通过制作消息标记来解决单个线程的问题是一种解决方法(或者说是一种黑客行为)——例如,尝试在没有无限循环和/或中央进程范围调度机制的情况下为多个线程实现类似的
MPI\u ANY\u标记

在MPI-3.0的早期阶段,有人建议将所谓的端点包括在内,这基本上是一种机制,允许将一组列组分配给进程内的一组线程。该提案没有通过投票机制,文本还需要进一步完善

也就是说,以下是一种可行的方法,可以实现您想要的功能,而无需使用pt2pt操作重新实现集合调用:

#pragma omp并行共享(gbuf)专用(buf,tid)
{
tid=omp_get_thread_num();
...
//将线程的数据收集到共享缓冲区“gbuf”中
//数据应该从gbuf开始[rank*num_threads*Data_per_thread]
memcpy(gbuf+(秩*num_线程+tid)*每个线程的数据,
buf,每个螺纹的数据(单位*尺寸);
//确保所有线程都已完成其块的复制
//然后从所有其他级别收集数据
#布拉格奥姆普屏障
#布拉格omp单曲
{
MPI\u所有聚集(MPI\u在\u位置,0,MPI\u类型\u NULL,
gbuf,num_threads*每个线程的数据,数据类型,comm);
}
...
}
它首先从每个线程的本地缓冲区
buf
将数据收集到全局接收缓冲区
gbuf
。在本例中,使用了一个简单的
memcpy
,但如果使用的是复杂的派生数据类型,则它可能更复杂。正确收集本地数据后,将使用就地
MPI\u Allgather
从其他流程收集碎片。
single
构造确保每个进程只有一个线程会执行gather-to-all调用


如果所有进程中的线程数不同,则应使用MPI\u Allgatherv。

我不理解您的问题。您是否正在尝试编写一个类似于
mpi\u allgather
的OpenMP程序(或例程),或了解
mpi\u allgather
的工作原理?我在一个程序中同时使用OpenMP和mpi。多个进程,每个进程有多个线程。现在,我尝试在所有这些进程/线程中应用MPI_Allgather。也就是说,在执行MPI_Allgather之后,每个进程中的每个线程都将有一个数据副本。但似乎MPI_Allgather并不是这样工作的。所以我正在寻找方法。顺便说一句,使用MPI_Send可以将数据从进程j的线程I发送到进程q的线程p。我建议您编辑您的问题,以便更清楚地解释您想要学习的内容。评论中的材料经常被忽视,这是正确的。是的,我相信这应该做到。必须有一个额外的步骤——在MPI_Allgather调用之后,我需要将数据从gbuf复制回本地线程缓冲区,以便每个线程都有自己的整个数据副本,并独立处理它。