Next: , Previous: , Up: Communication statements   [Contents][Index]


4.4.2 Sending

The SEND statement is fundamental to coNCePTuaL. It is used to send a multiple messages from multiple source tasks to multiple target tasks. The syntax is formally specified as follows:

<send_stmt> ::= <source_task>
[ ASYNCHRONOUSLY] SENDS
<message_spec>
TO [ UNSUSPECTING] <target_tasks>
| <source_task>
[ ASYNCHRONOUSLY] SENDS
<message_spec>
TO <target_tasks>
WHO RECEIVE IT
<recv_message_spec>

<source_task> is described in Source tasks; <message_spec> and <recv_message_spec> are described in Message specifications; and, <target_tasks> is described in Target tasks.

The SEND statement’s simplest form, “ <source_task> SENDS <message_spec> TO <target_tasks>”, is fairly straightforward. The following is a example:

TASK 0 SENDS A 0 BYTE MESSAGE TO TASK 1

The only subtlety in the preceding statement is that it implicitly causes task 1 to perform a corresponding receive. This receive can be suppressed by adding the keyword UNSUSPECTING before the <target_tasks> description:

TASK 0 SENDS A 0 BYTE MESSAGE TO UNSUSPECTING TASK 1

Here are some further examples of valid <send_stmt>s:

There are a number of attributes associated with every message transmission:

A few of those appear in the preceding examples.

When UNSUSPECTING is omitted, the implicit RECEIVE statement normally inherits all of the attributes of the corresponding SEND. However, the second form of a <send_stmt>, which contains a WHO RECEIVES IT (or WHO RECEIVES THEM) clause, enables the receiver’s attributes to be overridden on a per-attribute basis. For instance, consider the following SEND statement:

TASK 0 SENDS A 1 MEGABYTE MESSAGE TO TASK 1 WHO RECEIVES IT
ASYNCHRONOUSLY

The alternative sequence of statements that does not use WHO RECEIVES IT is less straightforward to read because it splits a single message transmission into two statements:

  1. TASK 1 ASYNCHRONOUSLY RECEIVES A 1 MEGABYTE MESSAGE FROM TASK 0
  2. TASK 0 SENDS A 1 MEGABYTE MESSAGE TO UNSUSPECTING TASK 1

Some further examples of WHO RECEIVES IT follow:

TASKS left SUCH THAT left IS EVEN SEND 5 2 KILOBYTE 64 BYTE ALIGNED
MESSAGES TO TASKS left+1 WHO RECEIVE THEM AS UNALIGNED MESSAGES WITH
DATA TOUCHING

TASK num_tasks-1 ASYNCHRONOUSLY SENDS A 1E5 BYTE MESSAGE WITH
VERIFICATION TO TASK 0 WHO RECEIVES IT SYNCHRONOUSLY

TASK leaf SUCH THAT KNOMIAL_CHILDREN(leaf,2)=0 SENDS A UNIQUE 1536
BYTE MESSAGE WITH DATA TOUCHING TO TASK KNOMIAL_PARENT(leaf,2) WHO
RECEIVES IT ASYNCHRONOUSLY AS A NONUNIQUE QUADWORD ALIGNED MESSAGE
WITHOUT DATA TOUCHING INTO BUFFER KNOMIAL_PARENT(leaf,2)

One subtlety of the SEND statement when used without UNSUSPECTING involves the orderings of the sends and receives. The rule is that receives are posted before sends. Furthermore, <restricted_ident>s (see Restricted identifiers) are evaluated in order from 0 to num_tasks-1. The implication is that a statement such as ‘TASKS ev SUCH THAT ev IS EVEN /\ ev<6 SEND A 4 WORD MESSAGE TO TASK ev+2’ is exactly equivalent to the following ordered sequence of statements (assuming num_tasks >= 5):

  1. TASK 2 RECEIVES A 4 WORD MESSAGE FROM TASK 0
  2. TASK 4 RECEIVES A 4 WORD MESSAGE FROM TASK 2
  3. TASK 6 RECEIVES A 4 WORD MESSAGE FROM TASK 4
  4. TASK 0 SENDS A 4 WORD MESSAGE TO UNSUSPECTING TASK 2
  5. TASK 2 SENDS A 4 WORD MESSAGE TO UNSUSPECTING TASK 4
  6. TASK 4 SENDS A 4 WORD MESSAGE TO UNSUSPECTING TASK 6

(The RECEIVE statement is described in Receiving.)

If the above sequence were executed, tasks 2, 4, and 6 would immediately block on their receives (steps 1–3) . Task 0 would awaken task 2 by sending it a message (step 4). Then, task 2 would be able to continue to step 5 at which point it would send a message to task 4. Task 4 would then finally be able to send a message to task 6 (step 6). Hence, even though the original coNCePTuaL statement encapsulates multiple communication operations, the component communications proceed sequentially because of data dependences and because the operations are blocking.

As another example of send/receive ordering, consider the statement, ‘TASKS x SUCH THAT x IS IN {1,4,5} SEND A 768 BYTE MESSAGE FROM 4 DOUBLEWORDS INTO THE DEFAULT BUFFER TO TASKS y SUCH THAT y IS IN {6,2,3}’. This statement causes nine messages to be sent and received and in the following order: 1 ⇒ 2 , 1 ⇒ 3, 1 ⇒ 6 , 4 ⇒ 2, 4 ⇒ 3 , 4 ⇒ 6, 5 ⇒ 2 , 5 ⇒ 3, 5 ⇒ 6 . The reason that task 6 receives from each sender after tasks 2 and 3 relates to the comment above that <restricted_ident>s are evaluated in order from 0 to num_tasks-1 . One can therefore think of the preceding coNCePTuaL statement as being implemented with the following pseudocode:

for s := 0 to num_tasks-1 do
  if s is in {1, 4, 5} then
    for r := 0 to num_tasks-1 do
      if r is in {6, 2, 3} then
        r receives from s
for s := 0 to num_tasks-1 do
  if s is in {1, 4, 5} then
    for r := 0 to num_tasks-1 do
      if r is in {6, 2, 3} then
        s sends to r

Next: , Previous: , Up: Communication statements   [Contents][Index]

Scott Pakin, pakin@lanl.gov