LAPI_Rmw64 Subroutine

Purpose

Provides data synchronization primitives for 64-bit applications.

Library

Availability Library (liblapi_r.a)

C Syntax

#include <lapi.h>
 
int LAPI_Rmw64(hndl, op, tgt, tgt_var, in_val, prev_tgt_val, org_cntr)
 
lapi_handle_t hndl;
Rmw_ops_t op;
uint tgt;
long long *tgt_var;
long long *in_val;
long long *prev_tgt_val;
lapi_cntr_t *org_cntr;

FORTRAN Syntax

include 'lapif.h'
 
LAPI_RMW64(hndl, op, tgt, tgt_var, in_val, prev_tgt_val, org_cntr,  ierror)

INTEGER hndl
INTEGER op
INTEGER tgt
INTEGER (KIND=LAPI_ADDR_TYPE) :: tgt_var
INTEGER (KIND=LAPI_LONG_LONG_TYPE) :: in_val, prev_tgt_val
TYPE (LAPI_CNTR_T) :: org_cntr
INTEGER ierror

Description

Type of call: point-to-point communication (non-blocking)

This subroutine is the 64-bit version of LAPI_Rmw. It is used to synchronize two independent pieces of 64-bit data, such as two tasks sharing a common data structure. The operation is performed at the target task (tgt) and is atomic. The operation takes an input value (in_val) from the origin and performs one of four operations (op) on a variable (tgt_var) at the target (tgt), and then replaces the target variable (tgt_var) with the results of the operation (op). The original value (prev_tgt_val) of the target variable (tgt_var) is returned to the origin.

The operations (op) are performed over the context referred to by hndl. The outcome of the execution of these calls is as if the following code was executed atomically:
*prev_tgt_val = *tgt_var;
*tgt_var      = f(*tgt_var, *in_val);

where:

f(a,b) = a + b for FETCH_AND_ADD

f(a,b) = a | b for FETCH_AND_OR (bitwise or)

f(a,b) = b for SWAP

For COMPARE_AND_SWAP, in_val is treated as a pointer to an array of two integers, and the op is the following atomic operation:
if(*tgt_var == in_val[0])  {
   *prev_tgt_val = TRUE;
   *tgt_var      = in_val[1];
} else {
   *prev_tgt_val = FALSE;
}

This subroutine can also be used on a 32-bit processor.

All LAPI_Rmw64 calls are non-blocking. To test for completion, use the LAPI_Getcntr and LAPI_Waitcntr subroutines. LAPI_Rmw64 does not include a target counter (tgt_cntr), so LAPI_Rmw64 calls do not provide any indication of completion on the target task (tgt).

Parameters

INPUT
hndl
Specifies the LAPI handle.
op
Specifies the operation to be performed. The valid operations are:
  • COMPARE_AND_SWAP
  • FETCH_AND_ADD
  • FETCH_AND_OR
  • SWAP
tgt
Specifies the task ID of the target task where the read-modify-write (Rmw64) variable resides. The value of this parameter must be in the range 0 <= tgt < NUM_TASKS.
tgt_var
Specifies the target read-modify-write (Rmw64) variable (in FORTRAN) or its address (in C). The value of this parameter cannot be NULL (in C) or LAPI_ADDR_NULL (in FORTRAN).
in_val
Specifies the value that is passed in to the operation (op). This value cannot be NULL (in C) or LAPI_ADDR_NULL (in FORTRAN).
INPUT/OUTPUT
prev_tgt_val
Specifies the location at the origin in which the previous tgt_var on the target task is stored before the operation (op) is executed. The value of this parameter can be NULL (in C) or LAPI_ADDR_NULL (in FORTRAN).
org_cntr
Specifies the origin counter address (in C) or the origin counter (in FORTRAN). If prev_tgt_val is set, the origin counter (org_cntr) is incremented when prev_tgt_val is returned to the origin side. If prev_tgt_val is not set, the origin counter (org_cntr) is updated after the operation (op) is completed at the target side.
OUTPUT
ierror
Specifies a FORTRAN return code. This is always the last parameter.

Restrictions

LAPI statistics are not reported for shared memory communication and data transfer, or for messages that a task sends to itself.

C Examples

  1. To synchronize a data value between two tasks (with FETCH_AND_ADD):
    {
    
          long long local_var;
          long long *addr_list;
    
          /* both tasks initialize local_var to a value        */
    
          /* local_var addresses are exchanged and stored      */
          /* in addr_list (using LAPI_Address_init64)          */
          /* addr_list[tgt] now contains address of            */
          /* local_var on tgt                                  */
          .
          .
          .
          /* add value to local_var on some task               */
    
          /* use LAPI to add value to local_var on remote task */
          LAPI_Rmw64(hndl, FETCH_AND_ADD, tgt, addr_list[tgt],
                     value, prev_tgt_val, &org_cntr);
    
          /* local_var on remote task has been increased       */
          /* by value.  prev_tgt_val now contains value of     */
          /* local_var on remote task before the addition      */
    
    }
  2. To synchronize a data value between two tasks (with SWAP):
    {
    
          long long local_var;
          long long *addr_list;
    
          /* local_var addresses are exchanged and stored           */
          /* in addr_list (using LAPI_Address_init64).              */
          /* addr_list[tgt] now contains the address of             */
          /* local_var on tgt.                                      */
          .
          .
          .
          /* local_var is assigned some value                       */
    
          /* assign local_var to local_var on the remote task       */
          LAPI_Rmw64(hndl, SWAP, tgt, addr_list[tgt],
                     local_var, prev_tgt_val, &org_cntr);
    
          /* local_var on the remote task is now equal to local_var */
          /* on the local task. prev_tgt_val now contains the value */
          /* of local_var on the remote task before the swap.       */
    
    }
  3. To conditionally swap a data value (with COMPARE_AND_SWAP):
    {
    
          long long local_var;
          long long *addr_list;
          long long in_val[2];
    
          /* local_var addresses are exchanged and stored        */
          /* in addr_list (using LAPI_Address_init64).           */
          /* addr_list[tgt] now contains the address of          */
          /* local_var on tgt.                                   */
          .
          .
          .
          /* if local_var on remote_task is equal to comparator, */
          /* assign value to local_var on the remote task        */
    			
          in_val[0] = comparator;
          in_val[1] = value;
    
          LAPI_Rmw64(hndl, COMPARE_AND_SWAP, tgt, addr_list[tgt],
                     in_val, prev_tgt_val, &org_cntr);
    
          /* local_var on remote task is now in_val[1] if it     */
          /* had previously been equal to in_val[0]. If the      */ 
          /* swap was performed, prev_tgt_val now contains       */ 
          /* TRUE; otherwise, it contains FALSE.                 */
    
    }

Return Values

LAPI_SUCCESS
Indicates that the function call completed successfully.
LAPI_ERR_HNDL_INVALID
Indicates that the hndl passed in is not valid (not initialized or in terminated state).
LAPI_ERR_IN_VAL_NULL
Indicates that the in_val pointer is NULL (in C) or that the value of in_val is LAPI_ADDR_NULL (in FORTRAN).
LAPI_ERR_RMW_OP
Indicates that op is not valid.
LAPI_ERR_TGT
Indicates that the tgt passed in is outside the range of tasks defined in the job.
LAPI_ERR_TGT_PURGED
Indicates that the subroutine returned early because LAPI_Purge_totask() was called.
LAPI_ERR_TGT_VAR_NULL
Indicates that the tgt_var address is NULL (in C) or that the value of tgt_var is LAPI_ADDR_NULL (in FORTRAN).

Location

/usr/lib/liblapi_r.a