root/opal/mca/hwloc/hwloc201/hwloc/include/hwloc/linux-libnuma.h

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hwloc_cpuset_to_linux_libnuma_ulongs
  2. hwloc_nodeset_to_linux_libnuma_ulongs
  3. hwloc_cpuset_from_linux_libnuma_ulongs
  4. hwloc_nodeset_from_linux_libnuma_ulongs
  5. hwloc_cpuset_to_linux_libnuma_bitmask
  6. hwloc_nodeset_to_linux_libnuma_bitmask
  7. hwloc_cpuset_from_linux_libnuma_bitmask
  8. hwloc_nodeset_from_linux_libnuma_bitmask

   1 /*
   2  * Copyright © 2009 CNRS
   3  * Copyright © 2009-2017 Inria.  All rights reserved.
   4  * Copyright © 2009-2010, 2012 Université Bordeaux
   5  * See COPYING in top-level directory.
   6  */
   7 
   8 /** \file
   9  * \brief Macros to help interaction between hwloc and Linux libnuma.
  10  *
  11  * Applications that use both Linux libnuma and hwloc may want to
  12  * include this file so as to ease conversion between their respective types.
  13 */
  14 
  15 #ifndef HWLOC_LINUX_LIBNUMA_H
  16 #define HWLOC_LINUX_LIBNUMA_H
  17 
  18 #include <hwloc.h>
  19 #include <numa.h>
  20 
  21 
  22 #ifdef __cplusplus
  23 extern "C" {
  24 #endif
  25 
  26 
  27 /** \defgroup hwlocality_linux_libnuma_ulongs Interoperability with Linux libnuma unsigned long masks
  28  *
  29  * This interface helps converting between Linux libnuma unsigned long masks
  30  * and hwloc cpusets and nodesets.
  31  *
  32  * \note Topology \p topology must match the current machine.
  33  *
  34  * \note The behavior of libnuma is undefined if the kernel is not NUMA-aware.
  35  * (when CONFIG_NUMA is not set in the kernel configuration).
  36  * This helper and libnuma may thus not be strictly compatible in this case,
  37  * which may be detected by checking whether numa_available() returns -1.
  38  *
  39  * @{
  40  */
  41 
  42 
  43 /** \brief Convert hwloc CPU set \p cpuset into the array of unsigned long \p mask
  44  *
  45  * \p mask is the array of unsigned long that will be filled.
  46  * \p maxnode contains the maximal node number that may be stored in \p mask.
  47  * \p maxnode will be set to the maximal node number that was found, plus one.
  48  *
  49  * This function may be used before calling set_mempolicy, mbind, migrate_pages
  50  * or any other function that takes an array of unsigned long and a maximal
  51  * node number as input parameter.
  52  */
  53 static __hwloc_inline int
  54 hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,
  55                                     unsigned long *mask, unsigned long *maxnode)
  56 {
  57   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
  58   unsigned long outmaxnode = -1;
  59   hwloc_obj_t node = NULL;
  60 
  61   /* round-up to the next ulong and clear all bytes */
  62   *maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);
  63   memset(mask, 0, *maxnode/8);
  64 
  65   while ((node = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, node)) != NULL) {
  66     if (node->os_index >= *maxnode)
  67       continue;
  68     mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));
  69     if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)
  70       outmaxnode = node->os_index;
  71   }
  72 
  73   *maxnode = outmaxnode+1;
  74   return 0;
  75 }
  76 
  77 /** \brief Convert hwloc NUMA node set \p nodeset into the array of unsigned long \p mask
  78  *
  79  * \p mask is the array of unsigned long that will be filled.
  80  * \p maxnode contains the maximal node number that may be stored in \p mask.
  81  * \p maxnode will be set to the maximal node number that was found, plus one.
  82  *
  83  * This function may be used before calling set_mempolicy, mbind, migrate_pages
  84  * or any other function that takes an array of unsigned long and a maximal
  85  * node number as input parameter.
  86  */
  87 static __hwloc_inline int
  88 hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,
  89                                       unsigned long *mask, unsigned long *maxnode)
  90 {
  91   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
  92   unsigned long outmaxnode = -1;
  93   hwloc_obj_t node = NULL;
  94 
  95   /* round-up to the next ulong and clear all bytes */
  96   *maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);
  97   memset(mask, 0, *maxnode/8);
  98 
  99   while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL) {
 100     if (node->os_index >= *maxnode)
 101       continue;
 102     if (!hwloc_bitmap_isset(nodeset, node->os_index))
 103       continue;
 104     mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));
 105     if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)
 106       outmaxnode = node->os_index;
 107   }
 108 
 109   *maxnode = outmaxnode+1;
 110   return 0;
 111 }
 112 
 113 /** \brief Convert the array of unsigned long \p mask into hwloc CPU set
 114  *
 115  * \p mask is a array of unsigned long that will be read.
 116  * \p maxnode contains the maximal node number that may be read in \p mask.
 117  *
 118  * This function may be used after calling get_mempolicy or any other function
 119  * that takes an array of unsigned long as output parameter (and possibly
 120  * a maximal node number as input parameter).
 121  */
 122 static __hwloc_inline int
 123 hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
 124                                       const unsigned long *mask, unsigned long maxnode)
 125 {
 126   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
 127   hwloc_obj_t node = NULL;
 128   hwloc_bitmap_zero(cpuset);
 129   while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
 130     if (node->os_index < maxnode
 131         && (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
 132       hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
 133   return 0;
 134 }
 135 
 136 /** \brief Convert the array of unsigned long \p mask into hwloc NUMA node set
 137  *
 138  * \p mask is a array of unsigned long that will be read.
 139  * \p maxnode contains the maximal node number that may be read in \p mask.
 140  *
 141  * This function may be used after calling get_mempolicy or any other function
 142  * that takes an array of unsigned long as output parameter (and possibly
 143  * a maximal node number as input parameter).
 144  */
 145 static __hwloc_inline int
 146 hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
 147                                         const unsigned long *mask, unsigned long maxnode)
 148 {
 149   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
 150   hwloc_obj_t node = NULL;
 151   hwloc_bitmap_zero(nodeset);
 152   while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
 153     if (node->os_index < maxnode
 154         && (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
 155       hwloc_bitmap_set(nodeset, node->os_index);
 156   return 0;
 157 }
 158 
 159 /** @} */
 160 
 161 
 162 
 163 /** \defgroup hwlocality_linux_libnuma_bitmask Interoperability with Linux libnuma bitmask
 164  *
 165  * This interface helps converting between Linux libnuma bitmasks
 166  * and hwloc cpusets and nodesets.
 167  *
 168  * \note Topology \p topology must match the current machine.
 169  *
 170  * \note The behavior of libnuma is undefined if the kernel is not NUMA-aware.
 171  * (when CONFIG_NUMA is not set in the kernel configuration).
 172  * This helper and libnuma may thus not be strictly compatible in this case,
 173  * which may be detected by checking whether numa_available() returns -1.
 174  *
 175  * @{
 176  */
 177 
 178 
 179 /** \brief Convert hwloc CPU set \p cpuset into the returned libnuma bitmask
 180  *
 181  * The returned bitmask should later be freed with numa_bitmask_free.
 182  *
 183  * This function may be used before calling many numa_ functions
 184  * that use a struct bitmask as an input parameter.
 185  *
 186  * \return newly allocated struct bitmask.
 187  */
 188 static __hwloc_inline struct bitmask *
 189 hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset) __hwloc_attribute_malloc;
 190 static __hwloc_inline struct bitmask *
 191 hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset)
 192 {
 193   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
 194   hwloc_obj_t node = NULL;
 195   struct bitmask *bitmask = numa_allocate_cpumask();
 196   if (!bitmask)
 197     return NULL;
 198   while ((node = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, node)) != NULL)
 199     if (node->attr->numanode.local_memory)
 200       numa_bitmask_setbit(bitmask, node->os_index);
 201   return bitmask;
 202 }
 203 
 204 /** \brief Convert hwloc NUMA node set \p nodeset into the returned libnuma bitmask
 205  *
 206  * The returned bitmask should later be freed with numa_bitmask_free.
 207  *
 208  * This function may be used before calling many numa_ functions
 209  * that use a struct bitmask as an input parameter.
 210  *
 211  * \return newly allocated struct bitmask.
 212  */
 213 static __hwloc_inline struct bitmask *
 214 hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset) __hwloc_attribute_malloc;
 215 static __hwloc_inline struct bitmask *
 216 hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset)
 217 {
 218   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
 219   hwloc_obj_t node = NULL;
 220   struct bitmask *bitmask = numa_allocate_cpumask();
 221   if (!bitmask)
 222     return NULL;
 223   while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
 224     if (hwloc_bitmap_isset(nodeset, node->os_index) && node->attr->numanode.local_memory)
 225       numa_bitmask_setbit(bitmask, node->os_index);
 226   return bitmask;
 227 }
 228 
 229 /** \brief Convert libnuma bitmask \p bitmask into hwloc CPU set \p cpuset
 230  *
 231  * This function may be used after calling many numa_ functions
 232  * that use a struct bitmask as an output parameter.
 233  */
 234 static __hwloc_inline int
 235 hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
 236                                         const struct bitmask *bitmask)
 237 {
 238   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
 239   hwloc_obj_t node = NULL;
 240   hwloc_bitmap_zero(cpuset);
 241   while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
 242     if (numa_bitmask_isbitset(bitmask, node->os_index))
 243       hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
 244   return 0;
 245 }
 246 
 247 /** \brief Convert libnuma bitmask \p bitmask into hwloc NUMA node set \p nodeset
 248  *
 249  * This function may be used after calling many numa_ functions
 250  * that use a struct bitmask as an output parameter.
 251  */
 252 static __hwloc_inline int
 253 hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
 254                                          const struct bitmask *bitmask)
 255 {
 256   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
 257   hwloc_obj_t node = NULL;
 258   hwloc_bitmap_zero(nodeset);
 259   while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
 260     if (numa_bitmask_isbitset(bitmask, node->os_index))
 261       hwloc_bitmap_set(nodeset, node->os_index);
 262   return 0;
 263 }
 264 
 265 /** @} */
 266 
 267 
 268 #ifdef __cplusplus
 269 } /* extern "C" */
 270 #endif
 271 
 272 
 273 #endif /* HWLOC_LINUX_NUMA_H */

/* [<][>][^][v][top][bottom][index][help] */