Transfers strided data from a specified processing element (PE).
#include <shmem.h> void shmem_int_iget(int *target, const int *source, ptrdiff_t tst, ptrdiff_t sst, size_t len, int pe);
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.
Please refer to Atomicity and Coherency section for atomicity and coherence model in the OpenSHMEM documentation
#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; iarray[%d] is: %d\n", i, gIntArray[i]); } for (int i=0; i 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 array[%d] is: %d\n", i, gIntArray[i]); } for (int i=0; i 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 array[%d] is: %d\n", i, gIntArray[i]); } for (int i=0; i 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; }
Subroutines: shmem_int_g, shmem_get