#include "fib_quant.h"
#include <math.h>
void fq_compressed_attention_logits(const uint16_t *key_indices,
size_t n_keys,
const float *key_norms,
const float *gram_table,
size_t gram_size,
const uint16_t *query_indices,
size_t query_count,
float query_norm,
float scale,
float *out_logits) {
for (size_t k_i = 0; k_i < n_keys; k_i++) {
const uint16_t *k_indices = key_indices + k_i * query_count;
float total = 0.0f;
for (size_t b = 0; b < query_count; b++) {
size_t qi = (size_t)query_indices[b];
size_t ki = (size_t)k_indices[b];
total += gram_table[qi * gram_size + ki];
}
float stored_norm = key_norms[k_i];
out_logits[k_i] = total * query_norm * stored_norm / scale;
}
}
int fq_softmax(float *logits, size_t n) {
if (n == 0) return -1;
float max = logits[0];
for (size_t i = 1; i < n; i++) {
if (logits[i] > max) max = logits[i];
}
double sum = 0.0;
for (size_t i = 0; i < n; i++) {
double e = exp((double)(logits[i] - max));
sum += e;
logits[i] = (float)e;
}
if (!isfinite(sum) || sum <= 0.0) return -1;
for (size_t i = 0; i < n; i++) {
logits[i] = (float)((double)logits[i] / sum);
}
return 0;
}