
#include <stdint.h>
#include <unistd.h>
#include <omp.h>

static inline void thermal_pause(int *counter, int every, int us) {
    if (++(*counter) >= every) {
        *counter = 0;
        usleep(us);
    }
}

void hyper_dot_thermal(
    const uint8_t *X, const uint8_t *W_T,
    uint32_t *out,
    const uint16_t *lut,
    int M, int K, int N,
    int thermal_sleep_every, int thermal_sleep_us)
{
    #pragma omp parallel for collapse(2)
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < N; j++) {
            const uint8_t *row_x = X + i * K;
            const uint8_t *row_w = W_T + j * K;
            uint32_t sum = 0;
            int thermal_cnt = 0;

            #pragma omp simd reduction(+:sum)
            for (int k = 0; k < K; k++) {
                sum += lut[row_x[k] * 256 + row_w[k]];
                thermal_pause(&thermal_cnt, thermal_sleep_every, thermal_sleep_us);
            }
            out[i * N + j] = sum;
        }
    }
}
