-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/coll/barrier.c
-: 0:Graph:barrier.gcno
-: 0:Data:barrier.gcda
-: 0:Runs:4383
-: 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_Barrier */
-: 11:#if defined(HAVE_PRAGMA_WEAK)
-: 12:#pragma weak MPI_Barrier = PMPI_Barrier
-: 13:#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
-: 14:#pragma _HP_SECONDARY_DEF PMPI_Barrier MPI_Barrier
-: 15:#elif defined(HAVE_PRAGMA_CRI_DUP)
-: 16:#pragma _CRI duplicate MPI_Barrier as PMPI_Barrier
-: 17:#endif
-: 18:/* -- End Profiling Symbol Block */
-: 19:
-: 20:PMPI_LOCAL int MPIR_Barrier_or_coll_fn(MPID_Comm *comm_ptr );
-: 21:
-: 22:/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
-: 23: the MPI routines */
-: 24:#ifndef MPICH_MPI_FROM_PMPI
-: 25:#undef MPI_Barrier
-: 26:#define MPI_Barrier PMPI_Barrier
-: 27:
-: 28:
-: 29:/* This is the default implementation of the barrier operation. The
-: 30: algorithm is:
-: 31:
-: 32: Algorithm: MPI_Barrier
-: 33:
-: 34: We use the dissemination algorithm described in:
-: 35: Debra Hensgen, Raphael Finkel, and Udi Manbet, "Two Algorithms for
-: 36: Barrier Synchronization," International Journal of Parallel
-: 37: Programming, 17(1):1-17, 1988.
-: 38:
-: 39: It uses ceiling(lgp) steps. In step k, 0 <= k <= (ceiling(lgp)-1),
-: 40: process i sends to process (i + 2^k) % p and receives from process
-: 41: (i - 2^k + p) % p.
-: 42:
-: 43: Possible improvements:
-: 44:
-: 45: End Algorithm: MPI_Barrier
-: 46:
-: 47: This is an intracommunicator barrier only!
-: 48:*/
-: 49:
-: 50:/* not declared static because it is called in ch3_comm_connect/accept */
-: 51:#undef FUNCNAME
-: 52:#define FUNCNAME MPIR_Barrier
-: 53:#undef FCNAME
-: 54:#define FCNAME MPIU_QUOTE(FUNCNAME)
-: 55:int MPIR_Barrier( MPID_Comm *comm_ptr )
946810: 56:{
946810: 57: int size, rank, src, dst, mask, mpi_errno=MPI_SUCCESS;
-: 58: MPI_Comm comm;
-: 59:
946810: 60: size = comm_ptr->local_size;
-: 61: /* Trivial barriers return immediately */
946810: 62: if (size == 1) return MPI_SUCCESS;
-: 63:
718973: 64: rank = comm_ptr->rank;
718973: 65: comm = comm_ptr->handle;
-: 66:
-: 67: /* Only one collective operation per communicator can be active at any
-: 68: time */
-: 69: MPIDU_ERR_CHECK_MULTIPLE_THREADS_ENTER( comm_ptr );
-: 70:
718973: 71: mask = 0x1;
3126725: 72: while (mask < size) {
1688781: 73: dst = (rank + mask) % size;
1688781: 74: src = (rank - mask + size) % size;
1688781: 75: mpi_errno = MPIC_Sendrecv(NULL, 0, MPI_BYTE, dst,
-: 76: MPIR_BARRIER_TAG, NULL, 0, MPI_BYTE,
-: 77: src, MPIR_BARRIER_TAG, comm,
-: 78: MPI_STATUS_IGNORE);
|
-: 79: /* --BEGIN ERROR HANDLING-- */
1688781: 80: if (mpi_errno)
-: 81: {
2: 82: mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0);
2: 83: return mpi_errno;
-: 84: }
-: 85: /* --END ERROR HANDLING-- */
|
1688779: 86: mask <<= 1;
-: 87: }
-: 88:
-: 89: MPIDU_ERR_CHECK_MULTIPLE_THREADS_EXIT( comm_ptr );
-: 90:
718971: 91: return mpi_errno;
-: 92:}
-: 93:
-: 94:
-: 95:#if 0
-: 96:
-: 97:/* This is the default implementation of the barrier operation. The
-: 98: algorithm is:
-: 99:
-: 100: Algorithm: MPI_Barrier
-: 101:
-: 102: Find the largest power of two that is less than or equal to the size of
-: 103: the communicator. Call tbis twon_within.
-: 104:
-: 105: Divide the communicator by rank into two groups: those with
-: 106: rank < twon_within and those with greater rank. The barrier
-: 107: executes in three steps. First, the group with rank >= twon_within
-: 108: sends to the first (size-twon_within) ranks of the first group.
-: 109: That group then executes a recursive doubling algorithm for the barrier.
-: 110: For the third step, the first (size-twon_within) ranks send to the top
-: 111: group. This is the same algorithm used in MPICH-1.
-: 112:
-: 113: Possible improvements:
-: 114: The upper group could apply recursively this approach to reduce the
-: 115: total number of messages sent (in the case of of a size of 2^n-1, there
-: 116: are 2^(n-1) messages sent in the first and third steps).
-: 117:
-: 118: End Algorithm: MPI_Barrier
-: 119:
-: 120: This is an intracommunicator barrier only!
-: 121:*/
-: 122:int MPIR_Barrier( MPID_Comm *comm_ptr )
-: 123:{
-: 124: int size, rank;
-: 125: int twon_within, n2, remaining, gap, partner;
-: 126: MPID_Request *request_ptr;
-: 127: int mpi_errno = MPI_SUCCESS;
-: 128:
-: 129: size = comm_ptr->remote_size;
-: 130: rank = comm_ptr->rank;
-: 131:
-: 132: /* Trivial barriers return immediately */
-: 133: if (size == 1) return MPI_SUCCESS;
-: 134:
-: 135: /* Only one collective operation per communicator can be active at any
-: 136: time */
-: 137: MPIDU_ERR_CHECK_MULTIPLE_THREADS_ENTER( comm_ptr );
-: 138:
-: 139: /* Find the twon_within (this could be cached if more routines
-: 140: need it) */
-: 141: twon_within = 1;
-: 142: n2 = 2;
-: 143: while (n2 <= size) { twon_within = n2; n2 <<= 1; }
-: 144: remaining = size - twon_within;
-: 145:
-: 146: if (rank < twon_within) {
-: 147: /* First step: receive from the upper group */
-: 148: if (rank < remaining) {
-: 149: MPID_Recv( 0, 0, MPI_BYTE, twon_within + rank, MPIR_BARRIER_TAG,
-: 150: comm_ptr, MPID_CONTEXT_INTRA_COLL, MPI_STATUS_IGNORE,
-: 151: &request_ptr );
-: 152: if (request_ptr) {
-: 153: mpi_errno = MPIC_Wait(request_ptr);
-: 154: MPID_Request_release(request_ptr);
|
-: 155: /* --BEGIN ERROR HANDLING-- */
-: 156: if (mpi_errno != MPI_SUCCESS)
-: 157: {
-: 158: goto fn_exit;
-: 159: }
-: 160: /* --END ERROR HANDLING-- */
-: 161: }
-: 162: }
-: 163: /* Second step: recursive doubling exchange */
-: 164: for (gap=1; gap<twon_within; gap <<= 1) {
-: 165: partner = (rank ^ gap);
-: 166: MPIC_Sendrecv( 0, 0, MPI_BYTE, partner, MPIR_BARRIER_TAG,
-: 167: 0, 0, MPI_BYTE, partner, MPIR_BARRIER_TAG,
-: 168: comm_ptr->handle, MPI_STATUS_IGNORE );
-: 169: }
-: 170:
-: 171: /* Third step: send to the upper group */
-: 172: if (rank < remaining) {
-: 173: MPID_Send( 0, 0, MPI_BYTE, rank + twon_within, MPIR_BARRIER_TAG,
-: 174: comm_ptr, MPID_CONTEXT_INTRA_COLL, &request_ptr );
-: 175: if (request_ptr) {
-: 176: mpi_errno = MPIC_Wait(request_ptr);
-: 177: MPID_Request_release(request_ptr);
-: 178: /* --BEGIN ERROR HANDLING-- */
-: 179: if (mpi_errno != MPI_SUCCESS)
-: 180: {
-: 181: goto fn_exit;
-: 182: }
-: 183: /* --END ERROR HANDLING-- */
-: 184: }
-: 185: }
-: 186: }
-: 187: else {
-: 188: /* For the upper group, step one is a send */
-: 189: MPID_Send( 0, 0, MPI_BYTE, rank - twon_within, MPIR_BARRIER_TAG,
-: 190: comm_ptr, MPID_CONTEXT_INTRA_COLL, &request_ptr );
-: 191: if (request_ptr) {
-: 192: mpi_errno = MPIC_Wait(request_ptr);
-: 193: MPID_Request_release(request_ptr);
-: 194: /* --BEGIN ERROR HANDLING-- */
-: 195: if (mpi_errno != MPI_SUCCESS)
-: 196: {
-: 197: goto fn_exit;
-: 198: }
-: 199: /* --END ERROR HANDLING-- */
-: 200: }
-: 201: /* There is no second step; for the third step, recv */
-: 202: MPID_Recv( 0, 0, MPI_BYTE, rank - twon_within, MPIR_BARRIER_TAG,
-: 203: comm_ptr, MPID_CONTEXT_INTRA_COLL, MPI_STATUS_IGNORE,
-: 204: &request_ptr );
-: 205: if (request_ptr) {
-: 206: mpi_errno = MPIC_Wait(request_ptr);
-: 207: MPID_Request_release(request_ptr);
-: 208: /* --BEGIN ERROR HANDLING-- */
-: 209: if (mpi_errno != MPI_SUCCESS)
-: 210: {
-: 211: goto fn_exit;
-: 212: }
-: 213: /* --END ERROR HANDLING-- */
-: 214: }
-: 215: }
-: 216:
-: 217: fn_exit:
-: 218: MPIDU_ERR_CHECK_MULTIPLE_THREADS_EXIT( comm_ptr );
-: 219:
-: 220: return mpi_errno;
-: 221:}
-: 222:#endif
-: 223:
-: 224:
-: 225:/* A simple utility function to that calls the comm_ptr->coll_fns->Barrier
-: 226:override if it exists or else it calls MPIR_Barrier with the same arguments. */
-: 227:/* Note that this function must *not* be inline - if weak symbols are not
-: 228: available, this function must be a global symbol. */
-: 229:#undef FUNCNAME
-: 230:#define FUNCNAME MPIR_Barrier_or_coll_fn
-: 231:#undef FCNAME
-: 232:#define FCNAME MPIU_QUOTE(FUNCNAME)
-: 233:PMPI_LOCAL int MPIR_Barrier_or_coll_fn(MPID_Comm *comm_ptr )
|
911416: 234:{
911416: 235: int mpi_errno = MPI_SUCCESS;
-: 236:
911416: 237: if (comm_ptr->coll_fns != NULL && comm_ptr->coll_fns->Barrier != NULL)
-: 238: {
|
-: 239: /* --BEGIN USEREXTENSION-- */
#####: 240: mpi_errno = comm_ptr->node_roots_comm->coll_fns->Barrier(comm_ptr);
-: 241: /* --END USEREXTENSION-- */
-: 242: }
-: 243: else {
|
911416: 244: mpi_errno = MPIR_Barrier(comm_ptr);
-: 245: }
-: 246:
911416: 247: return mpi_errno;
-: 248:}
-: 249:
-: 250:
-: 251:/* not declared static because a machine-specific function may call this one
-: 252: in some cases */
-: 253:#undef FUNCNAME
-: 254:#define FUNCNAME MPIR_Barrier_inter
-: 255:#undef FCNAME
-: 256:#define FCNAME MPIU_QUOTE(FUNCNAME)
-: 257:int MPIR_Barrier_inter( MPID_Comm *comm_ptr )
114: 258:{
-: 259: int rank, mpi_errno, i, root;
114: 260: MPID_Comm *newcomm_ptr = NULL;
-: 261:
114: 262: rank = comm_ptr->rank;
-: 263:
-: 264: /* Get the local intracommunicator */
114: 265: if (!comm_ptr->local_comm)
114: 266: MPIR_Setup_intercomm_localcomm( comm_ptr );
-: 267:
114: 268: newcomm_ptr = comm_ptr->local_comm;
-: 269:
-: 270: /* do a barrier on the local intracommunicator */
114: 271: mpi_errno = MPIR_Barrier(newcomm_ptr);
|
-: 272: /* --BEGIN ERROR HANDLING-- */
114: 273: if (mpi_errno)
-: 274: {
#####: 275: mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0);
#####: 276: return mpi_errno;
-: 277: }
-: 278: /* --END ERROR HANDLING-- */
-: 279:
-: 280: /* rank 0 on each group does an intercommunicator broadcast to the
-: 281: remote group to indicate that all processes in the local group
-: 282: have reached the barrier. We do a 1-byte bcast because a 0-byte
-: 283: bcast will just return without doing anything. */
-: 284:
-: 285: /* first broadcast from left to right group, then from right to
-: 286: left group */
|
114: 287: if (comm_ptr->is_low_group) {
-: 288: /* bcast to right*/
45: 289: root = (rank == 0) ? MPI_ROOT : MPI_PROC_NULL;
45: 290: mpi_errno = MPIR_Bcast_inter(&i, 1, MPI_BYTE, root, comm_ptr);
|
-: 291: /* --BEGIN ERROR HANDLING-- */
45: 292: if (mpi_errno)
-: 293: {
#####: 294: mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0);
#####: 295: return mpi_errno;
-: 296: }
-: 297: /* --END ERROR HANDLING-- */
-: 298: /* receive bcast from right */
|
45: 299: root = 0;
45: 300: mpi_errno = MPIR_Bcast_inter(&i, 1, MPI_BYTE, root, comm_ptr);
|
-: 301: /* --BEGIN ERROR HANDLING-- */
45: 302: if (mpi_errno)
-: 303: {
#####: 304: mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0);
#####: 305: return mpi_errno;
-: 306: }
-: 307: /* --END ERROR HANDLING-- */
-: 308: }
-: 309: else {
-: 310: /* receive bcast from left */
|
69: 311: root = 0;
69: 312: mpi_errno = MPIR_Bcast_inter(&i, 1, MPI_BYTE, root, comm_ptr);
|
-: 313: /* --BEGIN ERROR HANDLING-- */
69: 314: if (mpi_errno)
-: 315: {
#####: 316: mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0);
#####: 317: return mpi_errno;
-: 318: }
-: 319: /* --END ERROR HANDLING-- */
-: 320: /* bcast to left */
|
69: 321: root = (rank == 0) ? MPI_ROOT : MPI_PROC_NULL;
69: 322: mpi_errno = MPIR_Bcast_inter(&i, 1, MPI_BYTE, root, comm_ptr);
|
-: 323: /* --BEGIN ERROR HANDLING-- */
69: 324: if (mpi_errno)
-: 325: {
#####: 326: mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0);
#####: 327: return mpi_errno;
-: 328: }
-: 329: /* --END ERROR HANDLING-- */
-: 330: }
-: 331:
|
114: 332: return mpi_errno;
-: 333:}
-: 334:
-: 335:#endif
-: 336:
-: 337:
-: 338:#undef FUNCNAME
-: 339:#define FUNCNAME MPI_Barrier
-: 340:#undef FCNAME
-: 341:#define FCNAME MPIU_QUOTE(FUNCNAME)
-: 342:
-: 343:/*@
-: 344:
-: 345:MPI_Barrier - Blocks until all processes in the communicator have
-: 346:reached this routine.
-: 347:
-: 348:Input Parameter:
-: 349:. comm - communicator (handle)
-: 350:
-: 351:Notes:
-: 352:Blocks the caller until all processes in the communicator have called it;
-: 353:that is, the call returns at any process only after all members of the
-: 354:communicator have entered the call.
-: 355:
-: 356:.N ThreadSafe
-: 357:
-: 358:.N Fortran
-: 359:
-: 360:.N Errors
-: 361:.N MPI_SUCCESS
-: 362:.N MPI_ERR_COMM
-: 363:@*/
-: 364:int MPI_Barrier( MPI_Comm comm )
744853: 365:{
744853: 366: int mpi_errno = MPI_SUCCESS;
744853: 367: MPID_Comm *comm_ptr = NULL;
744853: 368: MPIU_THREADPRIV_DECL;
-: 369: MPID_MPI_STATE_DECL(MPID_STATE_MPI_BARRIER);
-: 370:
744853: 371: MPIR_ERRTEST_INITIALIZED_ORDIE();
-: 372:
744851: 373: MPIU_THREAD_CS_ENTER(ALLFUNC,);
-: 374: MPID_MPI_COLL_FUNC_ENTER(MPID_STATE_MPI_BARRIER);
-: 375:
-: 376: /* Validate parameters, especially handles needing to be converted */
|
-: 377:# ifdef HAVE_ERROR_CHECKING
-: 378: {
-: 379: MPID_BEGIN_ERROR_CHECKS;
-: 380: {
744851: 381: MPIR_ERRTEST_COMM(comm, mpi_errno);
744851: 382: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 383: }
-: 384: MPID_END_ERROR_CHECKS;
-: 385: }
-: 386:# endif /* HAVE_ERROR_CHECKING */
-: 387:
-: 388: /* Convert MPI object handles to object pointers */
|
744843: 389: MPID_Comm_get_ptr( comm, comm_ptr );
-: 390:
-: 391: /* Validate parameters and objects (post conversion) */
|
-: 392:# ifdef HAVE_ERROR_CHECKING
-: 393: {
-: 394: MPID_BEGIN_ERROR_CHECKS;
-: 395: {
-: 396: /* Validate communicator */
744843: 397: MPID_Comm_valid_ptr( comm_ptr, mpi_errno );
744843: 398: if (mpi_errno) goto fn_fail;
-: 399: }
-: 400: MPID_END_ERROR_CHECKS;
-: 401: }
-: 402:# endif /* HAVE_ERROR_CHECKING */
-: 403:
-: 404: /* ... body of routine ... */
-: 405:
|
744837: 406: if (comm_ptr->coll_fns != NULL && comm_ptr->coll_fns->Barrier != NULL)
-: 407: {
|
#####: 408: mpi_errno = comm_ptr->coll_fns->Barrier(comm_ptr);
-: 409: }
-: 410: else
-: 411: {
|
744837: 412: MPIU_THREADPRIV_GET;
744837: 413: MPIR_Nest_incr();
744837: 414: if (comm_ptr->comm_kind == MPID_INTRACOMM) {
-: 415:#if defined(USE_SMP_COLLECTIVES)
744723: 416: if (MPIR_Comm_is_node_aware(comm_ptr)) {
-: 417:
-: 418: /* do the intranode barrier on all nodes */
714849: 419: if (comm_ptr->node_comm != NULL)
-: 420: {
714849: 421: mpi_errno = MPIR_Barrier_or_coll_fn(comm_ptr->node_comm);
714849: 422: if (mpi_errno) {
2: 423: MPIR_Nest_decr();
|
2: 424: goto fn_fail;
-: 425: }
-: 426: }
-: 427:
-: 428: /* do the barrier across roots of all nodes */
|
714847: 429: if (comm_ptr->node_roots_comm != NULL) {
196567: 430: mpi_errno = MPIR_Barrier_or_coll_fn(comm_ptr->node_roots_comm);
196567: 431: if (mpi_errno) {
|
#####: 432: MPIR_Nest_decr();
|
#####: 433: goto fn_fail;
-: 434: }
-: 435: }
-: 436:
-: 437: /* release the local processes on each node with a 1-byte broadcast
-: 438: (0-byte broadcast just returns without doing anything) */
|
714847: 439: if (comm_ptr->node_comm != NULL)
-: 440: {
714847: 441: int i=0;
714847: 442: mpi_errno = MPIR_Bcast_or_coll_fn(&i, 1, MPI_BYTE, 0,
-: 443: comm_ptr->node_comm);
-: 444: }
-: 445: }
-: 446: else {
29874: 447: mpi_errno = MPIR_Barrier( comm_ptr );
-: 448: }
-: 449:#else
-: 450: mpi_errno = MPIR_Barrier( comm_ptr );
-: 451:#endif
-: 452: }
-: 453: else {
-: 454: /* intercommunicator */
114: 455: mpi_errno = MPIR_Barrier_inter( comm_ptr );
-: 456: }
744835: 457: MPIR_Nest_decr();
-: 458: }
-: 459:
|
-: 460: /* --BEGIN ERROR HANDLING-- */
744835: 461: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 462: /* --END ERROR HANDLING-- */
-: 463:
-: 464: /* ... end of body of routine ... */
-: 465:
|
744849: 466: fn_exit:
|
-: 467: MPID_MPI_COLL_FUNC_EXIT(MPID_STATE_MPI_BARRIER);
|
744849: 468: MPIU_THREAD_CS_EXIT(ALLFUNC,);
744849: 469: return mpi_errno;
-: 470:
|
16: 471: fn_fail:
-: 472: /* --BEGIN ERROR HANDLING-- */
-: 473:# ifdef HAVE_ERROR_CHECKING
-: 474: {
16: 475: mpi_errno = MPIR_Err_create_code(
-: 476: mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER,
-: 477: "**mpi_barrier", "**mpi_barrier %C", comm);
-: 478: }
-: 479:# endif
16: 480: mpi_errno = MPIR_Err_return_comm( comm_ptr, FCNAME, mpi_errno );
14: 481: goto fn_exit;
-: 482: /* --END ERROR HANDLING-- */
-: 483:}
|