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