-
Notifications
You must be signed in to change notification settings - Fork 769
[SYCL] Implement new env var SYCL_DEVICE_FILTER #2239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b4a5ffa
0456825
72634d5
6ec2671
5471b63
6b25217
0e9c8d4
6304163
35937b5
8e38292
779d304
f8034c3
da4eab2
b995852
fa1fd6e
230bbd4
1e4bac0
ded32d0
18bb025
0eb0697
1b12fb2
c1475c7
1c0226b
a1f075e
e0d037f
7721ca5
432eb20
ff720c4
b70a425
7a375f4
52c1c88
c46a497
facf402
a996dc0
be44799
800afe4
dd06217
6864017
8494203
156045a
8de7500
39c0725
f7f3718
4399a96
9b83eee
092673f
84a80ef
0a0cf63
dd12cba
f3c6387
4708688
ba2c293
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
//==---------- device_filter.hpp - SYCL device filter descriptor -----------==// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#pragma once | ||
|
||
#include <CL/sycl/backend_types.hpp> | ||
#include <CL/sycl/detail/defines.hpp> | ||
#include <CL/sycl/info/info_desc.hpp> | ||
|
||
#include <iostream> | ||
#include <string> | ||
|
||
__SYCL_INLINE_NAMESPACE(cl) { | ||
namespace sycl { | ||
namespace detail { | ||
|
||
struct device_filter { | ||
backend Backend = backend::all; | ||
info::device_type DeviceType = info::device_type::all; | ||
int DeviceNum = 0; | ||
bool HasBackend = false; | ||
bool HasDeviceType = false; | ||
bool HasDeviceNum = false; | ||
vladimirlaz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
int MatchesSeen = 0; | ||
|
||
device_filter(){}; | ||
device_filter(const std::string &FilterString); | ||
friend std::ostream &operator<<(std::ostream &Out, | ||
const device_filter &Filter); | ||
}; | ||
|
||
class device_filter_list { | ||
std::vector<device_filter> FilterList; | ||
|
||
public: | ||
device_filter_list() {} | ||
device_filter_list(const std::string &FilterString); | ||
device_filter_list(device_filter &Filter); | ||
void addFilter(device_filter &Filter); | ||
std::vector<device_filter> &get() { return FilterList; } | ||
friend std::ostream &operator<<(std::ostream &Out, | ||
const device_filter_list &List); | ||
}; | ||
|
||
inline std::ostream &operator<<(std::ostream &Out, | ||
const device_filter &Filter) { | ||
Out << Filter.Backend << ":"; | ||
if (Filter.DeviceType == info::device_type::host) { | ||
Out << "host"; | ||
} else if (Filter.DeviceType == info::device_type::cpu) { | ||
Out << "cpu"; | ||
} else if (Filter.DeviceType == info::device_type::gpu) { | ||
Out << "gpu"; | ||
} else if (Filter.DeviceType == info::device_type::accelerator) { | ||
Out << "accelerator"; | ||
} else if (Filter.DeviceType == info::device_type::all) { | ||
Out << "*"; | ||
} else { | ||
Out << "unknown"; | ||
} | ||
if (Filter.HasDeviceNum) { | ||
Out << ":" << Filter.DeviceNum; | ||
} | ||
return Out; | ||
} | ||
|
||
inline std::ostream &operator<<(std::ostream &Out, | ||
const device_filter_list &List) { | ||
for (const device_filter &Filter : List.FilterList) { | ||
Out << Filter; | ||
Out << ","; | ||
} | ||
return Out; | ||
} | ||
|
||
} // namespace detail | ||
} // namespace sycl | ||
} // __SYCL_INLINE_NAMESPACE(cl) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
//==------------------- device_filter.cpp ----------------------------------==// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include <CL/sycl/detail/device_filter.hpp> | ||
#include <CL/sycl/info/info_desc.hpp> | ||
#include <detail/config.hpp> | ||
#include <detail/device_impl.hpp> | ||
|
||
#include <cstring> | ||
|
||
__SYCL_INLINE_NAMESPACE(cl) { | ||
namespace sycl { | ||
namespace detail { | ||
|
||
device_filter::device_filter(const std::string &FilterString) { | ||
const std::array<std::pair<std::string, info::device_type>, 5> | ||
SyclDeviceTypeMap = {{{"host", info::device_type::host}, | ||
{"cpu", info::device_type::cpu}, | ||
{"gpu", info::device_type::gpu}, | ||
{"acc", info::device_type::accelerator}, | ||
{"*", info::device_type::all}}}; | ||
const std::array<std::pair<std::string, backend>, 5> SyclBeMap = { | ||
{{"host", backend::host}, | ||
{"opencl", backend::opencl}, | ||
{"level_zero", backend::level_zero}, | ||
{"cuda", backend::cuda}, | ||
{"*", backend::all}}}; | ||
|
||
size_t Cursor = 0; | ||
size_t ColonPos = 0; | ||
auto findElement = [&](auto Element) { | ||
size_t Found = FilterString.find(Element.first, Cursor); | ||
if (Found == std::string::npos) | ||
return false; | ||
Cursor = Found; | ||
return true; | ||
}; | ||
auto selectElement = [&](auto It, auto Map, auto EltIfNotFound) { | ||
if (It == Map.end()) | ||
return EltIfNotFound; | ||
ColonPos = FilterString.find(":", Cursor); | ||
if (ColonPos != std::string::npos) | ||
Cursor = ColonPos + 1; | ||
else | ||
Cursor = Cursor + It->first.size(); | ||
return It->second; | ||
}; | ||
|
||
// Handle the optional 1st field of the filter, backend | ||
// Check if the first entry matches with a known backend type | ||
auto It = | ||
std::find_if(std::begin(SyclBeMap), std::end(SyclBeMap), findElement); | ||
// If no match is found, set the backend type backend::all | ||
// which actually means 'any backend' will be a match. | ||
Backend = selectElement(It, SyclBeMap, backend::all); | ||
|
||
// Handle the optional 2nd field of the filter - device type. | ||
// Check if the 2nd entry matches with any known device type. | ||
if (Cursor >= FilterString.size()) { | ||
DeviceType = info::device_type::all; | ||
} else { | ||
auto Iter = std::find_if(std::begin(SyclDeviceTypeMap), | ||
std::end(SyclDeviceTypeMap), findElement); | ||
// If no match is found, set device_type 'all', | ||
// which actually means 'any device_type' will be a match. | ||
DeviceType = selectElement(Iter, SyclDeviceTypeMap, info::device_type::all); | ||
} | ||
|
||
// Handle the optional 3rd field of the filter, device number | ||
// Try to convert the remaining string to an integer. | ||
// If succeessful, the converted integer is the desired device num. | ||
if (Cursor < FilterString.size()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please comment the code from time to time. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. Done. |
||
try { | ||
DeviceNum = stoi(FilterString.substr(ColonPos + 1)); | ||
HasDeviceNum = true; | ||
} catch (...) { | ||
std::string Message = | ||
std::string("Invalid device filter: ") + FilterString + | ||
"\nPossible backend values are {host,opencl,level_zero,cuda,*}.\n" | ||
"Possible device types are {host,cpu,gpu,acc,*}.\n" | ||
"Device number should be an non-negative integer.\n"; | ||
throw cl::sycl::invalid_parameter_error(Message, PI_INVALID_VALUE); | ||
} | ||
} | ||
} | ||
|
||
device_filter_list::device_filter_list(const std::string &FilterStr) { | ||
// First, change the string in all lowercase. | ||
// This means we allow the user to use both uppercase and lowercase strings. | ||
std::string FilterString = FilterStr; | ||
std::transform(FilterString.begin(), FilterString.end(), FilterString.begin(), | ||
::tolower); | ||
// SYCL_DEVICE_FILTER can set multiple filters separated by commas. | ||
// convert each filter triple string into an istance of device_filter class. | ||
size_t Pos = 0; | ||
while (Pos < FilterString.size()) { | ||
size_t CommaPos = FilterString.find(",", Pos); | ||
if (CommaPos == std::string::npos) { | ||
v-klochkov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
CommaPos = FilterString.size(); | ||
} | ||
std::string SubString = FilterString.substr(Pos, CommaPos - Pos); | ||
FilterList.push_back(device_filter(SubString)); | ||
Pos = CommaPos + 1; | ||
} | ||
} | ||
|
||
device_filter_list::device_filter_list(device_filter &Filter) { | ||
FilterList.push_back(Filter); | ||
} | ||
|
||
void device_filter_list::addFilter(device_filter &Filter) { | ||
FilterList.push_back(Filter); | ||
} | ||
|
||
} // namespace detail | ||
} // namespace sycl | ||
} // __SYCL_INLINE_NAMESPACE(cl) |
Uh oh!
There was an error while loading. Please reload this page.