-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/coll/scatterv.c
-: 0:Graph:scatterv.gcno
-: 0:Data:scatterv.gcda
-: 0:Runs:4381
-: 0:Programs:1376
-: 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_Scatterv */
-: 11:#if defined(HAVE_PRAGMA_WEAK)
-: 12:#pragma weak MPI_Scatterv = PMPI_Scatterv
-: 13:#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
-: 14:#pragma _HP_SECONDARY_DEF PMPI_Scatterv MPI_Scatterv
-: 15:#elif defined(HAVE_PRAGMA_CRI_DUP)
-: 16:#pragma _CRI duplicate MPI_Scatterv as PMPI_Scatterv
-: 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_Scatterv
-: 24:#define MPI_Scatterv PMPI_Scatterv
-: 25:
-: 26:/* This is the default implementation of scatterv. The algorithm is:
-: 27:
-: 28: Algorithm: MPI_Scatterv
-: 29:
-: 30: Since the array of sendcounts is valid only on the root, we cannot
-: 31: do a tree algorithm without first communicating the sendcounts to
-: 32: other processes. Therefore, we simply use a linear algorithm for the
-: 33: scatter, 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_Scatterv
-: 41:*/
-: 42:
-: 43:/* not declared static because it is called in intercomm. reduce_scatter */
-: 44:#undef FUNCNAME
-: 45:#define FUNCNAME MPIR_Scatterv
-: 46:int MPIR_Scatterv (
-: 47: void *sendbuf,
-: 48: int *sendcnts,
-: 49: int *displs,
-: 50: MPI_Datatype sendtype,
-: 51: void *recvbuf,
-: 52: int recvcnt,
-: 53: MPI_Datatype recvtype,
-: 54: int root,
-: 55: MPID_Comm *comm_ptr )
5528: 56:{
-: 57: static const char FCNAME[] = "MPIR_Scatterv";
5528: 58: int rank, comm_size, mpi_errno = MPI_SUCCESS;
-: 59: MPI_Comm comm;
-: 60: MPI_Aint extent;
-: 61: int i, reqs;
-: 62: MPI_Request *reqarray;
-: 63: MPI_Status *starray;
5528: 64: MPIU_CHKLMEM_DECL(2);
-: 65:
5528: 66: comm = comm_ptr->handle;
5528: 67: rank = comm_ptr->rank;
-: 68:
-: 69: /* check if multiple threads are calling this collective function */
-: 70: MPIDU_ERR_CHECK_MULTIPLE_THREADS_ENTER( comm_ptr );
-: 71:
-: 72: /* If I'm the root, then scatter */
5528: 73: if (((comm_ptr->comm_kind == MPID_INTRACOMM) && (root == rank)) ||
-: 74: ((comm_ptr->comm_kind == MPID_INTERCOMM) && (root == MPI_ROOT))) {
2792: 75: if (comm_ptr->comm_kind == MPID_INTRACOMM)
2536: 76: comm_size = comm_ptr->local_size;
-: 77: else
256: 78: comm_size = comm_ptr->remote_size;
-: 79:
2792: 80: MPID_Datatype_get_extent_macro(sendtype, extent);
-: 81: /* We need a check to ensure extent will fit in a
-: 82: * pointer. That needs extent * (max count) but we can't get
-: 83: * that without looping over the input data. This is at least
-: 84: * a minimal sanity check. Maybe add a global var since we do
-: 85: * loop over sendcount[] in MPI_Scatterv before calling
-: 86: * this? */
-: 87: MPID_Ensure_Aint_fits_in_pointer(MPI_VOID_PTR_CAST_TO_MPI_AINT sendbuf + extent);
-: 88:
2792: 89: MPIU_CHKLMEM_MALLOC(reqarray, MPI_Request *, comm_size * sizeof(MPI_Request), mpi_errno, "reqarray");
2792: 90: MPIU_CHKLMEM_MALLOC(starray, MPI_Status *, comm_size * sizeof(MPI_Status), mpi_errno, "starray");
-: 91:
2792: 92: reqs = 0;
7824: 93: for (i = 0; i < comm_size; i++) {
5032: 94: if (sendcnts[i]) {
4822: 95: if ((comm_ptr->comm_kind == MPID_INTRACOMM) && (i == rank)) {
2389: 96: if (recvbuf != MPI_IN_PLACE) {
2388: 97: mpi_errno = MPIR_Localcopy(((char *)sendbuf+displs[rank]*extent),
-: 98: sendcnts[rank], sendtype,
-: 99: recvbuf, recvcnt, recvtype);
-: 100: }
-: 101: }
-: 102: else {
2433: 103: mpi_errno = MPIC_Isend(((char *)sendbuf+displs[i]*extent),
-: 104: sendcnts[i], sendtype, i,
-: 105: MPIR_SCATTERV_TAG, comm, &reqarray[reqs++]);
-: 106: }
|
-: 107: /* --BEGIN ERROR HANDLING-- */
4822: 108: if (mpi_errno) {
#####: 109: mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0);
#####: 110: return mpi_errno;
-: 111: }
-: 112: /* --END ERROR HANDLING-- */
-: 113: }
-: 114: }
-: 115: /* ... then wait for *all* of them to finish: */
|
2792: 116: mpi_errno = NMPI_Waitall(reqs, reqarray, starray);
|
-: 117: /* --BEGIN ERROR HANDLING-- */
2792: 118: if (mpi_errno == MPI_ERR_IN_STATUS) {
#####: 119: for (i = 0; i < reqs; i++) {
#####: 120: if (starray[i].MPI_ERROR != MPI_SUCCESS)
#####: 121: mpi_errno = starray[i].MPI_ERROR;
-: 122: }
-: 123: }
-: 124: /* --END ERROR HANDLING-- */
-: 125: }
-: 126:
|
2736: 127: else if (root != MPI_PROC_NULL) { /* non-root nodes, and in the intercomm. case, non-root nodes on remote side */
2496: 128: if (recvcnt) {
2433: 129: mpi_errno = MPIC_Recv(recvbuf,recvcnt,recvtype,root,
-: 130: MPIR_SCATTERV_TAG,comm,MPI_STATUS_IGNORE);
|
-: 131: /* --BEGIN ERROR HANDLING-- */
2433: 132: if (mpi_errno) {
#####: 133: mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0);
#####: 134: return mpi_errno;
-: 135: }
-: 136: /* --END ERROR HANDLING-- */
-: 137: }
-: 138: }
-: 139:
-: 140: /* check if multiple threads are calling this collective function */
-: 141: MPIDU_ERR_CHECK_MULTIPLE_THREADS_EXIT( comm_ptr );
-: 142:
-: 143:fn_exit:
|
5584: 144: MPIU_CHKLMEM_FREEALL();
5528: 145: return mpi_errno;
|
-: 146:fn_fail:
-: 147: goto fn_exit;
-: 148:}
-: 149:
-: 150:#endif
-: 151:
-: 152:#undef FUNCNAME
-: 153:#define FUNCNAME MPI_Scatterv
-: 154:
-: 155:/*@
-: 156:
-: 157:MPI_Scatterv - Scatters a buffer in parts to all processes in a communicator
-: 158:
-: 159:Input Parameters:
-: 160:+ sendbuf - address of send buffer (choice, significant only at 'root')
-: 161:. sendcounts - integer array (of length group size)
-: 162:specifying the number of elements to send to each processor
-: 163:. displs - integer array (of length group size). Entry
-: 164: 'i' specifies the displacement (relative to sendbuf from
-: 165:which to take the outgoing data to process 'i'
-: 166:. sendtype - data type of send buffer elements (handle)
-: 167:. recvcount - number of elements in receive buffer (integer)
-: 168:. recvtype - data type of receive buffer elements (handle)
-: 169:. root - rank of sending process (integer)
-: 170:- comm - communicator (handle)
-: 171:
-: 172:Output Parameter:
-: 173:. recvbuf - address of receive buffer (choice)
-: 174:
-: 175:.N ThreadSafe
-: 176:
-: 177:.N Fortran
-: 178:
-: 179:.N Errors
-: 180:.N MPI_SUCCESS
-: 181:.N MPI_ERR_COMM
-: 182:.N MPI_ERR_COUNT
-: 183:.N MPI_ERR_TYPE
-: 184:.N MPI_ERR_BUFFER
-: 185:@*/
-: 186:int MPI_Scatterv( void *sendbuf, int *sendcnts, int *displs,
-: 187: MPI_Datatype sendtype, void *recvbuf, int recvcnt,
-: 188: MPI_Datatype recvtype,
-: 189: int root, MPI_Comm comm)
|
5540: 190:{
-: 191: static const char FCNAME[] = "MPI_Scatterv";
5540: 192: int mpi_errno = MPI_SUCCESS;
5540: 193: MPID_Comm *comm_ptr = NULL;
5540: 194: MPIU_THREADPRIV_DECL;
-: 195: MPID_MPI_STATE_DECL(MPID_STATE_MPI_SCATTERV);
-: 196:
5540: 197: MPIR_ERRTEST_INITIALIZED_ORDIE();
-: 198:
5540: 199: MPIU_THREAD_CS_ENTER(ALLFUNC,);
-: 200: MPID_MPI_COLL_FUNC_ENTER(MPID_STATE_MPI_SCATTERV);
-: 201:
-: 202: /* Validate parameters, especially handles needing to be converted */
|
-: 203:# ifdef HAVE_ERROR_CHECKING
-: 204: {
-: 205: MPID_BEGIN_ERROR_CHECKS;
-: 206: {
5540: 207: MPIR_ERRTEST_COMM(comm, mpi_errno);
5540: 208: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 209: }
-: 210: MPID_END_ERROR_CHECKS;
-: 211: }
-: 212:# endif /* HAVE_ERROR_CHECKING */
-: 213:
-: 214: /* Convert MPI object handles to object pointers */
|
5538: 215: MPID_Comm_get_ptr( comm, comm_ptr );
-: 216:
-: 217: /* Validate parameters and objects (post conversion) */
|
-: 218:# ifdef HAVE_ERROR_CHECKING
-: 219: {
-: 220: MPID_BEGIN_ERROR_CHECKS;
-: 221: {
5538: 222: MPID_Datatype *sendtype_ptr=NULL, *recvtype_ptr=NULL;
-: 223: int i, comm_size, rank;
-: 224:
5538: 225: MPID_Comm_valid_ptr( comm_ptr, mpi_errno );
5538: 226: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 227:
5536: 228: if (comm_ptr->comm_kind == MPID_INTRACOMM) {
4096: 229: MPIR_ERRTEST_INTRA_ROOT(comm_ptr, root, mpi_errno);
4096: 230: rank = comm_ptr->rank;
4096: 231: comm_size = comm_ptr->local_size;
-: 232:
4096: 233: if (rank == root) {
6630: 234: for (i=0; i<comm_size; i++) {
4092: 235: MPIR_ERRTEST_COUNT(sendcnts[i], mpi_errno);
4092: 236: MPIR_ERRTEST_DATATYPE(sendtype, "sendtype", mpi_errno);
-: 237: }
2538: 238: if (HANDLE_GET_KIND(sendtype) != HANDLE_KIND_BUILTIN) {
364: 239: MPID_Datatype_get_ptr(sendtype, sendtype_ptr);
364: 240: MPID_Datatype_valid_ptr( sendtype_ptr, mpi_errno );
364: 241: MPID_Datatype_committed_ptr( sendtype_ptr, mpi_errno );
-: 242: }
2750: 243: for (i=0; i<comm_size; i++) {
2665: 244: if (sendcnts[i] > 0) {
2453: 245: MPIR_ERRTEST_USERBUFFER(sendbuf,sendcnts[i],sendtype,mpi_errno);
-: 246: break;
-: 247: }
-: 248: }
2750: 249: for (i=0; i<comm_size; i++) {
2665: 250: if (sendcnts[i] > 0) {
2453: 251: MPIR_ERRTEST_SENDBUF_INPLACE(sendbuf, sendcnts[i], mpi_errno);
-: 252: break;
-: 253: }
-: 254: }
-: 255: }
-: 256: else
1558: 257: MPIR_ERRTEST_RECVBUF_INPLACE(recvbuf, recvcnt, mpi_errno);
-: 258:
4096: 259: if (recvbuf != MPI_IN_PLACE) {
4095: 260: MPIR_ERRTEST_COUNT(recvcnt, mpi_errno);
4095: 261: MPIR_ERRTEST_DATATYPE(recvtype, "recvtype", mpi_errno);
4095: 262: if (HANDLE_GET_KIND(recvtype) != HANDLE_KIND_BUILTIN) {
578: 263: MPID_Datatype_get_ptr(recvtype, recvtype_ptr);
578: 264: MPID_Datatype_valid_ptr( recvtype_ptr, mpi_errno );
578: 265: MPID_Datatype_committed_ptr( recvtype_ptr, mpi_errno );
-: 266: }
4095: 267: MPIR_ERRTEST_USERBUFFER(recvbuf,recvcnt,recvtype,mpi_errno);
-: 268: }
-: 269: }
-: 270:
5536: 271: if (comm_ptr->comm_kind == MPID_INTERCOMM) {
1440: 272: MPIR_ERRTEST_INTER_ROOT(comm_ptr, root, mpi_errno);
1440: 273: if (root == MPI_ROOT) {
256: 274: comm_size = comm_ptr->remote_size;
1200: 275: for (i=0; i<comm_size; i++) {
944: 276: MPIR_ERRTEST_COUNT(sendcnts[i], mpi_errno);
944: 277: MPIR_ERRTEST_DATATYPE(sendtype, "sendtype", mpi_errno);
-: 278: }
256: 279: if (HANDLE_GET_KIND(sendtype) != HANDLE_KIND_BUILTIN) {
#####: 280: MPID_Datatype_get_ptr(sendtype, sendtype_ptr);
#####: 281: MPID_Datatype_valid_ptr( sendtype_ptr, mpi_errno );
#####: 282: MPID_Datatype_committed_ptr( sendtype_ptr, mpi_errno );
-: 283: }
256: 284: for (i=0; i<comm_size; i++) {
256: 285: if (sendcnts[i] > 0) {
256: 286: MPIR_ERRTEST_SENDBUF_INPLACE(sendbuf, sendcnts[i], mpi_errno);
256: 287: MPIR_ERRTEST_USERBUFFER(sendbuf,sendcnts[i],sendtype,mpi_errno);
-: 288: break;
-: 289: }
-: 290: }
-: 291: }
1184: 292: else if (root != MPI_PROC_NULL) {
944: 293: MPIR_ERRTEST_COUNT(recvcnt, mpi_errno);
944: 294: MPIR_ERRTEST_DATATYPE(recvtype, "recvtype", mpi_errno);
944: 295: if (HANDLE_GET_KIND(recvtype) != HANDLE_KIND_BUILTIN) {
#####: 296: MPID_Datatype_get_ptr(recvtype, recvtype_ptr);
#####: 297: MPID_Datatype_valid_ptr( recvtype_ptr, mpi_errno );
#####: 298: MPID_Datatype_committed_ptr( recvtype_ptr, mpi_errno );
-: 299: }
944: 300: MPIR_ERRTEST_RECVBUF_INPLACE(recvbuf, recvcnt, mpi_errno);
944: 301: MPIR_ERRTEST_USERBUFFER(recvbuf,recvcnt,recvtype,mpi_errno);
-: 302: }
-: 303: }
-: 304:
5536: 305: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 306: }
-: 307: MPID_END_ERROR_CHECKS;
-: 308: }
-: 309:# endif /* HAVE_ERROR_CHECKING */
-: 310:
-: 311: /* ... body of routine ... */
-: 312:
|
5528: 313: if (comm_ptr->coll_fns != NULL && comm_ptr->coll_fns->Scatter != NULL)
-: 314: {
|
#####: 315: mpi_errno = comm_ptr->coll_fns->Scatterv(sendbuf, sendcnts, displs,
-: 316: sendtype, recvbuf, recvcnt,
-: 317: recvtype, root, comm_ptr);
-: 318: }
-: 319: else
-: 320: {
|
5528: 321: MPIU_THREADPRIV_GET;
-: 322:
5528: 323: MPIR_Nest_incr();
5528: 324: mpi_errno = MPIR_Scatterv(sendbuf, sendcnts, displs, sendtype,
-: 325: recvbuf, recvcnt, recvtype,
-: 326: root, comm_ptr);
5528: 327: MPIR_Nest_decr();
-: 328: }
-: 329:
|
5528: 330: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 331:
-: 332: /* ... end of body of routine ... */
-: 333:
|
5540: 334: fn_exit:
|
-: 335: MPID_MPI_COLL_FUNC_EXIT(MPID_STATE_MPI_SCATTERV);
|
5540: 336: MPIU_THREAD_CS_EXIT(ALLFUNC,);
5540: 337: return mpi_errno;
-: 338:
|
12: 339: fn_fail:
-: 340: /* --BEGIN ERROR HANDLING-- */
-: 341:# ifdef HAVE_ERROR_CHECKING
-: 342: {
12: 343: mpi_errno = MPIR_Err_create_code(
-: 344: mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_scatterv",
-: 345: "**mpi_scatterv %p %p %p %D %p %d %D %d %C", sendbuf, sendcnts, displs, sendtype,
-: 346: recvbuf, recvcnt, recvtype, root, comm);
-: 347: }
-: 348:# endif
12: 349: mpi_errno = MPIR_Err_return_comm( comm_ptr, FCNAME, mpi_errno );
12: 350: goto fn_exit;
-: 351: /* --END ERROR HANDLING-- */
-: 352:}
|