00001
00002
00003
00004
00005
00006
00007
00008
00013 #ifndef HWLOC_HELPER_H
00014 #define HWLOC_HELPER_H
00015
00016 #ifndef HWLOC_H
00017 #error Please include the main hwloc.h instead
00018 #endif
00019
00020 #include <stdlib.h>
00021 #include <errno.h>
00022
00023
00024 #ifdef __cplusplus
00025 extern "C" {
00026 #endif
00027
00028
00044 static __hwloc_inline hwloc_obj_t
00045 hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
00046 {
00047 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00048 if (!obj->cpuset || !hwloc_bitmap_intersects(obj->cpuset, set))
00049 return NULL;
00050 while (!hwloc_bitmap_isincluded(obj->cpuset, set)) {
00051
00052 hwloc_obj_t child = obj->first_child;
00053 while (child) {
00054 if (child->cpuset && hwloc_bitmap_intersects(child->cpuset, set))
00055 break;
00056 child = child->next_sibling;
00057 }
00058 if (!child)
00059
00060 return obj;
00061
00062 obj = child;
00063 }
00064
00065 return obj;
00066 }
00067
00075 HWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00076 hwloc_obj_t * __hwloc_restrict objs, int max);
00077
00087 static __hwloc_inline hwloc_obj_t
00088 hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00089 unsigned depth, hwloc_obj_t prev)
00090 {
00091 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00092 if (!next || !next->cpuset)
00093 return NULL;
00094 while (next && !hwloc_bitmap_isincluded(next->cpuset, set))
00095 next = next->next_cousin;
00096 return next;
00097 }
00098
00108 static __hwloc_inline hwloc_obj_t
00109 hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00110 hwloc_obj_type_t type, hwloc_obj_t prev)
00111 {
00112 int depth = hwloc_get_type_depth(topology, type);
00113 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00114 return NULL;
00115 return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
00116 }
00117
00123 static __hwloc_inline hwloc_obj_t
00124 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00125 unsigned depth, unsigned idx) __hwloc_attribute_pure;
00126 static __hwloc_inline hwloc_obj_t
00127 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00128 unsigned depth, unsigned idx)
00129 {
00130 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00131 unsigned count = 0;
00132 if (!obj || !obj->cpuset)
00133 return NULL;
00134 while (obj) {
00135 if (hwloc_bitmap_isincluded(obj->cpuset, set)) {
00136 if (count == idx)
00137 return obj;
00138 count++;
00139 }
00140 obj = obj->next_cousin;
00141 }
00142 return NULL;
00143 }
00144
00154 static __hwloc_inline hwloc_obj_t
00155 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00156 hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure;
00157 static __hwloc_inline hwloc_obj_t
00158 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00159 hwloc_obj_type_t type, unsigned idx)
00160 {
00161 int depth = hwloc_get_type_depth(topology, type);
00162 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00163 return NULL;
00164 return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
00165 }
00166
00172 static __hwloc_inline unsigned
00173 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00174 unsigned depth) __hwloc_attribute_pure;
00175 static __hwloc_inline unsigned
00176 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00177 unsigned depth)
00178 {
00179 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00180 unsigned count = 0;
00181 if (!obj || !obj->cpuset)
00182 return 0;
00183 while (obj) {
00184 if (hwloc_bitmap_isincluded(obj->cpuset, set))
00185 count++;
00186 obj = obj->next_cousin;
00187 }
00188 return count;
00189 }
00190
00200 static __hwloc_inline int
00201 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00202 hwloc_obj_type_t type) __hwloc_attribute_pure;
00203 static __hwloc_inline int
00204 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00205 hwloc_obj_type_t type)
00206 {
00207 int depth = hwloc_get_type_depth(topology, type);
00208 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
00209 return 0;
00210 if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00211 return -1;
00212 return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
00213 }
00214
00223 static __hwloc_inline int
00224 hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00225 hwloc_obj_t obj) __hwloc_attribute_pure;
00226 static __hwloc_inline int
00227 hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00228 hwloc_obj_t obj)
00229 {
00230 int idx = 0;
00231 if (!hwloc_bitmap_isincluded(obj->cpuset, set))
00232 return -1;
00233
00234 while ((obj = obj->prev_cousin) != NULL)
00235 if (hwloc_bitmap_isincluded(obj->cpuset, set))
00236 idx++;
00237 return idx;
00238 }
00239
00254 static __hwloc_inline hwloc_obj_t
00255 hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00256 hwloc_obj_t parent) __hwloc_attribute_pure;
00257 static __hwloc_inline hwloc_obj_t
00258 hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00259 hwloc_obj_t parent)
00260 {
00261 hwloc_obj_t child;
00262 if (!parent->cpuset || hwloc_bitmap_iszero(set))
00263 return NULL;
00264 child = parent->first_child;
00265 while (child) {
00266 if (child->cpuset && hwloc_bitmap_isincluded(set, child->cpuset))
00267 return child;
00268 child = child->next_sibling;
00269 }
00270 return NULL;
00271 }
00272
00280 static __hwloc_inline hwloc_obj_t
00281 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure;
00282 static __hwloc_inline hwloc_obj_t
00283 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00284 {
00285 struct hwloc_obj *current = hwloc_get_root_obj(topology);
00286 if (hwloc_bitmap_iszero(set) || !current->cpuset || !hwloc_bitmap_isincluded(set, current->cpuset))
00287 return NULL;
00288 while (1) {
00289 hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
00290 if (!child)
00291 return current;
00292 current = child;
00293 }
00294 }
00295
00306 static __hwloc_inline hwloc_obj_t
00307 hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00308 unsigned depth, hwloc_obj_t prev)
00309 {
00310 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00311 if (!next || !next->cpuset)
00312 return NULL;
00313 while (next && !hwloc_bitmap_intersects(set, next->cpuset))
00314 next = next->next_cousin;
00315 return next;
00316 }
00317
00333 static __hwloc_inline hwloc_obj_t
00334 hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00335 hwloc_obj_type_t type, hwloc_obj_t prev)
00336 {
00337 int depth = hwloc_get_type_depth(topology, type);
00338 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00339 return NULL;
00340 return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
00341 }
00342
00357 static __hwloc_inline hwloc_obj_t
00358 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj) __hwloc_attribute_pure;
00359 static __hwloc_inline hwloc_obj_t
00360 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj)
00361 {
00362 hwloc_obj_t ancestor = obj;
00363 if (obj->depth < depth)
00364 return NULL;
00365 while (ancestor && ancestor->depth > depth)
00366 ancestor = ancestor->parent;
00367 return ancestor;
00368 }
00369
00371 static __hwloc_inline hwloc_obj_t
00372 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;
00373 static __hwloc_inline hwloc_obj_t
00374 hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj)
00375 {
00376 hwloc_obj_t ancestor = obj->parent;
00377 while (ancestor && ancestor->type != type)
00378 ancestor = ancestor->parent;
00379 return ancestor;
00380 }
00381
00383 static __hwloc_inline hwloc_obj_t
00384 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2) __hwloc_attribute_pure;
00385 static __hwloc_inline hwloc_obj_t
00386 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2)
00387 {
00388
00389
00390
00391
00392
00393 while (obj1 != obj2) {
00394 while (obj1->depth > obj2->depth)
00395 obj1 = obj1->parent;
00396 while (obj2->depth > obj1->depth)
00397 obj2 = obj2->parent;
00398 if (obj1 != obj2 && obj1->depth == obj2->depth) {
00399 obj1 = obj1->parent;
00400 obj2 = obj2->parent;
00401 }
00402 }
00403 return obj1;
00404 }
00405
00410 static __hwloc_inline int
00411 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root) __hwloc_attribute_pure;
00412 static __hwloc_inline int
00413 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root)
00414 {
00415 return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
00416 }
00417
00422 static __hwloc_inline hwloc_obj_t
00423 hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev)
00424 {
00425 if (!prev)
00426 return parent->first_child;
00427 if (prev->parent != parent)
00428 return NULL;
00429 return prev->next_sibling;
00430 }
00431
00459 static __hwloc_inline int
00460 hwloc_get_cache_type_depth (hwloc_topology_t topology,
00461 unsigned cachelevel, hwloc_obj_cache_type_t cachetype)
00462 {
00463 int depth;
00464 int found = HWLOC_TYPE_DEPTH_UNKNOWN;
00465 for (depth=0; ; depth++) {
00466 hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, 0);
00467 if (!obj)
00468 break;
00469 if (obj->type != HWLOC_OBJ_CACHE || obj->attr->cache.depth != cachelevel)
00470
00471 continue;
00472 if (cachetype == (hwloc_obj_cache_type_t) -1) {
00473 if (found != HWLOC_TYPE_DEPTH_UNKNOWN) {
00474
00475 return HWLOC_TYPE_DEPTH_MULTIPLE;
00476 }
00477
00478 found = depth;
00479 continue;
00480 }
00481 if (obj->attr->cache.type == cachetype || obj->attr->cache.type == HWLOC_OBJ_CACHE_UNIFIED)
00482
00483 return depth;
00484 }
00485
00486 return found;
00487 }
00488
00496 static __hwloc_inline hwloc_obj_t
00497 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure;
00498 static __hwloc_inline hwloc_obj_t
00499 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00500 {
00501 hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
00502 while (current) {
00503 if (current->type == HWLOC_OBJ_CACHE)
00504 return current;
00505 current = current->parent;
00506 }
00507 return NULL;
00508 }
00509
00514 static __hwloc_inline hwloc_obj_t
00515 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj) __hwloc_attribute_pure;
00516 static __hwloc_inline hwloc_obj_t
00517 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj)
00518 {
00519 hwloc_obj_t current = obj->parent;
00520 if (!obj->cpuset)
00521 return NULL;
00522 while (current && current->cpuset) {
00523 if (!hwloc_bitmap_isequal(current->cpuset, obj->cpuset)
00524 && current->type == HWLOC_OBJ_CACHE)
00525 return current;
00526 current = current->parent;
00527 }
00528 return NULL;
00529 }
00530
00552 static __hwloc_inline hwloc_obj_t
00553 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure;
00554 static __hwloc_inline hwloc_obj_t
00555 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
00556 {
00557 hwloc_obj_t obj = NULL;
00558 while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
00559 if (obj->os_index == os_index)
00560 return obj;
00561 return NULL;
00562 }
00563
00575
00576 HWLOC_DECLSPEC unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * __hwloc_restrict objs, unsigned max);
00577
00590 static __hwloc_inline hwloc_obj_t
00591 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
00592 hwloc_obj_type_t type1, unsigned idx1,
00593 hwloc_obj_type_t type2, unsigned idx2) __hwloc_attribute_pure;
00594 static __hwloc_inline hwloc_obj_t
00595 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
00596 hwloc_obj_type_t type1, unsigned idx1,
00597 hwloc_obj_type_t type2, unsigned idx2)
00598 {
00599 hwloc_obj_t obj;
00600 obj = hwloc_get_obj_by_type (topology, type1, idx1);
00601 if (!obj || !obj->cpuset)
00602 return NULL;
00603 return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
00604 }
00605
00624 static __hwloc_inline hwloc_obj_t
00625 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv) __hwloc_attribute_pure;
00626 static __hwloc_inline hwloc_obj_t
00627 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
00628 {
00629 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00630 int i;
00631 for(i=0; i<nr; i++) {
00632 if (!obj || !obj->cpuset)
00633 return NULL;
00634 obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
00635 }
00636 return obj;
00637 }
00638
00649 enum hwloc_distrib_flags_e {
00653 HWLOC_DISTRIB_FLAG_REVERSE = (1UL<<0)
00654 };
00655
00679 static __hwloc_inline int
00680 hwloc_distrib(hwloc_topology_t topology,
00681 hwloc_obj_t *roots, unsigned n_roots,
00682 hwloc_cpuset_t *set,
00683 unsigned n,
00684 unsigned until, unsigned long flags)
00685 {
00686 unsigned i;
00687 unsigned tot_weight;
00688 hwloc_cpuset_t *cpusetp = set;
00689
00690 if (flags & ~HWLOC_DISTRIB_FLAG_REVERSE) {
00691 errno = EINVAL;
00692 return -1;
00693 }
00694
00695 tot_weight = 0;
00696 for (i = 0; i < n_roots; i++)
00697 if (roots[i]->cpuset)
00698 tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);
00699
00700 for (i = 0; i < n_roots && tot_weight; i++) {
00701
00702 hwloc_obj_t root = roots[flags & HWLOC_DISTRIB_FLAG_REVERSE ? n_roots-1-i : i];
00703 unsigned weight = root->cpuset ? hwloc_bitmap_weight(root->cpuset) : 0;
00704 unsigned chunk = (n * weight + tot_weight-1) / tot_weight;
00705 if (!root->arity || chunk == 1 || root->depth >= until) {
00706
00707 unsigned j;
00708 for (j=0; j<n; j++)
00709 cpusetp[j] = hwloc_bitmap_dup(root->cpuset);
00710 } else {
00711
00712 hwloc_distrib(topology, root->children, root->arity, cpusetp, chunk, until, flags);
00713 }
00714 cpusetp += chunk;
00715 tot_weight -= weight;
00716 n -= chunk;
00717 }
00718
00719 return 0;
00720 }
00721
00738 static __hwloc_inline hwloc_const_cpuset_t
00739 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
00740 static __hwloc_inline hwloc_const_cpuset_t
00741 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
00742 {
00743 return hwloc_get_root_obj(topology)->complete_cpuset;
00744 }
00745
00756 static __hwloc_inline hwloc_const_cpuset_t
00757 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
00758 static __hwloc_inline hwloc_const_cpuset_t
00759 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
00760 {
00761 return hwloc_get_root_obj(topology)->cpuset;
00762 }
00763
00773 static __hwloc_inline hwloc_const_cpuset_t
00774 hwloc_topology_get_online_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
00775 static __hwloc_inline hwloc_const_cpuset_t
00776 hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
00777 {
00778 return hwloc_get_root_obj(topology)->online_cpuset;
00779 }
00780
00790 static __hwloc_inline hwloc_const_cpuset_t
00791 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
00792 static __hwloc_inline hwloc_const_cpuset_t
00793 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
00794 {
00795 return hwloc_get_root_obj(topology)->allowed_cpuset;
00796 }
00797
00807 static __hwloc_inline hwloc_const_nodeset_t
00808 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
00809 static __hwloc_inline hwloc_const_nodeset_t
00810 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
00811 {
00812 return hwloc_get_root_obj(topology)->complete_nodeset;
00813 }
00814
00825 static __hwloc_inline hwloc_const_nodeset_t
00826 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
00827 static __hwloc_inline hwloc_const_nodeset_t
00828 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
00829 {
00830 return hwloc_get_root_obj(topology)->nodeset;
00831 }
00832
00842 static __hwloc_inline hwloc_const_nodeset_t
00843 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
00844 static __hwloc_inline hwloc_const_nodeset_t
00845 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
00846 {
00847 return hwloc_get_root_obj(topology)->allowed_nodeset;
00848 }
00849
00880 static __hwloc_inline void
00881 hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset)
00882 {
00883 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00884 hwloc_obj_t obj;
00885
00886 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
00887 if (hwloc_bitmap_iszero(_cpuset))
00888 hwloc_bitmap_zero(nodeset);
00889 else
00890
00891 hwloc_bitmap_fill(nodeset);
00892 return;
00893 }
00894
00895 hwloc_bitmap_zero(nodeset);
00896 obj = NULL;
00897 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, _cpuset, depth, obj)) != NULL)
00898 hwloc_bitmap_set(nodeset, obj->os_index);
00899 }
00900
00908 static __hwloc_inline void
00909 hwloc_cpuset_to_nodeset_strict(struct hwloc_topology *topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset)
00910 {
00911 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00912 hwloc_obj_t obj;
00913 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
00914 return;
00915 hwloc_bitmap_zero(nodeset);
00916 obj = NULL;
00917 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, _cpuset, depth, obj)) != NULL)
00918 hwloc_bitmap_set(nodeset, obj->os_index);
00919 }
00920
00929 static __hwloc_inline void
00930 hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset)
00931 {
00932 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00933 hwloc_obj_t obj;
00934
00935 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) {
00936 if (hwloc_bitmap_iszero(nodeset))
00937 hwloc_bitmap_zero(_cpuset);
00938 else
00939
00940 hwloc_bitmap_fill(_cpuset);
00941 return;
00942 }
00943
00944 hwloc_bitmap_zero(_cpuset);
00945 obj = NULL;
00946 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
00947 if (hwloc_bitmap_isset(nodeset, obj->os_index))
00948
00949 hwloc_bitmap_or(_cpuset, _cpuset, obj->cpuset);
00950 }
00951 }
00952
00960 static __hwloc_inline void
00961 hwloc_cpuset_from_nodeset_strict(struct hwloc_topology *topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset)
00962 {
00963 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00964 hwloc_obj_t obj;
00965 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
00966 return;
00967 hwloc_bitmap_zero(_cpuset);
00968 obj = NULL;
00969 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL)
00970 if (hwloc_bitmap_isset(nodeset, obj->os_index))
00971
00972 hwloc_bitmap_or(_cpuset, _cpuset, obj->cpuset);
00973 }
00974
01002 static __hwloc_inline const struct hwloc_distances_s *
01003 hwloc_get_whole_distance_matrix_by_depth(hwloc_topology_t topology, unsigned depth)
01004 {
01005 hwloc_obj_t root = hwloc_get_root_obj(topology);
01006 unsigned i;
01007 for(i=0; i<root->distances_count; i++)
01008 if (root->distances[i]->relative_depth == depth)
01009 return root->distances[i];
01010 return NULL;
01011 }
01012
01032 static __hwloc_inline const struct hwloc_distances_s *
01033 hwloc_get_whole_distance_matrix_by_type(hwloc_topology_t topology, hwloc_obj_type_t type)
01034 {
01035 int depth = hwloc_get_type_depth(topology, type);
01036 if (depth < 0)
01037 return NULL;
01038 return hwloc_get_whole_distance_matrix_by_depth(topology, depth);
01039 }
01040
01054 static __hwloc_inline const struct hwloc_distances_s *
01055 hwloc_get_distance_matrix_covering_obj_by_depth(hwloc_topology_t topology,
01056 hwloc_obj_t obj, unsigned depth,
01057 unsigned *firstp)
01058 {
01059 while (obj && obj->cpuset) {
01060 unsigned i;
01061 for(i=0; i<obj->distances_count; i++)
01062 if (obj->distances[i]->relative_depth == depth - obj->depth) {
01063 if (!obj->distances[i]->nbobjs)
01064 continue;
01065 *firstp = hwloc_get_next_obj_inside_cpuset_by_depth(topology, obj->cpuset, depth, NULL)->logical_index;
01066 return obj->distances[i];
01067 }
01068 obj = obj->parent;
01069 }
01070 return NULL;
01071 }
01072
01084 static __hwloc_inline int
01085 hwloc_get_latency(hwloc_topology_t topology,
01086 hwloc_obj_t obj1, hwloc_obj_t obj2,
01087 float *latency, float *reverse_latency)
01088 {
01089 hwloc_obj_t ancestor;
01090 const struct hwloc_distances_s * distances;
01091 unsigned first_logical ;
01092
01093 if (obj1->depth != obj2->depth) {
01094 errno = EINVAL;
01095 return -1;
01096 }
01097
01098 ancestor = hwloc_get_common_ancestor_obj(topology, obj1, obj2);
01099 distances = hwloc_get_distance_matrix_covering_obj_by_depth(topology, ancestor, obj1->depth, &first_logical);
01100 if (distances && distances->latency) {
01101 const float * latency_matrix = distances->latency;
01102 unsigned nbobjs = distances->nbobjs;
01103 unsigned l1 = obj1->logical_index - first_logical;
01104 unsigned l2 = obj2->logical_index - first_logical;
01105 *latency = latency_matrix[l1*nbobjs+l2];
01106 *reverse_latency = latency_matrix[l2*nbobjs+l1];
01107 return 0;
01108 }
01109
01110 errno = ENOSYS;
01111 return -1;
01112 }
01113
01128 static __hwloc_inline hwloc_obj_t
01129 hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused,
01130 hwloc_obj_t ioobj)
01131 {
01132 hwloc_obj_t obj = ioobj;
01133 while (obj && !obj->cpuset) {
01134 obj = obj->parent;
01135 }
01136 return obj;
01137 }
01138
01143 static __hwloc_inline hwloc_obj_t
01144 hwloc_get_next_pcidev(hwloc_topology_t topology, hwloc_obj_t prev)
01145 {
01146 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PCI_DEVICE, prev);
01147 }
01148
01152 static __hwloc_inline hwloc_obj_t
01153 hwloc_get_pcidev_by_busid(hwloc_topology_t topology,
01154 unsigned domain, unsigned bus, unsigned dev, unsigned func)
01155 {
01156 hwloc_obj_t obj = NULL;
01157 while ((obj = hwloc_get_next_pcidev(topology, obj)) != NULL) {
01158 if (obj->attr->pcidev.domain == domain
01159 && obj->attr->pcidev.bus == bus
01160 && obj->attr->pcidev.dev == dev
01161 && obj->attr->pcidev.func == func)
01162 return obj;
01163 }
01164 return NULL;
01165 }
01166
01170 static __hwloc_inline hwloc_obj_t
01171 hwloc_get_pcidev_by_busidstring(hwloc_topology_t topology, const char *busid)
01172 {
01173 unsigned domain = 0;
01174 unsigned bus, dev, func;
01175
01176 if (sscanf(busid, "%x:%x.%x", &bus, &dev, &func) != 3
01177 && sscanf(busid, "%x:%x:%x.%x", &domain, &bus, &dev, &func) != 4) {
01178 errno = EINVAL;
01179 return NULL;
01180 }
01181
01182 return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, func);
01183 }
01184
01189 static __hwloc_inline hwloc_obj_t
01190 hwloc_get_next_osdev(hwloc_topology_t topology, hwloc_obj_t prev)
01191 {
01192 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_OS_DEVICE, prev);
01193 }
01194
01199 static __hwloc_inline hwloc_obj_t
01200 hwloc_get_next_bridge(hwloc_topology_t topology, hwloc_obj_t prev)
01201 {
01202 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_BRIDGE, prev);
01203 }
01204
01205
01206
01207 static __hwloc_inline int
01208 hwloc_bridge_covers_pcibus(hwloc_obj_t bridge,
01209 unsigned domain, unsigned bus)
01210 {
01211 return bridge->type == HWLOC_OBJ_BRIDGE
01212 && bridge->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI
01213 && bridge->attr->bridge.downstream.pci.domain == domain
01214 && bridge->attr->bridge.downstream.pci.secondary_bus <= bus
01215 && bridge->attr->bridge.downstream.pci.subordinate_bus >= bus;
01216 }
01217
01223 static __hwloc_inline hwloc_obj_t
01224 hwloc_get_hostbridge_by_pcibus(hwloc_topology_t topology,
01225 unsigned domain, unsigned bus)
01226 {
01227 hwloc_obj_t obj = NULL;
01228 while ((obj = hwloc_get_next_bridge(topology, obj)) != NULL) {
01229 if (hwloc_bridge_covers_pcibus(obj, domain, bus)) {
01230
01231 assert(obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_HOST);
01232 assert(obj->parent->type != HWLOC_OBJ_BRIDGE);
01233 assert(obj->parent->cpuset);
01234 return obj;
01235 }
01236 }
01237 return NULL;
01238 }
01239
01244 #ifdef __cplusplus
01245 }
01246 #endif
01247
01248
01249 #endif