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