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