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; iFAILED, 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; iarray[%d] is: %d\n", i, gIntArray[i]);
}
for (int i=0; iFAILED, 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; iarray[%d] is: %d\n", i, gIntArray[i]);
}
for (int i=0; iFAILED, 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