arnaucube
arnaucube/poulpyPublic Self-hosted repository
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