From 51a051b072ceef8901607c38215f3349ccf954ca Mon Sep 17 00:00:00 2001 From: Jeff Squyres Date: Thu, 22 Jul 2010 02:23:47 +0000 Subject: [PATCH] This commit, along with r23467, r23468, r23470, r23471 should fix #2241. This commit: * Adds the configury to figure out how many Fortran INTEGERs are necessary to represent the C MPI_Status (which now includes a size_t member). * Sets MPI_STATUS_SIZE to this value in mpif-config.h.in. * Adds a big comment in status_c2f.c explaining why the no changes were necessary to how we copy statuses between Fortran and C. This commit was SVN r23472. The following SVN revision numbers were found above: r23467 --> open-mpi/ompi@733d25a8a37a5f74256d352f39842db3689b4999 r23468 --> open-mpi/ompi@963fcb13a54d5df25db822cf6bf7cead6743b7f8 r23470 --> open-mpi/ompi@418b989781d948d84b9c38a86424dcbb2ba402ba r23471 --> open-mpi/ompi@bc74a446acacedafd10eed87242cfd0eab929de0 --- ompi/config/ompi_setup_mpi_fortran.m4 | 26 ++++++++++++++++++++++- ompi/include/mpif-config.h.in | 4 ++-- ompi/mpi/c/status_c2f.c | 30 ++++++++++++++++++++------- ompi/mpi/c/status_f2c.c | 15 +++++++------- 4 files changed, 57 insertions(+), 18 deletions(-) diff --git a/ompi/config/ompi_setup_mpi_fortran.m4 b/ompi/config/ompi_setup_mpi_fortran.m4 index fa3ab41fa6..bdb5622f9e 100644 --- a/ompi/config/ompi_setup_mpi_fortran.m4 +++ b/ompi/config/ompi_setup_mpi_fortran.m4 @@ -10,7 +10,7 @@ # University of Stuttgart. All rights reserved. # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. -# Copyright (c) 2006-2009 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2006-2010 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2006-2008 Sun Microsystems, Inc. All rights reserved. # Copyright (c) 2006-2007 Los Alamos National Security, LLC. All rights # reserved. @@ -114,6 +114,30 @@ AC_DEFUN([OMPI_SETUP_MPI_FORTRAN],[ OMPI_F77_GET_VALUE_TRUE OMPI_F77_CHECK_LOGICAL_ARRAY + # How big should MPI_STATUS_SIZE be? (i.e., the size of + # MPI_STATUS, expressed in units of Fortran INTEGERs). The C + # equivalent of MPI_Status contains 4 C ints and a size_t. + + AC_MSG_CHECKING([for the value of MPI_STATUS_SIZE]) + OMPI_FORTRAN_STATUS_SIZE=0 + if test $OMPI_WANT_F77_BINDINGS -eq 0; then + AC_MSG_RESULT([skipped (no Fortran bindings)]) + else + bytes=`expr 4 \* $ac_cv_sizeof_int + $ac_cv_sizeof_size_t` + num_integers=`expr $bytes / $OMPI_SIZEOF_FORTRAN_INTEGER` + sanity=`expr $num_integers \* $OMPI_SIZEOF_FORTRAN_INTEGER` + AS_IF([test "$sanity" != "$bytes"], + [AC_MSG_RESULT([unknown!]) + AC_MSG_WARN([WARNING: Size of C int: $ac_cv_sizeof_int]) + AC_MSG_WARN([WARNING: Size of C size_t: $ac_cv_sizeof_size_t]) + AC_MSG_WARN([WARNING: Size of Fortran INTEGER: $OMPI_SIZEOF_FORTRAN_INTEGER]) + AC_MSG_WARN([Could not make this work out evenly...!]) + AC_MSG_ERROR([Cannot continue])]) + OMPI_FORTRAN_STATUS_SIZE=$num_integers + AC_MSG_RESULT([$OMPI_FORTRAN_STATUS_SIZE Fortran INTEGERs]) + fi + AC_SUBST(OMPI_FORTRAN_STATUS_SIZE) + # # There are 2 layers to the MPI f77 layer. The only extra thing that # determine f77 bindings is that fortran can be disabled by user. In diff --git a/ompi/include/mpif-config.h.in b/ompi/include/mpif-config.h.in index 0e33652e9a..905adcf2fc 100644 --- a/ompi/include/mpif-config.h.in +++ b/ompi/include/mpif-config.h.in @@ -10,7 +10,7 @@ ! University of Stuttgart. All rights reserved. ! Copyright (c) 2004-2005 The Regents of the University of California. ! All rights reserved. -! Copyright (c) 2006 Cisco Systems, Inc. All rights reserved. +! Copyright (c) 2006-2010 Cisco Systems, Inc. All rights reserved. ! $COPYRIGHT$ ! ! Additional copyrights may follow @@ -88,7 +88,7 @@ ! Miscellaneous constants ! integer MPI_STATUS_SIZE - parameter (MPI_STATUS_SIZE=5) + parameter (MPI_STATUS_SIZE=@OMPI_FORTRAN_STATUS_SIZE@) ! ! Configurable length constants ! diff --git a/ompi/mpi/c/status_c2f.c b/ompi/mpi/c/status_c2f.c index 22fd96f1e5..17ad5d17cb 100644 --- a/ompi/mpi/c/status_c2f.c +++ b/ompi/mpi/c/status_c2f.c @@ -9,6 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. + * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -66,16 +67,31 @@ int MPI_Status_c2f(MPI_Status *c_status, MPI_Fint *f_status) } } + /* Note that MPI-2.2 16.3.5 states that even the hidden data in a + status must be converted (!). This is somewhat problematic + because the Fortran data is all INTEGERS while the C MPI_Status + contains a size_t. That being said, note 2 things: + + 1. The _ucount and _canceled members are never accessed from + Fortran. + 2. configure calculated a value of MPI_STATUS_SIZE to ensure + that the Fortran status is the Right size to hold the C + MPI_Status (including the size_t member). + + So for the purposes of this function, just copy over all the + data as if they were int's. This works because all OMPI + Fortran MPI API functions that take a status as an IN argument + first call MPI_Status_f2c on it before using it (in which case + we'll do the exact opposite copy, thereby rebuilding the size_t + value properly before it is accessed in C). + + Note that if sizeof(int) > sizeof(INTEGER), we're potentially + hosed anyway (i.e., even the public values in the status could + get truncated). But if sizeof(int) == sizeof(INTEGER) or + sizeof(int) < sizeof(INTEGER), everything should be kosher. */ c_ints = (int*)c_status; for( i = 0; i < (int)(sizeof(MPI_Status) / sizeof(int)); i++ ) f_status[i] = OMPI_INT_2_FINT(c_ints[i]); - /* - f_status[0] = OMPI_INT_2_FINT(c_status->MPI_SOURCE); - f_status[1] = OMPI_INT_2_FINT(c_status->MPI_TAG); - f_status[2] = OMPI_INT_2_FINT(c_status->MPI_ERROR); - f_status[3] = OMPI_INT_2_FINT(c_status->_count); - f_status[4] = OMPI_INT_2_FINT(c_status->_cancelled); - */ return MPI_SUCCESS; } diff --git a/ompi/mpi/c/status_f2c.c b/ompi/mpi/c/status_f2c.c index b24807697f..bb404e0118 100644 --- a/ompi/mpi/c/status_f2c.c +++ b/ompi/mpi/c/status_f2c.c @@ -9,6 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. + * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -62,18 +63,16 @@ int MPI_Status_f2c(MPI_Fint *f_status, MPI_Status *c_status) } } - /* We can't use OMPI_FINT_2_INT here because of some complications + /* ***NOTE*** See huge comment in status_c2f.c (yes, I know + there's a size_t member in the C MPI_Status -- go + read that comment for an explanation why copying + everything as a bunch of int's is ok). + + We can't use OMPI_FINT_2_INT here because of some complications with include files. :-( So just do the casting manually. */ c_ints = (int*)c_status; for( i = 0; i < (int)(sizeof(MPI_Status) / sizeof(int)); i++ ) c_ints[i] = (int)f_status[i]; - /* - c_status->MPI_SOURCE = (int) f_status[0]; - c_status->MPI_TAG = (int) f_status[1]; - c_status->MPI_ERROR = (int) f_status[2]; - c_status->_count = (int) f_status[3]; - c_status->_cancelled = (int) f_status[4]; - */ return MPI_SUCCESS; }