gpt4 book ai didi

multithreading - MPI_Bcast 在 MPI 中使用线程 (OpenMP)

转载 作者:行者123 更新时间:2023-12-03 12:52:36 26 4
gpt4 key购买 nike

MPI 标准 3.0 在第 5.13 节中说

Finally, in multithreaded implementations, one can have more than one, concurrently executing, collective communication call at a process. In these situations, it is the user’s re- sponsibility to ensure that the same communicator is not used concurrently by two different collective communication calls at the same process.



我编写了以下程序,它不能正确执行(但可以编译)并转储一个核心
void main(int argc, char *argv[])
{
int required = MPI_THREAD_MULTIPLE, provided, rank, size, threadID, threadProcRank ;
MPI_Comm comm = MPI_COMM_WORLD ;

MPI_Init_thread(&argc, &argv, required, &provided);
MPI_Comm_size(comm, &size);
MPI_Comm_rank(comm, &rank);

int buffer1[10000] = {0} ;
int buffer2[10000] = {0} ;

#pragma omp parallel private(threadID,threadProcRank) shared(comm, buffer1)
{
threadID = omp_get_thread_num();
MPI_Comm_rank(comm, &threadProcRank);
printf("\nMy thread ID is %d and I am in process ranked %d", threadID, threadProcRank);

if(threadID == 0)
MPI_Bcast(buffer1, 10000, MPI_INTEGER, 0, comm);

If (threadID == 1)
MPI_Bcast(buffer1, 10000, MPI_INTEGER, 0, comm);
}

MPI_Finalize();
}

我的问题是:每个进程中具有线程 ID 0 和线程 ID 1 的两个线程发布一个广播调用,可以将其视为根进程(即进程 0)中的 MPI_Send()。我将其解释为两个 MPI_Send() 循环,其中目标是剩余进程。目标进程还在线程 ID 0 和线程 ID 1 中发布 MPI_Bcast()。这些可以视为两个线程中的每个进程发布的两个 MPI_Recv()。由于 MPI_Bcast() 是相同的 - 在接收进程 0(根)发送的消息时应该没有匹配问题。但是该程序仍然无法正常工作。为什么 ?是因为消息可能会在同一个通信器上的不同/相同集合中混淆吗?并且由于 MPI (mpich2) 看到了这种可能性,它只是不允许同一通信器上的两个集体同时挂起?

最佳答案

首先,您没有检查 provided 的值。其中 MPI 实现返回实际提供的线程支持级别。该标准允许此级别低于请求的级别,并且正确的 MPI 应用程序宁愿执行以下操作:

MPI_Init_thread(&argc, &argv, required, &provided);
if (provided < required)
{
printf("Error: MPI does not provide the required thread support\n");
MPI_Abort(MPI_COMM_WORLD, 1);
exit(1);
}

其次,这行代码是多余的:

MPI_Comm_rank(comm, &threadProcRank);

MPI 中的线程 不要有单独的等级 - 只有进程有等级。有人提议在 MPI 3.0 中引入所谓的端点,这将允许单个进程拥有多个等级并将它们绑定(bind)到不同的线程,但它没有进入标准的最终版本。

第三,您在两个集合中使用相同的缓冲区变量。我猜你的意图是使用 buffer1在线程 0 和 buffer2 的调用中在线程 1 的调用中。还有 MPI_INTEGER是对应于 INTEGER 的数据类型在 Fortran 中。对于 C int type 对应的 MPI 数据类型为 MPI_INT .

四、 MPI_BCAST的解释作为 MPI_SEND 的循环和相应的 MPI_RECV就是这样-一种解释。实际上,实现有很大不同 - 见 here .例如,对于初始网络设置延迟远高于物理数据传输时间的较小消息,使用二叉树和二叉树以最小化集体的延迟。较大的消息通常被分成许多段,然后使用管道将这些段从根秩传递到所有其他段。即使在树分布情况下,消息仍然可以被分段。

问题在于,实际上每个集合操作都是使用具有相同标签的消息来实现的,通常带有负标签值(应用程序程序员不允许使用这些值)。这意味着 MPI_Bcast在您的情况下,调用将使用相同的标签来传输它们的消息,并且由于等级相同并且通信器相同,因此消息会全部混淆。因此,仅在单独的通信器上进行并发集合的要求。

您的程序崩溃有两个原因。原因一是MPI库不提供 MPI_THREAD_MULTIPLE .第二个原因是如果消息被分成两个大小不均匀的 block ,例如较大的第一部分和较小的第二部分。两个集体调用之间的干扰可能导致第二个线程在等待第二个较小的 block 时接收指向第一个线程的大的第一个 block 。结果将是消息截断,并且将调用中止 MPI 错误处理程序。这通常不会导致段错误和核心转储,所以我认为您的 MPICH2 根本没有被编译为线程安全的。

这不是 MPICH2 特定的。 Open MPI 和其他实现也容易受到同样的限制。

关于multithreading - MPI_Bcast 在 MPI 中使用线程 (OpenMP),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17633942/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com