1
1

Fix the use of hard markers MPI_LB and MPI_UB in the creation of

subarray and darray. Thanks to Gus Correa for pointing to the
MPICH bug report.
Этот коммит содержится в:
George Bosilca 2015-01-17 23:11:07 -05:00
родитель 04bec4475e
Коммит 19c96465f3
2 изменённых файлов: 20 добавлений и 9 удалений

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

@ -247,8 +247,7 @@ int32_t ompi_datatype_create_darray(int size,
} }
/* set displacement and UB correctly. Use struct instead of /* set displacement and UB correctly. Please read the comment in subarray */
resized for same reason as subarray */
{ {
ptrdiff_t displs[3], tmp_size; ptrdiff_t displs[3], tmp_size;
ompi_datatype_t *types[3]; ompi_datatype_t *types[3];
@ -267,9 +266,13 @@ int32_t ompi_datatype_create_darray(int size,
for (i = 0 ; i < ndims ; i++) { for (i = 0 ; i < ndims ; i++) {
displs[2] *= gsize_array[i]; displs[2] *= gsize_array[i];
} }
types[0] = MPI_LB; types[1] = lastType; types[2] = MPI_UB; if(oldtype->super.flags & (OPAL_DATATYPE_FLAG_USER_LB | OPAL_DATATYPE_FLAG_USER_UB) ) {
types[0] = MPI_LB; types[1] = lastType; types[2] = MPI_UB;
rc = ompi_datatype_create_struct(3, blength, displs, types, newtype); rc = ompi_datatype_create_struct(3, blength, displs, types, newtype);
} else {
ompi_datatype_create_resized(lastType, displs[0], displs[2], newtype);
}
ompi_datatype_destroy(&lastType); ompi_datatype_destroy(&lastType);
/* need to destroy the old type even in error condition, so /* need to destroy the old type even in error condition, so
don't check return code from above until after cleanup. */ don't check return code from above until after cleanup. */

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

@ -40,6 +40,12 @@ int32_t ompi_datatype_create_subarray(int ndims,
int32_t i, step, end_loop; int32_t i, step, end_loop;
MPI_Aint size, displ, extent; MPI_Aint size, displ, extent;
/**
* If the oldtype contains the original MPI_LB and MPI_UB markers then we
* are forced to follow the MPI standard suggestion and reset these 2
* markers (MPI 3.0 page 96 line 37). Otherwise we can simply resize the
* datatype.
*/
ompi_datatype_type_extent( oldtype, &extent ); ompi_datatype_type_extent( oldtype, &extent );
/* If the ndims is zero then return the NULL datatype */ /* If the ndims is zero then return the NULL datatype */
@ -85,12 +91,12 @@ int32_t ompi_datatype_create_subarray(int ndims,
replace_subarray_type: replace_subarray_type:
/** /**
* We cannot use resized here. Resized will only set the soft lb and ub markers * Resized will only set the soft lb and ub markers without moving the real
* without moving the real data inside. What we need is to force the displacement * data inside. Thus, in case the original data contains the hard markers
* of the data upward to the right position AND set the LB and UB. A type * (MPI_LB or MPI_UB) we must force the displacement of the data upward to
* struct is the function we need. * the right position AND set the hard markers LB and UB.
*/ */
{ if( oldtype->super.flags & (OPAL_DATATYPE_FLAG_USER_LB | OPAL_DATATYPE_FLAG_USER_UB) ) {
MPI_Aint displs[3]; MPI_Aint displs[3];
MPI_Datatype types[3]; MPI_Datatype types[3];
int blength[3] = { 1, 1, 1 }; int blength[3] = { 1, 1, 1 };
@ -98,6 +104,8 @@ int32_t ompi_datatype_create_subarray(int ndims,
displs[0] = 0; displs[1] = displ * extent; displs[2] = size * extent; displs[0] = 0; displs[1] = displ * extent; displs[2] = size * extent;
types[0] = MPI_LB; types[1] = last_type; types[2] = MPI_UB; types[0] = MPI_LB; types[1] = last_type; types[2] = MPI_UB;
ompi_datatype_create_struct( 3, blength, displs, types, newtype ); ompi_datatype_create_struct( 3, blength, displs, types, newtype );
} else {
ompi_datatype_create_resized(last_type, 0, size * extent, newtype);
} }
ompi_datatype_destroy( &last_type ); ompi_datatype_destroy( &last_type );