// File: gemm.h
#pragma once
#include <cstdint>

// Per-definition constants for this gemm Q8_0 (weight+activation quantized)
// specialisation.
// C[m, n] = sum_k A[m, k] * B[n, k]  (B is the [N, K] "weight" matrix, transposed)
// A and B are both int8 with a separate per-32-element-block fp16 scale tensor
// (Definition-level ABI, not GGML's packed block_q8_0 struct):
//   A/B:        [rows, K]      int8
//   A/B_scales: [rows, K_blk]  raw fp16 bit pattern (uint16_t) -- one value per
//                                32-element block.
// Dequant is `real[l] = scale[l/32] * value[l]`.
// Output accumulates/returns in fp32.
namespace gemm_def {
constexpr int N = 1024;
constexpr int K = 2048;
constexpr int K_blk = 64;
} // namespace gemm_def

#ifdef __cplusplus
extern "C" {
#endif
// LLM target: implement this in kernel.cpp.
// M is the only var dim. A: (M, K) int8; A_scales: (M, K_blk) raw fp16 bits;
// B: (N, K) int8; B_scales: (N, K_blk) raw fp16 bits; output: (M, N) float32.
void inner_gemm(const int8_t* A, float* output, const uint16_t* A_scales,
                 const int8_t* B, const uint16_t* B_scales, int M);
#ifdef __cplusplus
}
#endif