open_cl_low_level/
context_builder.rs

1use 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}