<br><br><div class="gmail_quote">Le 11 février 2012 21:09, Dmitri Gribenko <span dir="ltr"><<a href="mailto:gribozavr@gmail.com">gribozavr@gmail.com</a>></span> a écrit :<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hello,<br>
<br>
=== Objective ===<br>
Implement a set of annotations for MPI libraries and a diagnostic for<br>
clang that checks that specified buffer type matches the passed<br>
MPI_Datatype.<br>
<br>
=== Background ===<br>
Many MPI functions take a void* `buffer' and an MPI_Datatype (like<br>
MPI_INT, MPI_LONG etc) that describes how to send/receive that buffer.<br>
 For example,<br>
<br>
int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest,<br>
    int tag, MPI_Comm comm);<br>
<br>
Users call it like this:<br>
int *int_buf = ...;<br>
MPI_Send(int_buf, 1, MPI_INT, ...);<br>
<br>
Thus, user is on its own to ensure that buffer type matches the MPI_Datatype.<br>
<br>
=== Annotation design ===<br>
I decided to annotate MPI functions that have buffer arguments and<br>
declarations of built-in `MPI_Datatype's.  Functions are easy: we use<br>
mpi_typed_arg(buffer-arg-index, type-arg-index) attribute:<br>
<br>
int MPI_Send(void *buf, int count, MPI_Datatype datatype, ...etc...)<br>
    __attribute__(( mpi_typed_arg(1,3) ));<br>
<br></blockquote><div><br>Just a small remark here: indexes in C and C++ are usually 0-based, while counting is 1-based. To avoid the ambiguity altogether it would be even simpler to use the *names* of the arguments rather than their position, it seems to be it would also be slightly easier to read and maintain.<br>
 </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
`MPI_Datatype's are trickier.  From the grammar of GNU attributes in<br>
lib/Parse/ParseDecl.cpp we see that there is no easy way to pass a<br>
type argument to an attribute.  For example, this is not currently<br>
parseable by clang:<br>
<br>
#define MPI_INT ((MPI_Datatype) &ompi_mpi_int)<br>
extern struct ompi_predefined_datatype_t ompi_mpi_int<br>
        __attribute__(( mpi_datatype(int) ));<br>
<br>
Matching C datatype for MPI_DATATYPE_NULL is void.<br>
<br>
#define MPI_DATATYPE_NULL ((MPI_Datatype) &ompi_mpi_int)<br>
extern struct ompi_predefined_datatype_t ompi_mpi_void<br>
        __attribute__(( mpi_datatype(void) ));<br>
<br>
While checking a function call we recognize mpi_datatype attribute if<br>
datatype argument is either:<br>
* an OpenMPI-style expression `((MPI_Datatype) &ident)';<br>
* a user-specified type `ident';<br>
where ident has mpi_datatype attribute.<br>
<br>
We emit a diagnostic in 2 cases.<br>
Case 1.  (Any type except MPI_DATATYPE_NULL)  All of the following is true:<br>
* buffer is not of `void *' type;<br>
* buffer's element type doesn't match specified MPI_Datatype.<br>
<br>
Case 2.  (MPI_DATATYPE_NULL)  All of the following is true:<br>
* buffer is not of `void *' type;<br>
* buffer is not a null pointer constant;<br>
* mpi_datatype(void) was specified.<br>
<br>
=== Clang modifications ===<br>
We need to allow arbitrary types as attribute arguments.  If I<br>
understand everything correctly, GNU attribute grammar becomes<br>
ambiguous in that case, so attribute argument parsing will be driven<br>
by attribute name.  Fortunately, that is compatible with C++11<br>
attributes where attribute argument list is just a sequence of tokens<br>
with balanced delimiters.<br>
<br>
I added AttributeList::TypeArg member, the required AttributeList<br>
constructor and factory method.  In Attr.td a new field,<br>
HasTypeArgument, was added and a tablegen pass was implemented.  The<br>
parser uses the generated table to decide if it should parse a list of<br>
expressions or a type name.<br>
<br>
The check itself is called from Sema::CheckFunctionCall, which seems<br>
to be designed for similar purposes.<br>
<br>
=== Compatibility ===<br>
The annotation-based approach is compatible with OpenMPI and LAM MPI.<br>
I already have a prototype patch for OpenMPI.<br>
<br>
MPICH is not compatible without refactoring their mpi.h header (they<br>
have MPI_XXX macros defined to magic numbers).<br>
<br>
=== Miscellaneous ===<br>
There is an `iboutletcollection' attribute that takes a type argument.<br>
 It would be good if this implementation of type arguments could be<br>
used for that, too.<br>
<br>
Please see attached patch.  Parsing diagnostics are not very good (see<br>
testcase), advice is welcome.<br>
<span class="HOEnZb"><font color="#888888"><br>
Dmitri<br>
<br>
--<br>
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if<br>
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <<a href="mailto:gribozavr@gmail.com">gribozavr@gmail.com</a>>*/<br>
</font></span><br></blockquote><div><br>-- Matthieu <br></div></div><br>