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
00090 static __hwloc_inline hwloc_obj_t
00091 hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00092 unsigned depth, hwloc_obj_t prev)
00093 {
00094 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00095 if (!next || !next->cpuset)
00096 return NULL;
00097 while (next && (hwloc_bitmap_iszero(next->cpuset) || !hwloc_bitmap_isincluded(next->cpuset, set)))
00098 next = next->next_cousin;
00099 return next;
00100 }
00101
00114 static __hwloc_inline hwloc_obj_t
00115 hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00116 hwloc_obj_type_t type, hwloc_obj_t prev)
00117 {
00118 int depth = hwloc_get_type_depth(topology, type);
00119 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00120 return NULL;
00121 return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
00122 }
00123
00132 static __hwloc_inline hwloc_obj_t
00133 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00134 unsigned depth, unsigned idx) __hwloc_attribute_pure;
00135 static __hwloc_inline hwloc_obj_t
00136 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00137 unsigned depth, unsigned idx)
00138 {
00139 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00140 unsigned count = 0;
00141 if (!obj || !obj->cpuset)
00142 return NULL;
00143 while (obj) {
00144 if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set)) {
00145 if (count == idx)
00146 return obj;
00147 count++;
00148 }
00149 obj = obj->next_cousin;
00150 }
00151 return NULL;
00152 }
00153
00166 static __hwloc_inline hwloc_obj_t
00167 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00168 hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure;
00169 static __hwloc_inline hwloc_obj_t
00170 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00171 hwloc_obj_type_t type, unsigned idx)
00172 {
00173 int depth = hwloc_get_type_depth(topology, type);
00174 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00175 return NULL;
00176 return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
00177 }
00178
00187 static __hwloc_inline unsigned
00188 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00189 unsigned depth) __hwloc_attribute_pure;
00190 static __hwloc_inline unsigned
00191 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00192 unsigned depth)
00193 {
00194 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00195 unsigned count = 0;
00196 if (!obj || !obj->cpuset)
00197 return 0;
00198 while (obj) {
00199 if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set))
00200 count++;
00201 obj = obj->next_cousin;
00202 }
00203 return count;
00204 }
00205
00218 static __hwloc_inline int
00219 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00220 hwloc_obj_type_t type) __hwloc_attribute_pure;
00221 static __hwloc_inline int
00222 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00223 hwloc_obj_type_t type)
00224 {
00225 int depth = hwloc_get_type_depth(topology, type);
00226 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
00227 return 0;
00228 if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00229 return -1;
00230 return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
00231 }
00232
00244 static __hwloc_inline int
00245 hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00246 hwloc_obj_t obj) __hwloc_attribute_pure;
00247 static __hwloc_inline int
00248 hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00249 hwloc_obj_t obj)
00250 {
00251 int idx = 0;
00252 if (!hwloc_bitmap_isincluded(obj->cpuset, set))
00253 return -1;
00254
00255 while ((obj = obj->prev_cousin) != NULL)
00256 if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set))
00257 idx++;
00258 return idx;
00259 }
00260
00275 static __hwloc_inline hwloc_obj_t
00276 hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00277 hwloc_obj_t parent) __hwloc_attribute_pure;
00278 static __hwloc_inline hwloc_obj_t
00279 hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00280 hwloc_obj_t parent)
00281 {
00282 hwloc_obj_t child;
00283 if (!parent->cpuset || hwloc_bitmap_iszero(set))
00284 return NULL;
00285 child = parent->first_child;
00286 while (child) {
00287 if (child->cpuset && hwloc_bitmap_isincluded(set, child->cpuset))
00288 return child;
00289 child = child->next_sibling;
00290 }
00291 return NULL;
00292 }
00293
00301 static __hwloc_inline hwloc_obj_t
00302 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure;
00303 static __hwloc_inline hwloc_obj_t
00304 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00305 {
00306 struct hwloc_obj *current = hwloc_get_root_obj(topology);
00307 if (hwloc_bitmap_iszero(set) || !current->cpuset || !hwloc_bitmap_isincluded(set, current->cpuset))
00308 return NULL;
00309 while (1) {
00310 hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
00311 if (!child)
00312 return current;
00313 current = child;
00314 }
00315 }
00316
00327 static __hwloc_inline hwloc_obj_t
00328 hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00329 unsigned depth, hwloc_obj_t prev)
00330 {
00331 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00332 if (!next || !next->cpuset)
00333 return NULL;
00334 while (next && !hwloc_bitmap_intersects(set, next->cpuset))
00335 next = next->next_cousin;
00336 return next;
00337 }
00338
00354 static __hwloc_inline hwloc_obj_t
00355 hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00356 hwloc_obj_type_t type, hwloc_obj_t prev)
00357 {
00358 int depth = hwloc_get_type_depth(topology, type);
00359 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00360 return NULL;
00361 return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
00362 }
00363
00378 static __hwloc_inline hwloc_obj_t
00379 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj) __hwloc_attribute_pure;
00380 static __hwloc_inline hwloc_obj_t
00381 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj)
00382 {
00383 hwloc_obj_t ancestor = obj;
00384 if (obj->depth < depth)
00385 return NULL;
00386 while (ancestor && ancestor->depth > depth)
00387 ancestor = ancestor->parent;
00388 return ancestor;
00389 }
00390
00392 static __hwloc_inline hwloc_obj_t
00393 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;
00394 static __hwloc_inline hwloc_obj_t
00395 hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj)
00396 {
00397 hwloc_obj_t ancestor = obj->parent;
00398 while (ancestor && ancestor->type != type)
00399 ancestor = ancestor->parent;
00400 return ancestor;
00401 }
00402
00404 static __hwloc_inline hwloc_obj_t
00405 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2) __hwloc_attribute_pure;
00406 static __hwloc_inline hwloc_obj_t
00407 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2)
00408 {
00409
00410
00411
00412
00413
00414 while (obj1 != obj2) {
00415 while (obj1->depth > obj2->depth)
00416 obj1 = obj1->parent;
00417 while (obj2->depth > obj1->depth)
00418 obj2 = obj2->parent;
00419 if (obj1 != obj2 && obj1->depth == obj2->depth) {
00420 obj1 = obj1->parent;
00421 obj2 = obj2->parent;
00422 }
00423 }
00424 return obj1;
00425 }
00426
00431 static __hwloc_inline int
00432 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root) __hwloc_attribute_pure;
00433 static __hwloc_inline int
00434 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root)
00435 {
00436 return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
00437 }
00438
00443 static __hwloc_inline hwloc_obj_t
00444 hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev)
00445 {
00446 if (!prev)
00447 return parent->first_child;
00448 if (prev->parent != parent)
00449 return NULL;
00450 return prev->next_sibling;
00451 }
00452
00480 static __hwloc_inline int
00481 hwloc_get_cache_type_depth (hwloc_topology_t topology,
00482 unsigned cachelevel, hwloc_obj_cache_type_t cachetype)
00483 {
00484 int depth;
00485 int found = HWLOC_TYPE_DEPTH_UNKNOWN;
00486 for (depth=0; ; depth++) {
00487 hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, 0);
00488 if (!obj)
00489 break;
00490 if (obj->type != HWLOC_OBJ_CACHE || obj->attr->cache.depth != cachelevel)
00491
00492 continue;
00493 if (cachetype == (hwloc_obj_cache_type_t) -1) {
00494 if (found != HWLOC_TYPE_DEPTH_UNKNOWN) {
00495
00496 return HWLOC_TYPE_DEPTH_MULTIPLE;
00497 }
00498
00499 found = depth;
00500 continue;
00501 }
00502 if (obj->attr->cache.type == cachetype || obj->attr->cache.type == HWLOC_OBJ_CACHE_UNIFIED)
00503
00504 return depth;
00505 }
00506
00507 return found;
00508 }
00509
00517 static __hwloc_inline hwloc_obj_t
00518 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure;
00519 static __hwloc_inline hwloc_obj_t
00520 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00521 {
00522 hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
00523 while (current) {
00524 if (current->type == HWLOC_OBJ_CACHE)
00525 return current;
00526 current = current->parent;
00527 }
00528 return NULL;
00529 }
00530
00535 static __hwloc_inline hwloc_obj_t
00536 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj) __hwloc_attribute_pure;
00537 static __hwloc_inline hwloc_obj_t
00538 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj)
00539 {
00540 hwloc_obj_t current = obj->parent;
00541 if (!obj->cpuset)
00542 return NULL;
00543 while (current && current->cpuset) {
00544 if (!hwloc_bitmap_isequal(current->cpuset, obj->cpuset)
00545 && current->type == HWLOC_OBJ_CACHE)
00546 return current;
00547 current = current->parent;
00548 }
00549 return NULL;
00550 }
00551
00574 static __hwloc_inline hwloc_obj_t
00575 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure;
00576 static __hwloc_inline hwloc_obj_t
00577 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
00578 {
00579 hwloc_obj_t obj = NULL;
00580 while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
00581 if (obj->os_index == os_index)
00582 return obj;
00583 return NULL;
00584 }
00585
00595 static __hwloc_inline hwloc_obj_t
00596 hwloc_get_numanode_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure;
00597 static __hwloc_inline hwloc_obj_t
00598 hwloc_get_numanode_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
00599 {
00600 hwloc_obj_t obj = NULL;
00601 while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NUMANODE, obj)) != NULL)
00602 if (obj->os_index == os_index)
00603 return obj;
00604 return NULL;
00605 }
00606
00618
00619 HWLOC_DECLSPEC unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * __hwloc_restrict objs, unsigned max);
00620
00633 static __hwloc_inline hwloc_obj_t
00634 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
00635 hwloc_obj_type_t type1, unsigned idx1,
00636 hwloc_obj_type_t type2, unsigned idx2) __hwloc_attribute_pure;
00637 static __hwloc_inline hwloc_obj_t
00638 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
00639 hwloc_obj_type_t type1, unsigned idx1,
00640 hwloc_obj_type_t type2, unsigned idx2)
00641 {
00642 hwloc_obj_t obj;
00643 obj = hwloc_get_obj_by_type (topology, type1, idx1);
00644 if (!obj || !obj->cpuset)
00645 return NULL;
00646 return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
00647 }
00648
00667 static __hwloc_inline hwloc_obj_t
00668 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv) __hwloc_attribute_pure;
00669 static __hwloc_inline hwloc_obj_t
00670 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
00671 {
00672 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00673 int i;
00674 for(i=0; i<nr; i++) {
00675 if (!obj || !obj->cpuset)
00676 return NULL;
00677 obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
00678 }
00679 return obj;
00680 }
00681
00692 enum hwloc_distrib_flags_e {
00696 HWLOC_DISTRIB_FLAG_REVERSE = (1UL<<0)
00697 };
00698
00722 static __hwloc_inline int
00723 hwloc_distrib(hwloc_topology_t topology,
00724 hwloc_obj_t *roots, unsigned n_roots,
00725 hwloc_cpuset_t *set,
00726 unsigned n,
00727 unsigned until, unsigned long flags)
00728 {
00729 unsigned i;
00730 unsigned tot_weight;
00731 unsigned given, givenweight;
00732 hwloc_cpuset_t *cpusetp = set;
00733
00734 if (flags & ~HWLOC_DISTRIB_FLAG_REVERSE) {
00735 errno = EINVAL;
00736 return -1;
00737 }
00738
00739 tot_weight = 0;
00740 for (i = 0; i < n_roots; i++)
00741 if (roots[i]->cpuset)
00742 tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);
00743
00744 for (i = 0, given = 0, givenweight = 0; i < n_roots; i++) {
00745 unsigned chunk, weight;
00746 hwloc_obj_t root = roots[flags & HWLOC_DISTRIB_FLAG_REVERSE ? n_roots-1-i : i];
00747 hwloc_cpuset_t cpuset = root->cpuset;
00748 if (!cpuset)
00749 continue;
00750 weight = hwloc_bitmap_weight(cpuset);
00751 if (!weight)
00752 continue;
00753
00754
00755 chunk = (( (givenweight+weight) * n + tot_weight-1) / tot_weight)
00756 - (( givenweight * n + tot_weight-1) / tot_weight);
00757 if (!root->arity || chunk <= 1 || root->depth >= until) {
00758
00759 if (chunk) {
00760
00761 unsigned j;
00762 for (j=0; j < chunk; j++)
00763 cpusetp[j] = hwloc_bitmap_dup(cpuset);
00764 } else {
00765
00766
00767
00768
00769 assert(given);
00770 hwloc_bitmap_or(cpusetp[-1], cpusetp[-1], cpuset);
00771 }
00772 } else {
00773
00774 hwloc_distrib(topology, root->children, root->arity, cpusetp, chunk, until, flags);
00775 }
00776 cpusetp += chunk;
00777 given += chunk;
00778 givenweight += weight;
00779 }
00780
00781 return 0;
00782 }
00783
00800 static __hwloc_inline hwloc_const_cpuset_t
00801 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
00802 static __hwloc_inline hwloc_const_cpuset_t
00803 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
00804 {
00805 return hwloc_get_root_obj(topology)->complete_cpuset;
00806 }
00807
00818 static __hwloc_inline hwloc_const_cpuset_t
00819 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
00820 static __hwloc_inline hwloc_const_cpuset_t
00821 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
00822 {
00823 return hwloc_get_root_obj(topology)->cpuset;
00824 }
00825
00835 static __hwloc_inline hwloc_const_cpuset_t
00836 hwloc_topology_get_online_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
00837 static __hwloc_inline hwloc_const_cpuset_t
00838 hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
00839 {
00840 return hwloc_get_root_obj(topology)->online_cpuset;
00841 }
00842
00852 static __hwloc_inline hwloc_const_cpuset_t
00853 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
00854 static __hwloc_inline hwloc_const_cpuset_t
00855 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
00856 {
00857 return hwloc_get_root_obj(topology)->allowed_cpuset;
00858 }
00859
00869 static __hwloc_inline hwloc_const_nodeset_t
00870 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
00871 static __hwloc_inline hwloc_const_nodeset_t
00872 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
00873 {
00874 return hwloc_get_root_obj(topology)->complete_nodeset;
00875 }
00876
00887 static __hwloc_inline hwloc_const_nodeset_t
00888 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
00889 static __hwloc_inline hwloc_const_nodeset_t
00890 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
00891 {
00892 return hwloc_get_root_obj(topology)->nodeset;
00893 }
00894
00904 static __hwloc_inline hwloc_const_nodeset_t
00905 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
00906 static __hwloc_inline hwloc_const_nodeset_t
00907 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
00908 {
00909 return hwloc_get_root_obj(topology)->allowed_nodeset;
00910 }
00911
00942 static __hwloc_inline void
00943 hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset)
00944 {
00945 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
00946 hwloc_obj_t obj;
00947
00948 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
00949 if (hwloc_bitmap_iszero(_cpuset))
00950 hwloc_bitmap_zero(nodeset);
00951 else
00952
00953 hwloc_bitmap_fill(nodeset);
00954 return;
00955 }
00956
00957 hwloc_bitmap_zero(nodeset);
00958 obj = NULL;
00959 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, _cpuset, depth, obj)) != NULL)
00960 hwloc_bitmap_set(nodeset, obj->os_index);
00961 }
00962
00970 static __hwloc_inline void
00971 hwloc_cpuset_to_nodeset_strict(struct hwloc_topology *topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset)
00972 {
00973 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
00974 hwloc_obj_t obj;
00975 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
00976 return;
00977 hwloc_bitmap_zero(nodeset);
00978 obj = NULL;
00979 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, _cpuset, depth, obj)) != NULL)
00980 hwloc_bitmap_set(nodeset, obj->os_index);
00981 }
00982
00991 static __hwloc_inline void
00992 hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset)
00993 {
00994 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
00995 hwloc_obj_t obj;
00996
00997 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) {
00998 if (hwloc_bitmap_iszero(nodeset))
00999 hwloc_bitmap_zero(_cpuset);
01000 else
01001
01002 hwloc_bitmap_fill(_cpuset);
01003 return;
01004 }
01005
01006 hwloc_bitmap_zero(_cpuset);
01007 obj = NULL;
01008 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
01009 if (hwloc_bitmap_isset(nodeset, obj->os_index))
01010
01011 hwloc_bitmap_or(_cpuset, _cpuset, obj->cpuset);
01012 }
01013 }
01014
01022 static __hwloc_inline void
01023 hwloc_cpuset_from_nodeset_strict(struct hwloc_topology *topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset)
01024 {
01025 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
01026 hwloc_obj_t obj;
01027 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
01028 return;
01029 hwloc_bitmap_zero(_cpuset);
01030 obj = NULL;
01031 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL)
01032 if (hwloc_bitmap_isset(nodeset, obj->os_index))
01033
01034 hwloc_bitmap_or(_cpuset, _cpuset, obj->cpuset);
01035 }
01036
01064 static __hwloc_inline const struct hwloc_distances_s *
01065 hwloc_get_whole_distance_matrix_by_depth(hwloc_topology_t topology, unsigned depth)
01066 {
01067 hwloc_obj_t root = hwloc_get_root_obj(topology);
01068 unsigned i;
01069 for(i=0; i<root->distances_count; i++)
01070 if (root->distances[i]->relative_depth == depth)
01071 return root->distances[i];
01072 return NULL;
01073 }
01074
01094 static __hwloc_inline const struct hwloc_distances_s *
01095 hwloc_get_whole_distance_matrix_by_type(hwloc_topology_t topology, hwloc_obj_type_t type)
01096 {
01097 int depth = hwloc_get_type_depth(topology, type);
01098 if (depth < 0)
01099 return NULL;
01100 return hwloc_get_whole_distance_matrix_by_depth(topology, depth);
01101 }
01102
01116 static __hwloc_inline const struct hwloc_distances_s *
01117 hwloc_get_distance_matrix_covering_obj_by_depth(hwloc_topology_t topology,
01118 hwloc_obj_t obj, unsigned depth,
01119 unsigned *firstp)
01120 {
01121 while (obj && obj->cpuset) {
01122 unsigned i;
01123 for(i=0; i<obj->distances_count; i++)
01124 if (obj->distances[i]->relative_depth == depth - obj->depth) {
01125 if (!obj->distances[i]->nbobjs)
01126 continue;
01127 *firstp = hwloc_get_next_obj_inside_cpuset_by_depth(topology, obj->cpuset, depth, NULL)->logical_index;
01128 return obj->distances[i];
01129 }
01130 obj = obj->parent;
01131 }
01132 return NULL;
01133 }
01134
01146 static __hwloc_inline int
01147 hwloc_get_latency(hwloc_topology_t topology,
01148 hwloc_obj_t obj1, hwloc_obj_t obj2,
01149 float *latency, float *reverse_latency)
01150 {
01151 hwloc_obj_t ancestor;
01152 const struct hwloc_distances_s * distances;
01153 unsigned first_logical ;
01154
01155 if (obj1->depth != obj2->depth) {
01156 errno = EINVAL;
01157 return -1;
01158 }
01159
01160 ancestor = hwloc_get_common_ancestor_obj(topology, obj1, obj2);
01161 distances = hwloc_get_distance_matrix_covering_obj_by_depth(topology, ancestor, obj1->depth, &first_logical);
01162 if (distances && distances->latency) {
01163 const float * latency_matrix = distances->latency;
01164 unsigned nbobjs = distances->nbobjs;
01165 unsigned l1 = obj1->logical_index - first_logical;
01166 unsigned l2 = obj2->logical_index - first_logical;
01167 *latency = latency_matrix[l1*nbobjs+l2];
01168 *reverse_latency = latency_matrix[l2*nbobjs+l1];
01169 return 0;
01170 }
01171
01172 errno = ENOSYS;
01173 return -1;
01174 }
01175
01190 static __hwloc_inline hwloc_obj_t
01191 hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused,
01192 hwloc_obj_t ioobj)
01193 {
01194 hwloc_obj_t obj = ioobj;
01195 while (obj && !obj->cpuset) {
01196 obj = obj->parent;
01197 }
01198 return obj;
01199 }
01200
01205 static __hwloc_inline hwloc_obj_t
01206 hwloc_get_next_pcidev(hwloc_topology_t topology, hwloc_obj_t prev)
01207 {
01208 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PCI_DEVICE, prev);
01209 }
01210
01214 static __hwloc_inline hwloc_obj_t
01215 hwloc_get_pcidev_by_busid(hwloc_topology_t topology,
01216 unsigned domain, unsigned bus, unsigned dev, unsigned func)
01217 {
01218 hwloc_obj_t obj = NULL;
01219 while ((obj = hwloc_get_next_pcidev(topology, obj)) != NULL) {
01220 if (obj->attr->pcidev.domain == domain
01221 && obj->attr->pcidev.bus == bus
01222 && obj->attr->pcidev.dev == dev
01223 && obj->attr->pcidev.func == func)
01224 return obj;
01225 }
01226 return NULL;
01227 }
01228
01232 static __hwloc_inline hwloc_obj_t
01233 hwloc_get_pcidev_by_busidstring(hwloc_topology_t topology, const char *busid)
01234 {
01235 unsigned domain = 0;
01236 unsigned bus, dev, func;
01237
01238 if (sscanf(busid, "%x:%x.%x", &bus, &dev, &func) != 3
01239 && sscanf(busid, "%x:%x:%x.%x", &domain, &bus, &dev, &func) != 4) {
01240 errno = EINVAL;
01241 return NULL;
01242 }
01243
01244 return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, func);
01245 }
01246
01251 static __hwloc_inline hwloc_obj_t
01252 hwloc_get_next_osdev(hwloc_topology_t topology, hwloc_obj_t prev)
01253 {
01254 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_OS_DEVICE, prev);
01255 }
01256
01261 static __hwloc_inline hwloc_obj_t
01262 hwloc_get_next_bridge(hwloc_topology_t topology, hwloc_obj_t prev)
01263 {
01264 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_BRIDGE, prev);
01265 }
01266
01267
01268
01269 static __hwloc_inline int
01270 hwloc_bridge_covers_pcibus(hwloc_obj_t bridge,
01271 unsigned domain, unsigned bus)
01272 {
01273 return bridge->type == HWLOC_OBJ_BRIDGE
01274 && bridge->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI
01275 && bridge->attr->bridge.downstream.pci.domain == domain
01276 && bridge->attr->bridge.downstream.pci.secondary_bus <= bus
01277 && bridge->attr->bridge.downstream.pci.subordinate_bus >= bus;
01278 }
01279
01285 static __hwloc_inline hwloc_obj_t
01286 hwloc_get_hostbridge_by_pcibus(hwloc_topology_t topology,
01287 unsigned domain, unsigned bus)
01288 {
01289 hwloc_obj_t obj = NULL;
01290 while ((obj = hwloc_get_next_bridge(topology, obj)) != NULL) {
01291 if (hwloc_bridge_covers_pcibus(obj, domain, bus)) {
01292
01293 assert(obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_HOST);
01294 assert(obj->parent->type != HWLOC_OBJ_BRIDGE);
01295 assert(obj->parent->cpuset);
01296 return obj;
01297 }
01298 }
01299 return NULL;
01300 }
01301
01306 #ifdef __cplusplus
01307 }
01308 #endif
01309
01310
01311 #endif