IBM Books

Administration Guide


putv_multi_gen (C)

This C program is an example of transferring noncontiguous data using the LAPI vector transfer function:

/* putv_multi_gen.c
** Example Program showing use of the LAPI vector transfer function.
*/
 
#include <stdio.h>
#include <assert.h>
#include "lapi.h"
 
#define MAX_TASKS             4           /* Max tasks in the parallel job */
#define MAX_GLOBAL_ADDR      16           /* Max size of local address table */
#define ARR_SZ          8280000           /* Size of array */
#define NUM_ITER             10           /* Max number of iterations */
#define NUM_TIMES             4
 
extern double microsecond();             /* defined in the timer library */
 
int sizes[] = {3,4,9, 16, 30, 64, 128, 171, 256, 353,1000};
lapi_handle_t     hndl;                           /* Handle to the lapi context */
lapi_info_t       info_lapi;                      /* to be passed to LAPI_Init */
 
int   myid, numtasks;                     /* taskid and numtasks in || job */
 
#define ROWS                353
#define COLUMNS            3000
 
char         g1[ROWS][COLUMNS];           /* Array which w   */
 
lapi_vec_t  org_vec,tgt_vec;
 
void        *g1_addr[MAX_TASKS];         /* Address of g1 of other tasks */
lapi_vec_t  *vec_addr[MAX_TASKS];        /* Address of g1 of other tasks */
void        *global_addr[MAX_TASKS];     /* Address of global_address tables
                                         ** of each task
                                         */
void        *local_addr[MAX_GLOBAL_ADDR]; /* Address of local address table */
lapi_cntr_t c1, c2, c3;                  /* LAPI counters */
lapi_cntr_t *c1_addr[MAX_TASKS], *c2_addr[MAX_TASKS], *c3_addr[MAX_TASKS];
                                         /* Address of counters on each task */
double results[NUM_TIMES];
 
/*
** Macros to turn interrupts on and off, and to turn error checking off
*/
#define INTR_ON       LAPI_Senv(hndl, INTERRUPT_SET, 1) /* Turn interrupts on*/
#define INTR_OFF      LAPI_Senv(hndl, INTERRUPT_SET, 0) /* Turn inter off */
#define INTR_CNT(num) LAPI_Qenv(hndl, 22, &(num))
#define INTR_CNT_OFF  LAPI_Senv(hndl, 22, 0)
#define ERR_CHK_OFF   LAPI_Senv(hndl, ERROR_CHK, 0)   /* Turn error checking off*/
 
/*
** Function: This measures Putv bandwidth for a given message size by sending
**           a message from task 0 to task 1 and returning the message
**           from task 1 to task 0.
*/
void
rr_one_way_lat(int cnt)
{
    double t0, t1, t1_pr, t1_dpr, diff;
    int i, rc, tmp_cntr = 0;
 
    diff = 0.0;
 
    t0 = microsecond();
    for (i=0;i<NUM_ITER; i++) {
        if (myid == 0)    {
            //g1[1] = 1024;
            rc=LAPI_Putv(hndl, 1, &tgt_vec, &org_vec, c1_addr[1], NULL, NULL);
            LAPI_Waitcntr(hndl, &c1, 1, NULL);
        } else if (myid == 1) {
         LAPI_Waitcntr(hndl, &c1, 1, NULL);
         rc=LAPI_Putv(hndl, 0, &tgt_vec, &org_vec, c1_addr[0], NULL, NULL);
        }
    }
    t1 = microsecond();
 
    if (myid == 0) {
        results[0] = (t1 - t0)/(2.0 * NUM_ITER);
        results[0] = (cnt*cnt*8)/(results[0]);
    }
}
 
/*
** Function: This runs the rr_one_way_lat function for various message sizes
**           and prints the results.
*/
void
run_tests(int i)
{
    int rc, cnt;
 
    INTR_OFF;
 
    for (cnt=0; cnt < 1; cnt++)  {
        rr_one_way_lat(i);
    }
    if (myid == 0)
        for(cnt=0; cnt < 1; cnt++)
            printf("Putv bandwidth (gen) for %d X %d array = %lf\n", i,i,results[cnt]);
}
 
/*
** Main function.
** Sets up the LAPI environment, initialized variables, counters, and addresses
** and calls run_tests.
*/
 
main()
{
    int  i,j,k,rc, cntr, partner;
    uint addr_ptr;
 
    /* Initialize global data structures to 0 */
    init_stamp(NULL, NULL);
    bzero(g1, sizeof(g1));
    bzero(local_addr, sizeof(local_addr));
    bzero(global_addr, sizeof(global_addr));
    bzero(&info_lapi, sizeof(lapi_info_t));
 
    rc = LAPI_Init(&hndl, &info_lapi);    /* Initialize the LAPI library */
    assert(rc == 0);
 
 
    /* Query LAPI library for taskid and number of tasks in job  */
    rc = LAPI_Qenv(hndl, TASK_ID, &myid);
    rc = LAPI_Qenv(hndl, NUM_TASKS, &numtasks);
    LAPI_Senv(hndl, ERROR_CHK,0);
    if (myid == 0) partner = 1; else partner = 0;
 
    /* Initialize LAPI counters */
    rc = LAPI_Setcntr(hndl, &c1, 0);
    rc = LAPI_Setcntr(hndl, &c2, 0);
    rc = LAPI_Setcntr(hndl, &c3, 0);
 
 
    /* Fill in local address table */
    rc = LAPI_Address(g1, (uint *)&local_addr[0]);
 
    /* Exchange local address table with every task */
    rc = LAPI_Address_init(hndl, local_addr, global_addr);
 
    /* Exchange other address of importance to LAPI like g1, and counters */
    rc = LAPI_Address_init(hndl, (void *)g1, g1_addr);
 
    rc = LAPI_Address_init(hndl, (void *)&org_vec, (void *)vec_addr);
    rc = LAPI_Address_init(hndl, (void *)&c1, (void *)c1_addr);
    rc = LAPI_Address_init(hndl, (void *)&c2, (void *)c2_addr);
    rc = LAPI_Address_init(hndl, (void *)&c3, (void *)c3_addr);
    // ERR_CHK_OFF;
 
    rc = LAPI_Gfence(hndl);
 
    for (k=0; k < 11; k++) {
         i = sizes[k];
 
         org_vec.vec_type = LAPI_GEN_IOVECTOR;
         org_vec.num_vecs  = i;
         org_vec.info = (void **) malloc(i * sizeof(void *));
         for (j=0;j<i;j++)
              org_vec.info[j] = (void *) g1[j];
         org_vec.len =  (uint *) malloc(i * sizeof(uint));
         for (j=0;j<i;j++)
            org_vec.len[j] =  i*8;
 
        tgt_vec.vec_type = LAPI_GEN_IOVECTOR;
        tgt_vec.num_vecs  = i;
        tgt_vec.info = (void **) malloc(i * sizeof(void *));
 
        for (j=0;j<i;j++)
             tgt_vec.info[j] = (void *) (g1_addr[partner] +j*COLUMNS);
        tgt_vec.len =  (uint *) malloc(i * sizeof(uint));
        for (j=0;j<i;j++)
            tgt_vec.len[j] =  i*8;
 
        run_tests(i);                                 /* Run various LAPI tests */
 
        rc = LAPI_Gfence(hndl);
        free(org_vec.info);
        free(tgt_vec.info);
  }
 
    rc = LAPI_Term(hndl);
}


[ Top of Page | Previous Page | Next Page | Table of Contents | Index ]