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
00047 static __hwloc_inline int __hwloc_attribute_pure
00048 hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
00049 {
00050 int depth = hwloc_get_type_depth(topology, type);
00051
00052 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
00053 return depth;
00054
00055
00056 for(depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); ; depth--)
00057 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
00058 return depth+1;
00059
00060
00061
00062 }
00063
00073 static __hwloc_inline int __hwloc_attribute_pure
00074 hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
00075 {
00076 int depth = hwloc_get_type_depth(topology, type);
00077
00078 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
00079 return depth;
00080
00081
00082 for(depth = 0; ; depth++)
00083 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) > 0)
00084 return depth-1;
00085
00086
00087
00088 }
00089
00109 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00110 hwloc_get_root_obj (hwloc_topology_t topology)
00111 {
00112 return hwloc_get_obj_by_depth (topology, 0, 0);
00113 }
00114
00116 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00117 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj)
00118 {
00119 hwloc_obj_t ancestor = obj;
00120 if (obj->depth < depth)
00121 return NULL;
00122 while (ancestor && ancestor->depth > depth)
00123 ancestor = ancestor->parent;
00124 return ancestor;
00125 }
00126
00128 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00129 hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj)
00130 {
00131 hwloc_obj_t ancestor = obj->parent;
00132 while (ancestor && ancestor->type != type)
00133 ancestor = ancestor->parent;
00134 return ancestor;
00135 }
00136
00141 static __hwloc_inline hwloc_obj_t
00142 hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev)
00143 {
00144 if (!prev)
00145 return hwloc_get_obj_by_depth (topology, depth, 0);
00146 if (prev->depth != depth)
00147 return NULL;
00148 return prev->next_cousin;
00149 }
00150
00157 static __hwloc_inline hwloc_obj_t
00158 hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
00159 hwloc_obj_t prev)
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_next_obj_by_depth (topology, depth, prev);
00165 }
00166
00175 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00176 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
00177 {
00178 hwloc_obj_t obj = NULL;
00179 while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
00180 if (obj->os_index == os_index)
00181 return obj;
00182 return NULL;
00183 }
00184
00189 static __hwloc_inline hwloc_obj_t
00190 hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev)
00191 {
00192 if (!prev)
00193 return parent->first_child;
00194 if (prev->parent != parent)
00195 return NULL;
00196 return prev->next_sibling;
00197 }
00198
00200 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00201 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2)
00202 {
00203
00204
00205
00206
00207
00208 while (obj1 != obj2) {
00209 while (obj1->depth > obj2->depth)
00210 obj1 = obj1->parent;
00211 while (obj2->depth > obj1->depth)
00212 obj2 = obj2->parent;
00213 if (obj1 != obj2 && obj1->depth == obj2->depth) {
00214 obj1 = obj1->parent;
00215 obj2 = obj2->parent;
00216 }
00217 }
00218 return obj1;
00219 }
00220
00225 static __hwloc_inline int __hwloc_attribute_pure
00226 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root)
00227 {
00228 return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
00229 }
00230
00250 static __hwloc_inline hwloc_obj_t
00251 hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
00252 {
00253 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00254 if (!obj->cpuset || !hwloc_bitmap_intersects(obj->cpuset, set))
00255 return NULL;
00256 while (!hwloc_bitmap_isincluded(obj->cpuset, set)) {
00257
00258 hwloc_obj_t child = NULL;
00259 while ((child = hwloc_get_next_child(topology, obj, child)) != NULL) {
00260 if (child->cpuset && hwloc_bitmap_intersects(child->cpuset, set))
00261 break;
00262 }
00263 if (!child)
00264
00265 return obj;
00266
00267 obj = child;
00268 }
00269
00270 return obj;
00271 }
00272
00280 HWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00281 hwloc_obj_t * __hwloc_restrict objs, int max);
00282
00292 static __hwloc_inline hwloc_obj_t
00293 hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00294 unsigned depth, hwloc_obj_t prev)
00295 {
00296 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00297 if (!next || !next->cpuset)
00298 return NULL;
00299 while (next && !hwloc_bitmap_isincluded(next->cpuset, set))
00300 next = next->next_cousin;
00301 return next;
00302 }
00303
00313 static __hwloc_inline hwloc_obj_t
00314 hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00315 hwloc_obj_type_t type, hwloc_obj_t prev)
00316 {
00317 int depth = hwloc_get_type_depth(topology, type);
00318 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00319 return NULL;
00320 return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
00321 }
00322
00328 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00329 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00330 unsigned depth, unsigned idx)
00331 {
00332 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00333 unsigned count = 0;
00334 if (!obj || !obj->cpuset)
00335 return NULL;
00336 while (obj) {
00337 if (hwloc_bitmap_isincluded(obj->cpuset, set)) {
00338 if (count == idx)
00339 return obj;
00340 count++;
00341 }
00342 obj = obj->next_cousin;
00343 }
00344 return NULL;
00345 }
00346
00356 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00357 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00358 hwloc_obj_type_t type, unsigned idx)
00359 {
00360 int depth = hwloc_get_type_depth(topology, type);
00361 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00362 return NULL;
00363 return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
00364 }
00365
00371 static __hwloc_inline unsigned __hwloc_attribute_pure
00372 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00373 unsigned depth)
00374 {
00375 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00376 unsigned count = 0;
00377 if (!obj || !obj->cpuset)
00378 return 0;
00379 while (obj) {
00380 if (hwloc_bitmap_isincluded(obj->cpuset, set))
00381 count++;
00382 obj = obj->next_cousin;
00383 }
00384 return count;
00385 }
00386
00396 static __hwloc_inline int __hwloc_attribute_pure
00397 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00398 hwloc_obj_type_t type)
00399 {
00400 int depth = hwloc_get_type_depth(topology, type);
00401 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
00402 return 0;
00403 if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00404 return -1;
00405 return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
00406 }
00407
00416 static __hwloc_inline int __hwloc_attribute_pure
00417 hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00418 hwloc_obj_t obj)
00419 {
00420 int index = 0;
00421 if (!hwloc_bitmap_isincluded(obj->cpuset, set))
00422 return -1;
00423
00424 while ((obj = obj->prev_cousin) != NULL)
00425 if (hwloc_bitmap_isincluded(obj->cpuset, set))
00426 index++;
00427 return index;
00428 }
00429
00444 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00445 hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00446 hwloc_obj_t parent)
00447 {
00448 hwloc_obj_t child;
00449 if (!parent->cpuset || hwloc_bitmap_iszero(set))
00450 return NULL;
00451 child = parent->first_child;
00452 while (child) {
00453 if (child->cpuset && hwloc_bitmap_isincluded(set, child->cpuset))
00454 return child;
00455 child = child->next_sibling;
00456 }
00457 return NULL;
00458 }
00459
00467 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00468 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00469 {
00470 struct hwloc_obj *current = hwloc_get_root_obj(topology);
00471 if (hwloc_bitmap_iszero(set) || !current->cpuset || !hwloc_bitmap_isincluded(set, current->cpuset))
00472 return NULL;
00473 while (1) {
00474 hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
00475 if (!child)
00476 return current;
00477 current = child;
00478 }
00479 }
00480
00481
00500 static __hwloc_inline hwloc_obj_t
00501 hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00502 unsigned depth, hwloc_obj_t prev)
00503 {
00504 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00505 if (!next || !next->cpuset)
00506 return NULL;
00507 while (next && !hwloc_bitmap_intersects(set, next->cpuset))
00508 next = next->next_cousin;
00509 return next;
00510 }
00511
00527 static __hwloc_inline hwloc_obj_t
00528 hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00529 hwloc_obj_type_t type, hwloc_obj_t prev)
00530 {
00531 int depth = hwloc_get_type_depth(topology, type);
00532 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00533 return NULL;
00534 return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
00535 }
00536
00552 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00553 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00554 {
00555 hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
00556 while (current) {
00557 if (current->type == HWLOC_OBJ_CACHE)
00558 return current;
00559 current = current->parent;
00560 }
00561 return NULL;
00562 }
00563
00568 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00569 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj)
00570 {
00571 hwloc_obj_t current = obj->parent;
00572 if (!obj->cpuset)
00573 return NULL;
00574 while (current && current->cpuset) {
00575 if (!hwloc_bitmap_isequal(current->cpuset, obj->cpuset)
00576 && current->type == HWLOC_OBJ_CACHE)
00577 return current;
00578 current = current->parent;
00579 }
00580 return NULL;
00581 }
00582
00607
00608 HWLOC_DECLSPEC unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * __hwloc_restrict objs, unsigned max);
00609
00622 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00623 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
00624 hwloc_obj_type_t type1, unsigned idx1,
00625 hwloc_obj_type_t type2, unsigned idx2)
00626 {
00627 hwloc_obj_t obj;
00628 obj = hwloc_get_obj_by_type (topology, type1, idx1);
00629 if (!obj || !obj->cpuset)
00630 return NULL;
00631 return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
00632 }
00633
00652 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00653 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
00654 {
00655 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00656 int i;
00657 for(i=0; i<nr; i++) {
00658 if (!obj || !obj->cpuset)
00659 return NULL;
00660 obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
00661 }
00662 return obj;
00663 }
00664
00688 static __hwloc_inline void
00689 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *root, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until);
00690 static __hwloc_inline void
00691 hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
00692 {
00693 unsigned i;
00694 if (!root->arity || n == 1 || root->depth >= until) {
00695
00696 for (i=0; i<n; i++)
00697 cpuset[i] = hwloc_bitmap_dup(root->cpuset);
00698 return;
00699 }
00700 hwloc_distributev(topology, root->children, root->arity, cpuset, n, until);
00701 }
00702
00710 static __hwloc_inline void
00711 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
00712 {
00713 unsigned i;
00714 unsigned tot_weight;
00715 hwloc_cpuset_t *cpusetp = cpuset;
00716
00717 tot_weight = 0;
00718 for (i = 0; i < n_roots; i++)
00719 if (roots[i]->cpuset)
00720 tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);
00721
00722 for (i = 0; i < n_roots && tot_weight; i++) {
00723
00724 unsigned weight = roots[i]->cpuset ? hwloc_bitmap_weight(roots[i]->cpuset) : 0;
00725 unsigned chunk = (n * weight + tot_weight-1) / tot_weight;
00726 hwloc_distribute(topology, roots[i], cpusetp, chunk, until);
00727 cpusetp += chunk;
00728 tot_weight -= weight;
00729 n -= chunk;
00730 }
00731 }
00732
00739 static __hwloc_inline void *
00740 hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
00741 {
00742 void *p = hwloc_alloc_membind_nodeset(topology, len, nodeset, policy, flags);
00743 if (p)
00744 return p;
00745 hwloc_set_membind_nodeset(topology, nodeset, policy, flags);
00746 p = hwloc_alloc(topology, len);
00747 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
00748
00749 memset(p, 0, len);
00750 return p;
00751 }
00752
00757 static __hwloc_inline void *
00758 hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t cpuset, hwloc_membind_policy_t policy, int flags)
00759 {
00760 void *p = hwloc_alloc_membind(topology, len, cpuset, policy, flags);
00761 if (p)
00762 return p;
00763 hwloc_set_membind(topology, cpuset, policy, flags);
00764 p = hwloc_alloc(topology, len);
00765 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
00766
00767 memset(p, 0, len);
00768 return p;
00769 }
00770
00787 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
00788 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
00789 {
00790 return hwloc_get_root_obj(topology)->complete_cpuset;
00791 }
00792
00803 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
00804 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
00805 {
00806 return hwloc_get_root_obj(topology)->cpuset;
00807 }
00808
00818 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
00819 hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
00820 {
00821 return hwloc_get_root_obj(topology)->online_cpuset;
00822 }
00823
00833 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
00834 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
00835 {
00836 return hwloc_get_root_obj(topology)->allowed_cpuset;
00837 }
00838
00855 static __hwloc_inline hwloc_const_nodeset_t __hwloc_attribute_pure
00856 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
00857 {
00858 return hwloc_get_root_obj(topology)->complete_nodeset;
00859 }
00860
00871 static __hwloc_inline hwloc_const_nodeset_t __hwloc_attribute_pure
00872 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
00873 {
00874 return hwloc_get_root_obj(topology)->nodeset;
00875 }
00876
00886 static __hwloc_inline hwloc_const_nodeset_t __hwloc_attribute_pure
00887 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
00888 {
00889 return hwloc_get_root_obj(topology)->allowed_nodeset;
00890 }
00891
00922 static __hwloc_inline void
00923 hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
00924 {
00925 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00926 hwloc_obj_t obj;
00927
00928 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
00929 if (hwloc_bitmap_iszero(cpuset))
00930 hwloc_bitmap_zero(nodeset);
00931 else
00932
00933 hwloc_bitmap_fill(nodeset);
00934 return;
00935 }
00936
00937 hwloc_bitmap_zero(nodeset);
00938 obj = NULL;
00939 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
00940 hwloc_bitmap_set(nodeset, obj->os_index);
00941 }
00942
00950 static __hwloc_inline void
00951 hwloc_cpuset_to_nodeset_strict(struct hwloc_topology *topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
00952 {
00953 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00954 hwloc_obj_t obj;
00955 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
00956 return;
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
00971 static __hwloc_inline void
00972 hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
00973 {
00974 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00975 hwloc_obj_t obj;
00976
00977 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) {
00978 if (hwloc_bitmap_iszero(nodeset))
00979 hwloc_bitmap_zero(cpuset);
00980 else
00981
00982 hwloc_bitmap_fill(cpuset);
00983 return;
00984 }
00985
00986 hwloc_bitmap_zero(cpuset);
00987 obj = NULL;
00988 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
00989 if (hwloc_bitmap_isset(nodeset, obj->os_index))
00990
00991 hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
00992 }
00993 }
00994
01002 static __hwloc_inline void
01003 hwloc_cpuset_from_nodeset_strict(struct hwloc_topology *topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
01004 {
01005 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
01006 hwloc_obj_t obj;
01007 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
01008 return;
01009 hwloc_bitmap_zero(cpuset);
01010 obj = NULL;
01011 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL)
01012 if (hwloc_bitmap_isset(nodeset, obj->os_index))
01013
01014 hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
01015 }
01016
01044 static __hwloc_inline const struct hwloc_distances_s *
01045 hwloc_get_whole_distance_matrix_by_depth(hwloc_topology_t topology, unsigned depth)
01046 {
01047 hwloc_obj_t root = hwloc_get_root_obj(topology);
01048 unsigned i;
01049 for(i=0; i<root->distances_count; i++)
01050 if (root->distances[i]->relative_depth == depth)
01051 return root->distances[i];
01052 return NULL;
01053 }
01054
01074 static __hwloc_inline const struct hwloc_distances_s *
01075 hwloc_get_whole_distance_matrix_by_type(hwloc_topology_t topology, hwloc_obj_type_t type)
01076 {
01077 int depth = hwloc_get_type_depth(topology, type);
01078 if (depth < 0)
01079 return NULL;
01080 return hwloc_get_whole_distance_matrix_by_depth(topology, depth);
01081 }
01082
01096 static __hwloc_inline const struct hwloc_distances_s *
01097 hwloc_get_distance_matrix_covering_obj_by_depth(hwloc_topology_t topology,
01098 hwloc_obj_t obj, unsigned depth,
01099 unsigned *firstp)
01100 {
01101 while (obj && obj->cpuset) {
01102 unsigned i;
01103 for(i=0; i<obj->distances_count; i++)
01104 if (obj->distances[i]->relative_depth == depth - obj->depth) {
01105 if (!obj->distances[i]->nbobjs)
01106 continue;
01107 *firstp = hwloc_get_next_obj_inside_cpuset_by_depth(topology, obj->cpuset, depth, NULL)->logical_index;
01108 return obj->distances[i];
01109 }
01110 obj = obj->parent;
01111 }
01112 return NULL;
01113 }
01114
01126 static __hwloc_inline int
01127 hwloc_get_latency(hwloc_topology_t topology,
01128 hwloc_obj_t obj1, hwloc_obj_t obj2,
01129 float *latency, float *reverse_latency)
01130 {
01131 hwloc_obj_t ancestor;
01132 const struct hwloc_distances_s * distances;
01133 unsigned first_logical ;
01134
01135 if (obj1->depth != obj2->depth) {
01136 errno = EINVAL;
01137 return -1;
01138 }
01139
01140 ancestor = hwloc_get_common_ancestor_obj(topology, obj1, obj2);
01141 distances = hwloc_get_distance_matrix_covering_obj_by_depth(topology, ancestor, obj1->depth, &first_logical);
01142 if (distances && distances->latency) {
01143 const float * latency_matrix = distances->latency;
01144 unsigned nbobjs = distances->nbobjs;
01145 unsigned l1 = obj1->logical_index - first_logical;
01146 unsigned l2 = obj2->logical_index - first_logical;
01147 *latency = latency_matrix[l1*nbobjs+l2];
01148 *reverse_latency = latency_matrix[l2*nbobjs+l1];
01149 return 0;
01150 }
01151
01152 errno = ENOSYS;
01153 return -1;
01154 }
01155
01170 static __hwloc_inline hwloc_obj_t
01171 hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused,
01172 hwloc_obj_t ioobj)
01173 {
01174 hwloc_obj_t obj = ioobj;
01175 while (obj && !obj->cpuset) {
01176 obj = obj->parent;
01177 }
01178 return obj;
01179 }
01180
01185 static __hwloc_inline hwloc_obj_t
01186 hwloc_get_next_pcidev(hwloc_topology_t topology, hwloc_obj_t prev)
01187 {
01188 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PCI_DEVICE, prev);
01189 }
01190
01194 static __hwloc_inline hwloc_obj_t
01195 hwloc_get_pcidev_by_busid(hwloc_topology_t topology,
01196 unsigned domain, unsigned bus, unsigned dev, unsigned func)
01197 {
01198 hwloc_obj_t obj = NULL;
01199 while ((obj = hwloc_get_next_pcidev(topology, obj)) != NULL) {
01200 if (obj->attr->pcidev.domain == domain
01201 && obj->attr->pcidev.bus == bus
01202 && obj->attr->pcidev.dev == dev
01203 && obj->attr->pcidev.func == func)
01204 return obj;
01205 }
01206 return NULL;
01207 }
01208
01212 static __hwloc_inline hwloc_obj_t
01213 hwloc_get_pcidev_by_busidstring(hwloc_topology_t topology, const char *busid)
01214 {
01215 unsigned domain = 0;
01216 unsigned bus, dev, func;
01217
01218 if (sscanf(busid, "%x:%x.%x", &bus, &dev, &func) != 3
01219 && sscanf(busid, "%x:%x:%x.%x", &domain, &bus, &dev, &func) != 4) {
01220 errno = EINVAL;
01221 return NULL;
01222 }
01223
01224 return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, func);
01225 }
01226
01231 static __hwloc_inline hwloc_obj_t
01232 hwloc_get_next_osdev(hwloc_topology_t topology, hwloc_obj_t prev)
01233 {
01234 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_OS_DEVICE, prev);
01235 }
01236
01241 static __hwloc_inline hwloc_obj_t
01242 hwloc_get_next_bridge(hwloc_topology_t topology, hwloc_obj_t prev)
01243 {
01244 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_BRIDGE, prev);
01245 }
01246
01247
01248
01249 static __hwloc_inline int
01250 hwloc_bridge_covers_pcibus(hwloc_obj_t bridge,
01251 unsigned domain, unsigned bus)
01252 {
01253 return bridge->type == HWLOC_OBJ_BRIDGE
01254 && bridge->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI
01255 && bridge->attr->bridge.downstream.pci.domain == domain
01256 && bridge->attr->bridge.downstream.pci.secondary_bus <= bus
01257 && bridge->attr->bridge.downstream.pci.subordinate_bus >= bus;
01258 }
01259
01265 static __hwloc_inline hwloc_obj_t
01266 hwloc_get_hostbridge_by_pcibus(hwloc_topology_t topology,
01267 unsigned domain, unsigned bus)
01268 {
01269 hwloc_obj_t obj = NULL;
01270 while ((obj = hwloc_get_next_bridge(topology, obj)) != NULL) {
01271 if (hwloc_bridge_covers_pcibus(obj, domain, bus)) {
01272
01273 assert(obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_HOST);
01274 assert(obj->parent->type != HWLOC_OBJ_BRIDGE);
01275 assert(obj->parent->cpuset);
01276 return obj;
01277 }
01278 }
01279 return NULL;
01280 }
01281
01286 #ifdef __cplusplus
01287 }
01288 #endif
01289
01290
01291 #endif