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 int __hwloc_attribute_pure
00045 hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
00046 {
00047 int depth = hwloc_get_type_depth(topology, type);
00048
00049 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
00050 return depth;
00051
00052
00053 for(depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); ; depth--)
00054 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
00055 return depth+1;
00056
00057
00058
00059 }
00060
00067 static __hwloc_inline int __hwloc_attribute_pure
00068 hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
00069 {
00070 int depth = hwloc_get_type_depth(topology, type);
00071
00072 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
00073 return depth;
00074
00075
00076 for(depth = 0; ; depth++)
00077 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) > 0)
00078 return depth-1;
00079
00080
00081
00082 }
00083
00103 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00104 hwloc_get_root_obj (hwloc_topology_t topology)
00105 {
00106 return hwloc_get_obj_by_depth (topology, 0, 0);
00107 }
00108
00110 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00111 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj)
00112 {
00113 hwloc_obj_t ancestor = obj;
00114 if (obj->depth < depth)
00115 return NULL;
00116 while (ancestor && ancestor->depth > depth)
00117 ancestor = ancestor->parent;
00118 return ancestor;
00119 }
00120
00122 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00123 hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj)
00124 {
00125 hwloc_obj_t ancestor = obj->parent;
00126 while (ancestor && ancestor->type != type)
00127 ancestor = ancestor->parent;
00128 return ancestor;
00129 }
00130
00135 static __hwloc_inline hwloc_obj_t
00136 hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev)
00137 {
00138 if (!prev)
00139 return hwloc_get_obj_by_depth (topology, depth, 0);
00140 if (prev->depth != depth)
00141 return NULL;
00142 return prev->next_cousin;
00143 }
00144
00151 static __hwloc_inline hwloc_obj_t
00152 hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
00153 hwloc_obj_t prev)
00154 {
00155 int depth = hwloc_get_type_depth(topology, type);
00156 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00157 return NULL;
00158 return hwloc_get_next_obj_by_depth (topology, depth, prev);
00159 }
00160
00169 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00170 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
00171 {
00172 hwloc_obj_t obj = NULL;
00173 while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
00174 if (obj->os_index == os_index)
00175 return obj;
00176 return NULL;
00177 }
00178
00183 static __hwloc_inline hwloc_obj_t
00184 hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev)
00185 {
00186 if (!prev)
00187 return parent->first_child;
00188 if (prev->parent != parent)
00189 return NULL;
00190 return prev->next_sibling;
00191 }
00192
00194 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00195 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2)
00196 {
00197
00198
00199
00200
00201
00202 while (obj1 != obj2) {
00203 while (obj1->depth > obj2->depth)
00204 obj1 = obj1->parent;
00205 while (obj2->depth > obj1->depth)
00206 obj2 = obj2->parent;
00207 if (obj1 != obj2 && obj1->depth == obj2->depth) {
00208 obj1 = obj1->parent;
00209 obj2 = obj2->parent;
00210 }
00211 }
00212 return obj1;
00213 }
00214
00219 static __hwloc_inline int __hwloc_attribute_pure
00220 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root)
00221 {
00222 return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
00223 }
00224
00241 static __hwloc_inline hwloc_obj_t
00242 hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
00243 {
00244 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00245
00246 if (!hwloc_bitmap_intersects(obj->cpuset, set))
00247 return NULL;
00248 while (!hwloc_bitmap_isincluded(obj->cpuset, set)) {
00249
00250 hwloc_obj_t child = NULL;
00251 while ((child = hwloc_get_next_child(topology, obj, child)) != NULL) {
00252 if (child->cpuset && hwloc_bitmap_intersects(child->cpuset, set))
00253 break;
00254 }
00255 if (!child)
00256
00257 return obj;
00258
00259 obj = child;
00260 }
00261
00262 return obj;
00263 }
00264
00269 HWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00270 hwloc_obj_t * __hwloc_restrict objs, int max);
00271
00278 static __hwloc_inline hwloc_obj_t
00279 hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00280 unsigned depth, hwloc_obj_t prev)
00281 {
00282 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00283
00284 while (next && !hwloc_bitmap_isincluded(next->cpuset, set))
00285 next = next->next_cousin;
00286 return next;
00287 }
00288
00295 static __hwloc_inline hwloc_obj_t
00296 hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00297 hwloc_obj_type_t type, hwloc_obj_t prev)
00298 {
00299 int depth = hwloc_get_type_depth(topology, type);
00300 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00301 return NULL;
00302 return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
00303 }
00304
00307 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00308 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00309 unsigned depth, unsigned idx)
00310 {
00311 unsigned count = 0;
00312 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00313 while (obj) {
00314
00315 if (hwloc_bitmap_isincluded(obj->cpuset, set)) {
00316 if (count == idx)
00317 return obj;
00318 count++;
00319 }
00320 obj = obj->next_cousin;
00321 }
00322 return NULL;
00323 }
00324
00331 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00332 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00333 hwloc_obj_type_t type, unsigned idx)
00334 {
00335 int depth = hwloc_get_type_depth(topology, type);
00336 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00337 return NULL;
00338 return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
00339 }
00340
00342 static __hwloc_inline unsigned __hwloc_attribute_pure
00343 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00344 unsigned depth)
00345 {
00346 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00347 int count = 0;
00348 while (obj) {
00349
00350 if (hwloc_bitmap_isincluded(obj->cpuset, set))
00351 count++;
00352 obj = obj->next_cousin;
00353 }
00354 return count;
00355 }
00356
00363 static __hwloc_inline int __hwloc_attribute_pure
00364 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00365 hwloc_obj_type_t type)
00366 {
00367 int depth = hwloc_get_type_depth(topology, type);
00368 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
00369 return 0;
00370 if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00371 return -1;
00372 return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
00373 }
00374
00387 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00388 hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00389 hwloc_obj_t parent)
00390 {
00391 hwloc_obj_t child;
00392
00393 if (hwloc_bitmap_iszero(set))
00394 return NULL;
00395
00396 child = parent->first_child;
00397 while (child) {
00398 if (child->cpuset && hwloc_bitmap_isincluded(set, child->cpuset))
00399 return child;
00400 child = child->next_sibling;
00401 }
00402 return NULL;
00403 }
00404
00409 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00410 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00411 {
00412 struct hwloc_obj *current = hwloc_get_root_obj(topology);
00413
00414 if (hwloc_bitmap_iszero(set))
00415 return NULL;
00416
00417
00418 if (!hwloc_bitmap_isincluded(set, current->cpuset))
00419 return NULL;
00420
00421 while (1) {
00422 hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
00423 if (!child)
00424 return current;
00425 current = child;
00426 }
00427 }
00428
00429
00445 static __hwloc_inline hwloc_obj_t
00446 hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00447 unsigned depth, hwloc_obj_t prev)
00448 {
00449 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00450
00451 while (next && !hwloc_bitmap_intersects(set, next->cpuset))
00452 next = next->next_cousin;
00453 return next;
00454 }
00455
00468 static __hwloc_inline hwloc_obj_t
00469 hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00470 hwloc_obj_type_t type, hwloc_obj_t prev)
00471 {
00472 int depth = hwloc_get_type_depth(topology, type);
00473 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00474 return NULL;
00475 return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
00476 }
00477
00490 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00491 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00492 {
00493 hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
00494 while (current) {
00495 if (current->type == HWLOC_OBJ_CACHE)
00496 return current;
00497 current = current->parent;
00498 }
00499 return NULL;
00500 }
00501
00506 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00507 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj)
00508 {
00509 hwloc_obj_t current = obj->parent;
00510 if (!obj->cpuset)
00511 return NULL;
00512 while (current && current->cpuset) {
00513 if (!hwloc_bitmap_isequal(current->cpuset, obj->cpuset)
00514 && current->type == HWLOC_OBJ_CACHE)
00515 return current;
00516 current = current->parent;
00517 }
00518 return NULL;
00519 }
00520
00543
00544 HWLOC_DECLSPEC unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * __hwloc_restrict objs, unsigned max);
00545
00556 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00557 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
00558 hwloc_obj_type_t type1, unsigned idx1,
00559 hwloc_obj_type_t type2, unsigned idx2)
00560 {
00561 hwloc_obj_t obj;
00562
00563 obj = hwloc_get_obj_by_type (topology, type1, idx1);
00564 if (!obj)
00565 return NULL;
00566
00567 return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
00568 }
00569
00585 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00586 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
00587 {
00588 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00589 int i;
00590
00591
00592 for(i=0; i<nr; i++) {
00593 obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
00594 if (!obj)
00595 return NULL;
00596 }
00597
00598 return obj;
00599 }
00600
00622 static __hwloc_inline void
00623 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *root, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until);
00624 static __hwloc_inline void
00625 hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
00626 {
00627 unsigned i;
00628
00629
00630 if (!root->arity || n == 1 || root->depth >= until) {
00631
00632 for (i=0; i<n; i++)
00633 cpuset[i] = hwloc_bitmap_dup(root->cpuset);
00634 return;
00635 }
00636
00637 hwloc_distributev(topology, root->children, root->arity, cpuset, n, until);
00638 }
00639
00645 static __hwloc_inline void
00646 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
00647 {
00648 unsigned i;
00649 unsigned tot_weight;
00650 hwloc_cpuset_t *cpusetp = cpuset;
00651
00652 tot_weight = 0;
00653 for (i = 0; i < n_roots; i++)
00654 if (roots[i]->cpuset)
00655 tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);
00656
00657 for (i = 0; i < n_roots && tot_weight; i++) {
00658
00659 unsigned weight = roots[i]->cpuset ? hwloc_bitmap_weight(roots[i]->cpuset) : 0;
00660 unsigned chunk = (n * weight + tot_weight-1) / tot_weight;
00661 hwloc_distribute(topology, roots[i], cpusetp, chunk, until);
00662 cpusetp += chunk;
00663 tot_weight -= weight;
00664 n -= chunk;
00665 }
00666 }
00667
00674 static __hwloc_inline void *
00675 hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
00676 {
00677 void *p = hwloc_alloc_membind_nodeset(topology, len, nodeset, policy, flags);
00678 if (p)
00679 return p;
00680 hwloc_set_membind_nodeset(topology, nodeset, policy, flags);
00681 p = hwloc_alloc(topology, len);
00682 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
00683
00684 memset(p, 0, len);
00685 return p;
00686 }
00687
00692 static __hwloc_inline void *
00693 hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t cpuset, hwloc_membind_policy_t policy, int flags)
00694 {
00695 void *p = hwloc_alloc_membind(topology, len, cpuset, policy, flags);
00696 if (p)
00697 return p;
00698 hwloc_set_membind(topology, cpuset, policy, flags);
00699 p = hwloc_alloc(topology, len);
00700 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
00701
00702 memset(p, 0, len);
00703 return p;
00704 }
00705
00722 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
00723 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
00724 {
00725 return hwloc_get_root_obj(topology)->complete_cpuset;
00726 }
00727
00738 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
00739 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
00740 {
00741 return hwloc_get_root_obj(topology)->cpuset;
00742 }
00743
00753 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
00754 hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
00755 {
00756 return hwloc_get_root_obj(topology)->online_cpuset;
00757 }
00758
00768 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
00769 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
00770 {
00771 return hwloc_get_root_obj(topology)->allowed_cpuset;
00772 }
00773
00790 static __hwloc_inline hwloc_const_nodeset_t __hwloc_attribute_pure
00791 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
00792 {
00793 return hwloc_get_root_obj(topology)->complete_nodeset;
00794 }
00795
00806 static __hwloc_inline hwloc_const_nodeset_t __hwloc_attribute_pure
00807 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
00808 {
00809 return hwloc_get_root_obj(topology)->nodeset;
00810 }
00811
00821 static __hwloc_inline hwloc_const_nodeset_t __hwloc_attribute_pure
00822 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
00823 {
00824 return hwloc_get_root_obj(topology)->allowed_nodeset;
00825 }
00826
00857 static __hwloc_inline void
00858 hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
00859 {
00860 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00861 hwloc_obj_t obj;
00862
00863 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
00864 if (hwloc_bitmap_iszero(cpuset))
00865 hwloc_bitmap_zero(nodeset);
00866 else
00867
00868 hwloc_bitmap_fill(nodeset);
00869 return;
00870 }
00871
00872 hwloc_bitmap_zero(nodeset);
00873 obj = NULL;
00874 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
00875 hwloc_bitmap_set(nodeset, obj->os_index);
00876 }
00877
00885 static __hwloc_inline void
00886 hwloc_cpuset_to_nodeset_strict(struct hwloc_topology *topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
00887 {
00888 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00889 hwloc_obj_t obj;
00890 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
00891 return;
00892 hwloc_bitmap_zero(nodeset);
00893 obj = NULL;
00894 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
00895 hwloc_bitmap_set(nodeset, obj->os_index);
00896 }
00897
00906 static __hwloc_inline void
00907 hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
00908 {
00909 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00910 hwloc_obj_t obj;
00911
00912 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) {
00913 if (hwloc_bitmap_iszero(nodeset))
00914 hwloc_bitmap_zero(cpuset);
00915 else
00916
00917 hwloc_bitmap_fill(cpuset);
00918 return;
00919 }
00920
00921 hwloc_bitmap_zero(cpuset);
00922 obj = NULL;
00923 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
00924 if (hwloc_bitmap_isset(nodeset, obj->os_index))
00925
00926 hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
00927 }
00928 }
00929
00937 static __hwloc_inline void
00938 hwloc_cpuset_from_nodeset_strict(struct hwloc_topology *topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
00939 {
00940 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00941 hwloc_obj_t obj;
00942 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
00943 return;
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
00979 static __hwloc_inline const struct hwloc_distances_s *
00980 hwloc_get_whole_distance_matrix_by_depth(hwloc_topology_t topology, unsigned depth)
00981 {
00982 hwloc_obj_t root = hwloc_get_root_obj(topology);
00983 unsigned i;
00984 for(i=0; i<root->distances_count; i++)
00985 if (root->distances[i]->relative_depth == depth)
00986 return root->distances[i];
00987 return NULL;
00988 }
00989
01009 static __hwloc_inline const struct hwloc_distances_s *
01010 hwloc_get_whole_distance_matrix_by_type(hwloc_topology_t topology, hwloc_obj_type_t type)
01011 {
01012 int depth = hwloc_get_type_depth(topology, type);
01013 if (depth < 0)
01014 return NULL;
01015 return hwloc_get_whole_distance_matrix_by_depth(topology, depth);
01016 }
01017
01031 static __hwloc_inline const struct hwloc_distances_s *
01032 hwloc_get_distance_matrix_covering_obj_by_depth(hwloc_topology_t topology,
01033 hwloc_obj_t obj, unsigned depth,
01034 unsigned *firstp)
01035 {
01036 while (obj && obj->cpuset) {
01037 unsigned i;
01038 for(i=0; i<obj->distances_count; i++)
01039 if (obj->distances[i]->relative_depth == depth - obj->depth) {
01040 if (!obj->distances[i]->nbobjs)
01041 continue;
01042 *firstp = hwloc_get_next_obj_inside_cpuset_by_depth(topology, obj->cpuset, depth, NULL)->logical_index;
01043 return obj->distances[i];
01044 }
01045 obj = obj->parent;
01046 }
01047 return NULL;
01048 }
01049
01061 static __hwloc_inline int
01062 hwloc_get_latency(hwloc_topology_t topology,
01063 hwloc_obj_t obj1, hwloc_obj_t obj2,
01064 float *latency, float *reverse_latency)
01065 {
01066 hwloc_obj_t ancestor;
01067 const struct hwloc_distances_s * distances;
01068 unsigned first_logical ;
01069
01070 if (obj1->depth != obj2->depth) {
01071 errno = EINVAL;
01072 return -1;
01073 }
01074
01075 ancestor = hwloc_get_common_ancestor_obj(topology, obj1, obj2);
01076 distances = hwloc_get_distance_matrix_covering_obj_by_depth(topology, ancestor, obj1->depth, &first_logical);
01077 if (distances && distances->latency) {
01078 const float * latency_matrix = distances->latency;
01079 unsigned nbobjs = distances->nbobjs;
01080 unsigned l1 = obj1->logical_index - first_logical;
01081 unsigned l2 = obj2->logical_index - first_logical;
01082 *latency = latency_matrix[l1*nbobjs+l2];
01083 *reverse_latency = latency_matrix[l2*nbobjs+l1];
01084 return 0;
01085 }
01086
01087 errno = ENOSYS;
01088 return -1;
01089 }
01090
01105 static __inline hwloc_obj_t
01106 hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused,
01107 hwloc_obj_t ioobj)
01108 {
01109 hwloc_obj_t obj = ioobj;
01110 while (obj && !obj->cpuset) {
01111 obj = obj->parent;
01112 }
01113 return obj;
01114 }
01115
01120 static __inline hwloc_obj_t
01121 hwloc_get_next_pcidev(hwloc_topology_t topology, hwloc_obj_t prev)
01122 {
01123 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PCI_DEVICE, prev);
01124 }
01125
01129 static __inline hwloc_obj_t
01130 hwloc_get_pcidev_by_busid(hwloc_topology_t topology,
01131 unsigned domain, unsigned bus, unsigned dev, unsigned func)
01132 {
01133 hwloc_obj_t obj = NULL;
01134 while ((obj = hwloc_get_next_pcidev(topology, obj)) != NULL) {
01135 if (obj->attr->pcidev.domain == domain
01136 && obj->attr->pcidev.bus == bus
01137 && obj->attr->pcidev.dev == dev
01138 && obj->attr->pcidev.func == func)
01139 return obj;
01140 }
01141 return NULL;
01142 }
01143
01147 static __inline hwloc_obj_t
01148 hwloc_get_pcidev_by_busidstring(hwloc_topology_t topology, const char *busid)
01149 {
01150 unsigned domain = 0;
01151 unsigned bus, dev, func;
01152
01153 if (sscanf(busid, "%x:%x.%x", &bus, &dev, &func) != 3
01154 && sscanf(busid, "%x:%x:%x.%x", &domain, &bus, &dev, &func) != 4) {
01155 errno = EINVAL;
01156 return NULL;
01157 }
01158
01159 return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, func);
01160 }
01161
01166 static __inline hwloc_obj_t
01167 hwloc_get_next_osdev(hwloc_topology_t topology, hwloc_obj_t prev)
01168 {
01169 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_OS_DEVICE, prev);
01170 }
01171
01176 static __inline hwloc_obj_t
01177 hwloc_get_next_bridge(hwloc_topology_t topology, hwloc_obj_t prev)
01178 {
01179 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_BRIDGE, prev);
01180 }
01181
01182
01183
01184 static __inline int
01185 hwloc_bridge_covers_pcibus(hwloc_obj_t bridge,
01186 unsigned domain, unsigned bus)
01187 {
01188 return bridge->type == HWLOC_OBJ_BRIDGE
01189 && bridge->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI
01190 && bridge->attr->bridge.downstream.pci.domain == domain
01191 && bridge->attr->bridge.downstream.pci.secondary_bus <= bus
01192 && bridge->attr->bridge.downstream.pci.subordinate_bus >= bus;
01193 }
01194
01200 static __inline hwloc_obj_t
01201 hwloc_get_hostbridge_by_pcibus(hwloc_topology_t topology,
01202 unsigned domain, unsigned bus)
01203 {
01204 hwloc_obj_t obj = NULL;
01205 while ((obj = hwloc_get_next_bridge(topology, obj)) != NULL) {
01206 if (hwloc_bridge_covers_pcibus(obj, domain, bus)) {
01207
01208 assert(obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_HOST);
01209 assert(obj->parent->type != HWLOC_OBJ_BRIDGE);
01210 assert(obj->parent->cpuset);
01211 return obj;
01212 }
01213 }
01214 return NULL;
01215 }
01216
01221 #ifdef __cplusplus
01222 }
01223 #endif
01224
01225
01226 #endif