poulpy/poulpy-hal/src/reference/fft64/reim4/arithmetic_ref.rs
poulpy-hal/src/reference/fft64/reim4/arithmetic_ref.rsRaw
1use crate::reference::fft64::reim::as_arr;
2
3#[inline(always)]
4pub fn reim4_extract_1blk_from_reim_ref(m: usize, rows: usize, blk: usize, dst: &mut [f64], src: &[f64]) {
5 let mut offset: usize = blk << 2;
6
7 debug_assert!(blk < (m >> 2));
8 debug_assert!(dst.len() >= 2 * rows * 4);
9
10 for chunk in dst.chunks_exact_mut(4).take(2 * rows) {
11 chunk.copy_from_slice(&src[offset..offset + 4]);
12 offset += m
13 }
14}
15
16#[inline(always)]
17pub fn reim4_save_1blk_to_reim_ref<const OVERWRITE: bool>(m: usize, blk: usize, dst: &mut [f64], src: &[f64]) {
18 let mut offset: usize = blk << 2;
19
20 debug_assert!(blk < (m >> 2));
21 debug_assert!(dst.len() >= offset + m + 4);
22 debug_assert!(src.len() >= 8);
23
24 let dst_off = &mut dst[offset..offset + 4];
25
26 if OVERWRITE {
27 dst_off.copy_from_slice(&src[0..4]);
28 } else {
29 dst_off[0] += src[0];
30 dst_off[1] += src[1];
31 dst_off[2] += src[2];
32 dst_off[3] += src[3];
33 }
34
35 offset += m;
36
37 let dst_off = &mut dst[offset..offset + 4];
38 if OVERWRITE {
39 dst_off.copy_from_slice(&src[4..8]);
40 } else {
41 dst_off[0] += src[4];
42 dst_off[1] += src[5];
43 dst_off[2] += src[6];
44 dst_off[3] += src[7];
45 }
46}
47
48#[inline(always)]
49pub fn reim4_save_2blk_to_reim_ref<const OVERWRITE: bool>(m: usize, blk: usize, dst: &mut [f64], src: &[f64]) {
50 let mut offset: usize = blk << 2;
51
52 debug_assert!(blk < (m >> 2));
53 debug_assert!(dst.len() >= offset + 3 * m + 4);
54 debug_assert!(src.len() >= 16);
55
56 let dst_off = &mut dst[offset..offset + 4];
57 if OVERWRITE {
58 dst_off.copy_from_slice(&src[0..4]);
59 } else {
60 dst_off[0] += src[0];
61 dst_off[1] += src[1];
62 dst_off[2] += src[2];
63 dst_off[3] += src[3];
64 }
65
66 offset += m;
67 let dst_off = &mut dst[offset..offset + 4];
68 if OVERWRITE {
69 dst_off.copy_from_slice(&src[4..8]);
70 } else {
71 dst_off[0] += src[4];
72 dst_off[1] += src[5];
73 dst_off[2] += src[6];
74 dst_off[3] += src[7];
75 }
76
77 offset += m;
78
79 let dst_off = &mut dst[offset..offset + 4];
80 if OVERWRITE {
81 dst_off.copy_from_slice(&src[8..12]);
82 } else {
83 dst_off[0] += src[8];
84 dst_off[1] += src[9];
85 dst_off[2] += src[10];
86 dst_off[3] += src[11];
87 }
88
89 offset += m;
90 let dst_off = &mut dst[offset..offset + 4];
91 if OVERWRITE {
92 dst_off.copy_from_slice(&src[12..16]);
93 } else {
94 dst_off[0] += src[12];
95 dst_off[1] += src[13];
96 dst_off[2] += src[14];
97 dst_off[3] += src[15];
98 }
99}
100
101#[inline(always)]
102pub fn reim4_vec_mat1col_product_ref(
103 nrows: usize,
104 dst: &mut [f64], // 8 doubles: [re1(4), im1(4)]
105 u: &[f64], // nrows * 8 doubles: [ur(4) | ui(4)] per row
106 v: &[f64], // nrows * 8 doubles: [ar(4) | ai(4)] per row
107) {
108 #[cfg(debug_assertions)]
109 {
110 assert!(dst.len() >= 8, "dst must have at least 8 doubles");
111 assert!(u.len() >= nrows * 8, "u must be at least nrows * 8 doubles");
112 assert!(v.len() >= nrows * 8, "v must be at least nrows * 8 doubles");
113 }
114
115 println!("u_ref: {:?}", &u[..nrows * 8]);
116 println!("v_ref: {:?}", &v[..nrows * 8]);
117
118 let mut acc: [f64; 8] = [0f64; 8];
119 let mut j = 0;
120 for _ in 0..nrows {
121 reim4_add_mul(&mut acc, as_arr(&u[j..]), as_arr(&v[j..]));
122 j += 8;
123 }
124 dst[0..8].copy_from_slice(&acc);
125
126 println!("dst_ref: {:?}", &dst[..8]);
127 println!();
128}
129
130#[inline(always)]
131pub fn reim4_vec_mat2cols_product_ref(
132 nrows: usize,
133 dst: &mut [f64], // 16 doubles: [re1(4), im1(4), re2(4), im2(4)]
134 u: &[f64], // nrows * 8 doubles: [ur(4) | ui(4)] per row
135 v: &[f64], // nrows * 16 doubles: [ar(4) | ai(4) | br(4) | bi(4)] per row
136) {
137 #[cfg(debug_assertions)]
138 {
139 assert_eq!(dst.len(), 16, "dst must have 16 doubles");
140 assert!(u.len() >= nrows * 8, "u must be at least nrows * 8 doubles");
141 assert!(
142 v.len() >= nrows * 16,
143 "v must be at least nrows * 16 doubles"
144 );
145 }
146
147 // zero accumulators
148 let mut acc_0: [f64; 8] = [0f64; 8];
149 let mut acc_1: [f64; 8] = [0f64; 8];
150 for i in 0..nrows {
151 let _1j: usize = i << 3;
152 let _2j: usize = i << 4;
153 let u_j: &[f64; 8] = as_arr(&u[_1j..]);
154 reim4_add_mul(&mut acc_0, u_j, as_arr(&v[_2j..]));
155 reim4_add_mul(&mut acc_1, u_j, as_arr(&v[_2j + 8..]));
156 }
157 dst[0..8].copy_from_slice(&acc_0);
158 dst[8..16].copy_from_slice(&acc_1);
159}
160
161#[inline(always)]
162pub fn reim4_vec_mat2cols_2ndcol_product_ref(
163 nrows: usize,
164 dst: &mut [f64], // 8 doubles: [re1(4), im1(4), re2(4), im2(4)]
165 u: &[f64], // nrows * 8 doubles: [ur(4) | ui(4)] per row
166 v: &[f64], // nrows * 16 doubles: [x | x | br(4) | bi(4)] per row
167) {
168 #[cfg(debug_assertions)]
169 {
170 assert!(
171 dst.len() >= 8,
172 "dst must be at least 8 doubles but is {}",
173 dst.len()
174 );
175 assert!(
176 u.len() >= nrows * 8,
177 "u must be at least nrows={} * 8 doubles but is {}",
178 nrows,
179 u.len()
180 );
181 assert!(
182 v.len() >= nrows * 16,
183 "v must be at least nrows={} * 16 doubles but is {}",
184 nrows,
185 v.len()
186 );
187 }
188
189 // zero accumulators
190 let mut acc: [f64; 8] = [0f64; 8];
191 for i in 0..nrows {
192 let _1j: usize = i << 3;
193 let _2j: usize = i << 4;
194 reim4_add_mul(&mut acc, as_arr(&u[_1j..]), as_arr(&v[_2j + 8..]));
195 }
196 dst[0..8].copy_from_slice(&acc);
197}
198
199#[inline(always)]
200pub fn reim4_add_mul(dst: &mut [f64; 8], a: &[f64; 8], b: &[f64; 8]) {
201 for k in 0..4 {
202 let ar: f64 = a[k];
203 let br: f64 = b[k];
204 let ai: f64 = a[k + 4];
205 let bi: f64 = b[k + 4];
206 dst[k] += ar * br - ai * bi;
207 dst[k + 4] += ar * bi + ai * br;
208 }
209}