rusticl/program: loop over all devices inside Program::build

We want to build the kernels once and atm we are doing it several times
for each device.

Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33892>
This commit is contained in:
Karol Herbst 2025-03-05 01:56:18 +01:00 committed by Marge Bot
parent e434ce1559
commit 241279ac2c
2 changed files with 39 additions and 36 deletions

View file

@ -322,7 +322,6 @@ fn build_program(
pfn_notify: Option<FuncProgramCB>,
user_data: *mut ::std::os::raw::c_void,
) -> CLResult<()> {
let mut res = true;
let p = Program::ref_from_raw(program)?;
let devs = validate_devices(device_list, num_devices, &p.devs)?;
@ -338,9 +337,7 @@ fn build_program(
// CL_BUILD_PROGRAM_FAILURE if there is a failure to build the program executable. This error
// will be returned if clBuildProgram does not return until the build has completed.
let options = c_string_to_string(options);
for dev in &devs {
res &= p.build(dev, &options);
}
let res = p.build(&devs, &options);
if let Some(cb) = cb_opt {
cb.call(p);

View file

@ -552,45 +552,51 @@ impl Program {
.any(|b| b.kernels.values().any(|b| Arc::strong_count(b) > 1))
}
pub fn build(&self, dev: &Device, options: &str) -> bool {
pub fn build(&self, devs: &[&Device], options: &str) -> bool {
let lib = options.contains("-create-library");
let mut info = self.build_info();
if !self.do_compile(dev, options, &Vec::new(), &mut info) {
return false;
}
let d = info.dev_build_mut(dev);
let mut res = true;
for dev in devs {
if !self.do_compile(dev, options, &Vec::new(), &mut info) {
res = false;
continue;
}
// skip compilation if we already have the right thing.
if self.is_bin() {
if d.bin_type == CL_PROGRAM_BINARY_TYPE_EXECUTABLE && !lib
|| d.bin_type == CL_PROGRAM_BINARY_TYPE_LIBRARY && lib
{
return true;
// skip compilation if we already have the right thing.
let d = info.dev_build_mut(dev);
if self.is_bin() {
if d.bin_type == CL_PROGRAM_BINARY_TYPE_EXECUTABLE && !lib
|| d.bin_type == CL_PROGRAM_BINARY_TYPE_LIBRARY && lib
{
continue;
}
}
let spirvs = [d.spirv.as_ref().unwrap()];
let (spirv, log) = spirv::SPIRVBin::link(&spirvs, lib);
d.log.push_str(&log);
d.spirv = spirv;
if let Some(spirv) = &d.spirv {
d.bin_type = if lib {
CL_PROGRAM_BINARY_TYPE_LIBRARY
} else {
CL_PROGRAM_BINARY_TYPE_EXECUTABLE
};
d.status = CL_BUILD_SUCCESS as cl_build_status;
let mut kernels = spirv.kernels();
info.kernels.append(&mut kernels);
info.build_nirs(self.is_src());
} else {
d.status = CL_BUILD_ERROR;
d.bin_type = CL_PROGRAM_BINARY_TYPE_NONE;
res = false;
}
}
let spirvs = [d.spirv.as_ref().unwrap()];
let (spirv, log) = spirv::SPIRVBin::link(&spirvs, lib);
d.log.push_str(&log);
d.spirv = spirv;
if let Some(spirv) = &d.spirv {
d.bin_type = if lib {
CL_PROGRAM_BINARY_TYPE_LIBRARY
} else {
CL_PROGRAM_BINARY_TYPE_EXECUTABLE
};
d.status = CL_BUILD_SUCCESS as cl_build_status;
let mut kernels = spirv.kernels();
info.kernels.append(&mut kernels);
info.build_nirs(self.is_src());
true
} else {
d.status = CL_BUILD_ERROR;
d.bin_type = CL_PROGRAM_BINARY_TYPE_NONE;
false
}
res
}
fn do_compile(