1*4bdc9457SAndroid Build Coastguard Worker#!/usr/bin/env python 2*4bdc9457SAndroid Build Coastguard Worker# Copyright 2020 Google LLC 3*4bdc9457SAndroid Build Coastguard Worker# 4*4bdc9457SAndroid Build Coastguard Worker# This source code is licensed under the BSD-style license found in the 5*4bdc9457SAndroid Build Coastguard Worker# LICENSE file in the root directory of this source tree. 6*4bdc9457SAndroid Build Coastguard Worker 7*4bdc9457SAndroid Build Coastguard Workerimport argparse 8*4bdc9457SAndroid Build Coastguard Workerimport codecs 9*4bdc9457SAndroid Build Coastguard Workerimport os 10*4bdc9457SAndroid Build Coastguard Workerimport re 11*4bdc9457SAndroid Build Coastguard Workerimport sys 12*4bdc9457SAndroid Build Coastguard Workerimport yaml 13*4bdc9457SAndroid Build Coastguard Worker 14*4bdc9457SAndroid Build Coastguard Workersys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) 15*4bdc9457SAndroid Build Coastguard Workerfrom primes import next_prime 16*4bdc9457SAndroid Build Coastguard Workerimport xngen 17*4bdc9457SAndroid Build Coastguard Workerimport xnncommon 18*4bdc9457SAndroid Build Coastguard Worker 19*4bdc9457SAndroid Build Coastguard Worker 20*4bdc9457SAndroid Build Coastguard Workerparser = argparse.ArgumentParser( 21*4bdc9457SAndroid Build Coastguard Worker description='Test generator for DWCONV2D CHW micro-kernels') 22*4bdc9457SAndroid Build Coastguard Workerparser.add_argument("-s", "--spec", metavar="FILE", required=True, 23*4bdc9457SAndroid Build Coastguard Worker help="Spec (YAML) file") 24*4bdc9457SAndroid Build Coastguard Workerparser.add_argument("-o", "--output", metavar="FILE", required=True, 25*4bdc9457SAndroid Build Coastguard Worker help='Output (C++ source) file') 26*4bdc9457SAndroid Build Coastguard Workerparser.set_defaults(defines=list()) 27*4bdc9457SAndroid Build Coastguard Worker 28*4bdc9457SAndroid Build Coastguard Worker 29*4bdc9457SAndroid Build Coastguard WorkerTEST_TEMPLATE = """\ 30*4bdc9457SAndroid Build Coastguard Worker$if SUBSAMPLING == 1: 31*4bdc9457SAndroid Build Coastguard Worker TEST(${TEST_NAME}, output_width_eq_${WIDTH_TILE}) { 32*4bdc9457SAndroid Build Coastguard Worker $if ISA_CHECK: 33*4bdc9457SAndroid Build Coastguard Worker ${ISA_CHECK}; 34*4bdc9457SAndroid Build Coastguard Worker DWConv2DMicrokernelTester() 35*4bdc9457SAndroid Build Coastguard Worker .input_width(${(WIDTH_TILE - 1) * SUBSAMPLING + KERNEL_WIDTH - 2 * PADDING}) 36*4bdc9457SAndroid Build Coastguard Worker .input_height(${HEIGHT_TILE * SUBSAMPLING + KERNEL_HEIGHT - 2 * PADDING - 1}) 37*4bdc9457SAndroid Build Coastguard Worker .kernel_height(${KERNEL_HEIGHT}) 38*4bdc9457SAndroid Build Coastguard Worker .kernel_width(${KERNEL_WIDTH}) 39*4bdc9457SAndroid Build Coastguard Worker .subsampling(${SUBSAMPLING}) 40*4bdc9457SAndroid Build Coastguard Worker .padding_left(${PADDING}) 41*4bdc9457SAndroid Build Coastguard Worker .padding_right(${PADDING}) 42*4bdc9457SAndroid Build Coastguard Worker .padding_top(${PADDING}) 43*4bdc9457SAndroid Build Coastguard Worker .padding_bottom(${PADDING}) 44*4bdc9457SAndroid Build Coastguard Worker .Test(${", ".join(TEST_ARGS)}); 45*4bdc9457SAndroid Build Coastguard Worker } 46*4bdc9457SAndroid Build Coastguard Worker$else: 47*4bdc9457SAndroid Build Coastguard Worker TEST(${TEST_NAME}, output_width_eq_${WIDTH_TILE}) { 48*4bdc9457SAndroid Build Coastguard Worker $if ISA_CHECK: 49*4bdc9457SAndroid Build Coastguard Worker ${ISA_CHECK}; 50*4bdc9457SAndroid Build Coastguard Worker for (size_t input_width = ${(WIDTH_TILE - 1) * SUBSAMPLING + KERNEL_WIDTH - 2 * PADDING}; input_width < ${WIDTH_TILE * SUBSAMPLING + KERNEL_WIDTH - 2 * PADDING}; input_width++) { 51*4bdc9457SAndroid Build Coastguard Worker DWConv2DMicrokernelTester() 52*4bdc9457SAndroid Build Coastguard Worker .input_width(input_width) 53*4bdc9457SAndroid Build Coastguard Worker .input_height(${HEIGHT_TILE * SUBSAMPLING + KERNEL_HEIGHT - 2 * PADDING - 1}) 54*4bdc9457SAndroid Build Coastguard Worker .kernel_height(${KERNEL_HEIGHT}) 55*4bdc9457SAndroid Build Coastguard Worker .kernel_width(${KERNEL_WIDTH}) 56*4bdc9457SAndroid Build Coastguard Worker .subsampling(${SUBSAMPLING}) 57*4bdc9457SAndroid Build Coastguard Worker .padding_left(${PADDING}) 58*4bdc9457SAndroid Build Coastguard Worker .padding_right(${PADDING}) 59*4bdc9457SAndroid Build Coastguard Worker .padding_top(${PADDING}) 60*4bdc9457SAndroid Build Coastguard Worker .padding_bottom(${PADDING}) 61*4bdc9457SAndroid Build Coastguard Worker .Test(${", ".join(TEST_ARGS)}); 62*4bdc9457SAndroid Build Coastguard Worker } 63*4bdc9457SAndroid Build Coastguard Worker } 64*4bdc9457SAndroid Build Coastguard Worker 65*4bdc9457SAndroid Build Coastguard Worker$if WIDTH_TILE > 1: 66*4bdc9457SAndroid Build Coastguard Worker TEST(${TEST_NAME}, output_width_div_${WIDTH_TILE}) { 67*4bdc9457SAndroid Build Coastguard Worker $if ISA_CHECK: 68*4bdc9457SAndroid Build Coastguard Worker ${ISA_CHECK}; 69*4bdc9457SAndroid Build Coastguard Worker for (size_t input_width = ${2 * WIDTH_TILE * SUBSAMPLING + KERNEL_WIDTH - 2 * PADDING - 1}; input_width < ${8 * WIDTH_TILE * SUBSAMPLING + KERNEL_WIDTH - 2 * PADDING - 1}; input_width += ${WIDTH_TILE * SUBSAMPLING}) { 70*4bdc9457SAndroid Build Coastguard Worker DWConv2DMicrokernelTester() 71*4bdc9457SAndroid Build Coastguard Worker .input_width(input_width) 72*4bdc9457SAndroid Build Coastguard Worker .input_height(${HEIGHT_TILE * SUBSAMPLING + KERNEL_HEIGHT - 2 * PADDING - 1}) 73*4bdc9457SAndroid Build Coastguard Worker .kernel_height(${KERNEL_HEIGHT}) 74*4bdc9457SAndroid Build Coastguard Worker .kernel_width(${KERNEL_WIDTH}) 75*4bdc9457SAndroid Build Coastguard Worker .subsampling(${SUBSAMPLING}) 76*4bdc9457SAndroid Build Coastguard Worker .padding_left(${PADDING}) 77*4bdc9457SAndroid Build Coastguard Worker .padding_right(${PADDING}) 78*4bdc9457SAndroid Build Coastguard Worker .padding_top(${PADDING}) 79*4bdc9457SAndroid Build Coastguard Worker .padding_bottom(${PADDING}) 80*4bdc9457SAndroid Build Coastguard Worker .Test(${", ".join(TEST_ARGS)}); 81*4bdc9457SAndroid Build Coastguard Worker } 82*4bdc9457SAndroid Build Coastguard Worker } 83*4bdc9457SAndroid Build Coastguard Worker 84*4bdc9457SAndroid Build Coastguard Worker TEST(${TEST_NAME}, output_width_lt_${WIDTH_TILE}) { 85*4bdc9457SAndroid Build Coastguard Worker $if ISA_CHECK: 86*4bdc9457SAndroid Build Coastguard Worker ${ISA_CHECK}; 87*4bdc9457SAndroid Build Coastguard Worker for (size_t input_width = ${max(1, KERNEL_WIDTH - 2 * PADDING)}; input_width < ${(WIDTH_TILE - 1) * SUBSAMPLING + KERNEL_WIDTH - 2 * PADDING}; input_width++) { 88*4bdc9457SAndroid Build Coastguard Worker DWConv2DMicrokernelTester() 89*4bdc9457SAndroid Build Coastguard Worker .input_width(${WIDTH_TILE * SUBSAMPLING}) 90*4bdc9457SAndroid Build Coastguard Worker .input_height(${HEIGHT_TILE * SUBSAMPLING + KERNEL_HEIGHT - 2 * PADDING - 1}) 91*4bdc9457SAndroid Build Coastguard Worker .kernel_height(${KERNEL_HEIGHT}) 92*4bdc9457SAndroid Build Coastguard Worker .kernel_width(${KERNEL_WIDTH}) 93*4bdc9457SAndroid Build Coastguard Worker .subsampling(${SUBSAMPLING}) 94*4bdc9457SAndroid Build Coastguard Worker .padding_left(${PADDING}) 95*4bdc9457SAndroid Build Coastguard Worker .padding_right(${PADDING}) 96*4bdc9457SAndroid Build Coastguard Worker .padding_top(${PADDING}) 97*4bdc9457SAndroid Build Coastguard Worker .padding_bottom(${PADDING}) 98*4bdc9457SAndroid Build Coastguard Worker .Test(${", ".join(TEST_ARGS)}); 99*4bdc9457SAndroid Build Coastguard Worker } 100*4bdc9457SAndroid Build Coastguard Worker } 101*4bdc9457SAndroid Build Coastguard Worker 102*4bdc9457SAndroid Build Coastguard WorkerTEST(${TEST_NAME}, output_width_gt_${WIDTH_TILE}) { 103*4bdc9457SAndroid Build Coastguard Worker $if ISA_CHECK: 104*4bdc9457SAndroid Build Coastguard Worker ${ISA_CHECK}; 105*4bdc9457SAndroid Build Coastguard Worker for (size_t input_width = ${WIDTH_TILE * SUBSAMPLING + KERNEL_WIDTH - 2 * PADDING}; input_width < ${(5 if WIDTH_TILE == 1 else 2) * WIDTH_TILE * SUBSAMPLING + KERNEL_WIDTH - 2 * PADDING}; input_width++) { 106*4bdc9457SAndroid Build Coastguard Worker DWConv2DMicrokernelTester() 107*4bdc9457SAndroid Build Coastguard Worker .input_width(input_width) 108*4bdc9457SAndroid Build Coastguard Worker .input_height(${HEIGHT_TILE * SUBSAMPLING + KERNEL_HEIGHT - 2 * PADDING - 1}) 109*4bdc9457SAndroid Build Coastguard Worker .kernel_height(${KERNEL_HEIGHT}) 110*4bdc9457SAndroid Build Coastguard Worker .kernel_width(${KERNEL_WIDTH}) 111*4bdc9457SAndroid Build Coastguard Worker .subsampling(${SUBSAMPLING}) 112*4bdc9457SAndroid Build Coastguard Worker .padding_left(${PADDING}) 113*4bdc9457SAndroid Build Coastguard Worker .padding_right(${PADDING}) 114*4bdc9457SAndroid Build Coastguard Worker .padding_top(${PADDING}) 115*4bdc9457SAndroid Build Coastguard Worker .padding_bottom(${PADDING}) 116*4bdc9457SAndroid Build Coastguard Worker .Test(${", ".join(TEST_ARGS)}); 117*4bdc9457SAndroid Build Coastguard Worker } 118*4bdc9457SAndroid Build Coastguard Worker} 119*4bdc9457SAndroid Build Coastguard Worker 120*4bdc9457SAndroid Build Coastguard Worker$if SUBSAMPLING > 1: 121*4bdc9457SAndroid Build Coastguard Worker TEST(${TEST_NAME}, output_height_eq_${HEIGHT_TILE}) { 122*4bdc9457SAndroid Build Coastguard Worker $if ISA_CHECK: 123*4bdc9457SAndroid Build Coastguard Worker ${ISA_CHECK}; 124*4bdc9457SAndroid Build Coastguard Worker for (size_t input_height = ${(HEIGHT_TILE - 1) * SUBSAMPLING + KERNEL_HEIGHT - 2 * PADDING}; input_height < ${HEIGHT_TILE * SUBSAMPLING + KERNEL_HEIGHT - 2 * PADDING}; input_height++) { 125*4bdc9457SAndroid Build Coastguard Worker for (size_t input_width = 1; input_width < ${5 * WIDTH_TILE * SUBSAMPLING + KERNEL_WIDTH - 2 * PADDING}; input_width += ${max(1, WIDTH_TILE * SUBSAMPLING - 1)}) { 126*4bdc9457SAndroid Build Coastguard Worker DWConv2DMicrokernelTester() 127*4bdc9457SAndroid Build Coastguard Worker .input_width(input_width) 128*4bdc9457SAndroid Build Coastguard Worker .input_height(input_height) 129*4bdc9457SAndroid Build Coastguard Worker .kernel_height(${KERNEL_HEIGHT}) 130*4bdc9457SAndroid Build Coastguard Worker .kernel_width(${KERNEL_WIDTH}) 131*4bdc9457SAndroid Build Coastguard Worker .subsampling(${SUBSAMPLING}) 132*4bdc9457SAndroid Build Coastguard Worker .padding_left(${PADDING}) 133*4bdc9457SAndroid Build Coastguard Worker .padding_right(${PADDING}) 134*4bdc9457SAndroid Build Coastguard Worker .padding_top(${PADDING}) 135*4bdc9457SAndroid Build Coastguard Worker .padding_bottom(${PADDING}) 136*4bdc9457SAndroid Build Coastguard Worker .Test(${", ".join(TEST_ARGS)}); 137*4bdc9457SAndroid Build Coastguard Worker } 138*4bdc9457SAndroid Build Coastguard Worker } 139*4bdc9457SAndroid Build Coastguard Worker } 140*4bdc9457SAndroid Build Coastguard Worker 141*4bdc9457SAndroid Build Coastguard Worker$if HEIGHT_TILE > 1: 142*4bdc9457SAndroid Build Coastguard Worker TEST(${TEST_NAME}, output_height_div_${HEIGHT_TILE}) { 143*4bdc9457SAndroid Build Coastguard Worker $if ISA_CHECK: 144*4bdc9457SAndroid Build Coastguard Worker ${ISA_CHECK}; 145*4bdc9457SAndroid Build Coastguard Worker for (size_t input_height = ${2 * HEIGHT_TILE * SUBSAMPLING + KERNEL_HEIGHT - 2 * PADDING - 1}; input_height < ${8 * HEIGHT_TILE * SUBSAMPLING + KERNEL_HEIGHT - 2 * PADDING - 1}; input_height += ${HEIGHT_TILE * SUBSAMPLING}) { 146*4bdc9457SAndroid Build Coastguard Worker for (size_t input_width = 1; input_width < ${5 * WIDTH_TILE * SUBSAMPLING + KERNEL_WIDTH - 2 * PADDING}; input_width += ${max(1, WIDTH_TILE * SUBSAMPLING - 1)}) { 147*4bdc9457SAndroid Build Coastguard Worker DWConv2DMicrokernelTester() 148*4bdc9457SAndroid Build Coastguard Worker .input_width(input_width) 149*4bdc9457SAndroid Build Coastguard Worker .input_height(input_height) 150*4bdc9457SAndroid Build Coastguard Worker .kernel_height(${KERNEL_HEIGHT}) 151*4bdc9457SAndroid Build Coastguard Worker .kernel_width(${KERNEL_WIDTH}) 152*4bdc9457SAndroid Build Coastguard Worker .subsampling(${SUBSAMPLING}) 153*4bdc9457SAndroid Build Coastguard Worker .padding_left(${PADDING}) 154*4bdc9457SAndroid Build Coastguard Worker .padding_right(${PADDING}) 155*4bdc9457SAndroid Build Coastguard Worker .padding_top(${PADDING}) 156*4bdc9457SAndroid Build Coastguard Worker .padding_bottom(${PADDING}) 157*4bdc9457SAndroid Build Coastguard Worker .Test(${", ".join(TEST_ARGS)}); 158*4bdc9457SAndroid Build Coastguard Worker } 159*4bdc9457SAndroid Build Coastguard Worker } 160*4bdc9457SAndroid Build Coastguard Worker } 161*4bdc9457SAndroid Build Coastguard Worker 162*4bdc9457SAndroid Build Coastguard Worker TEST(${TEST_NAME}, output_height_lt_${HEIGHT_TILE}) { 163*4bdc9457SAndroid Build Coastguard Worker $if ISA_CHECK: 164*4bdc9457SAndroid Build Coastguard Worker ${ISA_CHECK}; 165*4bdc9457SAndroid Build Coastguard Worker for (size_t input_height = ${max(1, KERNEL_HEIGHT - 2 * PADDING)}; input_height < ${(HEIGHT_TILE - 1) * SUBSAMPLING + KERNEL_HEIGHT - 2 * PADDING}; input_height++) { 166*4bdc9457SAndroid Build Coastguard Worker for (size_t input_width = 1; input_width < ${5 * WIDTH_TILE * SUBSAMPLING + KERNEL_WIDTH - 2 * PADDING}; input_width += ${max(1, WIDTH_TILE * SUBSAMPLING - 1)}) { 167*4bdc9457SAndroid Build Coastguard Worker DWConv2DMicrokernelTester() 168*4bdc9457SAndroid Build Coastguard Worker .input_width(input_width) 169*4bdc9457SAndroid Build Coastguard Worker .input_height(input_height) 170*4bdc9457SAndroid Build Coastguard Worker .kernel_height(${KERNEL_HEIGHT}) 171*4bdc9457SAndroid Build Coastguard Worker .kernel_width(${KERNEL_WIDTH}) 172*4bdc9457SAndroid Build Coastguard Worker .subsampling(${SUBSAMPLING}) 173*4bdc9457SAndroid Build Coastguard Worker .padding_left(${PADDING}) 174*4bdc9457SAndroid Build Coastguard Worker .padding_right(${PADDING}) 175*4bdc9457SAndroid Build Coastguard Worker .padding_top(${PADDING}) 176*4bdc9457SAndroid Build Coastguard Worker .padding_bottom(${PADDING}) 177*4bdc9457SAndroid Build Coastguard Worker .Test(${", ".join(TEST_ARGS)}); 178*4bdc9457SAndroid Build Coastguard Worker } 179*4bdc9457SAndroid Build Coastguard Worker } 180*4bdc9457SAndroid Build Coastguard Worker } 181*4bdc9457SAndroid Build Coastguard Worker 182*4bdc9457SAndroid Build Coastguard WorkerTEST(${TEST_NAME}, output_height_gt_${HEIGHT_TILE}) { 183*4bdc9457SAndroid Build Coastguard Worker $if ISA_CHECK: 184*4bdc9457SAndroid Build Coastguard Worker ${ISA_CHECK}; 185*4bdc9457SAndroid Build Coastguard Worker for (size_t input_height = ${HEIGHT_TILE * SUBSAMPLING + KERNEL_HEIGHT - 2 * PADDING}; input_height < ${(5 if WIDTH_TILE == 1 else 2) * HEIGHT_TILE * SUBSAMPLING + KERNEL_HEIGHT - 2 * PADDING}; input_height++) { 186*4bdc9457SAndroid Build Coastguard Worker for (size_t input_width = 1; input_width < ${5 * WIDTH_TILE * SUBSAMPLING + KERNEL_WIDTH - 2 * PADDING}; input_width += ${max(1, WIDTH_TILE * SUBSAMPLING - 1)}) { 187*4bdc9457SAndroid Build Coastguard Worker DWConv2DMicrokernelTester() 188*4bdc9457SAndroid Build Coastguard Worker .input_width(input_width) 189*4bdc9457SAndroid Build Coastguard Worker .input_height(input_height) 190*4bdc9457SAndroid Build Coastguard Worker .kernel_height(${KERNEL_HEIGHT}) 191*4bdc9457SAndroid Build Coastguard Worker .kernel_width(${KERNEL_WIDTH}) 192*4bdc9457SAndroid Build Coastguard Worker .subsampling(${SUBSAMPLING}) 193*4bdc9457SAndroid Build Coastguard Worker .padding_left(${PADDING}) 194*4bdc9457SAndroid Build Coastguard Worker .padding_right(${PADDING}) 195*4bdc9457SAndroid Build Coastguard Worker .padding_top(${PADDING}) 196*4bdc9457SAndroid Build Coastguard Worker .padding_bottom(${PADDING}) 197*4bdc9457SAndroid Build Coastguard Worker .Test(${", ".join(TEST_ARGS)}); 198*4bdc9457SAndroid Build Coastguard Worker } 199*4bdc9457SAndroid Build Coastguard Worker } 200*4bdc9457SAndroid Build Coastguard Worker} 201*4bdc9457SAndroid Build Coastguard Worker 202*4bdc9457SAndroid Build Coastguard Worker$if SUBSAMPLING > 1: 203*4bdc9457SAndroid Build Coastguard Worker TEST(${TEST_NAME}, padding_top_eq_${SUBSAMPLING - 1}) { 204*4bdc9457SAndroid Build Coastguard Worker $if ISA_CHECK: 205*4bdc9457SAndroid Build Coastguard Worker ${ISA_CHECK}; 206*4bdc9457SAndroid Build Coastguard Worker for (size_t input_height = ${max(1, KERNEL_HEIGHT - 2 * PADDING + 1)}; input_height < ${3 * HEIGHT_TILE * SUBSAMPLING + KERNEL_HEIGHT - 2 * PADDING + 1}; input_height++) { 207*4bdc9457SAndroid Build Coastguard Worker for (size_t input_width = 1; input_width < ${5 * WIDTH_TILE * SUBSAMPLING + KERNEL_WIDTH - 2 * PADDING}; input_width += ${max(1, WIDTH_TILE * SUBSAMPLING - 1)}) { 208*4bdc9457SAndroid Build Coastguard Worker DWConv2DMicrokernelTester() 209*4bdc9457SAndroid Build Coastguard Worker .input_width(input_width) 210*4bdc9457SAndroid Build Coastguard Worker .input_height(input_height) 211*4bdc9457SAndroid Build Coastguard Worker .kernel_height(${KERNEL_HEIGHT}) 212*4bdc9457SAndroid Build Coastguard Worker .kernel_width(${KERNEL_WIDTH}) 213*4bdc9457SAndroid Build Coastguard Worker .subsampling(${SUBSAMPLING}) 214*4bdc9457SAndroid Build Coastguard Worker .padding_left(${PADDING}) 215*4bdc9457SAndroid Build Coastguard Worker .padding_right(${PADDING}) 216*4bdc9457SAndroid Build Coastguard Worker .padding_top(${PADDING - 1}) 217*4bdc9457SAndroid Build Coastguard Worker .padding_bottom(${PADDING}) 218*4bdc9457SAndroid Build Coastguard Worker .Test(${", ".join(TEST_ARGS)}); 219*4bdc9457SAndroid Build Coastguard Worker } 220*4bdc9457SAndroid Build Coastguard Worker } 221*4bdc9457SAndroid Build Coastguard Worker } 222*4bdc9457SAndroid Build Coastguard Worker""" 223*4bdc9457SAndroid Build Coastguard Worker 224*4bdc9457SAndroid Build Coastguard Workerdef split_ukernel_name(name): 225*4bdc9457SAndroid Build Coastguard Worker match = re.fullmatch(r"xnn_(f16|f32)_dwconv2d_chw_ukernel_(\d+)x(\d+)(s2)?p(\d+)__(.+)_(\d+)x(\d+)(_acc\d+)?", name) 226*4bdc9457SAndroid Build Coastguard Worker assert match is not None 227*4bdc9457SAndroid Build Coastguard Worker kernel_height, kernel_width = int(match.group(2)), int(match.group(3)) 228*4bdc9457SAndroid Build Coastguard Worker if match.group(4): 229*4bdc9457SAndroid Build Coastguard Worker assert match.group(4).startswith("s") 230*4bdc9457SAndroid Build Coastguard Worker stride = int(match.group(4)[1:]) 231*4bdc9457SAndroid Build Coastguard Worker else: 232*4bdc9457SAndroid Build Coastguard Worker stride = 1 233*4bdc9457SAndroid Build Coastguard Worker padding = int(match.group(5)) 234*4bdc9457SAndroid Build Coastguard Worker 235*4bdc9457SAndroid Build Coastguard Worker height_tile = int(match.group(7)) 236*4bdc9457SAndroid Build Coastguard Worker width_tile = int(match.group(8)) 237*4bdc9457SAndroid Build Coastguard Worker 238*4bdc9457SAndroid Build Coastguard Worker arch, isa = xnncommon.parse_target_name(target_name=match.group(6)) 239*4bdc9457SAndroid Build Coastguard Worker return kernel_height, kernel_width, stride, padding, arch, isa, \ 240*4bdc9457SAndroid Build Coastguard Worker height_tile, width_tile 241*4bdc9457SAndroid Build Coastguard Worker 242*4bdc9457SAndroid Build Coastguard Worker 243*4bdc9457SAndroid Build Coastguard Workerdef generate_test_cases(ukernel, kernel_height, kernel_width, subsampling, \ 244*4bdc9457SAndroid Build Coastguard Worker init_fn, padding, isa, height_tile, width_tile): 245*4bdc9457SAndroid Build Coastguard Worker """Generates all tests cases for a DWCONV2D CHW micro-kernel. 246*4bdc9457SAndroid Build Coastguard Worker 247*4bdc9457SAndroid Build Coastguard Worker Args: 248*4bdc9457SAndroid Build Coastguard Worker ukernel: C name of the micro-kernel function. 249*4bdc9457SAndroid Build Coastguard Worker kernel_height: convolution kernel height assumed by the micro-kernel. 250*4bdc9457SAndroid Build Coastguard Worker kernel_width: convolution kernel width assumed by the micro-kernel. 251*4bdc9457SAndroid Build Coastguard Worker subsampling: convolution subsampling (stride) assumed by the micro-kernel. 252*4bdc9457SAndroid Build Coastguard Worker The same subsampling factor is assumed for both horizontal and 253*4bdc9457SAndroid Build Coastguard Worker vertical directions. 254*4bdc9457SAndroid Build Coastguard Worker init_fn: C name of the function to initialize microkernel parameters. 255*4bdc9457SAndroid Build Coastguard Worker padding: convolution padding value assumed by the micro-kernel for right, 256*4bdc9457SAndroid Build Coastguard Worker bottom, and left padding. If convolution stride is 1, the same 257*4bdc9457SAndroid Build Coastguard Worker padding value is assumed for the top padding. If convolution stride 258*4bdc9457SAndroid Build Coastguard Worker is different than 1, top padding is specified via micro-kernel 259*4bdc9457SAndroid Build Coastguard Worker parameter, and can be either padding or (padding - 1). 260*4bdc9457SAndroid Build Coastguard Worker isa: instruction set required to run the micro-kernel. Generated unit test 261*4bdc9457SAndroid Build Coastguard Worker will skip execution if the host processor doesn't support this ISA. 262*4bdc9457SAndroid Build Coastguard Worker height_tile: number of output rows processed in one iteration of the main 263*4bdc9457SAndroid Build Coastguard Worker loop of the micro-kernel. 264*4bdc9457SAndroid Build Coastguard Worker width_tile: number of output columns processed in one iteration of the main 265*4bdc9457SAndroid Build Coastguard Worker loop of the micro-kernel. 266*4bdc9457SAndroid Build Coastguard Worker 267*4bdc9457SAndroid Build Coastguard Worker Returns: 268*4bdc9457SAndroid Build Coastguard Worker Code for the test case. 269*4bdc9457SAndroid Build Coastguard Worker """ 270*4bdc9457SAndroid Build Coastguard Worker _, test_name = ukernel.split("_", 1) 271*4bdc9457SAndroid Build Coastguard Worker _, datatype, ukernel_type, _ = ukernel.split("_", 3) 272*4bdc9457SAndroid Build Coastguard Worker test_args = [ukernel] 273*4bdc9457SAndroid Build Coastguard Worker if init_fn: 274*4bdc9457SAndroid Build Coastguard Worker test_args.append(init_fn) 275*4bdc9457SAndroid Build Coastguard Worker if not isa: 276*4bdc9457SAndroid Build Coastguard Worker test_args.append("DWConv2DMicrokernelTester::Variant::Scalar") 277*4bdc9457SAndroid Build Coastguard Worker return xngen.preprocess(TEST_TEMPLATE, { 278*4bdc9457SAndroid Build Coastguard Worker "TEST_NAME": test_name.upper().replace("UKERNEL_", ""), 279*4bdc9457SAndroid Build Coastguard Worker "TEST_ARGS": test_args, 280*4bdc9457SAndroid Build Coastguard Worker "UKERNEL_TYPE": ukernel_type.upper(), 281*4bdc9457SAndroid Build Coastguard Worker "DATATYPE": datatype, 282*4bdc9457SAndroid Build Coastguard Worker "KERNEL_HEIGHT": kernel_height, 283*4bdc9457SAndroid Build Coastguard Worker "KERNEL_WIDTH": kernel_width, 284*4bdc9457SAndroid Build Coastguard Worker "SUBSAMPLING": subsampling, 285*4bdc9457SAndroid Build Coastguard Worker "PADDING": padding, 286*4bdc9457SAndroid Build Coastguard Worker "HEIGHT_TILE": height_tile, 287*4bdc9457SAndroid Build Coastguard Worker "WIDTH_TILE": width_tile, 288*4bdc9457SAndroid Build Coastguard Worker "ISA_CHECK": xnncommon.generate_isa_check_macro(isa), 289*4bdc9457SAndroid Build Coastguard Worker "next_prime": next_prime, 290*4bdc9457SAndroid Build Coastguard Worker }) 291*4bdc9457SAndroid Build Coastguard Worker 292*4bdc9457SAndroid Build Coastguard Worker 293*4bdc9457SAndroid Build Coastguard Workerdef main(args): 294*4bdc9457SAndroid Build Coastguard Worker options = parser.parse_args(args) 295*4bdc9457SAndroid Build Coastguard Worker 296*4bdc9457SAndroid Build Coastguard Worker with codecs.open(options.spec, "r", encoding="utf-8") as spec_file: 297*4bdc9457SAndroid Build Coastguard Worker spec_yaml = yaml.safe_load(spec_file) 298*4bdc9457SAndroid Build Coastguard Worker if not isinstance(spec_yaml, list): 299*4bdc9457SAndroid Build Coastguard Worker raise ValueError("expected a list of micro-kernels in the spec") 300*4bdc9457SAndroid Build Coastguard Worker 301*4bdc9457SAndroid Build Coastguard Worker tests = """\ 302*4bdc9457SAndroid Build Coastguard Worker// Copyright 2020 Google LLC 303*4bdc9457SAndroid Build Coastguard Worker// 304*4bdc9457SAndroid Build Coastguard Worker// This source code is licensed under the BSD-style license found in the 305*4bdc9457SAndroid Build Coastguard Worker// LICENSE file in the root directory of this source tree. 306*4bdc9457SAndroid Build Coastguard Worker// 307*4bdc9457SAndroid Build Coastguard Worker// Auto-generated file. Do not edit! 308*4bdc9457SAndroid Build Coastguard Worker// Specification: {specification} 309*4bdc9457SAndroid Build Coastguard Worker// Generator: {generator} 310*4bdc9457SAndroid Build Coastguard Worker 311*4bdc9457SAndroid Build Coastguard Worker 312*4bdc9457SAndroid Build Coastguard Worker#include <gtest/gtest.h> 313*4bdc9457SAndroid Build Coastguard Worker 314*4bdc9457SAndroid Build Coastguard Worker#include <xnnpack/common.h> 315*4bdc9457SAndroid Build Coastguard Worker#include <xnnpack/isa-checks.h> 316*4bdc9457SAndroid Build Coastguard Worker 317*4bdc9457SAndroid Build Coastguard Worker#include <xnnpack/dwconv.h> 318*4bdc9457SAndroid Build Coastguard Worker#include "dwconv2d-microkernel-tester.h" 319*4bdc9457SAndroid Build Coastguard Worker""".format(specification=options.spec, generator=sys.argv[0]) 320*4bdc9457SAndroid Build Coastguard Worker 321*4bdc9457SAndroid Build Coastguard Worker for ukernel_spec in spec_yaml: 322*4bdc9457SAndroid Build Coastguard Worker name = ukernel_spec["name"] 323*4bdc9457SAndroid Build Coastguard Worker init_fn = ukernel_spec.get("init") 324*4bdc9457SAndroid Build Coastguard Worker pipelined = bool(ukernel_spec.get("pipelined", False)) 325*4bdc9457SAndroid Build Coastguard Worker assembly = bool(ukernel_spec.get("assembly", False)) 326*4bdc9457SAndroid Build Coastguard Worker kernel_height, kernel_width, subsampling, padding, arch, isa, \ 327*4bdc9457SAndroid Build Coastguard Worker height_tile, width_tile = split_ukernel_name(name) 328*4bdc9457SAndroid Build Coastguard Worker 329*4bdc9457SAndroid Build Coastguard Worker # specification can override architecture 330*4bdc9457SAndroid Build Coastguard Worker arch = ukernel_spec.get("arch", arch) 331*4bdc9457SAndroid Build Coastguard Worker 332*4bdc9457SAndroid Build Coastguard Worker test_case = generate_test_cases(name, kernel_height, kernel_width, \ 333*4bdc9457SAndroid Build Coastguard Worker subsampling, init_fn, padding, isa, \ 334*4bdc9457SAndroid Build Coastguard Worker height_tile, width_tile) 335*4bdc9457SAndroid Build Coastguard Worker tests += "\n\n" + xnncommon.postprocess_test_case(test_case, arch, isa, assembly) 336*4bdc9457SAndroid Build Coastguard Worker 337*4bdc9457SAndroid Build Coastguard Worker txt_changed = True 338*4bdc9457SAndroid Build Coastguard Worker if os.path.exists(options.output): 339*4bdc9457SAndroid Build Coastguard Worker with codecs.open(options.output, "r", encoding="utf-8") as output_file: 340*4bdc9457SAndroid Build Coastguard Worker txt_changed = output_file.read() != tests 341*4bdc9457SAndroid Build Coastguard Worker 342*4bdc9457SAndroid Build Coastguard Worker if txt_changed: 343*4bdc9457SAndroid Build Coastguard Worker with codecs.open(options.output, "w", encoding="utf-8") as output_file: 344*4bdc9457SAndroid Build Coastguard Worker output_file.write(tests) 345*4bdc9457SAndroid Build Coastguard Worker 346*4bdc9457SAndroid Build Coastguard Worker 347*4bdc9457SAndroid Build Coastguard Workerif __name__ == "__main__": 348*4bdc9457SAndroid Build Coastguard Worker main(sys.argv[1:]) 349