Re: generalized requests without communication handlers

Steve Huss-Lederman (lederman@cs.wisc.edu)
Wed, 12 Jun 1996 08:05:39 -0500

I am glad that the issue of generalized request (GR) has been raised.
We do need to settle this so that we can start voting on it. Here are
my thoughts. I hope a serious discussion will commence.

Steve

>
> Generalized requests are up in the air, or about to crash on the
> ground. They are considered to be not much of use unless combined
> with communication handlers, which have been voted out.
This is not my understanding of what the Forum voted for. They voted
to send handlers to a chapter on threads. Thus, handlers may only be
required on systems with threads. This does limit their use in GR so
I think the proposal below is interesting.
>
> I think generalized requests can be useful even without a help of
> communication handlers.
>
> One of the problems you have with the current proposal when you can not
> use handlers is you do not know who should call MARK_COMPLETE. But
> MARK_COMPLETE need not be called if TEST/WAIT is called with
> non-generalized, plain requests, which I assume every generalized
> request would usually maintain a few inside.
I'm not sure that MARK_COMPLETE is the sticking point. I may not yet
understand the proposal. See below.
>
> Take the current proposal and replace a user-supplied
> call-back function "mark_complete_fn" with a different type of
> call-back function "proceed", which may look like:
>
> typedef int
> request_proceed_fn(void *extra_state,
> MPI_Request request,
> MPI_Request *subrequest,
> MPI_Status *status);
>
> This call-back function is invoked by TEST/WAIT to extract
> an internally maintained request which TEST/WAIT can block on.
> WAIT could be changed like this;
>
> int MPI_Wait(MPI_Request *request, MPI_Status *status)
> {
> MPI_Request subrequest;
>
> /* if the request is plain, handle it
> as we do now */
> if (!request->is_general) {
> return non_generalized_wait(request, status);
> }
>
> /* otherwise, first extract an inner request */
> subrequest = MPI_REQUEST_NULL;
> request->proceed_fn(request->extra_state,
> request,
> &subrequest,
> status);
This is where I am confused. It seems as if the proceed
function only gets called when a test/wait is called. It seems to me
that progress on the GR is only made once a wait/test is called. One
of the goals of GR was that they go on asychonously in the
"background". If you have a GR with sequentially called MPI
functions that generate requests, it seems as if they will not proceed
until the test/wait is called. Also, can only 1 request go on at a
time? The current proposal allows multiple ones. Thus, does wait hang
up until all the proceeds finish? This may depend on actions at other
processes so it could be a long delay. If this is the case, then it
does not seem to allow overlap of the GR with other work. Along the
same lines, test seems as if it can get hung up in the proceed. This
would seem to violate the difference between test and wait.
>
> /* then repeat calling 'plain wait' and proceed_fn
> until the latter returns MPI_COMM_NULL */
> while (subrequest != MPI_COMM_NULL) {
> MPI_Request newsubreqest;
> non_generalized_wait(&subrequest, status);
> request->proceed_fn(request->extra_state,
> &subrequest, status);
Thus, there is 1 status for all the subrequests that occur from the
proceed(s) call(s). Status is mostly an opaque object. Where does
the info get placed in status? How does the proceed fn know where it
can write and what if it wants to place lots of info. It cannot
control the size of status.

In the current proposal this type of info might get put into
extra_state. Is that that is intended? If not, how is status being
exposed?
> }
>
> return MPI_SUCCESS;
> }
>
> Example in section 6.2 can be changed to have a proceed_fn
> as follows instead of a handler_fn there:
>
> int proceed_fn(void *extra_state,
> MPI_Request *request,
> MPI_Status *status)
> {
> My_Extra *myextra = (MyExtra*)extra_state;
>
> switch (myextra->phase) {
> case 1:
> *request = myextra->req_recv;
> break;
> case 2:
> MPI_Request_free(request);
> *request = myextra->req_send;
> break;
> case 3:
> MPI_Request_free(request);
> *request = MPI_Request_null;
> /* fill status as you like */
> break;
> }
> return MPI_SUCCESS;
> }
>
> I wish I could return more than one internal requests
> at once and let WAIT block on them, but that
> would make proceed_fn and WAIT look much messier.
I think this indicates that my question above about mulitple requests
is not possible. We may want to think about this.
>
> The changes above supplies a few of "Missing" items indicated
> in this section.
>
> - How can we use status: you can put whatever you
> want in status in a call to proceed_fn, which works
> like a new callback function suggested in "Missing"
> paragraph at line 36 p162.
> - There is no complete function in the example:
> now there is none in the proposal, either.
>
> I appreciate any comments.
>
> Koichi Konishi konishi@research.nj.nec.com
> NEC Research Institute Office: 609-951-2628
> FAX: 609-951-2488
>
>
Thanks for the interesting input.