@@ -37,6 +37,7 @@ struct hwloc_calc_level {
37
37
int depth ;
38
38
hwloc_obj_type_t type ;
39
39
union hwloc_obj_attr_u attr ;
40
+ int pci_vendor , pci_device ;
40
41
int only_hbm ; /* -1 for everything, 0 for only non-HBM, 1 for only HBM numa nodes */
41
42
};
42
43
@@ -151,16 +152,69 @@ hwloc_calc_get_obj_inside_sets_by_depth(struct hwloc_calc_location_context_s *lc
151
152
return NULL ;
152
153
}
153
154
154
- /* return the length of the type/depth prefix
155
+ /* return the length of the type/depth prefix (including filters if any)
155
156
* 0 if not found or invalid.
156
157
*/
157
158
static __hwloc_inline size_t
158
159
hwloc_calc_parse_level_size (const char * string )
159
160
{
161
+ size_t len ;
162
+ const char * filter_end ;
163
+
160
164
/* type/depth prefix ends with either '.' (for child), "=" (for name of osdev),
161
- * ':' (for index).
165
+ * ':' (for index), or '[' (for filters) .
162
166
*/
163
- return strcspn (string , ":=." );
167
+ len = strcspn (string , ":=.[" );
168
+ if (string [len ] != '[' )
169
+ return len ;
170
+
171
+ /* we want to include filters */
172
+ filter_end = strchr (string + len , ']' );
173
+ if (!filter_end )
174
+ return 0 ;
175
+ return filter_end + 1 - string ;
176
+ }
177
+
178
+ static __hwloc_inline int
179
+ hwloc_calc_parse_level_filter (hwloc_topology_t topology __hwloc_attribute_unused ,
180
+ const char * filter ,
181
+ struct hwloc_calc_level * level )
182
+ {
183
+ const char * current = filter ;
184
+
185
+ if (level -> type == HWLOC_OBJ_PCI_DEVICE ) {
186
+ /* try to match by [vendor:device] */
187
+ char * endp ;
188
+
189
+ level -> pci_vendor = strtoul (current , & endp , 16 );
190
+ if (* endp != ':' ) {
191
+ fprintf (stderr , "invalid PCI vendor:device filter specification %s\n" , filter );
192
+ return -1 ;
193
+ }
194
+ if (endp == current )
195
+ level -> pci_vendor = -1 ;
196
+ current = endp + 1 ;
197
+
198
+ level -> pci_device = strtoul (current , & endp , 16 );
199
+ if (* endp != ']' ) {
200
+ fprintf (stderr , "invalid PCI vendor:device filter specification %s\n" , filter );
201
+ return -1 ;
202
+ }
203
+ if (endp == current )
204
+ level -> pci_device = -1 ;
205
+ current = endp + 1 ;
206
+
207
+ if (* current != ':' && * current != '\0' ) {
208
+ fprintf (stderr , "invalid PCI vendor:device filter specification %s\n" , filter );
209
+ return -1 ;
210
+ }
211
+
212
+ } else if (level -> type != HWLOC_OBJ_OS_DEVICE ) {
213
+ fprintf (stderr , "invalid filter specification %s\n" , filter );
214
+ return -1 ;
215
+ }
216
+
217
+ return 0 ;
164
218
}
165
219
166
220
static __hwloc_inline int
@@ -173,6 +227,7 @@ hwloc_calc_parse_level(struct hwloc_calc_location_context_s *lcontext,
173
227
char * endptr ;
174
228
int err ;
175
229
230
+ level -> pci_device = level -> pci_vendor = -1 ;
176
231
level -> only_hbm = -1 ;
177
232
if (lcontext )
178
233
level -> only_hbm = lcontext -> only_hbm ;
@@ -185,11 +240,19 @@ hwloc_calc_parse_level(struct hwloc_calc_location_context_s *lcontext,
185
240
186
241
err = hwloc_type_sscanf (typestring , & level -> type , & level -> attr , sizeof (level -> attr ));
187
242
if (!err ) {
243
+ char * bracket ;
188
244
/* parsed a correct type */
189
245
level -> depth = hwloc_get_type_depth_with_attr (topology , level -> type , & level -> attr , sizeof (level -> attr ));
190
246
if (level -> depth == HWLOC_TYPE_DEPTH_UNKNOWN
191
247
|| level -> depth == HWLOC_TYPE_DEPTH_MULTIPLE )
192
248
return -1 ;
249
+
250
+ bracket = strchr (typestring , '[' );
251
+ if (bracket ) {
252
+ err = hwloc_calc_parse_level_filter (topology , bracket + 1 , level );
253
+ if (err < 0 )
254
+ return -1 ;
255
+ }
193
256
return 0 ;
194
257
}
195
258
@@ -421,91 +484,17 @@ hwloc_calc_append_iodev(struct hwloc_calc_location_context_s *lcontext,
421
484
422
485
static __hwloc_inline int
423
486
hwloc_calc_append_iodev_by_index (struct hwloc_calc_location_context_s * lcontext ,
424
- hwloc_obj_type_t type , int depth , const char * string ,
487
+ struct hwloc_calc_level * level , const char * string ,
425
488
void (* cbfunc )(struct hwloc_calc_location_context_s * , void * , hwloc_obj_t ), void * cbdata )
426
489
{
427
490
hwloc_topology_t topology = lcontext -> topology ;
428
491
int verbose = lcontext -> verbose ;
429
492
hwloc_obj_t obj , prev = NULL ;
430
- int pcivendor = -1 , pcidevice = -1 ;
431
- hwloc_obj_osdev_type_t osdevtype = 0 ; /* none */
432
493
const char * current , * dot ;
433
- char * endp ;
434
494
int first = 0 , step = 1 , amount = 1 , wrap = 0 ; /* assume the index suffix is `:0' by default */
435
495
int err , i , max ;
436
496
437
- if (* string == '[' ) {
438
- /* matching */
439
- current = string + 1 ;
440
-
441
- if (type == HWLOC_OBJ_PCI_DEVICE ) {
442
- /* try to match by [vendor:device] */
443
- pcivendor = strtoul (current , & endp , 16 );
444
- if (* endp != ':' ) {
445
- if (verbose >= 0 )
446
- fprintf (stderr , "invalid PCI vendor:device matching specification %s\n" , string );
447
- return -1 ;
448
- }
449
- if (endp == current )
450
- pcivendor = -1 ;
451
- current = endp + 1 ;
452
-
453
- pcidevice = strtoul (current , & endp , 16 );
454
- if (* endp != ']' ) {
455
- if (verbose >= 0 )
456
- fprintf (stderr , "invalid PCI vendor:device matching specification %s\n" , string );
457
- return -1 ;
458
- }
459
- if (endp == current )
460
- pcidevice = -1 ;
461
- current = endp + 1 ;
462
-
463
- if (* current != ':' && * current != '\0' ) {
464
- if (verbose >= 0 )
465
- fprintf (stderr , "invalid PCI vendor:device matching specification %s\n" , string );
466
- return -1 ;
467
- }
468
-
469
- } else if (type == HWLOC_OBJ_OS_DEVICE ) {
470
- /* try to match by [osdevtype] */
471
- hwloc_obj_type_t type2 ;
472
- union hwloc_obj_attr_u attr ;
473
-
474
- endp = strchr (current , ']' );
475
- if (!endp ) {
476
- if (verbose >= 0 )
477
- fprintf (stderr , "invalid OS device subtype specification %s\n" , string );
478
- return -1 ;
479
- }
480
- * endp = 0 ;
481
-
482
- err = hwloc_type_sscanf (current , & type2 , & attr , sizeof (attr ));
483
- * endp = ']' ;
484
- if (err < 0 || type2 != HWLOC_OBJ_OS_DEVICE ) {
485
- if (verbose >= 0 )
486
- fprintf (stderr , "invalid OS device subtype specification %s\n" , string );
487
- return -1 ;
488
- }
489
- osdevtype = attr .osdev .type ;
490
-
491
- current = endp + 1 ;
492
- if (* current != ':' && * current != '\0' ) {
493
- if (verbose >= 0 )
494
- fprintf (stderr , "invalid OS device subtype specification %s\n" , string );
495
- return -1 ;
496
- }
497
-
498
- } else {
499
- /* no matching for non-PCI devices */
500
- if (verbose >= 0 )
501
- fprintf (stderr , "invalid matching specification %s\n" , string );
502
- return -1 ;
503
- }
504
-
505
- } else {
506
- /* no matching */
507
- current = string ;
508
- }
497
+ current = string ;
509
498
510
499
if (* current != '\0' ) {
511
500
current ++ ;
@@ -524,29 +513,29 @@ hwloc_calc_append_iodev_by_index(struct hwloc_calc_location_context_s *lcontext,
524
513
}
525
514
}
526
515
527
- max = hwloc_get_nbobjs_by_depth (topology , depth );
516
+ max = hwloc_get_nbobjs_by_depth (topology , level -> depth );
528
517
529
518
for (i = 0 ; i < max * (wrap + 1 ); i ++ ) {
530
519
if (i == max && wrap ) {
531
520
i = 0 ;
532
521
wrap = 0 ;
533
522
}
534
523
535
- obj = hwloc_get_obj_by_depth (topology , depth , i );
524
+ obj = hwloc_get_obj_by_depth (topology , level -> depth , i );
536
525
assert (obj );
537
526
538
527
if (obj == prev ) /* already used that object, stop wrapping around */
539
528
break ;
540
529
541
- if (type == HWLOC_OBJ_PCI_DEVICE ) {
542
- if (pcivendor != -1 && (int ) obj -> attr -> pcidev .vendor_id != pcivendor )
530
+ if (level -> type == HWLOC_OBJ_PCI_DEVICE ) {
531
+ if (level -> pci_vendor != -1 && (int ) obj -> attr -> pcidev .vendor_id != level -> pci_vendor )
543
532
continue ;
544
- if (pcidevice != -1 && (int ) obj -> attr -> pcidev .device_id != pcidevice )
533
+ if (level -> pci_device != -1 && (int ) obj -> attr -> pcidev .device_id != level -> pci_device )
545
534
continue ;
546
535
}
547
536
548
- if (type == HWLOC_OBJ_OS_DEVICE ) {
549
- if ((obj -> attr -> osdev .type & osdevtype ) != osdevtype )
537
+ if (level -> type == HWLOC_OBJ_OS_DEVICE ) {
538
+ if ((obj -> attr -> osdev .type & level -> attr . osdev . type ) != level -> attr . osdev . type )
550
539
continue ;
551
540
}
552
541
@@ -603,16 +592,8 @@ hwloc_calc_process_location(struct hwloc_calc_location_context_s *lcontext,
603
592
/* if we didn't find a depth but found a type, handle special cases */
604
593
hwloc_obj_t obj = NULL ;
605
594
606
- if (* sep == ':' || * sep == '[' ) {
607
- if (level .type == HWLOC_OBJ_PCI_DEVICE ) {
608
- /* FIXME: temporary hack because typelen includes pci and osdev filters
609
- * but only osdev types are handled in hwloc_calc_parse_level()
610
- */
611
- const char * bracket = strchr (arg , '[' );
612
- if (bracket && bracket - sep < 0 )
613
- sep = bracket ;
614
- }
615
- return hwloc_calc_append_iodev_by_index (lcontext , level .type , level .depth , sep , cbfunc , cbdata );
595
+ if (* sep == ':' ) {
596
+ return hwloc_calc_append_iodev_by_index (lcontext , & level , sep , cbfunc , cbdata );
616
597
617
598
} else if (* sep == '=' && level .type == HWLOC_OBJ_PCI_DEVICE ) {
618
599
/* try to match a busid */
@@ -717,7 +698,7 @@ hwloc_calc_process_location_as_set(struct hwloc_calc_location_context_s *lcontex
717
698
718
699
/* try to match a type/depth followed by a special character */
719
700
typelen = hwloc_calc_parse_level_size (arg );
720
- if (typelen && (arg [typelen ] == ':' || arg [typelen ] == '=' || arg [ typelen ] == '[' )) {
701
+ if (typelen && (arg [typelen ] == ':' || arg [typelen ] == '=' )) {
721
702
/* process type/depth */
722
703
struct hwloc_calc_process_location_set_cbdata_s cbdata ;
723
704
cbdata .set = hwloc_bitmap_alloc ();
0 commit comments