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