@@ -292,7 +292,12 @@ ur_result_t urDeviceGetSelected(ur_platform_handle_t hPlatform,
292
292
// discard term, for that backend.
293
293
// (If we wished to preserve the ordering of terms, we could replace `std::map`
294
294
// with `std::queue<std::pair<key_type_t, value_type_t>>` or something similar.)
295
- auto maybeEnvVarMap = getenv_to_map (" ONEAPI_DEVICE_SELECTOR" , true );
295
+ auto maybeEnvVarMap = getenv_to_map (" ONEAPI_DEVICE_SELECTOR" , false );
296
+ std::cout
297
+ << " DEBUG: " << (maybeEnvVarMap.has_value ()
298
+ ? " getenv_to_map parsed env var and produced a map"
299
+ : " getenv_to_map parsed env var and failed to produce a map" )
300
+ << std::endl;
296
301
297
302
// if the ODS env var is not set at all, then pretend it was set to the default
298
303
using EnvVarMap = std::map<std::string, std::vector<std::string>>;
@@ -419,53 +424,63 @@ ur_result_t urDeviceGetSelected(ur_platform_handle_t hPlatform,
419
424
std::vector<DeviceSpec> acceptDeviceList;
420
425
std::vector<DeviceSpec> discardDeviceList;
421
426
422
- std::vector<std::string> acceptFilters;
423
- std::vector<std::string> discardFilters;
424
427
for (auto &termPair : mapODS) {
425
428
std::string backend = termPair.first ;
426
- if (backend.empty ()) {
429
+ if (backend.empty ()) { // FIXME: never true because getenv_to_map rejects this case
427
430
// malformed term: missing backend -- output ERROR, then continue
428
431
// TODO: replace std::cout with URT message output mechanism
429
432
std::cout << " ERROR: missing backend, format of filter = "
430
- " '[!]backend:filterStrings'" ;
433
+ " '[!]backend:filterStrings'"
434
+ << std::endl;
431
435
continue ;
432
436
}
433
437
enum FilterType {
434
438
AcceptFilter,
435
439
DiscardFilter,
436
440
} termType = (backend.front () != ' !' ) ? AcceptFilter : DiscardFilter;
437
- auto &deviceList = acceptDeviceList;
441
+ std::cout << " DEBUG: termType is"
442
+ << (termType != AcceptFilter ? " DiscardFilter"
443
+ : " AcceptFilter" )
444
+ << std::endl;
445
+ auto &deviceList =
446
+ (termType != AcceptFilter) ? discardDeviceList : acceptDeviceList;
438
447
if (termType != AcceptFilter) {
448
+ std::cout << " DEBUG: backend was '" << backend << " '" << std::endl;
439
449
backend.erase (backend.cbegin ());
440
- deviceList = discardDeviceList ;
450
+ std::cout << " DEBUG: backend now ' " << backend << " ' " << std::endl ;
441
451
}
442
452
// Note the hPlatform -> platformBackend -> platformBackendName conversion above
443
453
// guarantees minimal sanity for the comparison with backend from the ODS string
444
- if (backend != " * " &&
445
- std::equal (platformBackendName.cbegin (), platformBackendName.cend (),
454
+ if (backend. front () != ' * ' &&
455
+ ! std::equal (platformBackendName.cbegin (), platformBackendName.cend (),
446
456
backend.cbegin (), backend.cend (),
447
457
[](const auto &a, const auto &b) {
448
458
// case-insensitive comparison by converting both tolower
449
459
return std::tolower (static_cast <unsigned char >(a)) ==
450
460
std::tolower (static_cast <unsigned char >(b));
451
461
})) {
452
462
// irrelevant term for current request: different backend -- silently ignore
463
+ // TODO: replace std::cout with URT message output mechanism
464
+ std::cout << " WARNING: ignoring term with irrelevant backend"
465
+ << std::endl;
453
466
continue ;
454
467
}
455
468
if (termPair.second .size () == 0 ) {
456
469
// malformed term: missing filterStrings -- output ERROR, then continue
457
470
// TODO: replace std::cout with URT message output mechanism
458
471
std::cout << " ERROR missing filterStrings, format of filter = "
459
- " '[!]backend:filterStrings'" ;
472
+ " '[!]backend:filterStrings'"
473
+ << std::endl;
460
474
continue ;
461
475
}
462
476
if (std::find_if (termPair.second .cbegin (), termPair.second .cend (),
463
477
[](const auto &s) { return s.empty (); }) !=
464
- termPair.second .cend ()) {
478
+ termPair.second .cend ()) { // FIXME: never true because getenv_to_map rejects this case
465
479
// malformed term: missing filterString -- output warning, then continue
466
480
// TODO: replace std::cout with URT message output mechanism
467
481
std::cout << " WARNING: empty filterString, format of filterStrings "
468
- " = 'filterString[,filterString[,...]]'" ;
482
+ " = 'filterString[,filterString[,...]]'"
483
+ << std::endl;
469
484
continue ;
470
485
}
471
486
if (std::find_if (termPair.second .cbegin (), termPair.second .cend (),
@@ -475,7 +490,8 @@ ur_result_t urDeviceGetSelected(ur_platform_handle_t hPlatform,
475
490
// malformed term: too many dots in filterString -- output warning, then continue
476
491
// TODO: replace std::cout with URT message output mechanism
477
492
std::cout << " WARNING: too many dots in filterString, format of "
478
- " filterString = 'root[.sub[.subsub]]'" ;
493
+ " filterString = 'root[.sub[.subsub]]'"
494
+ << std::endl;
479
495
continue ;
480
496
}
481
497
if (std::find_if (
@@ -497,7 +513,8 @@ ur_result_t urDeviceGetSelected(ur_platform_handle_t hPlatform,
497
513
// malformed term: star dot no-star in filterString -- output warning, then continue
498
514
// TODO: replace std::cout with URT message output mechanism
499
515
std::cout
500
- << " WARNING: invalid wildcard in filterString, '*.' => '*.*'" ;
516
+ << " WARNING: invalid wildcard in filterString, '*.' => '*.*'"
517
+ << std::endl;
501
518
continue ;
502
519
}
503
520
@@ -511,7 +528,7 @@ ur_result_t urDeviceGetSelected(ur_platform_handle_t hPlatform,
511
528
const auto firstDeviceId = getDeviceId (firstPart);
512
529
// first dot found, look for another
513
530
std::string::size_type locationDot2 =
514
- filterString.find (' .' , locationDot1);
531
+ filterString.find (' .' , locationDot1+ 1 );
515
532
std::string secondPart = filterString.substr (
516
533
locationDot1 + 1 , locationDot2 == std::string::npos
517
534
? std::string::npos
@@ -539,25 +556,26 @@ ur_result_t urDeviceGetSelected(ur_platform_handle_t hPlatform,
539
556
hardwareType, firstDeviceId});
540
557
}
541
558
}
542
-
543
- if (termType != AcceptFilter) {
544
- discardFilters.insert (discardFilters.end (),
545
- termPair.second .cbegin (),
546
- termPair.second .cend ());
547
- } else {
548
- acceptFilters.insert (acceptFilters.end (), termPair.second .cbegin (),
549
- termPair.second .cend ());
550
- }
551
559
}
552
560
553
- // if no accept filters are specified by the user, we must add a default "all root devices"
554
- if (acceptFilters.size () == 0 ) {
555
- acceptFilters.insert (acceptFilters.end (), 1 , " *" );
556
- }
557
- if (acceptDeviceList.size () == 0 ) {
561
+ if (acceptDeviceList.size () == 0 && discardDeviceList.size () == 0 ) {
562
+ // nothing in env var was understood as a valid term
563
+ return UR_RESULT_ERROR_INVALID_VALUE;
564
+ } else if (acceptDeviceList.size () == 0 ) {
565
+ // no accept terms were understood, but at least one discard term was
566
+ // we are magnanimous to the user when there were bad/ignored accept terms
567
+ // by pretending there were no bad/ignored accept terms in the env var
568
+ // for example, we pretend that "garbage:0;!cuda:*" was just "!cuda:*"
569
+ // so we add an implicit accept-all term (equivalent to prepending "*:*;")
570
+ // as we would have done if the user had given us the corrected string
558
571
acceptDeviceList.push_back (DeviceSpec{
559
572
DevicePartLevel::ROOT, ::UR_DEVICE_TYPE_ALL, DeviceIdTypeALL});
560
573
}
574
+
575
+ std::cout << " DEBUG: size of acceptDeviceList = " << acceptDeviceList.size ()
576
+ << std::endl
577
+ << " DEBUG: size of discardDeviceList = "
578
+ << discardDeviceList.size () << std::endl;
561
579
562
580
std::vector<DeviceSpec> rootDevices;
563
581
std::vector<DeviceSpec> subDevices;
@@ -688,30 +706,46 @@ ur_result_t urDeviceGetSelected(ur_platform_handle_t hPlatform,
688
706
// if this is a subsubdevice filter, then it must be '*.*.*'
689
707
matches = (filter.hwType == device.hwType ) ||
690
708
(filter.hwType == DeviceHardwareType::UR_DEVICE_TYPE_ALL);
709
+ std::cout << " DEBUG: In ApplyFilter, if block case 1, matches = "
710
+ << matches << std::endl;
691
711
} else if (filter.rootId != device.rootId ) {
692
712
// root part in filter is a number but does not match the number in the root part of device
693
713
matches = false ;
714
+ std::cout << " DEBUG: In ApplyFilter, if block case 2, matches = "
715
+ << matches << std::endl;
694
716
} else if (filter.level == DevicePartLevel::ROOT) {
695
717
// this is a root device filter with a number that matches
696
718
matches = true ;
719
+ std::cout << " DEBUG: In ApplyFilter, if block case 3, matches = "
720
+ << matches << std::endl;
697
721
} else if (filter.subId == DeviceIdTypeALL) {
698
722
// sub type of star always matches (when root part matches, which we already know here)
699
723
// if this is a subdevice filter, then it must be 'matches.*'
700
724
// if this is a subsubdevice filter, then it must be 'matches.*.*'
701
725
matches = true ;
726
+ std::cout << " DEBUG: In ApplyFilter, if block case 4, matches = "
727
+ << matches << std::endl;
702
728
} else if (filter.subId != device.subId ) {
703
729
// sub part in filter is a number but does not match the number in the sub part of device
704
730
matches = false ;
731
+ std::cout << " DEBUG: In ApplyFilter, if block case 5, matches = "
732
+ << matches << std::endl;
705
733
} else if (filter.level == DevicePartLevel::SUB) {
706
734
// this is a sub device number filter, numbers match in both parts
707
735
matches = true ;
736
+ std::cout << " DEBUG: In ApplyFilter, if block case 6, matches = "
737
+ << matches << std::endl;
708
738
} else if (filter.subsubId == DeviceIdTypeALL) {
709
739
// subsub type of star always matches (when other parts match, which we already know here)
710
740
// this is a subsub device filter, it must be 'matches.matches.*'
711
741
matches = true ;
742
+ std::cout << " DEBUG: In ApplyFilter, if block case 7, matches = "
743
+ << matches << std::endl;
712
744
} else {
713
745
// this is a subsub device filter, numbers in all three parts match
714
746
matches = (filter.subsubId == device.subsubId );
747
+ std::cout << " DEBUG: In ApplyFilter, if block case 8, matches = "
748
+ << matches << std::endl;
715
749
}
716
750
return matches;
717
751
};
@@ -759,6 +793,7 @@ ur_result_t urDeviceGetSelected(ur_platform_handle_t hPlatform,
759
793
}
760
794
return matches;
761
795
};
796
+ auto numAlreadySelected = selectedDevices.size ();
762
797
if (accept.level == DevicePartLevel::ROOT) {
763
798
rootDevices.erase (std::remove_if (rootDevices.begin (),
764
799
rootDevices.end (),
@@ -777,6 +812,13 @@ ur_result_t urDeviceGetSelected(ur_platform_handle_t hPlatform,
777
812
ApplyAcceptFilter),
778
813
subSubDevices.end ());
779
814
}
815
+ if (numAlreadySelected == selectedDevices.size ()) {
816
+ std::cout << " WARNING: an accept term was ignored because it "
817
+ " does not select any additional devices"
818
+ " selectedDevices.size() = "
819
+ << selectedDevices.size ()
820
+ << std::endl;
821
+ }
780
822
}
781
823
782
824
// selectedDevices is now a vector containing all the right device handles
0 commit comments