<div class="gmail_quote"><div class="gmail_quote">(This is a re-send; I got a pile of python errors on the last try)</div><br><div><a href="https://svn.mcs.anl.gov/repos/mpi/mpich2/trunk/test/mpi/f90/attr/fandcattrf90.f90" target="_blank">https://svn.mcs.anl.gov/repos/mpi/mpich2/trunk/test/mpi/f90/attr/fandcattrf90.f90</a></div>
<div><a href="https://svn.mcs.anl.gov/repos/mpi/mpich2/trunk/test/mpi/f90/attr/fandcattrc.c" target="_blank">https://svn.mcs.anl.gov/repos/mpi/mpich2/trunk/test/mpi/f90/attr/fandcattrc.c</a></div>
<div><br></div>This test creates an attribute in F90, sets it in F90, and then reads it back in C. It was getting the wrong answer:<div><font face="'courier new', monospace">Expected: 5555 (0x15b3)</font></div>
<div><font face="'courier new', monospace">Actual: 23858543329280 (0x15b300000000)</font></div><div><br></div><div><br></div><div><b>fandcattrf90.f90 excerpt</b></div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px">
<font face="'courier new', monospace"> program main<br> use mpi<br> integer (kind=MPI_ADDRESS_KIND) val<br><br> errs = 0<br> call mpi_init(ierr)<br> commextra = 1001<br>
call mpi_comm_create_keyval( mycopyfn, mydelfn, &<br> & fcomm2_keyval, commextra, ierr )<br> val = 5555<br> call mpi_comm_set_attr( MPI_COMM_WORLD, fcomm2_keyval, val, ierr )<br>
call chkcomm2inc( fcomm2_keyval, 5555, errs )</font></blockquote><div><br></div><div><br></div><div><br></div><div><b>fandcattrc.c excerpt</b></div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px">
<span style="font-family:'courier new';font-size:10px">int chkcomm2inc_ (int *keyval, const int *expected, int *ierr)</span><br><span style="font-family:'courier new';font-size:10px">{</span><br>
<span style="font-family:'courier new';font-size:10px"> int flag;</span><br><span style="font-family:'courier new';font-size:10px"> MPI_Aint *val;</span><br>
<font face="'courier new'" size="2"><span style="font-size:10px"><br></span></font><span style="font-family:'courier new';font-size:10px"> /* See Example 16.19 in MPI 2.2, part B. The use of MPI_Aint *val</span><br>
<span style="font-family:'courier new';font-size:10px"> and the address of val in the get_attr call is correct, as is</span><br><span style="font-family:'courier new';font-size:10px"> the use of *val to access the value. */</span><br>
<span style="font-family:'courier new';font-size:10px"> MPI_Comm_get_attr( MPI_COMM_WORLD, *keyval, &val, &flag );</span><br><span style="font-family:'courier new';font-size:10px"> if (!flag) {</span><br>
<span style="white-space:pre"><font face="'courier new', monospace">        </font></span><font face="'courier new', monospace">*ierr = 1;</font><br>
<span style="font-family:'courier new';font-size:10px"> }</span><br><span style="font-family:'courier new';font-size:10px"> else {</span><br>
<span style="white-space:pre"><font face="'courier new', monospace">        </font></span><font face="'courier new', monospace">if (*val != *expected) {</font><br>
<span style="white-space:pre"><font face="'courier new', monospace">        </font></span><font face="'courier new', monospace"> /* In some cases, using printf from a c routine linked </font><br>
<span style="white-space:pre"><font face="'courier new', monospace">        </font></span><font face="'courier new', monospace"> with a Fortran routine can cause linking difficulties.</font><br>
<span style="white-space:pre"><font face="'courier new', monospace">        </font></span><font face="'courier new', monospace"> To avoid problems in running the tests, this print</font><br>
<span style="white-space:pre"><font face="'courier new', monospace">        </font></span><font face="'courier new', monospace"> is commented out */</font><br>
<span style="white-space:pre"><font face="'courier new', monospace">        </font></span><font face="'courier new', monospace"> /* printf( "Val = %x, expected = %d\n", val, *expected ); */</font><br>
<span style="white-space:pre"><font face="'courier new', monospace">        </font></span><font face="'courier new', monospace"> *ierr = *ierr + 1;</font><br>
<span style="white-space:pre"><font face="'courier new', monospace">        </font></span><font face="'courier new', monospace">}</font><br>
<span style="font-family:'courier new';font-size:10px"> }</span><br><span style="font-family:'courier new';font-size:10px">}</span></blockquote>
<div><br></div><div><br></div><div><br></div><div>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.</div>
<div><div><br></div><div>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 <i>interesting</i> 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.</div>
<div><br></div><div><br></div><div>Comments or questions?</div><div><br></div><font color="#888888"><div>Joe Ratterman</div><div><a href="mailto:jratt@us.ibm.com" target="_blank">jratt@us.ibm.com</a></div></font></div>
</div><br>