blob: 4b13e36f93b228367d965f88d82825ef5b5275a3 [file] [log] [blame]
Marat Dukhan35dacfb2019-11-07 19:18:16 -08001#!/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 os
10import re
11import sys
12import yaml
13
14sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
15from primes import next_prime
16import xngen
17import xnncommon
18
19
20parser = argparse.ArgumentParser(
Marat Dukhan660fd192020-03-10 04:55:30 -070021 description='IBILINEAR microkernel test generator')
Marat Dukhan35dacfb2019-11-07 19:18:16 -080022parser.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):
Marat Dukhancdb42a52021-11-22 20:09:32 -080030 match = re.match(r"^xnn_(f16|f32|s8|u8)_ibilinear_ukernel__(.+)_c(\d+)$", name)
Marat Dukhan35dacfb2019-11-07 19:18:16 -080031 assert match is not None
32 channel_tile = int(match.group(3))
33 pixel_tile = 1
34
35 arch, isa = xnncommon.parse_target_name(target_name=match.group(2))
36 return channel_tile, pixel_tile, arch, isa
37
38
Marat Dukhan660fd192020-03-10 04:55:30 -070039IBILINEAR_TEST_TEMPLATE = """\
Marat Dukhan35dacfb2019-11-07 19:18:16 -080040TEST(${TEST_NAME}, channels_eq_${CHANNEL_TILE}) {
41 $if ISA_CHECK:
42 ${ISA_CHECK};
Marat Dukhan660fd192020-03-10 04:55:30 -070043 IBilinearMicrokernelTester()
Marat Dukhan35dacfb2019-11-07 19:18:16 -080044 .pixels(${PIXEL_TILE})
45 .channels(${CHANNEL_TILE})
46 .Test(${TEST_FUNC});
47}
48
49$if CHANNEL_TILE > 1:
50 TEST(${TEST_NAME}, channels_div_${CHANNEL_TILE}) {
51 $if ISA_CHECK:
52 ${ISA_CHECK};
53 for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*10}; channels += ${CHANNEL_TILE}) {
Marat Dukhan660fd192020-03-10 04:55:30 -070054 IBilinearMicrokernelTester()
Marat Dukhan35dacfb2019-11-07 19:18:16 -080055 .pixels(${PIXEL_TILE})
56 .channels(channels)
57 .Test(${TEST_FUNC});
58 }
59 }
60
61 TEST(${TEST_NAME}, channels_lt_${CHANNEL_TILE}) {
62 $if ISA_CHECK:
63 ${ISA_CHECK};
64 for (size_t channels = 1; channels < ${CHANNEL_TILE}; channels++) {
Marat Dukhan660fd192020-03-10 04:55:30 -070065 IBilinearMicrokernelTester()
Marat Dukhan35dacfb2019-11-07 19:18:16 -080066 .pixels(${PIXEL_TILE})
67 .channels(channels)
68 .Test(${TEST_FUNC});
69 }
70 }
71
72TEST(${TEST_NAME}, channels_gt_${CHANNEL_TILE}) {
73 $if ISA_CHECK:
74 ${ISA_CHECK};
75 for (size_t channels = ${CHANNEL_TILE+1}; channels < ${10 if CHANNEL_TILE == 1 else CHANNEL_TILE*2}; channels++) {
Marat Dukhan660fd192020-03-10 04:55:30 -070076 IBilinearMicrokernelTester()
Marat Dukhan35dacfb2019-11-07 19:18:16 -080077 .pixels(${PIXEL_TILE})
78 .channels(channels)
79 .Test(${TEST_FUNC});
80 }
81}
82
83$if PIXEL_TILE > 1:
84 TEST(${TEST_NAME}, pixels_div_${PIXEL_TILE}) {
85 $if ISA_CHECK:
86 ${ISA_CHECK};
87 for (size_t pixels = ${PIXEL_TILE*2}; pixels < ${PIXEL_TILE*10}; pixels += ${PIXEL_TILE}) {
88 for (size_t channels = 1; channels <= ${CHANNEL_TILE * 5}; channels += ${max(1, CHANNEL_TILE - 1)}) {
Marat Dukhan660fd192020-03-10 04:55:30 -070089 IBilinearMicrokernelTester()
Marat Dukhan35dacfb2019-11-07 19:18:16 -080090 .pixels(pixels)
91 .channels(channels)
92 .Test(${TEST_FUNC});
93 }
94 }
95 }
96
97 TEST(${TEST_NAME}, pixels_lt_${PIXEL_TILE}) {
98 $if ISA_CHECK:
99 ${ISA_CHECK};
100 for (size_t pixels = 1; pixels < ${PIXEL_TILE}; pixels++) {
101 for (size_t channels = 1; channels <= ${CHANNEL_TILE * 5}; channels += ${max(1, CHANNEL_TILE - 1)}) {
Marat Dukhan660fd192020-03-10 04:55:30 -0700102 IBilinearMicrokernelTester()
Marat Dukhan35dacfb2019-11-07 19:18:16 -0800103 .pixels(pixels)
104 .channels(channels)
105 .Test(${TEST_FUNC});
106 }
107 }
108 }
109
110TEST(${TEST_NAME}, pixels_gt_${PIXEL_TILE}) {
111 $if ISA_CHECK:
112 ${ISA_CHECK};
113 for (size_t pixels = ${PIXEL_TILE+1}; pixels < ${max(PIXEL_TILE*2, 3)}; pixels++) {
114 for (size_t channels = 1; channels <= ${CHANNEL_TILE * 5}; channels += ${max(1, CHANNEL_TILE - 1)}) {
Marat Dukhan660fd192020-03-10 04:55:30 -0700115 IBilinearMicrokernelTester()
Marat Dukhan35dacfb2019-11-07 19:18:16 -0800116 .pixels(pixels)
117 .channels(channels)
118 .Test(${TEST_FUNC});
119 }
120 }
121}
122
Marat Dukhan9fab3f92019-11-08 14:55:19 -0800123TEST(${TEST_NAME}, input_offset) {
124 $if ISA_CHECK:
125 ${ISA_CHECK};
126 for (size_t pixels = 1; pixels < ${PIXEL_TILE * 5}; pixels += ${max(1, PIXEL_TILE - 1)}) {
127 for (size_t channels = 1; channels <= ${CHANNEL_TILE * 5}; channels += ${max(1, CHANNEL_TILE - 1)}) {
Marat Dukhan660fd192020-03-10 04:55:30 -0700128 IBilinearMicrokernelTester()
Marat Dukhan9fab3f92019-11-08 14:55:19 -0800129 .pixels(pixels)
130 .channels(channels)
131 .input_offset(${next_prime(CHANNEL_TILE * 5 + 1)})
132 .Test(${TEST_FUNC});
133 }
134 }
135}
XNNPACK Team6be46b22020-10-22 23:34:54 -0700136
Marat Dukhan35dacfb2019-11-07 19:18:16 -0800137TEST(${TEST_NAME}, output_stride) {
138 $if ISA_CHECK:
139 ${ISA_CHECK};
140 for (size_t pixels = 1; pixels < ${PIXEL_TILE * 5}; pixels += ${max(1, PIXEL_TILE - 1)}) {
141 for (size_t channels = 1; channels <= ${CHANNEL_TILE * 5}; channels += ${max(1, CHANNEL_TILE - 1)}) {
Marat Dukhan660fd192020-03-10 04:55:30 -0700142 IBilinearMicrokernelTester()
Marat Dukhan35dacfb2019-11-07 19:18:16 -0800143 .pixels(pixels)
144 .channels(channels)
145 .output_stride(${next_prime(CHANNEL_TILE * 5 + 1)})
146 .Test(${TEST_FUNC});
147 }
148 }
149}
150"""
151
152
153def generate_test_cases(ukernel, channel_tile, pixel_tile, isa):
154 """Generates all tests cases for a BILINEAR micro-kernel.
155
156 Args:
157 ukernel: C name of the micro-kernel function.
158 channel_tile: Number of channels processed per one iteration of the inner
159 loop of the micro-kernel.
160 pixel_tile: Number of pixels processed per one iteration of the outer loop
161 of the micro-kernel.
162 isa: instruction set required to run the micro-kernel. Generated unit test
163 will skip execution if the host processor doesn't support this ISA.
164
165 Returns:
166 Code for the test case.
167 """
168 _, test_name = ukernel.split("_", 1)
169 _, datatype, ukernel_type, _ = ukernel.split("_", 3)
170 test_args = [ukernel]
Marat Dukhan660fd192020-03-10 04:55:30 -0700171 return xngen.preprocess(IBILINEAR_TEST_TEMPLATE, {
Marat Dukhan35dacfb2019-11-07 19:18:16 -0800172 "TEST_NAME": test_name.upper().replace("UKERNEL_", ""),
173 "TEST_FUNC": ukernel,
174 "UKERNEL_TYPE": ukernel_type.upper(),
175 "DATATYPE": datatype,
176 "CHANNEL_TILE": channel_tile,
177 "PIXEL_TILE": pixel_tile,
178 "ISA_CHECK": xnncommon.generate_isa_check_macro(isa),
179 "next_prime": next_prime,
180 })
181
182
183def main(args):
184 options = parser.parse_args(args)
185
186 with codecs.open(options.spec, "r", encoding="utf-8") as spec_file:
187 spec_yaml = yaml.safe_load(spec_file)
188 if not isinstance(spec_yaml, list):
189 raise ValueError("expected a list of micro-kernels in the spec")
190
191 tests = """\
192// Copyright 2019 Google LLC
193//
194// This source code is licensed under the BSD-style license found in the
195// LICENSE file in the root directory of this source tree.
196//
197// Auto-generated file. Do not edit!
198// Specification: {specification}
199// Generator: {generator}
200
201
202#include <gtest/gtest.h>
203
204#include <xnnpack/common.h>
205#include <xnnpack/isa-checks.h>
206
Marat Dukhan660fd192020-03-10 04:55:30 -0700207#include <xnnpack/ibilinear.h>
208#include "ibilinear-microkernel-tester.h"
Marat Dukhan35dacfb2019-11-07 19:18:16 -0800209""".format(specification=options.spec, generator=sys.argv[0])
210
211 for ukernel_spec in spec_yaml:
212 name = ukernel_spec["name"]
213 channel_tile, pixel_tile, arch, isa = split_ukernel_name(name)
214
215 # specification can override architecture
216 arch = ukernel_spec.get("arch", arch)
217
218 test_case = generate_test_cases(name, channel_tile, pixel_tile, isa)
219 tests += "\n\n" + xnncommon.postprocess_test_case(test_case, arch, isa)
220
Frank Barchard1f83cf92021-09-07 14:13:03 -0700221 txt_changed = True
222 if os.path.exists(options.output):
223 with codecs.open(options.output, "r", encoding="utf-8") as output_file:
224 txt_changed = output_file.read() != tests
225
226 if txt_changed:
227 with codecs.open(options.output, "w", encoding="utf-8") as output_file:
228 output_file.write(tests)
Marat Dukhan35dacfb2019-11-07 19:18:16 -0800229
230
231if __name__ == "__main__":
232 main(sys.argv[1:])