skip to content
==> tests/gemm.c <==
1/* A golden digest from the Rust over the inputs, the reference and the error at n = 1, 7, 64. */
2#include "mesh/ref/gemm.h"
3
4#include <stdint.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8
9static uint64_t fnv(uint64_t h, uint64_t w) { return (h ^ w) * 0x100000001b3ull; }
10
11static uint64_t bits64(double d) {
12    uint64_t u;
13    memcpy(&u, &d, 8);
14    return u;
15}
16
17int main(void) {
18    uint64_t h = 0xcbf29ce484222325ull;
19    const size_t ns[3] = {1, 7, 64};
20    for (int t = 0; t < 3; t++) {
21        size_t n = ns[t];
22        float *a = malloc(n * n * 4), *b = malloc(n * n * 4), *got = malloc(n * n * 4);
23        double *c = malloc(n * n * 8), *s = malloc(n * n * 8);
24        mesh_gemm_inputs(n, a, b);
25        for (size_t i = 0; i < n * n; i++) {
26            uint32_t u;
27            memcpy(&u, &a[i], 4);
28            h = fnv(h, u);
29        }
30        for (size_t i = 0; i < n * n; i++) {
31            uint32_t u;
32            memcpy(&u, &b[i], 4);
33            h = fnv(h, u);
34        }
35        mesh_gemm_reference(n, c, s);
36        for (size_t i = 0; i < n * n; i++) h = fnv(h, bits64(c[i]));
37        for (size_t i = 0; i < n * n; i++) h = fnv(h, bits64(s[i]));
38        for (size_t i = 0; i < n * n; i++) got[i] = (float)c[i];
39        h = fnv(h, bits64(mesh_gemm_max_rel_err(n, got)));
40        free(a), free(b), free(got), free(c), free(s);
41    }
42    if (h != 0xfb5560602c4daaf4ull) {
43        fprintf(stderr, "gemm digest %#018llx, want 0xfb5560602c4daaf4\n", (unsigned long long)h);
44        return 1;
45    }
46    return 0;
47}