This source file includes following definitions.
- NBC_Gather_args_compare
- nbc_gather_init
- ompi_coll_libnbc_igather
- nbc_gather_inter_init
- ompi_coll_libnbc_igather_inter
- ompi_coll_libnbc_gather_init
- ompi_coll_libnbc_gather_inter_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include "nbc_internal.h"
25
26 #ifdef NBC_CACHE_SCHEDULE
27
28 int NBC_Gather_args_compare(NBC_Gather_args *a, NBC_Gather_args *b, void *param) {
29 if ((a->sendbuf == b->sendbuf) &&
30 (a->sendcount == b->sendcount) &&
31 (a->sendtype == b->sendtype) &&
32 (a->recvbuf == b->recvbuf) &&
33 (a->recvcount == b->recvcount) &&
34 (a->recvtype == b->recvtype) &&
35 (a->root == b->root)) {
36 return 0;
37 }
38
39 if( a->sendbuf < b->sendbuf ) {
40 return -1;
41 }
42
43 return 1;
44 }
45 #endif
46
47 static int nbc_gather_init(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
48 int recvcount, MPI_Datatype recvtype, int root,
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 rank, p, res;
52 MPI_Aint rcvext = 0;
53 NBC_Schedule *schedule;
54 char *rbuf, inplace = 0;
55 ompi_coll_libnbc_module_t *libnbc_module = (ompi_coll_libnbc_module_t*) module;
56
57 rank = ompi_comm_rank (comm);
58 if (root == rank) {
59 NBC_IN_PLACE(sendbuf, recvbuf, inplace);
60 }
61 p = ompi_comm_size (comm);
62
63 if (rank == root) {
64 res = ompi_datatype_type_extent (recvtype, &rcvext);
65 if (MPI_SUCCESS != res) {
66 NBC_Error("MPI Error in ompi_datatype_type_extent() (%i)", res);
67 return res;
68 }
69 }
70
71 if (inplace) {
72 sendcount = recvcount;
73 sendtype = recvtype;
74 }
75
76 #ifdef NBC_CACHE_SCHEDULE
77 NBC_Gather_args *args, *found, search;
78
79
80 search.sendbuf = sendbuf;
81 search.sendcount = sendcount;
82 search.sendtype = sendtype;
83 search.recvbuf = recvbuf;
84 search.recvcount = recvcount;
85 search.recvtype = recvtype;
86 search.root = root;
87 found = (NBC_Gather_args *) hb_tree_search ((hb_tree *) libnbc_module->NBC_Dict[NBC_GATHER],
88 &search);
89 if (NULL == found) {
90 #endif
91 schedule = OBJ_NEW(NBC_Schedule);
92 if (OPAL_UNLIKELY(NULL == schedule)) {
93 return OMPI_ERR_OUT_OF_RESOURCE;
94 }
95
96
97 if (rank != root) {
98
99 res = NBC_Sched_send(sendbuf, false, sendcount, sendtype, root, schedule, false);
100 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
101 OBJ_RELEASE(schedule);
102 return res;
103 }
104 } else {
105 for (int i = 0 ; i < p ; ++i) {
106 rbuf = (char *)recvbuf + i * recvcount * rcvext;
107 if (i == root) {
108 if (!inplace) {
109
110 res = NBC_Sched_copy ((void *)sendbuf, false, sendcount, sendtype,
111 rbuf, false, recvcount, recvtype, schedule, false);
112 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
113 OBJ_RELEASE(schedule);
114 return res;
115 }
116 }
117 } else {
118
119 res = NBC_Sched_recv (rbuf, false, recvcount, recvtype, i, schedule, false);
120 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
121 OBJ_RELEASE(schedule);
122 return res;
123 }
124 }
125 }
126 }
127
128 res = NBC_Sched_commit (schedule);
129 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
130 OBJ_RELEASE(schedule);
131 return res;
132 }
133
134 #ifdef NBC_CACHE_SCHEDULE
135
136 args = (NBC_Gather_args *) malloc (sizeof (args));
137 if (NULL != args) {
138 args->sendbuf = sendbuf;
139 args->sendcount = sendcount;
140 args->sendtype = sendtype;
141 args->recvbuf = recvbuf;
142 args->recvcount = recvcount;
143 args->recvtype = recvtype;
144 args->root = root;
145 args->schedule = schedule;
146 res = hb_tree_insert ((hb_tree *) libnbc_module->NBC_Dict[NBC_GATHER], args, args, 0);
147 if (0 == res) {
148 OBJ_RETAIN(schedule);
149
150
151 if (++libnbc_module->NBC_Dict_size[NBC_GATHER] > NBC_SCHED_DICT_UPPER) {
152 NBC_SchedCache_dictwipe ((hb_tree *) libnbc_module->NBC_Dict[NBC_GATHER],
153 &libnbc_module->NBC_Dict_size[NBC_GATHER]);
154 }
155 } else {
156 NBC_Error("error in dict_insert() (%i)", res);
157 free (args);
158 }
159 }
160 } else {
161
162 schedule = found->schedule;
163 OBJ_RETAIN(schedule);
164 }
165 #endif
166
167 res = NBC_Schedule_request(schedule, comm, libnbc_module, persistent, request, NULL);
168 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
169 OBJ_RELEASE(schedule);
170 return res;
171 }
172
173 return OMPI_SUCCESS;
174 }
175
176 int ompi_coll_libnbc_igather(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
177 int recvcount, MPI_Datatype recvtype, int root,
178 struct ompi_communicator_t *comm, ompi_request_t ** request,
179 struct mca_coll_base_module_2_3_0_t *module) {
180 int res = nbc_gather_init(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root,
181 comm, request, module, false);
182 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
183 return res;
184 }
185
186 res = NBC_Start(*(ompi_coll_libnbc_request_t **)request);
187 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
188 NBC_Return_handle (*(ompi_coll_libnbc_request_t **)request);
189 *request = &ompi_request_null.request;
190 return res;
191 }
192
193 return OMPI_SUCCESS;
194 }
195
196 static int nbc_gather_inter_init (const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
197 int recvcount, MPI_Datatype recvtype, int root,
198 struct ompi_communicator_t *comm, ompi_request_t ** request,
199 struct mca_coll_base_module_2_3_0_t *module, bool persistent) {
200 int res, rsize;
201 MPI_Aint rcvext = 0;
202 NBC_Schedule *schedule;
203 char *rbuf;
204 ompi_coll_libnbc_module_t *libnbc_module = (ompi_coll_libnbc_module_t*) module;
205
206 rsize = ompi_comm_remote_size (comm);
207
208 if (root == MPI_ROOT) {
209 res = ompi_datatype_type_extent(recvtype, &rcvext);
210 if (MPI_SUCCESS != res) {
211 NBC_Error("MPI Error in ompi_datatype_type_extent() (%i)", res);
212 return res;
213 }
214 }
215
216 schedule = OBJ_NEW(NBC_Schedule);
217 if (OPAL_UNLIKELY(NULL == schedule)) {
218 return OMPI_ERR_OUT_OF_RESOURCE;
219 }
220
221
222 if (root != MPI_ROOT && root != MPI_PROC_NULL) {
223
224 res = NBC_Sched_send (sendbuf, false, sendcount, sendtype, root, schedule, false);
225 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
226 OBJ_RELEASE(schedule);
227 return res;
228 }
229 } else if (MPI_ROOT == root) {
230 for (int i = 0 ; i < rsize ; ++i) {
231 rbuf = ((char *)recvbuf) + (i * recvcount * rcvext);
232
233 res = NBC_Sched_recv (rbuf, false, recvcount, recvtype, i, schedule, false);
234 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
235 OBJ_RELEASE(schedule);
236 return res;
237 }
238 }
239 }
240
241 res = NBC_Sched_commit (schedule);
242 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
243 OBJ_RELEASE(schedule);
244 return res;
245 }
246
247 res = NBC_Schedule_request(schedule, comm, libnbc_module, persistent, request, NULL);
248 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
249 OBJ_RELEASE(schedule);
250 return res;
251 }
252
253 return OMPI_SUCCESS;
254 }
255
256 int ompi_coll_libnbc_igather_inter(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
257 int recvcount, MPI_Datatype recvtype, int root,
258 struct ompi_communicator_t *comm, ompi_request_t ** request,
259 struct mca_coll_base_module_2_3_0_t *module) {
260 int res = nbc_gather_inter_init(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root,
261 comm, request, module, false);
262 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
263 return res;
264 }
265
266 res = NBC_Start(*(ompi_coll_libnbc_request_t **)request);
267 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
268 NBC_Return_handle (*(ompi_coll_libnbc_request_t **)request);
269 *request = &ompi_request_null.request;
270 return res;
271 }
272
273 return OMPI_SUCCESS;
274 }
275
276 int ompi_coll_libnbc_gather_init(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
277 int recvcount, MPI_Datatype recvtype, int root,
278 struct ompi_communicator_t *comm, MPI_Info info, ompi_request_t ** request,
279 struct mca_coll_base_module_2_3_0_t *module) {
280 int res = nbc_gather_init(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root,
281 comm, request, module, true);
282 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
283 return res;
284 }
285
286 return OMPI_SUCCESS;
287 }
288
289 int ompi_coll_libnbc_gather_inter_init(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
290 int recvcount, MPI_Datatype recvtype, int root,
291 struct ompi_communicator_t *comm, MPI_Info info, ompi_request_t ** request,
292 struct mca_coll_base_module_2_3_0_t *module) {
293 int res = nbc_gather_inter_init(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root,
294 comm, request, module, true);
295 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
296 return res;
297 }
298
299 return OMPI_SUCCESS;
300 }