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