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
00041 static __hwloc_inline hwloc_obj_t
00042 hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
00043 {
00044 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00045 if (!hwloc_bitmap_intersects(obj->cpuset, set))
00046 return NULL;
00047 while (!hwloc_bitmap_isincluded(obj->cpuset, set)) {
00048
00049 hwloc_obj_t child = obj->first_child;
00050 while (child) {
00051 if (hwloc_bitmap_intersects(child->cpuset, set))
00052 break;
00053 child = child->next_sibling;
00054 }
00055 if (!child)
00056
00057 return obj;
00058
00059 obj = child;
00060 }
00061
00062 return obj;
00063 }
00064
00069 HWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00070 hwloc_obj_t * __hwloc_restrict objs, int max);
00071
00084 static __hwloc_inline hwloc_obj_t
00085 hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00086 int depth, hwloc_obj_t prev)
00087 {
00088 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00089 if (!next)
00090 return NULL;
00091 while (next && (hwloc_bitmap_iszero(next->cpuset) || !hwloc_bitmap_isincluded(next->cpuset, set)))
00092 next = next->next_cousin;
00093 return next;
00094 }
00095
00108 static __hwloc_inline hwloc_obj_t
00109 hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00110 hwloc_obj_type_t type, hwloc_obj_t prev)
00111 {
00112 int depth = hwloc_get_type_depth(topology, type);
00113 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00114 return NULL;
00115 return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
00116 }
00117
00126 static __hwloc_inline hwloc_obj_t
00127 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00128 int depth, unsigned idx) __hwloc_attribute_pure;
00129 static __hwloc_inline hwloc_obj_t
00130 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00131 int depth, unsigned idx)
00132 {
00133 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00134 unsigned count = 0;
00135 if (!obj)
00136 return NULL;
00137 while (obj) {
00138 if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set)) {
00139 if (count == idx)
00140 return obj;
00141 count++;
00142 }
00143 obj = obj->next_cousin;
00144 }
00145 return NULL;
00146 }
00147
00160 static __hwloc_inline hwloc_obj_t
00161 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00162 hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure;
00163 static __hwloc_inline hwloc_obj_t
00164 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00165 hwloc_obj_type_t type, unsigned idx)
00166 {
00167 int depth = hwloc_get_type_depth(topology, type);
00168 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00169 return NULL;
00170 return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
00171 }
00172
00181 static __hwloc_inline unsigned
00182 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00183 int depth) __hwloc_attribute_pure;
00184 static __hwloc_inline unsigned
00185 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00186 int depth)
00187 {
00188 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00189 unsigned count = 0;
00190 if (!obj)
00191 return 0;
00192 while (obj) {
00193 if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set))
00194 count++;
00195 obj = obj->next_cousin;
00196 }
00197 return count;
00198 }
00199
00212 static __hwloc_inline int
00213 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00214 hwloc_obj_type_t type) __hwloc_attribute_pure;
00215 static __hwloc_inline int
00216 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00217 hwloc_obj_type_t type)
00218 {
00219 int depth = hwloc_get_type_depth(topology, type);
00220 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
00221 return 0;
00222 if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00223 return -1;
00224 return (int) hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
00225 }
00226
00240 static __hwloc_inline int
00241 hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00242 hwloc_obj_t obj) __hwloc_attribute_pure;
00243 static __hwloc_inline int
00244 hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00245 hwloc_obj_t obj)
00246 {
00247 int idx = 0;
00248 if (!hwloc_bitmap_isincluded(obj->cpuset, set))
00249 return -1;
00250
00251 while ((obj = obj->prev_cousin) != NULL)
00252 if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set))
00253 idx++;
00254 return idx;
00255 }
00256
00271 static __hwloc_inline hwloc_obj_t
00272 hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00273 hwloc_obj_t parent) __hwloc_attribute_pure;
00274 static __hwloc_inline hwloc_obj_t
00275 hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00276 hwloc_obj_t parent)
00277 {
00278 hwloc_obj_t child;
00279 if (hwloc_bitmap_iszero(set))
00280 return NULL;
00281 child = parent->first_child;
00282 while (child) {
00283 if (child->cpuset && hwloc_bitmap_isincluded(set, child->cpuset))
00284 return child;
00285 child = child->next_sibling;
00286 }
00287 return NULL;
00288 }
00289
00294 static __hwloc_inline hwloc_obj_t
00295 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure;
00296 static __hwloc_inline hwloc_obj_t
00297 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00298 {
00299 struct hwloc_obj *current = hwloc_get_root_obj(topology);
00300 if (hwloc_bitmap_iszero(set) || !hwloc_bitmap_isincluded(set, current->cpuset))
00301 return NULL;
00302 while (1) {
00303 hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
00304 if (!child)
00305 return current;
00306 current = child;
00307 }
00308 }
00309
00320 static __hwloc_inline hwloc_obj_t
00321 hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00322 int depth, hwloc_obj_t prev)
00323 {
00324 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00325 if (!next)
00326 return NULL;
00327 while (next && !hwloc_bitmap_intersects(set, next->cpuset))
00328 next = next->next_cousin;
00329 return next;
00330 }
00331
00347 static __hwloc_inline hwloc_obj_t
00348 hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00349 hwloc_obj_type_t type, hwloc_obj_t prev)
00350 {
00351 int depth = hwloc_get_type_depth(topology, type);
00352 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00353 return NULL;
00354 return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
00355 }
00356
00377 static __hwloc_inline hwloc_obj_t
00378 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, int depth, hwloc_obj_t obj) __hwloc_attribute_pure;
00379 static __hwloc_inline hwloc_obj_t
00380 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, int depth, hwloc_obj_t obj)
00381 {
00382 hwloc_obj_t ancestor = obj;
00383 if (obj->depth < depth)
00384 return NULL;
00385 while (ancestor && ancestor->depth > depth)
00386 ancestor = ancestor->parent;
00387 return ancestor;
00388 }
00389
00397 static __hwloc_inline hwloc_obj_t
00398 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;
00399 static __hwloc_inline hwloc_obj_t
00400 hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj)
00401 {
00402 hwloc_obj_t ancestor = obj->parent;
00403 while (ancestor && ancestor->type != type)
00404 ancestor = ancestor->parent;
00405 return ancestor;
00406 }
00407
00409 static __hwloc_inline hwloc_obj_t
00410 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2) __hwloc_attribute_pure;
00411 static __hwloc_inline hwloc_obj_t
00412 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2)
00413 {
00414
00415
00416
00417
00418
00419 while (obj1 != obj2) {
00420 while (obj1->depth > obj2->depth)
00421 obj1 = obj1->parent;
00422 while (obj2->depth > obj1->depth)
00423 obj2 = obj2->parent;
00424 if (obj1 != obj2 && obj1->depth == obj2->depth) {
00425 obj1 = obj1->parent;
00426 obj2 = obj2->parent;
00427 }
00428 }
00429 return obj1;
00430 }
00431
00437 static __hwloc_inline int
00438 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root) __hwloc_attribute_pure;
00439 static __hwloc_inline int
00440 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root)
00441 {
00442 return obj->cpuset && subtree_root->cpuset && hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
00443 }
00444
00455 static __hwloc_inline hwloc_obj_t
00456 hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev)
00457 {
00458 hwloc_obj_t obj;
00459 int state = 0;
00460 if (prev) {
00461 if (prev->type == HWLOC_OBJ_MISC)
00462 state = 3;
00463 else if (prev->type == HWLOC_OBJ_BRIDGE || prev->type == HWLOC_OBJ_PCI_DEVICE || prev->type == HWLOC_OBJ_OS_DEVICE)
00464 state = 2;
00465 else if (prev->type == HWLOC_OBJ_NUMANODE)
00466 state = 1;
00467 obj = prev->next_sibling;
00468 } else {
00469 obj = parent->first_child;
00470 }
00471 if (!obj && state == 0) {
00472 obj = parent->memory_first_child;
00473 state = 1;
00474 }
00475 if (!obj && state == 1) {
00476 obj = parent->io_first_child;
00477 state = 2;
00478 }
00479 if (!obj && state == 2) {
00480 obj = parent->misc_first_child;
00481 state = 3;
00482 }
00483 return obj;
00484 }
00485
00512 HWLOC_DECLSPEC int
00513 hwloc_obj_type_is_normal(hwloc_obj_type_t type);
00514
00523 HWLOC_DECLSPEC int
00524 hwloc_obj_type_is_io(hwloc_obj_type_t type);
00525
00534 HWLOC_DECLSPEC int
00535 hwloc_obj_type_is_memory(hwloc_obj_type_t type);
00536
00543 HWLOC_DECLSPEC int
00544 hwloc_obj_type_is_cache(hwloc_obj_type_t type);
00545
00552 HWLOC_DECLSPEC int
00553 hwloc_obj_type_is_dcache(hwloc_obj_type_t type);
00554
00561 HWLOC_DECLSPEC int
00562 hwloc_obj_type_is_icache(hwloc_obj_type_t type);
00563
00593 static __hwloc_inline int
00594 hwloc_get_cache_type_depth (hwloc_topology_t topology,
00595 unsigned cachelevel, hwloc_obj_cache_type_t cachetype)
00596 {
00597 int depth;
00598 int found = HWLOC_TYPE_DEPTH_UNKNOWN;
00599 for (depth=0; ; depth++) {
00600 hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, 0);
00601 if (!obj)
00602 break;
00603 if (!hwloc_obj_type_is_dcache(obj->type) || obj->attr->cache.depth != cachelevel)
00604
00605 continue;
00606 if (cachetype == (hwloc_obj_cache_type_t) -1) {
00607 if (found != HWLOC_TYPE_DEPTH_UNKNOWN) {
00608
00609 return HWLOC_TYPE_DEPTH_MULTIPLE;
00610 }
00611
00612 found = depth;
00613 continue;
00614 }
00615 if (obj->attr->cache.type == cachetype || obj->attr->cache.type == HWLOC_OBJ_CACHE_UNIFIED)
00616
00617 return depth;
00618 }
00619
00620 return found;
00621 }
00622
00627 static __hwloc_inline hwloc_obj_t
00628 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure;
00629 static __hwloc_inline hwloc_obj_t
00630 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00631 {
00632 hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
00633 while (current) {
00634 if (hwloc_obj_type_is_dcache(current->type))
00635 return current;
00636 current = current->parent;
00637 }
00638 return NULL;
00639 }
00640
00645 static __hwloc_inline hwloc_obj_t
00646 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj) __hwloc_attribute_pure;
00647 static __hwloc_inline hwloc_obj_t
00648 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj)
00649 {
00650 hwloc_obj_t current = obj->parent;
00651 if (!obj->cpuset)
00652 return NULL;
00653 while (current) {
00654 if (!hwloc_bitmap_isequal(current->cpuset, obj->cpuset)
00655 && hwloc_obj_type_is_dcache(current->type))
00656 return current;
00657 current = current->parent;
00658 }
00659 return NULL;
00660 }
00661
00691 HWLOC_DECLSPEC int hwloc_bitmap_singlify_per_core(hwloc_topology_t topology, hwloc_bitmap_t cpuset, unsigned which);
00692
00702 static __hwloc_inline hwloc_obj_t
00703 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure;
00704 static __hwloc_inline hwloc_obj_t
00705 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
00706 {
00707 hwloc_obj_t obj = NULL;
00708 while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
00709 if (obj->os_index == os_index)
00710 return obj;
00711 return NULL;
00712 }
00713
00723 static __hwloc_inline hwloc_obj_t
00724 hwloc_get_numanode_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure;
00725 static __hwloc_inline hwloc_obj_t
00726 hwloc_get_numanode_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
00727 {
00728 hwloc_obj_t obj = NULL;
00729 while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NUMANODE, obj)) != NULL)
00730 if (obj->os_index == os_index)
00731 return obj;
00732 return NULL;
00733 }
00734
00746
00747 HWLOC_DECLSPEC unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * __hwloc_restrict objs, unsigned max);
00748
00761 static __hwloc_inline hwloc_obj_t
00762 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
00763 hwloc_obj_type_t type1, unsigned idx1,
00764 hwloc_obj_type_t type2, unsigned idx2) __hwloc_attribute_pure;
00765 static __hwloc_inline hwloc_obj_t
00766 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
00767 hwloc_obj_type_t type1, unsigned idx1,
00768 hwloc_obj_type_t type2, unsigned idx2)
00769 {
00770 hwloc_obj_t obj;
00771 obj = hwloc_get_obj_by_type (topology, type1, idx1);
00772 if (!obj)
00773 return NULL;
00774 return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
00775 }
00776
00795 static __hwloc_inline hwloc_obj_t
00796 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv) __hwloc_attribute_pure;
00797 static __hwloc_inline hwloc_obj_t
00798 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
00799 {
00800 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00801 int i;
00802 for(i=0; i<nr; i++) {
00803 if (!obj)
00804 return NULL;
00805 obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
00806 }
00807 return obj;
00808 }
00809
00820 enum hwloc_distrib_flags_e {
00824 HWLOC_DISTRIB_FLAG_REVERSE = (1UL<<0)
00825 };
00826
00850 static __hwloc_inline int
00851 hwloc_distrib(hwloc_topology_t topology,
00852 hwloc_obj_t *roots, unsigned n_roots,
00853 hwloc_cpuset_t *set,
00854 unsigned n,
00855 int until, unsigned long flags)
00856 {
00857 unsigned i;
00858 unsigned tot_weight;
00859 unsigned given, givenweight;
00860 hwloc_cpuset_t *cpusetp = set;
00861
00862 if (flags & ~HWLOC_DISTRIB_FLAG_REVERSE) {
00863 errno = EINVAL;
00864 return -1;
00865 }
00866
00867 tot_weight = 0;
00868 for (i = 0; i < n_roots; i++)
00869 tot_weight += (unsigned) hwloc_bitmap_weight(roots[i]->cpuset);
00870
00871 for (i = 0, given = 0, givenweight = 0; i < n_roots; i++) {
00872 unsigned chunk, weight;
00873 hwloc_obj_t root = roots[flags & HWLOC_DISTRIB_FLAG_REVERSE ? n_roots-1-i : i];
00874 hwloc_cpuset_t cpuset = root->cpuset;
00875 if (root->type == HWLOC_OBJ_NUMANODE)
00876
00877 root = root->parent;
00878 weight = (unsigned) hwloc_bitmap_weight(cpuset);
00879 if (!weight)
00880 continue;
00881
00882
00883 chunk = (( (givenweight+weight) * n + tot_weight-1) / tot_weight)
00884 - (( givenweight * n + tot_weight-1) / tot_weight);
00885 if (!root->arity || chunk <= 1 || root->depth >= until) {
00886
00887 if (chunk) {
00888
00889 unsigned j;
00890 for (j=0; j < chunk; j++)
00891 cpusetp[j] = hwloc_bitmap_dup(cpuset);
00892 } else {
00893
00894
00895
00896
00897 assert(given);
00898 hwloc_bitmap_or(cpusetp[-1], cpusetp[-1], cpuset);
00899 }
00900 } else {
00901
00902 hwloc_distrib(topology, root->children, root->arity, cpusetp, chunk, until, flags);
00903 }
00904 cpusetp += chunk;
00905 given += chunk;
00906 givenweight += weight;
00907 }
00908
00909 return 0;
00910 }
00911
00929 HWLOC_DECLSPEC hwloc_const_cpuset_t
00930 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
00931
00943 HWLOC_DECLSPEC hwloc_const_cpuset_t
00944 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
00945
00962 HWLOC_DECLSPEC hwloc_const_cpuset_t
00963 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
00964
00974 HWLOC_DECLSPEC hwloc_const_nodeset_t
00975 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
00976
00988 HWLOC_DECLSPEC hwloc_const_nodeset_t
00989 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
00990
01007 HWLOC_DECLSPEC hwloc_const_nodeset_t
01008 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
01009
01030 static __hwloc_inline int
01031 hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset)
01032 {
01033 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
01034 hwloc_obj_t obj = NULL;
01035 assert(depth != HWLOC_TYPE_DEPTH_UNKNOWN);
01036 hwloc_bitmap_zero(nodeset);
01037 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, _cpuset, depth, obj)) != NULL)
01038 if (hwloc_bitmap_set(nodeset, obj->os_index) < 0)
01039 return -1;
01040 return 0;
01041 }
01042
01054 static __hwloc_inline int
01055 hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset)
01056 {
01057 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
01058 hwloc_obj_t obj = NULL;
01059 assert(depth != HWLOC_TYPE_DEPTH_UNKNOWN);
01060 hwloc_bitmap_zero(_cpuset);
01061 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
01062 if (hwloc_bitmap_isset(nodeset, obj->os_index))
01063
01064 if (hwloc_bitmap_or(_cpuset, _cpuset, obj->cpuset) < 0)
01065 return -1;
01066 }
01067 return 0;
01068 }
01069
01089 static __hwloc_inline hwloc_obj_t
01090 hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused,
01091 hwloc_obj_t ioobj)
01092 {
01093 hwloc_obj_t obj = ioobj;
01094 while (obj && !obj->cpuset) {
01095 obj = obj->parent;
01096 }
01097 return obj;
01098 }
01099
01104 static __hwloc_inline hwloc_obj_t
01105 hwloc_get_next_pcidev(hwloc_topology_t topology, hwloc_obj_t prev)
01106 {
01107 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PCI_DEVICE, prev);
01108 }
01109
01113 static __hwloc_inline hwloc_obj_t
01114 hwloc_get_pcidev_by_busid(hwloc_topology_t topology,
01115 unsigned domain, unsigned bus, unsigned dev, unsigned func)
01116 {
01117 hwloc_obj_t obj = NULL;
01118 while ((obj = hwloc_get_next_pcidev(topology, obj)) != NULL) {
01119 if (obj->attr->pcidev.domain == domain
01120 && obj->attr->pcidev.bus == bus
01121 && obj->attr->pcidev.dev == dev
01122 && obj->attr->pcidev.func == func)
01123 return obj;
01124 }
01125 return NULL;
01126 }
01127
01131 static __hwloc_inline hwloc_obj_t
01132 hwloc_get_pcidev_by_busidstring(hwloc_topology_t topology, const char *busid)
01133 {
01134 unsigned domain = 0;
01135 unsigned bus, dev, func;
01136
01137 if (sscanf(busid, "%x:%x.%x", &bus, &dev, &func) != 3
01138 && sscanf(busid, "%x:%x:%x.%x", &domain, &bus, &dev, &func) != 4) {
01139 errno = EINVAL;
01140 return NULL;
01141 }
01142
01143 return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, func);
01144 }
01145
01150 static __hwloc_inline hwloc_obj_t
01151 hwloc_get_next_osdev(hwloc_topology_t topology, hwloc_obj_t prev)
01152 {
01153 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_OS_DEVICE, prev);
01154 }
01155
01160 static __hwloc_inline hwloc_obj_t
01161 hwloc_get_next_bridge(hwloc_topology_t topology, hwloc_obj_t prev)
01162 {
01163 return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_BRIDGE, prev);
01164 }
01165
01166
01167
01168 static __hwloc_inline int
01169 hwloc_bridge_covers_pcibus(hwloc_obj_t bridge,
01170 unsigned domain, unsigned bus)
01171 {
01172 return bridge->type == HWLOC_OBJ_BRIDGE
01173 && bridge->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI
01174 && bridge->attr->bridge.downstream.pci.domain == domain
01175 && bridge->attr->bridge.downstream.pci.secondary_bus <= bus
01176 && bridge->attr->bridge.downstream.pci.subordinate_bus >= bus;
01177 }
01178
01183 #ifdef __cplusplus
01184 }
01185 #endif
01186
01187
01188 #endif