use std::sync::Arc;
use oxicuda_driver::Context;
use crate::handle::SparseHandle;
pub(crate) fn gpu_handle() -> Option<SparseHandle> {
oxicuda_driver::init().ok()?;
if oxicuda_driver::Device::count().ok()? == 0 {
return None;
}
let dev = oxicuda_driver::Device::get(0).ok()?;
let ctx = Arc::new(Context::new(&dev).ok()?);
Some(SparseHandle::new(&ctx).expect("test: build SparseHandle"))
}
pub(crate) fn assert_close(got: &[f64], want: &[f64], tol: f64, ctx: &str) {
assert_eq!(got.len(), want.len(), "{ctx}: length mismatch");
for (i, (g, w)) in got.iter().zip(want.iter()).enumerate() {
let diff = (g - w).abs();
let scale = w.abs().max(1.0);
assert!(
diff <= tol * scale,
"{ctx}: element {i}: got {g}, want {w} (|diff| {diff} > {bound})",
bound = tol * scale
);
}
}