[mpich2-dev] fandcattrf90 test on BGP

Joe Ratterman jratt at us.ibm.com
Thu Jul 16 16:55:53 CDT 2009


(This is a re-send; I got a pile of python errors on the last try)

https://svn.mcs.anl.gov/repos/mpi/mpich2/trunk/test/mpi/f90/attr/fandcattrf90.f90
https://svn.mcs.anl.gov/repos/mpi/mpich2/trunk/test/mpi/f90/attr/fandcattrc.c

This test creates an attribute in F90, sets it in F90, and then reads it
back in C.  It was getting the wrong answer:Expected:           5555
(0x15b3)
Actual:   23858543329280 (0x15b300000000)


*fandcattrf90.f90 excerpt*

      program main
      use mpi
      integer (kind=MPI_ADDRESS_KIND) val

      errs      = 0
      call mpi_init(ierr)
      commextra = 1001
      call mpi_comm_create_keyval( mycopyfn, mydelfn,                     &
     &                             fcomm2_keyval, commextra, ierr )
      val = 5555
      call mpi_comm_set_attr( MPI_COMM_WORLD, fcomm2_keyval, val, ierr )
      call chkcomm2inc( fcomm2_keyval, 5555, errs )




*fandcattrc.c excerpt*

int chkcomm2inc_ (int *keyval, const int *expected, int *ierr)
{
    int      flag;
    MPI_Aint *val;

    /* See Example 16.19 in MPI 2.2, part B.  The use of MPI_Aint *val
       and the address of val in the get_attr call is correct, as is
       the use of *val to access the value. */
    MPI_Comm_get_attr( MPI_COMM_WORLD, *keyval, &val, &flag );
    if (!flag) {
 *ierr = 1;
    }
    else {
 if (*val != *expected) {
    /* In some cases, using printf from a c routine linked
       with a Fortran routine can cause linking difficulties.
       To avoid problems in running the tests, this print
       is commented out */
    /* printf( "Val = %x, expected = %d\n", val, *expected ); */
    *ierr = *ierr + 1;
 }
    }
}




BGP has an 8-byte MPI_Aint and a 4-byte void*, which seems to be the root of
the problem.  MPI_Comm_get_attr() stores the integer data in a void*
internally.  That means that there are only 4 bytes of actual data, but
*(MPI_Aint*)val tries to read 8 bytes.  Effectively, that means that
MPI_Comm_get_attr() only returns an int*.  This is a problem caused by
assuming that everything--specifically including MPI_Aint values--will fit
in the space used by a void*.  The solution is to store all attributes in an
MPI_Aint. Since an MPI_Aint clearly cannot be smaller than a void*, this
will work fine.  There is already special code to handle the case of storing
a 4-byte big-endian int in a 8-byte void*, so a 4-byte void* in a 8-byte
MPI_Aint would be very similar.

One idea that strikes me as really good is to change the "value" field in
the MPID_Attribute structure to be a union of int, void*, and MPI_Aint types
with three different names.  That would get rid of the *interesting* work
that is required to handle 8-byte void* and 4-byte ints.  It would also make
it easier to add MPI_Aint changes.  You wouldn't have to worry about the
strangeness of storing an integer type in a pointer type, and it would
automatically handle any differences in the sizes of the elements.  You
already track the data type, so you would know into which element the
attribute should be stored.


Comments or questions?

Joe Ratterman
jratt at us.ibm.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/mpich2-dev/attachments/20090716/c3f97c3c/attachment.htm>


More information about the mpich2-dev mailing list