/
soa.c
124 lines (103 loc) · 3.66 KB
/
soa.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
119
120
121
122
123
124
#include "ct-head/test.h"
#include "data/array.h"
#include "data/soa.h"
CT_TEST_DECLS
#define NUM (1 << 2)
static void trace_soa(CT_SOA *s) {
float **c = (float **)s->comps;
for (size_t i = 0; i < s->width; i++) {
fprintf(stderr, "%zu: ", i);
for (size_t j = 0; j < s->num; j++) {
fprintf(stderr, "%f, ", c[i][j]);
}
fputs("\n", stderr);
}
}
static void reset_soa2(CT_SOA *a, CT_SOA *b) {
for (size_t i = 0; i < NUM; i++) {
CT_Vec2f va = {i + 1, i + 1};
CT_Vec2f vb = {(i + 1) * 10, (i + 1) * 10};
ct_soa_set2f(a, i, &va);
ct_soa_set2f(b, i, &vb);
}
}
int test_soa() {
CT_DEBUG("word size: %d, mask: %d, shift: %d", CT_SOA_WORD_SIZE,
CT_SOA_SIZE_MASK, CT_SOA_WORD_SHIFT);
CT_SOA a, b;
float *buf = malloc(NUM * 4 * 4);
float *xa = buf, *ya = buf + NUM, *xb = buf + NUM * 2, *yb = buf + NUM * 3;
float *bufa[] = {xa, ya};
float *bufb[] = {xb, yb};
CT_IS(!ct_soa_init(&a, (void **)bufa, 2, NUM, sizeof(float)), "init a");
CT_IS(!ct_soa_init(&b, (void **)bufb, 2, NUM, sizeof(float)), "init b");
reset_soa2(&a, &b);
ct_soa_add1f_imm(&a, 10);
CT_IS(0 == ct_array_compare_f32(xa, FVEC(11, 12, 13, 14), EPS, NUM), "add1x");
CT_IS(0 == ct_array_compare_f32(ya, FVEC(11, 12, 13, 14), EPS, NUM), "add1y");
reset_soa2(&a, &b);
ct_soa_add1fp_imm(&a, xb);
CT_IS(0 == ct_array_compare_f32(xa, FVEC(11, 12, 13, 14), EPS, NUM),
"add1fpx");
CT_IS(0 == ct_array_compare_f32(ya, FVEC(21, 22, 23, 24), EPS, NUM),
"add1fpy");
CT_Vec2f v2;
ct_soa_get2f(&a, 3, &v2);
CT_IS(14 == v2.x && 24 == v2.y, "get2f");
ct_soa_max_imm(&a, &b);
CT_IS(0 == ct_array_compare_f32(xa, FVEC(11, 20, 30, 40), EPS, NUM), "max x");
CT_IS(0 == ct_array_compare_f32(ya, FVEC(21, 22, 30, 40), EPS, NUM), "max y");
float *flat = ct_soa_flatten(&a, NULL);
CT_IS(flat, "flat == NULL");
CT_IS(0 == ct_array_compare_f32(flat, FVEC(11, 20, 30, 40, 21, 22, 30, 40),
EPS, NUM * 2),
"cmp flat");
free(flat);
ct_soa_min_imm(&a, &b);
CT_IS(0 == ct_array_compare_f32(xa, xb, EPS, NUM), "min x");
CT_IS(0 == ct_array_compare_f32(ya, yb, EPS, NUM), "min y");
reset_soa2(&a, &b);
ct_soa_add_imm(&a, &b);
CT_IS(0 == ct_array_compare_f32(xa, FVEC(11, 22, 33, 44), EPS, NUM), "addx");
CT_IS(0 == ct_array_compare_f32(ya, FVEC(11, 22, 33, 44), EPS, NUM), "addy");
reset_soa2(&a, &b);
ct_soa_dot2(&a, &b, xa);
CT_IS(0 == ct_array_compare_f32(xa, FVEC(20, 80, 180, 320), EPS, NUM),
"dot2");
reset_soa2(&a, &b);
ct_soa_dist2(&a, &b, xa);
CT_IS(0 == ct_array_compare_f32(xa, FVEC(12.73, 25.46, 38.18, 50.91), 0.01,
NUM),
"dist2");
reset_soa2(&a, &b);
ct_soa_normalize2f_imm(&a, 1);
CT_IS(0 == ct_array_compare_f32(xa, FVEC(0.707, 0.707, 0.707, 0.707), 0.01,
NUM),
"norm2x");
CT_IS(0 == ct_array_compare_f32(ya, FVEC(0.707, 0.707, 0.707, 0.707), 0.01,
NUM),
"norm2y");
free(buf);
CT_SOA *aa = ct_soa_new(16, 16, 4);
CT_IS(aa, "new 16x16");
float *data = calloc(aa->width * aa->num, sizeof(float));
float **comps = (float **)aa->comps;
for (size_t i = 0; i < aa->width; i++) {
float *dc = data + i * aa->num;
float scale = powf(10, i);
for (size_t j = 0; j < aa->num; j++) {
comps[i][j] = (j + 1) * scale;
dc[j] = comps[i][j] * 2;
}
}
ct_soa_add_imm(aa, aa);
for (size_t i = 0; i < aa->width; i++) {
float *dc = data + i * aa->num;
CT_IS(0 == ct_array_compare_f32(aa->comps[i], dc, EPS, aa->num), "row %zu",
i);
}
//trace_soa(aa);
ct_soa_free(aa);
free(data);
return 0;
}