Communication Basics
Introducing coNCePTuaL communication

Specifying senders and receivers

Sending messages from task to task is central to any nontrivial coNCePTuaL program. Consequently, the language makes it exceptionally easy to send messages, as demonstrated by the following example:

Task 0 sends a message to task 1

As expected, the preceding line of code—itself a complete program that can be compiled and run—instructs the task with task number 0 to send a message to the task with task number 1. More subtly, it also instructs task 1 to receive a message sent to it by task 0. All other tasks (if any) do nothing. If the program is run with a single task, task  will also quietly do nothing. In some communication libraries, sending to a nonexistent task hangs or crashes the program; in coNCePTuaL it's perfectly safe to send a message to a nonexistent task.

Messages don't have to be sent individually. A single statement can specify multiple senders and/or multiple receivers. The following statement causes the middle task to send a message to each other task in turn:

Task num_tasks/2 sends a message to all other tasks

num_tasks is a predefined variable set equal to the total number of tasks in the program. num_tasks/2 refers to half that number (i.e., the middle task).

coNCePTuaL provides a rich set of operators for specifying tasks. In the following code, each task with an odd task number sends a message to every fourth task. For example, in a 10-task run, tasks 1, 3, 5, 7, and 9 would each send to each of tasks 0, 4, and 8 for a total of 15 separate messages.

Tasks src such that src is odd sends a message to tasks dst such that 4 divides dst

Specifying message attributes

All of the code examples in the previous section utilize the default messaging attributes:

We now examine how to alter each attribute in turn.

Message count

Task 0 sends 100 messages to task 1

Message size

Task 0 sends a 4 kilobyte message to task 1

Nonblocking communication

Task 0 asynchronously sends a message to task 1

Buffer control

The following code uses a different message buffer every time it executes:

Task 0 sends a unique message to task 1

The following code explicitly specifies a buffer (#7) and uses that even if other buffers are idle:

Task 0 sends a message from buffer 7 to task 1

Buffer alignment

The following ensures that the send and receive message buffers lie at a memory location whose address is divisible by 128 (0, 128, 256, 384, …):

Task 0 sends a 128-byte-aligned message to task 1

The following ensures that the send and receive message buffers lie at a memory location whose address is 128 bytes past a page boundary. Assuming that the operating system uses 4096-byte pages, the buffers can therefore lie at one of addresses 0, 4224, 8320, 12416, ….

Task 0 sends a 128-byte-misaligned message to task 1

Accessing message content

Messages in coNCePTuaL are opaque. It is not possible for a program to examine message contents. However, two message attributes enable particular operations to be performed on message data. The following code instructs the sender to touch (read and write) every word of the message before sending it and the receiver to touch every word of the message after receiving it. The goal is to ensure that the messages are warm in the cache, which may be a more realistic modus operandi than communicating data that is never used.

Task 0 sends a 4 kilobyte message with data touching to task 1

Alteratively, coNCePTuaL can check message contents for bit errors. The implementation actually examines every bit of the message and can therefore detect errors that slip by a checksum or CRC calculation:

Task 0 sends a 4 kilobyte message with verification to task 1

The predefined bit_errors variable stores the number of incorrect bits detected by the receiver when receiving a message sent with verification.

Specifying multiple attributes

Although we presented each message attribute individually, combinations are of course possible. The following code specifies all attributes at once just to prove that doing so is valid:

Task 0 asynchronously sends 100 4-kilobyte 128-byte-aligned messages with verification from buffer 7 to task 1

Summary of concepts

Let's review what we learned on this page:

  1. coNCePTuaL programs specify task-to-task communication.
  2. A single statement can specify multiple sending tasks and multiple receiving tasks.
  3. A variety of message attributes provide precise control over the number, size, blocking behavior, buffer use, buffer alignment, and content disposition of messages.
Scott Pakin, pakin@lanl.gov