Open MPI logo

Portable Hardware Locality (hwloc) Documentation: v1.4.1

  |   Home   |   Support   |   FAQ   |  
linux-libnuma.h
00001 /*
00002  * Copyright © 2009 CNRS
00003  * Copyright © 2009-2010 inria.  All rights reserved.
00004  * Copyright © 2009-2010, 2012 Université Bordeaux 1
00005  * See COPYING in top-level directory.
00006  */
00007 
00024 #ifndef HWLOC_LINUX_LIBNUMA_H
00025 #define HWLOC_LINUX_LIBNUMA_H
00026 
00027 #include <hwloc.h>
00028 #include <numa.h>
00029 
00030 
00031 #ifdef __cplusplus
00032 extern "C" {
00033 #endif
00034 
00035 
00051 static inline int
00052 hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,
00053                                     unsigned long *mask, unsigned long *maxnode)
00054 {
00055   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00056   unsigned long outmaxnode = -1;
00057 
00058   /* round-up to the next ulong and clear all bytes */
00059   *maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);
00060   memset(mask, 0, *maxnode/8);
00061 
00062   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00063     hwloc_obj_t node = NULL;
00064     while ((node = hwloc_get_next_obj_covering_cpuset_by_type(topology, cpuset, HWLOC_OBJ_NODE, node)) != NULL) {
00065       if (node->os_index >= *maxnode)
00066         continue;
00067       mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));
00068       if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)
00069         outmaxnode = node->os_index;
00070     }
00071 
00072   } else {
00073     /* if no numa, libnuma assumes we have a single node */
00074     if (!hwloc_bitmap_iszero(cpuset)) {
00075       mask[0] = 1;
00076       outmaxnode = 0;
00077     }
00078   }
00079 
00080   *maxnode = outmaxnode+1;
00081   return 0;
00082 }
00083 
00094 static inline int
00095 hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,
00096                                       unsigned long *mask, unsigned long *maxnode)
00097 {
00098   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00099   unsigned long outmaxnode = -1;
00100 
00101   /* round-up to the next ulong and clear all bytes */
00102   *maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);
00103   memset(mask, 0, *maxnode/8);
00104 
00105   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00106     hwloc_obj_t node = NULL;
00107     while ((node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, node)) != NULL) {
00108       if (node->os_index >= *maxnode)
00109         continue;
00110       if (!hwloc_bitmap_isset(nodeset, node->os_index))
00111         continue;
00112       mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));
00113       if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)
00114         outmaxnode = node->os_index;
00115     }
00116 
00117   } else {
00118     /* if no numa, libnuma assumes we have a single node */
00119     if (!hwloc_bitmap_iszero(nodeset)) {
00120       mask[0] = 1;
00121       outmaxnode = 0;
00122     }
00123   }
00124 
00125   *maxnode = outmaxnode+1;
00126   return 0;
00127 }
00128 
00138 static inline int
00139 hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
00140                                       const unsigned long *mask, unsigned long maxnode)
00141 {
00142   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00143 
00144   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00145     hwloc_obj_t node = NULL;
00146     hwloc_bitmap_zero(cpuset);
00147     while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
00148       if (node->os_index < maxnode
00149           && (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
00150         hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
00151   } else {
00152     /* if no numa, libnuma assumes we have a single node */
00153     if (mask[0] & 1)
00154       hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
00155     else
00156       hwloc_bitmap_zero(cpuset);
00157   }
00158 
00159   return 0;
00160 }
00161 
00171 static inline int
00172 hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
00173                                         const unsigned long *mask, unsigned long maxnode)
00174 {
00175   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00176 
00177   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00178     hwloc_obj_t node = NULL;
00179     hwloc_bitmap_zero(nodeset);
00180     while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
00181       if (node->os_index < maxnode
00182           && (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
00183         hwloc_bitmap_set(nodeset, node->os_index);
00184   } else {
00185     /* if no numa, libnuma assumes we have a single node */
00186     if (mask[0] & 1)
00187       hwloc_bitmap_fill(nodeset);
00188     else
00189       hwloc_bitmap_zero(nodeset);
00190   }
00191 
00192   return 0;
00193 }
00194 
00213 static inline struct bitmask *
00214 hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset) ;
00215 static inline struct bitmask *
00216 hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset)
00217 {
00218   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00219   struct bitmask *bitmask = numa_allocate_cpumask();
00220   if (!bitmask)
00221     return NULL;
00222 
00223   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00224     hwloc_obj_t node = NULL;
00225     while ((node = hwloc_get_next_obj_covering_cpuset_by_type(topology, cpuset, HWLOC_OBJ_NODE, node)) != NULL)
00226       if (node->memory.local_memory)
00227         numa_bitmask_setbit(bitmask, node->os_index);
00228   } else {
00229     /* if no numa, libnuma assumes we have a single node */
00230     if (!hwloc_bitmap_iszero(cpuset))
00231       numa_bitmask_setbit(bitmask, 0);
00232   }
00233 
00234   return bitmask;
00235 }
00236 
00246 static inline struct bitmask *
00247 hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset) ;
00248 static inline struct bitmask *
00249 hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset)
00250 {
00251   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00252   struct bitmask *bitmask = numa_allocate_cpumask();
00253   if (!bitmask)
00254     return NULL;
00255 
00256   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00257     hwloc_obj_t node = NULL;
00258     while ((node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, node)) != NULL)
00259       if (hwloc_bitmap_isset(nodeset, node->os_index) && node->memory.local_memory)
00260         numa_bitmask_setbit(bitmask, node->os_index);
00261   } else {
00262     /* if no numa, libnuma assumes we have a single node */
00263     if (!hwloc_bitmap_iszero(nodeset))
00264       numa_bitmask_setbit(bitmask, 0);
00265   }
00266 
00267   return bitmask;
00268 }
00269 
00275 static inline int
00276 hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
00277                                         const struct bitmask *bitmask)
00278 {
00279   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00280 
00281   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00282     hwloc_obj_t node = NULL;
00283     hwloc_bitmap_zero(cpuset);
00284     while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
00285       if (numa_bitmask_isbitset(bitmask, node->os_index))
00286         hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
00287   } else {
00288     /* if no numa, libnuma assumes we have a single node */
00289     if (numa_bitmask_isbitset(bitmask, 0))
00290       hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
00291     else
00292       hwloc_bitmap_zero(cpuset);
00293   }
00294 
00295   return 0;
00296 }
00297 
00303 static inline int
00304 hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
00305                                          const struct bitmask *bitmask)
00306 {
00307   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00308 
00309   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00310     hwloc_obj_t node = NULL;
00311     hwloc_bitmap_zero(nodeset);
00312     while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
00313       if (numa_bitmask_isbitset(bitmask, node->os_index))
00314         hwloc_bitmap_set(nodeset, node->os_index);
00315   } else {
00316     /* if no numa, libnuma assumes we have a single node */
00317     if (numa_bitmask_isbitset(bitmask, 0))
00318       hwloc_bitmap_fill(nodeset);
00319     else
00320       hwloc_bitmap_zero(nodeset);
00321   }
00322 
00323   return 0;
00324 }
00325 
00330 #ifdef NUMA_VERSION1_COMPATIBILITY
00331 
00347 static inline int
00348 hwloc_cpuset_to_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,
00349                                       nodemask_t *nodemask)
00350 {
00351   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00352 
00353   nodemask_zero(nodemask);
00354 
00355   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00356     hwloc_obj_t node = NULL;
00357     while ((node = hwloc_get_next_obj_covering_cpuset_by_type(topology, cpuset, HWLOC_OBJ_NODE, node)) != NULL)
00358       nodemask_set(nodemask, node->os_index);
00359   } else {
00360     /* if no numa, libnuma assumes we have a single node */
00361     if (!hwloc_bitmap_iszero(cpuset))
00362       nodemask_set(nodemask, 0);
00363   }
00364 
00365   return 0;
00366 }
00367 
00373 static inline int
00374 hwloc_nodeset_to_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,
00375                                         nodemask_t *nodemask)
00376 {
00377   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00378 
00379   nodemask_zero(nodemask);
00380 
00381   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00382     hwloc_obj_t node = NULL;
00383     while ((node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, node)) != NULL)
00384       if (hwloc_bitmap_isset(nodeset, node->os_index))
00385         nodemask_set(nodemask, node->os_index);
00386   } else {
00387     /* if no numa, libnuma assumes we have a single node */
00388     if (!hwloc_bitmap_iszero(nodeset))
00389       nodemask_set(nodemask, 0);
00390   }
00391 
00392   return 0;
00393 }
00394 
00400 static inline int
00401 hwloc_cpuset_from_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
00402                                         const nodemask_t *nodemask)
00403 {
00404   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00405 
00406   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00407     hwloc_obj_t node = NULL;
00408     hwloc_bitmap_zero(cpuset);
00409     while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
00410       if (nodemask_isset(nodemask, node->os_index))
00411         hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
00412   } else {
00413     /* if no numa, libnuma assumes we have a single node */
00414     if (nodemask_isset(nodemask, 0))
00415       hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
00416     else
00417       hwloc_bitmap_zero(cpuset);
00418   }
00419 
00420   return 0;
00421 }
00422 
00428 static inline int
00429 hwloc_nodeset_from_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
00430                                           const nodemask_t *nodemask)
00431 {
00432   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00433 
00434   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00435     hwloc_obj_t node = NULL;
00436     hwloc_bitmap_zero(nodeset);
00437     while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
00438       if (nodemask_isset(nodemask, node->os_index))
00439         hwloc_bitmap_set(nodeset, node->os_index);
00440   } else {
00441     /* if no numa, libnuma assumes we have a single node */
00442     if (nodemask_isset(nodemask, 0))
00443       hwloc_bitmap_fill(nodeset);
00444     else
00445       hwloc_bitmap_zero(nodeset);
00446   }
00447 
00448   return 0;
00449 }
00450 
00452 #endif /* NUMA_VERSION1_COMPATIBILITY */
00453 
00454 
00455 #ifdef __cplusplus
00456 } /* extern "C" */
00457 #endif
00458 
00459 
00460 #endif /* HWLOC_LINUX_NUMA_H */