poulpy/poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/cplx/cplx_fft.h
poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/cplx/cplx_fft.hRaw
1#ifndef SPQLIOS_CPLX_FFT_H
2#define SPQLIOS_CPLX_FFT_H
3
4#include "../commons.h"
5
6typedef struct cplx_fft_precomp CPLX_FFT_PRECOMP;
7typedef struct cplx_ifft_precomp CPLX_IFFT_PRECOMP;
8typedef struct cplx_mul_precomp CPLX_FFTVEC_MUL_PRECOMP;
9typedef struct cplx_addmul_precomp CPLX_FFTVEC_ADDMUL_PRECOMP;
10typedef struct cplx_from_znx32_precomp CPLX_FROM_ZNX32_PRECOMP;
11typedef struct cplx_from_tnx32_precomp CPLX_FROM_TNX32_PRECOMP;
12typedef struct cplx_to_tnx32_precomp CPLX_TO_TNX32_PRECOMP;
13typedef struct cplx_to_znx32_precomp CPLX_TO_ZNX32_PRECOMP;
14typedef struct cplx_from_rnx64_precomp CPLX_FROM_RNX64_PRECOMP;
15typedef struct cplx_to_rnx64_precomp CPLX_TO_RNX64_PRECOMP;
16typedef struct cplx_round_to_rnx64_precomp CPLX_ROUND_TO_RNX64_PRECOMP;
17
18/**
19 * @brief precomputes fft tables.
20 * The FFT tables contains a constant section that is required for efficient FFT operations in dimension nn.
21 * The resulting pointer is to be passed as "tables" argument to any call to the fft function.
22 * The user can optionnally allocate zero or more computation buffers, which are scratch spaces that are contiguous to
23 * the constant tables in memory, and allow for more efficient operations. It is the user's responsibility to ensure
24 * that each of those buffers are never used simultaneously by two ffts on different threads at the same time. The fft
25 * table must be deleted by delete_fft_precomp after its last usage.
26 */
27EXPORT CPLX_FFT_PRECOMP* new_cplx_fft_precomp(uint32_t m, uint32_t num_buffers);
28
29/**
30 * @brief gets the address of a fft buffer allocated during new_fft_precomp.
31 * This buffer can be used as data pointer in subsequent calls to fft,
32 * and does not need to be released afterwards.
33 */
34EXPORT void* cplx_fft_precomp_get_buffer(const CPLX_FFT_PRECOMP* tables, uint32_t buffer_index);
35
36/**
37 * @brief allocates a new fft buffer.
38 * This buffer can be used as data pointer in subsequent calls to fft,
39 * and must be deleted afterwards by calling delete_fft_buffer.
40 */
41EXPORT void* new_cplx_fft_buffer(uint32_t m);
42
43/**
44 * @brief allocates a new fft buffer.
45 * This buffer can be used as data pointer in subsequent calls to fft,
46 * and must be deleted afterwards by calling delete_fft_buffer.
47 */
48EXPORT void delete_cplx_fft_buffer(void* buffer);
49
50/**
51 * @brief deallocates a fft table and all its built-in buffers.
52 */
53#define delete_cplx_fft_precomp free
54
55/**
56 * @brief computes a direct fft in-place over data.
57 */
58EXPORT void cplx_fft(const CPLX_FFT_PRECOMP* tables, void* data);
59
60EXPORT CPLX_IFFT_PRECOMP* new_cplx_ifft_precomp(uint32_t m, uint32_t num_buffers);
61EXPORT void* cplx_ifft_precomp_get_buffer(const CPLX_IFFT_PRECOMP* tables, uint32_t buffer_index);
62EXPORT void cplx_ifft(const CPLX_IFFT_PRECOMP* tables, void* data);
63#define delete_cplx_ifft_precomp free
64
65EXPORT CPLX_FFTVEC_MUL_PRECOMP* new_cplx_fftvec_mul_precomp(uint32_t m);
66EXPORT void cplx_fftvec_mul(const CPLX_FFTVEC_MUL_PRECOMP* tables, void* r, const void* a, const void* b);
67#define delete_cplx_fftvec_mul_precomp free
68
69EXPORT CPLX_FFTVEC_ADDMUL_PRECOMP* new_cplx_fftvec_addmul_precomp(uint32_t m);
70EXPORT void cplx_fftvec_addmul(const CPLX_FFTVEC_ADDMUL_PRECOMP* tables, void* r, const void* a, const void* b);
71#define delete_cplx_fftvec_addmul_precomp free
72
73/**
74 * @brief prepares a conversion from ZnX to the cplx layout.
75 * All the coefficients must be strictly lower than 2^log2bound in absolute value. Any attempt to use
76 * this function on a larger coefficient is undefined behaviour. The resulting precomputed data must
77 * be freed with `new_cplx_from_znx32_precomp`
78 * @param m the target complex dimension m from C[X] mod X^m-i. Note that the inputs have n=2m
79 * int32 coefficients in natural order modulo X^n+1
80 * @param log2bound bound on the input coefficients. Must be between 0 and 32
81 */
82EXPORT CPLX_FROM_ZNX32_PRECOMP* new_cplx_from_znx32_precomp(uint32_t m);
83/**
84 * @brief converts from ZnX to the cplx layout.
85 * @param tables precomputed data obtained by new_cplx_from_znx32_precomp.
86 * @param r resulting array of m complexes coefficients mod X^m-i
87 * @param x input array of n bounded integer coefficients mod X^n+1
88 */
89EXPORT void cplx_from_znx32(const CPLX_FROM_ZNX32_PRECOMP* tables, void* r, const int32_t* a);
90/** @brief frees a precomputed conversion data initialized with new_cplx_from_znx32_precomp. */
91#define delete_cplx_from_znx32_precomp free
92
93/**
94 * @brief prepares a conversion from TnX to the cplx layout.
95 * @param m the target complex dimension m from C[X] mod X^m-i. Note that the inputs have n=2m
96 * torus32 coefficients. The resulting precomputed data must
97 * be freed with `delete_cplx_from_tnx32_precomp`
98 */
99EXPORT CPLX_FROM_TNX32_PRECOMP* new_cplx_from_tnx32_precomp(uint32_t m);
100/**
101 * @brief converts from TnX to the cplx layout.
102 * @param tables precomputed data obtained by new_cplx_from_tnx32_precomp.
103 * @param r resulting array of m complexes coefficients mod X^m-i
104 * @param x input array of n torus32 coefficients mod X^n+1
105 */
106EXPORT void cplx_from_tnx32(const CPLX_FROM_TNX32_PRECOMP* tables, void* r, const int32_t* a);
107/** @brief frees a precomputed conversion data initialized with new_cplx_from_tnx32_precomp. */
108#define delete_cplx_from_tnx32_precomp free
109
110/**
111 * @brief prepares a rescale and conversion from the cplx layout to TnX.
112 * @param m the target complex dimension m from C[X] mod X^m-i. Note that the outputs have n=2m
113 * torus32 coefficients.
114 * @param divisor must be a power of two. The inputs are rescaled by divisor before being reduced modulo 1.
115 * Remember that the output of an iFFT must be divided by m.
116 * @param log2overhead all inputs absolute values must be within divisor.2^log2overhead.
117 * For any inputs outside of these bounds, the conversion is undefined behaviour.
118 * The maximum supported log2overhead is 52, and the algorithm is faster for log2overhead=18.
119 */
120EXPORT CPLX_TO_TNX32_PRECOMP* new_cplx_to_tnx32_precomp(uint32_t m, double divisor, uint32_t log2overhead);
121/**
122 * @brief rescale, converts and reduce mod 1 from cplx layout to torus32.
123 * @param tables precomputed data obtained by new_cplx_from_tnx32_precomp.
124 * @param r resulting array of n torus32 coefficients mod X^n+1
125 * @param x input array of m cplx coefficients mod X^m-i
126 */
127EXPORT void cplx_to_tnx32(const CPLX_TO_TNX32_PRECOMP* tables, int32_t* r, const void* a);
128#define delete_cplx_to_tnx32_precomp free
129
130EXPORT CPLX_TO_ZNX32_PRECOMP* new_cplx_to_znx32_precomp(uint32_t m, double divisor);
131EXPORT void cplx_to_znx32(const CPLX_TO_ZNX32_PRECOMP* precomp, int32_t* r, const void* x);
132#define delete_cplx_to_znx32_simple free
133
134EXPORT CPLX_FROM_RNX64_PRECOMP* new_cplx_from_rnx64_simple(uint32_t m);
135EXPORT void cplx_from_rnx64(const CPLX_FROM_RNX64_PRECOMP* precomp, void* r, const double* x);
136#define delete_cplx_from_rnx64_simple free
137
138EXPORT CPLX_TO_RNX64_PRECOMP* new_cplx_to_rnx64(uint32_t m, double divisor);
139EXPORT void cplx_to_rnx64(const CPLX_TO_RNX64_PRECOMP* precomp, double* r, const void* x);
140#define delete_cplx_round_to_rnx64_simple free
141
142EXPORT CPLX_ROUND_TO_RNX64_PRECOMP* new_cplx_round_to_rnx64(uint32_t m, double divisor, uint32_t log2bound);
143EXPORT void cplx_round_to_rnx64(const CPLX_ROUND_TO_RNX64_PRECOMP* precomp, double* r, const void* x);
144#define delete_cplx_round_to_rnx64_simple free
145
146/**
147 * @brief Simpler API for the fft function.
148 * For each dimension, the precomputed tables for this dimension are generated automatically.
149 * It is advised to do one dry-run per desired dimension before using in a multithread environment */
150EXPORT void cplx_fft_simple(uint32_t m, void* data);
151/**
152 * @brief Simpler API for the ifft function.
153 * For each dimension, the precomputed tables for this dimension are generated automatically the first time.
154 * It is advised to do one dry-run call per desired dimension in the main thread before using in a multithread
155 * environment */
156EXPORT void cplx_ifft_simple(uint32_t m, void* data);
157/**
158 * @brief Simpler API for the fftvec multiplication function.
159 * For each dimension, the precomputed tables for this dimension are generated automatically the first time.
160 * It is advised to do one dry-run call per desired dimension before using in a multithread environment */
161EXPORT void cplx_fftvec_mul_simple(uint32_t m, void* r, const void* a, const void* b);
162/**
163 * @brief Simpler API for the fftvec addmul function.
164 * For each dimension, the precomputed tables for this dimension are generated automatically the first time.
165 * It is advised to do one dry-run call per desired dimension before using in a multithread environment */
166EXPORT void cplx_fftvec_addmul_simple(uint32_t m, void* r, const void* a, const void* b);
167/**
168 * @brief Simpler API for the znx32 to cplx conversion.
169 * For each dimension, the precomputed tables for this dimension are generated automatically the first time.
170 * It is advised to do one dry-run call per desired dimension before using in a multithread environment */
171EXPORT void cplx_from_znx32_simple(uint32_t m, void* r, const int32_t* x);
172/**
173 * @brief Simpler API for the tnx32 to cplx conversion.
174 * For each dimension, the precomputed tables for this dimension are generated automatically the first time.
175 * It is advised to do one dry-run call per desired dimension before using in a multithread environment */
176EXPORT void cplx_from_tnx32_simple(uint32_t m, void* r, const int32_t* x);
177/**
178 * @brief Simpler API for the cplx to tnx32 conversion.
179 * For each dimension, the precomputed tables for this dimension are generated automatically the first time.
180 * It is advised to do one dry-run call per desired dimension before using in a multithread environment */
181EXPORT void cplx_to_tnx32_simple(uint32_t m, double divisor, uint32_t log2overhead, int32_t* r, const void* x);
182
183/**
184 * @brief converts, divides and round from cplx to znx32 (simple API)
185 * @param m the complex dimension
186 * @param divisor the divisor: a power of two, often m after an ifft
187 * @param r the result: must be a double array of size 2m. r must be distinct from x
188 * @param x the input: must hold m complex numbers.
189 */
190EXPORT void cplx_to_znx32_simple(uint32_t m, double divisor, int32_t* r, const void* x);
191
192/**
193 * @brief converts from rnx64 to cplx (simple API)
194 * The bound on the output is assumed to be within ]2^-31,2^31[.
195 * Any coefficient that would fall outside this range is undefined behaviour.
196 * @param m the complex dimension
197 * @param r the result: must be an array of m complex numbers. r must be distinct from x
198 * @param x the input: must be an array of 2m doubles.
199 */
200EXPORT void cplx_from_rnx64_simple(uint32_t m, void* r, const double* x);
201
202/**
203 * @brief converts, divides from cplx to rnx64 (simple API)
204 * @param m the complex dimension
205 * @param divisor the divisor: a power of two, often m after an ifft
206 * @param r the result: must be a double array of size 2m. r must be distinct from x
207 * @param x the input: must hold m complex numbers.
208 */
209EXPORT void cplx_to_rnx64_simple(uint32_t m, double divisor, double* r, const void* x);
210
211/**
212 * @brief converts, divides and round to integer from cplx to rnx32 (simple API)
213 * @param m the complex dimension
214 * @param divisor the divisor: a power of two, often m after an ifft
215 * @param log2bound a guarantee on the log2bound of the output. log2bound<=48 will use a more efficient algorithm.
216 * @param r the result: must be a double array of size 2m. r must be distinct from x
217 * @param x the input: must hold m complex numbers.
218 */
219EXPORT void cplx_round_to_rnx64_simple(uint32_t m, double divisor, uint32_t log2bound, double* r, const void* x);
220
221#endif // SPQLIOS_CPLX_FFT_H