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) 2006-2010 University of Houston. All rights reserved.
13 * Copyright (c) 2015-2017 Research Organization for Information Science
14 * and Technology (RIST). All rights reserved.
15 * $COPYRIGHT$
16 *
17 * Additional copyrights may follow
18 *
19 * $HEADER$
20 */
21
22 #include "ompi_config.h"
23 #include "coll_inter.h"
24
25 #include <stdlib.h>
26
27 #include "mpi.h"
28 #include "ompi/constants.h"
29 #include "ompi/datatype/ompi_datatype.h"
30 #include "ompi/communicator/communicator.h"
31 #include "ompi/mca/coll/coll.h"
32 #include "ompi/mca/pml/pml.h"
33 #include "ompi/mca/coll/base/coll_tags.h"
34 #include "ompi/mca/coll/base/coll_base_util.h"
35
36 /*
37 * allgather_inter
38 *
39 * Function: - allgather using other MPI collections
40 * Accepts: - same as MPI_Allgather()
41 * Returns: - MPI_SUCCESS or error code
42 */
43 int
44 mca_coll_inter_allgather_inter(const void *sbuf, int scount,
45 struct ompi_datatype_t *sdtype,
46 void *rbuf, int rcount,
47 struct ompi_datatype_t *rdtype,
48 struct ompi_communicator_t *comm,
49 mca_coll_base_module_t *module)
50 {
51 int rank, root = 0, size, rsize, err = OMPI_SUCCESS;
52 char *ptmp_free = NULL, *ptmp = NULL;
53 ptrdiff_t gap, span;
54
55 rank = ompi_comm_rank(comm);
56 size = ompi_comm_size(comm->c_local_comm);
57 rsize = ompi_comm_remote_size(comm);
58
59 /* Perform the gather locally at the root */
60 if ( scount > 0 ) {
61 span = opal_datatype_span(&sdtype->super, (int64_t)scount*(int64_t)size, &gap);
62 ptmp_free = (char*)malloc(span);
63 if (NULL == ptmp_free) {
64 return OMPI_ERR_OUT_OF_RESOURCE;
65 }
66 ptmp = ptmp_free - gap;
67
68 err = comm->c_local_comm->c_coll->coll_gather(sbuf, scount, sdtype,
69 ptmp, scount, sdtype,
70 0, comm->c_local_comm,
71 comm->c_local_comm->c_coll->coll_gather_module);
72 if (OMPI_SUCCESS != err) {
73 goto exit;
74 }
75 }
76
77 if (rank == root) {
78 /* Do a send-recv between the two root procs. to avoid deadlock */
79 err = ompi_coll_base_sendrecv_actual(ptmp, scount*size, sdtype, 0,
80 MCA_COLL_BASE_TAG_ALLGATHER,
81 rbuf, rcount*rsize, rdtype, 0,
82 MCA_COLL_BASE_TAG_ALLGATHER,
83 comm, MPI_STATUS_IGNORE);
84 if (OMPI_SUCCESS != err) {
85 goto exit;
86 }
87 }
88 /* bcast the message to all the local processes */
89 if ( rcount > 0 ) {
90 err = comm->c_local_comm->c_coll->coll_bcast(rbuf, rcount*rsize, rdtype,
91 root, comm->c_local_comm,
92 comm->c_local_comm->c_coll->coll_bcast_module);
93 if (OMPI_SUCCESS != err) {
94 goto exit;
95 }
96 }
97
98 exit:
99 if (NULL != ptmp_free) {
100 free(ptmp_free);
101 }
102
103 return err;
104 }