(corrected) Simplified version of generalized requests

Nathan E. Doss (doss@ERC.MsState.Edu)
Fri, 28 Jul 1995 08:12:43 -0500 (CDT)

The example is more correct than in the one I'd sent out earlier.

-- 
Nathan Doss                  doss@ERC.MsState.Edu

This is a simplified version of the current generalized request proposal. It consists of the following four functions:

MPI_REQUEST_TYPE_CREATE ( init, start, free, request_type ) IN init Callback invoked when request is init'ed IN start Callback invoked when request is started IN free Callback invoked when request is freed OUT request_type MPI created request type

MPI_REQUEST_TYPE_FREE ( request_type ) INOUT request_type Type of request to be freed

MPI_REQUEST_INIT ( request_type, extra_state, comm, request ) IN request_type Type of request IN extra_state Extra request_type specific state IN comm MPI communicator OUT request MPI request

MPI_REQUEST_MARK_COMPLETED ( request ) OUT request Request to be marked complete

One thing the current version of the proposal attempts to manage is handlers that fire as a result of the completion of an associated request. IF we are going to have hsend/hrecv, this functionality doesn't necessarily have to be in the generalized request mechanism.

Below is a version of the allgather example from section 3.2.4 of the July 24 draft using these functions and a persistant version of the hrecv/hsend proposed by Snir.

Main routine that calls the non-blocking operation:

MPI_Request_type_create( init_fn, start_fn, free_fn, &type_req ); Fill_in_extra_state( &extra_state ); MPI_Request_init( type_req, extra_state, comm, &request ); MPI_Start( &request ); Do_other_stuff(); MPI_Wait( &request ); MPI_Type_request_free( &type_req );

The init_fn, start_fn, & free_fn:

init_fn( extra, comm, request ) { MPI_Comm_size ( comm, &size ); MPI_Comm_rank ( comm, &rank ); extra->comm = comm; extra->request = request; extra->req_completed = 0; from = (i-1) % p; to = (i+1) % p;

MPI_Hrecv_init(extra->rbuf,1,MPI_DOUBLE,from,13,comm,handler_fn,extra, &extra->rreq); MPI_Hsend_init(extra->sbuf,1,MPI_DOUBLE,to, 13,comm,handler_fn,extra, &extra->sreq);

return (MPI_SUCCESS); }

start_fn( extra, comm, request ) { extra->sbuf = extra->buf[rank]; extra->num_done = 0;

MPI_Start( extra->rreq ); MPI_Start( extra->sreq );

return (MPI_SUCCESS); }

free_fn( extra, comm, request ) { MPI_Request_free( &extra->sreq ); MPI_Request_free( &extra->rreq );

return (MPI_SUCCESS); }

The handler_fn used by the hrecv/hsend:

handler_fn( extra, status ) { extra->num_completed++; if (extra->num_completed != 2) return (MPI_SUCCESS); extra->num_completed = 0; /* reset */ /* We don't get here unless both the send & recv completed */ MPI_Comm_size ( extra->comm, &size ); extra->num_done++;

if (extra->num_done == size - 1) { MPI_Request_mark_completed( extra->request ); return (MPI_SUCCESS); }

/* store away received data/set data to be sent */ extra->buf[?number determined by num_done?] = extra->rbuf; extra->sbuf = extra->buf[?number determined by num_done?];

MPI_Start( extra->sreq ); MPI_Start( extra->rreq );

return (MPI_SUCCESS); }