This source file includes following definitions.
- NBC_Ineighbor_alltoallv_args_compare
- nbc_neighbor_alltoallv_init
- ompi_coll_libnbc_ineighbor_alltoallv
- ompi_coll_libnbc_neighbor_alltoallv_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include "nbc_internal.h"
22
23
24 #undef NBC_CACHE_SCHEDULE
25
26 #ifdef NBC_CACHE_SCHEDULE
27
28 int NBC_Ineighbor_alltoallv_args_compare(NBC_Ineighbor_alltoallv_args *a, NBC_Ineighbor_alltoallv_args *b, void *param) {
29 if ((a->sbuf == b->sbuf) &&
30 (a->scount == b->scount) &&
31 (a->stype == b->stype) &&
32 (a->rbuf == b->rbuf) &&
33 (a->rcount == b->rcount) &&
34 (a->rtype == b->rtype) ) {
35 return 0;
36 }
37
38 if (a->sbuf < b->sbuf) {
39 return -1;
40 }
41
42 return 1;
43 }
44 #endif
45
46
47 static int nbc_neighbor_alltoallv_init(const void *sbuf, const int *scounts, const int *sdispls, MPI_Datatype stype,
48 void *rbuf, const int *rcounts, const int *rdispls, MPI_Datatype rtype,
49 struct ompi_communicator_t *comm, ompi_request_t ** request,
50 struct mca_coll_base_module_2_3_0_t *module, bool persistent) {
51 int res, indegree, outdegree, *srcs, *dsts;
52 MPI_Aint sndext, rcvext;
53 ompi_coll_libnbc_module_t *libnbc_module = (ompi_coll_libnbc_module_t*) module;
54 NBC_Schedule *schedule;
55
56 res = ompi_datatype_type_extent (stype, &sndext);
57 if (MPI_SUCCESS != res) {
58 NBC_Error("MPI Error in ompi_datatype_type_extent() (%i)", res);
59 return res;
60 }
61
62 res = ompi_datatype_type_extent (rtype, &rcvext);
63 if (MPI_SUCCESS != res) {
64 NBC_Error("MPI Error in ompi_datatype_type_extent() (%i)", res);
65 return res;
66 }
67
68 #ifdef NBC_CACHE_SCHEDULE
69 NBC_Ineighbor_alltoallv_args *args, *found, search;
70
71
72 search.sbuf = sbuf;
73 search.scount = scount;
74 search.stype = stype;
75 search.rbuf = rbuf;
76 search.rcount = rcount;
77 search.rtype = rtype;
78 found = (NBC_Ineighbor_alltoallv_args *) hb_tree_search ((hb_tree *) libnbc_module->NBC_Dict[NBC_NEIGHBOR_ALLTOALLV],
79 &search);
80 if (NULL == found) {
81 #endif
82 schedule = OBJ_NEW(NBC_Schedule);
83 if (OPAL_UNLIKELY(NULL == schedule)) {
84 return OMPI_ERR_OUT_OF_RESOURCE;
85 }
86
87 res = NBC_Comm_neighbors (comm, &srcs, &indegree, &dsts, &outdegree);
88 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
89 OBJ_RELEASE(schedule);
90 return res;
91 }
92
93
94 for (int i = 0 ; i < indegree ; ++i) {
95 if (srcs[i] != MPI_PROC_NULL) {
96 res = NBC_Sched_recv ((char *) rbuf + rdispls[i] * rcvext, false, rcounts[i], rtype, srcs[i], schedule, false);
97 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
98 break;
99 }
100 }
101 }
102
103 free (srcs);
104
105 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
106 OBJ_RELEASE(schedule);
107 free (dsts);
108 return res;
109 }
110
111 for (int i = 0 ; i < outdegree ; ++i) {
112 if (dsts[i] != MPI_PROC_NULL) {
113 res = NBC_Sched_send ((char *) sbuf + sdispls[i] * sndext, false, scounts[i], stype, dsts[i], schedule, false);
114 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
115 break;
116 }
117 }
118 }
119
120 free (dsts);
121
122 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
123 OBJ_RELEASE(schedule);
124 return res;
125 }
126
127 res = NBC_Sched_commit (schedule);
128 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
129 OBJ_RELEASE(schedule);
130 return res;
131 }
132
133 #ifdef NBC_CACHE_SCHEDULE
134
135 args = (NBC_Ineighbor_alltoallv_args *) malloc (sizeof (args));
136 if (NULL != args) {
137 args->sbuf = sbuf;
138 args->scount = scount;
139 args->stype = stype;
140 args->rbuf = rbuf;
141 args->rcount = rcount;
142 args->rtype = rtype;
143 args->schedule = schedule;
144 res = hb_tree_insert ((hb_tree *) libnbc_module->NBC_Dict[NBC_NEIGHBOR_ALLTOALLV], args, args, 0);
145 if (0 == res) {
146 OBJ_RETAIN(schedule);
147
148
149 if (++libnbc_module->NBC_Dict_size[NBC_NEIGHBOR_ALLTOALLV] > NBC_SCHED_DICT_UPPER) {
150 NBC_SchedCache_dictwipe ((hb_tree *) libnbc_module->NBC_Dict[NBC_NEIGHBOR_ALLTOALLV],
151 &libnbc_module->NBC_Dict_size[NBC_NEIGHBOR_ALLTOALLV]);
152 }
153 } else {
154 NBC_Error("error in dict_insert() (%i)", res);
155 free (args);
156 }
157 }
158 } else {
159
160 schedule = found->schedule;
161 OBJ_RETAIN(schedule);
162 }
163 #endif
164
165 res = NBC_Schedule_request(schedule, comm, libnbc_module, persistent, request, NULL);
166 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
167 OBJ_RELEASE(schedule);
168 return res;
169 }
170
171 return OMPI_SUCCESS;
172 }
173
174 int ompi_coll_libnbc_ineighbor_alltoallv(const void *sbuf, const int *scounts, const int *sdispls, MPI_Datatype stype,
175 void *rbuf, const int *rcounts, const int *rdispls, MPI_Datatype rtype,
176 struct ompi_communicator_t *comm, ompi_request_t ** request,
177 struct mca_coll_base_module_2_3_0_t *module) {
178 int res = nbc_neighbor_alltoallv_init(sbuf, scounts, sdispls, stype, rbuf, rcounts, rdispls, rtype,
179 comm, request, module, false);
180 if (OPAL_LIKELY(OMPI_SUCCESS != res)) {
181 return res;
182 }
183 res = NBC_Start(*(ompi_coll_libnbc_request_t **)request);
184 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
185 NBC_Return_handle (*(ompi_coll_libnbc_request_t **)request);
186 *request = &ompi_request_null.request;
187 return res;
188 }
189
190 return OMPI_SUCCESS;
191 }
192
193 int ompi_coll_libnbc_neighbor_alltoallv_init(const void *sbuf, const int *scounts, const int *sdispls, MPI_Datatype stype,
194 void *rbuf, const int *rcounts, const int *rdispls, MPI_Datatype rtype,
195 struct ompi_communicator_t *comm, MPI_Info info, ompi_request_t ** request,
196 struct mca_coll_base_module_2_3_0_t *module) {
197 int res = nbc_neighbor_alltoallv_init(sbuf, scounts, sdispls, stype, rbuf, rcounts, rdispls, rtype,
198 comm, request, module, true);
199 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
200 return res;
201 }
202
203 return OMPI_SUCCESS;
204 }