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 inline unsigned
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_PROC); ; depth--)
00042 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
00043 return depth+1;
00044
00045
00046 abort();
00047 }
00048
00055 static inline unsigned
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 abort();
00070 }
00071
00081 static inline hwloc_obj_t
00082 hwloc_get_system_obj (hwloc_topology_t topology)
00083 {
00084 return hwloc_get_obj_by_depth (topology, 0, 0);
00085 }
00086
00091 static inline hwloc_obj_t
00092 hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev)
00093 {
00094 if (!prev)
00095 return hwloc_get_obj_by_depth (topology, depth, 0);
00096 if (prev->depth != depth)
00097 return NULL;
00098 return prev->next_cousin;
00099 }
00100
00107 static inline hwloc_obj_t
00108 hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
00109 hwloc_obj_t prev)
00110 {
00111 int depth = hwloc_get_type_depth(topology, type);
00112 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00113 return NULL;
00114 return hwloc_get_next_obj_by_depth (topology, depth, prev);
00115 }
00116
00121 static inline hwloc_obj_t
00122 hwloc_get_next_child (hwloc_topology_t topology, hwloc_obj_t father, hwloc_obj_t prev)
00123 {
00124 if (!prev)
00125 return father->first_child;
00126 if (prev->father != father)
00127 return NULL;
00128 return prev->next_sibling;
00129 }
00130
00132 static inline hwloc_obj_t
00133 hwloc_get_common_ancestor_obj (hwloc_topology_t topology, hwloc_obj_t obj1, hwloc_obj_t obj2)
00134 {
00135 while (obj1->depth > obj2->depth)
00136 obj1 = obj1->father;
00137 while (obj2->depth > obj1->depth)
00138 obj2 = obj2->father;
00139 while (obj1 != obj2) {
00140 obj1 = obj1->father;
00141 obj2 = obj2->father;
00142 }
00143 return obj1;
00144 }
00145
00148 static inline int
00149 hwloc_obj_is_in_subtree (hwloc_topology_t topology, hwloc_obj_t obj, hwloc_obj_t subtree_root)
00150 {
00151 return hwloc_cpuset_isincluded(obj->cpuset, subtree_root->cpuset);
00152 }
00153
00166 extern int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_cpuset_t set,
00167 hwloc_obj_t * restrict objs, int max);
00168
00175 static inline hwloc_obj_t
00176 hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_cpuset_t set,
00177 unsigned depth, hwloc_obj_t prev)
00178 {
00179 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00180 while (next && !hwloc_cpuset_isincluded(next->cpuset, set))
00181 next = next->next_cousin;
00182 return next;
00183 }
00184
00190 static inline hwloc_obj_t
00191 hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_cpuset_t set,
00192 hwloc_obj_type_t type, hwloc_obj_t prev)
00193 {
00194 int depth = hwloc_get_type_depth(topology, type);
00195 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00196 return NULL;
00197 return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);
00198 }
00199
00202 static inline hwloc_obj_t
00203 hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_cpuset_t set,
00204 unsigned depth, unsigned idx)
00205 {
00206 int count = 0;
00207 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00208 while (obj) {
00209 if (hwloc_cpuset_isincluded(obj->cpuset, set)) {
00210 if (count == idx)
00211 return obj;
00212 count++;
00213 }
00214 obj = obj->next_cousin;
00215 }
00216 return NULL;
00217 }
00218
00224 static inline hwloc_obj_t
00225 hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_cpuset_t set,
00226 hwloc_obj_type_t type, unsigned idx)
00227 {
00228 int depth = hwloc_get_type_depth(topology, type);
00229 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00230 return NULL;
00231 return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);
00232 }
00233
00235 static inline unsigned
00236 hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_cpuset_t set,
00237 unsigned depth)
00238 {
00239 hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
00240 int count = 0;
00241 while (obj) {
00242 if (hwloc_cpuset_isincluded(obj->cpuset, set))
00243 count++;
00244 obj = obj->next_cousin;
00245 }
00246 return count;
00247 }
00248
00254 static inline int
00255 hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_cpuset_t set,
00256 hwloc_obj_type_t type)
00257 {
00258 int depth = hwloc_get_type_depth(topology, type);
00259 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
00260 return 0;
00261 if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00262 return -1;
00263 return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
00264 }
00265
00278 static inline hwloc_obj_t
00279 hwloc_get_child_covering_cpuset (hwloc_topology_t topology, hwloc_cpuset_t set,
00280 hwloc_obj_t father)
00281 {
00282 hwloc_obj_t child = father->first_child;
00283 while (child) {
00284 if (hwloc_cpuset_isincluded(set, child->cpuset))
00285 return child;
00286 child = child->next_sibling;
00287 }
00288 return NULL;
00289 }
00290
00295 static inline hwloc_obj_t
00296 hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_cpuset_t set)
00297 {
00298 struct hwloc_obj *current = hwloc_get_system_obj(topology);
00299
00300 if (!hwloc_cpuset_isincluded(set, current->cpuset))
00301 return NULL;
00302
00303 while (1) {
00304 hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);
00305 if (!child)
00306 return current;
00307 current = child;
00308 }
00309 }
00310
00311
00327 static inline hwloc_obj_t
00328 hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_cpuset_t set,
00329 unsigned depth, hwloc_obj_t prev)
00330 {
00331 hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
00332 while (next && !hwloc_cpuset_intersects(set, next->cpuset))
00333 next = next->next_cousin;
00334 return next;
00335 }
00336
00348 static inline hwloc_obj_t
00349 hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_cpuset_t set,
00350 hwloc_obj_type_t type, hwloc_obj_t prev)
00351 {
00352 int depth = hwloc_get_type_depth(topology, type);
00353 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
00354 return NULL;
00355 return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);
00356 }
00357
00370 static inline hwloc_obj_t
00371 hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_cpuset_t set)
00372 {
00373 hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);
00374 while (current) {
00375 if (current->type == HWLOC_OBJ_CACHE)
00376 return current;
00377 current = current->father;
00378 }
00379 return NULL;
00380 }
00381
00386 static inline hwloc_obj_t
00387 hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology, hwloc_obj_t obj)
00388 {
00389 hwloc_obj_t current = obj->father;
00390 while (current) {
00391 if (!hwloc_cpuset_isequal(current->cpuset, obj->cpuset)
00392 && current->type == HWLOC_OBJ_CACHE)
00393 return current;
00394 current = current->father;
00395 }
00396 return NULL;
00397 }
00398
00414
00415 extern int hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * restrict objs, int max);
00416
00437 static inline void
00438 hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *cpuset, int n)
00439 {
00440 int i;
00441 int chunk_size, complete_chunks;
00442 hwloc_cpuset_t *cpusetp;
00443
00444 if (!root->arity || n == 1) {
00445
00446 for (i=0; i<n; i++)
00447 cpuset[i] = hwloc_cpuset_dup(root->cpuset);
00448 return;
00449 }
00450
00451
00452 chunk_size = (n + root->arity - 1) / root->arity;
00453 complete_chunks = n % root->arity;
00454 if (!complete_chunks)
00455 complete_chunks = root->arity;
00456
00457
00458 for (cpusetp = cpuset, i = 0;
00459 i < complete_chunks;
00460 i ++, cpusetp += chunk_size)
00461 hwloc_distribute(topology, root->children[i], cpusetp, chunk_size);
00462
00463
00464 for ( ;
00465 i < root->arity;
00466 i++, cpusetp += chunk_size-1)
00467 hwloc_distribute(topology, root->children[i], cpusetp, chunk_size-1);
00468 }
00469
00472 #endif