Commit f5fc876d authored by Pavan Balaji's avatar Pavan Balaji
Browse files

[svn-r1249] Merging the BG/P changes into trunk. Let's see how the nightly tests do.

parent a311024b
......@@ -98,6 +98,7 @@ enum MPIU_DBG_CLASS { MPIU_DBG_PT2PT = 0x1,
MPIU_DBG_NEM_SOCK_DET = 0x80000,
MPIU_DBG_VC = 0x100000,
MPIU_DBG_REFCOUNT = 0x200000,
MPIU_DBG_ROMIO = 0x400000,
MPIU_DBG_ALL = (~0) }; /* alias for all */
extern int MPIU_DBG_ActiveClasses;
......
......@@ -32,6 +32,12 @@
do not want mpi.h to depend on any other files or configure flags */
#include "mpichconf.h"
/* Adding the 32-bit compute/64-bit I/O related type-casts in here as
* they are not a part of the MPI standard yet. */
#define MPI_AINT_CAST_TO_VOID_PTR (void *)(MPIR_Pint)
#define MPI_VOID_PTR_CAST_TO_MPI_AINT (MPI_Aint)(MPIR_Upint)
#define MPI_PTR_DISP_CAST_TO_MPI_AINT (MPI_Aint)(MPIR_Pint)
#ifdef STDC_HEADERS
#include <stdlib.h>
#include <stdarg.h>
......@@ -88,6 +94,11 @@
#define MPIDI_QUOTE2(A) #A
#endif
/* Include definitions from the device which must exist before items in this
file (mpiimpl.h) can be defined. */
/* ------------------------------------------------------------------------- */
#include "mpidpre.h"
/* ------------------------------------------------------------------------- */
/*
Include the implementation definitions (e.g., error reporting, thread
......@@ -102,13 +113,6 @@
#include "mpiutil.h"
/* Include definitions from the device which must exist before items in this
file (mpiimpl.h) can be defined. */
/* ------------------------------------------------------------------------- */
#include "mpidpre.h"
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* mpidebug.h */
/* ------------------------------------------------------------------------- */
......@@ -1370,6 +1374,7 @@ typedef struct MPID_Request {
MPID_DEV_REQUEST_DECL
#endif
} MPID_Request;
extern MPIU_Object_alloc_t MPID_Request_mem;
/* Preallocated request objects */
extern MPID_Request MPID_Request_direct[];
......
......@@ -79,4 +79,32 @@ int MPID_Abort( struct MPID_Comm *comm, int mpi_errno, int exit_code, const char
} \
}
/*
* Ensure an MPI_Aint value fits into a signed int.
* Useful for detecting overflow when MPI_Aint is larger than an int.
*
* \param[in] aint Variable of type MPI_Aint
*/
#define MPID_Ensure_Aint_fits_in_int(aint) \
MPIU_Assert((aint) == (MPI_Aint)(int)(aint));
/*
* Ensure an MPI_Aint value fits into an unsigned int.
* Useful for detecting overflow when MPI_Aint is larger than an
* unsigned int.
*
* \param[in] aint Variable of type MPI_Aint
*/
#define MPID_Ensure_Aint_fits_in_uint(aint) \
MPIU_Assert((aint) == (MPI_Aint)(unsigned int)(aint));
/*
* Ensure an MPI_Aint value fits into a pointer.
* Useful for detecting overflow when MPI_Aint is larger than a pointer.
*
* \param[in] aint Variable of type MPI_Aint
*/
#define MPID_Ensure_Aint_fits_in_pointer(aint) \
MPIU_Assert((aint) == (MPI_Aint)(MPIR_Upint) MPI_AINT_CAST_TO_VOID_PTR(aint));
#endif /* !defined(MPIUTIL_H_INCLUDED) */
......@@ -94,7 +94,7 @@ int MPI_Attr_get(MPI_Comm comm, int keyval, void *attr_value, int *flag)
should have been used. We can test for this specific
case. Note that this code assumes sizeof(MPI_Aint) is
a power of 2. */
if ((MPI_Aint)attr_value & (sizeof(MPI_Aint)-1)) {
if ((MPIR_Pint)attr_value & (sizeof(MPIR_Pint)-1)) {
MPIU_ERR_SET(mpi_errno,MPI_ERR_ARG,"**attrnotptr");
}
# endif
......
......@@ -119,7 +119,7 @@ int MPIR_Call_attr_delete( int handle, MPID_Attribute *attr_p )
are MPI_Fint values, and we assume
sizeof(MPI_Fint) <= sizeof(MPI_Aint).
See also src/binding/f77/attr_getf.c . */
fvalue = (MPI_Fint) (MPI_Aint)(attr_p->value);
fvalue = (MPI_Fint) MPI_VOID_PTR_CAST_TO_MPI_AINT(attr_p->value);
fextra = (MPI_Fint*) (attr_p->keyval->extra_state);
delfn.F77_DeleteFunction( &fhandle, &fkeyval, &fvalue,
fextra, &ierr );
......@@ -141,7 +141,7 @@ int MPIR_Call_attr_delete( int handle, MPID_Attribute *attr_p )
if (delfn.F90_DeleteFunction) {
fhandle = (MPI_Fint) (handle);
fkeyval = (MPI_Fint) (attr_p->keyval->handle);
fvalue = (MPI_Aint) (attr_p->value);
fvalue = MPI_VOID_PTR_CAST_TO_MPI_AINT(attr_p->value);
fextra = (MPI_Aint*) (attr_p->keyval->extra_state );
delfn.F90_DeleteFunction( &fhandle, &fkeyval, &fvalue,
fextra, &ierr );
......@@ -241,13 +241,13 @@ int MPIR_Attr_dup_list( int handle, MPID_Attribute *old_attrs,
fkeyval = (MPI_Fint) (p->keyval->handle);
/* The following cast can lose data on systems whose
pointers are longer than integers */
fvalue = (MPI_Fint) (MPI_Aint)(p->value);
fvalue = (MPI_Fint) MPI_VOID_PTR_CAST_TO_MPI_AINT(p->value);
fextra = (MPI_Fint*) (p->keyval->extra_state );
copyfn.F77_CopyFunction( &fhandle, &fkeyval, fextra,
&fvalue, &fnew, &fflag, &ierr );
if (ierr) mpi_errno = (int)ierr;
flag = fflag;
new_value = (void *)(MPI_Aint)fnew;
new_value = MPI_AINT_CAST_TO_VOID_PTR (MPI_Aint) fnew;
/* --BEGIN ERROR HANDLING-- */
if (mpi_errno != 0)
{
......@@ -264,13 +264,13 @@ int MPIR_Attr_dup_list( int handle, MPID_Attribute *old_attrs,
MPI_Aint fvalue, fnew, *fextra;
fhandle = (MPI_Fint) (handle);
fkeyval = (MPI_Fint) (p->keyval->handle);
fvalue = (MPI_Aint) (p->value);
fvalue = MPI_VOID_PTR_CAST_TO_MPI_AINT(p->value);
fextra = (MPI_Aint*) (p->keyval->extra_state );
copyfn.F90_CopyFunction( &fhandle, &fkeyval, fextra,
&fvalue, &fnew, &fflag, &ierr );
if (ierr) mpi_errno = (int)ierr;
flag = fflag;
new_value = (void *)fnew;
new_value = MPI_AINT_CAST_TO_VOID_PTR fnew;
/* --BEGIN ERROR HANDLING-- */
if (mpi_errno != 0)
{
......@@ -291,7 +291,8 @@ int MPIR_Attr_dup_list( int handle, MPID_Attribute *old_attrs,
new_p = (MPID_Attribute *)MPIU_Handle_obj_alloc( &MPID_Attr_mem );
/* --BEGIN ERROR HANDLING-- */
if (!new_p) {
mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "MPIR_Attr_dup_list", __LINE__,
mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
"MPIR_Attr_dup_list", __LINE__,
MPI_ERR_OTHER, "**nomem", 0 );
goto fn_exit;
}
......
......@@ -86,7 +86,7 @@ int MPI_Comm_get_attr(MPI_Comm comm, int comm_keyval, void *attribute_val, int *
should have been used. We can test for this specific
case. Note that this code assumes sizeof(MPI_Aint) is
a power of 2. */
if ((MPI_Aint)attribute_val & (sizeof(MPI_Aint)-1)) {
if ((MPIR_Pint)attribute_val & (sizeof(MPIR_Pint)-1)) {
MPIU_ERR_SET(mpi_errno,MPI_ERR_ARG,"**attrnotptr");
}
# endif
......@@ -130,11 +130,11 @@ int MPI_Comm_get_attr(MPI_Comm comm, int comm_keyval, void *attribute_val, int *
/* This is an address-sized int instead of a Fortran (MPI_Fint)
integer because, even for the Fortran keyvals, the C interface is
used which stores the result in a pointer (hence we need a
pointer-sized int). Thus we use MPI_Aint instead of MPI_Fint.
pointer-sized int). Thus we use MPIR_Pint instead of MPI_Fint.
On some 64-bit plaforms, such as Solaris-SPARC, using an MPI_Fint
will cause the value to placed into the high, rather than low,
end of the output value. */
MPI_Aint *attr_int = (MPI_Aint *)attribute_val;
MPIR_Pint *attr_int = (MPIR_Pint *)attribute_val;
#endif
*flag = 1;
......
......@@ -88,7 +88,7 @@ int MPI_Type_get_attr(MPI_Datatype type, int type_keyval, void *attribute_val,
should have been used. We can test for this specific
case. Note that this code assumes sizeof(MPI_Aint) is
a power of 2. */
if ((MPI_Aint)attribute_val & (sizeof(MPI_Aint)-1)) {
if ((MPIR_Pint)attribute_val & (sizeof(MPIR_Pint)-1)) {
MPIU_ERR_SET(mpi_errno,MPI_ERR_ARG,"**attrnotptr");
}
# endif
......
......@@ -82,9 +82,9 @@ int MPI_Win_get_attr(MPI_Win win, int win_keyval, void *attribute_val,
/* A common user error is to pass the address of a 4-byte
int when the address of a pointer (or an address-sized int)
should have been used. We can test for this specific
case. Note that this code assumes sizeof(MPI_Aint) is
case. Note that this code assumes sizeof(MPI_Aint) is
a power of 2. */
if ((MPI_Aint)attribute_val & (sizeof(MPI_Aint)-1)) {
if ((MPIR_Pint)attribute_val & (sizeof(MPIR_Pint)-1)) {
MPIU_ERR_SET(mpi_errno,MPI_ERR_ARG,"**attrnotptr");
}
# endif
......@@ -127,14 +127,14 @@ int MPI_Win_get_attr(MPI_Win win, int win_keyval, void *attribute_val,
#ifdef HAVE_FORTRAN_BINDING
/* Note that this routine only has a Fortran 90 binding,
so the attribute value is an address-sized int */
MPI_Aint *attr_int = (MPI_Aint *)attribute_val;
MPIR_Pint *attr_int = (MPIR_Pint *)attribute_val;
#endif
*flag = 1;
/*
* The C versions of the attributes return the address of a
* *COPY* of the value (to prevent the user from changing it)
* and the Fortran versions provide the actual value (as an Fint)
* and the Fortran versions provide the actual value (as a Fint)
*/
switch (attr_idx) {
case 1: /* WIN_BASE */
......@@ -152,7 +152,7 @@ int MPI_Win_get_attr(MPI_Win win, int win_keyval, void *attribute_val,
case 2: /* Fortran BASE */
/* The Fortran routine that matches this routine should
provide an address-sized integer, not an MPI_Fint */
*attr_int = (MPI_Aint)(win_ptr->base);
*attr_int = MPI_VOID_PTR_CAST_TO_MPI_AINT(win_ptr->base);
break;
case 4: /* Fortran SIZE */
/* We do not need to copy because we return the value,
......
......@@ -106,6 +106,10 @@ int MPIR_Allgather (
MPID_Datatype_get_extent_macro( recvtype, recvtype_extent );
MPID_Datatype_get_size_macro( recvtype, type_size );
/* This is the largest offset we add to recvbuf */
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT recvbuf +
(comm_size * recvcount * recvtype_extent));
/* check if comm_size is a power of two */
pof2 = 1;
while (pof2 < comm_size)
......@@ -626,6 +630,7 @@ int MPIR_Allgather_inter (
MPID_Datatype_get_extent_macro( sendtype, send_extent );
extent = MPIR_MAX(send_extent, true_extent);
MPID_Ensure_Aint_fits_in_pointer(extent * sendcount * local_size);
tmp_buf = MPIU_Malloc(extent*sendcount*local_size);
if (!tmp_buf) {
MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem");
......
......@@ -140,6 +140,8 @@ int MPIR_Allgatherv (
}
/* --END ERROR HANDLING-- */
MPID_Ensure_Aint_fits_in_pointer(total_count *
(MPIR_MAX(recvtype_true_extent, recvtype_extent)));
tmp_buf = MPIU_Malloc(total_count*(MPIR_MAX(recvtype_true_extent,recvtype_extent)));
/* --BEGIN ERROR HANDLING-- */
if (!tmp_buf)
......@@ -560,6 +562,8 @@ int MPIR_Allgatherv (
}
/* --END ERROR HANDLING-- */
MPID_Ensure_Aint_fits_in_pointer(total_count *
MPIR_MAX(recvtype_true_extent, recvtype_extent));
recvbuf_extent = total_count *
(MPIR_MAX(recvtype_true_extent, recvtype_extent));
......
......@@ -190,6 +190,7 @@ int MPIR_Allreduce (
MPIU_ERR_CHKANDJUMP((mpi_errno), mpi_errno, MPI_ERR_OTHER, "**fail");
MPID_Datatype_get_extent_macro(datatype, extent);
MPID_Ensure_Aint_fits_in_pointer(count * MPIR_MAX(extent, true_extent));
MPIU_CHKLMEM_MALLOC(tmp_buf, void *, count*(MPIR_MAX(extent,true_extent)), mpi_errno, "temporary buffer");
/* adjust for potential negative lower bound in datatype */
......
......@@ -536,6 +536,10 @@ int MPIR_Alltoall_inter(
/* Do the pairwise exchanges */
max_size = MPIR_MAX(local_size, remote_size);
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT recvbuf +
max_size*recvcount*recvtype_extent);
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT sendbuf +
max_size*sendcount*sendtype_extent);
for (i=0; i<max_size; i++) {
src = (rank - i + max_size) % max_size;
dst = (rank + i) % max_size;
......
......@@ -95,6 +95,8 @@ int MPIR_Alltoallv (
for ( i=0; i<comm_size; i++ ) {
dst = (rank+i) % comm_size;
if (recvcnts[dst]) {
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT recvbuf +
rdispls[dst]*recv_extent);
mpi_errno = MPIC_Irecv((char *)recvbuf+rdispls[dst]*recv_extent,
recvcnts[dst], recvtype, dst,
MPIR_ALLTOALLV_TAG, comm,
......@@ -113,6 +115,8 @@ int MPIR_Alltoallv (
for ( i=0; i<comm_size; i++ ) {
dst = (rank+i) % comm_size;
if (sendcnts[dst]) {
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT sendbuf +
sdispls[dst]*send_extent);
mpi_errno = MPIC_Isend((char *)sendbuf+sdispls[dst]*send_extent,
sendcnts[dst], sendtype, dst,
MPIR_ALLTOALLV_TAG, comm,
......@@ -206,6 +210,8 @@ int MPIR_Alltoallv_inter (
recvcount = 0;
}
else {
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT recvbuf +
rdispls[src]*recv_extent);
recvaddr = (char *)recvbuf + rdispls[src]*recv_extent;
recvcount = recvcnts[src];
}
......@@ -215,6 +221,8 @@ int MPIR_Alltoallv_inter (
sendcount = 0;
}
else {
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT sendbuf +
sdispls[dst]*send_extent);
sendaddr = (char *)sendbuf + sdispls[dst]*send_extent;
sendcount = sendcnts[dst];
}
......
......@@ -96,7 +96,11 @@ int MPIR_Gather (
relative_rank = (rank >= root) ? rank - root : rank - root + comm_size;
if (rank == root)
{
MPID_Datatype_get_extent_macro(recvtype, extent);
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT recvbuf+
(extent*recvcnt*comm_size));
}
if (is_homogeneous)
{
......@@ -252,10 +256,10 @@ int MPIR_Gather (
}
else {
blocks[0] = sendcnt;
struct_displs[0] = (MPI_Aint) sendbuf;
struct_displs[0] = MPI_VOID_PTR_CAST_TO_MPI_AINT sendbuf;
types[0] = sendtype;
blocks[1] = curr_cnt - nbytes;
struct_displs[1] = (MPI_Aint) tmp_buf;
struct_displs[1] = MPI_VOID_PTR_CAST_TO_MPI_AINT tmp_buf;
types[1] = MPI_BYTE;
NMPI_Type_create_struct(2, blocks, struct_displs, types, &tmp_type);
......@@ -492,6 +496,8 @@ int MPIR_Gather_inter (
/* --END ERROR HANDLING-- */
MPID_Datatype_get_extent_macro(sendtype, extent);
MPID_Ensure_Aint_fits_in_pointer(sendcnt*local_size*
(MPIR_MAX(extent, true_extent)));
tmp_buf =
MPIU_Malloc(sendcnt*local_size*(MPIR_MAX(extent,true_extent)));
/* --BEGIN ERROR HANDLING-- */
......@@ -540,6 +546,9 @@ int MPIR_Gather_inter (
if (root == MPI_ROOT)
{
MPID_Datatype_get_extent_macro(recvtype, extent);
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT recvbuf +
(recvcnt*remote_size*extent));
for (i=0; i<remote_size; i++)
{
mpi_errno = MPIC_Recv(((char *)recvbuf+recvcnt*i*extent),
......
......@@ -71,6 +71,10 @@ int MPIR_Gatherv (
comm_size = comm_ptr->local_size;
MPID_Datatype_get_extent_macro(recvtype, extent);
/* each node can make sure it is not going to overflow aint */
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT recvbuf +
displs[rank] * extent);
for ( i=0; i<root; i++ ) {
if (recvcnts[i]) {
mpi_errno = MPIC_Recv(((char *)recvbuf+displs[i]*extent),
......@@ -88,6 +92,8 @@ int MPIR_Gatherv (
}
if (sendbuf != MPI_IN_PLACE) {
if (recvcnts[rank]) {
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT recvbuf +
displs[rank]*extent);
mpi_errno = MPIR_Localcopy(sendbuf, sendcnt, sendtype,
((char *)recvbuf+displs[rank]*extent),
recvcnts[rank], recvtype);
......@@ -100,6 +106,9 @@ int MPIR_Gatherv (
/* --END ERROR HANDLING-- */
}
}
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT recvbuf +
displs[rank] * extent);
for ( i=root+1; i<comm_size; i++ ) {
if (recvcnts[i]) {
mpi_errno = MPIC_Recv(((char *)recvbuf+displs[i]*extent),
......@@ -122,6 +131,8 @@ int MPIR_Gatherv (
remote_comm_size = comm_ptr->remote_size;
MPID_Datatype_get_extent_macro(recvtype, extent);
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT recvbuf +
displs[rank] * extent);
for (i=0; i<remote_comm_size; i++) {
if (recvcnts[i]) {
mpi_errno = MPIC_Recv(((char *)recvbuf+displs[i]*extent),
......
......@@ -171,6 +171,11 @@ int MPIR_Reduce_scatter (
/* check if multiple threads are calling this collective function */
MPIDU_ERR_CHECK_MULTIPLE_THREADS_ENTER( comm_ptr );
/* total_count*extent eventually gets malloced. it isn't added to
* a user-passed in buffer */
MPID_Ensure_Aint_fits_in_pointer(total_count * MPIR_MAX(true_extent, extent));
MPIR_Nest_incr();
if ((is_commutative) && (nbytes < MPIR_REDSCAT_COMMUTATIVE_LONG_MSG)) {
......
......@@ -146,6 +146,11 @@ int MPIR_Reduce (
if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }
MPID_Datatype_get_extent_macro(datatype, extent);
/* I think this is the worse case, so we can avoid an assert()
* inside the for loop */
/* should be buf+{this}? */
MPID_Ensure_Aint_fits_in_pointer(count * MPIR_MAX(extent, true_extent));
MPIU_CHKLMEM_MALLOC(tmp_buf, void *, count*(MPIR_MAX(extent,true_extent)),
mpi_errno, "temporary buffer");
/* adjust for potential negative lower bound in datatype */
......@@ -629,6 +634,10 @@ int MPIR_Reduce_inter (
if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }
MPID_Datatype_get_extent_macro(datatype, extent);
/* I think this is the worse case, so we can avoid an assert()
* inside the for loop */
/* Should MPIU_CHKLMEM_MALLOC do this? */
MPID_Ensure_Aint_fits_in_pointer(count * MPIR_MAX(extent, true_extent));
MPIU_CHKLMEM_MALLOC(tmp_buf, void *, count*(MPIR_MAX(extent,true_extent)), mpi_errno, "temporary buffer");
/* adjust for potential negative lower bound in datatype */
tmp_buf = (void *)((char*)tmp_buf - true_lb);
......
......@@ -133,6 +133,11 @@ int MPIR_Scan (
MPID_Datatype_get_extent_macro(datatype, extent);
partial_scan = MPIU_Malloc(count*(MPIR_MAX(extent,true_extent)));
/* This eventually gets malloc()ed as a temp buffer, not added to
* any user buffers */
MPID_Ensure_Aint_fits_in_pointer(count * MPIR_MAX(extent, true_extent));
/* --BEGIN ERROR HANDLING-- */
if (!partial_scan) {
mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**nomem", 0 );
......
......@@ -98,10 +98,14 @@ int MPIR_Scatter (
in the event of recvbuf=MPI_IN_PLACE on the root,
recvcnt and recvtype are not valid */
MPID_Datatype_get_size_macro(sendtype, sendtype_size);
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT sendbuf +
extent*sendcnt*comm_size);
nbytes = sendtype_size * sendcnt;
}
else {
MPID_Datatype_get_size_macro(recvtype, recvtype_size);
MPID_Ensure_Aint_fits_in_pointer(extent*recvcnt*comm_size);
nbytes = recvtype_size * recvcnt;
}
......@@ -507,6 +511,10 @@ int MPIR_Scatter_inter (
/* --END ERROR HANDLING-- */
MPID_Datatype_get_extent_macro(recvtype, extent);
MPID_Ensure_Aint_fits_in_pointer(extent*recvcnt*local_size);
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT sendbuf +
sendcnt*remote_size*extent);
tmp_buf =
MPIU_Malloc(recvcnt*local_size*(MPIR_MAX(extent,true_extent)));
/* --BEGIN ERROR HANDLING-- */
......
......@@ -73,6 +73,13 @@ int MPIR_Scatterv (
comm_size = comm_ptr->local_size;
MPID_Datatype_get_extent_macro(sendtype, extent);
/* We need a check to ensure extent will fit in a
* pointer. That needs extent * (max count) but we can't get
* that without looping over the input data. This is at least
* a minimal sanity check. Maybe add a global var since we do
* loop over sendcount[] in MPI_Scatterv before calling
* this? */
MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT sendbuf + extent);
/* We could use Isend here, but since the receivers need to execute
a simple Recv, it may not make much difference in performance,
......
Markdown is supported
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