blob: fb3fa4b16999d9671974cd8dd953a01f2f48bc4e [file] [log] [blame]
XNNPACK Team6be46b22020-10-22 23:34:54 -07001#!/usr/bin/env python
2# Copyright 2020 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(
21 description='IBILINEAR 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.match(r"^xnn_(f16|f32)_ibilinear_chw_ukernel__(.+)_p(\d+)$", name)
31 assert match is not None
32 pixel_tile = int(match.group(3))
33 channel_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
39IBILINEAR_TEST_TEMPLATE = """\
40TEST(${TEST_NAME}, pixels_eq_${PIXEL_TILE}) {
41 $if ISA_CHECK:
42 ${ISA_CHECK};
43 IBilinearMicrokernelTester()
44 .pixels(${PIXEL_TILE})
45 .channels(${CHANNEL_TILE})
XNNPACK Teamcb2b6672020-10-23 19:30:50 -070046 .TestCHW(${TEST_FUNC});
XNNPACK Team6be46b22020-10-22 23:34:54 -070047}
48
49$if PIXEL_TILE > 1:
50 TEST(${TEST_NAME}, pixels_div_${PIXEL_TILE}) {
51 $if ISA_CHECK:
52 ${ISA_CHECK};
53 for (size_t pixels = ${PIXEL_TILE*2}; pixels < ${PIXEL_TILE*10}; pixels += ${PIXEL_TILE}) {
54 IBilinearMicrokernelTester()
55 .pixels(pixels)
56 .channels(${CHANNEL_TILE})
XNNPACK Teamcb2b6672020-10-23 19:30:50 -070057 .TestCHW(${TEST_FUNC});
XNNPACK Team6be46b22020-10-22 23:34:54 -070058 }
59 }
60
61 TEST(${TEST_NAME}, pixels_lt_${PIXEL_TILE}) {
62 $if ISA_CHECK:
63 ${ISA_CHECK};
64 for (size_t pixels = 1; pixels < ${PIXEL_TILE}; pixels++) {
65 IBilinearMicrokernelTester()
66 .pixels(pixels)
67 .channels(${CHANNEL_TILE})
XNNPACK Teamcb2b6672020-10-23 19:30:50 -070068 .TestCHW(${TEST_FUNC});
XNNPACK Team6be46b22020-10-22 23:34:54 -070069 }
70 }
71
72TEST(${TEST_NAME}, pixels_gt_${PIXEL_TILE}) {
73 $if ISA_CHECK:
74 ${ISA_CHECK};
75 for (size_t pixels = ${PIXEL_TILE+1}; pixels < ${10 if PIXEL_TILE == 1 else PIXEL_TILE*2}; pixels++) {
76 IBilinearMicrokernelTester()
77 .pixels(pixels)
78 .channels(${CHANNEL_TILE})
XNNPACK Teamcb2b6672020-10-23 19:30:50 -070079 .TestCHW(${TEST_FUNC});
XNNPACK Team6be46b22020-10-22 23:34:54 -070080 }
81}
82
83$if CHANNEL_TILE > 1:
84 TEST(${TEST_NAME}, channels_div_${PIXEL_TILE}) {
85 $if ISA_CHECK:
86 ${ISA_CHECK};
87 for (size_t channels = ${CHANNEL_TILE*2}; channels < ${CHANNEL_TILE*10}; channels += ${CHANNEL_TILE}) {
88 for (size_t pixels = 1; pixels <= ${PIXEL_TILE * 5}; pixels += ${max(1, PIXEL_TILE - 1)}) {
89 IBilinearMicrokernelTester()
90 .pixels(pixels)
91 .channels(channels)
XNNPACK Teamcb2b6672020-10-23 19:30:50 -070092 .TestCHW(${TEST_FUNC});
XNNPACK Team6be46b22020-10-22 23:34:54 -070093 }
94 }
95 }
96
XNNPACK Team965272b2020-10-23 21:10:15 -070097TEST(${TEST_NAME}, channels_eq_1) {
98 $if ISA_CHECK:
99 ${ISA_CHECK};
100 for (size_t pixels = 1; pixels <= ${PIXEL_TILE * 5}; pixels += ${max(1, PIXEL_TILE - 1)}) {
101 IBilinearMicrokernelTester()
102 .pixels(pixels)
103 .channels(1)
104 .TestCHW(${TEST_FUNC});
XNNPACK Team6be46b22020-10-22 23:34:54 -0700105 }
XNNPACK Team965272b2020-10-23 21:10:15 -0700106}
XNNPACK Team6be46b22020-10-22 23:34:54 -0700107
XNNPACK Team965272b2020-10-23 21:10:15 -0700108TEST(${TEST_NAME}, channels_gt_1) {
XNNPACK Team6be46b22020-10-22 23:34:54 -0700109 $if ISA_CHECK:
110 ${ISA_CHECK};
111 for (size_t channels = ${CHANNEL_TILE+1}; channels < ${max(CHANNEL_TILE*2, 3)}; channels++) {
112 for (size_t pixels = 1; pixels <= ${PIXEL_TILE * 5}; pixels += ${max(1, PIXEL_TILE - 1)}) {
113 IBilinearMicrokernelTester()
114 .pixels(pixels)
115 .channels(channels)
XNNPACK Teamcb2b6672020-10-23 19:30:50 -0700116 .TestCHW(${TEST_FUNC});
XNNPACK Team6be46b22020-10-22 23:34:54 -0700117 }
118 }
119}
120
121TEST(${TEST_NAME}, input_offset) {
122 $if ISA_CHECK:
123 ${ISA_CHECK};
124 for (size_t pixels = 1; pixels < ${PIXEL_TILE * 5}; pixels += ${max(1, PIXEL_TILE - 1)}) {
125 for (size_t channels = 1; channels <= ${CHANNEL_TILE * 5}; channels += ${max(1, CHANNEL_TILE - 1)}) {
126 IBilinearMicrokernelTester()
127 .pixels(pixels)
128 .channels(channels)
129 .input_offset(${next_prime(CHANNEL_TILE * 5 + 1)})
XNNPACK Teamcb2b6672020-10-23 19:30:50 -0700130 .TestCHW(${TEST_FUNC});
XNNPACK Team6be46b22020-10-22 23:34:54 -0700131 }
132 }
133}
134
135TEST(${TEST_NAME}, input_stride) {
136 $if ISA_CHECK:
137 ${ISA_CHECK};
138 for (size_t pixels = 1; pixels < ${PIXEL_TILE * 5}; pixels += ${max(1, PIXEL_TILE - 1)}) {
139 for (size_t channels = 1; channels <= ${CHANNEL_TILE * 5}; channels += ${max(1, CHANNEL_TILE - 1)}) {
140 IBilinearMicrokernelTester()
141 .pixels(pixels)
142 .channels(channels)
143 .input_stride(${next_prime(4 * (PIXEL_TILE * 5) + 1)})
XNNPACK Teamcb2b6672020-10-23 19:30:50 -0700144 .TestCHW(${TEST_FUNC});
XNNPACK Team6be46b22020-10-22 23:34:54 -0700145 }
146 }
147}
148
149"""
150
151
152def generate_test_cases(ukernel, channel_tile, pixel_tile, isa):
153 """Generates all tests cases for a BILINEAR micro-kernel.
154
155 Args:
156 ukernel: C name of the micro-kernel function.
157 channel_tile: Number of channels processed per one iteration of the inner
158 loop of the micro-kernel.
159 pixel_tile: Number of pixels processed per one iteration of the outer loop
160 of the micro-kernel.
161 isa: instruction set required to run the micro-kernel. Generated unit test
162 will skip execution if the host processor doesn't support this ISA.
163
164 Returns:
165 Code for the test case.
166 """
167 _, test_name = ukernel.split("_", 1)
168 _, datatype, ukernel_type, _ = ukernel.split("_", 3)
169 test_args = [ukernel]
170 return xngen.preprocess(IBILINEAR_TEST_TEMPLATE, {
171 "TEST_NAME": test_name.upper().replace("UKERNEL_", ""),
172 "TEST_FUNC": ukernel,
173 "UKERNEL_TYPE": ukernel_type.upper(),
174 "DATATYPE": datatype,
175 "CHANNEL_TILE": channel_tile,
176 "PIXEL_TILE": pixel_tile,
177 "ISA_CHECK": xnncommon.generate_isa_check_macro(isa),
178 "next_prime": next_prime,
179 })
180
181
182def main(args):
183 options = parser.parse_args(args)
184
185 with codecs.open(options.spec, "r", encoding="utf-8") as spec_file:
186 spec_yaml = yaml.safe_load(spec_file)
187 if not isinstance(spec_yaml, list):
188 raise ValueError("expected a list of micro-kernels in the spec")
189
190 tests = """\
191// Copyright 2020 Google LLC
192//
193// This source code is licensed under the BSD-style license found in the
194// LICENSE file in the root directory of this source tree.
195//
196// Auto-generated file. Do not edit!
197// Specification: {specification}
198// Generator: {generator}
199
200
201#include <gtest/gtest.h>
202
203#include <xnnpack/common.h>
204#include <xnnpack/isa-checks.h>
205
206#include <xnnpack/ibilinear.h>
207#include "ibilinear-microkernel-tester.h"
208""".format(specification=options.spec, generator=sys.argv[0])
209
210 for ukernel_spec in spec_yaml:
211 name = ukernel_spec["name"]
212 channel_tile, pixel_tile, arch, isa = split_ukernel_name(name)
213
214 # specification can override architecture
215 arch = ukernel_spec.get("arch", arch)
216
217 test_case = generate_test_cases(name, channel_tile, pixel_tile, isa)
218 tests += "\n\n" + xnncommon.postprocess_test_case(test_case, arch, isa)
219
220 with codecs.open(options.output, "w", encoding="utf-8") as output_file:
221 output_file.write(tests)
222
223
224if __name__ == "__main__":
225 main(sys.argv[1:])