rusticl: write CLInfoValues from iterators instead of collecting

All of the current instances of writing info values from `Vec`s involve
building an iterator and then collecting it specifically for writing.
By using an `ExactSizeIterator`, we can avoid the need for allocating in
these cases.

v2: use existing `CLInfoValue::write_iter()` instead of custom type

Reviewed-by: @LingMan
Reviewed-by: Karol Herbst <kherbst@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34389>
This commit is contained in:
Seán de Búrca 2025-04-03 14:35:23 -07:00 committed by Marge Bot
parent 3a16c9ab43
commit 543b07bee8
6 changed files with 17 additions and 39 deletions

View file

@ -23,12 +23,9 @@ unsafe impl CLInfo<cl_context_info> for cl_context {
fn query(&self, q: cl_context_info, v: CLInfoValue) -> CLResult<CLInfoRes> {
let ctx = Context::ref_from_raw(*self)?;
match q {
CL_CONTEXT_DEVICES => v.write::<Vec<cl_device_id>>(
ctx.devs
.iter()
.map(|&d| cl_device_id::from_ptr(d))
.collect(),
),
CL_CONTEXT_DEVICES => {
v.write_iter::<cl_device_id>(ctx.devs.iter().map(|&d| cl_device_id::from_ptr(d)))
}
CL_CONTEXT_NUM_DEVICES => v.write::<cl_uint>(ctx.devs.len() as u32),
// need to return None if no properties exist
CL_CONTEXT_PROPERTIES => v.write::<&Properties<cl_context_properties>>(&ctx.properties),

View file

@ -275,11 +275,11 @@ unsafe impl CLInfo<cl_device_info> for cl_device_id {
),
CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS => v.write::<bool>(false),
CL_DEVICE_SUB_GROUP_SIZES_INTEL => {
v.write::<Vec<usize>>(if dev.subgroups_supported() {
dev.subgroup_sizes().collect()
if dev.subgroups_supported() {
v.write_iter::<usize>(dev.subgroup_sizes())
} else {
vec![0; 1]
})
v.write::<&[usize]>(&[0; 1])
}
}
CL_DEVICE_SVM_CAPABILITIES | CL_DEVICE_SVM_CAPABILITIES_ARM => {
v.write::<cl_device_svm_capabilities>(

View file

@ -198,7 +198,7 @@ unsafe impl CLInfoObj<cl_kernel_sub_group_info, (cl_device_id, usize, *const c_v
}
CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT => {
let subgroups = input[0];
let mut res = vec![0; 3];
let mut res = [0; 3];
for subgroup_size in kernel.subgroup_sizes(dev) {
let threads = subgroups * subgroup_size;
@ -211,13 +211,12 @@ unsafe impl CLInfoObj<cl_kernel_sub_group_info, (cl_device_id, usize, *const c_v
let real_subgroups = kernel.subgroups_for_block(dev, &block);
if real_subgroups == subgroups {
res = block.to_vec();
res = block;
break;
}
}
res.truncate(output_value_size / usize_byte);
v.write::<Vec<usize>>(res)
v.write_iter::<usize>(res.into_iter().take(output_value_size / usize_byte))
}
CL_KERNEL_MAX_NUM_SUB_GROUPS => {
let threads = kernel.max_threads_per_block(dev);

View file

@ -55,7 +55,7 @@ unsafe impl CLInfo<cl_program_info> for cl_program {
}
v.write_len_only::<&[*mut u8]>(prog.devs.len())
}
CL_PROGRAM_BINARY_SIZES => v.write::<Vec<usize>>(prog.bin_sizes()),
CL_PROGRAM_BINARY_SIZES => v.write_iter::<usize>(prog.bin_sizes()),
CL_PROGRAM_CONTEXT => {
// Note we use as_ptr here which doesn't increase the reference count.
let ptr = Arc::as_ptr(&prog.context);

View file

@ -340,21 +340,6 @@ impl CLProp for &CStr {
}
}
impl<T> CLProp for Vec<T>
where
T: CLProp + Copy,
{
type Output = T;
fn count(&self) -> usize {
self.len()
}
fn write_to(&self, out: &mut [MaybeUninit<T>]) {
self.as_slice().write_to(out);
}
}
impl<T> CLProp for &[T]
where
T: CLProp + Copy,

View file

@ -477,19 +477,16 @@ impl Program {
}
// we need to precalculate the size
pub fn bin_sizes(&self) -> Vec<usize> {
pub fn bin_sizes(&self) -> impl ExactSizeIterator<Item = usize> + '_ {
let lock = self.build_info();
self.devs
.iter()
.map(|&device| {
let info = lock.dev_build(device);
self.devs.iter().map(move |&device| {
let info = lock.dev_build(device);
info.spirv.as_ref().map_or(0, |s| {
s.to_bin().len() + device.screen().name().to_bytes().len() + BIN_HEADER_SIZE
})
info.spirv.as_ref().map_or(0, |s| {
s.to_bin().len() + device.screen().name().to_bytes().len() + BIN_HEADER_SIZE
})
.collect()
})
}
pub fn binaries(&self, ptrs: &[*mut u8]) -> CLResult<()> {