OpenMPI  0.1.1
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
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
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
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
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
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
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  */
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
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
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
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
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
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
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
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
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
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
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
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
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 *
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 *
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
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
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
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
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
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
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
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
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
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
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
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 *
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 *
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 *
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
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
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
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
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
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
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
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_DECLSPEC void hwloc_bitmap_zero(hwloc_bitmap_t bitmap)
Empty the bitmap bitmap.
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
Host-side of a bridge, only possible upstream.
Definition: hwloc.h:257
Data cache.
Definition: hwloc.h:192
unsigned os_index
OS-provided physical index number.
Definition: hwloc.h:332
HWLOC_DECLSPEC int hwloc_bitmap_iszero(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure
Test whether bitmap bitmap is empty.
Distances between objects.
Definition: hwloc.h:522
Operating system device.
Definition: hwloc.h:237
unsigned nbobjs
Number of objects considered in the matrix.
Definition: hwloc.h:525
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
Allocate memory but do not immediately bind it to a specific locality.
Definition: hwloc.h:1482
struct hwloc_obj * next_sibling
Next object below the same parent.
Definition: hwloc.h:353
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_cpuset_t allowed_cpuset
The CPU set of allowed logical processors.
Definition: hwloc.h:398
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
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
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
struct hwloc_obj * first_child
First child.
Definition: hwloc.h:359
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
struct hwloc_obj * parent
Parent, NULL if root (system object)
Definition: hwloc.h:351
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_cpuset_t online_cpuset
The CPU set of online logical processors.
Definition: hwloc.h:390
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_cpuset_t complete_cpuset
The complete CPU set of logical processors of this object,.
Definition: hwloc.h:379
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_t type
Type of object.
Definition: hwloc.h:331
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
Objects of given type exist at different depth in the topology.
Definition: hwloc.h:1046
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
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
Bridge.
Definition: hwloc.h:225
hwloc_nodeset_t nodeset
NUMA nodes covered by this object or containing this object.
Definition: hwloc.h:409
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.
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
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
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
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_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
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
struct hwloc_obj ** children
Children, children[0 .
Definition: hwloc.h:358
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
Structure of a topology object.
Definition: hwloc.h:329
struct hwloc_obj * next_cousin
Next object of same type and depth.
Definition: hwloc.h:347
float * latency
Matrix of latencies between objects, stored as a one-dimension array.
Definition: hwloc.h:530
unsigned relative_depth
Relative depth of the considered objects below the object containing this distance information...
Definition: hwloc.h:523
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_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
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
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
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_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.
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
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_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
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
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_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.
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_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_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.
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
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
PCI device.
Definition: hwloc.h:232
NUMA node.
Definition: hwloc.h:184
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_nodeset_t complete_nodeset
The complete NUMA node set of this object,.
Definition: hwloc.h:426
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
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
No object of given type exists in the topology.
Definition: hwloc.h:1045
unsigned arity
Number of children.
Definition: hwloc.h:357
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
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
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
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
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
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
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
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
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_DECLSPEC void * hwloc_alloc(hwloc_topology_t topology, size_t len)
Allocate some memory.
Definition: bind.c:487
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.
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
Type of topology object.
Definition: hwloc.h:164
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...
PCI-side of a bridge.
Definition: hwloc.h:258
HWLOC_DECLSPEC void hwloc_bitmap_set(hwloc_bitmap_t bitmap, unsigned id)
Add index id in bitmap bitmap.
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_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.
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
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
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
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_cpuset_t cpuset
CPUs covered by this object.
Definition: hwloc.h:366
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_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
Memory binding policy.
Definition: hwloc.h:1479
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_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.
union hwloc_obj_attr_u * attr
Object type-specific Attributes, may be NULL if no attribute value was found.
Definition: hwloc.h:337
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
Definition: private.h:56
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_nodeset_t allowed_nodeset
The set of allowed NUMA memory nodes.
Definition: hwloc.h:440
Processing Unit, or (Logical) Processor.
Definition: hwloc.h:199
struct hwloc_distances_s ** distances
Distances between all objects at same depth below this object.
Definition: hwloc.h:453
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
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
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
Definition: cpuset.c:38
HWLOC_DECLSPEC int hwloc_get_type_depth(hwloc_topology_t topology, hwloc_obj_type_t type)
Returns the depth of objects of type type.
unsigned depth
Vertical index in the hierarchy.
Definition: hwloc.h:341
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
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