## shmem_int_iget

#### Purpose

Transfers strided data from a specified processing element (PE).

#### C syntax

    #include <shmem.h>

    void shmem_int_iget(int *target, const int *source, ptrdiff_t tst, ptrdiff_t sst, size_t len, int pe);

#### Parameters

INPUT
target
  Local strided array to be updated.
source
  Remotely accessible strided array on the remote PE that contains the data to be copied.
tst
  The stride between consecutive elements of the target array. The stride is scaled by the element size of the target array. A value of 1 indicates contiguous data.
sst
  The stride between consecutive elements of the source array. The stride is scaled by the element size of the source array. A value of 1 indicates contiguous data.
len
  Number of elements in the target and source arrays.
pe
  Processing element number of the remote PE

#### Description

This input routine provides a high-performance method for copying a strided array from a remote PE to a local strided array

The routine returns when the data has been copied into the local target array.

The function shmem_int_iget() reads strided array of type integer from the remote PE.

#### IBM NOTES

Please refer to Atomicity and Coherency section for atomicity and coherence model in the OpenSHMEM documentation

#### C examples

    #include <pthread.h>
    #include <signal.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <assert.h>

    #include <stdlib.h>
    #include <stdio.h>

    #include <shmem.h>

    #define GLOBAL_ARRAY_SIZE     20
    //source stride
    #define WTHREAD1_SOURCE_STRIDE 1
    #define WTHREAD2_SOURCE_STRIDE 2
    #define WTHREAD3_SOURCE_STRIDE 3
    //target stride
    #define TARGET_STRIDE         3
    #define NUM_OF_TRANS_ELEM     5

    static int gIntArray[GLOBAL_ARRAY_SIZE] = {0};
    pthread_mutex_t mtx;

    void * wthread1(void * para)
    {
        pthread_mutex_lock(&mtx);
        assert(para);
        int* p_data = (int*)para;
        int src_task = *p_data;
        shmem_int_iget(gIntArray, gIntArray, TARGET_STRIDE, WTHREAD1_SOURCE_STRIDE, NUM_OF_TRANS_ELEM, src_task);

        printf("wthread1----->The Targe Stride is: %d, the following data have been got.\n", TARGET_STRIDE);
        for (int i=0; i<TARGET_STRIDE*NUM_OF_TRANS_ELEM; i=i+TARGET_STRIDE) {
            printf("wthread1----->array[%d] is: %d\n", i, gIntArray[i]);
        }

        for (int i=0; i<TARGET_STRIDE*NUM_OF_TRANS_ELEM; i=i+TARGET_STRIDE) {
            if (gIntArray[i] != i*WTHREAD1_SOURCE_STRIDE/TARGET_STRIDE) {
                printf("wthread1----->FAILED, array[%d] should be %d instead of %d\n", i, i*WTHREAD1_SOURCE_STRIDE/TARGET_STRIDE, gIntArray[i]);
                exit(1);
            }
        }
        pthread_mutex_unlock(&mtx);
        return NULL;
    }

    void * wthread2(void * para)
    {
        pthread_mutex_lock(&mtx);
        assert(para);
        int* p_data = (int*)para;
        int src_task = *p_data;
        shmem_int_iget(gIntArray, gIntArray, TARGET_STRIDE, WTHREAD2_SOURCE_STRIDE, NUM_OF_TRANS_ELEM, src_task);

        printf("wthread2----->The Targe Stride is: %d, the following data have been got.\n", TARGET_STRIDE);
        for (int i=0; i<TARGET_STRIDE*NUM_OF_TRANS_ELEM; i=i+TARGET_STRIDE) {
            printf("wthread2----->array[%d] is: %d\n", i, gIntArray[i]);
        }

        for (int i=0; i<TARGET_STRIDE*NUM_OF_TRANS_ELEM; i=i+TARGET_STRIDE) {
            if (gIntArray[i] != i*WTHREAD2_SOURCE_STRIDE/TARGET_STRIDE) {
                printf("wthread2----->FAILED, array[%d] should be %d instead of %d\n", i, i*WTHREAD2_SOURCE_STRIDE/TARGET_STRIDE, gIntArray[i]);
                exit(1);
            }
        }
        pthread_mutex_unlock(&mtx);
        return NULL;
    }

    void * wthread3(void * para)
    {
        pthread_mutex_lock(&mtx);
        assert(para);
        int* p_data = (int*)para;
        int src_task = *p_data;
        shmem_int_iget(gIntArray, gIntArray, TARGET_STRIDE, WTHREAD3_SOURCE_STRIDE, NUM_OF_TRANS_ELEM, src_task);

        printf("wthread3----->The Targe Stride is: %d, the following data have been got.\n", TARGET_STRIDE);
        for (int i=0; i<TARGET_STRIDE*NUM_OF_TRANS_ELEM; i=i+TARGET_STRIDE) {
            printf("wthread3----->array[%d] is: %d\n", i, gIntArray[i]);
        }

        for (int i=0; i<TARGET_STRIDE*NUM_OF_TRANS_ELEM; i=i+TARGET_STRIDE) {
            if (gIntArray[i] != i*WTHREAD3_SOURCE_STRIDE/TARGET_STRIDE) {
                printf("wthread3----->FAILED, array[%d] should be %d instead of %d\n", i, i*WTHREAD3_SOURCE_STRIDE/TARGET_STRIDE, gIntArray[i]);
                exit(1);
            }
        }
        pthread_mutex_unlock(&mtx);
        return NULL;
    }

    int main (int argc, char* argv[])
    {

        int total_tasks = -1;
        int my_task = -1;

        start_pes(0);
        total_tasks = _num_pes();

        if (total_tasks <= 0) {
            printf("FAILED\n");
            exit(1);
        } else {
            printf("number of pes is %d\n", total_tasks);
        }

        if (total_tasks < 2 || total_tasks % 2) {
            printf("FAILED: The number of pes should be an even number. (at least 2)\n");
            exit(1);
        }

        my_task = _my_pe();

        if (my_task < 0){
            printf("FAILED\n");
            exit(1);
        } else {
            printf("my pe id is %d\n", my_task);
        }

        printf("The address of gIntArray is %p\n", gIntArray);

        if (my_task%2 == 0) {
            //for int
            for (int i=0; i<GLOBAL_ARRAY_SIZE; i++) {
                gIntArray[i] = i;
            }

            printf("The Wthread1--->Source Stride is: %d, the following data will be got.\n", WTHREAD1_SOURCE_STRIDE);
            for (int i=0; i<WTHREAD1_SOURCE_STRIDE*NUM_OF_TRANS_ELEM; i=i+WTHREAD1_SOURCE_STRIDE) {
                printf("array[%d] is: %d\n", i, gIntArray[i]);
            }

            printf("The Wthread2--->Source Stride is: %d, the following data will be got.\n", WTHREAD2_SOURCE_STRIDE);
            for (int i=0; i<WTHREAD2_SOURCE_STRIDE*NUM_OF_TRANS_ELEM; i=i+WTHREAD2_SOURCE_STRIDE) {
                printf("array[%d] is: %d\n", i, gIntArray[i]);
            }

            printf("The Wthread3--->Source Stride is: %d, the following data will be got.\n", WTHREAD3_SOURCE_STRIDE);
            for (int i=0; i<WTHREAD3_SOURCE_STRIDE*NUM_OF_TRANS_ELEM; i=i+WTHREAD3_SOURCE_STRIDE) {
                printf("array[%d] is: %d\n", i, gIntArray[i]);
            }
        }

        shmem_barrier_all();

        if (my_task%2 == 1) {
            int src_task = my_task - 1;
            // multi_threads testing
            int rc;
            pthread_t tid1;
            pthread_t tid2;
            pthread_t tid3;
            rc = ::pthread_create(&tid1, NULL, wthread1, &src_task);
            if (rc !=0) {
                printf("Creating thread1 failed");
                exit(1);
            }
            rc = ::pthread_create(&tid2, NULL, wthread2, &src_task);
            if (rc !=0) {
                printf("Creating thread2 failed");
                exit(1);
            }
            rc = ::pthread_create(&tid3, NULL, wthread3, &src_task);
            if (rc !=0) {
                printf("Creating thread3 failed");
                exit(1);
            }

            // wait until wthread to exit
            if (::pthread_kill(tid1, 0) == 0)
                ::pthread_join(tid1, NULL);
            if (::pthread_kill(tid2, 0) == 0)
                ::pthread_join(tid2, NULL);
            if (::pthread_kill(tid3, 0) == 0)
                ::pthread_join(tid3, NULL);
        }

        shmem_barrier_all();

        printf("PASSED\n");
        return 0;
    }

#### Related information

Subroutines: shmem_int_g, shmem_get

OpenSHMEM API Index