Floating point 相同的操作数在同一代码中不同的结果相同的机器
在fortran90语言中,相同的操作数产生不同的实数类型单精度结果,编译器选项似乎给出了不同的结果Floating point 相同的操作数在同一代码中不同的结果相同的机器,floating-point,fortran,fortran90,Floating Point,Fortran,Fortran90,在fortran90语言中,相同的操作数产生不同的实数类型单精度结果,编译器选项似乎给出了不同的结果 real , dimension(n_pft) :: sapwood_ratio real , dimension(n_pft) :: qsw real , dimension(n_pft) :: SLA !these 4 variables are also real type sla_scale = 0.1 * C2B sla_inter = 2.4 sla
real , dimension(n_pft) :: sapwood_ratio
real , dimension(n_pft) :: qsw
real , dimension(n_pft) :: SLA
!these 4 variables are also real type
sla_scale = 0.1 * C2B
sla_inter = 2.4
sla_slope = -0.46
leaf_turnover_rate(2) = 1.0
leaf_turnover_rate(3) = 0.5
leaf_turnover_rate(4) = 1./3.
leaf_turnover_rate(12) = 1.0
leaf_turnover_rate(13) = 0.5
leaf_turnover_rate(14) = 1./3.
sapwood_ratio(1:17) = 3900.0
SLA( 2) = 10.0**(sla_inter + sla_slope * log10(12.0/leaf_turnover_rate( 2))) * sla_scale
SLA( 3) = 10.0**(sla_inter + sla_slope * log10(12.0/leaf_turnover_rate( 3))) * sla_scale
SLA( 4) = 10.0**(sla_inter + sla_slope * log10(12.0/leaf_turnover_rate( 4))) * sla_scale
SLA(12) = 10.0**(sla_inter + sla_slope * log10(12.0/leaf_turnover_rate(12))) * sla_scale
SLA(13) = 10.0**(sla_inter + sla_slope * log10(12.0/leaf_turnover_rate(13))) * sla_scale
SLA(14) = 10.0**(sla_inter + sla_slope * log10(12.0/leaf_turnover_rate(14))) * sla_scale
这里的一切都很完美,但当我计算
qsw(1:4) = SLA(1:4) / sapwood_ratio(1:4)
qsw(5:13) = SLA(5:13) / sapwood_ratio(5:13)
qsw(14:15) = SLA(14:15) / sapwood_ratio(14:15)
当我在集群上运行它时,我得到
qsw(3) 0.0029858516063541173934937
qsw(13) 0.0029858518391847610473633
在我的本地机器中
qsw(3) 0.0029858518391847610473633
qsw(13) 0.0029858518391847610473633
但它们应该具有相同的精确值,就像元素2/12和4/14一样。此外,其他类似的计算也应该匹配。相同的代码在另一台机器上运行得很好,使用相同的包装器mpif90,但使用gfortran作为加载程序和稍微不同的编译选项,两者都有-O3。无论如何,为什么这个计算不能在同一台机器上产生相同的结果?
当我使用这些选项编译时,这个结果是有效的,但它没有得到优化
USE_INTERF=0
F_OPTS= -FR -O0 -recursive -check all -g -debug extended -debug-parameters used \
-fpe0 -no-ftz -traceback -ftrapuv -fp-stack-check -implicitnone \
-assume byterecl -warn unused -warn uncalled -warn usage -gen-interfaces
C_OPTS= -O0 -DLITTLE -g -traceback
LOADER_OPTS=$(F_OPTS)
这是产生这个错误的另一个选项
USE_INTERF=1
F_OPTS= -FR -O3 -recursive -traceback -assume byterecl
C_OPTS= -O3 -DLITTLE -traceback
F_LOWO_OPTS=-FR -O2 -recursive -traceback -assume byterecl
LOADER_OPTS=$(F_OPTS)
不一致是由编译选项引起的。单独使用“O0”编译或使用“O2”或“O3”以及-fp source编译,可以解决此问题。这是浮点数学的一个问题。在我看来,“同一台机器”的名称是错误的。。。您在不同的计算机上有不同的结果(本地计算机与群集)。编译器选项也略有不同。两者都可能影响浮点计算并导致不同的结果,例如不同的内部表示、不同的操作顺序……您可以通过使用
kind
参数来提高浮点可移植性。@M.S.B.关于同一台机器的观点很好,但在同一台机器上,对于独立于顺序的计算,应该给出相同的结果。好的,这肯定是一些编译器选项,只是重新编译,它做了正确的计算