-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathcontext.cc
More file actions
123 lines (95 loc) · 5 KB
/
context.cc
File metadata and controls
123 lines (95 loc) · 5 KB
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
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "simsycl/sycl/context.hh"
#include "simsycl/sycl/device.hh"
#include "simsycl/sycl/exception.hh"
#include "simsycl/sycl/info.hh"
#include "simsycl/sycl/platform.hh"
#include "simsycl/system.hh"
namespace simsycl::detail {
template<typename Info>
typename Info::return_type common_capabilities(const std::vector<sycl::device> &devices) {
SIMSYCL_CHECK(!devices.empty()); // TODO throw instead
auto common_caps = devices[0].get_info<Info>();
for(size_t i = 1; i < devices.size(); ++i) {
const auto caps = devices[i].get_info<Info>();
const auto last = std::remove_if(common_caps.begin(), common_caps.end(),
[&](const auto c) { return std::find(caps.begin(), caps.end(), c) == caps.end(); });
common_caps.erase(last, common_caps.end());
}
return common_caps;
}
struct context_state {
sycl::platform platform;
std::vector<sycl::device> devices;
sycl::async_handler async_handler;
std::vector<sycl::memory_order> atomic_memory_order_capabilities;
std::vector<sycl::memory_order> atomic_fence_order_capabilities;
std::vector<sycl::memory_scope> atomic_memory_scope_capabilities;
std::vector<sycl::memory_scope> atomic_fence_scope_capabilities;
context_state(const sycl::platform &platform, const std::vector<sycl::device> &devices,
const sycl::async_handler &async_handler)
: platform(platform), devices(devices), async_handler(async_handler),
atomic_memory_order_capabilities(
common_capabilities<sycl::info::device::atomic_memory_order_capabilities>(devices)),
atomic_fence_order_capabilities(
common_capabilities<sycl::info::device::atomic_fence_order_capabilities>(devices)),
atomic_memory_scope_capabilities(
common_capabilities<sycl::info::device::atomic_memory_scope_capabilities>(devices)),
atomic_fence_scope_capabilities(
common_capabilities<sycl::info::device::atomic_fence_scope_capabilities>(devices)) {}
};
sycl::platform get_common_platform(const std::vector<sycl::device> &devices) {
if(devices.empty()) {
throw sycl::exception(sycl::errc::invalid, "sycl::context: device list must not be empty");
}
const auto common = devices[0].get_platform();
for(size_t i = 1; i < devices.size(); ++i) { SIMSYCL_CHECK(devices[i].get_platform() == common); }
return common;
}
} // namespace simsycl::detail
namespace simsycl::sycl {
context::context(internal_t /* tag */, const std::vector<device> &devices, const async_handler &async_handler,
const property_list &prop_list)
: reference_type(std::in_place, get_common_platform(devices), devices, async_handler),
property_interface(prop_list, property_compatibility{}) {}
context::context(const property_list &prop_list)
: context(internal, {detail::select_device(default_selector_v)}, {}, prop_list) {}
context::context(async_handler async_handler, const property_list &prop_list)
: context(internal, {detail::select_device(default_selector_v)}, async_handler, prop_list) {}
context::context(const device &dev, const property_list &prop_list) : context(internal, {dev}, {}, prop_list) {}
context::context(const device &dev, async_handler async_handler, const property_list &prop_list)
: context(internal, {dev}, async_handler, prop_list) {}
context::context(const std::vector<device> &device_list, const property_list &prop_list)
: context(internal, device_list, {}, prop_list) {}
context::context(const std::vector<device> &device_list, async_handler async_handler, const property_list &prop_list)
: context(internal, device_list, async_handler, prop_list) {}
context::context(const platform &plat, const property_list &prop_list)
: context(internal, plat.get_devices(), {}, prop_list) {}
context::context(const platform &plat, async_handler async_handler, const property_list &prop_list)
: context(internal, plat.get_devices(), async_handler, prop_list) {}
template<>
platform context::get_info<info::context::platform>() const {
return state().platform;
}
template<>
std::vector<device> context::get_info<info::context::devices>() const {
return state().devices;
}
template<>
std::vector<sycl::memory_order> context::get_info<info::context::atomic_memory_order_capabilities>() const {
return state().atomic_memory_order_capabilities;
}
template<>
std::vector<sycl::memory_order> context::get_info<info::context::atomic_fence_order_capabilities>() const {
return state().atomic_fence_order_capabilities;
}
template<>
std::vector<sycl::memory_scope> context::get_info<info::context::atomic_memory_scope_capabilities>() const {
return state().atomic_memory_scope_capabilities;
}
template<>
std::vector<sycl::memory_scope> context::get_info<info::context::atomic_fence_scope_capabilities>() const {
return state().atomic_fence_scope_capabilities;
}
platform context::get_platform() const { return get_info<info::context::platform>(); }
std::vector<device> context::get_devices() const { return state().devices; }
} // namespace simsycl::sycl