Non Blocking Channel Operations in Fortran

Our first example demonstrates non-blocking channel operations in Fortran. While Fortran doesn’t have built-in channels or select statements like Go, we can simulate similar behavior using coarrays and non-blocking synchronization.

program non_blocking_operations
  use iso_fortran_env
  implicit none

  integer :: this_image, num_images
  character(len=20) :: message
  logical :: flag

  this_image = this_image()
  num_images = num_images()

  ! Simulate non-blocking receive
  if (this_image == 1) then
    call simulate_non_blocking_receive()
  end if

  ! Simulate non-blocking send
  if (this_image == 1) then
    call simulate_non_blocking_send()
  end if

  ! Simulate multi-way non-blocking select
  if (this_image == 1) then
    call simulate_multi_way_non_blocking_select()
  end if

contains

  subroutine simulate_non_blocking_receive()
    logical :: received
    
    call co_broadcast(message, source_image=2)
    call co_reduce(flag, logical_and)
    
    if (flag) then
      print *, "received message", message
    else
      print *, "no message received"
    end if
  end subroutine simulate_non_blocking_receive

  subroutine simulate_non_blocking_send()
    logical :: sent
    
    message = "hi"
    call co_broadcast(message, source_image=1)
    call co_reduce(sent, logical_and)
    
    if (sent) then
      print *, "sent message", message
    else
      print *, "no message sent"
    end if
  end subroutine simulate_non_blocking_send

  subroutine simulate_multi_way_non_blocking_select()
    logical :: received_message, received_signal
    
    call co_broadcast(message, source_image=2)
    call co_reduce(received_message, logical_and)
    
    call co_broadcast(flag, source_image=3)
    call co_reduce(received_signal, logical_and)
    
    if (received_message) then
      print *, "received message", message
    else if (received_signal) then
      print *, "received signal", flag
    else
      print *, "no activity"
    end if
  end subroutine simulate_multi_way_non_blocking_select

end program non_blocking_operations

In this Fortran example, we use coarrays and non-blocking synchronization to simulate the behavior of non-blocking channel operations. The program is designed to run on multiple images (Fortran’s equivalent to processes or threads).

  1. We simulate a non-blocking receive operation. If a message is available from image 2, it’s received and printed. Otherwise, it prints “no message received”.

  2. We then simulate a non-blocking send operation. It attempts to send a message “hi” to other images. If the send is successful, it prints “sent message hi”. Otherwise, it prints “no message sent”.

  3. Finally, we simulate a multi-way non-blocking select. It checks for both a message from image 2 and a signal from image 3. If either is received, it prints the appropriate message. If neither is received, it prints “no activity”.

To run this Fortran program:

$ gfortran -coarray=single non_blocking_operations.f90 -o non_blocking_operations
$ ./non_blocking_operations

Note that this is a simplified simulation of non-blocking operations. In a real-world scenario, you would need to implement more sophisticated synchronization and communication mechanisms between images.