This source file includes following definitions.
- OMPI_Affinity_str
- get_rsrc_ompi_bound
- get_rsrc_current_binding
- get_rsrc_exists
- get_layout_ompi_bound
- get_layout_current_binding
- get_layout_exists
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 #include "ompi_config.h"
28
29 #include <stdio.h>
30 #include <string.h>
31
32 #include "opal/mca/hwloc/base/base.h"
33 #include "opal/runtime/opal.h"
34 #include "opal/util/string_copy.h"
35
36 #include "ompi/communicator/communicator.h"
37 #include "ompi/errhandler/errhandler.h"
38 #include "ompi/mca/rte/rte.h"
39 #include "ompi/mpi/c/bindings.h"
40 #include "ompi/mpiext/affinity/c/mpiext_affinity_c.h"
41
42 static const char FUNC_NAME[] = "OMPI_Affinity";
43 static const char ompi_nobind_str[] = "Open MPI did not bind this process";
44 static const char not_bound_str[] = "Not bound (i.e., bound to all processors)";
45
46
47 static int get_rsrc_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX]);
48 static int get_rsrc_current_binding(char str[OMPI_AFFINITY_STRING_MAX]);
49 static int get_rsrc_exists(char str[OMPI_AFFINITY_STRING_MAX]);
50 static int get_layout_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX]);
51 static int get_layout_current_binding(char str[OMPI_AFFINITY_STRING_MAX]);
52 static int get_layout_exists(char str[OMPI_AFFINITY_STRING_MAX]);
53
54
55 int OMPI_Affinity_str(ompi_affinity_fmt_t fmt_type,
56 char ompi_bound[OMPI_AFFINITY_STRING_MAX],
57 char current_binding[OMPI_AFFINITY_STRING_MAX],
58 char exists[OMPI_AFFINITY_STRING_MAX])
59 {
60 int ret;
61
62 memset(ompi_bound, 0, OMPI_AFFINITY_STRING_MAX);
63 memset(current_binding, 0, OMPI_AFFINITY_STRING_MAX);
64 memset(exists, 0, OMPI_AFFINITY_STRING_MAX);
65
66
67 if (NULL == opal_hwloc_topology) {
68 return MPI_SUCCESS;
69 }
70
71
72 switch (fmt_type) {
73 case OMPI_AFFINITY_RSRC_STRING_FMT:
74 if (OMPI_SUCCESS != (ret = get_rsrc_ompi_bound(ompi_bound)) ||
75 OMPI_SUCCESS != (ret = get_rsrc_current_binding(current_binding)) ||
76 OMPI_SUCCESS != (ret = get_rsrc_exists(exists))) {
77 return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, ret, FUNC_NAME);
78 }
79 break;
80 case OMPI_AFFINITY_LAYOUT_FMT:
81 if (OMPI_SUCCESS != (ret = get_layout_ompi_bound(ompi_bound)) ||
82 OMPI_SUCCESS != (ret = get_layout_current_binding(current_binding)) ||
83 OMPI_SUCCESS != (ret = get_layout_exists(exists))) {
84 return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, ret, FUNC_NAME);
85 }
86 break;
87 default:
88 return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME);
89 }
90
91 return MPI_SUCCESS;
92 }
93
94
95
96
97
98
99 static int get_rsrc_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX])
100 {
101 int ret;
102
103
104 if (!ompi_rte_proc_is_bound) {
105 opal_string_copy(str, ompi_nobind_str, OMPI_AFFINITY_STRING_MAX);
106 return OMPI_SUCCESS;
107 }
108
109 if (NULL == ompi_proc_applied_binding) {
110 ret = OPAL_ERR_NOT_BOUND;
111 } else {
112 ret = opal_hwloc_base_cset2str(str, OMPI_AFFINITY_STRING_MAX,
113 opal_hwloc_topology,
114 ompi_proc_applied_binding);
115 }
116 if (OPAL_ERR_NOT_BOUND == ret) {
117 opal_string_copy(str, not_bound_str, OMPI_AFFINITY_STRING_MAX);
118 ret = OMPI_SUCCESS;
119 }
120 return ret;
121 }
122
123
124
125
126
127 static int get_rsrc_current_binding(char str[OMPI_AFFINITY_STRING_MAX])
128 {
129 int ret;
130 hwloc_obj_t root;
131 hwloc_cpuset_t boundset, rootset;
132 bool bound = false;
133
134
135 root = hwloc_get_root_obj(opal_hwloc_topology);
136 rootset = root->cpuset;
137
138
139 boundset = hwloc_bitmap_alloc();
140 if (hwloc_get_cpubind(opal_hwloc_topology, boundset,
141 HWLOC_CPUBIND_PROCESS) < 0) {
142
143
144 bound = false;
145 } else {
146
147
148 if (0 != hwloc_bitmap_compare(boundset, rootset) ||
149 opal_hwloc_base_single_cpu(rootset) ||
150 opal_hwloc_base_single_cpu(boundset)) {
151 bound = true;
152 }
153 }
154
155
156 if (!bound) {
157 strncat(str, not_bound_str, OMPI_AFFINITY_STRING_MAX - 1);
158 ret = OMPI_SUCCESS;
159 }
160
161
162 else {
163 ret = opal_hwloc_base_cset2str(str, OMPI_AFFINITY_STRING_MAX,
164 opal_hwloc_topology,
165 boundset);
166 if (OPAL_ERR_NOT_BOUND == ret) {
167 opal_string_copy(str, not_bound_str, OMPI_AFFINITY_STRING_MAX);
168 ret = OMPI_SUCCESS;
169 }
170 }
171 hwloc_bitmap_free(boundset);
172
173 return ret;
174 }
175
176
177
178
179
180
181
182 static int get_rsrc_exists(char str[OMPI_AFFINITY_STRING_MAX])
183 {
184 bool first = true;
185 int i, num_cores, num_pus;
186 char tmp[BUFSIZ];
187 const int stmp = sizeof(tmp) - 1;
188 hwloc_obj_t socket, core, c2;
189
190 str[0] = '\0';
191 for (socket = hwloc_get_obj_by_type(opal_hwloc_topology,
192 HWLOC_OBJ_SOCKET, 0);
193 NULL != socket; socket = socket->next_cousin) {
194
195 if (!first) {
196 strncat(str, "; ", OMPI_AFFINITY_STRING_MAX - strlen(str));
197 }
198 first = false;
199
200 snprintf(tmp, stmp, "socket %d has ", socket->os_index);
201 strncat(str, tmp, OMPI_AFFINITY_STRING_MAX - strlen(str));
202
203
204
205
206 num_cores = hwloc_get_nbobjs_inside_cpuset_by_type(opal_hwloc_topology,
207 socket->cpuset,
208 HWLOC_OBJ_CORE);
209 core = hwloc_get_obj_inside_cpuset_by_type(opal_hwloc_topology,
210 socket->cpuset,
211 HWLOC_OBJ_CORE, 0);
212 if (NULL != core) {
213 num_pus =
214 hwloc_get_nbobjs_inside_cpuset_by_type(opal_hwloc_topology,
215 core->cpuset,
216 HWLOC_OBJ_PU);
217
218
219 if (1 == num_cores) {
220 strncat(str, "1 core with ",
221 OMPI_AFFINITY_STRING_MAX - strlen(str));
222 if (1 == num_pus) {
223 strncat(str, "1 hwt",
224 OMPI_AFFINITY_STRING_MAX - strlen(str));
225 } else {
226 snprintf(tmp, stmp, "%d hwts", num_pus);
227 strncat(str, tmp, OMPI_AFFINITY_STRING_MAX - strlen(str));
228 }
229 }
230
231
232 else {
233 bool same = true;
234
235 snprintf(tmp, stmp, "%d cores", num_cores);
236 strncat(str, tmp, OMPI_AFFINITY_STRING_MAX - strlen(str));
237
238
239 for (c2 = core; NULL != c2; c2 = c2->next_cousin) {
240 if (hwloc_get_nbobjs_inside_cpuset_by_type(opal_hwloc_topology,
241 core->cpuset,
242 HWLOC_OBJ_PU) !=
243 num_pus) {
244 same = false;
245 break;
246 }
247 }
248
249
250 if (same) {
251 snprintf(tmp, stmp, ", each with %d hwt", num_pus);
252 strncat(str, tmp, OMPI_AFFINITY_STRING_MAX - strlen(str));
253 if (num_pus != 1) {
254 strncat(str, "s", OMPI_AFFINITY_STRING_MAX - strlen(str));
255 }
256 }
257
258
259 else {
260 bool first = true;
261
262 strncat(str, "with (", OMPI_AFFINITY_STRING_MAX - strlen(str));
263 for (c2 = core; NULL != c2; c2 = c2->next_cousin) {
264 if (!first) {
265 strncat(str, ", ",
266 OMPI_AFFINITY_STRING_MAX - strlen(str));
267 }
268 first = false;
269
270 i = hwloc_get_nbobjs_inside_cpuset_by_type(opal_hwloc_topology,
271 core->cpuset,
272 HWLOC_OBJ_PU);
273 snprintf(tmp, stmp, "%d", i);
274 strncat(str, tmp, OMPI_AFFINITY_STRING_MAX - strlen(str));
275 }
276 strncat(str, ") hwts",
277 OMPI_AFFINITY_STRING_MAX - strlen(str));
278 }
279 }
280 }
281 }
282
283 return OMPI_SUCCESS;
284 }
285
286
287
288
289
290
291 static int get_layout_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX])
292 {
293 int ret;
294
295
296 if (!ompi_rte_proc_is_bound) {
297 opal_string_copy(str, ompi_nobind_str, OMPI_AFFINITY_STRING_MAX);
298 return OMPI_SUCCESS;
299 }
300
301
302 if (NULL == ompi_proc_applied_binding) {
303 ret = OPAL_ERR_NOT_BOUND;
304 } else {
305 ret = opal_hwloc_base_cset2mapstr(str, OMPI_AFFINITY_STRING_MAX,
306 opal_hwloc_topology,
307 ompi_proc_applied_binding);
308 }
309 if (OPAL_ERR_NOT_BOUND == ret) {
310 opal_string_copy(str, not_bound_str, OMPI_AFFINITY_STRING_MAX);
311 ret = OMPI_SUCCESS;
312 }
313
314 return ret;
315 }
316
317
318
319
320 static int get_layout_current_binding(char str[OMPI_AFFINITY_STRING_MAX])
321 {
322 int ret;
323 hwloc_obj_t root;
324 hwloc_cpuset_t boundset, rootset;
325 bool bound = false;
326
327
328 root = hwloc_get_root_obj(opal_hwloc_topology);
329 rootset = root->cpuset;
330
331
332 boundset = hwloc_bitmap_alloc();
333 if (hwloc_get_cpubind(opal_hwloc_topology, boundset,
334 HWLOC_CPUBIND_PROCESS) < 0) {
335
336
337 bound = false;
338 } else {
339
340
341 if (0 != hwloc_bitmap_compare(boundset, rootset) ||
342 opal_hwloc_base_single_cpu(rootset) ||
343 opal_hwloc_base_single_cpu(boundset)) {
344 bound = true;
345 }
346 }
347
348
349 if (!bound) {
350 strncat(str, not_bound_str, OMPI_AFFINITY_STRING_MAX - 1);
351 ret = OMPI_SUCCESS;
352 }
353
354
355 else {
356 ret = opal_hwloc_base_cset2mapstr(str, OMPI_AFFINITY_STRING_MAX,
357 opal_hwloc_topology,
358 boundset);
359 if (OPAL_ERR_NOT_BOUND == ret) {
360 opal_string_copy(str, not_bound_str, OMPI_AFFINITY_STRING_MAX);
361 ret = OMPI_SUCCESS;
362 }
363 }
364 hwloc_bitmap_free(boundset);
365
366 return ret;
367 }
368
369
370
371
372
373
374
375
376
377
378
379 static int get_layout_exists(char str[OMPI_AFFINITY_STRING_MAX])
380 {
381 int core_index, pu_index;
382 int len = OMPI_AFFINITY_STRING_MAX;
383 hwloc_obj_t socket, core, pu;
384
385 str[0] = '\0';
386
387
388 for (socket = hwloc_get_obj_by_type(opal_hwloc_topology,
389 HWLOC_OBJ_SOCKET, 0);
390 NULL != socket;
391 socket = socket->next_cousin) {
392 strncat(str, "[", len - strlen(str));
393
394
395 core_index = 0;
396 for (core = hwloc_get_obj_inside_cpuset_by_type(opal_hwloc_topology,
397 socket->cpuset,
398 HWLOC_OBJ_CORE, core_index);
399 NULL != core;
400 core = hwloc_get_obj_inside_cpuset_by_type(opal_hwloc_topology,
401 socket->cpuset,
402 HWLOC_OBJ_CORE, ++core_index)) {
403 if (core_index > 0) {
404 strncat(str, "/", len - strlen(str));
405 }
406
407
408 pu_index = 0;
409 for (pu = hwloc_get_obj_inside_cpuset_by_type(opal_hwloc_topology,
410 core->cpuset,
411 HWLOC_OBJ_PU, pu_index);
412 NULL != pu;
413 pu = hwloc_get_obj_inside_cpuset_by_type(opal_hwloc_topology,
414 core->cpuset,
415 HWLOC_OBJ_PU, ++pu_index)) {
416 strncat(str, ".", len - strlen(str));
417 }
418 }
419 strncat(str, "]", len - strlen(str));
420 }
421
422 return OMPI_SUCCESS;
423 }