use super::*;
#[test]
fn test_zero_sized_buffer() {
let ctx = CudaContext::new(0).expect("Context");
let buf_result = GpuBuffer::<f32>::new(&ctx, 0);
if let Ok(mut buf) = buf_result {
assert_eq!(buf.len(), 0);
let src: Vec<f32> = vec![];
buf.copy_from_host(&src)
.expect("Zero-byte copy should succeed");
}
}
#[test]
fn test_unaligned_byte_copy() {
let ctx = CudaContext::new(0).expect("Context");
let len = 1024;
let mut buf = GpuBuffer::<u8>::new(&ctx, len).expect("Alloc");
let data: Vec<u8> = (0..len).map(|i| (i % 255) as u8).collect();
buf.copy_from_host(&data).expect("Copy");
let mut out = vec![0u8; len];
buf.copy_to_host(&mut out).expect("Download");
assert_eq!(data, out);
}
#[test]
fn test_oom_resilience() {
let _exclusive = device_memory_exclusive();
let ctx = CudaContext::new(0).expect("Context");
let outstanding_start = device_bytes_outstanding();
let mut allocations = Vec::new();
let chunk_size = 1024 * 1024 * 1024 / 4;
let mut hit_oom = false;
for i in 0..30 {
match GpuBuffer::<f32>::new(&ctx, chunk_size) {
Ok(buf) => allocations.push(buf),
Err(GpuError::OutOfMemory { .. }) => {
hit_oom = true;
println!("Hit OOM at chunk {}", i);
break;
}
Err(GpuError::MemoryAllocation(msg)) if msg.contains("OUT_OF_MEMORY") => {
hit_oom = true;
println!("Hit OOM (MemoryAllocation) at chunk {}", i);
break;
}
Err(e) => panic!("Unexpected error during OOM stress: {:?}", e),
}
}
drop(allocations);
assert_eq!(
device_bytes_outstanding(),
outstanding_start,
"Memory leak after allocating to OOM and dropping (hit_oom={hit_oom})"
);
}