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
00022 #ifdef __cplusplus
00023 extern "C" {
00024 #endif
00025
00026
00037 static inline int
00038 hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
00039 {
00040 int depth = hwloc_get_type_depth(topology, type);
00041
00042 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
00043 return depth;
00044
00045
00046 for(depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); ; depth--)
00047 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
00048 return depth+1;
00049
00050
00051
00052 }
00053
00060 static inline int
00061 hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
00062 {
00063 int depth = hwloc_get_type_depth(topology, type);
00064
00065 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
00066 return depth;
00067
00068
00069 for(depth = 0; ; depth++)
00070 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) > 0)
00071 return depth-1;
00072
00073
00074
00075 }
00076
00091 static inline hwloc_obj_t
00092 hwloc_get_root_obj (hwloc_topology_t topology)
00093 {
00094 return hwloc_get_obj_by_depth (topology, 0, 0);
00095 }
00096
00098 static inline hwloc_obj_t
00099 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology , unsigned depth, hwloc_obj_t obj)
00100 {
00101 hwloc_obj_t ancestor = obj;
00102 if (obj->depth < depth)
00103 return NULL;
00104 while (ancestor && ancestor->depth > depth)
00105 ancestor = ancestor->parent;
00106 return ancestor;
00107 }
00108
00110 static inline hwloc_obj_t
00111 hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology , hwloc_obj_type_t type, hwloc_obj_t obj)
00112 {
00113 hwloc_obj_t ancestor = obj->parent;
00114 while (ancestor && ancestor->type != type)
00115 ancestor = ancestor->parent;
00116 return ancestor;
00117 }
00118
00123 static inline hwloc_obj_t
00124 hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev)
00125 {
00126 if (!prev)
00127 return hwloc_get_obj_by_depth (topology, depth, 0);
00128 if (prev->depth != depth)
00129 return NULL;
00130 return prev->next_cousin;
00131 }
00132
00139 static inline hwloc_obj_t
00140 hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
00141 hwloc_obj_t prev)
00142 {
00143 int depth = hwloc_get_type_depth(topology, type);
00144 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00145 return NULL;
00146 return hwloc_get_next_obj_by_depth (topology, depth, prev);
00147 }
00148
00157 static inline hwloc_obj_t
00158 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
00159 {
00160 hwloc_obj_t obj = NULL;
00161 while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
00162 if (obj->os_index == os_index)
00163 return obj;
00164 return NULL;
00165 }
00166
00171 static inline hwloc_obj_t
00172 hwloc_get_next_child (hwloc_topology_t topology , hwloc_obj_t parent, hwloc_obj_t prev)
00173 {
00174 if (!prev)
00175 return parent->first_child;
00176 if (prev->parent != parent)
00177 return NULL;
00178 return prev->next_sibling;
00179 }
00180
00182 static inline hwloc_obj_t
00183 hwloc_get_common_ancestor_obj (hwloc_topology_t topology , hwloc_obj_t obj1, hwloc_obj_t obj2)
00184 {
00185
00186
00187
00188
00189
00190 while (obj1 != obj2) {
00191 while (obj1->depth > obj2->depth)
00192 obj1 = obj1->parent;
00193 while (obj2->depth > obj1->depth)
00194 obj2 = obj2->parent;
00195 if (obj1 != obj2 && obj1->depth == obj2->depth) {
00196 obj1 = obj1->parent;
00197 obj2 = obj2->parent;
00198 }
00199 }
00200 return obj1;
00201 }
00202
00205 static inline int
00206 hwloc_obj_is_in_subtree (hwloc_topology_t topology , hwloc_obj_t obj, hwloc_obj_t subtree_root)
00207 {
00208 return hwloc_cpuset_isincluded(obj->cpuset, subtree_root->cpuset);
00209 }
00210
00227 static inline hwloc_obj_t
00228 hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
00229 {
00230 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00231 if (!hwloc_cpuset_intersects(obj->cpuset, set))
00232 return NULL;
00233 while (!hwloc_cpuset_isincluded(obj->cpuset, set)) {
00234
00235 hwloc_obj_t child = NULL;
00236 while ((child = hwloc_get_next_child(topology, obj, child)) != NULL) {
00237 if (hwloc_cpuset_intersects(child->cpuset, set))
00238 break;
00239 }
00240 if (!child)
00241
00242 return obj;
00243
00244 obj = child;
00245 }
00246
00247 return obj;
00248 }
00249
00254 int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00255 hwloc_obj_t * restrict objs, int max);
00256
00263 static inline hwloc_obj_t
00264 hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00265 unsigned depth, hwloc_obj_t prev)
00266 {
00267 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00268 while (next && !hwloc_cpuset_isincluded(next->cpuset, set))
00269 next = next->next_cousin;
00270 return next;
00271 }
00272
00279 static inline hwloc_obj_t
00280 hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00281 hwloc_obj_type_t type, hwloc_obj_t prev)
00282 {
00283 int depth = hwloc_get_type_depth(topology, type);
00284 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00285 return NULL;
00286 return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
00287 }
00288
00291 static inline hwloc_obj_t
00292 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00293 unsigned depth, unsigned idx)
00294 {
00295 unsigned count = 0;
00296 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00297 while (obj) {
00298 if (hwloc_cpuset_isincluded(obj->cpuset, set)) {
00299 if (count == idx)
00300 return obj;
00301 count++;
00302 }
00303 obj = obj->next_cousin;
00304 }
00305 return NULL;
00306 }
00307
00314 static inline hwloc_obj_t
00315 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00316 hwloc_obj_type_t type, unsigned idx)
00317 {
00318 int depth = hwloc_get_type_depth(topology, type);
00319 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00320 return NULL;
00321 return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
00322 }
00323
00325 static inline unsigned
00326 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00327 unsigned depth)
00328 {
00329 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00330 int count = 0;
00331 while (obj) {
00332 if (hwloc_cpuset_isincluded(obj->cpuset, set))
00333 count++;
00334 obj = obj->next_cousin;
00335 }
00336 return count;
00337 }
00338
00345 static inline int
00346 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
00347 hwloc_obj_type_t type)
00348 {
00349 int depth = hwloc_get_type_depth(topology, type);
00350 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
00351 return 0;
00352 if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00353 return -1;
00354 return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
00355 }
00356
00369 static inline hwloc_obj_t
00370 hwloc_get_child_covering_cpuset (hwloc_topology_t topology , hwloc_const_cpuset_t set,
00371 hwloc_obj_t parent)
00372 {
00373 hwloc_obj_t child;
00374
00375 if (hwloc_cpuset_iszero(set))
00376 return NULL;
00377
00378 child = parent->first_child;
00379 while (child) {
00380 if (hwloc_cpuset_isincluded(set, child->cpuset))
00381 return child;
00382 child = child->next_sibling;
00383 }
00384 return NULL;
00385 }
00386
00391 static inline hwloc_obj_t
00392 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00393 {
00394 struct hwloc_obj *current = hwloc_get_root_obj(topology);
00395
00396 if (hwloc_cpuset_iszero(set))
00397 return NULL;
00398
00399 if (!hwloc_cpuset_isincluded(set, current->cpuset))
00400 return NULL;
00401
00402 while (1) {
00403 hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
00404 if (!child)
00405 return current;
00406 current = child;
00407 }
00408 }
00409
00410
00426 static inline hwloc_obj_t
00427 hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00428 unsigned depth, hwloc_obj_t prev)
00429 {
00430 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00431 while (next && !hwloc_cpuset_intersects(set, next->cpuset))
00432 next = next->next_cousin;
00433 return next;
00434 }
00435
00448 static inline hwloc_obj_t
00449 hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
00450 hwloc_obj_type_t type, hwloc_obj_t prev)
00451 {
00452 int depth = hwloc_get_type_depth(topology, type);
00453 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00454 return NULL;
00455 return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
00456 }
00457
00470 static inline hwloc_obj_t
00471 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
00472 {
00473 hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
00474 while (current) {
00475 if (current->type == HWLOC_OBJ_CACHE)
00476 return current;
00477 current = current->parent;
00478 }
00479 return NULL;
00480 }
00481
00486 static inline hwloc_obj_t
00487 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology , hwloc_obj_t obj)
00488 {
00489 hwloc_obj_t current = obj->parent;
00490 while (current) {
00491 if (!hwloc_cpuset_isequal(current->cpuset, obj->cpuset)
00492 && current->type == HWLOC_OBJ_CACHE)
00493 return current;
00494 current = current->parent;
00495 }
00496 return NULL;
00497 }
00498
00514
00515 unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * restrict objs, unsigned max);
00516
00527 static inline hwloc_obj_t
00528 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
00529 hwloc_obj_type_t type1, unsigned idx1,
00530 hwloc_obj_type_t type2, unsigned idx2)
00531 {
00532 hwloc_obj_t obj;
00533
00534 obj = hwloc_get_obj_by_type (topology, type1, idx1);
00535 if (!obj)
00536 return NULL;
00537
00538 return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
00539 }
00540
00556 static inline hwloc_obj_t
00557 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
00558 {
00559 hwloc_obj_t obj = hwloc_get_root_obj(topology);
00560 int i;
00561
00562 for(i=0; i<nr; i++) {
00563 obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
00564 if (!obj)
00565 return NULL;
00566 }
00567
00568 return obj;
00569 }
00570
00591 static inline void
00592 hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *cpuset, unsigned n)
00593 {
00594 unsigned i;
00595 unsigned u;
00596 unsigned chunk_size, complete_chunks;
00597 hwloc_cpuset_t *cpusetp;
00598
00599 if (!root->arity || n == 1) {
00600
00601 for (i=0; i<n; i++)
00602 cpuset[i] = hwloc_cpuset_dup(root->cpuset);
00603 return;
00604 }
00605
00606
00607 chunk_size = (n + root->arity - 1) / root->arity;
00608 complete_chunks = n % root->arity;
00609 if (!complete_chunks)
00610 complete_chunks = root->arity;
00611
00612
00613 for (cpusetp = cpuset, i = 0;
00614 i < complete_chunks;
00615 i ++, cpusetp += chunk_size)
00616 hwloc_distribute(topology, root->children[i], cpusetp, chunk_size);
00617
00618
00619 for (u = i;
00620 u < root->arity;
00621 u++, cpusetp += chunk_size-1)
00622 hwloc_distribute(topology, root->children[u], cpusetp, chunk_size-1);
00623 }
00624
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 static inline hwloc_const_cpuset_t
00640 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
00641 {
00642 return hwloc_get_root_obj(topology)->complete_cpuset;
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 static inline hwloc_const_cpuset_t
00656 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
00657 {
00658 return hwloc_get_root_obj(topology)->cpuset;
00659 }
00660
00670 static inline hwloc_const_cpuset_t
00671 hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
00672 {
00673 return hwloc_get_root_obj(topology)->online_cpuset;
00674 }
00675
00685 static inline hwloc_const_cpuset_t
00686 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
00687 {
00688 return hwloc_get_root_obj(topology)->allowed_cpuset;
00689 }
00690
00691
00695 #ifdef __cplusplus
00696 }
00697 #endif
00698
00699
00700 #endif