Skip to content

Commit 56deb3b

Browse files
committed
utils/calc: rework parsing of levels for -I -N and -H
Replace hwloc_calc_type_depth() with hwloc_calc_parse_level(). Make it more generic for future reuses in other cases, save all parsed info a new hwloc_calc_level structure. HBM and MCDRAM are allowed but only used as raw NUMA for now. Signed-off-by: Brice Goglin <[email protected]>
1 parent 5fa11e1 commit 56deb3b

File tree

2 files changed

+105
-65
lines changed

2 files changed

+105
-65
lines changed

utils/hwloc/hwloc-calc.c

Lines changed: 53 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,10 @@ static int logicalo = 1;
7272
static int nodeseti = 0;
7373
static int nodeseto = 0;
7474
static int objecto = 0;
75-
static int numberofdepth = -1;
76-
static union hwloc_obj_attr_u numberofattr;
77-
static int intersectdepth = -1;
78-
static union hwloc_obj_attr_u intersectattr;
79-
static int hiernblevels = 0;
80-
static int *hierdepth = NULL;
75+
static struct hwloc_calc_level numberof;
76+
static struct hwloc_calc_level intersect;
77+
static int hiernblevels;
78+
static struct hwloc_calc_level *hierlevels;
8179
static int local_numanodes = 0;
8280
static unsigned long local_numanode_flags = HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY | HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY;
8381
static hwloc_memattr_id_t best_memattr_id = (hwloc_memattr_id_t) -1;
@@ -119,7 +117,7 @@ hwloc_calc_hierarch_output(hwloc_topology_t topology, const char *prefix, const
119117
hwloc_obj_t obj, prev = NULL;
120118
unsigned logi = 0;
121119
int first = 1;
122-
while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, root->cpuset, hierdepth[level], prev)) != NULL) {
120+
while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, root->cpuset, hierlevels[level].depth, prev)) != NULL) {
123121
char string[256];
124122
char type[32];
125123
unsigned idx = logicalo ? logi : obj->os_index;
@@ -190,25 +188,25 @@ hwloc_calc_output(hwloc_topology_t topology, const char *sep, hwloc_bitmap_t set
190188
}
191189
printf("\n");
192190
hwloc_bitmap_free(remaining);
193-
} else if (numberofdepth != -1) {
191+
} else if (numberof.depth != -1) {
194192
unsigned nb = 0;
195193
hwloc_obj_t obj = NULL;
196-
while ((obj = hwloc_calc_get_next_obj_covering_set_by_depth(topology, set, nodeseto, numberofdepth, obj)) != NULL) {
197-
if (numberofdepth == HWLOC_TYPE_DEPTH_OS_DEVICE
198-
&& (obj->attr->osdev.type & numberofattr.osdev.type) != numberofattr.osdev.type)
194+
while ((obj = hwloc_calc_get_next_obj_covering_set_by_depth(topology, set, nodeseto, numberof.depth, obj)) != NULL) {
195+
if (numberof.depth == HWLOC_TYPE_DEPTH_OS_DEVICE
196+
&& (obj->attr->osdev.type & numberof.attr.osdev.type) != numberof.attr.osdev.type)
199197
continue;
200198
nb++;
201199
}
202200
printf("%u\n", nb);
203-
} else if (intersectdepth != -1) {
201+
} else if (intersect.depth != -1) {
204202
hwloc_obj_t obj = NULL;
205203
int first = 1;
206204
if (!sep)
207205
sep = ",";
208-
while ((obj = hwloc_calc_get_next_obj_covering_set_by_depth(topology, set, nodeseto, intersectdepth, obj)) != NULL) {
206+
while ((obj = hwloc_calc_get_next_obj_covering_set_by_depth(topology, set, nodeseto, intersect.depth, obj)) != NULL) {
209207
unsigned idx;
210-
if (intersectdepth == HWLOC_TYPE_DEPTH_OS_DEVICE
211-
&& (obj->attr->osdev.type & intersectattr.osdev.type) != intersectattr.osdev.type)
208+
if (intersect.depth == HWLOC_TYPE_DEPTH_OS_DEVICE
209+
&& (obj->attr->osdev.type & intersect.attr.osdev.type) != intersect.attr.osdev.type)
212210
continue;
213211
if (!first)
214212
printf("%s", sep);
@@ -288,41 +286,6 @@ hwloc_calc_output(hwloc_topology_t topology, const char *sep, hwloc_bitmap_t set
288286
return EXIT_SUCCESS;
289287
}
290288

291-
static int hwloc_calc_type_depth(hwloc_topology_t topology, const char *string, int *depthp, union hwloc_obj_attr_u *attrp, const char *caller)
292-
{
293-
union hwloc_obj_attr_u attr;
294-
hwloc_obj_type_t type;
295-
int depth;
296-
int err;
297-
298-
err = hwloc_type_sscanf(string, &type, &attr, sizeof(attr));
299-
if (err < 0) {
300-
char *endptr;
301-
depth = strtoul(string, &endptr, 0);
302-
if (*endptr) {
303-
fprintf(stderr, "unrecognized %s type or depth %s\n", caller, string);
304-
return -1;
305-
}
306-
307-
*depthp = depth;
308-
return 0;
309-
}
310-
311-
depth = hwloc_get_type_depth_with_attr(topology, type, &attr, sizeof(attr));
312-
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
313-
fprintf(stderr, "unavailable %s type %s\n", caller, hwloc_obj_type_string(type));
314-
return -1;
315-
} else if (depth == HWLOC_TYPE_DEPTH_MULTIPLE) {
316-
fprintf(stderr, "cannot use %s type %s with multiple depth, please use the relevant depth\n", caller, hwloc_obj_type_string(type));
317-
return -1;
318-
}
319-
320-
if (attrp)
321-
memcpy(attrp, &attr, sizeof(attr));
322-
*depthp = depth;
323-
return 0;
324-
}
325-
326289
int main(int argc, char *argv[])
327290
{
328291
hwloc_topology_t topology;
@@ -333,10 +296,10 @@ int main(int argc, char *argv[])
333296
int depth = 0;
334297
hwloc_bitmap_t set;
335298
int cmdline_args = 0;
336-
const char * numberoftype = NULL;
337-
const char * intersecttype = NULL;
299+
const char * numberof_string = NULL;
300+
const char * intersect_string = NULL;
338301
char *restrictstring = NULL;
339-
char * hiertype = NULL;
302+
char * hier_string = NULL;
340303
char * best_memattr_str = NULL;
341304
char *callname;
342305
char *outsep = NULL;
@@ -520,7 +483,7 @@ int main(int argc, char *argv[])
520483
usage(callname, stderr);
521484
return EXIT_FAILURE;
522485
}
523-
numberoftype = argv[1];
486+
numberof_string = argv[1];
524487
opt = 1;
525488
goto next;
526489
}
@@ -529,7 +492,7 @@ int main(int argc, char *argv[])
529492
usage(callname, stderr);
530493
return EXIT_FAILURE;
531494
}
532-
intersecttype = argv[1];
495+
intersect_string = argv[1];
533496
opt = 1;
534497
goto next;
535498
}
@@ -538,7 +501,7 @@ int main(int argc, char *argv[])
538501
usage(callname, stderr);
539502
return EXIT_FAILURE;
540503
}
541-
hiertype = argv[1];
504+
hier_string = argv[1];
542505
opt = 1;
543506
goto next;
544507
}
@@ -663,32 +626,57 @@ int main(int argc, char *argv[])
663626
argv += opt+1;
664627
}
665628

666-
if (numberoftype && hwloc_calc_type_depth(topology, numberoftype, &numberofdepth, &numberofattr, "--number-of") < 0)
629+
numberof.depth = HWLOC_TYPE_DEPTH_UNKNOWN; /* disable this feature by default */
630+
if (numberof_string && hwloc_calc_parse_level(NULL, topology, numberof_string, strlen(numberof_string), &numberof) < 0) {
631+
if (numberof.depth == HWLOC_TYPE_DEPTH_MULTIPLE)
632+
fprintf(stderr, "cannot use --number-of type %s with multiple depth, please use the relevant depth\n",
633+
numberof_string);
634+
else if (numberof.depth == HWLOC_TYPE_DEPTH_UNKNOWN)
635+
fprintf(stderr, "cannot use --number-of type %s, unavailable\n",
636+
numberof_string);
667637
goto out;
638+
}
668639

669-
if (intersecttype && hwloc_calc_type_depth(topology, intersecttype, &intersectdepth, &intersectattr, "--intersect") < 0)
640+
intersect.depth = HWLOC_TYPE_DEPTH_UNKNOWN; /* disable this feature by default */
641+
if (intersect_string && hwloc_calc_parse_level(NULL, topology, intersect_string, strlen(intersect_string), &intersect) < 0) {
642+
if (intersect.depth == HWLOC_TYPE_DEPTH_MULTIPLE)
643+
fprintf(stderr, "cannot use --intersect type %s with multiple depth, please use the relevant depth\n",
644+
intersect_string);
645+
else if (intersect.depth == HWLOC_TYPE_DEPTH_UNKNOWN)
646+
fprintf(stderr, "cannot use --intersect type %s, unavailable\n",
647+
intersect_string);
670648
goto out;
649+
}
671650

672-
if (hiertype) {
651+
hiernblevels = 0; /* disable this feature by default */
652+
hierlevels = NULL;
653+
if (hier_string) {
673654
char *tmp, *next;
674655
hiernblevels = 1;
675-
tmp = hiertype;
656+
tmp = hier_string;
676657
while (1) {
677658
tmp = strchr(tmp, '.');
678659
if (!tmp)
679660
break;
680661
tmp++;
681662
hiernblevels++;
682663
}
683-
hierdepth = malloc(hiernblevels * sizeof(int));
684-
tmp = hiertype;
664+
hierlevels = malloc(hiernblevels * sizeof(struct hwloc_calc_level));
665+
tmp = hier_string;
685666
for(i=0; i<hiernblevels; i++) {
686667
next = strchr(tmp, '.');
687668
if (next)
688669
*next = '\0';
689-
if (hwloc_calc_type_depth(topology, tmp, &hierdepth[i], NULL, "--hierarchical") < 0)
670+
if (hwloc_calc_parse_level(NULL, topology, tmp, strlen(tmp), &hierlevels[i]) < 0) {
671+
if (hierlevels[i].depth == HWLOC_TYPE_DEPTH_MULTIPLE)
672+
fprintf(stderr, "cannot use --hierarchical %s with multiple depth, please use the relevant depth\n",
673+
tmp);
674+
else if (hierlevels[i].depth == HWLOC_TYPE_DEPTH_UNKNOWN)
675+
fprintf(stderr, "cannot use --hierarchical type %s, unavailable\n",
676+
tmp);
690677
goto out;
691-
if (hierdepth[i] < 0 && hierdepth[i] != HWLOC_TYPE_DEPTH_NUMANODE) {
678+
}
679+
if (hierlevels[i].depth < 0 && hierlevels[i].depth != HWLOC_TYPE_DEPTH_NUMANODE) {
692680
fprintf(stderr, "unsupported (non-normal) --hierarchical type %s\n", tmp);
693681
goto out;
694682
}
@@ -768,7 +756,7 @@ int main(int argc, char *argv[])
768756
hwloc_bitmap_free(set);
769757
hwloc_bitmap_free(cpukind_cpuset);
770758

771-
free(hierdepth);
759+
free(hierlevels);
772760

773761
return ret;
774762
}

utils/hwloc/hwloc-calc.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <ctype.h>
2222
#include <assert.h>
2323

24+
/* this is a global that doesn't change when walking hierarchy of locations, etc */
2425
struct hwloc_calc_location_context_s {
2526
hwloc_topology_t topology;
2627
int topodepth;
@@ -29,6 +30,13 @@ struct hwloc_calc_location_context_s {
2930
int verbose;
3031
};
3132

33+
/* this a local that changes when going from one level to another in the hierarchy of locations, etc */
34+
struct hwloc_calc_level {
35+
int depth;
36+
hwloc_obj_type_t type;
37+
union hwloc_obj_attr_u attr;
38+
};
39+
3240
typedef enum hwloc_calc_append_mode_e {
3341
HWLOC_CALC_APPEND_ADD,
3442
HWLOC_CALC_APPEND_CLR,
@@ -140,6 +148,50 @@ hwloc_calc_get_obj_inside_sets_by_depth(struct hwloc_calc_location_context_s *lc
140148
return NULL;
141149
}
142150

151+
static __hwloc_inline int
152+
hwloc_calc_parse_level(struct hwloc_calc_location_context_s *lcontext,
153+
hwloc_topology_t topology,
154+
const char *_typestring, size_t typelen,
155+
struct hwloc_calc_level *level)
156+
{
157+
char typestring[20+1]; /* large enough to store all type names, even with a depth attribute */
158+
char *endptr;
159+
int err;
160+
161+
level->depth = HWLOC_TYPE_DEPTH_UNKNOWN;
162+
163+
if (typelen >= sizeof(typestring))
164+
return -1;
165+
snprintf(typestring, typelen+1, "%s", _typestring);
166+
167+
err = hwloc_type_sscanf(typestring, &level->type, &level->attr, sizeof(level->attr));
168+
if (!err) {
169+
/* parsed a correct type */
170+
level->depth = hwloc_get_type_depth_with_attr(topology, level->type, &level->attr, sizeof(level->attr));
171+
if (level->depth == HWLOC_TYPE_DEPTH_UNKNOWN
172+
|| level->depth == HWLOC_TYPE_DEPTH_MULTIPLE)
173+
return -1;
174+
return 0;
175+
}
176+
177+
if (!strcasecmp(typestring, "HBM") || !strcasecmp(typestring, "MCDRAM")) {
178+
if (lcontext && lcontext->only_hbm == -1)
179+
lcontext->only_hbm = 1;
180+
level->type = HWLOC_OBJ_NUMANODE;
181+
level->depth = HWLOC_TYPE_DEPTH_NUMANODE;
182+
return 0;
183+
}
184+
185+
/* couldn't parse the type, try a depth value */
186+
level->depth = strtoul(typestring, &endptr, 0);
187+
if (typestring[0] == '-' || *endptr || level->depth >= hwloc_topology_get_depth(topology)) {
188+
level->depth = HWLOC_TYPE_DEPTH_UNKNOWN;
189+
return -1;
190+
}
191+
level->type = HWLOC_OBJ_TYPE_NONE;
192+
return 0;
193+
}
194+
143195
static __hwloc_inline int
144196
hwloc_calc_parse_depth_prefix(struct hwloc_calc_location_context_s *lcontext,
145197
const char *string, size_t typelen,

0 commit comments

Comments
 (0)