OpenMPI 0.1.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

helper.h
Go to the documentation of this file.
1 /*
2 * Copyright © 2009 CNRS
3 * Copyright © 2009-2011 inria. All rights reserved.
4 * Copyright © 2009-2011 Université Bordeaux 1
5 * Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
6 * See COPYING in top-level directory.
7 */
8
9 /** \file
10 * \brief High-level hwloc traversal helpers.
11 */
12
13 #ifndef HWLOC_HELPER_H
14 #define HWLOC_HELPER_H
15
16 #ifndef HWLOC_H
17 #error Please include the main hwloc.h instead
18 #endif
19
20 #include <stdlib.h>
21 #include <errno.h>
22
23
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27
28
29 /** \defgroup hwlocality_helper_types Object Type Helpers
30 * @{
31 *
32 * Be sure to see the figure in \ref termsanddefs that shows a
33 * complete topology tree, including depths, child/sibling/cousin
34 * relationships, and an example of an asymmetric topology where one
35 * socket has fewer caches than its peers.
36 */
37
38 /** \brief Returns the depth of objects of type \p type or below
39 *
40 * If no object of this type is present on the underlying architecture, the
41 * function returns the depth of the first "present" object typically found
42 * inside \p type.
43 *
44 * If some objects of the given type exist in different levels, for instance
45 * L1 and L2 caches, the function returns HWLOC_TYPE_DEPTH_MULTIPLE.
46 */
47 static __hwloc_inline int __hwloc_attribute_pure
48 hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
49 {
50 int depth = hwloc_get_type_depth(topology, type);
51
52 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
53 return depth;
54
55 /* find the highest existing level with type order >= */
56 for(depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); ; depth--)
57 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
58 return depth+1;
59
60 /* Shouldn't ever happen, as there is always a SYSTEM level with lower order and known depth. */
61 /* abort(); */
62 }
63
64 /** \brief Returns the depth of objects of type \p type or above
65 *
66 * If no object of this type is present on the underlying architecture, the
67 * function returns the depth of the first "present" object typically
68 * containing \p type.
69 *
70 * If some objects of the given type exist in different levels, for instance
71 * L1 and L2 caches, the function returns HWLOC_TYPE_DEPTH_MULTIPLE.
72 */
73 static __hwloc_inline int __hwloc_attribute_pure
74 hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
75 {
76 int depth = hwloc_get_type_depth(topology, type);
77
78 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
79 return depth;
80
81 /* find the lowest existing level with type order <= */
82 for(depth = 0; ; depth++)
83 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) > 0)
84 return depth-1;
85
86 /* Shouldn't ever happen, as there is always a PU level with higher order and known depth. */
87 /* abort(); */
88 }
89
90 /** @} */
91
92
93
94 /** \defgroup hwlocality_helper_traversal_basic Basic Traversal Helpers
95 * @{
96 *
97 * Be sure to see the figure in \ref termsanddefs that shows a
98 * complete topology tree, including depths, child/sibling/cousin
99 * relationships, and an example of an asymmetric topology where one
100 * socket has fewer caches than its peers.
101 */
102
103 /** \brief Returns the top-object of the topology-tree.
104 *
105 * Its type is typically ::HWLOC_OBJ_MACHINE but it could be different
106 * for complex topologies. This function replaces the old deprecated
107 * hwloc_get_system_obj().
108 */
109 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
110 hwloc_get_root_obj (hwloc_topology_t topology)
111 {
112 return hwloc_get_obj_by_depth (topology, 0, 0);
113 }
114
115 /** \brief Returns the ancestor object of \p obj at depth \p depth. */
116 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
117 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj)
118 {
119 hwloc_obj_t ancestor = obj;
120 if (obj->depth < depth)
121 return NULL;
122 while (ancestor && ancestor->depth > depth)
123 ancestor = ancestor->parent;
124 return ancestor;
125 }
126
127 /** \brief Returns the ancestor object of \p obj with type \p type. */
128 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
129 hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj)
130 {
131 hwloc_obj_t ancestor = obj->parent;
132 while (ancestor && ancestor->type != type)
133 ancestor = ancestor->parent;
134 return ancestor;
135 }
136
137 /** \brief Returns the next object at depth \p depth.
138 *
139 * If \p prev is \c NULL, return the first object at depth \p depth.
140 */
141 static __hwloc_inline hwloc_obj_t
142 hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev)
143 {
144 if (!prev)
145 return hwloc_get_obj_by_depth (topology, depth, 0);
146 if (prev->depth != depth)
147 return NULL;
148 return prev->next_cousin;
149 }
150
151 /** \brief Returns the next object of type \p type.
152 *
153 * If \p prev is \c NULL, return the first object at type \p type. If
154 * there are multiple or no depth for given type, return \c NULL and
155 * let the caller fallback to hwloc_get_next_obj_by_depth().
156 */
157 static __hwloc_inline hwloc_obj_t
158 hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
159 hwloc_obj_t prev)
160 {
161 int depth = hwloc_get_type_depth(topology, type);
162 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
163 return NULL;
164 return hwloc_get_next_obj_by_depth (topology, depth, prev);
165 }
166
167 /** \brief Returns the object of type ::HWLOC_OBJ_PU with \p os_index.
168 *
169 * \note The \p os_index field of object should most of the times only be
170 * used for pretty-printing purpose. Type ::HWLOC_OBJ_PU is the only case
171 * where \p os_index could actually be useful, when manually binding to
172 * processors.
173 * However, using CPU sets to hide this complexity should often be preferred.
174 */
175 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
176 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
177 {
178 hwloc_obj_t obj = NULL;
179 while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
180 if (obj->os_index == os_index)
181 return obj;
182 return NULL;
183 }
184
185 /** \brief Return the next child.
186 *
187 * If \p prev is \c NULL, return the first child.
188 */
189 static __hwloc_inline hwloc_obj_t
190 hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev)
191 {
192 if (!prev)
193 return parent->first_child;
194 if (prev->parent != parent)
195 return NULL;
196 return prev->next_sibling;
197 }
198
199 /** \brief Returns the common parent object to objects lvl1 and lvl2 */
200 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
201 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2)
202 {
203 /* the loop isn't so easy since intermediate ancestors may have
204 * different depth, causing us to alternate between using obj1->parent
205 * and obj2->parent. Also, even if at some point we find ancestors of
206 * of the same depth, their ancestors may have different depth again.
207 */
208 while (obj1 != obj2) {
209 while (obj1->depth > obj2->depth)
210 obj1 = obj1->parent;
211 while (obj2->depth > obj1->depth)
212 obj2 = obj2->parent;
213 if (obj1 != obj2 && obj1->depth == obj2->depth) {
214 obj1 = obj1->parent;
215 obj2 = obj2->parent;
216 }
217 }
218 return obj1;
219 }
220
221 /** \brief Returns true if \p obj is inside the subtree beginning with \p subtree_root.
222 *
223 * \note This function assumes that both \p obj and \p subtree_root have a \p cpuset.
224 */
225 static __hwloc_inline int __hwloc_attribute_pure
226 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root)
227 {
228 return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
229 }
230
231 /** @} */
232
233
234
235 /** \defgroup hwlocality_helper_find_inside Finding Objects Inside a CPU set
236 * @{
237 */
238
239 /** \brief Get the first largest object included in the given cpuset \p set.
240 *
241 * \return the first object that is included in \p set and whose parent is not.
242 *
243 * This is convenient for iterating over all largest objects within a CPU set
244 * by doing a loop getting the first largest object and clearing its CPU set
245 * from the remaining CPU set.
246 */
247 static __hwloc_inline hwloc_obj_t
248 hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
249 {
250 hwloc_obj_t obj = hwloc_get_root_obj(topology);
251 /* FIXME: what if !root->cpuset? */
252 if (!hwloc_bitmap_intersects(obj->cpuset, set))
253 return NULL;
254 while (!hwloc_bitmap_isincluded(obj->cpuset, set)) {
255 /* while the object intersects without being included, look at its children */
256 hwloc_obj_t child = NULL;
257 while ((child = hwloc_get_next_child(topology, obj, child)) != NULL) {
258 if (child->cpuset && hwloc_bitmap_intersects(child->cpuset, set))
259 break;
260 }
261 if (!child)
262 /* no child intersects, return their father */
263 return obj;
264 /* found one intersecting child, look at its children */
265 obj = child;
266 }
267 /* obj is included, return it */
268 return obj;
269 }
270
271 /** \brief Get the set of largest objects covering exactly a given cpuset \p set
272 *
273 * \return the number of objects returned in \p objs.
274 */
275 HWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,
276 hwloc_obj_t * __hwloc_restrict objs, int max);
277
278 /** \brief Return the next object at depth \p depth included in CPU set \p set.
279 *
280 * If \p prev is \c NULL, return the first object at depth \p depth
281 * included in \p set. The next invokation should pass the previous
282 * return value in \p prev so as to obtain the next object in \p set.
283 */
284 static __hwloc_inline hwloc_obj_t
285 hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
286 unsigned depth, hwloc_obj_t prev)
287 {
288 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
289 /* no need to check next->cpuset because objects in levels always have a cpuset */
290 while (next && !hwloc_bitmap_isincluded(next->cpuset, set))
291 next = next->next_cousin;
292 return next;
293 }
294
295 /** \brief Return the next object of type \p type included in CPU set \p set.
296 *
297 * If there are multiple or no depth for given type, return \c NULL
298 * and let the caller fallback to
299 * hwloc_get_next_obj_inside_cpuset_by_depth().
300 */
301 static __hwloc_inline hwloc_obj_t
302 hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
303 hwloc_obj_type_t type, hwloc_obj_t prev)
304 {
305 int depth = hwloc_get_type_depth(topology, type);
306 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
307 return NULL;
308 return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
309 }
310
311 /** \brief Return the (logically) \p idx -th object at depth \p depth included in CPU set \p set.
312 */
313 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
314 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
315 unsigned depth, unsigned idx)
316 {
317 unsigned count = 0;
318 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
319 while (obj) {
320 /* no need to check obj->cpuset because objects in levels always have a cpuset */
321 if (hwloc_bitmap_isincluded(obj->cpuset, set)) {
322 if (count == idx)
323 return obj;
324 count++;
325 }
326 obj = obj->next_cousin;
327 }
328 return NULL;
329 }
330
331 /** \brief Return the \p idx -th object of type \p type included in CPU set \p set.
332 *
333 * If there are multiple or no depth for given type, return \c NULL
334 * and let the caller fallback to
335 * hwloc_get_obj_inside_cpuset_by_depth().
336 */
337 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
338 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
339 hwloc_obj_type_t type, unsigned idx)
340 {
341 int depth = hwloc_get_type_depth(topology, type);
342 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
343 return NULL;
344 return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
345 }
346
347 /** \brief Return the number of objects at depth \p depth included in CPU set \p set. */
348 static __hwloc_inline unsigned __hwloc_attribute_pure
349 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
350 unsigned depth)
351 {
352 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
353 int count = 0;
354 while (obj) {
355 /* no need to check obj->cpuset because objects in levels always have a cpuset */
356 if (hwloc_bitmap_isincluded(obj->cpuset, set))
357 count++;
358 obj = obj->next_cousin;
359 }
360 return count;
361 }
362
363 /** \brief Return the number of objects of type \p type included in CPU set \p set.
364 *
365 * If no object for that type exists inside CPU set \p set, 0 is
366 * returned. If there are several levels with objects of that type
367 * inside CPU set \p set, -1 is returned.
368 */
369 static __hwloc_inline int __hwloc_attribute_pure
370 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
371 hwloc_obj_type_t type)
372 {
373 int depth = hwloc_get_type_depth(topology, type);
374 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
375 return 0;
376 if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
377 return -1; /* FIXME: agregate nbobjs from different levels? */
378 return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
379 }
380
381 /** @} */
382
383
384
385 /** \defgroup hwlocality_helper_find_covering Finding a single Object covering at least CPU set
386 * @{
387 */
388
389 /** \brief Get the child covering at least CPU set \p set.
390 *
391 * \return \c NULL if no child matches or if \p set is empty.
392 */
393 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
394 hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
395 hwloc_obj_t parent)
396 {
397 hwloc_obj_t child;
398
399 if (hwloc_bitmap_iszero(set))
400 return NULL;
401
402 child = parent->first_child;
403 while (child) {
404 if (child->cpuset && hwloc_bitmap_isincluded(set, child->cpuset))
405 return child;
406 child = child->next_sibling;
407 }
408 return NULL;
409 }
410
411 /** \brief Get the lowest object covering at least CPU set \p set
412 *
413 * \return \c NULL if no object matches or if \p set is empty.
414 */
415 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
416 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
417 {
418 struct hwloc_obj *current = hwloc_get_root_obj(topology);
419
420 if (hwloc_bitmap_iszero(set))
421 return NULL;
422
423 /* FIXME: what if !root->cpuset? */
424 if (!hwloc_bitmap_isincluded(set, current->cpuset))
425 return NULL;
426
427 while (1) {
428 hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
429 if (!child)
430 return current;
431 current = child;
432 }
433 }
434
435
436 /** @} */
437
438
439
440 /** \defgroup hwlocality_helper_find_coverings Finding a set of similar Objects covering at least a CPU set
441 * @{
442 */
443
444 /** \brief Iterate through same-depth objects covering at least CPU set \p set
445 *
446 * If object \p prev is \c NULL, return the first object at depth \p
447 * depth covering at least part of CPU set \p set. The next
448 * invokation should pass the previous return value in \p prev so as
449 * to obtain the next object covering at least another part of \p set.
450 */
451 static __hwloc_inline hwloc_obj_t
452 hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,
453 unsigned depth, hwloc_obj_t prev)
454 {
455 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
456 /* no need to check next->cpuset because objects in levels always have a cpuset */
457 while (next && !hwloc_bitmap_intersects(set, next->cpuset))
458 next = next->next_cousin;
459 return next;
460 }
461
462 /** \brief Iterate through same-type objects covering at least CPU set \p set
463 *
464 * If object \p prev is \c NULL, return the first object of type \p
465 * type covering at least part of CPU set \p set. The next invokation
466 * should pass the previous return value in \p prev so as to obtain
467 * the next object of type \p type covering at least another part of
468 * \p set.
469 *
470 * If there are no or multiple depths for type \p type, \c NULL is returned.
471 * The caller may fallback to hwloc_get_next_obj_covering_cpuset_by_depth()
472 * for each depth.
473 */
474 static __hwloc_inline hwloc_obj_t
475 hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
476 hwloc_obj_type_t type, hwloc_obj_t prev)
477 {
478 int depth = hwloc_get_type_depth(topology, type);
479 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
480 return NULL;
481 return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
482 }
483
484 /** @} */
485
486
487
488 /** \defgroup hwlocality_helper_find_cache Cache-specific Finding Helpers
489 * @{
490 */
491
492 /** \brief Get the first cache covering a cpuset \p set
493 *
494 * \return \c NULL if no cache matches
495 */
496 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
497 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
498 {
499 hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
500 while (current) {
501 if (current->type == HWLOC_OBJ_CACHE)
502 return current;
503 current = current->parent;
504 }
505 return NULL;
506 }
507
508 /** \brief Get the first cache shared between an object and somebody else.
509 *
510 * \return \c NULL if no cache matches or if an invalid object is given.
511 */
512 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
513 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj)
514 {
515 hwloc_obj_t current = obj->parent;
516 if (!obj->cpuset)
517 return NULL;
518 while (current && current->cpuset) {
519 if (!hwloc_bitmap_isequal(current->cpuset, obj->cpuset)
520 && current->type == HWLOC_OBJ_CACHE)
521 return current;
522 current = current->parent;
523 }
524 return NULL;
525 }
526
527 /** @} */
528
529
530
531 /** \defgroup hwlocality_helper_traversal Advanced Traversal Helpers
532 * @{
533 *
534 * Be sure to see the figure in \ref termsanddefs that shows a
535 * complete topology tree, including depths, child/sibling/cousin
536 * relationships, and an example of an asymmetric topology where one
537 * socket has fewer caches than its peers.
538 */
539
540 /** \brief Do a depth-first traversal of the topology to find and sort
541 *
542 * all objects that are at the same depth than \p src.
543 * Report in \p objs up to \p max physically closest ones to \p src.
544 *
545 * \return the number of objects returned in \p objs.
546 *
547 * \return 0 if \p src is an I/O object.
548 */
549 /* TODO: rather provide an iterator? Provide a way to know how much should be allocated? By returning the total number of objects instead? */
550 HWLOC_DECLSPEC unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * __hwloc_restrict objs, unsigned max);
551
552 /** \brief Find an object below another object, both specified by types and indexes.
553 *
554 * Start from the top system object and find object of type \p type1
555 * and logical index \p idx1. Then look below this object and find another
556 * object of type \p type2 and logical index \p idx2. Indexes are specified
557 * within the parent, not withing the entire system.
558 *
559 * For instance, if type1 is SOCKET, idx1 is 2, type2 is CORE and idx2
560 * is 3, return the fourth core object below the third socket.
561 */
562 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
563 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
564 hwloc_obj_type_t type1, unsigned idx1,
565 hwloc_obj_type_t type2, unsigned idx2)
566 {
567 hwloc_obj_t obj;
568
569 obj = hwloc_get_obj_by_type (topology, type1, idx1);
570 if (!obj)
571 return NULL;
572
573 return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
574 }
575
576 /** \brief Find an object below a chain of objects specified by types and indexes.
577 *
578 * This is a generalized version of hwloc_get_obj_below_by_type().
579 *
580 * Arrays \p typev and \p idxv must contain \p nr types and indexes.
581 *
582 * Start from the top system object and walk the arrays \p typev and \p idxv.
583 * For each type and logical index couple in the arrays, look under the previously found
584 * object to find the index-th object of the given type.
585 * Indexes are specified within the parent, not withing the entire system.
586 *
587 * For instance, if nr is 3, typev contains NODE, SOCKET and CORE,
588 * and idxv contains 0, 1 and 2, return the third core object below
589 * the second socket below the first NUMA node.
590 */
591 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
592 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
593 {
594 hwloc_obj_t obj = hwloc_get_root_obj(topology);
595 int i;
596
597 /* FIXME: what if !root->cpuset? */
598 for(i=0; i<nr; i++) {
599 obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
600 if (!obj)
601 return NULL;
602 }
603
604 return obj;
605 }
606
607 /** @} */
608
609
610
611 /** \defgroup hwlocality_helper_binding Binding Helpers
612 * @{
613 */
614
615 /** \brief Distribute \p n items over the topology under \p root
616 *
617 * Array \p cpuset will be filled with \p n cpusets recursively distributed
618 * linearly over the topology under \p root, down to depth \p until (which can
619 * be INT_MAX to distribute down to the finest level).
620 *
621 * This is typically useful when an application wants to distribute \p n
622 * threads over a machine, giving each of them as much private cache as
623 * possible and keeping them locally in number order.
624 *
625 * The caller may typically want to also call hwloc_bitmap_singlify()
626 * before binding a thread so that it does not move at all.
627 */
628 static __hwloc_inline void
629 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *root, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until);
630 static __hwloc_inline void
631 hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
632 {
633 unsigned i;
634
635 /* FIXME: what if !root->cpuset? */
636 if (!root->arity || n == 1 || root->depth >= until) {
637 /* Got to the bottom, we can't split any more, put everything there. */
638 for (i=0; i<n; i++)
639 cpuset[i] = hwloc_bitmap_dup(root->cpuset);
640 return;
641 }
642
643 hwloc_distributev(topology, root->children, root->arity, cpuset, n, until);
644 }
645
646 /** \brief Distribute \p n items over the topology under \p roots
647 *
648 * This is the same as hwloc_distribute, but takes an array of roots instead of
649 * just one root.
650 */
651 static __hwloc_inline void
652 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
653 {
654 unsigned i;
655 unsigned tot_weight;
656 hwloc_cpuset_t *cpusetp = cpuset;
657
658 tot_weight = 0;
659 for (i = 0; i < n_roots; i++)
660 if (roots[i]->cpuset)
661 tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);
662
663 for (i = 0; i < n_roots && tot_weight; i++) {
664 /* Give to roots[i] a portion proportional to its weight */
665 unsigned weight = roots[i]->cpuset ? hwloc_bitmap_weight(roots[i]->cpuset) : 0;
666 unsigned chunk = (n * weight + tot_weight-1) / tot_weight;
667 hwloc_distribute(topology, roots[i], cpusetp, chunk, until);
668 cpusetp += chunk;
669 tot_weight -= weight;
670 n -= chunk;
671 }
672 }
673
674 /** \brief Allocate some memory on the given nodeset \p nodeset
675 *
676 * This is similar to hwloc_alloc_membind except that it is allowed to change
677 * the current memory binding policy, thus providing more binding support, at
678 * the expense of changing the current state.
679 */
680 static __hwloc_inline void *
681 hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
682 {
683 void *p = hwloc_alloc_membind_nodeset(topology, len, nodeset, policy, flags);
684 if (p)
685 return p;
686 hwloc_set_membind_nodeset(topology, nodeset, policy, flags);
687 p = hwloc_alloc(topology, len);
688 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
689 /* Enforce the binding by touching the data */
690 memset(p, 0, len);
691 return p;
692 }
693
694 /** \brief Allocate some memory on the memory nodes near given cpuset \p cpuset
695 *
696 * This is similar to hwloc_alloc_membind_policy_nodeset, but for a given cpuset.
697 */
698 static __hwloc_inline void *
699 hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t cpuset, hwloc_membind_policy_t policy, int flags)
700 {
701 void *p = hwloc_alloc_membind(topology, len, cpuset, policy, flags);
702 if (p)
703 return p;
704 hwloc_set_membind(topology, cpuset, policy, flags);
705 p = hwloc_alloc(topology, len);
706 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
707 /* Enforce the binding by touching the data */
708 memset(p, 0, len);
709 return p;
710 }
711
712 /** @} */
713
714
715
716 /** \defgroup hwlocality_helper_cpuset Cpuset Helpers
717 * @{
718 */
719 /** \brief Get complete CPU set
720 *
721 * \return the complete CPU set of logical processors of the system. If the
722 * topology is the result of a combination of several systems, NULL is
723 * returned.
724 *
725 * \note The returned cpuset is not newly allocated and should thus not be
726 * changed or freed; hwloc_cpuset_dup must be used to obtain a local copy.
727 */
728 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
729 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
730 {
731 return hwloc_get_root_obj(topology)->complete_cpuset;
732 }
733
734 /** \brief Get topology CPU set
735 *
736 * \return the CPU set of logical processors of the system for which hwloc
737 * provides topology information. This is equivalent to the cpuset of the
738 * system object. If the topology is the result of a combination of several
739 * systems, NULL is returned.
740 *
741 * \note The returned cpuset is not newly allocated and should thus not be
742 * changed or freed; hwloc_cpuset_dup must be used to obtain a local copy.
743 */
744 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
745 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
746 {
747 return hwloc_get_root_obj(topology)->cpuset;
748 }
749
750 /** \brief Get online CPU set
751 *
752 * \return the CPU set of online logical processors of the system. If the
753 * topology is the result of a combination of several systems, NULL is
754 * returned.
755 *
756 * \note The returned cpuset is not newly allocated and should thus not be
757 * changed or freed; hwloc_cpuset_dup must be used to obtain a local copy.
758 */
759 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
760 hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
761 {
762 return hwloc_get_root_obj(topology)->online_cpuset;
763 }
764
765 /** \brief Get allowed CPU set
766 *
767 * \return the CPU set of allowed logical processors of the system. If the
768 * topology is the result of a combination of several systems, NULL is
769 * returned.
770 *
771 * \note The returned cpuset is not newly allocated and should thus not be
772 * changed or freed, hwloc_cpuset_dup must be used to obtain a local copy.
773 */
774 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
775 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
776 {
777 return hwloc_get_root_obj(topology)->allowed_cpuset;
778 }
779
780 /** @} */
781
782
783
784 /** \defgroup hwlocality_helper_nodeset Nodeset Helpers
785 * @{
786 */
787 /** \brief Get complete node set
788 *
789 * \return the complete node set of memory of the system. If the
790 * topology is the result of a combination of several systems, NULL is
791 * returned.
792 *
793 * \note The returned nodeset is not newly allocated and should thus not be
794 * changed or freed; hwloc_nodeset_dup must be used to obtain a local copy.
795 */
796 static __hwloc_inline hwloc_const_nodeset_t __hwloc_attribute_pure
797 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
798 {
799 return hwloc_get_root_obj(topology)->complete_nodeset;
800 }
801
802 /** \brief Get topology node set
803 *
804 * \return the node set of memory of the system for which hwloc
805 * provides topology information. This is equivalent to the nodeset of the
806 * system object. If the topology is the result of a combination of several
807 * systems, NULL is returned.
808 *
809 * \note The returned nodeset is not newly allocated and should thus not be
810 * changed or freed; hwloc_nodeset_dup must be used to obtain a local copy.
811 */
812 static __hwloc_inline hwloc_const_nodeset_t __hwloc_attribute_pure
813 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
814 {
815 return hwloc_get_root_obj(topology)->nodeset;
816 }
817
818 /** \brief Get allowed node set
819 *
820 * \return the node set of allowed memory of the system. If the
821 * topology is the result of a combination of several systems, NULL is
822 * returned.
823 *
824 * \note The returned nodeset is not newly allocated and should thus not be
825 * changed or freed, hwloc_nodeset_dup must be used to obtain a local copy.
826 */
827 static __hwloc_inline hwloc_const_nodeset_t __hwloc_attribute_pure
828 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
829 {
830 return hwloc_get_root_obj(topology)->allowed_nodeset;
831 }
832
833 /** @} */
834
835
836
837 /** \defgroup hwlocality_helper_nodeset_convert Conversion between cpuset and nodeset
838 *
839 * There are two semantics for converting cpusets to nodesets depending on how
840 * non-NUMA machines are handled.
841 *
842 * When manipulating nodesets for memory binding, non-NUMA machines should be
843 * considered as having a single NUMA node. The standard conversion routines
844 * below should be used so that marking the first bit of the nodeset means
845 * that memory should be bound to a non-NUMA whole machine.
846 *
847 * When manipulating nodesets as an actual list of NUMA nodes without any
848 * need to handle memory binding on non-NUMA machines, the strict conversion
849 * routines may be used instead.
850 * @{
851 */
852
853 /** \brief Convert a CPU set into a NUMA node set and handle non-NUMA cases
854 *
855 * If some NUMA nodes have no CPUs at all, this function never sets their
856 * indexes in the output node set, even if a full CPU set is given in input.
857 *
858 * If the topology contains no NUMA nodes, the machine is considered
859 * as a single memory node, and the following behavior is used:
860 * If \p cpuset is empty, \p nodeset will be emptied as well.
861 * Otherwise \p nodeset will be entirely filled.
862 */
863 static __hwloc_inline void
864 hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
865 {
866 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
867 hwloc_obj_t obj;
868
869 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
870 if (hwloc_bitmap_iszero(cpuset))
871 hwloc_bitmap_zero(nodeset);
872 else
873 /* Assume the whole system */
874 hwloc_bitmap_fill(nodeset);
875 return;
876 }
877
878 hwloc_bitmap_zero(nodeset);
879 obj = NULL;
880 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
881 hwloc_bitmap_set(nodeset, obj->os_index);
882 }
883
884 /** \brief Convert a CPU set into a NUMA node set without handling non-NUMA cases
885 *
886 * This is the strict variant of ::hwloc_cpuset_to_nodeset. It does not fix
887 * non-NUMA cases. If the topology contains some NUMA nodes, behave exactly
888 * the same. However, if the topology contains no NUMA nodes, return an empty
889 * nodeset.
890 */
891 static __hwloc_inline void
892 hwloc_cpuset_to_nodeset_strict(struct hwloc_topology *topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
893 {
894 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
895 hwloc_obj_t obj;
896 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
897 return;
898 hwloc_bitmap_zero(nodeset);
899 obj = NULL;
900 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
901 hwloc_bitmap_set(nodeset, obj->os_index);
902 }
903
904 /** \brief Convert a NUMA node set into a CPU set and handle non-NUMA cases
905 *
906 * If the topology contains no NUMA nodes, the machine is considered
907 * as a single memory node, and the following behavior is used:
908 * If \p nodeset is empty, \p cpuset will be emptied as well.
909 * Otherwise \p cpuset will be entirely filled.
910 * This is useful for manipulating memory binding sets.
911 */
912 static __hwloc_inline void
913 hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
914 {
915 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
916 hwloc_obj_t obj;
917
918 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) {
919 if (hwloc_bitmap_iszero(nodeset))
920 hwloc_bitmap_zero(cpuset);
921 else
922 /* Assume the whole system */
923 hwloc_bitmap_fill(cpuset);
924 return;
925 }
926
927 hwloc_bitmap_zero(cpuset);
928 obj = NULL;
929 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
930 if (hwloc_bitmap_isset(nodeset, obj->os_index))
931 /* no need to check obj->cpuset because objects in levels always have a cpuset */
932 hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
933 }
934 }
935
936 /** \brief Convert a NUMA node set into a CPU set without handling non-NUMA cases
937 *
938 * This is the strict variant of ::hwloc_cpuset_from_nodeset. It does not fix
939 * non-NUMA cases. If the topology contains some NUMA nodes, behave exactly
940 * the same. However, if the topology contains no NUMA nodes, return an empty
941 * cpuset.
942 */
943 static __hwloc_inline void
944 hwloc_cpuset_from_nodeset_strict(struct hwloc_topology *topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
945 {
946 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
947 hwloc_obj_t obj;
948 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
949 return;
950 hwloc_bitmap_zero(cpuset);
951 obj = NULL;
952 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL)
953 if (hwloc_bitmap_isset(nodeset, obj->os_index))
954 /* no need to check obj->cpuset because objects in levels always have a cpuset */
955 hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
956 }
957
958 /** @} */
959
960
961
962 /** \defgroup hwlocality_distances Distances
963 * @{
964 */
965
966 /** \brief Get the distances between all objects at the given depth.
967 *
968 * \return a distances structure containing a matrix with all distances
969 * between all objects at the given depth.
970 *
971 * Slot i+nbobjs*j contains the distance from the object of logical index i
972 * the object of logical index j.
973 *
974 * \note This function only returns matrices covering the whole topology,
975 * without any unknown distance value. Those matrices are available in
976 * top-level object of the hierarchy. Matrices of lower objects are not
977 * reported here since they cover only part of the machine.
978 *
979 * The returned structure belongs to the hwloc library. The caller should
980 * not modify or free it.
981 *
982 * \return \c NULL if no such distance matrix exists.
983 */
984
985 static __hwloc_inline const struct hwloc_distances_s *
986 hwloc_get_whole_distance_matrix_by_depth(hwloc_topology_t topology, unsigned depth)
987 {
988 hwloc_obj_t root = hwloc_get_root_obj(topology);
989 unsigned i;
990 for(i=0; i<root->distances_count; i++)
991 if (root->distances[i]->relative_depth == depth)
992 return root->distances[i];
993 return NULL;
994 }
995
996 /** \brief Get the distances between all objects of a given type.
997 *
998 * \return a distances structure containing a matrix with all distances
999 * between all objects of the given type.
1000 *
1001 * Slot i+nbobjs*j contains the distance from the object of logical index i
1002 * the object of logical index j.
1003 *
1004 * \note This function only returns matrices covering the whole topology,
1005 * without any unknown distance value. Those matrices are available in
1006 * top-level object of the hierarchy. Matrices of lower objects are not
1007 * reported here since they cover only part of the machine.
1008 *
1009 * The returned structure belongs to the hwloc library. The caller should
1010 * not modify or free it.
1011 *
1012 * \return \c NULL if no such distance matrix exists.
1013 */
1014
1015 static __hwloc_inline const struct hwloc_distances_s *
1016 hwloc_get_whole_distance_matrix_by_type(hwloc_topology_t topology, hwloc_obj_type_t type)
1017 {
1018 int depth = hwloc_get_type_depth(topology, type);
1019 if (depth < 0)
1020 return NULL;
1021 return hwloc_get_whole_distance_matrix_by_depth(topology, depth);
1022 }
1023
1024 /** \brief Get distances for the given depth and covering some objects
1025 *
1026 * Return a distance matrix that describes depth \p depth and covers at
1027 * least object \p obj and all its children.
1028 *
1029 * When looking for the distance between some objects, a common ancestor should
1030 * be passed in \p obj.
1031 *
1032 * \p firstp is set to logical index of the first object described by the matrix.
1033 *
1034 * The returned structure belongs to the hwloc library. The caller should
1035 * not modify or free it.
1036 */
1037 static __hwloc_inline const struct hwloc_distances_s *
1038 hwloc_get_distance_matrix_covering_obj_by_depth(hwloc_topology_t topology,
1039 hwloc_obj_t obj, unsigned depth,
1040 unsigned *firstp)
1041 {
1042 while (obj && obj->cpuset) {
1043 unsigned i;
1044 for(i=0; i<obj->distances_count; i++)
1045 if (obj->distances[i]->relative_depth == depth - obj->depth) {
1046 if (!obj->distances[i]->nbobjs)
1047 continue;
1048 *firstp = hwloc_get_next_obj_inside_cpuset_by_depth(topology, obj->cpuset, depth, NULL)->logical_index;
1049 return obj->distances[i];
1050 }
1051 obj = obj->parent;
1052 }
1053 return NULL;
1054 }
1055
1056 /** \brief Get the latency in both directions between two objects.
1057 *
1058 * Look at ancestor objects from the bottom to the top until one of them
1059 * contains a distance matrix that matches the objects exactly.
1060 *
1061 * \p latency gets the value from object \p obj1 to \p obj2, while
1062 * \p reverse_latency gets the reverse-direction value, which
1063 * may be different on some architectures.
1064 *
1065 * \return -1 if no ancestor contains a matching latency matrix.
1066 */
1067 static __hwloc_inline int
1068 hwloc_get_latency(hwloc_topology_t topology,
1069 hwloc_obj_t obj1, hwloc_obj_t obj2,
1070 float *latency, float *reverse_latency)
1071 {
1072 hwloc_obj_t ancestor;
1073 const struct hwloc_distances_s * distances;
1074 unsigned first_logical ;
1075
1076 if (obj1->depth != obj2->depth) {
1077 errno = EINVAL;
1078 return -1;
1079 }
1080
1081 ancestor = hwloc_get_common_ancestor_obj(topology, obj1, obj2);
1082 distances = hwloc_get_distance_matrix_covering_obj_by_depth(topology, ancestor, obj1->depth, &first_logical);
1083 if (distances && distances->latency) {
1084 const float * latency_matrix = distances->latency;
1085 unsigned nbobjs = distances->nbobjs;
1086 unsigned l1 = obj1->logical_index - first_logical;
1087 unsigned l2 = obj2->logical_index - first_logical;
1088 *latency = latency_matrix[l1*nbobjs+l2];
1089 *reverse_latency = latency_matrix[l2*nbobjs+l1];
1090 return 0;
1091 }
1092
1093 errno = ENOSYS;
1094 return -1;
1095 }
1096
1097 /** @} */
1098
1099
1100
1101 /** \defgroup hwlocality_advanced_io Advanced I/O object traversal helpers
1102 * @{
1103 */
1104
1105 /** \brief Get the first non-I/O ancestor object.
1106 *
1107 * Given the I/O object \p ioobj, find the smallest non-I/O ancestor
1108 * object. This regular object may then be used for binding because
1109 * its locality is the same as \p ioobj.
1110 */
1111 static __hwloc_inline hwloc_obj_t
1112 hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused,
1113 hwloc_obj_t ioobj)
1114 {
1115 hwloc_obj_t obj = ioobj;
1116 while (obj && !obj->cpuset) {
1117 obj = obj->parent;
1118 }
1119 return obj;
1120 }
1121
1122 /** \brief Get the next PCI device in the system.
1123 *
1124 * \return the first PCI device if \p prev is \c NULL.
1125 */
1126 static __hwloc_inline hwloc_obj_t
1127 hwloc_get_next_pcidev(hwloc_topology_t topology, hwloc_obj_t prev)
1128 {
1129 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PCI_DEVICE, prev);
1130 }
1131
1132 /** \brief Find the PCI device object matching the PCI bus id
1133 * given domain, bus device and function PCI bus id.
1134 */
1135 static __hwloc_inline hwloc_obj_t
1136 hwloc_get_pcidev_by_busid(hwloc_topology_t topology,
1137 unsigned domain, unsigned bus, unsigned dev, unsigned func)
1138 {
1139 hwloc_obj_t obj = NULL;
1140 while ((obj = hwloc_get_next_pcidev(topology, obj)) != NULL) {
1141 if (obj->attr->pcidev.domain == domain
1142 && obj->attr->pcidev.bus == bus
1143 && obj->attr->pcidev.dev == dev
1144 && obj->attr->pcidev.func == func)
1145 return obj;
1146 }
1147 return NULL;
1148 }
1149
1150 /** \brief Find the PCI device object matching the PCI bus id
1151 * given as a string xxxx:yy:zz.t or yy:zz.t.
1152 */
1153 static __hwloc_inline hwloc_obj_t
1154 hwloc_get_pcidev_by_busidstring(hwloc_topology_t topology, const char *busid)
1155 {
1156 unsigned domain = 0; /* default */
1157 unsigned bus, dev, func;
1158
1159 if (sscanf(busid, "%x:%x.%x", &bus, &dev, &func) != 3
1160 && sscanf(busid, "%x:%x:%x.%x", &domain, &bus, &dev, &func) != 4) {
1161 errno = EINVAL;
1162 return NULL;
1163 }
1164
1165 return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, func);
1166 }
1167
1168 /** \brief Get the next OS device in the system.
1169 *
1170 * \return the first OS device if \p prev is \c NULL.
1171 */
1172 static __hwloc_inline hwloc_obj_t
1173 hwloc_get_next_osdev(hwloc_topology_t topology, hwloc_obj_t prev)
1174 {
1175 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_OS_DEVICE, prev);
1176 }
1177
1178 /** \brief Get the next bridge in the system.
1179 *
1180 * \return the first bridge if \p prev is \c NULL.
1181 */
1182 static __hwloc_inline hwloc_obj_t
1183 hwloc_get_next_bridge(hwloc_topology_t topology, hwloc_obj_t prev)
1184 {
1185 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_BRIDGE, prev);
1186 }
1187
1188 /* \brief Checks whether a given bridge covers a given PCI bus.
1189 */
1190 static __hwloc_inline int
1191 hwloc_bridge_covers_pcibus(hwloc_obj_t bridge,
1192 unsigned domain, unsigned bus)
1193 {
1194 return bridge->type == HWLOC_OBJ_BRIDGE
1195 && bridge->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI
1196 && bridge->attr->bridge.downstream.pci.domain == domain
1197 && bridge->attr->bridge.downstream.pci.secondary_bus <= bus
1198 && bridge->attr->bridge.downstream.pci.subordinate_bus >= bus;
1199 }
1200
1201 /** \brief Find the hostbridge that covers the given PCI bus.
1202 *
1203 * This is useful for finding the locality of a bus because
1204 * it is the hostbridge parent cpuset.
1205 */
1206 static __hwloc_inline hwloc_obj_t
1207 hwloc_get_hostbridge_by_pcibus(hwloc_topology_t topology,
1208 unsigned domain, unsigned bus)
1209 {
1210 hwloc_obj_t obj = NULL;
1211 while ((obj = hwloc_get_next_bridge(topology, obj)) != NULL) {
1212 if (hwloc_bridge_covers_pcibus(obj, domain, bus)) {
1213 /* found bridge covering this pcibus, make sure it's a hostbridge */
1214 assert(obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_HOST);
1215 assert(obj->parent->type != HWLOC_OBJ_BRIDGE);
1216 assert(obj->parent->cpuset);
1217 return obj;
1218 }
1219 }
1220 return NULL;
1221 }
1222
1223 /** @} */
1224
1225
1226
1227 #ifdef __cplusplus
1228 } /* extern "C" */
1229 #endif
1230
1231
1232 #endif /* HWLOC_HELPER_H */
hwloc_bitmap_zero
HWLOC_DECLSPEC void hwloc_bitmap_zero(hwloc_bitmap_t bitmap)
Empty the bitmap bitmap.
hwloc_get_next_child
static __hwloc_inline hwloc_obj_t hwloc_get_next_child(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev)
Return the next child.
Definition: helper.h:190
HWLOC_OBJ_BRIDGE_HOST
Host-side of a bridge, only possible upstream.
Definition: hwloc.h:257
HWLOC_OBJ_CACHE
Data cache.
Definition: hwloc.h:192
hwloc_obj::os_index
unsigned os_index
OS-provided physical index number.
Definition: hwloc.h:332
hwloc_bitmap_iszero
HWLOC_DECLSPEC int hwloc_bitmap_iszero(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure
Test whether bitmap bitmap is empty.
hwloc_distances_s
Distances between objects.
Definition: hwloc.h:522
HWLOC_OBJ_OS_DEVICE
Operating system device.
Definition: hwloc.h:237
hwloc_distances_s::nbobjs
unsigned nbobjs
Number of objects considered in the matrix.
Definition: hwloc.h:525
hwloc_get_shared_cache_covering_obj
static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure hwloc_get_shared_cache_covering_obj(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj)
Get the first cache shared between an object and somebody else.
Definition: helper.h:513
HWLOC_MEMBIND_FIRSTTOUCH
Allocate memory but do not immediately bind it to a specific locality.
Definition: hwloc.h:1482
hwloc_obj::next_sibling
struct hwloc_obj * next_sibling
Next object below the same parent.
Definition: hwloc.h:353
hwloc_bitmap_dup
HWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_dup(hwloc_const_bitmap_t bitmap) __hwloc_attribute_malloc
Duplicate bitmap bitmap by allocating a new bitmap and copying bitmap contents.
hwloc_obj::allowed_cpuset
hwloc_cpuset_t allowed_cpuset
The CPU set of allowed logical processors.
Definition: hwloc.h:398
hwloc_topology_get_topology_nodeset
static __hwloc_inline hwloc_const_nodeset_t __hwloc_attribute_pure hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
Get topology node set.
Definition: helper.h:813
hwloc_get_whole_distance_matrix_by_depth
static __hwloc_inline const struct hwloc_distances_s * hwloc_get_whole_distance_matrix_by_depth(hwloc_topology_t topology, unsigned depth)
Get the distances between all objects at the given depth.
Definition: helper.h:986
hwloc_get_ancestor_obj_by_type
static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure hwloc_get_ancestor_obj_by_type(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj)
Returns the ancestor object of obj with type type.
Definition: helper.h:129
hwloc_obj::first_child
struct hwloc_obj * first_child
First child.
Definition: hwloc.h:359
hwloc_get_pcidev_by_busid
static __hwloc_inline hwloc_obj_t hwloc_get_pcidev_by_busid(hwloc_topology_t topology, unsigned domain, unsigned bus, unsigned dev, unsigned func)
Find the PCI device object matching the PCI bus id given domain, bus device and function PCI bus id...
Definition: helper.h:1136
hwloc_obj::parent
struct hwloc_obj * parent
Parent, NULL if root (system object)
Definition: hwloc.h:351
hwloc_get_obj_covering_cpuset
static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure hwloc_get_obj_covering_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
Get the lowest object covering at least CPU set set.
Definition: helper.h:416
hwloc_obj::online_cpuset
hwloc_cpuset_t online_cpuset
The CPU set of online logical processors.
Definition: hwloc.h:390
hwloc_bitmap_isincluded
HWLOC_DECLSPEC int hwloc_bitmap_isincluded(hwloc_const_bitmap_t sub_bitmap, hwloc_const_bitmap_t super_bitmap) __hwloc_attribute_pure
Test whether bitmap sub_bitmap is part of bitmap super_bitmap.
hwloc_obj::complete_cpuset
hwloc_cpuset_t complete_cpuset
The complete CPU set of logical processors of this object,.
Definition: hwloc.h:379
hwloc_topology_get_complete_nodeset
static __hwloc_inline hwloc_const_nodeset_t __hwloc_attribute_pure hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
Get complete node set.
Definition: helper.h:797
hwloc_obj::type
hwloc_obj_type_t type
Type of object.
Definition: hwloc.h:331
hwloc_set_membind_nodeset
HWLOC_DECLSPEC int hwloc_set_membind_nodeset(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
Set the default memory binding policy of the current process or thread to prefer the NUMA node(s) spe...
Definition: bind.c:260
HWLOC_TYPE_DEPTH_MULTIPLE
Objects of given type exist at different depth in the topology.
Definition: hwloc.h:1046
hwloc_get_nbobjs_inside_cpuset_by_type
static __hwloc_inline int __hwloc_attribute_pure hwloc_get_nbobjs_inside_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_obj_type_t type)
Return the number of objects of type type included in CPU set set.
Definition: helper.h:370
hwloc_get_distance_matrix_covering_obj_by_depth
static __hwloc_inline const struct hwloc_distances_s * hwloc_get_distance_matrix_covering_obj_by_depth(hwloc_topology_t topology, hwloc_obj_t obj, unsigned depth, unsigned *firstp)
Get distances for the given depth and covering some objects.
Definition: helper.h:1038
HWLOC_OBJ_BRIDGE
Bridge.
Definition: hwloc.h:225
hwloc_obj::nodeset
hwloc_nodeset_t nodeset
NUMA nodes covered by this object or containing this object.
Definition: hwloc.h:409
hwloc_bitmap_isset
HWLOC_DECLSPEC int hwloc_bitmap_isset(hwloc_const_bitmap_t bitmap, unsigned id) __hwloc_attribute_pure
Test whether index id is part of bitmap bitmap.
hwloc_topology_get_complete_cpuset
static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
Get complete CPU set.
Definition: helper.h:729
hwloc_get_next_pcidev
static __hwloc_inline hwloc_obj_t hwloc_get_next_pcidev(hwloc_topology_t topology, hwloc_obj_t prev)
Get the next PCI device in the system.
Definition: helper.h:1127
hwloc_cpuset_from_nodeset_strict
static __hwloc_inline void hwloc_cpuset_from_nodeset_strict(struct hwloc_topology *topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
Convert a NUMA node set into a CPU set without handling non-NUMA cases.
Definition: helper.h:944
hwloc_get_next_obj_inside_cpuset_by_type
static __hwloc_inline hwloc_obj_t hwloc_get_next_obj_inside_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_obj_type_t type, hwloc_obj_t prev)
Return the next object of type type included in CPU set set.
Definition: helper.h:302
hwloc_compare_types
HWLOC_DECLSPEC int hwloc_compare_types(hwloc_obj_type_t type1, hwloc_obj_type_t type2) __hwloc_attribute_const
Compare the depth of two object types.
Definition: topology.c:384
hwloc_get_child_covering_cpuset
static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure hwloc_get_child_covering_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set, hwloc_obj_t parent)
Get the child covering at least CPU set set.
Definition: helper.h:394
hwloc_obj::children
struct hwloc_obj ** children
Children, children[0 .
Definition: hwloc.h:358
hwloc_get_next_obj_covering_cpuset_by_type
static __hwloc_inline hwloc_obj_t hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_obj_type_t type, hwloc_obj_t prev)
Iterate through same-type objects covering at least CPU set set.
Definition: helper.h:475
hwloc_obj
Structure of a topology object.
Definition: hwloc.h:329
hwloc_obj::next_cousin
struct hwloc_obj * next_cousin
Next object of same type and depth.
Definition: hwloc.h:347
hwloc_distances_s::latency
float * latency
Matrix of latencies between objects, stored as a one-dimension array.
Definition: hwloc.h:530
hwloc_distances_s::relative_depth
unsigned relative_depth
Relative depth of the considered objects below the object containing this distance information...
Definition: hwloc.h:523
hwloc_get_nbobjs_inside_cpuset_by_depth
static __hwloc_inline unsigned __hwloc_attribute_pure hwloc_get_nbobjs_inside_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set, unsigned depth)
Return the number of objects at depth depth included in CPU set set.
Definition: helper.h:349
hwloc_alloc_membind
HWLOC_DECLSPEC void * hwloc_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t cpuset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_malloc
Allocate some memory on memory nodes near the given physical cpuset cpuset.
Definition: bind.c:532
hwloc_get_cache_covering_cpuset
static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure hwloc_get_cache_covering_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
Get the first cache covering a cpuset set.
Definition: helper.h:497
hwloc_obj_is_in_subtree
static __hwloc_inline int __hwloc_attribute_pure hwloc_obj_is_in_subtree(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root)
Returns true if obj is inside the subtree beginning with subtree_root.
Definition: helper.h:226
hwloc_get_hostbridge_by_pcibus
static __hwloc_inline hwloc_obj_t hwloc_get_hostbridge_by_pcibus(hwloc_topology_t topology, unsigned domain, unsigned bus)
Find the hostbridge that covers the given PCI bus.
Definition: helper.h:1207
hwloc_bitmap_isequal
HWLOC_DECLSPEC int hwloc_bitmap_isequal(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure
Test whether bitmap bitmap1 is equal to bitmap bitmap2.
hwloc_get_next_obj_by_depth
static __hwloc_inline hwloc_obj_t hwloc_get_next_obj_by_depth(hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev)
Returns the next object at depth depth.
Definition: helper.h:142
hwloc_get_common_ancestor_obj
static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure hwloc_get_common_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2)
Returns the common parent object to objects lvl1 and lvl2.
Definition: helper.h:201
hwloc_get_depth_type
HWLOC_DECLSPEC hwloc_obj_type_t hwloc_get_depth_type(hwloc_topology_t topology, unsigned depth) __hwloc_attribute_pure
Returns the type of objects at depth depth.
Definition: traversal.c:22
hwloc_topology_get_online_cpuset
static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
Get online CPU set.
Definition: helper.h:760
hwloc_get_whole_distance_matrix_by_type
static __hwloc_inline const struct hwloc_distances_s * hwloc_get_whole_distance_matrix_by_type(hwloc_topology_t topology, hwloc_obj_type_t type)
Get the distances between all objects of a given type.
Definition: helper.h:1016
hwloc_get_largest_objs_inside_cpuset
HWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_obj_t *__hwloc_restrict objs, int max)
Get the set of largest objects covering exactly a given cpuset set.
hwloc_get_type_or_above_depth
static __hwloc_inline int __hwloc_attribute_pure hwloc_get_type_or_above_depth(hwloc_topology_t topology, hwloc_obj_type_t type)
Returns the depth of objects of type type or above.
Definition: helper.h:74
hwloc_alloc_membind_nodeset
HWLOC_DECLSPEC void * hwloc_alloc_membind_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_malloc
Allocate some memory on the given physical nodeset nodeset.
Definition: bind.c:495
hwloc_bitmap_intersects
HWLOC_DECLSPEC int hwloc_bitmap_intersects(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure
Test whether bitmaps bitmap1 and bitmap2 intersects.
hwloc_get_root_obj
static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure hwloc_get_root_obj(hwloc_topology_t topology)
Returns the top-object of the topology-tree.
Definition: helper.h:110
hwloc_obj::logical_index
unsigned logical_index
Horizontal index in the whole list of similar objects, could be a "cousin_rank" since it's the rank w...
Definition: hwloc.h:342
HWLOC_OBJ_PCI_DEVICE
PCI device.
Definition: hwloc.h:232
HWLOC_OBJ_NODE
NUMA node.
Definition: hwloc.h:184
hwloc_get_obj_below_array_by_type
static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure hwloc_get_obj_below_array_by_type(hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
Find an object below a chain of objects specified by types and indexes.
Definition: helper.h:592
hwloc_obj::complete_nodeset
hwloc_nodeset_t complete_nodeset
The complete NUMA node set of this object,.
Definition: hwloc.h:426
hwloc_get_obj_inside_cpuset_by_depth
static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure hwloc_get_obj_inside_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set, unsigned depth, unsigned idx)
Return the (logically) idx -th object at depth depth included in CPU set set.
Definition: helper.h:314
hwloc_topology_get_allowed_nodeset
static __hwloc_inline hwloc_const_nodeset_t __hwloc_attribute_pure hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
Get allowed node set.
Definition: helper.h:828
HWLOC_TYPE_DEPTH_UNKNOWN
No object of given type exists in the topology.
Definition: hwloc.h:1045
hwloc_obj::arity
unsigned arity
Number of children.
Definition: hwloc.h:357
hwloc_get_next_obj_by_type
static __hwloc_inline hwloc_obj_t hwloc_get_next_obj_by_type(hwloc_topology_t topology, hwloc_obj_type_t type, hwloc_obj_t prev)
Returns the next object of type type.
Definition: helper.h:158
hwloc_alloc_membind_policy
static __hwloc_inline void * hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t cpuset, hwloc_membind_policy_t policy, int flags)
Allocate some memory on the memory nodes near given cpuset cpuset.
Definition: helper.h:699
hwloc_get_obj_by_type
static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure hwloc_get_obj_by_type(hwloc_topology_t topology, hwloc_obj_type_t type, unsigned idx)
Returns the topology object at logical index idx with type type.
Definition: hwloc.h:1110
hwloc_get_latency
static __hwloc_inline int hwloc_get_latency(hwloc_topology_t topology, hwloc_obj_t obj1, hwloc_obj_t obj2, float *latency, float *reverse_latency)
Get the latency in both directions between two objects.
Definition: helper.h:1068
hwloc_get_next_obj_inside_cpuset_by_depth
static __hwloc_inline hwloc_obj_t hwloc_get_next_obj_inside_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set, unsigned depth, hwloc_obj_t prev)
Return the next object at depth depth included in CPU set set.
Definition: helper.h:285
hwloc_distributev
static __hwloc_inline void hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *root, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
Distribute n items over the topology under root.
Definition: helper.h:652
hwloc_get_type_or_below_depth
static __hwloc_inline int __hwloc_attribute_pure hwloc_get_type_or_below_depth(hwloc_topology_t topology, hwloc_obj_type_t type)
Returns the depth of objects of type type or below.
Definition: helper.h:48
hwloc_get_obj_inside_cpuset_by_type
static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure hwloc_get_obj_inside_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_obj_type_t type, unsigned idx)
Return the idx -th object of type type included in CPU set set.
Definition: helper.h:338
hwloc_get_pcidev_by_busidstring
static __hwloc_inline hwloc_obj_t hwloc_get_pcidev_by_busidstring(hwloc_topology_t topology, const char *busid)
Find the PCI device object matching the PCI bus id given as a string xxxx:yy:zz.t or yy:zz...
Definition: helper.h:1154
hwloc_alloc
HWLOC_DECLSPEC void * hwloc_alloc(hwloc_topology_t topology, size_t len)
Allocate some memory.
Definition: bind.c:487
hwloc_get_closest_objs
HWLOC_DECLSPEC unsigned hwloc_get_closest_objs(hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t *__hwloc_restrict objs, unsigned max)
Do a depth-first traversal of the topology to find and sort.
hwloc_get_next_osdev
static __hwloc_inline hwloc_obj_t hwloc_get_next_osdev(hwloc_topology_t topology, hwloc_obj_t prev)
Get the next OS device in the system.
Definition: helper.h:1173
hwloc_obj_type_t
hwloc_obj_type_t
Type of topology object.
Definition: hwloc.h:164
hwloc_bitmap_fill
HWLOC_DECLSPEC void hwloc_bitmap_fill(hwloc_bitmap_t bitmap)
Fill bitmap bitmap with all possible indexes (even if those objects don't exist or are otherwise unav...
HWLOC_OBJ_BRIDGE_PCI
PCI-side of a bridge.
Definition: hwloc.h:258
hwloc_bitmap_set
HWLOC_DECLSPEC void hwloc_bitmap_set(hwloc_bitmap_t bitmap, unsigned id)
Add index id in bitmap bitmap.
hwloc_get_next_bridge
static __hwloc_inline hwloc_obj_t hwloc_get_next_bridge(hwloc_topology_t topology, hwloc_obj_t prev)
Get the next bridge in the system.
Definition: helper.h:1183
hwloc_bitmap_or
HWLOC_DECLSPEC void hwloc_bitmap_or(hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2)
Or bitmaps bitmap1 and bitmap2 and store the result in bitmap res.
hwloc_cpuset_to_nodeset
static __hwloc_inline void hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
Convert a CPU set into a NUMA node set and handle non-NUMA cases.
Definition: helper.h:864
hwloc_get_first_largest_obj_inside_cpuset
static __hwloc_inline hwloc_obj_t hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
Get the first largest object included in the given cpuset set.
Definition: helper.h:248
hwloc_topology_get_allowed_cpuset
static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
Get allowed CPU set.
Definition: helper.h:775
hwloc_cpuset_to_nodeset_strict
static __hwloc_inline void hwloc_cpuset_to_nodeset_strict(struct hwloc_topology *topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
Convert a CPU set into a NUMA node set without handling non-NUMA cases.
Definition: helper.h:892
hwloc_obj::cpuset
hwloc_cpuset_t cpuset
CPUs covered by this object.
Definition: hwloc.h:366
hwloc_get_pu_obj_by_os_index
static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
Returns the object of type HWLOC_OBJ_PU with os_index.
Definition: helper.h:176
hwloc_bitmap_weight
HWLOC_DECLSPEC int hwloc_bitmap_weight(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure
Compute the "weight" of bitmap bitmap (i.e., number of indexes that are in the bitmap).
hwloc_membind_policy_t
hwloc_membind_policy_t
Memory binding policy.
Definition: hwloc.h:1479
hwloc_topology_get_topology_cpuset
static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
Get topology CPU set.
Definition: helper.h:745
hwloc_get_obj_by_depth
HWLOC_DECLSPEC hwloc_obj_t hwloc_get_obj_by_depth(hwloc_topology_t topology, unsigned depth, unsigned idx) __hwloc_attribute_pure
Returns the topology object at logical index idx from depth depth.
hwloc_obj::attr
union hwloc_obj_attr_u * attr
Object type-specific Attributes, may be NULL if no attribute value was found.
Definition: hwloc.h:337
hwloc_get_non_io_ancestor_obj
static __hwloc_inline hwloc_obj_t hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t ioobj)
Get the first non-I/O ancestor object.
Definition: helper.h:1112
hwloc_topology
Definition: private.h:56
hwloc_set_membind
HWLOC_DECLSPEC int hwloc_set_membind(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, hwloc_membind_policy_t policy, int flags)
Set the default memory binding policy of the current process or thread to prefer the NUMA node(s) nea...
Definition: bind.c:284
hwloc_obj::allowed_nodeset
hwloc_nodeset_t allowed_nodeset
The set of allowed NUMA memory nodes.
Definition: hwloc.h:440
HWLOC_OBJ_PU
Processing Unit, or (Logical) Processor.
Definition: hwloc.h:199
hwloc_obj::distances
struct hwloc_distances_s ** distances
Distances between all objects at same depth below this object.
Definition: hwloc.h:453
hwloc_get_ancestor_obj_by_depth
static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure hwloc_get_ancestor_obj_by_depth(hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj)
Returns the ancestor object of obj at depth depth.
Definition: helper.h:117
hwloc_alloc_membind_policy_nodeset
static __hwloc_inline void * hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
Allocate some memory on the given nodeset nodeset.
Definition: helper.h:681
hwloc_cpuset_from_nodeset
static __hwloc_inline void hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
Convert a NUMA node set into a CPU set and handle non-NUMA cases.
Definition: helper.h:913
hwloc_bitmap_s
Definition: cpuset.c:38
hwloc_get_type_depth
HWLOC_DECLSPEC int hwloc_get_type_depth(hwloc_topology_t topology, hwloc_obj_type_t type)
Returns the depth of objects of type type.
hwloc_obj::depth
unsigned depth
Vertical index in the hierarchy.
Definition: hwloc.h:341
hwloc_get_obj_below_by_type
static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure hwloc_get_obj_below_by_type(hwloc_topology_t topology, hwloc_obj_type_t type1, unsigned idx1, hwloc_obj_type_t type2, unsigned idx2)
Find an object below another object, both specified by types and indexes.
Definition: helper.h:563
hwloc_get_next_obj_covering_cpuset_by_depth
static __hwloc_inline hwloc_obj_t hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set, unsigned depth, hwloc_obj_t prev)
Iterate through same-depth objects covering at least CPU set set.
Definition: helper.h:452