If we're going to have cacheing on MPI_DATATYPEs and MPI_DATATYPE_DUP,
then we should at least make them consistent with the behaviour on
communicators.
MPI_COMM_DUP returns a *NEW* communicator which is the same as a
pre-existing one, and has a new set of attributes, which
are copied (by the attribute copy functions) from the old
communicator. (Note, of course that the freedom of the
copy function allows you to decide *not* to copy specific
attributes if that's appropriate)
The definition of MPI_TYPE_DUP should be the same.
1) It returns a *NEW* datatype which is a copy of the old one.
2) Attributes on the new datatype are the results of the attribute
copy functions applied to the old one.
This scheme appears to have worked perfectly well for people
implementing collective operations by cacheing duplicate communicators
on user communicators, I see no reason why it won't work for datatypes
too.
Note :
1) It allows you to tag the original datatype with a reference to your
copy, so that you can always execute your internal calls using your
copy. You then know that your copy won't go away at an inconvenient
moment.
2) You can use the delete callback either to delete your copy (if it
is not in use), or mark it for deletion so that it gets deleted as
soon as it isn't in use (you'll have to check the flag [in the
attributes] on your dataype as you exit your completion operations).
3) There's no danger of getting stale information provided you use the
attribute copy functions correctly.
4) It's sympathetic to the way MPI-1 works.
5) It doesn't expose implementation details like reference counts.
6) It relies on the fact that MPI_DATATYPE objects do not change after
they are created. (I think we took the right decisions on
MPI_TYPE_RESIZED, so this is true).
7) I assume that all type constructors (apart from MPI_TYPE_DUP)
produce new types with empty attribute caches, this seems the only
useful and consistent behaviour.
8) We need to decide whether to have separate attribute keys for type
attributes, or share the keys with communicator attributes.
If we share them we don't need new key allocation routines, but
the keys probably really are disjoint, so one might save some space
if one used separate key spaces. (Though maybe no more than the
extra code space which would be required to hold the new routines
:-)).
Implementation note
-------------------
Assuming a reference counted implementation, these are the issues to
be solved :-
1) You can't put the attribute cache into the existing datatype
object, because you may need to have multiple attribute caches for
the same "fundamental" datatype.
2) If you are going to constant integers as the user representation of
MPI_DATATYPE (and MPI 1.1 pretty much forces you into this), then
it's easy enough to make them indices into a table of
struct
{
Implementation_attr_cache * cache;
Implementation_datatype * datatype;
};
objects (or equivalently just have two arrays of pointers), rather
than just into Implementation_datatype * [];
3) MPI_DATATYPE_DUP is then a simple operation of incrementing the
reference count on the underlying data structure, finding a slot in
the datatype table, putting a pointer into it, and running the
cache copying code to copy the cache from the old to the new slot.
Conclusion
----------
This approach seems implementable, and I believe it meets all the
requirements. Why would we do something else ?
-- Jim
James Cownie
Dolphin Interconnect Solutions
Phone : +44 117 9071438
E-Mail: jcownie@dolphinics.com