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
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.
14 * Additional copyrights may follow
19 #include "ompi_config.h"
20 #include "coll_basic.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"
35 * Function: - broadcast using O(N) algorithm
36 * Accepts: - same arguments as MPI_Bcast()
37 * Returns: - MPI_SUCCESS or error code
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
)
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. */
57 return MCA_PML_CALL(recv(buff
, count
, datatype
, root
,
58 MCA_COLL_BASE_TAG_BCAST
, comm
,
62 /* Root sends data to all others. */
64 for (i
= 0, preq
= reqs
; i
< size
; ++i
) {
69 err
= MCA_PML_CALL(isend_init(buff
, count
, datatype
, i
,
70 MCA_COLL_BASE_TAG_BCAST
,
71 MCA_PML_BASE_SEND_STANDARD
,
73 if (MPI_SUCCESS
!= err
) {
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
);
94 mca_coll_basic_free_reqs(reqs
, i
);
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
)
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
);
135 /* Receive data from parent in the tree. */
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
) {
148 /* Send data to the children. */
153 for (i
= hibit
+ 1, mask
= 1 << i
; i
<= dim
; ++i
, mask
<<= 1) {
156 peer
= (peer
+ root
) % size
;
159 err
= MCA_PML_CALL(isend_init(buff
, count
, datatype
, peer
,
160 MCA_COLL_BASE_TAG_BCAST
,
161 MCA_PML_BASE_SEND_STANDARD
,
163 if (MPI_SUCCESS
!= err
) {
164 mca_coll_basic_free_reqs(reqs
, preq
- reqs
);
170 /* Start and wait on all requests. */
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
);
189 mca_coll_basic_free_reqs(reqs
, nreqs
);
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
)
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
) {
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
,
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
,
234 if (OMPI_SUCCESS
!= err
) {
238 err
= ompi_request_wait_all(rsize
, reqs
, MPI_STATUSES_IGNORE
);
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
;