|Using LAPI_Rmw64 is like using LAPI_Rmw, with the |following exceptions: |
This C program is an example of LAPI_Rmw (read-modify-write function):
/* Rmw.c
** Example Program showing use of read modify write function (LAPI_Rmw).
*/
#include <lapi.h>
#include <signal.h>
#include <unistd.h>
#define A_MAX 2
/*
** User error handler function.
*/
void my_err_hndlr (lapi_handle_t *hndl, int *error_code,
lapi_err_t *err_type, int *task_id, int *src)
{
char buf[LAPI_MAX_ERR_STRING];
printf("In my error handler, hndl=%d, error_code=%d, err_type=%d, "
"task_id=%d, src=%d\n", *hndl,*error_code,*err_type,*task_id,*src);
LAPI_Msg_string(*error_code,buf);
printf("In my error handler, error code = %d, error reason = %s\n",
*error_code, buf);
if (*error_code != LAPI_ERR_TIMEOUT)
kill(getpid(),SIGTERM); /* Cause program to exit */
}
int
main(int argc, char **argv) main
{
lapi_handle_t t_hndl; /* LAPI context handle - returned */
lapi_info_t t_info; /* LAPI info structure */
int task_id, /* My task id */
num_tasks; /* Number of tasks in my job */
int t_buf; /* Buffer to manipulate */
int t2_buf; /* Temporary Buffer */
lapi_cntr_t l_cntr; /* Origin counter */
lapi_cntr_t t_cntr; /* Target counter */
void *global_addr[A_MAX]; /* Array to store t_buf addr from */
/* all the tasks. The size of */
/* this array needs to each */
/* number of tasks */
void *tgt_addr[A_MAX]; /* Array to store target counter */
/* addr from all the tasks. */
int loop, rc, tgt, val, cur_val, prev_tgt_val;
char err_msg_buf[LAPI_MAX_ERR_STRING];
int time_out; /* Get current timeout value */
int intr_set; /* Get current interrupt setting */
bzero(&info_lapi, sizeof(lapi_info_t));
t_info.err_hndlr = my_err_hndlr; /* register an error handler */
/* function */
if ((rc = LAPI_Init(&t_hndl, &t_info)) != LAPI_SUCCESS) {
LAPI_Msg_string(rc, err_msg_buf);
printf("Error Message: %s, rc = %d\n", err_msg_buf, rc);
exit (rc);
}
rc = LAPI_Qenv(t_hndl, TASK_ID, &task_id);
rc = LAPI_Qenv(t_hndl, NUM_TASKS, &num_tasks);
if (num_tasks != 2) {
printf("Error Message: Run with MP_PROCS set to 2\n");
LAPI_Term (t_hndl);
exit(1);
}
rc = LAPI_Qenv(t_hndl, TIMEOUT, &time_out); /* Value in seconds */
rc = LAPI_Qenv(t_hndl, INTERRUPT_SET, &intr_set);
if (time_out > 30) {
rc = LAPI_Senv(t_hndl, TIMEOUT, 15); /* Should be > */
/* MIN_TIMEOUT */
}
if (intr_set == 1) {
rc = LAPI_Senv(t_hndl, INTERRUPT_SET, 0); /* Turn off */
/* interrupts */
}
/* Turn off parameter checking - default is on */
rc = LAPI_Senv(t_hndl, ERROR_CHK, 0);
/* Initialize counters to be zero at the start */
rc = LAPI_Setcntr(t_hndl, &l_cntr, 0);
rc = LAPI_Setcntr(t_hndl, &t_cntr, 0);
/* Exchange buffer address to every task */
rc = LAPI_Address_init(t_hndl, &t_buf, global_addr); /* Collective */
/* call */
rc = LAPI_Address_init(t_hndl, &t_cntr, tgt_addr); /* Collective */
/* call */
if (task_id == 0) { /* Task id is 0 , Origin */
tgt = task_id + 1;
t_buf = 1; /* Initial value to add at target */
rc = LAPI_Gfence(t_hndl); /* Global fence to sync before */
/* starting */
rc = LAPI_Rmw(t_hndl, FETCH_AND_ADD, tgt, global_addr[tgt],
&t_buf, &prev_tgt_val, &l_cntr);
/* Wait for local Rmw completion */
rc = LAPI_Waitcntr(t_hndl, &l_cntr, 1, NULL);
printf("Node %d, done issuing Rmw to node %d\n", task_id, tgt);
rc = LAPI_Get(t_hndl,tgt,sizeof(int),global_addr [tgt],
(void *)&t2_buf,tgt_addr [tgt],&l_cntr);
/* Wait for local Get completion */
rc = LAPI_Waitcntr(t_hndl, &l_cntr, 1, NULL);
printf("Node %d, done issuing Get from node %d\n", task_id, tgt);
printf("Result of Get after the Rmw from node %d:\n", tgt);
printf("Correct value should be %d = %d\n",
t_buf + prev_tgt_val, t2_buf);
} else { /* Task id is 1 , Target */
tgt = task_id - 1;
...main
t_buf = 5; /* Set initial buffer value */
rc = LAPI_Gfence(t_hndl); /* Global fence to sync before */
/* starting */
/* Process Get */
rc=LAPI_Getcntr(t_hndl, &t_cntr, &val);
while (val < 1) {
sleep(1); /* Do some work */
rc = LAPI_Probe(t_hndl); /* Poll the adapter once */
rc = LAPI_Getcntr(t_hndl, &t_cntr, &val);
}
/* To clear the t_cntr value */
rc = LAPI_Waitcntr(t_hndl, &t_cntr, 1, &cur_val);
printf("Node %d, done doing work and processing Get\n", task_id);
}
rc = LAPI_Gfence(t_hndl); /* Global fence to sync before */
/* terminating job */
rc = LAPI_Term(t_hndl);
}