Coverage Report

Created: 2026-07-21 07:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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__