Re: More IO issues

Jeff Squyres (squyres@cse.nd.edu)
Thu, 17 Apr 1997 08:29:46 -0400

(Sorry, I was away from my e-mail for several days -- I'm just now
catching up on the backlog of messages)

John May wrote:

> > But yes, this second one is much nicer, but still not the Right Thing,
> > IMHO. It leads to user code like this:
> >
> > void
> > foo()
> > {
> > MPI::File fp;
> >
> > fp = MPI::File::Open(MPI::COMM_WORLD, ...);
> > }
>
> Looks perfect to me!

It works, yes, but is a bit cumbersome. I guess it's ironic that I
should make this about any function in MPI-2, though. :-)

> > I still don't think that this is right for the same reasons that I've
> > been citing:
> >
> > 1. There's a perfectly good opaque MPI IN argument in the parameter list
>
> I don't hold with the view that a function ought to be a member
> of whatever class is handy. I claim that none of the types in
> argument list to the file open call has any legitimate business
> knowing how to open a file.

I think this is our fundamental disagreement -- I think that the
MPI::Comm has a perfect right to know since the MPI::Comm defines the
scope (i.e. the members) of the file handle. Since it is a collective
call, I think that the communicator is a perfect object to contain the
open file function. Keep in mind that there are programming tricks that
one can use to put the actual "open file" code in the MPI::File class
(where it probably belongs), but since we're defining the user interface
here, I still maintain that the scope-defining object should be the
controlling object.

But I say this tounge in cheek because John pointed out that MPI IO is
supposed to be layered on top of MPI-2, and I still don't see a way to
put a function in MPI::Comm if this is supposed to be layered code.
:-( So my above point is probably moot.

> > 2. All MPI opaque objects that are created from other MPI opaque objects
> > use member function of the IN argument
>
> In this case, that seems like an unfortunate choice. For some reason
> (and it may be a good reason; I don't know), we're not using
> constructors to create these opaque objects. If we were, it would
> be clear that opening a file corresponded to constructing a
> File object, and the constructor would certainly belong to class File.
> It seems to me that this logic should apply, even though we're not
> using explicit constructor functions.

We're not using constructors because that would imply that we invoke the
corresponding MPI_*_FREE function in the destructor. We decided not to
do this for two reasons:

1. The MPI model has the user maintain all memory management (i.e. alloc
and dealloc).
2. There would be problems with invoking collective MPI_*_FREE functions
in destructors when this is not the intended action. It would
necessisitate a reference-counting scheme on the implementation to
ensure that the proper MPI_*_FREE function is not called before all
instances of the MPI object are destroyed.

> > > MPI::Datatype MPI::Datatype:Create_struct( int count,
> > > const int array_of_blocklengths[],
> > > const Aint array_of_displacements[],
> > > const Datatype array_of_types[] );
> >
> > Er, I'm not sure what you're trying to say here. Both Create_contiguous
> > and Crate_struct are the same case -- the newtype argument is not
> > "this", and is returned as the OUT argument. The oldtype IN argument is
> > "this".
>
> They're not the same. A struct is created from an array of
> Datatypes, not a single object. MPI::Datatype::Create_struct has
> no C++ class objects in its parameter list, so it has to be a
> static function and cannot have a "this".

Oops! Looks like you found a mistake. We have fixed this in the C++
bindings annex.

> I guess this is our key point of disagreement. I don't see
> Files as being "created from" Comms, any more than they are created
> from filenames, amodes, or info lists. All contribute to the
> creation of a File, and none has any special relationship with it.
> If the filename were a C++ String type, one could argue that String
> has just as much right to scope the open file function as Comm does.
> In reality, Comm has no special knowledge of a File, and everything
> that a File needs to know about the Comm in its argument list is
> accessible through public member functions. Remember that a File
> only uses a Comm's group, not its context or even its error handler.
> This lack of a special connection between Comms and Files is what makes
> me bristle at putting what amounts to a File constructor in Comm's
> scope.

See my argument above about this.

> > > There are several other MPI-2 names that also take advantage of Rule 2:
> > > MPI_Put, MPI_Get, MPI_Spawn, and MPI_Accept. As it happens, these
> > > names correpond to names for similar operations that exist outside MPI,
> > > just as MPI_Open does.
> >
> > Yes, and they've all been renamed, because they still happen within the
> > scope of an MPI opaque object. I've been doing a lot of editing in 2
> > weeks since I've gotten back! Much of the C++ text in the March
> > document has been changed. For example, MPI_Win_put(), MPI_Win_get(),
> > MPI_Comm_spawn(), MPI_Comm_accept(), etc. (and yes, the chapter authors
> > know :-).
>
> Did they accept it willingly, or did they put up a fight? ;-) (And I'm
> not even chapter editor... C'mon Bill, where are you?)

Some fought. Some just accepted. You will be assimilated. :-)

{+} Jeff Squyres
{+} squyres@cse.nd.edu
{+} Perpetual Obsessive Notre Dame Student Craving Utter Madness
{+} "I came to Notre Dame for 4 years and ended up staying for a
decade."