blob: f5730bd91529839bbce552b495923891662b57cf [file] [log] [blame]
Marat Dukhan5098c3e2019-11-07 12:01:19 -08001// Auto-generated file. Do not edit!
2// Template: src/f32-dwconv/up-psimd.c.in
3// Generator: tools/xngen
4//
5// Copyright 2019 Google LLC
6//
7// This source code is licensed under the BSD-style license found in the
8// LICENSE file in the root directory of this source tree.
9
10#include <assert.h>
11
12#include <psimd.h>
13
14#include <xnnpack/dwconv.h>
15
16
17void xnn_f32_dwconv_ukernel_up8x9__psimd_acc2(
18 size_t channels,
19 size_t output_width,
20 const float** input,
21 const float* weights,
22 float* output,
23 size_t input_stride,
24 size_t output_increment,
Marat Dukhaneb09a6b2020-04-08 17:34:32 -070025 const union xnn_f32_minmax_params params[restrict static 1])
Marat Dukhan5098c3e2019-11-07 12:01:19 -080026{
27 assert(channels != 0);
28 assert(output_width != 0);
29
30 const psimd_f32 vmax = psimd_load_splat_f32(&params->scalar.max);
31 const psimd_f32 vmin = psimd_load_splat_f32(&params->scalar.min);
32 do {
33 const float* i0 = input[0];
Marat Dukhan68660992020-02-03 13:31:12 -080034 assert(i0 != NULL);
Marat Dukhan5098c3e2019-11-07 12:01:19 -080035 const float* i1 = input[1];
Marat Dukhan68660992020-02-03 13:31:12 -080036 assert(i1 != NULL);
Marat Dukhan5098c3e2019-11-07 12:01:19 -080037 const float* i2 = input[2];
Marat Dukhan68660992020-02-03 13:31:12 -080038 assert(i2 != NULL);
Marat Dukhan5098c3e2019-11-07 12:01:19 -080039 const float* i3 = input[3];
Marat Dukhan68660992020-02-03 13:31:12 -080040 assert(i3 != NULL);
Marat Dukhan5098c3e2019-11-07 12:01:19 -080041 const float* i4 = input[4];
Marat Dukhan68660992020-02-03 13:31:12 -080042 assert(i4 != NULL);
Marat Dukhan5098c3e2019-11-07 12:01:19 -080043 const float* i5 = input[5];
Marat Dukhan68660992020-02-03 13:31:12 -080044 assert(i5 != NULL);
Marat Dukhan5098c3e2019-11-07 12:01:19 -080045 const float* i6 = input[6];
Marat Dukhan68660992020-02-03 13:31:12 -080046 assert(i6 != NULL);
Marat Dukhan5098c3e2019-11-07 12:01:19 -080047 const float* i7 = input[7];
Marat Dukhan68660992020-02-03 13:31:12 -080048 assert(i7 != NULL);
Marat Dukhan5098c3e2019-11-07 12:01:19 -080049 const float* i8 = input[8];
Marat Dukhan68660992020-02-03 13:31:12 -080050 assert(i8 != NULL);
Marat Dukhan5098c3e2019-11-07 12:01:19 -080051 input = (const float**) ((uintptr_t) input + input_stride);
52
53 size_t c = channels;
54 const float* w = weights;
55 for (; c >= 8; c -= 8) {
56 psimd_f32 vacc0123p0 = psimd_load_f32(w);
57 psimd_f32 vacc4567p0 = psimd_load_f32(w + 4);
58
59
60 const psimd_f32 vi0x0123 = psimd_load_f32(i0);
61 const psimd_f32 vi0x4567 = psimd_load_f32(i0 + 4);
62 i0 += 8;
63
64 const psimd_f32 vk0x0123 = psimd_load_f32(w + 8);
65 const psimd_f32 vk0x4567 = psimd_load_f32(w + 12);
66 vacc0123p0 = psimd_qfma_f32(vacc0123p0, vi0x0123, vk0x0123);
67 vacc4567p0 = psimd_qfma_f32(vacc4567p0, vi0x4567, vk0x4567);
68
69 const psimd_f32 vi1x0123 = psimd_load_f32(i1);
70 const psimd_f32 vi1x4567 = psimd_load_f32(i1 + 4);
71 i1 += 8;
72
73 const psimd_f32 vk1x0123 = psimd_load_f32(w + 16);
74 const psimd_f32 vk1x4567 = psimd_load_f32(w + 20);
75 psimd_f32 vacc0123p1 = psimd_mul_f32(vi1x0123, vk1x0123);
76 psimd_f32 vacc4567p1 = psimd_mul_f32(vi1x4567, vk1x4567);
77
78 const psimd_f32 vi2x0123 = psimd_load_f32(i2);
79 const psimd_f32 vi2x4567 = psimd_load_f32(i2 + 4);
80 i2 += 8;
81
82 const psimd_f32 vk2x0123 = psimd_load_f32(w + 24);
83 const psimd_f32 vk2x4567 = psimd_load_f32(w + 28);
84 vacc0123p0 = psimd_qfma_f32(vacc0123p0, vi2x0123, vk2x0123);
85 vacc4567p0 = psimd_qfma_f32(vacc4567p0, vi2x4567, vk2x4567);
86
87 const psimd_f32 vi3x0123 = psimd_load_f32(i3);
88 const psimd_f32 vi3x4567 = psimd_load_f32(i3 + 4);
89 i3 += 8;
90
91 const psimd_f32 vk3x0123 = psimd_load_f32(w + 32);
92 const psimd_f32 vk3x4567 = psimd_load_f32(w + 36);
93 vacc0123p1 = psimd_qfma_f32(vacc0123p1, vi3x0123, vk3x0123);
94 vacc4567p1 = psimd_qfma_f32(vacc4567p1, vi3x4567, vk3x4567);
95
96 const psimd_f32 vi4x0123 = psimd_load_f32(i4);
97 const psimd_f32 vi4x4567 = psimd_load_f32(i4 + 4);
98 i4 += 8;
99
100 const psimd_f32 vk4x0123 = psimd_load_f32(w + 40);
101 const psimd_f32 vk4x4567 = psimd_load_f32(w + 44);
102 vacc0123p0 = psimd_qfma_f32(vacc0123p0, vi4x0123, vk4x0123);
103 vacc4567p0 = psimd_qfma_f32(vacc4567p0, vi4x4567, vk4x4567);
104
105 const psimd_f32 vi5x0123 = psimd_load_f32(i5);
106 const psimd_f32 vi5x4567 = psimd_load_f32(i5 + 4);
107 i5 += 8;
108
109 const psimd_f32 vk5x0123 = psimd_load_f32(w + 48);
110 const psimd_f32 vk5x4567 = psimd_load_f32(w + 52);
111 vacc0123p1 = psimd_qfma_f32(vacc0123p1, vi5x0123, vk5x0123);
112 vacc4567p1 = psimd_qfma_f32(vacc4567p1, vi5x4567, vk5x4567);
113
114 const psimd_f32 vi6x0123 = psimd_load_f32(i6);
115 const psimd_f32 vi6x4567 = psimd_load_f32(i6 + 4);
116 i6 += 8;
117
118 const psimd_f32 vk6x0123 = psimd_load_f32(w + 56);
119 const psimd_f32 vk6x4567 = psimd_load_f32(w + 60);
120 vacc0123p0 = psimd_qfma_f32(vacc0123p0, vi6x0123, vk6x0123);
121 vacc4567p0 = psimd_qfma_f32(vacc4567p0, vi6x4567, vk6x4567);
122
123 const psimd_f32 vi7x0123 = psimd_load_f32(i7);
124 const psimd_f32 vi7x4567 = psimd_load_f32(i7 + 4);
125 i7 += 8;
126
127 const psimd_f32 vk7x0123 = psimd_load_f32(w + 64);
128 const psimd_f32 vk7x4567 = psimd_load_f32(w + 68);
129 vacc0123p1 = psimd_qfma_f32(vacc0123p1, vi7x0123, vk7x0123);
130 vacc4567p1 = psimd_qfma_f32(vacc4567p1, vi7x4567, vk7x4567);
131
132 const psimd_f32 vi8x0123 = psimd_load_f32(i8);
133 const psimd_f32 vi8x4567 = psimd_load_f32(i8 + 4);
134 i8 += 8;
135
136 const psimd_f32 vk8x0123 = psimd_load_f32(w + 72);
137 const psimd_f32 vk8x4567 = psimd_load_f32(w + 76);
138 vacc0123p0 = psimd_qfma_f32(vacc0123p0, vi8x0123, vk8x0123);
139 vacc4567p0 = psimd_qfma_f32(vacc4567p0, vi8x4567, vk8x4567);
140
141 w += 80;
142
143 // Add up all accumulators to vacc01234567p0
144 vacc0123p0 = psimd_add_f32(vacc0123p0, vacc0123p1);
145 vacc4567p0 = psimd_add_f32(vacc4567p0, vacc4567p1);
146
147 psimd_f32 vacc0123 = psimd_max_f32(vacc0123p0, vmin);
148 psimd_f32 vacc4567 = psimd_max_f32(vacc4567p0, vmin);
149 vacc0123 = psimd_min_f32(vacc0123, vmax);
150 vacc4567 = psimd_min_f32(vacc4567, vmax);
151
152 psimd_store_f32(output, vacc0123);
153 psimd_store_f32(output + 4, vacc4567);
154 output += 8;
155 }
156 for (; c >= 4; c -= 4) {
157 psimd_f32 vacc0123p0 = psimd_load_f32(w);
158
159 const psimd_f32 vi0x0123 = psimd_load_f32(i0);
160 i0 += 4;
161
162 const psimd_f32 vk0x0123 = psimd_load_f32(w + 8);
163 vacc0123p0 = psimd_qfma_f32(vacc0123p0, vi0x0123, vk0x0123);
164
165 const psimd_f32 vi1x0123 = psimd_load_f32(i1);
166 i1 += 4;
167
168 const psimd_f32 vk1x0123 = psimd_load_f32(w + 16);
169 psimd_f32 vacc0123p1 = psimd_mul_f32(vi1x0123, vk1x0123);
170
171 const psimd_f32 vi2x0123 = psimd_load_f32(i2);
172 i2 += 4;
173
174 const psimd_f32 vk2x0123 = psimd_load_f32(w + 24);
175 vacc0123p0 = psimd_qfma_f32(vacc0123p0, vi2x0123, vk2x0123);
176
177 const psimd_f32 vi3x0123 = psimd_load_f32(i3);
178 i3 += 4;
179
180 const psimd_f32 vk3x0123 = psimd_load_f32(w + 32);
181 vacc0123p1 = psimd_qfma_f32(vacc0123p1, vi3x0123, vk3x0123);
182
183 const psimd_f32 vi4x0123 = psimd_load_f32(i4);
184 i4 += 4;
185
186 const psimd_f32 vk4x0123 = psimd_load_f32(w + 40);
187 vacc0123p0 = psimd_qfma_f32(vacc0123p0, vi4x0123, vk4x0123);
188
189 const psimd_f32 vi5x0123 = psimd_load_f32(i5);
190 i5 += 4;
191
192 const psimd_f32 vk5x0123 = psimd_load_f32(w + 48);
193 vacc0123p1 = psimd_qfma_f32(vacc0123p1, vi5x0123, vk5x0123);
194
195 const psimd_f32 vi6x0123 = psimd_load_f32(i6);
196 i6 += 4;
197
198 const psimd_f32 vk6x0123 = psimd_load_f32(w + 56);
199 vacc0123p0 = psimd_qfma_f32(vacc0123p0, vi6x0123, vk6x0123);
200
201 const psimd_f32 vi7x0123 = psimd_load_f32(i7);
202 i7 += 4;
203
204 const psimd_f32 vk7x0123 = psimd_load_f32(w + 64);
205 vacc0123p1 = psimd_qfma_f32(vacc0123p1, vi7x0123, vk7x0123);
206
207 const psimd_f32 vi8x0123 = psimd_load_f32(i8);
208 i8 += 4;
209
210 const psimd_f32 vk8x0123 = psimd_load_f32(w + 72);
211 vacc0123p0 = psimd_qfma_f32(vacc0123p0, vi8x0123, vk8x0123);
212
213 w += 4;
214
215 // Add up all accumulators to vacc01234567p0
216 vacc0123p0 = psimd_add_f32(vacc0123p0, vacc0123p1);
217
218 psimd_f32 vacc0123 = psimd_max_f32(vacc0123p0, vmin);
219 vacc0123 = psimd_min_f32(vacc0123, vmax);
220
221 psimd_store_f32(output, vacc0123);
222 output += 4;
223 }
224 if XNN_UNLIKELY(c != 0) {
225 psimd_f32 vacc0123p0 = psimd_load_f32(w);
226
227 const psimd_f32 vi0x0123 = psimd_load_f32(i0);
228 const psimd_f32 vk0x0123 = psimd_load_f32(w + 8);
229 vacc0123p0 = psimd_qfma_f32(vacc0123p0, vi0x0123, vk0x0123);
230
231 const psimd_f32 vi1x0123 = psimd_load_f32(i1);
232 const psimd_f32 vk1x0123 = psimd_load_f32(w + 16);
233 psimd_f32 vacc0123p1 = psimd_mul_f32(vi1x0123, vk1x0123);
234
235 const psimd_f32 vi2x0123 = psimd_load_f32(i2);
236 const psimd_f32 vk2x0123 = psimd_load_f32(w + 24);
237 vacc0123p0 = psimd_qfma_f32(vacc0123p0, vi2x0123, vk2x0123);
238
239 const psimd_f32 vi3x0123 = psimd_load_f32(i3);
240 const psimd_f32 vk3x0123 = psimd_load_f32(w + 32);
241 vacc0123p1 = psimd_qfma_f32(vacc0123p1, vi3x0123, vk3x0123);
242
243 const psimd_f32 vi4x0123 = psimd_load_f32(i4);
244 const psimd_f32 vk4x0123 = psimd_load_f32(w + 40);
245 vacc0123p0 = psimd_qfma_f32(vacc0123p0, vi4x0123, vk4x0123);
246
247 const psimd_f32 vi5x0123 = psimd_load_f32(i5);
248 const psimd_f32 vk5x0123 = psimd_load_f32(w + 48);
249 vacc0123p1 = psimd_qfma_f32(vacc0123p1, vi5x0123, vk5x0123);
250
251 const psimd_f32 vi6x0123 = psimd_load_f32(i6);
252 const psimd_f32 vk6x0123 = psimd_load_f32(w + 56);
253 vacc0123p0 = psimd_qfma_f32(vacc0123p0, vi6x0123, vk6x0123);
254
255 const psimd_f32 vi7x0123 = psimd_load_f32(i7);
256 const psimd_f32 vk7x0123 = psimd_load_f32(w + 64);
257 vacc0123p1 = psimd_qfma_f32(vacc0123p1, vi7x0123, vk7x0123);
258
259 const psimd_f32 vi8x0123 = psimd_load_f32(i8);
260 const psimd_f32 vk8x0123 = psimd_load_f32(w + 72);
261 vacc0123p0 = psimd_qfma_f32(vacc0123p0, vi8x0123, vk8x0123);
262
263 // Add up all accumulators to vacc01234567p0
264 vacc0123p0 = psimd_add_f32(vacc0123p0, vacc0123p1);
265
266 psimd_f32 vacc0123 = psimd_max_f32(vacc0123p0, vmin);
267 vacc0123 = psimd_min_f32(vacc0123, vmax);
268
269 if (c & 2) {
270 psimd_store2_f32(output, vacc0123);
271 vacc0123 = psimd_concat_hi_f32(vacc0123, vacc0123);
272 output += 2;
273 }
274 if (c & 1) {
275 psimd_store1_f32(output, vacc0123);
276 output += 1;
277 }
278 }
279
280 output = (float*) ((uintptr_t) output + output_increment);
281 } while (--output_width != 0);
282}