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

MPI-2.0 of July 18, 1997
HTML Generated on August 11, 1997