| <html>
|
| <head>
|
| <title>shmem_int_iget</title>
|
| </head>
|
| <h2 id="top">shmem_int_iget</h2>
|
| <h4>Purpose</h4>
|
|
|
|
|
| <p>Transfers strided data from a specified processing element (PE).
|
| </p>
|
|
|
| <h4>C syntax</h4>
|
|
|
| <pre>
|
| #include <shmem.h>
|
|
|
| void shmem_int_iget(int *target, const int *source, ptrdiff_t tst, ptrdiff_t sst, size_t len, int pe);
|
|
|
| </pre>
|
|
|
| <h4>Parameters</h4>
|
|
|
|
|
| <dl>
|
| <dt class="bold">INPUT</dt>
|
| <dd>
|
|
|
| </dd>
|
| <dt class="bold ">target</dt>
|
| <dd>Local strided array to be updated.
|
| </dd>
|
| <dt class="bold ">source</dt>
|
| <dd>Remotely accessible strided array on the remote PE that contains the data to be copied.
|
| </dd>
|
| <dt class="bold">tst</dt>
|
| <dd>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.
|
| </dd>
|
| <dt class="bold ">sst</dt>
|
| <dd>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.
|
| </dd>
|
| <dt class="bold ">len</dt>
|
| <dd>Number of elements in the target and source arrays.
|
| </dd>
|
| <dt class="bold ">pe</dt>
|
| <dd>Processing element number of the remote PE</dd>
|
| </dl>
|
| <h4>Description</h4>
|
|
|
| <div class="ledi">
|
| <p>This input routine provides a high-performance method for copying a
|
| strided array from a remote PE to a local strided array</p>
|
| <p>The routine returns when the data has been copied into the local target array.</p>
|
| <p>The function shmem_int_iget() reads strided array of type integer from the
|
| remote PE.</p>
|
|
|
|
|
| <h4>IBM NOTES</h4>
|
| <div class="ledi">
|
| <dl>
|
| <p>Please refer to Atomicity and Coherency section for atomicity and coherence model in the OpenSHMEM documentation</p>
|
| </dd>
|
| </dl>
|
|
|
| <h4>C examples</h4>
|
| <pre>
|
| #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;
|
| }
|
| </pre>
|
|
|
|
|
| <h4>Related information</h4>
|
|
|
| <p>Subroutines: shmem_int_g, shmem_get
|
| </p>
|
| <hr><a href="apiIndex.html">OpenSHMEM API Index</a> |
| </html> |