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