aboutsummaryrefslogtreecommitdiffhomepage
path: root/level_zero
diff options
context:
space:
mode:
authorAndrzej Janik <[email protected]>2020-10-31 21:28:15 +0100
committerAndrzej Janik <[email protected]>2020-10-31 21:28:15 +0100
commita82eb2081717c1fb48e140176fec0e5b5974a432 (patch)
treeb5ca6934333d1707ed43a1e21a8f02f630929dc4 /level_zero
parent861116f223081528cf1e32f5e1eddb733ac00241 (diff)
downloadZLUDA-a82eb2081717c1fb48e140176fec0e5b5974a432.tar.gz
ZLUDA-a82eb2081717c1fb48e140176fec0e5b5974a432.zip
Implement atomic instructions
Diffstat (limited to 'level_zero')
-rw-r--r--level_zero/Cargo.toml6
-rw-r--r--level_zero/src/ze.rs73
2 files changed, 76 insertions, 3 deletions
diff --git a/level_zero/Cargo.toml b/level_zero/Cargo.toml
index 97537b3..851159d 100644
--- a/level_zero/Cargo.toml
+++ b/level_zero/Cargo.toml
@@ -7,4 +7,8 @@ edition = "2018"
[lib]
[dependencies]
-level_zero-sys = { path = "../level_zero-sys" } \ No newline at end of file
+level_zero-sys = { path = "../level_zero-sys" }
+
+[dependencies.ocl-core]
+version = "0.11"
+features = ["opencl_version_1_2", "opencl_version_2_0", "opencl_version_2_1"] \ No newline at end of file
diff --git a/level_zero/src/ze.rs b/level_zero/src/ze.rs
index 5ced5d0..f8a2c3b 100644
--- a/level_zero/src/ze.rs
+++ b/level_zero/src/ze.rs
@@ -238,7 +238,76 @@ impl Drop for CommandQueue {
pub struct Module(sys::ze_module_handle_t);
impl Module {
- pub fn new_spirv(
+ // HACK ALERT
+ // We use OpenCL for now to do SPIR-V linking, because Level0
+ // does not allow linking. Don't let presence of zeModuleDynamicLink fool
+ // you, it's not currently possible to create non-compiled modules.
+ // zeModuleCreate always compiles (builds and links).
+ pub fn build_link_spirv<'a>(
+ ctx: &mut Context,
+ d: &Device,
+ binaries: &[&'a [u8]],
+ ) -> (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),
+ Ok(prog) => prog,
+ };
+ match ocl_core::get_program_info(&ocl_program, ocl_core::ProgramInfo::Binaries) {
+ Ok(ocl_core::ProgramInfoResult::Binaries(binaries)) => {
+ let (module, build_log) = Self::build_native(ctx, d, &binaries[0]);
+ (module, Some(build_log))
+ }
+ _ => return (Err(sys::ze_result_t::ZE_RESULT_ERROR_UNKNOWN), None),
+ }
+ }
+
+ fn build_link_spirv_impl<'a>(binaries: &[&'a [u8]]) -> ocl_core::Result<ocl_core::Program> {
+ let platforms = ocl_core::get_platform_ids()?;
+ let (platform, device) = platforms
+ .iter()
+ .find_map(|plat| {
+ let devices =
+ ocl_core::get_device_ids(plat, Some(ocl_core::DeviceType::GPU), None).ok()?;
+ for dev in devices {
+ let vendor =
+ ocl_core::get_device_info(dev, ocl_core::DeviceInfo::VendorId).ok()?;
+ if let ocl_core::DeviceInfoResult::VendorId(0x8086) = vendor {
+ let dev_type =
+ ocl_core::get_device_info(dev, ocl_core::DeviceInfo::Type).ok()?;
+ if let ocl_core::DeviceInfoResult::Type(ocl_core::DeviceType::GPU) =
+ dev_type
+ {
+ return Some((plat.clone(), dev));
+ }
+ }
+ }
+ None
+ })
+ .ok_or("")?;
+ let ctx_props = ocl_core::ContextProperties::new().platform(platform);
+ let ocl_ctx = ocl_core::create_context_from_type::<ocl_core::DeviceId>(
+ Some(&ctx_props),
+ ocl_core::DeviceType::GPU,
+ None,
+ None,
+ )?;
+ let mut programs = Vec::with_capacity(binaries.len());
+ for binary in binaries {
+ programs.push(ocl_core::create_program_with_il(&ocl_ctx, binary, None)?);
+ }
+ let options = CString::default();
+ ocl_core::link_program::<ocl_core::DeviceId, _>(
+ &ocl_ctx,
+ Some(&[device]),
+ &options,
+ &programs.iter().collect::<Vec<_>>(),
+ None,
+ None,
+ None,
+ )
+ }
+
+ pub fn build_spirv(
ctx: &mut Context,
d: &Device,
bin: &[u8],
@@ -247,7 +316,7 @@ impl Module {
Module::new(ctx, true, d, bin, opts)
}
- pub fn new_native(ctx: &mut Context, d: &Device, bin: &[u8]) -> (Result<Self>, BuildLog) {
+ pub fn build_native(ctx: &mut Context, d: &Device, bin: &[u8]) -> (Result<Self>, BuildLog) {
Module::new(ctx, false, d, bin, None)
}