xref: /aosp_15_r20/external/XNNPACK/tools/generate-maxpool-test.py (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
1#!/usr/bin/env python
2# Copyright 2019 Google LLC
3#
4# This source code is licensed under the BSD-style license found in the
5# LICENSE file in the root directory of this source tree.
6
7import argparse
8import codecs
9import math
10import os
11import re
12import sys
13import yaml
14
15sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
16from primes import next_prime
17import xngen
18import xnncommon
19
20
21parser = argparse.ArgumentParser(description='MaxPool microkernel test generator')
22parser.add_argument("-s", "--spec", metavar="FILE", required=True,
23                    help="Specification (YAML) file")
24parser.add_argument("-o", "--output", metavar="FILE", required=True,
25                    help='Output (C++ source) file')
26parser.set_defaults(defines=list())
27
28
29def split_ukernel_name(name):
30  match = re.fullmatch(r"xnn_(s8|u8|s16|f16|f32)_maxpool(_(minmax))?_ukernel_(\d+)p(\d+)x__(.+)_c(\d+)", name)
31  if match is None:
32    raise ValueError("Unexpected microkernel name: " + name)
33
34  primary_tile = int(match.group(4))
35  incremental_tile = int(match.group(5))
36  channel_tile = int(match.group(7))
37
38  arch, isa = xnncommon.parse_target_name(target_name=match.group(6))
39  return primary_tile, incremental_tile, channel_tile, arch, isa
40
41
42MAXPOOL_TEST_TEMPLATE = """\
43TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_unipass_fulltile) {
44  $if ISA_CHECK:
45    ${ISA_CHECK};
46  MaxPoolMicrokernelTester()
47    .pooling_elements(${PRIMARY_TILE})
48    .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
49    .channels(${CHANNEL_TILE})
50    $if DATATYPE in ["s8", "u8"]:
51      .qmin(std::numeric_limits<${CTYPE}>::min())
52      .qmax(std::numeric_limits<${CTYPE}>::max())
53    .Test(${", ".join(TEST_ARGS)});
54}
55
56TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_unipass_fulltile_with_input_offset) {
57  $if ISA_CHECK:
58    ${ISA_CHECK};
59  MaxPoolMicrokernelTester()
60    .pooling_elements(${PRIMARY_TILE})
61    .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
62    .channels(${CHANNEL_TILE})
63    .input_offset(${next_prime(CHANNEL_TILE+1)})
64    $if DATATYPE in ["s8", "u8"]:
65      .qmin(std::numeric_limits<${CTYPE}>::min())
66      .qmax(std::numeric_limits<${CTYPE}>::max())
67    .Test(${", ".join(TEST_ARGS)});
68}
69
70TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_unipass_fulltile_with_qmin) {
71  $if ISA_CHECK:
72    ${ISA_CHECK};
73  MaxPoolMicrokernelTester()
74    .pooling_elements(${PRIMARY_TILE})
75    .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
76    .channels(${CHANNEL_TILE})
77    .qmin(${QMIN})
78    $if DATATYPE in ["s8", "u8"]:
79      .qmax(std::numeric_limits<${CTYPE}>::max())
80    .Test(${", ".join(TEST_ARGS)});
81}
82
83TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_unipass_fulltile_with_qmax) {
84  $if ISA_CHECK:
85    ${ISA_CHECK};
86  MaxPoolMicrokernelTester()
87    .pooling_elements(${PRIMARY_TILE})
88    .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
89    .channels(${CHANNEL_TILE})
90    $if DATATYPE in ["s8", "u8"]:
91      .qmin(std::numeric_limits<${CTYPE}>::min())
92    .qmax(${QMAX})
93    .Test(${", ".join(TEST_ARGS)});
94}
95
96TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_unipass_subtile) {
97  $if ISA_CHECK:
98    ${ISA_CHECK};
99  for (size_t pooling_elements = 2; pooling_elements < ${PRIMARY_TILE}; pooling_elements++) {
100    MaxPoolMicrokernelTester()
101      .pooling_elements(pooling_elements)
102      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
103      .channels(${CHANNEL_TILE})
104      $if DATATYPE in ["s8", "u8"]:
105        .qmin(std::numeric_limits<${CTYPE}>::min())
106        .qmax(std::numeric_limits<${CTYPE}>::max())
107      .Test(${", ".join(TEST_ARGS)});
108  }
109}
110
111TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_unipass_subtile_with_input_offset) {
112  $if ISA_CHECK:
113    ${ISA_CHECK};
114  for (size_t pooling_elements = 2; pooling_elements < ${PRIMARY_TILE}; pooling_elements++) {
115    MaxPoolMicrokernelTester()
116      .pooling_elements(pooling_elements)
117      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
118      .channels(${CHANNEL_TILE})
119      .input_offset(${next_prime(CHANNEL_TILE+1)})
120      $if DATATYPE in ["s8", "u8"]:
121        .qmin(std::numeric_limits<${CTYPE}>::min())
122        .qmax(std::numeric_limits<${CTYPE}>::max())
123      .Test(${", ".join(TEST_ARGS)});
124  }
125}
126
127$if CHANNEL_TILE > 1:
128  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_unipass_fulltile) {
129    $if ISA_CHECK:
130      ${ISA_CHECK};
131    for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
132      MaxPoolMicrokernelTester()
133        .pooling_elements(${PRIMARY_TILE})
134        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
135        .channels(channels)
136        $if DATATYPE in ["s8", "u8"]:
137          .qmin(std::numeric_limits<${CTYPE}>::min())
138          .qmax(std::numeric_limits<${CTYPE}>::max())
139        .Test(${", ".join(TEST_ARGS)});
140    }
141  }
142
143  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_unipass_fulltile_with_input_offset) {
144    $if ISA_CHECK:
145      ${ISA_CHECK};
146    for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
147      MaxPoolMicrokernelTester()
148        .pooling_elements(${PRIMARY_TILE})
149        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
150        .channels(channels)
151        .input_offset(${next_prime(CHANNEL_TILE*8)})
152        $if DATATYPE in ["s8", "u8"]:
153          .qmin(std::numeric_limits<${CTYPE}>::min())
154          .qmax(std::numeric_limits<${CTYPE}>::max())
155        .Test(${", ".join(TEST_ARGS)});
156    }
157  }
158
159  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_unipass_fulltile_with_qmin) {
160    $if ISA_CHECK:
161      ${ISA_CHECK};
162    for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
163      MaxPoolMicrokernelTester()
164        .pooling_elements(${PRIMARY_TILE})
165        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
166        .channels(channels)
167        .qmin(${QMIN})
168        $if DATATYPE in ["s8", "u8"]:
169          .qmax(std::numeric_limits<${CTYPE}>::max())
170        .Test(${", ".join(TEST_ARGS)});
171    }
172  }
173
174  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_unipass_fulltile_with_qmax) {
175    $if ISA_CHECK:
176      ${ISA_CHECK};
177    for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
178      MaxPoolMicrokernelTester()
179        .pooling_elements(${PRIMARY_TILE})
180        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
181        .channels(channels)
182        $if DATATYPE in ["s8", "u8"]:
183          .qmin(std::numeric_limits<${CTYPE}>::min())
184        .qmax(${QMAX})
185        .Test(${", ".join(TEST_ARGS)});
186    }
187  }
188
189  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_unipass_subtile) {
190    $if ISA_CHECK:
191      ${ISA_CHECK};
192    for (size_t pooling_elements = 2; pooling_elements < ${PRIMARY_TILE}; pooling_elements++) {
193      for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
194        MaxPoolMicrokernelTester()
195          .pooling_elements(pooling_elements)
196          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
197          .channels(channels)
198          $if DATATYPE in ["s8", "u8"]:
199            .qmin(std::numeric_limits<${CTYPE}>::min())
200            .qmax(std::numeric_limits<${CTYPE}>::max())
201          .Test(${", ".join(TEST_ARGS)});
202      }
203    }
204  }
205
206  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_unipass_subtile_with_input_offset) {
207    $if ISA_CHECK:
208      ${ISA_CHECK};
209    for (size_t pooling_elements = 2; pooling_elements < ${PRIMARY_TILE}; pooling_elements++) {
210      for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
211        MaxPoolMicrokernelTester()
212          .pooling_elements(pooling_elements)
213          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
214          .channels(channels)
215          .input_offset(${next_prime(CHANNEL_TILE*8)})
216          $if DATATYPE in ["s8", "u8"]:
217            .qmin(std::numeric_limits<${CTYPE}>::min())
218            .qmax(std::numeric_limits<${CTYPE}>::max())
219          .Test(${", ".join(TEST_ARGS)});
220      }
221    }
222  }
223
224  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_unipass_fulltile) {
225    $if ISA_CHECK:
226      ${ISA_CHECK};
227    for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
228      MaxPoolMicrokernelTester()
229        .pooling_elements(${PRIMARY_TILE})
230        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
231        .channels(channels)
232        $if DATATYPE in ["s8", "u8"]:
233          .qmin(std::numeric_limits<${CTYPE}>::min())
234          .qmax(std::numeric_limits<${CTYPE}>::max())
235        .Test(${", ".join(TEST_ARGS)});
236    }
237  }
238
239  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_unipass_fulltile_with_input_offset) {
240    $if ISA_CHECK:
241      ${ISA_CHECK};
242    for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
243      MaxPoolMicrokernelTester()
244        .pooling_elements(${PRIMARY_TILE})
245        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
246        .channels(channels)
247        .input_offset(${next_prime(CHANNEL_TILE)})
248        $if DATATYPE in ["s8", "u8"]:
249          .qmin(std::numeric_limits<${CTYPE}>::min())
250          .qmax(std::numeric_limits<${CTYPE}>::max())
251        .Test(${", ".join(TEST_ARGS)});
252    }
253  }
254
255  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_unipass_fulltile_with_qmin) {
256    $if ISA_CHECK:
257      ${ISA_CHECK};
258    for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
259      MaxPoolMicrokernelTester()
260        .pooling_elements(${PRIMARY_TILE})
261        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
262        .channels(channels)
263        .qmin(${QMIN})
264        $if DATATYPE in ["s8", "u8"]:
265          .qmax(std::numeric_limits<${CTYPE}>::max())
266        .Test(${", ".join(TEST_ARGS)});
267    }
268  }
269
270  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_unipass_fulltile_with_qmax) {
271    $if ISA_CHECK:
272      ${ISA_CHECK};
273    for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
274      MaxPoolMicrokernelTester()
275        .pooling_elements(${PRIMARY_TILE})
276        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
277        .channels(channels)
278        $if DATATYPE in ["s8", "u8"]:
279          .qmin(std::numeric_limits<${CTYPE}>::min())
280        .qmax(${QMAX})
281        .Test(${", ".join(TEST_ARGS)});
282    }
283  }
284
285  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_unipass_subtile) {
286    $if ISA_CHECK:
287      ${ISA_CHECK};
288    for (size_t pooling_elements = 2; pooling_elements < ${PRIMARY_TILE}; pooling_elements++) {
289      for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
290        MaxPoolMicrokernelTester()
291          .pooling_elements(pooling_elements)
292          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
293          .channels(channels)
294          $if DATATYPE in ["s8", "u8"]:
295            .qmin(std::numeric_limits<${CTYPE}>::min())
296            .qmax(std::numeric_limits<${CTYPE}>::max())
297          .Test(${", ".join(TEST_ARGS)});
298      }
299    }
300  }
301
302  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_unipass_subtile_with_input_offset) {
303    $if ISA_CHECK:
304      ${ISA_CHECK};
305    for (size_t pooling_elements = 2; pooling_elements < ${PRIMARY_TILE}; pooling_elements++) {
306      for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
307        MaxPoolMicrokernelTester()
308          .pooling_elements(pooling_elements)
309          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
310          .channels(channels)
311          .input_offset(${next_prime(CHANNEL_TILE)})
312          $if DATATYPE in ["s8", "u8"]:
313            .qmin(std::numeric_limits<${CTYPE}>::min())
314            .qmax(std::numeric_limits<${CTYPE}>::max())
315          .Test(${", ".join(TEST_ARGS)});
316      }
317    }
318  }
319
320TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_unipass_fulltile) {
321  $if ISA_CHECK:
322    ${ISA_CHECK};
323  for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
324    MaxPoolMicrokernelTester()
325      .pooling_elements(${PRIMARY_TILE})
326      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
327      .channels(channels)
328      $if DATATYPE in ["s8", "u8"]:
329        .qmin(std::numeric_limits<${CTYPE}>::min())
330        .qmax(std::numeric_limits<${CTYPE}>::max())
331      .Test(${", ".join(TEST_ARGS)});
332  }
333}
334
335TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_unipass_fulltile_with_input_offset) {
336  $if ISA_CHECK:
337    ${ISA_CHECK};
338  for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
339    MaxPoolMicrokernelTester()
340      .pooling_elements(${PRIMARY_TILE})
341      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
342      .channels(channels)
343      .input_offset(${next_prime(CHANNEL_TILE*2)})
344      $if DATATYPE in ["s8", "u8"]:
345        .qmin(std::numeric_limits<${CTYPE}>::min())
346        .qmax(std::numeric_limits<${CTYPE}>::max())
347      .Test(${", ".join(TEST_ARGS)});
348  }
349}
350
351TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_unipass_fulltile_with_qmin) {
352  $if ISA_CHECK:
353    ${ISA_CHECK};
354  for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
355    MaxPoolMicrokernelTester()
356      .pooling_elements(${PRIMARY_TILE})
357      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
358      .channels(channels)
359      .qmin(${QMIN})
360      $if DATATYPE in ["s8", "u8"]:
361        .qmax(std::numeric_limits<${CTYPE}>::max())
362      .Test(${", ".join(TEST_ARGS)});
363  }
364}
365
366TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_unipass_fulltile_with_qmax) {
367  $if ISA_CHECK:
368    ${ISA_CHECK};
369  for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
370    MaxPoolMicrokernelTester()
371      .pooling_elements(${PRIMARY_TILE})
372      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
373      .channels(channels)
374      $if DATATYPE in ["s8", "u8"]:
375        .qmin(std::numeric_limits<${CTYPE}>::min())
376      .qmax(${QMAX})
377      .Test(${", ".join(TEST_ARGS)});
378  }
379}
380
381TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_unipass_subtile) {
382  $if ISA_CHECK:
383    ${ISA_CHECK};
384  for (size_t pooling_elements = 2; pooling_elements < ${PRIMARY_TILE}; pooling_elements++) {
385    for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
386      MaxPoolMicrokernelTester()
387        .pooling_elements(pooling_elements)
388        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
389        .channels(channels)
390        $if DATATYPE in ["s8", "u8"]:
391          .qmin(std::numeric_limits<${CTYPE}>::min())
392          .qmax(std::numeric_limits<${CTYPE}>::max())
393        .Test(${", ".join(TEST_ARGS)});
394    }
395  }
396}
397
398TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_unipass_subtile_with_input_offset) {
399  $if ISA_CHECK:
400    ${ISA_CHECK};
401  for (size_t pooling_elements = 2; pooling_elements < ${PRIMARY_TILE}; pooling_elements++) {
402    for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
403      MaxPoolMicrokernelTester()
404        .pooling_elements(pooling_elements)
405        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
406        .channels(channels)
407        .input_offset(${next_prime(CHANNEL_TILE*2)})
408        $if DATATYPE in ["s8", "u8"]:
409          .qmin(std::numeric_limits<${CTYPE}>::min())
410          .qmax(std::numeric_limits<${CTYPE}>::max())
411        .Test(${", ".join(TEST_ARGS)});
412    }
413  }
414}
415
416TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_twopass_fulltile) {
417  $if ISA_CHECK:
418    ${ISA_CHECK};
419  MaxPoolMicrokernelTester()
420    .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
421    .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
422    .channels(${CHANNEL_TILE})
423    $if DATATYPE in ["s8", "u8"]:
424      .qmin(std::numeric_limits<${CTYPE}>::min())
425      .qmax(std::numeric_limits<${CTYPE}>::max())
426    .Test(${", ".join(TEST_ARGS)});
427}
428
429TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_twopass_fulltile_with_input_offset) {
430  $if ISA_CHECK:
431    ${ISA_CHECK};
432  MaxPoolMicrokernelTester()
433    .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
434    .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
435    .channels(${CHANNEL_TILE})
436    .input_offset(${next_prime(CHANNEL_TILE+1)})
437    $if DATATYPE in ["s8", "u8"]:
438      .qmin(std::numeric_limits<${CTYPE}>::min())
439      .qmax(std::numeric_limits<${CTYPE}>::max())
440    .Test(${", ".join(TEST_ARGS)});
441}
442
443TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_twopass_fulltile_with_qmin) {
444  $if ISA_CHECK:
445    ${ISA_CHECK};
446  MaxPoolMicrokernelTester()
447    .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
448    .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
449    .channels(${CHANNEL_TILE})
450    .qmin(${QMIN})
451    $if DATATYPE in ["s8", "u8"]:
452      .qmax(std::numeric_limits<${CTYPE}>::max())
453    .Test(${", ".join(TEST_ARGS)});
454}
455
456TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_twopass_fulltile_with_qmax) {
457  $if ISA_CHECK:
458    ${ISA_CHECK};
459  MaxPoolMicrokernelTester()
460    .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
461    .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
462    .channels(${CHANNEL_TILE})
463    $if DATATYPE in ["s8", "u8"]:
464      .qmin(std::numeric_limits<${CTYPE}>::min())
465    .qmax(${QMAX})
466    .Test(${", ".join(TEST_ARGS)});
467}
468
469TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_twopass_subtile) {
470  $if ISA_CHECK:
471    ${ISA_CHECK};
472  for (size_t pooling_elements = ${PRIMARY_TILE+1}; pooling_elements < ${PRIMARY_TILE+INCREMENTAL_TILE}; pooling_elements++) {
473    MaxPoolMicrokernelTester()
474      .pooling_elements(pooling_elements)
475      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
476      .channels(${CHANNEL_TILE})
477      $if DATATYPE in ["s8", "u8"]:
478        .qmin(std::numeric_limits<${CTYPE}>::min())
479        .qmax(std::numeric_limits<${CTYPE}>::max())
480      .Test(${", ".join(TEST_ARGS)});
481  }
482}
483
484TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_twopass_subtile_with_input_offset) {
485  $if ISA_CHECK:
486    ${ISA_CHECK};
487  for (size_t pooling_elements = ${PRIMARY_TILE+1}; pooling_elements < ${PRIMARY_TILE+INCREMENTAL_TILE}; pooling_elements++) {
488    MaxPoolMicrokernelTester()
489      .pooling_elements(pooling_elements)
490      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
491      .channels(${CHANNEL_TILE})
492      .input_offset(${next_prime(CHANNEL_TILE+1)})
493      $if DATATYPE in ["s8", "u8"]:
494        .qmin(std::numeric_limits<${CTYPE}>::min())
495        .qmax(std::numeric_limits<${CTYPE}>::max())
496      .Test(${", ".join(TEST_ARGS)});
497  }
498}
499
500$if CHANNEL_TILE > 1:
501  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_twopass_fulltile) {
502    $if ISA_CHECK:
503      ${ISA_CHECK};
504    for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
505      MaxPoolMicrokernelTester()
506        .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
507        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
508        .channels(channels)
509        $if DATATYPE in ["s8", "u8"]:
510          .qmin(std::numeric_limits<${CTYPE}>::min())
511          .qmax(std::numeric_limits<${CTYPE}>::max())
512        .Test(${", ".join(TEST_ARGS)});
513    }
514  }
515
516  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_twopass_fulltile_with_input_offset) {
517    $if ISA_CHECK:
518      ${ISA_CHECK};
519    for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
520      MaxPoolMicrokernelTester()
521        .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
522        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
523        .channels(channels)
524        .input_offset(${next_prime(CHANNEL_TILE*5)})
525        $if DATATYPE in ["s8", "u8"]:
526          .qmin(std::numeric_limits<${CTYPE}>::min())
527          .qmax(std::numeric_limits<${CTYPE}>::max())
528        .Test(${", ".join(TEST_ARGS)});
529    }
530  }
531
532  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_twopass_fulltile_with_qmin) {
533    $if ISA_CHECK:
534      ${ISA_CHECK};
535    for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
536      MaxPoolMicrokernelTester()
537        .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
538        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
539        .channels(channels)
540        .qmin(${QMIN})
541        $if DATATYPE in ["s8", "u8"]:
542          .qmax(std::numeric_limits<${CTYPE}>::max())
543        .Test(${", ".join(TEST_ARGS)});
544    }
545  }
546
547  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_twopass_fulltile_with_qmax) {
548    $if ISA_CHECK:
549      ${ISA_CHECK};
550    for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
551      MaxPoolMicrokernelTester()
552        .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
553        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
554        .channels(channels)
555        $if DATATYPE in ["s8", "u8"]:
556          .qmin(std::numeric_limits<${CTYPE}>::min())
557        .qmax(${QMAX})
558        .Test(${", ".join(TEST_ARGS)});
559    }
560  }
561
562  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_twopass_subtile) {
563    $if ISA_CHECK:
564      ${ISA_CHECK};
565    for (size_t pooling_elements = ${PRIMARY_TILE+1}; pooling_elements < ${PRIMARY_TILE+INCREMENTAL_TILE}; pooling_elements++) {
566      for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
567        MaxPoolMicrokernelTester()
568          .pooling_elements(pooling_elements)
569          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
570          .channels(channels)
571          $if DATATYPE in ["s8", "u8"]:
572            .qmin(std::numeric_limits<${CTYPE}>::min())
573            .qmax(std::numeric_limits<${CTYPE}>::max())
574          .Test(${", ".join(TEST_ARGS)});
575      }
576    }
577  }
578
579  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_twopass_subtile_with_input_offset) {
580    $if ISA_CHECK:
581      ${ISA_CHECK};
582    for (size_t pooling_elements = ${PRIMARY_TILE+1}; pooling_elements < ${PRIMARY_TILE+INCREMENTAL_TILE}; pooling_elements++) {
583      for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
584        MaxPoolMicrokernelTester()
585          .pooling_elements(pooling_elements)
586          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
587          .channels(channels)
588          .input_offset(${next_prime(CHANNEL_TILE*8)})
589          $if DATATYPE in ["s8", "u8"]:
590            .qmin(std::numeric_limits<${CTYPE}>::min())
591            .qmax(std::numeric_limits<${CTYPE}>::max())
592          .Test(${", ".join(TEST_ARGS)});
593      }
594    }
595  }
596
597  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_twopass_fulltile) {
598    $if ISA_CHECK:
599      ${ISA_CHECK};
600    for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
601      MaxPoolMicrokernelTester()
602        .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
603        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
604        .channels(channels)
605        $if DATATYPE in ["s8", "u8"]:
606          .qmin(std::numeric_limits<${CTYPE}>::min())
607          .qmax(std::numeric_limits<${CTYPE}>::max())
608        .Test(${", ".join(TEST_ARGS)});
609    }
610  }
611
612  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_twopass_fulltile_with_input_offset) {
613    $if ISA_CHECK:
614      ${ISA_CHECK};
615    for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
616      MaxPoolMicrokernelTester()
617        .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
618        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
619        .channels(channels)
620        .input_offset(${next_prime(CHANNEL_TILE)})
621        $if DATATYPE in ["s8", "u8"]:
622          .qmin(std::numeric_limits<${CTYPE}>::min())
623          .qmax(std::numeric_limits<${CTYPE}>::max())
624        .Test(${", ".join(TEST_ARGS)});
625    }
626  }
627
628  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_twopass_fulltile_with_qmin) {
629    $if ISA_CHECK:
630      ${ISA_CHECK};
631    for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
632      MaxPoolMicrokernelTester()
633        .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
634        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
635        .channels(channels)
636        .qmin(${QMIN})
637        $if DATATYPE in ["s8", "u8"]:
638          .qmax(std::numeric_limits<${CTYPE}>::max())
639        .Test(${", ".join(TEST_ARGS)});
640    }
641  }
642
643  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_twopass_fulltile_with_qmax) {
644    $if ISA_CHECK:
645      ${ISA_CHECK};
646    for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
647      MaxPoolMicrokernelTester()
648        .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
649        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
650        .channels(channels)
651        $if DATATYPE in ["s8", "u8"]:
652          .qmin(std::numeric_limits<${CTYPE}>::min())
653        .qmax(${QMAX})
654        .Test(${", ".join(TEST_ARGS)});
655    }
656  }
657
658  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_twopass_subtile) {
659    $if ISA_CHECK:
660      ${ISA_CHECK};
661    for (size_t pooling_elements = ${PRIMARY_TILE+1}; pooling_elements < ${PRIMARY_TILE+INCREMENTAL_TILE}; pooling_elements++) {
662      for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
663        MaxPoolMicrokernelTester()
664          .pooling_elements(pooling_elements)
665          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
666          .channels(channels)
667          $if DATATYPE in ["s8", "u8"]:
668            .qmin(std::numeric_limits<${CTYPE}>::min())
669            .qmax(std::numeric_limits<${CTYPE}>::max())
670          .Test(${", ".join(TEST_ARGS)});
671      }
672    }
673  }
674
675  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_twopass_subtile_with_input_offset) {
676    $if ISA_CHECK:
677      ${ISA_CHECK};
678    for (size_t pooling_elements = ${PRIMARY_TILE+1}; pooling_elements < ${PRIMARY_TILE+INCREMENTAL_TILE}; pooling_elements++) {
679      for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
680        MaxPoolMicrokernelTester()
681          .pooling_elements(pooling_elements)
682          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
683          .channels(channels)
684          .input_offset(${next_prime(CHANNEL_TILE)})
685          $if DATATYPE in ["s8", "u8"]:
686            .qmin(std::numeric_limits<${CTYPE}>::min())
687            .qmax(std::numeric_limits<${CTYPE}>::max())
688          .Test(${", ".join(TEST_ARGS)});
689      }
690    }
691  }
692
693TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_twopass_fulltile) {
694  $if ISA_CHECK:
695    ${ISA_CHECK};
696  for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
697    MaxPoolMicrokernelTester()
698      .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
699      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
700      .channels(channels)
701      $if DATATYPE in ["s8", "u8"]:
702        .qmin(std::numeric_limits<${CTYPE}>::min())
703        .qmax(std::numeric_limits<${CTYPE}>::max())
704      .Test(${", ".join(TEST_ARGS)});
705  }
706}
707
708TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_twopass_fulltile_with_input_offset) {
709  $if ISA_CHECK:
710    ${ISA_CHECK};
711  for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
712    MaxPoolMicrokernelTester()
713      .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
714      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
715      .channels(channels)
716      .input_offset(${next_prime(CHANNEL_TILE*2)})
717      $if DATATYPE in ["s8", "u8"]:
718        .qmin(std::numeric_limits<${CTYPE}>::min())
719        .qmax(std::numeric_limits<${CTYPE}>::max())
720      .Test(${", ".join(TEST_ARGS)});
721  }
722}
723
724TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_twopass_fulltile_with_qmin) {
725  $if ISA_CHECK:
726    ${ISA_CHECK};
727  for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
728    MaxPoolMicrokernelTester()
729      .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
730      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
731      .channels(channels)
732      .qmin(${QMIN})
733      $if DATATYPE in ["s8", "u8"]:
734        .qmax(std::numeric_limits<${CTYPE}>::max())
735      .Test(${", ".join(TEST_ARGS)});
736  }
737}
738
739TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_twopass_fulltile_with_qmax) {
740  $if ISA_CHECK:
741    ${ISA_CHECK};
742  for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
743    MaxPoolMicrokernelTester()
744      .pooling_elements(${PRIMARY_TILE+INCREMENTAL_TILE})
745      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
746      .channels(channels)
747      $if DATATYPE in ["s8", "u8"]:
748        .qmin(std::numeric_limits<${CTYPE}>::min())
749      .qmax(${QMAX})
750      .Test(${", ".join(TEST_ARGS)});
751  }
752}
753
754TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_twopass_subtile) {
755  $if ISA_CHECK:
756    ${ISA_CHECK};
757  for (size_t pooling_elements = ${PRIMARY_TILE+1}; pooling_elements < ${PRIMARY_TILE+INCREMENTAL_TILE}; pooling_elements++) {
758    for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
759      MaxPoolMicrokernelTester()
760        .pooling_elements(pooling_elements)
761        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
762        .channels(channels)
763        $if DATATYPE in ["s8", "u8"]:
764          .qmin(std::numeric_limits<${CTYPE}>::min())
765          .qmax(std::numeric_limits<${CTYPE}>::max())
766        .Test(${", ".join(TEST_ARGS)});
767    }
768  }
769}
770
771TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_twopass_subtile_with_input_offset) {
772  $if ISA_CHECK:
773    ${ISA_CHECK};
774  for (size_t pooling_elements = ${PRIMARY_TILE+1}; pooling_elements < ${PRIMARY_TILE+INCREMENTAL_TILE}; pooling_elements++) {
775    for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
776      MaxPoolMicrokernelTester()
777        .pooling_elements(pooling_elements)
778        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
779        .channels(channels)
780        .input_offset(${next_prime(CHANNEL_TILE*2)})
781        $if DATATYPE in ["s8", "u8"]:
782          .qmin(std::numeric_limits<${CTYPE}>::min())
783          .qmax(std::numeric_limits<${CTYPE}>::max())
784        .Test(${", ".join(TEST_ARGS)});
785    }
786  }
787}
788
789TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_multipass) {
790  $if ISA_CHECK:
791    ${ISA_CHECK};
792  for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
793    MaxPoolMicrokernelTester()
794      .pooling_elements(pooling_elements)
795      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
796      .channels(${CHANNEL_TILE})
797      $if DATATYPE in ["s8", "u8"]:
798        .qmin(std::numeric_limits<${CTYPE}>::min())
799        .qmax(std::numeric_limits<${CTYPE}>::max())
800      .Test(${", ".join(TEST_ARGS)});
801  }
802}
803
804TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_multipass_with_input_offset) {
805  $if ISA_CHECK:
806    ${ISA_CHECK};
807  for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
808    MaxPoolMicrokernelTester()
809      .pooling_elements(pooling_elements)
810      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
811      .channels(${CHANNEL_TILE})
812      .input_offset(${next_prime(CHANNEL_TILE+1)})
813      $if DATATYPE in ["s8", "u8"]:
814        .qmin(std::numeric_limits<${CTYPE}>::min())
815        .qmax(std::numeric_limits<${CTYPE}>::max())
816      .Test(${", ".join(TEST_ARGS)});
817  }
818}
819
820TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_multipass_with_qmin) {
821  $if ISA_CHECK:
822    ${ISA_CHECK};
823  for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
824    MaxPoolMicrokernelTester()
825      .pooling_elements(pooling_elements)
826      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
827      .channels(${CHANNEL_TILE})
828      .qmin(${QMIN})
829      $if DATATYPE in ["s8", "u8"]:
830        .qmax(std::numeric_limits<${CTYPE}>::max())
831      .Test(${", ".join(TEST_ARGS)});
832  }
833}
834
835TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}_multipass_with_qmax) {
836  $if ISA_CHECK:
837    ${ISA_CHECK};
838  for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
839    MaxPoolMicrokernelTester()
840      .pooling_elements(pooling_elements)
841      .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
842      .channels(${CHANNEL_TILE})
843      $if DATATYPE in ["s8", "u8"]:
844        .qmin(std::numeric_limits<${CTYPE}>::min())
845      .qmax(${QMAX})
846      .Test(${", ".join(TEST_ARGS)});
847  }
848}
849
850$if CHANNEL_TILE > 1:
851  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_multipass) {
852    $if ISA_CHECK:
853      ${ISA_CHECK};
854    for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
855      for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
856        MaxPoolMicrokernelTester()
857          .pooling_elements(pooling_elements)
858          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
859          .channels(channels)
860          $if DATATYPE in ["s8", "u8"]:
861            .qmin(std::numeric_limits<${CTYPE}>::min())
862            .qmax(std::numeric_limits<${CTYPE}>::max())
863          .Test(${", ".join(TEST_ARGS)});
864      }
865    }
866  }
867
868  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_multipass_with_input_offset) {
869    $if ISA_CHECK:
870      ${ISA_CHECK};
871    for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
872      for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
873        MaxPoolMicrokernelTester()
874          .pooling_elements(pooling_elements)
875          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
876          .channels(channels)
877          .input_offset(${next_prime(CHANNEL_TILE*8)})
878          $if DATATYPE in ["s8", "u8"]:
879            .qmin(std::numeric_limits<${CTYPE}>::min())
880            .qmax(std::numeric_limits<${CTYPE}>::max())
881          .Test(${", ".join(TEST_ARGS)});
882      }
883    }
884  }
885
886  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_multipass_with_qmin) {
887    $if ISA_CHECK:
888      ${ISA_CHECK};
889    for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
890      for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
891        MaxPoolMicrokernelTester()
892          .pooling_elements(pooling_elements)
893          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
894          .channels(channels)
895          .qmin(${QMIN})
896          $if DATATYPE in ["s8", "u8"]:
897            .qmax(std::numeric_limits<${CTYPE}>::max())
898          .Test(${", ".join(TEST_ARGS)});
899      }
900    }
901  }
902
903  TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}_multipass_with_qmax) {
904    $if ISA_CHECK:
905      ${ISA_CHECK};
906    for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
907      for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*8}; channels += ${CHANNEL_TILE}) {
908        MaxPoolMicrokernelTester()
909          .pooling_elements(pooling_elements)
910          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
911          .channels(channels)
912          $if DATATYPE in ["s8", "u8"]:
913            .qmin(std::numeric_limits<${CTYPE}>::min())
914          .qmax(${QMAX})
915          .Test(${", ".join(TEST_ARGS)});
916      }
917    }
918  }
919
920  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_multipass) {
921    $if ISA_CHECK:
922      ${ISA_CHECK};
923    for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
924      for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
925        MaxPoolMicrokernelTester()
926          .pooling_elements(pooling_elements)
927          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
928          .channels(channels)
929          $if DATATYPE in ["s8", "u8"]:
930            .qmin(std::numeric_limits<${CTYPE}>::min())
931            .qmax(std::numeric_limits<${CTYPE}>::max())
932          .Test(${", ".join(TEST_ARGS)});
933      }
934    }
935  }
936
937  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_multipass_with_input_offset) {
938    $if ISA_CHECK:
939      ${ISA_CHECK};
940    for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
941      for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
942        MaxPoolMicrokernelTester()
943          .pooling_elements(pooling_elements)
944          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
945          .channels(channels)
946          .input_offset(${CHANNEL_TILE})
947          $if DATATYPE in ["s8", "u8"]:
948            .qmin(std::numeric_limits<${CTYPE}>::min())
949            .qmax(std::numeric_limits<${CTYPE}>::max())
950          .Test(${", ".join(TEST_ARGS)});
951      }
952    }
953  }
954
955  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_multipass_with_qmin) {
956    $if ISA_CHECK:
957      ${ISA_CHECK};
958    for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
959      for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
960        MaxPoolMicrokernelTester()
961          .pooling_elements(pooling_elements)
962          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
963          .channels(channels)
964          .qmin(${QMIN})
965          $if DATATYPE in ["s8", "u8"]:
966            .qmax(std::numeric_limits<${CTYPE}>::max())
967          .Test(${", ".join(TEST_ARGS)});
968      }
969    }
970  }
971
972  TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}_multipass_with_qmax) {
973    $if ISA_CHECK:
974      ${ISA_CHECK};
975    for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
976      for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
977        MaxPoolMicrokernelTester()
978          .pooling_elements(pooling_elements)
979          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
980          .channels(channels)
981          $if DATATYPE in ["s8", "u8"]:
982            .qmin(std::numeric_limits<${CTYPE}>::min())
983          .qmax(${QMAX})
984          .Test(${", ".join(TEST_ARGS)});
985      }
986    }
987  }
988
989TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_multipass) {
990  $if ISA_CHECK:
991    ${ISA_CHECK};
992  for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
993    for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
994      MaxPoolMicrokernelTester()
995        .pooling_elements(pooling_elements)
996        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
997        .channels(channels)
998        $if DATATYPE in ["s8", "u8"]:
999          .qmin(std::numeric_limits<${CTYPE}>::min())
1000          .qmax(std::numeric_limits<${CTYPE}>::max())
1001        .Test(${", ".join(TEST_ARGS)});
1002    }
1003  }
1004}
1005
1006TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_multipass_with_input_offset) {
1007  $if ISA_CHECK:
1008    ${ISA_CHECK};
1009  for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
1010    for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
1011      MaxPoolMicrokernelTester()
1012        .pooling_elements(pooling_elements)
1013        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
1014        .channels(channels)
1015        .input_offset(${next_prime(CHANNEL_TILE*2)})
1016        $if DATATYPE in ["s8", "u8"]:
1017          .qmin(std::numeric_limits<${CTYPE}>::min())
1018          .qmax(std::numeric_limits<${CTYPE}>::max())
1019        .Test(${", ".join(TEST_ARGS)});
1020    }
1021  }
1022}
1023
1024TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_multipass_with_qmin) {
1025  $if ISA_CHECK:
1026    ${ISA_CHECK};
1027  for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
1028    for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
1029      MaxPoolMicrokernelTester()
1030        .pooling_elements(pooling_elements)
1031        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
1032        .channels(channels)
1033        .qmin(${QMIN})
1034        $if DATATYPE in ["s8", "u8"]:
1035          .qmax(std::numeric_limits<${CTYPE}>::max())
1036        .Test(${", ".join(TEST_ARGS)});
1037    }
1038  }
1039}
1040
1041TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}_multipass_with_qmax) {
1042  $if ISA_CHECK:
1043    ${ISA_CHECK};
1044  for (size_t pooling_elements = ${PRIMARY_TILE+INCREMENTAL_TILE+1}; pooling_elements <= ${PRIMARY_TILE+INCREMENTAL_TILE*3}; pooling_elements += 3) {
1045    for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
1046      MaxPoolMicrokernelTester()
1047        .pooling_elements(pooling_elements)
1048        .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
1049        .channels(channels)
1050        $if DATATYPE in ["s8", "u8"]:
1051          .qmin(std::numeric_limits<${CTYPE}>::min())
1052        .qmax(${QMAX})
1053        .Test(${", ".join(TEST_ARGS)});
1054    }
1055  }
1056}
1057
1058TEST(${TEST_NAME}, few_output_pixels) {
1059  $if ISA_CHECK:
1060    ${ISA_CHECK};
1061  for (size_t output_pixels = 2; output_pixels <= 5; output_pixels++) {
1062    for (size_t pooling_elements : std::vector<size_t>{{2, ${PRIMARY_TILE}, ${PRIMARY_TILE+INCREMENTAL_TILE-1}}}) {
1063      for (size_t channels = 1; channels <= ${CHANNEL_TILE*5}; channels += ${max(1, CHANNEL_TILE-1)}) {
1064        MaxPoolMicrokernelTester()
1065          .output_pixels(output_pixels)
1066          .pooling_elements(pooling_elements)
1067          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
1068          .channels(channels)
1069          $if DATATYPE in ["s8", "u8"]:
1070            .qmin(std::numeric_limits<${CTYPE}>::min())
1071            .qmax(std::numeric_limits<${CTYPE}>::max())
1072          .Test(${", ".join(TEST_ARGS)});
1073      }
1074    }
1075  }
1076}
1077
1078TEST(${TEST_NAME}, few_output_pixels_with_input_offset) {
1079  $if ISA_CHECK:
1080    ${ISA_CHECK};
1081  for (size_t output_pixels = 2; output_pixels <= 5; output_pixels++) {
1082    for (size_t pooling_elements : std::vector<size_t>{{2, ${PRIMARY_TILE}, ${PRIMARY_TILE+INCREMENTAL_TILE-1}}}) {
1083      for (size_t channels = 1; channels <= ${CHANNEL_TILE*5}; channels += ${max(1, CHANNEL_TILE-1)}) {
1084        MaxPoolMicrokernelTester()
1085          .output_pixels(output_pixels)
1086          .pooling_elements(pooling_elements)
1087          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
1088          .channels(channels)
1089          .input_offset(${next_prime(CHANNEL_TILE*5+1)})
1090          $if DATATYPE in ["s8", "u8"]:
1091            .qmin(std::numeric_limits<${CTYPE}>::min())
1092            .qmax(std::numeric_limits<${CTYPE}>::max())
1093          .Test(${", ".join(TEST_ARGS)});
1094      }
1095    }
1096  }
1097}
1098
1099TEST(${TEST_NAME}, few_output_pixels_with_qmin) {
1100  $if ISA_CHECK:
1101    ${ISA_CHECK};
1102  for (size_t output_pixels = 2; output_pixels <= 5; output_pixels++) {
1103    for (size_t pooling_elements : std::vector<size_t>{{2, ${PRIMARY_TILE}, ${PRIMARY_TILE+INCREMENTAL_TILE-1}}}) {
1104      for (size_t channels = 1; channels <= ${CHANNEL_TILE*5}; channels += ${max(1, CHANNEL_TILE-1)}) {
1105        MaxPoolMicrokernelTester()
1106          .output_pixels(output_pixels)
1107          .pooling_elements(pooling_elements)
1108          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
1109          .channels(channels)
1110          .qmin(${QMIN})
1111          $if DATATYPE in ["s8", "u8"]:
1112            .qmax(std::numeric_limits<${CTYPE}>::max())
1113          .Test(${", ".join(TEST_ARGS)});
1114      }
1115    }
1116  }
1117}
1118
1119TEST(${TEST_NAME}, few_output_pixels_with_qmax) {
1120  $if ISA_CHECK:
1121    ${ISA_CHECK};
1122  for (size_t output_pixels = 2; output_pixels <= 5; output_pixels++) {
1123    for (size_t pooling_elements : std::vector<size_t>{{2, ${PRIMARY_TILE}, ${PRIMARY_TILE+INCREMENTAL_TILE-1}}}) {
1124      for (size_t channels = 1; channels <= ${CHANNEL_TILE*5}; channels += ${max(1, CHANNEL_TILE-1)}) {
1125        MaxPoolMicrokernelTester()
1126          .output_pixels(output_pixels)
1127          .pooling_elements(pooling_elements)
1128          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
1129          .channels(channels)
1130          $if DATATYPE in ["s8", "u8"]:
1131            .qmin(std::numeric_limits<${CTYPE}>::min())
1132          .qmax(${QMAX})
1133          .Test(${", ".join(TEST_ARGS)});
1134      }
1135    }
1136  }
1137}
1138
1139TEST(${TEST_NAME}, few_output_pixels_with_output_stride) {
1140  $if ISA_CHECK:
1141    ${ISA_CHECK};
1142  for (size_t output_pixels = 2; output_pixels <= 5; output_pixels++) {
1143    for (size_t pooling_elements : std::vector<size_t>{{2, ${PRIMARY_TILE}, ${PRIMARY_TILE+INCREMENTAL_TILE-1}}}) {
1144      for (size_t channels = 1; channels <= ${CHANNEL_TILE*5}; channels += ${max(1, CHANNEL_TILE-1)}) {
1145        MaxPoolMicrokernelTester()
1146          .output_pixels(output_pixels)
1147          .pooling_elements(pooling_elements)
1148          .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
1149          .channels(channels)
1150          .output_stride(${next_prime(CHANNEL_TILE*5+1)})
1151          $if DATATYPE in ["s8", "u8"]:
1152            .qmin(std::numeric_limits<${CTYPE}>::min())
1153            .qmax(std::numeric_limits<${CTYPE}>::max())
1154          .Test(${", ".join(TEST_ARGS)});
1155      }
1156    }
1157  }
1158}
1159
1160TEST(${TEST_NAME}, few_output_pixels_with_step) {
1161  $if ISA_CHECK:
1162    ${ISA_CHECK};
1163  for (size_t output_pixels = 2; output_pixels <= 5; output_pixels++) {
1164    for (size_t pooling_elements : std::vector<size_t>{{2, ${PRIMARY_TILE}, ${PRIMARY_TILE+INCREMENTAL_TILE-1}}}) {
1165      for (size_t channels = 1; channels <= ${CHANNEL_TILE*5}; channels += ${max(1, CHANNEL_TILE-1)}) {
1166        for (size_t step = 2; step <= pooling_elements; step++) {
1167          MaxPoolMicrokernelTester()
1168            .output_pixels(output_pixels)
1169            .pooling_elements(pooling_elements)
1170            .pooling_tile(${PRIMARY_TILE}, ${INCREMENTAL_TILE})
1171            .step(step)
1172            .channels(channels)
1173            .output_stride(${next_prime(CHANNEL_TILE*5+1)})
1174            $if DATATYPE in ["s8", "u8"]:
1175              .qmin(std::numeric_limits<${CTYPE}>::min())
1176              .qmax(std::numeric_limits<${CTYPE}>::max())
1177            .Test(${", ".join(TEST_ARGS)});
1178        }
1179      }
1180    }
1181  }
1182}
1183"""
1184
1185
1186def generate_test_cases(ukernel, init_fn, primary_tile, incremental_tile,
1187                        channel_tile, isa):
1188  """Generates all tests cases for a MAXPOOL micro-kernel.
1189
1190  Args:
1191    ukernel: C name of the micro-kernel function.
1192    init_fn: C name of the function to initialize microkernel parameters.
1193    primary_tile: Number of rows (pixels) processed per one iteration of the
1194                  primary outer loop of the micro-kernel.
1195    incremental_tile: Number of rows (pixels) processed per one iteration of
1196                      the incremental outer loop of the micro-kernel.
1197    channel_tile: Number of channels processed per one iteration of the inner
1198                  loops of the micro-kernel.
1199    isa: instruction set required to run the micro-kernel. Generated unit test
1200         will skip execution if the host processor doesn't support this ISA.
1201
1202  Returns:
1203    Code for the test case.
1204  """
1205  _, test_name = ukernel.split("_", 1)
1206  _, datatype, ukernel_type, _ = ukernel.split("_", 3)
1207  test_args = [ukernel, init_fn]
1208  return xngen.preprocess(MAXPOOL_TEST_TEMPLATE, {
1209      "TEST_NAME": test_name.upper().replace("UKERNEL_", ""),
1210      "TEST_ARGS": test_args,
1211      "DATATYPE": datatype,
1212      "CTYPE": {"s8": "int8_t", "u8": "uint8_t", "f16": "uint16_t", "f32": "int16_t"}[datatype],
1213      "QMIN": {"s8": -64, "u8": 64}.get(datatype, -16384),
1214      "QMAX": {"s8": 64, "u8": 192}.get(datatype, 16384),
1215      "PRIMARY_TILE": primary_tile,
1216      "INCREMENTAL_TILE": incremental_tile,
1217      "CHANNEL_TILE": channel_tile,
1218      "ISA_CHECK": xnncommon.generate_isa_check_macro(isa),
1219      "next_prime": next_prime,
1220    })
1221
1222
1223def main(args):
1224  options = parser.parse_args(args)
1225
1226  with codecs.open(options.spec, "r", encoding="utf-8") as spec_file:
1227    spec_yaml = yaml.safe_load(spec_file)
1228    if not isinstance(spec_yaml, list):
1229      raise ValueError("expected a list of micro-kernels in the spec")
1230
1231    tests = """\
1232// Copyright (c) Facebook, Inc. and its affiliates.
1233// All rights reserved.
1234//
1235// Copyright 2019 Google LLC
1236//
1237// This source code is licensed under the BSD-style license found in the
1238// LICENSE file in the root directory of this source tree.
1239//
1240// Auto-generated file. Do not edit!
1241//   Specification: {specification}
1242//   Generator: {generator}
1243
1244
1245#include <gtest/gtest.h>
1246
1247#include <xnnpack/common.h>
1248#include <xnnpack/isa-checks.h>
1249
1250#include <xnnpack/maxpool.h>
1251#include "maxpool-microkernel-tester.h"
1252""".format(specification=options.spec, generator=sys.argv[0])
1253
1254    for ukernel_spec in spec_yaml:
1255      name = ukernel_spec["name"]
1256      init_fn = ukernel_spec["init"]
1257      primary_tile, incremental_tile, channel_tile, arch, isa = \
1258        split_ukernel_name(name)
1259
1260      # specification can override architecture
1261      arch = ukernel_spec.get("arch", arch)
1262
1263      test_case = generate_test_cases(name, init_fn, primary_tile,
1264                                      incremental_tile, channel_tile, isa)
1265      tests += "\n\n" + xnncommon.postprocess_test_case(test_case, arch, isa)
1266
1267    txt_changed = True
1268    if os.path.exists(options.output):
1269      with codecs.open(options.output, "r", encoding="utf-8") as output_file:
1270        txt_changed = output_file.read() != tests
1271
1272    if txt_changed:
1273      with codecs.open(options.output, "w", encoding="utf-8") as output_file:
1274        output_file.write(tests)
1275
1276
1277if __name__ == "__main__":
1278  main(sys.argv[1:])
1279