Foundry/cuda_kernels/tests/test_q2_0_half_round.c

56 lines
1.8 KiB
C

/* SPDX-License-Identifier: AGPL-3.0-or-later */
/* Copyright (C) 2026 David (Corey) Herrera */
/*
* test_q2_0_half_round.c — exhaustive host check of the Q2_0 activation-scale rounding in
* cuda_kernels/matvec_kquants.cu (fc_q2_0_round_via_half): float -> binary16 RNE -> float
* for every non-negative binary32 up to +Inf, against the compiler's _Float16 conversion.
*
* The function body below mirrors the device helper line for line; keep them in sync.
* --mutate breaks the tie rule (round half up) to show the check can fail.
*
* Build/run: make test-q2-0-half-round (no -ffast-math: it would fold the subnormal add).
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
static int mutate_ties = 0;
static float bits_to_float(uint32_t bits) {
float f = 0.0f;
memcpy(&f, &bits, sizeof(f));
return f;
}
static uint32_t float_to_bits(float f) {
uint32_t bits = 0;
memcpy(&bits, &f, sizeof(bits));
return bits;
}
static float round_via_half(float v) {
uint32_t bits = float_to_bits(v);
if (bits >= 0x477FF000u)
return bits_to_float(0x7F800000u);
if (bits < 0x38800000u)
return (v + 0.5f) - 0.5f;
bits += 0x0FFFu + (mutate_ties ? 1u : ((bits >> 13) & 1u));
return bits_to_float(bits & ~0x1FFFu);
}
int main(int argc, char **argv) {
unsigned long long mismatches = 0;
mutate_ties = argc > 1 && strcmp(argv[1], "--mutate") == 0;
for (uint32_t bits = 0; bits <= 0x7F800000u; bits++) {
const float v = bits_to_float(bits);
const float want = (float)(_Float16)v;
if (float_to_bits(round_via_half(v)) != float_to_bits(want) && mismatches++ < 5)
printf("mismatch at 0x%08X\n", bits);
}
printf("%llu mismatches over all non-negative binary32 values up to +Inf\n", mismatches);
return mismatches != 0;
}