Open MPI logo

Portable Hardware Locality (hwloc) Documentation: v1.4.2

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