gpt4 book ai didi

multithreading - 在混合 MPI/OpenMP 中进行 MPI 调用的线程

转载 作者:行者123 更新时间:2023-12-01 10:37:00 26 4
gpt4 key购买 nike

我在复制的混合 MPI/OpenMP 代码中发现了一个问题在下面引用的代码中以最简单的形式。我正在使用 2 个线程每个 MPI 等级。然后将这两个线程用于 OpenMP“部分”要进行多项计算,其中一项包括对两个不同的向量 A 和 B 进行“mpi_allreduce”调用,其结果存储在 W 和 WW 中。问题是每次我运行程序我最终得到了不同的输出。我的想法是 MPI 调用是重叠和减少的阵列 W 和 WW 组合,即使它们有不同的名字,但我不确定。关于如何克服的任何评论欢迎这个问题。

详细信息:MPI线程级别在代码中初始化为MPI_THREAD_MULTIPLE但我也尝试过串行和漏斗(同样的问题)。

我编译代码 mpiifort -openmp allreduce_omp_mpi.f90 和运行我使用:

导出 OMP_NUM_THREADS=2mpirun -np 3 ./a.out

      PROGRAM HELLO
use mpi
use omp_lib
IMPLICIT NONE

INTEGER nthreads, tid

Integer Provided,mpi_err,myid,nproc
CHARACTER(MPI_MAX_PROCESSOR_NAME):: hostname
INTEGER :: nhostchars

integer :: i
real*8 :: A(1000), B(1000), W(1000),WW(1000)

provided=0
!Initialize MPI context
call mpi_init_thread(MPI_THREAD_MULTIPLE,provided,mpi_err)
CALL mpi_comm_rank(mpi_comm_world,myid,mpi_err)
CALL mpi_comm_size(mpi_comm_world,nproc,mpi_err)
CALL mpi_get_processor_name(hostname,nhostchars,mpi_err)

!Initialize arrays
A=1.0
B=2.0
!Check if MPI_THREAD_MULTIPLE is available
if (provided >= MPI_THREAD_MULTIPLE) then
write(6,*) ' mpi_thread_multiple provided',myid
else
write(6,*) ' not mpi_thread_multiple provided',myid
endif

!$OMP PARALLEL PRIVATE(nthreads, tid) NUM_THREADS(2)
!$omp sections
!$omp section
call mpi_allreduce(A,W,1000,mpi_double_precision,mpi_sum,mpi_comm_world,mpi_err)
!$omp section
call mpi_allreduce(B,WW,1000,mpi_double_precision,mpi_sum,mpi_comm_world,mpi_err)
!$omp end sections
!$OMP END PARALLEL

write(6,*) 'W',(w(i),i=1,10)
write(6,*) 'WW',(ww(i),i=1,10)

CALL mpi_finalize(mpi_err)
END

最佳答案

MPI standard禁止在同一通信器上并发执行(阻塞)集体操作(第 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 responsibility to ensure that the same communicator is not used concurrently by two different collective communication calls at the same process.

这里的关键点是:相同的通信器。没有什么能阻止您通过不同的通信器开始并发集体通信:

integer, dimension(2) :: comms

call MPI_COMM_DUP(MPI_COMM_WORLD, comms(1), ierr)
call MPI_COMM_DUP(MPI_COMM_WORLD, comms(2), ierr)

!$omp parallel sections num_threads(2)
!$omp section
call MPI_ALLREDUCE(A, W, 1000, MPI_REAL8, MPI_SUM, comms(1), ierr)
!$omp section
call MPI_ALLREDUCE(B, WW, 1000, MPI_REAL8, MPI_SUM, comms(2), ierr)
!$omp end parallel sections

call MPI_COMM_FREE(comms(1), ierr)
call MPI_COMM_FREE(comms(2), ierr)

这个程序简单地复制了 MPI_COMM_WORLD 两次。第一个副本用于第一个并行部分,第二个副本用于第二个并行部分。虽然这两个新的通信器是 MPI_COMM_WORLD 的副本,但它们是独立的上下文,因此可以对它们进行并发操作。

MPI_COMM_DUP 是一项开销很大的操作,因此新创建的通信器在被释放之前应尽可能长时间地使用。

关于multithreading - 在混合 MPI/OpenMP 中进行 MPI 调用的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33586549/

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