use cubecl::prelude::*;
use crate::core::edge::{EDGE_NEAREST, EDGE_ODD, EDGE_REFLECT};
#[cube]
pub fn read_extended<F: Float>(input: &[F], base: usize, len: u32, pad: u32, j: u32, #[comptime] mode: u32) -> F {
read_extended_strided::<F>(input, base, 1u32, len, pad, j, mode)
}
#[cube]
pub fn read_extended_strided<F: Float>(input: &[F], base: usize, stride: u32, len: u32, pad: u32, j: u32, #[comptime] mode: u32) -> F {
let last = len - 1u32;
let mut value = F::new(0.0f32);
if j < pad {
let k = pad - j;
if comptime!(mode == EDGE_ODD) {
value = F::new(2.0f32) * input[base] - input[base + (u32::min(k, last) * stride) as usize];
} else if comptime!(mode == EDGE_REFLECT) {
value = input[base + (u32::min(k - 1u32, last) * stride) as usize];
} else if comptime!(mode == EDGE_NEAREST) {
value = input[base];
}
} else if j - pad <= last {
value = input[base + ((j - pad) * stride) as usize];
} else {
let k = u32::min(j - pad - last, last + 1u32);
if comptime!(mode == EDGE_ODD) {
value = F::new(2.0f32) * input[base + (last * stride) as usize] - input[base + ((last - u32::min(k, last)) * stride) as usize];
} else if comptime!(mode == EDGE_REFLECT) {
value = input[base + ((last + 1u32 - k) * stride) as usize];
} else if comptime!(mode == EDGE_NEAREST) {
value = input[base + (last * stride) as usize];
}
}
value
}