#![cfg(all(feature = "cuda", feature = "jit"))]
use std::sync::{Arc, RwLock};
use baracuda_kernels_types::{ArchSku, ElementKind, OperandDesc};
use baracuda_nvrtc::{CompileOptions, Program};
use fuel_cuda_backend::{CudaDevice, CudaStorageBytes};
use fuel_dispatch::jit_adopt::adopt_from_response;
use fuel_dispatch::jit_cuda_load::load_synth_kernel;
use fuel_dispatch::kernel::OpParams;
use fuel_dispatch::runtime_fused_kernels::{fused_kernel_available, lookup_runtime_kernel};
use fuel_graph::jit::{OpAttrs, OpTag, PatternNode};
use fuel_ir::probe::BackendId;
use fuel_ir::{DType, Layout, Shape};
use fuel_kernel_seam::{
ArtifactKind, JitBudget, JitRequest, JitResponse, LinkEntry, SynthArtifact, Synthesizer,
};
use fuel_memory::{BackendStorage, Storage};
fn dev() -> CudaDevice {
fuel_test_support::require_gpu_run_lock();
fuel_test_support::required_ok("CUDA device 0", CudaDevice::new(0))
}
const ENTRY: &str = "fuel_test_jit_relu_add_f32_scalar";
fn relu_add_cuda_source() -> String {
[
format!("extern \"C\" __global__ void {ENTRY}("),
" const float* __restrict__ in0,".to_string(),
" const float* __restrict__ in1,".to_string(),
" float* __restrict__ out,".to_string(),
" long long n) {".to_string(),
" long long i = (long long)blockIdx.x * blockDim.x + threadIdx.x;".to_string(),
" long long step = (long long)gridDim.x * blockDim.x;".to_string(),
" for (; i < n; i += step) {".to_string(),
" float v = in0[i] + in1[i];".to_string(),
" out[i] = v > 0.0f ? v : 0.0f;".to_string(),
" }".to_string(),
"}".to_string(),
]
.join("\n")
}
fn compile_relu_add_ptx() -> Vec<u8> {
let source = relu_add_cuda_source();
let opts = CompileOptions::default();
let ptx = Program::compile_with(&source, ENTRY, &opts)
.unwrap_or_else(|e| panic!("nvrtc compile of the test relu(add) kernel failed: {e}"));
ptx.into_bytes()
}
fn relu_add_region() -> PatternNode {
PatternNode::Op {
op: OpTag::Relu,
attrs: OpAttrs::default(),
operands: vec![PatternNode::Op {
op: OpTag::Add,
attrs: OpAttrs::default(),
operands: vec![
PatternNode::Bind { index: 0 },
PatternNode::Bind { index: 1 },
],
}],
}
}
struct MockSynth {
art: std::sync::Mutex<Option<SynthArtifact>>,
}
impl Synthesizer for MockSynth {
fn synthesize(&self, _req: &JitRequest) -> JitResponse {
JitResponse::Synthesized {
entry_point: ENTRY.into(),
}
}
fn take_kernel(&self, entry_point: &str) -> Option<SynthArtifact> {
if entry_point != ENTRY {
return None;
}
self.art.lock().unwrap().take()
}
}
fn upload_f32(dev: &CudaDevice, host: &[f32]) -> Storage {
let bytes: &[u8] = bytemuck::cast_slice(host);
let cuda_bytes = CudaStorageBytes::from_cpu_bytes(dev, bytes).expect("h2d");
Storage::new(BackendStorage::Cuda(cuda_bytes), DType::F32)
}
fn download_f32(s: &Storage) -> Vec<f32> {
match &s.inner {
BackendStorage::Cuda(c) => {
bytemuck::cast_slice::<u8, f32>(&c.to_cpu_bytes().expect("d2h")).to_vec()
}
_ => panic!("not on CUDA"),
}
}
fn alloc_out_nan_filled(dev: &CudaDevice, n: usize) -> Arc<RwLock<Storage>> {
Arc::new(RwLock::new(upload_f32(dev, &vec![f32::NAN; n])))
}
fn assert_fully_written(got: &[f32], label: &str) {
let unwritten: Vec<usize> = got
.iter()
.enumerate()
.filter(|(_, v)| v.is_nan())
.map(|(i, _)| i)
.collect();
if unwritten.is_empty() {
return;
}
let n = got.len();
let is_suffix = unwritten.first() == Some(&(n - unwritten.len()));
let verdict = if unwritten.len() == n {
"NOTHING was written to this buffer. The kernel either never launched, or launched and wrote somewhere else (a freed/rebound output binding). Both mechanisms are on the launch/marshaling side rather than in the emitted body — but this assertion does not distinguish them, so do not report that it does."
} else if is_suffix {
"the written region is a PREFIX — the kernel ran with too small an element count. That is a count-unit/marshaling defect (elements vs bytes, or a grid sized off the wrong extent), NOT a defect in the emitted body."
} else {
"the survivors are SCATTERED — some elements were written and others skipped, which points at indexing/stride handling inside the body."
};
panic!(
"{label}: {} of {n} output elements still hold the pre-fill NaN — {verdict}
With the zero-initialized alloc this test used before, every one of these would have read as 0.0 and been indistinguishable from a correct relu output.
Unwritten indices: {unwritten:?}
got: {got:?}",
unwritten.len(),
);
}
#[test]
#[ignore]
fn jit_adopt_loads_and_launches_a_synthesized_cuda_kernel() {
let device = dev();
let artifact = SynthArtifact {
artifact: compile_relu_add_ptx(),
kind: ArtifactKind::Ptx,
link: LinkEntry {
entry_point: ENTRY.into(),
symbol: ENTRY.into(),
structure_key: "elementwise:f32".into(),
revision_hash: 1,
},
contract: "## fused_op: fuel_test_jit_relu_add\ncost: n\n".into(),
};
let synth = MockSynth {
art: std::sync::Mutex::new(Some(artifact)),
};
let req = JitRequest::new(
relu_add_region(),
vec![
OperandDesc::new(1, &[4], &[1], ElementKind::F32, 256),
OperandDesc::new(1, &[4], &[1], ElementKind::F32, 256),
],
ArchSku::Sm89,
JitBudget {
max_compile_ms: 5_000,
},
);
let adopted = adopt_from_response(&synth, &req, BackendId::Cuda, |art| {
load_synth_kernel(art, &device)
})
.expect("adopt_from_response should not error")
.expect("the mock synthesizer always synthesizes");
let id = adopted.id;
assert!(id.is_runtime(), "adopted a runtime FusedOpId");
assert!(
fused_kernel_available(id, BackendId::Cuda),
"the adopted op's kernel is visible to the capability gate on Cuda",
);
let kernel = lookup_runtime_kernel(id, BackendId::Cuda)
.expect("kernel bound on Cuda")
.kernel;
let a = [1.0_f32, -5.0, 2.0, -0.5];
let b = [2.0_f32, 3.0, -10.0, 0.5];
let lhs = Arc::new(RwLock::new(upload_f32(&device, &a)));
let rhs = Arc::new(RwLock::new(upload_f32(&device, &b)));
let out = alloc_out_nan_filled(&device, a.len());
let layout = Layout::contiguous(Shape::from_dims(&[a.len()]));
kernel(
&[lhs, rhs],
&mut [out.clone()],
&[layout.clone(), layout.clone(), layout],
&OpParams::None,
)
.expect("launch");
let got = download_f32(&out.read().unwrap());
let want: Vec<f32> = a
.iter()
.zip(b.iter())
.map(|(x, y)| (x + y).max(0.0))
.collect();
assert_fully_written(&got, "mock relu(add) scalar kernel");
assert_eq!(got, want, "relu(a + b) via the JIT-loaded CUDA kernel");
}
#[test]
#[ignore]
fn jit_kernel_refuses_operands_on_a_foreign_cuda_context() {
let (dev1, dev2) = (dev(), dev());
assert_ne!(
dev1.id(),
dev2.id(),
"two fresh devices on one ordinal must have distinct DeviceIds — the premise",
);
let artifact = SynthArtifact {
artifact: compile_relu_add_ptx(),
kind: ArtifactKind::Ptx,
link: LinkEntry {
entry_point: ENTRY.into(),
symbol: ENTRY.into(),
structure_key: "elementwise:f32".into(),
revision_hash: 1,
},
contract: "## fused_op: fuel_test_jit_relu_add_gap214\ncost: n\n".into(),
};
let kernel = load_synth_kernel(&artifact, &dev1).expect("load on dev1");
let a = [1.0_f32, -5.0, 2.0, -0.5];
let b = [2.0_f32, 3.0, -10.0, 0.5];
let layout = Layout::contiguous(Shape::from_dims(&[a.len()]));
let layouts = [layout.clone(), layout.clone(), layout];
{
let lhs = Arc::new(RwLock::new(upload_f32(&dev1, &a)));
let rhs = Arc::new(RwLock::new(upload_f32(&dev1, &b)));
let out = alloc_out_nan_filled(&dev1, a.len());
kernel(&[lhs, rhs], &mut [out.clone()], &layouts, &OpParams::None)
.expect("arm1: matching-device dispatch must LAUNCH, not refuse");
let got = download_f32(&out.read().unwrap());
assert_fully_written(&got, "gap214 arm1 (matching device)");
let want: Vec<f32> = a.iter().zip(&b).map(|(x, y)| (x + y).max(0.0)).collect();
assert_eq!(got, want, "arm1: relu(a + b) on the loading device");
}
{
let lhs = Arc::new(RwLock::new(upload_f32(&dev2, &a)));
let rhs = Arc::new(RwLock::new(upload_f32(&dev2, &b)));
let out = alloc_out_nan_filled(&dev2, a.len());
let err = kernel(&[lhs, rhs], &mut [out], &layouts, &OpParams::None)
.expect_err("arm2: operands on a foreign context must be REFUSED, not launched");
let msg = format!("{err:?}");
assert!(
msg.contains("different") && msg.contains("context"),
"arm2: the refusal must name the device-context mismatch, got: {msg}",
);
}
{
let lhs = Arc::new(RwLock::new(upload_f32(&dev1, &a)));
let rhs = Arc::new(RwLock::new(upload_f32(&dev1, &b)));
let out = alloc_out_nan_filled(&dev2, a.len()); kernel(&[lhs, rhs], &mut [out], &layouts, &OpParams::None)
.expect_err("arm3: a mixed-device operand set (output on dev2) must be REFUSED");
}
}
const PARAM_ENTRY: &str = "fuel_test_jit_mul_param_f32_scalar";
fn mul_param_cuda_source() -> String {
[
format!("extern \"C\" __global__ void {PARAM_ENTRY}("),
" const float* __restrict__ in0,".to_string(),
" float* __restrict__ out,".to_string(),
" long long n,".to_string(),
" float p0) {".to_string(),
" long long i = (long long)blockIdx.x * blockDim.x + threadIdx.x;".to_string(),
" long long step = (long long)gridDim.x * blockDim.x;".to_string(),
" for (; i < n; i += step) {".to_string(),
" out[i] = in0[i] * p0;".to_string(),
" }".to_string(),
"}".to_string(),
]
.join("\n")
}
fn mul_scalar_slot_region() -> PatternNode {
PatternNode::Op {
op: OpTag::MulScalar,
attrs: OpAttrs::default(),
operands: vec![PatternNode::Bind { index: 0 }],
}
}
#[test]
#[ignore]
fn jit_scalar_param_kernel_launches_with_live_value() {
let device = dev();
let source = mul_param_cuda_source();
let opts = CompileOptions::default();
let ptx = Program::compile_with(&source, PARAM_ENTRY, &opts)
.unwrap_or_else(|e| panic!("nvrtc compile of the mul_param kernel failed: {e}"));
let artifact = SynthArtifact {
artifact: ptx.into_bytes(),
kind: ArtifactKind::Ptx,
link: LinkEntry {
entry_point: PARAM_ENTRY.into(),
symbol: PARAM_ENTRY.into(),
structure_key: "elementwise:f32:p1".into(),
revision_hash: 2,
},
contract: "## fused_op: fuel_test_jit_mul_param\ncost: n\n".into(),
};
struct ParamSynth {
art: std::sync::Mutex<Option<SynthArtifact>>,
}
impl Synthesizer for ParamSynth {
fn synthesize(&self, _req: &JitRequest) -> JitResponse {
JitResponse::Synthesized {
entry_point: PARAM_ENTRY.into(),
}
}
fn take_kernel(&self, entry_point: &str) -> Option<SynthArtifact> {
if entry_point != PARAM_ENTRY {
return None;
}
self.art.lock().unwrap().take()
}
}
let synth = ParamSynth {
art: std::sync::Mutex::new(Some(artifact)),
};
let req = JitRequest::new(
mul_scalar_slot_region(),
vec![OperandDesc::new(1, &[4], &[1], ElementKind::F32, 256)],
ArchSku::Sm89,
JitBudget {
max_compile_ms: 5_000,
},
);
let adopted = adopt_from_response(&synth, &req, BackendId::Cuda, |art| {
load_synth_kernel(art, &device)
})
.expect("adopt_from_response should not error")
.expect("the mock synthesizer always synthesizes");
let id = adopted.id;
assert!(id.is_runtime());
let kernel = lookup_runtime_kernel(id, BackendId::Cuda)
.expect("kernel bound on Cuda")
.kernel;
let x = [1.0_f32, -5.0, 2.0, -0.5];
let inp = Arc::new(RwLock::new(upload_f32(&device, &x)));
let out = alloc_out_nan_filled(&device, x.len());
let layout = Layout::contiguous(Shape::from_dims(&[x.len()]));
kernel(
&[inp],
&mut [out.clone()],
&[layout.clone(), layout],
&OpParams::JitScalars { scalars: vec![2.5] },
)
.expect("launch with a trailing float p0");
let got = download_f32(&out.read().unwrap());
let want: Vec<f32> = x.iter().map(|v| v * 2.5).collect();
assert_fully_written(&got, "mock mul_param scalar-Param kernel");
assert_eq!(
got, want,
"x * p0 via the JIT-loaded scalar-Param CUDA kernel"
);
}
#[test]
#[ignore]
#[cfg(feature = "jit-synth")]
fn live_baracuda_synthesizer_full_loop_scalar() {
use baracuda_cuda_emit::seam::BaracudaSynthesizer;
use fuel_kernel_seam::{JitBudget, JitRequest, JitResponse, Synthesizer};
let device = dev();
let synth = BaracudaSynthesizer::new(5_000);
let operand = || OperandDesc::new(1, &[7], &[1], ElementKind::F32, 4);
let req = JitRequest::new(
relu_add_region(),
vec![operand(), operand(), operand()],
ArchSku::Sm89,
JitBudget {
max_compile_ms: 5_000,
},
);
match synth.synthesize(&req) {
JitResponse::Synthesized { entry_point } => {
eprintln!("BaracudaSynthesizer synthesized: {entry_point}");
}
JitResponse::Declined { reason } => {
panic!("BaracudaSynthesizer declined relu(add): {reason}");
}
}
let adopted = adopt_from_response(&synth, &req, BackendId::Cuda, |art| {
eprintln!(
"synth emitted symbol: {} (kind {:?})",
art.link.symbol, art.kind
);
eprintln!(" structure_key: {}", art.link.structure_key);
eprintln!(" revision_hash: {:#x}", art.link.revision_hash);
let mut declared = 0usize;
for line in art.contract.lines() {
let l = line.to_ascii_lowercase();
if l.contains("count")
|| l.contains("launch")
|| l.contains("grid")
|| l.contains("block")
|| l.contains("schedule")
|| l.contains("elem")
{
declared += 1;
eprintln!(" contract| {}", line.trim_end());
}
}
eprintln!(" contract lines declaring count/launch geometry: {declared}");
load_synth_kernel(art, &device)
})
.expect("adopt_from_response: the full loop reached adopt")
.expect("the real synthesizer produced an adoptable kernel");
let id = adopted.id;
assert!(id.is_runtime(), "adopted a runtime FusedOpId");
assert!(
fused_kernel_available(id, BackendId::Cuda),
"the adopted kernel is visible to the capability gate on Cuda",
);
let kernel = adopted.kernel;
assert!(
std::ptr::fn_addr_eq(kernel, adopted.kernel),
"launching a DIFFERENT kernel than was adopted — an id resolved to another alternative. Dispatch through `adopted.kernel`; an id names a RECIPE, and a recipe legitimately has many kernels (GAP-213).",
);
let a = [1.0_f32, -5.0, 2.0, -0.5, 3.0, -7.0, 0.0];
let b = [2.0_f32, 3.0, -10.0, 0.5, -1.0, 7.0, 4.0];
let lhs = Arc::new(RwLock::new(upload_f32(&device, &a)));
let rhs = Arc::new(RwLock::new(upload_f32(&device, &b)));
let out = alloc_out_nan_filled(&device, a.len());
let layout = Layout::contiguous(Shape::from_dims(&[a.len()]));
kernel(
&[lhs, rhs],
&mut [out.clone()],
&[layout.clone(), layout.clone(), layout],
&OpParams::None,
)
.expect("launch Baracuda's synthesized relu(add)");
let got = download_f32(&out.read().unwrap());
let want: Vec<f32> = a
.iter()
.zip(b.iter())
.map(|(x, y)| (x + y).max(0.0))
.collect();
assert_fully_written(&got, "REAL BaracudaSynthesizer scalar kernel (GAP-001)");
assert_eq!(
got, want,
"relu(a + b) via Baracuda's OWN alpha.76-synthesized CUDA kernel — the LIVE LOOP",
);
}
#[test]
#[ignore]
#[cfg(feature = "jit-synth")]
fn live_baracuda_synthesizer_paged_attn_dense_region() {
use baracuda_cuda_emit::seam::BaracudaSynthesizer;
use fuel_graph::registry::{FusedOpParams, FusedOps};
use fuel_graph::{Graph, Node, NodeId, Op};
const B: usize = 1;
const HQ: usize = 4;
const HKV: usize = 4;
const SQ: usize = 1;
const D: usize = 4;
const NUM_BLOCKS: usize = 32;
const BLOCK_SIZE: usize = 4;
const MAX_BLK: usize = 8;
let mut g = Graph::new();
let leaf = |g: &mut Graph, dims: &[usize], dtype: DType| {
g.push(Node {
op: Op::Const,
inputs: vec![],
shape: Shape::from_dims(dims),
dtype,
})
};
let q = leaf(&mut g, &[B, HQ, SQ, D], DType::F32);
let kc = leaf(&mut g, &[NUM_BLOCKS, BLOCK_SIZE, HKV, D], DType::F32);
let vc = leaf(&mut g, &[NUM_BLOCKS, BLOCK_SIZE, HKV, D], DType::F32);
let bt = leaf(&mut g, &[B, MAX_BLK], DType::U32);
let cl = leaf(&mut g, &[B], DType::U32);
let params = FusedOpParams::PagedAttn {
softmax_scale: 1.0 / (D as f32).sqrt(),
block_size: BLOCK_SIZE,
softcap: None,
};
let fused = g.push(Node {
op: Op::Fused(FusedOps::PAGED_ATTN, params.clone()),
inputs: vec![q, kc, vc, bt, cl],
shape: Shape::from_dims(&[B, HQ, SQ, D]),
dtype: DType::F32,
});
let region = fuel_graph::registry::paged_attn::recipe_for(&g, fused, ¶ms)
.expect("well-formed PagedAttn node yields a recipe");
assert!(
matches!(region, PatternNode::Op { .. }),
"the region must be an Op tree",
);
let od = |dims: &[usize], k: ElementKind, elem: u32| {
let mut strides = vec![1usize; dims.len()];
for i in (0..dims.len().saturating_sub(1)).rev() {
strides[i] = strides[i + 1] * dims[i + 1];
}
let d: Vec<i64> = dims.iter().map(|&x| x as i64).collect();
let s: Vec<i64> = strides.iter().map(|&x| x as i64).collect();
OperandDesc::new(dims.len(), &d, &s, k, elem)
};
let operands = vec![
od(&[B, HQ, SQ, D], ElementKind::F32, 4), od(&[NUM_BLOCKS, BLOCK_SIZE, HKV, D], ElementKind::F32, 4), od(&[NUM_BLOCKS, BLOCK_SIZE, HKV, D], ElementKind::F32, 4), od(&[B, MAX_BLK], ElementKind::U32, 4), od(&[B], ElementKind::U32, 4), od(&[B, HQ, SQ, D], ElementKind::F32, 4), ];
let synth = BaracudaSynthesizer::new(10_000);
let req = JitRequest::new(
region,
operands,
ArchSku::Sm89,
JitBudget {
max_compile_ms: 10_000,
},
);
println!("\n=== PagedAttn dense region -> real BaracudaSynthesizer ===");
match synth.synthesize(&req) {
JitResponse::Synthesized { entry_point } => {
println!("RESULT: ACCEPTED — entry_point = {entry_point}");
println!(
"The generator will synthesize a fused kernel for a discovered region \
of this size. JIT-from-a-region is in scope for it."
);
}
JitResponse::Declined { reason } => {
println!("RESULT: DECLINED — reason: {reason}");
println!(
"A decline is a first-class answer, not a failure: it says \
JIT-from-a-discovered-region of this shape is out of scope for this \
generator, which is what the RFC needs to know."
);
}
}
println!("=== END RESULT ===\n");
}
#[test]
#[ignore]
fn jit_slot_reclamation_frees_dead_device_slots_but_not_live_ones() {
use fuel_cuda_backend::{DeviceId, is_device_live};
use fuel_dispatch::jit_cuda_load::{
clear_slots_for_tests, reclaim_dead_slots_for_tests, slot_device_ids_for_tests,
};
let ptx = compile_relu_add_ptx();
let art = || SynthArtifact {
artifact: ptx.clone(),
kind: ArtifactKind::Ptx,
link: LinkEntry {
entry_point: ENTRY.into(),
symbol: ENTRY.into(),
structure_key: "elementwise:f32".into(),
revision_hash: 1,
},
contract: "## fused_op: fuel_test_jit_relu_add_inc3\ncost: n\n".into(),
};
let slot_of = |id: DeviceId| {
slot_device_ids_for_tests()
.iter()
.position(|s| *s == Some(id))
.expect("the device's slot is claimed")
};
{
clear_slots_for_tests();
let dev1 = dev();
let id1 = dev1.id();
let _r1 = load_synth_kernel(&art(), &dev1).expect("arm(a): load on dev1");
let idx1 = slot_of(id1);
assert!(is_device_live(id1), "arm(a): dev1 live while held");
drop(dev1);
assert!(
!is_device_live(id1),
"arm(a): dev1 dead after its last clone drops"
);
let freed = reclaim_dead_slots_for_tests();
assert_eq!(
freed,
vec![idx1],
"arm(a): reclaimed EXACTLY dev1's slot (which slot, not just how many)"
);
assert_eq!(
slot_device_ids_for_tests()[idx1],
None,
"arm(a): the reclaimed slot is now free/reusable"
);
}
{
clear_slots_for_tests();
let dev_b = dev(); let id_b = dev_b.id();
let _rb = load_synth_kernel(&art(), &dev_b).expect("arm(b): load on dev_b");
let idx_b = slot_of(id_b);
assert!(is_device_live(id_b), "arm(b): dev_b held alive");
let freed = reclaim_dead_slots_for_tests();
assert!(
freed.is_empty(),
"arm(b): a LIVE device's slot must NOT be reclaimed, got freed={freed:?} \
(fails if reclamation ignores liveness, or if liveness is keyed on ordinal)"
);
assert_eq!(
slot_device_ids_for_tests()[idx_b],
Some(id_b),
"arm(b): dev_b's slot is untouched"
);
drop(dev_b);
}
{
clear_slots_for_tests();
let dev_old = dev();
let id_old = dev_old.id();
let r_old = load_synth_kernel(&art(), &dev_old).expect("arm(c): load on dev_old");
let idx = slot_of(id_old);
drop(dev_old);
assert_eq!(
reclaim_dead_slots_for_tests(),
vec![idx],
"arm(c): dead dev_old's slot reclaimed"
);
let dev_new = dev();
let id_new = dev_new.id();
let _r_new = load_synth_kernel(&art(), &dev_new).expect("arm(c): load on dev_new");
assert_eq!(
slot_device_ids_for_tests()[idx],
Some(id_new),
"arm(c): the reclaimed index was REUSED by dev_new"
);
let dev_fgn = dev();
let a = [1.0_f32, 2.0, 3.0, 4.0];
let b = [5.0_f32, 6.0, 7.0, 8.0];
let lhs = Arc::new(RwLock::new(upload_f32(&dev_fgn, &a)));
let rhs = Arc::new(RwLock::new(upload_f32(&dev_fgn, &b)));
let out = alloc_out_nan_filled(&dev_fgn, a.len());
let layout = Layout::contiguous(Shape::from_dims(&[a.len()]));
r_old(
&[lhs, rhs],
&mut [out],
&[layout.clone(), layout.clone(), layout],
&OpParams::None,
)
.expect_err(
"arm(c): old KernelRef through a reused index, operands on a foreign device → \
inc 2 must refuse (cross-context launch)",
);
}
clear_slots_for_tests();
}