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 124 125 126 127
use crate::{ list_devices_by_type, list_platforms, ClContext, ClDeviceID, ClPlatformID, DeviceType, Error, Output, }; #[derive(Debug, Fail, PartialEq, Eq, Clone)] pub enum ContextBuilderError { #[fail(display = "For context building devices and device type cannot both be specified")] CannotSpecifyDevicesAndDeviceType, #[fail(display = "For context building devices and platforms cannot both be specified")] CannotSpecifyDevicesAndPlatforms, } const DEVICES_AND_DEVICE_TYPE_ERROR: Error = Error::ContextBuilderError(ContextBuilderError::CannotSpecifyDevicesAndDeviceType); const DEVICES_AND_PLATFORMS_ERROR: Error = Error::ContextBuilderError(ContextBuilderError::CannotSpecifyDevicesAndPlatforms); pub struct ClContextBuilder<'a> { pub platforms: Option<&'a [ClPlatformID]>, pub device_type: Option<DeviceType>, pub devices: Option<&'a [ClDeviceID]>, } impl<'a> ClContextBuilder<'a> { pub fn new() -> ClContextBuilder<'a> { ClContextBuilder { platforms: None, device_type: None, devices: None, } } pub fn with_platforms(mut self, platforms: &'a [ClPlatformID]) -> ClContextBuilder<'a> { self.platforms = Some(platforms); self } pub fn with_device_type(mut self, device_type: DeviceType) -> ClContextBuilder<'a> { self.device_type = Some(device_type); self } pub fn with_devices(mut self, devices: &'a [ClDeviceID]) -> ClContextBuilder<'a> { self.devices = Some(devices); self } pub unsafe fn build(self) -> Output<BuiltClContext> { use ClContextBuilder as B; match self { B { device_type: Some(device_type), devices: None, platforms: None, } => ClContextBuilder::build_from_device_type(device_type), B { devices: Some(devices), device_type: None, platforms: None, } => ClContextBuilder::build_from_devices(devices), B { platforms: Some(platforms), device_type: None, devices: None, } => ClContextBuilder::build_from_platforms(platforms), B { platforms: Some(platforms), device_type: Some(device_type), devices: None, } => ClContextBuilder::build_from_platforms_with_device_type(platforms, device_type), B { platforms: None, device_type: None, devices: None, } => ClContextBuilder::build_with_defaults(), B { device_type: Some(_), devices: Some(_), .. } => Err(DEVICES_AND_DEVICE_TYPE_ERROR), B { devices: Some(_), platforms: Some(_), .. } => Err(DEVICES_AND_PLATFORMS_ERROR), } } pub unsafe fn build_with_defaults() -> Output<BuiltClContext> { let platforms = list_platforms()?; ClContextBuilder::build_from_platforms(&platforms[..]) } pub unsafe fn build_from_platforms(platforms: &[ClPlatformID]) -> Output<BuiltClContext> { ClContextBuilder::build_from_platforms_with_device_type(platforms, DeviceType::ALL) } pub unsafe fn build_from_platforms_with_device_type( platforms: &[ClPlatformID], device_type: DeviceType, ) -> Output<BuiltClContext> { let mut devices = Vec::new(); for p in platforms.iter() { let p_devices = list_devices_by_type(p, device_type)?; devices.extend(p_devices); } let context = ClContext::create(&devices[..])?; Ok(BuiltClContext::ContextWithDevices(context, devices)) } pub unsafe fn build_from_devices(devices: &[ClDeviceID]) -> Output<BuiltClContext> { let context = ClContext::create(&devices[..])?; Ok(BuiltClContext::Context(context)) } pub unsafe fn build_from_device_type(device_type: DeviceType) -> Output<BuiltClContext> { let platforms = list_platforms()?; ClContextBuilder::build_from_platforms_with_device_type(&platforms[..], device_type) } } pub enum BuiltClContext { Context(ClContext), ContextWithDevices(ClContext, Vec<ClDeviceID>), }