## 8.2.1. Examples

Up: Generalized Requests Next: Associating Information with Status Previous: Generalized Requests

Example This example shows the code for a user-defined reduce operation on an `int` using a binary tree: each non-root node receives two messages, sums them, and sends them up. We assume that no status is returned and that the operation cannot be cancelled.

    typedef struct {
       MPI_Comm comm;
       int tag;
       int root;
       int valin;
       int *valout;
       MPI_Request request;
       } ARGS;

    int myreduce(MPI_Comm comm, int tag, int root,
                  int valin, int *valout, MPI_Request *request)
    {
    ARGS *args;
    pthread_t thread;

    /* start request */
    MPI_Grequest_start(query_fn, free_fn, cancel_fn, NULL, request);

    args = (ARGS*)malloc(sizeof(ARGS));
    args->comm = comm;
    args->tag = tag;
    args->root = root;
    args->valin = valin;
    args->valout = valout;
    args->request = *request;

    /* spawn thread to handle request */
    /* The availability of the pthread_create call is system dependent */
    pthread_create(&thread, NULL, reduce_thread, args);

    return MPI_SUCCESS;
    }

    /* thread code */
    void reduce_thread(void *ptr)
    {
    int lchild, rchild, parent, lval, rval, val;
    MPI_Request req[2];
    ARGS *args;

    args = (ARGS*)ptr;

    /* compute left,right child and parent in tree; set
       to MPI_PROC_NULL if does not exist  */
    /* code not shown */
    ...

    MPI_Irecv(&lval, 1, MPI_INT, lchild, args->tag, args->comm, &req[0]);
    MPI_Irecv(&rval, 1, MPI_INT, rchild, args->tag, args->comm, &req[1]);
    MPI_Waitall(2, req, MPI_STATUSES_IGNORE);
    val = lval + args->valin + rval;
    MPI_Send( &val, 1, MPI_INT, parent, args->tag, args->comm );
    if (parent == MPI_PROC_NULL) *(args->valout) = val;
    MPI_Grequest_complete((args->request));
    free(ptr);
    return;
    }

    int query_fn(void *extra_state, MPI_Status *status)
    {
    /* always send just one int */
    MPI_Status_set_elements(status, MPI_INT, 1);
    /* can never cancel so always true */
    MPI_Status_set_cancelled(status, 0);
    /* choose not to return a value for this */
    status->MPI_SOURCE = MPI_UNDEFINED;
    /* tag has not meaning for this generalized request */
    status->MPI_TAG = MPI_UNDEFINED;
    /* this generalized request never fails */
    return MPI_SUCCESS;
    }

    int free_fn(void *extra_state)
    {
    /* this generalized request does not need to do any freeing */
    /* as a result it never fails here */
    return MPI_SUCCESS;
    }

    int cancel_fn(void *extra_state, int complete)
    {
    /* This generalized request does not support cancelling.
       Abort if not already done.  If done then treat as if cancel failed. */
    if (!complete) {
      fprintf(stderr, "Cannot cancel generalized request - aborting program\n");
      MPI_Abort(MPI_COMM_WORLD, 99);
      }
    return MPI_SUCCESS;
    }

Up: Generalized Requests Next: Associating Information with Status Previous: Generalized Requests

Return to MPI-2 Standard Index
Return to MPI 1.1 Standard Index
Return to MPI Forum Home Page

MPI-2.0 of July 18, 1997
HTML Generated on September 10, 2001