xref: /aosp_15_r20/external/XNNPACK/test/average-pooling-nhwc.cc (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
1 // Copyright (c) Facebook, Inc. and its affiliates.
2 // All rights reserved.
3 //
4 // Copyright 2019 Google LLC
5 //
6 // This source code is licensed under the BSD-style license found in the
7 // LICENSE file in the root directory of this source tree.
8 
9 #include <gtest/gtest.h>
10 
11 #include <utility>
12 
13 #include <xnnpack/params.h>
14 
15 #include "average-pooling-operator-tester.h"
16 
SmallPoolSize(size_t max_elements)17 static std::pair<size_t, size_t> SmallPoolSize(size_t max_elements) {
18   const size_t small_side = size_t(std::floor(std::sqrt(double(max_elements))));
19   const size_t large_side = small_side + 1;
20   if (small_side * large_side < max_elements) {
21     return std::make_pair(small_side, large_side);
22   } else {
23     return std::make_pair(small_side - 1, large_side - 1);
24   }
25 }
26 
LargePoolSize(size_t min_elements)27 static std::pair<size_t, size_t> LargePoolSize(size_t min_elements) {
28   const size_t small_side = size_t(std::ceil(std::sqrt(double(min_elements))));
29   return std::make_pair(small_side, small_side + 1);
30 }
31 
32 /**************************** AVGPOOL path, unipass ****************************/
33 
TEST(AVERAGE_POOLING_NHWC_QU8,small_pool)34 TEST(AVERAGE_POOLING_NHWC_QU8, small_pool) {
35   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
36   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
37   for (size_t channels = 1; channels <= 100; channels += 15) {
38     AveragePoolingOperatorTester()
39       .input_height(pooling_size.first + 3)
40       .input_width(pooling_size.second + 2)
41       .pooling_height(pooling_size.first)
42       .pooling_width(pooling_size.second)
43       .channels(channels)
44       .TestQU8();
45     AveragePoolingOperatorTester()
46       .input_height(pooling_size.second + 3)
47       .input_width(pooling_size.first + 2)
48       .pooling_height(pooling_size.second)
49       .pooling_width(pooling_size.first)
50       .channels(channels)
51       .TestQU8();
52   }
53 }
54 
TEST(AVERAGE_POOLING_NHWC_QU8,small_pool_with_stride)55 TEST(AVERAGE_POOLING_NHWC_QU8, small_pool_with_stride) {
56   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
57   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
58   for (size_t channels = 1; channels <= 100; channels += 15) {
59     for (size_t stride_width = 1; stride_width <= 2; stride_width++) {
60       for (size_t stride_height = 1; stride_height <= 2; stride_height++) {
61         if (stride_width == 1 && stride_height == 1) {
62           continue;
63         }
64 
65         AveragePoolingOperatorTester()
66           .input_height(pooling_size.first + 3)
67           .input_width(pooling_size.second + 2)
68           .pooling_height(pooling_size.first)
69           .pooling_width(pooling_size.second)
70           .stride_height(stride_height)
71           .stride_width(stride_width)
72           .channels(channels)
73           .TestQU8();
74         AveragePoolingOperatorTester()
75           .input_height(pooling_size.second + 3)
76           .input_width(pooling_size.first + 2)
77           .pooling_height(pooling_size.second)
78           .pooling_width(pooling_size.first)
79           .stride_height(stride_height)
80           .stride_width(stride_width)
81           .channels(channels)
82           .TestQU8();
83       }
84     }
85   }
86 }
87 
TEST(AVERAGE_POOLING_NHWC_QU8,small_pool_with_width_padding)88 TEST(AVERAGE_POOLING_NHWC_QU8, small_pool_with_width_padding) {
89   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
90   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
91   for (size_t channels = 1; channels <= 100; channels += 15) {
92     for (size_t stride = 1; stride <= 2; stride++) {
93       for (size_t padding_left = 0; padding_left <= 1; padding_left++) {
94         for (size_t padding_right = 0; padding_right <= 1; padding_right++) {
95           AveragePoolingOperatorTester()
96             .input_height(pooling_size.first + 3)
97             .input_width(pooling_size.second + 2)
98             .padding_left(padding_left)
99             .padding_right(padding_right)
100             .pooling_height(pooling_size.first)
101             .pooling_width(pooling_size.second)
102             .stride(stride)
103             .channels(channels)
104             .TestQU8();
105           AveragePoolingOperatorTester()
106             .input_height(pooling_size.second + 3)
107             .input_width(pooling_size.first + 2)
108             .padding_left(padding_left)
109             .padding_right(padding_right)
110             .pooling_height(pooling_size.second)
111             .pooling_width(pooling_size.first)
112             .stride(stride)
113             .channels(channels)
114             .TestQU8();
115         }
116       }
117     }
118   }
119 }
120 
TEST(AVERAGE_POOLING_NHWC_QU8,small_pool_with_height_padding)121 TEST(AVERAGE_POOLING_NHWC_QU8, small_pool_with_height_padding) {
122   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
123   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
124   for (size_t channels = 1; channels <= 100; channels += 15) {
125     for (size_t stride = 1; stride <= 2; stride++) {
126       for (size_t padding_top = 0; padding_top <= 1; padding_top++) {
127         for (size_t padding_bottom = 0; padding_bottom <= 1; padding_bottom++) {
128           AveragePoolingOperatorTester()
129             .input_height(pooling_size.first + 3)
130             .input_width(pooling_size.second + 2)
131             .padding_top(padding_top)
132             .padding_bottom(padding_bottom)
133             .pooling_height(pooling_size.first)
134             .pooling_width(pooling_size.second)
135             .stride(stride)
136             .channels(channels)
137             .TestQU8();
138           AveragePoolingOperatorTester()
139             .input_height(pooling_size.second + 3)
140             .input_width(pooling_size.first + 2)
141             .padding_top(padding_top)
142             .padding_bottom(padding_bottom)
143             .pooling_height(pooling_size.second)
144             .pooling_width(pooling_size.first)
145             .stride(stride)
146             .channels(channels)
147             .TestQU8();
148         }
149       }
150     }
151   }
152 }
153 
TEST(AVERAGE_POOLING_NHWC_QU8,small_pool_with_tf_same_padding)154 TEST(AVERAGE_POOLING_NHWC_QU8, small_pool_with_tf_same_padding) {
155   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
156   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
157   for (size_t channels = 1; channels <= 100; channels += 15) {
158     for (size_t stride = 1; stride <= 2; stride++) {
159       for (size_t input_height = pooling_size.first + 3; input_height <= pooling_size.first + 4; input_height++) {
160         AveragePoolingOperatorTester()
161           .input_height(input_height)
162           .input_width(pooling_size.second + 2)
163           .padding_tf_same(true)
164           .pooling_height(pooling_size.first)
165           .pooling_width(pooling_size.second)
166           .stride(stride)
167           .channels(channels)
168           .TestQU8();
169       }
170       for (size_t input_width = pooling_size.second + 2; input_width <= pooling_size.second + 3; input_width++) {
171         AveragePoolingOperatorTester()
172           .input_height(pooling_size.first + 3)
173           .input_width(input_width)
174           .padding_tf_same(true)
175           .pooling_height(pooling_size.first)
176           .pooling_width(pooling_size.second)
177           .stride(stride)
178           .channels(channels)
179           .TestQU8();
180       }
181       for (size_t input_height = pooling_size.second + 3; input_height <= pooling_size.second + 4; input_height++) {
182         AveragePoolingOperatorTester()
183           .input_height(input_height)
184           .input_width(pooling_size.first + 2)
185           .padding_tf_same(true)
186           .pooling_height(pooling_size.second)
187           .pooling_width(pooling_size.first)
188           .stride(stride)
189           .channels(channels)
190           .TestQU8();
191       }
192       for (size_t input_width = pooling_size.first + 2; input_width <= pooling_size.first + 3; input_width++) {
193         AveragePoolingOperatorTester()
194           .input_height(pooling_size.second + 3)
195           .input_width(input_width)
196           .padding_tf_same(true)
197           .pooling_height(pooling_size.second)
198           .pooling_width(pooling_size.first)
199           .stride(stride)
200           .channels(channels)
201           .TestQU8();
202       }
203     }
204   }
205 }
206 
TEST(AVERAGE_POOLING_NHWC_QU8,small_pool_with_input_stride)207 TEST(AVERAGE_POOLING_NHWC_QU8, small_pool_with_input_stride) {
208   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
209   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
210   for (size_t channels = 1; channels <= 100; channels += 15) {
211     AveragePoolingOperatorTester()
212       .input_height(pooling_size.first + 3)
213       .input_width(pooling_size.second + 2)
214       .pooling_height(pooling_size.first)
215       .pooling_width(pooling_size.second)
216       .channels(channels)
217       .input_pixel_stride(2 * channels + 3)
218       .TestQU8();
219     AveragePoolingOperatorTester()
220       .input_height(pooling_size.second + 3)
221       .input_width(pooling_size.first + 2)
222       .pooling_height(pooling_size.second)
223       .pooling_width(pooling_size.first)
224       .channels(channels)
225       .input_pixel_stride(2 * channels + 3)
226       .TestQU8();
227   }
228 }
229 
TEST(AVERAGE_POOLING_NHWC_QU8,small_pool_with_output_stride)230 TEST(AVERAGE_POOLING_NHWC_QU8, small_pool_with_output_stride) {
231   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
232   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
233   for (size_t channels = 1; channels <= 100; channels += 15) {
234     AveragePoolingOperatorTester()
235       .input_height(pooling_size.first + 3)
236       .input_width(pooling_size.second + 2)
237       .pooling_height(pooling_size.first)
238       .pooling_width(pooling_size.second)
239       .channels(channels)
240       .output_pixel_stride(2 * channels + 3)
241       .TestQU8();
242     AveragePoolingOperatorTester()
243       .input_height(pooling_size.second + 3)
244       .input_width(pooling_size.first + 2)
245       .pooling_height(pooling_size.second)
246       .pooling_width(pooling_size.first)
247       .channels(channels)
248       .output_pixel_stride(2 * channels + 3)
249       .TestQU8();
250   }
251 }
252 
TEST(AVERAGE_POOLING_NHWC_QU8,small_pool_with_input_scale)253 TEST(AVERAGE_POOLING_NHWC_QU8, small_pool_with_input_scale) {
254   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
255   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
256   for (size_t channels = 1; channels <= 100; channels += 15) {
257     for (float input_scale = 0.01f; input_scale < 100.0f; input_scale *= 3.14159265f) {
258       AveragePoolingOperatorTester()
259         .input_height(pooling_size.first + 3)
260         .input_width(pooling_size.second + 2)
261         .pooling_height(pooling_size.first)
262         .pooling_width(pooling_size.second)
263         .channels(channels)
264         .input_scale(input_scale)
265         .TestQU8();
266       AveragePoolingOperatorTester()
267         .input_height(pooling_size.second + 3)
268         .input_width(pooling_size.first + 2)
269         .pooling_height(pooling_size.second)
270         .pooling_width(pooling_size.first)
271         .channels(channels)
272         .input_scale(input_scale)
273         .TestQU8();
274     }
275   }
276 }
277 
TEST(AVERAGE_POOLING_NHWC_QU8,small_pool_with_input_zero_point)278 TEST(AVERAGE_POOLING_NHWC_QU8, small_pool_with_input_zero_point) {
279   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
280   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
281   for (size_t channels = 1; channels <= 100; channels += 15) {
282     for (int32_t input_zero_point = 0; input_zero_point <= 255; input_zero_point += 51) {
283       AveragePoolingOperatorTester()
284         .input_height(pooling_size.first + 3)
285         .input_width(pooling_size.second + 2)
286         .pooling_height(pooling_size.first)
287         .pooling_width(pooling_size.second)
288         .channels(channels)
289         .input_zero_point(uint8_t(input_zero_point))
290         .TestQU8();
291       AveragePoolingOperatorTester()
292         .input_height(pooling_size.second + 3)
293         .input_width(pooling_size.first + 2)
294         .pooling_height(pooling_size.second)
295         .pooling_width(pooling_size.first)
296         .channels(channels)
297         .input_zero_point(uint8_t(input_zero_point))
298         .TestQU8();
299     }
300   }
301 }
302 
TEST(AVERAGE_POOLING_NHWC_QU8,small_pool_with_output_scale)303 TEST(AVERAGE_POOLING_NHWC_QU8, small_pool_with_output_scale) {
304   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
305   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
306   for (size_t channels = 1; channels <= 100; channels += 15) {
307     for (float output_scale = 0.01f; output_scale < 100.0f; output_scale *= 3.14159265f) {
308       AveragePoolingOperatorTester()
309         .input_height(pooling_size.first + 3)
310         .input_width(pooling_size.second + 2)
311         .pooling_height(pooling_size.first)
312         .pooling_width(pooling_size.second)
313         .channels(channels)
314         .output_scale(output_scale)
315         .TestQU8();
316       AveragePoolingOperatorTester()
317         .input_height(pooling_size.second + 3)
318         .input_width(pooling_size.first + 2)
319         .pooling_height(pooling_size.second)
320         .pooling_width(pooling_size.first)
321         .channels(channels)
322         .output_scale(output_scale)
323         .TestQU8();
324     }
325   }
326 }
327 
TEST(AVERAGE_POOLING_NHWC_QU8,small_pool_with_output_zero_point)328 TEST(AVERAGE_POOLING_NHWC_QU8, small_pool_with_output_zero_point) {
329   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
330   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
331   for (size_t channels = 1; channels <= 100; channels += 15) {
332     for (int32_t output_zero_point = 0; output_zero_point <= 255; output_zero_point += 51) {
333       AveragePoolingOperatorTester()
334         .input_height(pooling_size.first + 3)
335         .input_width(pooling_size.second + 2)
336         .pooling_height(pooling_size.first)
337         .pooling_width(pooling_size.second)
338         .channels(channels)
339         .output_zero_point(uint8_t(output_zero_point))
340         .TestQU8();
341       AveragePoolingOperatorTester()
342         .input_height(pooling_size.second + 3)
343         .input_width(pooling_size.first + 2)
344         .pooling_height(pooling_size.second)
345         .pooling_width(pooling_size.first)
346         .channels(channels)
347         .output_zero_point(uint8_t(output_zero_point))
348         .TestQU8();
349     }
350   }
351 }
352 
TEST(AVERAGE_POOLING_NHWC_QU8,small_pool_with_qmin)353 TEST(AVERAGE_POOLING_NHWC_QU8, small_pool_with_qmin) {
354   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
355   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
356   for (size_t channels = 1; channels <= 100; channels += 15) {
357     AveragePoolingOperatorTester()
358       .input_height(pooling_size.first + 3)
359       .input_width(pooling_size.second + 2)
360       .pooling_height(pooling_size.first)
361       .pooling_width(pooling_size.second)
362       .channels(channels)
363       .qmin(128)
364       .TestQU8();
365     AveragePoolingOperatorTester()
366       .input_height(pooling_size.second + 3)
367       .input_width(pooling_size.first + 2)
368       .pooling_height(pooling_size.second)
369       .pooling_width(pooling_size.first)
370       .channels(channels)
371       .qmin(128)
372       .TestQU8();
373   }
374 }
375 
TEST(AVERAGE_POOLING_NHWC_QU8,small_pool_with_qmax)376 TEST(AVERAGE_POOLING_NHWC_QU8, small_pool_with_qmax) {
377   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
378   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
379   for (size_t channels = 1; channels <= 100; channels += 15) {
380     AveragePoolingOperatorTester()
381       .input_height(pooling_size.first + 3)
382       .input_width(pooling_size.second + 2)
383       .pooling_height(pooling_size.first)
384       .pooling_width(pooling_size.second)
385       .channels(channels)
386       .qmax(128)
387       .TestQU8();
388     AveragePoolingOperatorTester()
389       .input_height(pooling_size.second + 3)
390       .input_width(pooling_size.first + 2)
391       .pooling_height(pooling_size.second)
392       .pooling_width(pooling_size.first)
393       .channels(channels)
394       .qmax(128)
395       .TestQU8();
396   }
397 }
398 
399 /**************************** AVGPOOL path, unipass, batched ****************************/
400 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_pool)401 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_pool) {
402   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
403   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
404   for (size_t channels = 1; channels <= 100; channels += 15) {
405     AveragePoolingOperatorTester()
406       .batch_size(2)
407       .input_height(pooling_size.first + 3)
408       .input_width(pooling_size.second + 2)
409       .pooling_height(pooling_size.first)
410       .pooling_width(pooling_size.second)
411       .channels(channels)
412       .TestQU8();
413     AveragePoolingOperatorTester()
414       .batch_size(2)
415       .input_height(pooling_size.second + 3)
416       .input_width(pooling_size.first + 2)
417       .pooling_height(pooling_size.second)
418       .pooling_width(pooling_size.first)
419       .channels(channels)
420       .TestQU8();
421   }
422 }
423 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_pool_with_stride)424 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_pool_with_stride) {
425   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
426   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
427   for (size_t channels = 1; channels <= 100; channels += 15) {
428     for (size_t stride_width = 1; stride_width <= 2; stride_width++) {
429       for (size_t stride_height = 1; stride_height <= 2; stride_height++) {
430         if (stride_width == 1 && stride_height == 1) {
431           continue;
432         }
433 
434         AveragePoolingOperatorTester()
435           .batch_size(2)
436           .input_height(pooling_size.first + 3)
437           .input_width(pooling_size.second + 2)
438           .pooling_height(pooling_size.first)
439           .pooling_width(pooling_size.second)
440           .stride_height(stride_height)
441           .stride_width(stride_width)
442           .channels(channels)
443           .TestQU8();
444         AveragePoolingOperatorTester()
445           .batch_size(2)
446           .input_height(pooling_size.second + 3)
447           .input_width(pooling_size.first + 2)
448           .pooling_height(pooling_size.second)
449           .pooling_width(pooling_size.first)
450           .stride_height(stride_height)
451           .stride_width(stride_width)
452           .channels(channels)
453           .TestQU8();
454       }
455     }
456   }
457 }
458 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_pool_with_width_padding)459 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_pool_with_width_padding) {
460   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
461   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
462   for (size_t channels = 1; channels <= 100; channels += 15) {
463     for (size_t stride = 1; stride <= 2; stride++) {
464       for (size_t padding_left = 0; padding_left <= 1; padding_left++) {
465         for (size_t padding_right = 0; padding_right <= 1; padding_right++) {
466           AveragePoolingOperatorTester()
467             .batch_size(2)
468             .input_height(pooling_size.first + 3)
469             .input_width(pooling_size.second + 2)
470             .padding_left(padding_left)
471             .padding_right(padding_right)
472             .pooling_height(pooling_size.first)
473             .pooling_width(pooling_size.second)
474             .stride(stride)
475             .channels(channels)
476             .TestQU8();
477           AveragePoolingOperatorTester()
478             .batch_size(2)
479             .input_height(pooling_size.second + 3)
480             .input_width(pooling_size.first + 2)
481             .padding_left(padding_left)
482             .padding_right(padding_right)
483             .pooling_height(pooling_size.second)
484             .pooling_width(pooling_size.first)
485             .stride(stride)
486             .channels(channels)
487             .TestQU8();
488         }
489       }
490     }
491   }
492 }
493 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_pool_with_height_padding)494 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_pool_with_height_padding) {
495   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
496   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
497   for (size_t channels = 1; channels <= 100; channels += 15) {
498     for (size_t stride = 1; stride <= 2; stride++) {
499       for (size_t padding_top = 0; padding_top <= 1; padding_top++) {
500         for (size_t padding_bottom = 0; padding_bottom <= 1; padding_bottom++) {
501           AveragePoolingOperatorTester()
502             .batch_size(2)
503             .input_height(pooling_size.first + 3)
504             .input_width(pooling_size.second + 2)
505             .padding_top(padding_top)
506             .padding_bottom(padding_bottom)
507             .pooling_height(pooling_size.first)
508             .pooling_width(pooling_size.second)
509             .stride(stride)
510             .channels(channels)
511             .TestQU8();
512           AveragePoolingOperatorTester()
513             .batch_size(2)
514             .input_height(pooling_size.second + 3)
515             .input_width(pooling_size.first + 2)
516             .padding_top(padding_top)
517             .padding_bottom(padding_bottom)
518             .pooling_height(pooling_size.second)
519             .pooling_width(pooling_size.first)
520             .stride(stride)
521             .channels(channels)
522             .TestQU8();
523         }
524       }
525     }
526   }
527 }
528 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_pool_with_tf_same_padding)529 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_pool_with_tf_same_padding) {
530   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
531   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
532   for (size_t channels = 1; channels <= 100; channels += 15) {
533     for (size_t stride = 1; stride <= 2; stride++) {
534       for (size_t input_height = pooling_size.first + 3; input_height <= pooling_size.first + 4; input_height++) {
535         AveragePoolingOperatorTester()
536           .batch_size(2)
537           .input_height(input_height)
538           .input_width(pooling_size.second + 2)
539           .padding_tf_same(true)
540           .pooling_height(pooling_size.first)
541           .pooling_width(pooling_size.second)
542           .stride(stride)
543           .channels(channels)
544           .TestQU8();
545       }
546       for (size_t input_width = pooling_size.second + 2; input_width <= pooling_size.second + 3; input_width++) {
547         AveragePoolingOperatorTester()
548           .batch_size(2)
549           .input_height(pooling_size.first + 3)
550           .input_width(input_width)
551           .padding_tf_same(true)
552           .pooling_height(pooling_size.first)
553           .pooling_width(pooling_size.second)
554           .stride(stride)
555           .channels(channels)
556           .TestQU8();
557       }
558       for (size_t input_height = pooling_size.second + 3; input_height <= pooling_size.second + 4; input_height++) {
559         AveragePoolingOperatorTester()
560           .batch_size(2)
561           .input_height(input_height)
562           .input_width(pooling_size.first + 2)
563           .padding_tf_same(true)
564           .pooling_height(pooling_size.second)
565           .pooling_width(pooling_size.first)
566           .stride(stride)
567           .channels(channels)
568           .TestQU8();
569       }
570       for (size_t input_width = pooling_size.first + 2; input_width <= pooling_size.first + 3; input_width++) {
571         AveragePoolingOperatorTester()
572           .batch_size(2)
573           .input_height(pooling_size.second + 3)
574           .input_width(input_width)
575           .padding_tf_same(true)
576           .pooling_height(pooling_size.second)
577           .pooling_width(pooling_size.first)
578           .stride(stride)
579           .channels(channels)
580           .TestQU8();
581       }
582     }
583   }
584 }
585 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_pool_with_input_stride)586 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_pool_with_input_stride) {
587   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
588   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
589   for (size_t channels = 1; channels <= 100; channels += 15) {
590     AveragePoolingOperatorTester()
591       .batch_size(2)
592       .input_height(pooling_size.first + 3)
593       .input_width(pooling_size.second + 2)
594       .pooling_height(pooling_size.first)
595       .pooling_width(pooling_size.second)
596       .channels(channels)
597       .input_pixel_stride(2 * channels + 3)
598       .TestQU8();
599     AveragePoolingOperatorTester()
600       .batch_size(2)
601       .input_height(pooling_size.second + 3)
602       .input_width(pooling_size.first + 2)
603       .pooling_height(pooling_size.second)
604       .pooling_width(pooling_size.first)
605       .channels(channels)
606       .input_pixel_stride(2 * channels + 3)
607       .TestQU8();
608   }
609 }
610 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_pool_with_output_stride)611 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_pool_with_output_stride) {
612   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
613   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
614   for (size_t channels = 1; channels <= 100; channels += 15) {
615     AveragePoolingOperatorTester()
616       .batch_size(2)
617       .input_height(pooling_size.first + 3)
618       .input_width(pooling_size.second + 2)
619       .pooling_height(pooling_size.first)
620       .pooling_width(pooling_size.second)
621       .channels(channels)
622       .output_pixel_stride(2 * channels + 3)
623       .TestQU8();
624     AveragePoolingOperatorTester()
625       .batch_size(2)
626       .input_height(pooling_size.second + 3)
627       .input_width(pooling_size.first + 2)
628       .pooling_height(pooling_size.second)
629       .pooling_width(pooling_size.first)
630       .channels(channels)
631       .output_pixel_stride(2 * channels + 3)
632       .TestQU8();
633   }
634 }
635 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_pool_with_input_scale)636 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_pool_with_input_scale) {
637   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
638   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
639   for (size_t channels = 1; channels <= 100; channels += 15) {
640     for (float input_scale = 0.01f; input_scale < 100.0f; input_scale *= 3.14159265f) {
641       AveragePoolingOperatorTester()
642         .batch_size(2)
643         .input_height(pooling_size.first + 3)
644         .input_width(pooling_size.second + 2)
645         .pooling_height(pooling_size.first)
646         .pooling_width(pooling_size.second)
647         .channels(channels)
648         .input_scale(input_scale)
649         .TestQU8();
650       AveragePoolingOperatorTester()
651         .batch_size(2)
652         .input_height(pooling_size.second + 3)
653         .input_width(pooling_size.first + 2)
654         .pooling_height(pooling_size.second)
655         .pooling_width(pooling_size.first)
656         .channels(channels)
657         .input_scale(input_scale)
658         .TestQU8();
659     }
660   }
661 }
662 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_pool_with_input_zero_point)663 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_pool_with_input_zero_point) {
664   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
665   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
666   for (size_t channels = 1; channels <= 100; channels += 15) {
667     for (int32_t input_zero_point = 0; input_zero_point <= 255; input_zero_point += 51) {
668       AveragePoolingOperatorTester()
669         .batch_size(2)
670         .input_height(pooling_size.first + 3)
671         .input_width(pooling_size.second + 2)
672         .pooling_height(pooling_size.first)
673         .pooling_width(pooling_size.second)
674         .channels(channels)
675         .input_zero_point(uint8_t(input_zero_point))
676         .TestQU8();
677       AveragePoolingOperatorTester()
678         .batch_size(2)
679         .input_height(pooling_size.second + 3)
680         .input_width(pooling_size.first + 2)
681         .pooling_height(pooling_size.second)
682         .pooling_width(pooling_size.first)
683         .channels(channels)
684         .input_zero_point(uint8_t(input_zero_point))
685         .TestQU8();
686     }
687   }
688 }
689 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_pool_with_output_scale)690 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_pool_with_output_scale) {
691   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
692   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
693   for (size_t channels = 1; channels <= 100; channels += 15) {
694     for (float output_scale = 0.01f; output_scale < 100.0f; output_scale *= 3.14159265f) {
695       AveragePoolingOperatorTester()
696         .batch_size(2)
697         .input_height(pooling_size.first + 3)
698         .input_width(pooling_size.second + 2)
699         .pooling_height(pooling_size.first)
700         .pooling_width(pooling_size.second)
701         .channels(channels)
702         .output_scale(output_scale)
703         .TestQU8();
704       AveragePoolingOperatorTester()
705         .batch_size(2)
706         .input_height(pooling_size.second + 3)
707         .input_width(pooling_size.first + 2)
708         .pooling_height(pooling_size.second)
709         .pooling_width(pooling_size.first)
710         .channels(channels)
711         .output_scale(output_scale)
712         .TestQU8();
713     }
714   }
715 }
716 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_pool_with_output_zero_point)717 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_pool_with_output_zero_point) {
718   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
719   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
720   for (size_t channels = 1; channels <= 100; channels += 15) {
721     for (int32_t output_zero_point = 0; output_zero_point <= 255; output_zero_point += 51) {
722       AveragePoolingOperatorTester()
723         .batch_size(2)
724         .input_height(pooling_size.first + 3)
725         .input_width(pooling_size.second + 2)
726         .pooling_height(pooling_size.first)
727         .pooling_width(pooling_size.second)
728         .channels(channels)
729         .output_zero_point(uint8_t(output_zero_point))
730         .TestQU8();
731       AveragePoolingOperatorTester()
732         .batch_size(2)
733         .input_height(pooling_size.second + 3)
734         .input_width(pooling_size.first + 2)
735         .pooling_height(pooling_size.second)
736         .pooling_width(pooling_size.first)
737         .channels(channels)
738         .output_zero_point(uint8_t(output_zero_point))
739         .TestQU8();
740     }
741   }
742 }
743 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_pool_with_qmin)744 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_pool_with_qmin) {
745   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
746   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
747   for (size_t channels = 1; channels <= 100; channels += 15) {
748     AveragePoolingOperatorTester()
749       .batch_size(2)
750       .input_height(pooling_size.first + 3)
751       .input_width(pooling_size.second + 2)
752       .pooling_height(pooling_size.first)
753       .pooling_width(pooling_size.second)
754       .channels(channels)
755       .qmin(128)
756       .TestQU8();
757     AveragePoolingOperatorTester()
758       .batch_size(2)
759       .input_height(pooling_size.second + 3)
760       .input_width(pooling_size.first + 2)
761       .pooling_height(pooling_size.second)
762       .pooling_width(pooling_size.first)
763       .channels(channels)
764       .qmin(128)
765       .TestQU8();
766   }
767 }
768 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_pool_with_qmax)769 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_pool_with_qmax) {
770   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
771   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.avgpool.primary_tile);
772   for (size_t channels = 1; channels <= 100; channels += 15) {
773     AveragePoolingOperatorTester()
774       .batch_size(2)
775       .input_height(pooling_size.first + 3)
776       .input_width(pooling_size.second + 2)
777       .pooling_height(pooling_size.first)
778       .pooling_width(pooling_size.second)
779       .channels(channels)
780       .qmax(128)
781       .TestQU8();
782     AveragePoolingOperatorTester()
783       .batch_size(2)
784       .input_height(pooling_size.second + 3)
785       .input_width(pooling_size.first + 2)
786       .pooling_height(pooling_size.second)
787       .pooling_width(pooling_size.first)
788       .channels(channels)
789       .qmax(128)
790       .TestQU8();
791   }
792 }
793 
794 /**************************** AVGPOOL path, multipass ****************************/
795 
TEST(AVERAGE_POOLING_NHWC_QU8,large_pool)796 TEST(AVERAGE_POOLING_NHWC_QU8, large_pool) {
797   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
798   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.avgpool.primary_tile * 2);
799   for (size_t channels = 1; channels <= 100; channels += 15) {
800     AveragePoolingOperatorTester()
801       .input_height(pooling_size.first + 3)
802       .input_width(pooling_size.second + 2)
803       .pooling_height(pooling_size.first)
804       .pooling_width(pooling_size.second)
805       .channels(channels)
806       .TestQU8();
807     AveragePoolingOperatorTester()
808       .input_height(pooling_size.second + 3)
809       .input_width(pooling_size.first + 2)
810       .pooling_height(pooling_size.second)
811       .pooling_width(pooling_size.first)
812       .channels(channels)
813       .TestQU8();
814   }
815 }
816 
TEST(AVERAGE_POOLING_NHWC_QU8,large_pool_with_stride)817 TEST(AVERAGE_POOLING_NHWC_QU8, large_pool_with_stride) {
818   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
819   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
820   for (size_t channels = 1; channels <= 100; channels += 15) {
821     for (size_t stride_width = 1; stride_width <= 2; stride_width++) {
822       for (size_t stride_height = 1; stride_height <= 2; stride_height++) {
823         if (stride_width == 1 && stride_height == 1) {
824           continue;
825         }
826 
827         AveragePoolingOperatorTester()
828           .input_height(pooling_size.first + 3)
829           .input_width(pooling_size.second + 2)
830           .pooling_height(pooling_size.first)
831           .pooling_width(pooling_size.second)
832           .stride_height(stride_height)
833           .stride_width(stride_width)
834           .channels(channels)
835           .TestQU8();
836         AveragePoolingOperatorTester()
837           .input_height(pooling_size.second + 3)
838           .input_width(pooling_size.first + 2)
839           .pooling_height(pooling_size.second)
840           .pooling_width(pooling_size.first)
841           .stride_height(stride_height)
842           .stride_width(stride_width)
843           .channels(channels)
844           .TestQU8();
845       }
846     }
847   }
848 }
849 
TEST(AVERAGE_POOLING_NHWC_QU8,large_pool_with_width_padding)850 TEST(AVERAGE_POOLING_NHWC_QU8, large_pool_with_width_padding) {
851   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
852   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
853   for (size_t channels = 1; channels <= 100; channels += 15) {
854     for (size_t stride = 1; stride <= 2; stride++) {
855       for (size_t padding_left = 0; padding_left <= 1; padding_left++) {
856         for (size_t padding_right = 0; padding_right <= 1; padding_right++) {
857           AveragePoolingOperatorTester()
858             .input_height(pooling_size.first + 3)
859             .input_width(pooling_size.second + 2)
860             .padding_left(padding_left)
861             .padding_right(padding_right)
862             .pooling_height(pooling_size.first)
863             .pooling_width(pooling_size.second)
864             .stride(stride)
865             .channels(channels)
866             .TestQU8();
867           AveragePoolingOperatorTester()
868             .input_height(pooling_size.second + 3)
869             .input_width(pooling_size.first + 2)
870             .padding_left(padding_left)
871             .padding_right(padding_right)
872             .pooling_height(pooling_size.second)
873             .pooling_width(pooling_size.first)
874             .stride(stride)
875             .channels(channels)
876             .TestQU8();
877         }
878       }
879     }
880   }
881 }
882 
TEST(AVERAGE_POOLING_NHWC_QU8,large_pool_with_height_padding)883 TEST(AVERAGE_POOLING_NHWC_QU8, large_pool_with_height_padding) {
884   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
885   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
886   for (size_t channels = 1; channels <= 100; channels += 15) {
887     for (size_t stride = 1; stride <= 2; stride++) {
888       for (size_t padding_top = 0; padding_top <= 1; padding_top++) {
889         for (size_t padding_bottom = 0; padding_bottom <= 1; padding_bottom++) {
890           AveragePoolingOperatorTester()
891             .input_height(pooling_size.first + 3)
892             .input_width(pooling_size.second + 2)
893             .padding_top(padding_top)
894             .padding_bottom(padding_bottom)
895             .pooling_height(pooling_size.first)
896             .pooling_width(pooling_size.second)
897             .stride(stride)
898             .channels(channels)
899             .TestQU8();
900           AveragePoolingOperatorTester()
901             .input_height(pooling_size.second + 3)
902             .input_width(pooling_size.first + 2)
903             .padding_top(padding_top)
904             .padding_bottom(padding_bottom)
905             .pooling_height(pooling_size.second)
906             .pooling_width(pooling_size.first)
907             .stride(stride)
908             .channels(channels)
909             .TestQU8();
910         }
911       }
912     }
913   }
914 }
915 
TEST(AVERAGE_POOLING_NHWC_QU8,large_pool_with_tf_same_padding)916 TEST(AVERAGE_POOLING_NHWC_QU8, large_pool_with_tf_same_padding) {
917   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
918   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
919   for (size_t channels = 1; channels <= 100; channels += 15) {
920     for (size_t stride = 1; stride <= 2; stride++) {
921       for (size_t input_height = pooling_size.first + 3; input_height <= pooling_size.first + 4; input_height++) {
922         AveragePoolingOperatorTester()
923           .input_height(input_height)
924           .input_width(pooling_size.second + 2)
925           .padding_tf_same(true)
926           .pooling_height(pooling_size.first)
927           .pooling_width(pooling_size.second)
928           .stride(stride)
929           .channels(channels)
930           .TestQU8();
931       }
932       for (size_t input_width = pooling_size.second + 2; input_width <= pooling_size.second + 3; input_width++) {
933         AveragePoolingOperatorTester()
934           .input_height(pooling_size.first + 3)
935           .input_width(input_width)
936           .padding_tf_same(true)
937           .pooling_height(pooling_size.first)
938           .pooling_width(pooling_size.second)
939           .stride(stride)
940           .channels(channels)
941           .TestQU8();
942       }
943       for (size_t input_height = pooling_size.second + 3; input_height <= pooling_size.second + 4; input_height++) {
944         AveragePoolingOperatorTester()
945           .input_height(input_height)
946           .input_width(pooling_size.first + 2)
947           .padding_tf_same(true)
948           .pooling_height(pooling_size.second)
949           .pooling_width(pooling_size.first)
950           .stride(stride)
951           .channels(channels)
952           .TestQU8();
953       }
954       for (size_t input_width = pooling_size.first + 2; input_width <= pooling_size.first + 3; input_width++) {
955         AveragePoolingOperatorTester()
956           .input_height(pooling_size.second + 3)
957           .input_width(input_width)
958           .padding_tf_same(true)
959           .pooling_height(pooling_size.second)
960           .pooling_width(pooling_size.first)
961           .stride(stride)
962           .channels(channels)
963           .TestQU8();
964       }
965     }
966   }
967 }
968 
TEST(AVERAGE_POOLING_NHWC_QU8,large_pool_with_input_stride)969 TEST(AVERAGE_POOLING_NHWC_QU8, large_pool_with_input_stride) {
970   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
971   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
972   for (size_t channels = 1; channels <= 100; channels += 15) {
973     AveragePoolingOperatorTester()
974       .input_height(pooling_size.first + 3)
975       .input_width(pooling_size.second + 2)
976       .pooling_height(pooling_size.first)
977       .pooling_width(pooling_size.second)
978       .channels(channels)
979       .input_pixel_stride(2 * channels + 3)
980       .TestQU8();
981     AveragePoolingOperatorTester()
982       .input_height(pooling_size.second + 3)
983       .input_width(pooling_size.first + 2)
984       .pooling_height(pooling_size.second)
985       .pooling_width(pooling_size.first)
986       .channels(channels)
987       .input_pixel_stride(2 * channels + 3)
988       .TestQU8();
989   }
990 }
991 
TEST(AVERAGE_POOLING_NHWC_QU8,large_pool_with_output_stride)992 TEST(AVERAGE_POOLING_NHWC_QU8, large_pool_with_output_stride) {
993   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
994   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
995   for (size_t channels = 1; channels <= 100; channels += 15) {
996     AveragePoolingOperatorTester()
997       .input_height(pooling_size.first + 3)
998       .input_width(pooling_size.second + 2)
999       .pooling_height(pooling_size.first)
1000       .pooling_width(pooling_size.second)
1001       .channels(channels)
1002       .output_pixel_stride(2 * channels + 3)
1003       .TestQU8();
1004     AveragePoolingOperatorTester()
1005       .input_height(pooling_size.second + 3)
1006       .input_width(pooling_size.first + 2)
1007       .pooling_height(pooling_size.second)
1008       .pooling_width(pooling_size.first)
1009       .channels(channels)
1010       .output_pixel_stride(2 * channels + 3)
1011       .TestQU8();
1012   }
1013 }
1014 
TEST(AVERAGE_POOLING_NHWC_QU8,large_pool_with_input_scale)1015 TEST(AVERAGE_POOLING_NHWC_QU8, large_pool_with_input_scale) {
1016   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1017   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1018   for (size_t channels = 1; channels <= 100; channels += 15) {
1019     for (float input_scale = 0.01f; input_scale < 100.0f; input_scale *= 3.14159265f) {
1020       AveragePoolingOperatorTester()
1021         .input_height(pooling_size.first + 3)
1022         .input_width(pooling_size.second + 2)
1023         .pooling_height(pooling_size.first)
1024         .pooling_width(pooling_size.second)
1025         .channels(channels)
1026         .input_scale(input_scale)
1027         .TestQU8();
1028       AveragePoolingOperatorTester()
1029         .input_height(pooling_size.second + 3)
1030         .input_width(pooling_size.first + 2)
1031         .pooling_height(pooling_size.second)
1032         .pooling_width(pooling_size.first)
1033         .channels(channels)
1034         .input_scale(input_scale)
1035         .TestQU8();
1036     }
1037   }
1038 }
1039 
TEST(AVERAGE_POOLING_NHWC_QU8,large_pool_with_input_zero_point)1040 TEST(AVERAGE_POOLING_NHWC_QU8, large_pool_with_input_zero_point) {
1041   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1042   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1043   for (size_t channels = 1; channels <= 100; channels += 15) {
1044     for (int32_t input_zero_point = 0; input_zero_point <= 255; input_zero_point += 51) {
1045       AveragePoolingOperatorTester()
1046         .input_height(pooling_size.first + 3)
1047         .input_width(pooling_size.second + 2)
1048         .pooling_height(pooling_size.first)
1049         .pooling_width(pooling_size.second)
1050         .channels(channels)
1051         .input_zero_point(uint8_t(input_zero_point))
1052         .TestQU8();
1053       AveragePoolingOperatorTester()
1054         .input_height(pooling_size.second + 3)
1055         .input_width(pooling_size.first + 2)
1056         .pooling_height(pooling_size.second)
1057         .pooling_width(pooling_size.first)
1058         .channels(channels)
1059         .input_zero_point(uint8_t(input_zero_point))
1060         .TestQU8();
1061     }
1062   }
1063 }
1064 
TEST(AVERAGE_POOLING_NHWC_QU8,large_pool_with_output_scale)1065 TEST(AVERAGE_POOLING_NHWC_QU8, large_pool_with_output_scale) {
1066   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1067   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1068   for (size_t channels = 1; channels <= 100; channels += 15) {
1069     for (float output_scale = 0.01f; output_scale < 100.0f; output_scale *= 3.14159265f) {
1070       AveragePoolingOperatorTester()
1071         .input_height(pooling_size.first + 3)
1072         .input_width(pooling_size.second + 2)
1073         .pooling_height(pooling_size.first)
1074         .pooling_width(pooling_size.second)
1075         .channels(channels)
1076         .output_scale(output_scale)
1077         .TestQU8();
1078       AveragePoolingOperatorTester()
1079         .input_height(pooling_size.second + 3)
1080         .input_width(pooling_size.first + 2)
1081         .pooling_height(pooling_size.second)
1082         .pooling_width(pooling_size.first)
1083         .channels(channels)
1084         .output_scale(output_scale)
1085         .TestQU8();
1086     }
1087   }
1088 }
1089 
TEST(AVERAGE_POOLING_NHWC_QU8,large_pool_with_output_zero_point)1090 TEST(AVERAGE_POOLING_NHWC_QU8, large_pool_with_output_zero_point) {
1091   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1092   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1093   for (size_t channels = 1; channels <= 100; channels += 15) {
1094     for (int32_t output_zero_point = 0; output_zero_point <= 255; output_zero_point += 51) {
1095       AveragePoolingOperatorTester()
1096         .input_height(pooling_size.first + 3)
1097         .input_width(pooling_size.second + 2)
1098         .pooling_height(pooling_size.first)
1099         .pooling_width(pooling_size.second)
1100         .channels(channels)
1101         .output_zero_point(uint8_t(output_zero_point))
1102         .TestQU8();
1103       AveragePoolingOperatorTester()
1104         .input_height(pooling_size.second + 3)
1105         .input_width(pooling_size.first + 2)
1106         .pooling_height(pooling_size.second)
1107         .pooling_width(pooling_size.first)
1108         .channels(channels)
1109         .output_zero_point(uint8_t(output_zero_point))
1110         .TestQU8();
1111     }
1112   }
1113 }
1114 
TEST(AVERAGE_POOLING_NHWC_QU8,large_pool_with_qmin)1115 TEST(AVERAGE_POOLING_NHWC_QU8, large_pool_with_qmin) {
1116   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1117   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1118   for (size_t channels = 1; channels <= 100; channels += 15) {
1119     AveragePoolingOperatorTester()
1120       .input_height(pooling_size.first + 3)
1121       .input_width(pooling_size.second + 2)
1122       .pooling_height(pooling_size.first)
1123       .pooling_width(pooling_size.second)
1124       .channels(channels)
1125       .qmin(128)
1126       .TestQU8();
1127     AveragePoolingOperatorTester()
1128       .input_height(pooling_size.second + 3)
1129       .input_width(pooling_size.first + 2)
1130       .pooling_height(pooling_size.second)
1131       .pooling_width(pooling_size.first)
1132       .channels(channels)
1133       .qmin(128)
1134       .TestQU8();
1135   }
1136 }
1137 
TEST(AVERAGE_POOLING_NHWC_QU8,large_pool_with_qmax)1138 TEST(AVERAGE_POOLING_NHWC_QU8, large_pool_with_qmax) {
1139   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1140   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1141   for (size_t channels = 1; channels <= 100; channels += 15) {
1142     AveragePoolingOperatorTester()
1143       .input_height(pooling_size.first + 3)
1144       .input_width(pooling_size.second + 2)
1145       .pooling_height(pooling_size.first)
1146       .pooling_width(pooling_size.second)
1147       .channels(channels)
1148       .qmax(128)
1149       .TestQU8();
1150     AveragePoolingOperatorTester()
1151       .input_height(pooling_size.second + 3)
1152       .input_width(pooling_size.first + 2)
1153       .pooling_height(pooling_size.second)
1154       .pooling_width(pooling_size.first)
1155       .channels(channels)
1156       .qmax(128)
1157       .TestQU8();
1158   }
1159 }
1160 
1161 /**************************** AVGPOOL path, multipass, batched ****************************/
1162 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_pool)1163 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_pool) {
1164   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1165   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.avgpool.primary_tile * 2);
1166   for (size_t channels = 1; channels <= 100; channels += 15) {
1167     AveragePoolingOperatorTester()
1168       .batch_size(2)
1169       .input_height(pooling_size.first + 3)
1170       .input_width(pooling_size.second + 2)
1171       .pooling_height(pooling_size.first)
1172       .pooling_width(pooling_size.second)
1173       .channels(channels)
1174       .TestQU8();
1175     AveragePoolingOperatorTester()
1176       .batch_size(2)
1177       .input_height(pooling_size.second + 3)
1178       .input_width(pooling_size.first + 2)
1179       .pooling_height(pooling_size.second)
1180       .pooling_width(pooling_size.first)
1181       .channels(channels)
1182       .TestQU8();
1183   }
1184 }
1185 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_pool_with_stride)1186 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_pool_with_stride) {
1187   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1188   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1189   for (size_t channels = 1; channels <= 100; channels += 15) {
1190     for (size_t stride_width = 1; stride_width <= 2; stride_width++) {
1191       for (size_t stride_height = 1; stride_height <= 2; stride_height++) {
1192         if (stride_width == 1 && stride_height == 1) {
1193           continue;
1194         }
1195 
1196         AveragePoolingOperatorTester()
1197           .batch_size(2)
1198           .input_height(pooling_size.first + 3)
1199           .input_width(pooling_size.second + 2)
1200           .pooling_height(pooling_size.first)
1201           .pooling_width(pooling_size.second)
1202           .stride_height(stride_height)
1203           .stride_width(stride_width)
1204           .channels(channels)
1205           .TestQU8();
1206         AveragePoolingOperatorTester()
1207           .batch_size(2)
1208           .input_height(pooling_size.second + 3)
1209           .input_width(pooling_size.first + 2)
1210           .pooling_height(pooling_size.second)
1211           .pooling_width(pooling_size.first)
1212           .stride_height(stride_height)
1213           .stride_width(stride_width)
1214           .channels(channels)
1215           .TestQU8();
1216       }
1217     }
1218   }
1219 }
1220 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_pool_with_width_padding)1221 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_pool_with_width_padding) {
1222   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1223   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1224   for (size_t channels = 1; channels <= 100; channels += 15) {
1225     for (size_t stride = 1; stride <= 2; stride++) {
1226       for (size_t padding_left = 0; padding_left <= 1; padding_left++) {
1227         for (size_t padding_right = 0; padding_right <= 1; padding_right++) {
1228           AveragePoolingOperatorTester()
1229             .batch_size(2)
1230             .input_height(pooling_size.first + 3)
1231             .input_width(pooling_size.second + 2)
1232             .padding_left(padding_left)
1233             .padding_right(padding_right)
1234             .pooling_height(pooling_size.first)
1235             .pooling_width(pooling_size.second)
1236             .stride(stride)
1237             .channels(channels)
1238             .TestQU8();
1239           AveragePoolingOperatorTester()
1240             .batch_size(2)
1241             .input_height(pooling_size.second + 3)
1242             .input_width(pooling_size.first + 2)
1243             .padding_left(padding_left)
1244             .padding_right(padding_right)
1245             .pooling_height(pooling_size.second)
1246             .pooling_width(pooling_size.first)
1247             .stride(stride)
1248             .channels(channels)
1249             .TestQU8();
1250         }
1251       }
1252     }
1253   }
1254 }
1255 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_pool_with_height_padding)1256 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_pool_with_height_padding) {
1257   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1258   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1259   for (size_t channels = 1; channels <= 100; channels += 15) {
1260     for (size_t stride = 1; stride <= 2; stride++) {
1261       for (size_t padding_top = 0; padding_top <= 1; padding_top++) {
1262         for (size_t padding_bottom = 0; padding_bottom <= 1; padding_bottom++) {
1263           AveragePoolingOperatorTester()
1264             .batch_size(2)
1265             .input_height(pooling_size.first + 3)
1266             .input_width(pooling_size.second + 2)
1267             .padding_top(padding_top)
1268             .padding_bottom(padding_bottom)
1269             .pooling_height(pooling_size.first)
1270             .pooling_width(pooling_size.second)
1271             .stride(stride)
1272             .channels(channels)
1273             .TestQU8();
1274           AveragePoolingOperatorTester()
1275             .batch_size(2)
1276             .input_height(pooling_size.second + 3)
1277             .input_width(pooling_size.first + 2)
1278             .padding_top(padding_top)
1279             .padding_bottom(padding_bottom)
1280             .pooling_height(pooling_size.second)
1281             .pooling_width(pooling_size.first)
1282             .stride(stride)
1283             .channels(channels)
1284             .TestQU8();
1285         }
1286       }
1287     }
1288   }
1289 }
1290 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_pool_with_tf_same_padding)1291 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_pool_with_tf_same_padding) {
1292   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1293   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1294   for (size_t channels = 1; channels <= 100; channels += 15) {
1295     for (size_t stride = 1; stride <= 2; stride++) {
1296       for (size_t input_height = pooling_size.first + 3; input_height <= pooling_size.first + 4; input_height++) {
1297         AveragePoolingOperatorTester()
1298           .batch_size(2)
1299           .input_height(input_height)
1300           .input_width(pooling_size.second + 2)
1301           .padding_tf_same(true)
1302           .pooling_height(pooling_size.first)
1303           .pooling_width(pooling_size.second)
1304           .stride(stride)
1305           .channels(channels)
1306           .TestQU8();
1307       }
1308       for (size_t input_width = pooling_size.second + 2; input_width <= pooling_size.second + 3; input_width++) {
1309         AveragePoolingOperatorTester()
1310           .batch_size(2)
1311           .input_height(pooling_size.first + 3)
1312           .input_width(input_width)
1313           .padding_tf_same(true)
1314           .pooling_height(pooling_size.first)
1315           .pooling_width(pooling_size.second)
1316           .stride(stride)
1317           .channels(channels)
1318           .TestQU8();
1319       }
1320       for (size_t input_height = pooling_size.second + 3; input_height <= pooling_size.second + 4; input_height++) {
1321         AveragePoolingOperatorTester()
1322           .batch_size(2)
1323           .input_height(input_height)
1324           .input_width(pooling_size.first + 2)
1325           .padding_tf_same(true)
1326           .pooling_height(pooling_size.second)
1327           .pooling_width(pooling_size.first)
1328           .stride(stride)
1329           .channels(channels)
1330           .TestQU8();
1331       }
1332       for (size_t input_width = pooling_size.first + 2; input_width <= pooling_size.first + 3; input_width++) {
1333         AveragePoolingOperatorTester()
1334           .batch_size(2)
1335           .input_height(pooling_size.second + 3)
1336           .input_width(input_width)
1337           .padding_tf_same(true)
1338           .pooling_height(pooling_size.second)
1339           .pooling_width(pooling_size.first)
1340           .stride(stride)
1341           .channels(channels)
1342           .TestQU8();
1343       }
1344     }
1345   }
1346 }
1347 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_pool_with_input_stride)1348 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_pool_with_input_stride) {
1349   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1350   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1351   for (size_t channels = 1; channels <= 100; channels += 15) {
1352     AveragePoolingOperatorTester()
1353       .batch_size(2)
1354       .input_height(pooling_size.first + 3)
1355       .input_width(pooling_size.second + 2)
1356       .pooling_height(pooling_size.first)
1357       .pooling_width(pooling_size.second)
1358       .channels(channels)
1359       .input_pixel_stride(2 * channels + 3)
1360       .TestQU8();
1361     AveragePoolingOperatorTester()
1362       .batch_size(2)
1363       .input_height(pooling_size.second + 3)
1364       .input_width(pooling_size.first + 2)
1365       .pooling_height(pooling_size.second)
1366       .pooling_width(pooling_size.first)
1367       .channels(channels)
1368       .input_pixel_stride(2 * channels + 3)
1369       .TestQU8();
1370   }
1371 }
1372 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_pool_with_output_stride)1373 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_pool_with_output_stride) {
1374   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1375   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1376   for (size_t channels = 1; channels <= 100; channels += 15) {
1377     AveragePoolingOperatorTester()
1378       .batch_size(2)
1379       .input_height(pooling_size.first + 3)
1380       .input_width(pooling_size.second + 2)
1381       .pooling_height(pooling_size.first)
1382       .pooling_width(pooling_size.second)
1383       .channels(channels)
1384       .output_pixel_stride(2 * channels + 3)
1385       .TestQU8();
1386     AveragePoolingOperatorTester()
1387       .batch_size(2)
1388       .input_height(pooling_size.second + 3)
1389       .input_width(pooling_size.first + 2)
1390       .pooling_height(pooling_size.second)
1391       .pooling_width(pooling_size.first)
1392       .channels(channels)
1393       .output_pixel_stride(2 * channels + 3)
1394       .TestQU8();
1395   }
1396 }
1397 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_pool_with_input_scale)1398 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_pool_with_input_scale) {
1399   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1400   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1401   for (size_t channels = 1; channels <= 100; channels += 15) {
1402     for (float input_scale = 0.01f; input_scale < 100.0f; input_scale *= 3.14159265f) {
1403       AveragePoolingOperatorTester()
1404         .batch_size(2)
1405         .input_height(pooling_size.first + 3)
1406         .input_width(pooling_size.second + 2)
1407         .pooling_height(pooling_size.first)
1408         .pooling_width(pooling_size.second)
1409         .channels(channels)
1410         .input_scale(input_scale)
1411         .TestQU8();
1412       AveragePoolingOperatorTester()
1413         .batch_size(2)
1414         .input_height(pooling_size.second + 3)
1415         .input_width(pooling_size.first + 2)
1416         .pooling_height(pooling_size.second)
1417         .pooling_width(pooling_size.first)
1418         .channels(channels)
1419         .input_scale(input_scale)
1420         .TestQU8();
1421     }
1422   }
1423 }
1424 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_pool_with_input_zero_point)1425 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_pool_with_input_zero_point) {
1426   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1427   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1428   for (size_t channels = 1; channels <= 100; channels += 15) {
1429     for (int32_t input_zero_point = 0; input_zero_point <= 255; input_zero_point += 51) {
1430       AveragePoolingOperatorTester()
1431         .batch_size(2)
1432         .input_height(pooling_size.first + 3)
1433         .input_width(pooling_size.second + 2)
1434         .pooling_height(pooling_size.first)
1435         .pooling_width(pooling_size.second)
1436         .channels(channels)
1437         .input_zero_point(uint8_t(input_zero_point))
1438         .TestQU8();
1439       AveragePoolingOperatorTester()
1440         .batch_size(2)
1441         .input_height(pooling_size.second + 3)
1442         .input_width(pooling_size.first + 2)
1443         .pooling_height(pooling_size.second)
1444         .pooling_width(pooling_size.first)
1445         .channels(channels)
1446         .input_zero_point(uint8_t(input_zero_point))
1447         .TestQU8();
1448     }
1449   }
1450 }
1451 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_pool_with_output_scale)1452 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_pool_with_output_scale) {
1453   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1454   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1455   for (size_t channels = 1; channels <= 100; channels += 15) {
1456     for (float output_scale = 0.01f; output_scale < 100.0f; output_scale *= 3.14159265f) {
1457       AveragePoolingOperatorTester()
1458         .batch_size(2)
1459         .input_height(pooling_size.first + 3)
1460         .input_width(pooling_size.second + 2)
1461         .pooling_height(pooling_size.first)
1462         .pooling_width(pooling_size.second)
1463         .channels(channels)
1464         .output_scale(output_scale)
1465         .TestQU8();
1466       AveragePoolingOperatorTester()
1467         .batch_size(2)
1468         .input_height(pooling_size.second + 3)
1469         .input_width(pooling_size.first + 2)
1470         .pooling_height(pooling_size.second)
1471         .pooling_width(pooling_size.first)
1472         .channels(channels)
1473         .output_scale(output_scale)
1474         .TestQU8();
1475     }
1476   }
1477 }
1478 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_pool_with_output_zero_point)1479 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_pool_with_output_zero_point) {
1480   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1481   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1482   for (size_t channels = 1; channels <= 100; channels += 15) {
1483     for (int32_t output_zero_point = 0; output_zero_point <= 255; output_zero_point += 51) {
1484       AveragePoolingOperatorTester()
1485         .batch_size(2)
1486         .input_height(pooling_size.first + 3)
1487         .input_width(pooling_size.second + 2)
1488         .pooling_height(pooling_size.first)
1489         .pooling_width(pooling_size.second)
1490         .channels(channels)
1491         .output_zero_point(uint8_t(output_zero_point))
1492         .TestQU8();
1493       AveragePoolingOperatorTester()
1494         .batch_size(2)
1495         .input_height(pooling_size.second + 3)
1496         .input_width(pooling_size.first + 2)
1497         .pooling_height(pooling_size.second)
1498         .pooling_width(pooling_size.first)
1499         .channels(channels)
1500         .output_zero_point(uint8_t(output_zero_point))
1501         .TestQU8();
1502     }
1503   }
1504 }
1505 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_pool_with_qmin)1506 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_pool_with_qmin) {
1507   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1508   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1509   for (size_t channels = 1; channels <= 100; channels += 15) {
1510     AveragePoolingOperatorTester()
1511       .batch_size(2)
1512       .input_height(pooling_size.first + 3)
1513       .input_width(pooling_size.second + 2)
1514       .pooling_height(pooling_size.first)
1515       .pooling_width(pooling_size.second)
1516       .channels(channels)
1517       .qmin(128)
1518       .TestQU8();
1519     AveragePoolingOperatorTester()
1520       .batch_size(2)
1521       .input_height(pooling_size.second + 3)
1522       .input_width(pooling_size.first + 2)
1523       .pooling_height(pooling_size.second)
1524       .pooling_width(pooling_size.first)
1525       .channels(channels)
1526       .qmin(128)
1527       .TestQU8();
1528   }
1529 }
1530 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_pool_with_qmax)1531 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_pool_with_qmax) {
1532   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1533   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
1534   for (size_t channels = 1; channels <= 100; channels += 15) {
1535     AveragePoolingOperatorTester()
1536       .batch_size(2)
1537       .input_height(pooling_size.first + 3)
1538       .input_width(pooling_size.second + 2)
1539       .pooling_height(pooling_size.first)
1540       .pooling_width(pooling_size.second)
1541       .channels(channels)
1542       .qmax(128)
1543       .TestQU8();
1544     AveragePoolingOperatorTester()
1545       .batch_size(2)
1546       .input_height(pooling_size.second + 3)
1547       .input_width(pooling_size.first + 2)
1548       .pooling_height(pooling_size.second)
1549       .pooling_width(pooling_size.first)
1550       .channels(channels)
1551       .qmax(128)
1552       .TestQU8();
1553   }
1554 }
1555 
1556 /**************************** GAVGPOOL path, unipass ****************************/
1557 
TEST(AVERAGE_POOLING_NHWC_QU8,small_image)1558 TEST(AVERAGE_POOLING_NHWC_QU8, small_image) {
1559   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1560   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
1561   for (size_t channels = 1; channels <= 100; channels += 15) {
1562     AveragePoolingOperatorTester()
1563       .input_height(pooling_size.first)
1564       .input_width(pooling_size.second)
1565       .pooling_height(pooling_size.first)
1566       .pooling_width(pooling_size.second)
1567       .channels(channels)
1568       .TestQU8();
1569     AveragePoolingOperatorTester()
1570       .input_height(pooling_size.second)
1571       .input_width(pooling_size.first)
1572       .pooling_height(pooling_size.second)
1573       .pooling_width(pooling_size.first)
1574       .channels(channels)
1575       .TestQU8();
1576   }
1577 }
1578 
TEST(AVERAGE_POOLING_NHWC_QU8,small_image_with_width_padding)1579 TEST(AVERAGE_POOLING_NHWC_QU8, small_image_with_width_padding) {
1580   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1581   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
1582   for (size_t channels = 1; channels <= 100; channels += 15) {
1583     /* With left padding */
1584     AveragePoolingOperatorTester()
1585       .input_height(pooling_size.first)
1586       .input_width(pooling_size.second - 1)
1587       .padding_left(1)
1588       .pooling_height(pooling_size.first)
1589       .pooling_width(pooling_size.second)
1590       .channels(channels)
1591       .TestQU8();
1592     AveragePoolingOperatorTester()
1593       .input_height(pooling_size.second)
1594       .input_width(pooling_size.first - 1)
1595       .padding_left(1)
1596       .pooling_height(pooling_size.second)
1597       .pooling_width(pooling_size.first)
1598       .channels(channels)
1599       .TestQU8();
1600 
1601     /* With right padding */
1602     AveragePoolingOperatorTester()
1603       .input_height(pooling_size.first)
1604       .input_width(pooling_size.second - 1)
1605       .padding_right(1)
1606       .pooling_height(pooling_size.first)
1607       .pooling_width(pooling_size.second)
1608       .channels(channels)
1609       .TestQU8();
1610     AveragePoolingOperatorTester()
1611       .input_height(pooling_size.second)
1612       .input_width(pooling_size.first - 1)
1613       .padding_right(1)
1614       .pooling_height(pooling_size.second)
1615       .pooling_width(pooling_size.first)
1616       .channels(channels)
1617       .TestQU8();
1618   }
1619 }
1620 
TEST(AVERAGE_POOLING_NHWC_QU8,small_image_with_height_padding)1621 TEST(AVERAGE_POOLING_NHWC_QU8, small_image_with_height_padding) {
1622   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1623   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
1624   for (size_t channels = 1; channels <= 100; channels += 15) {
1625     /* With top padding */
1626     AveragePoolingOperatorTester()
1627       .input_height(pooling_size.first - 1)
1628       .input_width(pooling_size.second)
1629       .padding_top(1)
1630       .pooling_height(pooling_size.first)
1631       .pooling_width(pooling_size.second)
1632       .channels(channels)
1633       .TestQU8();
1634     AveragePoolingOperatorTester()
1635       .input_height(pooling_size.second - 1)
1636       .input_width(pooling_size.first)
1637       .padding_top(1)
1638       .pooling_height(pooling_size.second)
1639       .pooling_width(pooling_size.first)
1640       .channels(channels)
1641       .TestQU8();
1642 
1643     /* With bottom padding */
1644     AveragePoolingOperatorTester()
1645       .input_height(pooling_size.first - 1)
1646       .input_width(pooling_size.second)
1647       .padding_bottom(1)
1648       .pooling_height(pooling_size.first)
1649       .pooling_width(pooling_size.second)
1650       .channels(channels)
1651       .TestQU8();
1652     AveragePoolingOperatorTester()
1653       .input_height(pooling_size.second - 1)
1654       .input_width(pooling_size.first)
1655       .padding_bottom(1)
1656       .pooling_height(pooling_size.second)
1657       .pooling_width(pooling_size.first)
1658       .channels(channels)
1659       .TestQU8();
1660   }
1661 }
1662 
TEST(AVERAGE_POOLING_NHWC_QU8,small_image_with_input_stride)1663 TEST(AVERAGE_POOLING_NHWC_QU8, small_image_with_input_stride) {
1664   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1665   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
1666   for (size_t channels = 1; channels <= 100; channels += 15) {
1667     AveragePoolingOperatorTester()
1668       .input_height(pooling_size.first)
1669       .input_width(pooling_size.second)
1670       .pooling_height(pooling_size.first)
1671       .pooling_width(pooling_size.second)
1672       .channels(channels)
1673       .input_pixel_stride(2 * channels + 3)
1674       .TestQU8();
1675     AveragePoolingOperatorTester()
1676       .input_height(pooling_size.second)
1677       .input_width(pooling_size.first)
1678       .pooling_height(pooling_size.second)
1679       .pooling_width(pooling_size.first)
1680       .channels(channels)
1681       .input_pixel_stride(2 * channels + 3)
1682       .TestQU8();
1683   }
1684 }
1685 
TEST(AVERAGE_POOLING_NHWC_QU8,small_image_with_output_stride)1686 TEST(AVERAGE_POOLING_NHWC_QU8, small_image_with_output_stride) {
1687   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1688   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
1689   for (size_t channels = 1; channels <= 100; channels += 15) {
1690     AveragePoolingOperatorTester()
1691       .input_height(pooling_size.first)
1692       .input_width(pooling_size.second)
1693       .pooling_height(pooling_size.first)
1694       .pooling_width(pooling_size.second)
1695       .channels(channels)
1696       .output_pixel_stride(2 * channels + 3)
1697       .TestQU8();
1698     AveragePoolingOperatorTester()
1699       .input_height(pooling_size.second)
1700       .input_width(pooling_size.first)
1701       .pooling_height(pooling_size.second)
1702       .pooling_width(pooling_size.first)
1703       .channels(channels)
1704       .output_pixel_stride(2 * channels + 3)
1705       .TestQU8();
1706   }
1707 }
1708 
TEST(AVERAGE_POOLING_NHWC_QU8,small_image_with_input_scale)1709 TEST(AVERAGE_POOLING_NHWC_QU8, small_image_with_input_scale) {
1710   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1711   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
1712   for (size_t channels = 1; channels <= 100; channels += 15) {
1713     for (float input_scale = 0.01f; input_scale < 100.0f; input_scale *= 3.14159265f) {
1714       AveragePoolingOperatorTester()
1715         .input_height(pooling_size.first)
1716         .input_width(pooling_size.second)
1717         .pooling_height(pooling_size.first)
1718         .pooling_width(pooling_size.second)
1719         .channels(channels)
1720         .input_scale(input_scale)
1721         .TestQU8();
1722       AveragePoolingOperatorTester()
1723         .input_height(pooling_size.second)
1724         .input_width(pooling_size.first)
1725         .pooling_height(pooling_size.second)
1726         .pooling_width(pooling_size.first)
1727         .channels(channels)
1728         .input_scale(input_scale)
1729         .TestQU8();
1730     }
1731   }
1732 }
1733 
TEST(AVERAGE_POOLING_NHWC_QU8,small_image_with_input_zero_point)1734 TEST(AVERAGE_POOLING_NHWC_QU8, small_image_with_input_zero_point) {
1735   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1736   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
1737   for (size_t channels = 1; channels <= 100; channels += 15) {
1738     for (int32_t input_zero_point = 0; input_zero_point <= 255; input_zero_point += 51) {
1739       AveragePoolingOperatorTester()
1740         .input_height(pooling_size.first)
1741         .input_width(pooling_size.second)
1742         .pooling_height(pooling_size.first)
1743         .pooling_width(pooling_size.second)
1744         .channels(channels)
1745         .input_zero_point(uint8_t(input_zero_point))
1746         .TestQU8();
1747       AveragePoolingOperatorTester()
1748         .input_height(pooling_size.second)
1749         .input_width(pooling_size.first)
1750         .pooling_height(pooling_size.second)
1751         .pooling_width(pooling_size.first)
1752         .channels(channels)
1753         .input_zero_point(uint8_t(input_zero_point))
1754         .TestQU8();
1755     }
1756   }
1757 }
1758 
TEST(AVERAGE_POOLING_NHWC_QU8,small_image_with_output_scale)1759 TEST(AVERAGE_POOLING_NHWC_QU8, small_image_with_output_scale) {
1760   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1761   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
1762   for (size_t channels = 1; channels <= 100; channels += 15) {
1763     for (float output_scale = 0.01f; output_scale < 100.0f; output_scale *= 3.14159265f) {
1764       AveragePoolingOperatorTester()
1765         .input_height(pooling_size.first)
1766         .input_width(pooling_size.second)
1767         .pooling_height(pooling_size.first)
1768         .pooling_width(pooling_size.second)
1769         .channels(channels)
1770         .output_scale(output_scale)
1771         .TestQU8();
1772       AveragePoolingOperatorTester()
1773         .input_height(pooling_size.second)
1774         .input_width(pooling_size.first)
1775         .pooling_height(pooling_size.second)
1776         .pooling_width(pooling_size.first)
1777         .channels(channels)
1778         .output_scale(output_scale)
1779         .TestQU8();
1780     }
1781   }
1782 }
1783 
TEST(AVERAGE_POOLING_NHWC_QU8,small_image_with_output_zero_point)1784 TEST(AVERAGE_POOLING_NHWC_QU8, small_image_with_output_zero_point) {
1785   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1786   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
1787   for (size_t channels = 1; channels <= 100; channels += 15) {
1788     for (int32_t output_zero_point = 0; output_zero_point <= 255; output_zero_point += 51) {
1789       AveragePoolingOperatorTester()
1790         .input_height(pooling_size.first)
1791         .input_width(pooling_size.second)
1792         .pooling_height(pooling_size.first)
1793         .pooling_width(pooling_size.second)
1794         .channels(channels)
1795         .output_zero_point(uint8_t(output_zero_point))
1796         .TestQU8();
1797       AveragePoolingOperatorTester()
1798         .input_height(pooling_size.second)
1799         .input_width(pooling_size.first)
1800         .pooling_height(pooling_size.second)
1801         .pooling_width(pooling_size.first)
1802         .channels(channels)
1803         .output_zero_point(uint8_t(output_zero_point))
1804         .TestQU8();
1805     }
1806   }
1807 }
1808 
TEST(AVERAGE_POOLING_NHWC_QU8,small_image_with_qmin)1809 TEST(AVERAGE_POOLING_NHWC_QU8, small_image_with_qmin) {
1810   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1811   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
1812   for (size_t channels = 1; channels <= 100; channels += 15) {
1813     AveragePoolingOperatorTester()
1814       .input_height(pooling_size.first)
1815       .input_width(pooling_size.second)
1816       .pooling_height(pooling_size.first)
1817       .pooling_width(pooling_size.second)
1818       .channels(channels)
1819       .qmin(128)
1820       .TestQU8();
1821     AveragePoolingOperatorTester()
1822       .input_height(pooling_size.second)
1823       .input_width(pooling_size.first)
1824       .pooling_height(pooling_size.second)
1825       .pooling_width(pooling_size.first)
1826       .channels(channels)
1827       .qmin(128)
1828       .TestQU8();
1829   }
1830 }
1831 
TEST(AVERAGE_POOLING_NHWC_QU8,small_image_with_qmax)1832 TEST(AVERAGE_POOLING_NHWC_QU8, small_image_with_qmax) {
1833   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1834   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
1835   for (size_t channels = 1; channels <= 100; channels += 15) {
1836     AveragePoolingOperatorTester()
1837       .input_height(pooling_size.first)
1838       .input_width(pooling_size.second)
1839       .pooling_height(pooling_size.first)
1840       .pooling_width(pooling_size.second)
1841       .channels(channels)
1842       .qmax(128)
1843       .TestQU8();
1844     AveragePoolingOperatorTester()
1845       .input_height(pooling_size.second)
1846       .input_width(pooling_size.first)
1847       .pooling_height(pooling_size.second)
1848       .pooling_width(pooling_size.first)
1849       .channels(channels)
1850       .qmax(128)
1851       .TestQU8();
1852   }
1853 }
1854 
1855 /**************************** GAVGPOOL path, unipass, batched ****************************/
1856 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_image)1857 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_image) {
1858   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1859   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
1860   for (size_t channels = 1; channels <= 100; channels += 15) {
1861     AveragePoolingOperatorTester()
1862       .batch_size(2)
1863       .input_height(pooling_size.first)
1864       .input_width(pooling_size.second)
1865       .pooling_height(pooling_size.first)
1866       .pooling_width(pooling_size.second)
1867       .channels(channels)
1868       .TestQU8();
1869     AveragePoolingOperatorTester()
1870       .batch_size(2)
1871       .input_height(pooling_size.second)
1872       .input_width(pooling_size.first)
1873       .pooling_height(pooling_size.second)
1874       .pooling_width(pooling_size.first)
1875       .channels(channels)
1876       .TestQU8();
1877   }
1878 }
1879 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_image_with_width_padding)1880 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_image_with_width_padding) {
1881   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1882   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
1883   for (size_t channels = 1; channels <= 100; channels += 15) {
1884     /* With left padding */
1885     AveragePoolingOperatorTester()
1886       .batch_size(2)
1887       .input_height(pooling_size.first)
1888       .input_width(pooling_size.second - 1)
1889       .padding_left(1)
1890       .pooling_height(pooling_size.first)
1891       .pooling_width(pooling_size.second)
1892       .channels(channels)
1893       .TestQU8();
1894     AveragePoolingOperatorTester()
1895       .batch_size(2)
1896       .input_height(pooling_size.second)
1897       .input_width(pooling_size.first - 1)
1898       .padding_left(1)
1899       .pooling_height(pooling_size.second)
1900       .pooling_width(pooling_size.first)
1901       .channels(channels)
1902       .TestQU8();
1903 
1904     /* With right padding */
1905     AveragePoolingOperatorTester()
1906       .batch_size(2)
1907       .input_height(pooling_size.first)
1908       .input_width(pooling_size.second - 1)
1909       .padding_right(1)
1910       .pooling_height(pooling_size.first)
1911       .pooling_width(pooling_size.second)
1912       .channels(channels)
1913       .TestQU8();
1914     AveragePoolingOperatorTester()
1915       .batch_size(2)
1916       .input_height(pooling_size.second)
1917       .input_width(pooling_size.first - 1)
1918       .padding_right(1)
1919       .pooling_height(pooling_size.second)
1920       .pooling_width(pooling_size.first)
1921       .channels(channels)
1922       .TestQU8();
1923   }
1924 }
1925 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_image_with_height_padding)1926 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_image_with_height_padding) {
1927   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1928   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
1929   for (size_t channels = 1; channels <= 100; channels += 15) {
1930     /* With top padding */
1931     AveragePoolingOperatorTester()
1932       .batch_size(2)
1933       .input_height(pooling_size.first - 1)
1934       .input_width(pooling_size.second)
1935       .padding_top(1)
1936       .pooling_height(pooling_size.first)
1937       .pooling_width(pooling_size.second)
1938       .channels(channels)
1939       .TestQU8();
1940     AveragePoolingOperatorTester()
1941       .batch_size(2)
1942       .input_height(pooling_size.second - 1)
1943       .input_width(pooling_size.first)
1944       .padding_top(1)
1945       .pooling_height(pooling_size.second)
1946       .pooling_width(pooling_size.first)
1947       .channels(channels)
1948       .TestQU8();
1949 
1950     /* With bottom padding */
1951     AveragePoolingOperatorTester()
1952       .batch_size(2)
1953       .input_height(pooling_size.first - 1)
1954       .input_width(pooling_size.second)
1955       .padding_bottom(1)
1956       .pooling_height(pooling_size.first)
1957       .pooling_width(pooling_size.second)
1958       .channels(channels)
1959       .TestQU8();
1960     AveragePoolingOperatorTester()
1961       .batch_size(2)
1962       .input_height(pooling_size.second - 1)
1963       .input_width(pooling_size.first)
1964       .padding_bottom(1)
1965       .pooling_height(pooling_size.second)
1966       .pooling_width(pooling_size.first)
1967       .channels(channels)
1968       .TestQU8();
1969   }
1970 }
1971 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_image_with_input_stride)1972 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_image_with_input_stride) {
1973   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1974   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
1975   for (size_t channels = 1; channels <= 100; channels += 15) {
1976     AveragePoolingOperatorTester()
1977       .batch_size(2)
1978       .input_height(pooling_size.first)
1979       .input_width(pooling_size.second)
1980       .pooling_height(pooling_size.first)
1981       .pooling_width(pooling_size.second)
1982       .channels(channels)
1983       .input_pixel_stride(2 * channels + 3)
1984       .TestQU8();
1985     AveragePoolingOperatorTester()
1986       .batch_size(2)
1987       .input_height(pooling_size.second)
1988       .input_width(pooling_size.first)
1989       .pooling_height(pooling_size.second)
1990       .pooling_width(pooling_size.first)
1991       .channels(channels)
1992       .input_pixel_stride(2 * channels + 3)
1993       .TestQU8();
1994   }
1995 }
1996 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_image_with_output_stride)1997 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_image_with_output_stride) {
1998   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
1999   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
2000   for (size_t channels = 1; channels <= 100; channels += 15) {
2001     AveragePoolingOperatorTester()
2002       .batch_size(2)
2003       .input_height(pooling_size.first)
2004       .input_width(pooling_size.second)
2005       .pooling_height(pooling_size.first)
2006       .pooling_width(pooling_size.second)
2007       .channels(channels)
2008       .output_pixel_stride(2 * channels + 3)
2009       .TestQU8();
2010     AveragePoolingOperatorTester()
2011       .batch_size(2)
2012       .input_height(pooling_size.second)
2013       .input_width(pooling_size.first)
2014       .pooling_height(pooling_size.second)
2015       .pooling_width(pooling_size.first)
2016       .channels(channels)
2017       .output_pixel_stride(2 * channels + 3)
2018       .TestQU8();
2019   }
2020 }
2021 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_image_with_input_scale)2022 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_image_with_input_scale) {
2023   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2024   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
2025   for (size_t channels = 1; channels <= 100; channels += 15) {
2026     for (float input_scale = 0.01f; input_scale < 100.0f; input_scale *= 3.14159265f) {
2027       AveragePoolingOperatorTester()
2028         .batch_size(2)
2029         .input_height(pooling_size.first)
2030         .input_width(pooling_size.second)
2031         .pooling_height(pooling_size.first)
2032         .pooling_width(pooling_size.second)
2033         .channels(channels)
2034         .input_scale(input_scale)
2035         .TestQU8();
2036       AveragePoolingOperatorTester()
2037         .batch_size(2)
2038         .input_height(pooling_size.second)
2039         .input_width(pooling_size.first)
2040         .pooling_height(pooling_size.second)
2041         .pooling_width(pooling_size.first)
2042         .channels(channels)
2043         .input_scale(input_scale)
2044         .TestQU8();
2045     }
2046   }
2047 }
2048 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_image_with_input_zero_point)2049 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_image_with_input_zero_point) {
2050   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2051   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
2052   for (size_t channels = 1; channels <= 100; channels += 15) {
2053     for (int32_t input_zero_point = 0; input_zero_point <= 255; input_zero_point += 51) {
2054       AveragePoolingOperatorTester()
2055         .batch_size(2)
2056         .input_height(pooling_size.first)
2057         .input_width(pooling_size.second)
2058         .pooling_height(pooling_size.first)
2059         .pooling_width(pooling_size.second)
2060         .channels(channels)
2061         .input_zero_point(uint8_t(input_zero_point))
2062         .TestQU8();
2063       AveragePoolingOperatorTester()
2064         .batch_size(2)
2065         .input_height(pooling_size.second)
2066         .input_width(pooling_size.first)
2067         .pooling_height(pooling_size.second)
2068         .pooling_width(pooling_size.first)
2069         .channels(channels)
2070         .input_zero_point(uint8_t(input_zero_point))
2071         .TestQU8();
2072     }
2073   }
2074 }
2075 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_image_with_output_scale)2076 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_image_with_output_scale) {
2077   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2078   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
2079   for (size_t channels = 1; channels <= 100; channels += 15) {
2080     for (float output_scale = 0.01f; output_scale < 100.0f; output_scale *= 3.14159265f) {
2081       AveragePoolingOperatorTester()
2082         .batch_size(2)
2083         .input_height(pooling_size.first)
2084         .input_width(pooling_size.second)
2085         .pooling_height(pooling_size.first)
2086         .pooling_width(pooling_size.second)
2087         .channels(channels)
2088         .output_scale(output_scale)
2089         .TestQU8();
2090       AveragePoolingOperatorTester()
2091         .batch_size(2)
2092         .input_height(pooling_size.second)
2093         .input_width(pooling_size.first)
2094         .pooling_height(pooling_size.second)
2095         .pooling_width(pooling_size.first)
2096         .channels(channels)
2097         .output_scale(output_scale)
2098         .TestQU8();
2099     }
2100   }
2101 }
2102 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_image_with_output_zero_point)2103 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_image_with_output_zero_point) {
2104   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2105   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
2106   for (size_t channels = 1; channels <= 100; channels += 15) {
2107     for (int32_t output_zero_point = 0; output_zero_point <= 255; output_zero_point += 51) {
2108       AveragePoolingOperatorTester()
2109         .batch_size(2)
2110         .input_height(pooling_size.first)
2111         .input_width(pooling_size.second)
2112         .pooling_height(pooling_size.first)
2113         .pooling_width(pooling_size.second)
2114         .channels(channels)
2115         .output_zero_point(uint8_t(output_zero_point))
2116         .TestQU8();
2117       AveragePoolingOperatorTester()
2118         .batch_size(2)
2119         .input_height(pooling_size.second)
2120         .input_width(pooling_size.first)
2121         .pooling_height(pooling_size.second)
2122         .pooling_width(pooling_size.first)
2123         .channels(channels)
2124         .output_zero_point(uint8_t(output_zero_point))
2125         .TestQU8();
2126     }
2127   }
2128 }
2129 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_image_with_qmin)2130 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_image_with_qmin) {
2131   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2132   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
2133   for (size_t channels = 1; channels <= 100; channels += 15) {
2134     AveragePoolingOperatorTester()
2135       .batch_size(2)
2136       .input_height(pooling_size.first)
2137       .input_width(pooling_size.second)
2138       .pooling_height(pooling_size.first)
2139       .pooling_width(pooling_size.second)
2140       .channels(channels)
2141       .qmin(128)
2142       .TestQU8();
2143     AveragePoolingOperatorTester()
2144       .batch_size(2)
2145       .input_height(pooling_size.second)
2146       .input_width(pooling_size.first)
2147       .pooling_height(pooling_size.second)
2148       .pooling_width(pooling_size.first)
2149       .channels(channels)
2150       .qmin(128)
2151       .TestQU8();
2152   }
2153 }
2154 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_small_image_with_qmax)2155 TEST(AVERAGE_POOLING_NHWC_QU8, batched_small_image_with_qmax) {
2156   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2157   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.qu8.gavgpool.row_tile);
2158   for (size_t channels = 1; channels <= 100; channels += 15) {
2159     AveragePoolingOperatorTester()
2160       .batch_size(2)
2161       .input_height(pooling_size.first)
2162       .input_width(pooling_size.second)
2163       .pooling_height(pooling_size.first)
2164       .pooling_width(pooling_size.second)
2165       .channels(channels)
2166       .qmax(128)
2167       .TestQU8();
2168     AveragePoolingOperatorTester()
2169       .batch_size(2)
2170       .input_height(pooling_size.second)
2171       .input_width(pooling_size.first)
2172       .pooling_height(pooling_size.second)
2173       .pooling_width(pooling_size.first)
2174       .channels(channels)
2175       .qmax(128)
2176       .TestQU8();
2177   }
2178 }
2179 
2180 /**************************** GAVGPOOL path, multipass ****************************/
2181 
TEST(AVERAGE_POOLING_NHWC_QU8,large_image)2182 TEST(AVERAGE_POOLING_NHWC_QU8, large_image) {
2183   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2184   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2185   for (size_t channels = 1; channels <= 100; channels += 15) {
2186     AveragePoolingOperatorTester()
2187       .input_height(pooling_size.first)
2188       .input_width(pooling_size.second)
2189       .pooling_height(pooling_size.first)
2190       .pooling_width(pooling_size.second)
2191       .channels(channels)
2192       .TestQU8();
2193     AveragePoolingOperatorTester()
2194       .input_height(pooling_size.second)
2195       .input_width(pooling_size.first)
2196       .pooling_height(pooling_size.second)
2197       .pooling_width(pooling_size.first)
2198       .channels(channels)
2199       .TestQU8();
2200   }
2201 }
2202 
TEST(AVERAGE_POOLING_NHWC_QU8,large_image_with_width_padding)2203 TEST(AVERAGE_POOLING_NHWC_QU8, large_image_with_width_padding) {
2204   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2205   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2206   for (size_t channels = 1; channels <= 100; channels += 15) {
2207     for (size_t padding_left = 1; padding_left <= 2; padding_left++) {
2208       AveragePoolingOperatorTester()
2209         .input_height(pooling_size.first)
2210         .input_width(pooling_size.second - padding_left)
2211         .padding_left(padding_left)
2212         .pooling_height(pooling_size.first)
2213         .pooling_width(pooling_size.second)
2214         .channels(channels)
2215         .TestQU8();
2216       AveragePoolingOperatorTester()
2217         .input_height(pooling_size.second)
2218         .input_width(pooling_size.first - padding_left)
2219         .padding_left(padding_left)
2220         .pooling_height(pooling_size.second)
2221         .pooling_width(pooling_size.first)
2222         .channels(channels)
2223         .TestQU8();
2224     }
2225     for (size_t padding_right = 1; padding_right <= 2; padding_right++) {
2226       AveragePoolingOperatorTester()
2227         .input_height(pooling_size.first)
2228         .input_width(pooling_size.second - padding_right)
2229         .padding_right(padding_right)
2230         .pooling_height(pooling_size.first)
2231         .pooling_width(pooling_size.second)
2232         .channels(channels)
2233         .TestQU8();
2234       AveragePoolingOperatorTester()
2235         .input_height(pooling_size.second)
2236         .input_width(pooling_size.first - padding_right)
2237         .padding_right(padding_right)
2238         .pooling_height(pooling_size.second)
2239         .pooling_width(pooling_size.first)
2240         .channels(channels)
2241         .TestQU8();
2242     }
2243   }
2244 }
2245 
TEST(AVERAGE_POOLING_NHWC_QU8,large_image_with_height_padding)2246 TEST(AVERAGE_POOLING_NHWC_QU8, large_image_with_height_padding) {
2247   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2248   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2249   for (size_t channels = 1; channels <= 100; channels += 15) {
2250     for (size_t padding_top = 1; padding_top <= 2; padding_top++) {
2251       AveragePoolingOperatorTester()
2252         .input_height(pooling_size.first - padding_top)
2253         .input_width(pooling_size.second)
2254         .padding_top(padding_top)
2255         .pooling_height(pooling_size.first)
2256         .pooling_width(pooling_size.second)
2257         .channels(channels)
2258         .TestQU8();
2259       AveragePoolingOperatorTester()
2260         .input_height(pooling_size.second - padding_top)
2261         .input_width(pooling_size.first)
2262         .padding_top(padding_top)
2263         .pooling_height(pooling_size.second)
2264         .pooling_width(pooling_size.first)
2265         .channels(channels)
2266         .TestQU8();
2267     }
2268     for (size_t padding_bottom = 0; padding_bottom <= 1; padding_bottom++) {
2269       AveragePoolingOperatorTester()
2270         .input_height(pooling_size.first - padding_bottom)
2271         .input_width(pooling_size.second)
2272         .padding_bottom(padding_bottom)
2273         .pooling_height(pooling_size.first)
2274         .pooling_width(pooling_size.second)
2275         .channels(channels)
2276         .TestQU8();
2277       AveragePoolingOperatorTester()
2278         .input_height(pooling_size.second - padding_bottom)
2279         .input_width(pooling_size.first)
2280         .padding_bottom(padding_bottom)
2281         .pooling_height(pooling_size.second)
2282         .pooling_width(pooling_size.first)
2283         .channels(channels)
2284         .TestQU8();
2285     }
2286   }
2287 }
2288 
TEST(AVERAGE_POOLING_NHWC_QU8,large_image_with_input_stride)2289 TEST(AVERAGE_POOLING_NHWC_QU8, large_image_with_input_stride) {
2290   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2291   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2292   for (size_t channels = 1; channels <= 100; channels += 15) {
2293     AveragePoolingOperatorTester()
2294       .input_height(pooling_size.first)
2295       .input_width(pooling_size.second)
2296       .pooling_height(pooling_size.first)
2297       .pooling_width(pooling_size.second)
2298       .channels(channels)
2299       .input_pixel_stride(2 * channels + 3)
2300       .TestQU8();
2301     AveragePoolingOperatorTester()
2302       .input_height(pooling_size.second)
2303       .input_width(pooling_size.first)
2304       .pooling_height(pooling_size.second)
2305       .pooling_width(pooling_size.first)
2306       .channels(channels)
2307       .input_pixel_stride(2 * channels + 3)
2308       .TestQU8();
2309   }
2310 }
2311 
TEST(AVERAGE_POOLING_NHWC_QU8,large_image_with_output_stride)2312 TEST(AVERAGE_POOLING_NHWC_QU8, large_image_with_output_stride) {
2313   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2314   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2315   for (size_t channels = 1; channels <= 100; channels += 15) {
2316     AveragePoolingOperatorTester()
2317       .input_height(pooling_size.first)
2318       .input_width(pooling_size.second)
2319       .pooling_height(pooling_size.first)
2320       .pooling_width(pooling_size.second)
2321       .channels(channels)
2322       .output_pixel_stride(2 * channels + 3)
2323       .TestQU8();
2324     AveragePoolingOperatorTester()
2325       .input_height(pooling_size.second)
2326       .input_width(pooling_size.first)
2327       .pooling_height(pooling_size.second)
2328       .pooling_width(pooling_size.first)
2329       .channels(channels)
2330       .output_pixel_stride(2 * channels + 3)
2331       .TestQU8();
2332   }
2333 }
2334 
TEST(AVERAGE_POOLING_NHWC_QU8,large_image_with_input_scale)2335 TEST(AVERAGE_POOLING_NHWC_QU8, large_image_with_input_scale) {
2336   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2337   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2338   for (size_t channels = 1; channels <= 100; channels += 15) {
2339     for (float input_scale = 0.01f; input_scale < 100.0f; input_scale *= 3.14159265f) {
2340       AveragePoolingOperatorTester()
2341         .input_height(pooling_size.first)
2342         .input_width(pooling_size.second)
2343         .pooling_height(pooling_size.first)
2344         .pooling_width(pooling_size.second)
2345         .channels(channels)
2346         .input_scale(input_scale)
2347         .TestQU8();
2348       AveragePoolingOperatorTester()
2349         .input_height(pooling_size.second)
2350         .input_width(pooling_size.first)
2351         .pooling_height(pooling_size.second)
2352         .pooling_width(pooling_size.first)
2353         .channels(channels)
2354         .input_scale(input_scale)
2355         .TestQU8();
2356     }
2357   }
2358 }
2359 
TEST(AVERAGE_POOLING_NHWC_QU8,large_image_with_input_zero_point)2360 TEST(AVERAGE_POOLING_NHWC_QU8, large_image_with_input_zero_point) {
2361   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2362   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2363   for (size_t channels = 1; channels <= 100; channels += 15) {
2364     for (int32_t input_zero_point = 0; input_zero_point <= 255; input_zero_point += 51) {
2365       AveragePoolingOperatorTester()
2366         .input_height(pooling_size.first)
2367         .input_width(pooling_size.second)
2368         .pooling_height(pooling_size.first)
2369         .pooling_width(pooling_size.second)
2370         .channels(channels)
2371         .input_zero_point(uint8_t(input_zero_point))
2372         .TestQU8();
2373       AveragePoolingOperatorTester()
2374         .input_height(pooling_size.second)
2375         .input_width(pooling_size.first)
2376         .pooling_height(pooling_size.second)
2377         .pooling_width(pooling_size.first)
2378         .channels(channels)
2379         .input_zero_point(uint8_t(input_zero_point))
2380         .TestQU8();
2381     }
2382   }
2383 }
2384 
TEST(AVERAGE_POOLING_NHWC_QU8,large_image_with_output_scale)2385 TEST(AVERAGE_POOLING_NHWC_QU8, large_image_with_output_scale) {
2386   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2387   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2388   for (size_t channels = 1; channels <= 100; channels += 15) {
2389     for (float output_scale = 0.01f; output_scale < 100.0f; output_scale *= 3.14159265f) {
2390       AveragePoolingOperatorTester()
2391         .input_height(pooling_size.first)
2392         .input_width(pooling_size.second)
2393         .pooling_height(pooling_size.first)
2394         .pooling_width(pooling_size.second)
2395         .channels(channels)
2396         .output_scale(output_scale)
2397         .TestQU8();
2398       AveragePoolingOperatorTester()
2399         .input_height(pooling_size.second)
2400         .input_width(pooling_size.first)
2401         .pooling_height(pooling_size.second)
2402         .pooling_width(pooling_size.first)
2403         .channels(channels)
2404         .output_scale(output_scale)
2405         .TestQU8();
2406     }
2407   }
2408 }
2409 
TEST(AVERAGE_POOLING_NHWC_QU8,large_image_with_output_zero_point)2410 TEST(AVERAGE_POOLING_NHWC_QU8, large_image_with_output_zero_point) {
2411   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2412   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2413   for (size_t channels = 1; channels <= 100; channels += 15) {
2414     for (int32_t output_zero_point = 0; output_zero_point <= 255; output_zero_point += 51) {
2415       AveragePoolingOperatorTester()
2416         .input_height(pooling_size.first)
2417         .input_width(pooling_size.second)
2418         .pooling_height(pooling_size.first)
2419         .pooling_width(pooling_size.second)
2420         .channels(channels)
2421         .output_zero_point(uint8_t(output_zero_point))
2422         .TestQU8();
2423       AveragePoolingOperatorTester()
2424         .input_height(pooling_size.second)
2425         .input_width(pooling_size.first)
2426         .pooling_height(pooling_size.second)
2427         .pooling_width(pooling_size.first)
2428         .channels(channels)
2429         .output_zero_point(uint8_t(output_zero_point))
2430         .TestQU8();
2431     }
2432   }
2433 }
2434 
TEST(AVERAGE_POOLING_NHWC_QU8,large_image_with_qmin)2435 TEST(AVERAGE_POOLING_NHWC_QU8, large_image_with_qmin) {
2436   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2437   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2438   for (size_t channels = 1; channels <= 100; channels += 15) {
2439     AveragePoolingOperatorTester()
2440       .input_height(pooling_size.first)
2441       .input_width(pooling_size.second)
2442       .pooling_height(pooling_size.first)
2443       .pooling_width(pooling_size.second)
2444       .channels(channels)
2445       .qmin(128)
2446       .TestQU8();
2447     AveragePoolingOperatorTester()
2448       .input_height(pooling_size.second)
2449       .input_width(pooling_size.first)
2450       .pooling_height(pooling_size.second)
2451       .pooling_width(pooling_size.first)
2452       .channels(channels)
2453       .qmin(128)
2454       .TestQU8();
2455   }
2456 }
2457 
TEST(AVERAGE_POOLING_NHWC_QU8,large_image_with_qmax)2458 TEST(AVERAGE_POOLING_NHWC_QU8, large_image_with_qmax) {
2459   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2460   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2461   for (size_t channels = 1; channels <= 100; channels += 15) {
2462     AveragePoolingOperatorTester()
2463       .input_height(pooling_size.first)
2464       .input_width(pooling_size.second)
2465       .pooling_height(pooling_size.first)
2466       .pooling_width(pooling_size.second)
2467       .channels(channels)
2468       .qmax(128)
2469       .TestQU8();
2470     AveragePoolingOperatorTester()
2471       .input_height(pooling_size.second)
2472       .input_width(pooling_size.first)
2473       .pooling_height(pooling_size.second)
2474       .pooling_width(pooling_size.first)
2475       .channels(channels)
2476       .qmax(128)
2477       .TestQU8();
2478   }
2479 }
2480 
2481 /**************************** GAVGPOOL path, multipass, batched ****************************/
2482 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_image)2483 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_image) {
2484   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2485   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2486   for (size_t channels = 1; channels <= 100; channels += 15) {
2487     AveragePoolingOperatorTester()
2488       .batch_size(2)
2489       .input_height(pooling_size.first)
2490       .input_width(pooling_size.second)
2491       .pooling_height(pooling_size.first)
2492       .pooling_width(pooling_size.second)
2493       .channels(channels)
2494       .TestQU8();
2495     AveragePoolingOperatorTester()
2496       .batch_size(2)
2497       .input_height(pooling_size.second)
2498       .input_width(pooling_size.first)
2499       .pooling_height(pooling_size.second)
2500       .pooling_width(pooling_size.first)
2501       .channels(channels)
2502       .TestQU8();
2503   }
2504 }
2505 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_image_with_width_padding)2506 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_image_with_width_padding) {
2507   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2508   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2509   for (size_t channels = 1; channels <= 100; channels += 15) {
2510     for (size_t padding_left = 1; padding_left <= 2; padding_left++) {
2511       AveragePoolingOperatorTester()
2512         .batch_size(2)
2513         .input_height(pooling_size.first)
2514         .input_width(pooling_size.second - padding_left)
2515         .padding_left(padding_left)
2516         .pooling_height(pooling_size.first)
2517         .pooling_width(pooling_size.second)
2518         .channels(channels)
2519         .TestQU8();
2520       AveragePoolingOperatorTester()
2521         .batch_size(2)
2522         .input_height(pooling_size.second)
2523         .input_width(pooling_size.first - padding_left)
2524         .padding_left(padding_left)
2525         .pooling_height(pooling_size.second)
2526         .pooling_width(pooling_size.first)
2527         .channels(channels)
2528         .TestQU8();
2529     }
2530     for (size_t padding_right = 1; padding_right <= 2; padding_right++) {
2531       AveragePoolingOperatorTester()
2532         .batch_size(2)
2533         .input_height(pooling_size.first)
2534         .input_width(pooling_size.second - padding_right)
2535         .padding_right(padding_right)
2536         .pooling_height(pooling_size.first)
2537         .pooling_width(pooling_size.second)
2538         .channels(channels)
2539         .TestQU8();
2540       AveragePoolingOperatorTester()
2541         .batch_size(2)
2542         .input_height(pooling_size.second)
2543         .input_width(pooling_size.first - padding_right)
2544         .padding_right(padding_right)
2545         .pooling_height(pooling_size.second)
2546         .pooling_width(pooling_size.first)
2547         .channels(channels)
2548         .TestQU8();
2549     }
2550   }
2551 }
2552 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_image_with_height_padding)2553 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_image_with_height_padding) {
2554   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2555   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2556   for (size_t channels = 1; channels <= 100; channels += 15) {
2557     for (size_t padding_top = 1; padding_top <= 2; padding_top++) {
2558       AveragePoolingOperatorTester()
2559         .batch_size(2)
2560         .input_height(pooling_size.first - padding_top)
2561         .input_width(pooling_size.second)
2562         .padding_top(padding_top)
2563         .pooling_height(pooling_size.first)
2564         .pooling_width(pooling_size.second)
2565         .channels(channels)
2566         .TestQU8();
2567       AveragePoolingOperatorTester()
2568         .batch_size(2)
2569         .input_height(pooling_size.second - padding_top)
2570         .input_width(pooling_size.first)
2571         .padding_top(padding_top)
2572         .pooling_height(pooling_size.second)
2573         .pooling_width(pooling_size.first)
2574         .channels(channels)
2575         .TestQU8();
2576     }
2577     for (size_t padding_bottom = 1; padding_bottom <= 2; padding_bottom++) {
2578       AveragePoolingOperatorTester()
2579         .batch_size(2)
2580         .input_height(pooling_size.first - padding_bottom)
2581         .input_width(pooling_size.second)
2582         .padding_bottom(padding_bottom)
2583         .pooling_height(pooling_size.first)
2584         .pooling_width(pooling_size.second)
2585         .channels(channels)
2586         .TestQU8();
2587       AveragePoolingOperatorTester()
2588         .batch_size(2)
2589         .input_height(pooling_size.second - padding_bottom)
2590         .input_width(pooling_size.first)
2591         .padding_bottom(padding_bottom)
2592         .pooling_height(pooling_size.second)
2593         .pooling_width(pooling_size.first)
2594         .channels(channels)
2595         .TestQU8();
2596     }
2597   }
2598 }
2599 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_image_with_input_stride)2600 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_image_with_input_stride) {
2601   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2602   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2603   for (size_t channels = 1; channels <= 100; channels += 15) {
2604     AveragePoolingOperatorTester()
2605       .batch_size(2)
2606       .input_height(pooling_size.first)
2607       .input_width(pooling_size.second)
2608       .pooling_height(pooling_size.first)
2609       .pooling_width(pooling_size.second)
2610       .channels(channels)
2611       .input_pixel_stride(2 * channels + 3)
2612       .TestQU8();
2613     AveragePoolingOperatorTester()
2614       .batch_size(2)
2615       .input_height(pooling_size.second)
2616       .input_width(pooling_size.first)
2617       .pooling_height(pooling_size.second)
2618       .pooling_width(pooling_size.first)
2619       .channels(channels)
2620       .input_pixel_stride(2 * channels + 3)
2621       .TestQU8();
2622   }
2623 }
2624 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_image_with_output_stride)2625 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_image_with_output_stride) {
2626   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2627   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2628   for (size_t channels = 1; channels <= 100; channels += 15) {
2629     AveragePoolingOperatorTester()
2630       .batch_size(2)
2631       .input_height(pooling_size.first)
2632       .input_width(pooling_size.second)
2633       .pooling_height(pooling_size.first)
2634       .pooling_width(pooling_size.second)
2635       .channels(channels)
2636       .output_pixel_stride(2 * channels + 3)
2637       .TestQU8();
2638     AveragePoolingOperatorTester()
2639       .batch_size(2)
2640       .input_height(pooling_size.second)
2641       .input_width(pooling_size.first)
2642       .pooling_height(pooling_size.second)
2643       .pooling_width(pooling_size.first)
2644       .channels(channels)
2645       .output_pixel_stride(2 * channels + 3)
2646       .TestQU8();
2647   }
2648 }
2649 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_image_with_input_scale)2650 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_image_with_input_scale) {
2651   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2652   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2653   for (size_t channels = 1; channels <= 100; channels += 15) {
2654     for (float input_scale = 0.01f; input_scale < 100.0f; input_scale *= 3.14159265f) {
2655       AveragePoolingOperatorTester()
2656         .batch_size(2)
2657         .input_height(pooling_size.first)
2658         .input_width(pooling_size.second)
2659         .pooling_height(pooling_size.first)
2660         .pooling_width(pooling_size.second)
2661         .channels(channels)
2662         .input_scale(input_scale)
2663         .TestQU8();
2664       AveragePoolingOperatorTester()
2665         .batch_size(2)
2666         .input_height(pooling_size.second)
2667         .input_width(pooling_size.first)
2668         .pooling_height(pooling_size.second)
2669         .pooling_width(pooling_size.first)
2670         .channels(channels)
2671         .input_scale(input_scale)
2672         .TestQU8();
2673     }
2674   }
2675 }
2676 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_image_with_input_zero_point)2677 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_image_with_input_zero_point) {
2678   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2679   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2680   for (size_t channels = 1; channels <= 100; channels += 15) {
2681     for (int32_t input_zero_point = 0; input_zero_point <= 255; input_zero_point += 51) {
2682       AveragePoolingOperatorTester()
2683         .batch_size(2)
2684         .input_height(pooling_size.first)
2685         .input_width(pooling_size.second)
2686         .pooling_height(pooling_size.first)
2687         .pooling_width(pooling_size.second)
2688         .channels(channels)
2689         .input_zero_point(uint8_t(input_zero_point))
2690         .TestQU8();
2691       AveragePoolingOperatorTester()
2692         .batch_size(2)
2693         .input_height(pooling_size.second)
2694         .input_width(pooling_size.first)
2695         .pooling_height(pooling_size.second)
2696         .pooling_width(pooling_size.first)
2697         .channels(channels)
2698         .input_zero_point(uint8_t(input_zero_point))
2699         .TestQU8();
2700     }
2701   }
2702 }
2703 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_image_with_output_scale)2704 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_image_with_output_scale) {
2705   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2706   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2707   for (size_t channels = 1; channels <= 100; channels += 15) {
2708     for (float output_scale = 0.01f; output_scale < 100.0f; output_scale *= 3.14159265f) {
2709       AveragePoolingOperatorTester()
2710         .batch_size(2)
2711         .input_height(pooling_size.first)
2712         .input_width(pooling_size.second)
2713         .pooling_height(pooling_size.first)
2714         .pooling_width(pooling_size.second)
2715         .channels(channels)
2716         .output_scale(output_scale)
2717         .TestQU8();
2718       AveragePoolingOperatorTester()
2719         .batch_size(2)
2720         .input_height(pooling_size.second)
2721         .input_width(pooling_size.first)
2722         .pooling_height(pooling_size.second)
2723         .pooling_width(pooling_size.first)
2724         .channels(channels)
2725         .output_scale(output_scale)
2726         .TestQU8();
2727     }
2728   }
2729 }
2730 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_image_with_output_zero_point)2731 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_image_with_output_zero_point) {
2732   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2733   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2734   for (size_t channels = 1; channels <= 100; channels += 15) {
2735     for (int32_t output_zero_point = 0; output_zero_point <= 255; output_zero_point += 51) {
2736       AveragePoolingOperatorTester()
2737         .batch_size(2)
2738         .input_height(pooling_size.first)
2739         .input_width(pooling_size.second)
2740         .pooling_height(pooling_size.first)
2741         .pooling_width(pooling_size.second)
2742         .channels(channels)
2743         .output_zero_point(uint8_t(output_zero_point))
2744         .TestQU8();
2745       AveragePoolingOperatorTester()
2746         .batch_size(2)
2747         .input_height(pooling_size.second)
2748         .input_width(pooling_size.first)
2749         .pooling_height(pooling_size.second)
2750         .pooling_width(pooling_size.first)
2751         .channels(channels)
2752         .output_zero_point(uint8_t(output_zero_point))
2753         .TestQU8();
2754     }
2755   }
2756 }
2757 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_image_with_qmin)2758 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_image_with_qmin) {
2759   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2760   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2761   for (size_t channels = 1; channels <= 100; channels += 15) {
2762     AveragePoolingOperatorTester()
2763       .batch_size(2)
2764       .input_height(pooling_size.first)
2765       .input_width(pooling_size.second)
2766       .pooling_height(pooling_size.first)
2767       .pooling_width(pooling_size.second)
2768       .channels(channels)
2769       .qmin(128)
2770       .TestQU8();
2771     AveragePoolingOperatorTester()
2772       .batch_size(2)
2773       .input_height(pooling_size.second)
2774       .input_width(pooling_size.first)
2775       .pooling_height(pooling_size.second)
2776       .pooling_width(pooling_size.first)
2777       .channels(channels)
2778       .qmin(128)
2779       .TestQU8();
2780   }
2781 }
2782 
TEST(AVERAGE_POOLING_NHWC_QU8,batched_large_image_with_qmax)2783 TEST(AVERAGE_POOLING_NHWC_QU8, batched_large_image_with_qmax) {
2784   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2785   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.qu8.gavgpool.row_tile * 2);
2786   for (size_t channels = 1; channels <= 100; channels += 15) {
2787     AveragePoolingOperatorTester()
2788       .batch_size(2)
2789       .input_height(pooling_size.first)
2790       .input_width(pooling_size.second)
2791       .pooling_height(pooling_size.first)
2792       .pooling_width(pooling_size.second)
2793       .channels(channels)
2794       .qmax(128)
2795       .TestQU8();
2796     AveragePoolingOperatorTester()
2797       .batch_size(2)
2798       .input_height(pooling_size.second)
2799       .input_width(pooling_size.first)
2800       .pooling_height(pooling_size.second)
2801       .pooling_width(pooling_size.first)
2802       .channels(channels)
2803       .qmax(128)
2804       .TestQU8();
2805   }
2806 }
2807 
2808 /**************************** AVGPOOL path, setup ****************************/
2809 
TEST(AVERAGE_POOLING_NHWC_QU8,setup_increasing_batch)2810 TEST(AVERAGE_POOLING_NHWC_QU8, setup_increasing_batch) {
2811   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2812   AveragePoolingOperatorTester()
2813     .batch_size(2)
2814     .next_batch_size(5)
2815     .input_height(8)
2816     .input_width(8)
2817     .pooling_height(5)
2818     .pooling_width(3)
2819     .channels(24)
2820     .TestSetupQU8();
2821 }
2822 
TEST(AVERAGE_POOLING_NHWC_QU8,setup_decreasing_batch)2823 TEST(AVERAGE_POOLING_NHWC_QU8, setup_decreasing_batch) {
2824   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2825   AveragePoolingOperatorTester()
2826     .batch_size(5)
2827     .next_batch_size(2)
2828     .input_height(8)
2829     .input_width(8)
2830     .pooling_height(5)
2831     .pooling_width(3)
2832     .channels(24)
2833     .TestSetupQU8();
2834 }
2835 
TEST(AVERAGE_POOLING_NHWC_QU8,setup_changing_height)2836 TEST(AVERAGE_POOLING_NHWC_QU8, setup_changing_height) {
2837   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2838   AveragePoolingOperatorTester()
2839     .batch_size(2)
2840     .input_height(8)
2841     .input_width(8)
2842     .next_input_height(9)
2843     .pooling_height(5)
2844     .pooling_width(3)
2845     .channels(24)
2846     .TestSetupQU8();
2847   AveragePoolingOperatorTester()
2848     .batch_size(2)
2849     .input_height(8)
2850     .input_width(8)
2851     .next_input_height(7)
2852     .pooling_height(5)
2853     .pooling_width(3)
2854     .channels(24)
2855     .TestSetupQU8();
2856 }
2857 
TEST(AVERAGE_POOLING_NHWC_QU8,setup_changing_width)2858 TEST(AVERAGE_POOLING_NHWC_QU8, setup_changing_width) {
2859   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2860   AveragePoolingOperatorTester()
2861     .batch_size(2)
2862     .input_height(8)
2863     .input_width(8)
2864     .next_input_width(9)
2865     .pooling_height(5)
2866     .pooling_width(3)
2867     .channels(24)
2868     .TestSetupQU8();
2869   AveragePoolingOperatorTester()
2870     .batch_size(2)
2871     .input_height(8)
2872     .input_width(8)
2873     .next_input_width(7)
2874     .pooling_height(5)
2875     .pooling_width(3)
2876     .channels(24)
2877     .TestSetupQU8();
2878 }
2879 
TEST(AVERAGE_POOLING_NHWC_QU8,setup_swap_height_and_width)2880 TEST(AVERAGE_POOLING_NHWC_QU8, setup_swap_height_and_width) {
2881   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2882   AveragePoolingOperatorTester()
2883     .batch_size(2)
2884     .input_height(9)
2885     .input_width(8)
2886     .next_input_height(8)
2887     .next_input_width(9)
2888     .pooling_height(5)
2889     .pooling_width(3)
2890     .channels(24)
2891     .TestSetupQU8();
2892 }
2893 
TEST(AVERAGE_POOLING_NHWC_QU8,setup_local_to_global)2894 TEST(AVERAGE_POOLING_NHWC_QU8, setup_local_to_global) {
2895   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2896   AveragePoolingOperatorTester()
2897     .batch_size(2)
2898     .input_height(6)
2899     .input_width(5)
2900     .next_input_height(5)
2901     .next_input_width(3)
2902     .pooling_height(5)
2903     .pooling_width(3)
2904     .channels(24)
2905     .TestSetupQU8();
2906 }
2907 
TEST(AVERAGE_POOLING_NHWC_QU8,setup_global_to_local)2908 TEST(AVERAGE_POOLING_NHWC_QU8, setup_global_to_local) {
2909   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2910   AveragePoolingOperatorTester()
2911     .batch_size(2)
2912     .input_height(5)
2913     .input_width(3)
2914     .next_input_height(6)
2915     .next_input_width(5)
2916     .pooling_height(5)
2917     .pooling_width(3)
2918     .channels(24)
2919     .TestSetupQU8();
2920 }
2921 
2922 /**************************** AVGPOOL path, unipass ****************************/
2923 
TEST(AVERAGE_POOLING_NHWC_F16,small_pool)2924 TEST(AVERAGE_POOLING_NHWC_F16, small_pool) {
2925   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2926   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
2927   for (size_t channels = 1; channels <= 100; channels += 15) {
2928     AveragePoolingOperatorTester()
2929       .input_height(pooling_size.first + 3)
2930       .input_width(pooling_size.second + 2)
2931       .pooling_height(pooling_size.first)
2932       .pooling_width(pooling_size.second)
2933       .channels(channels)
2934       .TestF16();
2935     AveragePoolingOperatorTester()
2936       .input_height(pooling_size.second + 3)
2937       .input_width(pooling_size.first + 2)
2938       .pooling_height(pooling_size.second)
2939       .pooling_width(pooling_size.first)
2940       .channels(channels)
2941       .TestF16();
2942   }
2943 }
2944 
TEST(AVERAGE_POOLING_NHWC_F16,small_pool_with_stride)2945 TEST(AVERAGE_POOLING_NHWC_F16, small_pool_with_stride) {
2946   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2947   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
2948   for (size_t channels = 1; channels <= 100; channels += 15) {
2949     for (size_t stride_width = 1; stride_width <= 2; stride_width++) {
2950       for (size_t stride_height = 1; stride_height <= 2; stride_height++) {
2951         if (stride_width == 1 && stride_height == 1) {
2952           continue;
2953         }
2954 
2955         AveragePoolingOperatorTester()
2956           .input_height(pooling_size.first + 3)
2957           .input_width(pooling_size.second + 2)
2958           .pooling_height(pooling_size.first)
2959           .pooling_width(pooling_size.second)
2960           .stride_height(stride_height)
2961           .stride_width(stride_width)
2962           .channels(channels)
2963           .TestF16();
2964         AveragePoolingOperatorTester()
2965           .input_height(pooling_size.second + 3)
2966           .input_width(pooling_size.first + 2)
2967           .pooling_height(pooling_size.second)
2968           .pooling_width(pooling_size.first)
2969           .stride_height(stride_height)
2970           .stride_width(stride_width)
2971           .channels(channels)
2972           .TestF16();
2973       }
2974     }
2975   }
2976 }
2977 
TEST(AVERAGE_POOLING_NHWC_F16,small_pool_with_width_padding)2978 TEST(AVERAGE_POOLING_NHWC_F16, small_pool_with_width_padding) {
2979   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
2980   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
2981   for (size_t channels = 1; channels <= 100; channels += 15) {
2982     for (size_t stride = 1; stride <= 2; stride++) {
2983       for (size_t padding_left = 0; padding_left <= 1; padding_left++) {
2984         for (size_t padding_right = 0; padding_right <= 1; padding_right++) {
2985           AveragePoolingOperatorTester()
2986             .input_height(pooling_size.first + 3)
2987             .input_width(pooling_size.second + 2)
2988             .padding_left(padding_left)
2989             .padding_right(padding_right)
2990             .pooling_height(pooling_size.first)
2991             .pooling_width(pooling_size.second)
2992             .stride(stride)
2993             .channels(channels)
2994             .TestF16();
2995           AveragePoolingOperatorTester()
2996             .input_height(pooling_size.second + 3)
2997             .input_width(pooling_size.first + 2)
2998             .padding_left(padding_left)
2999             .padding_right(padding_right)
3000             .pooling_height(pooling_size.second)
3001             .pooling_width(pooling_size.first)
3002             .stride(stride)
3003             .channels(channels)
3004             .TestF16();
3005         }
3006       }
3007     }
3008   }
3009 }
3010 
TEST(AVERAGE_POOLING_NHWC_F16,small_pool_with_height_padding)3011 TEST(AVERAGE_POOLING_NHWC_F16, small_pool_with_height_padding) {
3012   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3013   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
3014   for (size_t channels = 1; channels <= 100; channels += 15) {
3015     for (size_t stride = 1; stride <= 2; stride++) {
3016       for (size_t padding_top = 0; padding_top <= 1; padding_top++) {
3017         for (size_t padding_bottom = 0; padding_bottom <= 1; padding_bottom++) {
3018           AveragePoolingOperatorTester()
3019             .input_height(pooling_size.first + 3)
3020             .input_width(pooling_size.second + 2)
3021             .padding_top(padding_top)
3022             .padding_bottom(padding_bottom)
3023             .pooling_height(pooling_size.first)
3024             .pooling_width(pooling_size.second)
3025             .stride(stride)
3026             .channels(channels)
3027             .TestF16();
3028           AveragePoolingOperatorTester()
3029             .input_height(pooling_size.second + 3)
3030             .input_width(pooling_size.first + 2)
3031             .padding_top(padding_top)
3032             .padding_bottom(padding_bottom)
3033             .pooling_height(pooling_size.second)
3034             .pooling_width(pooling_size.first)
3035             .stride(stride)
3036             .channels(channels)
3037             .TestF16();
3038         }
3039       }
3040     }
3041   }
3042 }
3043 
TEST(AVERAGE_POOLING_NHWC_F16,small_pool_with_tf_same_padding)3044 TEST(AVERAGE_POOLING_NHWC_F16, small_pool_with_tf_same_padding) {
3045   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3046   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
3047   for (size_t channels = 1; channels <= 100; channels += 15) {
3048     for (size_t stride = 1; stride <= 2; stride++) {
3049       for (size_t input_height = pooling_size.first + 3; input_height <= pooling_size.first + 4; input_height++) {
3050         AveragePoolingOperatorTester()
3051           .input_height(input_height)
3052           .input_width(pooling_size.second + 2)
3053           .padding_tf_same(true)
3054           .pooling_height(pooling_size.first)
3055           .pooling_width(pooling_size.second)
3056           .stride(stride)
3057           .channels(channels)
3058           .TestF16();
3059       }
3060       for (size_t input_width = pooling_size.second + 2; input_width <= pooling_size.second + 3; input_width++) {
3061         AveragePoolingOperatorTester()
3062           .input_height(pooling_size.first + 3)
3063           .input_width(input_width)
3064           .padding_tf_same(true)
3065           .pooling_height(pooling_size.first)
3066           .pooling_width(pooling_size.second)
3067           .stride(stride)
3068           .channels(channels)
3069           .TestF16();
3070       }
3071       for (size_t input_height = pooling_size.second + 3; input_height <= pooling_size.second + 4; input_height++) {
3072         AveragePoolingOperatorTester()
3073           .input_height(input_height)
3074           .input_width(pooling_size.first + 2)
3075           .padding_tf_same(true)
3076           .pooling_height(pooling_size.second)
3077           .pooling_width(pooling_size.first)
3078           .stride(stride)
3079           .channels(channels)
3080           .TestF16();
3081       }
3082       for (size_t input_width = pooling_size.first + 2; input_width <= pooling_size.first + 3; input_width++) {
3083         AveragePoolingOperatorTester()
3084           .input_height(pooling_size.second + 3)
3085           .input_width(input_width)
3086           .padding_tf_same(true)
3087           .pooling_height(pooling_size.second)
3088           .pooling_width(pooling_size.first)
3089           .stride(stride)
3090           .channels(channels)
3091           .TestF16();
3092       }
3093     }
3094   }
3095 }
3096 
TEST(AVERAGE_POOLING_NHWC_F16,small_pool_with_input_stride)3097 TEST(AVERAGE_POOLING_NHWC_F16, small_pool_with_input_stride) {
3098   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3099   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
3100   for (size_t channels = 1; channels <= 100; channels += 15) {
3101     AveragePoolingOperatorTester()
3102       .input_height(pooling_size.first + 3)
3103       .input_width(pooling_size.second + 2)
3104       .pooling_height(pooling_size.first)
3105       .pooling_width(pooling_size.second)
3106       .channels(channels)
3107       .input_pixel_stride(2 * channels + 3)
3108       .TestF16();
3109     AveragePoolingOperatorTester()
3110       .input_height(pooling_size.second + 3)
3111       .input_width(pooling_size.first + 2)
3112       .pooling_height(pooling_size.second)
3113       .pooling_width(pooling_size.first)
3114       .channels(channels)
3115       .input_pixel_stride(2 * channels + 3)
3116       .TestF16();
3117   }
3118 }
3119 
TEST(AVERAGE_POOLING_NHWC_F16,small_pool_with_output_stride)3120 TEST(AVERAGE_POOLING_NHWC_F16, small_pool_with_output_stride) {
3121   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3122   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
3123   for (size_t channels = 1; channels <= 100; channels += 15) {
3124     AveragePoolingOperatorTester()
3125       .input_height(pooling_size.first + 3)
3126       .input_width(pooling_size.second + 2)
3127       .pooling_height(pooling_size.first)
3128       .pooling_width(pooling_size.second)
3129       .channels(channels)
3130       .output_pixel_stride(2 * channels + 3)
3131       .TestF16();
3132     AveragePoolingOperatorTester()
3133       .input_height(pooling_size.second + 3)
3134       .input_width(pooling_size.first + 2)
3135       .pooling_height(pooling_size.second)
3136       .pooling_width(pooling_size.first)
3137       .channels(channels)
3138       .output_pixel_stride(2 * channels + 3)
3139       .TestF16();
3140   }
3141 }
3142 
TEST(AVERAGE_POOLING_NHWC_F16,small_pool_with_qmin)3143 TEST(AVERAGE_POOLING_NHWC_F16, small_pool_with_qmin) {
3144   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3145   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
3146   for (size_t channels = 1; channels <= 100; channels += 15) {
3147     AveragePoolingOperatorTester()
3148       .input_height(pooling_size.first + 3)
3149       .input_width(pooling_size.second + 2)
3150       .pooling_height(pooling_size.first)
3151       .pooling_width(pooling_size.second)
3152       .channels(channels)
3153       .qmin(128)
3154       .TestF16();
3155     AveragePoolingOperatorTester()
3156       .input_height(pooling_size.second + 3)
3157       .input_width(pooling_size.first + 2)
3158       .pooling_height(pooling_size.second)
3159       .pooling_width(pooling_size.first)
3160       .channels(channels)
3161       .qmin(128)
3162       .TestF16();
3163   }
3164 }
3165 
TEST(AVERAGE_POOLING_NHWC_F16,small_pool_with_qmax)3166 TEST(AVERAGE_POOLING_NHWC_F16, small_pool_with_qmax) {
3167   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3168   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
3169   for (size_t channels = 1; channels <= 100; channels += 15) {
3170     AveragePoolingOperatorTester()
3171       .input_height(pooling_size.first + 3)
3172       .input_width(pooling_size.second + 2)
3173       .pooling_height(pooling_size.first)
3174       .pooling_width(pooling_size.second)
3175       .channels(channels)
3176       .qmax(128)
3177       .TestF16();
3178     AveragePoolingOperatorTester()
3179       .input_height(pooling_size.second + 3)
3180       .input_width(pooling_size.first + 2)
3181       .pooling_height(pooling_size.second)
3182       .pooling_width(pooling_size.first)
3183       .channels(channels)
3184       .qmax(128)
3185       .TestF16();
3186   }
3187 }
3188 
3189 /**************************** AVGPOOL path, unipass, batched ****************************/
3190 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_pool)3191 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_pool) {
3192   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3193   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
3194   for (size_t channels = 1; channels <= 100; channels += 15) {
3195     AveragePoolingOperatorTester()
3196       .batch_size(2)
3197       .input_height(pooling_size.first + 3)
3198       .input_width(pooling_size.second + 2)
3199       .pooling_height(pooling_size.first)
3200       .pooling_width(pooling_size.second)
3201       .channels(channels)
3202       .TestF16();
3203     AveragePoolingOperatorTester()
3204       .batch_size(2)
3205       .input_height(pooling_size.second + 3)
3206       .input_width(pooling_size.first + 2)
3207       .pooling_height(pooling_size.second)
3208       .pooling_width(pooling_size.first)
3209       .channels(channels)
3210       .TestF16();
3211   }
3212 }
3213 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_pool_with_stride)3214 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_pool_with_stride) {
3215   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3216   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
3217   for (size_t channels = 1; channels <= 100; channels += 15) {
3218     for (size_t stride_width = 1; stride_width <= 2; stride_width++) {
3219       for (size_t stride_height = 1; stride_height <= 2; stride_height++) {
3220         if (stride_width == 1 && stride_height == 1) {
3221           continue;
3222         }
3223 
3224         AveragePoolingOperatorTester()
3225           .batch_size(2)
3226           .input_height(pooling_size.first + 3)
3227           .input_width(pooling_size.second + 2)
3228           .pooling_height(pooling_size.first)
3229           .pooling_width(pooling_size.second)
3230           .stride_height(stride_height)
3231           .stride_width(stride_width)
3232           .channels(channels)
3233           .TestF16();
3234         AveragePoolingOperatorTester()
3235           .batch_size(2)
3236           .input_height(pooling_size.second + 3)
3237           .input_width(pooling_size.first + 2)
3238           .pooling_height(pooling_size.second)
3239           .pooling_width(pooling_size.first)
3240           .stride_height(stride_height)
3241           .stride_width(stride_width)
3242           .channels(channels)
3243           .TestF16();
3244       }
3245     }
3246   }
3247 }
3248 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_pool_with_width_padding)3249 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_pool_with_width_padding) {
3250   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3251   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
3252   for (size_t channels = 1; channels <= 100; channels += 15) {
3253     for (size_t stride = 1; stride <= 2; stride++) {
3254       for (size_t padding_left = 0; padding_left <= 1; padding_left++) {
3255         for (size_t padding_right = 0; padding_right <= 1; padding_right++) {
3256           AveragePoolingOperatorTester()
3257             .batch_size(2)
3258             .input_height(pooling_size.first + 3)
3259             .input_width(pooling_size.second + 2)
3260             .padding_left(padding_left)
3261             .padding_right(padding_right)
3262             .pooling_height(pooling_size.first)
3263             .pooling_width(pooling_size.second)
3264             .stride(stride)
3265             .channels(channels)
3266             .TestF16();
3267           AveragePoolingOperatorTester()
3268             .batch_size(2)
3269             .input_height(pooling_size.second + 3)
3270             .input_width(pooling_size.first + 2)
3271             .padding_left(padding_left)
3272             .padding_right(padding_right)
3273             .pooling_height(pooling_size.second)
3274             .pooling_width(pooling_size.first)
3275             .stride(stride)
3276             .channels(channels)
3277             .TestF16();
3278         }
3279       }
3280     }
3281   }
3282 }
3283 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_pool_with_height_padding)3284 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_pool_with_height_padding) {
3285   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3286   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
3287   for (size_t channels = 1; channels <= 100; channels += 15) {
3288     for (size_t stride = 1; stride <= 2; stride++) {
3289       for (size_t padding_top = 0; padding_top <= 1; padding_top++) {
3290         for (size_t padding_bottom = 0; padding_bottom <= 1; padding_bottom++) {
3291           AveragePoolingOperatorTester()
3292             .batch_size(2)
3293             .input_height(pooling_size.first + 3)
3294             .input_width(pooling_size.second + 2)
3295             .padding_top(padding_top)
3296             .padding_bottom(padding_bottom)
3297             .pooling_height(pooling_size.first)
3298             .pooling_width(pooling_size.second)
3299             .stride(stride)
3300             .channels(channels)
3301             .TestF16();
3302           AveragePoolingOperatorTester()
3303             .batch_size(2)
3304             .input_height(pooling_size.second + 3)
3305             .input_width(pooling_size.first + 2)
3306             .padding_top(padding_top)
3307             .padding_bottom(padding_bottom)
3308             .pooling_height(pooling_size.second)
3309             .pooling_width(pooling_size.first)
3310             .stride(stride)
3311             .channels(channels)
3312             .TestF16();
3313         }
3314       }
3315     }
3316   }
3317 }
3318 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_pool_with_tf_same_padding)3319 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_pool_with_tf_same_padding) {
3320   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3321   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
3322   for (size_t channels = 1; channels <= 100; channels += 15) {
3323     for (size_t stride = 1; stride <= 2; stride++) {
3324       for (size_t input_height = pooling_size.first + 3; input_height <= pooling_size.first + 4; input_height++) {
3325         AveragePoolingOperatorTester()
3326           .batch_size(2)
3327           .input_height(input_height)
3328           .input_width(pooling_size.second + 2)
3329           .padding_tf_same(true)
3330           .pooling_height(pooling_size.first)
3331           .pooling_width(pooling_size.second)
3332           .stride(stride)
3333           .channels(channels)
3334           .TestF16();
3335       }
3336       for (size_t input_width = pooling_size.second + 2; input_width <= pooling_size.second + 3; input_width++) {
3337         AveragePoolingOperatorTester()
3338           .batch_size(2)
3339           .input_height(pooling_size.first + 3)
3340           .input_width(input_width)
3341           .padding_tf_same(true)
3342           .pooling_height(pooling_size.first)
3343           .pooling_width(pooling_size.second)
3344           .stride(stride)
3345           .channels(channels)
3346           .TestF16();
3347       }
3348       for (size_t input_height = pooling_size.second + 3; input_height <= pooling_size.second + 4; input_height++) {
3349         AveragePoolingOperatorTester()
3350           .batch_size(2)
3351           .input_height(input_height)
3352           .input_width(pooling_size.first + 2)
3353           .padding_tf_same(true)
3354           .pooling_height(pooling_size.second)
3355           .pooling_width(pooling_size.first)
3356           .stride(stride)
3357           .channels(channels)
3358           .TestF16();
3359       }
3360       for (size_t input_width = pooling_size.first + 2; input_width <= pooling_size.first + 3; input_width++) {
3361         AveragePoolingOperatorTester()
3362           .batch_size(2)
3363           .input_height(pooling_size.second + 3)
3364           .input_width(input_width)
3365           .padding_tf_same(true)
3366           .pooling_height(pooling_size.second)
3367           .pooling_width(pooling_size.first)
3368           .stride(stride)
3369           .channels(channels)
3370           .TestF16();
3371       }
3372     }
3373   }
3374 }
3375 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_pool_with_input_stride)3376 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_pool_with_input_stride) {
3377   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3378   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
3379   for (size_t channels = 1; channels <= 100; channels += 15) {
3380     AveragePoolingOperatorTester()
3381       .batch_size(2)
3382       .input_height(pooling_size.first + 3)
3383       .input_width(pooling_size.second + 2)
3384       .pooling_height(pooling_size.first)
3385       .pooling_width(pooling_size.second)
3386       .channels(channels)
3387       .input_pixel_stride(2 * channels + 3)
3388       .TestF16();
3389     AveragePoolingOperatorTester()
3390       .batch_size(2)
3391       .input_height(pooling_size.second + 3)
3392       .input_width(pooling_size.first + 2)
3393       .pooling_height(pooling_size.second)
3394       .pooling_width(pooling_size.first)
3395       .channels(channels)
3396       .input_pixel_stride(2 * channels + 3)
3397       .TestF16();
3398   }
3399 }
3400 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_pool_with_output_stride)3401 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_pool_with_output_stride) {
3402   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3403   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
3404   for (size_t channels = 1; channels <= 100; channels += 15) {
3405     AveragePoolingOperatorTester()
3406       .batch_size(2)
3407       .input_height(pooling_size.first + 3)
3408       .input_width(pooling_size.second + 2)
3409       .pooling_height(pooling_size.first)
3410       .pooling_width(pooling_size.second)
3411       .channels(channels)
3412       .output_pixel_stride(2 * channels + 3)
3413       .TestF16();
3414     AveragePoolingOperatorTester()
3415       .batch_size(2)
3416       .input_height(pooling_size.second + 3)
3417       .input_width(pooling_size.first + 2)
3418       .pooling_height(pooling_size.second)
3419       .pooling_width(pooling_size.first)
3420       .channels(channels)
3421       .output_pixel_stride(2 * channels + 3)
3422       .TestF16();
3423   }
3424 }
3425 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_pool_with_qmin)3426 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_pool_with_qmin) {
3427   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3428   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
3429   for (size_t channels = 1; channels <= 100; channels += 15) {
3430     AveragePoolingOperatorTester()
3431       .batch_size(2)
3432       .input_height(pooling_size.first + 3)
3433       .input_width(pooling_size.second + 2)
3434       .pooling_height(pooling_size.first)
3435       .pooling_width(pooling_size.second)
3436       .channels(channels)
3437       .qmin(128)
3438       .TestF16();
3439     AveragePoolingOperatorTester()
3440       .batch_size(2)
3441       .input_height(pooling_size.second + 3)
3442       .input_width(pooling_size.first + 2)
3443       .pooling_height(pooling_size.second)
3444       .pooling_width(pooling_size.first)
3445       .channels(channels)
3446       .qmin(128)
3447       .TestF16();
3448   }
3449 }
3450 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_pool_with_qmax)3451 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_pool_with_qmax) {
3452   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3453   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
3454   for (size_t channels = 1; channels <= 100; channels += 15) {
3455     AveragePoolingOperatorTester()
3456       .batch_size(2)
3457       .input_height(pooling_size.first + 3)
3458       .input_width(pooling_size.second + 2)
3459       .pooling_height(pooling_size.first)
3460       .pooling_width(pooling_size.second)
3461       .channels(channels)
3462       .qmax(128)
3463       .TestF16();
3464     AveragePoolingOperatorTester()
3465       .batch_size(2)
3466       .input_height(pooling_size.second + 3)
3467       .input_width(pooling_size.first + 2)
3468       .pooling_height(pooling_size.second)
3469       .pooling_width(pooling_size.first)
3470       .channels(channels)
3471       .qmax(128)
3472       .TestF16();
3473   }
3474 }
3475 
3476 /**************************** AVGPOOL path, multipass ****************************/
3477 
TEST(AVERAGE_POOLING_NHWC_F16,large_pool)3478 TEST(AVERAGE_POOLING_NHWC_F16, large_pool) {
3479   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3480   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.avgpool.primary_tile * 2);
3481   for (size_t channels = 1; channels <= 100; channels += 15) {
3482     AveragePoolingOperatorTester()
3483       .input_height(pooling_size.first + 3)
3484       .input_width(pooling_size.second + 2)
3485       .pooling_height(pooling_size.first)
3486       .pooling_width(pooling_size.second)
3487       .channels(channels)
3488       .TestF16();
3489     AveragePoolingOperatorTester()
3490       .input_height(pooling_size.second + 3)
3491       .input_width(pooling_size.first + 2)
3492       .pooling_height(pooling_size.second)
3493       .pooling_width(pooling_size.first)
3494       .channels(channels)
3495       .TestF16();
3496   }
3497 }
3498 
TEST(AVERAGE_POOLING_NHWC_F16,large_pool_with_stride)3499 TEST(AVERAGE_POOLING_NHWC_F16, large_pool_with_stride) {
3500   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3501   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
3502   for (size_t channels = 1; channels <= 100; channels += 15) {
3503     for (size_t stride_width = 1; stride_width <= 2; stride_width++) {
3504       for (size_t stride_height = 1; stride_height <= 2; stride_height++) {
3505         if (stride_width == 1 && stride_height == 1) {
3506           continue;
3507         }
3508 
3509         AveragePoolingOperatorTester()
3510           .input_height(pooling_size.first + 3)
3511           .input_width(pooling_size.second + 2)
3512           .pooling_height(pooling_size.first)
3513           .pooling_width(pooling_size.second)
3514           .stride_height(stride_height)
3515           .stride_width(stride_width)
3516           .channels(channels)
3517           .TestF16();
3518         AveragePoolingOperatorTester()
3519           .input_height(pooling_size.second + 3)
3520           .input_width(pooling_size.first + 2)
3521           .pooling_height(pooling_size.second)
3522           .pooling_width(pooling_size.first)
3523           .stride_height(stride_height)
3524           .stride_width(stride_width)
3525           .channels(channels)
3526           .TestF16();
3527       }
3528     }
3529   }
3530 }
3531 
TEST(AVERAGE_POOLING_NHWC_F16,large_pool_with_width_padding)3532 TEST(AVERAGE_POOLING_NHWC_F16, large_pool_with_width_padding) {
3533   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3534   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
3535   for (size_t channels = 1; channels <= 100; channels += 15) {
3536     for (size_t stride = 1; stride <= 2; stride++) {
3537       for (size_t padding_left = 1; padding_left <= 2; padding_left++) {
3538         AveragePoolingOperatorTester()
3539           .input_height(pooling_size.first + 3)
3540           .input_width(pooling_size.second + 2)
3541           .padding_left(padding_left)
3542           .pooling_height(pooling_size.first)
3543           .pooling_width(pooling_size.second)
3544           .stride(stride)
3545           .channels(channels)
3546           .TestF16();
3547         AveragePoolingOperatorTester()
3548           .input_height(pooling_size.second + 3)
3549           .input_width(pooling_size.first + 2)
3550           .padding_left(padding_left)
3551           .pooling_height(pooling_size.second)
3552           .pooling_width(pooling_size.first)
3553           .stride(stride)
3554           .channels(channels)
3555           .TestF16();
3556       }
3557       for (size_t padding_right = 1; padding_right <= 2; padding_right++) {
3558         AveragePoolingOperatorTester()
3559           .input_height(pooling_size.first + 3)
3560           .input_width(pooling_size.second + 2)
3561           .padding_right(padding_right)
3562           .pooling_height(pooling_size.first)
3563           .pooling_width(pooling_size.second)
3564           .stride(stride)
3565           .channels(channels)
3566           .TestF16();
3567         AveragePoolingOperatorTester()
3568           .input_height(pooling_size.second + 3)
3569           .input_width(pooling_size.first + 2)
3570           .padding_right(padding_right)
3571           .pooling_height(pooling_size.second)
3572           .pooling_width(pooling_size.first)
3573           .stride(stride)
3574           .channels(channels)
3575           .TestF16();
3576       }
3577     }
3578   }
3579 }
3580 
TEST(AVERAGE_POOLING_NHWC_F16,large_pool_with_height_padding)3581 TEST(AVERAGE_POOLING_NHWC_F16, large_pool_with_height_padding) {
3582   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3583   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
3584   for (size_t channels = 1; channels <= 100; channels += 15) {
3585     for (size_t stride = 1; stride <= 2; stride++) {
3586       for (size_t padding_top = 0; padding_top <= 1; padding_top++) {
3587         for (size_t padding_bottom = 0; padding_bottom <= 1; padding_bottom++) {
3588           AveragePoolingOperatorTester()
3589             .input_height(pooling_size.first + 3)
3590             .input_width(pooling_size.second + 2)
3591             .padding_top(padding_top)
3592             .padding_bottom(padding_bottom)
3593             .pooling_height(pooling_size.first)
3594             .pooling_width(pooling_size.second)
3595             .stride(stride)
3596             .channels(channels)
3597             .TestF16();
3598           AveragePoolingOperatorTester()
3599             .input_height(pooling_size.second + 3)
3600             .input_width(pooling_size.first + 2)
3601             .padding_top(padding_top)
3602             .padding_bottom(padding_bottom)
3603             .pooling_height(pooling_size.second)
3604             .pooling_width(pooling_size.first)
3605             .stride(stride)
3606             .channels(channels)
3607             .TestF16();
3608         }
3609       }
3610     }
3611   }
3612 }
3613 
TEST(AVERAGE_POOLING_NHWC_F16,large_pool_with_tf_same_padding)3614 TEST(AVERAGE_POOLING_NHWC_F16, large_pool_with_tf_same_padding) {
3615   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3616   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
3617   for (size_t channels = 1; channels <= 100; channels += 15) {
3618     for (size_t stride = 1; stride <= 2; stride++) {
3619       for (size_t input_height = pooling_size.first + 3; input_height <= pooling_size.first + 4; input_height++) {
3620         AveragePoolingOperatorTester()
3621           .input_height(input_height)
3622           .input_width(pooling_size.second + 2)
3623           .padding_tf_same(true)
3624           .pooling_height(pooling_size.first)
3625           .pooling_width(pooling_size.second)
3626           .stride(stride)
3627           .channels(channels)
3628           .TestF16();
3629       }
3630       for (size_t input_width = pooling_size.second + 2; input_width <= pooling_size.second + 3; input_width++) {
3631         AveragePoolingOperatorTester()
3632           .input_height(pooling_size.first + 3)
3633           .input_width(input_width)
3634           .padding_tf_same(true)
3635           .pooling_height(pooling_size.first)
3636           .pooling_width(pooling_size.second)
3637           .stride(stride)
3638           .channels(channels)
3639           .TestF16();
3640       }
3641       for (size_t input_height = pooling_size.second + 3; input_height <= pooling_size.second + 4; input_height++) {
3642         AveragePoolingOperatorTester()
3643           .input_height(input_height)
3644           .input_width(pooling_size.first + 2)
3645           .padding_tf_same(true)
3646           .pooling_height(pooling_size.second)
3647           .pooling_width(pooling_size.first)
3648           .stride(stride)
3649           .channels(channels)
3650           .TestF16();
3651       }
3652       for (size_t input_width = pooling_size.first + 2; input_width <= pooling_size.first + 3; input_width++) {
3653         AveragePoolingOperatorTester()
3654           .input_height(pooling_size.second + 3)
3655           .input_width(input_width)
3656           .padding_tf_same(true)
3657           .pooling_height(pooling_size.second)
3658           .pooling_width(pooling_size.first)
3659           .stride(stride)
3660           .channels(channels)
3661           .TestF16();
3662       }
3663     }
3664   }
3665 }
3666 
TEST(AVERAGE_POOLING_NHWC_F16,large_pool_with_input_stride)3667 TEST(AVERAGE_POOLING_NHWC_F16, large_pool_with_input_stride) {
3668   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3669   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
3670   for (size_t channels = 1; channels <= 100; channels += 15) {
3671     AveragePoolingOperatorTester()
3672       .input_height(pooling_size.first + 3)
3673       .input_width(pooling_size.second + 2)
3674       .pooling_height(pooling_size.first)
3675       .pooling_width(pooling_size.second)
3676       .channels(channels)
3677       .input_pixel_stride(2 * channels + 3)
3678       .TestF16();
3679     AveragePoolingOperatorTester()
3680       .input_height(pooling_size.second + 3)
3681       .input_width(pooling_size.first + 2)
3682       .pooling_height(pooling_size.second)
3683       .pooling_width(pooling_size.first)
3684       .channels(channels)
3685       .input_pixel_stride(2 * channels + 3)
3686       .TestF16();
3687   }
3688 }
3689 
TEST(AVERAGE_POOLING_NHWC_F16,large_pool_with_output_stride)3690 TEST(AVERAGE_POOLING_NHWC_F16, large_pool_with_output_stride) {
3691   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3692   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
3693   for (size_t channels = 1; channels <= 100; channels += 15) {
3694     AveragePoolingOperatorTester()
3695       .input_height(pooling_size.first + 3)
3696       .input_width(pooling_size.second + 2)
3697       .pooling_height(pooling_size.first)
3698       .pooling_width(pooling_size.second)
3699       .channels(channels)
3700       .output_pixel_stride(2 * channels + 3)
3701       .TestF16();
3702     AveragePoolingOperatorTester()
3703       .input_height(pooling_size.second + 3)
3704       .input_width(pooling_size.first + 2)
3705       .pooling_height(pooling_size.second)
3706       .pooling_width(pooling_size.first)
3707       .channels(channels)
3708       .output_pixel_stride(2 * channels + 3)
3709       .TestF16();
3710   }
3711 }
3712 
TEST(AVERAGE_POOLING_NHWC_F16,large_pool_with_qmin)3713 TEST(AVERAGE_POOLING_NHWC_F16, large_pool_with_qmin) {
3714   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3715   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
3716   for (size_t channels = 1; channels <= 100; channels += 15) {
3717     AveragePoolingOperatorTester()
3718       .input_height(pooling_size.first + 3)
3719       .input_width(pooling_size.second + 2)
3720       .pooling_height(pooling_size.first)
3721       .pooling_width(pooling_size.second)
3722       .channels(channels)
3723       .qmin(128)
3724       .TestF16();
3725     AveragePoolingOperatorTester()
3726       .input_height(pooling_size.second + 3)
3727       .input_width(pooling_size.first + 2)
3728       .pooling_height(pooling_size.second)
3729       .pooling_width(pooling_size.first)
3730       .channels(channels)
3731       .qmin(128)
3732       .TestF16();
3733   }
3734 }
3735 
TEST(AVERAGE_POOLING_NHWC_F16,large_pool_with_qmax)3736 TEST(AVERAGE_POOLING_NHWC_F16, large_pool_with_qmax) {
3737   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3738   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
3739   for (size_t channels = 1; channels <= 100; channels += 15) {
3740     AveragePoolingOperatorTester()
3741       .input_height(pooling_size.first + 3)
3742       .input_width(pooling_size.second + 2)
3743       .pooling_height(pooling_size.first)
3744       .pooling_width(pooling_size.second)
3745       .channels(channels)
3746       .qmax(128)
3747       .TestF16();
3748     AveragePoolingOperatorTester()
3749       .input_height(pooling_size.second + 3)
3750       .input_width(pooling_size.first + 2)
3751       .pooling_height(pooling_size.second)
3752       .pooling_width(pooling_size.first)
3753       .channels(channels)
3754       .qmax(128)
3755       .TestF16();
3756   }
3757 }
3758 
3759 /**************************** AVGPOOL path, multipass, batched ****************************/
3760 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_pool)3761 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_pool) {
3762   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3763   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.avgpool.primary_tile * 2);
3764   for (size_t channels = 1; channels <= 100; channels += 15) {
3765     AveragePoolingOperatorTester()
3766       .batch_size(2)
3767       .input_height(pooling_size.first + 3)
3768       .input_width(pooling_size.second + 2)
3769       .pooling_height(pooling_size.first)
3770       .pooling_width(pooling_size.second)
3771       .channels(channels)
3772       .TestF16();
3773     AveragePoolingOperatorTester()
3774       .batch_size(2)
3775       .input_height(pooling_size.second + 3)
3776       .input_width(pooling_size.first + 2)
3777       .pooling_height(pooling_size.second)
3778       .pooling_width(pooling_size.first)
3779       .channels(channels)
3780       .TestF16();
3781   }
3782 }
3783 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_pool_with_stride)3784 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_pool_with_stride) {
3785   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3786   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
3787   for (size_t channels = 1; channels <= 100; channels += 15) {
3788     for (size_t stride_width = 1; stride_width <= 2; stride_width++) {
3789       for (size_t stride_height = 1; stride_height <= 2; stride_height++) {
3790         if (stride_width == 1 && stride_height == 1) {
3791           continue;
3792         }
3793 
3794         AveragePoolingOperatorTester()
3795           .batch_size(2)
3796           .input_height(pooling_size.first + 3)
3797           .input_width(pooling_size.second + 2)
3798           .pooling_height(pooling_size.first)
3799           .pooling_width(pooling_size.second)
3800           .stride_height(stride_height)
3801           .stride_width(stride_width)
3802           .channels(channels)
3803           .TestF16();
3804         AveragePoolingOperatorTester()
3805           .batch_size(2)
3806           .input_height(pooling_size.second + 3)
3807           .input_width(pooling_size.first + 2)
3808           .pooling_height(pooling_size.second)
3809           .pooling_width(pooling_size.first)
3810           .stride_height(stride_height)
3811           .stride_width(stride_width)
3812           .channels(channels)
3813           .TestF16();
3814       }
3815     }
3816   }
3817 }
3818 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_pool_with_width_padding)3819 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_pool_with_width_padding) {
3820   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3821   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
3822   for (size_t channels = 1; channels <= 100; channels += 15) {
3823     for (size_t stride = 1; stride <= 2; stride++) {
3824       for (size_t padding_left = 0; padding_left <= 1; padding_left++) {
3825         for (size_t padding_right = 0; padding_right <= 1; padding_right++) {
3826           AveragePoolingOperatorTester()
3827             .batch_size(2)
3828             .input_height(pooling_size.first + 3)
3829             .input_width(pooling_size.second + 2)
3830             .padding_left(padding_left)
3831             .padding_right(padding_right)
3832             .pooling_height(pooling_size.first)
3833             .pooling_width(pooling_size.second)
3834             .stride(stride)
3835             .channels(channels)
3836             .TestF16();
3837           AveragePoolingOperatorTester()
3838             .batch_size(2)
3839             .input_height(pooling_size.second + 3)
3840             .input_width(pooling_size.first + 2)
3841             .padding_left(padding_left)
3842             .padding_right(padding_right)
3843             .pooling_height(pooling_size.second)
3844             .pooling_width(pooling_size.first)
3845             .stride(stride)
3846             .channels(channels)
3847             .TestF16();
3848         }
3849       }
3850     }
3851   }
3852 }
3853 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_pool_with_height_padding)3854 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_pool_with_height_padding) {
3855   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3856   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
3857   for (size_t channels = 1; channels <= 100; channels += 15) {
3858     for (size_t stride = 1; stride <= 2; stride++) {
3859       for (size_t padding_top = 0; padding_top <= 1; padding_top++) {
3860         for (size_t padding_bottom = 0; padding_bottom <= 1; padding_bottom++) {
3861           AveragePoolingOperatorTester()
3862             .batch_size(2)
3863             .input_height(pooling_size.first + 3)
3864             .input_width(pooling_size.second + 2)
3865             .padding_top(padding_top)
3866             .padding_bottom(padding_bottom)
3867             .pooling_height(pooling_size.first)
3868             .pooling_width(pooling_size.second)
3869             .stride(stride)
3870             .channels(channels)
3871             .TestF16();
3872           AveragePoolingOperatorTester()
3873             .batch_size(2)
3874             .input_height(pooling_size.second + 3)
3875             .input_width(pooling_size.first + 2)
3876             .padding_top(padding_top)
3877             .padding_bottom(padding_bottom)
3878             .pooling_height(pooling_size.second)
3879             .pooling_width(pooling_size.first)
3880             .stride(stride)
3881             .channels(channels)
3882             .TestF16();
3883         }
3884       }
3885     }
3886   }
3887 }
3888 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_pool_with_tf_same_padding)3889 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_pool_with_tf_same_padding) {
3890   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3891   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
3892   for (size_t channels = 1; channels <= 100; channels += 15) {
3893     for (size_t stride = 1; stride <= 2; stride++) {
3894       for (size_t input_height = pooling_size.first + 3; input_height <= pooling_size.first + 4; input_height++) {
3895         AveragePoolingOperatorTester()
3896           .batch_size(2)
3897           .input_height(input_height)
3898           .input_width(pooling_size.second + 2)
3899           .padding_tf_same(true)
3900           .pooling_height(pooling_size.first)
3901           .pooling_width(pooling_size.second)
3902           .stride(stride)
3903           .channels(channels)
3904           .TestF16();
3905       }
3906       for (size_t input_width = pooling_size.second + 2; input_width <= pooling_size.second + 3; input_width++) {
3907         AveragePoolingOperatorTester()
3908           .batch_size(2)
3909           .input_height(pooling_size.first + 3)
3910           .input_width(input_width)
3911           .padding_tf_same(true)
3912           .pooling_height(pooling_size.first)
3913           .pooling_width(pooling_size.second)
3914           .stride(stride)
3915           .channels(channels)
3916           .TestF16();
3917       }
3918       for (size_t input_height = pooling_size.second + 3; input_height <= pooling_size.second + 4; input_height++) {
3919         AveragePoolingOperatorTester()
3920           .batch_size(2)
3921           .input_height(input_height)
3922           .input_width(pooling_size.first + 2)
3923           .padding_tf_same(true)
3924           .pooling_height(pooling_size.second)
3925           .pooling_width(pooling_size.first)
3926           .stride(stride)
3927           .channels(channels)
3928           .TestF16();
3929       }
3930       for (size_t input_width = pooling_size.first + 2; input_width <= pooling_size.first + 3; input_width++) {
3931         AveragePoolingOperatorTester()
3932           .batch_size(2)
3933           .input_height(pooling_size.second + 3)
3934           .input_width(input_width)
3935           .padding_tf_same(true)
3936           .pooling_height(pooling_size.second)
3937           .pooling_width(pooling_size.first)
3938           .stride(stride)
3939           .channels(channels)
3940           .TestF16();
3941       }
3942     }
3943   }
3944 }
3945 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_pool_with_input_stride)3946 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_pool_with_input_stride) {
3947   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3948   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
3949   for (size_t channels = 1; channels <= 100; channels += 15) {
3950     AveragePoolingOperatorTester()
3951       .batch_size(2)
3952       .input_height(pooling_size.first + 3)
3953       .input_width(pooling_size.second + 2)
3954       .pooling_height(pooling_size.first)
3955       .pooling_width(pooling_size.second)
3956       .channels(channels)
3957       .input_pixel_stride(2 * channels + 3)
3958       .TestF16();
3959     AveragePoolingOperatorTester()
3960       .batch_size(2)
3961       .input_height(pooling_size.second + 3)
3962       .input_width(pooling_size.first + 2)
3963       .pooling_height(pooling_size.second)
3964       .pooling_width(pooling_size.first)
3965       .channels(channels)
3966       .input_pixel_stride(2 * channels + 3)
3967       .TestF16();
3968   }
3969 }
3970 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_pool_with_output_stride)3971 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_pool_with_output_stride) {
3972   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3973   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
3974   for (size_t channels = 1; channels <= 100; channels += 15) {
3975     AveragePoolingOperatorTester()
3976       .batch_size(2)
3977       .input_height(pooling_size.first + 3)
3978       .input_width(pooling_size.second + 2)
3979       .pooling_height(pooling_size.first)
3980       .pooling_width(pooling_size.second)
3981       .channels(channels)
3982       .output_pixel_stride(2 * channels + 3)
3983       .TestF16();
3984     AveragePoolingOperatorTester()
3985       .batch_size(2)
3986       .input_height(pooling_size.second + 3)
3987       .input_width(pooling_size.first + 2)
3988       .pooling_height(pooling_size.second)
3989       .pooling_width(pooling_size.first)
3990       .channels(channels)
3991       .output_pixel_stride(2 * channels + 3)
3992       .TestF16();
3993   }
3994 }
3995 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_pool_with_qmin)3996 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_pool_with_qmin) {
3997   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
3998   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
3999   for (size_t channels = 1; channels <= 100; channels += 15) {
4000     AveragePoolingOperatorTester()
4001       .batch_size(2)
4002       .input_height(pooling_size.first + 3)
4003       .input_width(pooling_size.second + 2)
4004       .pooling_height(pooling_size.first)
4005       .pooling_width(pooling_size.second)
4006       .channels(channels)
4007       .qmin(128)
4008       .TestF16();
4009     AveragePoolingOperatorTester()
4010       .batch_size(2)
4011       .input_height(pooling_size.second + 3)
4012       .input_width(pooling_size.first + 2)
4013       .pooling_height(pooling_size.second)
4014       .pooling_width(pooling_size.first)
4015       .channels(channels)
4016       .qmin(128)
4017       .TestF16();
4018   }
4019 }
4020 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_pool_with_qmax)4021 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_pool_with_qmax) {
4022   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4023   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
4024   for (size_t channels = 1; channels <= 100; channels += 15) {
4025     AveragePoolingOperatorTester()
4026       .batch_size(2)
4027       .input_height(pooling_size.first + 3)
4028       .input_width(pooling_size.second + 2)
4029       .pooling_height(pooling_size.first)
4030       .pooling_width(pooling_size.second)
4031       .channels(channels)
4032       .qmax(128)
4033       .TestF16();
4034     AveragePoolingOperatorTester()
4035       .batch_size(2)
4036       .input_height(pooling_size.second + 3)
4037       .input_width(pooling_size.first + 2)
4038       .pooling_height(pooling_size.second)
4039       .pooling_width(pooling_size.first)
4040       .channels(channels)
4041       .qmax(128)
4042       .TestF16();
4043   }
4044 }
4045 
4046 /**************************** GAVGPOOL path, unipass ****************************/
4047 
TEST(AVERAGE_POOLING_NHWC_F16,small_image)4048 TEST(AVERAGE_POOLING_NHWC_F16, small_image) {
4049   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4050   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
4051   for (size_t channels = 1; channels <= 100; channels += 15) {
4052     AveragePoolingOperatorTester()
4053       .input_height(pooling_size.first)
4054       .input_width(pooling_size.second)
4055       .pooling_height(pooling_size.first)
4056       .pooling_width(pooling_size.second)
4057       .channels(channels)
4058       .TestF16();
4059     AveragePoolingOperatorTester()
4060       .input_height(pooling_size.second)
4061       .input_width(pooling_size.first)
4062       .pooling_height(pooling_size.second)
4063       .pooling_width(pooling_size.first)
4064       .channels(channels)
4065       .TestF16();
4066   }
4067 }
4068 
TEST(AVERAGE_POOLING_NHWC_F16,small_image_with_width_padding)4069 TEST(AVERAGE_POOLING_NHWC_F16, small_image_with_width_padding) {
4070   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4071   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
4072   for (size_t channels = 1; channels <= 100; channels += 15) {
4073     /* With left padding */
4074     AveragePoolingOperatorTester()
4075       .input_height(pooling_size.first)
4076       .input_width(pooling_size.second - 1)
4077       .padding_left(1)
4078       .pooling_height(pooling_size.first)
4079       .pooling_width(pooling_size.second)
4080       .channels(channels)
4081       .TestF16();
4082     AveragePoolingOperatorTester()
4083       .input_height(pooling_size.second)
4084       .input_width(pooling_size.first - 1)
4085       .padding_left(1)
4086       .pooling_height(pooling_size.second)
4087       .pooling_width(pooling_size.first)
4088       .channels(channels)
4089       .TestF16();
4090 
4091     /* With right padding */
4092     AveragePoolingOperatorTester()
4093       .input_height(pooling_size.first)
4094       .input_width(pooling_size.second - 1)
4095       .padding_right(1)
4096       .pooling_height(pooling_size.first)
4097       .pooling_width(pooling_size.second)
4098       .channels(channels)
4099       .TestF16();
4100     AveragePoolingOperatorTester()
4101       .input_height(pooling_size.second)
4102       .input_width(pooling_size.first - 1)
4103       .padding_right(1)
4104       .pooling_height(pooling_size.second)
4105       .pooling_width(pooling_size.first)
4106       .channels(channels)
4107       .TestF16();
4108   }
4109 }
4110 
TEST(AVERAGE_POOLING_NHWC_F16,small_image_with_height_padding)4111 TEST(AVERAGE_POOLING_NHWC_F16, small_image_with_height_padding) {
4112   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4113   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
4114   for (size_t channels = 1; channels <= 100; channels += 15) {
4115     /* With top padding */
4116     AveragePoolingOperatorTester()
4117       .input_height(pooling_size.first - 1)
4118       .input_width(pooling_size.second)
4119       .padding_top(1)
4120       .pooling_height(pooling_size.first)
4121       .pooling_width(pooling_size.second)
4122       .channels(channels)
4123       .TestF16();
4124     AveragePoolingOperatorTester()
4125       .input_height(pooling_size.second - 1)
4126       .input_width(pooling_size.first)
4127       .padding_top(1)
4128       .pooling_height(pooling_size.second)
4129       .pooling_width(pooling_size.first)
4130       .channels(channels)
4131       .TestF16();
4132 
4133     /* With bottom padding */
4134     AveragePoolingOperatorTester()
4135       .input_height(pooling_size.first - 1)
4136       .input_width(pooling_size.second)
4137       .padding_bottom(1)
4138       .pooling_height(pooling_size.first)
4139       .pooling_width(pooling_size.second)
4140       .channels(channels)
4141       .TestF16();
4142     AveragePoolingOperatorTester()
4143       .input_height(pooling_size.second - 1)
4144       .input_width(pooling_size.first)
4145       .padding_bottom(1)
4146       .pooling_height(pooling_size.second)
4147       .pooling_width(pooling_size.first)
4148       .channels(channels)
4149       .TestF16();
4150   }
4151 }
4152 
TEST(AVERAGE_POOLING_NHWC_F16,small_image_with_input_stride)4153 TEST(AVERAGE_POOLING_NHWC_F16, small_image_with_input_stride) {
4154   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4155   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
4156   for (size_t channels = 1; channels <= 100; channels += 15) {
4157     AveragePoolingOperatorTester()
4158       .input_height(pooling_size.first)
4159       .input_width(pooling_size.second)
4160       .pooling_height(pooling_size.first)
4161       .pooling_width(pooling_size.second)
4162       .channels(channels)
4163       .input_pixel_stride(2 * channels + 3)
4164       .TestF16();
4165     AveragePoolingOperatorTester()
4166       .input_height(pooling_size.second)
4167       .input_width(pooling_size.first)
4168       .pooling_height(pooling_size.second)
4169       .pooling_width(pooling_size.first)
4170       .channels(channels)
4171       .input_pixel_stride(2 * channels + 3)
4172       .TestF16();
4173   }
4174 }
4175 
TEST(AVERAGE_POOLING_NHWC_F16,small_image_with_output_stride)4176 TEST(AVERAGE_POOLING_NHWC_F16, small_image_with_output_stride) {
4177   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4178   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
4179   for (size_t channels = 1; channels <= 100; channels += 15) {
4180     AveragePoolingOperatorTester()
4181       .input_height(pooling_size.first)
4182       .input_width(pooling_size.second)
4183       .pooling_height(pooling_size.first)
4184       .pooling_width(pooling_size.second)
4185       .channels(channels)
4186       .output_pixel_stride(2 * channels + 3)
4187       .TestF16();
4188     AveragePoolingOperatorTester()
4189       .input_height(pooling_size.second)
4190       .input_width(pooling_size.first)
4191       .pooling_height(pooling_size.second)
4192       .pooling_width(pooling_size.first)
4193       .channels(channels)
4194       .output_pixel_stride(2 * channels + 3)
4195       .TestF16();
4196   }
4197 }
4198 
TEST(AVERAGE_POOLING_NHWC_F16,small_image_with_qmin)4199 TEST(AVERAGE_POOLING_NHWC_F16, small_image_with_qmin) {
4200   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4201   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
4202   for (size_t channels = 1; channels <= 100; channels += 15) {
4203     AveragePoolingOperatorTester()
4204       .input_height(pooling_size.first)
4205       .input_width(pooling_size.second)
4206       .pooling_height(pooling_size.first)
4207       .pooling_width(pooling_size.second)
4208       .channels(channels)
4209       .qmin(128)
4210       .TestF16();
4211     AveragePoolingOperatorTester()
4212       .input_height(pooling_size.second)
4213       .input_width(pooling_size.first)
4214       .pooling_height(pooling_size.second)
4215       .pooling_width(pooling_size.first)
4216       .channels(channels)
4217       .qmin(128)
4218       .TestF16();
4219   }
4220 }
4221 
TEST(AVERAGE_POOLING_NHWC_F16,small_image_with_qmax)4222 TEST(AVERAGE_POOLING_NHWC_F16, small_image_with_qmax) {
4223   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4224   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
4225   for (size_t channels = 1; channels <= 100; channels += 15) {
4226     AveragePoolingOperatorTester()
4227       .input_height(pooling_size.first)
4228       .input_width(pooling_size.second)
4229       .pooling_height(pooling_size.first)
4230       .pooling_width(pooling_size.second)
4231       .channels(channels)
4232       .qmax(128)
4233       .TestF16();
4234     AveragePoolingOperatorTester()
4235       .input_height(pooling_size.second)
4236       .input_width(pooling_size.first)
4237       .pooling_height(pooling_size.second)
4238       .pooling_width(pooling_size.first)
4239       .channels(channels)
4240       .qmax(128)
4241       .TestF16();
4242   }
4243 }
4244 
4245 /**************************** GAVGPOOL path, unipass, batched ****************************/
4246 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_image)4247 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_image) {
4248   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4249   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
4250   for (size_t channels = 1; channels <= 100; channels += 15) {
4251     AveragePoolingOperatorTester()
4252       .batch_size(2)
4253       .input_height(pooling_size.first)
4254       .input_width(pooling_size.second)
4255       .pooling_height(pooling_size.first)
4256       .pooling_width(pooling_size.second)
4257       .channels(channels)
4258       .TestF16();
4259     AveragePoolingOperatorTester()
4260       .batch_size(2)
4261       .input_height(pooling_size.second)
4262       .input_width(pooling_size.first)
4263       .pooling_height(pooling_size.second)
4264       .pooling_width(pooling_size.first)
4265       .channels(channels)
4266       .TestF16();
4267   }
4268 }
4269 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_image_with_width_padding)4270 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_image_with_width_padding) {
4271   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4272   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
4273   for (size_t channels = 1; channels <= 100; channels += 15) {
4274     /* With left padding */
4275     AveragePoolingOperatorTester()
4276       .batch_size(2)
4277       .input_height(pooling_size.first)
4278       .input_width(pooling_size.second - 1)
4279       .padding_left(1)
4280       .pooling_height(pooling_size.first)
4281       .pooling_width(pooling_size.second)
4282       .channels(channels)
4283       .TestF16();
4284     AveragePoolingOperatorTester()
4285       .batch_size(2)
4286       .input_height(pooling_size.second)
4287       .input_width(pooling_size.first - 1)
4288       .padding_left(1)
4289       .pooling_height(pooling_size.second)
4290       .pooling_width(pooling_size.first)
4291       .channels(channels)
4292       .TestF16();
4293 
4294     /* With right padding */
4295     AveragePoolingOperatorTester()
4296       .batch_size(2)
4297       .input_height(pooling_size.first)
4298       .input_width(pooling_size.second - 1)
4299       .padding_right(1)
4300       .pooling_height(pooling_size.first)
4301       .pooling_width(pooling_size.second)
4302       .channels(channels)
4303       .TestF16();
4304     AveragePoolingOperatorTester()
4305       .batch_size(2)
4306       .input_height(pooling_size.second)
4307       .input_width(pooling_size.first - 1)
4308       .padding_right(1)
4309       .pooling_height(pooling_size.second)
4310       .pooling_width(pooling_size.first)
4311       .channels(channels)
4312       .TestF16();
4313   }
4314 }
4315 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_image_with_height_padding)4316 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_image_with_height_padding) {
4317   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4318   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
4319   for (size_t channels = 1; channels <= 100; channels += 15) {
4320     /* With top padding */
4321     AveragePoolingOperatorTester()
4322       .batch_size(2)
4323       .input_height(pooling_size.first - 1)
4324       .input_width(pooling_size.second)
4325       .padding_top(1)
4326       .pooling_height(pooling_size.first)
4327       .pooling_width(pooling_size.second)
4328       .channels(channels)
4329       .TestF16();
4330     AveragePoolingOperatorTester()
4331       .batch_size(2)
4332       .input_height(pooling_size.second - 1)
4333       .input_width(pooling_size.first)
4334       .padding_top(1)
4335       .pooling_height(pooling_size.second)
4336       .pooling_width(pooling_size.first)
4337       .channels(channels)
4338       .TestF16();
4339 
4340     /* With bottom padding */
4341     AveragePoolingOperatorTester()
4342       .batch_size(2)
4343       .input_height(pooling_size.first - 1)
4344       .input_width(pooling_size.second)
4345       .padding_bottom(1)
4346       .pooling_height(pooling_size.first)
4347       .pooling_width(pooling_size.second)
4348       .channels(channels)
4349       .TestF16();
4350     AveragePoolingOperatorTester()
4351       .batch_size(2)
4352       .input_height(pooling_size.second - 1)
4353       .input_width(pooling_size.first)
4354       .padding_bottom(1)
4355       .pooling_height(pooling_size.second)
4356       .pooling_width(pooling_size.first)
4357       .channels(channels)
4358       .TestF16();
4359   }
4360 }
4361 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_image_with_input_stride)4362 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_image_with_input_stride) {
4363   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4364   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
4365   for (size_t channels = 1; channels <= 100; channels += 15) {
4366     AveragePoolingOperatorTester()
4367       .batch_size(2)
4368       .input_height(pooling_size.first)
4369       .input_width(pooling_size.second)
4370       .pooling_height(pooling_size.first)
4371       .pooling_width(pooling_size.second)
4372       .channels(channels)
4373       .input_pixel_stride(2 * channels + 3)
4374       .TestF16();
4375     AveragePoolingOperatorTester()
4376       .batch_size(2)
4377       .input_height(pooling_size.second)
4378       .input_width(pooling_size.first)
4379       .pooling_height(pooling_size.second)
4380       .pooling_width(pooling_size.first)
4381       .channels(channels)
4382       .input_pixel_stride(2 * channels + 3)
4383       .TestF16();
4384   }
4385 }
4386 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_image_with_output_stride)4387 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_image_with_output_stride) {
4388   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4389   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
4390   for (size_t channels = 1; channels <= 100; channels += 15) {
4391     AveragePoolingOperatorTester()
4392       .batch_size(2)
4393       .input_height(pooling_size.first)
4394       .input_width(pooling_size.second)
4395       .pooling_height(pooling_size.first)
4396       .pooling_width(pooling_size.second)
4397       .channels(channels)
4398       .output_pixel_stride(2 * channels + 3)
4399       .TestF16();
4400     AveragePoolingOperatorTester()
4401       .batch_size(2)
4402       .input_height(pooling_size.second)
4403       .input_width(pooling_size.first)
4404       .pooling_height(pooling_size.second)
4405       .pooling_width(pooling_size.first)
4406       .channels(channels)
4407       .output_pixel_stride(2 * channels + 3)
4408       .TestF16();
4409   }
4410 }
4411 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_image_with_qmin)4412 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_image_with_qmin) {
4413   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4414   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
4415   for (size_t channels = 1; channels <= 100; channels += 15) {
4416     AveragePoolingOperatorTester()
4417       .batch_size(2)
4418       .input_height(pooling_size.first)
4419       .input_width(pooling_size.second)
4420       .pooling_height(pooling_size.first)
4421       .pooling_width(pooling_size.second)
4422       .channels(channels)
4423       .qmin(128)
4424       .TestF16();
4425     AveragePoolingOperatorTester()
4426       .batch_size(2)
4427       .input_height(pooling_size.second)
4428       .input_width(pooling_size.first)
4429       .pooling_height(pooling_size.second)
4430       .pooling_width(pooling_size.first)
4431       .channels(channels)
4432       .qmin(128)
4433       .TestF16();
4434   }
4435 }
4436 
TEST(AVERAGE_POOLING_NHWC_F16,batched_small_image_with_qmax)4437 TEST(AVERAGE_POOLING_NHWC_F16, batched_small_image_with_qmax) {
4438   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4439   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
4440   for (size_t channels = 1; channels <= 100; channels += 15) {
4441     AveragePoolingOperatorTester()
4442       .batch_size(2)
4443       .input_height(pooling_size.first)
4444       .input_width(pooling_size.second)
4445       .pooling_height(pooling_size.first)
4446       .pooling_width(pooling_size.second)
4447       .channels(channels)
4448       .qmax(128)
4449       .TestF16();
4450     AveragePoolingOperatorTester()
4451       .batch_size(2)
4452       .input_height(pooling_size.second)
4453       .input_width(pooling_size.first)
4454       .pooling_height(pooling_size.second)
4455       .pooling_width(pooling_size.first)
4456       .channels(channels)
4457       .qmax(128)
4458       .TestF16();
4459   }
4460 }
4461 
4462 /**************************** GAVGPOOL path, multipass ****************************/
4463 
TEST(AVERAGE_POOLING_NHWC_F16,large_image)4464 TEST(AVERAGE_POOLING_NHWC_F16, large_image) {
4465   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4466   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
4467   for (size_t channels = 1; channels <= 100; channels += 15) {
4468     AveragePoolingOperatorTester()
4469       .input_height(pooling_size.first)
4470       .input_width(pooling_size.second)
4471       .pooling_height(pooling_size.first)
4472       .pooling_width(pooling_size.second)
4473       .channels(channels)
4474       .TestF16();
4475     AveragePoolingOperatorTester()
4476       .input_height(pooling_size.second)
4477       .input_width(pooling_size.first)
4478       .pooling_height(pooling_size.second)
4479       .pooling_width(pooling_size.first)
4480       .channels(channels)
4481       .TestF16();
4482   }
4483 }
4484 
TEST(AVERAGE_POOLING_NHWC_F16,large_image_with_width_padding)4485 TEST(AVERAGE_POOLING_NHWC_F16, large_image_with_width_padding) {
4486   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4487   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
4488   for (size_t channels = 1; channels <= 100; channels += 15) {
4489     for (size_t padding_left = 1; padding_left <= 2; padding_left++) {
4490       AveragePoolingOperatorTester()
4491         .input_height(pooling_size.first)
4492         .input_width(pooling_size.second - padding_left)
4493         .padding_left(padding_left)
4494         .pooling_height(pooling_size.first)
4495         .pooling_width(pooling_size.second)
4496         .channels(channels)
4497         .TestF16();
4498       AveragePoolingOperatorTester()
4499         .input_height(pooling_size.second)
4500         .input_width(pooling_size.first - padding_left)
4501         .padding_left(padding_left)
4502         .pooling_height(pooling_size.second)
4503         .pooling_width(pooling_size.first)
4504         .channels(channels)
4505         .TestF16();
4506     }
4507     for (size_t padding_right = 1; padding_right <= 2; padding_right++) {
4508       AveragePoolingOperatorTester()
4509         .input_height(pooling_size.first)
4510         .input_width(pooling_size.second - padding_right)
4511         .padding_right(padding_right)
4512         .pooling_height(pooling_size.first)
4513         .pooling_width(pooling_size.second)
4514         .channels(channels)
4515         .TestF16();
4516       AveragePoolingOperatorTester()
4517         .input_height(pooling_size.second)
4518         .input_width(pooling_size.first - padding_right)
4519         .padding_right(padding_right)
4520         .pooling_height(pooling_size.second)
4521         .pooling_width(pooling_size.first)
4522         .channels(channels)
4523         .TestF16();
4524     }
4525   }
4526 }
4527 
TEST(AVERAGE_POOLING_NHWC_F16,large_image_with_height_padding)4528 TEST(AVERAGE_POOLING_NHWC_F16, large_image_with_height_padding) {
4529   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4530   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
4531   for (size_t channels = 1; channels <= 100; channels += 15) {
4532     for (size_t padding_top = 1; padding_top <= 2; padding_top++) {
4533       AveragePoolingOperatorTester()
4534         .input_height(pooling_size.first - padding_top)
4535         .input_width(pooling_size.second)
4536         .padding_top(padding_top)
4537         .pooling_height(pooling_size.first)
4538         .pooling_width(pooling_size.second)
4539         .channels(channels)
4540         .TestF16();
4541       AveragePoolingOperatorTester()
4542         .input_height(pooling_size.second - padding_top)
4543         .input_width(pooling_size.first)
4544         .padding_top(padding_top)
4545         .pooling_height(pooling_size.second)
4546         .pooling_width(pooling_size.first)
4547         .channels(channels)
4548         .TestF16();
4549     }
4550     for (size_t padding_bottom = 1; padding_bottom <= 2; padding_bottom++) {
4551       AveragePoolingOperatorTester()
4552         .input_height(pooling_size.first - padding_bottom)
4553         .input_width(pooling_size.second)
4554         .padding_bottom(padding_bottom)
4555         .pooling_height(pooling_size.first)
4556         .pooling_width(pooling_size.second)
4557         .channels(channels)
4558         .TestF16();
4559       AveragePoolingOperatorTester()
4560         .input_height(pooling_size.second - padding_bottom)
4561         .input_width(pooling_size.first)
4562         .padding_bottom(padding_bottom)
4563         .pooling_height(pooling_size.second)
4564         .pooling_width(pooling_size.first)
4565         .channels(channels)
4566         .TestF16();
4567     }
4568   }
4569 }
4570 
TEST(AVERAGE_POOLING_NHWC_F16,large_image_with_input_stride)4571 TEST(AVERAGE_POOLING_NHWC_F16, large_image_with_input_stride) {
4572   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4573   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
4574   for (size_t channels = 1; channels <= 100; channels += 15) {
4575     AveragePoolingOperatorTester()
4576       .input_height(pooling_size.first)
4577       .input_width(pooling_size.second)
4578       .pooling_height(pooling_size.first)
4579       .pooling_width(pooling_size.second)
4580       .channels(channels)
4581       .input_pixel_stride(2 * channels + 3)
4582       .TestF16();
4583     AveragePoolingOperatorTester()
4584       .input_height(pooling_size.second)
4585       .input_width(pooling_size.first)
4586       .pooling_height(pooling_size.second)
4587       .pooling_width(pooling_size.first)
4588       .channels(channels)
4589       .input_pixel_stride(2 * channels + 3)
4590       .TestF16();
4591   }
4592 }
4593 
TEST(AVERAGE_POOLING_NHWC_F16,large_image_with_output_stride)4594 TEST(AVERAGE_POOLING_NHWC_F16, large_image_with_output_stride) {
4595   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4596   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
4597   for (size_t channels = 1; channels <= 100; channels += 15) {
4598     AveragePoolingOperatorTester()
4599       .input_height(pooling_size.first)
4600       .input_width(pooling_size.second)
4601       .pooling_height(pooling_size.first)
4602       .pooling_width(pooling_size.second)
4603       .channels(channels)
4604       .output_pixel_stride(2 * channels + 3)
4605       .TestF16();
4606     AveragePoolingOperatorTester()
4607       .input_height(pooling_size.second)
4608       .input_width(pooling_size.first)
4609       .pooling_height(pooling_size.second)
4610       .pooling_width(pooling_size.first)
4611       .channels(channels)
4612       .output_pixel_stride(2 * channels + 3)
4613       .TestF16();
4614   }
4615 }
4616 
TEST(AVERAGE_POOLING_NHWC_F16,large_image_with_qmin)4617 TEST(AVERAGE_POOLING_NHWC_F16, large_image_with_qmin) {
4618   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4619   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
4620   for (size_t channels = 1; channels <= 100; channels += 15) {
4621     AveragePoolingOperatorTester()
4622       .input_height(pooling_size.first)
4623       .input_width(pooling_size.second)
4624       .pooling_height(pooling_size.first)
4625       .pooling_width(pooling_size.second)
4626       .channels(channels)
4627       .qmin(128)
4628       .TestF16();
4629     AveragePoolingOperatorTester()
4630       .input_height(pooling_size.second)
4631       .input_width(pooling_size.first)
4632       .pooling_height(pooling_size.second)
4633       .pooling_width(pooling_size.first)
4634       .channels(channels)
4635       .qmin(128)
4636       .TestF16();
4637   }
4638 }
4639 
TEST(AVERAGE_POOLING_NHWC_F16,large_image_with_qmax)4640 TEST(AVERAGE_POOLING_NHWC_F16, large_image_with_qmax) {
4641   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4642   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
4643   for (size_t channels = 1; channels <= 100; channels += 15) {
4644     AveragePoolingOperatorTester()
4645       .input_height(pooling_size.first)
4646       .input_width(pooling_size.second)
4647       .pooling_height(pooling_size.first)
4648       .pooling_width(pooling_size.second)
4649       .channels(channels)
4650       .qmax(128)
4651       .TestF16();
4652     AveragePoolingOperatorTester()
4653       .input_height(pooling_size.second)
4654       .input_width(pooling_size.first)
4655       .pooling_height(pooling_size.second)
4656       .pooling_width(pooling_size.first)
4657       .channels(channels)
4658       .qmax(128)
4659       .TestF16();
4660   }
4661 }
4662 
4663 /**************************** GAVGPOOL path, multipass, batched ****************************/
4664 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_image)4665 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_image) {
4666   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4667   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
4668   for (size_t channels = 1; channels <= 100; channels += 15) {
4669     AveragePoolingOperatorTester()
4670       .batch_size(2)
4671       .input_height(pooling_size.first)
4672       .input_width(pooling_size.second)
4673       .pooling_height(pooling_size.first)
4674       .pooling_width(pooling_size.second)
4675       .channels(channels)
4676       .TestF16();
4677     AveragePoolingOperatorTester()
4678       .batch_size(2)
4679       .input_height(pooling_size.second)
4680       .input_width(pooling_size.first)
4681       .pooling_height(pooling_size.second)
4682       .pooling_width(pooling_size.first)
4683       .channels(channels)
4684       .TestF16();
4685   }
4686 }
4687 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_image_with_width_padding)4688 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_image_with_width_padding) {
4689   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4690   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
4691   for (size_t channels = 1; channels <= 100; channels += 15) {
4692     for (size_t padding_left = 1; padding_left <= 2; padding_left++) {
4693       AveragePoolingOperatorTester()
4694         .batch_size(2)
4695         .input_height(pooling_size.first)
4696         .input_width(pooling_size.second - padding_left)
4697         .padding_left(padding_left)
4698         .pooling_height(pooling_size.first)
4699         .pooling_width(pooling_size.second)
4700         .channels(channels)
4701         .TestF16();
4702       AveragePoolingOperatorTester()
4703         .batch_size(2)
4704         .input_height(pooling_size.second)
4705         .input_width(pooling_size.first - padding_left)
4706         .padding_left(padding_left)
4707         .pooling_height(pooling_size.second)
4708         .pooling_width(pooling_size.first)
4709         .channels(channels)
4710         .TestF16();
4711     }
4712     for (size_t padding_right = 1; padding_right <= 2; padding_right++) {
4713       AveragePoolingOperatorTester()
4714         .batch_size(2)
4715         .input_height(pooling_size.first)
4716         .input_width(pooling_size.second - padding_right)
4717         .padding_right(padding_right)
4718         .pooling_height(pooling_size.first)
4719         .pooling_width(pooling_size.second)
4720         .channels(channels)
4721         .TestF16();
4722       AveragePoolingOperatorTester()
4723         .batch_size(2)
4724         .input_height(pooling_size.second)
4725         .input_width(pooling_size.first - padding_right)
4726         .padding_right(padding_right)
4727         .pooling_height(pooling_size.second)
4728         .pooling_width(pooling_size.first)
4729         .channels(channels)
4730         .TestF16();
4731     }
4732   }
4733 }
4734 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_image_with_height_padding)4735 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_image_with_height_padding) {
4736   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4737   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
4738   for (size_t channels = 1; channels <= 100; channels += 15) {
4739     for (size_t padding_top = 0; padding_top <= 1; padding_top++) {
4740       AveragePoolingOperatorTester()
4741         .batch_size(2)
4742         .input_height(pooling_size.first - padding_top)
4743         .input_width(pooling_size.second)
4744         .padding_top(padding_top)
4745         .pooling_height(pooling_size.first)
4746         .pooling_width(pooling_size.second)
4747         .channels(channels)
4748         .TestF16();
4749       AveragePoolingOperatorTester()
4750         .batch_size(2)
4751         .input_height(pooling_size.second - padding_top)
4752         .input_width(pooling_size.first)
4753         .padding_top(padding_top)
4754         .pooling_height(pooling_size.second)
4755         .pooling_width(pooling_size.first)
4756         .channels(channels)
4757         .TestF16();
4758     }
4759     for (size_t padding_bottom = 1; padding_bottom <= 2; padding_bottom++) {
4760       AveragePoolingOperatorTester()
4761         .batch_size(2)
4762         .input_height(pooling_size.first - padding_bottom)
4763         .input_width(pooling_size.second)
4764         .padding_bottom(padding_bottom)
4765         .pooling_height(pooling_size.first)
4766         .pooling_width(pooling_size.second)
4767         .channels(channels)
4768         .TestF16();
4769       AveragePoolingOperatorTester()
4770         .batch_size(2)
4771         .input_height(pooling_size.second - padding_bottom)
4772         .input_width(pooling_size.first)
4773         .padding_bottom(padding_bottom)
4774         .pooling_height(pooling_size.second)
4775         .pooling_width(pooling_size.first)
4776         .channels(channels)
4777         .TestF16();
4778     }
4779   }
4780 }
4781 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_image_with_input_stride)4782 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_image_with_input_stride) {
4783   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4784   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
4785   for (size_t channels = 1; channels <= 100; channels += 15) {
4786     AveragePoolingOperatorTester()
4787       .batch_size(2)
4788       .input_height(pooling_size.first)
4789       .input_width(pooling_size.second)
4790       .pooling_height(pooling_size.first)
4791       .pooling_width(pooling_size.second)
4792       .channels(channels)
4793       .input_pixel_stride(2 * channels + 3)
4794       .TestF16();
4795     AveragePoolingOperatorTester()
4796       .batch_size(2)
4797       .input_height(pooling_size.second)
4798       .input_width(pooling_size.first)
4799       .pooling_height(pooling_size.second)
4800       .pooling_width(pooling_size.first)
4801       .channels(channels)
4802       .input_pixel_stride(2 * channels + 3)
4803       .TestF16();
4804   }
4805 }
4806 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_image_with_output_stride)4807 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_image_with_output_stride) {
4808   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4809   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
4810   for (size_t channels = 1; channels <= 100; channels += 15) {
4811     AveragePoolingOperatorTester()
4812       .batch_size(2)
4813       .input_height(pooling_size.first)
4814       .input_width(pooling_size.second)
4815       .pooling_height(pooling_size.first)
4816       .pooling_width(pooling_size.second)
4817       .channels(channels)
4818       .output_pixel_stride(2 * channels + 3)
4819       .TestF16();
4820     AveragePoolingOperatorTester()
4821       .batch_size(2)
4822       .input_height(pooling_size.second)
4823       .input_width(pooling_size.first)
4824       .pooling_height(pooling_size.second)
4825       .pooling_width(pooling_size.first)
4826       .channels(channels)
4827       .output_pixel_stride(2 * channels + 3)
4828       .TestF16();
4829   }
4830 }
4831 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_image_with_qmin)4832 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_image_with_qmin) {
4833   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4834   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
4835   for (size_t channels = 1; channels <= 100; channels += 15) {
4836     AveragePoolingOperatorTester()
4837       .batch_size(2)
4838       .input_height(pooling_size.first)
4839       .input_width(pooling_size.second)
4840       .pooling_height(pooling_size.first)
4841       .pooling_width(pooling_size.second)
4842       .channels(channels)
4843       .qmin(128)
4844       .TestF16();
4845     AveragePoolingOperatorTester()
4846       .batch_size(2)
4847       .input_height(pooling_size.second)
4848       .input_width(pooling_size.first)
4849       .pooling_height(pooling_size.second)
4850       .pooling_width(pooling_size.first)
4851       .channels(channels)
4852       .qmin(128)
4853       .TestF16();
4854   }
4855 }
4856 
TEST(AVERAGE_POOLING_NHWC_F16,batched_large_image_with_qmax)4857 TEST(AVERAGE_POOLING_NHWC_F16, batched_large_image_with_qmax) {
4858   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4859   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
4860   for (size_t channels = 1; channels <= 100; channels += 15) {
4861     AveragePoolingOperatorTester()
4862       .batch_size(2)
4863       .input_height(pooling_size.first)
4864       .input_width(pooling_size.second)
4865       .pooling_height(pooling_size.first)
4866       .pooling_width(pooling_size.second)
4867       .channels(channels)
4868       .qmax(128)
4869       .TestF16();
4870     AveragePoolingOperatorTester()
4871       .batch_size(2)
4872       .input_height(pooling_size.second)
4873       .input_width(pooling_size.first)
4874       .pooling_height(pooling_size.second)
4875       .pooling_width(pooling_size.first)
4876       .channels(channels)
4877       .qmax(128)
4878       .TestF16();
4879   }
4880 }
4881 
4882 /**************************** AVGPOOL path, setup ****************************/
4883 
TEST(AVERAGE_POOLING_NHWC_F16,setup_increasing_batch)4884 TEST(AVERAGE_POOLING_NHWC_F16, setup_increasing_batch) {
4885   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4886   AveragePoolingOperatorTester()
4887     .batch_size(2)
4888     .next_batch_size(5)
4889     .input_height(8)
4890     .input_width(8)
4891     .pooling_height(5)
4892     .pooling_width(3)
4893     .channels(24)
4894     .TestSetupF16();
4895 }
4896 
TEST(AVERAGE_POOLING_NHWC_F16,setup_decreasing_batch)4897 TEST(AVERAGE_POOLING_NHWC_F16, setup_decreasing_batch) {
4898   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4899   AveragePoolingOperatorTester()
4900     .batch_size(5)
4901     .next_batch_size(2)
4902     .input_height(8)
4903     .input_width(8)
4904     .pooling_height(5)
4905     .pooling_width(3)
4906     .channels(24)
4907     .TestSetupF16();
4908 }
4909 
TEST(AVERAGE_POOLING_NHWC_F16,setup_changing_height)4910 TEST(AVERAGE_POOLING_NHWC_F16, setup_changing_height) {
4911   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4912   AveragePoolingOperatorTester()
4913     .batch_size(2)
4914     .input_height(8)
4915     .input_width(8)
4916     .next_input_height(9)
4917     .pooling_height(5)
4918     .pooling_width(3)
4919     .channels(24)
4920     .TestSetupF16();
4921   AveragePoolingOperatorTester()
4922     .batch_size(2)
4923     .input_height(8)
4924     .input_width(8)
4925     .next_input_height(7)
4926     .pooling_height(5)
4927     .pooling_width(3)
4928     .channels(24)
4929     .TestSetupF16();
4930 }
4931 
TEST(AVERAGE_POOLING_NHWC_F16,setup_changing_width)4932 TEST(AVERAGE_POOLING_NHWC_F16, setup_changing_width) {
4933   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4934   AveragePoolingOperatorTester()
4935     .batch_size(2)
4936     .input_height(8)
4937     .input_width(8)
4938     .next_input_width(9)
4939     .pooling_height(5)
4940     .pooling_width(3)
4941     .channels(24)
4942     .TestSetupF16();
4943   AveragePoolingOperatorTester()
4944     .batch_size(2)
4945     .input_height(8)
4946     .input_width(8)
4947     .next_input_width(7)
4948     .pooling_height(5)
4949     .pooling_width(3)
4950     .channels(24)
4951     .TestSetupF16();
4952 }
4953 
TEST(AVERAGE_POOLING_NHWC_F16,setup_swap_height_and_width)4954 TEST(AVERAGE_POOLING_NHWC_F16, setup_swap_height_and_width) {
4955   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4956   AveragePoolingOperatorTester()
4957     .batch_size(2)
4958     .input_height(9)
4959     .input_width(8)
4960     .next_input_height(8)
4961     .next_input_width(9)
4962     .pooling_height(5)
4963     .pooling_width(3)
4964     .channels(24)
4965     .TestSetupF16();
4966 }
4967 
TEST(AVERAGE_POOLING_NHWC_F16,setup_local_to_global)4968 TEST(AVERAGE_POOLING_NHWC_F16, setup_local_to_global) {
4969   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4970   AveragePoolingOperatorTester()
4971     .batch_size(2)
4972     .input_height(6)
4973     .input_width(5)
4974     .next_input_height(5)
4975     .next_input_width(3)
4976     .pooling_height(5)
4977     .pooling_width(3)
4978     .channels(24)
4979     .TestSetupF16();
4980 }
4981 
TEST(AVERAGE_POOLING_NHWC_F16,setup_global_to_local)4982 TEST(AVERAGE_POOLING_NHWC_F16, setup_global_to_local) {
4983   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
4984   AveragePoolingOperatorTester()
4985     .batch_size(2)
4986     .input_height(5)
4987     .input_width(3)
4988     .next_input_height(6)
4989     .next_input_width(5)
4990     .pooling_height(5)
4991     .pooling_width(3)
4992     .channels(24)
4993     .TestSetupF16();
4994 }
4995 
4996 /**************************** AVGPOOL path, unipass ****************************/
4997 
TEST(AVERAGE_POOLING_NHWC_F32,small_pool)4998 TEST(AVERAGE_POOLING_NHWC_F32, small_pool) {
4999   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5000   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5001   for (size_t channels = 1; channels <= 100; channels += 15) {
5002     AveragePoolingOperatorTester()
5003       .input_height(pooling_size.first + 3)
5004       .input_width(pooling_size.second + 2)
5005       .pooling_height(pooling_size.first)
5006       .pooling_width(pooling_size.second)
5007       .channels(channels)
5008       .TestF32();
5009     AveragePoolingOperatorTester()
5010       .input_height(pooling_size.second + 3)
5011       .input_width(pooling_size.first + 2)
5012       .pooling_height(pooling_size.second)
5013       .pooling_width(pooling_size.first)
5014       .channels(channels)
5015       .TestF32();
5016   }
5017 }
5018 
TEST(AVERAGE_POOLING_NHWC_F32,small_pool_with_stride)5019 TEST(AVERAGE_POOLING_NHWC_F32, small_pool_with_stride) {
5020   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5021   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5022   for (size_t channels = 1; channels <= 100; channels += 15) {
5023     for (size_t stride_width = 1; stride_width <= 2; stride_width++) {
5024       for (size_t stride_height = 1; stride_height <= 2; stride_height++) {
5025         if (stride_width == 1 && stride_height == 1) {
5026           continue;
5027         }
5028 
5029         AveragePoolingOperatorTester()
5030           .input_height(pooling_size.first + 3)
5031           .input_width(pooling_size.second + 2)
5032           .pooling_height(pooling_size.first)
5033           .pooling_width(pooling_size.second)
5034           .stride_height(stride_height)
5035           .stride_width(stride_width)
5036           .channels(channels)
5037           .TestF32();
5038         AveragePoolingOperatorTester()
5039           .input_height(pooling_size.second + 3)
5040           .input_width(pooling_size.first + 2)
5041           .pooling_height(pooling_size.second)
5042           .pooling_width(pooling_size.first)
5043           .stride_height(stride_height)
5044           .stride_width(stride_width)
5045           .channels(channels)
5046           .TestF32();
5047       }
5048     }
5049   }
5050 }
5051 
TEST(AVERAGE_POOLING_NHWC_F32,small_pool_with_width_padding)5052 TEST(AVERAGE_POOLING_NHWC_F32, small_pool_with_width_padding) {
5053   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5054   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5055   for (size_t channels = 1; channels <= 100; channels += 15) {
5056     for (size_t stride = 1; stride <= 2; stride++) {
5057       for (size_t padding_left = 0; padding_left <= 1; padding_left++) {
5058         for (size_t padding_right = 0; padding_right <= 1; padding_right++) {
5059           AveragePoolingOperatorTester()
5060             .input_height(pooling_size.first + 3)
5061             .input_width(pooling_size.second + 2)
5062             .padding_left(padding_left)
5063             .padding_right(padding_right)
5064             .pooling_height(pooling_size.first)
5065             .pooling_width(pooling_size.second)
5066             .stride(stride)
5067             .channels(channels)
5068             .TestF32();
5069           AveragePoolingOperatorTester()
5070             .input_height(pooling_size.second + 3)
5071             .input_width(pooling_size.first + 2)
5072             .padding_left(padding_left)
5073             .padding_right(padding_right)
5074             .pooling_height(pooling_size.second)
5075             .pooling_width(pooling_size.first)
5076             .stride(stride)
5077             .channels(channels)
5078             .TestF32();
5079         }
5080       }
5081     }
5082   }
5083 }
5084 
TEST(AVERAGE_POOLING_NHWC_F32,small_pool_with_height_padding)5085 TEST(AVERAGE_POOLING_NHWC_F32, small_pool_with_height_padding) {
5086   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5087   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5088   for (size_t channels = 1; channels <= 100; channels += 15) {
5089     for (size_t stride = 1; stride <= 2; stride++) {
5090       for (size_t padding_top = 0; padding_top <= 1; padding_top++) {
5091         for (size_t padding_bottom = 0; padding_bottom <= 1; padding_bottom++) {
5092           AveragePoolingOperatorTester()
5093             .input_height(pooling_size.first + 3)
5094             .input_width(pooling_size.second + 2)
5095             .padding_top(padding_top)
5096             .padding_bottom(padding_bottom)
5097             .pooling_height(pooling_size.first)
5098             .pooling_width(pooling_size.second)
5099             .stride(stride)
5100             .channels(channels)
5101             .TestF32();
5102           AveragePoolingOperatorTester()
5103             .input_height(pooling_size.second + 3)
5104             .input_width(pooling_size.first + 2)
5105             .padding_top(padding_top)
5106             .padding_bottom(padding_bottom)
5107             .pooling_height(pooling_size.second)
5108             .pooling_width(pooling_size.first)
5109             .stride(stride)
5110             .channels(channels)
5111             .TestF32();
5112         }
5113       }
5114     }
5115   }
5116 }
5117 
TEST(AVERAGE_POOLING_NHWC_F32,small_pool_with_tf_same_padding)5118 TEST(AVERAGE_POOLING_NHWC_F32, small_pool_with_tf_same_padding) {
5119   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5120   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5121   for (size_t channels = 1; channels <= 100; channels += 15) {
5122     for (size_t stride = 1; stride <= 2; stride++) {
5123       for (size_t input_height = pooling_size.first + 3; input_height <= pooling_size.first + 4; input_height++) {
5124         AveragePoolingOperatorTester()
5125           .input_height(input_height)
5126           .input_width(pooling_size.second + 2)
5127           .padding_tf_same(true)
5128           .pooling_height(pooling_size.first)
5129           .pooling_width(pooling_size.second)
5130           .stride(stride)
5131           .channels(channels)
5132           .TestF32();
5133       }
5134       for (size_t input_width = pooling_size.second + 2; input_width <= pooling_size.second + 3; input_width++) {
5135         AveragePoolingOperatorTester()
5136           .input_height(pooling_size.first + 3)
5137           .input_width(input_width)
5138           .padding_tf_same(true)
5139           .pooling_height(pooling_size.first)
5140           .pooling_width(pooling_size.second)
5141           .stride(stride)
5142           .channels(channels)
5143           .TestF32();
5144       }
5145       for (size_t input_height = pooling_size.second + 3; input_height <= pooling_size.second + 4; input_height++) {
5146         AveragePoolingOperatorTester()
5147           .input_height(input_height)
5148           .input_width(pooling_size.first + 2)
5149           .padding_tf_same(true)
5150           .pooling_height(pooling_size.second)
5151           .pooling_width(pooling_size.first)
5152           .stride(stride)
5153           .channels(channels)
5154           .TestF32();
5155       }
5156       for (size_t input_width = pooling_size.first + 2; input_width <= pooling_size.first + 3; input_width++) {
5157         AveragePoolingOperatorTester()
5158           .input_height(pooling_size.second + 3)
5159           .input_width(input_width)
5160           .padding_tf_same(true)
5161           .pooling_height(pooling_size.second)
5162           .pooling_width(pooling_size.first)
5163           .stride(stride)
5164           .channels(channels)
5165           .TestF32();
5166       }
5167     }
5168   }
5169 }
5170 
TEST(AVERAGE_POOLING_NHWC_F32,small_pool_with_input_stride)5171 TEST(AVERAGE_POOLING_NHWC_F32, small_pool_with_input_stride) {
5172   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5173   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5174   for (size_t channels = 1; channels <= 100; channels += 15) {
5175     AveragePoolingOperatorTester()
5176       .input_height(pooling_size.first + 3)
5177       .input_width(pooling_size.second + 2)
5178       .pooling_height(pooling_size.first)
5179       .pooling_width(pooling_size.second)
5180       .channels(channels)
5181       .input_pixel_stride(2 * channels + 3)
5182       .TestF32();
5183     AveragePoolingOperatorTester()
5184       .input_height(pooling_size.second + 3)
5185       .input_width(pooling_size.first + 2)
5186       .pooling_height(pooling_size.second)
5187       .pooling_width(pooling_size.first)
5188       .channels(channels)
5189       .input_pixel_stride(2 * channels + 3)
5190       .TestF32();
5191   }
5192 }
5193 
TEST(AVERAGE_POOLING_NHWC_F32,small_pool_with_output_stride)5194 TEST(AVERAGE_POOLING_NHWC_F32, small_pool_with_output_stride) {
5195   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5196   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5197   for (size_t channels = 1; channels <= 100; channels += 15) {
5198     AveragePoolingOperatorTester()
5199       .input_height(pooling_size.first + 3)
5200       .input_width(pooling_size.second + 2)
5201       .pooling_height(pooling_size.first)
5202       .pooling_width(pooling_size.second)
5203       .channels(channels)
5204       .output_pixel_stride(2 * channels + 3)
5205       .TestF32();
5206     AveragePoolingOperatorTester()
5207       .input_height(pooling_size.second + 3)
5208       .input_width(pooling_size.first + 2)
5209       .pooling_height(pooling_size.second)
5210       .pooling_width(pooling_size.first)
5211       .channels(channels)
5212       .output_pixel_stride(2 * channels + 3)
5213       .TestF32();
5214   }
5215 }
5216 
TEST(AVERAGE_POOLING_NHWC_F32,small_pool_with_qmin)5217 TEST(AVERAGE_POOLING_NHWC_F32, small_pool_with_qmin) {
5218   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5219   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5220   for (size_t channels = 1; channels <= 100; channels += 15) {
5221     AveragePoolingOperatorTester()
5222       .input_height(pooling_size.first + 3)
5223       .input_width(pooling_size.second + 2)
5224       .pooling_height(pooling_size.first)
5225       .pooling_width(pooling_size.second)
5226       .channels(channels)
5227       .qmin(128)
5228       .TestF32();
5229     AveragePoolingOperatorTester()
5230       .input_height(pooling_size.second + 3)
5231       .input_width(pooling_size.first + 2)
5232       .pooling_height(pooling_size.second)
5233       .pooling_width(pooling_size.first)
5234       .channels(channels)
5235       .qmin(128)
5236       .TestF32();
5237   }
5238 }
5239 
TEST(AVERAGE_POOLING_NHWC_F32,small_pool_with_qmax)5240 TEST(AVERAGE_POOLING_NHWC_F32, small_pool_with_qmax) {
5241   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5242   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5243   for (size_t channels = 1; channels <= 100; channels += 15) {
5244     AveragePoolingOperatorTester()
5245       .input_height(pooling_size.first + 3)
5246       .input_width(pooling_size.second + 2)
5247       .pooling_height(pooling_size.first)
5248       .pooling_width(pooling_size.second)
5249       .channels(channels)
5250       .qmax(128)
5251       .TestF32();
5252     AveragePoolingOperatorTester()
5253       .input_height(pooling_size.second + 3)
5254       .input_width(pooling_size.first + 2)
5255       .pooling_height(pooling_size.second)
5256       .pooling_width(pooling_size.first)
5257       .channels(channels)
5258       .qmax(128)
5259       .TestF32();
5260   }
5261 }
5262 
5263 /**************************** AVGPOOL path, unipass, batched ****************************/
5264 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_pool)5265 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_pool) {
5266   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5267   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5268   for (size_t channels = 1; channels <= 100; channels += 15) {
5269     AveragePoolingOperatorTester()
5270       .batch_size(2)
5271       .input_height(pooling_size.first + 3)
5272       .input_width(pooling_size.second + 2)
5273       .pooling_height(pooling_size.first)
5274       .pooling_width(pooling_size.second)
5275       .channels(channels)
5276       .TestF32();
5277     AveragePoolingOperatorTester()
5278       .batch_size(2)
5279       .input_height(pooling_size.second + 3)
5280       .input_width(pooling_size.first + 2)
5281       .pooling_height(pooling_size.second)
5282       .pooling_width(pooling_size.first)
5283       .channels(channels)
5284       .TestF32();
5285   }
5286 }
5287 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_pool_with_stride)5288 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_pool_with_stride) {
5289   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5290   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5291   for (size_t channels = 1; channels <= 100; channels += 15) {
5292     for (size_t stride_width = 1; stride_width <= 2; stride_width++) {
5293       for (size_t stride_height = 1; stride_height <= 2; stride_height++) {
5294         if (stride_width == 1 && stride_height == 1) {
5295           continue;
5296         }
5297 
5298         AveragePoolingOperatorTester()
5299           .batch_size(2)
5300           .input_height(pooling_size.first + 3)
5301           .input_width(pooling_size.second + 2)
5302           .pooling_height(pooling_size.first)
5303           .pooling_width(pooling_size.second)
5304           .stride_height(stride_height)
5305           .stride_width(stride_width)
5306           .channels(channels)
5307           .TestF32();
5308         AveragePoolingOperatorTester()
5309           .batch_size(2)
5310           .input_height(pooling_size.second + 3)
5311           .input_width(pooling_size.first + 2)
5312           .pooling_height(pooling_size.second)
5313           .pooling_width(pooling_size.first)
5314           .stride_height(stride_height)
5315           .stride_width(stride_width)
5316           .channels(channels)
5317           .TestF32();
5318       }
5319     }
5320   }
5321 }
5322 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_pool_with_width_padding)5323 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_pool_with_width_padding) {
5324   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5325   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5326   for (size_t channels = 1; channels <= 100; channels += 15) {
5327     for (size_t stride = 1; stride <= 2; stride++) {
5328       for (size_t padding_left = 0; padding_left <= 1; padding_left++) {
5329         for (size_t padding_right = 0; padding_right <= 1; padding_right++) {
5330           AveragePoolingOperatorTester()
5331             .batch_size(2)
5332             .input_height(pooling_size.first + 3)
5333             .input_width(pooling_size.second + 2)
5334             .padding_left(padding_left)
5335             .padding_right(padding_right)
5336             .pooling_height(pooling_size.first)
5337             .pooling_width(pooling_size.second)
5338             .stride(stride)
5339             .channels(channels)
5340             .TestF32();
5341           AveragePoolingOperatorTester()
5342             .batch_size(2)
5343             .input_height(pooling_size.second + 3)
5344             .input_width(pooling_size.first + 2)
5345             .padding_left(padding_left)
5346             .padding_right(padding_right)
5347             .pooling_height(pooling_size.second)
5348             .pooling_width(pooling_size.first)
5349             .stride(stride)
5350             .channels(channels)
5351             .TestF32();
5352         }
5353       }
5354     }
5355   }
5356 }
5357 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_pool_with_height_padding)5358 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_pool_with_height_padding) {
5359   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5360   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5361   for (size_t channels = 1; channels <= 100; channels += 15) {
5362     for (size_t stride = 1; stride <= 2; stride++) {
5363       for (size_t padding_top = 0; padding_top <= 1; padding_top++) {
5364         for (size_t padding_bottom = 0; padding_bottom <= 1; padding_bottom++) {
5365           AveragePoolingOperatorTester()
5366             .batch_size(2)
5367             .input_height(pooling_size.first + 3)
5368             .input_width(pooling_size.second + 2)
5369             .padding_top(padding_top)
5370             .padding_bottom(padding_bottom)
5371             .pooling_height(pooling_size.first)
5372             .pooling_width(pooling_size.second)
5373             .stride(stride)
5374             .channels(channels)
5375             .TestF32();
5376           AveragePoolingOperatorTester()
5377             .batch_size(2)
5378             .input_height(pooling_size.second + 3)
5379             .input_width(pooling_size.first + 2)
5380             .padding_top(padding_top)
5381             .padding_bottom(padding_bottom)
5382             .pooling_height(pooling_size.second)
5383             .pooling_width(pooling_size.first)
5384             .stride(stride)
5385             .channels(channels)
5386             .TestF32();
5387         }
5388       }
5389     }
5390   }
5391 }
5392 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_pool_with_tf_same_padding)5393 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_pool_with_tf_same_padding) {
5394   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5395   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5396   for (size_t channels = 1; channels <= 100; channels += 15) {
5397     for (size_t stride = 1; stride <= 2; stride++) {
5398       for (size_t input_height = pooling_size.first + 3; input_height <= pooling_size.first + 4; input_height++) {
5399         AveragePoolingOperatorTester()
5400           .batch_size(2)
5401           .input_height(input_height)
5402           .input_width(pooling_size.second + 2)
5403           .padding_tf_same(true)
5404           .pooling_height(pooling_size.first)
5405           .pooling_width(pooling_size.second)
5406           .stride(stride)
5407           .channels(channels)
5408           .TestF32();
5409       }
5410       for (size_t input_width = pooling_size.second + 2; input_width <= pooling_size.second + 3; input_width++) {
5411         AveragePoolingOperatorTester()
5412           .batch_size(2)
5413           .input_height(pooling_size.first + 3)
5414           .input_width(input_width)
5415           .padding_tf_same(true)
5416           .pooling_height(pooling_size.first)
5417           .pooling_width(pooling_size.second)
5418           .stride(stride)
5419           .channels(channels)
5420           .TestF32();
5421       }
5422       for (size_t input_height = pooling_size.second + 3; input_height <= pooling_size.second + 4; input_height++) {
5423         AveragePoolingOperatorTester()
5424           .batch_size(2)
5425           .input_height(input_height)
5426           .input_width(pooling_size.first + 2)
5427           .padding_tf_same(true)
5428           .pooling_height(pooling_size.second)
5429           .pooling_width(pooling_size.first)
5430           .stride(stride)
5431           .channels(channels)
5432           .TestF32();
5433       }
5434       for (size_t input_width = pooling_size.first + 2; input_width <= pooling_size.first + 3; input_width++) {
5435         AveragePoolingOperatorTester()
5436           .batch_size(2)
5437           .input_height(pooling_size.second + 3)
5438           .input_width(input_width)
5439           .padding_tf_same(true)
5440           .pooling_height(pooling_size.second)
5441           .pooling_width(pooling_size.first)
5442           .stride(stride)
5443           .channels(channels)
5444           .TestF32();
5445       }
5446     }
5447   }
5448 }
5449 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_pool_with_input_stride)5450 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_pool_with_input_stride) {
5451   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5452   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5453   for (size_t channels = 1; channels <= 100; channels += 15) {
5454     AveragePoolingOperatorTester()
5455       .batch_size(2)
5456       .input_height(pooling_size.first + 3)
5457       .input_width(pooling_size.second + 2)
5458       .pooling_height(pooling_size.first)
5459       .pooling_width(pooling_size.second)
5460       .channels(channels)
5461       .input_pixel_stride(2 * channels + 3)
5462       .TestF32();
5463     AveragePoolingOperatorTester()
5464       .batch_size(2)
5465       .input_height(pooling_size.second + 3)
5466       .input_width(pooling_size.first + 2)
5467       .pooling_height(pooling_size.second)
5468       .pooling_width(pooling_size.first)
5469       .channels(channels)
5470       .input_pixel_stride(2 * channels + 3)
5471       .TestF32();
5472   }
5473 }
5474 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_pool_with_output_stride)5475 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_pool_with_output_stride) {
5476   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5477   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5478   for (size_t channels = 1; channels <= 100; channels += 15) {
5479     AveragePoolingOperatorTester()
5480       .batch_size(2)
5481       .input_height(pooling_size.first + 3)
5482       .input_width(pooling_size.second + 2)
5483       .pooling_height(pooling_size.first)
5484       .pooling_width(pooling_size.second)
5485       .channels(channels)
5486       .output_pixel_stride(2 * channels + 3)
5487       .TestF32();
5488     AveragePoolingOperatorTester()
5489       .batch_size(2)
5490       .input_height(pooling_size.second + 3)
5491       .input_width(pooling_size.first + 2)
5492       .pooling_height(pooling_size.second)
5493       .pooling_width(pooling_size.first)
5494       .channels(channels)
5495       .output_pixel_stride(2 * channels + 3)
5496       .TestF32();
5497   }
5498 }
5499 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_pool_with_qmin)5500 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_pool_with_qmin) {
5501   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5502   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5503   for (size_t channels = 1; channels <= 100; channels += 15) {
5504     AveragePoolingOperatorTester()
5505       .batch_size(2)
5506       .input_height(pooling_size.first + 3)
5507       .input_width(pooling_size.second + 2)
5508       .pooling_height(pooling_size.first)
5509       .pooling_width(pooling_size.second)
5510       .channels(channels)
5511       .qmin(128)
5512       .TestF32();
5513     AveragePoolingOperatorTester()
5514       .batch_size(2)
5515       .input_height(pooling_size.second + 3)
5516       .input_width(pooling_size.first + 2)
5517       .pooling_height(pooling_size.second)
5518       .pooling_width(pooling_size.first)
5519       .channels(channels)
5520       .qmin(128)
5521       .TestF32();
5522   }
5523 }
5524 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_pool_with_qmax)5525 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_pool_with_qmax) {
5526   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5527   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.avgpool.primary_tile);
5528   for (size_t channels = 1; channels <= 100; channels += 15) {
5529     AveragePoolingOperatorTester()
5530       .batch_size(2)
5531       .input_height(pooling_size.first + 3)
5532       .input_width(pooling_size.second + 2)
5533       .pooling_height(pooling_size.first)
5534       .pooling_width(pooling_size.second)
5535       .channels(channels)
5536       .qmax(128)
5537       .TestF32();
5538     AveragePoolingOperatorTester()
5539       .batch_size(2)
5540       .input_height(pooling_size.second + 3)
5541       .input_width(pooling_size.first + 2)
5542       .pooling_height(pooling_size.second)
5543       .pooling_width(pooling_size.first)
5544       .channels(channels)
5545       .qmax(128)
5546       .TestF32();
5547   }
5548 }
5549 
5550 /**************************** AVGPOOL path, multipass ****************************/
5551 
TEST(AVERAGE_POOLING_NHWC_F32,large_pool)5552 TEST(AVERAGE_POOLING_NHWC_F32, large_pool) {
5553   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5554   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.avgpool.primary_tile * 2);
5555   for (size_t channels = 1; channels <= 100; channels += 15) {
5556     AveragePoolingOperatorTester()
5557       .input_height(pooling_size.first + 3)
5558       .input_width(pooling_size.second + 2)
5559       .pooling_height(pooling_size.first)
5560       .pooling_width(pooling_size.second)
5561       .channels(channels)
5562       .TestF32();
5563     AveragePoolingOperatorTester()
5564       .input_height(pooling_size.second + 3)
5565       .input_width(pooling_size.first + 2)
5566       .pooling_height(pooling_size.second)
5567       .pooling_width(pooling_size.first)
5568       .channels(channels)
5569       .TestF32();
5570   }
5571 }
5572 
TEST(AVERAGE_POOLING_NHWC_F32,large_pool_with_stride)5573 TEST(AVERAGE_POOLING_NHWC_F32, large_pool_with_stride) {
5574   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5575   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
5576   for (size_t channels = 1; channels <= 100; channels += 15) {
5577     for (size_t stride_width = 1; stride_width <= 2; stride_width++) {
5578       for (size_t stride_height = 1; stride_height <= 2; stride_height++) {
5579         if (stride_width == 1 && stride_height == 1) {
5580           continue;
5581         }
5582 
5583         AveragePoolingOperatorTester()
5584           .input_height(pooling_size.first + 3)
5585           .input_width(pooling_size.second + 2)
5586           .pooling_height(pooling_size.first)
5587           .pooling_width(pooling_size.second)
5588           .stride_height(stride_height)
5589           .stride_width(stride_width)
5590           .channels(channels)
5591           .TestF32();
5592         AveragePoolingOperatorTester()
5593           .input_height(pooling_size.second + 3)
5594           .input_width(pooling_size.first + 2)
5595           .pooling_height(pooling_size.second)
5596           .pooling_width(pooling_size.first)
5597           .stride_height(stride_height)
5598           .stride_width(stride_width)
5599           .channels(channels)
5600           .TestF32();
5601       }
5602     }
5603   }
5604 }
5605 
TEST(AVERAGE_POOLING_NHWC_F32,large_pool_with_width_padding)5606 TEST(AVERAGE_POOLING_NHWC_F32, large_pool_with_width_padding) {
5607   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5608   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
5609   for (size_t channels = 1; channels <= 100; channels += 15) {
5610     for (size_t stride = 1; stride <= 2; stride++) {
5611       for (size_t padding_left = 1; padding_left <= 2; padding_left++) {
5612         AveragePoolingOperatorTester()
5613           .input_height(pooling_size.first + 3)
5614           .input_width(pooling_size.second + 2)
5615           .padding_left(padding_left)
5616           .pooling_height(pooling_size.first)
5617           .pooling_width(pooling_size.second)
5618           .stride(stride)
5619           .channels(channels)
5620           .TestF32();
5621         AveragePoolingOperatorTester()
5622           .input_height(pooling_size.second + 3)
5623           .input_width(pooling_size.first + 2)
5624           .padding_left(padding_left)
5625           .pooling_height(pooling_size.second)
5626           .pooling_width(pooling_size.first)
5627           .stride(stride)
5628           .channels(channels)
5629           .TestF32();
5630       }
5631       for (size_t padding_right = 1; padding_right <= 2; padding_right++) {
5632         AveragePoolingOperatorTester()
5633           .input_height(pooling_size.first + 3)
5634           .input_width(pooling_size.second + 2)
5635           .padding_right(padding_right)
5636           .pooling_height(pooling_size.first)
5637           .pooling_width(pooling_size.second)
5638           .stride(stride)
5639           .channels(channels)
5640           .TestF32();
5641         AveragePoolingOperatorTester()
5642           .input_height(pooling_size.second + 3)
5643           .input_width(pooling_size.first + 2)
5644           .padding_right(padding_right)
5645           .pooling_height(pooling_size.second)
5646           .pooling_width(pooling_size.first)
5647           .stride(stride)
5648           .channels(channels)
5649           .TestF32();
5650       }
5651     }
5652   }
5653 }
5654 
TEST(AVERAGE_POOLING_NHWC_F32,large_pool_with_height_padding)5655 TEST(AVERAGE_POOLING_NHWC_F32, large_pool_with_height_padding) {
5656   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5657   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
5658   for (size_t channels = 1; channels <= 100; channels += 15) {
5659     for (size_t stride = 1; stride <= 2; stride++) {
5660       for (size_t padding_top = 0; padding_top <= 1; padding_top++) {
5661         for (size_t padding_bottom = 0; padding_bottom <= 1; padding_bottom++) {
5662           AveragePoolingOperatorTester()
5663             .input_height(pooling_size.first + 3)
5664             .input_width(pooling_size.second + 2)
5665             .padding_top(padding_top)
5666             .padding_bottom(padding_bottom)
5667             .pooling_height(pooling_size.first)
5668             .pooling_width(pooling_size.second)
5669             .stride(stride)
5670             .channels(channels)
5671             .TestF32();
5672           AveragePoolingOperatorTester()
5673             .input_height(pooling_size.second + 3)
5674             .input_width(pooling_size.first + 2)
5675             .padding_top(padding_top)
5676             .padding_bottom(padding_bottom)
5677             .pooling_height(pooling_size.second)
5678             .pooling_width(pooling_size.first)
5679             .stride(stride)
5680             .channels(channels)
5681             .TestF32();
5682         }
5683       }
5684     }
5685   }
5686 }
5687 
TEST(AVERAGE_POOLING_NHWC_F32,large_pool_with_tf_same_padding)5688 TEST(AVERAGE_POOLING_NHWC_F32, large_pool_with_tf_same_padding) {
5689   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5690   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
5691   for (size_t channels = 1; channels <= 100; channels += 15) {
5692     for (size_t stride = 1; stride <= 2; stride++) {
5693       for (size_t input_height = pooling_size.first + 3; input_height <= pooling_size.first + 4; input_height++) {
5694         AveragePoolingOperatorTester()
5695           .input_height(input_height)
5696           .input_width(pooling_size.second + 2)
5697           .padding_tf_same(true)
5698           .pooling_height(pooling_size.first)
5699           .pooling_width(pooling_size.second)
5700           .stride(stride)
5701           .channels(channels)
5702           .TestF32();
5703       }
5704       for (size_t input_width = pooling_size.second + 2; input_width <= pooling_size.second + 3; input_width++) {
5705         AveragePoolingOperatorTester()
5706           .input_height(pooling_size.first + 3)
5707           .input_width(input_width)
5708           .padding_tf_same(true)
5709           .pooling_height(pooling_size.first)
5710           .pooling_width(pooling_size.second)
5711           .stride(stride)
5712           .channels(channels)
5713           .TestF32();
5714       }
5715       for (size_t input_height = pooling_size.second + 3; input_height <= pooling_size.second + 4; input_height++) {
5716         AveragePoolingOperatorTester()
5717           .input_height(input_height)
5718           .input_width(pooling_size.first + 2)
5719           .padding_tf_same(true)
5720           .pooling_height(pooling_size.second)
5721           .pooling_width(pooling_size.first)
5722           .stride(stride)
5723           .channels(channels)
5724           .TestF32();
5725       }
5726       for (size_t input_width = pooling_size.first + 2; input_width <= pooling_size.first + 3; input_width++) {
5727         AveragePoolingOperatorTester()
5728           .input_height(pooling_size.second + 3)
5729           .input_width(input_width)
5730           .padding_tf_same(true)
5731           .pooling_height(pooling_size.second)
5732           .pooling_width(pooling_size.first)
5733           .stride(stride)
5734           .channels(channels)
5735           .TestF32();
5736       }
5737     }
5738   }
5739 }
5740 
TEST(AVERAGE_POOLING_NHWC_F32,large_pool_with_input_stride)5741 TEST(AVERAGE_POOLING_NHWC_F32, large_pool_with_input_stride) {
5742   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5743   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
5744   for (size_t channels = 1; channels <= 100; channels += 15) {
5745     AveragePoolingOperatorTester()
5746       .input_height(pooling_size.first + 3)
5747       .input_width(pooling_size.second + 2)
5748       .pooling_height(pooling_size.first)
5749       .pooling_width(pooling_size.second)
5750       .channels(channels)
5751       .input_pixel_stride(2 * channels + 3)
5752       .TestF32();
5753     AveragePoolingOperatorTester()
5754       .input_height(pooling_size.second + 3)
5755       .input_width(pooling_size.first + 2)
5756       .pooling_height(pooling_size.second)
5757       .pooling_width(pooling_size.first)
5758       .channels(channels)
5759       .input_pixel_stride(2 * channels + 3)
5760       .TestF32();
5761   }
5762 }
5763 
TEST(AVERAGE_POOLING_NHWC_F32,large_pool_with_output_stride)5764 TEST(AVERAGE_POOLING_NHWC_F32, large_pool_with_output_stride) {
5765   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5766   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
5767   for (size_t channels = 1; channels <= 100; channels += 15) {
5768     AveragePoolingOperatorTester()
5769       .input_height(pooling_size.first + 3)
5770       .input_width(pooling_size.second + 2)
5771       .pooling_height(pooling_size.first)
5772       .pooling_width(pooling_size.second)
5773       .channels(channels)
5774       .output_pixel_stride(2 * channels + 3)
5775       .TestF32();
5776     AveragePoolingOperatorTester()
5777       .input_height(pooling_size.second + 3)
5778       .input_width(pooling_size.first + 2)
5779       .pooling_height(pooling_size.second)
5780       .pooling_width(pooling_size.first)
5781       .channels(channels)
5782       .output_pixel_stride(2 * channels + 3)
5783       .TestF32();
5784   }
5785 }
5786 
TEST(AVERAGE_POOLING_NHWC_F32,large_pool_with_qmin)5787 TEST(AVERAGE_POOLING_NHWC_F32, large_pool_with_qmin) {
5788   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5789   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
5790   for (size_t channels = 1; channels <= 100; channels += 15) {
5791     AveragePoolingOperatorTester()
5792       .input_height(pooling_size.first + 3)
5793       .input_width(pooling_size.second + 2)
5794       .pooling_height(pooling_size.first)
5795       .pooling_width(pooling_size.second)
5796       .channels(channels)
5797       .qmin(128)
5798       .TestF32();
5799     AveragePoolingOperatorTester()
5800       .input_height(pooling_size.second + 3)
5801       .input_width(pooling_size.first + 2)
5802       .pooling_height(pooling_size.second)
5803       .pooling_width(pooling_size.first)
5804       .channels(channels)
5805       .qmin(128)
5806       .TestF32();
5807   }
5808 }
5809 
TEST(AVERAGE_POOLING_NHWC_F32,large_pool_with_qmax)5810 TEST(AVERAGE_POOLING_NHWC_F32, large_pool_with_qmax) {
5811   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5812   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
5813   for (size_t channels = 1; channels <= 100; channels += 15) {
5814     AveragePoolingOperatorTester()
5815       .input_height(pooling_size.first + 3)
5816       .input_width(pooling_size.second + 2)
5817       .pooling_height(pooling_size.first)
5818       .pooling_width(pooling_size.second)
5819       .channels(channels)
5820       .qmax(128)
5821       .TestF32();
5822     AveragePoolingOperatorTester()
5823       .input_height(pooling_size.second + 3)
5824       .input_width(pooling_size.first + 2)
5825       .pooling_height(pooling_size.second)
5826       .pooling_width(pooling_size.first)
5827       .channels(channels)
5828       .qmax(128)
5829       .TestF32();
5830   }
5831 }
5832 
5833 /**************************** AVGPOOL path, multipass, batched ****************************/
5834 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_pool)5835 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_pool) {
5836   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5837   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.avgpool.primary_tile * 2);
5838   for (size_t channels = 1; channels <= 100; channels += 15) {
5839     AveragePoolingOperatorTester()
5840       .batch_size(2)
5841       .input_height(pooling_size.first + 3)
5842       .input_width(pooling_size.second + 2)
5843       .pooling_height(pooling_size.first)
5844       .pooling_width(pooling_size.second)
5845       .channels(channels)
5846       .TestF32();
5847     AveragePoolingOperatorTester()
5848       .batch_size(2)
5849       .input_height(pooling_size.second + 3)
5850       .input_width(pooling_size.first + 2)
5851       .pooling_height(pooling_size.second)
5852       .pooling_width(pooling_size.first)
5853       .channels(channels)
5854       .TestF32();
5855   }
5856 }
5857 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_pool_with_stride)5858 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_pool_with_stride) {
5859   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5860   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
5861   for (size_t channels = 1; channels <= 100; channels += 15) {
5862     for (size_t stride_width = 1; stride_width <= 2; stride_width++) {
5863       for (size_t stride_height = 1; stride_height <= 2; stride_height++) {
5864         if (stride_width == 1 && stride_height == 1) {
5865           continue;
5866         }
5867 
5868         AveragePoolingOperatorTester()
5869           .batch_size(2)
5870           .input_height(pooling_size.first + 3)
5871           .input_width(pooling_size.second + 2)
5872           .pooling_height(pooling_size.first)
5873           .pooling_width(pooling_size.second)
5874           .stride_height(stride_height)
5875           .stride_width(stride_width)
5876           .channels(channels)
5877           .TestF32();
5878         AveragePoolingOperatorTester()
5879           .batch_size(2)
5880           .input_height(pooling_size.second + 3)
5881           .input_width(pooling_size.first + 2)
5882           .pooling_height(pooling_size.second)
5883           .pooling_width(pooling_size.first)
5884           .stride_height(stride_height)
5885           .stride_width(stride_width)
5886           .channels(channels)
5887           .TestF32();
5888       }
5889     }
5890   }
5891 }
5892 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_pool_with_width_padding)5893 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_pool_with_width_padding) {
5894   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5895   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
5896   for (size_t channels = 1; channels <= 100; channels += 15) {
5897     for (size_t stride = 1; stride <= 2; stride++) {
5898       for (size_t padding_left = 0; padding_left <= 1; padding_left++) {
5899         for (size_t padding_right = 0; padding_right <= 1; padding_right++) {
5900           AveragePoolingOperatorTester()
5901             .batch_size(2)
5902             .input_height(pooling_size.first + 3)
5903             .input_width(pooling_size.second + 2)
5904             .padding_left(padding_left)
5905             .padding_right(padding_right)
5906             .pooling_height(pooling_size.first)
5907             .pooling_width(pooling_size.second)
5908             .stride(stride)
5909             .channels(channels)
5910             .TestF32();
5911           AveragePoolingOperatorTester()
5912             .batch_size(2)
5913             .input_height(pooling_size.second + 3)
5914             .input_width(pooling_size.first + 2)
5915             .padding_left(padding_left)
5916             .padding_right(padding_right)
5917             .pooling_height(pooling_size.second)
5918             .pooling_width(pooling_size.first)
5919             .stride(stride)
5920             .channels(channels)
5921             .TestF32();
5922         }
5923       }
5924     }
5925   }
5926 }
5927 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_pool_with_height_padding)5928 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_pool_with_height_padding) {
5929   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5930   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
5931   for (size_t channels = 1; channels <= 100; channels += 15) {
5932     for (size_t stride = 1; stride <= 2; stride++) {
5933       for (size_t padding_top = 0; padding_top <= 1; padding_top++) {
5934         for (size_t padding_bottom = 0; padding_bottom <= 1; padding_bottom++) {
5935           AveragePoolingOperatorTester()
5936             .batch_size(2)
5937             .input_height(pooling_size.first + 3)
5938             .input_width(pooling_size.second + 2)
5939             .padding_top(padding_top)
5940             .padding_bottom(padding_bottom)
5941             .pooling_height(pooling_size.first)
5942             .pooling_width(pooling_size.second)
5943             .stride(stride)
5944             .channels(channels)
5945             .TestF32();
5946           AveragePoolingOperatorTester()
5947             .batch_size(2)
5948             .input_height(pooling_size.second + 3)
5949             .input_width(pooling_size.first + 2)
5950             .padding_top(padding_top)
5951             .padding_bottom(padding_bottom)
5952             .pooling_height(pooling_size.second)
5953             .pooling_width(pooling_size.first)
5954             .stride(stride)
5955             .channels(channels)
5956             .TestF32();
5957         }
5958       }
5959     }
5960   }
5961 }
5962 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_pool_with_tf_same_padding)5963 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_pool_with_tf_same_padding) {
5964   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
5965   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
5966   for (size_t channels = 1; channels <= 100; channels += 15) {
5967     for (size_t stride = 1; stride <= 2; stride++) {
5968       for (size_t input_height = pooling_size.first + 3; input_height <= pooling_size.first + 4; input_height++) {
5969         AveragePoolingOperatorTester()
5970           .batch_size(2)
5971           .input_height(input_height)
5972           .input_width(pooling_size.second + 2)
5973           .padding_tf_same(true)
5974           .pooling_height(pooling_size.first)
5975           .pooling_width(pooling_size.second)
5976           .stride(stride)
5977           .channels(channels)
5978           .TestF32();
5979       }
5980       for (size_t input_width = pooling_size.second + 2; input_width <= pooling_size.second + 3; input_width++) {
5981         AveragePoolingOperatorTester()
5982           .batch_size(2)
5983           .input_height(pooling_size.first + 3)
5984           .input_width(input_width)
5985           .padding_tf_same(true)
5986           .pooling_height(pooling_size.first)
5987           .pooling_width(pooling_size.second)
5988           .stride(stride)
5989           .channels(channels)
5990           .TestF32();
5991       }
5992       for (size_t input_height = pooling_size.second + 3; input_height <= pooling_size.second + 4; input_height++) {
5993         AveragePoolingOperatorTester()
5994           .batch_size(2)
5995           .input_height(input_height)
5996           .input_width(pooling_size.first + 2)
5997           .padding_tf_same(true)
5998           .pooling_height(pooling_size.second)
5999           .pooling_width(pooling_size.first)
6000           .stride(stride)
6001           .channels(channels)
6002           .TestF32();
6003       }
6004       for (size_t input_width = pooling_size.first + 2; input_width <= pooling_size.first + 3; input_width++) {
6005         AveragePoolingOperatorTester()
6006           .batch_size(2)
6007           .input_height(pooling_size.second + 3)
6008           .input_width(input_width)
6009           .padding_tf_same(true)
6010           .pooling_height(pooling_size.second)
6011           .pooling_width(pooling_size.first)
6012           .stride(stride)
6013           .channels(channels)
6014           .TestF32();
6015       }
6016     }
6017   }
6018 }
6019 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_pool_with_input_stride)6020 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_pool_with_input_stride) {
6021   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6022   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6023   for (size_t channels = 1; channels <= 100; channels += 15) {
6024     AveragePoolingOperatorTester()
6025       .batch_size(2)
6026       .input_height(pooling_size.first + 3)
6027       .input_width(pooling_size.second + 2)
6028       .pooling_height(pooling_size.first)
6029       .pooling_width(pooling_size.second)
6030       .channels(channels)
6031       .input_pixel_stride(2 * channels + 3)
6032       .TestF32();
6033     AveragePoolingOperatorTester()
6034       .batch_size(2)
6035       .input_height(pooling_size.second + 3)
6036       .input_width(pooling_size.first + 2)
6037       .pooling_height(pooling_size.second)
6038       .pooling_width(pooling_size.first)
6039       .channels(channels)
6040       .input_pixel_stride(2 * channels + 3)
6041       .TestF32();
6042   }
6043 }
6044 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_pool_with_output_stride)6045 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_pool_with_output_stride) {
6046   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6047   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6048   for (size_t channels = 1; channels <= 100; channels += 15) {
6049     AveragePoolingOperatorTester()
6050       .batch_size(2)
6051       .input_height(pooling_size.first + 3)
6052       .input_width(pooling_size.second + 2)
6053       .pooling_height(pooling_size.first)
6054       .pooling_width(pooling_size.second)
6055       .channels(channels)
6056       .output_pixel_stride(2 * channels + 3)
6057       .TestF32();
6058     AveragePoolingOperatorTester()
6059       .batch_size(2)
6060       .input_height(pooling_size.second + 3)
6061       .input_width(pooling_size.first + 2)
6062       .pooling_height(pooling_size.second)
6063       .pooling_width(pooling_size.first)
6064       .channels(channels)
6065       .output_pixel_stride(2 * channels + 3)
6066       .TestF32();
6067   }
6068 }
6069 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_pool_with_qmin)6070 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_pool_with_qmin) {
6071   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6072   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6073   for (size_t channels = 1; channels <= 100; channels += 15) {
6074     AveragePoolingOperatorTester()
6075       .batch_size(2)
6076       .input_height(pooling_size.first + 3)
6077       .input_width(pooling_size.second + 2)
6078       .pooling_height(pooling_size.first)
6079       .pooling_width(pooling_size.second)
6080       .channels(channels)
6081       .qmin(128)
6082       .TestF32();
6083     AveragePoolingOperatorTester()
6084       .batch_size(2)
6085       .input_height(pooling_size.second + 3)
6086       .input_width(pooling_size.first + 2)
6087       .pooling_height(pooling_size.second)
6088       .pooling_width(pooling_size.first)
6089       .channels(channels)
6090       .qmin(128)
6091       .TestF32();
6092   }
6093 }
6094 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_pool_with_qmax)6095 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_pool_with_qmax) {
6096   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6097   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6098   for (size_t channels = 1; channels <= 100; channels += 15) {
6099     AveragePoolingOperatorTester()
6100       .batch_size(2)
6101       .input_height(pooling_size.first + 3)
6102       .input_width(pooling_size.second + 2)
6103       .pooling_height(pooling_size.first)
6104       .pooling_width(pooling_size.second)
6105       .channels(channels)
6106       .qmax(128)
6107       .TestF32();
6108     AveragePoolingOperatorTester()
6109       .batch_size(2)
6110       .input_height(pooling_size.second + 3)
6111       .input_width(pooling_size.first + 2)
6112       .pooling_height(pooling_size.second)
6113       .pooling_width(pooling_size.first)
6114       .channels(channels)
6115       .qmax(128)
6116       .TestF32();
6117   }
6118 }
6119 
6120 /**************************** GAVGPOOL path, unipass ****************************/
6121 
TEST(AVERAGE_POOLING_NHWC_F32,small_image)6122 TEST(AVERAGE_POOLING_NHWC_F32, small_image) {
6123   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6124   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
6125   for (size_t channels = 1; channels <= 100; channels += 15) {
6126     AveragePoolingOperatorTester()
6127       .input_height(pooling_size.first)
6128       .input_width(pooling_size.second)
6129       .pooling_height(pooling_size.first)
6130       .pooling_width(pooling_size.second)
6131       .channels(channels)
6132       .TestF32();
6133     AveragePoolingOperatorTester()
6134       .input_height(pooling_size.second)
6135       .input_width(pooling_size.first)
6136       .pooling_height(pooling_size.second)
6137       .pooling_width(pooling_size.first)
6138       .channels(channels)
6139       .TestF32();
6140   }
6141 }
6142 
TEST(AVERAGE_POOLING_NHWC_F32,small_image_with_width_padding)6143 TEST(AVERAGE_POOLING_NHWC_F32, small_image_with_width_padding) {
6144   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6145   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
6146   for (size_t channels = 1; channels <= 100; channels += 15) {
6147     /* With left padding */
6148     AveragePoolingOperatorTester()
6149       .input_height(pooling_size.first)
6150       .input_width(pooling_size.second - 1)
6151       .padding_left(1)
6152       .pooling_height(pooling_size.first)
6153       .pooling_width(pooling_size.second)
6154       .channels(channels)
6155       .TestF32();
6156     AveragePoolingOperatorTester()
6157       .input_height(pooling_size.second)
6158       .input_width(pooling_size.first - 1)
6159       .padding_left(1)
6160       .pooling_height(pooling_size.second)
6161       .pooling_width(pooling_size.first)
6162       .channels(channels)
6163       .TestF32();
6164 
6165     /* With right padding */
6166     AveragePoolingOperatorTester()
6167       .input_height(pooling_size.first)
6168       .input_width(pooling_size.second - 1)
6169       .padding_right(1)
6170       .pooling_height(pooling_size.first)
6171       .pooling_width(pooling_size.second)
6172       .channels(channels)
6173       .TestF32();
6174     AveragePoolingOperatorTester()
6175       .input_height(pooling_size.second)
6176       .input_width(pooling_size.first - 1)
6177       .padding_right(1)
6178       .pooling_height(pooling_size.second)
6179       .pooling_width(pooling_size.first)
6180       .channels(channels)
6181       .TestF32();
6182   }
6183 }
6184 
TEST(AVERAGE_POOLING_NHWC_F32,small_image_with_height_padding)6185 TEST(AVERAGE_POOLING_NHWC_F32, small_image_with_height_padding) {
6186   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6187   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
6188   for (size_t channels = 1; channels <= 100; channels += 15) {
6189     /* With top padding */
6190     AveragePoolingOperatorTester()
6191       .input_height(pooling_size.first - 1)
6192       .input_width(pooling_size.second)
6193       .padding_top(1)
6194       .pooling_height(pooling_size.first)
6195       .pooling_width(pooling_size.second)
6196       .channels(channels)
6197       .TestF32();
6198     AveragePoolingOperatorTester()
6199       .input_height(pooling_size.second - 1)
6200       .input_width(pooling_size.first)
6201       .padding_top(1)
6202       .pooling_height(pooling_size.second)
6203       .pooling_width(pooling_size.first)
6204       .channels(channels)
6205       .TestF32();
6206 
6207     /* With bottom padding */
6208     AveragePoolingOperatorTester()
6209       .input_height(pooling_size.first - 1)
6210       .input_width(pooling_size.second)
6211       .padding_bottom(1)
6212       .pooling_height(pooling_size.first)
6213       .pooling_width(pooling_size.second)
6214       .channels(channels)
6215       .TestF32();
6216     AveragePoolingOperatorTester()
6217       .input_height(pooling_size.second - 1)
6218       .input_width(pooling_size.first)
6219       .padding_bottom(1)
6220       .pooling_height(pooling_size.second)
6221       .pooling_width(pooling_size.first)
6222       .channels(channels)
6223       .TestF32();
6224   }
6225 }
6226 
TEST(AVERAGE_POOLING_NHWC_F32,small_image_with_input_stride)6227 TEST(AVERAGE_POOLING_NHWC_F32, small_image_with_input_stride) {
6228   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6229   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
6230   for (size_t channels = 1; channels <= 100; channels += 15) {
6231     AveragePoolingOperatorTester()
6232       .input_height(pooling_size.first)
6233       .input_width(pooling_size.second)
6234       .pooling_height(pooling_size.first)
6235       .pooling_width(pooling_size.second)
6236       .channels(channels)
6237       .input_pixel_stride(2 * channels + 3)
6238       .TestF32();
6239     AveragePoolingOperatorTester()
6240       .input_height(pooling_size.second)
6241       .input_width(pooling_size.first)
6242       .pooling_height(pooling_size.second)
6243       .pooling_width(pooling_size.first)
6244       .channels(channels)
6245       .input_pixel_stride(2 * channels + 3)
6246       .TestF32();
6247   }
6248 }
6249 
TEST(AVERAGE_POOLING_NHWC_F32,small_image_with_output_stride)6250 TEST(AVERAGE_POOLING_NHWC_F32, small_image_with_output_stride) {
6251   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6252   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
6253   for (size_t channels = 1; channels <= 100; channels += 15) {
6254     AveragePoolingOperatorTester()
6255       .input_height(pooling_size.first)
6256       .input_width(pooling_size.second)
6257       .pooling_height(pooling_size.first)
6258       .pooling_width(pooling_size.second)
6259       .channels(channels)
6260       .output_pixel_stride(2 * channels + 3)
6261       .TestF32();
6262     AveragePoolingOperatorTester()
6263       .input_height(pooling_size.second)
6264       .input_width(pooling_size.first)
6265       .pooling_height(pooling_size.second)
6266       .pooling_width(pooling_size.first)
6267       .channels(channels)
6268       .output_pixel_stride(2 * channels + 3)
6269       .TestF32();
6270   }
6271 }
6272 
TEST(AVERAGE_POOLING_NHWC_F32,small_image_with_qmin)6273 TEST(AVERAGE_POOLING_NHWC_F32, small_image_with_qmin) {
6274   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6275   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
6276   for (size_t channels = 1; channels <= 100; channels += 15) {
6277     AveragePoolingOperatorTester()
6278       .input_height(pooling_size.first)
6279       .input_width(pooling_size.second)
6280       .pooling_height(pooling_size.first)
6281       .pooling_width(pooling_size.second)
6282       .channels(channels)
6283       .qmin(128)
6284       .TestF32();
6285     AveragePoolingOperatorTester()
6286       .input_height(pooling_size.second)
6287       .input_width(pooling_size.first)
6288       .pooling_height(pooling_size.second)
6289       .pooling_width(pooling_size.first)
6290       .channels(channels)
6291       .qmin(128)
6292       .TestF32();
6293   }
6294 }
6295 
TEST(AVERAGE_POOLING_NHWC_F32,small_image_with_qmax)6296 TEST(AVERAGE_POOLING_NHWC_F32, small_image_with_qmax) {
6297   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6298   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
6299   for (size_t channels = 1; channels <= 100; channels += 15) {
6300     AveragePoolingOperatorTester()
6301       .input_height(pooling_size.first)
6302       .input_width(pooling_size.second)
6303       .pooling_height(pooling_size.first)
6304       .pooling_width(pooling_size.second)
6305       .channels(channels)
6306       .qmax(128)
6307       .TestF32();
6308     AveragePoolingOperatorTester()
6309       .input_height(pooling_size.second)
6310       .input_width(pooling_size.first)
6311       .pooling_height(pooling_size.second)
6312       .pooling_width(pooling_size.first)
6313       .channels(channels)
6314       .qmax(128)
6315       .TestF32();
6316   }
6317 }
6318 
6319 /**************************** GAVGPOOL path, unipass, batched ****************************/
6320 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_image)6321 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_image) {
6322   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6323   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
6324   for (size_t channels = 1; channels <= 100; channels += 15) {
6325     AveragePoolingOperatorTester()
6326       .batch_size(2)
6327       .input_height(pooling_size.first)
6328       .input_width(pooling_size.second)
6329       .pooling_height(pooling_size.first)
6330       .pooling_width(pooling_size.second)
6331       .channels(channels)
6332       .TestF32();
6333     AveragePoolingOperatorTester()
6334       .batch_size(2)
6335       .input_height(pooling_size.second)
6336       .input_width(pooling_size.first)
6337       .pooling_height(pooling_size.second)
6338       .pooling_width(pooling_size.first)
6339       .channels(channels)
6340       .TestF32();
6341   }
6342 }
6343 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_image_with_width_padding)6344 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_image_with_width_padding) {
6345   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6346   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
6347   for (size_t channels = 1; channels <= 100; channels += 15) {
6348     /* With left padding */
6349     AveragePoolingOperatorTester()
6350       .batch_size(2)
6351       .input_height(pooling_size.first)
6352       .input_width(pooling_size.second - 1)
6353       .padding_left(1)
6354       .pooling_height(pooling_size.first)
6355       .pooling_width(pooling_size.second)
6356       .channels(channels)
6357       .TestF32();
6358     AveragePoolingOperatorTester()
6359       .batch_size(2)
6360       .input_height(pooling_size.second)
6361       .input_width(pooling_size.first - 1)
6362       .padding_left(1)
6363       .pooling_height(pooling_size.second)
6364       .pooling_width(pooling_size.first)
6365       .channels(channels)
6366       .TestF32();
6367 
6368     /* With right padding */
6369     AveragePoolingOperatorTester()
6370       .batch_size(2)
6371       .input_height(pooling_size.first)
6372       .input_width(pooling_size.second - 1)
6373       .padding_right(1)
6374       .pooling_height(pooling_size.first)
6375       .pooling_width(pooling_size.second)
6376       .channels(channels)
6377       .TestF32();
6378     AveragePoolingOperatorTester()
6379       .batch_size(2)
6380       .input_height(pooling_size.second)
6381       .input_width(pooling_size.first - 1)
6382       .padding_right(1)
6383       .pooling_height(pooling_size.second)
6384       .pooling_width(pooling_size.first)
6385       .channels(channels)
6386       .TestF32();
6387   }
6388 }
6389 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_image_with_height_padding)6390 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_image_with_height_padding) {
6391   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6392   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
6393   for (size_t channels = 1; channels <= 100; channels += 15) {
6394     /* With top padding */
6395     AveragePoolingOperatorTester()
6396       .batch_size(2)
6397       .input_height(pooling_size.first - 1)
6398       .input_width(pooling_size.second)
6399       .padding_top(1)
6400       .pooling_height(pooling_size.first)
6401       .pooling_width(pooling_size.second)
6402       .channels(channels)
6403       .TestF32();
6404     AveragePoolingOperatorTester()
6405       .batch_size(2)
6406       .input_height(pooling_size.second - 1)
6407       .input_width(pooling_size.first)
6408       .padding_top(1)
6409       .pooling_height(pooling_size.second)
6410       .pooling_width(pooling_size.first)
6411       .channels(channels)
6412       .TestF32();
6413 
6414     /* With bottom padding */
6415     AveragePoolingOperatorTester()
6416       .batch_size(2)
6417       .input_height(pooling_size.first - 1)
6418       .input_width(pooling_size.second)
6419       .padding_bottom(1)
6420       .pooling_height(pooling_size.first)
6421       .pooling_width(pooling_size.second)
6422       .channels(channels)
6423       .TestF32();
6424     AveragePoolingOperatorTester()
6425       .batch_size(2)
6426       .input_height(pooling_size.second - 1)
6427       .input_width(pooling_size.first)
6428       .padding_bottom(1)
6429       .pooling_height(pooling_size.second)
6430       .pooling_width(pooling_size.first)
6431       .channels(channels)
6432       .TestF32();
6433   }
6434 }
6435 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_image_with_input_stride)6436 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_image_with_input_stride) {
6437   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6438   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
6439   for (size_t channels = 1; channels <= 100; channels += 15) {
6440     AveragePoolingOperatorTester()
6441       .batch_size(2)
6442       .input_height(pooling_size.first)
6443       .input_width(pooling_size.second)
6444       .pooling_height(pooling_size.first)
6445       .pooling_width(pooling_size.second)
6446       .channels(channels)
6447       .input_pixel_stride(2 * channels + 3)
6448       .TestF32();
6449     AveragePoolingOperatorTester()
6450       .batch_size(2)
6451       .input_height(pooling_size.second)
6452       .input_width(pooling_size.first)
6453       .pooling_height(pooling_size.second)
6454       .pooling_width(pooling_size.first)
6455       .channels(channels)
6456       .input_pixel_stride(2 * channels + 3)
6457       .TestF32();
6458   }
6459 }
6460 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_image_with_output_stride)6461 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_image_with_output_stride) {
6462   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6463   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
6464   for (size_t channels = 1; channels <= 100; channels += 15) {
6465     AveragePoolingOperatorTester()
6466       .batch_size(2)
6467       .input_height(pooling_size.first)
6468       .input_width(pooling_size.second)
6469       .pooling_height(pooling_size.first)
6470       .pooling_width(pooling_size.second)
6471       .channels(channels)
6472       .output_pixel_stride(2 * channels + 3)
6473       .TestF32();
6474     AveragePoolingOperatorTester()
6475       .batch_size(2)
6476       .input_height(pooling_size.second)
6477       .input_width(pooling_size.first)
6478       .pooling_height(pooling_size.second)
6479       .pooling_width(pooling_size.first)
6480       .channels(channels)
6481       .output_pixel_stride(2 * channels + 3)
6482       .TestF32();
6483   }
6484 }
6485 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_image_with_qmin)6486 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_image_with_qmin) {
6487   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6488   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
6489   for (size_t channels = 1; channels <= 100; channels += 15) {
6490     AveragePoolingOperatorTester()
6491       .batch_size(2)
6492       .input_height(pooling_size.first)
6493       .input_width(pooling_size.second)
6494       .pooling_height(pooling_size.first)
6495       .pooling_width(pooling_size.second)
6496       .channels(channels)
6497       .qmin(128)
6498       .TestF32();
6499     AveragePoolingOperatorTester()
6500       .batch_size(2)
6501       .input_height(pooling_size.second)
6502       .input_width(pooling_size.first)
6503       .pooling_height(pooling_size.second)
6504       .pooling_width(pooling_size.first)
6505       .channels(channels)
6506       .qmin(128)
6507       .TestF32();
6508   }
6509 }
6510 
TEST(AVERAGE_POOLING_NHWC_F32,batched_small_image_with_qmax)6511 TEST(AVERAGE_POOLING_NHWC_F32, batched_small_image_with_qmax) {
6512   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6513   const std::pair<size_t, size_t> pooling_size = SmallPoolSize(xnn_params.f32.gavgpool.row_tile);
6514   for (size_t channels = 1; channels <= 100; channels += 15) {
6515     AveragePoolingOperatorTester()
6516       .batch_size(2)
6517       .input_height(pooling_size.first)
6518       .input_width(pooling_size.second)
6519       .pooling_height(pooling_size.first)
6520       .pooling_width(pooling_size.second)
6521       .channels(channels)
6522       .qmax(128)
6523       .TestF32();
6524     AveragePoolingOperatorTester()
6525       .batch_size(2)
6526       .input_height(pooling_size.second)
6527       .input_width(pooling_size.first)
6528       .pooling_height(pooling_size.second)
6529       .pooling_width(pooling_size.first)
6530       .channels(channels)
6531       .qmax(128)
6532       .TestF32();
6533   }
6534 }
6535 
6536 /**************************** GAVGPOOL path, multipass ****************************/
6537 
TEST(AVERAGE_POOLING_NHWC_F32,large_image)6538 TEST(AVERAGE_POOLING_NHWC_F32, large_image) {
6539   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6540   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6541   for (size_t channels = 1; channels <= 100; channels += 15) {
6542     AveragePoolingOperatorTester()
6543       .input_height(pooling_size.first)
6544       .input_width(pooling_size.second)
6545       .pooling_height(pooling_size.first)
6546       .pooling_width(pooling_size.second)
6547       .channels(channels)
6548       .TestF32();
6549     AveragePoolingOperatorTester()
6550       .input_height(pooling_size.second)
6551       .input_width(pooling_size.first)
6552       .pooling_height(pooling_size.second)
6553       .pooling_width(pooling_size.first)
6554       .channels(channels)
6555       .TestF32();
6556   }
6557 }
6558 
TEST(AVERAGE_POOLING_NHWC_F32,large_image_with_width_padding)6559 TEST(AVERAGE_POOLING_NHWC_F32, large_image_with_width_padding) {
6560   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6561   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6562   for (size_t channels = 1; channels <= 100; channels += 15) {
6563     for (size_t padding_left = 1; padding_left <= 2; padding_left++) {
6564       AveragePoolingOperatorTester()
6565         .input_height(pooling_size.first)
6566         .input_width(pooling_size.second - padding_left)
6567         .padding_left(padding_left)
6568         .pooling_height(pooling_size.first)
6569         .pooling_width(pooling_size.second)
6570         .channels(channels)
6571         .TestF32();
6572       AveragePoolingOperatorTester()
6573         .input_height(pooling_size.second)
6574         .input_width(pooling_size.first - padding_left)
6575         .padding_left(padding_left)
6576         .pooling_height(pooling_size.second)
6577         .pooling_width(pooling_size.first)
6578         .channels(channels)
6579         .TestF32();
6580     }
6581     for (size_t padding_right = 1; padding_right <= 2; padding_right++) {
6582       AveragePoolingOperatorTester()
6583         .input_height(pooling_size.first)
6584         .input_width(pooling_size.second - padding_right)
6585         .padding_right(padding_right)
6586         .pooling_height(pooling_size.first)
6587         .pooling_width(pooling_size.second)
6588         .channels(channels)
6589         .TestF32();
6590       AveragePoolingOperatorTester()
6591         .input_height(pooling_size.second)
6592         .input_width(pooling_size.first - padding_right)
6593         .padding_right(padding_right)
6594         .pooling_height(pooling_size.second)
6595         .pooling_width(pooling_size.first)
6596         .channels(channels)
6597         .TestF32();
6598     }
6599   }
6600 }
6601 
TEST(AVERAGE_POOLING_NHWC_F32,large_image_with_height_padding)6602 TEST(AVERAGE_POOLING_NHWC_F32, large_image_with_height_padding) {
6603   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6604   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6605   for (size_t channels = 1; channels <= 100; channels += 15) {
6606     for (size_t padding_top = 1; padding_top <= 2; padding_top++) {
6607       AveragePoolingOperatorTester()
6608         .input_height(pooling_size.first - padding_top)
6609         .input_width(pooling_size.second)
6610         .padding_top(padding_top)
6611         .pooling_height(pooling_size.first)
6612         .pooling_width(pooling_size.second)
6613         .channels(channels)
6614         .TestF32();
6615       AveragePoolingOperatorTester()
6616         .input_height(pooling_size.second - padding_top)
6617         .input_width(pooling_size.first)
6618         .padding_top(padding_top)
6619         .pooling_height(pooling_size.second)
6620         .pooling_width(pooling_size.first)
6621         .channels(channels)
6622         .TestF32();
6623     }
6624     for (size_t padding_bottom = 1; padding_bottom <= 2; padding_bottom++) {
6625       AveragePoolingOperatorTester()
6626         .input_height(pooling_size.first - padding_bottom)
6627         .input_width(pooling_size.second)
6628         .padding_bottom(padding_bottom)
6629         .pooling_height(pooling_size.first)
6630         .pooling_width(pooling_size.second)
6631         .channels(channels)
6632         .TestF32();
6633       AveragePoolingOperatorTester()
6634         .input_height(pooling_size.second - padding_bottom)
6635         .input_width(pooling_size.first)
6636         .padding_bottom(padding_bottom)
6637         .pooling_height(pooling_size.second)
6638         .pooling_width(pooling_size.first)
6639         .channels(channels)
6640         .TestF32();
6641     }
6642   }
6643 }
6644 
TEST(AVERAGE_POOLING_NHWC_F32,large_image_with_input_stride)6645 TEST(AVERAGE_POOLING_NHWC_F32, large_image_with_input_stride) {
6646   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6647   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6648   for (size_t channels = 1; channels <= 100; channels += 15) {
6649     AveragePoolingOperatorTester()
6650       .input_height(pooling_size.first)
6651       .input_width(pooling_size.second)
6652       .pooling_height(pooling_size.first)
6653       .pooling_width(pooling_size.second)
6654       .channels(channels)
6655       .input_pixel_stride(2 * channels + 3)
6656       .TestF32();
6657     AveragePoolingOperatorTester()
6658       .input_height(pooling_size.second)
6659       .input_width(pooling_size.first)
6660       .pooling_height(pooling_size.second)
6661       .pooling_width(pooling_size.first)
6662       .channels(channels)
6663       .input_pixel_stride(2 * channels + 3)
6664       .TestF32();
6665   }
6666 }
6667 
TEST(AVERAGE_POOLING_NHWC_F32,large_image_with_output_stride)6668 TEST(AVERAGE_POOLING_NHWC_F32, large_image_with_output_stride) {
6669   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6670   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6671   for (size_t channels = 1; channels <= 100; channels += 15) {
6672     AveragePoolingOperatorTester()
6673       .input_height(pooling_size.first)
6674       .input_width(pooling_size.second)
6675       .pooling_height(pooling_size.first)
6676       .pooling_width(pooling_size.second)
6677       .channels(channels)
6678       .output_pixel_stride(2 * channels + 3)
6679       .TestF32();
6680     AveragePoolingOperatorTester()
6681       .input_height(pooling_size.second)
6682       .input_width(pooling_size.first)
6683       .pooling_height(pooling_size.second)
6684       .pooling_width(pooling_size.first)
6685       .channels(channels)
6686       .output_pixel_stride(2 * channels + 3)
6687       .TestF32();
6688   }
6689 }
6690 
TEST(AVERAGE_POOLING_NHWC_F32,large_image_with_qmin)6691 TEST(AVERAGE_POOLING_NHWC_F32, large_image_with_qmin) {
6692   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6693   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6694   for (size_t channels = 1; channels <= 100; channels += 15) {
6695     AveragePoolingOperatorTester()
6696       .input_height(pooling_size.first)
6697       .input_width(pooling_size.second)
6698       .pooling_height(pooling_size.first)
6699       .pooling_width(pooling_size.second)
6700       .channels(channels)
6701       .qmin(128)
6702       .TestF32();
6703     AveragePoolingOperatorTester()
6704       .input_height(pooling_size.second)
6705       .input_width(pooling_size.first)
6706       .pooling_height(pooling_size.second)
6707       .pooling_width(pooling_size.first)
6708       .channels(channels)
6709       .qmin(128)
6710       .TestF32();
6711   }
6712 }
6713 
TEST(AVERAGE_POOLING_NHWC_F32,large_image_with_qmax)6714 TEST(AVERAGE_POOLING_NHWC_F32, large_image_with_qmax) {
6715   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6716   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6717   for (size_t channels = 1; channels <= 100; channels += 15) {
6718     AveragePoolingOperatorTester()
6719       .input_height(pooling_size.first)
6720       .input_width(pooling_size.second)
6721       .pooling_height(pooling_size.first)
6722       .pooling_width(pooling_size.second)
6723       .channels(channels)
6724       .qmax(128)
6725       .TestF32();
6726     AveragePoolingOperatorTester()
6727       .input_height(pooling_size.second)
6728       .input_width(pooling_size.first)
6729       .pooling_height(pooling_size.second)
6730       .pooling_width(pooling_size.first)
6731       .channels(channels)
6732       .qmax(128)
6733       .TestF32();
6734   }
6735 }
6736 
6737 /**************************** GAVGPOOL path, multipass, batched ****************************/
6738 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_image)6739 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_image) {
6740   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6741   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6742   for (size_t channels = 1; channels <= 100; channels += 15) {
6743     AveragePoolingOperatorTester()
6744       .batch_size(2)
6745       .input_height(pooling_size.first)
6746       .input_width(pooling_size.second)
6747       .pooling_height(pooling_size.first)
6748       .pooling_width(pooling_size.second)
6749       .channels(channels)
6750       .TestF32();
6751     AveragePoolingOperatorTester()
6752       .batch_size(2)
6753       .input_height(pooling_size.second)
6754       .input_width(pooling_size.first)
6755       .pooling_height(pooling_size.second)
6756       .pooling_width(pooling_size.first)
6757       .channels(channels)
6758       .TestF32();
6759   }
6760 }
6761 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_image_with_width_padding)6762 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_image_with_width_padding) {
6763   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6764   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6765   for (size_t channels = 1; channels <= 100; channels += 15) {
6766     for (size_t padding_left = 1; padding_left <= 2; padding_left++) {
6767       AveragePoolingOperatorTester()
6768         .batch_size(2)
6769         .input_height(pooling_size.first)
6770         .input_width(pooling_size.second - padding_left)
6771         .padding_left(padding_left)
6772         .pooling_height(pooling_size.first)
6773         .pooling_width(pooling_size.second)
6774         .channels(channels)
6775         .TestF32();
6776       AveragePoolingOperatorTester()
6777         .batch_size(2)
6778         .input_height(pooling_size.second)
6779         .input_width(pooling_size.first - padding_left)
6780         .padding_left(padding_left)
6781         .pooling_height(pooling_size.second)
6782         .pooling_width(pooling_size.first)
6783         .channels(channels)
6784         .TestF32();
6785     }
6786     for (size_t padding_right = 1; padding_right <= 2; padding_right++) {
6787       AveragePoolingOperatorTester()
6788         .batch_size(2)
6789         .input_height(pooling_size.first)
6790         .input_width(pooling_size.second - padding_right)
6791         .padding_right(padding_right)
6792         .pooling_height(pooling_size.first)
6793         .pooling_width(pooling_size.second)
6794         .channels(channels)
6795         .TestF32();
6796       AveragePoolingOperatorTester()
6797         .batch_size(2)
6798         .input_height(pooling_size.second)
6799         .input_width(pooling_size.first - padding_right)
6800         .padding_right(padding_right)
6801         .pooling_height(pooling_size.second)
6802         .pooling_width(pooling_size.first)
6803         .channels(channels)
6804         .TestF32();
6805     }
6806   }
6807 }
6808 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_image_with_height_padding)6809 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_image_with_height_padding) {
6810   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6811   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6812   for (size_t channels = 1; channels <= 100; channels += 15) {
6813     for (size_t padding_top = 0; padding_top <= 1; padding_top++) {
6814       AveragePoolingOperatorTester()
6815         .batch_size(2)
6816         .input_height(pooling_size.first - padding_top)
6817         .input_width(pooling_size.second)
6818         .padding_top(padding_top)
6819         .pooling_height(pooling_size.first)
6820         .pooling_width(pooling_size.second)
6821         .channels(channels)
6822         .TestF32();
6823       AveragePoolingOperatorTester()
6824         .batch_size(2)
6825         .input_height(pooling_size.second - padding_top)
6826         .input_width(pooling_size.first)
6827         .padding_top(padding_top)
6828         .pooling_height(pooling_size.second)
6829         .pooling_width(pooling_size.first)
6830         .channels(channels)
6831         .TestF32();
6832     }
6833     for (size_t padding_bottom = 1; padding_bottom <= 2; padding_bottom++) {
6834       AveragePoolingOperatorTester()
6835         .batch_size(2)
6836         .input_height(pooling_size.first - padding_bottom)
6837         .input_width(pooling_size.second)
6838         .padding_bottom(padding_bottom)
6839         .pooling_height(pooling_size.first)
6840         .pooling_width(pooling_size.second)
6841         .channels(channels)
6842         .TestF32();
6843       AveragePoolingOperatorTester()
6844         .batch_size(2)
6845         .input_height(pooling_size.second - padding_bottom)
6846         .input_width(pooling_size.first)
6847         .padding_bottom(padding_bottom)
6848         .pooling_height(pooling_size.second)
6849         .pooling_width(pooling_size.first)
6850         .channels(channels)
6851         .TestF32();
6852     }
6853   }
6854 }
6855 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_image_with_input_stride)6856 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_image_with_input_stride) {
6857   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6858   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6859   for (size_t channels = 1; channels <= 100; channels += 15) {
6860     AveragePoolingOperatorTester()
6861       .batch_size(2)
6862       .input_height(pooling_size.first)
6863       .input_width(pooling_size.second)
6864       .pooling_height(pooling_size.first)
6865       .pooling_width(pooling_size.second)
6866       .channels(channels)
6867       .input_pixel_stride(2 * channels + 3)
6868       .TestF32();
6869     AveragePoolingOperatorTester()
6870       .batch_size(2)
6871       .input_height(pooling_size.second)
6872       .input_width(pooling_size.first)
6873       .pooling_height(pooling_size.second)
6874       .pooling_width(pooling_size.first)
6875       .channels(channels)
6876       .input_pixel_stride(2 * channels + 3)
6877       .TestF32();
6878   }
6879 }
6880 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_image_with_output_stride)6881 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_image_with_output_stride) {
6882   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6883   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6884   for (size_t channels = 1; channels <= 100; channels += 15) {
6885     AveragePoolingOperatorTester()
6886       .batch_size(2)
6887       .input_height(pooling_size.first)
6888       .input_width(pooling_size.second)
6889       .pooling_height(pooling_size.first)
6890       .pooling_width(pooling_size.second)
6891       .channels(channels)
6892       .output_pixel_stride(2 * channels + 3)
6893       .TestF32();
6894     AveragePoolingOperatorTester()
6895       .batch_size(2)
6896       .input_height(pooling_size.second)
6897       .input_width(pooling_size.first)
6898       .pooling_height(pooling_size.second)
6899       .pooling_width(pooling_size.first)
6900       .channels(channels)
6901       .output_pixel_stride(2 * channels + 3)
6902       .TestF32();
6903   }
6904 }
6905 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_image_with_qmin)6906 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_image_with_qmin) {
6907   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6908   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6909   for (size_t channels = 1; channels <= 100; channels += 15) {
6910     AveragePoolingOperatorTester()
6911       .batch_size(2)
6912       .input_height(pooling_size.first)
6913       .input_width(pooling_size.second)
6914       .pooling_height(pooling_size.first)
6915       .pooling_width(pooling_size.second)
6916       .channels(channels)
6917       .qmin(128)
6918       .TestF32();
6919     AveragePoolingOperatorTester()
6920       .batch_size(2)
6921       .input_height(pooling_size.second)
6922       .input_width(pooling_size.first)
6923       .pooling_height(pooling_size.second)
6924       .pooling_width(pooling_size.first)
6925       .channels(channels)
6926       .qmin(128)
6927       .TestF32();
6928   }
6929 }
6930 
TEST(AVERAGE_POOLING_NHWC_F32,batched_large_image_with_qmax)6931 TEST(AVERAGE_POOLING_NHWC_F32, batched_large_image_with_qmax) {
6932   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6933   const std::pair<size_t, size_t> pooling_size = LargePoolSize(xnn_params.f32.gavgpool.row_tile * 2);
6934   for (size_t channels = 1; channels <= 100; channels += 15) {
6935     AveragePoolingOperatorTester()
6936       .batch_size(2)
6937       .input_height(pooling_size.first)
6938       .input_width(pooling_size.second)
6939       .pooling_height(pooling_size.first)
6940       .pooling_width(pooling_size.second)
6941       .channels(channels)
6942       .qmax(128)
6943       .TestF32();
6944     AveragePoolingOperatorTester()
6945       .batch_size(2)
6946       .input_height(pooling_size.second)
6947       .input_width(pooling_size.first)
6948       .pooling_height(pooling_size.second)
6949       .pooling_width(pooling_size.first)
6950       .channels(channels)
6951       .qmax(128)
6952       .TestF32();
6953   }
6954 }
6955 
6956 /**************************** AVGPOOL path, setup ****************************/
6957 
TEST(AVERAGE_POOLING_NHWC_F32,setup_increasing_batch)6958 TEST(AVERAGE_POOLING_NHWC_F32, setup_increasing_batch) {
6959   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6960   AveragePoolingOperatorTester()
6961     .batch_size(2)
6962     .next_batch_size(5)
6963     .input_height(8)
6964     .input_width(8)
6965     .pooling_height(5)
6966     .pooling_width(3)
6967     .channels(24)
6968     .TestSetupF32();
6969 }
6970 
TEST(AVERAGE_POOLING_NHWC_F32,setup_decreasing_batch)6971 TEST(AVERAGE_POOLING_NHWC_F32, setup_decreasing_batch) {
6972   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6973   AveragePoolingOperatorTester()
6974     .batch_size(5)
6975     .next_batch_size(2)
6976     .input_height(8)
6977     .input_width(8)
6978     .pooling_height(5)
6979     .pooling_width(3)
6980     .channels(24)
6981     .TestSetupF32();
6982 }
6983 
TEST(AVERAGE_POOLING_NHWC_F32,setup_changing_height)6984 TEST(AVERAGE_POOLING_NHWC_F32, setup_changing_height) {
6985   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
6986   AveragePoolingOperatorTester()
6987     .batch_size(2)
6988     .input_height(8)
6989     .input_width(8)
6990     .next_input_height(9)
6991     .pooling_height(5)
6992     .pooling_width(3)
6993     .channels(24)
6994     .TestSetupF32();
6995   AveragePoolingOperatorTester()
6996     .batch_size(2)
6997     .input_height(8)
6998     .input_width(8)
6999     .next_input_height(7)
7000     .pooling_height(5)
7001     .pooling_width(3)
7002     .channels(24)
7003     .TestSetupF32();
7004 }
7005 
TEST(AVERAGE_POOLING_NHWC_F32,setup_changing_width)7006 TEST(AVERAGE_POOLING_NHWC_F32, setup_changing_width) {
7007   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
7008   AveragePoolingOperatorTester()
7009     .batch_size(2)
7010     .input_height(8)
7011     .input_width(8)
7012     .next_input_width(9)
7013     .pooling_height(5)
7014     .pooling_width(3)
7015     .channels(24)
7016     .TestSetupF32();
7017   AveragePoolingOperatorTester()
7018     .batch_size(2)
7019     .input_height(8)
7020     .input_width(8)
7021     .next_input_width(7)
7022     .pooling_height(5)
7023     .pooling_width(3)
7024     .channels(24)
7025     .TestSetupF32();
7026 }
7027 
TEST(AVERAGE_POOLING_NHWC_F32,setup_swap_height_and_width)7028 TEST(AVERAGE_POOLING_NHWC_F32, setup_swap_height_and_width) {
7029   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
7030   AveragePoolingOperatorTester()
7031     .batch_size(2)
7032     .input_height(9)
7033     .input_width(8)
7034     .next_input_height(8)
7035     .next_input_width(9)
7036     .pooling_height(5)
7037     .pooling_width(3)
7038     .channels(24)
7039     .TestSetupF32();
7040 }
7041 
TEST(AVERAGE_POOLING_NHWC_F32,setup_local_to_global)7042 TEST(AVERAGE_POOLING_NHWC_F32, setup_local_to_global) {
7043   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
7044   AveragePoolingOperatorTester()
7045     .batch_size(2)
7046     .input_height(6)
7047     .input_width(5)
7048     .next_input_height(5)
7049     .next_input_width(3)
7050     .pooling_height(5)
7051     .pooling_width(3)
7052     .channels(24)
7053     .TestSetupF32();
7054 }
7055 
TEST(AVERAGE_POOLING_NHWC_F32,setup_global_to_local)7056 TEST(AVERAGE_POOLING_NHWC_F32, setup_global_to_local) {
7057   ASSERT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
7058   AveragePoolingOperatorTester()
7059     .batch_size(2)
7060     .input_height(5)
7061     .input_width(3)
7062     .next_input_height(6)
7063     .next_input_width(5)
7064     .pooling_height(5)
7065     .pooling_width(3)
7066     .channels(24)
7067     .TestSetupF32();
7068 }
7069