Gcc/gfortran 16 released

GCC 16.1 was officially released today:

2 Likes

does anyone have a ./configure line that has worked? I am not being able to compile gcc

1 Like

Jerry guided me to compile GCC a few weeks ago.

I had created a gcc-dev directory with three subdirs:

  • trunk/ (gcc sources)
  • objdir/ (empty)
  • usr/ (empty)

First, in trunk/:

$ ./contrib/download_prerequisites
$ sudo dnf install gcc-c++ glibc-devel.i686

From objdir/, I had in my script:

readonly repertoire=/home/my_login/gcc_dev
../trunk/configure --prefix="${repertoire}"/usr --enable-languages=c,c++,fortran --enable-multilib --enable-libgomp --disable-bootstrap

make -j10 1>/dev/null && make install 1>/dev/null

Drink you coffee… :hot_beverage:

Finally I tested my snippets with:

gcc_dev/my_snippets$ LD_LIBRARY_PATH=/home/my_login/gcc_dev/usr/lib:/home/my_login/gcc_dev/usr/lib64
gcc_dev/my_snippets$ export LD_LIBRARY_PATH
gcc_dev/my_snippets$ ../usr/bin/gfortran -fcoarray=lib collective.f90 -lcaf_shmem

I should update the Fortran Wiki page with those info.

1 Like

For adventurers only, GFortran 16.1 has arrived in Fedora Rawhide (development distribution):

Next steps should be Fedora 44 Testing, then Stable.

It has just arrived in Fedora Linux 44:

$ gfortran --version
GNU Fortran (GCC) 16.1.1 20260501 (Red Hat 16.1.1-1)
Copyright © 2026 Free Software Foundation, Inc.
1 Like

Does gfortran 16 have an entirely new front-end? What kinds of problems should we watch for with new front end code?

The gfortran front end is an evolution of what has existed for many years. So you shouldn’t have to change anything. (Modulo bug fixes. One I know about is that Jerry D and I worked to get certain INQUIRE return values corrected.) The new front ends over the past couple of major releases are Algol 68 and COBOL.

2 Likes

DO CONCURRENT can speedup like openMP in gfortran 16.1?

I’ve had little success with GNU accelerating do concurrent, if you have good experiences please do tell

2 Likes

the solution was to do an out of source build…

1 Like

Indeed @jorgeg , that’s an advice that Jerry gave me, after my first attempts.

1 Like

Jerry is smart! thanks so much

2 Likes

That is definitely a prerequisite to be a GFortran developer :grin: . I guess he compiles GCC every day, so you can trust him.

1 Like

Another news about GCC (17 ?):

I don’t know if Fortran will be concerned, but if it is a back-end… LFortran has already a WebAssembly back-end.

1 Like

I did some comparative bench marking of gfortran and Intel ifx.
Here is the source code of the main program.

! include ‘precision_module.f90’
! include ‘integer_kind_module.f90’
! Included in the timing_module

include ‘timing_module.f90’

program ch3403

use precision_module
use timing_module

implicit none

real (dp) :: fortran_internal_pi
real (dp) :: partial_pi
real (dp) :: coarray_pi
real (dp) :: width
real (dp) :: total_sum
real (dp) :: x
real (dp), codimension [ * ] :: partial_sum

integer :: n_intervals
integer :: i
integer :: j
integer :: current_image
integer :: n_images

fortran_internal_pi = 4.0_dp*atan(1.0_dp)
n_images = num_images()
current_image = this_image()

if (current_image==1) then
print *, ’ Number of images = ', n_images
call start_timing()
end if

n_intervals = 100000

do j = 1, 5
width = 1.0_dp/real(n_intervals, dp)
total_sum = 0.0_dp
partial_sum = 0.0_dp
do i = current_image, n_intervals, n_images
x = (real(i,dp)-0.5_dp)width
partial_sum = partial_sum + f(x)
end do
partial_sum = partial_sumwidth
sync all
if (current_image==1) then
do i = 1, n_images
total_sum = total_sum + partial_sum[ i ]
end do
coarray_pi = total_sum
print 100, n_intervals, time_difference()
print 110, coarray_pi, abs(coarray_pi-fortran_internal_pi)
end if
n_intervals = n_intervals*10
sync all
end do

if (current_image==1) then
call end_timing()
end if

100 format (’ n intervals = ‘, i12, ’ time =’, f18.6)
110 format (’ pi = ', f20.16, /, ’ difference = ', f20.16)

contains

real (dp) function f(x)
implicit none
real (dp), intent (in) :: x

f = 4.0_dp/(1.0_dp+x*x)

end function

end program

Here are the timing details.

Intervals Average of 10 runs
gfortran 100,000 0.000408
gfortran 1,000,000 0.000907
gfortran 10,000,000 0.001538
gfortran 100,000,000 0.009646
gfortran 1,000,000,000 0.098619
gfortran Total 0.111455
Intel ifx 100,000 0.000275
Intel ifx 1,000,000 0.000289
Intel ifx 10,000,000 0.001027
Intel ifx 100,000,000 0.007884
Intel ifx 1,000,000,000 0.108436
Intel ifx Total 0.118361
gfortran 16.1.1 20260501
ifx 2026.0.0
Fedora Fedora Linux 44 Workstation edition
Redhat 16.1.1-1
Processor Intel I9 10980XE
hyper-v
memory 32 GB
cores 16

The source files are on our web sites.

There is a tar file of all the source files.

2 Likes

GCC 16 has appeared in the Ubuntu repositories. I installed it on my Linux Mint 21.3 (Ubuntu 22.04 LTS Jammy) system with sudo apt install

2 Likes

What is the status of coarray support in gfortran 16? I’m curious about both threads-based and image-based capabilities, and possibly the combination of the two. Is there a gfortran link that has this information?

The page https://gcc.gnu.org/wiki/Coarray is totally outdated (2016).

I am no expert on CAF, so I asked ChatGPT to construct a test program for as many Coarrays features as it can. The output is below, so you can check its completeness yourself.

Gfortran 16.1 on Fedora 44 VM (6 CPUs) passes all tests. Interestingly, ‘ifx’ 2025.3.2 segfaults on test_sync_images_memory() procedure. I have yet to check the newest, 2026 version.

Coarray test program (created by ChatGPT 5.5)
module reducers
contains
  pure function add_int(a, b) result(c)
    integer, intent(in) :: a, b
    integer :: c
    c = a + b
  end function add_int
end module reducers

program caf_feature_test
  use reducers
  use iso_fortran_env, only : atomic_int_kind, event_type, lock_type, team_type
  implicit none

   integer :: me, nimg, i
   integer :: scalar[*]
   integer, allocatable :: arr(:)[:]
   integer(atomic_int_kind) :: acount[*]
   type(lock_type) :: lk[*]
   type(event_type) :: ev[*]
   type(team_type) :: even_odd_team
   integer :: team_no

   me   = this_image()
   nimg = num_images()

   if (me == 1) then
      print *, "========================================"
      print *, "Coarray Fortran feature test"
      print *, "num_images() =", nimg
      print *, "========================================"
   end if
   sync all

   call test_images_and_coindexed_access()
   call test_allocatable_coarray()
   call test_sync_images()
   call test_sync_images_memory()
   call test_atomic()
   call test_lock()
   call test_events()
   call test_collectives()
   call test_teams()

   sync all
   if (me == 1) print *, "All tests finished."

contains

   subroutine say(name)
      character(*), intent(in) :: name
      sync all
      if (me == 1) then
         print *
         print *, "---- ", trim(name), " ----"
      end if
      sync all
   end subroutine say


   subroutine test_images_and_coindexed_access()
      call say("images and coindexed access")

      scalar = 1000 + me
      sync all

      if (me == 1) then
         do i = 1, nimg
            print *, "scalar on image", i, "=", scalar[i]
         end do
      end if

      sync all
   end subroutine test_images_and_coindexed_access


   subroutine test_allocatable_coarray()
      call say("allocatable coarray")

      allocate(arr(3)[*])
      arr = [me, 10*me, 100*me]
      sync all

      if (me == 1) then
         do i = 1, nimg
            print *, "arr(:, image", i, ") =", arr(:)[i]
         end do
      end if

      sync all
      deallocate(arr)
   end subroutine test_allocatable_coarray

 subroutine test_sync_images()
   integer :: left, right

   call say("sync images / remote write")

   left  = merge(me - 1, nimg, me > 1)
   right = merge(me + 1, 1,    me < nimg)

   scalar = -1
   sync all

   scalar[right] = me

   sync all

   print *, "image", me, "received scalar =", scalar, &
            "from left neighbour", left

   sync all
 end subroutine test_sync_images

subroutine test_sync_images_memory()
   integer :: left, right
   integer, allocatable :: partners(:)

   call say("sync images and sync memory")

   left  = merge(me - 1, nimg, me > 1)
   right = merge(me + 1, 1,    me < nimg)

   scalar = -1
   sync all

   ! Each image writes to its right neighbour.
   scalar[right] = me

   ! Ensure remote write is completed before synchronization.
   sync memory

   ! Synchronize with both neighbours, so synchronization is matched.
   if (nimg == 1) then
      sync all
   else if (nimg == 2) then
      sync images(left)
   else
      partners = [left, right]
      sync images(partners)
   end if

   print *, "image", me, "received scalar =", scalar, &
            "from left neighbour", left

   sync all
end subroutine test_sync_images_memory
 
   subroutine test_atomic()
      integer(atomic_int_kind) :: old

      call say("atomic add / atomic ref")

      acount = 0_atomic_int_kind
      sync all

      call atomic_add(acount[1], 1_atomic_int_kind)

      sync all
      if (me == 1) then
         call atomic_ref(old, acount)
         print *, "atomic counter on image 1 =", old, "expected", nimg
      end if

      sync all
   end subroutine test_atomic


   subroutine test_lock()
      integer :: old

      call say("locks")

      scalar = 0
      sync all

      lock(lk[1])
      old = scalar[1]
      scalar[1] = old + 1
      unlock(lk[1])

      sync all
      if (me == 1) then
         print *, "locked counter =", scalar, "expected", nimg
      end if

      sync all
   end subroutine test_lock


   subroutine test_events()
      integer :: src

      call say("events")

      if (nimg < 2) then
         if (me == 1) print *, "Skipping event test: need at least 2 images."
         sync all
         return
      end if

      if (me == 1) then
         scalar = 12345
         event post(ev[2])
      else if (me == 2) then
         event wait(ev)
         src = scalar[1]
         print *, "image 2 received event; scalar[1] =", src
      end if

      sync all
   end subroutine test_events


   subroutine test_collectives()
      integer :: x, y
      integer :: result
      character(len=40) :: msg

      call say("collective subroutines")

      x = me

      y = x
      call co_sum(y)
      if (me == 1) print *, "co_sum(image index) =", y, "expected", nimg*(nimg+1)/2

      y = x
      call co_max(y)
      if (me == 1) print *, "co_max(image index) =", y, "expected", nimg

      y = x
      call co_min(y)
      if (me == 1) print *, "co_min(image index) =", y, "expected", 1

      msg = ""
      if (me == 1) msg = "hello from image 1"
      call co_broadcast(msg, source_image=1)
      print *, "image", me, "after co_broadcast:", trim(msg)

      result = me
      call co_reduce(result, add_int)
      if (me == 1) print *, "co_reduce(add_int) =", result

      sync all
   end subroutine test_collectives

   subroutine test_teams()
      integer :: local_sum

      call say("teams and change team")

      if (nimg < 2) then
         if (me == 1) print *, "Skipping team test: need at least 2 images."
         sync all
         return
      end if

      ! Team 1: odd original images.
      ! Team 2: even original images.
      team_no = merge(1, 2, mod(me,2) == 1)

      form team(team_no, even_odd_team)

      change team(even_odd_team)
         local_sum = this_image()
         call co_sum(local_sum)

         if (this_image() == 1) then
            print *, "original image", me, &
                     "is leader of team", team_number(), &
                     "with num_images() =", num_images(), &
                     "and local co_sum =", local_sum
         end if

         sync all
      end team

      sync all
   end subroutine test_teams

end program caf_feature_test
2 Likes

When will gfortran 16 be available to Ubuntu systems? My sad little dialogue with it this morning is

sudo apt install gfortran
[sudo] password for john: 
gfortran is already the newest version (4:15.2.0-4ubuntu1).
Summary:                    
  Upgrading: 0, Installing: 0, Removing: 0, Not Upgrading: 1495