/src/Simd/src/Simd/SimdWinograd.h
Line | Count | Source |
1 | | /* |
2 | | * Simd Library (http://ermig1979.github.io/Simd). |
3 | | * |
4 | | * Copyright (c) 2011-2022 Yermalayeu Ihar. |
5 | | * |
6 | | * Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | | * of this software and associated documentation files (the "Software"), to deal |
8 | | * in the Software without restriction, including without limitation the rights |
9 | | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
10 | | * copies of the Software, and to permit persons to whom the Software is |
11 | | * furnished to do so, subject to the following conditions: |
12 | | * |
13 | | * The above copyright notice and this permission notice shall be included in |
14 | | * all copies or substantial portions of the Software. |
15 | | * |
16 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
19 | | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 | | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
21 | | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
22 | | * SOFTWARE. |
23 | | */ |
24 | | #ifndef __SimdWinograd_h__ |
25 | | #define __SimdWinograd_h__ |
26 | | |
27 | | #include "Simd/SimdMath.h" |
28 | | #include "Simd/SimdLoad.h" |
29 | | |
30 | | namespace Simd |
31 | | { |
32 | | enum PadType |
33 | | { |
34 | | PadNose1, |
35 | | PadNone, |
36 | | PadTail1, |
37 | | PadTail2, |
38 | | }; |
39 | | |
40 | | namespace Base |
41 | | { |
42 | | SIMD_INLINE void WinogradKernel1x3Block1x4SetFilter1n(const float* src, float* dst, size_t stride) |
43 | 0 | { |
44 | 0 | const float r4 = float(1.0f / 4.0f); |
45 | 0 | const float r6 = float(1.0f / 6.0f); |
46 | 0 | const float r12 = float(1.0f / 12.0f); |
47 | 0 | const float r24 = float(1.0f / 24.0f); |
48 | |
|
49 | 0 | dst[stride * 0] = r4 * src[0]; |
50 | 0 | dst[stride * 1] = -r6 * (src[0] + src[1] + src[2]); |
51 | 0 | dst[stride * 2] = -r6 * (src[0] - src[1] + src[2]); |
52 | 0 | dst[stride * 3] = r24 * src[0] + r12 * src[1] + r6 * src[2]; |
53 | 0 | dst[stride * 4] = r24 * src[0] - r12 * src[1] + r6 * src[2]; |
54 | 0 | dst[stride * 5] = src[2]; |
55 | 0 | } |
56 | | |
57 | | SIMD_INLINE void WinogradKernel1x3Block1x4SetFilter1t(const float* src, float* dst, size_t stride) |
58 | 0 | { |
59 | 0 | float _src[3]; |
60 | 0 | _src[0] = src[0 * stride]; |
61 | 0 | _src[1] = src[1 * stride]; |
62 | 0 | _src[2] = src[2 * stride]; |
63 | 0 | WinogradKernel1x3Block1x4SetFilter1n(_src, dst, stride); |
64 | 0 | } |
65 | | |
66 | | //----------------------------------------------------------------------- |
67 | | |
68 | | SIMD_INLINE void WinogradKernel1x5Block1x4SetFilter1n(const float* src, float* dst, size_t stride) |
69 | 0 | { |
70 | 0 | const float r36 = float(1.0f / 36.0f); |
71 | 0 | const float r48 = float(1.0f / 48.0f); |
72 | 0 | const float r120 = float(1.0f / 120.0f); |
73 | 0 | const float r720 = float(1.0f / 720.0f); |
74 | |
|
75 | 0 | dst[stride * 0] = r36 * src[0]; |
76 | 0 | dst[stride * 1] = r48 * (src[0] + src[1] + src[2] + src[3] + src[4]); |
77 | 0 | dst[stride * 2] = r48 * (src[0] - src[1] + src[2] - src[3] + src[4]); |
78 | 0 | dst[stride * 3] = -r120 * (src[0] + 2 * src[1] + 4 * src[2] + 8 * src[3] + 16 * src[4]); |
79 | 0 | dst[stride * 4] = -r120 * (src[0] - 2 * src[1] + 4 * src[2] - 8 * src[3] + 16 * src[4]); |
80 | 0 | dst[stride * 5] = r720 * (src[0] + 3 * src[1] + 9 * src[2] + 27 * src[3] + 81 * src[4]); |
81 | 0 | dst[stride * 6] = r720 * (src[0] - 3 * src[1] + 9 * src[2] - 27 * src[3] + 81 * src[4]); |
82 | 0 | dst[stride * 7] = src[4]; |
83 | 0 | } |
84 | | |
85 | | SIMD_INLINE void WinogradKernel1x5Block1x4SetFilter1t(const float* src, float* dst, size_t stride) |
86 | 0 | { |
87 | 0 | float _src[5]; |
88 | 0 | _src[0] = src[0 * stride]; |
89 | 0 | _src[1] = src[1 * stride]; |
90 | 0 | _src[2] = src[2 * stride]; |
91 | 0 | _src[3] = src[3 * stride]; |
92 | 0 | _src[4] = src[4 * stride]; |
93 | 0 | WinogradKernel1x5Block1x4SetFilter1n(_src, dst, stride); |
94 | 0 | } |
95 | | |
96 | | //----------------------------------------------------------------------- |
97 | | |
98 | | SIMD_INLINE void WinogradKernel2x2Block2x2SetFilter1n(const float* src, float* dst, size_t stride) |
99 | 0 | { |
100 | 0 | dst[0 * stride] = src[0]; |
101 | 0 | dst[1 * stride] = src[0] + src[1]; |
102 | 0 | dst[2 * stride] = src[1]; |
103 | 0 | dst[3 * stride] = src[0] + src[2]; |
104 | 0 | dst[4 * stride] = src[0] + src[1] + src[2] + src[3]; |
105 | 0 | dst[5 * stride] = src[1] + src[3]; |
106 | 0 | dst[6 * stride] = src[2]; |
107 | 0 | dst[7 * stride] = src[2] + src[3]; |
108 | 0 | dst[8 * stride] = src[3]; |
109 | 0 | } |
110 | | |
111 | | SIMD_INLINE void WinogradKernel2x2Block2x2SetFilter1t(const float* src, float* dst, size_t stride) |
112 | 0 | { |
113 | 0 | float src0 = src[0 * stride]; |
114 | 0 | float src1 = src[1 * stride]; |
115 | 0 | float src2 = src[2 * stride]; |
116 | 0 | float src3 = src[3 * stride]; |
117 | 0 | dst[0 * stride] = src0; |
118 | 0 | dst[1 * stride] = src0 + src1; |
119 | 0 | dst[2 * stride] = src1; |
120 | 0 | dst[3 * stride] = src0 + src2; |
121 | 0 | dst[4 * stride] = src0 + src1 + src2 + src3; |
122 | 0 | dst[5 * stride] = src1 + src3; |
123 | 0 | dst[6 * stride] = src2; |
124 | 0 | dst[7 * stride] = src2 + src3; |
125 | 0 | dst[8 * stride] = src3; |
126 | 0 | } |
127 | | |
128 | | //----------------------------------------------------------------------- |
129 | | |
130 | | SIMD_INLINE void WinogradKernel2x2Block4x4SetFilter1n(const float* src, float* dst, size_t stride) |
131 | 0 | { |
132 | 0 | const float r2 = 1.0f / 2.0f; |
133 | 0 | const float r3 = 1.0f / 3.0f; |
134 | 0 | const float r6 = 1.0f / 6.0f; |
135 | |
|
136 | 0 | float t[10]; |
137 | 0 | t[0] = r2 * src[0]; |
138 | 0 | t[1] = r2 * src[1]; |
139 | 0 | t[2] = r2 * (- src[0] - src[2]); |
140 | 0 | t[3] = r2 * (- src[1] - src[3]); |
141 | 0 | t[4] = r6 * (src[2] - src[0]); |
142 | 0 | t[5] = r6 * (src[3] - src[1]); |
143 | 0 | t[6] = r6 * src[0] + r3 * src[2]; |
144 | 0 | t[7] = r6 * src[1] + r3 * src[3]; |
145 | 0 | t[8] = src[2]; |
146 | 0 | t[9] = src[3]; |
147 | |
|
148 | 0 | dst[0 * stride] = r2 * t[0]; |
149 | 0 | dst[1 * stride] = r2 * (-t[0] - t[1]); |
150 | 0 | dst[2 * stride] = r6 * (t[1] - t[0]); |
151 | 0 | dst[3 * stride] = r6 * t[0] + r3* t[1]; |
152 | 0 | dst[4 * stride] = t[1]; |
153 | |
|
154 | 0 | dst[5 * stride] = r2 * t[2]; |
155 | 0 | dst[6 * stride] = r2 * (-t[2] - t[3]); |
156 | 0 | dst[7 * stride] = r6 * (t[3] - t[2]); |
157 | 0 | dst[8 * stride] = r6 * t[2] + r3 * t[3]; |
158 | 0 | dst[9 * stride] = t[3]; |
159 | |
|
160 | 0 | dst[10 * stride] = r2 * t[4]; |
161 | 0 | dst[11 * stride] = r2 * (-t[4] - t[5]); |
162 | 0 | dst[12 * stride] = r6 * (t[5] - t[4]); |
163 | 0 | dst[13 * stride] = r6 * t[4] + r3 * t[5]; |
164 | 0 | dst[14 * stride] = t[5]; |
165 | |
|
166 | 0 | dst[15 * stride] = r2 * t[6]; |
167 | 0 | dst[16 * stride] = r2 * (-t[6] - t[7]); |
168 | 0 | dst[17 * stride] = r6 * (t[7] - t[6]); |
169 | 0 | dst[18 * stride] = r6 * t[6] + r3 * t[7]; |
170 | 0 | dst[19 * stride] = t[7]; |
171 | |
|
172 | 0 | dst[20 * stride] = r2 * t[8]; |
173 | 0 | dst[21 * stride] = r2 * (-t[8] - t[9]); |
174 | 0 | dst[22 * stride] = r6 * (t[9] - t[8]); |
175 | 0 | dst[23 * stride] = r6 * t[8] + r3 * t[9]; |
176 | 0 | dst[24 * stride] = t[9]; |
177 | 0 | } |
178 | | |
179 | | SIMD_INLINE void WinogradKernel2x2Block4x4SetFilter1t(const float* src, float* dst, size_t stride) |
180 | 0 | { |
181 | 0 | const float r2 = 1.0f / 2.0f; |
182 | 0 | const float r3 = 1.0f / 3.0f; |
183 | 0 | const float r6 = 1.0f / 6.0f; |
184 | 0 | float src0 = src[0 * stride]; |
185 | 0 | float src1 = src[1 * stride]; |
186 | 0 | float src2 = src[2 * stride]; |
187 | 0 | float src3 = src[3 * stride]; |
188 | |
|
189 | 0 | float t[10]; |
190 | 0 | t[0] = r2 * src0; |
191 | 0 | t[1] = r2 * src1; |
192 | 0 | t[2] = r2 * (-src0 - src2); |
193 | 0 | t[3] = r2 * (-src1 - src3); |
194 | 0 | t[4] = r6 * (src2 - src0); |
195 | 0 | t[5] = r6 * (src3 - src1); |
196 | 0 | t[6] = r6 * src0 + r3 * src2; |
197 | 0 | t[7] = r6 * src1 + r3 * src3; |
198 | 0 | t[8] = src2; |
199 | 0 | t[9] = src3; |
200 | |
|
201 | 0 | dst[0 * stride] = r2 * t[0]; |
202 | 0 | dst[1 * stride] = r2 * (-t[0] - t[1]); |
203 | 0 | dst[2 * stride] = r6 * (t[1] - t[0]); |
204 | 0 | dst[3 * stride] = r6 * t[0] + r3 * t[1]; |
205 | 0 | dst[4 * stride] = t[1]; |
206 | |
|
207 | 0 | dst[5 * stride] = r2 * t[2]; |
208 | 0 | dst[6 * stride] = r2 * (-t[2] - t[3]); |
209 | 0 | dst[7 * stride] = r6 * (t[3] - t[2]); |
210 | 0 | dst[8 * stride] = r6 * t[2] + r3 * t[3]; |
211 | 0 | dst[9 * stride] = t[3]; |
212 | |
|
213 | 0 | dst[10 * stride] = r2 * t[4]; |
214 | 0 | dst[11 * stride] = r2 * (-t[4] - t[5]); |
215 | 0 | dst[12 * stride] = r6 * (t[5] - t[4]); |
216 | 0 | dst[13 * stride] = r6 * t[4] + r3 * t[5]; |
217 | 0 | dst[14 * stride] = t[5]; |
218 | |
|
219 | 0 | dst[15 * stride] = r2 * t[6]; |
220 | 0 | dst[16 * stride] = r2 * (-t[6] - t[7]); |
221 | 0 | dst[17 * stride] = r6 * (t[7] - t[6]); |
222 | 0 | dst[18 * stride] = r6 * t[6] + r3 * t[7]; |
223 | 0 | dst[19 * stride] = t[7]; |
224 | |
|
225 | 0 | dst[20 * stride] = r2 * t[8]; |
226 | 0 | dst[21 * stride] = r2 * (-t[8] - t[9]); |
227 | 0 | dst[22 * stride] = r6 * (t[9] - t[8]); |
228 | 0 | dst[23 * stride] = r6 * t[8] + r3 * t[9]; |
229 | 0 | dst[24 * stride] = t[9]; |
230 | 0 | } |
231 | | |
232 | | //----------------------------------------------------------------------- |
233 | | |
234 | | SIMD_INLINE void WinogradKernel3x3Block2x2SetFilter1n(const float * src, float * dst, size_t stride) |
235 | 0 | { |
236 | 0 | const float r2 = 1.0f / 2.0f; |
237 | 0 | const float r4 = 1.0f / 4.0f; |
238 | 0 | dst[0 * stride] = src[0]; |
239 | 0 | dst[1 * stride] = (src[0] + src[2] + src[1])*r2; |
240 | 0 | dst[2 * stride] = (src[0] + src[2] - src[1])*r2; |
241 | 0 | dst[3 * stride] = src[2]; |
242 | 0 | dst[4 * stride] = (src[0] + src[6] + src[3])*r2; |
243 | 0 | dst[5 * stride] = ((src[0] + src[6] + src[3]) + (src[2] + src[8] + src[5]) + (src[1] + src[7] + src[4]))*r4; |
244 | 0 | dst[6 * stride] = ((src[0] + src[6] + src[3]) + (src[2] + src[8] + src[5]) - (src[1] + src[7] + src[4]))*r4; |
245 | 0 | dst[7 * stride] = (src[2] + src[8] + src[5])*r2; |
246 | 0 | dst[8 * stride] = (src[0] + src[6] - src[3])*r2; |
247 | 0 | dst[9 * stride] = ((src[0] + src[6] - src[3]) + (src[2] + src[8] - src[5]) + (src[1] + src[7] - src[4]))*r4; |
248 | 0 | dst[10 * stride] = ((src[0] + src[6] - src[3]) + (src[2] + src[8] - src[5]) - (src[1] + src[7] - src[4]))*r4; |
249 | 0 | dst[11 * stride] = (src[2] + src[8] - src[5])*r2; |
250 | 0 | dst[12 * stride] = src[6]; |
251 | 0 | dst[13 * stride] = (src[6] + src[8] + src[7])*r2; |
252 | 0 | dst[14 * stride] = (src[6] + src[8] - src[7])*r2; |
253 | 0 | dst[15 * stride] = src[8]; |
254 | 0 | } |
255 | | |
256 | | SIMD_INLINE void WinogradKernel3x3Block2x2SetFilter1t(const float * src, float * dst, size_t stride) |
257 | 0 | { |
258 | 0 | const float r2 = 1.0f / 2.0f; |
259 | 0 | const float r4 = 1.0f / 4.0f; |
260 | 0 | float src0 = src[0 * stride]; |
261 | 0 | float src1 = src[1 * stride]; |
262 | 0 | float src2 = src[2 * stride]; |
263 | 0 | float src3 = src[3 * stride]; |
264 | 0 | float src4 = src[4 * stride]; |
265 | 0 | float src5 = src[5 * stride]; |
266 | 0 | float src6 = src[6 * stride]; |
267 | 0 | float src7 = src[7 * stride]; |
268 | 0 | float src8 = src[8 * stride]; |
269 | 0 | dst[0 * stride] = src0; |
270 | 0 | dst[1 * stride] = (src0 + src2 + src1)*r2; |
271 | 0 | dst[2 * stride] = (src0 + src2 - src1)*r2; |
272 | 0 | dst[3 * stride] = src2; |
273 | 0 | dst[4 * stride] = (src0 + src6 + src3)*r2; |
274 | 0 | dst[5 * stride] = ((src0 + src6 + src3) + (src2 + src8 + src5) + (src1 + src7 + src4))*r4; |
275 | 0 | dst[6 * stride] = ((src0 + src6 + src3) + (src2 + src8 + src5) - (src1 + src7 + src4))*r4; |
276 | 0 | dst[7 * stride] = (src2 + src8 + src5)*r2; |
277 | 0 | dst[8 * stride] = (src0 + src6 - src3)*r2; |
278 | 0 | dst[9 * stride] = ((src0 + src6 - src3) + (src2 + src8 - src5) + (src1 + src7 - src4))*r4; |
279 | 0 | dst[10 * stride] = ((src0 + src6 - src3) + (src2 + src8 - src5) - (src1 + src7 - src4))*r4; |
280 | 0 | dst[11 * stride] = (src2 + src8 - src5)*r2; |
281 | 0 | dst[12 * stride] = src6; |
282 | 0 | dst[13 * stride] = (src6 + src8 + src7)*r2; |
283 | 0 | dst[14 * stride] = (src6 + src8 - src7)*r2; |
284 | 0 | dst[15 * stride] = src8; |
285 | 0 | } |
286 | | |
287 | | //----------------------------------------------------------------------- |
288 | | |
289 | | SIMD_INLINE void WinogradKernel3x3Block3x3SetFilter1n(const float * src, float * dst, size_t stride) |
290 | 0 | { |
291 | 0 | const float r6 = float(1.0f / 6.0f); |
292 | 0 | const float r3 = float(1.0f / 3.0f); |
293 | 0 | const float r2 = float(1.0f / 2.0f); |
294 | 0 | const float f2_3 = float(2.0f / 3.0f); |
295 | 0 | float t[15]; |
296 | 0 | t[0] = r2 * src[0]; |
297 | 0 | t[1] = r2 * src[1]; |
298 | 0 | t[2] = r2 * src[2]; |
299 | 0 | t[3] = -r2 * (src[0] + src[3] + src[6]); |
300 | 0 | t[4] = -r2 * (src[1] + src[4] + src[7]); |
301 | 0 | t[5] = -r2 * (src[2] + src[5] + src[8]); |
302 | 0 | t[6] = -r6 * (src[0] - src[3] + src[6]); |
303 | 0 | t[7] = -r6 * (src[1] - src[4] + src[7]); |
304 | 0 | t[8] = -r6 * (src[2] - src[5] + src[8]); |
305 | 0 | t[9] = r6 * src[0] + r3 * src[3] + f2_3 * src[6]; |
306 | 0 | t[10] = r6 * src[1] + r3 * src[4] + f2_3 * src[7]; |
307 | 0 | t[11] = r6 * src[2] + r3 * src[5] + f2_3 * src[8]; |
308 | 0 | t[12] = src[6]; |
309 | 0 | t[13] = src[7]; |
310 | 0 | t[14] = src[8]; |
311 | |
|
312 | 0 | dst[stride * 0] = r2 * t[0]; |
313 | 0 | dst[stride * 1] = -r2 * (t[0] + t[1] + t[2]); |
314 | 0 | dst[stride * 2] = -r6 * (t[0] - t[1] + t[2]); |
315 | 0 | dst[stride * 3] = r6 * t[0] + r3 * t[1] + f2_3 * t[2]; |
316 | 0 | dst[stride * 4] = t[2]; |
317 | |
|
318 | 0 | dst[stride * 5] = r2 * t[3]; |
319 | 0 | dst[stride * 6] = -r2 * (t[3] + t[4] + t[5]); |
320 | 0 | dst[stride * 7] = -r6 * (t[3] - t[4] + t[5]); |
321 | 0 | dst[stride * 8] = r6 * t[3] + r3 * t[4] + f2_3 * t[5]; |
322 | 0 | dst[stride * 9] = t[5]; |
323 | |
|
324 | 0 | dst[stride * 10] = r2 * t[6]; |
325 | 0 | dst[stride * 11] = -r2 * (t[6] + t[7] + t[8]); |
326 | 0 | dst[stride * 12] = -r6 * (t[6] - t[7] + t[8]); |
327 | 0 | dst[stride * 13] = r6 * t[6] + r3 * t[7] + f2_3 * t[8]; |
328 | 0 | dst[stride * 14] = t[8]; |
329 | |
|
330 | 0 | dst[stride * 15] = r2 * t[9]; |
331 | 0 | dst[stride * 16] = -r2 * (t[9] + t[10] + t[11]); |
332 | 0 | dst[stride * 17] = -r6 * (t[9] - t[10] + t[11]); |
333 | 0 | dst[stride * 18] = r6 * t[9] + r3 * t[10] + f2_3 * t[11]; |
334 | 0 | dst[stride * 19] = t[11]; |
335 | |
|
336 | 0 | dst[stride * 20] = r2 * t[12]; |
337 | 0 | dst[stride * 21] = -r2 * (t[12] + t[13] + t[14]); |
338 | 0 | dst[stride * 22] = -r6 * (t[12] - t[13] + t[14]); |
339 | 0 | dst[stride * 23] = r6 * t[12] + r3 * t[13] + f2_3 * t[14]; |
340 | 0 | dst[stride * 24] = t[14]; |
341 | 0 | } |
342 | | |
343 | | SIMD_INLINE void WinogradKernel3x3Block3x3SetFilter1t(const float * src, float * dst, size_t stride) |
344 | 0 | { |
345 | 0 | const float r6 = float(1.0f / 6.0f); |
346 | 0 | const float r3 = float(1.0f / 3.0f); |
347 | 0 | const float r2 = float(1.0f / 2.0f); |
348 | 0 | const float f2_3 = float(2.0f / 3.0f); |
349 | 0 | float src0 = src[0 * stride]; |
350 | 0 | float src1 = src[1 * stride]; |
351 | 0 | float src2 = src[2 * stride]; |
352 | 0 | float src3 = src[3 * stride]; |
353 | 0 | float src4 = src[4 * stride]; |
354 | 0 | float src5 = src[5 * stride]; |
355 | 0 | float src6 = src[6 * stride]; |
356 | 0 | float src7 = src[7 * stride]; |
357 | 0 | float src8 = src[8 * stride]; |
358 | 0 | float t[15]; |
359 | |
|
360 | 0 | t[0] = r2 * src0; |
361 | 0 | t[1] = r2 * src1; |
362 | 0 | t[2] = r2 * src2; |
363 | 0 | t[3] = -r2 * (src0 + src3 + src6); |
364 | 0 | t[4] = -r2 * (src1 + src4 + src7); |
365 | 0 | t[5] = -r2 * (src2 + src5 + src8); |
366 | 0 | t[6] = -r6 * (src0 - src3 + src6); |
367 | 0 | t[7] = -r6 * (src1 - src4 + src7); |
368 | 0 | t[8] = -r6 * (src2 - src5 + src8); |
369 | 0 | t[9] = r6 * src0 + r3 * src3 + f2_3 * src6; |
370 | 0 | t[10] = r6 * src1 + r3 * src4 + f2_3 * src7; |
371 | 0 | t[11] = r6 * src2 + r3 * src5 + f2_3 * src8; |
372 | 0 | t[12] = src6; |
373 | 0 | t[13] = src7; |
374 | 0 | t[14] = src8; |
375 | |
|
376 | 0 | dst[stride * 0] = r2 * t[0]; |
377 | 0 | dst[stride * 1] = -r2 * (t[0] + t[1] + t[2]); |
378 | 0 | dst[stride * 2] = -r6 * (t[0] - t[1] + t[2]); |
379 | 0 | dst[stride * 3] = r6 * t[0] + r3 * t[1] + f2_3 * t[2]; |
380 | 0 | dst[stride * 4] = t[2]; |
381 | |
|
382 | 0 | dst[stride * 5] = r2 * t[3]; |
383 | 0 | dst[stride * 6] = -r2 * (t[3] + t[4] + t[5]); |
384 | 0 | dst[stride * 7] = -r6 * (t[3] - t[4] + t[5]); |
385 | 0 | dst[stride * 8] = r6 * t[3] + r3 * t[4] + f2_3 * t[5]; |
386 | 0 | dst[stride * 9] = t[5]; |
387 | |
|
388 | 0 | dst[stride * 10] = r2 * t[6]; |
389 | 0 | dst[stride * 11] = -r2 * (t[6] + t[7] + t[8]); |
390 | 0 | dst[stride * 12] = -r6 * (t[6] - t[7] + t[8]); |
391 | 0 | dst[stride * 13] = r6 * t[6] + r3 * t[7] + f2_3 * t[8]; |
392 | 0 | dst[stride * 14] = t[8]; |
393 | |
|
394 | 0 | dst[stride * 15] = r2 * t[9]; |
395 | 0 | dst[stride * 16] = -r2 * (t[9] + t[10] + t[11]); |
396 | 0 | dst[stride * 17] = -r6 * (t[9] - t[10] + t[11]); |
397 | 0 | dst[stride * 18] = r6 * t[9] + r3 * t[10] + f2_3 * t[11]; |
398 | 0 | dst[stride * 19] = t[11]; |
399 | |
|
400 | 0 | dst[stride * 20] = r2 * t[12]; |
401 | 0 | dst[stride * 21] = -r2 * (t[12] + t[13] + t[14]); |
402 | 0 | dst[stride * 22] = -r6 * (t[12] - t[13] + t[14]); |
403 | 0 | dst[stride * 23] = r6 * t[12] + r3 * t[13] + f2_3 * t[14]; |
404 | 0 | dst[stride * 24] = t[14]; |
405 | 0 | } |
406 | | |
407 | | //----------------------------------------------------------------------- |
408 | | |
409 | | SIMD_INLINE void WinogradKernel3x3Block4x4SetFilter1n(const float * src, float * dst, size_t stride) |
410 | 0 | { |
411 | 0 | const float r4 = float(1.0f / 4.0f); |
412 | 0 | const float r6 = float(1.0f / 6.0f); |
413 | 0 | const float r12 = float(1.0f / 12.0f); |
414 | 0 | const float r24 = float(1.0f / 24.0f); |
415 | 0 | float t[18]; |
416 | 0 | t[0] = r4 * src[0]; |
417 | 0 | t[1] = r4 * src[1]; |
418 | 0 | t[2] = r4 * src[2]; |
419 | 0 | t[3] = -r6 * (src[0] + src[3] + src[6]); |
420 | 0 | t[4] = -r6 * (src[1] + src[4] + src[7]); |
421 | 0 | t[5] = -r6 * (src[2] + src[5] + src[8]); |
422 | 0 | t[6] = -r6 * (src[0] - src[3] + src[6]); |
423 | 0 | t[7] = -r6 * (src[1] - src[4] + src[7]); |
424 | 0 | t[8] = -r6 * (src[2] - src[5] + src[8]); |
425 | 0 | t[9] = r24 * src[0] + r12 * src[3] + r6 * src[6]; |
426 | 0 | t[10] = r24 * src[1] + r12 * src[4] + r6 * src[7]; |
427 | 0 | t[11] = r24 * src[2] + r12 * src[5] + r6 * src[8]; |
428 | 0 | t[12] = r24 * src[0] - r12 * src[3] + r6 * src[6]; |
429 | 0 | t[13] = r24 * src[1] - r12 * src[4] + r6 * src[7]; |
430 | 0 | t[14] = r24 * src[2] - r12 * src[5] + r6 * src[8]; |
431 | 0 | t[15] = src[6]; |
432 | 0 | t[16] = src[7]; |
433 | 0 | t[17] = src[8]; |
434 | |
|
435 | 0 | dst[stride*0] = r4 * t[0]; |
436 | 0 | dst[stride*1] = -r6 * (t[0] + t[1] + t[2]); |
437 | 0 | dst[stride*2] = -r6 * (t[0] - t[1] + t[2]); |
438 | 0 | dst[stride*3] = r24 * t[0] + r12 * t[1] + r6 * t[2]; |
439 | 0 | dst[stride*4] = r24 * t[0] - r12 * t[1] + r6 * t[2]; |
440 | 0 | dst[stride*5] = t[2]; |
441 | |
|
442 | 0 | dst[stride*6] = r4 * t[3]; |
443 | 0 | dst[stride*7] = -r6 * (t[3] + t[4] + t[5]); |
444 | 0 | dst[stride*8] = -r6 * (t[3] - t[4] + t[5]); |
445 | 0 | dst[stride*9] = r24 * t[3] + r12 * t[4] + r6 * t[5]; |
446 | 0 | dst[stride*10] = r24 * t[3] - r12 * t[4] + r6 * t[5]; |
447 | 0 | dst[stride*11] = t[5]; |
448 | |
|
449 | 0 | dst[stride*12] = r4 * t[6]; |
450 | 0 | dst[stride*13] = -r6 * (t[6] + t[7] + t[8]); |
451 | 0 | dst[stride*14] = -r6 * (t[6] - t[7] + t[8]); |
452 | 0 | dst[stride*15] = r24 * t[6] + r12 * t[7] + r6 * t[8]; |
453 | 0 | dst[stride*16] = r24 * t[6] - r12 * t[7] + r6 * t[8]; |
454 | 0 | dst[stride*17] = t[8]; |
455 | |
|
456 | 0 | dst[stride*18] = r4 * t[9]; |
457 | 0 | dst[stride*19] = -r6 * (t[9] + t[10] + t[11]); |
458 | 0 | dst[stride*20] = -r6 * (t[9] - t[10] + t[11]); |
459 | 0 | dst[stride*21] = r24 * t[9] + r12 * t[10] + r6 * t[11]; |
460 | 0 | dst[stride*22] = r24 * t[9] - r12 * t[10] + r6 * t[11]; |
461 | 0 | dst[stride*23] = t[11]; |
462 | |
|
463 | 0 | dst[stride*24] = r4 * t[12]; |
464 | 0 | dst[stride*25] = -r6 * (t[12] + t[13] + t[14]); |
465 | 0 | dst[stride*26] = -r6 * (t[12] - t[13] + t[14]); |
466 | 0 | dst[stride*27] = r24 * t[12] + r12 * t[13] + r6 * t[14]; |
467 | 0 | dst[stride*28] = r24 * t[12] - r12 * t[13] + r6 * t[14]; |
468 | 0 | dst[stride*29] = t[14]; |
469 | |
|
470 | 0 | dst[stride*30] = r4 * t[15]; |
471 | 0 | dst[stride*31] = -r6 * (t[15] + t[16] + t[17]); |
472 | 0 | dst[stride*32] = -r6 * (t[15] - t[16] + t[17]); |
473 | 0 | dst[stride*33] = r24 * t[15] + r12 * t[16] + r6 * t[17]; |
474 | 0 | dst[stride*34] = r24 * t[15] - r12 * t[16] + r6 * t[17]; |
475 | 0 | dst[stride*35] = t[17]; |
476 | 0 | } |
477 | | |
478 | | SIMD_INLINE void WinogradKernel3x3Block4x4SetFilter1t(const float * src, float * dst, size_t stride) |
479 | 0 | { |
480 | 0 | const float r4 = float(1.0f / 4.0f); |
481 | 0 | const float r6 = float(1.0f / 6.0f); |
482 | 0 | const float r12 = float(1.0f / 12.0f); |
483 | 0 | const float r24 = float(1.0f / 24.0f); |
484 | 0 | float src0 = src[0 * stride]; |
485 | 0 | float src1 = src[1 * stride]; |
486 | 0 | float src2 = src[2 * stride]; |
487 | 0 | float src3 = src[3 * stride]; |
488 | 0 | float src4 = src[4 * stride]; |
489 | 0 | float src5 = src[5 * stride]; |
490 | 0 | float src6 = src[6 * stride]; |
491 | 0 | float src7 = src[7 * stride]; |
492 | 0 | float src8 = src[8 * stride]; |
493 | 0 | float t[18]; |
494 | 0 | t[0] = r4 * src0; |
495 | 0 | t[1] = r4 * src1; |
496 | 0 | t[2] = r4 * src2; |
497 | 0 | t[3] = -r6 * (src0 + src3 + src6); |
498 | 0 | t[4] = -r6 * (src1 + src4 + src7); |
499 | 0 | t[5] = -r6 * (src2 + src5 + src8); |
500 | 0 | t[6] = -r6 * (src0 - src3 + src6); |
501 | 0 | t[7] = -r6 * (src1 - src4 + src7); |
502 | 0 | t[8] = -r6 * (src2 - src5 + src8); |
503 | 0 | t[9] = r24 * src0 + r12 * src3 + r6 * src6; |
504 | 0 | t[10] = r24 * src1 + r12 * src4 + r6 * src7; |
505 | 0 | t[11] = r24 * src2 + r12 * src5 + r6 * src8; |
506 | 0 | t[12] = r24 * src0 - r12 * src3 + r6 * src6; |
507 | 0 | t[13] = r24 * src1 - r12 * src4 + r6 * src7; |
508 | 0 | t[14] = r24 * src2 - r12 * src5 + r6 * src8; |
509 | 0 | t[15] = src6; |
510 | 0 | t[16] = src7; |
511 | 0 | t[17] = src8; |
512 | |
|
513 | 0 | dst[stride * 0] = r4 * t[0]; |
514 | 0 | dst[stride * 1] = -r6 * (t[0] + t[1] + t[2]); |
515 | 0 | dst[stride * 2] = -r6 * (t[0] - t[1] + t[2]); |
516 | 0 | dst[stride * 3] = r24 * t[0] + r12 * t[1] + r6 * t[2]; |
517 | 0 | dst[stride * 4] = r24 * t[0] - r12 * t[1] + r6 * t[2]; |
518 | 0 | dst[stride * 5] = t[2]; |
519 | |
|
520 | 0 | dst[stride * 6] = r4 * t[3]; |
521 | 0 | dst[stride * 7] = -r6 * (t[3] + t[4] + t[5]); |
522 | 0 | dst[stride * 8] = -r6 * (t[3] - t[4] + t[5]); |
523 | 0 | dst[stride * 9] = r24 * t[3] + r12 * t[4] + r6 * t[5]; |
524 | 0 | dst[stride * 10] = r24 * t[3] - r12 * t[4] + r6 * t[5]; |
525 | 0 | dst[stride * 11] = t[5]; |
526 | |
|
527 | 0 | dst[stride * 12] = r4 * t[6]; |
528 | 0 | dst[stride * 13] = -r6 * (t[6] + t[7] + t[8]); |
529 | 0 | dst[stride * 14] = -r6 * (t[6] - t[7] + t[8]); |
530 | 0 | dst[stride * 15] = r24 * t[6] + r12 * t[7] + r6 * t[8]; |
531 | 0 | dst[stride * 16] = r24 * t[6] - r12 * t[7] + r6 * t[8]; |
532 | 0 | dst[stride * 17] = t[8]; |
533 | |
|
534 | 0 | dst[stride * 18] = r4 * t[9]; |
535 | 0 | dst[stride * 19] = -r6 * (t[9] + t[10] + t[11]); |
536 | 0 | dst[stride * 20] = -r6 * (t[9] - t[10] + t[11]); |
537 | 0 | dst[stride * 21] = r24 * t[9] + r12 * t[10] + r6 * t[11]; |
538 | 0 | dst[stride * 22] = r24 * t[9] - r12 * t[10] + r6 * t[11]; |
539 | 0 | dst[stride * 23] = t[11]; |
540 | |
|
541 | 0 | dst[stride * 24] = r4 * t[12]; |
542 | 0 | dst[stride * 25] = -r6 * (t[12] + t[13] + t[14]); |
543 | 0 | dst[stride * 26] = -r6 * (t[12] - t[13] + t[14]); |
544 | 0 | dst[stride * 27] = r24 * t[12] + r12 * t[13] + r6 * t[14]; |
545 | 0 | dst[stride * 28] = r24 * t[12] - r12 * t[13] + r6 * t[14]; |
546 | 0 | dst[stride * 29] = t[14]; |
547 | |
|
548 | 0 | dst[stride * 30] = r4 * t[15]; |
549 | 0 | dst[stride * 31] = -r6 * (t[15] + t[16] + t[17]); |
550 | 0 | dst[stride * 32] = -r6 * (t[15] - t[16] + t[17]); |
551 | 0 | dst[stride * 33] = r24 * t[15] + r12 * t[16] + r6 * t[17]; |
552 | 0 | dst[stride * 34] = r24 * t[15] - r12 * t[16] + r6 * t[17]; |
553 | 0 | dst[stride * 35] = t[17]; |
554 | 0 | } |
555 | | } |
556 | | |
557 | | #if defined(SIMD_SSE41_ENABLE) && defined(SIMD_SYNET_ENABLE) |
558 | | namespace Sse41 |
559 | | { |
560 | | SIMD_INLINE void Load4(const float* src, size_t step, __m128* dst) |
561 | 0 | { |
562 | 0 | __m128 a0 = _mm_loadu_ps(src + 0 * step); |
563 | 0 | __m128 a1 = _mm_loadu_ps(src + 1 * step); |
564 | 0 | __m128 a2 = _mm_loadu_ps(src + 2 * step); |
565 | 0 | __m128 a3 = _mm_loadu_ps(src + 3 * step); |
566 | 0 | __m128 b0 = _mm_unpacklo_ps(a0, a2); |
567 | 0 | __m128 b1 = _mm_unpackhi_ps(a0, a2); |
568 | 0 | __m128 b2 = _mm_unpacklo_ps(a1, a3); |
569 | 0 | __m128 b3 = _mm_unpackhi_ps(a1, a3); |
570 | 0 | dst[0] = _mm_unpacklo_ps(b0, b2); |
571 | 0 | dst[1] = _mm_unpackhi_ps(b0, b2); |
572 | 0 | dst[2] = _mm_unpacklo_ps(b1, b3); |
573 | 0 | dst[3] = _mm_unpackhi_ps(b1, b3); |
574 | 0 | } |
575 | | } |
576 | | #endif |
577 | | |
578 | | #if defined(SIMD_NEON_ENABLE) && defined(SIMD_SYNET_ENABLE) |
579 | | namespace Neon |
580 | | { |
581 | | SIMD_INLINE void Load4(const float* src, size_t step, float32x4_t* dst) |
582 | | { |
583 | | float32x4_t a0 = Load<false>(src + 0 * step); |
584 | | float32x4_t a1 = Load<false>(src + 1 * step); |
585 | | float32x4_t a2 = Load<false>(src + 2 * step); |
586 | | float32x4_t a3 = Load<false>(src + 3 * step); |
587 | | float32x4x2_t b0 = vzipq_f32(a0, a2); |
588 | | float32x4x2_t b1 = vzipq_f32(a1, a3); |
589 | | *(float32x4x2_t*)(dst + 0) = vzipq_f32(b0.val[0], b1.val[0]); |
590 | | *(float32x4x2_t*)(dst + 2) = vzipq_f32(b0.val[1], b1.val[1]); |
591 | | } |
592 | | } |
593 | | #endif |
594 | | } |
595 | | |
596 | | #endif//__SimdWinograd_h__ |