[mpich-commits] [mpich] MPICH primary repository branch, release/mpich-3.0.x, updated. v3.0.4-6-g9a19e6b

mysql vizuser noreply at mpich.org
Thu May 2 18:05:32 CDT 2013


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "MPICH primary repository".

The branch, release/mpich-3.0.x has been updated
       via  9a19e6b6774e8b9a9fd2ffe86fe5cbe570c86559 (commit)
       via  a9a1d54629a910b7bfa57d60bf665ddd1b83b066 (commit)
      from  45305a3a74fe8a4bb4667892ccebc9b2f15fbbc4 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.mpich.org/mpich.git/commitdiff/9a19e6b6774e8b9a9fd2ffe86fe5cbe570c86559

commit 9a19e6b6774e8b9a9fd2ffe86fe5cbe570c86559
Author: William Gropp <wgropp at illinois.edu>
Date:   Thu May 2 12:49:26 2013 -0400

    Fixes for #1804 and #1828, related to alignment issues with MPI_Status
    
    There are two alignment-related problems with MPI_STATUS arguments in
    Fortran.  The first is that while MPI_STATUS is an INTEGER array in
    Fortran, in C there is an element of type MPI_Count.  MPI_Count may
    be longer than an INTEGER and thus a C MPI_Status may have a stricter
    alignment requirement than a Fortran INTEGER array. The fixes to
    src/binding/f77/buildiface ensures that STATUS arguments that are
    provided to C by the Fortran wrappers are properly aligned, while avoiding
    copies when possible.  The second fix deals with padding that the
    introduction of MPI_Count as the count type into the C structure for
    status will often introduce.

diff --git a/.gitignore b/.gitignore
index 1634a5a..ed5203c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -159,6 +159,7 @@ Makefile.am-stamp
 /README.envvar
 /maint/extracterrmsgs
 /src/binding/f90/mpi_base.f90.in
+/src/binding/f90/mpi_constants.f90.in
 /src/env/mpixxx_opts.conf
 /src/mpi/romio/include/mpio.h
 /src/mpi/romio/include/mpiof.h
diff --git a/configure.ac b/configure.ac
index 6b7237c..f3d3c2d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4079,9 +4079,10 @@ dnl     len_doublecplx=$hexlen
         #
         PAC_PROG_FC_INT_KIND(INTEGER_KIND,$pac_cv_f77_sizeof_integer,$CROSS_F90_INTEGER_KIND)
         if test "$INTEGER_KIND" = "-1" ; then
-	    # Wild guess; probably means that Fortran 90 is not available
-	    AC_MSG_WARN([Unable to determine Fortran 90 KIND values for either address-sized integers or offset-sized integers.  Using 4 in that case.])
-            INTEGER_KIND=4
+	    # In our experience, this usually means that there is some
+	    # problem building and/or running the f90 program.  Fail
+	    # in this case rather than attempt to continue
+	    AC_MSG_ERROR([Unable to determine Fortran 90 KIND values for either address-sized integers or offset-sized integers.])
         fi
 	#
         # Some compilers won't allow a -1 kind (e.g., absoft).  In this case, 
@@ -5792,6 +5793,8 @@ if test "$enable_f77" = yes -a -z "$MPI_STATUS_SIZE" ; then
     if test $MPI_SIZEOF_COUNT -gt $pac_cv_f77_sizeof_integer ; then
         # Alignment test looks at the low address bits, as long
 	# as the sizeof(MPI_Count) is 2^j.  
+	# If we can't tell, pick a value that forces the Fortran
+	# wrappers to use a local copy.
 	MPIR_COUNT_ALIGNMENT=0
 	case $MPI_SIZEOF_COUNT in 
 	4)  MPIR_COUNT_ALIGNMENT="0x3";;
@@ -5801,6 +5804,77 @@ if test "$enable_f77" = yes -a -z "$MPI_STATUS_SIZE" ; then
 	esac
         
         AC_DEFINE_UNQUOTED([MPIR_COUNT_ALIGNMENT],[$MPIR_COUNT_ALIGNMENT],[Value that anded with an address will give 0 if the address is properly aligned for MPI_Count])
+
+	# Compare the size of MPI_Status to the sizes of the individual 
+	# elements.  If the sizeof(MPI_Status) > sum of the sizes, then
+	# determine if simple padding will work.
+	# FIXME: DETERMINED TO SEE IF THERE IS PROBLEM BUT NOT YET USED
+	AC_MSG_CHECKING([whether MPI_Status contains padding])
+	sum_of_status_element_sizes=`expr 6 \* $ac_cv_sizeof_int + $MPI_SIZEOF_COUNT`
+	if test $sum_of_status_element_sizes -lt $pac_cv_sizeof_mpi_status ; then
+	    AC_MSG_RESULT([yes])
+	    if test "$enable_fc" = "yes" ; then
+	        # FIXME: We could compute the padding or delete the 
+		# status definition from mpi_constants
+		AC_MSG_CHECKING([padding size before count field in MPI_Status])
+                rm -f pac_mpi_status.h
+dnl quote with [] since otherwise m4 strips the array declaration out of this
+dnl structure
+[                cat > pac_mpi_status.h <<_EOF
+typedef struct {
+    int MPI_SOURCE;
+    int MPI_TAG;
+    int MPI_ERROR;
+    $MPI_COUNT count;
+    int cancelled;
+    int abi_slush_fund[2];
+    $EXTRA_STATUS_DECL
+} MPI_Status;
+MPI_Status mya;
+_EOF
+]
+		AC_COMPUTE_INT(pac_cv_fc_pad1,[((char*)&mya.count-(((char*)&mya)+3*sizeof(int)))],[AC_INCLUDES_DEFAULT()
+#include "pac_mpi_status.h"])
+                AC_MSG_RESULT($pac_cv_fc_pad1)
+		AC_MSG_CHECKING([padding at end of MPI_Status])
+		AC_COMPUTE_INT(pac_cv_fc_pad2,[((char*)(&mya + 1) - ((char *)(mya.abi_slush_fund+1) + sizeof(int)))],[AC_INCLUDES_DEFAULT()
+#include "pac_mpi_status.h"])
+		AC_MSG_RESULT($pac_cv_fc_pad2)
+                rm -f pac_mpi_status.h
+		pac_cv_pad1found=no
+		pac_cv_pad2found=no
+		FC_STATUS_PAD1=""
+		FC_STATUS_PAD2=""
+		AC_SUBST(FC_STATUS_PAD1)
+		AC_SUBST(FC_STATUS_PAD2)
+		if test $pac_cv_fc_pad1 -gt 0 ; then
+		    if test $pac_cv_fc_pad1 -eq $ac_cv_sizeof_int ; then
+		        pac_cv_pad1found=yes
+			FC_STATUS_PAD1="INTEGER :: PAD1"
+		    fi
+                else 
+		    # No padding needed here, so successfully determined
+		    # padding
+		    pac_cv_pad1found=yes
+                fi
+		if test $pac_cv_fc_pad2 -gt 0 ; then
+		    if test $pac_cv_fc_pad2 -eq $ac_cv_sizeof_int ; then
+		        pac_cv_pad2found=yes
+			FC_STATUS_PAD2="INTEGER :: PAD2"
+		    fi
+                else 
+		    # No padding needed here, so successfully determined
+		    # padding
+		    pac_cv_pad2found=yes
+                fi
+		if test $pac_cv_pad1found = "no" -o \
+		        $pac_cv_pad2found = "no" ; then
+                    AC_MSG_ERROR([INTERNAL ERROR: definition of MPI_Status in C and Fortran 90 is incompatible due to padding in the C definition])
+		fi
+	    fi
+	else
+	    AC_MSG_RESULT([no])
+	fi
     fi 
 fi
 AC_SUBST([MPI_STATUS_SIZE])
@@ -6063,6 +6137,7 @@ AC_OUTPUT(Makefile \
 	  src/binding/f77/setbot.c \
 	  src/binding/f90/mpi_sizeofs.f90 \
 	  src/binding/f90/mpi_base.f90 \
+	  src/binding/f90/mpi_constants.f90 \
 	  src/packaging/pkgconfig/mpich.pc \
 	  src/packaging/envmods/mpich.module \
           src/env/mpixxx_opts.conf \
diff --git a/src/binding/f77/buildiface b/src/binding/f77/buildiface
index f6c6611..5f30c6d 100755
--- a/src/binding/f77/buildiface
+++ b/src/binding/f77/buildiface
@@ -2553,10 +2553,18 @@ sub status_out_ftoc {
 	# casting to a pointer with greater alignment (and which the
 	# specific runtime check is used to ensure the alignments are 
 	# ok).
+	# Horrible requirement: MPI Standard (see MPI-3, Section 3.2.5, 
+        # page 30, lines 39-43) implies that the MPI_ERROR field needs
+	# to be *preserved*.  Thus, if we have a temp status, we need to
+	# either copy it to the temp status (as here) or *not* copy over 
+	# it when storing the result.  This is simpler.
 	print $OUTFD "\
-    if (l$count != MPI_STATUS_IGNORE && 
-        (((MPI_Aint)v$count) & MPIR_COUNT_ALIGNMENT) == 0) 
-        l$count = (MPI_Status*)(void *)v$count;\n";
+    if (l$count != MPI_STATUS_IGNORE) {
+        if ((((MPI_Aint)v$count) & MPIR_COUNT_ALIGNMENT) == 0) 
+            l$count = (MPI_Status*)(void *)v$count;
+	else 
+            l$count->MPI_ERROR = ((MPI_Status*)v$count)->MPI_ERROR;
+    }\n";
     }
 }
 sub status_out_arg {
@@ -2679,9 +2687,17 @@ sub status_array_out_fnulltoc {
 }
 sub status_array_out_ftoc {
     my $count = $_[0];
-    
+ 
+    # See discussion of status_out_ftoc - unfortunately, we need to
+    # copy *just* the MPI_ERROR field
     if ($within_fint) {
-	print $OUTFD "    if (l$count != MPI_STATUSES_IGNORE) { l$count = (MPI_Status*)$malloc($Array_size * sizeof(MPI_Status)); }\n";
+	print $OUTFD "\
+    if (l$count != MPI_STATUSES_IGNORE) { 
+        int li;
+        l$count = (MPI_Status*)$malloc($Array_size * sizeof(MPI_Status)); 
+        for (li=0; li<$Array_size; li++) 
+            l$count\[li].MPI_ERROR = ((MPI_Status*)v$count)[li].MPI_ERROR;
+    }\n";
     }
     elsif ($fixStatusAlignment) {
 	print $OUTFD "\
@@ -2689,8 +2705,11 @@ sub status_array_out_ftoc {
         if( (((MPI_Aint)v$count) & MPIR_COUNT_ALIGNMENT) == 0) 
             l$count = (MPI_Status*)(void *)v$count;
         else {
+            int li;
             lalloc$count = 1;
             l$count = (MPI_Status*)$malloc($Array_size * sizeof(MPI_Status));
+            for (li=0; li<$Array_size; li++) 
+                l$count\[li].MPI_ERROR = ((MPI_Status*)v$count)[li].MPI_ERROR;
         }
     }\n";
     }
@@ -2714,7 +2733,7 @@ sub status_array_ctof {
 "    if ($testFlag$coutvar != MPI_STATUSES_IGNORE) {
         int li;
         for (li=0; li<$ActSize; li++) {
-            MPI_Status_c2f($coutvar+li,$outvar+li*5);
+            MPI_Status_c2f($coutvar+li,$outvar+li*MPIF_STATUS_SIZE);
         }
     }\n";
 	$clean_up .= "     if ($coutvar != MPI_STATUSES_IGNORE) { $free($coutvar); }\n";
@@ -2732,7 +2751,7 @@ sub status_array_ctof {
 "    if (${testFlag}lalloc$count) {
         int li;
         for (li=0; li<$ActSize; li++) {
-            MPI_Status_c2f($coutvar+li,$outvar+li*5);
+            MPI_Status_c2f($coutvar+li,$outvar+li*MPIF_STATUS_SIZE);
         }
     }\n";
 	$clean_up .= "     if (lalloc$count) { $free($coutvar); }\n";
diff --git a/src/binding/f90/buildiface b/src/binding/f90/buildiface
index c5eb901..d84ef1f 100755
--- a/src/binding/f90/buildiface
+++ b/src/binding/f90/buildiface
@@ -603,7 +603,7 @@ print MPIBASEFD "       END MODULE ${ucoutfile_prefix}_BASE\n";
 close MPIBASEFD;
 &ReplaceIfDifferent( "${outfile_prefix}_base.f90.in", "${outfile_prefix}_base.f90.in.new" );
 
-open ( MPIFD, ">${outfile_prefix}_constants.f90.new" ) || die "Cannot open ${outfile_prefix}_constants.f90.new\n";
+open ( MPIFD, ">${outfile_prefix}_constants.f90.in.new" ) || die "Cannot open ${outfile_prefix}_constants.f90.in.new\n";
 print MPIFD "!     -*- Mode: Fortran; -*-
 !  (C) 2008 by Argonne National Laboratory.
 !       See COPYRIGHT in top-level directory.
@@ -642,13 +642,21 @@ $PRIVATEVAR = "";
 #
 #$BINDACCESS = ", BIND(C)";
 #$BINDDEF ="";
+# Yet another problem.
+# Because MPI_Count may be longer than a single (Fortran) INTEGER, 
+# alignment restrictions may introduce padding in the structure
+# And one more problem: If a Fortran INTEGER is not the same as a C int,
+# then these are also wrong (see the "fint" option in 
+# src/binding/f77/buildiface 
 print MPIFD <<EOT;
         TYPE$BINDACCESS :: MPI_Status
            $BINDDEF
            INTEGER$PUBLICVAR :: MPI_SOURCE, MPI_TAG, MPI_ERROR
+           \@FC_STATUS_PAD1\@
            INTEGER$PRIVATEVAR(KIND=MPI_COUNT_KIND) :: count
            INTEGER$PRIVATEVAR :: cancelled
            INTEGER$PRIVATEVAR(2) :: abi_slush_fund
+           \@FC_STATUS_PAD2\@
         END TYPE MPI_Status
 EOT
 
@@ -708,7 +716,7 @@ foreach $handle (keys(%handles)) {
 
 print MPIFD "        END MODULE ${ucoutfile_prefix}_CONSTANTS\n";
 close MPIFD;
-&ReplaceIfDifferent( "${outfile_prefix}_constants.f90", "${outfile_prefix}_constants.f90.new" );
+&ReplaceIfDifferent( "${outfile_prefix}_constants.f90.in", "${outfile_prefix}_constants.f90.in.new" );
 
 #
 # Generate the choice argument routines

http://git.mpich.org/mpich.git/commitdiff/a9a1d54629a910b7bfa57d60bf665ddd1b83b066

commit a9a1d54629a910b7bfa57d60bf665ddd1b83b066
Author: William Gropp <wgropp at illinois.edu>
Date:   Sun Apr 28 19:16:05 2013 -0500

    Fix for #1804 - Alignment issues in Fortran with MPI_Status
    
    Changed the Fortran wrapper generator to test for proper alignment of
    MPI_Status - because of the new MPI_Count field, some systems may need
    MPI_Status to be aligned on a multiple of sizeof(MPI_Count).  By
    default, new code enforces that, using a temporay status variable only
    when required.  Cost is a few additional tests.

diff --git a/configure.ac b/configure.ac
index 35dc573..6b7237c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5783,6 +5783,25 @@ if test "$enable_f77" = yes -a -z "$MPI_STATUS_SIZE" ; then
     else
         AC_MSG_ERROR([MPI_STATUS_SIZE was not defined!])
     fi
+
+    # Because MPI_Status may contain C integers of different sizes 
+    # and with different alignments, we determine the maximum element
+    # size and then tell Fortran to enforce maximal alignment.  
+    # A more sophisticated test would determine the required alignment,
+    # rather than assuming alignment to maximum size
+    if test $MPI_SIZEOF_COUNT -gt $pac_cv_f77_sizeof_integer ; then
+        # Alignment test looks at the low address bits, as long
+	# as the sizeof(MPI_Count) is 2^j.  
+	MPIR_COUNT_ALIGNMENT=0
+	case $MPI_SIZEOF_COUNT in 
+	4)  MPIR_COUNT_ALIGNMENT="0x3";;
+	8)  MPIR_COUNT_ALIGNMENT="0x7";;
+	16) MPIR_COUNT_ALIGNMENT="0xF";;
+	*)  MPIR_COUNT_ALIGNMENT=-1 ;;
+	esac
+        
+        AC_DEFINE_UNQUOTED([MPIR_COUNT_ALIGNMENT],[$MPIR_COUNT_ALIGNMENT],[Value that anded with an address will give 0 if the address is properly aligned for MPI_Count])
+    fi 
 fi
 AC_SUBST([MPI_STATUS_SIZE])
 MPIF_STATUS_SIZE=$MPI_STATUS_SIZE
diff --git a/src/binding/f77/buildiface b/src/binding/f77/buildiface
index 66ad07e..f6c6611 100755
--- a/src/binding/f77/buildiface
+++ b/src/binding/f77/buildiface
@@ -46,6 +46,10 @@ $do_fint = 0;            # Set to 1 to support C and Fortran integers of a
                          # different size
 $within_fint = 0;        # This is set to 1 while generating code for the 
                          # do_fint branch
+$fixStatusAlignment = 1; # Set to 1 to generate code that 
+                         # handles different alignment rules between
+                         # Fortran (INTEGER) and C (likely MPI_Count)
+                         # Note set by feature value do_fixstatus .
 %fintToHandle = ( 'int' => 1, 'MPI_Request' => 1, 'MPI_Group' => 1, 
 		  'MPI_Win' => 1, 'MPI_Info' => 1, 'MPI_Errhandler' => 1, 
 		  'MPI_File' => 1, 'MPI_Op' => 1, 'MPI_Message' => 1 );
@@ -68,6 +72,7 @@ $do_logical = 1;
 $do_weak    = 1;
 $do_subdecls = 1;
 $do_bufptr = 1;
+$do_fixstatus = 1;
 $prototype_file = "../../include/mpi.h.in";
 
 # Global hashes used for definitions and to record the locations of the
@@ -107,8 +112,8 @@ $specialInitString = "\
 # Process arguments
 #
 # Args
-# -feature={logical,fint,subdecls,weak,bufptr}, separated by :, value given 
-# by =on or =off, eg
+# -feature={logical,fint,subdecls,weak,bufptr,fixstatus}, 
+#  separated by :, value given by =on or =off, eg
 # -feature=logical=on:fint=off
 # The feature names mean:
 #    logical - Fortran logicals are converted to/from C
@@ -117,6 +122,11 @@ $specialInitString = "\
 #    weak    - Use weak symbols 
 #    bufptr  - Check for MPI_BOTTOM as a special address.  This is
 #              not needed if a POINTER declaration is available.
+#    fixstatus - The alignment of a Fortran STATUS array may not always
+#              be what is required in C (particularly with MPI_Count in 
+#              MPI_Status now).  If set, generate code to handle this case.
+#              Systems without alignment restrictions can set this to off,
+#              which will remove some tests.
 foreach $_ (@ARGV) {
     if (/-noprototypes/) { $build_prototypes = 0; }
     elsif (/-infile=(.*)/) {
@@ -161,6 +171,8 @@ foreach $_ (@ARGV) {
 	print STDERR "Unrecognized argument $_\n";
     }
 }
+# For now, make these equal.  
+$fixStatusAlignment = $do_fixstatus;
 
 # Note that the code that looks up values strips blanks out of the type name
 # No blanks should be used in the key.
@@ -647,18 +659,18 @@ foreach $_ (@ARGV) {
                  'Testsome-2' => 'inout:handle_array:*v1:MPI_Request',
                  'Testsome-3' => 'out:fint2int',
                  'Testsome-4' => 'out:index_array:*v1:*v3',
-		 'Testsome-5' => 'out:status_array:*v1:*v3:l3>0',
+		 'Testsome-5' => 'out:status_array:*v1:*v3:*v3>0',
     'Get_count' => '1', 'Get_count-1' => 'in:status',
     'Request_get_status' => '2:3',
       'Request_get_status-2' => 'out:logical',
       'Request_get_status-3' => 'out:status',
     'Status_set_cancelled' => '1:2',
-      'Status_set_cancelled-1' => 'in:status',
+      'Status_set_cancelled-1' => 'inout:status',
       'Status_set_cancelled-2' => 'in:logical',
     'Status_set_elements' => '1',
-      'Status_set_elements-1' => 'out:status',
+      'Status_set_elements-1' => 'inout:status',
     'Status_set_elements_x' => '1', 
-      'Status_set_elements_x-1' => 'out:status',
+      'Status_set_elements_x-1' => 'inout:status',
     'Type_contiguous' => '2:3', 
                   'Type_contiguous-2' => 'in:handle::MPI_Datatype',
                   'Type_contiguous-3' => 'out:handle::MPI_Datatype',
@@ -1744,6 +1756,7 @@ sub bufptr_in_arg {
 sub bufptr_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
 }
 # --------------------------------------------------------------------------
 # MPI_IN_PLACE buffer pointers
@@ -1763,6 +1776,7 @@ sub inplace_in_arg {
 sub inplace_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
 }
 # --------------------------------------------------------------------------
 # MPI_UNWEIGHTED pointers.  Note that unweighted is only used to indicate
@@ -1839,6 +1853,7 @@ sub unweighted_out_arg {
 sub unweighted_out_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
 
     if ($within_fint) {
         # MPI_WEIGHTS_EMPTY should never be an output value from the MPI library
@@ -1877,6 +1892,7 @@ sub logical_in_arg {
 sub logical_out_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
     if ($do_logical) {
 	print $OUTFD "    if ($errparmlval == MPI_SUCCESS) *$outvar = MPIR_TO_FLOG($coutvar);\n";
     }
@@ -1940,6 +1956,7 @@ sub logical_array_in_arg {
 sub logical_array_out_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
     # Special case if MPI_Fint == int: we use the input variable
     # for space.
     my $ActSize = $Array_size;
@@ -1984,6 +2001,7 @@ sub index_ftoc {
 sub index_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
     print $OUTFD "    *$outvar = (MPI_Fint)$coutvar;\n";
     print $OUTFD "    if ($coutvar >= 0) *$outvar = *$outvar + 1;\n";
 }
@@ -2010,6 +2028,7 @@ sub index_array_out_ftoc {
 sub index_array_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
     my $ActSize = $Array_size;
     # In the case where the input and out sizes are not the same,
     # the output size is in the fourth argument.
@@ -2082,6 +2101,7 @@ sub handle_inout_ftoc {
 sub handle_out_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
     if ($within_fint) {
 	print $OUTFD "    if ($errparmlval==MPI_SUCCESS) *$outvar = (MPI_Fint)$coutvar;\n";
     }
@@ -2204,7 +2224,8 @@ sub handle_array_out_ftoc {
 sub handle_array_inout_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
-    &handle_array_ctof( $coutvar, $outvar );
+    my $count   = $_[2];
+    &handle_array_ctof( $coutvar, $outvar, $count );
 }
 
 # Make sure that there is no output processing (other than to free the 
@@ -2212,12 +2233,14 @@ sub handle_array_inout_ctof {
 sub handle_array_in_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
-    #&handle_array_ctof( $coutvar, $outvar );
+    my $count   = $_[2];
+    #&handle_array_ctof( $coutvar, $outvar, $count );
 }
 
 sub handle_array_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
     if ($within_fint) {
 	my $basetype = $nativeType;
 	$basetype =~ s/MPI_//;
@@ -2228,7 +2251,7 @@ sub handle_array_ctof {
 	    $asize = "_csize";
 	}
 	print $OUTFD "\
-        /* handle_array_ctof( $coutvar, $outvar ) */
+        /* handle_array_ctof( $coutvar, $outvar, $count ) */
     {int li;
      for (li=0; li<$asize; li++) {
         $outvar\[li\] = $convfunc( $coutvar\[li\] );
@@ -2336,6 +2359,7 @@ sub addrint_in_arg {
 sub attrint_ctof {
     my $fvar = $_[0];
     my $cvar = $_[1];
+    my $count   = $_[2];
     my $flagarg = 4; # get from option
     # The strange cast is due to the following:
     # The MPICH attribute code returns an int in the void *.  In
@@ -2392,6 +2416,7 @@ sub addraint_in_arg {
 sub attraint_ctof {
     my $fvar = $_[0];
     my $cvar = $_[1];
+    my $count   = $_[2];
     my $flagarg = 4; # get from option
     print $OUTFD "
     if ((int)*ierr || !l$flagarg) {
@@ -2429,6 +2454,7 @@ sub bufaddr_out_arg {
 sub bufaddr_ctof {
     my $fvar = $_[0];
     my $cvar = $_[1];
+    my $count   = $_[2];
 }
 # --------------------------------------------------------------------------
 # 
@@ -2449,6 +2475,10 @@ sub status_out_fnulltoc {
     if (v$count == MPI_F_STATUS_IGNORE) { l$count = MPI_STATUS_IGNORE; }
     else { l$count->MPI_ERROR = (int)(v$count\[2\]); }\n";
     }
+    elsif ($fixStatusAlignment) {
+	print $OUTFD "\
+    if (v$count == MPI_F_STATUS_IGNORE) { l$count = MPI_STATUS_IGNORE; }\n";
+    }
     else {
 	print $OUTFD "\
     if (v$count == MPI_F_STATUS_IGNORE) { v$count = (MPI_Fint*)MPI_STATUS_IGNORE; }\n";
@@ -2460,11 +2490,26 @@ sub status_in_ftoc {
     if ($within_fint) {
 	print $OUTFD "    MPI_Status_f2c( v$count, l$count );\n";
     }
+    elsif ($fixStatusAlignment) {
+	print $OUTFD "\
+    if ( l$count != MPI_STATUS_IGNORE && 
+        (((MPI_Aint)v$count) & MPIR_COUNT_ALIGNMENT) == 0 ) 
+        l$count = (MPI_Status *)(void*)v$count;
+    else {
+        MPI_Status_f2c( v$count, l$count );
+    }
+";
+    }
+}
+sub status_inout_ftoc {
+    my $count = $_[0];
+    status_in_ftoc( $count );
 }
 
 sub status_out_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
     if ($within_fint) {
 	my $testFlag = "";
 	if (defined($condition) && $condition ne "") {
@@ -2473,24 +2518,50 @@ sub status_out_ctof {
 	print $OUTFD 
 "    if ($testFlag$coutvar != MPI_STATUS_IGNORE && $errparmlval == MPI_SUCCESS) {
 	MPI_Status_c2f($coutvar,$outvar);
-    }\n"
+    }\n";
+    }
+    elsif ($fixStatusAlignment) {
+	# only copy if Fortran is not properly aligned
+	print $OUTFD "\
+    if ($coutvar != MPI_STATUS_IGNORE && $errparmlval == MPI_SUCCESS && $outvar != (MPI_Fint*)$coutvar) {
+        MPI_Status_c2f($coutvar,$outvar);
+    }\n";
     }
 }
 sub status_in_decl {
     my $count = $_[0];
-    if ($within_fint) {
+    if ($within_fint || $fixStatusAlignment) {
 	print $OUTFD "    MPI_Status vtmp$count, *l$count = &vtmp$count;\n";
     }
 }
 sub status_out_decl {
     my $count = $_[0];
-    if ($within_fint) {
+    if ($within_fint || $fixStatusAlignment) {
 	print $OUTFD "    MPI_Status vtmp$count, *l$count = &vtmp$count;\n";
     }
 }
+sub status_inout_decl {
+    my $count = $_[0];
+    if ($within_fint || $fixStatusAlignment) {
+	print $OUTFD "    MPI_Status vtmp$count, *l$count = &vtmp$count;\n";
+    }
+}
+sub status_out_ftoc {
+    my $count = $_[0];
+    if ($fixStatusAlignment) {
+	# The first (void *) cast helps suppress compiler warnings about
+	# casting to a pointer with greater alignment (and which the
+	# specific runtime check is used to ensure the alignments are 
+	# ok).
+	print $OUTFD "\
+    if (l$count != MPI_STATUS_IGNORE && 
+        (((MPI_Aint)v$count) & MPIR_COUNT_ALIGNMENT) == 0) 
+        l$count = (MPI_Status*)(void *)v$count;\n";
+    }
+}
 sub status_out_arg {
     my $count = $_[0];
-    if ($within_fint) {
+    if ($within_fint|| $fixStatusAlignment) {
 	print $OUTFD "l$count";
     }
     else {
@@ -2499,7 +2570,16 @@ sub status_out_arg {
 }
 sub status_in_arg {
     my $count = $_[0];
-    if ($within_fint) {
+    if ($within_fint || $fixStatusAlignment) {
+	print $OUTFD "l$count";
+    }
+    else {
+	print $OUTFD "(MPI_Status *)(v$count)";
+    }
+}
+sub status_inout_arg {
+    my $count = $_[0];
+    if ($within_fint || $fixStatusAlignment) {
 	print $OUTFD "l$count";
     }
     else {
@@ -2549,6 +2629,7 @@ sub errcodesignore_out_ftoc {
 sub errcodesignore_out_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
 
     if ($within_fint) {
 	$asize = $Array_size;
@@ -2592,7 +2673,7 @@ sub status_array_out_fnulltoc {
     &specialInitStatement( $OUTFD );
     my $varname = "v";
     my $varcast = "(MPI_Fint *)";
-    if ($within_fint) { $varname = "l"; $varcast = ""; }
+    if ($within_fint || $fixStatusAlignment) { $varname = "l"; $varcast = ""; }
     print $OUTFD "\
     if (v$count == MPI_F_STATUSES_IGNORE) { $varname$count = ${varcast}MPI_STATUSES_IGNORE; }\n";
 }
@@ -2602,11 +2683,23 @@ sub status_array_out_ftoc {
     if ($within_fint) {
 	print $OUTFD "    if (l$count != MPI_STATUSES_IGNORE) { l$count = (MPI_Status*)$malloc($Array_size * sizeof(MPI_Status)); }\n";
     }
+    elsif ($fixStatusAlignment) {
+	print $OUTFD "\
+    if (l$count != MPI_STATUSES_IGNORE) {
+        if( (((MPI_Aint)v$count) & MPIR_COUNT_ALIGNMENT) == 0) 
+            l$count = (MPI_Status*)(void *)v$count;
+        else {
+            lalloc$count = 1;
+            l$count = (MPI_Status*)$malloc($Array_size * sizeof(MPI_Status));
+        }
+    }\n";
+    }
 }
 
 sub status_array_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
 
     if ($within_fint) {
 	my $ActSize = $Array_size;
@@ -2626,17 +2719,38 @@ sub status_array_ctof {
     }\n";
 	$clean_up .= "     if ($coutvar != MPI_STATUSES_IGNORE) { $free($coutvar); }\n";
     }
+    elsif ($fixStatusAlignment) {
+	my $ActSize = $Array_size;
+	if (defined($nativeType) && $nativeType ne "") { 
+	    $ActSize = $nativeType; 
+	}
+	my $testFlag = "";
+	if (defined($condition) && $condition ne "") {
+	    $testFlag = "$condition && "
+	}
+	print $OUTFD 
+"    if (${testFlag}lalloc$count) {
+        int li;
+        for (li=0; li<$ActSize; li++) {
+            MPI_Status_c2f($coutvar+li,$outvar+li*5);
+        }
+    }\n";
+	$clean_up .= "     if (lalloc$count) { $free($coutvar); }\n";
+    }
 }
 sub status_array_out_decl {
     my $count = $_[0];
     if ($within_fint) {
 	print $OUTFD "    MPI_Status *l$count=0;\n";
+    } 
+    elsif ($fixStatusAlignment) {
+	print $OUTFD "    MPI_Status *l$count=0;\n    int lalloc$count=0;\n";
     }
 }
 sub status_array_out_arg {
     my $count = $_[0];
 
-    if ($within_fint) {
+    if ($within_fint || $fixStatusAlignment) {
 	print $OUTFD "l$count";
     }
     else {
@@ -2648,6 +2762,7 @@ sub status_array_out_arg {
 sub aintToInt_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
     print $OUTFD "    if ($errparmlval == MPI_SUCCESS) *$outvar = (MPI_Fint)($coutvar);\n";
 }
 sub aintToInt_out_decl {
@@ -2685,6 +2800,7 @@ sub fint2int_ftoc {
 sub fint2int_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
     if ($within_fint) {
 	print $OUTFD "    if ($errparmlval == MPI_SUCCESS) *$outvar = (MPI_Fint)$coutvar;\n";
     }
@@ -2800,6 +2916,7 @@ sub fint2int_array_out_ftoc {
 sub fint2int_array_out_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
     if ($within_fint) {
 	my $asize = $Array_size;
 	if ($Array_size =~ /_commsize/) {
@@ -3033,16 +3150,16 @@ sub print_post_call {
 	    $processing_routine       = "${method}_${direction}_ctof";
 	    # Prefer a specific choice matching the direction
 	    if (defined(&$processing_routine)) {
-		&$processing_routine( "l$count", "v$count" );
+		&$processing_routine( "l$count", "v$count", $count );
 	    }
 	    elsif ($direction eq "inout" && 
 		   defined(&$processing_out_routine)) {
-		&$processing_out_routine( "l$count", "v$count" );
+		&$processing_out_routine( "l$count", "v$count", $count );
 		}
 	    else {
 		$processing_routine = "${method}_ctof";
 		if (defined(&$processing_routine)) {
-		    &$processing_routine( "l$count", "v$count" );
+		    &$processing_routine( "l$count", "v$count", $count );
 		}
 		elsif ($direction ne "in") {
 		    print STDERR "Missing $processing_routine for $routine_name\n";
@@ -3090,6 +3207,7 @@ sub blankpad_out_ftoc {
 sub blankpad_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
     
     # find the null character.  Replace with blanks from there to the
     # end of the string.  The declared lenght is given by a variable
@@ -3132,6 +3250,7 @@ sub blankpadonflag_out_ftoc {
 sub blankpadonflag_ctof {
     my $coutvar = $_[0];
     my $outvar  = $_[1];
+    my $count   = $_[2];
     
     # find the null character.  Replace with blanks from there to the
     # end of the string.  The declared lenght is given by a variable
@@ -3455,6 +3574,7 @@ sub intToAintArr_in_arg {
 sub intToAintArr_in_ctof {
     my $lname = $_[0];
     my $vname = $_[1];
+    my $count   = $_[2];
     print $OUTFD "
 #ifdef HAVE_AINT_LARGER_THAN_FINT
     if ($lname) { $free($lname); }
@@ -3500,6 +3620,7 @@ sub FileToFint_out_decl {
 sub FileToFint_ctof {
     my $lvar = $_[0];
     my $gvar = $_[1];
+    my $count   = $_[2];
     print $OUTFD "    *$gvar = MPI_File_c2f($lvar);\n";
 }
 sub FileToFint_out_arg {
@@ -4515,6 +4636,7 @@ print $OUTFD "\
 	return MPIR_Err_return_comm( 0, \"MPI_Status_f2c\",  mpi_errno );
     }\n";
     if ($do_fint) {
+        #FIXME: Invalid alignment assumptions on MPI_Count field.
         print $OUTFD "\
 #ifdef HAVE_FINT_IS_INT
     *c_status = *(MPI_Status *)	f_status;
@@ -4553,7 +4675,11 @@ print $OUTFD "\
 #include \"mpi_fortimpl.h\"
 /* mpierrs.h and mpierror.h for the error code creation */
 #include \"mpierrs.h\"
-#include <stdio.h> 
+#include <stdio.h>\n";
+    if ($fixStatusAlignment) {
+	print $OUTFD "#include <string.h>\n";
+    }
+    print $OUTFD "\
 #include \"mpierror.h\"
 
 /* -- Begin Profiling Symbol Block for routine MPI_Status_c2f */
@@ -4589,6 +4715,8 @@ int MPI_Status_c2f( const MPI_Status *c_status, MPI_Fint *f_status )
 	return MPIR_Err_return_comm( 0, \"MPI_Status_c2f\",  mpi_errno );
     }\n";
     if ($do_fint) { 
+        #FIXME: Copy to f_status of MPI_Count data makes invalid alignment
+        # data.
         print $OUTFD "\
 #ifdef HAVE_FINT_IS_INT
     *(MPI_Status *)f_status = *c_status;
@@ -4601,14 +4729,24 @@ int MPI_Status_c2f( const MPI_Status *c_status, MPI_Fint *f_status )
 #endif\n";
     }
     else {
-        print $OUTFD "    *(MPI_Status *)f_status = *c_status;\n";
+        if ($fixStatusAlignment) {
+            # Within this routine, MPI_STATUS_IGNORE is invalid
+            print $OUTFD "\
+    if ( (((MPI_Aint)f_status) & MPIR_COUNT_ALIGNMENT) == 0 ) 
+        *(MPI_Status*)(void *)f_status = *c_status;
+    else
+        memcpy(f_status,c_status,sizeof(MPI_Status));
+    \n";
+        }
+        else {
+            print $OUTFD "    *(MPI_Status *)f_status = *c_status;\n";
+        }
     }
     print $OUTFD "
     return MPI_SUCCESS;
 }\n";
     close ($OUTFD);
     &ReplaceIfDifferent( $filename, $filename . ".new" );
-
 }
 
 sub print_mpif_int {

-----------------------------------------------------------------------

Summary of changes:
 .gitignore                 |    1 +
 configure.ac               |  100 +++++++++++++++++++++-
 src/binding/f77/buildiface |  207 ++++++++++++++++++++++++++++++++++++++------
 src/binding/f90/buildiface |   12 ++-
 4 files changed, 290 insertions(+), 30 deletions(-)


hooks/post-receive
-- 
MPICH primary repository


More information about the commits mailing list