273. Examples

PreviousUpNext
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 and 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(NULL); 
} 
 
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 no 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; 
} 


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


Return to MPI-3.1 Standard Index
Return to MPI Forum Home Page

(Unofficial) MPI-3.1 of June 4, 2015
HTML Generated on June 4, 2015