1 /*
2  * Copyright © 2016-2020 Inria.  All rights reserved.
3  * See COPYING in top-level directory.
4  */
5 
6 #include <stdio.h>
7 #include <errno.h>
8 
9 #include "hwloc.h"
10 #include "private/misc.h" /* for for_each_*child() */
11 
_check(hwloc_topology_t topology,hwloc_obj_t obj,const char * buffer,int checkattrs)12 static void _check(hwloc_topology_t topology, hwloc_obj_t obj, const char *buffer, int checkattrs)
13 {
14   hwloc_obj_type_t type;
15   union hwloc_obj_attr_u attr;
16   int depth;
17   int err;
18 
19   err = hwloc_type_sscanf(buffer, &type, &attr, sizeof(attr));
20   assert(!err);
21   assert(obj->type == type);
22 
23   if (checkattrs) {
24     if (hwloc_obj_type_is_cache(type)) {
25       assert(attr.cache.type == obj->attr->cache.type);
26       assert(attr.cache.depth == obj->attr->cache.depth);
27     } else if (type == HWLOC_OBJ_GROUP) {
28       assert(attr.group.depth == obj->attr->group.depth);
29     } else if (type == HWLOC_OBJ_BRIDGE) {
30       assert(attr.bridge.upstream_type == obj->attr->bridge.upstream_type);
31       assert(attr.bridge.downstream_type == obj->attr->bridge.downstream_type);
32     } else if (type == HWLOC_OBJ_OS_DEVICE) {
33       assert(attr.osdev.type == obj->attr->osdev.type);
34     }
35   }
36 
37   err = hwloc_type_sscanf_as_depth(buffer, NULL, topology, &depth);
38   assert(!err);
39   assert(depth == (int) obj->depth);
40 }
41 
check(hwloc_topology_t topology,hwloc_obj_t obj)42 static void check(hwloc_topology_t topology, hwloc_obj_t obj)
43 {
44   hwloc_obj_t child;
45   char buffer[64];
46   const char *constname;
47   int err;
48 
49   constname = hwloc_obj_type_string(obj->type);
50 
51   printf("  checking %s L#%u %s%s%s...\n",
52 	 constname, obj->logical_index,
53 	 obj->subtype ? "(" : "",
54 	 obj->subtype ? obj->subtype : "",
55 	 obj->subtype ? ") " : "");
56   printf("    parsing hwloc_obj_type_string() output = %s\n", constname);
57   _check(topology, obj, constname, 0);
58 
59   err = hwloc_obj_type_snprintf(buffer, sizeof(buffer), obj, 0);
60   assert(err > 0);
61   printf("    parsing hwloc_obj_type_snprintf() normal output = %s\n", buffer);
62   _check(topology, obj, buffer, 1);
63 
64   err = hwloc_obj_type_snprintf(buffer, sizeof(buffer), obj, 1);
65   assert(err > 0);
66   printf("    parsing hwloc_obj_type_snprintf() verbose output = %s\n", buffer);
67   _check(topology, obj, buffer, 1);
68 
69   for_each_child(child, obj)
70     check(topology, child);
71   for_each_memory_child(child, obj)
72     check(topology, child);
73   for_each_io_child(child, obj)
74     check(topology, child);
75   for_each_misc_child(child, obj)
76     check(topology, child);
77 }
78 
check_topo(void)79 static void check_topo(void)
80 {
81   int err;
82   hwloc_topology_t topology;
83 
84   err = hwloc_topology_init(&topology);
85   assert(!err);
86   hwloc_topology_set_all_types_filter(topology, HWLOC_TYPE_FILTER_KEEP_ALL);
87   err = hwloc_topology_load(topology);
88   assert(!err);
89 
90   check(topology, hwloc_get_root_obj(topology));
91 
92   hwloc_topology_destroy(topology);
93 }
94 
95 /* check whether type_sscanf() understand what type_snprintf() wrote */
main(void)96 int main(void)
97 {
98   hwloc_obj_type_t type;
99   union hwloc_obj_attr_u attr;
100   int err;
101 
102   printf("testing basic strings ...\n");
103 
104   err = hwloc_type_sscanf("osdev", &type, &attr, sizeof(attr));
105   assert(!err);
106   assert(type == HWLOC_OBJ_OS_DEVICE);
107   err = hwloc_type_sscanf("osdev0", &type, &attr, sizeof(attr));
108   assert(!err);
109   assert(type == HWLOC_OBJ_OS_DEVICE);
110   err = hwloc_type_sscanf("osdev:", &type, &attr, sizeof(attr));
111   assert(!err);
112   assert(type == HWLOC_OBJ_OS_DEVICE);
113   err = hwloc_type_sscanf("osde_", &type, &attr, sizeof(attr));
114   assert(!err);
115   assert(type == HWLOC_OBJ_OS_DEVICE);
116   err = hwloc_type_sscanf("osD[", &type, &attr, sizeof(attr));
117   assert(!err);
118   assert(type == HWLOC_OBJ_OS_DEVICE);
119   err = hwloc_type_sscanf("os(", &type, &attr, sizeof(attr));
120   assert(!err);
121   assert(type == HWLOC_OBJ_OS_DEVICE);
122   err = hwloc_type_sscanf("os-", &type, &attr, sizeof(attr));
123   assert(err == -1);
124   err = hwloc_type_sscanf("o1", &type, &attr, sizeof(attr));
125   printf("err %d %s for type %s\n", errno, strerror(errno), hwloc_obj_type_string(type));
126   assert(err == -1);
127 
128   err = hwloc_type_sscanf("l3IcaChe", &type, &attr, sizeof(attr));
129   assert(!err);
130   assert(type == HWLOC_OBJ_L3ICACHE);
131   assert(attr.cache.type == HWLOC_OBJ_CACHE_INSTRUCTION);
132   err = hwloc_type_sscanf("l2dcA", &type, &attr, sizeof(attr));
133   assert(!err);
134   assert(type == HWLOC_OBJ_L2CACHE);
135   assert(attr.cache.type == HWLOC_OBJ_CACHE_DATA);
136   err = hwloc_type_sscanf("l1U", &type, &attr, sizeof(attr));
137   assert(!err);
138   assert(type == HWLOC_OBJ_L1CACHE);
139   assert(attr.cache.type == HWLOC_OBJ_CACHE_UNIFIED);
140   err = hwloc_type_sscanf("l3cacHe:", &type, &attr, sizeof(attr));
141   assert(!err);
142   assert(type == HWLOC_OBJ_L3CACHE);
143   assert(attr.cache.type == HWLOC_OBJ_CACHE_UNIFIED);
144   err = hwloc_type_sscanf("l1", &type, &attr, sizeof(attr));
145   assert(!err);
146   assert(type == HWLOC_OBJ_L1CACHE);
147   assert(attr.cache.type == HWLOC_OBJ_CACHE_UNIFIED);
148   err = hwloc_type_sscanf("l1cc", &type, &attr, sizeof(attr));
149   assert(err == -1);
150 
151   err = hwloc_type_sscanf("group2", &type, &attr, sizeof(attr));
152   assert(!err);
153   assert(type == HWLOC_OBJ_GROUP);
154   assert(attr.group.depth == 2);
155   err = hwloc_type_sscanf("GR3:", &type, &attr, sizeof(attr));
156   assert(!err);
157   assert(type == HWLOC_OBJ_GROUP);
158   assert(attr.group.depth == 3);
159   err = hwloc_type_sscanf("GRa", &type, &attr, sizeof(attr));
160   assert(err == -1);
161 
162   printf("testing the local topology ...\n");
163   check_topo();
164 
165   printf("testing topology 32em64t-2n8c2t-pci-wholeio.xml ...\n");
166   putenv((char *) "HWLOC_XMLFILE=" XMLTESTDIR "/32em64t-2n8c2t-pci-wholeio.xml");
167   check_topo();
168 }
169