关注this thread,我想投一个/双精度实数" AA"整数" II"计算分布式变量的校验和。
发表评论后,我使用了内在的'转移'并完全重写了这篇文章。下面是一个小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
答案 0 :(得分:1)
根据标准,fortran和MPI_reduce以同样的方式处理整数溢出?
Fortran标准和MPI 3.0标准都没有提到整数溢出,所以你受到实施者的支配。
但是,我发现你只使用默认种的整数,对中间结果使用更大的整数类,你可以实现自己的溢出检测。
答案 1 :(得分:1)
Fortran标准未定义整数溢出。在C signed中,整数溢出是未定义的行为。
如果在gfortran中启用未定义的行为santizations,您的程序将停止并显示错误消息。 (当我使用第三方随机数发生器时发生在我身上。)
您可以使用更大的整数执行操作并裁剪结果或调用使用无符号整数的C函数。只有有符号整数才能很好地定义整数溢出。