From fdbf953d829197d972c385152b952c927f8d9b9e Mon Sep 17 00:00:00 2001 From: Ken Barker Date: Thu, 18 Mar 2021 18:01:13 +0000 Subject: [PATCH] Change InfoType to_str handling for #2. Remove `Str` enum value, use `VecUchar` instead. Add `to_str_unchecked` method to convert a `VecUchar` into a `CString` including all `nul` characters. --- src/device.rs | 2 +- src/info_type.rs | 28 ++++++++++++++++++---------- src/kernel.rs | 36 ++++++++++++++++++++++++++---------- src/platform.rs | 2 +- src/program.rs | 8 +++++--- 5 files changed, 51 insertions(+), 25 deletions(-) diff --git a/src/device.rs b/src/device.rs index 012c445..43d2f46 100644 --- a/src/device.rs +++ b/src/device.rs @@ -313,7 +313,7 @@ pub fn get_device_info(device: cl_device_id, param_name: DeviceInfo) -> Result { api_info_vector!(get_string, u8, clGetDeviceInfo); let size = get_size(device, param_id)?; - Ok(InfoType::Str(get_string(device, param_id, size)?)) + Ok(InfoType::VecUchar(get_string(device, param_id, size)?)) } DeviceInfo::CL_DEVICE_VENDOR_ID diff --git a/src/info_type.rs b/src/info_type.rs index 883f2f6..db46bf3 100644 --- a/src/info_type.rs +++ b/src/info_type.rs @@ -21,7 +21,6 @@ use std::ffi::{CString, NulError}; /// The functions will panic if they are called for the incorrect type. #[derive(Debug)] pub enum InfoType { - Str(Vec), Int(cl_int), Uint(cl_uint), Ulong(cl_ulong), @@ -38,16 +37,25 @@ pub enum InfoType { impl InfoType { pub fn to_str(self) -> Result { - match self { - InfoType::Str(mut a) => { - // remove all trailing nulls if any - while let Some(0) = a.last() { - a.pop(); - } - CString::new(a) - } - _ => panic!("not a String"), + let mut a = self.to_vec_uchar(); + + // remove all trailing nulls if any + while let Some(0) = a.last() { + a.pop(); + } + + CString::new(a) + } + + pub unsafe fn to_str_unchecked(self) -> CString { + let mut a = self.to_vec_uchar(); + + // remove all trailing nulls if any + while let Some(0) = a.last() { + a.pop(); } + + CString::from_vec_unchecked(a) } pub fn to_int(self) -> cl_int { diff --git a/src/kernel.rs b/src/kernel.rs index 8de0d98..375d3bb 100644 --- a/src/kernel.rs +++ b/src/kernel.rs @@ -251,7 +251,7 @@ pub fn get_kernel_info(kernel: cl_kernel, param_name: KernelInfo) -> Result { api_info_vector!(get_string, u8, clGetKernelInfo); let size = get_size(kernel, param_id)?; - Ok(InfoType::Str(get_string(kernel, param_id, size)?)) + Ok(InfoType::VecUchar(get_string(kernel, param_id, size)?)) } KernelInfo::CL_KERNEL_NUM_ARGS | KernelInfo::CL_KERNEL_REFERENCE_COUNT => { @@ -309,7 +309,7 @@ pub fn get_kernel_arg_info( api2_info_size!(get_device_size, cl_uint, clGetKernelArgInfo); api2_info_vector!(get_device_string, cl_uint, u8, clGetKernelArgInfo); let size = get_device_size(kernel, arg_indx, param_id)?; - Ok(InfoType::Str(get_device_string( + Ok(InfoType::VecUchar(get_device_string( kernel, arg_indx, param_id, size, )?)) } @@ -491,9 +491,9 @@ mod tests { use super::*; use crate::context::{create_context, release_context}; use crate::device::{get_device_ids, CL_DEVICE_TYPE_GPU}; + use crate::error_codes::error_text; use crate::platform::get_platform_ids; use crate::program::{build_program, create_program_with_source, release_program}; - use crate::error_codes::error_text; use std::ffi::CString; #[test] @@ -569,7 +569,10 @@ mod tests { let value = value.to_uint(); println!("CL_KERNEL_ARG_ADDRESS_QUALIFIER: {:X}", value) } - Err(e) => println!("OpenCL error, CL_KERNEL_ARG_ADDRESS_QUALIFIER: {}", error_text(e)) + Err(e) => println!( + "OpenCL error, CL_KERNEL_ARG_ADDRESS_QUALIFIER: {}", + error_text(e) + ), } match get_kernel_arg_info(kernel, 0, KernelArgInfo::CL_KERNEL_ARG_ACCESS_QUALIFIER) { @@ -577,7 +580,10 @@ mod tests { let value = value.to_uint(); println!("CL_KERNEL_ARG_ACCESS_QUALIFIER: {:X}", value) } - Err(e) => println!("OpenCL error, CL_KERNEL_ARG_ACCESS_QUALIFIER: {}", error_text(e)) + Err(e) => println!( + "OpenCL error, CL_KERNEL_ARG_ACCESS_QUALIFIER: {}", + error_text(e) + ), } match get_kernel_arg_info(kernel, 0, KernelArgInfo::CL_KERNEL_ARG_TYPE_NAME) { @@ -586,7 +592,7 @@ mod tests { println!("CL_KERNEL_ARG_TYPE_NAME: {:?}", value); assert!(0 < value.to_bytes().len()) } - Err(e) => println!("OpenCL error, CL_KERNEL_ARG_TYPE_NAME: {}", error_text(e)) + Err(e) => println!("OpenCL error, CL_KERNEL_ARG_TYPE_NAME: {}", error_text(e)), } match get_kernel_arg_info(kernel, 0, KernelArgInfo::CL_KERNEL_ARG_TYPE_QUALIFIER) { @@ -594,7 +600,10 @@ mod tests { let value = value.to_ulong(); println!("CL_KERNEL_ARG_TYPE_QUALIFIER: {:X}", value) } - Err(e) => println!("OpenCL error, CL_KERNEL_ARG_TYPE_QUALIFIER: {}", error_text(e)) + Err(e) => println!( + "OpenCL error, CL_KERNEL_ARG_TYPE_QUALIFIER: {}", + error_text(e) + ), } match get_kernel_arg_info(kernel, 0, KernelArgInfo::CL_KERNEL_ARG_NAME) { @@ -603,7 +612,7 @@ mod tests { println!("CL_KERNEL_ARG_NAME: {:?}", value); assert!(0 < value.to_bytes().len()) } - Err(e) => println!("OpenCL error, CL_KERNEL_ARG_NAME: {}", error_text(e)) + Err(e) => println!("OpenCL error, CL_KERNEL_ARG_NAME: {}", error_text(e)), } let value = get_kernel_work_group_info( @@ -651,12 +660,19 @@ mod tests { let value = value.to_ulong(); println!("CL_KERNEL_PRIVATE_MEM_SIZE: {}", value); - match get_kernel_work_group_info(kernel, device_id, KernelWorkGroupInfo::CL_KERNEL_GLOBAL_WORK_SIZE) { + match get_kernel_work_group_info( + kernel, + device_id, + KernelWorkGroupInfo::CL_KERNEL_GLOBAL_WORK_SIZE, + ) { Ok(value) => { let value = value.to_vec_size(); println!("CL_KERNEL_GLOBAL_WORK_SIZE: {}", value.len()) } - Err(e) => println!("OpenCL error, CL_KERNEL_GLOBAL_WORK_SIZE: {}", error_text(e)) + Err(e) => println!( + "OpenCL error, CL_KERNEL_GLOBAL_WORK_SIZE: {}", + error_text(e) + ), } release_kernel(kernel).unwrap(); diff --git a/src/platform.rs b/src/platform.rs index 31c74b5..510a8d4 100644 --- a/src/platform.rs +++ b/src/platform.rs @@ -126,7 +126,7 @@ pub fn get_platform_info( | PlatformInfo::CL_PLATFORM_EXTENSIONS => { api_info_vector!(get_string, u8, clGetPlatformInfo); let size = get_size(platform, param_id)?; - Ok(InfoType::Str(get_string(platform, param_id, size)?)) + Ok(InfoType::VecUchar(get_string(platform, param_id, size)?)) } // CL_VERSION_3_0 PlatformInfo::CL_PLATFORM_NUMERIC_VERSION => { diff --git a/src/program.rs b/src/program.rs index 7d8f54b..ffbb47e 100644 --- a/src/program.rs +++ b/src/program.rs @@ -498,7 +498,7 @@ pub fn get_program_info( ProgramInfo::CL_PROGRAM_SOURCE | ProgramInfo::CL_PROGRAM_KERNEL_NAMES | ProgramInfo::CL_PROGRAM_IL => { api_info_vector!(get_string, u8, clGetProgramInfo); let size = get_size(program, param_id)?; - Ok(InfoType::Str(get_string(program, param_id, size)?)) + Ok(InfoType::VecUchar(get_string(program, param_id, size)?)) } ProgramInfo::CL_PROGRAM_BINARY_SIZES => { @@ -586,7 +586,7 @@ pub fn get_program_build_info( api2_info_size!(get_device_size, cl_device_id, clGetProgramBuildInfo); api2_info_vector!(get_device_string, cl_device_id, u8, clGetProgramBuildInfo); let size = get_device_size(program, device, param_id)?; - Ok(InfoType::Str(get_device_string(program, device, param_id, size)?)) + Ok(InfoType::VecUchar(get_device_string(program, device, param_id, size)?)) } ProgramBuildInfo::CL_PROGRAM_BINARY_TYPE => { @@ -690,9 +690,11 @@ mod tests { let value = value.to_str().unwrap(); println!("CL_PROGRAM_BUILD_OPTIONS: {:?}", value); + unsafe { let value = get_program_build_info(program, device_id, ProgramBuildInfo::CL_PROGRAM_BUILD_LOG).unwrap(); - let value = value.to_str().unwrap(); + let value = value.to_str_unchecked(); println!("CL_PROGRAM_BUILD_LOG: {:?}", value); + } let value = get_program_build_info(program, device_id, ProgramBuildInfo::CL_PROGRAM_BINARY_TYPE).unwrap(); let value = value.to_uint();