1
1

Correct the MPI_Indexed bug. Actually it can be triggered by any type of

data, if the packed data is contiguous and the unpacked one is not. The
problem was that the unpack function did not update the bConverted value
to the real number of bytes extracted from the iovecs, but limit the update
to the number of bytes moved into the user buffers. So, if there were some
bytes copied in the internal pending buffer, they were lost because the next
convertor instead of using the correct bConverted (with the total number of
bytes) has only the transfered number. The result of this bug, is a shift to
left by few bytes of the values in the user buffers.
Add a protection against such kind of errors in the new_position.c.

This commit was SVN r8997.
Этот коммит содержится в:
George Bosilca 2006-02-12 20:19:22 +00:00
родитель 1398169700
Коммит 25020f58c1
3 изменённых файлов: 40 добавлений и 29 удалений

Просмотреть файл

@ -1,14 +1,12 @@
/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2005 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* Copyright (c) 2004-2006 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2004-2006 The Trustees of the University of Tennessee.
* All rights reserved.
* Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* Copyright (c) 2004-2006 The Regents of the University of California.
* All rights reserved.
* $COPYRIGHT$
*
@ -26,6 +24,7 @@
extern int ompi_unpack_debug;
extern int ompi_pack_debug;
extern int ompi_copy_debug;
extern int ompi_position_debug;
#endif /* OMPI_ENABLE_DEBUG */
extern size_t ompi_datatype_memcpy_block_size;
@ -363,6 +362,10 @@ int ompi_ddt_register_params(void)
"Whether to output debugging information in the ddt pack functions (nonzero = enabled)",
false, false,
ompi_pack_debug, &ompi_pack_debug );
mca_base_param_reg_int_name( "datatype", "position_debug",
"Non zero lead to output generated by the datatype position functions",
false, false, 0, &ompi_position_debug );
mca_base_param_reg_int_name( "mpi", "ddt_copy_debug",
"Whether to output debugging information in the ddt copy functions (nonzero = enabled)",
false, false,
@ -662,9 +665,9 @@ static int __dump_data_desc( dt_elem_desc_t* pDesc, int nbElems, char* ptr, size
(int)pDesc->end_loop.items, pDesc->end_loop.first_elem_disp,
(int)pDesc->end_loop.size );
else
index += snprintf( ptr + index, length - index, "count %d disp 0x%lx (%ld) extent %d\n",
index += snprintf( ptr + index, length - index, "count %d disp 0x%lx (%ld) extent %d (size %ld)\n",
(int)pDesc->elem.count, pDesc->elem.disp, pDesc->elem.disp,
(int)pDesc->elem.extent );
(int)pDesc->elem.extent, pDesc->elem.count * ompi_ddt_basicDatatypes[pDesc->elem.common.type]->size );
pDesc++;
if( length <= index ) break;

Просмотреть файл

@ -1,12 +1,12 @@
/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*
* Copyright (c) 2004-2005 The Trustees of Indiana University.
* Copyright (c) 2004-2006 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
* Copyright (c) 2004-2006 The Trustees of the University of Tennessee.
* All rights reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* Copyright (c) 2004-2006 The Regents of the University of California.
* All rights reserved.
* $COPYRIGHT$
*
@ -26,9 +26,14 @@
#endif
#include <stdlib.h>
static int ompi_pack_debug=0;
#if OMPI_ENABLE_DEBUG
int32_t ompi_position_debug = 0;
#define DO_DEBUG(INST) if( ompi_position_debug ) { INST }
#else
#define DO_DEBUG(INST)
#endif /* OMPI_ENABLE_DEBUG */
#define DO_DEBUG(INST) if( ompi_pack_debug ) { INST }
#define DO_DEBUG(INST) if( ompi_position_debug ) { INST }
/* The pack/unpack functions need a cleanup. I have to create a proper interface to access
* all basic functionalities, hence using them as basic blocks for all conversion functions.
@ -215,6 +220,10 @@ int ompi_convertor_generic_simple_position( ompi_convertor_t* pConvertor,
(*position) -= iov_len_local;
pConvertor->bConverted = *position; /* update the already converted bytes */
assert( iov_len_local >= 0 );
if( (pConvertor->pending_length != iov_len_local) &&
(pConvertor->flags & CONVERTOR_RECV) ) {
opal_output( 0, "Missing some data ?" );
}
if( !(pConvertor->flags & CONVERTOR_COMPLETED) ) {
/* I complete an element, next step I should go to the next one */
PUSH_STACK( pStack, pConvertor->stack_pos, pos_desc, DT_BYTE, count_desc,

Просмотреть файл

@ -1,14 +1,12 @@
/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2005 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* Copyright (c) 2004-2006 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2004-2006 The Trustees of the University of Tennessee.
* All rights reserved.
* Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* Copyright (c) 2004-2006 The Regents of the University of California.
* All rights reserved.
* $COPYRIGHT$
*
@ -265,19 +263,20 @@ int ompi_convertor_generic_simple_unpack( ompi_convertor_t* pConvertor,
}
}
complete_loop:
iov[iov_count].iov_len -= iov_len_local; /* update the amount of valid data */
total_unpacked += iov[iov_count].iov_len;
pConvertor->bConverted += iov[iov_count].iov_len; /* update the already converted bytes */
assert( iov_len_local >= 0 );
if( !(pConvertor->flags & CONVERTOR_COMPLETED) && (0 != iov_len_local) ) {
/* We have some partial data here. Let's copy it into the convertor
* and keep it hot until the next round.
*/
assert( iov_len_local < 16 );
assert( iov_len_local < ompi_ddt_basicDatatypes[type]->size );
memcpy( pConvertor->pending, packed_buffer, iov_len_local );
DO_DEBUG( opal_output( 0, "Saving %d bytes for the next call\n", iov_len_local ); );
pConvertor->pending_length = iov_len_local;
iov_len_local = 0;
}
iov[iov_count].iov_len -= iov_len_local; /* update the amount of valid data */
total_unpacked += iov[iov_count].iov_len;
pConvertor->bConverted += iov[iov_count].iov_len; /* update the already converted bytes */
assert( iov_len_local >= 0 );
/* We compute the checksum if we have to. But we will store the temporary
* values in the a and b variables, and only at the end take in account the
* value of the convertor checksum.