Hardware Locality (hwloc) 1.4.2

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List

helper.h

    00001 /*
    00002  * Copyright © 2009 CNRS
    00003  * Copyright © 2009-2011 inria.  All rights reserved.
    00004  * Copyright © 2009-2012 Université Bordeaux 1
    00005  * Copyright © 2009-2010 Cisco Systems, Inc.  All rights reserved.
    00006  * See COPYING in top-level directory.
    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
    00047 static inline int
    00048 hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type) ;
    00049 static inline int
    00050 hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
    00051 {
    00052   int depth = hwloc_get_type_depth(topology, type);
    00053
    00054   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
    00055     return depth;
    00056
    00057   /* find the highest existing level with type order >= */
    00058   for(depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); ; depth--)
    00059     if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
    00060       return depth+1;
    00061
    00062   /* Shouldn't ever happen, as there is always a SYSTEM level with lower order and known depth.  */
    00063   /* abort(); */
    00064 }
    00065
    00075 static inline int
    00076 hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type) ;
    00077 static inline int
    00078 hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
    00079 {
    00080   int depth = hwloc_get_type_depth(topology, type);
    00081
    00082   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
    00083     return depth;
    00084
    00085   /* find the lowest existing level with type order <= */
    00086   for(depth = 0; ; depth++)
    00087     if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) > 0)
    00088       return depth-1;
    00089
    00090   /* Shouldn't ever happen, as there is always a PU level with higher order and known depth.  */
    00091   /* abort(); */
    00092 }
    00093
    00113 static inline hwloc_obj_t
    00114 hwloc_get_root_obj (hwloc_topology_t topology) ;
    00115 static inline hwloc_obj_t
    00116 hwloc_get_root_obj (hwloc_topology_t topology)
    00117 {
    00118   return hwloc_get_obj_by_depth (topology, 0, 0);
    00119 }
    00120
    00122 static inline hwloc_obj_t
    00123 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology , unsigned depth, hwloc_obj_t obj) ;
    00124 static inline hwloc_obj_t
    00125 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology , unsigned depth, hwloc_obj_t obj)
    00126 {
    00127   hwloc_obj_t ancestor = obj;
    00128   if (obj->depth < depth)
    00129     return NULL;
    00130   while (ancestor && ancestor->depth > depth)
    00131     ancestor = ancestor->parent;
    00132   return ancestor;
    00133 }
    00134
    00136 static inline hwloc_obj_t
    00137 hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology , hwloc_obj_type_t type, hwloc_obj_t obj) ;
    00138 static inline hwloc_obj_t
    00139 hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology , hwloc_obj_type_t type, hwloc_obj_t obj)
    00140 {
    00141   hwloc_obj_t ancestor = obj->parent;
    00142   while (ancestor && ancestor->type != type)
    00143     ancestor = ancestor->parent;
    00144   return ancestor;
    00145 }
    00146
    00151 static inline hwloc_obj_t
    00152 hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev)
    00153 {
    00154   if (!prev)
    00155     return hwloc_get_obj_by_depth (topology, depth, 0);
    00156   if (prev->depth != depth)
    00157     return NULL;
    00158   return prev->next_cousin;
    00159 }
    00160
    00167 static inline hwloc_obj_t
    00168 hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
    00169                    hwloc_obj_t prev)
    00170 {
    00171   int depth = hwloc_get_type_depth(topology, type);
    00172   if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
    00173     return NULL;
    00174   return hwloc_get_next_obj_by_depth (topology, depth, prev);
    00175 }
    00176
    00185 static inline hwloc_obj_t
    00186 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) ;
    00187 static inline hwloc_obj_t
    00188 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
    00189 {
    00190   hwloc_obj_t obj = NULL;
    00191   while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
    00192     if (obj->os_index == os_index)
    00193       return obj;
    00194   return NULL;
    00195 }
    00196
    00201 static inline hwloc_obj_t
    00202 hwloc_get_next_child (hwloc_topology_t topology , hwloc_obj_t parent, hwloc_obj_t prev)
    00203 {
    00204   if (!prev)
    00205     return parent->first_child;
    00206   if (prev->parent != parent)
    00207     return NULL;
    00208   return prev->next_sibling;
    00209 }
    00210
    00212 static inline hwloc_obj_t
    00213 hwloc_get_common_ancestor_obj (hwloc_topology_t topology , hwloc_obj_t obj1, hwloc_obj_t obj2) ;
    00214 static inline hwloc_obj_t
    00215 hwloc_get_common_ancestor_obj (hwloc_topology_t topology , hwloc_obj_t obj1, hwloc_obj_t obj2)
    00216 {
    00217   /* the loop isn't so easy since intermediate ancestors may have
    00218    * different depth, causing us to alternate between using obj1->parent
    00219    * and obj2->parent. Also, even if at some point we find ancestors of
    00220    * of the same depth, their ancestors may have different depth again.
    00221    */
    00222   while (obj1 != obj2) {
    00223     while (obj1->depth > obj2->depth)
    00224       obj1 = obj1->parent;
    00225     while (obj2->depth > obj1->depth)
    00226       obj2 = obj2->parent;
    00227     if (obj1 != obj2 && obj1->depth == obj2->depth) {
    00228       obj1 = obj1->parent;
    00229       obj2 = obj2->parent;
    00230     }
    00231   }
    00232   return obj1;
    00233 }
    00234
    00239 static inline int
    00240 hwloc_obj_is_in_subtree (hwloc_topology_t topology , hwloc_obj_t obj, hwloc_obj_t subtree_root) ;
    00241 static inline int
    00242 hwloc_obj_is_in_subtree (hwloc_topology_t topology , hwloc_obj_t obj, hwloc_obj_t subtree_root)
    00243 {
    00244   return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
    00245 }
    00246
    00266 static inline hwloc_obj_t
    00267 hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
    00268 {
    00269   hwloc_obj_t obj = hwloc_get_root_obj(topology);
    00270   if (!obj->cpuset || !hwloc_bitmap_intersects(obj->cpuset, set))
    00271     return NULL;
    00272   while (!hwloc_bitmap_isincluded(obj->cpuset, set)) {
    00273     /* while the object intersects without being included, look at its children */
    00274     hwloc_obj_t child = NULL;
    00275     while ((child = hwloc_get_next_child(topology, obj, child)) != NULL) {
    00276       if (child->cpuset && hwloc_bitmap_intersects(child->cpuset, set))
    00277         break;
    00278     }
    00279     if (!child)
    00280       /* no child intersects, return their father */
    00281       return obj;
    00282     /* found one intersecting child, look at its children */
    00283     obj = child;
    00284   }
    00285   /* obj is included, return it */
    00286   return obj;
    00287 }
    00288
    00296  int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00297                                                  hwloc_obj_t * restrict objs, int max);
    00298
    00308 static inline hwloc_obj_t
    00309 hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00310                                            unsigned depth, hwloc_obj_t prev)
    00311 {
    00312   hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
    00313   if (!next || !next->cpuset)
    00314     return NULL;
    00315   while (next && !hwloc_bitmap_isincluded(next->cpuset, set))
    00316     next = next->next_cousin;
    00317   return next;
    00318 }
    00319
    00329 static inline hwloc_obj_t
    00330 hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00331                                           hwloc_obj_type_t type, hwloc_obj_t prev)
    00332 {
    00333   int depth = hwloc_get_type_depth(topology, type);
    00334   if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
    00335     return NULL;
    00336   return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
    00337 }
    00338
    00344 static inline hwloc_obj_t
    00345 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00346                                       unsigned depth, unsigned idx) ;
    00347 static inline hwloc_obj_t
    00348 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00349                                       unsigned depth, unsigned idx)
    00350 {
    00351   hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
    00352   unsigned count = 0;
    00353   if (!obj || !obj->cpuset)
    00354     return NULL;
    00355   while (obj) {
    00356     if (hwloc_bitmap_isincluded(obj->cpuset, set)) {
    00357       if (count == idx)
    00358         return obj;
    00359       count++;
    00360     }
    00361     obj = obj->next_cousin;
    00362   }
    00363   return NULL;
    00364 }
    00365
    00375 static inline hwloc_obj_t
    00376 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00377                                      hwloc_obj_type_t type, unsigned idx) ;
    00378 static inline hwloc_obj_t
    00379 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00380                                      hwloc_obj_type_t type, unsigned idx)
    00381 {
    00382   int depth = hwloc_get_type_depth(topology, type);
    00383   if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
    00384     return NULL;
    00385   return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
    00386 }
    00387
    00393 static inline unsigned
    00394 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00395                                          unsigned depth) ;
    00396 static inline unsigned
    00397 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00398                                          unsigned depth)
    00399 {
    00400   hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
    00401   unsigned count = 0;
    00402   if (!obj || !obj->cpuset)
    00403     return 0;
    00404   while (obj) {
    00405     if (hwloc_bitmap_isincluded(obj->cpuset, set))
    00406       count++;
    00407     obj = obj->next_cousin;
    00408   }
    00409   return count;
    00410 }
    00411
    00421 static inline int
    00422 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00423                                         hwloc_obj_type_t type) ;
    00424 static inline int
    00425 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00426                                         hwloc_obj_type_t type)
    00427 {
    00428   int depth = hwloc_get_type_depth(topology, type);
    00429   if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
    00430     return 0;
    00431   if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
    00432     return -1; /* FIXME: agregate nbobjs from different levels? */
    00433   return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
    00434 }
    00435
    00444 static inline int
    00445 hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology , hwloc_const_cpuset_t set,
    00446                                    hwloc_obj_t obj) ;
    00447 static inline int
    00448 hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology , hwloc_const_cpuset_t set,
    00449                                    hwloc_obj_t obj)
    00450 {
    00451   int idx = 0;
    00452   if (!hwloc_bitmap_isincluded(obj->cpuset, set))
    00453     return -1;
    00454   /* count how many objects are inside the cpuset on the way from us to the beginning of the level */
    00455   while ((obj = obj->prev_cousin) != NULL)
    00456     if (hwloc_bitmap_isincluded(obj->cpuset, set))
    00457       idx++;
    00458   return idx;
    00459 }
    00460
    00475 static inline hwloc_obj_t
    00476 hwloc_get_child_covering_cpuset (hwloc_topology_t topology , hwloc_const_cpuset_t set,
    00477                                 hwloc_obj_t parent) ;
    00478 static inline hwloc_obj_t
    00479 hwloc_get_child_covering_cpuset (hwloc_topology_t topology , hwloc_const_cpuset_t set,
    00480                                 hwloc_obj_t parent)
    00481 {
    00482   hwloc_obj_t child;
    00483   if (!parent->cpuset || hwloc_bitmap_iszero(set))
    00484     return NULL;
    00485   child = parent->first_child;
    00486   while (child) {
    00487     if (child->cpuset && hwloc_bitmap_isincluded(set, child->cpuset))
    00488       return child;
    00489     child = child->next_sibling;
    00490   }
    00491   return NULL;
    00492 }
    00493
    00501 static inline hwloc_obj_t
    00502 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) ;
    00503 static inline hwloc_obj_t
    00504 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
    00505 {
    00506   struct hwloc_obj *current = hwloc_get_root_obj(topology);
    00507   if (hwloc_bitmap_iszero(set) || !current->cpuset || !hwloc_bitmap_isincluded(set, current->cpuset))
    00508     return NULL;
    00509   while (1) {
    00510     hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
    00511     if (!child)
    00512       return current;
    00513     current = child;
    00514   }
    00515 }
    00516
    00517
    00536 static inline hwloc_obj_t
    00537 hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00538                                             unsigned depth, hwloc_obj_t prev)
    00539 {
    00540   hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
    00541   if (!next || !next->cpuset)
    00542     return NULL;
    00543   while (next && !hwloc_bitmap_intersects(set, next->cpuset))
    00544     next = next->next_cousin;
    00545   return next;
    00546 }
    00547
    00563 static inline hwloc_obj_t
    00564 hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00565                                            hwloc_obj_type_t type, hwloc_obj_t prev)
    00566 {
    00567   int depth = hwloc_get_type_depth(topology, type);
    00568   if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
    00569     return NULL;
    00570   return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
    00571 }
    00572
    00588 static inline hwloc_obj_t
    00589 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) ;
    00590 static inline hwloc_obj_t
    00591 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
    00592 {
    00593   hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
    00594   while (current) {
    00595     if (current->type == HWLOC_OBJ_CACHE)
    00596       return current;
    00597     current = current->parent;
    00598   }
    00599   return NULL;
    00600 }
    00601
    00606 static inline hwloc_obj_t
    00607 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology , hwloc_obj_t obj) ;
    00608 static inline hwloc_obj_t
    00609 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology , hwloc_obj_t obj)
    00610 {
    00611   hwloc_obj_t current = obj->parent;
    00612   if (!obj->cpuset)
    00613     return NULL;
    00614   while (current && current->cpuset) {
    00615     if (!hwloc_bitmap_isequal(current->cpuset, obj->cpuset)
    00616         && current->type == HWLOC_OBJ_CACHE)
    00617       return current;
    00618     current = current->parent;
    00619   }
    00620   return NULL;
    00621 }
    00622
    00647 /* TODO: rather provide an iterator? Provide a way to know how much should be allocated? By returning the total number of objects instead? */
    00648  unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * restrict objs, unsigned max);
    00649
    00662 static inline hwloc_obj_t
    00663 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
    00664                              hwloc_obj_type_t type1, unsigned idx1,
    00665                              hwloc_obj_type_t type2, unsigned idx2) ;
    00666 static inline hwloc_obj_t
    00667 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
    00668                              hwloc_obj_type_t type1, unsigned idx1,
    00669                              hwloc_obj_type_t type2, unsigned idx2)
    00670 {
    00671   hwloc_obj_t obj;
    00672   obj = hwloc_get_obj_by_type (topology, type1, idx1);
    00673   if (!obj || !obj->cpuset)
    00674     return NULL;
    00675   return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
    00676 }
    00677
    00696 static inline hwloc_obj_t
    00697 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv) ;
    00698 static inline hwloc_obj_t
    00699 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
    00700 {
    00701   hwloc_obj_t obj = hwloc_get_root_obj(topology);
    00702   int i;
    00703   for(i=0; i<nr; i++) {
    00704     if (!obj || !obj->cpuset)
    00705       return NULL;
    00706     obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
    00707   }
    00708   return obj;
    00709 }
    00710
    00734 static inline void
    00735 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *root, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until);
    00736 static inline void
    00737 hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
    00738 {
    00739   unsigned i;
    00740   if (!root->arity || n == 1 || root->depth >= until) {
    00741     /* Got to the bottom, we can't split any more, put everything there.  */
    00742     for (i=0; i<n; i++)
    00743       cpuset[i] = hwloc_bitmap_dup(root->cpuset);
    00744     return;
    00745   }
    00746   hwloc_distributev(topology, root->children, root->arity, cpuset, n, until);
    00747 }
    00748
    00756 static inline void
    00757 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
    00758 {
    00759   unsigned i;
    00760   unsigned tot_weight;
    00761   hwloc_cpuset_t *cpusetp = cpuset;
    00762
    00763   tot_weight = 0;
    00764   for (i = 0; i < n_roots; i++)
    00765     if (roots[i]->cpuset)
    00766       tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);
    00767
    00768   for (i = 0; i < n_roots && tot_weight; i++) {
    00769     /* Give to roots[i] a portion proportional to its weight */
    00770     unsigned weight = roots[i]->cpuset ? hwloc_bitmap_weight(roots[i]->cpuset) : 0;
    00771     unsigned chunk = (n * weight + tot_weight-1) / tot_weight;
    00772     hwloc_distribute(topology, roots[i], cpusetp, chunk, until);
    00773     cpusetp += chunk;
    00774     tot_weight -= weight;
    00775     n -= chunk;
    00776   }
    00777 }
    00778
    00785 static inline void *
    00786 hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
    00787 {
    00788   void *p = hwloc_alloc_membind_nodeset(topology, len, nodeset, policy, flags);
    00789   if (p)
    00790     return p;
    00791   hwloc_set_membind_nodeset(topology, nodeset, policy, flags);
    00792   p = hwloc_alloc(topology, len);
    00793   if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
    00794     /* Enforce the binding by touching the data */
    00795     memset(p, 0, len);
    00796   return p;
    00797 }
    00798
    00803 static inline void *
    00804 hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t cpuset, hwloc_membind_policy_t policy, int flags)
    00805 {
    00806   void *p = hwloc_alloc_membind(topology, len, cpuset, policy, flags);
    00807   if (p)
    00808     return p;
    00809   hwloc_set_membind(topology, cpuset, policy, flags);
    00810   p = hwloc_alloc(topology, len);
    00811   if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
    00812     /* Enforce the binding by touching the data */
    00813     memset(p, 0, len);
    00814   return p;
    00815 }
    00816
    00833 static inline hwloc_const_cpuset_t
    00834 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology) ;
    00835 static inline hwloc_const_cpuset_t
    00836 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
    00837 {
    00838   return hwloc_get_root_obj(topology)->complete_cpuset;
    00839 }
    00840
    00851 static inline hwloc_const_cpuset_t
    00852 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology) ;
    00853 static inline hwloc_const_cpuset_t
    00854 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
    00855 {
    00856   return hwloc_get_root_obj(topology)->cpuset;
    00857 }
    00858
    00868 static inline hwloc_const_cpuset_t
    00869 hwloc_topology_get_online_cpuset(hwloc_topology_t topology) ;
    00870 static inline hwloc_const_cpuset_t
    00871 hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
    00872 {
    00873   return hwloc_get_root_obj(topology)->online_cpuset;
    00874 }
    00875
    00885 static inline hwloc_const_cpuset_t
    00886 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology) ;
    00887 static inline hwloc_const_cpuset_t
    00888 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
    00889 {
    00890   return hwloc_get_root_obj(topology)->allowed_cpuset;
    00891 }
    00892
    00909 static inline hwloc_const_nodeset_t
    00910 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology) ;
    00911 static inline hwloc_const_nodeset_t
    00912 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
    00913 {
    00914   return hwloc_get_root_obj(topology)->complete_nodeset;
    00915 }
    00916
    00927 static inline hwloc_const_nodeset_t
    00928 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology) ;
    00929 static inline hwloc_const_nodeset_t
    00930 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
    00931 {
    00932   return hwloc_get_root_obj(topology)->nodeset;
    00933 }
    00934
    00944 static inline hwloc_const_nodeset_t
    00945 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology) ;
    00946 static inline hwloc_const_nodeset_t
    00947 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
    00948 {
    00949   return hwloc_get_root_obj(topology)->allowed_nodeset;
    00950 }
    00951
    00982 static inline void
    00983 hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
    00984 {
    00985         int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00986         hwloc_obj_t obj;
    00987
    00988         if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
    00989                  if (hwloc_bitmap_iszero(cpuset))
    00990                         hwloc_bitmap_zero(nodeset);
    00991                 else
    00992                         /* Assume the whole system */
    00993                         hwloc_bitmap_fill(nodeset);
    00994                 return;
    00995         }
    00996
    00997         hwloc_bitmap_zero(nodeset);
    00998         obj = NULL;
    00999         while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
    01000                 hwloc_bitmap_set(nodeset, obj->os_index);
    01001 }
    01002
    01010 static inline void
    01011 hwloc_cpuset_to_nodeset_strict(struct hwloc_topology *topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
    01012 {
    01013         int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    01014         hwloc_obj_t obj;
    01015         if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
    01016                 return;
    01017         hwloc_bitmap_zero(nodeset);
    01018         obj = NULL;
    01019         while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
    01020                 hwloc_bitmap_set(nodeset, obj->os_index);
    01021 }
    01022
    01031 static inline void
    01032 hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
    01033 {
    01034         int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    01035         hwloc_obj_t obj;
    01036
    01037         if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) {
    01038                 if (hwloc_bitmap_iszero(nodeset))
    01039                         hwloc_bitmap_zero(cpuset);
    01040                 else
    01041                         /* Assume the whole system */
    01042                         hwloc_bitmap_fill(cpuset);
    01043                 return;
    01044         }
    01045
    01046         hwloc_bitmap_zero(cpuset);
    01047         obj = NULL;
    01048         while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
    01049                 if (hwloc_bitmap_isset(nodeset, obj->os_index))
    01050                         /* no need to check obj->cpuset because objects in levels always have a cpuset */
    01051                         hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
    01052         }
    01053 }
    01054
    01062 static inline void
    01063 hwloc_cpuset_from_nodeset_strict(struct hwloc_topology *topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
    01064 {
    01065         int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    01066         hwloc_obj_t obj;
    01067         if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
    01068                 return;
    01069         hwloc_bitmap_zero(cpuset);
    01070         obj = NULL;
    01071         while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL)
    01072                 if (hwloc_bitmap_isset(nodeset, obj->os_index))
    01073                         /* no need to check obj->cpuset because objects in levels always have a cpuset */
    01074                         hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
    01075 }
    01076
    01104 static inline const struct hwloc_distances_s *
    01105 hwloc_get_whole_distance_matrix_by_depth(hwloc_topology_t topology, unsigned depth)
    01106 {
    01107   hwloc_obj_t root = hwloc_get_root_obj(topology);
    01108   unsigned i;
    01109   for(i=0; i<root->distances_count; i++)
    01110     if (root->distances[i]->relative_depth == depth)
    01111       return root->distances[i];
    01112   return NULL;
    01113 }
    01114
    01134 static inline const struct hwloc_distances_s *
    01135 hwloc_get_whole_distance_matrix_by_type(hwloc_topology_t topology, hwloc_obj_type_t type)
    01136 {
    01137   int depth = hwloc_get_type_depth(topology, type);
    01138   if (depth < 0)
    01139     return NULL;
    01140   return hwloc_get_whole_distance_matrix_by_depth(topology, depth);
    01141 }
    01142
    01156 static inline const struct hwloc_distances_s *
    01157 hwloc_get_distance_matrix_covering_obj_by_depth(hwloc_topology_t topology,
    01158                                                 hwloc_obj_t obj, unsigned depth,
    01159                                                 unsigned *firstp)
    01160 {
    01161   while (obj && obj->cpuset) {
    01162     unsigned i;
    01163     for(i=0; i<obj->distances_count; i++)
    01164       if (obj->distances[i]->relative_depth == depth - obj->depth) {
    01165         if (!obj->distances[i]->nbobjs)
    01166           continue;
    01167         *firstp = hwloc_get_next_obj_inside_cpuset_by_depth(topology, obj->cpuset, depth, NULL)->logical_index;
    01168         return obj->distances[i];
    01169       }
    01170     obj = obj->parent;
    01171   }
    01172   return NULL;
    01173 }
    01174
    01186 static inline int
    01187 hwloc_get_latency(hwloc_topology_t topology,
    01188                    hwloc_obj_t obj1, hwloc_obj_t obj2,
    01189                    float *latency, float *reverse_latency)
    01190 {
    01191   hwloc_obj_t ancestor;
    01192   const struct hwloc_distances_s * distances;
    01193   unsigned first_logical ;
    01194
    01195   if (obj1->depth != obj2->depth) {
    01196     errno = EINVAL;
    01197     return -1;
    01198   }
    01199
    01200   ancestor = hwloc_get_common_ancestor_obj(topology, obj1, obj2);
    01201   distances = hwloc_get_distance_matrix_covering_obj_by_depth(topology, ancestor, obj1->depth, &first_logical);
    01202   if (distances && distances->latency) {
    01203     const float * latency_matrix = distances->latency;
    01204     unsigned nbobjs = distances->nbobjs;
    01205     unsigned l1 = obj1->logical_index - first_logical;
    01206     unsigned l2 = obj2->logical_index - first_logical;
    01207     *latency = latency_matrix[l1*nbobjs+l2];
    01208     *reverse_latency = latency_matrix[l2*nbobjs+l1];
    01209     return 0;
    01210   }
    01211
    01212   errno = ENOSYS;
    01213   return -1;
    01214 }
    01215
    01230 static inline hwloc_obj_t
    01231 hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology ,
    01232                               hwloc_obj_t ioobj)
    01233 {
    01234   hwloc_obj_t obj = ioobj;
    01235   while (obj && !obj->cpuset) {
    01236     obj = obj->parent;
    01237   }
    01238   return obj;
    01239 }
    01240
    01245 static inline hwloc_obj_t
    01246 hwloc_get_next_pcidev(hwloc_topology_t topology, hwloc_obj_t prev)
    01247 {
    01248   return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PCI_DEVICE, prev);
    01249 }
    01250
    01254 static inline hwloc_obj_t
    01255 hwloc_get_pcidev_by_busid(hwloc_topology_t topology,
    01256                           unsigned domain, unsigned bus, unsigned dev, unsigned func)
    01257 {
    01258   hwloc_obj_t obj = NULL;
    01259   while ((obj = hwloc_get_next_pcidev(topology, obj)) != NULL) {
    01260     if (obj->attr->pcidev.domain == domain
    01261         && obj->attr->pcidev.bus == bus
    01262         && obj->attr->pcidev.dev == dev
    01263         && obj->attr->pcidev.func == func)
    01264       return obj;
    01265   }
    01266   return NULL;
    01267 }
    01268
    01272 static inline hwloc_obj_t
    01273 hwloc_get_pcidev_by_busidstring(hwloc_topology_t topology, const char *busid)
    01274 {
    01275   unsigned domain = 0; /* default */
    01276   unsigned bus, dev, func;
    01277
    01278   if (sscanf(busid, "%x:%x.%x", &bus, &dev, &func) != 3
    01279       && sscanf(busid, "%x:%x:%x.%x", &domain, &bus, &dev, &func) != 4) {
    01280     errno = EINVAL;
    01281     return NULL;
    01282   }
    01283
    01284   return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, func);
    01285 }
    01286
    01291 static inline hwloc_obj_t
    01292 hwloc_get_next_osdev(hwloc_topology_t topology, hwloc_obj_t prev)
    01293 {
    01294   return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_OS_DEVICE, prev);
    01295 }
    01296
    01301 static inline hwloc_obj_t
    01302 hwloc_get_next_bridge(hwloc_topology_t topology, hwloc_obj_t prev)
    01303 {
    01304   return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_BRIDGE, prev);
    01305 }
    01306
    01307 /* \brief Checks whether a given bridge covers a given PCI bus.
    01308  */
    01309 static inline int
    01310 hwloc_bridge_covers_pcibus(hwloc_obj_t bridge,
    01311                            unsigned domain, unsigned bus)
    01312 {
    01313   return bridge->type == HWLOC_OBJ_BRIDGE
    01314     && bridge->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI
    01315     && bridge->attr->bridge.downstream.pci.domain == domain
    01316     && bridge->attr->bridge.downstream.pci.secondary_bus <= bus
    01317     && bridge->attr->bridge.downstream.pci.subordinate_bus >= bus;
    01318 }
    01319
    01325 static inline hwloc_obj_t
    01326 hwloc_get_hostbridge_by_pcibus(hwloc_topology_t topology,
    01327                                unsigned domain, unsigned bus)
    01328 {
    01329   hwloc_obj_t obj = NULL;
    01330   while ((obj = hwloc_get_next_bridge(topology, obj)) != NULL) {
    01331     if (hwloc_bridge_covers_pcibus(obj, domain, bus)) {
    01332       /* found bridge covering this pcibus, make sure it's a hostbridge */
    01333       assert(obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_HOST);
    01334       assert(obj->parent->type != HWLOC_OBJ_BRIDGE);
    01335       assert(obj->parent->cpuset);
    01336       return obj;
    01337     }
    01338   }
    01339   return NULL;
    01340 }
    01341
    01346 #ifdef __cplusplus
    01347 } /* extern "C" */
    01348 #endif
    01349
    01350
    01351 #endif /* HWLOC_HELPER_H */