1 /*
2  * Copyright © 2017-2020 Inria.  All rights reserved.
3  * See COPYING in top-level directory.
4  */
5 
6 #include "hwloc.h"
7 #include "private/debug.h" /* HWLOC_BUILD_ASSERT */
8 #include "private/private.h" /* for struct topology fields */
9 
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <assert.h>
14 #include <stddef.h>
15 
main(void)16 int main(void)
17 {
18   hwloc_topology_t topo, dup;
19   int err;
20 
21   printf("loading and checking...\n");
22   err = hwloc_topology_init(&topo);
23   assert(!err);
24   err = hwloc_topology_load(topo);
25   assert(!err);
26   err = hwloc_topology_abi_check(topo);
27   assert(!err);
28 
29   printf("dupping and checking\n");
30   err = hwloc_topology_dup(&dup, topo);
31   assert(!err);
32   err = hwloc_topology_abi_check(dup);
33   assert(!err);
34   hwloc_topology_destroy(dup);
35 
36 #if (defined HWLOC_LINUX_SYS) && (defined HWLOC_X86_64_ARCH)
37   if (!getenv("HWLOC_IGNORE_TOPOLOGY_ABI")) {
38     size_t size, offset __hwloc_attribute_unused;
39     printf("checking offsets and sizes in struct hwloc_topology for topology ABI 0x%x...\n", (unsigned) HWLOC_TOPOLOGY_ABI);
40 
41     /*******************************************************************
42      * WARNING: if anything breaks below, the topology ABI has changed.
43      * HWLOC_TOPOLOGY_ABI must be bumped when updating these checks.
44      *******************************************************************/
45 
46     HWLOC_BUILD_ASSERT(HWLOC_OBJ_TYPE_MAX == 20);
47     HWLOC_BUILD_ASSERT(HWLOC_NR_SLEVELS == 6);
48 
49     offset = offsetof(struct hwloc_topology, topology_abi);
50     assert(offset == 0);
51 
52     offset = offsetof(struct hwloc_topology, adopted_shmem_addr);
53     assert(offset == 232);
54 
55     offset = offsetof(struct hwloc_topology, binding_hooks);
56     assert(offset == 456);
57     size = sizeof(struct hwloc_binding_hooks);
58     assert(size == 192);
59 
60     offset = offsetof(struct hwloc_topology, support);
61     assert(offset == 648);
62 
63     offset = offsetof(struct hwloc_topology, first_dist);
64     assert(offset == 704);
65     size = sizeof(struct hwloc_internal_distances_s);
66     assert(size == 88);
67 
68     offset = offsetof(struct hwloc_topology, memattrs);
69     assert(offset == 728);
70     size = sizeof(struct hwloc_internal_memattr_s);
71     assert(size == 32);
72     size = sizeof(struct hwloc_internal_memattr_target_s);
73     assert(size == 48);
74     size = sizeof(struct hwloc_internal_memattr_initiator_s);
75     assert(size == 40);
76     size = sizeof(struct hwloc_internal_location_s);
77     assert(size == 32);
78 
79     offset = offsetof(struct hwloc_topology, cpukinds);
80     assert(offset == 744);
81     size = sizeof(struct hwloc_internal_cpukind_s);
82     assert(size == 40);
83 
84     offset = offsetof(struct hwloc_topology, grouping_next_subkind);
85     assert(offset == 784);
86 
87     /* fields after this one aren't needed after discovery */
88 
89     /* check bitmap ABI too, but those fields are private to bitmap.c */
90     printf("checking bitmaps for topology ABI 0x%x...\n", (unsigned) HWLOC_TOPOLOGY_ABI);
91     {
92       hwloc_bitmap_t set = hwloc_bitmap_alloc();
93       unsigned *ulongs_count =     (unsigned*)       (((char*)set)   );
94       unsigned *ulongs_allocated = (unsigned*)       (((char*)set)+4 );
95       unsigned long **ulongs =     (unsigned long**) (((char*)set)+8 );
96       int *infinite =              (int*)            (((char*)set)+16);
97 
98       /* empty set */
99       assert(*ulongs_count >= 1);
100       assert(*ulongs_allocated >= *ulongs_count);
101       assert((*ulongs)[0] == 0UL);
102       assert(!*infinite);
103 
104       /* 260th bit */
105       hwloc_bitmap_set(set, 260);
106       assert(*ulongs_count >= 5);
107       assert(*ulongs_allocated >= *ulongs_count);
108       assert((*ulongs)[0] == 0UL);
109       assert((*ulongs)[1] == 0UL);
110       assert((*ulongs)[2] == 0UL);
111       assert((*ulongs)[3] == 0UL);
112       assert((*ulongs)[4] == 0x10UL);
113       assert(!*infinite);
114 
115       /* full set */
116       hwloc_bitmap_fill(set);
117       assert((*ulongs)[0] == ~0UL);
118       assert(*infinite);
119 
120       hwloc_bitmap_free(set);
121     }
122 
123     /*******************************************************************
124      * WARNING: if anything breaks above, the topology ABI has changed.
125      * HWLOC_TOPOLOGY_ABI must be bumped when updating these checks.
126      *******************************************************************/
127 
128     printf("checking sizes of public objects...\n");
129 
130     /* if these first lines break, you may be breaking the main library ABI.
131      * adding fields may be OK. changing/removing likely isn't.
132      */
133     size = sizeof(struct hwloc_obj);
134     assert(size == 248);
135     size = sizeof(union hwloc_obj_attr_u);
136 #ifdef HWLOC_HAVE_32BITS_PCI_DOMAIN
137     assert(size == 48);
138 #else
139     assert(size == 40);
140 #endif
141     size = sizeof(struct hwloc_info_s);
142     assert(size == 16);
143 
144     size = sizeof(struct hwloc_topology_support);
145     assert(size == 32);
146     size = sizeof(struct hwloc_topology_discovery_support);
147     assert(size == 6);
148     size = sizeof(struct hwloc_topology_cpubind_support);
149     assert(size == 11);
150     size = sizeof(struct hwloc_topology_membind_support);
151     assert(size == 15);
152     size = sizeof(struct hwloc_topology_misc_support);
153     assert(size == 1);
154 
155     size = sizeof(struct hwloc_distances_s);
156     assert(size == 32);
157 
158     size = sizeof(struct hwloc_location);
159     assert(size == 16);
160 
161     size = sizeof(union hwloc_topology_diff_u);
162     assert(size == 56);
163     size = sizeof(union hwloc_topology_diff_obj_attr_u);
164     assert(size == 32);
165 
166   } else {
167     /* if building with non-binary-compatible compiler flags */
168     printf("checking topology ABI disabled by environment variable HWLOC_IGNORE_TOPOLOGY_ABI\n");
169   }
170 #else /* !LINUX || !X86_64 */
171   printf("checking topology ABI disabled, not running on Linux/x86_64\n");
172 #endif /* !LINUX || !X86_64 */
173 
174   hwloc_topology_destroy(topo);
175 
176   return 0;
177 }
178