use ruda_kernel::dsl as kernel_dsl;
use ruda_kernel::dsl::prelude::*;
pub(super) const SHARED_ALPHA_CAPACITY: u32 = 8192;
#[ruda]
pub(super) fn l_prime_class<I: Numeric>(
s: usize,
targets: &Tensor<I>,
n: usize,
tgt_n: usize,
tgt_s: usize,
blank: usize,
) -> usize {
if s % 2 == 1 {
u32::cast_from(targets[n * tgt_n + ((s - 1) / 2) * tgt_s]) as usize
} else {
blank
}
}
#[ruda]
pub(super) fn log_sum_exp2<F: Float>(a: F, b: F, unreachable_threshold: F, one: F) -> F {
let mut mx = a;
let mut mn = b;
if b > a {
mx = b;
mn = a;
}
if mx < unreachable_threshold {
mx
} else {
mx + (one + (mn - mx).exp()).ln()
}
}
#[ruda]
pub(super) fn recurrence_step<F: Float>(
near: F,
near_m1: F,
near_m2: F,
log_p: F,
skip_allowed: bool,
unreachable_threshold: F,
one: F,
) -> F {
let lse_01 = log_sum_exp2::<F>(near, near_m1, unreachable_threshold, one);
let combined = if skip_allowed {
log_sum_exp2::<F>(lse_01, near_m2, unreachable_threshold, one)
} else {
lse_01
};
log_p + combined
}
#[ruda]
pub(super) fn finalize_nll<F: Float>(
last_blank: F,
last_label: F,
target_len: usize,
unreachable_threshold: F,
one: F,
) -> F {
let mut mx = last_blank;
let mut mn = last_label;
if last_label > last_blank {
mx = last_label;
mn = last_blank;
}
if mx < unreachable_threshold {
(F::new(1000.0_f32) * F::cast_from(target_len as u32)).exp()
} else {
F::new(0.0) - (mx + (one + (mn - mx).exp()).ln())
}
}
#[ruda]
pub(super) fn empty_input_nll<F: Float>(target_len: usize) -> F {
if target_len == 0 {
F::new(0.0)
} else {
(F::new(1000.0_f32) * F::cast_from(target_len as u32)).exp()
}
}