Hardware Locality (hwloc): helper.h Source File

Hardware Locality (hwloc) 1.2.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-2011 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
    00044 static inline int
    00045 hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
    00046 {
    00047   int depth = hwloc_get_type_depth(topology, type);
    00048
    00049   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
    00050     return depth;
    00051
    00052   /* find the highest existing level with type order >= */
    00053   for(depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); ; depth--)
    00054     if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
    00055       return depth+1;
    00056
    00057   /* Shouldn't ever happen, as there is always a SYSTEM level with lower order and known depth.  */
    00058   /* abort(); */
    00059 }
    00060
    00067 static inline int
    00068 hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
    00069 {
    00070   int depth = hwloc_get_type_depth(topology, type);
    00071
    00072   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
    00073     return depth;
    00074
    00075   /* find the lowest existing level with type order <= */
    00076   for(depth = 0; ; depth++)
    00077     if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) > 0)
    00078       return depth-1;
    00079
    00080   /* Shouldn't ever happen, as there is always a PU level with higher order and known depth.  */
    00081   /* abort(); */
    00082 }
    00083
    00103 static inline hwloc_obj_t
    00104 hwloc_get_root_obj (hwloc_topology_t topology)
    00105 {
    00106   return hwloc_get_obj_by_depth (topology, 0, 0);
    00107 }
    00108
    00110 static inline hwloc_obj_t
    00111 hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology , unsigned depth, hwloc_obj_t obj)
    00112 {
    00113   hwloc_obj_t ancestor = obj;
    00114   if (obj->depth < depth)
    00115     return NULL;
    00116   while (ancestor && ancestor->depth > depth)
    00117     ancestor = ancestor->parent;
    00118   return ancestor;
    00119 }
    00120
    00122 static inline hwloc_obj_t
    00123 hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology , hwloc_obj_type_t type, hwloc_obj_t obj)
    00124 {
    00125   hwloc_obj_t ancestor = obj->parent;
    00126   while (ancestor && ancestor->type != type)
    00127     ancestor = ancestor->parent;
    00128   return ancestor;
    00129 }
    00130
    00135 static inline hwloc_obj_t
    00136 hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev)
    00137 {
    00138   if (!prev)
    00139     return hwloc_get_obj_by_depth (topology, depth, 0);
    00140   if (prev->depth != depth)
    00141     return NULL;
    00142   return prev->next_cousin;
    00143 }
    00144
    00151 static inline hwloc_obj_t
    00152 hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
    00153                    hwloc_obj_t prev)
    00154 {
    00155   int depth = hwloc_get_type_depth(topology, type);
    00156   if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
    00157     return NULL;
    00158   return hwloc_get_next_obj_by_depth (topology, depth, prev);
    00159 }
    00160
    00169 static inline hwloc_obj_t
    00170 hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
    00171 {
    00172   hwloc_obj_t obj = NULL;
    00173   while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
    00174     if (obj->os_index == os_index)
    00175       return obj;
    00176   return NULL;
    00177 }
    00178
    00183 static inline hwloc_obj_t
    00184 hwloc_get_next_child (hwloc_topology_t topology , hwloc_obj_t parent, hwloc_obj_t prev)
    00185 {
    00186   if (!prev)
    00187     return parent->first_child;
    00188   if (prev->parent != parent)
    00189     return NULL;
    00190   return prev->next_sibling;
    00191 }
    00192
    00194 static inline hwloc_obj_t
    00195 hwloc_get_common_ancestor_obj (hwloc_topology_t topology , hwloc_obj_t obj1, hwloc_obj_t obj2)
    00196 {
    00197   /* the loop isn't so easy since intermediate ancestors may have
    00198    * different depth, causing us to alternate between using obj1->parent
    00199    * and obj2->parent. Also, even if at some point we find ancestors of
    00200    * of the same depth, their ancestors may have different depth again.
    00201    */
    00202   while (obj1 != obj2) {
    00203     while (obj1->depth > obj2->depth)
    00204       obj1 = obj1->parent;
    00205     while (obj2->depth > obj1->depth)
    00206       obj2 = obj2->parent;
    00207     if (obj1 != obj2 && obj1->depth == obj2->depth) {
    00208       obj1 = obj1->parent;
    00209       obj2 = obj2->parent;
    00210     }
    00211   }
    00212   return obj1;
    00213 }
    00214
    00219 static inline int
    00220 hwloc_obj_is_in_subtree (hwloc_topology_t topology , hwloc_obj_t obj, hwloc_obj_t subtree_root)
    00221 {
    00222   return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
    00223 }
    00224
    00241 static inline hwloc_obj_t
    00242 hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)
    00243 {
    00244   hwloc_obj_t obj = hwloc_get_root_obj(topology);
    00245   /* FIXME: what if !root->cpuset? */
    00246   if (!hwloc_bitmap_intersects(obj->cpuset, set))
    00247     return NULL;
    00248   while (!hwloc_bitmap_isincluded(obj->cpuset, set)) {
    00249     /* while the object intersects without being included, look at its children */
    00250     hwloc_obj_t child = NULL;
    00251     while ((child = hwloc_get_next_child(topology, obj, child)) != NULL) {
    00252       if (child->cpuset && hwloc_bitmap_intersects(child->cpuset, set))
    00253         break;
    00254     }
    00255     if (!child)
    00256       /* no child intersects, return their father */
    00257       return obj;
    00258     /* found one intersecting child, look at its children */
    00259     obj = child;
    00260   }
    00261   /* obj is included, return it */
    00262   return obj;
    00263 }
    00264
    00269  int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00270                                                  hwloc_obj_t * restrict objs, int max);
    00271
    00278 static inline hwloc_obj_t
    00279 hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00280                                            unsigned depth, hwloc_obj_t prev)
    00281 {
    00282   hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
    00283   /* no need to check next->cpuset because objects in levels always have a cpuset */
    00284   while (next && !hwloc_bitmap_isincluded(next->cpuset, set))
    00285     next = next->next_cousin;
    00286   return next;
    00287 }
    00288
    00295 static inline hwloc_obj_t
    00296 hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00297                                           hwloc_obj_type_t type, hwloc_obj_t prev)
    00298 {
    00299   int depth = hwloc_get_type_depth(topology, type);
    00300   if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
    00301     return NULL;
    00302   return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
    00303 }
    00304
    00307 static inline hwloc_obj_t
    00308 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00309                                       unsigned depth, unsigned idx)
    00310 {
    00311   unsigned count = 0;
    00312   hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
    00313   while (obj) {
    00314     /* no need to check obj->cpuset because objects in levels always have a cpuset */
    00315     if (hwloc_bitmap_isincluded(obj->cpuset, set)) {
    00316       if (count == idx)
    00317         return obj;
    00318       count++;
    00319     }
    00320     obj = obj->next_cousin;
    00321   }
    00322   return NULL;
    00323 }
    00324
    00331 static inline hwloc_obj_t
    00332 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00333                                      hwloc_obj_type_t type, unsigned idx)
    00334 {
    00335   int depth = hwloc_get_type_depth(topology, type);
    00336   if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
    00337     return NULL;
    00338   return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
    00339 }
    00340
    00342 static inline unsigned
    00343 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00344                                          unsigned depth)
    00345 {
    00346   hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
    00347   int count = 0;
    00348   while (obj) {
    00349     /* no need to check obj->cpuset because objects in levels always have a cpuset */
    00350     if (hwloc_bitmap_isincluded(obj->cpuset, set))
    00351       count++;
    00352     obj = obj->next_cousin;
    00353   }
    00354   return count;
    00355 }
    00356
    00363 static inline int
    00364 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00365                                         hwloc_obj_type_t type)
    00366 {
    00367   int depth = hwloc_get_type_depth(topology, type);
    00368   if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
    00369     return 0;
    00370   if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
    00371     return -1; /* FIXME: agregate nbobjs from different levels? */
    00372   return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
    00373 }
    00374
    00387 static inline hwloc_obj_t
    00388 hwloc_get_child_covering_cpuset (hwloc_topology_t topology , hwloc_const_cpuset_t set,
    00389                                 hwloc_obj_t parent)
    00390 {
    00391   hwloc_obj_t child;
    00392
    00393   if (hwloc_bitmap_iszero(set))
    00394     return NULL;
    00395
    00396   child = parent->first_child;
    00397   while (child) {
    00398     if (child->cpuset && hwloc_bitmap_isincluded(set, child->cpuset))
    00399       return child;
    00400     child = child->next_sibling;
    00401   }
    00402   return NULL;
    00403 }
    00404
    00409 static inline hwloc_obj_t
    00410 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
    00411 {
    00412   struct hwloc_obj *current = hwloc_get_root_obj(topology);
    00413
    00414   if (hwloc_bitmap_iszero(set))
    00415     return NULL;
    00416
    00417   /* FIXME: what if !root->cpuset? */
    00418   if (!hwloc_bitmap_isincluded(set, current->cpuset))
    00419     return NULL;
    00420
    00421   while (1) {
    00422     hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
    00423     if (!child)
    00424       return current;
    00425     current = child;
    00426   }
    00427 }
    00428
    00429
    00445 static inline hwloc_obj_t
    00446 hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00447                                             unsigned depth, hwloc_obj_t prev)
    00448 {
    00449   hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
    00450   /* no need to check next->cpuset because objects in levels always have a cpuset */
    00451   while (next && !hwloc_bitmap_intersects(set, next->cpuset))
    00452     next = next->next_cousin;
    00453   return next;
    00454 }
    00455
    00468 static inline hwloc_obj_t
    00469 hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
    00470                                            hwloc_obj_type_t type, hwloc_obj_t prev)
    00471 {
    00472   int depth = hwloc_get_type_depth(topology, type);
    00473   if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
    00474     return NULL;
    00475   return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
    00476 }
    00477
    00490 static inline hwloc_obj_t
    00491 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)
    00492 {
    00493   hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
    00494   while (current) {
    00495     if (current->type == HWLOC_OBJ_CACHE)
    00496       return current;
    00497     current = current->parent;
    00498   }
    00499   return NULL;
    00500 }
    00501
    00506 static inline hwloc_obj_t
    00507 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology , hwloc_obj_t obj)
    00508 {
    00509   hwloc_obj_t current = obj->parent;
    00510   if (!obj->cpuset)
    00511     return NULL;
    00512   while (current && current->cpuset) {
    00513     if (!hwloc_bitmap_isequal(current->cpuset, obj->cpuset)
    00514         && current->type == HWLOC_OBJ_CACHE)
    00515       return current;
    00516     current = current->parent;
    00517   }
    00518   return NULL;
    00519 }
    00520
    00541 /* TODO: rather provide an iterator? Provide a way to know how much should be allocated? By returning the total number of objects instead? */
    00542  unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * restrict objs, unsigned max);
    00543
    00554 static inline hwloc_obj_t
    00555 hwloc_get_obj_below_by_type (hwloc_topology_t topology,
    00556                              hwloc_obj_type_t type1, unsigned idx1,
    00557                              hwloc_obj_type_t type2, unsigned idx2)
    00558 {
    00559   hwloc_obj_t obj;
    00560
    00561   obj = hwloc_get_obj_by_type (topology, type1, idx1);
    00562   if (!obj)
    00563     return NULL;
    00564
    00565   return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);
    00566 }
    00567
    00583 static inline hwloc_obj_t
    00584 hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)
    00585 {
    00586   hwloc_obj_t obj = hwloc_get_root_obj(topology);
    00587   int i;
    00588
    00589   /* FIXME: what if !root->cpuset? */
    00590   for(i=0; i<nr; i++) {
    00591     obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);
    00592     if (!obj)
    00593       return NULL;
    00594   }
    00595
    00596   return obj;
    00597 }
    00598
    00620 static inline void
    00621 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *root, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until);
    00622 static inline void
    00623 hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
    00624 {
    00625   unsigned i;
    00626
    00627   /* FIXME: what if !root->cpuset? */
    00628   if (!root->arity || n == 1 || root->depth >= until) {
    00629     /* Got to the bottom, we can't split any more, put everything there.  */
    00630     for (i=0; i<n; i++)
    00631       cpuset[i] = hwloc_bitmap_dup(root->cpuset);
    00632     return;
    00633   }
    00634
    00635   hwloc_distributev(topology, root->children, root->arity, cpuset, n, until);
    00636 }
    00637
    00643 static inline void
    00644 hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until)
    00645 {
    00646   unsigned i;
    00647   unsigned tot_weight;
    00648   hwloc_cpuset_t *cpusetp = cpuset;
    00649
    00650   tot_weight = 0;
    00651   for (i = 0; i < n_roots; i++)
    00652     if (roots[i]->cpuset)
    00653       tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);
    00654
    00655   for (i = 0; i < n_roots && tot_weight; i++) {
    00656     /* Give to roots[i] a portion proportional to its weight */
    00657     unsigned weight = roots[i]->cpuset ? hwloc_bitmap_weight(roots[i]->cpuset) : 0;
    00658     unsigned chunk = (n * weight + tot_weight-1) / tot_weight;
    00659     hwloc_distribute(topology, roots[i], cpusetp, chunk, until);
    00660     cpusetp += chunk;
    00661     tot_weight -= weight;
    00662     n -= chunk;
    00663   }
    00664 }
    00665
    00672 static inline void *
    00673 hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
    00674 {
    00675   void *p = hwloc_alloc_membind_nodeset(topology, len, nodeset, policy, flags);
    00676   if (p)
    00677     return p;
    00678   hwloc_set_membind_nodeset(topology, nodeset, policy, flags);
    00679   p = hwloc_alloc(topology, len);
    00680   if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
    00681     /* Enforce the binding by touching the data */
    00682     memset(p, 0, len);
    00683   return p;
    00684 }
    00685
    00690 static inline void *
    00691 hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t cpuset, hwloc_membind_policy_t policy, int flags)
    00692 {
    00693   void *p = hwloc_alloc_membind(topology, len, cpuset, policy, flags);
    00694   if (p)
    00695     return p;
    00696   hwloc_set_membind(topology, cpuset, policy, flags);
    00697   p = hwloc_alloc(topology, len);
    00698   if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
    00699     /* Enforce the binding by touching the data */
    00700     memset(p, 0, len);
    00701   return p;
    00702 }
    00703
    00720 static inline hwloc_const_cpuset_t
    00721 hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
    00722 {
    00723   return hwloc_get_root_obj(topology)->complete_cpuset;
    00724 }
    00725
    00736 static inline hwloc_const_cpuset_t
    00737 hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
    00738 {
    00739   return hwloc_get_root_obj(topology)->cpuset;
    00740 }
    00741
    00751 static inline hwloc_const_cpuset_t
    00752 hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
    00753 {
    00754   return hwloc_get_root_obj(topology)->online_cpuset;
    00755 }
    00756
    00766 static inline hwloc_const_cpuset_t
    00767 hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
    00768 {
    00769   return hwloc_get_root_obj(topology)->allowed_cpuset;
    00770 }
    00771
    00788 static inline hwloc_const_nodeset_t
    00789 hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
    00790 {
    00791   return hwloc_get_root_obj(topology)->complete_nodeset;
    00792 }
    00793
    00804 static inline hwloc_const_nodeset_t
    00805 hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
    00806 {
    00807   return hwloc_get_root_obj(topology)->nodeset;
    00808 }
    00809
    00819 static inline hwloc_const_nodeset_t
    00820 hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
    00821 {
    00822   return hwloc_get_root_obj(topology)->allowed_nodeset;
    00823 }
    00824
    00855 static inline void
    00856 hwloc_cpuset_to_nodeset(hwloc_topology_t 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
    00861         if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
    00862                  if (hwloc_bitmap_iszero(cpuset))
    00863                         hwloc_bitmap_zero(nodeset);
    00864                 else
    00865                         /* Assume the whole system */
    00866                         hwloc_bitmap_fill(nodeset);
    00867                 return;
    00868         }
    00869
    00870         hwloc_bitmap_zero(nodeset);
    00871         obj = NULL;
    00872         while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
    00873                 hwloc_bitmap_set(nodeset, obj->os_index);
    00874 }
    00875
    00883 static inline void
    00884 hwloc_cpuset_to_nodeset_strict(struct hwloc_topology *topology, hwloc_const_cpuset_t cpuset, hwloc_nodeset_t nodeset)
    00885 {
    00886         int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00887         hwloc_obj_t obj;
    00888         if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
    00889                 return;
    00890         hwloc_bitmap_zero(nodeset);
    00891         obj = NULL;
    00892         while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, obj)) != NULL)
    00893                 hwloc_bitmap_set(nodeset, obj->os_index);
    00894 }
    00895
    00904 static inline void
    00905 hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
    00906 {
    00907         int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00908         hwloc_obj_t obj;
    00909
    00910         if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) {
    00911                 if (hwloc_bitmap_iszero(nodeset))
    00912                         hwloc_bitmap_zero(cpuset);
    00913                 else
    00914                         /* Assume the whole system */
    00915                         hwloc_bitmap_fill(cpuset);
    00916                 return;
    00917         }
    00918
    00919         hwloc_bitmap_zero(cpuset);
    00920         obj = NULL;
    00921         while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
    00922                 if (hwloc_bitmap_isset(nodeset, obj->os_index))
    00923                         /* no need to check obj->cpuset because objects in levels always have a cpuset */
    00924                         hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
    00925         }
    00926 }
    00927
    00935 static inline void
    00936 hwloc_cpuset_from_nodeset_strict(struct hwloc_topology *topology, hwloc_cpuset_t cpuset, hwloc_const_nodeset_t nodeset)
    00937 {
    00938         int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00939         hwloc_obj_t obj;
    00940         if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
    00941                 return;
    00942         hwloc_bitmap_zero(cpuset);
    00943         obj = NULL;
    00944         while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL)
    00945                 if (hwloc_bitmap_isset(nodeset, obj->os_index))
    00946                         /* no need to check obj->cpuset because objects in levels always have a cpuset */
    00947                         hwloc_bitmap_or(cpuset, cpuset, obj->cpuset);
    00948 }
    00949
    00977 static inline const struct hwloc_distances_s *
    00978 hwloc_get_whole_distance_matrix_by_depth(hwloc_topology_t topology, unsigned depth)
    00979 {
    00980   hwloc_obj_t root = hwloc_get_root_obj(topology);
    00981   unsigned i;
    00982   for(i=0; i<root->distances_count; i++)
    00983     if (root->distances[i]->relative_depth == depth)
    00984       return root->distances[i];
    00985   return NULL;
    00986 }
    00987
    01007 static inline const struct hwloc_distances_s *
    01008 hwloc_get_whole_distance_matrix_by_type(hwloc_topology_t topology, hwloc_obj_type_t type)
    01009 {
    01010   int depth = hwloc_get_type_depth(topology, type);
    01011   if (depth < 0)
    01012     return NULL;
    01013   return hwloc_get_whole_distance_matrix_by_depth(topology, depth);
    01014 }
    01015
    01029 static inline const struct hwloc_distances_s *
    01030 hwloc_get_distance_matrix_covering_obj_by_depth(hwloc_topology_t topology,
    01031                                                 hwloc_obj_t obj, unsigned depth,
    01032                                                 unsigned *firstp)
    01033 {
    01034   while (obj && obj->cpuset) {
    01035     unsigned i;
    01036     for(i=0; i<obj->distances_count; i++)
    01037       if (obj->distances[i]->relative_depth == depth - obj->depth) {
    01038         if (!obj->distances[i]->nbobjs)
    01039           continue;
    01040         *firstp = hwloc_get_next_obj_inside_cpuset_by_depth(topology, obj->cpuset, depth, NULL)->logical_index;
    01041         return obj->distances[i];
    01042       }
    01043     obj = obj->parent;
    01044   }
    01045   return NULL;
    01046 }
    01047
    01059 static inline int
    01060 hwloc_get_latency(hwloc_topology_t topology,
    01061                    hwloc_obj_t obj1, hwloc_obj_t obj2,
    01062                    float *latency, float *reverse_latency)
    01063 {
    01064   hwloc_obj_t ancestor;
    01065   const struct hwloc_distances_s * distances;
    01066   unsigned first_logical ;
    01067
    01068   if (obj1->depth != obj2->depth) {
    01069     errno = EINVAL;
    01070     return -1;
    01071   }
    01072
    01073   ancestor = hwloc_get_common_ancestor_obj(topology, obj1, obj2);
    01074   distances = hwloc_get_distance_matrix_covering_obj_by_depth(topology, ancestor, obj1->depth, &first_logical);
    01075   if (distances && distances->latency) {
    01076     const float * latency_matrix = distances->latency;
    01077     unsigned nbobjs = distances->nbobjs;
    01078     unsigned l1 = obj1->logical_index - first_logical;
    01079     unsigned l2 = obj2->logical_index - first_logical;
    01080     *latency = latency_matrix[l1*nbobjs+l2];
    01081     *reverse_latency = latency_matrix[l2*nbobjs+l1];
    01082     return 0;
    01083   }
    01084
    01085   errno = ENOSYS;
    01086   return -1;
    01087 }
    01088
    01093 #ifdef __cplusplus
    01094 } /* extern "C" */
    01095 #endif
    01096
    01097
    01098 #endif /* HWLOC_HELPER_H */