poulpy/poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/test/spqlios_cplx_conversions_test.cpp
poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/test/spqlios_cplx_conversions_test.cppRaw
1#include <gtest/gtest.h>
2
3#include <cmath>
4
5#include "spqlios/cplx/cplx_fft_internal.h"
6#include "spqlios/cplx/cplx_fft_private.h"
7
8#ifdef __x86_64__
9TEST(fft, cplx_from_znx32_ref_vs_fma) {
10 const uint32_t m = 128;
11 int32_t* src = (int32_t*)spqlios_alloc_custom_align(32, 10 * m * sizeof(int32_t));
12 CPLX* dst1 = (CPLX*)(src + 2 * m);
13 CPLX* dst2 = (CPLX*)(src + 6 * m);
14 for (uint64_t i = 0; i < 2 * m; ++i) {
15 src[i] = rand() - RAND_MAX / 2;
16 }
17 CPLX_FROM_ZNX32_PRECOMP precomp;
18 precomp.m = m;
19 cplx_from_znx32_ref(&precomp, dst1, src);
20 // cplx_from_znx32_simple(m, 32, dst1, src);
21 cplx_from_znx32_avx2_fma(&precomp, dst2, src);
22 for (uint64_t i = 0; i < m; ++i) {
23 ASSERT_EQ(dst1[i][0], dst2[i][0]);
24 ASSERT_EQ(dst1[i][1], dst2[i][1]);
25 }
26 spqlios_free(src);
27}
28#endif
29
30#ifdef __x86_64__
31TEST(fft, cplx_from_tnx32_ref_vs_fma) {
32 const uint32_t m = 128;
33 int32_t* src = (int32_t*)spqlios_alloc_custom_align(32, 10 * m * sizeof(int32_t));
34 CPLX* dst1 = (CPLX*)(src + 2 * m);
35 CPLX* dst2 = (CPLX*)(src + 6 * m);
36 for (uint64_t i = 0; i < 2 * m; ++i) {
37 src[i] = rand() + (rand() << 20);
38 }
39 CPLX_FROM_TNX32_PRECOMP precomp;
40 precomp.m = m;
41 cplx_from_tnx32_ref(&precomp, dst1, src);
42 // cplx_from_tnx32_simple(m, dst1, src);
43 cplx_from_tnx32_avx2_fma(&precomp, dst2, src);
44 for (uint64_t i = 0; i < m; ++i) {
45 ASSERT_EQ(dst1[i][0], dst2[i][0]);
46 ASSERT_EQ(dst1[i][1], dst2[i][1]);
47 }
48 spqlios_free(src);
49}
50#endif
51
52#ifdef __x86_64__
53TEST(fft, cplx_to_tnx32_ref_vs_fma) {
54 for (const uint32_t m : {8, 128, 1024, 65536}) {
55 for (const double divisor : {double(1), double(m), double(0.5)}) {
56 CPLX* src = (CPLX*)spqlios_alloc_custom_align(32, 10 * m * sizeof(int32_t));
57 int32_t* dst1 = (int32_t*)(src + m);
58 int32_t* dst2 = (int32_t*)(src + 2 * m);
59 for (uint64_t i = 0; i < 2 * m; ++i) {
60 src[i][0] = (rand() / double(RAND_MAX) - 0.5) * pow(2., 19 - (rand() % 60)) * divisor;
61 src[i][1] = (rand() / double(RAND_MAX) - 0.5) * pow(2., 19 - (rand() % 60)) * divisor;
62 }
63 CPLX_TO_TNX32_PRECOMP precomp;
64 precomp.m = m;
65 precomp.divisor = divisor;
66 cplx_to_tnx32_ref(&precomp, dst1, src);
67 cplx_to_tnx32_avx2_fma(&precomp, dst2, src);
68 // cplx_to_tnx32_simple(m, divisor, 18, dst2, src);
69 for (uint64_t i = 0; i < 2 * m; ++i) {
70 double truevalue =
71 (src[i % m][i / m] / divisor - floor(src[i % m][i / m] / divisor + 0.5)) * (INT64_C(1) << 32);
72 if (fabs(truevalue - floor(truevalue)) == 0.5) {
73 // ties can differ by 0, 1 or -1
74 ASSERT_LE(abs(dst1[i] - dst2[i]), 0)
75 << i << " " << dst1[i] << " " << dst2[i] << " " << truevalue << std::endl;
76 } else {
77 // otherwise, we should have equality
78 ASSERT_LE(abs(dst1[i] - dst2[i]), 0)
79 << i << " " << dst1[i] << " " << dst2[i] << " " << truevalue << std::endl;
80 }
81 }
82 spqlios_free(src);
83 }
84 }
85}
86#endif