shmem_float_p

Purpose

Transfers one data item to a remote Processing Element (PE).

C syntax

#include <shmem.h>
 
void shmem_float_p(float *addr, float value, int pe);
 

Parameters

INPUT
addr
The remotely accessible data object which will receive the data on the remote PE.
value
The value to be transferred to addr on the remote PE.
pe
Processing element number of the remote PE.

Description

This routine provides a very low latency remote read write capability for single elements of most basic types

This function starts the remote transfer and may return before the data is delivered to the remote PE. To enforce the ordering/completion of the put routines, the use of shmem_fence, shmem_quiet, shmem_barrier or shmem_barrier_all is needed.

The function shmem_float_p() transfers a float data item to the remote PE.

IBM NOTES

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

C examples

#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);

    // even tasks put value to odd tasks
    if (my_task%2 == 0) {
        int tgt_task = my_task + 1;
   
        //for int
        gIntElement = INT_INIT_VALUE;
        for (int i=0; i<GLOBAL_ARRAY_SIZE; i++) {
            gIntArray[i] = INT_INIT_VALUE;
        }
        
        shmem_int_p(&gIntElement, gIntElement, tgt_task);
        shmem_int_put(gIntArray, gIntArray, GLOBAL_ARRAY_SIZE, tgt_task);

        //for float
        gFloatElement = FLOAT_INIT_VALUE;
        for (int i=0; i<GLOBAL_ARRAY_SIZE; i++) {
            gFloatArray[i] = FLOAT_INIT_VALUE;
        }
        
        shmem_float_p(&gFloatElement, gFloatElement, tgt_task);
        shmem_float_put(gFloatArray, gFloatArray, GLOBAL_ARRAY_SIZE, tgt_task);
    }

    shmem_barrier_all();

    // odd tasks check value
    if (my_task%2 == 1) {
        //for int
        if (gIntElement != INT_INIT_VALUE) {
            printf("FAILED: element should be %d instead of %d\n", INT_INIT_VALUE, gIntElement);
            exit(1);
        }

        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
        if (gFloatElement != FLOAT_INIT_VALUE) {
            printf("FAILED: element should be %f instead of %f\n", FLOAT_INIT_VALUE, gFloatElement);
            exit(1);
        }

        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;
}

Related information

Subroutines: shmem_barrier, shmem_put, shmem_fence, shmem_iput, shmem_quiet


OpenSHMEM API Index