poulpy/poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/cplx/cplx_fftvec_ref.c
poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/cplx/cplx_fftvec_ref.cRaw
1#include <string.h>
2
3#include "../commons_private.h"
4#include "cplx_fft_internal.h"
5#include "cplx_fft_private.h"
6
7EXPORT void cplx_fftvec_addmul_ref(const CPLX_FFTVEC_ADDMUL_PRECOMP* precomp, void* r, const void* a, const void* b) {
8 const uint32_t m = precomp->m;
9 const CPLX* aa = (CPLX*)a;
10 const CPLX* bb = (CPLX*)b;
11 CPLX* rr = (CPLX*)r;
12 for (uint32_t i = 0; i < m; ++i) {
13 const double re = aa[i][0] * bb[i][0] - aa[i][1] * bb[i][1];
14 const double im = aa[i][0] * bb[i][1] + aa[i][1] * bb[i][0];
15 rr[i][0] += re;
16 rr[i][1] += im;
17 }
18}
19
20EXPORT void cplx_fftvec_mul_ref(const CPLX_FFTVEC_MUL_PRECOMP* precomp, void* r, const void* a, const void* b) {
21 const uint32_t m = precomp->m;
22 const CPLX* aa = (CPLX*)a;
23 const CPLX* bb = (CPLX*)b;
24 CPLX* rr = (CPLX*)r;
25 for (uint32_t i = 0; i < m; ++i) {
26 const double re = aa[i][0] * bb[i][0] - aa[i][1] * bb[i][1];
27 const double im = aa[i][0] * bb[i][1] + aa[i][1] * bb[i][0];
28 rr[i][0] = re;
29 rr[i][1] = im;
30 }
31}
32
33EXPORT void* init_cplx_fftvec_addmul_precomp(CPLX_FFTVEC_ADDMUL_PRECOMP* r, uint32_t m) {
34 if (m & (m - 1)) return spqlios_error("m must be a power of two");
35 r->m = m;
36 if (m <= 4) {
37 r->function = cplx_fftvec_addmul_ref;
38 } else if (CPU_SUPPORTS("fma")) {
39 r->function = cplx_fftvec_addmul_fma;
40 } else {
41 r->function = cplx_fftvec_addmul_ref;
42 }
43 return r;
44}
45
46EXPORT void* init_cplx_fftvec_mul_precomp(CPLX_FFTVEC_MUL_PRECOMP* r, uint32_t m) {
47 if (m & (m - 1)) return spqlios_error("m must be a power of two");
48 r->m = m;
49 if (m <= 4) {
50 r->function = cplx_fftvec_mul_ref;
51 } else if (CPU_SUPPORTS("fma")) {
52 r->function = cplx_fftvec_mul_fma;
53 } else {
54 r->function = cplx_fftvec_mul_ref;
55 }
56 return r;
57}
58
59EXPORT CPLX_FFTVEC_ADDMUL_PRECOMP* new_cplx_fftvec_addmul_precomp(uint32_t m) {
60 CPLX_FFTVEC_ADDMUL_PRECOMP* r = malloc(sizeof(CPLX_FFTVEC_MUL_PRECOMP));
61 return spqlios_keep_or_free(r, init_cplx_fftvec_addmul_precomp(r, m));
62}
63
64EXPORT CPLX_FFTVEC_MUL_PRECOMP* new_cplx_fftvec_mul_precomp(uint32_t m) {
65 CPLX_FFTVEC_MUL_PRECOMP* r = malloc(sizeof(CPLX_FFTVEC_MUL_PRECOMP));
66 return spqlios_keep_or_free(r, init_cplx_fftvec_mul_precomp(r, m));
67}
68
69EXPORT void cplx_fftvec_mul_simple(uint32_t m, void* r, const void* a, const void* b) {
70 static CPLX_FFTVEC_MUL_PRECOMP p[31] = {0};
71 CPLX_FFTVEC_MUL_PRECOMP* f = p + log2m(m);
72 if (!f->function) {
73 if (!init_cplx_fftvec_mul_precomp(f, m)) abort();
74 }
75 f->function(f, r, a, b);
76}
77
78EXPORT void cplx_fftvec_addmul_simple(uint32_t m, void* r, const void* a, const void* b) {
79 static CPLX_FFTVEC_ADDMUL_PRECOMP p[31] = {0};
80 CPLX_FFTVEC_ADDMUL_PRECOMP* f = p + log2m(m);
81 if (!f->function) {
82 if (!init_cplx_fftvec_addmul_precomp(f, m)) abort();
83 }
84 f->function(f, r, a, b);
85}