Fortran 不同的程序结果取决于程序的链接方式
我正在开发一个大型ish数值模拟程序,该程序主要用Fortran编写,由英特尔Fortran编译器(v18.0.3)编译 最近,我遇到了一个神秘的问题:如果我将程序与外部库链接为绝对路径,那么与使用Fortran 不同的程序结果取决于程序的链接方式,fortran,intel-fortran,Fortran,Intel Fortran,我正在开发一个大型ish数值模拟程序,该程序主要用Fortran编写,由英特尔Fortran编译器(v18.0.3)编译 最近,我遇到了一个神秘的问题:如果我将程序与外部库链接为绝对路径,那么与使用-L/path/to/lib-lnameoflb链接的程序相比,数值结果略有不同 我已检查了以下各项: 共享库的运行时加载:我用strace检查了这两种情况,在这两种情况下加载相同的库,并且它们以相同的顺序加载 单位化变量:使用-check all-ftrapuv编译时,没有警告或错误 这两个二进制
-L/path/to/lib-lnameoflb链接的程序相比,数值结果略有不同
我已检查了以下各项:
- 共享库的运行时加载:我用
strace
检查了这两种情况,在这两种情况下加载相同的库,并且它们以相同的顺序加载李>
- 单位化变量:使用
-check all-ftrapuv
编译时,没有警告或错误李>
- 这两个二进制文件都是用valgrind运行的,除了在外部库中,没有发现内存问题李>
- 在二进制文件上使用
diff
时,它们是不同的
我没有办法检查为什么会发生这种情况。如果有人能进一步建议如何处理这个问题,以及差异可能来自何处,我将非常高兴。我将根据这些建议得出以下结论。当与/usr/lib/libm.so链接时,将使用平台libm.so
。使用-lm
链接时,“英特尔编译器”将更改链接命令,以同时链接英特尔数学库libimf.so
。显然,这些不同的实现会产生数值舍入误差,从而导致差异。我将根据这些差异得出以下结论。当与/usr/lib/libm.so链接时,将使用平台libm.so
。使用-lm
链接时,“英特尔编译器”将更改链接命令,以同时链接英特尔数学库libimf.so
。显然,这些不同的实现会产生数值舍入错误,从而导致差异。至少在我上次检查英特尔编译器时,它无法捕获所有未初始化的变量,所以这是我的猜测。您可以访问NAG编译器吗?不幸的是,没有访问NAG编译器的权限。-ftrapuv没有任何有用的功能,而且名称有误导性。别费心了。我还怀疑未初始化的变量或参数不匹配。考虑添加“-警告界面”和重建。当你写“结果略有不同”时,最后一个数字还是两个不同?这可以用数字舍入或浮点运算的缺点来解释吗?我不确定这是否纯粹是数字舍入,但最终在其中一个测试用例中,差异出现在第三个小数点,并且由于这些差异,在达到收敛之前的迭代次数减少了一次。至少上次我检查英特尔编译器时,它无法捕获所有未初始化的变量,所以这是我的猜测。您可以访问NAG编译器吗?不幸的是,没有访问NAG编译器的权限。-ftrapuv没有任何有用的功能,而且名称有误导性。别费心了。我还怀疑未初始化的变量或参数不匹配。考虑添加“-警告界面”和重建。当你写“结果略有不同”时,最后一个数字还是两个不同?这可以用数字舍入或浮点运算的缺点来解释吗?我不确定这是否纯粹是数字舍入,但最终在其中一个测试用例中,差异出现在第三个小数点,并且由于这些差异,在达到收敛之前的迭代次数也减少了一次。