Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran 为什么边界检查会改变程序的行为?_Fortran_Intel Fortran - Fatal编程技术网

Fortran 为什么边界检查会改变程序的行为?

Fortran 为什么边界检查会改变程序的行为?,fortran,intel-fortran,Fortran,Intel Fortran,我有一个用Fortran编写的热工水力学代码。对于调试版本,我在编译时使用ifort 11.1中的-check-bounds选项。我过去曾以这种方式捕获数组边界错误。不过,最近我看到,对于一个给定的案例,解决方案很快就失败了。奇怪的是,它很好地融合到了代码的发布版本中。果然,从调试生成文件中删除-check-bounds标志就解决了这个问题 奇怪的是,对于我以前使用的许多其他测试用例,调试版本都工作得很好,并且在代码中超出任何数组边界时都不会出现任何错误。这种行为对我来说似乎很奇怪,我不知道我的

我有一个用Fortran编写的热工水力学代码。对于调试版本,我在编译时使用ifort 11.1中的
-check-bounds
选项。我过去曾以这种方式捕获数组边界错误。不过,最近我看到,对于一个给定的案例,解决方案很快就失败了。奇怪的是,它很好地融合到了代码的发布版本中。果然,从调试生成文件中删除
-check-bounds
标志就解决了这个问题

奇怪的是,对于我以前使用的许多其他测试用例,调试版本都工作得很好,并且在代码中超出任何数组边界时都不会出现任何错误。这种行为对我来说似乎很奇怪,我不知道我的代码中是否存在某种bug或者什么。有人知道是什么导致了这种行为吗

根据要求,我用于发布和调试的标志是:

发布:
-c-r8-traceback-extend source-override limits-zero-unroll-O3

调试:
-c-r8-traceback-extend source-override limits-zero-g-O0


当然,正如我最初的问题所指出的,我为调试案例打开和关闭了
-check bounds
标志。

我更怀疑您的数值算法,而不是Fortran代码。您是否已确保满足所有收敛和稳定性标准

听起来好像是舍入错误导致解决方案无法收敛。如果您正处于安全收敛的边缘,那么编译器优化肯定会以这样或那样的方式提示您

我使用的
gfortran
多于
ifort
,因此我不知道-unroll选项的所有细节,但是展开循环可以改变一些舍入,即使计算看起来应该保持不变。此外,debug肯定会更改内存和寄存器访问的确切顺序。如果数字以某种内部表示形式存在于处理器中,然后写入内存并再次读取,则该值可能会更改。通过仔细选择
种类
,可以在一定程度上缓解这种情况。从本质上讲,这将是特定于处理器的,而不是可移植的

理论上,完全遵守IEEE 754将使浮点运算重现,但情况并非总是如此。如果调试实际上导致了这些问题,而不是代码中的其他错误,那么与处理器内部工作相关的其他神秘事物也可能导致它崩溃


我会在代码中的各个关键点添加write语句,以输出数据矩阵(或您正在使用的任何数据结构)。确保使用二进制输出。使用
form='unformatted'
access='direct'

打开,我们也不知道您的代码中是否有bug,因为您没有显示任何bug。是的,我知道,但考虑到它有数万行长,我不太可能这样做。我也怀疑它是否有用。我只是想知道是否有人曾经遇到过类似的问题。也许他们可以给我指出一个更好的方向,因为我真的不知道是什么导致了这种行为,对我来说,这种行为似乎很奇怪。你没有得到任何关于代码中发生越界的详细信息吗?据我所知,没有越界错误。这是奇怪的部分。它似乎实际上改变了数值解的行为。对于越界错误,标准输出将明确表示类似“数组的索引i越界”。但在这种情况下,代码将停止,因为由于数值解发散,某些解参数在物理上变得不现实。对于其他模型,即使启用了检查边界,解决方案也不会出现问题。有限精度浮点算法不遵循实数公理。更改编译器选项可以更改操作顺序,从而更改结果。答案的显著变化表明您的算法可能不够健壮。您可能希望添加调试输出,并查看两个“版本”的差异,以及是否可以改进算法。廉价的解决方案是提高变量的精度:从单变量到双变量,等等。我建议现在就
access=“stream”