【问题标题】:Using Fortran90 and MPI, new to both, trying to use MPI_Gather to collect from a loop 3 different variables in each process使用 Fortran90 和 MPI,两者都是新手,尝试使用 MPI_Gather 从循环中收集每个进程中的 3 个不同变量
【发布时间】:2016-04-28 13:12:57
【问题描述】:

我是 Fortran90 和 MPI 的新手。我有一个循环,它根据每个单独的过程进行不同的迭代。在其中,我有一个嵌套循环,正是在这里我进行了我想要的计算以及各个循环的元素。但是,我想将所有这些数据、x、y 以及使用 x 和 y 计算的值发送到我的根进程 0。从这里,我想将所有数据写入“xy 计算”的格式。

program fortranMPI
use mpi

!GLOBAL VARIABLE DECLARATION
real :: step = 0.5, x, y, comput
integer :: count = 0, finalCount = 5, outFile = 20, i   
!MPI 
integer :: ierr, myrank, mysize, status(MPI_STATUS_SIZE)

call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD,myrank,ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD,mysize,ierr)

if(myrank == 0) then
    !I want to gather my data here?
end if

do i = 1, mysize, 1
    if(myrank == i) then
        x = -2. + (myrank - 1.)*step
        do while (x<= 2.) 
            y= -2.
            do while (y<=2.)
                !Here is where I am trying to send my data!
                y = y + step
            end do
            x = x + (mysize-1)*(step)
        end do
    end if
end do
call MPI_FINALIZE(ierr)
end program fortranMPI

我一直在尝试传递数据时遇到问题!如果有人可以帮助我,那就太好了!抱歉,如果这比我做的简单,我仍在尝试找出 Fortran/MPI。提前致谢!

【问题讨论】:

  • 如我所见,带有i 索引的循环是没用的。此外,根进程不进行任何计算。所以if(myrank == i) then应该变成if(myrank /= 0) then。由于在计算之前没有进程收到任何数据,因此您应该在计算之后收集数据。 MPI_gather 将成为您的朋友。使用此评论进行改进,如果您需要进一步的帮助,请回复评论。
  • @innoSPG 感谢您的帮助。对带有 i 索引的循环有意义,应该看到这一点。我尝试使用 MPI_Gather:if(myrank == 0) then call MPI_GATHER(x, 1, MPI_REAL, xbuf, 1, MPI_REAL, 0, MPI_COMM_WORLD, ierr) open (unit=outFile,file="mandelbrotDynamic.txt",action="write",status="replace") write(outFile,*) xbuf close(outFile) end if 但是,这只是卡住并且永远不会完成。我只是想通过收集 1 x 值来测试它,但由于我是 MPI 和 Fortran 的新手,我可能做错了。任何帮助都会很棒!谢谢!
  • MPI_GATHER 是一个集体操作,所以通信器中的所有进程都必须调用它。而master会接收到所有进程的数据。

标签: math fortran mpi fortran90 computation


【解决方案1】:

首先,该程序似乎对其所做的事情没有任何意义。如果您可以更具体地说明您想做什么,我可以提供进一步的帮助。

现在,通常,在计算之前,这个if (myrank==0) 语句是您发送其余流程数据的地方。由于进程 0 将发送数据,因此您必须在此之后立即添加代码,以便进程接收数据。此外,您可能需要在计算开始之前添加 MPI_BARRIER (call MPI_BARRIER),以确保数据已到达每个流程。

至于计算部分,您还必须决定,不仅要在哪里发送数据,还要决定从哪里接收数据,以及是否还需要在通信上进行任何同步。这与您的程序设计有关,因此您是知道自己到底想做什么的人。

发送和接收数据最常用的命令是MPI_SENDMPI_RECV

那些是阻塞命令,这意味着通信应该是同步的。一个发送命令应该与一个接收命令匹配,然后两个进程才能继续。 还有非阻塞命令,你可以在这里找到它们: http://www.mpich.org/static/docs/v3.1/www3/

至于MPI_GATHER 命令,它用于从一组进程中收集数据。只有当您要使用超过 2 个进程来进一步加速您的程序时,这才会对您有所帮助。除了 MPI_GATHER 用于您想要收集数据并以数组方式存储它们时,当然只有当您要接收大量数据时才值得使用,这绝对不是您的情况。

最后关于打印结果,我不确定您的要求是否可行。尝试使用 2 个进程打开相同的文件句柄可能会导致操作系统错误。通常为了打印结果,你有 0 级来执行此操作,就在其他所有过程完成之后。

【讨论】:

  • 感谢您的想法。本质上,我正在尝试创建一个 Mandelbrot 错误,其中进程 0 收集坐标(x 和 y),使用函数来计算 Mandelbrot 数,然后将 x、y 和计数传递给进程 0 以写入文件。 if(myrank == 0) then ! Recieves x, y, mandel count end if do i = 1, mysize, 1 if(myrank == i) then x = -2. + (myrank - 1.)*step do while (x&lt;= 2.) y= -2. do while (y&lt;=2.) ! Sends x,y, mandel count to 0 y = y + step end do x = x + (mysize-1)*(step) end do end if end do call MPI_FINALIZE(ierr)
  • 这个答案更像是评论。当您需要澄清以理解问题时,请发表评论,否则您将获得很多对您不利的负面声誉,因为您现在还不够。
  • 我想到了这一点,但这将是一个相当大的评论,这就是为什么我决定将其发布为答案。事实上,我认为它回答了@jep9223 几个问题,关于如何发送数据以及如何编写输出。至于代表,我对他们一点都不关心,我只是想帮助人们。
  • @jep9223 如果我理解正确,proc 1 会进行实际计算,proc 0 只是简单地写入输出。如果是这种情况,您甚至不必发送输入数据。您只需在每次计算后立即发送/接收曼德尔计数。我建议您为每个进程使用单独的 if 块,然后协调发送和接收,以便 proc 0 获得计算结果。 Proc 的 0 循环应该只接收数据并写入输出。 Proc 的 1 循环应该进行计算并立即发送结果。
  • @GregK。谢谢你的建议。我能够使用 send 和 recv 将所有数据收集到 proc 0。谢谢!
猜你喜欢
  • 2016-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-21
  • 2013-10-22
  • 2021-09-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多