1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
4 * University Research and Technology
5 * Corporation. All rights reserved.
6 * Copyright (c) 2004-2016 The University of Tennessee and The University
7 * of Tennessee Research Foundation. All rights
8 * reserved.
9 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
10 * University of Stuttgart. All rights reserved.
11 * Copyright (c) 2004-2005 The Regents of the University of California.
12 * All rights reserved.
13 * Copyright (c) 2013 Los Alamos National Security, LLC. All rights
14 * reserved.
15 * Copyright (c) 2013 FUJITSU LIMITED. All rights reserved.
16 * Copyright (c) 2014-2015 Research Organization for Information Science
17 * and Technology (RIST). All rights reserved.
18 * Copyright (c) 2017 IBM Corporation. All rights reserved.
19 * $COPYRIGHT$
20 *
21 * Additional copyrights may follow
22 *
23 * $HEADER$
24 */
25
26 #include "ompi_config.h"
27 #include "coll_basic.h"
28
29 #include "mpi.h"
30 #include "ompi/constants.h"
31 #include "ompi/datatype/ompi_datatype.h"
32 #include "ompi/mca/coll/coll.h"
33 #include "ompi/mca/coll/base/coll_tags.h"
34 #include "ompi/mca/pml/pml.h"
35
36
37 /*
38 * alltoallv_inter
39 *
40 * Function: - MPI_Alltoallv
41 * Accepts: - same as MPI_Alltoallv()
42 * Returns: - MPI_SUCCESS or an MPI error code
43 */
44 int
45 mca_coll_basic_alltoallv_inter(const void *sbuf, const int *scounts, const int *sdisps,
46 struct ompi_datatype_t *sdtype, void *rbuf,
47 const int *rcounts, const int *rdisps,
48 struct ompi_datatype_t *rdtype,
49 struct ompi_communicator_t *comm,
50 mca_coll_base_module_t *module)
51 {
52 int i;
53 int rsize;
54 int err;
55 char *psnd;
56 char *prcv;
57 size_t nreqs;
58 MPI_Aint sndextent;
59 MPI_Aint rcvextent;
60
61 ompi_request_t **preq;
62
63 /* Initialize. */
64
65 rsize = ompi_comm_remote_size(comm);
66
67 ompi_datatype_type_extent(sdtype, &sndextent);
68 ompi_datatype_type_extent(rdtype, &rcvextent);
69
70 /* Initiate all send/recv to/from others. */
71 nreqs = rsize * 2;
72 preq = ompi_coll_base_comm_get_reqs(module->base_data, nreqs);
73 if( NULL == preq ) { return OMPI_ERR_OUT_OF_RESOURCE; }
74
75 /* Post all receives first */
76 /* A simple optimization: do not send and recv msgs of length zero */
77 for (i = 0; i < rsize; ++i) {
78 prcv = ((char *) rbuf) + (rdisps[i] * rcvextent);
79 if (rcounts[i] > 0) {
80 err = MCA_PML_CALL(irecv(prcv, rcounts[i], rdtype,
81 i, MCA_COLL_BASE_TAG_ALLTOALLV, comm,
82 &preq[i]));
83 if (MPI_SUCCESS != err) {
84 ompi_coll_base_free_reqs(preq, i + 1);
85 return err;
86 }
87 }
88 }
89
90 /* Now post all sends */
91 for (i = 0; i < rsize; ++i) {
92 psnd = ((char *) sbuf) + (sdisps[i] * sndextent);
93 if (scounts[i] > 0) {
94 err = MCA_PML_CALL(isend(psnd, scounts[i], sdtype,
95 i, MCA_COLL_BASE_TAG_ALLTOALLV,
96 MCA_PML_BASE_SEND_STANDARD, comm,
97 &preq[rsize + i]));
98 if (MPI_SUCCESS != err) {
99 ompi_coll_base_free_reqs(preq, rsize + i + 1);
100 return err;
101 }
102 }
103 }
104
105 err = ompi_request_wait_all(nreqs, preq, MPI_STATUSES_IGNORE);
106 if (MPI_SUCCESS != err) {
107 ompi_coll_base_free_reqs(preq, nreqs);
108 }
109
110 /* All done */
111 return err;
112 }