1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3 * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
4 * University Research and Technology
5 * Corporation. All rights reserved.
6 * Copyright (c) 2004-2017 The University of Tennessee and The University
7 * of Tennessee Research Foundation. All rights
8 * reserved.
9 * Copyright (c) 2004-2008 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) 2007 Cisco Systems, Inc. All rights reserved.
14 * Copyright (c) 2012-2017 Los Alamos National Security, LLC. All rights
15 * 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 <stdio.h>
28
29 #include "ompi/mpi/c/bindings.h"
30 #include "ompi/runtime/params.h"
31 #include "ompi/communicator/communicator.h"
32 #include "ompi/errhandler/errhandler.h"
33 #include "ompi/datatype/ompi_datatype.h"
34 #include "ompi/memchecker.h"
35 #include "ompi/mca/topo/topo.h"
36 #include "ompi/mca/topo/base/base.h"
37
38 #if OMPI_BUILD_MPI_PROFILING
39 #if OPAL_HAVE_WEAK_SYMBOLS
40 #pragma weak MPI_Ineighbor_alltoallw = PMPI_Ineighbor_alltoallw
41 #endif
42 #define MPI_Ineighbor_alltoallw PMPI_Ineighbor_alltoallw
43 #endif
44
45 static const char FUNC_NAME[] = "MPI_Ineighbor_alltoallw";
46
47
MPI_Ineighbor_alltoallw(const void * sendbuf,const int sendcounts[],const MPI_Aint sdispls[],const MPI_Datatype sendtypes[],void * recvbuf,const int recvcounts[],const MPI_Aint rdispls[],const MPI_Datatype recvtypes[],MPI_Comm comm,MPI_Request * request)48 int MPI_Ineighbor_alltoallw(const void *sendbuf, const int sendcounts[], const MPI_Aint sdispls[],
49 const MPI_Datatype sendtypes[], void *recvbuf, const int recvcounts[],
50 const MPI_Aint rdispls[], const MPI_Datatype recvtypes[], MPI_Comm comm,
51 MPI_Request *request)
52 {
53 int i, err;
54 int indegree, outdegree;
55
56 MEMCHECKER(
57 ptrdiff_t recv_ext;
58 ptrdiff_t send_ext;
59
60 memchecker_comm(comm);
61
62 err = mca_topo_base_neighbor_count (comm, &indegree, &outdegree);
63 if (MPI_SUCCESS == err) {
64 if (MPI_IN_PLACE != sendbuf) {
65 for ( i = 0; i < outdegree; i++ ) {
66 memchecker_datatype(sendtypes[i]);
67
68 ompi_datatype_type_extent(sendtypes[i], &send_ext);
69
70 memchecker_call(&opal_memchecker_base_isdefined,
71 (char *)(sendbuf)+sdispls[i]*send_ext,
72 sendcounts[i], sendtypes[i]);
73 }
74 }
75 for ( i = 0; i < indegree; i++ ) {
76 memchecker_datatype(recvtypes[i]);
77
78 ompi_datatype_type_extent(recvtypes[i], &recv_ext);
79
80 memchecker_call(&opal_memchecker_base_isaddressable,
81 (char *)(recvbuf)+sdispls[i]*recv_ext,
82 recvcounts[i], recvtypes[i]);
83 }
84 }
85 );
86
87 if (MPI_PARAM_CHECK) {
88
89 /* Unrooted operation -- same checks for all ranks */
90
91 err = MPI_SUCCESS;
92 OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
93 if (ompi_comm_invalid(comm) || OMPI_COMM_IS_INTER(comm)) {
94 return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM,
95 FUNC_NAME);
96 } else if (! OMPI_COMM_IS_TOPO(comm)) {
97 return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_TOPOLOGY,
98 FUNC_NAME);
99 }
100
101 if ((NULL == sendcounts) || (NULL == sdispls) || (NULL == sendtypes) ||
102 (NULL == recvcounts) || (NULL == rdispls) || (NULL == recvtypes) ||
103 MPI_IN_PLACE == sendbuf || MPI_IN_PLACE == recvbuf) {
104 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
105 }
106
107 err = mca_topo_base_neighbor_count (comm, &indegree, &outdegree);
108 OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
109 for (i = 0; i < outdegree; ++i) {
110 OMPI_CHECK_DATATYPE_FOR_SEND(err, sendtypes[i], sendcounts[i]);
111 OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
112 }
113 for (i = 0; i < indegree; ++i) {
114 OMPI_CHECK_DATATYPE_FOR_RECV(err, recvtypes[i], recvcounts[i]);
115 OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
116 }
117
118 if( OMPI_COMM_IS_CART(comm) ) {
119 const mca_topo_base_comm_cart_2_2_0_t *cart = comm->c_topo->mtc.cart;
120 if( 0 > cart->ndims ) {
121 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
122 }
123 }
124 else if( OMPI_COMM_IS_GRAPH(comm) ) {
125 int degree;
126 mca_topo_base_graph_neighbors_count(comm, ompi_comm_rank(comm), °ree);
127 if( 0 > degree ) {
128 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
129 }
130 }
131 else if( OMPI_COMM_IS_DIST_GRAPH(comm) ) {
132 const mca_topo_base_comm_dist_graph_2_2_0_t *dist_graph = comm->c_topo->mtc.dist_graph;
133 indegree = dist_graph->indegree;
134 outdegree = dist_graph->outdegree;
135 if( indegree < 0 || outdegree < 0 ) {
136 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
137 }
138 }
139 }
140
141 OPAL_CR_ENTER_LIBRARY();
142
143 /* Invoke the coll component to perform the back-end operation */
144 err = comm->c_coll->coll_ineighbor_alltoallw(sendbuf, sendcounts, sdispls, sendtypes,
145 recvbuf, recvcounts, rdispls, recvtypes, comm, request,
146 comm->c_coll->coll_ineighbor_alltoallw_module);
147 OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME);
148 }
149
150