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