Open MPI logo

Portable Hardware Locality (hwloc) Documentation: v1.3.1

  |   Home   |   Support   |   FAQ   |  
linux-libnuma.h
00001 /*
00002  * Copyright © 2009 CNRS
00003  * Copyright © 2009-2010 INRIA.  All rights reserved.
00004  * Copyright © 2009-2010 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;
00146     unsigned i;
00147     hwloc_bitmap_zero(cpuset);
00148     for(i=0; i<maxnode; i++)
00149       if (mask[i/sizeof(*mask)/8] & (1UL << (i% (sizeof(*mask)*8)))) {
00150         node = hwloc_get_obj_by_depth(topology, depth, i);
00151         if (node)
00152           hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
00153       }
00154   } else {
00155     /* if no numa, libnuma assumes we have a single node */
00156     if (mask[0] & 1)
00157       hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
00158     else
00159       hwloc_bitmap_zero(cpuset);
00160   }
00161 
00162   return 0;
00163 }
00164 
00174 static inline int
00175 hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
00176                                         const unsigned long *mask, unsigned long maxnode)
00177 {
00178   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00179 
00180   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00181     hwloc_obj_t node;
00182     unsigned i;
00183     hwloc_bitmap_zero(nodeset);
00184     for(i=0; i<maxnode; i++)
00185       if (mask[i/sizeof(*mask)/8] & (1UL << (i% (sizeof(*mask)*8)))) {
00186         node = hwloc_get_obj_by_depth(topology, depth, i);
00187         if (node)
00188           hwloc_bitmap_set(nodeset, node->os_index);
00189       }
00190   } else {
00191     /* if no numa, libnuma assumes we have a single node */
00192     if (mask[0] & 1)
00193       hwloc_bitmap_fill(nodeset);
00194     else
00195       hwloc_bitmap_zero(nodeset);
00196   }
00197 
00198   return 0;
00199 }
00200 
00219 static inline struct bitmask * 
00220 hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset)
00221 {
00222   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00223   struct bitmask *bitmask = numa_allocate_cpumask();
00224   if (!bitmask)
00225     return NULL;
00226 
00227   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00228     hwloc_obj_t node = NULL;
00229     while ((node = hwloc_get_next_obj_covering_cpuset_by_type(topology, cpuset, HWLOC_OBJ_NODE, node)) != NULL)
00230       numa_bitmask_setbit(bitmask, node->os_index);
00231   } else {
00232     /* if no numa, libnuma assumes we have a single node */
00233     if (!hwloc_bitmap_iszero(cpuset))
00234       numa_bitmask_setbit(bitmask, 0);
00235   }
00236 
00237   return bitmask;
00238 }
00239 
00249 static inline struct bitmask * 
00250 hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset)
00251 {
00252   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00253   struct bitmask *bitmask = numa_allocate_cpumask();
00254   if (!bitmask)
00255     return NULL;
00256 
00257   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00258     hwloc_obj_t node = NULL;
00259     while ((node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, node)) != NULL)
00260       if (hwloc_bitmap_isset(nodeset, node->os_index))
00261         numa_bitmask_setbit(bitmask, node->os_index);
00262   } else {
00263     /* if no numa, libnuma assumes we have a single node */
00264     if (!hwloc_bitmap_iszero(nodeset))
00265       numa_bitmask_setbit(bitmask, 0);
00266   }
00267 
00268   return bitmask;
00269 }
00270 
00276 static inline int
00277 hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
00278                                         const struct bitmask *bitmask)
00279 {
00280   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00281 
00282   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00283     hwloc_obj_t node;
00284     int i;
00285     hwloc_bitmap_zero(cpuset);
00286     for(i=0; i<NUMA_NUM_NODES; i++)
00287       if (numa_bitmask_isbitset(bitmask, i)) {
00288         node = hwloc_get_obj_by_depth(topology, depth, i);
00289         if (node)
00290           hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
00291       }
00292   } else {
00293     /* if no numa, libnuma assumes we have a single node */
00294     if (numa_bitmask_isbitset(bitmask, 0))
00295       hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
00296     else
00297       hwloc_bitmap_zero(cpuset);
00298   }
00299 
00300   return 0;
00301 }
00302 
00308 static inline int
00309 hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
00310                                          const struct bitmask *bitmask)
00311 {
00312   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00313 
00314   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00315     hwloc_obj_t node;
00316     int i;
00317     hwloc_bitmap_zero(nodeset);
00318     for(i=0; i<NUMA_NUM_NODES; i++)
00319       if (numa_bitmask_isbitset(bitmask, i)) {
00320         node = hwloc_get_obj_by_depth(topology, depth, i);
00321         if (node)
00322           hwloc_bitmap_set(nodeset, node->os_index);
00323       }
00324   } else {
00325     /* if no numa, libnuma assumes we have a single node */
00326     if (numa_bitmask_isbitset(bitmask, 0))
00327       hwloc_bitmap_fill(nodeset);
00328     else
00329       hwloc_bitmap_zero(nodeset);
00330   }
00331 
00332   return 0;
00333 }
00334 
00339 #ifdef NUMA_VERSION1_COMPATIBILITY
00340 
00350 static inline int
00351 hwloc_cpuset_to_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,
00352                                       nodemask_t *nodemask)
00353 {
00354   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00355 
00356   nodemask_zero(nodemask);
00357 
00358   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00359     hwloc_obj_t node = NULL;
00360     while ((node = hwloc_get_next_obj_covering_cpuset_by_type(topology, cpuset, HWLOC_OBJ_NODE, node)) != NULL)
00361       nodemask_set(nodemask, node->os_index);
00362   } else {
00363     /* if no numa, libnuma assumes we have a single node */
00364     if (!hwloc_bitmap_iszero(cpuset))
00365       nodemask_set(nodemask, 0);
00366   }
00367 
00368   return 0;
00369 }
00370 
00376 static inline int
00377 hwloc_nodeset_to_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,
00378                                         nodemask_t *nodemask)
00379 {
00380   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00381 
00382   nodemask_zero(nodemask);
00383 
00384   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00385     hwloc_obj_t node = NULL;
00386     while ((node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, node)) != NULL)
00387       if (hwloc_bitmap_isset(nodeset, node->os_index))
00388         nodemask_set(nodemask, node->os_index);
00389   } else {
00390     /* if no numa, libnuma assumes we have a single node */
00391     if (!hwloc_bitmap_iszero(nodeset))
00392       nodemask_set(nodemask, 0);
00393   }
00394 
00395   return 0;
00396 }
00397 
00403 static inline int
00404 hwloc_cpuset_from_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
00405                                         const nodemask_t *nodemask)
00406 {
00407   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00408 
00409   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00410     hwloc_obj_t node;
00411     int i;
00412     hwloc_bitmap_zero(cpuset);
00413     for(i=0; i<NUMA_NUM_NODES; i++)
00414       if (nodemask_isset(nodemask, i)) {
00415         node = hwloc_get_obj_by_depth(topology, depth, i);
00416         if (node)
00417           hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
00418       }
00419   } else {
00420     /* if no numa, libnuma assumes we have a single node */
00421     if (nodemask_isset(nodemask, 0))
00422       hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
00423     else
00424       hwloc_bitmap_zero(cpuset);
00425   }
00426 
00427   return 0;
00428 }
00429 
00435 static inline int
00436 hwloc_nodeset_from_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
00437                                           const nodemask_t *nodemask)
00438 {
00439   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00440 
00441   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00442     hwloc_obj_t node;
00443     int i;
00444     hwloc_bitmap_zero(nodeset);
00445     for(i=0; i<NUMA_NUM_NODES; i++)
00446       if (nodemask_isset(nodemask, i)) {
00447         node = hwloc_get_obj_by_depth(topology, depth, i);
00448         if (node)
00449           hwloc_bitmap_set(nodeset, node->os_index);
00450       }
00451   } else {
00452     /* if no numa, libnuma assumes we have a single node */
00453     if (nodemask_isset(nodemask, 0))
00454       hwloc_bitmap_fill(nodeset);
00455     else
00456       hwloc_bitmap_zero(nodeset);
00457   }
00458 
00459   return 0;
00460 }
00461 
00463 #endif /* NUMA_VERSION1_COMPATIBILITY */
00464 
00465 
00466 #ifdef __cplusplus
00467 } /* extern "C" */
00468 #endif
00469 
00470 
00471 #endif /* HWLOC_LINUX_NUMA_H */