poulpy/poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/reim4/reim4_arithmetic.h
poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/reim4/reim4_arithmetic.hRaw
1#ifndef SPQLIOS_REIM4_ARITHMETIC_H
2#define SPQLIOS_REIM4_ARITHMETIC_H
3
4#include "../commons.h"
5
6// the reim4 structure represent 4 complex numbers,
7// represented as re0,re1,re2,re3,im0,im1,im2,im3
8
9// TODO implement these basic arithmetic functions. (only ref is needed)
10
11/** @brief dest = 0 */
12EXPORT void reim4_zero(double* dest);
13/** @brief dest = a + b */
14EXPORT void reim4_add(double* dest, const double* u, const double* v);
15/** @brief dest = a * b */
16EXPORT void reim4_mul(double* dest, const double* u, const double* v);
17/** @brief dest += a * b */
18EXPORT void reim4_add_mul(double* dest, const double* a, const double* b);
19
20// TODO add the dot products: vec x mat1col, vec x mat2cols functions here (ref and avx)
21
22// TODO implement the convolution functions here (ref and avx)
23/**
24 * @brief k-th coefficient of the convolution product a * b.
25 *
26 * The k-th coefficient is defined as sum_{i+j=k} a[i].b[j].
27 * (in this sum, i and j must remain within the bounds [0,sizea[ and [0,sizeb[)
28 *
29 * In practice, accounting for these bounds, the convolution function boils down to
30 * ```
31 * res := 0
32 * if (k<sizeb+sizea-1) then
33 * for j from max(0,k+1-sizea) incl to min(sizeb,k+1) excl do
34 * res += a[k-j] * b[j]
35 * return res
36 * ```
37 */
38EXPORT void reim4_convolution_1coeff_ref(uint64_t k, double* dest, const double* a, uint64_t sizea, const double* b,
39 uint64_t sizeb);
40EXPORT void reim4_convolution_1coeff_avx(uint64_t k, double* dest, const double* a, uint64_t sizea, const double* b,
41 uint64_t sizeb);
42/** @brief returns two consecutive convolution coefficients: k and k+1 */
43EXPORT void reim4_convolution_2coeff_ref(uint64_t k, double* dest, const double* a, uint64_t sizea, const double* b,
44 uint64_t sizeb);
45EXPORT void reim4_convolution_2coeff_avx(uint64_t k, double* dest, const double* a, uint64_t sizea, const double* b,
46 uint64_t sizeb);
47
48/**
49 * @brief From the convolution a * b, return the coefficients between offset and offset + size
50 * For the full convolution, use offset=0 and size=sizea+sizeb-1.
51 */
52EXPORT void reim4_convolution_ref(double* dest, uint64_t dest_size, uint64_t dest_offset, const double* a,
53 uint64_t sizea, const double* b, uint64_t sizeb);
54EXPORT void reim4_convolution_avx(double* dest, uint64_t dest_size, uint64_t dest_offset, const double* a,
55 uint64_t sizea, const double* b, uint64_t sizeb);
56
57// The reim fft layout that encodes m = nn/2 complex evaluations
58// can be decomposed into m/4 reim4 blocks
59// the i-th block of v is noted v(i);
60// it contains the 4 evaluations (e[4i],e[4i+1],e[4i+2],e[4i+3])
61
62/**
63 * @brief extract 1 reim4 block from one reim vectors of m complexes
64 * @param m the size of each reim
65 * @param blk the block id to extract (<m/4)
66 * @param dst the output: nrows reim4's dst[i] = src[i](blk)
67 * @param src the input: nrows reim's
68 */
69EXPORT void reim4_extract_1blk_from_reim_ref(uint64_t m, uint64_t blk,
70 double* const dst, // 8 doubles
71 const double* const src // a reim vector
72);
73EXPORT void reim4_extract_1blk_from_reim_avx(uint64_t m, uint64_t blk,
74 double* const dst, // 8 doubles
75 const double* const src // a reim vectors
76);
77
78/**
79 * @brief extract 1 reim vectors from one reim4 block of m complexes
80 * @param m the size of each reim
81 * @param blk the block id to extract (<m/4)
82 * @param dst the output: nrows reim4's dst[i](blk) = src[i]
83 * @param src the input: nrows reim's
84 */
85EXPORT void reim4_extract_reim_from_1blk_ref(uint64_t m, uint64_t blk,
86 double* const dst, // 8 doubles
87 const double* const src // a reim vector
88);
89
90/**
91 * @brief extract 1 reim4 block from nrows reim vectors of m complexes
92 * @param nrows the number of reim (fft) vectors
93 * @param m the size of each reim
94 * @param blk the block id to extract (<m/4)
95 * @param dst the output: nrows reim4's dst[i] = src[i](blk)
96 * @param src the input: nrows reim's
97 */
98EXPORT void reim4_extract_1blk_from_contiguous_reim_ref(uint64_t m, uint64_t nrows, uint64_t blk, double* const dst,
99 const double* const src);
100EXPORT void reim4_extract_1blk_from_contiguous_reim_avx(uint64_t m, uint64_t nrows, uint64_t blk, double* const dst,
101 const double* const src);
102
103/**
104 * @brief extract 1 reim4 block from nrows reim vectors of m complexes with slice sl
105 * @param m the size of each reim
106 * @param sl the slice size
107 * @param nrows the number of reim (fft) vectors to extract
108 * @param blk the block id to extract (<m/4)
109 * @param dst the output: nrows reim4's dst[i] = src[i](blk)
110 * @param src the input: nrows reim's
111 */
112EXPORT void reim4_extract_1blk_from_contiguous_reim_sl_ref(uint64_t m, uint64_t sl, uint64_t nrows, uint64_t blk,
113 double* const dst, const double* const src);
114EXPORT void reim4_extract_1blk_from_contiguous_reim_sl_avx(uint64_t m, uint64_t sl, uint64_t nrows, uint64_t blk,
115 double* const dst, const double* const src);
116
117/**
118 * @brief saves 1 single reim4 block in a reim vectors of m complexes
119 * @param m the size of each reim
120 * @param blk the block id to save (<m/4)
121 * @param dest the output reim: dst(blk) = src
122 * @param src the input reim4
123 */
124EXPORT void reim4_save_1blk_to_reim_ref(uint64_t m, uint64_t blk,
125 double* dest, // 1 reim vector of length m
126 const double* src // 8 doubles
127);
128EXPORT void reim4_save_1blk_to_reim_avx(uint64_t m, uint64_t blk,
129 double* dest, // 1 reim vector of length m
130 const double* src // 8 doubles
131);
132
133/**
134 * @brief Adds 1 single reim4 block in a reim vectors of m complexes
135 * @param m the size of each reim
136 * @param blk the block id to save (<m/4)
137 * @param dest the output reim: dst(blk) += src
138 * @param src the input reim4
139 */
140EXPORT void reim4_add_1blk_to_reim_ref(uint64_t m, uint64_t blk,
141 double* dest, // 1 reim vector of length m
142 const double* src // 8 doubles
143);
144EXPORT void reim4_add_1blk_to_reim_avx(uint64_t m, uint64_t blk,
145 double* dest, // 1 reim vector of length m
146 const double* src // 8 doubles
147);
148
149// dest = sum u[i].v[i]
150// make ref and avx2 implem, needs to be fast
151// can accumulate the real and imaginary parts on 2 separate registers, and combine at the end
152EXPORT void reim4_vec_mat1col_product_ref(const uint64_t nrows,
153 double* const dst, // 8 doubles
154 const double* const u, // nrows * 8 doubles
155 const double* const v // nrows * 8 doubles
156);
157
158EXPORT void reim4_vec_mat1col_product_avx2(const uint64_t nrows,
159 double* const dst, // 8 doubles
160 const double* const u, // nrows * 8 doubles
161 const double* const v // nrows * 8 doubles
162);
163
164// dest = sum u[i].v[i]
165// make ref and avx2 implem, needs to be fast
166// can accumulate the real and imaginary parts on 2 separate registers, and recombine at the end
167EXPORT void reim4_vec_mat2cols_product_ref(uint64_t nrows, double* const dst, // 16 doubles
168 const double* const u, // nrows * 8 doubles
169 const double* const v // nrows * 16 doubles
170);
171
172EXPORT void reim4_vec_mat2cols_product_avx2(uint64_t nrows, double* const dst, // 16 doubles
173 const double* const u, // nrows * 8 doubles
174 const double* const v // nrows * 16 doubles
175);
176
177#endif // SPQLIOS_REIM4_ARITHMETIC_H