use hydroplane::{Gang, kernel};
#[kernel(tiny)]
fn any_gt<'a>(ctx: Gang, a: &'a [f32], b: &'a [f32]) -> bool {
let n = ctx.lanes::<f32>();
for off in ctx.chunks_exact::<f32>(a.len()) {
if ctx.load(&a[off..off + n]).gt(ctx.load(&b[off..off + n])).any() {
return true;
}
}
if let Some((off, cnt)) = ctx.remainder::<f32>(a.len()) {
let x = ctx.load_partial(&a[off..off + cnt], f32::NEG_INFINITY);
let y = ctx.load_partial(&b[off..off + cnt], f32::INFINITY);
return x.gt(y).any();
}
false
}
#[kernel(tiny)]
fn any_lt<'a>(ctx: Gang, a: &'a [f32], b: &'a [f32]) -> bool {
let n = ctx.lanes::<f32>();
for off in ctx.chunks_exact::<f32>(a.len()) {
if ctx.load(&a[off..off + n]).lt(ctx.load(&b[off..off + n])).any() {
return true;
}
}
if let Some((off, cnt)) = ctx.remainder::<f32>(a.len()) {
let x = ctx.load_partial(&a[off..off + cnt], f32::INFINITY);
let y = ctx.load_partial(&b[off..off + cnt], f32::NEG_INFINITY);
return x.lt(y).any();
}
false
}
#[kernel(tiny)]
fn out_of_limits<'a>(ctx: Gang, q: &'a [f32], lo: &'a [f32], hi: &'a [f32]) -> bool {
any_lt_on(ctx, q, lo) || any_gt_on(ctx, q, hi)
}
#[kernel(tiny)]
fn dist_sq<'a>(ctx: Gang, q: &'a [f32], p: &'a [f32]) -> f32 {
ctx.zip_sum(q, p, |acc, a, b| {
let d = a - b;
d.fma(d, acc)
})
}
fn main() {
let lo = [-3.2_f32, -2.0, -2.8, -3.2, -2.0, -6.4];
let hi = [3.2_f32, 2.0, 2.8, 3.2, 2.0, 6.4];
let inside = [0.1_f32, 0.5, -1.0, 1.2, 0.0, 3.0];
let high = [0.1_f32, 0.5, -1.0, 1.2, 0.0, 7.0]; let low = [0.1_f32, -2.5, -1.0, 1.2, 0.0, 3.0];
println!("inside limits? {}", !out_of_limits(&inside, &lo, &hi)); println!("high in limits {}", !out_of_limits(&high, &lo, &hi)); println!("low in limits {}", !out_of_limits(&low, &lo, &hi)); println!("dist² inside→high: {}", dist_sq(&inside, &high)); }