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.
Этот коммит содержится в:
родитель
04bec4475e
Коммит
19c96465f3
@ -247,8 +247,7 @@ int32_t ompi_datatype_create_darray(int size,
|
||||
}
|
||||
|
||||
|
||||
/* set displacement and UB correctly. Use struct instead of
|
||||
resized for same reason as subarray */
|
||||
/* set displacement and UB correctly. Please read the comment in subarray */
|
||||
{
|
||||
ptrdiff_t displs[3], tmp_size;
|
||||
ompi_datatype_t *types[3];
|
||||
@ -267,9 +266,13 @@ int32_t ompi_datatype_create_darray(int size,
|
||||
for (i = 0 ; i < ndims ; 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);
|
||||
/* need to destroy the old type even in error condition, so
|
||||
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;
|
||||
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 );
|
||||
|
||||
/* 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:
|
||||
/**
|
||||
* We cannot use resized here. Resized will only set the soft lb and ub markers
|
||||
* without moving the real data inside. What we need is to force the displacement
|
||||
* of the data upward to the right position AND set the LB and UB. A type
|
||||
* struct is the function we need.
|
||||
* Resized will only set the soft lb and ub markers without moving the real
|
||||
* data inside. Thus, in case the original data contains the hard markers
|
||||
* (MPI_LB or MPI_UB) we must force the displacement of the data upward to
|
||||
* 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_Datatype types[3];
|
||||
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;
|
||||
types[0] = MPI_LB; types[1] = last_type; types[2] = MPI_UB;
|
||||
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 );
|
||||
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user