[mpich2-dev] [PATCH 1/1] Issue 4882: Fix assertions when negative displacements are used in datatypes

William Gropp wgropp at uiuc.edu
Tue Apr 22 14:20:54 CDT 2008


Hi Jeff,

There are a few changes that I'd like to suggest.

Though we probably violate this rule ourselves, we try to be very  
careful with the use of the MPI_ prefix . (An example of something we  
got wrong is mentioned below.) Nonstandard items such as MPI_Pint and  
MPI_Puint should use one of the MPICH2 prefixes such as MPIR_Pint and  
MPIR_Puint if the use is entirely internal and MPIX_Pint and  
MPIX_Puint if they will be exposed in mpi.h .

An example of something that doesn't belong in mpi.h at all (and that  
we're probably responsible for) are the MPI_AINT_FMT_DEC_SPEC,  
MPI_AINT_FMT_HEX_SPEC definitions.  These aren't defined by the MPI  
standard and my guess is that these actually belong in some file  
loaded by the datatype/mpid_segment routine.  If mpiutil.h was  
created by configure, they could go into there; since its not, we'll  
need to do something different (see below).  This is important for  
us, because (a) it makes sure that our portable codes are in fact  
portable (e.g., the tests) and (b) users *will* read the mpi.h file  
and use anything they find in it (we've received bug reports from  
users that did this with another vendor's MPI).

Here's what I'd recommend.  Use MPIR_Pint and MPIR_Puint instead of  
MPI_Pint and MPI_Puint.  Put the definitions for AINT and PINT/PUINT  
into a new file, mpirdefs.h.in , that configure will use to create  
mpirdefs.h ; this file should be included by mpiutil.h .

Bill


On Apr 22, 2008, at 11:13 AM, Jeff Parker wrote:

> This patch contains a fix for problems with the BG/P MPI_Aint  
> changes previously posted, as follows:
>
> 1. Some functions in bgp/comm/lib/mpi/mpich2/src/mpid/common/ 
> datatype/dataloop/segment_ops.c have displacements in buffer  
> pointers.  The MPI_Aint changes that I previously made added  
> assertions to ensure that arithmetic on buffer pointers does not  
> overflow beyond the size of a pointer, and added casting of buffer  
> pointers to MPI_Aints.  These changes are not correct when the  
> buffer pointers contain negative offsets, and therefore have been  
> removed.
>
> 2. The MPI_Aint configurable variables were using (long) and  
> (unsigned long) as the arithmetic version of a pointer.  I changed  
> these to use the new MPI_Pint and MPI_Puint datatypes.  This will  
> generate the same code, but is the proper way to do this.
>
> Signed-off-by: Jeff Parker <jjparker at us.ibm.com>
> ---
>  lib/mpi/mpich2/configure.in                        |   36 +++---
>  lib/mpi/mpich2/src/include/mpi.h.in                |    1 +
>  lib/mpi/mpich2/src/include/mpiutil.h               |    2 +-
>  .../mpid/common/datatype/dataloop/segment_ops.c    |  124 +++++++++ 
> +++++------
>  4 files changed, 109 insertions(+), 54 deletions(-)
>
> diff --git a/lib/mpi/mpich2/configure.in b/lib/mpi/mpich2/configure.in
> index 2640d26..18f3938 100755
> --- a/lib/mpi/mpich2/configure.in
> +++ b/lib/mpi/mpich2/configure.in
> @@ -5003,6 +5003,24 @@ MPI_PUINT="unsigned $MPI_AINT"
>  AC_SUBST(MPI_PINT)
>  AC_SUBST(MPI_PUINT)
>
> +# Set:
> +#   - MPI_AINT cast to a void*
> +MPI_AINT_CAST_TO_VOID_PTR="(void*)(MPI_Pint)"
> +#   - void* cast to an MPI_AINT
> +MPI_VOID_PTR_CAST_TO_MPI_AINT="(MPI_Aint)(MPI_Puint)"
> +#   - void* containing a signed displacement cast to an MPI_AINT
> +MPI_PTR_DISP_CAST_TO_MPI_AINT="(MPI_Aint)(MPI_Pint)"
> +#   - MPI_AINT cast to a long long for printing
> +MPI_AINT_CAST_TO_LONG_LONG="(long long)"
> +export MPI_AINT_CAST_TO_VOID_PTR
> +export MPI_VOID_PTR_CAST_TO_MPI_AINT
> +export MPI_PTR_DISP_CAST_TO_MPI_AINT
> +export MPI_AINT_CAST_TO_LONG_LONG
> +AC_SUBST(MPI_AINT_CAST_TO_VOID_PTR)
> +AC_SUBST(MPI_VOID_PTR_CAST_TO_MPI_AINT)
> +AC_SUBST(MPI_PTR_DISP_CAST_TO_MPI_AINT)
> +AC_SUBST(MPI_AINT_CAST_TO_LONG_LONG)
> +
>  if test "$with_aint_size" == "0" ; then
>      # use default size
>      AC_MSG_RESULT([Default MPI_Aint $with_aint_size  
> $MPI_SIZEOF_AINT])
> @@ -5018,40 +5036,22 @@ if test "$with_aint_size" == "8" ; then
>      MPI_AINT_FMT_DEC_SPEC="%lld"
>      MPI_AINT_FMT_HEX_SPEC="%#llx"
>
> -    MPI_AINT_CAST_TO_VOID_PTR="(void*)(long)"
> -    MPI_VOID_PTR_CAST_TO_MPI_AINT="(MPI_Aint)(unsigned long)"
> -    MPI_AINT_CAST_TO_LONG_LONG="(long long)"
>      AC_DEFINE(HAVE_AINT_LARGER_THAN_FINT,1,[Define if addresses  
> are larger than Fortran integers])
>
>      export MPI_SIZEOF_AINT
>      export MPI_AINT_FMT_DEC_SPEC MPI_AINT_FMT_HEX_SPEC
> -    export MPI_AINT_CAST_TO_VOID_PTR
> -    export MPI_VOID_PTR_CAST_TO_MPI_AINT
> -    export MPI_AINT_CAST_TO_LONG_LONG
>      AC_SUBST(MPI_AINT)
>      AC_SUBST(MPI_AINT_FMT_DEC_SPEC)
>      AC_SUBST(MPI_AINT_FMT_HEX_SPEC)
> -    AC_SUBST(MPI_AINT_CAST_TO_VOID_PTR)
> -    AC_SUBST(MPI_VOID_PTR_CAST_TO_MPI_AINT)
> -    AC_SUBST(MPI_AINT_CAST_TO_LONG_LONG)
>  else
>      # use calculated MPI_Aint values
>      AC_MSG_RESULT([Use configured MPI_Aint $with_aint_size])
> -    MPI_AINT_CAST_TO_VOID_PTR="(void*)"
> -    MPI_VOID_PTR_CAST_TO_MPI_AINT="(MPI_Aint)(unsigned long)"
> -    MPI_AINT_CAST_TO_LONG_LONG="(long long)(unsigned long)"
>
>      export MPI_SIZEOF_AINT
>      export MPI_AINT_FMT_DEC_SPEC MPI_AINT_FMT_HEX_SPEC
> -    export MPI_AINT_CAST_TO_VOID_PTR
> -    export MPI_VOID_PTR_CAST_TO_MPI_AINT
> -    export MPI_AINT_CAST_TO_LONG_LONG
>      AC_SUBST(MPI_AINT)
>      AC_SUBST(MPI_AINT_FMT_DEC_SPEC)
>      AC_SUBST(MPI_AINT_FMT_HEX_SPEC)
> -    AC_SUBST(MPI_AINT_CAST_TO_VOID_PTR)
> -    AC_SUBST(MPI_VOID_PTR_CAST_TO_MPI_AINT)
> -    AC_SUBST(MPI_AINT_CAST_TO_LONG_LONG)
>  fi
>
>  # If sizeof(mpi_aint) = sizeof(int), set this value
> diff --git a/lib/mpi/mpich2/src/include/mpi.h.in b/lib/mpi/mpich2/ 
> src/include/mpi.h.in
> index b275bb7..d623a5e 100644
> --- a/lib/mpi/mpich2/src/include/mpi.h.in
> +++ b/lib/mpi/mpich2/src/include/mpi.h.in
> @@ -336,6 +336,7 @@ typedef @MPI_FINT@ MPI_Fint;
>  #define MPI_AINT_FMT_HEX_SPEC "@MPI_AINT_FMT_HEX_SPEC@"
>  #define MPI_AINT_CAST_TO_VOID_PTR @MPI_AINT_CAST_TO_VOID_PTR@
>  #define MPI_VOID_PTR_CAST_TO_MPI_AINT @MPI_VOID_PTR_CAST_TO_MPI_AINT@
> +#define MPI_PTR_DISP_CAST_TO_MPI_AINT @MPI_PTR_DISP_CAST_TO_MPI_AINT@
>  #define MPI_AINT_CAST_TO_LONG_LONG @MPI_AINT_CAST_TO_LONG_LONG@
>
>  /* Let ROMIO know that MPI_Offset is already defined */
> diff --git a/lib/mpi/mpich2/src/include/mpiutil.h b/lib/mpi/mpich2/ 
> src/include/mpiutil.h
> index 9df215c..bb9e550 100644
> --- a/lib/mpi/mpich2/src/include/mpiutil.h
> +++ b/lib/mpi/mpich2/src/include/mpiutil.h
> @@ -105,6 +105,6 @@ int MPID_Abort( struct MPID_Comm *comm, int  
> mpi_errno, int exit_code, const char
>   * \param[in]  aint  Variable of type MPI_Aint
>   */
>  #define MPID_Ensure_Aint_fits_in_pointer( aint ) \
> -  MPIU_Assert( (aint) == (MPI_Aint)(unsigned long)  
> MPI_AINT_CAST_TO_VOID_PTR (aint) );
> +  MPIU_Assert( (aint) == (MPI_Aint)(MPI_Puint)  
> MPI_AINT_CAST_TO_VOID_PTR (aint) );
>
>  #endif /* !defined(MPIUTIL_H_INCLUDED) */
> diff --git a/lib/mpi/mpich2/src/mpid/common/datatype/dataloop/ 
> segment_ops.c b/lib/mpi/mpich2/src/mpid/common/datatype/dataloop/ 
> segment_ops.c
> index 6fe799f..c7e5473 100644
> --- a/lib/mpi/mpich2/src/mpid/common/datatype/dataloop/segment_ops.c
> +++ b/lib/mpi/mpich2/src/mpid/common/datatype/dataloop/segment_ops.c
> @@ -37,6 +37,7 @@ int PREPEND_PREFIX(Segment_contig_m2m) 
> (DLOOP_Offset *blocks_p,
>
>      if (paramp->direction == DLOOP_M2M_TO_USERBUF) {
>         /* Ensure that pointer increment fits in a pointer */
> +       /* userbuf is a pointer (not a displacement) since it is  
> being used on a memcpy */
>         MPID_Ensure_Aint_fits_in_pointer 
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) + rel_off );
>         memcpy((char *) MPI_AINT_CAST_TO_VOID_PTR  
> ((MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) + rel_off),
>                paramp->streambuf,
> @@ -44,11 +45,14 @@ int PREPEND_PREFIX(Segment_contig_m2m) 
> (DLOOP_Offset *blocks_p,
>      }
>      else {
>         /* Ensure that pointer increment fits in a pointer */
> +       /* userbuf is a pointer (not a displacement) since it is  
> being used on a memcpy */
>         MPID_Ensure_Aint_fits_in_pointer 
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) + rel_off );
>         memcpy(paramp->streambuf,
>                (char *) ( MPI_AINT_CAST_TO_VOID_PTR  
> ((MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) + rel_off) ),
>                size);
>      }
> +    /* Ensure that pointer increment fits in a pointer */
> +    /* streambuf is a pointer (not a displacement) since it was  
> used on a memcpy */
>      MPID_Ensure_Aint_fits_in_pointer 
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->streambuf)) + size );
>      paramp->streambuf += size;
>      return 0;
> @@ -76,6 +80,7 @@ int PREPEND_PREFIX(Segment_vector_m2m) 
> (DLOOP_Offset *blocks_p,
>      char *cbufp;
>
>      /* Ensure that pointer increment fits in a pointer */
> +    /* userbuf is a pointer (not a displacement) since it is being  
> used for a memory copy */
>      MPID_Ensure_Aint_fits_in_pointer 
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) + rel_off );
>      cbufp = (char*)( MPI_AINT_CAST_TO_VOID_PTR  
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) + rel_off ) );
>      DLOOP_Handle_get_size_macro(el_type, el_size);
> @@ -109,6 +114,8 @@ int PREPEND_PREFIX(Segment_vector_m2m) 
> (DLOOP_Offset *blocks_p,
>         else {
>             for (i=0; i < whole_count; i++) {
>                 memcpy(cbufp, paramp->streambuf, ((DLOOP_Offset) 
> blksz) * el_size);
> +               /* Ensure that pointer increment fits in a pointer */
> +               /* streambuf is a pointer (not a displacement)  
> since it is being used for a memory copy */
>                 MPID_Ensure_Aint_fits_in_pointer 
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->streambuf)) +
>                                                   ((DLOOP_Offset) 
> blksz) * el_size );
>                 paramp->streambuf += ((DLOOP_Offset)blksz) * el_size;
> @@ -118,6 +125,8 @@ int PREPEND_PREFIX(Segment_vector_m2m) 
> (DLOOP_Offset *blocks_p,
>             }
>             if (blocks_left) {
>                 memcpy(cbufp, paramp->streambuf, ((DLOOP_Offset) 
> blocks_left) * el_size);
> +               /* Ensure that pointer increment fits in a pointer */
> +               /* streambuf is a pointer (not a displacement)  
> since it is being used for a memory copy */
>                 MPID_Ensure_Aint_fits_in_pointer 
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->streambuf)) +
>                                                   ((DLOOP_Offset) 
> blocks_left) * el_size );
>                 paramp->streambuf += ((DLOOP_Offset)blocks_left) *  
> el_size;
> @@ -150,6 +159,8 @@ int PREPEND_PREFIX(Segment_vector_m2m) 
> (DLOOP_Offset *blocks_p,
>         else {
>             for (i=0; i < whole_count; i++) {
>                 memcpy(paramp->streambuf, cbufp, (DLOOP_Offset) 
> blksz * el_size);
> +               /* Ensure that pointer increment fits in a pointer */
> +               /* streambuf is a pointer (not a displacement)  
> since it is being used for a memory copy */
>                 MPID_Ensure_Aint_fits_in_pointer 
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->streambuf)) +
>                                                   (DLOOP_Offset) 
> blksz * el_size );
>                 paramp->streambuf += (DLOOP_Offset)blksz * el_size;
> @@ -157,6 +168,8 @@ int PREPEND_PREFIX(Segment_vector_m2m) 
> (DLOOP_Offset *blocks_p,
>             }
>             if (blocks_left) {
>                 memcpy(paramp->streambuf, cbufp, (DLOOP_Offset) 
> blocks_left * el_size);
> +               /* Ensure that pointer increment fits in a pointer */
> +               /* streambuf is a pointer (not a displacement)  
> since it is being used for a memory copy */
>                 MPID_Ensure_Aint_fits_in_pointer 
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->streambuf)) +
>                                                   (DLOOP_Offset) 
> blocks_left * el_size );
>                 paramp->streambuf += (DLOOP_Offset)blocks_left *  
> el_size;
> @@ -191,6 +204,8 @@ int PREPEND_PREFIX(Segment_blkidx_m2m) 
> (DLOOP_Offset *blocks_p,
>
>         DLOOP_Assert(curblock < count);
>
> +       /* Ensure that pointer increment fits in a pointer */
> +       /* userbuf is a pointer (not a displacement) since it is  
> being used for a memory copy */
>         MPID_Ensure_Aint_fits_in_pointer 
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) +
>                                           rel_off + offsetarray 
> [curblock] );
>         cbufp = (char*) MPI_AINT_CAST_TO_VOID_PTR
> @@ -226,6 +241,8 @@ int PREPEND_PREFIX(Segment_blkidx_m2m) 
> (DLOOP_Offset *blocks_p,
>             memcpy(dest, src, (DLOOP_Offset)blocklen * el_size);
>         }
>
> +       /* Ensure that pointer increment fits in a pointer */
> +       /* streambuf is a pointer (not a displacement) since it is  
> being used for a memory copy */
>         MPID_Ensure_Aint_fits_in_pointer 
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->streambuf)) +
>                                           (DLOOP_Offset)blocklen *  
> el_size );
>         paramp->streambuf += (DLOOP_Offset)blocklen * el_size;
> @@ -262,6 +279,7 @@ int PREPEND_PREFIX(Segment_index_m2m) 
> (DLOOP_Offset *blocks_p,
>         cur_block_sz = blockarray[curblock];
>
>         /* Ensure that pointer increment fits in a pointer */
> +       /* userbuf is a pointer (not a displacement) since it is  
> being used for a memory copy */
>         MPID_Ensure_Aint_fits_in_pointer 
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) +
>                                           rel_off + offsetarray 
> [curblock]);
>         cbufp = (char*) MPI_AINT_CAST_TO_VOID_PTR
> @@ -297,6 +315,8 @@ int PREPEND_PREFIX(Segment_index_m2m) 
> (DLOOP_Offset *blocks_p,
>             memcpy(dest, src, cur_block_sz * el_size);
>         }
>
> +       /* Ensure that pointer increment fits in a pointer */
> +       /* streambuf is a pointer (not a displacement) since it is  
> being used for a memory copy */
>         MPID_Ensure_Aint_fits_in_pointer 
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->streambuf)) +
>                                           cur_block_sz * el_size );
>         paramp->streambuf += cur_block_sz * el_size;
> @@ -612,14 +632,20 @@ static int DLOOP_Segment_contig_mpi_flatten 
> (DLOOP_Offset *blocks_p,
>
>      last_idx = paramp->index - 1;
>      if (last_idx >= 0) {
> -       MPID_Ensure_Aint_fits_in_pointer( paramp->disps[last_idx] +  
> ((DLOOP_Offset)paramp->blklens[last_idx]) );
> -       last_end = (char*) MPI_AINT_CAST_TO_VOID_PTR
> +       /* Since disps can be negative, we cannot use  
> MPID_Ensure_Aint_fits_in_pointer to verify that
> +        * disps + blklens fits in a pointer.  Just let it  
> truncate, if the sizeof a pointer is less
> +        * than the sizeof an MPI_Aint.
> +        */
> +       last_end = (char*) MPI_AINT_CAST_TO_VOID_PTR
>                    (paramp->disps[last_idx] + ((DLOOP_Offset)paramp- 
> >blklens[last_idx]));
>      }
>
> -    MPID_Ensure_Aint_fits_in_pointer 
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT (bufp)) + rel_off);
> +    /* Since bufp can be a displacement and can be negative, we  
> cannot use
> +     * MPID_Ensure_Aint_fits_in_pointer to ensure the sum fits in  
> a pointer.
> +     * Just let it truncate.
> +     */
>      if ((last_idx == paramp->length-1) &&
> -       (last_end != ((char *) bufp + rel_off)))
> +        (last_end != ((char *) bufp + rel_off)))
>      {
>         /* we have used up all our entries, and this region doesn't  
> fit on
>          * the end of the last one.  setting blocks to 0 tells  
> manipulation
> @@ -634,7 +660,11 @@ static int DLOOP_Segment_contig_mpi_flatten 
> (DLOOP_Offset *blocks_p,
>         paramp->blklens[last_idx] += size;
>      }
>      else {
> -       paramp->disps[last_idx+1]   = MPI_VOID_PTR_CAST_TO_MPI_AINT  
> ((char *) bufp + rel_off);
> +       /* Since bufp can be a displacement and can be negative, we  
> cannot use
> +        * MPI_VOID_PTR_CAST_TO_MPI_AINT to cast the sum to a  
> pointer.  Just let it
> +        * sign extend.
> +        */
> +        paramp->disps[last_idx+1]   =  
> MPI_PTR_DISP_CAST_TO_MPI_AINT bufp + rel_off;
>         paramp->blklens[last_idx+1] = size;
>         paramp->index++;
>      }
> @@ -689,17 +719,22 @@ static int DLOOP_Segment_vector_mpi_flatten 
> (DLOOP_Offset *blocks_p,
>
>         last_idx = paramp->index - 1;
>         if (last_idx >= 0) {
> -           MPID_Ensure_Aint_fits_in_pointer( paramp->disps 
> [last_idx] +
> -                                             (MPI_Aint)(paramp- 
> >blklens[last_idx]) );
> -           last_end = (char *) MPI_AINT_CAST_TO_VOID_PTR
> +           /* Since disps can be negative, we cannot use  
> MPID_Ensure_Aint_fits_in_pointer to verify that
> +            * disps + blklens fits in a pointer.  Nor can we use  
> MPI_AINT_CAST_TO_VOID_PTR to cast the
> +            * sum to a pointer.  Just let it truncate, if the  
> sizeof a pointer is less than the sizeof
> +            * an MPI_Aint.
> +            */
> +           last_end = (char *) MPI_AINT_CAST_TO_VOID_PTR
>                        ( paramp->disps[last_idx] +
>                          (MPI_Aint)(paramp->blklens[last_idx]) );
>         }
>
> -       MPID_Ensure_Aint_fits_in_pointer 
> ( MPI_VOID_PTR_CAST_TO_MPI_AINT bufp + rel_off );
> -       if ((last_idx == paramp->length-1) &&
> -           (last_end != (char *) MPI_AINT_CAST_TO_VOID_PTR
> -                        ( MPI_VOID_PTR_CAST_TO_MPI_AINT bufp +  
> rel_off) ) )
> +       /* Since bufp can be a displacement and can be negative, we  
> cannot use
> +        * MPID_Ensure_Aint_fits_in_pointer to ensure the sum fits  
> in a pointer.
> +        * Just let it truncate.
> +        */
> +        if ((last_idx == paramp->length-1) &&
> +            (last_end != ((char *) bufp + rel_off)))
>         {
>             /* we have used up all our entries, and this one  
> doesn't fit on
>              * the end of the last one.
> @@ -712,14 +747,17 @@ static int DLOOP_Segment_vector_mpi_flatten 
> (DLOOP_Offset *blocks_p,
>  #endif
>             return 1;
>         }
> -       else if (last_idx >= 0 && (last_end == (char *)  
> MPI_AINT_CAST_TO_VOID_PTR
> -                                               
> ( MPI_VOID_PTR_CAST_TO_MPI_AINT bufp + rel_off ) ) )
> +        else if (last_idx >= 0 && (last_end == ((char *) bufp +  
> rel_off)))
>         {
>             /* add this size to the last vector rather than using  
> up new one */
>             paramp->blklens[last_idx] += size;
>         }
>         else {
> -           paramp->disps[last_idx+1]   =  
> MPI_VOID_PTR_CAST_TO_MPI_AINT bufp + rel_off;
> +           /* Since bufp can be a displacement and can be  
> negative, we cannot use
> +            * MPI_VOID_PTR_CAST_TO_MPI_AINT to cast the sum to a  
> pointer.  Just let it
> +            * sign extend.
> +            */
> +            paramp->disps[last_idx+1]   =  
> MPI_PTR_DISP_CAST_TO_MPI_AINT bufp + rel_off;
>             paramp->blklens[last_idx+1] = size;
>             paramp->index++;
>         }
> @@ -773,15 +811,21 @@ static int DLOOP_Segment_blkidx_mpi_flatten 
> (DLOOP_Offset *blocks_p,
>
>         last_idx = paramp->index - 1;
>         if (last_idx >= 0) {
> -           MPID_Ensure_Aint_fits_in_pointer( paramp->disps 
> [last_idx] + ((DLOOP_Offset)paramp->blklens[last_idx]) );
> -           last_end = (char*) MPI_AINT_CAST_TO_VOID_PTR
> +           /* Since disps can be negative, we cannot use  
> MPID_Ensure_Aint_fits_in_pointer to verify that
> +            * disps + blklens fits in a pointer.  Nor can we use  
> MPI_AINT_CAST_TO_VOID_PTR to cast the
> +            * sum to a pointer.  Just let it truncate, if the  
> sizeof a pointer is less than the sizeof
> +            * an MPI_Aint.
> +            */
> +           last_end = (char*) MPI_AINT_CAST_TO_VOID_PTR
>                        (paramp->disps[last_idx] + ((DLOOP_Offset) 
> paramp->blklens[last_idx]));
>         }
>
> -       MPID_Ensure_Aint_fits_in_pointer 
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp) + rel_off );
> -       if ((last_idx == paramp->length-1) &&
> -           (last_end != (char *) MPI_AINT_CAST_TO_VOID_PTR
> -                        (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp +  
> rel_off) ))
> +       /* Since bufp can be a displacement and can be negative, we  
> cannot use
> +        * MPID_Ensure_Aint_fits_in_pointer to ensure the sum fits  
> in a pointer.
> +        * Just let it truncate.
> +        */
> +        if ((last_idx == paramp->length-1) &&
> +            (last_end != ((char *) bufp + rel_off)))
>         {
>             /* we have used up all our entries, and this one  
> doesn't fit on
>              * the end of the last one.
> @@ -794,15 +838,17 @@ static int DLOOP_Segment_blkidx_mpi_flatten 
> (DLOOP_Offset *blocks_p,
>  #endif
>             return 1;
>         }
> -       else if (last_idx >= 0 && (last_end == (char *)  
> MPI_AINT_CAST_TO_VOID_PTR
> -                                               
> (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp + rel_off) ) )
> +        else if (last_idx >= 0 && (last_end == ((char *) bufp +  
> rel_off)))
>         {
>             /* add this size to the last vector rather than using  
> up new one */
>             paramp->blklens[last_idx] += size;
>         }
>         else {
> -           paramp->disps[last_idx+1]   = (MPI_Aint)  
> (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp +
> -                                                     rel_off +  
> offsetarray[last_idx+1]);
> +           /* Since bufp can be a displacement and can be  
> negative, we cannot use
> +            * MPI_VOID_PTR_CAST_TO_MPI_AINT to cast the sum to a  
> pointer.  Just let it
> +            * sign extend.
> +            */
> +            paramp->disps[last_idx+1]   =  
> MPI_PTR_DISP_CAST_TO_MPI_AINT bufp + rel_off + offsetarray[last_idx 
> +1];
>             paramp->blklens[last_idx+1] = size;
>             paramp->index++;
>         }
> @@ -856,17 +902,22 @@ static int DLOOP_Segment_index_mpi_flatten 
> (DLOOP_Offset *blocks_p,
>
>         last_idx = paramp->index - 1;
>         if (last_idx >= 0) {
> -           MPID_Ensure_Aint_fits_in_pointer( paramp->disps 
> [last_idx] +
> -                                             (MPI_Aint)(paramp- 
> >blklens[last_idx]) );
> -           last_end = (char *) MPI_AINT_CAST_TO_VOID_PTR
> +           /* Since disps can be negative, we cannot use  
> MPID_Ensure_Aint_fits_in_pointer to verify that
> +            * disps + blklens fits in a pointer.  Nor can we use  
> MPI_AINT_CAST_TO_VOID_PTR to cast the
> +            * sum to a pointer.  Just let it truncate, if the  
> sizeof a pointer is less than the sizeof
> +            * an MPI_Aint.
> +            */
> +           last_end = (char *) MPI_AINT_CAST_TO_VOID_PTR
>                        ( paramp->disps[last_idx] +
>                          (MPI_Aint)(paramp->blklens[last_idx]) );
>         }
>
> -       MPID_Ensure_Aint_fits_in_pointer 
> ( (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp) + rel_off );
> -       if ((last_idx == paramp->length-1) &&
> -           (last_end != (char *) MPI_AINT_CAST_TO_VOID_PTR
> -                        (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp +  
> rel_off) ))
> +       /* Since bufp can be a displacement and can be negative, we  
> cannot use
> +        * MPID_Ensure_Aint_fits_in_pointer to ensure the sum fits  
> in a pointer.
> +        * Just let it truncate.
> +        */
> +        if ((last_idx == paramp->length-1) &&
> +            (last_end != ((char *) bufp + rel_off)))
>         {
>             /* we have used up all our entries, and this one  
> doesn't fit on
>              * the end of the last one.
> @@ -879,14 +930,17 @@ static int DLOOP_Segment_index_mpi_flatten 
> (DLOOP_Offset *blocks_p,
>  #endif
>             return 1;
>         }
> -       else if (last_idx >= 0 && (last_end == (char *)  
> MPI_AINT_CAST_TO_VOID_PTR
> -                                               
> (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp + rel_off) ))
> +        else if (last_idx >= 0 && (last_end == ((char *) bufp +  
> rel_off)))
>         {
>             /* add this size to the last vector rather than using  
> up new one */
>             paramp->blklens[last_idx] += size;
>         }
>         else {
> -           paramp->disps[last_idx+1]   =  
> (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp) + rel_off + offsetarray 
> [last_idx+1];
> +           /* Since bufp can be a displacement and can be  
> negative, we cannot use
> +            * MPI_VOID_PTR_CAST_TO_MPI_AINT to cast the sum to a  
> pointer.  Just let it
> +            * sign extend.
> +            */
> +            paramp->disps[last_idx+1]   =  
> MPI_PTR_DISP_CAST_TO_MPI_AINT bufp + rel_off + offsetarray[last_idx 
> +1];
>             paramp->blklens[last_idx+1] = size;
>             paramp->index++;
>         }
> --
> 1.5.3.7
>

William Gropp
Paul and Cynthia Saylor Professor of Computer Science
University of Illinois Urbana-Champaign



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.mcs.anl.gov/mailman/private/mpich2-dev/attachments/20080422/216d7d32/attachment.htm>


More information about the mpich2-dev mailing list