среда, 10 октября 2018 г.

Bug in Intel Fortran 2018

Наткнулся на замечательнейший баг в компиляторе Intel Fortran 18.0.2 20180210 на институтском кластере под Linux. Есть большой код, который компилируется следующей строкой:
I faced a peculiar bug in Intel Fortran 18.0.2 20180210 on our Linux cluster. A big code compiles using the following command:
ifort -O3  -traceback -DD -debug -check bounds -check format -check uninit -autodouble  -132 -warn none -fpp -no-wrap-margin -heap-arrays -mcmodel=medium -shared-intel -c
Во время исполнения код падает со следующей строкой:
During execution code crashes with the following message:

forrtl: severe (408): fort: (3): Subscript #1 of the array LAYERS_PROP has value -1 which is less than the lower bound of 0
То есть идёт обращение к элементу по индексу -1 массиве LAYERS_PROP, минимальный элемент в котором имеет индекс 0.
So that program tries to access element -1 in an array LAYERS_PROP, which lowermost element has index 0.

Строчка кода, в которой он падает:
The line of code which causes crash:
if (any ((layers_prop(0:N_lay) - layers_prop(1:N_lay+1)) < 0.)) cycle
Смысл строчки: (1) из всех элементов массива layers_prop (он определён с 0 по N_lay+1) с 0 по N_lay вычесть элементы этого же массива с 1 по N_lay+1; (2) сравнить элементы получившегося массива с нулём; (3) в том случае, если для хоть одного элемента полученного массива условие выполнено (any - встроенный примитив фортрана), то условие выполнено и надо что-то сделать (не важно, что именно). Как мы видим, никакого элемента -1 нет, но он откуда-то возникает.
What does this line mean? (1) subtract all the elements from 1 to N_lay+1 of array layers_prop from elements 0 to N_lay of the same array (which is declared from 0 to N_lay+1); (2) compare new values against zero; (3) if for any element of the new array (any is an intrinsic function of fortran) condition is met, do something. One can clearly see, there is no -1 element, but somehow it appears.

Почему это баг Intel Fortran? Потому что при понижении уровня оптимизации с -O3 (самая агрессивная) до хотя бы -O2 проблема пропадает. Сходная проблема и нежелание её устранять описаны и на форуме Intel. Проблема также не наблюдается при компиляции с любым уровнем оптимизации gfortran (и да, это то почему я твержу, что код должен быть совместим с любой ОС и любым компилятором).

Why do I say this is a problem of Intel Fortran? Because one can eliminate this problem reducing optimization level from -)3 to O2 or less. A post on Intel forums describes a similar problem and lack of motivation of Intel software engineers to deal with it. One can also use gfortran compiler with any optimization level: it works just perfectly. That's actually why do I say that code must be compatible with any OS and any compiler.

Как я решил проблему? Внезапно, помогло переставить местами слагаемые. Похоже, это самое оптимальное решение, позволяющее сохранить универсальность кода и его (и его флагов) независимость от конкретного компилятора.
How did I solve the issue? Surprisingly, a simple change of addends' order helped. Seems to b the most universal solution to preserve code and its compilation options compatible with any compiler and its version:
if (any ((layers_prop(1:N_lay+1) - layers_prop(0:N_lay)) > 0.)) cycle









Комментариев нет:

Отправить комментарий