|
| 1 | +// SPDX-License-Identifier: Apache-2.0 |
| 2 | +use hip_bridge::HipRuntime; |
| 3 | +use redline_dispatch::aql::{Gfx10Pm4CommandBuffer, Gfx12Pm4CommandBuffer, GpuSelector, KernargPool, LaunchGeometry, Runtime, SingleQueuePm4Ib, load_symbols}; |
| 4 | +use std::sync::Arc; |
| 5 | +fn run_hip(gx: u32, gy: u32, hsaco: &[u8]) -> anyhow::Result<(Vec<(u32,u32)>, Vec<u32>)> { |
| 6 | + let hip = HipRuntime::load()?; hip.set_device(0)?; |
| 7 | + let module = hip.module_load_data(hsaco)?; let func = hip.module_get_function(&module, "debug_grid")?; |
| 8 | + let total_wg = (gx * gy) as usize; |
| 9 | + let out = hip.malloc(total_wg * 4)?; let hits = hip.malloc((gx*gy) as usize *4)?; let counter = hip.malloc(4)?; |
| 10 | + hip.memset(&out, 0, out.size())?; hip.memset(&hits, 0, hits.size())?; hip.memset(&counter, 0, counter.size())?; hip.device_synchronize()?; |
| 11 | + let mut kernarg = vec![0u8; 32]; |
| 12 | + let out_ptr = out.as_ptr() as u64; let hits_ptr = hits.as_ptr() as u64; let counter_ptr = counter.as_ptr() as u64; |
| 13 | + kernarg[0..8].copy_from_slice(&out_ptr.to_ne_bytes()); kernarg[8..16].copy_from_slice(&hits_ptr.to_ne_bytes()); kernarg[16..24].copy_from_slice(&counter_ptr.to_ne_bytes()); kernarg[24..28].copy_from_slice(&(gx as i32).to_ne_bytes()); |
| 14 | + let stream = hip.stream_create()?; |
| 15 | + unsafe { hip.launch_kernel_blob(&func, [gx, gy, 1], [32,1,1], 0, Some(&stream), &mut kernarg)?; } |
| 16 | + hip.stream_synchronize(&stream)?; |
| 17 | + let mut out_bytes = vec![0u8; total_wg*4]; let mut hits_bytes = vec![0u8; (gx*gy) as usize*4]; let mut counter_bytes = vec![0u8; 4]; |
| 18 | + hip.memcpy_dtoh(&mut out_bytes, &out)?; hip.memcpy_dtoh(&mut hits_bytes, &hits)?; hip.memcpy_dtoh(&mut counter_bytes, &counter)?; |
| 19 | + let counter_val = u32::from_ne_bytes(counter_bytes[0..4].try_into().unwrap()); |
| 20 | + let mut out_pairs = Vec::new(); for i in 0..counter_val as usize { let v = u32::from_ne_bytes(out_bytes[i*4..i*4+4].try_into().unwrap()); out_pairs.push((v & 0xFFFF, v >> 16)); } |
| 21 | + let mut hits_vals = Vec::new(); for i in 0..(gx*gy) as usize { hits_vals.push(u32::from_ne_bytes(hits_bytes[i*4..i*4+4].try_into().unwrap())); } |
| 22 | + Ok((out_pairs, hits_vals)) |
| 23 | +} |
| 24 | +fn run_redline(gx: u32, gy: u32, hsaco: &[u8]) -> anyhow::Result<(Vec<(u32,u32)>, Vec<u32>)> { |
| 25 | + let runtime = Runtime::initialize(load_symbols()?)?; |
| 26 | + let ordinal = std::env::var("HIP_VISIBLE_DEVICES").or_else(|_| std::env::var("ROCR_VISIBLE_DEVICES")).ok().and_then(|v| v.split(',').next().and_then(|s| s.trim().parse::<usize>().ok())).unwrap_or(0); |
| 27 | + let device = runtime.select_gpu(GpuSelector::Ordinal(ordinal)).or_else(|_| runtime.select_gpu(GpuSelector::Ordinal(0)))?; |
| 28 | + let exec = redline_dispatch::aql::Executable::load(&device, Arc::<[u8]>::from(hsaco))?; |
| 29 | + let kernel = exec.kernel("debug_grid.kd")?; |
| 30 | + let pool = KernargPool::discover(&device)?; |
| 31 | + let hip = HipRuntime::load()?; hip.set_device(0)?; |
| 32 | + let total_wg = (gx * gy) as usize; |
| 33 | + let out = hip.malloc(total_wg * 4)?; let hits = hip.malloc((gx*gy) as usize *4)?; let counter = hip.malloc(4)?; |
| 34 | + hip.memset(&out, 0, out.size())?; hip.memset(&hits, 0, hits.size())?; hip.memset(&counter, 0, counter.size())?; hip.device_synchronize()?; |
| 35 | + let mut karg = pool.allocate_for(kernel.metadata())?; |
| 36 | + let bytes = karg.as_mut_bytes(); bytes.fill(0); |
| 37 | + let out_ptr = out.as_ptr() as u64; let hits_ptr = hits.as_ptr() as u64; let counter_ptr = counter.as_ptr() as u64; |
| 38 | + bytes[0..8].copy_from_slice(&out_ptr.to_ne_bytes()); bytes[8..16].copy_from_slice(&hits_ptr.to_ne_bytes()); bytes[16..24].copy_from_slice(&counter_ptr.to_ne_bytes()); bytes[24..28].copy_from_slice(&(gx as i32).to_ne_bytes()); |
| 39 | + let geometry = LaunchGeometry::from_workgroups([gx, gy, 1], [32,1,1])?; |
| 40 | + let is_gfx12 = device.name().contains("gfx12"); |
| 41 | + let (mut ib, mut ownership) = if is_gfx12 { |
| 42 | + let mut cmds = Gfx12Pm4CommandBuffer::new_stateful(); cmds.dispatch(&kernel, geometry, 0, karg.address())?; |
| 43 | + let mut oc = Gfx12Pm4CommandBuffer::new(); oc.acquire_system_gfx12(); |
| 44 | + (SingleQueuePm4Ib::create(&device, &pool, &cmds)?, SingleQueuePm4Ib::create(&device, &pool, &oc)?) |
| 45 | + } else { |
| 46 | + let mut cmds = Gfx10Pm4CommandBuffer::new_stateful(); cmds.dispatch(&kernel, geometry, 0, karg.address())?; |
| 47 | + let mut oc = Gfx10Pm4CommandBuffer::new(); oc.acquire_system(); |
| 48 | + let ib = if device.name().contains("gfx11") { SingleQueuePm4Ib::create_gfx11(&device, &pool, &cmds)? } else { SingleQueuePm4Ib::create_gfx10(&device, &pool, &cmds)? }; |
| 49 | + let ownership = if device.name().contains("gfx11") { SingleQueuePm4Ib::create_gfx11(&device, &pool, &oc)? } else { SingleQueuePm4Ib::create_gfx10(&device, &pool, &oc)? }; |
| 50 | + (ib, ownership) |
| 51 | + }; |
| 52 | + let _keep = karg; |
| 53 | + unsafe { ownership.replay_and_wait()?; } unsafe { ib.replay_and_wait()?; } |
| 54 | + let mut out_bytes = vec![0u8; total_wg*4]; let mut hits_bytes = vec![0u8; (gx*gy) as usize*4]; let mut counter_bytes = vec![0u8; 4]; |
| 55 | + hip.memcpy_dtoh(&mut out_bytes, &out)?; hip.memcpy_dtoh(&mut hits_bytes, &hits)?; hip.memcpy_dtoh(&mut counter_bytes, &counter)?; |
| 56 | + let counter_val = u32::from_ne_bytes(counter_bytes[0..4].try_into().unwrap()); |
| 57 | + let mut out_pairs = Vec::new(); for i in 0..counter_val as usize { let v = u32::from_ne_bytes(out_bytes[i*4..i*4+4].try_into().unwrap()); out_pairs.push((v & 0xFFFF, v >> 16)); } |
| 58 | + let mut hits_vals = Vec::new(); for i in 0..(gx*gy) as usize { hits_vals.push(u32::from_ne_bytes(hits_bytes[i*4..i*4+4].try_into().unwrap())); } |
| 59 | + Ok((out_pairs, hits_vals)) |
| 60 | +} |
| 61 | +fn main() -> anyhow::Result<()> { |
| 62 | + let args: Vec<String> = std::env::args().collect(); |
| 63 | + let mut gx = 128; let mut gy = 2; let mut arch = "gfx1151".to_string(); |
| 64 | + for i in 0..args.len() { if args[i]=="--gx" { gx=args[i+1].parse()?; } if args[i]=="--gy" { gy=args[i+1].parse()?; } if args[i]=="--arch" { arch=args[i+1].clone(); } } |
| 65 | + let hsaco_path = match arch.as_str() { "gfx1151" => "/tmp/debug_grid_gfx1151.hsaco", "gfx1201" => "/tmp/debug_grid_gfx1201.hsaco", "gfx1100" => "/tmp/debug_grid_gfx1151.hsaco", _ => "/tmp/debug_grid.hsaco", }; |
| 66 | + let hsaco = std::fs::read(hsaco_path)?; |
| 67 | + println!("=== HIP gx={} gy={} arch={} ===", gx, gy, arch); |
| 68 | + match run_hip(gx, gy, &hsaco) { Ok((pairs, hits)) => { println!("HIP total {}", pairs.len()); let mut counts = std::collections::BTreeMap::new(); for (x,y) in &pairs { *counts.entry((*x,*y)).or_insert(0) +=1; } println!("HIP unique {}", counts.len()); for ((x,y),c) in &counts { println!(" ({},{}) x{}", x,y,c); } println!("HIP hits {:?}", hits); if counts.values().all(|&c| c==1) { println!("HIP: all once"); } }, Err(e) => println!("HIP failed: {:#}", e), } |
| 69 | + println!("=== Redline gx={} gy={} arch={} ===", gx, gy, arch); |
| 70 | + match run_redline(gx, gy, &hsaco) { Ok((pairs, hits)) => { println!("Redline total {}", pairs.len()); let mut counts = std::collections::BTreeMap::new(); for (x,y) in &pairs { *counts.entry((*x,*y)).or_insert(0) +=1; } println!("Redline unique {}", counts.len()); for ((x,y),c) in &counts { println!(" ({},{}) x{}", x,y,c); } println!("Redline hits {:?}", hits); if counts.values().all(|&c| c==1) { println!("Redline: all once"); } for y in 0..gy { for x in 0..gx { if hits[(y*gx+x) as usize]!=1 { println!("Redline missing at ({},{}) hits {}", x,y, hits[(y*gx+x) as usize]); } } } }, Err(e) => println!("Redline failed: {:#}", e), } |
| 71 | + Ok(()) |
| 72 | +} |
0 commit comments