From c29301da9529d8c5730e3d40f9302386fcd421ea Mon Sep 17 00:00:00 2001 From: Gilles Gouaillardet Date: Wed, 20 Jun 2018 10:10:34 +0900 Subject: [PATCH] io/romio321: fix minmax datatypes romio assumes that all predefined datatypes are contiguous. Because of the (terribly named) composed datatypes MPI_SHORT_INT, MPI_DOUBLE_INT, MPI_LONG_INT, etc this is an incorrect assumption. The simplest way to fix this is to override the MPI_Type_get_envelope and MPI_Type_get_contents calls with calls that will work on these datatypes. Note that not all calls to these MPI functions are replaced, only the ones used when flattening a non-contiguous datatype. References #5009 Signed-off-by: Nathan Hjelm (back-ported from commit open-mpi/ompi@4d876ec6fedd2f5d299259eff53ba37b12c5d7e0) Signed-off-by: Gilles Gouaillardet --- .../romio321/romio/adio/common/ad_set_view.c | 4 +- .../io/romio321/romio/adio/common/flatten.c | 162 ++++++++++++++---- .../io/romio321/romio/adio/include/adioi.h | 6 + 3 files changed, 135 insertions(+), 37 deletions(-) diff --git a/ompi/mca/io/romio321/romio/adio/common/ad_set_view.c b/ompi/mca/io/romio321/romio/adio/common/ad_set_view.c index 31aa6c6dd5..18becf269a 100644 --- a/ompi/mca/io/romio321/romio/adio/common/ad_set_view.c +++ b/ompi/mca/io/romio321/romio/adio/common/ad_set_view.c @@ -35,14 +35,14 @@ void ADIO_Set_view(ADIO_File fd, ADIO_Offset disp, MPI_Datatype etype, /* set new etypes and filetypes */ - MPI_Type_get_envelope(etype, &i, &j, &k, &combiner); + ADIOI_Type_get_envelope(etype, &i, &j, &k, &combiner); if (combiner == MPI_COMBINER_NAMED) fd->etype = etype; else { MPI_Type_contiguous(1, etype, ©_etype); MPI_Type_commit(©_etype); fd->etype = copy_etype; } - MPI_Type_get_envelope(filetype, &i, &j, &k, &combiner); + ADIOI_Type_get_envelope(filetype, &i, &j, &k, &combiner); if (combiner == MPI_COMBINER_NAMED) fd->filetype = filetype; else { diff --git a/ompi/mca/io/romio321/romio/adio/common/flatten.c b/ompi/mca/io/romio321/romio/adio/common/flatten.c index fb2610cac5..e89da5f67b 100644 --- a/ompi/mca/io/romio321/romio/adio/common/flatten.c +++ b/ompi/mca/io/romio321/romio/adio/common/flatten.c @@ -14,6 +14,90 @@ #define FLATTEN_DEBUG 1 #endif +struct adio_short_int { + short elem_s; + int elem_i; +}; + +struct adio_double_int { + double elem_d; + int elem_i; +}; + +struct adio_long_int { + long elem_l; + int elem_i; +}; + +struct adio_long_double_int { + long double elem_ld; + int elem_i; +}; + +int ADIOI_Type_get_envelope (MPI_Datatype datatype, int *num_integers, + int *num_addresses, int *num_datatypes, int *combiner) +{ + int rc, is_contig; + + ADIOI_Datatype_iscontig(datatype, &is_contig); + + rc = MPI_Type_get_envelope (datatype, num_integers, num_addresses, num_datatypes, combiner); + if (MPI_SUCCESS != rc || MPI_COMBINER_NAMED != *combiner || is_contig) { + return rc; + } + + if (MPI_SHORT_INT == datatype || MPI_DOUBLE_INT == datatype || MPI_LONG_DOUBLE_INT == datatype || + MPI_LONG_INT == datatype) { + *num_integers = 2; + *num_addresses = 2; + *num_datatypes = 2; + *combiner = MPI_COMBINER_STRUCT; + } + + return rc; +} + +int ADIOI_Type_get_contents (MPI_Datatype datatype, int max_integers, + int max_addresses, int max_datatypes, int array_of_integers[], + MPI_Aint array_of_addresses[], MPI_Datatype array_of_datatypes[]) +{ + int dontcare, combiner; + int rc; + + rc = MPI_Type_get_envelope (datatype, &dontcare, &dontcare, &dontcare, &combiner); + if (MPI_SUCCESS != rc) { + return rc; + } + + if (MPI_COMBINER_NAMED != combiner) { + return MPI_Type_get_contents (datatype, max_integers, max_addresses, max_datatypes, + array_of_integers, array_of_addresses, array_of_datatypes); + } + + array_of_integers[0] = 1; + array_of_integers[1] = 1; + array_of_addresses[0] = 0; + array_of_datatypes[1] = MPI_INT; + + if (MPI_SHORT_INT == datatype) { + array_of_datatypes[0] = MPI_SHORT; + array_of_addresses[1] = offsetof (struct adio_short_int, elem_i); + } else if (MPI_DOUBLE_INT == datatype) { + array_of_datatypes[0] = MPI_DOUBLE; + array_of_addresses[1] = offsetof (struct adio_double_int, elem_i); + } else if (MPI_LONG_DOUBLE_INT == datatype) { + array_of_datatypes[0] = MPI_LONG_DOUBLE; + array_of_addresses[1] = offsetof (struct adio_long_double_int, elem_i); + } else if (MPI_LONG_INT == datatype) { + array_of_datatypes[0] = MPI_LONG; + array_of_addresses[1] = offsetof (struct adio_long_int, elem_i); + } else { + rc = MPI_ERR_TYPE; + } + + return rc; +} + void ADIOI_Optimize_flattened(ADIOI_Flatlist_node *flat_type); /* flatten datatype and add it to Flatlist */ void ADIOI_Flatten_datatype(MPI_Datatype datatype) @@ -119,11 +203,15 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat, int *ints; MPI_Aint *adds; /* Make no assumptions about +/- sign on these */ MPI_Datatype *types; - MPI_Type_get_envelope(datatype, &nints, &nadds, &ntypes, &combiner); + ADIOI_Type_get_envelope(datatype, &nints, &nadds, &ntypes, &combiner); + if (combiner == MPI_COMBINER_NAMED) { + return; /* can't do anything else: calling get_contents on a builtin + type is an error */ + } ints = (int *) ADIOI_Malloc((nints+1)*sizeof(int)); adds = (MPI_Aint *) ADIOI_Malloc((nadds+1)*sizeof(MPI_Aint)); types = (MPI_Datatype *) ADIOI_Malloc((ntypes+1)*sizeof(MPI_Datatype)); - MPI_Type_get_contents(datatype, nints, nadds, ntypes, ints, adds, types); + ADIOI_Type_get_contents(datatype, nints, nadds, ntypes, ints, adds, types); #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr,"ADIOI_Flatten:: st_offset %#llX, curr_index %#llX\n",st_offset,*curr_index); @@ -154,8 +242,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat, #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_DUP\n"); #endif - MPI_Type_get_envelope(types[0], &old_nints, &old_nadds, - &old_ntypes, &old_combiner); + ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds, + &old_ntypes, &old_combiner); ADIOI_Datatype_iscontig(types[0], &old_is_contig); if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig)) ADIOI_Flatten(types[0], flat, st_offset, curr_index); @@ -219,8 +307,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat, DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_CONTIGUOUS\n"); #endif top_count = ints[0]; - MPI_Type_get_envelope(types[0], &old_nints, &old_nadds, - &old_ntypes, &old_combiner); + ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds, + &old_ntypes, &old_combiner); ADIOI_Datatype_iscontig(types[0], &old_is_contig); prev_index = *curr_index; @@ -264,8 +352,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat, DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_VECTOR\n"); #endif top_count = ints[0]; - MPI_Type_get_envelope(types[0], &old_nints, &old_nadds, - &old_ntypes, &old_combiner); + ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds, + &old_ntypes, &old_combiner); ADIOI_Datatype_iscontig(types[0], &old_is_contig); prev_index = *curr_index; @@ -327,8 +415,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat, DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_HVECTOR_INTEGER\n"); #endif top_count = ints[0]; - MPI_Type_get_envelope(types[0], &old_nints, &old_nadds, - &old_ntypes, &old_combiner); + ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds, + &old_ntypes, &old_combiner); ADIOI_Datatype_iscontig(types[0], &old_is_contig); prev_index = *curr_index; @@ -389,8 +477,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat, DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_INDEXED\n"); #endif top_count = ints[0]; - MPI_Type_get_envelope(types[0], &old_nints, &old_nadds, - &old_ntypes, &old_combiner); + ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds, + &old_ntypes, &old_combiner); ADIOI_Datatype_iscontig(types[0], &old_is_contig); MPI_Type_extent(types[0], &old_extent); @@ -495,8 +583,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat, DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_INDEXED_BLOCK\n"); #endif top_count = ints[0]; - MPI_Type_get_envelope(types[0], &old_nints, &old_nadds, - &old_ntypes, &old_combiner); + ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds, + &old_ntypes, &old_combiner); ADIOI_Datatype_iscontig(types[0], &old_is_contig); MPI_Type_extent(types[0], &old_extent); @@ -584,8 +672,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat, DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_HINDEXED_INTEGER\n"); #endif top_count = ints[0]; - MPI_Type_get_envelope(types[0], &old_nints, &old_nadds, - &old_ntypes, &old_combiner); + ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds, + &old_ntypes, &old_combiner); ADIOI_Datatype_iscontig(types[0], &old_is_contig); prev_index = *curr_index; @@ -676,8 +764,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat, #endif top_count = ints[0]; for (n=0; n