Fortran часто считают языком из прошлого, но в научных расчётах он остаётся рабочим инструментом. Коды климата, гидродинамики, квантовой химии и численных методов пишутся на нём десятилетиями, а компиляторы продолжают развиваться. Современный Fortran — это свободный формат исходников, модули, массивы с проверкой границ и средства параллелизма. Разберём, как начать проект в 2026 году, не унаследовав привычки Fortran 77.

Где Fortran действительно силён

Язык проектировался для численных массивов, и это видно в синтаксисе: срезы, поэлементные операции, встроенные функции над массивами. Компиляторы хорошо оптимизируют такие циклы, а библиотеки BLAS, LAPACK, ScaLAPACK и FFTW написаны на Fortran или имеют совместимый интерфейс. В задачах, где время считается часами, а не миллисекундами, выигрыш даёт не «магия языка», а отсутствие накладных расходов интерпретатора и предсказуемая работа с памятью.

Fortran не заменяет Python целиком: удобно писать расчётное ядро на Fortran, а обвязку, визуализацию и подготовку данных оставить на Python. Связка через C-интерфейс или файлы обмена работает устойчиво и не требует экзотических решений. Такой подход позволяет пользоваться библиотеками обеих экосистем без потери скорости.

Компиляторы и установка

Самый доступный компилятор — gfortran из состава GCC. Он поддерживает стандарт Fortran 2018 и значительную часть Fortran 2023. В дистрибутивах пакет ставится отдельно от gcc.

sudo apt install gfortran
sudo dnf install gcc-gfortran
gfortran --version
gfortran -std=f2018 -c hello.f90

Второй вариант — LLVM Flang, который активно развивается и удобен для интеграции с LLVM-инструментами. Для промышленных задач с коммерческой поддержкой существуют NVIDIA HPC SDK и Intel oneAPI. Начинать проще с gfortran: ошибки он объясняет понятнее, а сообщество больше.

Минимальная программа и модули

Современный стиль начинается с implicit none и явных типов. Модуль скрывает внутренние процедуры и даёт явный интерфейс, который компилятор проверяет при вызове.

module thermo
  use iso_fortran_env, only: real64
  implicit none
  private
  public :: celsius_to_kelvin

contains

  pure elemental function celsius_to_kelvin(c) result(k)
    real(real64), intent(in) :: c
    real(real64) :: k
    k = c + 273.15_real64
  end function celsius_to_kelvin

end module thermo

Атрибуты pure и elemental не украшение: они позволяют вызывать функцию в выражениях над массивами и дают компилятору свободу оптимизации. intent(in) фиксирует, что аргумент не меняется, и защищает от случайной записи.

Точность задаётся через real64 из iso_fortran_env, а не через устаревшее real*8. Это переносимо между компиляторами и платформами и не зависит от соглашений конкретной системы.

Рабочий пример: уравнение диффузии

Ниже — явная схема для двумерной диффузии. Она не претендует на вычислительную эффективность, но показывает массивы, срезы и контроль границ.

program diffusion
  use iso_fortran_env, only: real64
  implicit none
  integer, parameter :: n = 256, steps = 500
  real(real64), allocatable :: u(:,:), unew(:,:)
  real(real64) :: alpha
  integer :: i, j, k

  allocate(u(n,n), unew(n,n))
  u = 0.0_real64
  u(n/2, n/2) = 1.0_real64
  alpha = 0.1_real64

  do k = 1, steps
    do j = 2, n-1
      do i = 2, n-1
        unew(i,j) = u(i,j) + alpha * (u(i-1,j) + u(i+1,j) &
          + u(i,j-1) + u(i,j+1) - 4.0_real64*u(i,j))
      end do
    end do
    u(2:n-1,2:n-1) = unew(2:n-1,2:n-1)
  end do

  print '(a,es12.4)', 'max = ', maxval(u)
end program diffusion

Обратите внимание на порядок хранения: Fortran хранит массивы по столбцам, поэтому самый быстрый индекс — первый. Вложенные циклы выше идут по i внутри, что соответствует памяти. Перестановка циклов может замедлить код в разы без единой ошибки компиляции.

Сборка, проверки и отладка

Во время разработки включайте проверки, в релизе — оптимизацию. Смешивать их в одной сборке опасно: проверки меняют поведение и скорость.

gfortran -std=f2018 -O0 -g -Wall -Wextra -fcheck=all \
  -fbacktrace -ffpe-trap=invalid,zero,overflow \
  -o diffusion diffusion.f90
./diffusion
gfortran -std=f2018 -O3 -march=native -o diffusion diffusion.f90

-fcheck=all включает проверку границ и указателей, -ffpe-trap останавливает программу на делении на ноль и переполнении. Это лучше, чем получить NaN через час расчёта. -march=native использует инструкции текущего процессора; для переносимых сборок его не применяют.

Для поиска узкого места подойдут perf record и gprof. Начните с профиля, а не с переписывания кода: часто время уходит на одну функцию или на неэффективный доступ к памяти.

BLAS, LAPACK и параллелизм

Плотную линейную алгебру не пишут вручную. Подключение библиотек — обычные флаги компоновки, но порядок важен: сначала объектные файлы, затем библиотеки.

gfortran -O2 -fopenmp solve.f90 -llapack -lblas -o solve
OMP_NUM_THREADS=4 ./solve
gfortran -O2 -fcoarray=lib hello.f90 -lcaf_mpi -o hello
cafrun -n 4 ./hello

Coarrays дают параллелизм в стандарте языка, но для реального кластера нужен OpenCoarrays и MPI. OpenMP проще: директивы перед циклом и переменная числа потоков. Не запускайте гибрид MPI и OpenMP без расчёта: переподписка потоков на ядрах даёт падение производительности вместо ускорения.

Fortran Package Manager

fpm приносит в язык привычную структуру проекта, сборку и тесты. Он не заменяет CMake в больших унаследованных кодах, но для нового проекта удобнее.

fpm new diffusion
cd diffusion
fpm build
fpm test
fpm run

Манифест fpm.toml описывает зависимости и цели. Для связывания с C используйте iso_c_binding, а не угадывание соглашений о вызовах: тогда компилятор проверит типы и имена на границе языков. В больших проектах сборку чаще ведут через CMake, а fpm оставляют для прототипов и небольших библиотек: у него проще синтаксис, но меньше возможностей тонкой настройки флагов и внешних зависимостей.

Чек-лист

  • implicit none в каждом модуле и программе.
  • Типы точности из iso_fortran_env.
  • Модули вместо внешних процедур с неявным интерфейсом.
  • Проверки границ на этапе разработки, профилирование до оптимизации.
  • Порядок циклов соответствует столбцовому хранению.

Итог

Fortran остаётся языком, который решает свою задачу: быстрые вычисления над массивами с предсказуемым поведением. Современный стиль — модули, явные типы, проверки и пакетный менеджер — делает код читаемым и поддерживаемым. Если расчётное ядро живёт годами, Fortran с gfortran и BLAS остаётся разумным выбором и в 2026 году.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте