Hardware Locality (hwloc)  1.11.12
helper.h
1 /*
2  * Copyright © 2009 CNRS
3  * Copyright © 2009-2016 Inria. All rights reserved.
4  * Copyright © 2009-2012 Université Bordeaux
5  * Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
6  * See COPYING in top-level directory.
7  */
8 
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 
44 static __hwloc_inline hwloc_obj_t
46 {
47  hwloc_obj_t obj = hwloc_get_root_obj(topology);
48  if (!obj->cpuset || !hwloc_bitmap_intersects(obj->cpuset, set))
49  return NULL;
50  while (!hwloc_bitmap_isincluded(obj->cpuset, set)) {
51  /* while the object intersects without being included, look at its children */
52  hwloc_obj_t child = obj->first_child;
53  while (child) {
54  if (child->cpuset && hwloc_bitmap_intersects(child->cpuset, set))
55  break;
56  child = child->next_sibling;
57  }
58  if (!child)
59  /* no child intersects, return their father */
60  return obj;
61  /* found one intersecting child, look at its children */
62  obj = child;
63  }
64  /* obj is included, return it */
65  return obj;
66 }
67 
76  hwloc_obj_t * __hwloc_restrict objs, int max);
77 
90 static __hwloc_inline hwloc_obj_t
92  unsigned depth, hwloc_obj_t prev)
93 {
94  hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
95  if (!next || !next->cpuset)
96  return NULL;
97  while (next && (hwloc_bitmap_iszero(next->cpuset) || !hwloc_bitmap_isincluded(next->cpuset, set)))
98  next = next->next_cousin;
99  return next;
100 }
101 
114 static __hwloc_inline hwloc_obj_t
116  hwloc_obj_type_t type, hwloc_obj_t prev)
117 {
118  int depth = hwloc_get_type_depth(topology, type);
119  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
120  return NULL;
121  return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
122 }
123 
132 static __hwloc_inline hwloc_obj_t
134  unsigned depth, unsigned idx) __hwloc_attribute_pure;
135 static __hwloc_inline hwloc_obj_t
137  unsigned depth, unsigned idx)
138 {
139  hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
140  unsigned count = 0;
141  if (!obj || !obj->cpuset)
142  return NULL;
143  while (obj) {
144  if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set)) {
145  if (count == idx)
146  return obj;
147  count++;
148  }
149  obj = obj->next_cousin;
150  }
151  return NULL;
152 }
153 
166 static __hwloc_inline hwloc_obj_t
168  hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure;
169 static __hwloc_inline hwloc_obj_t
171  hwloc_obj_type_t type, unsigned idx)
172 {
173  int depth = hwloc_get_type_depth(topology, type);
174  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
175  return NULL;
176  return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
177 }
178 
187 static __hwloc_inline unsigned
189  unsigned depth) __hwloc_attribute_pure;
190 static __hwloc_inline unsigned
192  unsigned depth)
193 {
194  hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
195  unsigned count = 0;
196  if (!obj || !obj->cpuset)
197  return 0;
198  while (obj) {
199  if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set))
200  count++;
201  obj = obj->next_cousin;
202  }
203  return count;
204 }
205 
218 static __hwloc_inline int
220  hwloc_obj_type_t type) __hwloc_attribute_pure;
221 static __hwloc_inline int
223  hwloc_obj_type_t type)
224 {
225  int depth = hwloc_get_type_depth(topology, type);
226  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
227  return 0;
228  if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
229  return -1; /* FIXME: agregate nbobjs from different levels? */
230  return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
231 }
232 
244 static __hwloc_inline int
245 hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
246  hwloc_obj_t obj) __hwloc_attribute_pure;
247 static __hwloc_inline int
249  hwloc_obj_t obj)
250 {
251  int idx = 0;
252  if (!hwloc_bitmap_isincluded(obj->cpuset, set))
253  return -1;
254  /* count how many objects are inside the cpuset on the way from us to the beginning of the level */
255  while ((obj = obj->prev_cousin) != NULL)
256  if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set))
257  idx++;
258  return idx;
259 }
260 
275 static __hwloc_inline hwloc_obj_t
276 hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
277  hwloc_obj_t parent) __hwloc_attribute_pure;
278 static __hwloc_inline hwloc_obj_t
280  hwloc_obj_t parent)
281 {
282  hwloc_obj_t child;
283  if (!parent->cpuset || hwloc_bitmap_iszero(set))
284  return NULL;
285  child = parent->first_child;
286  while (child) {
287  if (child->cpuset && hwloc_bitmap_isincluded(set, child->cpuset))
288  return child;
289  child = child->next_sibling;
290  }
291  return NULL;
292 }
293 
301 static __hwloc_inline hwloc_obj_t
302 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure;
303 static __hwloc_inline hwloc_obj_t
305 {
306  struct hwloc_obj *current = hwloc_get_root_obj(topology);
307  if (hwloc_bitmap_iszero(set) || !current->cpuset || !hwloc_bitmap_isincluded(set, current->cpuset))
308  return NULL;
309  while (1) {
310  hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
311  if (!child)
312  return current;
313  current = child;
314  }
315 }
316 
327 static __hwloc_inline hwloc_obj_t
329  unsigned depth, hwloc_obj_t prev)
330 {
331  hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
332  if (!next || !next->cpuset)
333  return NULL;
334  while (next && !hwloc_bitmap_intersects(set, next->cpuset))
335  next = next->next_cousin;
336  return next;
337 }
338 
354 static __hwloc_inline hwloc_obj_t
357 {
358  int depth = hwloc_get_type_depth(topology, type);
359  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
360  return NULL;
361  return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
362 }
363 
378 static __hwloc_inline hwloc_obj_t
379 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj) __hwloc_attribute_pure;
380 static __hwloc_inline hwloc_obj_t
381 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj)
382 {
383  hwloc_obj_t ancestor = obj;
384  if (obj->depth < depth)
385  return NULL;
386  while (ancestor && ancestor->depth > depth)
387  ancestor = ancestor->parent;
388  return ancestor;
389 }
390 
392 static __hwloc_inline hwloc_obj_t
393 hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj) __hwloc_attribute_pure;
394 static __hwloc_inline hwloc_obj_t
396 {
397  hwloc_obj_t ancestor = obj->parent;
398  while (ancestor && ancestor->type != type)
399  ancestor = ancestor->parent;
400  return ancestor;
401 }
402 
404 static __hwloc_inline hwloc_obj_t
405 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2) __hwloc_attribute_pure;
406 static __hwloc_inline hwloc_obj_t
407 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2)
408 {
409  /* the loop isn't so easy since intermediate ancestors may have
410  * different depth, causing us to alternate between using obj1->parent
411  * and obj2->parent. Also, even if at some point we find ancestors of
412  * of the same depth, their ancestors may have different depth again.
413  */
414  while (obj1 != obj2) {
415  while (obj1->depth > obj2->depth)
416  obj1 = obj1->parent;
417  while (obj2->depth > obj1->depth)
418  obj2 = obj2->parent;
419  if (obj1 != obj2 && obj1->depth == obj2->depth) {
420  obj1 = obj1->parent;
421  obj2 = obj2->parent;
422  }
423  }
424  return obj1;
425 }
426 
431 static __hwloc_inline int
432 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root) __hwloc_attribute_pure;
433 static __hwloc_inline int
434 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root)
435 {
436  return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
437 }
438 
443 static __hwloc_inline hwloc_obj_t
444 hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev)
445 {
446  if (!prev)
447  return parent->first_child;
448  if (prev->parent != parent)
449  return NULL;
450  return prev->next_sibling;
451 }
452 
480 static __hwloc_inline int
482  unsigned cachelevel, hwloc_obj_cache_type_t cachetype)
483 {
484  int depth;
485  int found = HWLOC_TYPE_DEPTH_UNKNOWN;
486  for (depth=0; ; depth++) {
487  hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, 0);
488  if (!obj)
489  break;
490  if (obj->type != HWLOC_OBJ_CACHE || obj->attr->cache.depth != cachelevel)
491  /* doesn't match, try next depth */
492  continue;
493  if (cachetype == (hwloc_obj_cache_type_t) -1) {
494  if (found != HWLOC_TYPE_DEPTH_UNKNOWN) {
495  /* second match, return MULTIPLE */
497  }
498  /* first match, mark it as found */
499  found = depth;
500  continue;
501  }
502  if (obj->attr->cache.type == cachetype || obj->attr->cache.type == HWLOC_OBJ_CACHE_UNIFIED)
503  /* exact match (either unified is alone, or we match instruction or data), return immediately */
504  return depth;
505  }
506  /* went to the bottom, return what we found */
507  return found;
508 }
509 
517 static __hwloc_inline hwloc_obj_t
518 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure;
519 static __hwloc_inline hwloc_obj_t
521 {
522  hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
523  while (current) {
524  if (current->type == HWLOC_OBJ_CACHE)
525  return current;
526  current = current->parent;
527  }
528  return NULL;
529 }
530 
535 static __hwloc_inline hwloc_obj_t
536 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj) __hwloc_attribute_pure;
537 static __hwloc_inline hwloc_obj_t
538 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj)
539 {
540  hwloc_obj_t current = obj->parent;
541  if (!obj->cpuset)
542  return NULL;
543  while (current && current->cpuset) {
544  if (!hwloc_bitmap_isequal(current->cpuset, obj->cpuset)
545  && current->type == HWLOC_OBJ_CACHE)
546  return current;
547  current = current->parent;
548  }
549  return NULL;
550 }
551 
574 static __hwloc_inline hwloc_obj_t
575 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure;
576 static __hwloc_inline hwloc_obj_t
578 {
579  hwloc_obj_t obj = NULL;
580  while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
581  if (obj->os_index == os_index)
582  return obj;
583  return NULL;
584 }
585 
595 static __hwloc_inline hwloc_obj_t
596 hwloc_get_numanode_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure;
597 static __hwloc_inline hwloc_obj_t
599 {
600  hwloc_obj_t obj = NULL;
601  while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NUMANODE, obj)) != NULL)
602  if (obj->os_index == os_index)
603  return obj;
604  return NULL;
605 }
606 
618 /* TODO: rather provide an iterator? Provide a way to know how much should be allocated? By returning the total number of objects instead? */
619 HWLOC_DECLSPEC unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * __hwloc_restrict objs, unsigned max);
620 
633 static __hwloc_inline hwloc_obj_t
635  hwloc_obj_type_t type1, unsigned idx1,
636  hwloc_obj_type_t type2, unsigned idx2) __hwloc_attribute_pure;
637 static __hwloc_inline hwloc_obj_t
639  hwloc_obj_type_t type1, unsigned idx1,
640  hwloc_obj_type_t type2, unsigned idx2)
641 {
642  hwloc_obj_t obj;
643  obj = hwloc_get_obj_by_type (topology, type1, idx1);
644  if (!obj || !obj->cpuset)
645  return NULL;
646  return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
647 }
648 
667 static __hwloc_inline hwloc_obj_t
668 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv) __hwloc_attribute_pure;
669 static __hwloc_inline hwloc_obj_t
670 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
671 {
672  hwloc_obj_t obj = hwloc_get_root_obj(topology);
673  int i;
674  for(i=0; i<nr; i++) {
675  if (!obj || !obj->cpuset)
676  return NULL;
677  obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
678  }
679  return obj;
680 }
681 
697 };
698 
722 static __hwloc_inline int
724  hwloc_obj_t *roots, unsigned n_roots,
725  hwloc_cpuset_t *set,
726  unsigned n,
727  unsigned until, unsigned long flags)
728 {
729  unsigned i;
730  unsigned tot_weight;
731  unsigned given, givenweight;
732  hwloc_cpuset_t *cpusetp = set;
733 
734  if (flags & ~HWLOC_DISTRIB_FLAG_REVERSE) {
735  errno = EINVAL;
736  return -1;
737  }
738 
739  tot_weight = 0;
740  for (i = 0; i < n_roots; i++)
741  if (roots[i]->cpuset)
742  tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);
743 
744  for (i = 0, given = 0, givenweight = 0; i < n_roots; i++) {
745  unsigned chunk, weight;
746  hwloc_obj_t root = roots[flags & HWLOC_DISTRIB_FLAG_REVERSE ? n_roots-1-i : i];
747  hwloc_cpuset_t cpuset = root->cpuset;
748  if (!cpuset)
749  continue;
750  weight = hwloc_bitmap_weight(cpuset);
751  if (!weight)
752  continue;
753  /* Give to root a chunk proportional to its weight.
754  * If previous chunks got rounded-up, we may get a bit less. */
755  chunk = (( (givenweight+weight) * n + tot_weight-1) / tot_weight)
756  - (( givenweight * n + tot_weight-1) / tot_weight);
757  if (!root->arity || chunk <= 1 || root->depth >= until) {
758  /* We can't split any more, put everything there. */
759  if (chunk) {
760  /* Fill cpusets with ours */
761  unsigned j;
762  for (j=0; j < chunk; j++)
763  cpusetp[j] = hwloc_bitmap_dup(cpuset);
764  } else {
765  /* We got no chunk, just merge our cpuset to a previous one
766  * (the first chunk cannot be empty)
767  * so that this root doesn't get ignored.
768  */
769  assert(given);
770  hwloc_bitmap_or(cpusetp[-1], cpusetp[-1], cpuset);
771  }
772  } else {
773  /* Still more to distribute, recurse into children */
774  hwloc_distrib(topology, root->children, root->arity, cpusetp, chunk, until, flags);
775  }
776  cpusetp += chunk;
777  given += chunk;
778  givenweight += weight;
779  }
780 
781  return 0;
782 }
783 
800 static __hwloc_inline hwloc_const_cpuset_t
801 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
802 static __hwloc_inline hwloc_const_cpuset_t
804 {
805  return hwloc_get_root_obj(topology)->complete_cpuset;
806 }
807 
818 static __hwloc_inline hwloc_const_cpuset_t
819 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
820 static __hwloc_inline hwloc_const_cpuset_t
822 {
823  return hwloc_get_root_obj(topology)->cpuset;
824 }
825 
835 static __hwloc_inline hwloc_const_cpuset_t
836 hwloc_topology_get_online_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
837 static __hwloc_inline hwloc_const_cpuset_t
839 {
840  return hwloc_get_root_obj(topology)->online_cpuset;
841 }
842 
852 static __hwloc_inline hwloc_const_cpuset_t
853 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
854 static __hwloc_inline hwloc_const_cpuset_t
856 {
857  return hwloc_get_root_obj(topology)->allowed_cpuset;
858 }
859 
869 static __hwloc_inline hwloc_const_nodeset_t
870 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
871 static __hwloc_inline hwloc_const_nodeset_t
873 {
874  return hwloc_get_root_obj(topology)->complete_nodeset;
875 }
876 
887 static __hwloc_inline hwloc_const_nodeset_t
888 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
889 static __hwloc_inline hwloc_const_nodeset_t
891 {
892  return hwloc_get_root_obj(topology)->nodeset;
893 }
894 
904 static __hwloc_inline hwloc_const_nodeset_t
905 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
906 static __hwloc_inline hwloc_const_nodeset_t
908 {
909  return hwloc_get_root_obj(topology)->allowed_nodeset;
910 }
911 
942 static __hwloc_inline void
944 {
946  hwloc_obj_t obj;
947 
948  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
949  if (hwloc_bitmap_iszero(_cpuset))
950  hwloc_bitmap_zero(nodeset);
951  else
952  /* Assume the whole system */
953  hwloc_bitmap_fill(nodeset);
954  return;
955  }
956 
957  hwloc_bitmap_zero(nodeset);
958  obj = NULL;
959  while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, _cpuset, depth, obj)) != NULL)
960  hwloc_bitmap_set(nodeset, obj->os_index);
961 }
962 
970 static __hwloc_inline void
972 {
974  hwloc_obj_t obj;
975  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
976  return;
977  hwloc_bitmap_zero(nodeset);
978  obj = NULL;
979  while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, _cpuset, depth, obj)) != NULL)
980  hwloc_bitmap_set(nodeset, obj->os_index);
981 }
982 
991 static __hwloc_inline void
993 {
995  hwloc_obj_t obj;
996 
997  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) {
998  if (hwloc_bitmap_iszero(nodeset))
999  hwloc_bitmap_zero(_cpuset);
1000  else
1001  /* Assume the whole system */
1002  hwloc_bitmap_fill(_cpuset);
1003  return;
1004  }
1005 
1006  hwloc_bitmap_zero(_cpuset);
1007  obj = NULL;
1008  while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
1009  if (hwloc_bitmap_isset(nodeset, obj->os_index))
1010  /* no need to check obj->cpuset because objects in levels always have a cpuset */
1011  hwloc_bitmap_or(_cpuset, _cpuset, obj->cpuset);
1012  }
1013 }
1014 
1022 static __hwloc_inline void
1024 {
1026  hwloc_obj_t obj;
1027  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
1028  return;
1029  hwloc_bitmap_zero(_cpuset);
1030  obj = NULL;
1031  while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL)
1032  if (hwloc_bitmap_isset(nodeset, obj->os_index))
1033  /* no need to check obj->cpuset because objects in levels always have a cpuset */
1034  hwloc_bitmap_or(_cpuset, _cpuset, obj->cpuset);
1035 }
1036 
1064 static __hwloc_inline const struct hwloc_distances_s *
1066 {
1067  hwloc_obj_t root = hwloc_get_root_obj(topology);
1068  unsigned i;
1069  for(i=0; i<root->distances_count; i++)
1070  if (root->distances[i]->relative_depth == depth)
1071  return root->distances[i];
1072  return NULL;
1073 }
1074 
1094 static __hwloc_inline const struct hwloc_distances_s *
1096 {
1097  int depth = hwloc_get_type_depth(topology, type);
1098  if (depth < 0)
1099  return NULL;
1100  return hwloc_get_whole_distance_matrix_by_depth(topology, depth);
1101 }
1102 
1116 static __hwloc_inline const struct hwloc_distances_s *
1118  hwloc_obj_t obj, unsigned depth,
1119  unsigned *firstp)
1120 {
1121  while (obj && obj->cpuset) {
1122  unsigned i;
1123  for(i=0; i<obj->distances_count; i++)
1124  if (obj->distances[i]->relative_depth == depth - obj->depth) {
1125  if (!obj->distances[i]->nbobjs)
1126  continue;
1127  *firstp = hwloc_get_next_obj_inside_cpuset_by_depth(topology, obj->cpuset, depth, NULL)->logical_index;
1128  return obj->distances[i];
1129  }
1130  obj = obj->parent;
1131  }
1132  return NULL;
1133 }
1134 
1146 static __hwloc_inline int
1148  hwloc_obj_t obj1, hwloc_obj_t obj2,
1149  float *latency, float *reverse_latency)
1150 {
1151  hwloc_obj_t ancestor;
1152  const struct hwloc_distances_s * distances;
1153  unsigned first_logical ;
1154 
1155  if (obj1->depth != obj2->depth) {
1156  errno = EINVAL;
1157  return -1;
1158  }
1159 
1160  ancestor = hwloc_get_common_ancestor_obj(topology, obj1, obj2);
1161  distances = hwloc_get_distance_matrix_covering_obj_by_depth(topology, ancestor, obj1->depth, &first_logical);
1162  if (distances && distances->latency) {
1163  const float * latency_matrix = distances->latency;
1164  unsigned nbobjs = distances->nbobjs;
1165  unsigned l1 = obj1->logical_index - first_logical;
1166  unsigned l2 = obj2->logical_index - first_logical;
1167  *latency = latency_matrix[l1*nbobjs+l2];
1168  *reverse_latency = latency_matrix[l2*nbobjs+l1];
1169  return 0;
1170  }
1171 
1172  errno = ENOSYS;
1173  return -1;
1174 }
1175 
1190 static __hwloc_inline hwloc_obj_t
1191 hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused,
1192  hwloc_obj_t ioobj)
1193 {
1194  hwloc_obj_t obj = ioobj;
1195  while (obj && !obj->cpuset) {
1196  obj = obj->parent;
1197  }
1198  return obj;
1199 }
1200 
1205 static __hwloc_inline hwloc_obj_t
1207 {
1208  return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PCI_DEVICE, prev);
1209 }
1210 
1214 static __hwloc_inline hwloc_obj_t
1216  unsigned domain, unsigned bus, unsigned dev, unsigned func)
1217 {
1218  hwloc_obj_t obj = NULL;
1219  while ((obj = hwloc_get_next_pcidev(topology, obj)) != NULL) {
1220  if (obj->attr->pcidev.domain == domain
1221  && obj->attr->pcidev.bus == bus
1222  && obj->attr->pcidev.dev == dev
1223  && obj->attr->pcidev.func == func)
1224  return obj;
1225  }
1226  return NULL;
1227 }
1228 
1232 static __hwloc_inline hwloc_obj_t
1234 {
1235  unsigned domain = 0; /* default */
1236  unsigned bus, dev, func;
1237 
1238  if (sscanf(busid, "%x:%x.%x", &bus, &dev, &func) != 3
1239  && sscanf(busid, "%x:%x:%x.%x", &domain, &bus, &dev, &func) != 4) {
1240  errno = EINVAL;
1241  return NULL;
1242  }
1243 
1244  return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, func);
1245 }
1246 
1251 static __hwloc_inline hwloc_obj_t
1253 {
1254  return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_OS_DEVICE, prev);
1255 }
1256 
1261 static __hwloc_inline hwloc_obj_t
1263 {
1264  return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_BRIDGE, prev);
1265 }
1266 
1267 /* \brief Checks whether a given bridge covers a given PCI bus.
1268  */
1269 static __hwloc_inline int
1271  unsigned domain, unsigned bus)
1272 {
1273  return bridge->type == HWLOC_OBJ_BRIDGE
1275  && bridge->attr->bridge.downstream.pci.domain == domain
1276  && bridge->attr->bridge.downstream.pci.secondary_bus <= bus
1277  && bridge->attr->bridge.downstream.pci.subordinate_bus >= bus;
1278 }
1279 
1285 static __hwloc_inline hwloc_obj_t
1287  unsigned domain, unsigned bus)
1288 {
1289  hwloc_obj_t obj = NULL;
1290  while ((obj = hwloc_get_next_bridge(topology, obj)) != NULL) {
1291  if (hwloc_bridge_covers_pcibus(obj, domain, bus)) {
1292  /* found bridge covering this pcibus, make sure it's a hostbridge */
1294  assert(obj->parent->type != HWLOC_OBJ_BRIDGE);
1295  assert(obj->parent->cpuset);
1296  return obj;
1297  }
1298  }
1299  return NULL;
1300 }
1301 
1306 #ifdef __cplusplus
1307 } /* extern "C" */
1308 #endif
1309 
1310 
1311 #endif /* HWLOC_HELPER_H */
hwloc_obj_bridge_type_t upstream_type
Definition: hwloc.h:555
hwloc_obj_cache_type_t type
Cache type.
Definition: hwloc.h:535
struct hwloc_topology * hwloc_topology_t
Topology context.
Definition: hwloc.h:633
unsigned distances_count
Definition: hwloc.h:510
void hwloc_bitmap_set(hwloc_bitmap_t bitmap, unsigned id)
Add index id in bitmap bitmap.
static 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:328
static int hwloc_get_obj_index_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_obj_t obj)
Return the logical index among the objects included in CPU set set.
Definition: helper.h:248
unsigned os_index
OS-provided physical index number. It is not guaranteed unique across the entire machine, except for PUs and NUMA nodes.
Definition: hwloc.h:363
unsigned relative_depth
Relative depth of the considered objects below the object containing this distance information...
Definition: hwloc.h:585
int hwloc_bitmap_isset(hwloc_const_bitmap_t bitmap, unsigned id)
Test whether index id is part of bitmap bitmap.
struct hwloc_obj * prev_cousin
Previous object of same type and depth.
Definition: hwloc.h:401
static hwloc_obj_t hwloc_get_next_child(hwloc_topology_t topology, hwloc_obj_t parent, hwloc_obj_t prev)
Return the next child.
Definition: helper.h:444
unsigned nbobjs
Number of objects considered in the matrix. It is the number of descendant objects at relative_depth ...
Definition: hwloc.h:587
union hwloc_obj_attr_u::hwloc_bridge_attr_s::@1 downstream
static hwloc_obj_t 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:520
struct hwloc_obj_attr_u::hwloc_bridge_attr_s bridge
static 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:1286
unsigned hwloc_get_closest_objs(hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t *restrict objs, unsigned max)
Do a depth-first traversal of the topology to find and sort.
static hwloc_obj_t hwloc_get_numanode_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
Returns the object of type HWLOC_OBJ_NUMANODE with os_index.
Definition: helper.h:598
static int 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:222
hwloc_obj_type_t
Type of topology object.
Definition: hwloc.h:171
static 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:1065
static int hwloc_distrib(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *set, unsigned n, unsigned until, unsigned long flags)
Distribute n items over the topology under roots.
Definition: helper.h:723
static 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:1233
Bridge. Any bridge that connects the host or an I/O bus, to another I/O bus. Bridge objects have neit...
Definition: hwloc.h:240
hwloc_nodeset_t allowed_nodeset
The set of allowed NUMA memory nodes.
Definition: hwloc.h:496
hwloc_obj_t hwloc_get_obj_by_depth(hwloc_topology_t topology, unsigned depth, unsigned idx)
Returns the topology object at logical index idx from depth depth.
hwloc_bitmap_t hwloc_nodeset_t
A node set is a bitmap whose bits are set according to NUMA memory node physical OS indexes...
Definition: hwloc.h:152
static 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:1117
static hwloc_const_nodeset_t hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
Get allowed node set.
Definition: helper.h:907
static 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:1215
Unified cache.
Definition: hwloc.h:272
NUMA node. An object that contains memory that is directly and byte-accessible to the host processors...
Definition: hwloc.h:191
void hwloc_bitmap_zero(hwloc_bitmap_t bitmap)
Empty the bitmap bitmap.
enum hwloc_obj_cache_type_e hwloc_obj_cache_type_t
Cache type.
static 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:992
static hwloc_obj_t hwloc_get_shared_cache_covering_obj(hwloc_topology_t topology, hwloc_obj_t obj)
Get the first cache shared between an object and somebody else.
Definition: helper.h:538
static 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:1023
static hwloc_obj_t hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology, hwloc_obj_t ioobj)
Get the first non-I/O ancestor object.
Definition: helper.h:1191
hwloc_cpuset_t cpuset
CPUs covered by this object.
Definition: hwloc.h:422
unsigned arity
Number of children.
Definition: hwloc.h:410
struct hwloc_pcidev_attr_s pci
Definition: hwloc.h:553
int hwloc_bitmap_isequal(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2)
Test whether bitmap bitmap1 is equal to bitmap bitmap2.
static hwloc_obj_t hwloc_get_root_obj(hwloc_topology_t topology)
Returns the top-object of the topology-tree.
int hwloc_get_largest_objs_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_obj_t *restrict objs, int max)
Get the set of largest objects covering exactly a given cpuset set.
int hwloc_bitmap_intersects(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2)
Test whether bitmaps bitmap1 and bitmap2 intersects.
static 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:115
static 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:971
hwloc_cpuset_t allowed_cpuset
The CPU set of allowed logical processors.
Definition: hwloc.h:454
static hwloc_const_nodeset_t hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
Get complete node set.
Definition: helper.h:872
unsigned depth
Depth of cache (e.g., L1, L2, ...etc.)
Definition: hwloc.h:531
static hwloc_obj_t hwloc_get_child_covering_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_obj_t parent)
Get the child covering at least CPU set set.
Definition: helper.h:279
static hwloc_obj_t hwloc_get_ancestor_obj_by_type(hwloc_topology_t topology, hwloc_obj_type_t type, hwloc_obj_t obj)
Returns the ancestor object of obj with type type.
Definition: helper.h:395
static 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.
static hwloc_obj_t hwloc_get_common_ancestor_obj(hwloc_topology_t topology, hwloc_obj_t obj1, hwloc_obj_t obj2)
Returns the common parent object to objects obj1 and obj2.
Definition: helper.h:407
struct hwloc_obj_attr_u::hwloc_pcidev_attr_s pcidev
static 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:1095
Structure of a topology object.
Definition: hwloc.h:359
Objects of given type exist at different depth in the topology.
Definition: hwloc.h:1225
unsigned short domain
Definition: hwloc.h:543
static 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:1206
int hwloc_bitmap_isincluded(hwloc_const_bitmap_t sub_bitmap, hwloc_const_bitmap_t super_bitmap)
Test whether bitmap sub_bitmap is part of bitmap super_bitmap.
static hwloc_obj_t 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:670
static hwloc_obj_t 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:304
hwloc_nodeset_t nodeset
NUMA nodes covered by this object or containing this object.
Definition: hwloc.h:465
static hwloc_const_cpuset_t hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
Get complete CPU set.
Definition: helper.h:803
hwloc_bitmap_t hwloc_bitmap_dup(hwloc_const_bitmap_t bitmap)
Duplicate bitmap bitmap by allocating a new bitmap and copying bitmap contents.
static hwloc_const_nodeset_t hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
Get topology node set.
Definition: helper.h:890
struct hwloc_obj ** children
Children, children[0 .. arity -1].
Definition: hwloc.h:411
static hwloc_obj_t 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:638
static hwloc_obj_t 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:170
static 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.
struct hwloc_obj * next_sibling
Next object below the same parent.
Definition: hwloc.h:406
static 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:943
struct hwloc_obj * next_cousin
Next object of same type and depth.
Definition: hwloc.h:400
static hwloc_obj_t hwloc_get_ancestor_obj_by_depth(hwloc_topology_t topology, unsigned depth, hwloc_obj_t obj)
Returns the ancestor object of obj at depth depth.
Definition: helper.h:381
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...
unsigned char dev
Definition: hwloc.h:544
hwloc_cpuset_t online_cpuset
The CPU set of online logical processors.
Definition: hwloc.h:446
union hwloc_obj_attr_u * attr
Object type-specific Attributes, may be NULL if no attribute value was found.
Definition: hwloc.h:374
struct hwloc_obj * first_child
First child.
Definition: hwloc.h:412
hwloc_const_bitmap_t hwloc_const_cpuset_t
A non-modifiable hwloc_cpuset_t.
Definition: hwloc.h:135
No object of given type exists in the topology.
Definition: hwloc.h:1224
hwloc_obj_bridge_type_t downstream_type
Definition: hwloc.h:562
float * latency
Matrix of latencies between objects, stored as a one-dimension array. May be NULL if the distances co...
Definition: hwloc.h:592
static int hwloc_get_cache_type_depth(hwloc_topology_t topology, unsigned cachelevel, hwloc_obj_cache_type_t cachetype)
Find the depth of cache objects matching cache depth and type.
Definition: helper.h:481
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_const_cpuset_t hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
Get allowed CPU set.
Definition: helper.h:855
static hwloc_obj_t 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:136
hwloc_nodeset_t complete_nodeset
The complete NUMA node set of this object,.
Definition: hwloc.h:482
static 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:45
static 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:355
static int hwloc_bridge_covers_pcibus(hwloc_obj_t bridge, unsigned domain, unsigned bus)
Definition: helper.h:1270
static int hwloc_obj_is_in_subtree(hwloc_topology_t topology, hwloc_obj_t obj, hwloc_obj_t subtree_root)
Returns true if obj is inside the subtree beginning with ancestor object subtree_root.
Definition: helper.h:434
static hwloc_obj_t 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:577
hwloc_obj_type_t type
Type of object.
Definition: hwloc.h:361
static hwloc_const_cpuset_t hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
Get topology CPU set.
Definition: helper.h:821
hwloc_distrib_flags_e
Flags to be given to hwloc_distrib().
Definition: helper.h:692
Operating system device. These objects have neither CPU sets nor node sets. They are not added to the...
Definition: hwloc.h:252
unsigned logical_index
Horizontal index in the whole list of similar objects, hence guaranteed unique across the entire mach...
Definition: hwloc.h:393
unsigned char bus
Definition: hwloc.h:544
Distrib in reverse order, starting from the last objects.
Definition: helper.h:696
static 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:1252
static hwloc_obj_t 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.
struct hwloc_obj * parent
Parent, NULL if root (system object)
Definition: hwloc.h:404
static 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:91
hwloc_const_bitmap_t hwloc_const_nodeset_t
A non-modifiable hwloc_nodeset_t.
Definition: hwloc.h:155
Cache. Can be L1i, L1d, L2, L3, ...
Definition: hwloc.h:205
PCI device. These objects have neither CPU sets nor node sets. They are not added to the topology unl...
Definition: hwloc.h:247
static 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:1262
Processing Unit, or (Logical) Processor. An execution unit (may share a core with some other logical ...
Definition: hwloc.h:212
struct hwloc_distances_s ** distances
Distances between all objects at same depth below this object.
Definition: hwloc.h:509
static 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:1147
unsigned char func
Definition: hwloc.h:544
PCI-side of a bridge.
Definition: hwloc.h:281
int hwloc_bitmap_iszero(hwloc_const_bitmap_t bitmap)
Test whether bitmap bitmap is empty.
hwloc_cpuset_t complete_cpuset
The complete CPU set of logical processors of this object,.
Definition: hwloc.h:435
int hwloc_get_type_depth(hwloc_topology_t topology, hwloc_obj_type_t type)
Returns the depth of objects of type type.
int hwloc_bitmap_weight(hwloc_const_bitmap_t bitmap)
Compute the "weight" of bitmap bitmap (i.e., number of indexes that are in the bitmap).
static hwloc_const_cpuset_t hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
Get online CPU set.
Definition: helper.h:838
struct hwloc_obj_attr_u::hwloc_cache_attr_s cache
hwloc_bitmap_t hwloc_cpuset_t
A CPU set is a bitmap whose bits are set according to CPU physical OS indexes.
Definition: hwloc.h:133
unsigned depth
Vertical index in the hierarchy.
Definition: hwloc.h:378
static unsigned 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:191
Distances between objects.
Definition: hwloc.h:584
Host-side of a bridge, only possible upstream.
Definition: hwloc.h:280