Commit 31d95ed7 authored by Rob Latham's avatar Rob Latham
Browse files

a "large contig" type

despite promoting types throughout the gather path, still had one case of
constructing structs with larger-than-int blocklens.  solution: borrow BigMPI
strategy and construct types-of-chunks to get around limitations.

Ref: #1767
Signed-off-by: Pavan Balaji's avatarPavan Balaji <>
parent 68f8c7aa
......@@ -4464,6 +4464,9 @@ int MPIR_Type_create_hindexed_block_impl(int count, int blocklength,
int MPIR_Type_contiguous_impl(int count,
MPI_Datatype old_type,
MPI_Datatype *new_type_p);
int MPIR_Type_contiguous_x_impl(MPI_Count count,
MPI_Datatype old_type,
MPI_Datatype *new_type_p);
void MPIR_Type_get_extent_impl(MPI_Datatype datatype, MPI_Aint *lb, MPI_Aint *extent);
void MPIR_Type_get_true_extent_impl(MPI_Datatype datatype, MPI_Aint *true_lb, MPI_Aint *true_extent);
void MPIR_Type_get_envelope_impl(MPI_Datatype datatype, int *num_integers, int *num_addresses,
......@@ -329,10 +329,16 @@ int MPIR_Gather_intra(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
blocks[0] = sendcount;
struct_displs[0] = MPI_VOID_PTR_CAST_TO_MPI_AINT sendbuf;
types[0] = sendtype;
blocks[1] = curr_cnt - nbytes;
/* check for overflow. work around int limits if needed*/
if (curr_cnt - nbytes != (int)(curr_cnt - nbytes)) {
blocks[1] = 1;
MPIR_Type_contiguous_x_impl(curr_cnt - nbytes,
MPI_BYTE, &(types[1]));
} else {
MPIU_Assign_trunc(blocks[1], curr_cnt - nbytes, int);
types[1] = MPI_BYTE;
struct_displs[1] = MPI_VOID_PTR_CAST_TO_MPI_AINT tmp_buf;
types[1] = MPI_BYTE;
mpi_errno = MPIR_Type_create_struct_impl(2, blocks, struct_displs, types, &tmp_type);
if (mpi_errno) MPIU_ERR_POP(mpi_errno);
......@@ -348,6 +354,8 @@ int MPIR_Gather_intra(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
MPIU_ERR_ADD(mpi_errno_ret, mpi_errno);
if (types[1] != MPI_BYTE)
......@@ -63,7 +63,53 @@ int MPIR_Type_contiguous_impl(int count,
goto fn_exit;
#define FUNCNAME MPIR_Type_contiguous_x_impl
#undef FCNAME
int MPIR_Type_contiguous_x_impl(MPI_Count count,
MPI_Datatype oldtype,
MPI_Datatype *newtype)
/* to make 'count' fit MPI-3 type processing routines (which take integer
* counts), we construct a type consisting of N INT_MAX chunks followed by
* a remainder. e.g for a count of 4000000000 bytes you would end up with
* one 2147483647-byte chunk followed immediately by a 1852516353-byte
* chunk */
MPI_Datatype chunks, remainder;
MPI_Aint lb, extent, disps[2];
int blocklens[2];
MPI_Datatype types[2];
int mpi_errno;
/* truly stupendously large counts will overflow an integer with this math,
* but that is a problem for a few decades from now. Sorry, few decades
* from now! */
MPIU_Assert(count/INT_MAX == (int)(count/INT_MAX));
int c = (int)(count/INT_MAX); /* OK to cast until 'count' is 256 bits */
int r = count%INT_MAX;
mpi_errno = MPIR_Type_vector_impl(c, INT_MAX, INT_MAX, oldtype, &chunks);
if (mpi_errno != MPI_SUCCESS) goto fn_fail;
mpi_errno = MPIR_Type_contiguous_impl(r, oldtype, &remainder);
if (mpi_errno != MPI_SUCCESS) goto fn_fail;
MPIR_Type_get_extent_impl(oldtype, &lb, &extent);
blocklens[0] = 1; blocklens[1] = 1;
disps[0] = 0; disps[1] = c*extent*INT_MAX;
types[0] = chunks; types[1] = remainder;
mpi_errno = MPIR_Type_create_struct_impl(2, blocklens, disps, types, newtype);
return mpi_errno;
goto fn_exit;
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment