[cfe-commits] [PATCH] Compile-time MPI_Datatype checking, type arguments in attributes
Dmitri Gribenko
gribozavr at gmail.com
Sun May 13 08:04:54 PDT 2012
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
--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr at gmail.com>*/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mpi-datatype-check-v2.patch
Type: application/octet-stream
Size: 51728 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120513/553b4f96/attachment.obj>
More information about the cfe-commits
mailing list