我有一个 Fortran 程序,我在其中指定kind
数字数据类型以尝试保持最低级别的精度,而不管使用什么编译器来构建程序。例如:
integer, parameter :: rsp = selected_real_kind(4)
...
real(kind=rsp) :: real_var
问题是我已经使用 MPI 来并行化代码,我需要确保 MPI 通信指定具有相同精度的相同类型。我使用以下方法与我的程序中的方法保持一致:
call MPI_Type_create_f90_real(4,MPI_UNDEFINED,rsp_mpi,mpi_err)
...
call MPI_Send(real_var,1,rsp_mpi,dest,tag,MPI_COMM_WORLD,err)
然而,我发现这个 MPI 例程对于不同的 MPI 实现并没有特别好的支持,所以它实际上使我的程序不可移植。如果我省略了MPI_Type_create
例程,那么我就只能依赖标准类型MPI_REAL
和数据类型,但是如果该类型与最终将由 MPI 传递的实际类型MPI_DOUBLE_PRECISION
不一致怎么办?selected_real_kind
我是否坚持只使用real
数据类型的标准声明,没有kind
属性,如果我这样做,我是否保证MPI_REAL
并且real
总是具有相同的精度,无论编译器和机器如何?
更新:
我创建了一个简单的程序来演示当我的内部实数比类型提供的精度更高时看到的问题MPI_DOUBLE_PRECISION
:
program main
use mpi
implicit none
integer, parameter :: rsp = selected_real_kind(16)
integer :: err
integer :: rank
real(rsp) :: real_var
call MPI_Init(err)
call MPI_Comm_rank(MPI_COMM_WORLD,rank,err)
if (rank.eq.0) then
real_var = 1.123456789012345
call MPI_Send(real_var,1,MPI_DOUBLE_PRECISION,1,5,MPI_COMM_WORLD,err)
else
call MPI_Recv(real_var,1,MPI_DOUBLE_PRECISION,0,5,MPI_COMM_WORLD,&
MPI_STATUS_IGNORE,err)
end if
print *, rank, real_var
call MPI_Finalize(err)
end program main
如果我使用 2 个内核构建和运行,我会得到:
0 1.12345683574676513672
1 4.71241976735884452383E-3998
现在将 16 更改为 15 英寸selected_real_kind
,我得到:
0 1.1234568357467651
1 1.1234568357467651
selected_real_kind(15)
无论使用MPI_DOUBLE_PRECISION
什么机器/编译器进行构建 ,使用它是否总是安全的?