opencl_api/api/
platform.rs

1/*
2 * platform.rs - Platform API wrappers (Part of OpenCL Platform Layer).
3 *
4 * Copyright 2020-2021 Naman Bishnoi
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18//! The platform layer allows the host program to discover OpenCL devices
19//! and their capabilities and to create contexts.
20//!
21use crate::objects::enums::{ParamValue, Size};
22use crate::objects::functions::{bytes_into_string, status_update};
23use crate::objects::structs::PlatformInfo;
24use crate::objects::types::{APIResult, PlatformList, PlatformPtr};
25use crate::{gen_object_list, gen_param_value, get_count, size_getter};
26use libc::c_void;
27use opencl_heads::ffi::*;
28use std::ptr;
29
30/// Returns the list of all platforms available
31///
32/// `num_entries` is number of cl_platform_id entries can be added to platforms.
33/// if platforms is not null, num_entries must be greater than zero.
34///
35/// # Examples
36/// ```
37/// use opencl_api::api::platform::*;
38///
39/// let id = get_platform_ids();
40/// ```
41pub fn get_platform_ids() -> APIResult<PlatformList> {
42    let platform_count = get_count!(clGetPlatformIDs);
43
44    if platform_count == 0 {
45        Ok(Vec::default())
46    } else {
47        gen_object_list!(clGetPlatformIDs, PlatformList, platform_count)
48    }
49}
50
51pub fn get_platform_info(
52    platform: &PlatformPtr,
53    param_name: cl_platform_info,
54) -> APIResult<ParamValue> {
55    type P = PlatformInfo;
56    let platform = platform.unwrap();
57    size_getter!(get_platform_info_size, clGetPlatformInfo);
58    let fn_name = "clGetPlatformInfo";
59    match param_name {
60        P::PROFILE | P::VERSION | P::VENDOR | P::NAME | P::EXTENSIONS => {
61            let size = get_platform_info_size(platform, param_name)?;
62            let param_value = gen_param_value!(clGetPlatformInfo, u8, platform, param_name, size);
63            Ok(ParamValue::String(bytes_into_string(param_value)?))
64        }
65        // >= CL 2.1
66        P::HOST_TIMER_RESOLUTION => {
67            let param_value = gen_param_value!(clGetPlatformInfo, u64, platform, param_name);
68            Ok(ParamValue::ULong(param_value))
69        }
70        // >= CL 3.0
71        P::NUMERIC_VERSION => {
72            let param_value = gen_param_value!(clGetPlatformInfo, u32, platform, param_name);
73            Ok(ParamValue::UInt(param_value))
74        }
75        // >= CL 3.0
76        P::EXTENSIONS_WITH_VERSION => {
77            let size = get_platform_info_size(platform, param_name)?;
78            let param_value = gen_param_value!(
79                clGetPlatformInfo,
80                cl_name_version,
81                platform,
82                param_name,
83                size
84            );
85            Ok(ParamValue::NameVersion(param_value))
86        }
87        _ => status_update(40404, fn_name, ParamValue::default()),
88    }
89}
90
91/************************/
92/* /\ /\ /\ /\ /\ /\ /\ */
93/*|__|__|__|__|__|__|__|*/
94/*|  |  |  |  |  |  |  |*/
95/*|  |  Unit Tests  |  |*/
96/*|__|__|__|__|__|__|__|*/
97/*|__|__|__|__|__|__|__|*/
98/************************/
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103    #[test]
104    // #[ignore]
105    fn test_get_platform_ids() {
106        let id = get_platform_ids().unwrap();
107        assert_ne!(id, vec!(ptr::null_mut()));
108        assert_ne!(id, vec!());
109    }
110    #[test]
111    // #[ignore]
112    fn test_get_platform_info() {
113        let all_platforms = get_platform_ids().unwrap();
114        let id = PlatformPtr::from_ptr(all_platforms[0], "main_fn").unwrap();
115
116        let name = get_platform_info(&id, PlatformInfo::NAME).unwrap();
117        println!("CL_PLATFORM_NAME: {:?}", name);
118        assert_ne!(name.unwrap_string().unwrap(), "");
119
120        let version = get_platform_info(&id, PlatformInfo::VERSION).unwrap();
121        println!("CL_PLATFORM_VERSION: {:?}", version);
122        assert_ne!(version.unwrap_string().unwrap(), "");
123
124        let vendor = get_platform_info(&id, PlatformInfo::VENDOR).unwrap();
125        println!("CL_PLATFORM_VENDOR: {:?}", vendor);
126        assert_ne!(vendor.unwrap_string().unwrap(), "");
127
128        let profile = get_platform_info(&id, PlatformInfo::PROFILE).unwrap();
129        println!("CL_PLATFORM_PROFILE: {:?}", profile);
130        assert_ne!(profile.unwrap_string().unwrap(), "");
131
132        let extensions = get_platform_info(&id, PlatformInfo::EXTENSIONS).unwrap();
133        println!("CL_PLATFORM_EXTENSIONS: {:?}", extensions);
134        assert_ne!(extensions.unwrap_string().unwrap(), "");
135    }
136
137    #[test]
138    #[ignore]
139    fn test_get_platform_info_fail() {
140        let all_platforms = get_platform_ids().unwrap();
141        // let id = all_platforms[0];
142        let id = PlatformPtr::from_ptr(all_platforms[0], "main_fn").unwrap();
143        let wrong_id = 666;
144
145        let extensions = get_platform_info(&id, wrong_id)
146            .expect_err("Wrong ID entered, check your structs dude!");
147        println!("CL_PLATFORM_INVALID: {:?}", extensions);
148        // Bullshit! I will do this later on.
149        // assert_ne!(extensions, );
150    }
151
152    #[test]
153    #[cfg(feature = "cl_2_0")]
154    fn test_get_platform_info_v2() {
155        let all_platforms = get_platform_ids().unwrap();
156        // let id = all_platforms[0];
157        //TODO: Add auto-detection of platforms
158        let id = PlatformPtr::from_ptr(all_platforms[0], "main_fn").unwrap();
159
160        let extversion = get_platform_info(&id, PlatformInfo::HOST_TIMER_RESOLUTION).unwrap();
161        println!("CL_PLATFORM_HOST_TIMER_RESOLUTION: {:?}", extversion);
162        assert_ne!(extversion.unwrap_ulong().unwrap(), 0);
163    }
164
165    #[test]
166    #[cfg(feature = "cl_3_0")]
167    fn test_get_platform_info_v3() {
168        let all_platforms = get_platform_ids().unwrap();
169        println!("Number of platforms: {}", all_platforms.len());
170        let id = all_platforms[0];
171
172        let numver = get_platform_info(id, PlatformInfo::NUMERIC_VERSION).unwrap();
173        println!("CL_PLATFORM_NUMERIC_VERSION: {:?}", numver);
174        assert_eq!(numver.unwrap_uint().unwrap(), 0);
175
176        let extversion = get_platform_info(id, PlatformInfo::EXTENSIONS_WITH_VERSION).unwrap();
177        println!("CL_PLATFORM_EXTENSIONS_WITH_VERSION: {:?}", extversion);
178        assert_ne!(extversion.unwrap_name_version().unwrap().len(), 0);
179    }
180}