Channel Directions in Chapel

Chapel supports channel-like constructs called synchronization variables. These can be used to communicate between tasks, similar to how channels are used in other languages. Here’s an example demonstrating the use of sync variables for inter-task communication:

use IO;

// This `ping` function only accepts a sync variable for sending
// values. It would be a compile-time error to try to
// receive on this variable.
proc ping(ref pings: sync string, msg: string) {
  pings.writeXF(msg);
}

// The `pong` function accepts one sync variable for receives
// (`pings`) and a second for sends (`pongs`).
proc pong(ref pings: sync string, ref pongs: sync string) {
  var msg = pings.readFE();
  pongs.writeXF(msg);
}

proc main() {
  var pings: sync string;
  var pongs: sync string;
  
  begin ping(pings, "passed message");
  begin pong(pings, pongs);
  
  writeln(pongs.readFE());
}

In this Chapel code:

  1. We define a ping function that takes a sync string variable by reference and a message string. It writes the message to the sync variable using writeXF().

  2. The pong function takes two sync string variables by reference. It reads from pings using readFE() and writes to pongs using writeXF().

  3. In the main function, we create two sync string variables: pings and pongs.

  4. We use begin statements to start two tasks: one calling ping and another calling pong.

  5. Finally, we read and print the message from the pongs sync variable.

To run the program, save it as sync_directions.chpl and use the Chapel compiler:

$ chpl sync_directions.chpl
$ ./sync_directions
passed message

This example demonstrates how Chapel’s sync variables can be used for inter-task communication, similar to channel directions in other languages. The sync type ensures proper synchronization between tasks.