mirror of
https://github.com/vosen/ZLUDA.git
synced 2025-04-20 00:14:45 +00:00
Fix problems with linking
This commit is contained in:
parent
70dc298381
commit
84ac086146
4 changed files with 88 additions and 13 deletions
|
@ -257,9 +257,15 @@ impl Module {
|
|||
ctx: &mut Context,
|
||||
d: &Device,
|
||||
binaries: &[&'a [u8]],
|
||||
opts: Option<&CStr>,
|
||||
) -> (Result<Self>, Option<BuildLog>) {
|
||||
let ocl_program = match Self::build_link_spirv_impl(binaries) {
|
||||
Err(_) => return (Err(sys::ze_result_t::ZE_RESULT_ERROR_UNKNOWN), None),
|
||||
let ocl_program = match Self::build_link_spirv_impl(binaries, opts) {
|
||||
Err(_) => {
|
||||
return (
|
||||
Err(sys::ze_result_t::ZE_RESULT_ERROR_MODULE_LINK_FAILURE),
|
||||
None,
|
||||
)
|
||||
}
|
||||
Ok(prog) => prog,
|
||||
};
|
||||
match ocl_core::get_program_info(&ocl_program, ocl_core::ProgramInfo::Binaries) {
|
||||
|
@ -271,7 +277,10 @@ impl Module {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_link_spirv_impl<'a>(binaries: &[&'a [u8]]) -> ocl_core::Result<ocl_core::Program> {
|
||||
fn build_link_spirv_impl<'a>(
|
||||
binaries: &[&'a [u8]],
|
||||
opts: Option<&CStr>,
|
||||
) -> ocl_core::Result<ocl_core::Program> {
|
||||
let platforms = ocl_core::get_platform_ids()?;
|
||||
let (platform, device) = platforms
|
||||
.iter()
|
||||
|
@ -305,7 +314,22 @@ impl Module {
|
|||
for binary in binaries {
|
||||
programs.push(ocl_core::create_program_with_il(&ocl_ctx, binary, None)?);
|
||||
}
|
||||
let options = CString::default();
|
||||
let options = match opts {
|
||||
Some(o) => o.to_owned(),
|
||||
None => CString::default(),
|
||||
};
|
||||
for program in programs.iter() {
|
||||
ocl_core::compile_program(
|
||||
program,
|
||||
Some(&[device]),
|
||||
&options,
|
||||
&[],
|
||||
&[],
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)?;
|
||||
}
|
||||
ocl_core::link_program::<ocl_core::DeviceId, _>(
|
||||
&ocl_ctx,
|
||||
Some(&[device]),
|
||||
|
|
|
@ -83,8 +83,21 @@ impl SpirvModule {
|
|||
self.binaries.len() * mem::size_of::<u32>(),
|
||||
)
|
||||
};
|
||||
let l0_module = l0::Module::build_spirv(ctx, dev, byte_il, None).0?;
|
||||
Ok(l0_module)
|
||||
let l0_module = match self.should_link_ptx_impl {
|
||||
None => {
|
||||
l0::Module::build_spirv(ctx, dev, byte_il, Some(self.build_options.as_c_str())).0
|
||||
}
|
||||
Some(ptx_impl) => {
|
||||
l0::Module::build_link_spirv(
|
||||
ctx,
|
||||
&dev,
|
||||
&[ptx_impl, byte_il],
|
||||
Some(self.build_options.as_c_str()),
|
||||
)
|
||||
.0
|
||||
}
|
||||
};
|
||||
Ok(l0_module?)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ test_ptx!(setp, [10u64, 11u64], [1u64, 0u64]);
|
|||
test_ptx!(bra, [10u64], [11u64]);
|
||||
test_ptx!(not, [0u64], [u64::max_value()]);
|
||||
test_ptx!(shl, [11u64], [44u64]);
|
||||
test_ptx!(shl_link_hack, [11u64], [44u64]);
|
||||
test_ptx!(cvt_sat_s_u, [-1i32], [0i32]);
|
||||
test_ptx!(cvta, [3.0f32], [3.0f32]);
|
||||
test_ptx!(block, [1u64], [2u64]);
|
||||
|
@ -202,7 +203,12 @@ fn run_spirv<T: From<u8> + ze::SafeRepr + Copy + Debug>(
|
|||
let dev = devices.drain(0..1).next().unwrap();
|
||||
let queue = ze::CommandQueue::new(&mut ctx, &dev)?;
|
||||
let (module, maybe_log) = match module.should_link_ptx_impl {
|
||||
Some(ptx_impl) => ze::Module::build_link_spirv(&mut ctx, &dev, &[ptx_impl, byte_il]),
|
||||
Some(ptx_impl) => ze::Module::build_link_spirv(
|
||||
&mut ctx,
|
||||
&dev,
|
||||
&[ptx_impl, byte_il],
|
||||
Some(module.build_options.as_c_str()),
|
||||
),
|
||||
None => {
|
||||
let (module, log) = ze::Module::build_spirv(
|
||||
&mut ctx,
|
||||
|
@ -262,7 +268,6 @@ fn test_spvtxt_assert<'a>(
|
|||
let ast = ptx::ModuleParser::new().parse(&mut errors, ptx_txt)?;
|
||||
assert!(errors.len() == 0);
|
||||
let spirv_module = translate::to_spirv_module(ast)?;
|
||||
eprintln!("{}", rspirv::binary::Disassemble::disassemble(&spirv_module.spirv));
|
||||
let spv_context =
|
||||
unsafe { spirv_tools::spvContextCreate(spv_target_env::SPV_ENV_UNIVERSAL_1_3) };
|
||||
assert!(spv_context != ptr::null_mut());
|
||||
|
|
|
@ -2920,15 +2920,31 @@ fn emit_function_body_ops(
|
|||
}?;
|
||||
}
|
||||
ast::Instruction::Shl(t, a) => {
|
||||
let result_type = map.get_or_add(builder, SpirvType::from(t.to_type()));
|
||||
builder.shift_left_logical(result_type, Some(a.dst), a.src1, a.src2)?;
|
||||
let full_type = t.to_type();
|
||||
let size_of = full_type.size_of();
|
||||
let result_type = map.get_or_add(builder, SpirvType::from(full_type));
|
||||
let offset_src = insert_shift_hack(builder, map, a.src2, size_of)?;
|
||||
builder.shift_left_logical(result_type, Some(a.dst), a.src1, offset_src)?;
|
||||
}
|
||||
ast::Instruction::Shr(t, a) => {
|
||||
let result_type = map.get_or_add_scalar(builder, ast::ScalarType::from(*t));
|
||||
let full_type = ast::ScalarType::from(*t);
|
||||
let size_of = full_type.size_of();
|
||||
let result_type = map.get_or_add_scalar(builder, full_type);
|
||||
let offset_src = insert_shift_hack(builder, map, a.src2, size_of as usize)?;
|
||||
if t.signed() {
|
||||
builder.shift_right_arithmetic(result_type, Some(a.dst), a.src1, a.src2)?;
|
||||
builder.shift_right_arithmetic(
|
||||
result_type,
|
||||
Some(a.dst),
|
||||
a.src1,
|
||||
offset_src,
|
||||
)?;
|
||||
} else {
|
||||
builder.shift_right_logical(result_type, Some(a.dst), a.src1, a.src2)?;
|
||||
builder.shift_right_logical(
|
||||
result_type,
|
||||
Some(a.dst),
|
||||
a.src1,
|
||||
offset_src,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
ast::Instruction::Cvt(dets, arg) => {
|
||||
|
@ -3225,6 +3241,23 @@ fn emit_function_body_ops(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// HACK ALERT
|
||||
// For some reason IGC fails linking if the value and shift size are of different type
|
||||
fn insert_shift_hack(
|
||||
builder: &mut dr::Builder,
|
||||
map: &mut TypeWordMap,
|
||||
offset_var: spirv::Word,
|
||||
size_of: usize,
|
||||
) -> Result<spirv::Word, TranslateError> {
|
||||
let result_type = match size_of {
|
||||
2 => map.get_or_add_scalar(builder, ast::ScalarType::B16),
|
||||
8 => map.get_or_add_scalar(builder, ast::ScalarType::B64),
|
||||
4 => return Ok(offset_var),
|
||||
_ => return Err(TranslateError::Unreachable),
|
||||
};
|
||||
Ok(builder.u_convert(result_type, None, offset_var)?)
|
||||
}
|
||||
|
||||
// TODO: check what kind of assembly do we emit
|
||||
fn emit_logical_xor_spirv(
|
||||
builder: &mut dr::Builder,
|
||||
|
|
Loading…
Add table
Reference in a new issue