-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/coll/gatherv.c
-: 0:Graph:gatherv.gcno
-: 0:Data:gatherv.gcda
-: 0:Runs:739
-: 0:Programs:199
-: 1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
-: 2:/*
-: 3: *
-: 4: * (C) 2001 by Argonne National Laboratory.
-: 5: * See COPYRIGHT in top-level directory.
-: 6: */
-: 7:
-: 8:#include "mpiimpl.h"
-: 9:
-: 10:/* -- Begin Profiling Symbol Block for routine MPI_Gatherv */
-: 11:#if defined(HAVE_PRAGMA_WEAK)
-: 12:#pragma weak MPI_Gatherv = PMPI_Gatherv
-: 13:#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
-: 14:#pragma _HP_SECONDARY_DEF PMPI_Gatherv MPI_Gatherv
-: 15:#elif defined(HAVE_PRAGMA_CRI_DUP)
-: 16:#pragma _CRI duplicate MPI_Gatherv as PMPI_Gatherv
-: 17:#endif
-: 18:/* -- End Profiling Symbol Block */
-: 19:
-: 20:/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
-: 21: the MPI routines */
-: 22:#ifndef MPICH_MPI_FROM_PMPI
-: 23:#undef MPI_Gatherv
-: 24:#define MPI_Gatherv PMPI_Gatherv
-: 25:
-: 26:/* This is the default implementation of gatherv. The algorithm is:
-: 27:
-: 28: Algorithm: MPI_Gatherv
-: 29:
-: 30: Since the array of recvcounts is valid only on the root, we cannot
-: 31: do a tree algorithm without first communicating the recvcounts to
-: 32: other processes. Therefore, we simply use a linear algorithm for the
-: 33: gather, which takes (p-1) steps versus lgp steps for the tree
-: 34: algorithm. The bandwidth requirement is the same for both algorithms.
-: 35:
-: 36: Cost = (p-1).alpha + n.((p-1)/p).beta
-: 37:
-: 38: Possible improvements:
-: 39:
-: 40: End Algorithm: MPI_Gatherv
-: 41:*/
-: 42:
-: 43:/* not declared static because it is called in intercommunicator allgatherv */
-: 44:int MPIR_Gatherv (
-: 45: void *sendbuf,
-: 46: int sendcnt,
-: 47: MPI_Datatype sendtype,
-: 48: void *recvbuf,
-: 49: int *recvcnts,
-: 50: int *displs,
-: 51: MPI_Datatype recvtype,
-: 52: int root,
-: 53: MPID_Comm *comm_ptr )
11805: 54:{
-: 55: static const char FCNAME[] = "MPIR_Gatherv";
-: 56: int comm_size, rank;
11805: 57: int mpi_errno = MPI_SUCCESS;
-: 58: MPI_Comm comm;
-: 59: MPI_Aint extent;
-: 60: int i, reqs;
-: 61: int min_procs;
-: 62: char *min_procs_str;
-: 63: MPI_Request *reqarray;
-: 64: MPI_Status *starray;
11805: 65: MPIU_CHKLMEM_DECL(2);
-: 66:
11805: 67: comm = comm_ptr->handle;
11805: 68: rank = comm_ptr->rank;
-: 69:
-: 70: /* check if multiple threads are calling this collective function */
-: 71: MPIDU_ERR_CHECK_MULTIPLE_THREADS_ENTER( comm_ptr );
-: 72:
-: 73: /* If rank == root, then I recv lots, otherwise I send */
11805: 74: if (((comm_ptr->comm_kind == MPID_INTRACOMM) && (root == rank)) ||
-: 75: ((comm_ptr->comm_kind == MPID_INTERCOMM) && (root == MPI_ROOT))) {
4032: 76: if (comm_ptr->comm_kind == MPID_INTRACOMM)
2752: 77: comm_size = comm_ptr->local_size;
-: 78: else
1280: 79: comm_size = comm_ptr->remote_size;
-: 80:
4032: 81: MPID_Datatype_get_extent_macro(recvtype, extent);
-: 82: /* each node can make sure it is not going to overflow aint */
-: 83: MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT recvbuf +
-: 84: displs[rank] * extent);
-: 85:
4032: 86: MPIU_CHKLMEM_MALLOC(reqarray, MPI_Request *, comm_size * sizeof(MPI_Request), mpi_errno, "reqarray");
4032: 87: MPIU_CHKLMEM_MALLOC(starray, MPI_Status *, comm_size * sizeof(MPI_Status), mpi_errno, "starray");
-: 88:
4032: 89: reqs = 0;
12461: 90: for (i = 0; i < comm_size; i++) {
8429: 91: if (recvcnts[i]) {
7723: 92: if ((comm_ptr->comm_kind == MPID_INTRACOMM) && (i == rank)) {
2605: 93: if (sendbuf != MPI_IN_PLACE) {
2594: 94: mpi_errno = MPIR_Localcopy(sendbuf, sendcnt, sendtype,
-: 95: ((char *)recvbuf+displs[rank]*extent),
-: 96: recvcnts[rank], recvtype);
-: 97: }
-: 98: }
-: 99: else {
5118: 100: mpi_errno = MPIC_Irecv(((char *)recvbuf+displs[i]*extent),
-: 101: recvcnts[i], recvtype, i,
-: 102: MPIR_GATHERV_TAG, comm,
-: 103: &reqarray[reqs++]);
-: 104: }
|
-: 105: /* --BEGIN ERROR HANDLING-- */
7723: 106: if (mpi_errno) {
#####: 107: mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0);
#####: 108: return mpi_errno;
-: 109: }
-: 110: /* --END ERROR HANDLING-- */
-: 111: }
-: 112: }
-: 113: /* ... then wait for *all* of them to finish: */
|
4032: 114: mpi_errno = NMPI_Waitall(reqs, reqarray, starray);
|
-: 115: /* --BEGIN ERROR HANDLING-- */
4032: 116: if (mpi_errno == MPI_ERR_IN_STATUS) {
#####: 117: for (i = 0; i < reqs; i++) {
#####: 118: if (starray[i].MPI_ERROR != MPI_SUCCESS)
#####: 119: mpi_errno = starray[i].MPI_ERROR;
-: 120: }
-: 121: }
-: 122: /* --END ERROR HANDLING-- */
-: 123: }
-: 124:
|
7773: 125: else if (root != MPI_PROC_NULL) { /* non-root nodes, and in the intercomm. case, non-root nodes on remote side */
5677: 126: if (sendcnt) {
-: 127: /* we want local size in both the intracomm and intercomm cases
-: 128: because the size of the root's group (group A in the standard) is
-: 129: irrelevant here. */
5118: 130: comm_size = comm_ptr->local_size;
-: 131:
5118: 132: min_procs_str = getenv("MPICH2_GATHERV_MIN_PROCS");
5118: 133: if (min_procs_str != NULL)
-: 134: min_procs = atoi(min_procs_str);
-: 135: else
5118: 136: min_procs = comm_size + 1; /* Disable ssend if env not set */
-: 137:
5118: 138: if (min_procs == -1)
|
#####: 139: min_procs = comm_size + 1; /* Disable ssend */
|
5118: 140: else if (min_procs == 0)
|
#####: 141: min_procs = MPIR_GATHERV_MIN_PROCS; /* Use the default value */
-: 142:
|
5118: 143: if (comm_size >= min_procs) {
|
#####: 144: mpi_errno = MPIC_Ssend(sendbuf, sendcnt, sendtype, root,
-: 145: MPIR_GATHERV_TAG, comm);
-: 146: }
-: 147: else {
|
5118: 148: mpi_errno = MPIC_Send(sendbuf, sendcnt, sendtype, root,
-: 149: MPIR_GATHERV_TAG, comm);
-: 150: }
|
-: 151: /* --BEGIN ERROR HANDLING-- */
5118: 152: if (mpi_errno) {
#####: 153: mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0);
#####: 154: return mpi_errno;
-: 155: }
-: 156: /* --END ERROR HANDLING-- */
-: 157: }
-: 158: }
-: 159:
-: 160: /* check if multiple threads are calling this collective function */
-: 161: MPIDU_ERR_CHECK_MULTIPLE_THREADS_EXIT( comm_ptr );
-: 162:
-: 163:fn_exit:
|
8064: 164: MPIU_CHKLMEM_FREEALL();
11805: 165: return mpi_errno;
|
-: 166:fn_fail:
-: 167: goto fn_exit;
-: 168:}
-: 169:
-: 170:#endif
-: 171:
-: 172:#undef FUNCNAME
-: 173:#define FUNCNAME MPI_Gatherv
-: 174:
-: 175:/*@
-: 176:
-: 177:MPI_Gatherv - Gathers into specified locations from all processes in a group
-: 178:
-: 179:Input Parameters:
-: 180:+ sendbuf - starting address of send buffer (choice)
-: 181:. sendcount - number of elements in send buffer (integer)
-: 182:. sendtype - data type of send buffer elements (handle)
-: 183:. recvcounts - integer array (of length group size)
-: 184:containing the number of elements that are received from each process
-: 185:(significant only at 'root')
-: 186:. displs - integer array (of length group size). Entry
-: 187: 'i' specifies the displacement relative to recvbuf at
-: 188:which to place the incoming data from process 'i' (significant only
-: 189:at root)
-: 190:. recvtype - data type of recv buffer elements
-: 191:(significant only at 'root') (handle)
-: 192:. root - rank of receiving process (integer)
-: 193:- comm - communicator (handle)
-: 194:
-: 195:Output Parameter:
-: 196:. recvbuf - address of receive buffer (choice, significant only at 'root')
-: 197:
-: 198:.N ThreadSafe
-: 199:
-: 200:.N Fortran
-: 201:
-: 202:.N Errors
-: 203:.N MPI_SUCCESS
-: 204:.N MPI_ERR_COMM
-: 205:.N MPI_ERR_TYPE
-: 206:.N MPI_ERR_BUFFER
-: 207:@*/
-: 208:int MPI_Gatherv(void *sendbuf, int sendcnt, MPI_Datatype sendtype,
-: 209: void *recvbuf, int *recvcnts, int *displs,
-: 210: MPI_Datatype recvtype, int root, MPI_Comm comm)
|
6057: 211:{
-: 212: static const char FCNAME[] = "MPI_Gatherv";
6057: 213: int mpi_errno = MPI_SUCCESS;
6057: 214: MPID_Comm *comm_ptr = NULL;
6057: 215: MPIU_THREADPRIV_DECL;
-: 216: MPID_MPI_STATE_DECL(MPID_STATE_MPI_GATHERV);
-: 217:
6057: 218: MPIR_ERRTEST_INITIALIZED_ORDIE();
-: 219:
6057: 220: MPIU_THREAD_CS_ENTER(ALLFUNC,);
-: 221: MPID_MPI_COLL_FUNC_ENTER(MPID_STATE_MPI_GATHERV);
-: 222:
-: 223: /* Validate parameters, especially handles needing to be converted */
|
-: 224:# ifdef HAVE_ERROR_CHECKING
-: 225: {
-: 226: MPID_BEGIN_ERROR_CHECKS;
-: 227: {
6057: 228: MPIR_ERRTEST_COMM(comm, mpi_errno);
6057: 229: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 230: }
-: 231: MPID_END_ERROR_CHECKS;
-: 232: }
-: 233:# endif /* HAVE_ERROR_CHECKING */
-: 234:
-: 235: /* Convert MPI object handles to object pointers */
|
6055: 236: MPID_Comm_get_ptr( comm, comm_ptr );
-: 237:
-: 238: /* Validate parameters and objects (post conversion) */
|
-: 239:# ifdef HAVE_ERROR_CHECKING
-: 240: {
-: 241: MPID_BEGIN_ERROR_CHECKS;
-: 242: {
6055: 243: MPID_Datatype *sendtype_ptr=NULL, *recvtype_ptr=NULL;
-: 244: int i, rank, comm_size;
-: 245:
6055: 246: MPID_Comm_valid_ptr( comm_ptr, mpi_errno );
6055: 247: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 248:
6053: 249: if (comm_ptr->comm_kind == MPID_INTRACOMM) {
4613: 250: MPIR_ERRTEST_INTRA_ROOT(comm_ptr, root, mpi_errno);
-: 251:
4613: 252: if (sendbuf != MPI_IN_PLACE) {
4602: 253: MPIR_ERRTEST_COUNT(sendcnt, mpi_errno);
4602: 254: MPIR_ERRTEST_DATATYPE(sendtype, "sendtype", mpi_errno);
4602: 255: if (HANDLE_GET_KIND(sendtype) != HANDLE_KIND_BUILTIN) {
578: 256: MPID_Datatype_get_ptr(sendtype, sendtype_ptr);
578: 257: MPID_Datatype_valid_ptr( sendtype_ptr, mpi_errno );
578: 258: MPID_Datatype_committed_ptr( sendtype_ptr, mpi_errno );
-: 259: }
4602: 260: MPIR_ERRTEST_USERBUFFER(sendbuf,sendcnt,sendtype,mpi_errno);
-: 261: }
-: 262:
4613: 263: rank = comm_ptr->rank;
4613: 264: if (rank == root) {
2754: 265: comm_size = comm_ptr->local_size;
7363: 266: for (i=0; i<comm_size; i++) {
4609: 267: MPIR_ERRTEST_COUNT(recvcnts[i], mpi_errno);
4609: 268: MPIR_ERRTEST_DATATYPE(recvtype, "recvtype", mpi_errno);
-: 269: }
2754: 270: if (HANDLE_GET_KIND(recvtype) != HANDLE_KIND_BUILTIN) {
361: 271: MPID_Datatype_get_ptr(recvtype, recvtype_ptr);
361: 272: MPID_Datatype_valid_ptr( recvtype_ptr, mpi_errno );
361: 273: MPID_Datatype_committed_ptr( recvtype_ptr, mpi_errno );
-: 274: }
-: 275:
2964: 276: for (i=0; i<comm_size; i++) {
2880: 277: if (recvcnts[i] > 0) {
2670: 278: MPIR_ERRTEST_RECVBUF_INPLACE(recvbuf, recvcnts[i], mpi_errno);
2670: 279: MPIR_ERRTEST_USERBUFFER(recvbuf,recvcnts[i],recvtype,mpi_errno);
-: 280: break;
-: 281: }
-: 282: }
-: 283: }
-: 284: else
1859: 285: MPIR_ERRTEST_SENDBUF_INPLACE(sendbuf, sendcnt, mpi_errno);
-: 286: }
-: 287:
6053: 288: if (comm_ptr->comm_kind == MPID_INTERCOMM) {
1440: 289: MPIR_ERRTEST_INTER_ROOT(comm_ptr, root, mpi_errno);
-: 290:
1440: 291: if (root == MPI_ROOT) {
256: 292: comm_size = comm_ptr->remote_size;
1200: 293: for (i=0; i<comm_size; i++) {
944: 294: MPIR_ERRTEST_COUNT(recvcnts[i], mpi_errno);
944: 295: MPIR_ERRTEST_DATATYPE(recvtype, "recvtype", mpi_errno);
-: 296: }
256: 297: if (HANDLE_GET_KIND(recvtype) != HANDLE_KIND_BUILTIN) {
#####: 298: MPID_Datatype_get_ptr(recvtype, recvtype_ptr);
#####: 299: MPID_Datatype_valid_ptr( recvtype_ptr, mpi_errno );
#####: 300: MPID_Datatype_committed_ptr( recvtype_ptr, mpi_errno );
-: 301: }
256: 302: for (i=0; i<comm_size; i++) {
256: 303: if (recvcnts[i] > 0) {
256: 304: MPIR_ERRTEST_RECVBUF_INPLACE(recvbuf, recvcnts[i], mpi_errno);
256: 305: MPIR_ERRTEST_USERBUFFER(recvbuf,recvcnts[i],recvtype,mpi_errno);
-: 306: break;
-: 307: }
-: 308: }
-: 309: }
1184: 310: else if (root != MPI_PROC_NULL) {
944: 311: MPIR_ERRTEST_COUNT(sendcnt, mpi_errno);
944: 312: MPIR_ERRTEST_DATATYPE(sendtype, "sendtype", mpi_errno);
944: 313: if (HANDLE_GET_KIND(sendtype) != HANDLE_KIND_BUILTIN) {
#####: 314: MPID_Datatype_get_ptr(sendtype, sendtype_ptr);
#####: 315: MPID_Datatype_valid_ptr( sendtype_ptr, mpi_errno );
#####: 316: MPID_Datatype_committed_ptr( sendtype_ptr, mpi_errno );
-: 317: }
944: 318: MPIR_ERRTEST_SENDBUF_INPLACE(sendbuf, sendcnt, mpi_errno);
944: 319: MPIR_ERRTEST_USERBUFFER(sendbuf,sendcnt,sendtype,mpi_errno);
-: 320: }
-: 321: }
-: 322:
6053: 323: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 324: }
-: 325: MPID_END_ERROR_CHECKS;
-: 326: }
-: 327:# endif /* HAVE_ERROR_CHECKING */
-: 328:
-: 329: /* ... body of routine ... */
-: 330:
|
6045: 331: if (comm_ptr->coll_fns != NULL && comm_ptr->coll_fns->Gatherv != NULL)
-: 332: {
|
#####: 333: mpi_errno = comm_ptr->coll_fns->Gatherv(sendbuf, sendcnt,
-: 334: sendtype, recvbuf, recvcnts,
-: 335: displs, recvtype, root,
-: 336: comm_ptr);
-: 337: }
-: 338: else
-: 339: {
|
6045: 340: MPIU_THREADPRIV_GET;
-: 341:
6045: 342: MPIR_Nest_incr();
6045: 343: mpi_errno = MPIR_Gatherv(sendbuf, sendcnt, sendtype,
-: 344: recvbuf, recvcnts,
-: 345: displs, recvtype, root, comm_ptr);
6045: 346: MPIR_Nest_decr();
-: 347: }
-: 348:
|
6045: 349: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 350:
-: 351: /* ... end of body of routine ... */
-: 352:
|
6057: 353: fn_exit:
|
-: 354: MPID_MPI_COLL_FUNC_EXIT(MPID_STATE_MPI_GATHERV);
|
6057: 355: MPIU_THREAD_CS_EXIT(ALLFUNC,);
6057: 356: return mpi_errno;
-: 357:
|
12: 358: fn_fail:
-: 359: /* --BEGIN ERROR HANDLING-- */
-: 360:# ifdef HAVE_ERROR_CHECKING
-: 361: {
12: 362: mpi_errno = MPIR_Err_create_code(
-: 363: mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_gatherv",
-: 364: "**mpi_gatherv %p %d %D %p %p %p %D %d %C", sendbuf, sendcnt, sendtype,
-: 365: recvbuf, recvcnts, displs, recvtype, root, comm);
-: 366: }
-: 367:# endif
12: 368: mpi_errno = MPIR_Err_return_comm( comm_ptr, FCNAME, mpi_errno );
12: 369: goto fn_exit;
-: 370: /* --END ERROR HANDLING-- */
-: 371:}
|