Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 在MPI-Fortran中将数组缩减为数组_Arrays_Parallel Processing_Fortran_Mpi - Fatal编程技术网

Arrays 在MPI-Fortran中将数组缩减为数组

Arrays 在MPI-Fortran中将数组缩减为数组,arrays,parallel-processing,fortran,mpi,Arrays,Parallel Processing,Fortran,Mpi,我对Fortran中的MPI有些陌生。我有一个MPI代码,每个处理器都进行Ns模拟。所以在最后我应该有(mysize x Ns x 2)结果,因为我为每个模拟和每个过程创建了一个称为PHI的二维数组和一个对应于将每个PHI值平方的第二个数组PHI^2 然后,在Ns中进行所有模拟之后,我为每个过程生成一个基本上是总和(PHI)/Ns的PHI_AVG_秩数组和PHI^2的PHI^2 AVG_秩,类似地 我想通过一个归约和将来自每个处理器的所有结果矩阵PHI_AVG_秩(mysize矩阵的总数)发送到

我对Fortran中的MPI有些陌生。我有一个MPI代码,每个处理器都进行Ns模拟。所以在最后我应该有(mysize x Ns x 2)结果,因为我为每个模拟和每个过程创建了一个称为PHI的二维数组和一个对应于将每个PHI值平方的第二个数组PHI^2

然后,在Ns中进行所有模拟之后,我为每个过程生成一个基本上是总和(PHI)/Ns的PHI_AVG_秩数组和PHI^2的PHI^2 AVG_秩,类似地

我想通过一个归约和将来自每个处理器的所有结果矩阵PHI_AVG_秩(mysize矩阵的总数)发送到一个主处理器,然后对PHI_AVG_秩和PHI**2_AVG_秩再次进行平均。这样做的原因是我想计算所有(mysize x Ns)实现的RMS矩阵,即sqrt(SUM(PHI^2_AVG_秩)/mysize-(SUM(PHI_AVG_秩)/mysize)^2),然后将其保存到txt

为此,可以使用哪种数据类型?连续、矢量或子阵列?这是最好的电话吗

这是我到目前为止的计划(一段代码在完成所有Ns模拟之后,我为每个处理器提出了一个名为phi_moyen_1_2的100x100矩阵,并希望将其相加到名为mean_2_025的新矩阵100x100中,然后保存它:

    call MPI_BARRIER(MPI_COMM_WORLD,ierr)
    call MPI_TYPE_CONTIGUOUS(100,MPI_REAL,row,ierr)
    call MPI_TYPE_CONTIGUOUS(100,row,matrix,ierr)
    if (myrank==0) then
        call MPI_REDUCE(phi_moyen1_2,mean_2_025,1,matrix,MPI_SUM,0,MPI_COMM_WORLD,ierr)
        open(unit=1234, file='../results/PHI1/TESTE/teste.txt')
            do i=0,Nx-1
                write(ligne, *) mean_2_025(i,:)
                write(1234,'(a)') trim(ligne)
            end do
        close(unit=1234)
    endif
编辑:在实现@David Henty的建议后,我们不需要使用连续数据类型。实际上,我们可以直接使用任何中间数据类型和COMMIT子句,因为Fortran已经访问了每个数组元素。然后我做了以下工作:

if (myrank==0) then
        call MPI_REDUCE(phi_moyen1_2,mean_2_025,100*100,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD,ierr)
        mean_2_025=mean_2_025/(mysize)
        write(*,*) mean_2_025(1,1)
但是程序没有结束(好像它正在经历一个无限循环),也没有将任何内容打印到输出文件中(由于上面的写操作,它应该显示矩阵mean_2_025的第一个条目的nprocs编号).我在程序结束时做了一些cpu时间,它显示了NPROC的cpu时间,所以这意味着每个处理器都能通过,直到程序结束

编辑,解决:正如@Vladimir F所指出的,集合调用REDUCE由所有处理器进行(即使它在调用中有一个根处理器)。因此它不能在if子句中,从而导致无限循环(其他处理器无法访问REDUCE)


感谢大家。

您需要做的就是将类型指定为MPI_REAL,计数指定为100*100。对于reduce,对数组的每个元素分别进行reduce,因此这将完全满足您的需要,即对于i和j的所有100*100值,在秩0上,平均值_2_025(i,j)将是phi_moyen1_2(i,j)所有秩的总和

要得到平均值,只需除以大小。从技术上讲,您不需要屏障,因为MPI可以在集合中完成您需要的所有同步


在这里使用数据类型会使事情变得过于复杂。您需要首先提交它们,但更重要的是,简化操作不知道如何处理“matrix”类型的数据除非你通过定义和注册你自己的缩减操作来告诉它该做什么。

很多事情需要澄清。请展示你的代码,这比用文字描述事情并试图解释你的意思要好得多。请看。@VladimirF代码很长,但我已经用相关部分更新了问题,即缩减部分谢谢,我不知道。我已经实现了,代码应该在几秒钟内运行,但现在它永远不会像在无限循环中一样结束。我已经完成了以下操作:如果(myrank==0),那么调用MPI_REDUCE(phi_moyen1_2,mean_2_025100*100,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD,ierr)mean_2_025=mean_025/(mysize)写(,)平均值_2_025(1,1)但是is不会将任何内容打印到输出文件中。我在REDUCE调用之前和之后进行了一些写调用,它们显示每个处理器都进行了调用,但显然什么也没做。您使用REDUCE是错误的。通信器中的所有列组都必须调用它。研究集合操作。如果myrank==someth,则不会有任何
ing
@VladimirF谢谢你的耐心。抱歉你的无知。现在一切都好了。也谢谢David。很好的发现@VladimirF-我读代码太快了,认为“如果”只是IO语句的一部分。
call MPI_REDUCE(phi_moyen1_2,mean_2_025,100*100,MPI_REAL,MPI_SUM,0,MPI_COMM_WORLD,ierr)