#fortran
#fortran
Вопрос:
Я перехожу с ifort14 на ifort16, на 14 код компилируется и работает нормально, на 16 я получаю ошибку времени компиляции, которая для меня не имеет смысла. Короче говоря, компилятор жалуется на процедуру, определение которой является последним в файле, и если я изменю порядок, он будет жаловаться на другую процедуру, опять же ту, которая идет последней. Ошибка не имеет никакого смысла, и такое поведение тоже не имеет смысла. Кому-то это кажется знакомым, и есть ли у вас какие-либо идеи, где я мог бы искать проблему?
У меня следующая структура
Файл1:
module model_generic
implicit none
type, abstract :: modelGen
logical, public :: init_flag = .false.
contains
procedure :: isInit => dispInitFlag_model
procedure, nopass :: taylorRule_func
procedure, nopass :: penalty_func
end type modelGen
contains
function dispInitFlag_model(this) result(init_flag)
class(modelGen), intent(in) :: this
logical :: init_flag
init_flag = this%init_flag
end function dispInitFlag_model
end module model_generic
File2:
module model_nk_generic
use model_generic
implicit none
type, abstract, extends(modelGen) :: model_nk
logical, public :: init_flag_nk = .false.
contains
procedure :: isInit => dispInitFlag_model_nk
procedure :: setIniGuess => setIniGuess_model_nk_default
! deferred procedures
procedure(obj_func), deferred :: lossFunction
procedure(IS_PC_curves), deferred :: IS_PC0
procedure(Taylor_IS_PC_curves), deferred :: taylor_IS_PC
procedure(IS_curve), deferred :: IS
procedure(PC_curve), deferred :: PC
procedure(R_trans), deferred :: R_lom
procedure(A_trans), deferred :: A_lom
procedure(eps_trans), deferred :: eps_lom
generic :: IS_PC => IS_PC0, taylor_IS_PC
end type model_nk
abstract interface
! omitted
end interface
contains
function dispInitFlag_model_nk(this) result(init_flag_nk)
class(model_nk), intent(in) :: this
logical :: init_flag_nk
init_flag_nk = this%init_flag_nk
end function dispInitFlag_model_nk
subroutine setIniGuess_model_nk_default(this,VFonGrid,grid)
class(model_nk), intent(in) :: this
real(KIND=DP), dimension(:), intent(out) :: VFonGrid
real(KIND=DP), dimension(:,:), intent(in), optional :: grid
VFonGrid = 0e0
!VFonGrid = 1._DP
end subroutine setIniGuess_model_nk_default
end module model_nk_generic
Ошибка, которую я получаю во время компиляции (приведенное выше скомпилировано как часть более крупного проекта), является
error #8437: The type/rank signature for the arguments of this specific
subroutine matches another specific subroutine that shares the same
ASSIGNMENT generic binding.
end subroutine setIniGuess_model_nk_default
^
Процедура (или ее имя привязки) больше нигде не отображается в программе, кроме одного модуля, где она вызывается (я проверил это, чтобы быть уверенным). Таким образом, он не может использовать какую-либо общую привязку. Когда я удаляю ее, компилятор выдает мне ту же ошибку с dispInitFlag_model_nk
процедурой. Когда я добавляю do_nothing
процедуру, она будет жаловаться на нее. Компилятор, похоже, всегда жалуется на последнюю процедуру в файле.
Минималистичный тестовый пример, подобный приведенному ниже, отлично компилируется (с использованием того же файла makefile). Другой код без каких-либо функций ООП тоже компилируется нормально.
program main
use model_generic
use model_nk_generic
class(model_nk), allocatable :: svars
end program main
Каждый раз, когда я выполняю чистую компиляцию, все библиотеки, которые я использую, я компилирую из исходного кода, кроме MKL, но это должно быть связано правильно, я это проверил.
Есть ли у кого-нибудь идеи, что может быть не так с исходным файлом или с моей средой компиляции?
Edit1: Забыл упомянуть флаги компилятора. Обычно я использую ifort -openmp -O3
, но я также попробовал свой обычный набор флагов отладки ifort -openmp -g -p -traceback -check bounds -ftrapuv -fpe0 -O0 -warn -check uninit -gen-interfaces -warn interfaces -check all
, и я пробовал с -openmp
флагом и без него. В какой-то момент компилятор сказал мне, что флаг устарел, но использование -qopenmp
вместо этого ничего не изменило.
Редактирование 2: Вероятно, мне также следовало упомянуть, что я также использую препроцессор. И оба файла предварительно обработаны. Но опять же в версии 14 она работает нормально, и ошибка возникает в file2 после компиляции file1 (его зависимости).
Комментарии:
1. Что происходит с ifort v17? Какие параметры командной строки вы используете?
2. Возможно, какая-то интерпретация изменилась для более новых версий ifort …?
3. @IanH Верно, я забыл упомянуть о флагах. Я использовал
ifort -openmp -O3
, я тоже пробовалifort -openmp -g -p traceback =check bounds -ftrapuv -fpe0 -O0 -warn
, и я пробовал с и без-openmp
. Я не могу найти его сейчас, но вчера компилятор сказал мне, что-openmp
флаг устарел, и я должен использовать-qopenmp
его, если я правильно помню. Но устаревший не означает сломанный, плюс я попробовал, и, конечно, это ничего не изменило. Я добавлю флаги к вопросу, спасибо, что указали на это.4. @IanH Я не могу использовать v17, поскольку у меня нет лицензии. Он установлен в кластере, но я получаю ошибку лицензии. Возможно, у нас небольшое количество лицензий, и мне не повезло, что это было проверено. Я попытался установить пробную копию на свой ноутбук, но для этого требуется 4 ГБ места, и я никак не могу это получить. У меня есть другая машина, на которую я мог бы его установить, но сначала мне нужно будет установить linux-бокс в виртуальной машине, и вряд ли у меня будет время для этого в ближайшее время. Я сообщу, если случайно смогу заставить v17 работать.
5. Я не смог воспроизвести ошибку с компилируемым вариантом вашего кода. Без полного компилируемого примера больше ничего нельзя сказать. Если это проблема компилятора (и симптомы делают это вполне возможным), попытка использовать последнюю версию (а также самое последнее обновление до 16) является очевидным предложением. Для такого рода проблем вам лучше опубликовать сообщение на соответствующем форуме Intel или обратиться к их службе поддержки premier, если у вас есть к этому доступ.