Subject: yet more rambings...

From: [email-masked] (Tom Henderson)
Date: Tue, 29 Jun 93 11:24:00 MDT

> > Collective Context Operations
> > -----------------------------
> > MPI_CONTEXT_ALLOC (group, n, contexts)     (Uses group instead of comm)
> > IN  group (handle)
> > IN  n (integer)
> > OUT contexts (integer array)
> 
> I'm afraid it may need a communicator rather than a context, since
> otherwise how can it communicate to reserve the contexts ? It also
> probably needs the context in the communicator to be
> quiescent. (Actually this routine is just as hard as all the other
> collective routines to implement if you can't assume quiescence of the
> context. Let's see how we're supposed to do it (Lyndon ? Tony ? Mark
> ?))

I agree.  We went round and round on this for a bit when we were making up 
the examples.  (At least I did...)   What can we really say about 
"quiescence"?  

Can we guarantee that MPI_COMM_ALL is quiescent immediately after MPI_INIT() 
returns?  I hope so!  :-)

Can we guarantee is that a communicator is quiescent immediately after 
"collective" creation (via MPI_COMM_MAKE())?  I think so.  

Can we guarantee is that a communicator used in a collective communication 
function is quiescent immediately after the function returns?  I think so, as 
long as the communicator was quiescent before the function was called.  

Is it the user's responsibility to make sure a communicator is quiescent 
before using it in a collective communication call?  If so, will a user be 
forced to create lots of quiescent communicators?  Is this a bad thing?  

I could see programs starting out like this:  

    int i, numQuietComms = <some #define...>;
    group allGroup;
    comm quietComms[numQuietComms];

    MPI_INIT();

    MPI_COMM_GROUP(MPI_COMM_ALL, allGroup);

    for (i=0; i<numQuietComms; i++)
        {
        MPI_COMM_MAKE(MPI_COMM_ALL, allGroup, quietComms[i]);
        }

    /* etc. */

After working the examples we said we'd like the following "convenience" 
function:  

MPI_NEW_COMM (oldComm, newComm)
IN  oldComm (handle)
OUT newComm (handle)

where

   MPI_NEW_COMM (oldComm, newComm) is equivalent to:

      MPI_CONTEXTS_ALLOC (oldComm, 1, newContext)
      MPI_COMM_DUP (oldComm, newContext, newComm)

If we used MPI_NEW_COMM() in the above example we could remove the call to 
MPI_COMM_GROUP().  

Enough already...  :-)

Tom Henderson
NOAA Forecast Systems Laboratory

---

From: [email-masked] (Tom Henderson)
Date: Tue, 29 Jun 93 11:49:54 MDT

After looking at the program fragment I just sent out, it's obvious that I 
missed the "fast" way to do it...  

>     comm quietComms[numQuietComms];
      /* Local op */
>     for (i=0; i<numQuietComms; i++)
          /* Collective op */

    int i, numQuietComms = <some #define...>;
    group allGroup;
    comm quietComms[numQuietComms];
    context tmpContexts[numQuietComms];

    MPI_INIT();

    /* Local op */

    /* Collective op */
    MPI_CONTEXTS_ALLOC (MPI_COMM_ALL, numQuietComms, tmpContexts);

    for (i=0; i<numQuietComms; i++)
        {
        /* Local op */
        MPI_COMM_DUP (MPI_COMM_ALL, tmpContexts[i], quietComms[i]);
        }

    /* etc. */

I guess I've now mentioned three ways to do something pretty simple.  Each one 
uses different functions.  Looks like we're violating the "Peter (Rigsbee) 
Principle"...  :-)

Tom Henderson