1 /*
2 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3 * University Research and Technology
4 * Corporation. All rights reserved.
5 * Copyright (c) 2004-2017 The University of Tennessee and The University
6 * of Tennessee Research Foundation. All rights
7 * reserved.
8 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9 * University of Stuttgart. All rights reserved.
10 * Copyright (c) 2004-2005 The Regents of the University of California.
11 * All rights reserved.
12 * Copyright (c) 2012 Oak Ridge National Labs. All rights reserved.
13 * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved.
14 * $COPYRIGHT$
15 *
16 * Additional copyrights may follow
17 *
18 * $HEADER$
19 */
20
21 #include "ompi_config.h"
22 #include "coll_basic.h"
23
24 #include "mpi.h"
25 #include "ompi/constants.h"
26 #include "opal/util/bit_ops.h"
27 #include "ompi/mca/pml/pml.h"
28 #include "ompi/mca/coll/coll.h"
29 #include "ompi/mca/coll/base/coll_tags.h"
30 #include "coll_basic.h"
31
32
33 /*
34 * barrier_intra_log
35 *
36 * Function: - barrier using O(log(N)) algorithm
37 * Accepts: - same as MPI_Barrier()
38 * Returns: - MPI_SUCCESS or error code
39 */
40 int
41 mca_coll_basic_barrier_intra_log(struct ompi_communicator_t *comm,
42 mca_coll_base_module_t *module)
43 {
44 int i;
45 int err;
46 int peer;
47 int dim;
48 int hibit;
49 int mask;
50 int size = ompi_comm_size(comm);
51 int rank = ompi_comm_rank(comm);
52
53 /* Send null-messages up and down the tree. Synchronization at the
54 * root (rank 0). */
55
56 dim = comm->c_cube_dim;
57 hibit = opal_hibit(rank, dim);
58 --dim;
59
60 /* Receive from children. */
61
62 for (i = dim, mask = 1 << i; i > hibit; --i, mask >>= 1) {
63 peer = rank | mask;
64 if (peer < size) {
65 err = MCA_PML_CALL(recv(NULL, 0, MPI_BYTE, peer,
66 MCA_COLL_BASE_TAG_BARRIER,
67 comm, MPI_STATUS_IGNORE));
68 if (MPI_SUCCESS != err) {
69 return err;
70 }
71 }
72 }
73
74 /* Send to and receive from parent. */
75
76 if (rank > 0) {
77 peer = rank & ~(1 << hibit);
78 err =
79 MCA_PML_CALL(send
80 (NULL, 0, MPI_BYTE, peer,
81 MCA_COLL_BASE_TAG_BARRIER,
82 MCA_PML_BASE_SEND_STANDARD, comm));
83 if (MPI_SUCCESS != err) {
84 return err;
85 }
86
87 err = MCA_PML_CALL(recv(NULL, 0, MPI_BYTE, peer,
88 MCA_COLL_BASE_TAG_BARRIER,
89 comm, MPI_STATUS_IGNORE));
90 if (MPI_SUCCESS != err) {
91 return err;
92 }
93 }
94
95 /* Send to children. */
96
97 for (i = hibit + 1, mask = 1 << i; i <= dim; ++i, mask <<= 1) {
98 peer = rank | mask;
99 if (peer < size) {
100 err = MCA_PML_CALL(send(NULL, 0, MPI_BYTE, peer,
101 MCA_COLL_BASE_TAG_BARRIER,
102 MCA_PML_BASE_SEND_STANDARD, comm));
103 if (MPI_SUCCESS != err) {
104 return err;
105 }
106 }
107 }
108
109 /* All done */
110
111 return MPI_SUCCESS;
112 }
113
114
115 /*
116 * barrier_inter_lin
117 *
118 * Function: - barrier using O(log(N)) algorithm
119 * Accepts: - same as MPI_Barrier()
120 * Returns: - MPI_SUCCESS or error code
121 */
122 int
123 mca_coll_basic_barrier_inter_lin(struct ompi_communicator_t *comm,
124 mca_coll_base_module_t *module)
125 {
126 int rank;
127 int result;
128
129 rank = ompi_comm_rank(comm);
130 return comm->c_coll->coll_allreduce(&rank, &result, 1, MPI_INT, MPI_MAX,
131 comm, comm->c_coll->coll_allreduce_module);
132 }