Skip to content

Commit 4599ad6

Browse files
authored
Merge pull request #628 from bgoglin/location-filters
utils: cleanup and improve location "filters"
2 parents 5fa11e1 + 89dc706 commit 4599ad6

16 files changed

+403
-284
lines changed

utils/hwloc/hwloc-annotate.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ get_unique_obj(hwloc_topology_t topology, int topodepth, char *str,
171171
size_t typelen;
172172
int err;
173173

174-
typelen = strspn(str, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
175-
if (!typelen || (str[typelen] != ':' && str[typelen] != '=' && str[typelen] != '['))
174+
typelen = hwloc_calc_parse_level_size(str);
175+
if (!typelen || (str[typelen] != ':' && str[typelen] != '='))
176176
return NULL;
177177

178178
lcontext.topology = topology;
@@ -809,7 +809,7 @@ int main(int argc, char *argv[])
809809
apply(topology, hwloc_get_root_obj(topology));
810810
} else {
811811
size_t typelen;
812-
typelen = strspn(location, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
812+
typelen = hwloc_calc_parse_level_size(location);
813813
if (typelen && (location[typelen] == ':' || location[typelen] == '=' || location[typelen] == '[')) {
814814
struct hwloc_calc_location_context_s lcontext;
815815
lcontext.topology = topology;

utils/hwloc/hwloc-bind.1in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ in account when looking for NUMA nodes in the input locations.
8888

8989
This option must be combined with NUMA node locations,
9090
such as \fI--hbm numa:1\fR for binding on the second HBM node.
91-
It may also be written as \fIhbm:1\fR.
91+
It may also be written as \fInuma[hbm]:1\fR.
9292
.TP
9393
\fB\-\-no\-hbm\fR
9494
Ignore high bandwidth memory nodes (Intel Xeon Phi MCDRAM)
@@ -297,7 +297,7 @@ To bind on the memory node local to a PU with largest capacity:
297297

298298
To bind memory on the first high-bandwidth memory node on Intel Xeon Phi:
299299

300-
$ hwloc-bind --membind hbm:0 -- echo hello
300+
$ hwloc-bind --membind numa[mcdram]:0 -- echo hello
301301
$ hwloc-bind --hbm --membind numa:0 -- echo hello
302302

303303
Note that binding the "echo" command to multiple processors is

utils/hwloc/hwloc-calc.1in

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ When combined with \fB\-\-nodeset\fR or \fB\-\-nodeset-output\fR,
164164
the nodeset is considered instead of the CPU set for finding matching objects.
165165
This is useful when reporting the output as a number or set of NUMA nodes.
166166

167+
\fI<type\fR may contain a filter to select specific objects among
168+
the type. For instance \fB\-N "numa[mcdram]"\fR counts MCDRAM NUMA nodes on KNL.
169+
167170
If an OS device subtype such as \fIgpu\fR is given instead of \fIosdev\fR,
168171
only the os devices of that subtype will be counted.
169172
.TP
@@ -182,6 +185,9 @@ When combined with \fB\-\-nodeset\fR or \fB\-\-nodeset-output\fR,
182185
the nodeset is considered instead of the CPU set for finding matching objects.
183186
This is useful when reporting the output as a number or set of NUMA nodes.
184187

188+
\fI<type\fR may contain a filter to select specific objects among
189+
the type. For instance \fB\-I "numa[mcdram]"\fR lists MCDRAM NUMA nodes on KNL.
190+
185191
If an OS device subtype such as \fIgpu\fR is given instead of \fIosdev\fR,
186192
only the os devices of that subtype will be returned.
187193

@@ -391,6 +397,16 @@ whose locality is exactly equal to a Package:
391397
$ hwloc-calc --local-memory-flags 0 --best-memattr capacity --physical-output pack:1
392398
4
393399

400+
To find the number of NUMA nodes with subtype MCDRAM (on KNL):
401+
402+
$ hwloc-calc -N "numa[mcdram]" all
403+
4
404+
405+
To find the NUMA node of subtype MCDRAM (on KNL) near a PU:
406+
407+
$ hwloc-calc -I "numa[mcdram]" pu:157
408+
1
409+
394410
Converting object logical indexes (default) from/to physical/OS indexes
395411
may be performed with \fB--intersect\fR combined with either \fB--physical-output\fR
396412
(logical to physical conversion) or \fB--physical-input\fR (physical to logical):

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,12 +117,14 @@ 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;
126124
if (!hwloc_bitmap_intersects(set, obj->cpuset))
127125
goto next;
126+
if (hwloc_calc_check_object_filtered(obj, &hierlevels[level]))
127+
goto next;
128128
hwloc_obj_type_snprintf(type, sizeof(type), obj, HWLOC_OBJ_SNPRINTF_FLAG_LONG_NAMES);
129129
if (idx == (unsigned)-1)
130130
snprintf(string, sizeof(string), "%s%s%s:-1", prefix, level ? "." : "", type);
@@ -190,25 +190,23 @@ hwloc_calc_output(hwloc_topology_t topology, const char *sep, hwloc_bitmap_t set
190190
}
191191
printf("\n");
192192
hwloc_bitmap_free(remaining);
193-
} else if (numberofdepth != -1) {
193+
} else if (numberof.depth != -1) {
194194
unsigned nb = 0;
195195
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)
196+
while ((obj = hwloc_calc_get_next_obj_covering_set_by_depth(topology, set, nodeseto, numberof.depth, obj)) != NULL) {
197+
if (hwloc_calc_check_object_filtered(obj, &numberof))
199198
continue;
200199
nb++;
201200
}
202201
printf("%u\n", nb);
203-
} else if (intersectdepth != -1) {
202+
} else if (intersect.depth != -1) {
204203
hwloc_obj_t obj = NULL;
205204
int first = 1;
206205
if (!sep)
207206
sep = ",";
208-
while ((obj = hwloc_calc_get_next_obj_covering_set_by_depth(topology, set, nodeseto, intersectdepth, obj)) != NULL) {
207+
while ((obj = hwloc_calc_get_next_obj_covering_set_by_depth(topology, set, nodeseto, intersect.depth, obj)) != NULL) {
209208
unsigned idx;
210-
if (intersectdepth == HWLOC_TYPE_DEPTH_OS_DEVICE
211-
&& (obj->attr->osdev.type & intersectattr.osdev.type) != intersectattr.osdev.type)
209+
if (hwloc_calc_check_object_filtered(obj, &intersect))
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
}

0 commit comments

Comments
 (0)