00001
00002
00003
00004
00005
00006
00011 #ifndef HWLOC_HELPER_H
00012 #define HWLOC_HELPER_H
00013
00014 #ifndef HWLOC_H
00015 #error Please include the main hwloc.h instead
00016 #endif
00017
00018 #include <stdlib.h>
00019 #include <errno.h>
00020
00021
00032 static __hwloc_inline int __hwloc_attribute_pure
00033 hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
00034 {
00035 int depth = hwloc_get_type_depth(topology, type);
00036
00037 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
00038 return depth;
00039
00040
00041 for(depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); ; depth--)
00042 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
00043 return depth+1;
00044
00045
00046
00047 }
00048
00055 static __hwloc_inline int __hwloc_attribute_pure
00056 hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
00057 {
00058 int depth = hwloc_get_type_depth(topology, type);
00059
00060 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
00061 return depth;
00062
00063
00064 for(depth = 0; ; depth++)
00065 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) > 0)
00066 return depth-1;
00067
00068
00069
00070 }
00071
00086 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00087 hwloc_get_root_obj (hwloc_topology_t topology)
00088 {
00089 return hwloc_get_obj_by_depth (topology, 0, 0);
00090 }
00091
00093 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00094 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj)
00095 {
00096 hwloc_obj_t ancestor = obj;
00097 if (obj->depth < depth)
00098 return NULL;
00099 while (ancestor && ancestor->depth > depth)
00100 ancestor = ancestor->parent;
00101 return ancestor;
00102 }
00103
00105 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00106 hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj)
00107 {
00108 hwloc_obj_t ancestor = obj->parent;
00109 while (ancestor && ancestor->type != type)
00110 ancestor = ancestor->parent;
00111 return ancestor;
00112 }
00113
00118 static __hwloc_inline hwloc_obj_t
00119 hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev)
00120 {
00121 if (!prev)
00122 return hwloc_get_obj_by_depth (topology, depth, 0);
00123 if (prev->depth != depth)
00124 return NULL;
00125 return prev->next_cousin;
00126 }
00127
00134 static __hwloc_inline hwloc_obj_t
00135 hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
00136 hwloc_obj_t prev)
00137 {
00138 int depth = hwloc_get_type_depth(topology, type);
00139 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00140 return NULL;
00141 return hwloc_get_next_obj_by_depth (topology, depth, prev);
00142 }
00143
00152 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00153 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
00154 {
00155 hwloc_obj_t obj = NULL;
00156 while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
00157 if (obj->os_index == os_index)
00158 return obj;
00159 return NULL;
00160 }
00161
00166 static __hwloc_inline hwloc_obj_t
00167 hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev)
00168 {
00169 if (!prev)
00170 return parent->first_child;
00171 if (prev->parent != parent)
00172 return NULL;
00173 return prev->next_sibling;
00174 }
00175
00177 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00178 hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2)
00179 {
00180 while (obj1->depth > obj2->depth)
00181 obj1 = obj1->parent;
00182 while (obj2->depth > obj1->depth)
00183 obj2 = obj2->parent;
00184 while (obj1 != obj2) {
00185 obj1 = obj1->parent;
00186 obj2 = obj2->parent;
00187 }
00188 return obj1;
00189 }
00190
00193 static __hwloc_inline int __hwloc_attribute_pure
00194 hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root)
00195 {
00196 return hwloc_cpuset_isincluded(obj->cpuset, subtree_root->cpuset);
00197 }
00198
00215 static __hwloc_inline hwloc_obj_t
00216 hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
00217 {
00218 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00219 if (!hwloc_cpuset_intersects(obj->cpuset, set))
00220 return NULL;
00221 while (!hwloc_cpuset_isincluded(obj->cpuset, set)) {
00222
00223 hwloc_obj_t child = NULL;
00224 while ((child = hwloc_get_next_child(topology, obj, child)) != NULL) {
00225 if (hwloc_cpuset_intersects(child->cpuset, set))
00226 break;
00227 }
00228 if (!child)
00229
00230 return obj;
00231
00232 obj = child;
00233 }
00234
00235 return obj;
00236 }
00237
00242 HWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00243 hwloc_obj_t * __hwloc_restrict objs, int max);
00244
00251 static __hwloc_inline hwloc_obj_t
00252 hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00253 unsigned depth, hwloc_obj_t prev)
00254 {
00255 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00256 while (next && !hwloc_cpuset_isincluded(next->cpuset, set))
00257 next = next->next_cousin;
00258 return next;
00259 }
00260
00267 static __hwloc_inline hwloc_obj_t
00268 hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00269 hwloc_obj_type_t type, hwloc_obj_t prev)
00270 {
00271 int depth = hwloc_get_type_depth(topology, type);
00272 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00273 return NULL;
00274 return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
00275 }
00276
00279 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00280 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00281 unsigned depth, unsigned idx)
00282 {
00283 unsigned count = 0;
00284 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00285 while (obj) {
00286 if (hwloc_cpuset_isincluded(obj->cpuset, set)) {
00287 if (count == idx)
00288 return obj;
00289 count++;
00290 }
00291 obj = obj->next_cousin;
00292 }
00293 return NULL;
00294 }
00295
00302 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00303 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00304 hwloc_obj_type_t type, unsigned idx)
00305 {
00306 int depth = hwloc_get_type_depth(topology, type);
00307 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00308 return NULL;
00309 return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
00310 }
00311
00313 static __hwloc_inline unsigned __hwloc_attribute_pure
00314 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00315 unsigned depth)
00316 {
00317 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00318 int count = 0;
00319 while (obj) {
00320 if (hwloc_cpuset_isincluded(obj->cpuset, set))
00321 count++;
00322 obj = obj->next_cousin;
00323 }
00324 return count;
00325 }
00326
00333 static __hwloc_inline int __hwloc_attribute_pure
00334 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00335 hwloc_obj_type_t type)
00336 {
00337 int depth = hwloc_get_type_depth(topology, type);
00338 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
00339 return 0;
00340 if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00341 return -1;
00342 return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
00343 }
00344
00357 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00358 hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
00359 hwloc_obj_t parent)
00360 {
00361 hwloc_obj_t child;
00362
00363 if (hwloc_cpuset_iszero(set))
00364 return NULL;
00365
00366 child = parent->first_child;
00367 while (child) {
00368 if (hwloc_cpuset_isincluded(set, child->cpuset))
00369 return child;
00370 child = child->next_sibling;
00371 }
00372 return NULL;
00373 }
00374
00379 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00380 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00381 {
00382 struct hwloc_obj *current = hwloc_get_root_obj(topology);
00383
00384 if (hwloc_cpuset_iszero(set))
00385 return NULL;
00386
00387 if (!hwloc_cpuset_isincluded(set, current->cpuset))
00388 return NULL;
00389
00390 while (1) {
00391 hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
00392 if (!child)
00393 return current;
00394 current = child;
00395 }
00396 }
00397
00398
00414 static __hwloc_inline hwloc_obj_t
00415 hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00416 unsigned depth, hwloc_obj_t prev)
00417 {
00418 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00419 while (next && !hwloc_cpuset_intersects(set, next->cpuset))
00420 next = next->next_cousin;
00421 return next;
00422 }
00423
00436 static __hwloc_inline hwloc_obj_t
00437 hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00438 hwloc_obj_type_t type, hwloc_obj_t prev)
00439 {
00440 int depth = hwloc_get_type_depth(topology, type);
00441 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00442 return NULL;
00443 return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
00444 }
00445
00458 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00459 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00460 {
00461 hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
00462 while (current) {
00463 if (current->type == HWLOC_OBJ_CACHE)
00464 return current;
00465 current = current->parent;
00466 }
00467 return NULL;
00468 }
00469
00474 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00475 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj)
00476 {
00477 hwloc_obj_t current = obj->parent;
00478 while (current) {
00479 if (!hwloc_cpuset_isequal(current->cpuset, obj->cpuset)
00480 && current->type == HWLOC_OBJ_CACHE)
00481 return current;
00482 current = current->parent;
00483 }
00484 return NULL;
00485 }
00486
00502
00503 HWLOC_DECLSPEC unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * __hwloc_restrict objs, unsigned max);
00504
00515 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00516 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
00517 hwloc_obj_type_t type1, unsigned idx1,
00518 hwloc_obj_type_t type2, unsigned idx2)
00519 {
00520 hwloc_obj_t obj;
00521
00522 obj = hwloc_get_obj_by_type (topology, type1, idx1);
00523 if (!obj)
00524 return NULL;
00525
00526 return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
00527 }
00528
00544 static __hwloc_inline hwloc_obj_t __hwloc_attribute_pure
00545 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
00546 {
00547 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00548 int i;
00549
00550 for(i=0; i<nr; i++) {
00551 obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
00552 if (!obj)
00553 return NULL;
00554 }
00555
00556 return obj;
00557 }
00558
00579 static __hwloc_inline void
00580 hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *cpuset, unsigned n)
00581 {
00582 unsigned i;
00583 unsigned u;
00584 unsigned chunk_size, complete_chunks;
00585 hwloc_cpuset_t *cpusetp;
00586
00587 if (!root->arity || n == 1) {
00588
00589 for (i=0; i<n; i++)
00590 cpuset[i] = hwloc_cpuset_dup(root->cpuset);
00591 return;
00592 }
00593
00594
00595 chunk_size = (n + root->arity - 1) / root->arity;
00596 complete_chunks = n % root->arity;
00597 if (!complete_chunks)
00598 complete_chunks = root->arity;
00599
00600
00601 for (cpusetp = cpuset, i = 0;
00602 i < complete_chunks;
00603 i ++, cpusetp += chunk_size)
00604 hwloc_distribute(topology, root->children[i], cpusetp, chunk_size);
00605
00606
00607 for (u = i;
00608 u < root->arity;
00609 u++, cpusetp += chunk_size-1)
00610 hwloc_distribute(topology, root->children[u], cpusetp, chunk_size-1);
00611 }
00612
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
00628 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
00629 {
00630 return hwloc_get_root_obj(topology)->complete_cpuset;
00631 }
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
00644 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
00645 {
00646 return hwloc_get_root_obj(topology)->cpuset;
00647 }
00648
00658 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
00659 hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
00660 {
00661 return hwloc_get_root_obj(topology)->online_cpuset;
00662 }
00663
00673 static __hwloc_inline hwloc_const_cpuset_t __hwloc_attribute_pure
00674 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
00675 {
00676 return hwloc_get_root_obj(topology)->allowed_cpuset;
00677 }
00678
00679
00682 #endif