Open MPI logo

Portable Hardware Locality (hwloc) Documentation: v1.3

  |   Home   |   Support   |   FAQ   |  
linux-libnuma.h
Go to the documentation of this file.
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 
00015 #ifndef HWLOC_LINUX_LIBNUMA_H
00016 #define HWLOC_LINUX_LIBNUMA_H
00017 
00018 #include <hwloc.h>
00019 #include <numa.h>
00020 
00021 
00022 #ifdef __cplusplus
00023 extern "C" {
00024 #endif
00025 
00026 
00042 static inline int
00043 hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,
00044                                     unsigned long *mask, unsigned long *maxnode)
00045 {
00046   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00047   unsigned long outmaxnode = -1;
00048 
00049   /* round-up to the next ulong and clear all bytes */
00050   *maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);
00051   memset(mask, 0, *maxnode/8);
00052 
00053   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00054     hwloc_obj_t node = NULL;
00055     while ((node = hwloc_get_next_obj_covering_cpuset_by_type(topology, cpuset, HWLOC_OBJ_NODE, node)) != NULL) {
00056       if (node->os_index >= *maxnode)
00057         continue;
00058       mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));
00059       if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)
00060         outmaxnode = node->os_index;
00061     }
00062 
00063   } else {
00064     /* if no numa, libnuma assumes we have a single node */
00065     if (!hwloc_bitmap_iszero(cpuset)) {
00066       mask[0] = 1;
00067       outmaxnode = 0;
00068     }
00069   }
00070 
00071   *maxnode = outmaxnode+1;
00072   return 0;
00073 }
00074 
00085 static inline int
00086 hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,
00087                                       unsigned long *mask, unsigned long *maxnode)
00088 {
00089   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00090   unsigned long outmaxnode = -1;
00091 
00092   /* round-up to the next ulong and clear all bytes */
00093   *maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);
00094   memset(mask, 0, *maxnode/8);
00095 
00096   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00097     hwloc_obj_t node = NULL;
00098     while ((node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, node)) != NULL) {
00099       if (node->os_index >= *maxnode)
00100         continue;
00101       if (!hwloc_bitmap_isset(nodeset, node->os_index))
00102         continue;
00103       mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));
00104       if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)
00105         outmaxnode = node->os_index;
00106     }
00107 
00108   } else {
00109     /* if no numa, libnuma assumes we have a single node */
00110     if (!hwloc_bitmap_iszero(nodeset)) {
00111       mask[0] = 1;
00112       outmaxnode = 0;
00113     }
00114   }
00115 
00116   *maxnode = outmaxnode+1;
00117   return 0;
00118 }
00119 
00129 static inline int
00130 hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
00131                                       const unsigned long *mask, unsigned long maxnode)
00132 {
00133   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00134 
00135   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00136     hwloc_obj_t node;
00137     unsigned i;
00138     hwloc_bitmap_zero(cpuset);
00139     for(i=0; i<maxnode; i++)
00140       if (mask[i/sizeof(*mask)/8] & (1UL << (i% (sizeof(*mask)*8)))) {
00141         node = hwloc_get_obj_by_depth(topology, depth, i);
00142         if (node)
00143           hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
00144       }
00145   } else {
00146     /* if no numa, libnuma assumes we have a single node */
00147     if (mask[0] & 1)
00148       hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
00149     else
00150       hwloc_bitmap_zero(cpuset);
00151   }
00152 
00153   return 0;
00154 }
00155 
00165 static inline int
00166 hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
00167                                         const unsigned long *mask, unsigned long maxnode)
00168 {
00169   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00170 
00171   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00172     hwloc_obj_t node;
00173     unsigned i;
00174     hwloc_bitmap_zero(nodeset);
00175     for(i=0; i<maxnode; i++)
00176       if (mask[i/sizeof(*mask)/8] & (1UL << (i% (sizeof(*mask)*8)))) {
00177         node = hwloc_get_obj_by_depth(topology, depth, i);
00178         if (node)
00179           hwloc_bitmap_set(nodeset, node->os_index);
00180       }
00181   } else {
00182     /* if no numa, libnuma assumes we have a single node */
00183     if (mask[0] & 1)
00184       hwloc_bitmap_fill(nodeset);
00185     else
00186       hwloc_bitmap_zero(nodeset);
00187   }
00188 
00189   return 0;
00190 }
00191 
00210 static inline struct bitmask * 
00211 hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset)
00212 {
00213   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00214   struct bitmask *bitmask = numa_allocate_cpumask();
00215   if (!bitmask)
00216     return NULL;
00217 
00218   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00219     hwloc_obj_t node = NULL;
00220     while ((node = hwloc_get_next_obj_covering_cpuset_by_type(topology, cpuset, HWLOC_OBJ_NODE, node)) != NULL)
00221       numa_bitmask_setbit(bitmask, node->os_index);
00222   } else {
00223     /* if no numa, libnuma assumes we have a single node */
00224     if (!hwloc_bitmap_iszero(cpuset))
00225       numa_bitmask_setbit(bitmask, 0);
00226   }
00227 
00228   return bitmask;
00229 }
00230 
00240 static inline struct bitmask * 
00241 hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset)
00242 {
00243   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00244   struct bitmask *bitmask = numa_allocate_cpumask();
00245   if (!bitmask)
00246     return NULL;
00247 
00248   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00249     hwloc_obj_t node = NULL;
00250     while ((node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, node)) != NULL)
00251       if (hwloc_bitmap_isset(nodeset, node->os_index))
00252         numa_bitmask_setbit(bitmask, node->os_index);
00253   } else {
00254     /* if no numa, libnuma assumes we have a single node */
00255     if (!hwloc_bitmap_iszero(nodeset))
00256       numa_bitmask_setbit(bitmask, 0);
00257   }
00258 
00259   return bitmask;
00260 }
00261 
00267 static inline int
00268 hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
00269                                         const struct bitmask *bitmask)
00270 {
00271   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00272 
00273   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00274     hwloc_obj_t node;
00275     int i;
00276     hwloc_bitmap_zero(cpuset);
00277     for(i=0; i<NUMA_NUM_NODES; i++)
00278       if (numa_bitmask_isbitset(bitmask, i)) {
00279         node = hwloc_get_obj_by_depth(topology, depth, i);
00280         if (node)
00281           hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
00282       }
00283   } else {
00284     /* if no numa, libnuma assumes we have a single node */
00285     if (numa_bitmask_isbitset(bitmask, 0))
00286       hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
00287     else
00288       hwloc_bitmap_zero(cpuset);
00289   }
00290 
00291   return 0;
00292 }
00293 
00299 static inline int
00300 hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
00301                                          const struct bitmask *bitmask)
00302 {
00303   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00304 
00305   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00306     hwloc_obj_t node;
00307     int i;
00308     hwloc_bitmap_zero(nodeset);
00309     for(i=0; i<NUMA_NUM_NODES; i++)
00310       if (numa_bitmask_isbitset(bitmask, i)) {
00311         node = hwloc_get_obj_by_depth(topology, depth, i);
00312         if (node)
00313           hwloc_bitmap_set(nodeset, node->os_index);
00314       }
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 
00341 static inline int
00342 hwloc_cpuset_to_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,
00343                                       nodemask_t *nodemask)
00344 {
00345   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00346 
00347   nodemask_zero(nodemask);
00348 
00349   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00350     hwloc_obj_t node = NULL;
00351     while ((node = hwloc_get_next_obj_covering_cpuset_by_type(topology, cpuset, HWLOC_OBJ_NODE, node)) != NULL)
00352       nodemask_set(nodemask, node->os_index);
00353   } else {
00354     /* if no numa, libnuma assumes we have a single node */
00355     if (!hwloc_bitmap_iszero(cpuset))
00356       nodemask_set(nodemask, 0);
00357   }
00358 
00359   return 0;
00360 }
00361 
00367 static inline int
00368 hwloc_nodeset_to_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,
00369                                         nodemask_t *nodemask)
00370 {
00371   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00372 
00373   nodemask_zero(nodemask);
00374 
00375   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00376     hwloc_obj_t node = NULL;
00377     while ((node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, node)) != NULL)
00378       if (hwloc_bitmap_isset(nodeset, node->os_index))
00379         nodemask_set(nodemask, node->os_index);
00380   } else {
00381     /* if no numa, libnuma assumes we have a single node */
00382     if (!hwloc_bitmap_iszero(nodeset))
00383       nodemask_set(nodemask, 0);
00384   }
00385 
00386   return 0;
00387 }
00388 
00394 static inline int
00395 hwloc_cpuset_from_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
00396                                         const nodemask_t *nodemask)
00397 {
00398   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00399 
00400   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00401     hwloc_obj_t node;
00402     int i;
00403     hwloc_bitmap_zero(cpuset);
00404     for(i=0; i<NUMA_NUM_NODES; i++)
00405       if (nodemask_isset(nodemask, i)) {
00406         node = hwloc_get_obj_by_depth(topology, depth, i);
00407         if (node)
00408           hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
00409       }
00410   } else {
00411     /* if no numa, libnuma assumes we have a single node */
00412     if (nodemask_isset(nodemask, 0))
00413       hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
00414     else
00415       hwloc_bitmap_zero(cpuset);
00416   }
00417 
00418   return 0;
00419 }
00420 
00426 static inline int
00427 hwloc_nodeset_from_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
00428                                           const nodemask_t *nodemask)
00429 {
00430   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00431 
00432   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00433     hwloc_obj_t node;
00434     int i;
00435     hwloc_bitmap_zero(nodeset);
00436     for(i=0; i<NUMA_NUM_NODES; i++)
00437       if (nodemask_isset(nodemask, i)) {
00438         node = hwloc_get_obj_by_depth(topology, depth, i);
00439         if (node)
00440           hwloc_bitmap_set(nodeset, node->os_index);
00441       }
00442   } else {
00443     /* if no numa, libnuma assumes we have a single node */
00444     if (nodemask_isset(nodemask, 0))
00445       hwloc_bitmap_fill(nodeset);
00446     else
00447       hwloc_bitmap_zero(nodeset);
00448   }
00449 
00450   return 0;
00451 }
00452 
00454 #endif /* NUMA_VERSION1_COMPATIBILITY */
00455 
00456 
00457 #ifdef __cplusplus
00458 } /* extern "C" */
00459 #endif
00460 
00461 
00462 #endif /* HWLOC_LINUX_NUMA_H */