Fortran

Guide To Learn

A push notification example

In this section, we’ll build from our tsunami teams example and use events to post updates from the simulation team to the logging team about data being written to disk. While this is technically doable with coarrays alone, you’ll see that events are a perfect candidate for such parallel patterns. Before we jump back into the tsunami, let’s see how events work from a simple push notification example.

Sending a notification from one process to another will be important in any scenario in which you have data dependency between processes. Examples include a long-running data mining job by a worker process, waited on by a process whose role is to write a report for the user (see figure 12.1), or waiting for data to become available on a remote server.

This example will demonstrate using events to wait for another image to complete a long-running job. It doesn’t matter what the actual job is–here, we’ll emulate it by making the image wait for five seconds. When the time is up, the image will send a notification to another image that’s waiting for it. The following listing shows the complete program.

Listing 12.6 A push notification example using events

program push_notification
 
  use iso_fortran_env, only: event_type                             ❶
  implicit none
  type(event_type) :: notification[*]                               ❷
 
  if (num_images() /= 2) error stop &                               ❸
    'This program must be run on 2 images'                          ❸
 
  if (this_image() == 1) then
    print *, 'Image', this_image(), 'working a long job'
    call execute_command_line('sleep 5')                            ❹
    print *, 'Image', this_image(), 'done and notifying image 2'
    event post(notification[2])                                     ❺
  else
    print *, 'Image', this_image(), 'waiting for image 1'
    event wait(notification)                                        ❻
    print *, 'Image', this_image(), 'notified from image 1'
  end if
 
end program push_notification

❶ Imports event_type from the built-in module

❷ Declares an instance of event_type as a coarray

❸ Requires running on two images

❹ Simulates a long job by waiting for five seconds

❺ Posts the event to notification on image 2

❻ On image 2, waits for notification

First, we import event_type and declare a coarray instance of it. Like team_typeevent_type is also provided by the iso_fortran_env module. An event variable must either be declared as a coarray or be a component of a coarray derived type. Then, from image 1, we post the event by executing the event post statement on the notification variable, with image 2 as the target. This increments the event count in the notification variable, which can now be queried or waited for on image 2. On the other side, image 2 issues the matching event wait statement. This statement blocks the execution on image 2 until image 1 has posted the event.

If you compile and run this program, you’ll get

caf push_notification.f90 -o push_notification     ❶
cafrun -n 2 ./push_notification                    ❷
 Image           1 working a long job
 Image           2 waiting for image 1
 Image           1 done and notifying image 2
 Image           2 notified from image 1

❶ Compiles the program using the OpenCoarrays compiler

❷ Runs the program on two images

Notice the order of printed lines in the output. The sequence of operations is set by the event post and event wait statements. Because image 1 is working on a long job (here emulated by sleeping for five seconds), image 2 will announce that it’s waiting for image 1 before it receives the notification and will print that the message was received only after event wait has executed. The following two subsections describe the general syntax of event post and event wait statements.

Running external (system) commands

In listing 12.6, I used a built-in subroutine, execute_command_line, to run an external command and simulate a long job. On Linux, sleep 5 means “wait for five seconds.” You can run any external command by calling execute_command_line. The subroutine will block until the command completes. In general, this is useful for loosely integrating your Fortran programs with external (system) tools and scripts. Fortran itself, however, doesn’t provide a way to capture the output (or error message) of the external command. To do this, you’d have to redirect the output of the command into a file that you’d then read from your Fortran program (see chapter 6).

A push notification example

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top