forked from KhronosGroup/SYCL-CTS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdevice_set.cpp
110 lines (89 loc) · 3.12 KB
/
device_set.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*******************************************************************************
//
// SYCL 2020 Conformance Test Suite
//
// Provide generic device sets support for tests that require multiple
// devices to run
//
*******************************************************************************/
#include "device_set.h"
#include "cpp_compat.h"
#include <algorithm>
#include <stdexcept>
namespace sycl_cts::util {
device_set::device_set(const sycl::context& ctx, util::logger&)
: m_context(ctx) {
auto devices = ctx.get_devices();
m_devices.reserve(devices.size());
std::copy(devices.begin(), devices.end(),
std::inserter(m_devices, m_devices.end()));
}
void device_set::join(device_set other) {
if (m_context != other.m_context)
throw std::logic_error("Different contexts on device_set join");
m_devices.merge(other.m_devices);
}
void device_set::substract(const device_set& other) {
if (m_context != other.m_context)
throw std::logic_error("Different contexts on device_set substract");
for (const auto& device : other.m_devices) {
m_devices.erase(device);
}
}
void device_set::intersect(const device_set& other) {
if (m_context != other.m_context)
throw std::logic_error("Different contexts on device_set intersect");
auto condition = [&](const StorageType::iterator& it) {
const auto& device = *it;
return other.m_devices.find(device) == other.m_devices.end();
};
// must explicitly specify namespace `util` to avoid ambiguity with
// std::erase_if when compiling for C++20
util::erase_if(m_devices, condition);
}
void device_set::removeDevsWith(sycl::aspect aspect) {
auto condition = [&](const StorageType::iterator& it) {
const auto& device = *it;
return device.has(aspect);
};
util::erase_if(m_devices, condition);
}
void device_set::removeDevsWith(std::initializer_list<sycl::aspect> aspects) {
for (const auto& aspect : aspects) {
removeDevsWith(aspect);
}
}
void device_set::removeDevsWithout(sycl::aspect aspect) {
auto condition = [&](const StorageType::iterator& it) {
const auto& device = *it;
return !device.has(aspect);
};
util::erase_if(m_devices, condition);
}
void device_set::removeDevsWithout(const kernel_restrictions& restriction) {
auto condition = [&](const StorageType::iterator& it) {
const auto& device = *it;
return !restriction.is_compatible(device);
};
util::erase_if(m_devices, condition);
}
device_set device_set::filtered(const device_set& other, sycl::aspect aspect) {
device_set result(other);
result.removeDevsWithout(aspect);
return result;
}
device_set device_set::filtered(const device_set& other,
const kernel_restrictions& restrictions) {
device_set result(other);
result.removeDevsWithout(restrictions);
return result;
}
sycl::context device_set::get_context() const { return m_context; }
std::vector<sycl::device> device_set::get_devices() const {
std::vector<sycl::device> result;
result.reserve(m_devices.size());
std::copy(m_devices.begin(), m_devices.end(),
std::inserter(result, result.end()));
return result;
}
} // namespace sycl_cts::util