poulpy/poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/reim/reim_fft.h
poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/reim/reim_fft.hRaw
1#ifndef SPQLIOS_REIM_FFT_H
2#define SPQLIOS_REIM_FFT_H
3
4#include "../commons.h"
5
6typedef struct reim_fft_precomp REIM_FFT_PRECOMP;
7typedef struct reim_ifft_precomp REIM_IFFT_PRECOMP;
8typedef struct reim_add_precomp REIM_FFTVEC_ADD_PRECOMP;
9typedef struct reim_sub_precomp REIM_FFTVEC_SUB_PRECOMP;
10typedef struct reim_mul_precomp REIM_FFTVEC_MUL_PRECOMP;
11typedef struct reim_addmul_precomp REIM_FFTVEC_ADDMUL_PRECOMP;
12typedef struct reim_fftvec_automorphism_precomp REIM_FFTVEC_AUTOMORPHISM_PRECOMP;
13typedef struct reim_from_znx32_precomp REIM_FROM_ZNX32_PRECOMP;
14typedef struct reim_from_znx64_precomp REIM_FROM_ZNX64_PRECOMP;
15typedef struct reim_from_tnx32_precomp REIM_FROM_TNX32_PRECOMP;
16typedef struct reim_to_tnx32_precomp REIM_TO_TNX32_PRECOMP;
17typedef struct reim_to_tnx_precomp REIM_TO_TNX_PRECOMP;
18typedef struct reim_to_znx64_precomp REIM_TO_ZNX64_PRECOMP;
19
20/**
21 * @brief precomputes fft tables.
22 * The FFT tables contains a constant section that is required for efficient FFT operations in dimension nn.
23 * The resulting pointer is to be passed as "tables" argument to any call to the fft function.
24 * The user can optionnally allocate zero or more computation buffers, which are scratch spaces that are contiguous to
25 * the constant tables in memory, and allow for more efficient operations. It is the user's responsibility to ensure
26 * that each of those buffers are never used simultaneously by two ffts on different threads at the same time. The fft
27 * table must be deleted by delete_fft_precomp after its last usage.
28 */
29EXPORT REIM_FFT_PRECOMP* new_reim_fft_precomp(uint32_t m, uint32_t num_buffers);
30
31/**
32 * @brief gets the address of a fft buffer allocated during new_fft_precomp.
33 * This buffer can be used as data pointer in subsequent calls to fft,
34 * and does not need to be released afterwards.
35 */
36EXPORT double* reim_fft_precomp_get_buffer(const REIM_FFT_PRECOMP* tables, uint32_t buffer_index);
37
38/**
39 * @brief allocates a new fft buffer.
40 * This buffer can be used as data pointer in subsequent calls to fft,
41 * and must be deleted afterwards by calling delete_fft_buffer.
42 */
43EXPORT double* new_reim_fft_buffer(uint32_t m);
44
45/**
46 * @brief allocates a new fft buffer.
47 * This buffer can be used as data pointer in subsequent calls to fft,
48 * and must be deleted afterwards by calling delete_fft_buffer.
49 */
50EXPORT void delete_reim_fft_buffer(double* buffer);
51
52/**
53 * @brief deallocates a fft table and all its built-in buffers.
54 */
55#define delete_reim_fft_precomp free
56
57/**
58 * @brief computes a direct fft in-place over data.
59 */
60EXPORT void reim_fft(const REIM_FFT_PRECOMP* tables, double* data);
61
62EXPORT REIM_IFFT_PRECOMP* new_reim_ifft_precomp(uint32_t m, uint32_t num_buffers);
63EXPORT double* reim_ifft_precomp_get_buffer(const REIM_IFFT_PRECOMP* tables, uint32_t buffer_index);
64EXPORT void reim_ifft(const REIM_IFFT_PRECOMP* tables, double* data);
65#define delete_reim_ifft_precomp free
66
67EXPORT REIM_FFTVEC_ADD_PRECOMP* new_reim_fftvec_add_precomp(uint32_t m);
68EXPORT void reim_fftvec_add(const REIM_FFTVEC_ADD_PRECOMP* tables, double* r, const double* a, const double* b);
69#define delete_reim_fftvec_add_precomp free
70
71EXPORT REIM_FFTVEC_SUB_PRECOMP* new_reim_fftvec_sub_precomp(uint32_t m);
72EXPORT void reim_fftvec_sub(const REIM_FFTVEC_SUB_PRECOMP* tables, double* r, const double* a, const double* b);
73#define delete_reim_fftvec_sub_precomp free
74
75EXPORT REIM_FFTVEC_MUL_PRECOMP* new_reim_fftvec_mul_precomp(uint32_t m);
76EXPORT void reim_fftvec_mul(const REIM_FFTVEC_MUL_PRECOMP* tables, double* r, const double* a, const double* b);
77#define delete_reim_fftvec_mul_precomp free
78
79EXPORT REIM_FFTVEC_ADDMUL_PRECOMP* new_reim_fftvec_addmul_precomp(uint32_t m);
80EXPORT void reim_fftvec_addmul(const REIM_FFTVEC_ADDMUL_PRECOMP* tables, double* r, const double* a, const double* b);
81#define delete_reim_fftvec_addmul_precomp free
82
83EXPORT REIM_FFTVEC_AUTOMORPHISM_PRECOMP* new_reim_fftvec_automorphism_precomp(uint32_t m);
84EXPORT void reim_fftvec_automorphism(const REIM_FFTVEC_AUTOMORPHISM_PRECOMP* tables, int64_t p, double* r,
85 const double* a, uint64_t a_size);
86
87EXPORT void reim_fftvec_automorphism_inplace(const REIM_FFTVEC_AUTOMORPHISM_PRECOMP* tables, int64_t p, double* a,
88 uint64_t a_size, uint8_t* tmp_bytes);
89
90EXPORT uint64_t reim_fftvec_automorphism_inplace_tmp_bytes(const REIM_FFTVEC_AUTOMORPHISM_PRECOMP* tables);
91
92#define delete_reim_fftvec_automorphism_precomp free
93
94/**
95 * @brief prepares a conversion from ZnX to the cplx layout.
96 * All the coefficients must be strictly lower than 2^log2bound in absolute value. Any attempt to use
97 * this function on a larger coefficient is undefined behaviour. The resulting precomputed data must
98 * be freed with `new_reim_from_znx32_precomp`
99 * @param m the target complex dimension m from C[X] mod X^m-i. Note that the inputs have n=2m
100 * int32 coefficients in natural order modulo X^n+1
101 * @param log2bound bound on the input coefficients. Must be between 0 and 32
102 */
103EXPORT REIM_FROM_ZNX32_PRECOMP* new_reim_from_znx32_precomp(uint32_t m, uint32_t log2bound);
104
105/**
106 * @brief converts from ZnX to the cplx layout.
107 * @param tables precomputed data obtained by new_reim_from_znx32_precomp.
108 * @param r resulting array of m complexes coefficients mod X^m-i
109 * @param x input array of n bounded integer coefficients mod X^n+1
110 */
111EXPORT void reim_from_znx32(const REIM_FROM_ZNX32_PRECOMP* tables, void* r, const int32_t* a);
112/** @brief frees a precomputed conversion data initialized with new_reim_from_znx32_precomp. */
113#define delete_reim_from_znx32_precomp free
114
115/**
116 * @brief converts from ZnX to the cplx layout.
117 * @param tables precomputed data obtained by new_reim_from_znx64_precomp.
118 * @param r resulting array of m complexes coefficients mod X^m-i
119 * @param x input array of n bounded integer coefficients mod X^n+1
120 */
121EXPORT void reim_from_znx64(const REIM_FROM_ZNX64_PRECOMP* tables, void* r, const int64_t* a);
122/** @brief frees a precomputed conversion data initialized with new_reim_from_znx32_precomp. */
123EXPORT REIM_FROM_ZNX64_PRECOMP* new_reim_from_znx64_precomp(uint32_t m, uint32_t maxbnd);
124#define delete_reim_from_znx64_precomp free
125EXPORT void reim_from_znx64_simple(uint32_t m, uint32_t log2bound, void* r, const int64_t* a);
126
127/**
128 * @brief prepares a conversion from TnX to the cplx layout.
129 * @param m the target complex dimension m from C[X] mod X^m-i. Note that the inputs have n=2m
130 * torus32 coefficients. The resulting precomputed data must
131 * be freed with `delete_reim_from_tnx32_precomp`
132 */
133
134EXPORT REIM_FROM_TNX32_PRECOMP* new_reim_from_tnx32_precomp(uint32_t m);
135/**
136 * @brief converts from TnX to the cplx layout.
137 * @param tables precomputed data obtained by new_reim_from_tnx32_precomp.
138 * @param r resulting array of m complexes coefficients mod X^m-i
139 * @param x input array of n torus32 coefficients mod X^n+1
140 */
141EXPORT void reim_from_tnx32(const REIM_FROM_TNX32_PRECOMP* tables, void* r, const int32_t* a);
142/** @brief frees a precomputed conversion data initialized with new_reim_from_tnx32_precomp. */
143#define delete_reim_from_tnx32_precomp free
144
145/**
146 * @brief prepares a rescale and conversion from the cplx layout to TnX.
147 * @param m the target complex dimension m from C[X] mod X^m-i. Note that the outputs have n=2m
148 * torus32 coefficients.
149 * @param divisor must be a power of two. The inputs are rescaled by divisor before being reduced modulo 1.
150 * Remember that the output of an iFFT must be divided by m.
151 * @param log2overhead all inputs absolute values must be within divisor.2^log2overhead.
152 * For any inputs outside of these bounds, the conversion is undefined behaviour.
153 * The maximum supported log2overhead is 52, and the algorithm is faster for log2overhead=18.
154 */
155EXPORT REIM_TO_TNX32_PRECOMP* new_reim_to_tnx32_precomp(uint32_t m, double divisor, uint32_t log2overhead);
156
157/**
158 * @brief rescale, converts and reduce mod 1 from cplx layout to torus32.
159 * @param tables precomputed data obtained by new_reim_from_tnx32_precomp.
160 * @param r resulting array of n torus32 coefficients mod X^n+1
161 * @param x input array of m cplx coefficients mod X^m-i
162 */
163EXPORT void reim_to_tnx32(const REIM_TO_TNX32_PRECOMP* tables, int32_t* r, const void* a);
164#define delete_reim_to_tnx32_precomp free
165
166/**
167 * @brief prepares a rescale and conversion from the cplx layout to TnX (doubles).
168 * @param m the target complex dimension m from C[X] mod X^m-i. Note that the outputs have n=2m
169 * torus32 coefficients.
170 * @param divisor must be a power of two. The inputs are rescaled by divisor before being reduced modulo 1.
171 * Remember that the output of an iFFT must be divided by m.
172 * @param log2overhead all inputs absolute values must be within divisor.2^log2overhead.
173 * For any inputs outside of these bounds, the conversion is undefined behaviour.
174 * The maximum supported log2overhead is 52, and the algorithm is faster for log2overhead=18.
175 */
176EXPORT REIM_TO_TNX_PRECOMP* new_reim_to_tnx_precomp(uint32_t m, double divisor, uint32_t log2overhead);
177/**
178 * @brief rescale, converts and reduce mod 1 from cplx layout to torus32.
179 * @param tables precomputed data obtained by new_reim_from_tnx32_precomp.
180 * @param r resulting array of n torus32 coefficients mod X^n+1
181 * @param x input array of m cplx coefficients mod X^m-i
182 */
183EXPORT void reim_to_tnx(const REIM_TO_TNX_PRECOMP* tables, double* r, const double* a);
184#define delete_reim_to_tnx_precomp free
185EXPORT void reim_to_tnx_simple(uint32_t m, double divisor, uint32_t log2overhead, double* r, const double* a);
186
187EXPORT REIM_TO_ZNX64_PRECOMP* new_reim_to_znx64_precomp(uint32_t m, double divisor, uint32_t log2bound);
188#define delete_reim_to_znx64_precomp free
189EXPORT void reim_to_znx64(const REIM_TO_ZNX64_PRECOMP* precomp, int64_t* r, const void* a);
190EXPORT void reim_to_znx64_simple(uint32_t m, double divisor, uint32_t log2bound, int64_t* r, const void* a);
191
192/**
193 * @brief Simpler API for the fft function.
194 * For each dimension, the precomputed tables for this dimension are generated automatically.
195 * It is advised to do one dry-run per desired dimension before using in a multithread environment */
196EXPORT void reim_fft_simple(uint32_t m, void* data);
197/**
198 * @brief Simpler API for the ifft function.
199 * For each dimension, the precomputed tables for this dimension are generated automatically the first time.
200 * It is advised to do one dry-run call per desired dimension in the main thread before using in a multithread
201 * environment */
202EXPORT void reim_ifft_simple(uint32_t m, void* data);
203/**
204 * @brief Simpler API for the fftvec addition function.
205 * For each dimension, the precomputed tables for this dimension are generated automatically the first time.
206 * It is advised to do one dry-run call per desired dimension before using in a multithread environment */
207EXPORT void reim_fftvec_add_simple(uint32_t m, void* r, const void* a, const void* b);
208/**
209 * @brief Simpler API for the fftvec multiplication function.
210 * For each dimension, the precomputed tables for this dimension are generated automatically the first time.
211 * It is advised to do one dry-run call per desired dimension before using in a multithread environment */
212EXPORT void reim_fftvec_mul_simple(uint32_t m, void* r, const void* a, const void* b);
213/**
214 * @brief Simpler API for the fftvec addmul function.
215 * For each dimension, the precomputed tables for this dimension are generated automatically the first time.
216 * It is advised to do one dry-run call per desired dimension before using in a multithread environment */
217EXPORT void reim_fftvec_addmul_simple(uint32_t m, void* r, const void* a, const void* b);
218/**
219 * @brief Simpler API for the znx32 to cplx conversion.
220 * For each dimension, the precomputed tables for this dimension are generated automatically the first time.
221 * It is advised to do one dry-run call per desired dimension before using in a multithread environment */
222EXPORT void reim_from_znx32_simple(uint32_t m, uint32_t log2bound, void* r, const int32_t* x);
223/**
224 * @brief Simpler API for the tnx32 to cplx conversion.
225 * For each dimension, the precomputed tables for this dimension are generated automatically the first time.
226 * It is advised to do one dry-run call per desired dimension before using in a multithread environment */
227EXPORT void reim_from_tnx32_simple(uint32_t m, void* r, const int32_t* x);
228/**
229 * @brief Simpler API for the cplx to tnx32 conversion.
230 * For each dimension, the precomputed tables for this dimension are generated automatically the first time.
231 * It is advised to do one dry-run call per desired dimension before using in a multithread environment */
232EXPORT void reim_to_tnx32_simple(uint32_t m, double divisor, uint32_t log2overhead, int32_t* r, const void* x);
233
234#endif // SPQLIOS_REIM_FFT_H