Transfers one data item from a remote Processing Element (PE).
#include <shmem.h> float shmem_float_g(float *addr, int pe);
This routine provides a very low latency remote read write capability for single elements of most basic types
The function shmem_float_g() transfers a float data item from a remote PE.
Please refer to Atomicity and Coherency section for atomicity and coherence model in the OpenSHMEM documentation
#include <stdlib.h> #include <stdio.h> #include <shmem.h> #define GLOBAL_ARRAY_SIZE 10 #define INT_INIT_VALUE 1234 //can not use #define const float FLOAT_INIT_VALUE = 1234.123456; static float gFloatElement = 0; static float gFloatArray[GLOBAL_ARRAY_SIZE] = {0}; static int gIntElement = 0; static int gIntArray[GLOBAL_ARRAY_SIZE] = {0}; 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 gIntElement is %p\n", &gIntElement); printf("The address of gIntArray is %p\n", gIntArray); printf("The address of gFloatElement is %p\n", &gFloatElement); printf("The address of gFloatArray is %p\n", gFloatArray); if (my_task%2 == 0) { //for int gIntElement = INT_INIT_VALUE; for (int i=0; i<GLOBAL_ARRAY_SIZE; i++) { gIntArray[i] = INT_INIT_VALUE; } //for float gFloatElement = FLOAT_INIT_VALUE; for (int i=0; i<GLOBAL_ARRAY_SIZE; i++) { gFloatArray[i] = FLOAT_INIT_VALUE; } } shmem_barrier_all(); if (my_task%2 == 1) { int src_task = my_task - 1; //for int int element = shmem_int_g(&gIntElement, src_task); if (element != INT_INIT_VALUE) { printf("FAILED: element should be %d instead of %d\n", INT_INIT_VALUE, element); exit(1); } shmem_int_get(gIntArray, gIntArray, GLOBAL_ARRAY_SIZE, src_task); for (int i=0; i<GLOBAL_ARRAY_SIZE; i++) { if (gIntArray[i] != INT_INIT_VALUE) { printf("FAILED, array[%d] should be %d instead of %d\n", i, INT_INIT_VALUE, gIntArray[i]); } } //for float float fElement = shmem_float_g(&gFloatElement, src_task); if (fElement != FLOAT_INIT_VALUE) { printf("FAILED: element should be %f instead of %f\n", FLOAT_INIT_VALUE, fElement); exit(1); } shmem_float_get(gFloatArray, gFloatArray, GLOBAL_ARRAY_SIZE, src_task); for (int i=0; i<GLOBAL_ARRAY_SIZE; i++) { if (gFloatArray[i] != FLOAT_INIT_VALUE) { printf("FAILED, array[%d] should be %f instead of %f\n", i, FLOAT_INIT_VALUE, gFloatArray[i]); } } } shmem_barrier_all(); printf("PASSED\n"); return 0; }
Subroutines: shmem_get, shmem_iget