1 /*
2  * Copyright © 2009 CNRS
3  * Copyright © 2009-2017 Inria.  All rights reserved.
4  * Copyright © 2009-2010 Université Bordeaux
5  * Copyright © 2011 Cisco Systems, Inc.  All rights reserved.
6  * See COPYING in top-level directory.
7  */
8 
9 #include "hwloc.h"
10 
11 #include <assert.h>
12 
13 #define NUMA_VERSION1_COMPATIBILITY
14 #include "hwloc/linux-libnuma.h"
15 
16 /* check the linux libnuma helpers */
17 
main(void)18 int main(void)
19 {
20   hwloc_topology_t topology;
21   hwloc_bitmap_t set, set2, nocpunomemnodeset, nocpubutmemnodeset, nomembutcpunodeset, nomembutcpucpuset;
22   hwloc_obj_t node;
23   struct bitmask *bitmask, *bitmask2;
24   unsigned long mask;
25   unsigned long maxnode;
26   int i;
27 
28   if (numa_available() < 0)
29     /* libnuma has inconsistent behavior when the kernel isn't NUMA-aware.
30      * don't try to check everything precisely.
31      */
32     exit(77);
33 
34   hwloc_topology_init(&topology);
35   hwloc_topology_load(topology);
36 
37   /* convert full stuff between cpuset and libnuma */
38   set = hwloc_bitmap_alloc();
39   nocpunomemnodeset = hwloc_bitmap_alloc();
40   nocpubutmemnodeset = hwloc_bitmap_alloc();
41   nomembutcpunodeset = hwloc_bitmap_alloc();
42   nomembutcpucpuset = hwloc_bitmap_alloc();
43   /* gather all nodes if any */
44   node = NULL;
45   while ((node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NUMANODE, node)) != NULL) {
46     hwloc_bitmap_or(set, set, node->cpuset);
47     if (hwloc_bitmap_iszero(node->cpuset)) {
48       if (node->attr->numanode.local_memory)
49         hwloc_bitmap_set(nocpubutmemnodeset, node->os_index);
50       else
51 	hwloc_bitmap_set(nocpunomemnodeset, node->os_index);
52     } else if (!node->attr->numanode.local_memory) {
53       hwloc_bitmap_set(nomembutcpunodeset, node->os_index);
54       hwloc_bitmap_or(nomembutcpucpuset, nomembutcpucpuset, node->cpuset);
55     }
56   }
57 
58   set2 = hwloc_bitmap_alloc();
59   hwloc_cpuset_from_linux_libnuma_bitmask(topology, set2, numa_all_nodes_ptr);
60   /* numa_all_nodes_ptr doesn't contain NODES with CPU but no memory */
61   hwloc_bitmap_or(set2, set2, nomembutcpucpuset);
62   assert(hwloc_bitmap_isequal(set, set2));
63   hwloc_bitmap_free(set2);
64 
65   bitmask = hwloc_cpuset_to_linux_libnuma_bitmask(topology, set);
66   /* numa_all_nodes_ptr contains NODES with no CPU but with memory */
67   hwloc_bitmap_foreach_begin(i, nocpubutmemnodeset) { numa_bitmask_setbit(bitmask, i); } hwloc_bitmap_foreach_end();
68   assert(numa_bitmask_equal(bitmask, numa_all_nodes_ptr));
69   numa_bitmask_free(bitmask);
70 
71   hwloc_bitmap_free(set);
72 
73   /* convert full stuff between nodeset and libnuma */
74   set = hwloc_bitmap_dup(hwloc_get_root_obj(topology)->complete_nodeset);
75 
76   set2 = hwloc_bitmap_alloc();
77   hwloc_nodeset_from_linux_libnuma_bitmask(topology, set2, numa_all_nodes_ptr);
78   /* numa_all_nodes_ptr doesn't contain NODES with no CPU and no memory */
79   hwloc_bitmap_foreach_begin(i, nocpunomemnodeset) { hwloc_bitmap_set(set2, i); } hwloc_bitmap_foreach_end();
80   /* numa_all_nodes_ptr doesn't contain NODES with CPU but no memory */
81   hwloc_bitmap_or(set2, set2, nomembutcpunodeset);
82   assert(hwloc_bitmap_isequal(set, set2));
83   hwloc_bitmap_free(set2);
84 
85   bitmask = hwloc_nodeset_to_linux_libnuma_bitmask(topology, set);
86   assert(numa_bitmask_equal(bitmask, numa_all_nodes_ptr));
87   numa_bitmask_free(bitmask);
88 
89   hwloc_bitmap_free(set);
90 
91   /* convert empty stuff between cpuset and libnuma */
92   bitmask = numa_bitmask_alloc(1);
93   set = hwloc_bitmap_alloc();
94   hwloc_cpuset_from_linux_libnuma_bitmask(topology, set, bitmask);
95   numa_bitmask_free(bitmask);
96   assert(hwloc_bitmap_iszero(set));
97   hwloc_bitmap_free(set);
98 
99   mask=0;
100   set = hwloc_bitmap_alloc();
101   hwloc_cpuset_from_linux_libnuma_ulongs(topology, set, &mask, sizeof(mask)*8);
102   assert(hwloc_bitmap_iszero(set));
103   hwloc_bitmap_free(set);
104 
105   set = hwloc_bitmap_alloc();
106   bitmask = hwloc_cpuset_to_linux_libnuma_bitmask(topology, set);
107   bitmask2 = numa_bitmask_alloc(1);
108   assert(numa_bitmask_equal(bitmask, bitmask2));
109   numa_bitmask_free(bitmask);
110   numa_bitmask_free(bitmask2);
111   hwloc_bitmap_free(set);
112 
113   set = hwloc_bitmap_alloc();
114   maxnode = sizeof(mask)*8;
115   hwloc_cpuset_to_linux_libnuma_ulongs(topology, set, &mask, &maxnode);
116   assert(!mask);
117   assert(!maxnode);
118   hwloc_bitmap_free(set);
119 
120   /* convert empty stuff between nodeset and libnuma */
121   bitmask = numa_bitmask_alloc(1);
122   set = hwloc_bitmap_alloc();
123   hwloc_nodeset_from_linux_libnuma_bitmask(topology, set, bitmask);
124   numa_bitmask_free(bitmask);
125   assert(hwloc_bitmap_iszero(set));
126   hwloc_bitmap_free(set);
127 
128   mask=0;
129   set = hwloc_bitmap_alloc();
130   hwloc_nodeset_from_linux_libnuma_ulongs(topology, set, &mask, sizeof(mask)*8);
131   assert(hwloc_bitmap_iszero(set));
132   hwloc_bitmap_free(set);
133 
134   set = hwloc_bitmap_alloc();
135   bitmask = hwloc_nodeset_to_linux_libnuma_bitmask(topology, set);
136   bitmask2 = numa_bitmask_alloc(1);
137   assert(numa_bitmask_equal(bitmask, bitmask2));
138   numa_bitmask_free(bitmask);
139   numa_bitmask_free(bitmask2);
140   hwloc_bitmap_free(set);
141 
142   set = hwloc_bitmap_alloc();
143   maxnode = sizeof(mask)*8;
144   hwloc_nodeset_to_linux_libnuma_ulongs(topology, set, &mask, &maxnode);
145   assert(!mask);
146   assert(!maxnode);
147   hwloc_bitmap_free(set);
148 
149   /* convert first node (with CPU and memory) between cpuset/nodeset and libnuma */
150   node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NUMANODE, NULL);
151   while (node && (!node->attr->numanode.local_memory || hwloc_bitmap_iszero(node->cpuset)))
152     /* skip nodes with no cpus or no memory to avoid strange libnuma behaviors */
153     node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NUMANODE, node);
154   if (node) {
155     /* convert first node between cpuset and libnuma */
156     bitmask = hwloc_cpuset_to_linux_libnuma_bitmask(topology, node->cpuset);
157     assert(numa_bitmask_isbitset(bitmask, node->os_index));
158     numa_bitmask_clearbit(bitmask, node->os_index);
159     bitmask2 = numa_bitmask_alloc(node->os_index + 1);
160     assert(numa_bitmask_equal(bitmask, bitmask2));
161     numa_bitmask_free(bitmask);
162     numa_bitmask_free(bitmask2);
163 
164     maxnode = sizeof(mask)*8;
165     hwloc_cpuset_to_linux_libnuma_ulongs(topology, node->cpuset, &mask, &maxnode);
166     if (node->os_index >= sizeof(mask)*8) {
167       assert(!maxnode);
168       assert(!mask);
169     } else {
170       assert(maxnode == node->os_index + 1);
171       assert(mask == (1UL << node->os_index));
172     }
173 
174     set = hwloc_bitmap_alloc();
175     bitmask = numa_bitmask_alloc(node->os_index + 1);
176     numa_bitmask_setbit(bitmask, node->os_index);
177     hwloc_cpuset_from_linux_libnuma_bitmask(topology, set, bitmask);
178     numa_bitmask_free(bitmask);
179     assert(hwloc_bitmap_isequal(set, node->cpuset));
180     hwloc_bitmap_free(set);
181 
182     set = hwloc_bitmap_alloc();
183     if (node->os_index >= sizeof(mask)*8) {
184       mask = 0;
185     } else {
186       mask = 1UL << node->os_index;
187     }
188     hwloc_cpuset_from_linux_libnuma_ulongs(topology, set, &mask, node->os_index + 1);
189     assert(hwloc_bitmap_isequal(set, node->cpuset));
190     hwloc_bitmap_free(set);
191 
192     /* convert first node between nodeset and libnuma */
193     bitmask = hwloc_nodeset_to_linux_libnuma_bitmask(topology, node->nodeset);
194     assert(numa_bitmask_isbitset(bitmask, node->os_index));
195     numa_bitmask_clearbit(bitmask, node->os_index);
196     bitmask2 = numa_bitmask_alloc(node->os_index + 1);
197     assert(numa_bitmask_equal(bitmask, bitmask2));
198     numa_bitmask_free(bitmask);
199     numa_bitmask_free(bitmask2);
200 
201     maxnode = sizeof(mask)*8;
202     hwloc_nodeset_to_linux_libnuma_ulongs(topology, node->nodeset, &mask, &maxnode);
203     if (node->os_index >= sizeof(mask)*8) {
204       assert(!maxnode);
205       assert(!mask);
206     } else {
207       assert(maxnode == node->os_index + 1);
208       assert(mask == (1UL << node->os_index));
209     }
210 
211     set = hwloc_bitmap_alloc();
212     bitmask = numa_bitmask_alloc(node->os_index + 1);
213     numa_bitmask_setbit(bitmask, node->os_index);
214     hwloc_nodeset_from_linux_libnuma_bitmask(topology, set, bitmask);
215     numa_bitmask_free(bitmask);
216     assert(hwloc_bitmap_isequal(set, node->nodeset));
217     hwloc_bitmap_free(set);
218 
219     set = hwloc_bitmap_alloc();
220     if (node->os_index >= sizeof(mask)*8) {
221       mask = 0;
222     } else {
223       mask = 1UL << node->os_index;
224     }
225     hwloc_nodeset_from_linux_libnuma_ulongs(topology, set, &mask, node->os_index + 1);
226     assert(hwloc_bitmap_isequal(set, node->nodeset));
227     hwloc_bitmap_free(set);
228   }
229 
230   hwloc_bitmap_free(nomembutcpucpuset);
231   hwloc_bitmap_free(nomembutcpunodeset);
232   hwloc_bitmap_free(nocpubutmemnodeset);
233   hwloc_bitmap_free(nocpunomemnodeset);
234 
235   hwloc_topology_destroy(topology);
236   return 0;
237 }
238