// File: binding.cpp
#include "gemm_w8a8ch_contract.h"
#include "mat.h"
#include "option.h"

namespace {
constexpr int N = 1000;
} // namespace

extern "C" {
int armbench_entry_gemm(
    void* A_v, void* top_v,
    void* B_v, void* weight_scales_v,
    void* opt_v)
{
    const auto& A             = *reinterpret_cast<const ncnn::Mat*>(A_v);
    auto&       top           = *reinterpret_cast<ncnn::Mat*>(top_v);
    const auto& B             = *reinterpret_cast<const ncnn::Mat*>(B_v);
    const auto& weight_scales = *reinterpret_cast<const ncnn::Mat*>(weight_scales_v);
    const auto& opt           = *reinterpret_cast<const ncnn::Option*>(opt_v);

    // A arrives as a genuine 2D Mat (w=K, h=M) — M (rows) varies per workload.
    const int M = A.h;

    // Dequantized float32 output — same elemsize as the fp32 baseline. w8a8ch
    // only quantizes inputs; the task doesn't require requantizing the result.
    top.create(N, M, (size_t)4u, opt.blob_allocator);
    if (top.empty()) return -1;

    return ncnn::gemm_w8a8ch_kernel(A, top, B, weight_scales, opt);
}
} // extern "C"