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
00039 static inline int
00040 hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
00041 {
00042 int depth = hwloc_get_type_depth(topology, type);
00043
00044 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
00045 return depth;
00046
00047
00048 for(depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); ; depth--)
00049 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
00050 return depth+1;
00051
00052
00053
00054 }
00055
00062 static inline int
00063 hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
00064 {
00065 int depth = hwloc_get_type_depth(topology, type);
00066
00067 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
00068 return depth;
00069
00070
00071 for(depth = 0; ; depth++)
00072 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) > 0)
00073 return depth-1;
00074
00075
00076
00077 }
00078
00093 static inline hwloc_obj_t
00094 hwloc_get_root_obj (hwloc_topology_t topology)
00095 {
00096 return hwloc_get_obj_by_depth (topology, 0, 0);
00097 }
00098
00100 static inline hwloc_obj_t
00101 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology , unsigned depth, hwloc_obj_t obj)
00102 {
00103 hwloc_obj_t ancestor = obj;
00104 if (obj->depth < depth)
00105 return NULL;
00106 while (ancestor && ancestor->depth > depth)
00107 ancestor = ancestor->parent;
00108 return ancestor;
00109 }
00110
00112 static inline hwloc_obj_t
00113 hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology , hwloc_obj_type_t type, hwloc_obj_t obj)
00114 {
00115 hwloc_obj_t ancestor = obj->parent;
00116 while (ancestor && ancestor->type != type)
00117 ancestor = ancestor->parent;
00118 return ancestor;
00119 }
00120
00125 static inline hwloc_obj_t
00126 hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev)
00127 {
00128 if (!prev)
00129 return hwloc_get_obj_by_depth (topology, depth, 0);
00130 if (prev->depth != depth)
00131 return NULL;
00132 return prev->next_cousin;
00133 }
00134
00141 static inline hwloc_obj_t
00142 hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
00143 hwloc_obj_t prev)
00144 {
00145 int depth = hwloc_get_type_depth(topology, type);
00146 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00147 return NULL;
00148 return hwloc_get_next_obj_by_depth (topology, depth, prev);
00149 }
00150
00159 static inline hwloc_obj_t
00160 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
00161 {
00162 hwloc_obj_t obj = NULL;
00163 while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
00164 if (obj->os_index == os_index)
00165 return obj;
00166 return NULL;
00167 }
00168
00173 static inline hwloc_obj_t
00174 hwloc_get_next_child (hwloc_topology_t topology , hwloc_obj_t parent, hwloc_obj_t prev)
00175 {
00176 if (!prev)
00177 return parent->first_child;
00178 if (prev->parent != parent)
00179 return NULL;
00180 return prev->next_sibling;
00181 }
00182
00184 static inline hwloc_obj_t
00185 hwloc_get_common_ancestor_obj (hwloc_topology_t topology , hwloc_obj_t obj1, hwloc_obj_t obj2)
00186 {
00187
00188
00189
00190
00191
00192 while (obj1 != obj2) {
00193 while (obj1->depth > obj2->depth)
00194 obj1 = obj1->parent;
00195 while (obj2->depth > obj1->depth)
00196 obj2 = obj2->parent;
00197 if (obj1 != obj2 && obj1->depth == obj2->depth) {
00198 obj1 = obj1->parent;
00199 obj2 = obj2->parent;
00200 }
00201 }
00202 return obj1;
00203 }
00204
00207 static inline int
00208 hwloc_obj_is_in_subtree (hwloc_topology_t topology , hwloc_obj_t obj, hwloc_obj_t subtree_root)
00209 {
00210 return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
00211 }
00212
00229 static inline hwloc_obj_t
00230 hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
00231 {
00232 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00233 if (!hwloc_bitmap_intersects(obj->cpuset, set))
00234 return NULL;
00235 while (!hwloc_bitmap_isincluded(obj->cpuset, set)) {
00236
00237 hwloc_obj_t child = NULL;
00238 while ((child = hwloc_get_next_child(topology, obj, child)) != NULL) {
00239 if (hwloc_bitmap_intersects(child->cpuset, set))
00240 break;
00241 }
00242 if (!child)
00243
00244 return obj;
00245
00246 obj = child;
00247 }
00248
00249 return obj;
00250 }
00251
00256 int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00257 hwloc_obj_t * restrict objs, int max);
00258
00265 static inline hwloc_obj_t
00266 hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00267 unsigned depth, hwloc_obj_t prev)
00268 {
00269 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00270 while (next && !hwloc_bitmap_isincluded(next->cpuset, set))
00271 next = next->next_cousin;
00272 return next;
00273 }
00274
00281 static inline hwloc_obj_t
00282 hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00283 hwloc_obj_type_t type, hwloc_obj_t prev)
00284 {
00285 int depth = hwloc_get_type_depth(topology, type);
00286 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00287 return NULL;
00288 return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
00289 }
00290
00293 static inline hwloc_obj_t
00294 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00295 unsigned depth, unsigned idx)
00296 {
00297 unsigned count = 0;
00298 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00299 while (obj) {
00300 if (hwloc_bitmap_isincluded(obj->cpuset, set)) {
00301 if (count == idx)
00302 return obj;
00303 count++;
00304 }
00305 obj = obj->next_cousin;
00306 }
00307 return NULL;
00308 }
00309
00316 static inline hwloc_obj_t
00317 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00318 hwloc_obj_type_t type, unsigned idx)
00319 {
00320 int depth = hwloc_get_type_depth(topology, type);
00321 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00322 return NULL;
00323 return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
00324 }
00325
00327 static inline unsigned
00328 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00329 unsigned depth)
00330 {
00331 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00332 int count = 0;
00333 while (obj) {
00334 if (hwloc_bitmap_isincluded(obj->cpuset, set))
00335 count++;
00336 obj = obj->next_cousin;
00337 }
00338 return count;
00339 }
00340
00347 static inline int
00348 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00349 hwloc_obj_type_t type)
00350 {
00351 int depth = hwloc_get_type_depth(topology, type);
00352 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
00353 return 0;
00354 if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00355 return -1;
00356 return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
00357 }
00358
00371 static inline hwloc_obj_t
00372 hwloc_get_child_covering_cpuset (hwloc_topology_t topology , hwloc_const_cpuset_t set,
00373 hwloc_obj_t parent)
00374 {
00375 hwloc_obj_t child;
00376
00377 if (hwloc_bitmap_iszero(set))
00378 return NULL;
00379
00380 child = parent->first_child;
00381 while (child) {
00382 if (hwloc_bitmap_isincluded(set, child->cpuset))
00383 return child;
00384 child = child->next_sibling;
00385 }
00386 return NULL;
00387 }
00388
00393 static inline hwloc_obj_t
00394 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00395 {
00396 struct hwloc_obj *current = hwloc_get_root_obj(topology);
00397
00398 if (hwloc_bitmap_iszero(set))
00399 return NULL;
00400
00401 if (!hwloc_bitmap_isincluded(set, current->cpuset))
00402 return NULL;
00403
00404 while (1) {
00405 hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
00406 if (!child)
00407 return current;
00408 current = child;
00409 }
00410 }
00411
00412
00428 static inline hwloc_obj_t
00429 hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00430 unsigned depth, hwloc_obj_t prev)
00431 {
00432 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00433 while (next && !hwloc_bitmap_intersects(set, next->cpuset))
00434 next = next->next_cousin;
00435 return next;
00436 }
00437
00450 static inline hwloc_obj_t
00451 hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00452 hwloc_obj_type_t type, hwloc_obj_t prev)
00453 {
00454 int depth = hwloc_get_type_depth(topology, type);
00455 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00456 return NULL;
00457 return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
00458 }
00459
00472 static inline hwloc_obj_t
00473 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00474 {
00475 hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
00476 while (current) {
00477 if (current->type == HWLOC_OBJ_CACHE)
00478 return current;
00479 current = current->parent;
00480 }
00481 return NULL;
00482 }
00483
00488 static inline hwloc_obj_t
00489 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology , hwloc_obj_t obj)
00490 {
00491 hwloc_obj_t current = obj->parent;
00492 while (current) {
00493 if (!hwloc_bitmap_isequal(current->cpuset, obj->cpuset)
00494 && current->type == HWLOC_OBJ_CACHE)
00495 return current;
00496 current = current->parent;
00497 }
00498 return NULL;
00499 }
00500
00516
00517 unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * restrict objs, unsigned max);
00518
00529 static inline hwloc_obj_t
00530 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
00531 hwloc_obj_type_t type1, unsigned idx1,
00532 hwloc_obj_type_t type2, unsigned idx2)
00533 {
00534 hwloc_obj_t obj;
00535
00536 obj = hwloc_get_obj_by_type (topology, type1, idx1);
00537 if (!obj)
00538 return NULL;
00539
00540 return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
00541 }
00542
00558 static inline hwloc_obj_t
00559 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
00560 {
00561 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00562 int i;
00563
00564 for(i=0; i<nr; i++) {
00565 obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
00566 if (!obj)
00567 return NULL;
00568 }
00569
00570 return obj;
00571 }
00572
00594 static inline void
00595 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *root, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until);
00596 static inline void
00597 hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
00598 {
00599 unsigned i;
00600
00601 if (!root->arity || n == 1 || root->depth >= until) {
00602
00603 for (i=0; i<n; i++)
00604 cpuset[i] = hwloc_bitmap_dup(root->cpuset);
00605 return;
00606 }
00607
00608 hwloc_distributev(topology, root->children, root->arity, cpuset, n, until);
00609 }
00610
00616 static inline void
00617 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
00618 {
00619 unsigned i;
00620 unsigned tot_weight;
00621 hwloc_cpuset_t *cpusetp = cpuset;
00622
00623 tot_weight = 0;
00624 for (i = 0; i < n_roots; i++)
00625 tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);
00626
00627 for (i = 0; i < n_roots; i++) {
00628
00629 unsigned weight = hwloc_bitmap_weight(roots[i]->cpuset);
00630 unsigned chunk = (n * weight + tot_weight-1) / tot_weight;
00631 hwloc_distribute(topology, roots[i], cpusetp, chunk, until);
00632 cpusetp += chunk;
00633 tot_weight -= weight;
00634 n -= chunk;
00635 }
00636 }
00637
00644 static inline void *
00645 hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
00646 {
00647 void *p = hwloc_alloc_membind_nodeset(topology, len, nodeset, policy, flags);
00648 if (p)
00649 return p;
00650 hwloc_set_membind_nodeset(topology, nodeset, policy, flags);
00651 p = hwloc_alloc(topology, len);
00652 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
00653
00654 memset(p, 0, len);
00655 return p;
00656 }
00657
00662 static inline void *
00663 hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t cpuset, hwloc_membind_policy_t policy, int flags)
00664 {
00665 void *p = hwloc_alloc_membind(topology, len, cpuset, policy, flags);
00666 if (p)
00667 return p;
00668 hwloc_set_membind(topology, cpuset, policy, flags);
00669 p = hwloc_alloc(topology, len);
00670 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
00671
00672 memset(p, 0, len);
00673 return p;
00674 }
00675
00692 static inline hwloc_const_cpuset_t
00693 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
00694 {
00695 return hwloc_get_root_obj(topology)->complete_cpuset;
00696 }
00697
00708 static inline hwloc_const_cpuset_t
00709 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
00710 {
00711 return hwloc_get_root_obj(topology)->cpuset;
00712 }
00713
00723 static inline hwloc_const_cpuset_t
00724 hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
00725 {
00726 return hwloc_get_root_obj(topology)->online_cpuset;
00727 }
00728
00738 static inline hwloc_const_cpuset_t
00739 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
00740 {
00741 return hwloc_get_root_obj(topology)->allowed_cpuset;
00742 }
00743
00760 static inline hwloc_const_nodeset_t
00761 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
00762 {
00763 return hwloc_get_root_obj(topology)->complete_nodeset;
00764 }
00765
00776 static inline hwloc_const_nodeset_t
00777 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
00778 {
00779 return hwloc_get_root_obj(topology)->nodeset;
00780 }
00781
00791 static inline hwloc_const_nodeset_t
00792 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
00793 {
00794 return hwloc_get_root_obj(topology)->allowed_nodeset;
00795 }
00796
00827 static inline void
00828 hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
00829 {
00830 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00831 hwloc_obj_t obj;
00832
00833 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
00834 if (hwloc_bitmap_iszero(cpuset))
00835 hwloc_bitmap_zero(nodeset);
00836 else
00837
00838 hwloc_bitmap_fill(nodeset);
00839 return;
00840 }
00841
00842 hwloc_bitmap_zero(nodeset);
00843 obj = NULL;
00844 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
00845 hwloc_bitmap_set(nodeset, obj->os_index);
00846 }
00847
00855 static inline void
00856 hwloc_cpuset_to_nodeset_strict(struct hwloc_topology *topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
00857 {
00858 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00859 hwloc_obj_t obj;
00860 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
00861 return;
00862 hwloc_bitmap_zero(nodeset);
00863 obj = NULL;
00864 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
00865 hwloc_bitmap_set(nodeset, obj->os_index);
00866 }
00867
00876 static inline void
00877 hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
00878 {
00879 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00880 hwloc_obj_t obj;
00881
00882 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) {
00883 if (hwloc_bitmap_iszero(nodeset))
00884 hwloc_bitmap_zero(cpuset);
00885 else
00886
00887 hwloc_bitmap_fill(cpuset);
00888 return;
00889 }
00890
00891 hwloc_bitmap_zero(cpuset);
00892 obj = NULL;
00893 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
00894 if (hwloc_bitmap_isset(nodeset, obj->os_index))
00895 hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
00896 }
00897 }
00898
00906 static inline void
00907 hwloc_cpuset_from_nodeset_strict(struct hwloc_topology *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 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
00912 return;
00913 hwloc_bitmap_zero(cpuset);
00914 obj = NULL;
00915 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL)
00916 if (hwloc_bitmap_isset(nodeset, obj->os_index))
00917 hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
00918 }
00919
00924 #ifdef __cplusplus
00925 }
00926 #endif
00927
00928
00929 #endif