2016-11-11 122 views
0

this thread后,我想将一个单/双精度实数“AA”转换为一个整数“II”来计算分布式变量的校验和。Fortran和MPI_Reduce如何处理整数溢出?

以下评论,我已经使用内在的'转移',并完全改写这篇文章。下面是一个小Fortran模块,可用于计算分布式数组的校验和,这取决于库2DECOMP&FFT。该模块似乎在我的工作站上工作(gfortran 4.9.2,openmpi 1.6.5,4个处理器)。任何意见/评论,可能会提高代码的可移植性将不胜感激。关于可移植性的主要问题是:Fortran和MPI_reduce是否按照标准以相同的方式处理整数溢出?

module checksum 

    use MPI 
    use decomp_2d, only : mytype, nrank, & 
    xsize, ysize, zsize, & 
    transpose_x_to_y, transpose_y_to_z, & 
    transpose_z_to_y, transpose_y_to_x 

    implicit none 

    private ! Make everything private unless declared public 

    real(mytype), parameter :: xx=1. 

    integer, parameter, public :: chksum_size = size(transfer(xx,(/0,0/))) 

    integer, dimension(chksum_size) :: chkr1, chkr2, chkr3 

    logical, save :: chksum_is_working 

    ! Temporary work variables/arrays 
    integer :: code 
    integer, dimension(chksum_size) :: tmprchk 

    public :: init_chksum, chksum, equal_chksum 

    contains 

    ! 
    ! Function to compute the checksum of a real 3D array var 
    ! 
    function chksum(var,nx,ny,nz) 
     integer, intent(in) :: nx, ny, nz 
     real(mytype), dimension(nx,ny,nz), intent(in) :: var 
     integer, dimension(chksum_size) :: chksum 

     tmprchk = sum(transfer(var,(/0,0/))) 
     call MPI_ALLREDUCE(tmprchk,chksum,chksum_size,MPI_INTEGER,MPI_SUM,MPI_COMM_WORLD,code) 

    end function chksum 

    ! 
    ! Subroutine to make sure input arrays have the same checksum 
    ! First/second/third array are in X/Y/Z pencil 
    ! If switch is provided, reference array is var3. 
    ! Otherwise, reference array is var1 
    ! 
    subroutine equal_chksum(var1, var2, var3, switch) 
     real(mytype), dimension(xsize(1),xsize(2),xsize(3)), intent(inout) :: var1 
     real(mytype), dimension(ysize(1),ysize(2),ysize(3)), intent(inout) :: var2 
     real(mytype), dimension(zsize(1),zsize(2),zsize(3)), intent(inout) :: var3 
     logical, optional, intent(in) :: switch 

     if (chksum_is_working) then ! compute checksums 
     chkr1 = chksum(var1,xsize(1),xsize(2),xsize(3)) 
     chkr2 = chksum(var2,ysize(1),ysize(2),ysize(3)) 
     chkr3 = chksum(var3,zsize(1),zsize(2),zsize(3)) 
     else ! generate checksums 
     chkr1 = 1 
     chkr2 = 2 
     chkr3 = 3 
     endif 

     if (present(switch)) then 
     if (any(chkr3.ne.chkr2)) call transpose_z_to_y(var3,var2) 
     if (any(chkr3.ne.chkr1)) call transpose_y_to_x(var2,var1) 
     else 
     if (any(chkr1.ne.chkr2)) call transpose_x_to_y(var1,var2) 
     if (any(chkr1.ne.chkr3)) call transpose_y_to_z(var2,var3) 
     endif 

    end subroutine equal_chksum 

    ! 
    ! Subroutine used to check we have a working checksum 
    ! 
    subroutine init_chksum(var1,var2,var3) 
     real(mytype), dimension(xsize(1),xsize(2),xsize(3)), intent(out) :: var1 
     real(mytype), dimension(ysize(1),ysize(2),ysize(3)), intent(out) :: var2 
     real(mytype), dimension(zsize(1),zsize(2),zsize(3)), intent(out) :: var3 

     ! Same random data inside all arrays 
     call random_number(var1) 
     call transpose_x_to_y(var1,var2) 
     call transpose_y_to_z(var2,var3) 

     ! Compute checksums 
     chkr1 = chksum(var1,xsize(1),xsize(2),xsize(3)) 
     chkr2 = chksum(var2,ysize(1),ysize(2),ysize(3)) 
     chkr3 = chksum(var3,zsize(1),zsize(2),zsize(3)) 

     ! Check checksums 
     if (any(chkr1.ne.chkr2).or.any(chkr1.ne.chkr3)) then 
     chksum_is_working = .false. 
     if (nrank.eq.0) print *,'Checksums based on integer overflow do not work' 
     else 
     chksum_is_working = .true. 
     endif 

    end subroutine init_chksum 

end module checksum 
+1

你是什么意思的“演员”?你想使用相同的位模式而不是数值(例如'transfer')? – francescalus

+0

@francescalus谢谢,我不知道转让,这正是我需要的。它是标准/便携式吗? – user1824346

+1

你应该明白* cast *这个词是不明确的,你只需解释你对一些代码做了什么。例如在C++中有reinterpret_cast,dynamic_cast,static_cast和更多http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used我们无法从水晶球上看出你的意思。 –

回答

1

按标准做Fortran和MPI_reduce处理整数溢出以同样的方式?

Fortran标准和MPI 3.0标准都没有提到整数溢出,所以你受到实现者的摆布。

但是,我看到您只使用默认种类的整数,对于中间结果使用较大的整数类型,您可以实现自己的溢出检测。

1

整数溢出未由Fortran标准定义。在C中有符号整数溢出是未定义的行为

如果您在gfortran中启用未定义的行为santizations,您的程序将停止并显示错误消息。 (当我使用第三方随机数发生器时发生在我身上)

您可以使用较大的整数执行操作并裁剪结果或调用使用无符号整数的C函数。整数溢出仅为有符号整数定义好。