[cfe-commits] [PATCH] Compile-time MPI_Datatype checking, type arguments in attributes

Hal Finkel hfinkel at anl.gov
Sun May 13 08:56:49 PDT 2012


Dmitri,

Thanks for continuing to work on this, I think this is an incredibly
important capability for us to have.

As I said previously, I would really like to take 'mpi' out of the
attribute names and have all of the attributes take an arbitrary tag
instead. There are other important APIs that could use this feature as
well. To provide another example, the HDF5 library, which is a very
popular I/O library used for scientific computing (and now also, I
understand, by financial companies and users in other fields), has an
API that would benefit from this:

 status = H5Dwrite(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, 
         H5P_DEFAULT, dset_data);

Here, it is similarly important that the type of dset_data match the
H5T_NATIVE_INT tag. I suggest mpi_datatype(int) ->
tagged_type_datatype(mpi, int), etc. so that we can support other APIs
besides just MPI.

Another example which comes to mind as a function with type tags is the
POSIX fcntl function. Depending on the 'command' tag, the third
parameters should have different types: F_DUPFD -> long, but F_SETLK ->
struct flock *. ioctl, although system specific, is often the same way.
getsockopt/setsockopt also would benefit.

In short, I think that the generalization, even keeping the same
semantics, is simple to implement and would allow other APIs to
benefit. Maybe I'm oversimplifying things, and if you think so, please
say so.

Thanks again,
Hal

On Sun, 13 May 2012 18:04:54 +0300
Dmitri Gribenko <gribozavr at gmail.com> wrote:

> Hello,
> 
> I want to ask for a review of a new version of the patch that
> implements this proposal.  Major changes are:
> * compatibility with MPICH2 and MVAPICH2;
> * support for checking layout-compatible types (like MPI_DOUBLE_INT).
> 
> === Objective ===
> Implement a set of annotations for MPI libraries and a diagnostic for
> clang that checks that specified buffer type matches the passed
> MPI_Datatype.
> 
> === Background ===
> Many MPI functions take a void* `buffer' and an MPI_Datatype (from
> user's viewpoint -- an opaque identifier like MPI_INT, MPI_LONG etc.)
> that describes how to send/receive that buffer.  For example,
> 
> int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest,
>    int tag, MPI_Comm comm);
> 
> Users call it like this:
> int *int_buf = ...;
> MPI_Send(int_buf, 1, MPI_INT, ...);
> 
> Thus, user is on its own to ensure that buffer type matches the
> MPI_Datatype.
> 
> === Annotation design ===
> I decided to annotate MPI functions that have buffer arguments and
> declarations of built-in `MPI_Datatype's.  Functions are easy: we use
> mpi_typed_arg(buffer-arg-index, type-arg-index) attribute:
> 
> int MPI_Send(void *buf, int count, MPI_Datatype datatype, ...etc...)
>    __attribute__(( mpi_typed_arg(1,3) ));
> 
> `MPI_Datatype's are trickier because there are at least two approaches
> to declaring built-in datatypes.
> 
> OpenMPI-style declaration uses addresses of special objects as
> built-in dataypes:
> 
> #define MPI_INT ((MPI_Datatype) &ompi_mpi_int)
> extern struct ompi_predefined_datatype_t ompi_mpi_int
>        __attribute__(( mpi_datatype(int) ));
> 
> MPICH2-style declaration uses magic numbers, so an additional
> declaration is required to attach an attribute to:
> 
> #define MPI_INT ((MPI_Datatype) 0xa0000002)
> static const MPI_Datatype mpich_mpi_int
>              __attribute__(( mpi_datatype(int) )) = MPI_INT;
> 
> Matching C datatype for MPI_DATATYPE_NULL is void.
> 
> MPI also defines built-in datatypes like MPI_DOUBLE_INT which means
> "any C datatype that is layout-compatible to struct { double d; int i;
> }".  Attribute mpi_datatype_layout_compatible is used for these types.
> 
> 
> While checking a function call we recognize mpi_datatype attribute if
> datatype argument is either:
> * an OpenMPI-style expression `((MPI_Datatype) &ident)';
> * a MPICH2-style magic number `((MPI_Datatype) num)';
> * a user-specified type `ident';
> where ident has mpi_datatype or mpi_datatype_layout_compatible
> attribute.
> 
> We emit a diagnostic in 2 cases.
> Case 1.  (Any type except MPI_DATATYPE_NULL)  All of the following is
> true:
> * buffer is not of `void *' type;
> * buffer's element type doesn't match specified MPI_Datatype.
> 
> Case 2.  (MPI_DATATYPE_NULL)  All of the following is true:
> * buffer is not of `void *' type;
> * buffer is not a null pointer constant;
> * mpi_datatype(void) was specified.
> 
> === Clang modifications ===
> We need to allow arbitrary types as attribute arguments.  From the
> grammar of GNU attributes in lib/Parse/ParseDecl.cpp we see that there
> is no easy way to pass a type argument to an attribute.  If I
> understand everything correctly, GNU attribute grammar becomes
> ambiguous in that case, so attribute argument parsing will be driven
> by attribute name.  Fortunately, this modification is compatible with
> C++11 attributes where attribute argument list is just a sequence of
> tokens with balanced delimiters.
> 
> I added AttributeList::TypeArg member, the required AttributeList
> constructor and factory method.  In Attr.td a new field,
> HasTypeArgument, was added and a tablegen pass was implemented.  The
> parser uses the generated table to decide if it should parse a list of
> expressions or a type name.
> 
> The check itself is called from Sema::CheckFunctionCall, which seems
> to be designed for similar purposes.
> 
> === Compatibility ===
> The annotation-based approach is compatible with OpenMPI, LAM MPI,
> MPICH2 and MVAPICH2.  I already have a prototype patches for OpenMPI
> and MPICH2.
> 
> === Miscellaneous ===
> There is an `iboutletcollection' attribute that takes a type argument.
> It would be good if this implementation of type arguments could be
> used for that, too.
> 
> Best regards,
> Dmitri Gribenko
> 



-- 
Hal Finkel
Postdoctoral Appointee
Leadership Computing Facility
Argonne National Laboratory



More information about the cfe-commits mailing list