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
00209 static inline int
00210 hwloc_obj_is_in_subtree (hwloc_topology_t topology , hwloc_obj_t obj, hwloc_obj_t subtree_root)
00211 {
00212 return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
00213 }
00214
00231 static inline hwloc_obj_t
00232 hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
00233 {
00234 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00235 if (!hwloc_bitmap_intersects(obj->cpuset, set))
00236 return NULL;
00237 while (!hwloc_bitmap_isincluded(obj->cpuset, set)) {
00238
00239 hwloc_obj_t child = NULL;
00240 while ((child = hwloc_get_next_child(topology, obj, child)) != NULL) {
00241 if (hwloc_bitmap_intersects(child->cpuset, set))
00242 break;
00243 }
00244 if (!child)
00245
00246 return obj;
00247
00248 obj = child;
00249 }
00250
00251 return obj;
00252 }
00253
00258 int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00259 hwloc_obj_t * restrict objs, int max);
00260
00267 static inline hwloc_obj_t
00268 hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00269 unsigned depth, hwloc_obj_t prev)
00270 {
00271 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00272 while (next && !hwloc_bitmap_isincluded(next->cpuset, set))
00273 next = next->next_cousin;
00274 return next;
00275 }
00276
00283 static inline hwloc_obj_t
00284 hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00285 hwloc_obj_type_t type, hwloc_obj_t prev)
00286 {
00287 int depth = hwloc_get_type_depth(topology, type);
00288 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00289 return NULL;
00290 return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
00291 }
00292
00295 static inline hwloc_obj_t
00296 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00297 unsigned depth, unsigned idx)
00298 {
00299 unsigned count = 0;
00300 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00301 while (obj) {
00302 if (hwloc_bitmap_isincluded(obj->cpuset, set)) {
00303 if (count == idx)
00304 return obj;
00305 count++;
00306 }
00307 obj = obj->next_cousin;
00308 }
00309 return NULL;
00310 }
00311
00318 static inline hwloc_obj_t
00319 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00320 hwloc_obj_type_t type, unsigned idx)
00321 {
00322 int depth = hwloc_get_type_depth(topology, type);
00323 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00324 return NULL;
00325 return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
00326 }
00327
00329 static inline unsigned
00330 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00331 unsigned depth)
00332 {
00333 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00334 int count = 0;
00335 while (obj) {
00336 if (hwloc_bitmap_isincluded(obj->cpuset, set))
00337 count++;
00338 obj = obj->next_cousin;
00339 }
00340 return count;
00341 }
00342
00349 static inline int
00350 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00351 hwloc_obj_type_t type)
00352 {
00353 int depth = hwloc_get_type_depth(topology, type);
00354 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
00355 return 0;
00356 if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00357 return -1;
00358 return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
00359 }
00360
00373 static inline hwloc_obj_t
00374 hwloc_get_child_covering_cpuset (hwloc_topology_t topology , hwloc_const_cpuset_t set,
00375 hwloc_obj_t parent)
00376 {
00377 hwloc_obj_t child;
00378
00379 if (hwloc_bitmap_iszero(set))
00380 return NULL;
00381
00382 child = parent->first_child;
00383 while (child) {
00384 if (hwloc_bitmap_isincluded(set, child->cpuset))
00385 return child;
00386 child = child->next_sibling;
00387 }
00388 return NULL;
00389 }
00390
00395 static inline hwloc_obj_t
00396 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00397 {
00398 struct hwloc_obj *current = hwloc_get_root_obj(topology);
00399
00400 if (hwloc_bitmap_iszero(set))
00401 return NULL;
00402
00403 if (!hwloc_bitmap_isincluded(set, current->cpuset))
00404 return NULL;
00405
00406 while (1) {
00407 hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
00408 if (!child)
00409 return current;
00410 current = child;
00411 }
00412 }
00413
00414
00430 static inline hwloc_obj_t
00431 hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00432 unsigned depth, hwloc_obj_t prev)
00433 {
00434 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00435 while (next && !hwloc_bitmap_intersects(set, next->cpuset))
00436 next = next->next_cousin;
00437 return next;
00438 }
00439
00452 static inline hwloc_obj_t
00453 hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00454 hwloc_obj_type_t type, hwloc_obj_t prev)
00455 {
00456 int depth = hwloc_get_type_depth(topology, type);
00457 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00458 return NULL;
00459 return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
00460 }
00461
00474 static inline hwloc_obj_t
00475 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00476 {
00477 hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
00478 while (current) {
00479 if (current->type == HWLOC_OBJ_CACHE)
00480 return current;
00481 current = current->parent;
00482 }
00483 return NULL;
00484 }
00485
00490 static inline hwloc_obj_t
00491 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology , hwloc_obj_t obj)
00492 {
00493 hwloc_obj_t current = obj->parent;
00494 while (current) {
00495 if (!hwloc_bitmap_isequal(current->cpuset, obj->cpuset)
00496 && current->type == HWLOC_OBJ_CACHE)
00497 return current;
00498 current = current->parent;
00499 }
00500 return NULL;
00501 }
00502
00518
00519 unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * restrict objs, unsigned max);
00520
00531 static inline hwloc_obj_t
00532 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
00533 hwloc_obj_type_t type1, unsigned idx1,
00534 hwloc_obj_type_t type2, unsigned idx2)
00535 {
00536 hwloc_obj_t obj;
00537
00538 obj = hwloc_get_obj_by_type (topology, type1, idx1);
00539 if (!obj)
00540 return NULL;
00541
00542 return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
00543 }
00544
00560 static inline hwloc_obj_t
00561 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
00562 {
00563 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00564 int i;
00565
00566 for(i=0; i<nr; i++) {
00567 obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
00568 if (!obj)
00569 return NULL;
00570 }
00571
00572 return obj;
00573 }
00574
00596 static inline void
00597 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *root, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until);
00598 static inline void
00599 hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
00600 {
00601 unsigned i;
00602
00603 if (!root->arity || n == 1 || root->depth >= until) {
00604
00605 for (i=0; i<n; i++)
00606 cpuset[i] = hwloc_bitmap_dup(root->cpuset);
00607 return;
00608 }
00609
00610 hwloc_distributev(topology, root->children, root->arity, cpuset, n, until);
00611 }
00612
00618 static inline void
00619 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
00620 {
00621 unsigned i;
00622 unsigned tot_weight;
00623 hwloc_cpuset_t *cpusetp = cpuset;
00624
00625 tot_weight = 0;
00626 for (i = 0; i < n_roots; i++)
00627 tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);
00628
00629 for (i = 0; i < n_roots; i++) {
00630
00631 unsigned weight = hwloc_bitmap_weight(roots[i]->cpuset);
00632 unsigned chunk = (n * weight + tot_weight-1) / tot_weight;
00633 hwloc_distribute(topology, roots[i], cpusetp, chunk, until);
00634 cpusetp += chunk;
00635 tot_weight -= weight;
00636 n -= chunk;
00637 }
00638 }
00639
00646 static inline void *
00647 hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
00648 {
00649 void *p = hwloc_alloc_membind_nodeset(topology, len, nodeset, policy, flags);
00650 if (p)
00651 return p;
00652 hwloc_set_membind_nodeset(topology, nodeset, policy, flags);
00653 p = hwloc_alloc(topology, len);
00654 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
00655
00656 memset(p, 0, len);
00657 return p;
00658 }
00659
00664 static inline void *
00665 hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t cpuset, hwloc_membind_policy_t policy, int flags)
00666 {
00667 void *p = hwloc_alloc_membind(topology, len, cpuset, policy, flags);
00668 if (p)
00669 return p;
00670 hwloc_set_membind(topology, cpuset, policy, flags);
00671 p = hwloc_alloc(topology, len);
00672 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
00673
00674 memset(p, 0, len);
00675 return p;
00676 }
00677
00694 static inline hwloc_const_cpuset_t
00695 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
00696 {
00697 return hwloc_get_root_obj(topology)->complete_cpuset;
00698 }
00699
00710 static inline hwloc_const_cpuset_t
00711 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
00712 {
00713 return hwloc_get_root_obj(topology)->cpuset;
00714 }
00715
00725 static inline hwloc_const_cpuset_t
00726 hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
00727 {
00728 return hwloc_get_root_obj(topology)->online_cpuset;
00729 }
00730
00740 static inline hwloc_const_cpuset_t
00741 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
00742 {
00743 return hwloc_get_root_obj(topology)->allowed_cpuset;
00744 }
00745
00762 static inline hwloc_const_nodeset_t
00763 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
00764 {
00765 return hwloc_get_root_obj(topology)->complete_nodeset;
00766 }
00767
00778 static inline hwloc_const_nodeset_t
00779 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
00780 {
00781 return hwloc_get_root_obj(topology)->nodeset;
00782 }
00783
00793 static inline hwloc_const_nodeset_t
00794 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
00795 {
00796 return hwloc_get_root_obj(topology)->allowed_nodeset;
00797 }
00798
00829 static inline void
00830 hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
00831 {
00832 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00833 hwloc_obj_t obj;
00834
00835 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
00836 if (hwloc_bitmap_iszero(cpuset))
00837 hwloc_bitmap_zero(nodeset);
00838 else
00839
00840 hwloc_bitmap_fill(nodeset);
00841 return;
00842 }
00843
00844 hwloc_bitmap_zero(nodeset);
00845 obj = NULL;
00846 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
00847 hwloc_bitmap_set(nodeset, obj->os_index);
00848 }
00849
00857 static inline void
00858 hwloc_cpuset_to_nodeset_strict(struct hwloc_topology *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 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
00863 return;
00864 hwloc_bitmap_zero(nodeset);
00865 obj = NULL;
00866 while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
00867 hwloc_bitmap_set(nodeset, obj->os_index);
00868 }
00869
00878 static inline void
00879 hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
00880 {
00881 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00882 hwloc_obj_t obj;
00883
00884 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) {
00885 if (hwloc_bitmap_iszero(nodeset))
00886 hwloc_bitmap_zero(cpuset);
00887 else
00888
00889 hwloc_bitmap_fill(cpuset);
00890 return;
00891 }
00892
00893 hwloc_bitmap_zero(cpuset);
00894 obj = NULL;
00895 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
00896 if (hwloc_bitmap_isset(nodeset, obj->os_index))
00897 hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
00898 }
00899 }
00900
00908 static inline void
00909 hwloc_cpuset_from_nodeset_strict(struct hwloc_topology *topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
00910 {
00911 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00912 hwloc_obj_t obj;
00913 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
00914 return;
00915 hwloc_bitmap_zero(cpuset);
00916 obj = NULL;
00917 while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL)
00918 if (hwloc_bitmap_isset(nodeset, obj->os_index))
00919 hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
00920 }
00921
00926 #ifdef __cplusplus
00927 }
00928 #endif
00929
00930
00931 #endif