Open MPI logo

Portable Hardware Locality (hwloc) Documentation: v1.10.1

  |   Home   |   Support   |   FAQ   |  
helper.h
1 /*
2  * Copyright © 2009 CNRS
3  * Copyright © 2009-2014 Inria. All rights reserved.
4  * Copyright © 2009-2012 Université Bordeaux 1
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 
87 static __hwloc_inline hwloc_obj_t
89  unsigned depth, hwloc_obj_t prev)
90 {
91  hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
92  if (!next || !next->cpuset)
93  return NULL;
94  while (next && !hwloc_bitmap_isincluded(next->cpuset, set))
95  next = next->next_cousin;
96  return next;
97 }
98 
108 static __hwloc_inline hwloc_obj_t
110  hwloc_obj_type_t type, hwloc_obj_t prev)
111 {
112  int depth = hwloc_get_type_depth(topology, type);
113  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
114  return NULL;
115  return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
116 }
117 
123 static __hwloc_inline hwloc_obj_t
125  unsigned depth, unsigned idx) __hwloc_attribute_pure;
126 static __hwloc_inline hwloc_obj_t
128  unsigned depth, unsigned idx)
129 {
130  hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
131  unsigned count = 0;
132  if (!obj || !obj->cpuset)
133  return NULL;
134  while (obj) {
135  if (hwloc_bitmap_isincluded(obj->cpuset, set)) {
136  if (count == idx)
137  return obj;
138  count++;
139  }
140  obj = obj->next_cousin;
141  }
142  return NULL;
143 }
144 
154 static __hwloc_inline hwloc_obj_t
156  hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure;
157 static __hwloc_inline hwloc_obj_t
159  hwloc_obj_type_t type, unsigned idx)
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_obj_inside_cpuset_by_depth(topology, set, depth, idx);
165 }
166 
172 static __hwloc_inline unsigned
174  unsigned depth) __hwloc_attribute_pure;
175 static __hwloc_inline unsigned
177  unsigned depth)
178 {
179  hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
180  unsigned count = 0;
181  if (!obj || !obj->cpuset)
182  return 0;
183  while (obj) {
184  if (hwloc_bitmap_isincluded(obj->cpuset, set))
185  count++;
186  obj = obj->next_cousin;
187  }
188  return count;
189 }
190 
200 static __hwloc_inline int
202  hwloc_obj_type_t type) __hwloc_attribute_pure;
203 static __hwloc_inline int
205  hwloc_obj_type_t type)
206 {
207  int depth = hwloc_get_type_depth(topology, type);
208  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
209  return 0;
210  if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
211  return -1; /* FIXME: agregate nbobjs from different levels? */
212  return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
213 }
214 
223 static __hwloc_inline int
224 hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
225  hwloc_obj_t obj) __hwloc_attribute_pure;
226 static __hwloc_inline int
228  hwloc_obj_t obj)
229 {
230  int idx = 0;
231  if (!hwloc_bitmap_isincluded(obj->cpuset, set))
232  return -1;
233  /* count how many objects are inside the cpuset on the way from us to the beginning of the level */
234  while ((obj = obj->prev_cousin) != NULL)
235  if (hwloc_bitmap_isincluded(obj->cpuset, set))
236  idx++;
237  return idx;
238 }
239 
254 static __hwloc_inline hwloc_obj_t
255 hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
256  hwloc_obj_t parent) __hwloc_attribute_pure;
257 static __hwloc_inline hwloc_obj_t
259  hwloc_obj_t parent)
260 {
261  hwloc_obj_t child;
262  if (!parent->cpuset || hwloc_bitmap_iszero(set))
263  return NULL;
264  child = parent->first_child;
265  while (child) {
266  if (child->cpuset && hwloc_bitmap_isincluded(set, child->cpuset))
267  return child;
268  child = child->next_sibling;
269  }
270  return NULL;
271 }
272 
280 static __hwloc_inline hwloc_obj_t
281 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure;
282 static __hwloc_inline hwloc_obj_t
284 {
285  struct hwloc_obj *current = hwloc_get_root_obj(topology);
286  if (hwloc_bitmap_iszero(set) || !current->cpuset || !hwloc_bitmap_isincluded(set, current->cpuset))
287  return NULL;
288  while (1) {
289  hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
290  if (!child)
291  return current;
292  current = child;
293  }
294 }
295 
306 static __hwloc_inline hwloc_obj_t
308  unsigned depth, hwloc_obj_t prev)
309 {
310  hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
311  if (!next || !next->cpuset)
312  return NULL;
313  while (next && !hwloc_bitmap_intersects(set, next->cpuset))
314  next = next->next_cousin;
315  return next;
316 }
317 
333 static __hwloc_inline hwloc_obj_t
336 {
337  int depth = hwloc_get_type_depth(topology, type);
338  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
339  return NULL;
340  return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
341 }
342 
357 static __hwloc_inline hwloc_obj_t
358 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj) __hwloc_attribute_pure;
359 static __hwloc_inline hwloc_obj_t
360 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj)
361 {
362  hwloc_obj_t ancestor = obj;
363  if (obj->depth < depth)
364  return NULL;
365  while (ancestor && ancestor->depth > depth)
366  ancestor = ancestor->parent;
367  return ancestor;
368 }
369 
371 static __hwloc_inline hwloc_obj_t
372 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;
373 static __hwloc_inline hwloc_obj_t
375 {
376  hwloc_obj_t ancestor = obj->parent;
377  while (ancestor && ancestor->type != type)
378  ancestor = ancestor->parent;
379  return ancestor;
380 }
381 
383 static __hwloc_inline hwloc_obj_t
384 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2) __hwloc_attribute_pure;
385 static __hwloc_inline hwloc_obj_t
386 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2)
387 {
388  /* the loop isn't so easy since intermediate ancestors may have
389  * different depth, causing us to alternate between using obj1->parent
390  * and obj2->parent. Also, even if at some point we find ancestors of
391  * of the same depth, their ancestors may have different depth again.
392  */
393  while (obj1 != obj2) {
394  while (obj1->depth > obj2->depth)
395  obj1 = obj1->parent;
396  while (obj2->depth > obj1->depth)
397  obj2 = obj2->parent;
398  if (obj1 != obj2 && obj1->depth == obj2->depth) {
399  obj1 = obj1->parent;
400  obj2 = obj2->parent;
401  }
402  }
403  return obj1;
404 }
405 
410 static __hwloc_inline int
411 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root) __hwloc_attribute_pure;
412 static __hwloc_inline int
413 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root)
414 {
415  return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
416 }
417 
422 static __hwloc_inline hwloc_obj_t
423 hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev)
424 {
425  if (!prev)
426  return parent->first_child;
427  if (prev->parent != parent)
428  return NULL;
429  return prev->next_sibling;
430 }
431 
459 static __hwloc_inline int
461  unsigned cachelevel, hwloc_obj_cache_type_t cachetype)
462 {
463  int depth;
464  int found = HWLOC_TYPE_DEPTH_UNKNOWN;
465  for (depth=0; ; depth++) {
466  hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, 0);
467  if (!obj)
468  break;
469  if (obj->type != HWLOC_OBJ_CACHE || obj->attr->cache.depth != cachelevel)
470  /* doesn't match, try next depth */
471  continue;
472  if (cachetype == (hwloc_obj_cache_type_t) -1) {
473  if (found != HWLOC_TYPE_DEPTH_UNKNOWN) {
474  /* second match, return MULTIPLE */
476  }
477  /* first match, mark it as found */
478  found = depth;
479  continue;
480  }
481  if (obj->attr->cache.type == cachetype || obj->attr->cache.type == HWLOC_OBJ_CACHE_UNIFIED)
482  /* exact match (either unified is alone, or we match instruction or data), return immediately */
483  return depth;
484  }
485  /* went to the bottom, return what we found */
486  return found;
487 }
488 
496 static __hwloc_inline hwloc_obj_t
497 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure;
498 static __hwloc_inline hwloc_obj_t
500 {
501  hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
502  while (current) {
503  if (current->type == HWLOC_OBJ_CACHE)
504  return current;
505  current = current->parent;
506  }
507  return NULL;
508 }
509 
514 static __hwloc_inline hwloc_obj_t
515 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj) __hwloc_attribute_pure;
516 static __hwloc_inline hwloc_obj_t
517 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj)
518 {
519  hwloc_obj_t current = obj->parent;
520  if (!obj->cpuset)
521  return NULL;
522  while (current && current->cpuset) {
523  if (!hwloc_bitmap_isequal(current->cpuset, obj->cpuset)
524  && current->type == HWLOC_OBJ_CACHE)
525  return current;
526  current = current->parent;
527  }
528  return NULL;
529 }
530 
553 static __hwloc_inline hwloc_obj_t
554 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure;
555 static __hwloc_inline hwloc_obj_t
557 {
558  hwloc_obj_t obj = NULL;
559  while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
560  if (obj->os_index == os_index)
561  return obj;
562  return NULL;
563 }
564 
574 static __hwloc_inline hwloc_obj_t
575 hwloc_get_numanode_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_NODE, obj)) != NULL)
581  if (obj->os_index == os_index)
582  return obj;
583  return NULL;
584 }
585 
597 /* TODO: rather provide an iterator? Provide a way to know how much should be allocated? By returning the total number of objects instead? */
598 HWLOC_DECLSPEC unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * __hwloc_restrict objs, unsigned max);
599 
612 static __hwloc_inline hwloc_obj_t
614  hwloc_obj_type_t type1, unsigned idx1,
615  hwloc_obj_type_t type2, unsigned idx2) __hwloc_attribute_pure;
616 static __hwloc_inline hwloc_obj_t
618  hwloc_obj_type_t type1, unsigned idx1,
619  hwloc_obj_type_t type2, unsigned idx2)
620 {
621  hwloc_obj_t obj;
622  obj = hwloc_get_obj_by_type (topology, type1, idx1);
623  if (!obj || !obj->cpuset)
624  return NULL;
625  return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
626 }
627 
646 static __hwloc_inline hwloc_obj_t
647 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv) __hwloc_attribute_pure;
648 static __hwloc_inline hwloc_obj_t
649 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
650 {
651  hwloc_obj_t obj = hwloc_get_root_obj(topology);
652  int i;
653  for(i=0; i<nr; i++) {
654  if (!obj || !obj->cpuset)
655  return NULL;
656  obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
657  }
658  return obj;
659 }
660 
676 };
677 
701 static __hwloc_inline int
703  hwloc_obj_t *roots, unsigned n_roots,
704  hwloc_cpuset_t *set,
705  unsigned n,
706  unsigned until, unsigned long flags)
707 {
708  unsigned i;
709  unsigned tot_weight;
710  unsigned given, givenweight;
711  hwloc_cpuset_t *cpusetp = set;
712 
713  if (flags & ~HWLOC_DISTRIB_FLAG_REVERSE) {
714  errno = EINVAL;
715  return -1;
716  }
717 
718  tot_weight = 0;
719  for (i = 0; i < n_roots; i++)
720  if (roots[i]->cpuset)
721  tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);
722 
723  for (i = 0, given = 0, givenweight = 0; i < n_roots; i++) {
724  unsigned chunk, weight;
725  hwloc_obj_t root = roots[flags & HWLOC_DISTRIB_FLAG_REVERSE ? n_roots-1-i : i];
726  hwloc_cpuset_t cpuset = root->cpuset;
727  if (!cpuset)
728  continue;
729  weight = hwloc_bitmap_weight(cpuset);
730  if (!weight)
731  continue;
732  /* Give to root a chunk proportional to its weight.
733  * If previous chunks got rounded-up, we may get a bit less. */
734  chunk = (( (givenweight+weight) * n + tot_weight-1) / tot_weight)
735  - (( givenweight * n + tot_weight-1) / tot_weight);
736  if (!root->arity || chunk <= 1 || root->depth >= until) {
737  /* We can't split any more, put everything there. */
738  if (chunk) {
739  /* Fill cpusets with ours */
740  unsigned j;
741  for (j=0; j < chunk; j++)
742  cpusetp[j] = hwloc_bitmap_dup(cpuset);
743  } else {
744  /* We got no chunk, just merge our cpuset to a previous one
745  * (the first chunk cannot be empty)
746  * so that this root doesn't get ignored.
747  */
748  assert(given);
749  hwloc_bitmap_or(cpusetp[-1], cpusetp[-1], cpuset);
750  }
751  } else {
752  /* Still more to distribute, recurse into children */
753  hwloc_distrib(topology, root->children, root->arity, cpusetp, chunk, until, flags);
754  }
755  cpusetp += chunk;
756  given += chunk;
757  givenweight += weight;
758  }
759 
760  return 0;
761 }
762 
779 static __hwloc_inline hwloc_const_cpuset_t
780 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
781 static __hwloc_inline hwloc_const_cpuset_t
783 {
784  return hwloc_get_root_obj(topology)->complete_cpuset;
785 }
786 
797 static __hwloc_inline hwloc_const_cpuset_t
798 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
799 static __hwloc_inline hwloc_const_cpuset_t
801 {
802  return hwloc_get_root_obj(topology)->cpuset;
803 }
804 
814 static __hwloc_inline hwloc_const_cpuset_t
815 hwloc_topology_get_online_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
816 static __hwloc_inline hwloc_const_cpuset_t
818 {
819  return hwloc_get_root_obj(topology)->online_cpuset;
820 }
821 
831 static __hwloc_inline hwloc_const_cpuset_t
832 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
833 static __hwloc_inline hwloc_const_cpuset_t
835 {
836  return hwloc_get_root_obj(topology)->allowed_cpuset;
837 }
838 
848 static __hwloc_inline hwloc_const_nodeset_t
849 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
850 static __hwloc_inline hwloc_const_nodeset_t
852 {
853  return hwloc_get_root_obj(topology)->complete_nodeset;
854 }
855 
866 static __hwloc_inline hwloc_const_nodeset_t
867 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
868 static __hwloc_inline hwloc_const_nodeset_t
870 {
871  return hwloc_get_root_obj(topology)->nodeset;
872 }
873 
883 static __hwloc_inline hwloc_const_nodeset_t
884 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
885 static __hwloc_inline hwloc_const_nodeset_t
887 {
888  return hwloc_get_root_obj(topology)->allowed_nodeset;
889 }
890 
921 static __hwloc_inline void
923 {
924  int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
925  hwloc_obj_t obj;
926 
927  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
928  if (hwloc_bitmap_iszero(_cpuset))
929  hwloc_bitmap_zero(nodeset);
930  else
931  /* Assume the whole system */
932  hwloc_bitmap_fill(nodeset);
933  return;
934  }
935 
936  hwloc_bitmap_zero(nodeset);
937  obj = NULL;
938  while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, _cpuset, depth, obj)) != NULL)
939  hwloc_bitmap_set(nodeset, obj->os_index);
940 }
941 
949 static __hwloc_inline void
951 {
952  int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
953  hwloc_obj_t obj;
954  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
955  return;
956  hwloc_bitmap_zero(nodeset);
957  obj = NULL;
958  while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, _cpuset, depth, obj)) != NULL)
959  hwloc_bitmap_set(nodeset, obj->os_index);
960 }
961 
970 static __hwloc_inline void
972 {
973  int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
974  hwloc_obj_t obj;
975 
976  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) {
977  if (hwloc_bitmap_iszero(nodeset))
978  hwloc_bitmap_zero(_cpuset);
979  else
980  /* Assume the whole system */
981  hwloc_bitmap_fill(_cpuset);
982  return;
983  }
984 
985  hwloc_bitmap_zero(_cpuset);
986  obj = NULL;
987  while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
988  if (hwloc_bitmap_isset(nodeset, obj->os_index))
989  /* no need to check obj->cpuset because objects in levels always have a cpuset */
990  hwloc_bitmap_or(_cpuset, _cpuset, obj->cpuset);
991  }
992 }
993 
1001 static __hwloc_inline void
1003 {
1004  int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
1005  hwloc_obj_t obj;
1006  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
1007  return;
1008  hwloc_bitmap_zero(_cpuset);
1009  obj = NULL;
1010  while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL)
1011  if (hwloc_bitmap_isset(nodeset, obj->os_index))
1012  /* no need to check obj->cpuset because objects in levels always have a cpuset */
1013  hwloc_bitmap_or(_cpuset, _cpuset, obj->cpuset);
1014 }
1015 
1043 static __hwloc_inline const struct hwloc_distances_s *
1045 {
1046  hwloc_obj_t root = hwloc_get_root_obj(topology);
1047  unsigned i;
1048  for(i=0; i<root->distances_count; i++)
1049  if (root->distances[i]->relative_depth == depth)
1050  return root->distances[i];
1051  return NULL;
1052 }
1053 
1073 static __hwloc_inline const struct hwloc_distances_s *
1075 {
1076  int depth = hwloc_get_type_depth(topology, type);
1077  if (depth < 0)
1078  return NULL;
1079  return hwloc_get_whole_distance_matrix_by_depth(topology, depth);
1080 }
1081 
1095 static __hwloc_inline const struct hwloc_distances_s *
1097  hwloc_obj_t obj, unsigned depth,
1098  unsigned *firstp)
1099 {
1100  while (obj && obj->cpuset) {
1101  unsigned i;
1102  for(i=0; i<obj->distances_count; i++)
1103  if (obj->distances[i]->relative_depth == depth - obj->depth) {
1104  if (!obj->distances[i]->nbobjs)
1105  continue;
1106  *firstp = hwloc_get_next_obj_inside_cpuset_by_depth(topology, obj->cpuset, depth, NULL)->logical_index;
1107  return obj->distances[i];
1108  }
1109  obj = obj->parent;
1110  }
1111  return NULL;
1112 }
1113 
1125 static __hwloc_inline int
1127  hwloc_obj_t obj1, hwloc_obj_t obj2,
1128  float *latency, float *reverse_latency)
1129 {
1130  hwloc_obj_t ancestor;
1131  const struct hwloc_distances_s * distances;
1132  unsigned first_logical ;
1133 
1134  if (obj1->depth != obj2->depth) {
1135  errno = EINVAL;
1136  return -1;
1137  }
1138 
1139  ancestor = hwloc_get_common_ancestor_obj(topology, obj1, obj2);
1140  distances = hwloc_get_distance_matrix_covering_obj_by_depth(topology, ancestor, obj1->depth, &first_logical);
1141  if (distances && distances->latency) {
1142  const float * latency_matrix = distances->latency;
1143  unsigned nbobjs = distances->nbobjs;
1144  unsigned l1 = obj1->logical_index - first_logical;
1145  unsigned l2 = obj2->logical_index - first_logical;
1146  *latency = latency_matrix[l1*nbobjs+l2];
1147  *reverse_latency = latency_matrix[l2*nbobjs+l1];
1148  return 0;
1149  }
1150 
1151  errno = ENOSYS;
1152  return -1;
1153 }
1154 
1169 static __hwloc_inline hwloc_obj_t
1170 hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused,
1171  hwloc_obj_t ioobj)
1172 {
1173  hwloc_obj_t obj = ioobj;
1174  while (obj && !obj->cpuset) {
1175  obj = obj->parent;
1176  }
1177  return obj;
1178 }
1179 
1184 static __hwloc_inline hwloc_obj_t
1186 {
1187  return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PCI_DEVICE, prev);
1188 }
1189 
1193 static __hwloc_inline hwloc_obj_t
1195  unsigned domain, unsigned bus, unsigned dev, unsigned func)
1196 {
1197  hwloc_obj_t obj = NULL;
1198  while ((obj = hwloc_get_next_pcidev(topology, obj)) != NULL) {
1199  if (obj->attr->pcidev.domain == domain
1200  && obj->attr->pcidev.bus == bus
1201  && obj->attr->pcidev.dev == dev
1202  && obj->attr->pcidev.func == func)
1203  return obj;
1204  }
1205  return NULL;
1206 }
1207 
1211 static __hwloc_inline hwloc_obj_t
1213 {
1214  unsigned domain = 0; /* default */
1215  unsigned bus, dev, func;
1216 
1217  if (sscanf(busid, "%x:%x.%x", &bus, &dev, &func) != 3
1218  && sscanf(busid, "%x:%x:%x.%x", &domain, &bus, &dev, &func) != 4) {
1219  errno = EINVAL;
1220  return NULL;
1221  }
1222 
1223  return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, func);
1224 }
1225 
1230 static __hwloc_inline hwloc_obj_t
1232 {
1233  return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_OS_DEVICE, prev);
1234 }
1235 
1240 static __hwloc_inline hwloc_obj_t
1242 {
1243  return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_BRIDGE, prev);
1244 }
1245 
1246 /* \brief Checks whether a given bridge covers a given PCI bus.
1247  */
1248 static __hwloc_inline int
1250  unsigned domain, unsigned bus)
1251 {
1252  return bridge->type == HWLOC_OBJ_BRIDGE
1254  && bridge->attr->bridge.downstream.pci.domain == domain
1255  && bridge->attr->bridge.downstream.pci.secondary_bus <= bus
1256  && bridge->attr->bridge.downstream.pci.subordinate_bus >= bus;
1257 }
1258 
1264 static __hwloc_inline hwloc_obj_t
1266  unsigned domain, unsigned bus)
1267 {
1268  hwloc_obj_t obj = NULL;
1269  while ((obj = hwloc_get_next_bridge(topology, obj)) != NULL) {
1270  if (hwloc_bridge_covers_pcibus(obj, domain, bus)) {
1271  /* found bridge covering this pcibus, make sure it's a hostbridge */
1273  assert(obj->parent->type != HWLOC_OBJ_BRIDGE);
1274  assert(obj->parent->cpuset);
1275  return obj;
1276  }
1277  }
1278  return NULL;
1279 }
1280 
1285 #ifdef __cplusplus
1286 } /* extern "C" */
1287 #endif
1288 
1289 
1290 #endif /* HWLOC_HELPER_H */
Structure of a topology object.
Definition: hwloc.h:339
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:88
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:1265
static hwloc_const_nodeset_t hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
Get allowed node set.
Definition: helper.h:886
unsigned arity
Number of children.
Definition: hwloc.h:376
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:1096
unsigned short domain
Definition: hwloc.h:509
Processing Unit, or (Logical) Processor. An execution unit (may share a core with some other logical ...
Definition: hwloc.h:195
hwloc_distrib_flags_e
Flags to be given to hwloc_distrib().
Definition: helper.h:671
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:360
hwloc_const_bitmap_t hwloc_const_cpuset_t
A non-modifiable hwloc_cpuset_t.
Definition: hwloc.h:124
hwloc_obj_type_t
Type of topology object.
Definition: hwloc.h:160
unsigned char dev
Definition: hwloc.h:510
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:1241
struct hwloc_obj * prev_cousin
Previous object of same type and depth.
Definition: hwloc.h:367
unsigned distances_count
Definition: hwloc.h:476
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_NODE with os_index.
Definition: helper.h:577
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_topology_cpuset(hwloc_topology_t topology)
Get topology CPU set.
Definition: helper.h:800
Distances between objects.
Definition: hwloc.h:550
struct hwloc_obj_attr_u::hwloc_cache_attr_s cache
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:649
static hwloc_const_cpuset_t hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
Get complete CPU set.
Definition: helper.h:782
Operating system device. These objects have neither CPU sets nor node sets. They are not added to the...
Definition: hwloc.h:233
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:1126
void hwloc_bitmap_zero(hwloc_bitmap_t bitmap)
Empty the bitmap bitmap.
unsigned char func
Definition: hwloc.h:510
struct hwloc_obj_attr_u::hwloc_bridge_attr_s bridge
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:176
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:1231
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.
struct hwloc_obj * parent
Parent, NULL if root (system object)
Definition: hwloc.h:370
hwloc_nodeset_t allowed_nodeset
The set of allowed NUMA memory nodes.
Definition: hwloc.h:462
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.
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:109
PCI-side of a bridge.
Definition: hwloc.h:262
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:158
unsigned logical_index
Horizontal index in the whole list of similar objects, hence guaranteed unique across the entire mach...
Definition: hwloc.h:359
unsigned depth
Vertical index in the hierarchy. If the topology is symmetric, this is equal to the parent depth plus...
Definition: hwloc.h:354
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:342
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.
struct hwloc_distances_s ** distances
Distances between all objects at same depth below this object.
Definition: hwloc.h:475
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:617
hwloc_cpuset_t complete_cpuset
The complete CPU set of logical processors of this object,.
Definition: hwloc.h:401
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:971
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:1212
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:141
Distrib in reverse order, starting from the last objects.
Definition: helper.h:675
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:460
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:204
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:307
static hwloc_const_cpuset_t hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
Get online CPU set.
Definition: helper.h:817
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:1170
Objects of given type exist at different depth in the topology.
Definition: hwloc.h:1118
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:499
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:423
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:127
static hwloc_const_cpuset_t hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
Get allowed CPU set.
Definition: helper.h:834
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:283
hwloc_obj_cache_type_t type
Cache type.
Definition: hwloc.h:501
hwloc_obj_type_t type
Type of object.
Definition: hwloc.h:341
hwloc_nodeset_t complete_nodeset
The complete NUMA node set of this object,.
Definition: hwloc.h:448
int hwloc_bitmap_isset(hwloc_const_bitmap_t bitmap, unsigned id)
Test whether index id is part of bitmap bitmap.
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:122
NUMA node. A set of processors around memory which the processors can directly access.
Definition: hwloc.h:180
static hwloc_const_nodeset_t hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
Get topology node set.
Definition: helper.h:869
enum hwloc_obj_cache_type_e hwloc_obj_cache_type_t
Cache type.
struct hwloc_obj * next_sibling
Next object below the same parent.
Definition: hwloc.h:372
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:258
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:413
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:374
hwloc_nodeset_t nodeset
NUMA nodes covered by this object or containing this object.
Definition: hwloc.h:431
Host-side of a bridge, only possible upstream.
Definition: hwloc.h:261
int hwloc_bitmap_isequal(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2)
Test whether bitmap bitmap1 is equal to bitmap bitmap2.
hwloc_obj_bridge_type_t downstream_type
Definition: hwloc.h:528
union hwloc_obj_attr_u * attr
Object type-specific Attributes, may be NULL if no attribute value was found.
Definition: hwloc.h:350
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.
hwloc_cpuset_t online_cpuset
The CPU set of online logical processors.
Definition: hwloc.h:412
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:334
unsigned depth
Depth of cache (e.g., L1, L2, ...etc.)
Definition: hwloc.h:497
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 lvl1 and lvl2.
Definition: helper.h:386
hwloc_bitmap_t hwloc_bitmap_dup(hwloc_const_bitmap_t bitmap)
Duplicate bitmap bitmap by allocating a new bitmap and copying bitmap contents.
static int hwloc_bridge_covers_pcibus(hwloc_obj_t bridge, unsigned domain, unsigned bus)
Definition: helper.h:1249
struct hwloc_obj * first_child
First child.
Definition: hwloc.h:378
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
hwloc_const_bitmap_t hwloc_const_nodeset_t
A non-modifiable hwloc_nodeset_t.
Definition: hwloc.h:144
float * latency
Matrix of latencies between objects, stored as a one-dimension array. May be NULL if the distances co...
Definition: hwloc.h:558
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:1002
struct hwloc_obj_attr_u::hwloc_pcidev_attr_s pcidev
struct hwloc_obj * next_cousin
Next object of same type and depth.
Definition: hwloc.h:366
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:517
PCI device. These objects have neither CPU sets nor node sets. They are not added to the topology unl...
Definition: hwloc.h:228
Cache. Can be L1i, L1d, L2, L3, ...
Definition: hwloc.h:188
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.
int hwloc_bitmap_intersects(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2)
Test whether bitmaps bitmap1 and bitmap2 intersects.
struct hwloc_pcidev_attr_s pci
Definition: hwloc.h:519
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:227
No object of given type exists in the topology.
Definition: hwloc.h:1117
int hwloc_bitmap_iszero(hwloc_const_bitmap_t bitmap)
Test whether bitmap bitmap is empty.
unsigned char bus
Definition: hwloc.h:510
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:1074
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:922
struct hwloc_obj ** children
Children, children[0 .. arity -1].
Definition: hwloc.h:377
Unified cache.
Definition: hwloc.h:253
struct hwloc_topology * hwloc_topology_t
Topology context.
Definition: hwloc.h:596
hwloc_cpuset_t allowed_cpuset
The CPU set of allowed logical processors.
Definition: hwloc.h:420
int hwloc_get_type_depth(hwloc_topology_t topology, hwloc_obj_type_t type)
Returns the depth of objects of type type.
void hwloc_bitmap_set(hwloc_bitmap_t bitmap, unsigned id)
Add index id in bitmap bitmap.
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.
Bridge. Any bridge that connects the host or an I/O bus, to another I/O bus. Bridge objects have neit...
Definition: hwloc.h:221
hwloc_cpuset_t cpuset
CPUs covered by this object.
Definition: hwloc.h:388
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:1185
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:702
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:950
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:1044
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:556
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:1194
unsigned relative_depth
Relative depth of the considered objects below the object containing this distance information...
Definition: hwloc.h:551
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).
unsigned nbobjs
Number of objects considered in the matrix. It is the number of descendant objects at relative_depth ...
Definition: hwloc.h:553
static hwloc_const_nodeset_t hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
Get complete node set.
Definition: helper.h:851
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...
union hwloc_obj_attr_u::hwloc_bridge_attr_s::@1 downstream
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.
hwloc_obj_bridge_type_t upstream_type
Definition: hwloc.h:521