Open MPI logo

Portable Hardware Locality (hwloc) Documentation: v1.3.2

  |   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       if (node->memory.local_memory)
00231         numa_bitmask_setbit(bitmask, node->os_index);
00232   } else {
00233     /* if no numa, libnuma assumes we have a single node */
00234     if (!hwloc_bitmap_iszero(cpuset))
00235       numa_bitmask_setbit(bitmask, 0);
00236   }
00237 
00238   return bitmask;
00239 }
00240 
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;
00285     int i;
00286     hwloc_bitmap_zero(cpuset);
00287     for(i=0; i<NUMA_NUM_NODES; i++)
00288       if (numa_bitmask_isbitset(bitmask, i)) {
00289         node = hwloc_get_obj_by_depth(topology, depth, i);
00290         if (node)
00291           hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
00292       }
00293   } else {
00294     /* if no numa, libnuma assumes we have a single node */
00295     if (numa_bitmask_isbitset(bitmask, 0))
00296       hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
00297     else
00298       hwloc_bitmap_zero(cpuset);
00299   }
00300 
00301   return 0;
00302 }
00303 
00309 static inline int
00310 hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
00311                                          const struct bitmask *bitmask)
00312 {
00313   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00314 
00315   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00316     hwloc_obj_t node;
00317     int i;
00318     hwloc_bitmap_zero(nodeset);
00319     for(i=0; i<NUMA_NUM_NODES; i++)
00320       if (numa_bitmask_isbitset(bitmask, i)) {
00321         node = hwloc_get_obj_by_depth(topology, depth, i);
00322         if (node)
00323           hwloc_bitmap_set(nodeset, node->os_index);
00324       }
00325   } else {
00326     /* if no numa, libnuma assumes we have a single node */
00327     if (numa_bitmask_isbitset(bitmask, 0))
00328       hwloc_bitmap_fill(nodeset);
00329     else
00330       hwloc_bitmap_zero(nodeset);
00331   }
00332 
00333   return 0;
00334 }
00335 
00340 #ifdef NUMA_VERSION1_COMPATIBILITY
00341 
00351 static inline int
00352 hwloc_cpuset_to_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,
00353                                       nodemask_t *nodemask)
00354 {
00355   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00356 
00357   nodemask_zero(nodemask);
00358 
00359   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00360     hwloc_obj_t node = NULL;
00361     while ((node = hwloc_get_next_obj_covering_cpuset_by_type(topology, cpuset, HWLOC_OBJ_NODE, node)) != NULL)
00362       nodemask_set(nodemask, node->os_index);
00363   } else {
00364     /* if no numa, libnuma assumes we have a single node */
00365     if (!hwloc_bitmap_iszero(cpuset))
00366       nodemask_set(nodemask, 0);
00367   }
00368 
00369   return 0;
00370 }
00371 
00377 static inline int
00378 hwloc_nodeset_to_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,
00379                                         nodemask_t *nodemask)
00380 {
00381   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00382 
00383   nodemask_zero(nodemask);
00384 
00385   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00386     hwloc_obj_t node = NULL;
00387     while ((node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, node)) != NULL)
00388       if (hwloc_bitmap_isset(nodeset, node->os_index))
00389         nodemask_set(nodemask, node->os_index);
00390   } else {
00391     /* if no numa, libnuma assumes we have a single node */
00392     if (!hwloc_bitmap_iszero(nodeset))
00393       nodemask_set(nodemask, 0);
00394   }
00395 
00396   return 0;
00397 }
00398 
00404 static inline int
00405 hwloc_cpuset_from_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
00406                                         const nodemask_t *nodemask)
00407 {
00408   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00409 
00410   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00411     hwloc_obj_t node;
00412     int i;
00413     hwloc_bitmap_zero(cpuset);
00414     for(i=0; i<NUMA_NUM_NODES; i++)
00415       if (nodemask_isset(nodemask, i)) {
00416         node = hwloc_get_obj_by_depth(topology, depth, i);
00417         if (node)
00418           hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
00419       }
00420   } else {
00421     /* if no numa, libnuma assumes we have a single node */
00422     if (nodemask_isset(nodemask, 0))
00423       hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
00424     else
00425       hwloc_bitmap_zero(cpuset);
00426   }
00427 
00428   return 0;
00429 }
00430 
00436 static inline int
00437 hwloc_nodeset_from_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
00438                                           const nodemask_t *nodemask)
00439 {
00440   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
00441 
00442   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
00443     hwloc_obj_t node;
00444     int i;
00445     hwloc_bitmap_zero(nodeset);
00446     for(i=0; i<NUMA_NUM_NODES; i++)
00447       if (nodemask_isset(nodemask, i)) {
00448         node = hwloc_get_obj_by_depth(topology, depth, i);
00449         if (node)
00450           hwloc_bitmap_set(nodeset, node->os_index);
00451       }
00452   } else {
00453     /* if no numa, libnuma assumes we have a single node */
00454     if (nodemask_isset(nodemask, 0))
00455       hwloc_bitmap_fill(nodeset);
00456     else
00457       hwloc_bitmap_zero(nodeset);
00458   }
00459 
00460   return 0;
00461 }
00462 
00464 #endif /* NUMA_VERSION1_COMPATIBILITY */
00465 
00466 
00467 #ifdef __cplusplus
00468 } /* extern "C" */
00469 #endif
00470 
00471 
00472 #endif /* HWLOC_LINUX_NUMA_H */