Fortran: различия между сгенерированным кодом, скомпилированным с использованием двух разных компиляторов - PullRequest
4 голосов
/ 10 февраля 2011

Мне нужно поработать над программой на фортране, которую раньше компилировали с использованием Microsoft Compaq Visual Fortran 6.6.Я бы предпочел работать с Gfortran, но я столкнулся с множеством проблем.Основная проблема заключается в том, что сгенерированные двоичные файлы имеют различное поведение.Моя программа берет входной файл, а затем должен сгенерировать выходной файл.Но иногда, когда используется двоичный файл, скомпилированный gfortran, он вылетает до конца или дает разные числовые результаты.Это программа, написанная исследователями, которая использует много чисел с плавающей точкой.

Итак, мой вопрос: каковы различия между этими двумя компиляторами, которые могут привести к такого рода проблемам?

edit: Моя программа вычисляет значения некоторых параметров, и существует множество итераций.В начале все идет хорошо.После нескольких итераций появляются некоторые значения NaN (только когда они скомпилированы gfortran).

edit: Думайте всем за свои ответы.Поэтому я использовал компилятор intel, который помог мне, дав несколько полезных сообщений об ошибках.Источник моих проблем в том, что некоторые переменные не инициализированы должным образом.Похоже, что при компиляции с compaq visual fortran эти переменные автоматически принимают 0 в качестве значения, тогда как с gfortran (и intel) он принимает случайные значения, которые объясняют некоторые численные различия, которые складываются на следующих итерацияхТак что теперь решение - лучшее понимание программы для исправления этих пропущенных инициализаций.

Ответы [ 4 ]

3 голосов
/ 11 февраля 2011

Разные компиляторы могут выдавать разные инструкции для одного и того же исходного кода.Если численный расчет находится на грани работы, один набор инструкций может работать, а другой - нет.У большинства компиляторов есть опции для использования более консервативной арифметики с плавающей запятой по сравнению с оптимизацией по скорости - я предлагаю проверить опции компилятора, которые вы используете, для доступных опций.Более фундаментально эта проблема - особенно в том, что компиляторы соглашаются на несколько итераций, но затем расходятся - может быть признаком того, что численный подход программы является пограничным.Упрощенным решением является повышение точности расчетов, например, от одного до двойного.Возможно также настроить параметры, такие как размер шага или аналогичный параметр.Лучше было бы получить более глубокое понимание алгоритма и, возможно, внести более фундаментальные изменения.

2 голосов
/ 11 февраля 2011

Причин такого поведения может быть несколько. Что бы я сделал, это:

  1. Отключить любую оптимизацию

  2. Включить все параметры отладки. Если у вас есть доступ к, например, компилятор intel, используйте ifort -CB -CU -debug -traceback. Если вам нужно придерживаться gfortran, используйте valgrind, его вывод несколько менее читабелен, но часто лучше, чем ничего.

  3. Убедитесь, что нет неявных типизированных переменных, используйте implicit none во всех модулях и во всех кодовых блоках.

  4. Используйте согласованные типы с плавающей точкой. Лично я всегда использую real*8 как единственный тип float в моих кодах. Если вы используете внешние библиотеки, вам может потребоваться изменить подписи вызовов для некоторых подпрограмм (например, BLAS имеет разные имена подпрограмм для переменных одинарной и двойной точности).

Если вам повезет, просто какая-то переменная не будет правильно инициализирована, и вы поймаете ее одним из этих методов. В противном случае, как М.С.Б. Я предполагал, что необходимо более глубокое понимание того, что на самом деле делает программа. И, да, может потребоваться просто проверить алгоритм вручную, начиная с того места, где вы говорите «появляются некоторые значения NaN».

2 голосов
/ 10 февраля 2011

Я не знаю о сбое, но некоторые различия в результатах числового кода на машине Intel могут быть связаны с тем, что один компилятор использует 80-двойные, а другие 64-разрядные двойные, даже если не для переменных, но, возможно, длявременные значения.Более того, вычисления с плавающей точкой чувствительны к порядку выполнения элементарных операций.Разные компиляторы могут генерировать разную последовательность операций.

1 голос
/ 11 февраля 2011

Различия в реализациях разных типов, различия в различных нестандартных расширениях поставщиков могут быть разными.

Вот лишь некоторые из языковых возможностей, которые отличаются (см. gfortran и intel ).Программы, написанные на стандартном языке Fortran, работают на каждом компиляторе одинаково, но многие люди не знают, каковы стандартные возможности языка и каковы расширения языка, и поэтому используют их ... при компиляции с другим компилятором возникают проблемы.

Если вы разместите код где-нибудь, я могу быстро взглянуть на него;в противном случае, как это, трудно сказать наверняка.

...