Add native K/M/RR inference engines, HIP kernels, replay and validation harnesses, and Windows DLSS setup and runtime support. Include GPU profiling tools, build and packaging scripts, platform integration patches, and implementation documentation.
149 lines
6.7 KiB
Diff
149 lines
6.7 KiB
Diff
From b0161a4166652eee86a8113a38d042b02403db6e Mon Sep 17 00:00:00 2001
|
|
From: Codex <codex@localhost>
|
|
Date: Thu, 1 Oct 2026 18:07:07 +0300
|
|
Subject: [PATCH] Add opt-in Windows HIP event and occupancy diagnostics
|
|
|
|
---
|
|
zluda/src/impl/d4r_profile.rs | 60 +++++++++++++++++++++++++++++++++++
|
|
zluda/src/impl/function.rs | 9 ++++++
|
|
zluda/src/impl/mod.rs | 1 +
|
|
zluda/src/impl/module.rs | 2 +-
|
|
4 files changed, 71 insertions(+), 1 deletion(-)
|
|
create mode 100644 zluda/src/impl/d4r_profile.rs
|
|
|
|
diff --git a/zluda/src/impl/d4r_profile.rs b/zluda/src/impl/d4r_profile.rs
|
|
new file mode 100644
|
|
index 0000000..33ba5f6
|
|
--- /dev/null
|
|
+++ b/zluda/src/impl/d4r_profile.rs
|
|
@@ -0,0 +1,60 @@
|
|
+//! Optional, deliberately serializing HIP-event diagnostics. Not a production
|
|
+//! scheduler or a claim about application FPS / measured hardware occupancy.
|
|
+use hip_runtime_sys::*;
|
|
+use std::{ffi::CStr, ptr, time::Instant};
|
|
+
|
|
+pub(super) struct Launch {
|
|
+ start: hipEvent_t,
|
|
+ end: hipEvent_t,
|
|
+ host: Instant,
|
|
+}
|
|
+
|
|
+impl Drop for Launch {
|
|
+ fn drop(&mut self) {
|
|
+ unsafe {
|
|
+ if !self.end.is_null() { let _ = hipEventDestroy(self.end); }
|
|
+ if !self.start.is_null() { let _ = hipEventDestroy(self.start); }
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+impl Launch {
|
|
+ pub(super) unsafe fn begin(stream: hipStream_t) -> Result<Option<Self>, hipErrorCode_t> {
|
|
+ if std::env::var_os("D4R_ZLUDA_PROFILE").is_none() { return Ok(None); }
|
|
+ let mut result = Self { start: ptr::null_mut(), end: ptr::null_mut(), host: Instant::now() };
|
|
+ hipEventCreateWithFlags(&mut result.start, 0)?;
|
|
+ hipEventCreateWithFlags(&mut result.end, 0)?;
|
|
+ hipEventRecord(result.start, stream)?;
|
|
+ result.host = Instant::now();
|
|
+ Ok(Some(result))
|
|
+ }
|
|
+
|
|
+ pub(super) unsafe fn finish(self, function: hipFunction_t, name: &CStr, backend: &str,
|
|
+ phase: &str, grid: [u32;3], block: [u32;3], shared: u32, stream: hipStream_t) -> hipError_t {
|
|
+ let enqueue_ms = self.host.elapsed().as_secs_f64() * 1000.;
|
|
+ hipEventRecord(self.end, stream)?;
|
|
+ hipEventSynchronize(self.end)?;
|
|
+ let completion_ms = self.host.elapsed().as_secs_f64() * 1000.;
|
|
+ let mut gpu_ms = 0.;
|
|
+ hipEventElapsedTime(&mut gpu_ms, self.start, self.end)?;
|
|
+ // Module function handles use the Driver API attribute query. The
|
|
+ // plural Runtime API expects a registered host function address.
|
|
+ let mut lds = 0;
|
|
+ let mut regs = 0;
|
|
+ let mut private = 0;
|
|
+ let mut max_threads = 0;
|
|
+ hipFuncGetAttribute(&mut lds, hipFunction_attribute::HIP_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES, function)?;
|
|
+ hipFuncGetAttribute(&mut regs, hipFunction_attribute::HIP_FUNC_ATTRIBUTE_NUM_REGS, function)?;
|
|
+ hipFuncGetAttribute(&mut private, hipFunction_attribute::HIP_FUNC_ATTRIBUTE_LOCAL_SIZE_BYTES, function)?;
|
|
+ hipFuncGetAttribute(&mut max_threads, hipFunction_attribute::HIP_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, function)?;
|
|
+ let threads = block.iter().try_fold(1u32, |a, b| a.checked_mul(*b))
|
|
+ .filter(|n| *n <= i32::MAX as u32).ok_or(hipErrorCode_t::InvalidValue)?;
|
|
+ let mut blocks_per_multiprocessor = 0;
|
|
+ hipModuleOccupancyMaxActiveBlocksPerMultiprocessor(&mut blocks_per_multiprocessor,
|
|
+ function, threads as i32, shared as usize)?;
|
|
+ eprintln!("D4R_KERNEL_PROFILE kernel={name:?} backend={backend} phase={phase} gpu_ms={gpu_ms:.6} enqueue_ms={enqueue_ms:.6} completion_ms={completion_ms:.6} grid={},{},{} block={},{},{} static_lds_bytes={} dynamic_lds_bytes={shared} regs={} private_bytes={} max_threads={} predicted_blocks_per_multiprocessor={blocks_per_multiprocessor} serializing=1",
|
|
+ grid[0], grid[1], grid[2], block[0], block[1], block[2], lds,
|
|
+ regs, private, max_threads);
|
|
+ Ok(())
|
|
+ }
|
|
+}
|
|
diff --git a/zluda/src/impl/function.rs b/zluda/src/impl/function.rs
|
|
index 7a7470a..c456dfe 100644
|
|
--- a/zluda/src/impl/function.rs
|
|
+++ b/zluda/src/impl/function.rs
|
|
@@ -191,6 +191,7 @@ pub(crate) fn launch_kernel(
|
|
}
|
|
};
|
|
if let (Some((prep, blocks)), true) = (f.prep, run_prep) {
|
|
+ let profile = unsafe { super::d4r_profile::Launch::begin(stream) }?;
|
|
unsafe {
|
|
hipModuleLaunchKernel(
|
|
prep,
|
|
@@ -206,6 +207,9 @@ pub(crate) fn launch_kernel(
|
|
extra_for_hip,
|
|
)
|
|
}?;
|
|
+ if let Some(profile) = profile {
|
|
+ unsafe { profile.finish(prep, &f.name, "native", "prep", [blocks,1,1], [128,1,1], 0, stream) }?;
|
|
+ }
|
|
f.prep_last.store(prep_key, std::sync::atomic::Ordering::Relaxed);
|
|
}
|
|
let block_dim_z = if f.block_z != 0 { f.block_z } else { block_dim_z };
|
|
@@ -214,6 +218,7 @@ pub(crate) fn launch_kernel(
|
|
eprintln!("[d4r-launch] kernel={:?} backend={} grid={grid_dim_x},{grid_dim_y},{grid_dim_z} block={block_dim_x},{block_dim_y},{block_dim_z}",
|
|
f.name, if f.native_owner.is_some() { "native" } else { "translated" });
|
|
}
|
|
+ let profile = unsafe { super::d4r_profile::Launch::begin(stream) }?;
|
|
let result = unsafe {
|
|
hipModuleLaunchKernel(
|
|
f.base,
|
|
@@ -230,6 +235,10 @@ pub(crate) fn launch_kernel(
|
|
)
|
|
};
|
|
result?;
|
|
+ if let Some(profile) = profile {
|
|
+ unsafe { profile.finish(f.base, &f.name, if f.native_owner.is_some() { "native" } else { "translated" },
|
|
+ "main", [grid_dim_x, grid_dim_y, grid_dim_z], [block_dim_x, block_dim_y, block_dim_z], shared_mem_bytes, stream) }?;
|
|
+ }
|
|
if let Some(replay) = replay { replay.finish(stream)?; }
|
|
Ok(())
|
|
}
|
|
diff --git a/zluda/src/impl/mod.rs b/zluda/src/impl/mod.rs
|
|
index 14e0aee..380eb6e 100644
|
|
--- a/zluda/src/impl/mod.rs
|
|
+++ b/zluda/src/impl/mod.rs
|
|
@@ -6,6 +6,7 @@ pub(super) mod context;
|
|
pub(super) mod device;
|
|
pub(super) mod driver;
|
|
pub(super) mod d4r_replay;
|
|
+pub(super) mod d4r_profile;
|
|
pub(super) mod event;
|
|
pub(super) mod function;
|
|
pub(super) mod graph;
|
|
diff --git a/zluda/src/impl/module.rs b/zluda/src/impl/module.rs
|
|
index 5a79368..232f7d4 100644
|
|
--- a/zluda/src/impl/module.rs
|
|
+++ b/zluda/src/impl/module.rs
|
|
@@ -502,7 +502,7 @@ fn zluda_build_version() -> &'static str {
|
|
key.starts_with("D4R_ZLUDA_")
|
|
&& !matches!(
|
|
key.as_str(),
|
|
- "D4R_ZLUDA_NATIVE_DIR" | "D4R_ZLUDA_DIR" | "D4R_ZLUDA_DUMP_DIR" | "D4R_ZLUDA_DUMP_PTX_DIR" | "D4R_ZLUDA_LIBCUDA" | "D4R_ZLUDA_VERBOSE"
|
|
+ "D4R_ZLUDA_NATIVE_DIR" | "D4R_ZLUDA_DIR" | "D4R_ZLUDA_DUMP_DIR" | "D4R_ZLUDA_DUMP_PTX_DIR" | "D4R_ZLUDA_LIBCUDA" | "D4R_ZLUDA_VERBOSE" | "D4R_ZLUDA_PROFILE"
|
|
| "D4R_ZLUDA_WMMA_FP8_NATIVE" // keyed by effect (ExtraCacheAttributes)
|
|
)
|
|
})
|
|
--
|
|
2.55.0.windows.5
|
|
|