~ubuntu-branches/ubuntu/vivid/mpich/vivid-proposed

« back to all changes in this revision

Viewing changes to src/mpi/coll/barrier.c

  • Committer: Package Import Robot
  • Author(s): Anton Gladky
  • Date: 2014-04-01 20:24:20 UTC
  • mfrom: (5.2.4 sid)
  • Revision ID: package-import@ubuntu.com-20140401202420-t5ey1ia2klt5dkq3
Tags: 3.1-4
* [c3e3398] Disable test_primitives, which is unreliable on some platforms.
            (Closes: #743047)
* [265a699] Add minimal autotest.

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 
8
8
#include "mpiimpl.h"
9
9
 
 
10
/*
 
11
=== BEGIN_MPI_T_CVAR_INFO_BLOCK ===
 
12
 
 
13
cvars:
 
14
    - name        : MPIR_CVAR_ENABLE_SMP_BARRIER
 
15
      category    : COLLECTIVE
 
16
      type        : boolean
 
17
      default     : true
 
18
      class       : device
 
19
      verbosity   : MPI_T_VERBOSITY_USER_BASIC
 
20
      scope       : MPI_T_SCOPE_ALL_EQ
 
21
      description : Enable SMP aware barrier.
 
22
 
 
23
=== END_MPI_T_CVAR_INFO_BLOCK ===
 
24
*/
 
25
 
10
26
/* -- Begin Profiling Symbol Block for routine MPI_Barrier */
11
27
#if defined(HAVE_PRAGMA_WEAK)
12
28
#pragma weak MPI_Barrier = PMPI_Barrier
17
33
#endif
18
34
/* -- End Profiling Symbol Block */
19
35
 
20
 
PMPI_LOCAL int MPIR_Barrier_or_coll_fn(MPID_Comm *comm_ptr, int *errflag );
21
 
 
22
36
/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
23
37
   the MPI routines */
24
38
#ifndef MPICH_MPI_FROM_PMPI
47
61
   This is an intracommunicator barrier only!
48
62
*/
49
63
 
 
64
#undef FUNCNAME
 
65
#define FUNCNAME barrier_smp_intra
 
66
#undef FCNAME
 
67
#define FCNAME MPIU_QUOTE(FUNCNAME)
 
68
static int barrier_smp_intra(MPID_Comm *comm_ptr, int *errflag)
 
69
{
 
70
    int mpi_errno=MPI_SUCCESS;
 
71
    int mpi_errno_ret = MPI_SUCCESS;
 
72
 
 
73
    MPIU_Assert(MPIR_CVAR_ENABLE_SMP_COLLECTIVES && MPIR_CVAR_ENABLE_SMP_BARRIER &&
 
74
                MPIR_Comm_is_node_aware(comm_ptr));
 
75
 
 
76
    /* do the intranode barrier on all nodes */
 
77
    if (comm_ptr->node_comm != NULL)
 
78
    {
 
79
        mpi_errno = MPIR_Barrier_impl(comm_ptr->node_comm, errflag);
 
80
        if (mpi_errno) {
 
81
            /* for communication errors, just record the error but continue */
 
82
            *errflag = TRUE;
 
83
            MPIU_ERR_SET(mpi_errno, MPI_ERR_OTHER, "**fail");
 
84
            MPIU_ERR_ADD(mpi_errno_ret, mpi_errno);
 
85
        }
 
86
    }
 
87
 
 
88
    /* do the barrier across roots of all nodes */
 
89
    if (comm_ptr->node_roots_comm != NULL) {
 
90
        mpi_errno = MPIR_Barrier_impl(comm_ptr->node_roots_comm, errflag);
 
91
        if (mpi_errno) {
 
92
            /* for communication errors, just record the error but continue */
 
93
            *errflag = TRUE;
 
94
            MPIU_ERR_SET(mpi_errno, MPI_ERR_OTHER, "**fail");
 
95
            MPIU_ERR_ADD(mpi_errno_ret, mpi_errno);
 
96
        }
 
97
    }
 
98
 
 
99
    /* release the local processes on each node with a 1-byte
 
100
       broadcast (0-byte broadcast just returns without doing
 
101
       anything) */
 
102
    if (comm_ptr->node_comm != NULL)
 
103
    {
 
104
        int i=0;
 
105
        mpi_errno = MPIR_Bcast_impl(&i, 1, MPI_BYTE, 0, comm_ptr->node_comm, errflag);
 
106
        if (mpi_errno) {
 
107
            /* for communication errors, just record the error but continue */
 
108
            *errflag = TRUE;
 
109
            MPIU_ERR_SET(mpi_errno, MPI_ERR_OTHER, "**fail");
 
110
            MPIU_ERR_ADD(mpi_errno_ret, mpi_errno);
 
111
        }
 
112
    }
 
113
 
 
114
 fn_exit:
 
115
    if (mpi_errno_ret)
 
116
        mpi_errno = mpi_errno_ret;
 
117
    else if (*errflag)
 
118
        MPIU_ERR_SET(mpi_errno, MPI_ERR_OTHER, "**coll_fail");
 
119
    return mpi_errno;
 
120
 fn_fail:
 
121
    goto fn_exit;
 
122
}
 
123
 
50
124
/* not declared static because it is called in ch3_comm_connect/accept */
51
125
#undef FUNCNAME
52
126
#define FUNCNAME MPIR_Barrier_intra
66
140
    /* Trivial barriers return immediately */
67
141
    if (size == 1) goto fn_exit;
68
142
 
 
143
    if (MPIR_CVAR_ENABLE_SMP_COLLECTIVES && MPIR_CVAR_ENABLE_SMP_BARRIER &&
 
144
        MPIR_Comm_is_node_aware(comm_ptr)) {
 
145
        mpi_errno = barrier_smp_intra(comm_ptr, errflag);
 
146
        if (mpi_errno) {
 
147
            /* for communication errors, just record the error but continue */
 
148
            *errflag = TRUE;
 
149
            MPIU_ERR_SET(mpi_errno, MPI_ERR_OTHER, "**fail");
 
150
            MPIU_ERR_ADD(mpi_errno_ret, mpi_errno);
 
151
        }
 
152
        goto fn_exit;
 
153
    }
 
154
 
69
155
    rank = comm_ptr->rank;
70
156
    comm = comm_ptr->handle;
71
157
 
73
159
    while (mask < size) {
74
160
        dst = (rank + mask) % size;
75
161
        src = (rank - mask + size) % size;
76
 
        mpi_errno = MPIC_Sendrecv_ft(NULL, 0, MPI_BYTE, dst,
 
162
        mpi_errno = MPIC_Sendrecv(NULL, 0, MPI_BYTE, dst,
77
163
                                     MPIR_BARRIER_TAG, NULL, 0, MPI_BYTE,
78
164
                                     src, MPIR_BARRIER_TAG, comm,
79
165
                                     MPI_STATUS_IGNORE, errflag);
97
183
    goto fn_exit;
98
184
}
99
185
 
100
 
/* A simple utility function to that calls the comm_ptr->coll_fns->Barrier
101
 
override if it exists or else it calls MPIR_Barrier_intra with the same arguments. */
102
 
/* Note that this function must *not* be inline - if weak symbols are not 
103
 
   available, this function must be a global symbol. */
104
 
#undef FUNCNAME
105
 
#define FUNCNAME MPIR_Barrier_or_coll_fn
106
 
#undef FCNAME
107
 
#define FCNAME MPIU_QUOTE(FUNCNAME)
108
 
PMPI_LOCAL int MPIR_Barrier_or_coll_fn(MPID_Comm *comm_ptr, int *errflag )
109
 
{
110
 
    int mpi_errno = MPI_SUCCESS;
111
 
 
112
 
    if (comm_ptr->coll_fns != NULL && comm_ptr->coll_fns->Barrier != NULL)
113
 
    {
114
 
        /* --BEGIN USEREXTENSION-- */
115
 
        mpi_errno = comm_ptr->coll_fns->Barrier(comm_ptr, errflag);
116
 
        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
117
 
        /* --END USEREXTENSION-- */
118
 
    }
119
 
    else {
120
 
        mpi_errno = MPIR_Barrier_intra(comm_ptr, errflag);
121
 
        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
122
 
    }
123
 
 
124
 
 fn_exit:
125
 
    return mpi_errno;
126
 
 fn_fail:
127
 
    goto fn_exit;
128
 
}
129
 
 
130
 
 
131
186
/* not declared static because a machine-specific function may call this one 
132
187
   in some cases */
133
188
#undef FUNCNAME
269
324
    }
270
325
    else
271
326
    {
272
 
        if (comm_ptr->comm_kind == MPID_INTRACOMM) {
273
 
#if defined(USE_SMP_COLLECTIVES)
274
 
            if (MPIR_Comm_is_node_aware(comm_ptr)) {
275
 
 
276
 
                /* do the intranode barrier on all nodes */
277
 
                if (comm_ptr->node_comm != NULL)
278
 
                {
279
 
                    mpi_errno = MPIR_Barrier_or_coll_fn(comm_ptr->node_comm, errflag);
280
 
                    if (mpi_errno) {
281
 
                        /* for communication errors, just record the error but continue */
282
 
                        *errflag = TRUE;
283
 
                        MPIU_ERR_SET(mpi_errno, MPI_ERR_OTHER, "**fail");
284
 
                        MPIU_ERR_ADD(mpi_errno_ret, mpi_errno);
285
 
                    }
286
 
                }
287
 
 
288
 
                /* do the barrier across roots of all nodes */
289
 
                if (comm_ptr->node_roots_comm != NULL) {
290
 
                    mpi_errno = MPIR_Barrier_or_coll_fn(comm_ptr->node_roots_comm, errflag);
291
 
                    if (mpi_errno) {
292
 
                        /* for communication errors, just record the error but continue */
293
 
                        *errflag = TRUE;
294
 
                        MPIU_ERR_SET(mpi_errno, MPI_ERR_OTHER, "**fail");
295
 
                        MPIU_ERR_ADD(mpi_errno_ret, mpi_errno);
296
 
                    }
297
 
                }
298
 
 
299
 
                /* release the local processes on each node with a 1-byte broadcast
300
 
                   (0-byte broadcast just returns without doing anything) */
301
 
                if (comm_ptr->node_comm != NULL)
302
 
                {
303
 
                    int i=0;
304
 
                    mpi_errno = MPIR_Bcast_impl(&i, 1, MPI_BYTE, 0, comm_ptr->node_comm, errflag);
305
 
                    if (mpi_errno) {
306
 
                        /* for communication errors, just record the error but continue */
307
 
                        *errflag = TRUE;
308
 
                        MPIU_ERR_SET(mpi_errno, MPI_ERR_OTHER, "**fail");
309
 
                        MPIU_ERR_ADD(mpi_errno_ret, mpi_errno);
310
 
                    }
311
 
                }
312
 
            }
313
 
            else {
314
 
                mpi_errno = MPIR_Barrier_intra( comm_ptr, errflag );
315
 
                if (mpi_errno) MPIU_ERR_POP(mpi_errno);
316
 
            }
317
 
#else
318
 
            mpi_errno = MPIR_Barrier_intra( comm_ptr, errflag );
319
 
            if (mpi_errno) MPIU_ERR_POP(mpi_errno);
320
 
#endif
321
 
        }
322
 
        else {
323
 
            /* intercommunicator */ 
324
 
            mpi_errno = MPIR_Barrier_inter( comm_ptr, errflag );
325
 
            if (mpi_errno) MPIU_ERR_POP(mpi_errno);
326
 
        }
 
327
        mpi_errno = MPIR_Barrier(comm_ptr, errflag);
 
328
        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
327
329
    }
328
330
        
329
331
 fn_exit: