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
00048 hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;
00049 static __hwloc_inline int
00050 hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
00051 {
00052 int depth = hwloc_get_type_depth(topology, type);
00053
00054 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
00055 return depth;
00056
00057
00058 for(depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); ; depth--)
00059 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
00060 return depth+1;
00061
00062
00063
00064 }
00065
00075 static __hwloc_inline int
00076 hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;
00077 static __hwloc_inline int
00078 hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
00079 {
00080 int depth = hwloc_get_type_depth(topology, type);
00081
00082 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
00083 return depth;
00084
00085
00086 for(depth = 0; ; depth++)
00087 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) > 0)
00088 return depth-1;
00089
00090
00091
00092 }
00093
00113 static __hwloc_inline hwloc_obj_t
00114 hwloc_get_root_obj (hwloc_topology_t topology) __hwloc_attribute_pure;
00115 static __hwloc_inline hwloc_obj_t
00116 hwloc_get_root_obj (hwloc_topology_t topology)
00117 {
00118 return hwloc_get_obj_by_depth (topology, 0, 0);
00119 }
00120
00122 static __hwloc_inline hwloc_obj_t
00123 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj) __hwloc_attribute_pure;
00124 static __hwloc_inline hwloc_obj_t
00125 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj)
00126 {
00127 hwloc_obj_t ancestor = obj;
00128 if (obj->depth < depth)
00129 return NULL;
00130 while (ancestor && ancestor->depth > depth)
00131 ancestor = ancestor->parent;
00132 return ancestor;
00133 }
00134
00136 static __hwloc_inline hwloc_obj_t
00137 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;
00138 static __hwloc_inline hwloc_obj_t
00139 hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj)
00140 {
00141 hwloc_obj_t ancestor = obj->parent;
00142 while (ancestor && ancestor->type != type)
00143 ancestor = ancestor->parent;
00144 return ancestor;
00145 }
00146
00151 static __hwloc_inline hwloc_obj_t
00152 hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev)
00153 {
00154 if (!prev)
00155 return hwloc_get_obj_by_depth (topology, depth, 0);
00156 if (prev->depth != depth)
00157 return NULL;
00158 return prev->next_cousin;
00159 }
00160
00167 static __hwloc_inline hwloc_obj_t
00168 hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
00169 hwloc_obj_t prev)
00170 {
00171 int depth = hwloc_get_type_depth(topology, type);
00172 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00173 return NULL;
00174 return hwloc_get_next_obj_by_depth (topology, depth, prev);
00175 }
00176
00185 static __hwloc_inline hwloc_obj_t
00186 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure;
00187 static __hwloc_inline hwloc_obj_t
00188 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
00189 {
00190 hwloc_obj_t obj = NULL;
00191 while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
00192 if (obj->os_index == os_index)
00193 return obj;
00194 return NULL;
00195 }
00196
00201 static __hwloc_inline hwloc_obj_t
00202 hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev)
00203 {
00204 if (!prev)
00205 return parent->first_child;
00206 if (prev->parent != parent)
00207 return NULL;
00208 return prev->next_sibling;
00209 }
00210
00212 static __hwloc_inline hwloc_obj_t
00213 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2) __hwloc_attribute_pure;
00214 static __hwloc_inline hwloc_obj_t
00215 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2)
00216 {
00217
00218
00219
00220
00221
00222 while (obj1 != obj2) {
00223 while (obj1->depth > obj2->depth)
00224 obj1 = obj1->parent;
00225 while (obj2->depth > obj1->depth)
00226 obj2 = obj2->parent;
00227 if (obj1 != obj2 && obj1->depth == obj2->depth) {
00228 obj1 = obj1->parent;
00229 obj2 = obj2->parent;
00230 }
00231 }
00232 return obj1;
00233 }
00234
00239 static __hwloc_inline int
00240 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root) __hwloc_attribute_pure;
00241 static __hwloc_inline int
00242 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root)
00243 {
00244 return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
00245 }
00246
00266 static __hwloc_inline hwloc_obj_t
00267 hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
00268 {
00269 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00270 if (!obj->cpuset || !hwloc_bitmap_intersects(obj->cpuset, set))
00271 return NULL;
00272 while (!hwloc_bitmap_isincluded(obj->cpuset, set)) {
00273
00274 hwloc_obj_t child = NULL;
00275 while ((child = hwloc_get_next_child(topology, obj, child)) != NULL) {
00276 if (child->cpuset && hwloc_bitmap_intersects(child->cpuset, set))
00277 break;
00278 }
00279 if (!child)
00280
00281 return obj;
00282
00283 obj = child;
00284 }
00285
00286 return obj;
00287 }
00288
00296 HWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00297 hwloc_obj_t * __hwloc_restrict objs, int max);
00298
00308 static __hwloc_inline hwloc_obj_t
00309 hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00310 unsigned depth, hwloc_obj_t prev)
00311 {
00312 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00313 if (!next || !next->cpuset)
00314 return NULL;
00315 while (next && !hwloc_bitmap_isincluded(next->cpuset, set))
00316 next = next->next_cousin;
00317 return next;
00318 }
00319
00329 static __hwloc_inline hwloc_obj_t
00330 hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00331 hwloc_obj_type_t type, hwloc_obj_t prev)
00332 {
00333 int depth = hwloc_get_type_depth(topology, type);
00334 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00335 return NULL;
00336 return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
00337 }
00338
00344 static __hwloc_inline hwloc_obj_t
00345 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00346 unsigned depth, unsigned idx) __hwloc_attribute_pure;
00347 static __hwloc_inline hwloc_obj_t
00348 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00349 unsigned depth, unsigned idx)
00350 {
00351 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00352 unsigned count = 0;
00353 if (!obj || !obj->cpuset)
00354 return NULL;
00355 while (obj) {
00356 if (hwloc_bitmap_isincluded(obj->cpuset, set)) {
00357 if (count == idx)
00358 return obj;
00359 count++;
00360 }
00361 obj = obj->next_cousin;
00362 }
00363 return NULL;
00364 }
00365
00375 static __hwloc_inline hwloc_obj_t
00376 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00377 hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure;
00378 static __hwloc_inline hwloc_obj_t
00379 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00380 hwloc_obj_type_t type, unsigned idx)
00381 {
00382 int depth = hwloc_get_type_depth(topology, type);
00383 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00384 return NULL;
00385 return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
00386 }
00387
00393 static __hwloc_inline unsigned
00394 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00395 unsigned depth) __hwloc_attribute_pure;
00396 static __hwloc_inline unsigned
00397 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00398 unsigned depth)
00399 {
00400 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00401 unsigned count = 0;
00402 if (!obj || !obj->cpuset)
00403 return 0;
00404 while (obj) {
00405 if (hwloc_bitmap_isincluded(obj->cpuset, set))
00406 count++;
00407 obj = obj->next_cousin;
00408 }
00409 return count;
00410 }
00411
00421 static __hwloc_inline int
00422 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00423 hwloc_obj_type_t type) __hwloc_attribute_pure;
00424 static __hwloc_inline int
00425 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00426 hwloc_obj_type_t type)
00427 {
00428 int depth = hwloc_get_type_depth(topology, type);
00429 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
00430 return 0;
00431 if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00432 return -1;
00433 return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
00434 }
00435
00444 static __hwloc_inline int
00445 hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00446 hwloc_obj_t obj) __hwloc_attribute_pure;
00447 static __hwloc_inline int
00448 hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00449 hwloc_obj_t obj)
00450 {
00451 int index = 0;
00452 if (!hwloc_bitmap_isincluded(obj->cpuset, set))
00453 return -1;
00454
00455 while ((obj = obj->prev_cousin) != NULL)
00456 if (hwloc_bitmap_isincluded(obj->cpuset, set))
00457 index++;
00458 return index;
00459 }
00460
00475 static __hwloc_inline hwloc_obj_t
00476 hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00477 hwloc_obj_t parent) __hwloc_attribute_pure;
00478 static __hwloc_inline hwloc_obj_t
00479 hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00480 hwloc_obj_t parent)
00481 {
00482 hwloc_obj_t child;
00483 if (!parent->cpuset || hwloc_bitmap_iszero(set))
00484 return NULL;
00485 child = parent->first_child;
00486 while (child) {
00487 if (child->cpuset && hwloc_bitmap_isincluded(set, child->cpuset))
00488 return child;
00489 child = child->next_sibling;
00490 }
00491 return NULL;
00492 }
00493
00501 static __hwloc_inline hwloc_obj_t
00502 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure;
00503 static __hwloc_inline hwloc_obj_t
00504 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00505 {
00506 struct hwloc_obj *current = hwloc_get_root_obj(topology);
00507 if (hwloc_bitmap_iszero(set) || !current->cpuset || !hwloc_bitmap_isincluded(set, current->cpuset))
00508 return NULL;
00509 while (1) {
00510 hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
00511 if (!child)
00512 return current;
00513 current = child;
00514 }
00515 }
00516
00517
00536 static __hwloc_inline hwloc_obj_t
00537 hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00538 unsigned depth, hwloc_obj_t prev)
00539 {
00540 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00541 if (!next || !next->cpuset)
00542 return NULL;
00543 while (next && !hwloc_bitmap_intersects(set, next->cpuset))
00544 next = next->next_cousin;
00545 return next;
00546 }
00547
00563 static __hwloc_inline hwloc_obj_t
00564 hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00565 hwloc_obj_type_t type, hwloc_obj_t prev)
00566 {
00567 int depth = hwloc_get_type_depth(topology, type);
00568 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00569 return NULL;
00570 return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
00571 }
00572
00588 static __hwloc_inline hwloc_obj_t
00589 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure;
00590 static __hwloc_inline hwloc_obj_t
00591 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00592 {
00593 hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
00594 while (current) {
00595 if (current->type == HWLOC_OBJ_CACHE)
00596 return current;
00597 current = current->parent;
00598 }
00599 return NULL;
00600 }
00601
00606 static __hwloc_inline hwloc_obj_t
00607 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj) __hwloc_attribute_pure;
00608 static __hwloc_inline hwloc_obj_t
00609 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj)
00610 {
00611 hwloc_obj_t current = obj->parent;
00612 if (!obj->cpuset)
00613 return NULL;
00614 while (current && current->cpuset) {
00615 if (!hwloc_bitmap_isequal(current->cpuset, obj->cpuset)
00616 && current->type == HWLOC_OBJ_CACHE)
00617 return current;
00618 current = current->parent;
00619 }
00620 return NULL;
00621 }
00622
00647
00648 HWLOC_DECLSPEC unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * __hwloc_restrict objs, unsigned max);
00649
00662 static __hwloc_inline hwloc_obj_t
00663 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
00664 hwloc_obj_type_t type1, unsigned idx1,
00665 hwloc_obj_type_t type2, unsigned idx2) __hwloc_attribute_pure;
00666 static __hwloc_inline hwloc_obj_t
00667 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
00668 hwloc_obj_type_t type1, unsigned idx1,
00669 hwloc_obj_type_t type2, unsigned idx2)
00670 {
00671 hwloc_obj_t obj;
00672 obj = hwloc_get_obj_by_type (topology, type1, idx1);
00673 if (!obj || !obj->cpuset)
00674 return NULL;
00675 return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
00676 }
00677
00696 static __hwloc_inline hwloc_obj_t
00697 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv) __hwloc_attribute_pure;
00698 static __hwloc_inline hwloc_obj_t
00699 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
00700 {
00701 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00702 int i;
00703 for(i=0; i<nr; i++) {
00704 if (!obj || !obj->cpuset)
00705 return NULL;
00706 obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
00707 }
00708 return obj;
00709 }
00710
00734 static __hwloc_inline void
00735 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *root, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until);
00736 static __hwloc_inline void
00737 hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
00738 {
00739 unsigned i;
00740 if (!root->arity || n == 1 || root->depth >= until) {
00741
00742 for (i=0; i<n; i++)
00743 cpuset[i] = hwloc_bitmap_dup(root->cpuset);
00744 return;
00745 }
00746 hwloc_distributev(topology, root->children, root->arity, cpuset, n, until);
00747 }
00748
00756 static __hwloc_inline void
00757 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
00758 {
00759 unsigned i;
00760 unsigned tot_weight;
00761 hwloc_cpuset_t *cpusetp = cpuset;
00762
00763 tot_weight = 0;
00764 for (i = 0; i < n_roots; i++)
00765 if (roots[i]->cpuset)
00766 tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);
00767
00768 for (i = 0; i < n_roots && tot_weight; i++) {
00769
00770 unsigned weight = roots[i]->cpuset ? hwloc_bitmap_weight(roots[i]->cpuset) : 0;
00771 unsigned chunk = (n * weight + tot_weight-1) / tot_weight;
00772 hwloc_distribute(topology, roots[i], cpusetp, chunk, until);
00773 cpusetp += chunk;
00774 tot_weight -= weight;
00775 n -= chunk;
00776 }
00777 }
00778
00785 static __hwloc_inline void *
00786 hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
00787 {
00788 void *p = hwloc_alloc_membind_nodeset(topology, len, nodeset, policy, flags);
00789 if (p)
00790 return p;
00791 hwloc_set_membind_nodeset(topology, nodeset, policy, flags);
00792 p = hwloc_alloc(topology, len);
00793 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
00794
00795 memset(p, 0, len);
00796 return p;
00797 }
00798
00803 static __hwloc_inline void *
00804 hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t cpuset, hwloc_membind_policy_t policy, int flags)
00805 {
00806 void *p = hwloc_alloc_membind(topology, len, cpuset, policy, flags);
00807 if (p)
00808 return p;
00809 hwloc_set_membind(topology, cpuset, policy, flags);
00810 p = hwloc_alloc(topology, len);
00811 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
00812
00813 memset(p, 0, len);
00814 return p;
00815 }
00816
00833 static __hwloc_inline hwloc_const_cpuset_t
00834 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
00835 static __hwloc_inline hwloc_const_cpuset_t
00836 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
00837 {
00838 return hwloc_get_root_obj(topology)->complete_cpuset;
00839 }
00840
00851 static __hwloc_inline hwloc_const_cpuset_t
00852 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
00853 static __hwloc_inline hwloc_const_cpuset_t
00854 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
00855 {
00856 return hwloc_get_root_obj(topology)->cpuset;
00857 }
00858
00868 static __hwloc_inline hwloc_const_cpuset_t
00869 hwloc_topology_get_online_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
00870 static __hwloc_inline hwloc_const_cpuset_t
00871 hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
00872 {
00873 return hwloc_get_root_obj(topology)->online_cpuset;
00874 }
00875
00885 static __hwloc_inline hwloc_const_cpuset_t
00886 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
00887 static __hwloc_inline hwloc_const_cpuset_t
00888 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
00889 {
00890 return hwloc_get_root_obj(topology)->allowed_cpuset;
00891 }
00892
00909 static __hwloc_inline hwloc_const_nodeset_t
00910 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
00911 static __hwloc_inline hwloc_const_nodeset_t
00912 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
00913 {
00914 return hwloc_get_root_obj(topology)->complete_nodeset;
00915 }
00916
00927 static __hwloc_inline hwloc_const_nodeset_t
00928 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
00929 static __hwloc_inline hwloc_const_nodeset_t
00930 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
00931 {
00932 return hwloc_get_root_obj(topology)->nodeset;
00933 }
00934
00944 static __hwloc_inline hwloc_const_nodeset_t
00945 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
00946 static __hwloc_inline hwloc_const_nodeset_t
00947 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
00948 {
00949 return hwloc_get_root_obj(topology)->allowed_nodeset;
00950 }
00951
00982 static __hwloc_inline void
00983 hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
00984 {
00985 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00986 hwloc_obj_t obj;
00987
00988 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
00989 if (hwloc_bitmap_iszero(cpuset))
00990 hwloc_bitmap_zero(nodeset);
00991 else
00992
00993 hwloc_bitmap_fill(nodeset);
00994 return;
00995 }
00996
00997 hwloc_bitmap_zero(nodeset);
00998 obj = NULL;
00999 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
01000 hwloc_bitmap_set(nodeset, obj->os_index);
01001 }
01002
01010 static __hwloc_inline void
01011 hwloc_cpuset_to_nodeset_strict(struct hwloc_topology *topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
01012 {
01013 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
01014 hwloc_obj_t obj;
01015 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
01016 return;
01017 hwloc_bitmap_zero(nodeset);
01018 obj = NULL;
01019 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
01020 hwloc_bitmap_set(nodeset, obj->os_index);
01021 }
01022
01031 static __hwloc_inline void
01032 hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
01033 {
01034 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
01035 hwloc_obj_t obj;
01036
01037 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) {
01038 if (hwloc_bitmap_iszero(nodeset))
01039 hwloc_bitmap_zero(cpuset);
01040 else
01041
01042 hwloc_bitmap_fill(cpuset);
01043 return;
01044 }
01045
01046 hwloc_bitmap_zero(cpuset);
01047 obj = NULL;
01048 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
01049 if (hwloc_bitmap_isset(nodeset, obj->os_index))
01050
01051 hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
01052 }
01053 }
01054
01062 static __hwloc_inline void
01063 hwloc_cpuset_from_nodeset_strict(struct hwloc_topology *topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
01064 {
01065 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
01066 hwloc_obj_t obj;
01067 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
01068 return;
01069 hwloc_bitmap_zero(cpuset);
01070 obj = NULL;
01071 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL)
01072 if (hwloc_bitmap_isset(nodeset, obj->os_index))
01073
01074 hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
01075 }
01076
01104 static __hwloc_inline const struct hwloc_distances_s *
01105 hwloc_get_whole_distance_matrix_by_depth(hwloc_topology_t topology, unsigned depth)
01106 {
01107 hwloc_obj_t root = hwloc_get_root_obj(topology);
01108 unsigned i;
01109 for(i=0; i<root->distances_count; i++)
01110 if (root->distances[i]->relative_depth == depth)
01111 return root->distances[i];
01112 return NULL;
01113 }
01114
01134 static __hwloc_inline const struct hwloc_distances_s *
01135 hwloc_get_whole_distance_matrix_by_type(hwloc_topology_t topology, hwloc_obj_type_t type)
01136 {
01137 int depth = hwloc_get_type_depth(topology, type);
01138 if (depth < 0)
01139 return NULL;
01140 return hwloc_get_whole_distance_matrix_by_depth(topology, depth);
01141 }
01142
01156 static __hwloc_inline const struct hwloc_distances_s *
01157 hwloc_get_distance_matrix_covering_obj_by_depth(hwloc_topology_t topology,
01158 hwloc_obj_t obj, unsigned depth,
01159 unsigned *firstp)
01160 {
01161 while (obj && obj->cpuset) {
01162 unsigned i;
01163 for(i=0; i<obj->distances_count; i++)
01164 if (obj->distances[i]->relative_depth == depth - obj->depth) {
01165 if (!obj->distances[i]->nbobjs)
01166 continue;
01167 *firstp = hwloc_get_next_obj_inside_cpuset_by_depth(topology, obj->cpuset, depth, NULL)->logical_index;
01168 return obj->distances[i];
01169 }
01170 obj = obj->parent;
01171 }
01172 return NULL;
01173 }
01174
01186 static __hwloc_inline int
01187 hwloc_get_latency(hwloc_topology_t topology,
01188 hwloc_obj_t obj1, hwloc_obj_t obj2,
01189 float *latency, float *reverse_latency)
01190 {
01191 hwloc_obj_t ancestor;
01192 const struct hwloc_distances_s * distances;
01193 unsigned first_logical ;
01194
01195 if (obj1->depth != obj2->depth) {
01196 errno = EINVAL;
01197 return -1;
01198 }
01199
01200 ancestor = hwloc_get_common_ancestor_obj(topology, obj1, obj2);
01201 distances = hwloc_get_distance_matrix_covering_obj_by_depth(topology, ancestor, obj1->depth, &first_logical);
01202 if (distances && distances->latency) {
01203 const float * latency_matrix = distances->latency;
01204 unsigned nbobjs = distances->nbobjs;
01205 unsigned l1 = obj1->logical_index - first_logical;
01206 unsigned l2 = obj2->logical_index - first_logical;
01207 *latency = latency_matrix[l1*nbobjs+l2];
01208 *reverse_latency = latency_matrix[l2*nbobjs+l1];
01209 return 0;
01210 }
01211
01212 errno = ENOSYS;
01213 return -1;
01214 }
01215
01230 static __hwloc_inline hwloc_obj_t
01231 hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused,
01232 hwloc_obj_t ioobj)
01233 {
01234 hwloc_obj_t obj = ioobj;
01235 while (obj && !obj->cpuset) {
01236 obj = obj->parent;
01237 }
01238 return obj;
01239 }
01240
01245 static __hwloc_inline hwloc_obj_t
01246 hwloc_get_next_pcidev(hwloc_topology_t topology, hwloc_obj_t prev)
01247 {
01248 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PCI_DEVICE, prev);
01249 }
01250
01254 static __hwloc_inline hwloc_obj_t
01255 hwloc_get_pcidev_by_busid(hwloc_topology_t topology,
01256 unsigned domain, unsigned bus, unsigned dev, unsigned func)
01257 {
01258 hwloc_obj_t obj = NULL;
01259 while ((obj = hwloc_get_next_pcidev(topology, obj)) != NULL) {
01260 if (obj->attr->pcidev.domain == domain
01261 && obj->attr->pcidev.bus == bus
01262 && obj->attr->pcidev.dev == dev
01263 && obj->attr->pcidev.func == func)
01264 return obj;
01265 }
01266 return NULL;
01267 }
01268
01272 static __hwloc_inline hwloc_obj_t
01273 hwloc_get_pcidev_by_busidstring(hwloc_topology_t topology, const char *busid)
01274 {
01275 unsigned domain = 0;
01276 unsigned bus, dev, func;
01277
01278 if (sscanf(busid, "%x:%x.%x", &bus, &dev, &func) != 3
01279 && sscanf(busid, "%x:%x:%x.%x", &domain, &bus, &dev, &func) != 4) {
01280 errno = EINVAL;
01281 return NULL;
01282 }
01283
01284 return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, func);
01285 }
01286
01291 static __hwloc_inline hwloc_obj_t
01292 hwloc_get_next_osdev(hwloc_topology_t topology, hwloc_obj_t prev)
01293 {
01294 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_OS_DEVICE, prev);
01295 }
01296
01301 static __hwloc_inline hwloc_obj_t
01302 hwloc_get_next_bridge(hwloc_topology_t topology, hwloc_obj_t prev)
01303 {
01304 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_BRIDGE, prev);
01305 }
01306
01307
01308
01309 static __hwloc_inline int
01310 hwloc_bridge_covers_pcibus(hwloc_obj_t bridge,
01311 unsigned domain, unsigned bus)
01312 {
01313 return bridge->type == HWLOC_OBJ_BRIDGE
01314 && bridge->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI
01315 && bridge->attr->bridge.downstream.pci.domain == domain
01316 && bridge->attr->bridge.downstream.pci.secondary_bus <= bus
01317 && bridge->attr->bridge.downstream.pci.subordinate_bus >= bus;
01318 }
01319
01325 static __hwloc_inline hwloc_obj_t
01326 hwloc_get_hostbridge_by_pcibus(hwloc_topology_t topology,
01327 unsigned domain, unsigned bus)
01328 {
01329 hwloc_obj_t obj = NULL;
01330 while ((obj = hwloc_get_next_bridge(topology, obj)) != NULL) {
01331 if (hwloc_bridge_covers_pcibus(obj, domain, bus)) {
01332
01333 assert(obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_HOST);
01334 assert(obj->parent->type != HWLOC_OBJ_BRIDGE);
01335 assert(obj->parent->cpuset);
01336 return obj;
01337 }
01338 }
01339 return NULL;
01340 }
01341
01346 #ifdef __cplusplus
01347 }
01348 #endif
01349
01350
01351 #endif