67static MPI_Datatype copy_mpi_datatype(MPI_Datatype old_type,
MPI_Comm comm) {
69 MPI_Datatype datatype;
77gen_mpi_datatype_simple(
int displacement, MPI_Datatype old_type,
MPI_Comm comm)
79 MPI_Datatype datatype;
89gen_mpi_datatype_contiguous(
int displacement,
int blocklength,
90 MPI_Datatype old_type,
MPI_Comm comm) {
92 MPI_Datatype datatype;
94 if (displacement == 0)
99 &displacement, old_type,
109gen_mpi_datatype_vector(
int count,
int blocklength,
int stride,
110 int offset, MPI_Datatype old_type,
MPI_Comm comm) {
112 MPI_Datatype datatype;
118 MPI_Datatype datatype_;
119 int hindexed_blocklength = 1;
120 MPI_Aint old_type_size, old_type_lb;
122 xt_mpi_call(MPI_Type_get_extent(old_type, &old_type_lb,
123 &old_type_size), comm);
125 MPI_Aint displacement = offset * old_type_size;
128 &displacement, datatype, &datatype_),
131 datatype = datatype_;
139gen_mpi_datatype_indexed_block(
int const * displacements,
int blocklength,
140 int count, MPI_Datatype old_type,
MPI_Comm comm)
142 MPI_Datatype datatype;
145 (
void *)displacements,
146 old_type, &datatype), comm);
153gen_mpi_datatype_indexed(
const int *displacements,
const int *blocklengths,
154 int count, MPI_Datatype old_type,
MPI_Comm comm) {
156 MPI_Datatype datatype;
159 old_type, &datatype), comm);
166check_for_vector_type(
const int *displacements,
const int *blocklengths,
169 int blocklength = blocklengths[0];
171 for (
int i = 1; i < count; ++i)
172 if (blocklengths[i] != blocklength)
175 int stride = displacements[1] - displacements[0];
177 for (
int i = 1; i + 1 < count; ++i)
178 if (displacements[i+1] - displacements[i] != stride)
184static inline int check_for_indexed_block_type(
const int *blocklengths,
187 int blocklength = blocklengths[0];
189 for (
int i = 1; i < count; ++i)
190 if (blocklengths[i] != blocklength)
200 int count, MPI_Datatype old_type,
205 MPI_Datatype old_type,
MPI_Comm comm);
210 const int *blocklengths,
211 int count, MPI_Datatype old_type,
216 count, old_type, comm);
218 MPI_Datatype datatype;
221 datatype = MPI_DATATYPE_NULL;
222 else if (count == 1 && blocklengths[0] == 1 && displacements[0] == 0)
223 datatype = copy_mpi_datatype(old_type, comm);
224 else if (count == 1 && blocklengths[0] == 1)
225 datatype = gen_mpi_datatype_simple(displacements[0], old_type, comm);
227 datatype = gen_mpi_datatype_contiguous(displacements[0], blocklengths[0],
229 else if (check_for_vector_type(displacements, blocklengths, count))
230 datatype = gen_mpi_datatype_vector(count, blocklengths[0],
231 displacements[1] - displacements[0],
232 displacements[0], old_type, comm);
233 else if (check_for_indexed_block_type(blocklengths, count))
234 datatype = gen_mpi_datatype_indexed_block(displacements, blocklengths[0],
235 count, old_type, comm);
237 datatype = gen_mpi_datatype_indexed(displacements, blocklengths, count,
246 MPI_Datatype old_type,
MPI_Comm comm)
249 return MPI_DATATYPE_NULL;
254 int * blocklengths =
xmalloc((
size_t)count *
sizeof(*blocklengths));
260 while (i + j < count && displacements[i] + j == displacements[i + j])
262 blocklengths[new_count++] = j;
267 int * tmp_displ = NULL;
270 if (new_count != count) {
272 tmp_displ =
xmalloc((
size_t)new_count *
sizeof(*tmp_displ));
276 for (
int i = 0; i < new_count; ++i) {
278 tmp_displ[i] = displacements[offset];
279 offset += blocklengths[i];
284 displ = displacements;
286 MPI_Datatype datatype;
299#define XT_MPI_STRP_PRS_PREFIX
300#define XT_MPI_STRP_PRS_UNITSTRIDE 1
301#define XT_MPI_STRP_PRS_AOFS_TYPE int
302#define XT_MPI_STRP_PRS_DISP_ADJUST(val) ((val) * params->old_type_extent)
303#define XT_MPI_STRP_PRS_BLOCK_VEC_CREATE Xt_mpi_ddt_cache_acquire_vector
304#define XT_MPI_STRP_PRS_INDEXED_BLOCK_CREATE \
305 Xt_mpi_ddt_cache_acquire_indexed_block
306#define XT_MPI_STRP_PRS_INDEXED_CREATE Xt_mpi_ddt_cache_acquire_indexed
308#undef XT_MPI_STRP_PRS_PREFIX
309#undef XT_MPI_STRP_PRS_UNITSTRIDE
310#undef XT_MPI_STRP_PRS_AOFS_TYPE
311#undef XT_MPI_STRP_PRS_DISP_ADJUST
312#undef XT_MPI_STRP_PRS_BLOCK_VEC_CREATE
313#undef XT_MPI_STRP_PRS_INDEXED_BLOCK_CREATE
314#undef XT_MPI_STRP_PRS_INDEXED_CREATE
319 const MPI_Aint array_of_displacements[],
320 MPI_Datatype oldtype, MPI_Datatype *newtype)
322 size_t count_ = count > 0 ? (size_t)count : 0;
323 MPI_Datatype *restrict oldtypes =
xmalloc(count_ *
sizeof (*oldtypes)
324 + count_ *
sizeof (
int));
325 int *restrict blocklengths = (
int *)(oldtypes + count_);
326 for (
size_t i = 0; i < count_; ++i) {
327 blocklengths[i] = blocklength;
328 oldtypes[i] = oldtype;
331 CAST_MPI_SEND_BUF(array_of_displacements),
337#define MPI_Type_create_hindexed_block XtMPI_Type_create_hindexed_block
340#define XT_MPI_STRP_PRS_PREFIX a
341#define XT_MPI_STRP_PRS_UNITSTRIDE params->old_type_extent
342#define XT_MPI_STRP_PRS_AOFS_TYPE MPI_Aint
343#define XT_MPI_STRP_PRS_DISP_ADJUST(val) (val)
344#define XT_MPI_STRP_PRS_BLOCK_VEC_CREATE Xt_mpi_ddt_cache_acquire_hvector
345#define XT_MPI_STRP_PRS_INDEXED_BLOCK_CREATE \
346 Xt_mpi_ddt_cache_acquire_hindexed_block
347#define XT_MPI_STRP_PRS_INDEXED_CREATE Xt_mpi_ddt_cache_acquire_hindexed
353 int count, MPI_Datatype old_type,
367 size_t count_ = (size_t)0;
368 for (
int i=0; i<count; ++i)
369 count_ += (
size_t)(blocklengths[i] > 0);
370 if (count_ < 1)
return MPI_DATATYPE_NULL;
373 for (
size_t i=0; i<(size_t)count; ++i) {
374 v[j].start = disp[i];
376 int bl = blocklengths[i];
378 j += (size_t)(bl > 0);
380 MPI_Datatype dt = parse_stripe(v, count_, params);
387 MPI_Datatype old_type,
MPI_Comm comm)
389 if (disp_len < 1)
return MPI_DATATYPE_NULL;
396 MPI_Datatype dt = parse_stripe(v, vlen, ¶ms);
add versions of standard API functions not returning on error
int MPI_Type_create_struct(int count, XT_MPI2_CONST int array_of_block_lengths[], XT_MPI2_CONST MPI_Aint array_of_displacements[], XT_MPI2_CONST MPI_Datatype array_of_types[], MPI_Datatype *newtype)
int MPI_Type_create_indexed_block(int count, int blocklength, XT_MPI2_CONST int array_of_displacements[], MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_contiguous(int count, MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_free(MPI_Datatype *datatype)
int MPI_Type_indexed(int count, XT_MPI2_CONST int array_of_blocklengths[], XT_MPI2_CONST int array_of_displacements[], MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_create_hindexed(int count, XT_MPI2_CONST int array_of_blocklengths[], XT_MPI2_CONST MPI_Aint array_of_displacements[], MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_dup(MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_vector(int count, int blocklength, int stride, MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_commit(MPI_Datatype *datatype)
size_t xt_disp2ext_count(size_t disp_len, const int *disp)
size_t xt_disp2ext(size_t disp_len, const int *disp, struct Xt_offset_ext *restrict v)
#define xt_mpi_call(call, comm)
MPI_Datatype xt_mpi_generate_datatype(int const *displacements, int count, MPI_Datatype old_type, MPI_Comm comm)
static MPI_Datatype xt_mpi_generate_compact_datatype(int const *disp, int disp_len, MPI_Datatype old_type, MPI_Comm comm)
static MPI_Datatype xt_mpi_generate_compact_datatype_block(const int *disp, const int *blocklengths, int count, MPI_Datatype old_type, MPI_Comm comm)
MPI_Datatype xt_mpi_ddt_block_gen(int count, const int *disp, const int *blocklengths, struct Xt_mpi_strp_prs_params *params)
static int XtMPI_Type_create_hindexed_block(int count, int blocklength, const MPI_Aint array_of_displacements[], MPI_Datatype oldtype, MPI_Datatype *newtype)
MPI_Datatype xt_mpi_generate_datatype_block(const int *displacements, const int *blocklengths, int count, MPI_Datatype old_type, MPI_Comm comm)
static void xt_destroy_mpi_strp_prs_params(struct Xt_mpi_strp_prs_params *params)
static void xt_init_mpi_strp_prs_params(struct Xt_mpi_strp_prs_params *params, MPI_Datatype old_type, MPI_Comm comm)