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 inline int
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 inline int
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 inline hwloc_obj_t
00110 hwloc_get_root_obj (hwloc_topology_t topology)
00111 {
00112 return hwloc_get_obj_by_depth (topology, 0, 0);
00113 }
00114
00116 static inline hwloc_obj_t
00117 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology , 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 inline hwloc_obj_t
00129 hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology , 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 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 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 inline hwloc_obj_t
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 inline hwloc_obj_t
00190 hwloc_get_next_child (hwloc_topology_t topology , 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 inline hwloc_obj_t
00201 hwloc_get_common_ancestor_obj (hwloc_topology_t topology , 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 inline int
00226 hwloc_obj_is_in_subtree (hwloc_topology_t topology , hwloc_obj_t obj, hwloc_obj_t subtree_root)
00227 {
00228 return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
00229 }
00230
00247 static inline hwloc_obj_t
00248 hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
00249 {
00250 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00251
00252 if (!hwloc_bitmap_intersects(obj->cpuset, set))
00253 return NULL;
00254 while (!hwloc_bitmap_isincluded(obj->cpuset, set)) {
00255
00256 hwloc_obj_t child = NULL;
00257 while ((child = hwloc_get_next_child(topology, obj, child)) != NULL) {
00258 if (child->cpuset && hwloc_bitmap_intersects(child->cpuset, set))
00259 break;
00260 }
00261 if (!child)
00262
00263 return obj;
00264
00265 obj = child;
00266 }
00267
00268 return obj;
00269 }
00270
00275 int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00276 hwloc_obj_t * restrict objs, int max);
00277
00284 static inline hwloc_obj_t
00285 hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00286 unsigned depth, hwloc_obj_t prev)
00287 {
00288 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00289
00290 while (next && !hwloc_bitmap_isincluded(next->cpuset, set))
00291 next = next->next_cousin;
00292 return next;
00293 }
00294
00301 static inline hwloc_obj_t
00302 hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00303 hwloc_obj_type_t type, hwloc_obj_t prev)
00304 {
00305 int depth = hwloc_get_type_depth(topology, type);
00306 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00307 return NULL;
00308 return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
00309 }
00310
00313 static inline hwloc_obj_t
00314 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00315 unsigned depth, unsigned idx)
00316 {
00317 unsigned count = 0;
00318 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00319 while (obj) {
00320
00321 if (hwloc_bitmap_isincluded(obj->cpuset, set)) {
00322 if (count == idx)
00323 return obj;
00324 count++;
00325 }
00326 obj = obj->next_cousin;
00327 }
00328 return NULL;
00329 }
00330
00337 static inline hwloc_obj_t
00338 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00339 hwloc_obj_type_t type, unsigned idx)
00340 {
00341 int depth = hwloc_get_type_depth(topology, type);
00342 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00343 return NULL;
00344 return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
00345 }
00346
00348 static inline unsigned
00349 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00350 unsigned depth)
00351 {
00352 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00353 int count = 0;
00354 while (obj) {
00355
00356 if (hwloc_bitmap_isincluded(obj->cpuset, set))
00357 count++;
00358 obj = obj->next_cousin;
00359 }
00360 return count;
00361 }
00362
00369 static inline int
00370 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00371 hwloc_obj_type_t type)
00372 {
00373 int depth = hwloc_get_type_depth(topology, type);
00374 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
00375 return 0;
00376 if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00377 return -1;
00378 return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
00379 }
00380
00393 static inline hwloc_obj_t
00394 hwloc_get_child_covering_cpuset (hwloc_topology_t topology , hwloc_const_cpuset_t set,
00395 hwloc_obj_t parent)
00396 {
00397 hwloc_obj_t child;
00398
00399 if (hwloc_bitmap_iszero(set))
00400 return NULL;
00401
00402 child = parent->first_child;
00403 while (child) {
00404 if (child->cpuset && hwloc_bitmap_isincluded(set, child->cpuset))
00405 return child;
00406 child = child->next_sibling;
00407 }
00408 return NULL;
00409 }
00410
00415 static inline hwloc_obj_t
00416 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00417 {
00418 struct hwloc_obj *current = hwloc_get_root_obj(topology);
00419
00420 if (hwloc_bitmap_iszero(set))
00421 return NULL;
00422
00423
00424 if (!hwloc_bitmap_isincluded(set, current->cpuset))
00425 return NULL;
00426
00427 while (1) {
00428 hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
00429 if (!child)
00430 return current;
00431 current = child;
00432 }
00433 }
00434
00435
00451 static inline hwloc_obj_t
00452 hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00453 unsigned depth, hwloc_obj_t prev)
00454 {
00455 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00456
00457 while (next && !hwloc_bitmap_intersects(set, next->cpuset))
00458 next = next->next_cousin;
00459 return next;
00460 }
00461
00474 static inline hwloc_obj_t
00475 hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00476 hwloc_obj_type_t type, hwloc_obj_t prev)
00477 {
00478 int depth = hwloc_get_type_depth(topology, type);
00479 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00480 return NULL;
00481 return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
00482 }
00483
00496 static inline hwloc_obj_t
00497 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00498 {
00499 hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
00500 while (current) {
00501 if (current->type == HWLOC_OBJ_CACHE)
00502 return current;
00503 current = current->parent;
00504 }
00505 return NULL;
00506 }
00507
00512 static inline hwloc_obj_t
00513 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology , hwloc_obj_t obj)
00514 {
00515 hwloc_obj_t current = obj->parent;
00516 if (!obj->cpuset)
00517 return NULL;
00518 while (current && current->cpuset) {
00519 if (!hwloc_bitmap_isequal(current->cpuset, obj->cpuset)
00520 && current->type == HWLOC_OBJ_CACHE)
00521 return current;
00522 current = current->parent;
00523 }
00524 return NULL;
00525 }
00526
00549
00550 unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * restrict objs, unsigned max);
00551
00562 static inline hwloc_obj_t
00563 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
00564 hwloc_obj_type_t type1, unsigned idx1,
00565 hwloc_obj_type_t type2, unsigned idx2)
00566 {
00567 hwloc_obj_t obj;
00568
00569 obj = hwloc_get_obj_by_type (topology, type1, idx1);
00570 if (!obj)
00571 return NULL;
00572
00573 return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
00574 }
00575
00591 static inline hwloc_obj_t
00592 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
00593 {
00594 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00595 int i;
00596
00597
00598 for(i=0; i<nr; i++) {
00599 obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
00600 if (!obj)
00601 return NULL;
00602 }
00603
00604 return obj;
00605 }
00606
00628 static inline void
00629 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *root, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until);
00630 static inline void
00631 hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
00632 {
00633 unsigned i;
00634
00635
00636 if (!root->arity || n == 1 || root->depth >= until) {
00637
00638 for (i=0; i<n; i++)
00639 cpuset[i] = hwloc_bitmap_dup(root->cpuset);
00640 return;
00641 }
00642
00643 hwloc_distributev(topology, root->children, root->arity, cpuset, n, until);
00644 }
00645
00651 static inline void
00652 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
00653 {
00654 unsigned i;
00655 unsigned tot_weight;
00656 hwloc_cpuset_t *cpusetp = cpuset;
00657
00658 tot_weight = 0;
00659 for (i = 0; i < n_roots; i++)
00660 if (roots[i]->cpuset)
00661 tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);
00662
00663 for (i = 0; i < n_roots && tot_weight; i++) {
00664
00665 unsigned weight = roots[i]->cpuset ? hwloc_bitmap_weight(roots[i]->cpuset) : 0;
00666 unsigned chunk = (n * weight + tot_weight-1) / tot_weight;
00667 hwloc_distribute(topology, roots[i], cpusetp, chunk, until);
00668 cpusetp += chunk;
00669 tot_weight -= weight;
00670 n -= chunk;
00671 }
00672 }
00673
00680 static inline void *
00681 hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
00682 {
00683 void *p = hwloc_alloc_membind_nodeset(topology, len, nodeset, policy, flags);
00684 if (p)
00685 return p;
00686 hwloc_set_membind_nodeset(topology, nodeset, policy, flags);
00687 p = hwloc_alloc(topology, len);
00688 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
00689
00690 memset(p, 0, len);
00691 return p;
00692 }
00693
00698 static inline void *
00699 hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t cpuset, hwloc_membind_policy_t policy, int flags)
00700 {
00701 void *p = hwloc_alloc_membind(topology, len, cpuset, policy, flags);
00702 if (p)
00703 return p;
00704 hwloc_set_membind(topology, cpuset, policy, flags);
00705 p = hwloc_alloc(topology, len);
00706 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
00707
00708 memset(p, 0, len);
00709 return p;
00710 }
00711
00728 static inline hwloc_const_cpuset_t
00729 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
00730 {
00731 return hwloc_get_root_obj(topology)->complete_cpuset;
00732 }
00733
00744 static inline hwloc_const_cpuset_t
00745 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
00746 {
00747 return hwloc_get_root_obj(topology)->cpuset;
00748 }
00749
00759 static inline hwloc_const_cpuset_t
00760 hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
00761 {
00762 return hwloc_get_root_obj(topology)->online_cpuset;
00763 }
00764
00774 static inline hwloc_const_cpuset_t
00775 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
00776 {
00777 return hwloc_get_root_obj(topology)->allowed_cpuset;
00778 }
00779
00796 static inline hwloc_const_nodeset_t
00797 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
00798 {
00799 return hwloc_get_root_obj(topology)->complete_nodeset;
00800 }
00801
00812 static inline hwloc_const_nodeset_t
00813 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
00814 {
00815 return hwloc_get_root_obj(topology)->nodeset;
00816 }
00817
00827 static inline hwloc_const_nodeset_t
00828 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
00829 {
00830 return hwloc_get_root_obj(topology)->allowed_nodeset;
00831 }
00832
00863 static inline void
00864 hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
00865 {
00866 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00867 hwloc_obj_t obj;
00868
00869 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
00870 if (hwloc_bitmap_iszero(cpuset))
00871 hwloc_bitmap_zero(nodeset);
00872 else
00873
00874 hwloc_bitmap_fill(nodeset);
00875 return;
00876 }
00877
00878 hwloc_bitmap_zero(nodeset);
00879 obj = NULL;
00880 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
00881 hwloc_bitmap_set(nodeset, obj->os_index);
00882 }
00883
00891 static inline void
00892 hwloc_cpuset_to_nodeset_strict(struct hwloc_topology *topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
00893 {
00894 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00895 hwloc_obj_t obj;
00896 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
00897 return;
00898 hwloc_bitmap_zero(nodeset);
00899 obj = NULL;
00900 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
00901 hwloc_bitmap_set(nodeset, obj->os_index);
00902 }
00903
00912 static inline void
00913 hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
00914 {
00915 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00916 hwloc_obj_t obj;
00917
00918 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) {
00919 if (hwloc_bitmap_iszero(nodeset))
00920 hwloc_bitmap_zero(cpuset);
00921 else
00922
00923 hwloc_bitmap_fill(cpuset);
00924 return;
00925 }
00926
00927 hwloc_bitmap_zero(cpuset);
00928 obj = NULL;
00929 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
00930 if (hwloc_bitmap_isset(nodeset, obj->os_index))
00931
00932 hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
00933 }
00934 }
00935
00943 static inline void
00944 hwloc_cpuset_from_nodeset_strict(struct hwloc_topology *topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
00945 {
00946 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00947 hwloc_obj_t obj;
00948 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
00949 return;
00950 hwloc_bitmap_zero(cpuset);
00951 obj = NULL;
00952 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL)
00953 if (hwloc_bitmap_isset(nodeset, obj->os_index))
00954
00955 hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
00956 }
00957
00985 static inline const struct hwloc_distances_s *
00986 hwloc_get_whole_distance_matrix_by_depth(hwloc_topology_t topology, unsigned depth)
00987 {
00988 hwloc_obj_t root = hwloc_get_root_obj(topology);
00989 unsigned i;
00990 for(i=0; i<root->distances_count; i++)
00991 if (root->distances[i]->relative_depth == depth)
00992 return root->distances[i];
00993 return NULL;
00994 }
00995
01015 static inline const struct hwloc_distances_s *
01016 hwloc_get_whole_distance_matrix_by_type(hwloc_topology_t topology, hwloc_obj_type_t type)
01017 {
01018 int depth = hwloc_get_type_depth(topology, type);
01019 if (depth < 0)
01020 return NULL;
01021 return hwloc_get_whole_distance_matrix_by_depth(topology, depth);
01022 }
01023
01037 static inline const struct hwloc_distances_s *
01038 hwloc_get_distance_matrix_covering_obj_by_depth(hwloc_topology_t topology,
01039 hwloc_obj_t obj, unsigned depth,
01040 unsigned *firstp)
01041 {
01042 while (obj && obj->cpuset) {
01043 unsigned i;
01044 for(i=0; i<obj->distances_count; i++)
01045 if (obj->distances[i]->relative_depth == depth - obj->depth) {
01046 if (!obj->distances[i]->nbobjs)
01047 continue;
01048 *firstp = hwloc_get_next_obj_inside_cpuset_by_depth(topology, obj->cpuset, depth, NULL)->logical_index;
01049 return obj->distances[i];
01050 }
01051 obj = obj->parent;
01052 }
01053 return NULL;
01054 }
01055
01067 static inline int
01068 hwloc_get_latency(hwloc_topology_t topology,
01069 hwloc_obj_t obj1, hwloc_obj_t obj2,
01070 float *latency, float *reverse_latency)
01071 {
01072 hwloc_obj_t ancestor;
01073 const struct hwloc_distances_s * distances;
01074 unsigned first_logical ;
01075
01076 if (obj1->depth != obj2->depth) {
01077 errno = EINVAL;
01078 return -1;
01079 }
01080
01081 ancestor = hwloc_get_common_ancestor_obj(topology, obj1, obj2);
01082 distances = hwloc_get_distance_matrix_covering_obj_by_depth(topology, ancestor, obj1->depth, &first_logical);
01083 if (distances && distances->latency) {
01084 const float * latency_matrix = distances->latency;
01085 unsigned nbobjs = distances->nbobjs;
01086 unsigned l1 = obj1->logical_index - first_logical;
01087 unsigned l2 = obj2->logical_index - first_logical;
01088 *latency = latency_matrix[l1*nbobjs+l2];
01089 *reverse_latency = latency_matrix[l2*nbobjs+l1];
01090 return 0;
01091 }
01092
01093 errno = ENOSYS;
01094 return -1;
01095 }
01096
01111 static inline hwloc_obj_t
01112 hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology ,
01113 hwloc_obj_t ioobj)
01114 {
01115 hwloc_obj_t obj = ioobj;
01116 while (obj && !obj->cpuset) {
01117 obj = obj->parent;
01118 }
01119 return obj;
01120 }
01121
01126 static inline hwloc_obj_t
01127 hwloc_get_next_pcidev(hwloc_topology_t topology, hwloc_obj_t prev)
01128 {
01129 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PCI_DEVICE, prev);
01130 }
01131
01135 static inline hwloc_obj_t
01136 hwloc_get_pcidev_by_busid(hwloc_topology_t topology,
01137 unsigned domain, unsigned bus, unsigned dev, unsigned func)
01138 {
01139 hwloc_obj_t obj = NULL;
01140 while ((obj = hwloc_get_next_pcidev(topology, obj)) != NULL) {
01141 if (obj->attr->pcidev.domain == domain
01142 && obj->attr->pcidev.bus == bus
01143 && obj->attr->pcidev.dev == dev
01144 && obj->attr->pcidev.func == func)
01145 return obj;
01146 }
01147 return NULL;
01148 }
01149
01153 static inline hwloc_obj_t
01154 hwloc_get_pcidev_by_busidstring(hwloc_topology_t topology, const char *busid)
01155 {
01156 unsigned domain = 0;
01157 unsigned bus, dev, func;
01158
01159 if (sscanf(busid, "%x:%x.%x", &bus, &dev, &func) != 3
01160 && sscanf(busid, "%x:%x:%x.%x", &domain, &bus, &dev, &func) != 4) {
01161 errno = EINVAL;
01162 return NULL;
01163 }
01164
01165 return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, func);
01166 }
01167
01172 static inline hwloc_obj_t
01173 hwloc_get_next_osdev(hwloc_topology_t topology, hwloc_obj_t prev)
01174 {
01175 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_OS_DEVICE, prev);
01176 }
01177
01182 static inline hwloc_obj_t
01183 hwloc_get_next_bridge(hwloc_topology_t topology, hwloc_obj_t prev)
01184 {
01185 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_BRIDGE, prev);
01186 }
01187
01188
01189
01190 static inline int
01191 hwloc_bridge_covers_pcibus(hwloc_obj_t bridge,
01192 unsigned domain, unsigned bus)
01193 {
01194 return bridge->type == HWLOC_OBJ_BRIDGE
01195 && bridge->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI
01196 && bridge->attr->bridge.downstream.pci.domain == domain
01197 && bridge->attr->bridge.downstream.pci.secondary_bus <= bus
01198 && bridge->attr->bridge.downstream.pci.subordinate_bus >= bus;
01199 }
01200
01206 static inline hwloc_obj_t
01207 hwloc_get_hostbridge_by_pcibus(hwloc_topology_t topology,
01208 unsigned domain, unsigned bus)
01209 {
01210 hwloc_obj_t obj = NULL;
01211 while ((obj = hwloc_get_next_bridge(topology, obj)) != NULL) {
01212 if (hwloc_bridge_covers_pcibus(obj, domain, bus)) {
01213
01214 assert(obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_HOST);
01215 assert(obj->parent->type != HWLOC_OBJ_BRIDGE);
01216 assert(obj->parent->cpuset);
01217 return obj;
01218 }
01219 }
01220 return NULL;
01221 }
01222
01227 #ifdef __cplusplus
01228 }
01229 #endif
01230
01231
01232 #endif