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-2016 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) 2015 Research Organization for Information Science
13 * and Technology (RIST). All rights reserved.
14 * Copyright (c) 2017 IBM Corporation. All rights reserved.
15 * $COPYRIGHT$
16 *
17 * Additional copyrights may follow
18 *
19 * $HEADER$
20 */
21
22 #include "ompi_config.h"
23 #include "coll_basic.h"
24
25 #include "mpi.h"
26 #include "ompi/constants.h"
27 #include "ompi/datatype/ompi_datatype.h"
28 #include "ompi/mca/coll/coll.h"
29 #include "ompi/mca/coll/base/coll_tags.h"
30 #include "ompi/mca/pml/pml.h"
31 #include "coll_basic.h"
32
33
34 /*
35 * scatter_inter
36 *
37 * Function: - scatter operation
38 * Accepts: - same arguments as MPI_Scatter()
39 * Returns: - MPI_SUCCESS or error code
40 */
41 int
42 mca_coll_basic_scatter_inter(const void *sbuf, int scount,
43 struct ompi_datatype_t *sdtype,
44 void *rbuf, int rcount,
45 struct ompi_datatype_t *rdtype,
46 int root, struct ompi_communicator_t *comm,
47 mca_coll_base_module_t *module)
48 {
49 int i, size, err;
50 char *ptmp;
51 ptrdiff_t lb, incr;
52 ompi_request_t **reqs;
53
54 /* Initialize */
55 size = ompi_comm_remote_size(comm);
56
57 if (MPI_PROC_NULL == root) {
58 /* do nothing */
59 err = OMPI_SUCCESS;
60 } else if (MPI_ROOT != root) {
61 /* If not root, receive data. */
62 err = MCA_PML_CALL(recv(rbuf, rcount, rdtype, root,
63 MCA_COLL_BASE_TAG_SCATTER,
64 comm, MPI_STATUS_IGNORE));
65 } else {
66 /* I am the root, loop sending data. */
67 err = ompi_datatype_get_extent(sdtype, &lb, &incr);
68 if (OMPI_SUCCESS != err) {
69 return OMPI_ERROR;
70 }
71
72 reqs = ompi_coll_base_comm_get_reqs(module->base_data, size);
73 if( NULL == reqs ) { return OMPI_ERR_OUT_OF_RESOURCE; }
74
75 incr *= scount;
76 for (i = 0, ptmp = (char *) sbuf; i < size; ++i, ptmp += incr) {
77 err = MCA_PML_CALL(isend(ptmp, scount, sdtype, i,
78 MCA_COLL_BASE_TAG_SCATTER,
79 MCA_PML_BASE_SEND_STANDARD, comm,
80 reqs++));
81 if (OMPI_SUCCESS != err) {
82 ompi_coll_base_free_reqs(reqs, i + 1);
83 return err;
84 }
85 }
86
87 err = ompi_request_wait_all(size, reqs, MPI_STATUSES_IGNORE);
88 if (OMPI_SUCCESS != err) {
89 ompi_coll_base_free_reqs(reqs, size);
90 }
91 }
92
93 return err;
94 }