open_cl_low_level/
context_builder.rs1use crate::{
2 list_devices_by_type, list_platforms, ClContext, ClDeviceID, ClPlatformID, DeviceType, Error,
3 Output,
4};
5
6#[derive(Debug, Fail, PartialEq, Eq, Clone)]
7pub enum ContextBuilderError {
8 #[fail(display = "For context building devices and device type cannot both be specified")]
9 CannotSpecifyDevicesAndDeviceType,
10
11 #[fail(display = "For context building devices and platforms cannot both be specified")]
12 CannotSpecifyDevicesAndPlatforms,
13}
14
15const DEVICES_AND_DEVICE_TYPE_ERROR: Error =
16 Error::ContextBuilderError(ContextBuilderError::CannotSpecifyDevicesAndDeviceType);
17const DEVICES_AND_PLATFORMS_ERROR: Error =
18 Error::ContextBuilderError(ContextBuilderError::CannotSpecifyDevicesAndPlatforms);
19
20pub struct ClContextBuilder<'a> {
21 pub platforms: Option<&'a [ClPlatformID]>,
22 pub device_type: Option<DeviceType>,
23 pub devices: Option<&'a [ClDeviceID]>,
24}
25
26impl<'a> ClContextBuilder<'a> {
27 pub fn new() -> ClContextBuilder<'a> {
28 ClContextBuilder {
29 platforms: None,
30 device_type: None,
31 devices: None,
32 }
33 }
34
35 pub fn with_platforms(mut self, platforms: &'a [ClPlatformID]) -> ClContextBuilder<'a> {
36 self.platforms = Some(platforms);
37 self
38 }
39
40 pub fn with_device_type(mut self, device_type: DeviceType) -> ClContextBuilder<'a> {
41 self.device_type = Some(device_type);
42 self
43 }
44
45 pub fn with_devices(mut self, devices: &'a [ClDeviceID]) -> ClContextBuilder<'a> {
46 self.devices = Some(devices);
47 self
48 }
49
50 pub unsafe fn build(self) -> Output<BuiltClContext> {
51 use ClContextBuilder as B;
52 match self {
53 B {
54 device_type: Some(device_type),
55 devices: None,
56 platforms: None,
57 } => ClContextBuilder::build_from_device_type(device_type),
58 B {
59 devices: Some(devices),
60 device_type: None,
61 platforms: None,
62 } => ClContextBuilder::build_from_devices(devices),
63 B {
64 platforms: Some(platforms),
65 device_type: None,
66 devices: None,
67 } => ClContextBuilder::build_from_platforms(platforms),
68 B {
69 platforms: Some(platforms),
70 device_type: Some(device_type),
71 devices: None,
72 } => ClContextBuilder::build_from_platforms_with_device_type(platforms, device_type),
73 B {
74 platforms: None,
75 device_type: None,
76 devices: None,
77 } => ClContextBuilder::build_with_defaults(),
78 B {
79 device_type: Some(_),
80 devices: Some(_),
81 ..
82 } => Err(DEVICES_AND_DEVICE_TYPE_ERROR),
83 B {
84 devices: Some(_),
85 platforms: Some(_),
86 ..
87 } => Err(DEVICES_AND_PLATFORMS_ERROR),
88 }
89 }
90
91 pub unsafe fn build_with_defaults() -> Output<BuiltClContext> {
92 let platforms = list_platforms()?;
93 ClContextBuilder::build_from_platforms(&platforms[..])
94 }
95
96 pub unsafe fn build_from_platforms(platforms: &[ClPlatformID]) -> Output<BuiltClContext> {
97 ClContextBuilder::build_from_platforms_with_device_type(platforms, DeviceType::ALL)
98 }
99
100 pub unsafe fn build_from_platforms_with_device_type(
101 platforms: &[ClPlatformID],
102 device_type: DeviceType,
103 ) -> Output<BuiltClContext> {
104 let mut devices = Vec::new();
105 for p in platforms.iter() {
106 let p_devices = list_devices_by_type(p, device_type)?;
107 devices.extend(p_devices);
108 }
109 let context = ClContext::create(&devices[..])?;
110 Ok(BuiltClContext::ContextWithDevices(context, devices))
111 }
112
113 pub unsafe fn build_from_devices(devices: &[ClDeviceID]) -> Output<BuiltClContext> {
114 let context = ClContext::create(&devices[..])?;
115 Ok(BuiltClContext::Context(context))
116 }
117
118 pub unsafe fn build_from_device_type(device_type: DeviceType) -> Output<BuiltClContext> {
119 let platforms = list_platforms()?;
120 ClContextBuilder::build_from_platforms_with_device_type(&platforms[..], device_type)
121 }
122}
123
124pub enum BuiltClContext {
125 Context(ClContext),
126 ContextWithDevices(ClContext, Vec<ClDeviceID>),
127}