updating repository. Removing .Plo and .Po files that are generated automatically
[openmpi-llc.git] / ompi / mca / coll / basic / coll_basic_bcast.c
blob25d36f0f123af9851f94a01ae6e6cb5ea1efd678
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-2005 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$
14 * Additional copyrights may follow
16 * $HEADER$
19 #include "ompi_config.h"
20 #include "coll_basic.h"
22 #include "mpi.h"
23 #include "ompi/constants.h"
24 #include "ompi/datatype/datatype.h"
25 #include "ompi/mca/coll/coll.h"
26 #include "ompi/mca/coll/base/coll_tags.h"
27 #include "coll_basic.h"
28 #include "ompi/mca/pml/pml.h"
29 #include "opal/util/bit_ops.h"
33 * bcast_lin_intra
35 * Function: - broadcast using O(N) algorithm
36 * Accepts: - same arguments as MPI_Bcast()
37 * Returns: - MPI_SUCCESS or error code
39 int
40 mca_coll_basic_bcast_lin_intra(void *buff, int count,
41 struct ompi_datatype_t *datatype, int root,
42 struct ompi_communicator_t *comm)
44 int i;
45 int size;
46 int rank;
47 int err;
48 ompi_request_t **preq;
49 ompi_request_t **reqs = comm->c_coll_basic_data->mccb_reqs;
51 size = ompi_comm_size(comm);
52 rank = ompi_comm_rank(comm);
54 /* Non-root receive the data. */
56 if (rank != root) {
57 return MCA_PML_CALL(recv(buff, count, datatype, root,
58 MCA_COLL_BASE_TAG_BCAST, comm,
59 MPI_STATUS_IGNORE));
62 /* Root sends data to all others. */
64 for (i = 0, preq = reqs; i < size; ++i) {
65 if (i == rank) {
66 continue;
69 err = MCA_PML_CALL(isend_init(buff, count, datatype, i,
70 MCA_COLL_BASE_TAG_BCAST,
71 MCA_PML_BASE_SEND_STANDARD,
72 comm, preq++));
73 if (MPI_SUCCESS != err) {
74 return err;
77 --i;
79 /* Start your engines. This will never return an error. */
81 MCA_PML_CALL(start(i, reqs));
83 /* Wait for them all. If there's an error, note that we don't
84 * care what the error was -- just that there *was* an error. The
85 * PML will finish all requests, even if one or more of them fail.
86 * i.e., by the end of this call, all the requests are free-able.
87 * So free them anyway -- even if there was an error, and return
88 * the error after we free everything. */
90 err = ompi_request_wait_all(i, reqs, MPI_STATUSES_IGNORE);
92 /* Free the reqs */
94 mca_coll_basic_free_reqs(reqs, i);
96 /* All done */
98 return err;
103 * bcast_log_intra
105 * Function: - broadcast using O(log(N)) algorithm
106 * Accepts: - same arguments as MPI_Bcast()
107 * Returns: - MPI_SUCCESS or error code
110 mca_coll_basic_bcast_log_intra(void *buff, int count,
111 struct ompi_datatype_t *datatype, int root,
112 struct ompi_communicator_t *comm)
114 int i;
115 int size;
116 int rank;
117 int vrank;
118 int peer;
119 int dim;
120 int hibit;
121 int mask;
122 int err;
123 int nreqs;
124 ompi_request_t **preq;
125 ompi_request_t **reqs = comm->c_coll_basic_data->mccb_reqs;
127 size = ompi_comm_size(comm);
128 rank = ompi_comm_rank(comm);
129 vrank = (rank + size - root) % size;
131 dim = comm->c_cube_dim;
132 hibit = opal_hibit(vrank, dim);
133 --dim;
135 /* Receive data from parent in the tree. */
137 if (vrank > 0) {
138 peer = ((vrank & ~(1 << hibit)) + root) % size;
140 err = MCA_PML_CALL(recv(buff, count, datatype, peer,
141 MCA_COLL_BASE_TAG_BCAST,
142 comm, MPI_STATUS_IGNORE));
143 if (MPI_SUCCESS != err) {
144 return err;
148 /* Send data to the children. */
150 err = MPI_SUCCESS;
151 preq = reqs;
152 nreqs = 0;
153 for (i = hibit + 1, mask = 1 << i; i <= dim; ++i, mask <<= 1) {
154 peer = vrank | mask;
155 if (peer < size) {
156 peer = (peer + root) % size;
157 ++nreqs;
159 err = MCA_PML_CALL(isend_init(buff, count, datatype, peer,
160 MCA_COLL_BASE_TAG_BCAST,
161 MCA_PML_BASE_SEND_STANDARD,
162 comm, preq++));
163 if (MPI_SUCCESS != err) {
164 mca_coll_basic_free_reqs(reqs, preq - reqs);
165 return err;
170 /* Start and wait on all requests. */
172 if (nreqs > 0) {
174 /* Start your engines. This will never return an error. */
176 MCA_PML_CALL(start(nreqs, reqs));
178 /* Wait for them all. If there's an error, note that we don't
179 * care what the error was -- just that there *was* an error.
180 * The PML will finish all requests, even if one or more of them
181 * fail. i.e., by the end of this call, all the requests are
182 * free-able. So free them anyway -- even if there was an
183 * error, and return the error after we free everything. */
185 err = ompi_request_wait_all(nreqs, reqs, MPI_STATUSES_IGNORE);
187 /* Free the reqs */
189 mca_coll_basic_free_reqs(reqs, nreqs);
192 /* All done */
194 return err;
199 * bcast_lin_inter
201 * Function: - broadcast using O(N) algorithm
202 * Accepts: - same arguments as MPI_Bcast()
203 * Returns: - MPI_SUCCESS or error code
206 mca_coll_basic_bcast_lin_inter(void *buff, int count,
207 struct ompi_datatype_t *datatype, int root,
208 struct ompi_communicator_t *comm)
210 int i;
211 int rsize;
212 int rank;
213 int err;
214 ompi_request_t **reqs = comm->c_coll_basic_data->mccb_reqs;
216 rsize = ompi_comm_remote_size(comm);
217 rank = ompi_comm_rank(comm);
219 if (MPI_PROC_NULL == root) {
220 /* do nothing */
221 err = OMPI_SUCCESS;
222 } else if (MPI_ROOT != root) {
223 /* Non-root receive the data. */
224 err = MCA_PML_CALL(recv(buff, count, datatype, root,
225 MCA_COLL_BASE_TAG_BCAST, comm,
226 MPI_STATUS_IGNORE));
227 } else {
228 /* root section */
229 for (i = 0; i < rsize; i++) {
230 err = MCA_PML_CALL(isend(buff, count, datatype, i,
231 MCA_COLL_BASE_TAG_BCAST,
232 MCA_PML_BASE_SEND_STANDARD,
233 comm, &(reqs[i])));
234 if (OMPI_SUCCESS != err) {
235 return err;
238 err = ompi_request_wait_all(rsize, reqs, MPI_STATUSES_IGNORE);
242 /* All done */
243 return err;
248 * bcast_log_inter
250 * Function: - broadcast using O(N) algorithm
251 * Accepts: - same arguments as MPI_Bcast()
252 * Returns: - MPI_SUCCESS or error code
255 mca_coll_basic_bcast_log_inter(void *buff, int count,
256 struct ompi_datatype_t *datatype, int root,
257 struct ompi_communicator_t *comm)
259 return OMPI_ERR_NOT_IMPLEMENTED;