28 std::vector<std::string>
tokenize(
const std::string &Filter,
29 const std::string &Delim) {
30 std::vector<std::string> Tokens;
32 std::string Input = Filter;
35 while ((Pos = Input.find(Delim)) != std::string::npos) {
36 Tok = Input.substr(0, Pos);
37 Input.erase(0, Pos + Delim.length());
40 Tokens.push_back(std::move(Tok));
46 Tokens.push_back(std::move(Input));
53 constexpr
auto Error =
"Invalid filter string! Valid strings conform to "
54 "BE:DeviceType:DeviceNum, where any are optional";
56 std::vector<std::string> Tokens =
tokenize(Input,
":");
57 std::regex IntegerExpr(
"[[:digit:]]+");
61 if (Tokens.size() > 3)
64 for (
const std::string &Token : Tokens) {
72 Result.
DeviceType = info::device_type::accelerator;
74 }
else if (Token ==
"opencl" && !Result.
HasBackend) {
75 Result.
Backend = backend::opencl;
77 }
else if (Token ==
"level_zero" && !Result.
HasBackend) {
78 Result.
Backend = backend::ext_oneapi_level_zero;
80 }
else if (Token ==
"cuda" && !Result.
HasBackend) {
81 Result.
Backend = backend::ext_oneapi_cuda;
83 }
else if (Token ==
"hip" && !Result.
HasBackend) {
84 Result.
Backend = backend::ext_oneapi_hip;
86 }
else if (Token ==
"host") {
92 throw sycl::runtime_error(
93 "Cannot specify host device with non-host backend.",
96 }
else if (std::regex_match(Token, IntegerExpr) && !Result.
HasDeviceNum) {
99 }
catch (std::logic_error &) {
111 filter_selector_impl::filter_selector_impl(
const std::string &Input)
112 : mFilters(), mRanker(), mNumDevicesSeen(0), mMatchFound(false) {
116 for (
const std::string &Filter : Filters) {
118 mFilters.push_back(std::move(F));
123 int Score = REJECT_DEVICE_SCORE;
125 for (
auto &Filter : mFilters) {
126 bool BackendOK =
true;
127 bool DeviceTypeOK =
true;
128 bool DeviceNumOK =
true;
131 if (Filter.HasBackend) {
142 BackendOK = (BE == Filter.Backend);
144 if (Filter.HasDeviceType) {
150 DeviceTypeOK = (DT == Filter.DeviceType);
152 if (Filter.HasDeviceNum) {
154 if (BackendOK && DeviceTypeOK) {
156 DeviceNumOK = (Filter.MatchesSeen == Filter.DeviceNum);
158 Filter.MatchesSeen++;
161 if (BackendOK && DeviceTypeOK && DeviceNumOK) {
162 Score = mRanker(Dev);
169 if ((mNumDevicesSeen == mNumTotalDevices) && !mMatchFound) {
170 throw sycl::runtime_error(
171 "Could not find a device that matches the specified filter(s)!",
181 for (
auto &Filter : mFilters) {
182 Filter.MatchesSeen = 0;
193 using namespace ext::oneapi;