-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patht-ffge_prim_i8.c
118 lines (96 loc) · 3.55 KB
/
t-ffge_prim_i8.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/* -------------------------------------------------------------------------- *
* t-ffge_prim_i8.c: Test the implementation of ffge_prim_i8 *
* *
* Copyright 2024 ⧉⧉⧉ *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation, either version 3 of the License, or (at your *
* option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY* without even the implied warranty of MERCHANTABILITY *
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
* for more details. *
* *
* You should have received a copy of the GNU General Public License along *
* with this program. If not, see <https://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "test.h"
#include <stddef.h>
#include <stdint.h>
#include "ffge.h"
#include "utils.h"
#include "xoshiro256ss.h"
#define REPS (999L)
#define SEED UINT64_C(30393)
static struct xoshiro256ss RNG;
#define MAX_SIZE (28)
static int64_t m[MAX_SIZE * MAX_SIZE];
static alignas(64) int64_t m_i8[MAX_SIZE * MAX_SIZE * FFGE_WIDTH];
static void test_ffge_prim_i8_unit(void)
{
for (size_t k = 0; k < FFGE_WIDTH; k++)
m_i8[k] = 1;
TEST_EQ(ffge_prim_i8(m_i8, 1), 0xff);
m_i8[3] = 0;
TEST_EQ(ffge_prim_i8(m_i8, 1), 0b11110111);
m_i8[6] = 0;
TEST_EQ(ffge_prim_i8(m_i8, 1), 0b10110111);
}
static void test_ffge_prim_i8_two_01(void)
{
for (size_t k = 0; k < FFGE_WIDTH; k++) {
m_i8[(0*2 + 0)*FFGE_WIDTH + k] = 0;
m_i8[(0*2 + 1)*FFGE_WIDTH + k] = 1;
m_i8[(1*2 + 0)*FFGE_WIDTH + k] = 1;
m_i8[(1*2 + 1)*FFGE_WIDTH + k] = 0;
}
TEST_EQ(ffge_prim_i8(m_i8, 2), 0xff);
}
static void test_ffge_prim_i8_two_02(void)
{
for (size_t k = 0; k < FFGE_WIDTH; k++) {
m_i8[(0*2 + 0)*FFGE_WIDTH + k] = 0;
m_i8[(0*2 + 1)*FFGE_WIDTH + k] = 1;
m_i8[(1*2 + 0)*FFGE_WIDTH + k] = 1;
m_i8[(1*2 + 1)*FFGE_WIDTH + k] = 0;
}
m_i8[(0*2 + 1)*FFGE_WIDTH + 4] = 0;
TEST_EQ(ffge_prim_i8(m_i8, 2), 0b11101111);
}
static void test_ffge_prim_i8_randrank(size_t n)
{
for (size_t rep = 0; rep < REPS; rep++) {
uint8_t fl, fl_exp = 0;
/* generate random matrix; set ref. flags, pack it */
for (size_t k = 0; k < FFGE_WIDTH; k++) {
size_t rnk = (xoshiro256ss_next(&RNG) % 2) == 1 ?
n : xoshiro256ss_next(&RNG) % n;
if (rnk == n)
fl_exp |= (1 << k);
ffge_mat_genrand_prim(m, n, rnk, 99, &RNG);
for (size_t i = 0; i < n; i++)
for (size_t j = 0; j < n; j++)
m_i8[(i*n + j)*FFGE_WIDTH + k] = m[i*n + j];
}
TEST_ASSERT((fl = ffge_prim_i8(m_i8, n)) == fl_exp,
"fl=%x, fl_exp=%x, n=%zu, rep=%zu",
fl, fl_exp, n, rep);
}
}
static void test_ffge_prim_i8(void)
{
test_ffge_prim_i8_unit();
test_ffge_prim_i8_two_01();
test_ffge_prim_i8_two_02();
test_ffge_prim_i8_randrank(3);
test_ffge_prim_i8_randrank(6);
test_ffge_prim_i8_randrank(12);
test_ffge_prim_i8_randrank(23);
}
static void TEST_MAIN(void)
{
xoshiro256ss_init(&RNG, SEED);
test_ffge_prim_i8();
}