blob: dd9aa95aebef1f4ad3e8c0635a0c4ab844545fe0 [file] [log] [blame]
Marat Dukhan5b69f8b2020-07-24 15:26:48 -07001// Copyright (c) Facebook, Inc. and its affiliates.
2// All rights reserved.
3//
4// Copyright 2019 Google LLC
5//
6// This source code is licensed under the BSD-style license found in the
7// LICENSE file in the root directory of this source tree.
8
9#include <cmath>
10#include <cstddef>
11#include <cstdlib>
12
13#include <gtest/gtest.h>
14
15#include <xnnpack/common.h>
Marat Dukhan348ed6d2021-08-06 01:19:04 -070016#include <xnnpack/isa-checks.h>
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070017#include <xnnpack/requantization-stubs.h>
18#include "requantization-tester.h"
19
20
21/*
Marat Dukhan06716242021-05-26 15:56:39 -070022 * Round-to-nearest, ties away from zero, scalar implementation using unsigned 32-bit arithmetics.
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070023 */
24
Marat Dukhan06716242021-05-26 15:56:39 -070025TEST(QU8_RNDNA__SCALAR_UNSIGNED32, exact_divide_by_po2) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070026 for (uint32_t s = 1; s < 32; s++) {
27 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -070028 .qmin(std::numeric_limits<uint8_t>::min())
29 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070030 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -070031 .TestExactDivideByPO2(xnn_qu8_requantize_rndna__scalar_unsigned32);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070032 }
33}
34
Marat Dukhan06716242021-05-26 15:56:39 -070035TEST(QU8_RNDNA__SCALAR_UNSIGNED32, exact_divide_by_po2_with_zero_point) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070036 for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
37 for (uint32_t s = 1; s < 32; s++) {
38 RequantizationTester()
39 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -070040 .qmin(std::numeric_limits<uint8_t>::min())
41 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070042 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -070043 .TestExactDivideByPO2(xnn_qu8_requantize_rndna__scalar_unsigned32);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070044 }
45 }
46}
47
Marat Dukhan06716242021-05-26 15:56:39 -070048TEST(QU8_RNDNA__SCALAR_UNSIGNED32, divide_by_po2_with_rounding_up) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070049 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
50 for (uint32_t s = 1; s < 32; s++) {
51 RequantizationTester()
52 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -070053 .qmin(std::numeric_limits<uint8_t>::min())
54 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070055 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -070056 .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_rndna__scalar_unsigned32);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070057 }
58 }
59}
60
Marat Dukhan06716242021-05-26 15:56:39 -070061TEST(QU8_RNDNA__SCALAR_UNSIGNED32, divide_by_po2_with_rounding_down) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070062 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
63 for (uint32_t s = 1; s < 32; s++) {
64 RequantizationTester()
65 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -070066 .qmin(std::numeric_limits<uint8_t>::min())
67 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070068 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -070069 .TestDivideByPO2WithRoundingDown(xnn_qu8_requantize_rndna__scalar_unsigned32);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070070 }
71 }
72}
73
Marat Dukhan06716242021-05-26 15:56:39 -070074TEST(QU8_RNDNA__SCALAR_UNSIGNED32, divide_by_po2_with_rounding_away) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070075 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
76 for (uint32_t s = 1; s < 32; s++) {
77 RequantizationTester()
78 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -070079 .qmin(std::numeric_limits<uint8_t>::min())
80 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070081 .s(s)
Marat Dukhan062bee32021-05-27 20:31:07 -070082 .TestDivideByPO2WithRoundingTiesAway(xnn_qu8_requantize_rndna__scalar_unsigned32);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070083 }
84 }
85}
86
Marat Dukhan06716242021-05-26 15:56:39 -070087TEST(QU8_RNDNA__SCALAR_UNSIGNED32, special_cases) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070088 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -070089 .qmin(std::numeric_limits<uint8_t>::min())
90 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan06716242021-05-26 15:56:39 -070091 .TestSpecialCases(xnn_qu8_requantize_rndna__scalar_unsigned32);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070092}
93
Marat Dukhan06716242021-05-26 15:56:39 -070094TEST(QU8_RNDNA__SCALAR_UNSIGNED32, random_cases) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070095 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -070096 .qmin(std::numeric_limits<uint8_t>::min())
97 .qmax(std::numeric_limits<uint8_t>::max())
98 .zero_point(128)
Marat Dukhan5b69f8b2020-07-24 15:26:48 -070099 .iterations(100)
Marat Dukhan06716242021-05-26 15:56:39 -0700100 .TestRandomCasesRoundToNearestTiesAway(xnn_qu8_requantize_rndna__scalar_unsigned32);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700101}
102
103
104/*
Marat Dukhan06716242021-05-26 15:56:39 -0700105 * Round-to-nearest, ties away from zero, scalar implementation using unsigned 64-bit arithmetics.
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700106 */
107
Marat Dukhan06716242021-05-26 15:56:39 -0700108TEST(QU8_RNDNA__SCALAR_UNSIGNED64, exact_divide_by_po2) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700109 for (uint32_t s = 1; s < 32; s++) {
110 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700111 .qmin(std::numeric_limits<uint8_t>::min())
112 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700113 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700114 .TestExactDivideByPO2(xnn_qu8_requantize_rndna__scalar_unsigned64);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700115 }
116}
117
Marat Dukhan06716242021-05-26 15:56:39 -0700118TEST(QU8_RNDNA__SCALAR_UNSIGNED64, exact_divide_by_po2_with_zero_point) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700119 for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
120 for (uint32_t s = 1; s < 32; s++) {
121 RequantizationTester()
122 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700123 .qmin(std::numeric_limits<uint8_t>::min())
124 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700125 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700126 .TestExactDivideByPO2(xnn_qu8_requantize_rndna__scalar_unsigned64);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700127 }
128 }
129}
130
Marat Dukhan06716242021-05-26 15:56:39 -0700131TEST(QU8_RNDNA__SCALAR_UNSIGNED64, divide_by_po2_with_rounding_up) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700132 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
133 for (uint32_t s = 1; s < 32; s++) {
134 RequantizationTester()
135 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700136 .qmin(std::numeric_limits<uint8_t>::min())
137 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700138 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700139 .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_rndna__scalar_unsigned64);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700140 }
141 }
142}
143
Marat Dukhan06716242021-05-26 15:56:39 -0700144TEST(QU8_RNDNA__SCALAR_UNSIGNED64, divide_by_po2_with_rounding_down) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700145 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
146 for (uint32_t s = 1; s < 32; s++) {
147 RequantizationTester()
148 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700149 .qmin(std::numeric_limits<uint8_t>::min())
150 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700151 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700152 .TestDivideByPO2WithRoundingDown(xnn_qu8_requantize_rndna__scalar_unsigned64);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700153 }
154 }
155}
156
Marat Dukhan06716242021-05-26 15:56:39 -0700157TEST(QU8_RNDNA__SCALAR_UNSIGNED64, divide_by_po2_with_rounding_away) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700158 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
159 for (uint32_t s = 1; s < 32; s++) {
160 RequantizationTester()
161 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700162 .qmin(std::numeric_limits<uint8_t>::min())
163 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700164 .s(s)
Marat Dukhan062bee32021-05-27 20:31:07 -0700165 .TestDivideByPO2WithRoundingTiesAway(xnn_qu8_requantize_rndna__scalar_unsigned64);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700166 }
167 }
168}
169
Marat Dukhan06716242021-05-26 15:56:39 -0700170TEST(QU8_RNDNA__SCALAR_UNSIGNED64, special_cases) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700171 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700172 .qmin(std::numeric_limits<uint8_t>::min())
173 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan06716242021-05-26 15:56:39 -0700174 .TestSpecialCases(xnn_qu8_requantize_rndna__scalar_unsigned64);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700175}
176
Marat Dukhan06716242021-05-26 15:56:39 -0700177TEST(QU8_RNDNA__SCALAR_UNSIGNED64, random_cases) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700178 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700179 .qmin(std::numeric_limits<uint8_t>::min())
180 .qmax(std::numeric_limits<uint8_t>::max())
181 .zero_point(128)
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700182 .iterations(100)
Marat Dukhan06716242021-05-26 15:56:39 -0700183 .TestRandomCasesRoundToNearestTiesAway(xnn_qu8_requantize_rndna__scalar_unsigned64);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700184}
185
186
187/*
Marat Dukhan06716242021-05-26 15:56:39 -0700188 * Round-to-nearest, ties away from zero, scalar implementation using signed 64-bit arithmetics.
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700189 */
190
Marat Dukhan06716242021-05-26 15:56:39 -0700191TEST(QU8_RNDNA__SCALAR_SIGNED64, exact_divide_by_po2) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700192 for (uint32_t s = 1; s < 32; s++) {
193 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700194 .qmin(std::numeric_limits<uint8_t>::min())
195 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700196 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700197 .TestExactDivideByPO2(xnn_qu8_requantize_rndna__scalar_signed64);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700198 }
199}
200
Marat Dukhan06716242021-05-26 15:56:39 -0700201TEST(QU8_RNDNA__SCALAR_SIGNED64, exact_divide_by_po2_with_zero_point) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700202 for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
203 for (uint32_t s = 1; s < 32; s++) {
204 RequantizationTester()
205 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700206 .qmin(std::numeric_limits<uint8_t>::min())
207 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700208 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700209 .TestExactDivideByPO2(xnn_qu8_requantize_rndna__scalar_signed64);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700210 }
211 }
212}
213
Marat Dukhan06716242021-05-26 15:56:39 -0700214TEST(QU8_RNDNA__SCALAR_SIGNED64, divide_by_po2_with_rounding_up) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700215 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
216 for (uint32_t s = 1; s < 32; s++) {
217 RequantizationTester()
218 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700219 .qmin(std::numeric_limits<uint8_t>::min())
220 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700221 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700222 .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_rndna__scalar_signed64);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700223 }
224 }
225}
226
Marat Dukhan06716242021-05-26 15:56:39 -0700227TEST(QU8_RNDNA__SCALAR_SIGNED64, divide_by_po2_with_rounding_down) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700228 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
229 for (uint32_t s = 1; s < 32; s++) {
230 RequantizationTester()
231 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700232 .qmin(std::numeric_limits<uint8_t>::min())
233 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700234 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700235 .TestDivideByPO2WithRoundingDown(xnn_qu8_requantize_rndna__scalar_signed64);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700236 }
237 }
238}
239
Marat Dukhan06716242021-05-26 15:56:39 -0700240TEST(QU8_RNDNA__SCALAR_SIGNED64, divide_by_po2_with_rounding_away) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700241 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
242 for (uint32_t s = 1; s < 32; s++) {
243 RequantizationTester()
244 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700245 .qmin(std::numeric_limits<uint8_t>::min())
246 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700247 .s(s)
Marat Dukhan062bee32021-05-27 20:31:07 -0700248 .TestDivideByPO2WithRoundingTiesAway(xnn_qu8_requantize_rndna__scalar_signed64);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700249 }
250 }
251}
252
Marat Dukhan06716242021-05-26 15:56:39 -0700253TEST(QU8_RNDNA__SCALAR_SIGNED64, special_cases) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700254 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700255 .qmin(std::numeric_limits<uint8_t>::min())
256 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan06716242021-05-26 15:56:39 -0700257 .TestSpecialCases(xnn_qu8_requantize_rndna__scalar_signed64);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700258}
259
Marat Dukhan06716242021-05-26 15:56:39 -0700260TEST(QU8_RNDNA__SCALAR_SIGNED64, random_cases) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700261 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700262 .qmin(std::numeric_limits<uint8_t>::min())
263 .qmax(std::numeric_limits<uint8_t>::max())
264 .zero_point(128)
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700265 .iterations(100)
Marat Dukhan06716242021-05-26 15:56:39 -0700266 .TestRandomCasesRoundToNearestTiesAway(xnn_qu8_requantize_rndna__scalar_signed64);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700267}
268
269
270/*
271 * FP32-based scalar implementation using lrintf function.
272 */
273
274TEST(QU8_FP32__SCALAR_LRINTF, random_cases) {
275 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700276 .qmin(std::numeric_limits<uint8_t>::min())
277 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700278 .iterations(1000)
279 .TestRandomCasesApproximate(xnn_qu8_requantize_fp32__scalar_lrintf);
280}
281
282
283/*
284 * FP32-based scalar implementation using magic trick for FP32->INT32 conversion.
285 */
286
Marat Dukhan2ac722e2022-01-04 01:54:20 -0800287TEST(QU8_FP32__SCALAR_FMAGIC, random_cases) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700288 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700289 .qmin(std::numeric_limits<uint8_t>::min())
290 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700291 .iterations(1000)
Marat Dukhan2ac722e2022-01-04 01:54:20 -0800292 .TestRandomCasesApproximate(xnn_qu8_requantize_fp32__scalar_fmagic);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700293}
294
295
296/*
Marat Dukhan9976cd82021-05-24 23:15:45 -0700297 * GEMMLOWP-equivalent scalar implementation.
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700298 */
299
Marat Dukhan9976cd82021-05-24 23:15:45 -0700300TEST(QU8_GEMMLOWP__SCALAR, exact_divide_by_po2) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700301 for (uint32_t s = 1; s < 32; s++) {
302 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700303 .qmin(std::numeric_limits<uint8_t>::min())
304 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700305 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700306 .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__scalar);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700307 }
308}
309
Marat Dukhan9976cd82021-05-24 23:15:45 -0700310TEST(QU8_GEMMLOWP__SCALAR, exact_divide_by_po2_with_zero_point) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700311 for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
312 for (uint32_t s = 1; s < 32; s++) {
313 RequantizationTester()
314 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700315 .qmin(std::numeric_limits<uint8_t>::min())
316 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700317 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700318 .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__scalar);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700319 }
320 }
321}
322
Marat Dukhan9976cd82021-05-24 23:15:45 -0700323TEST(QU8_GEMMLOWP__SCALAR, divide_by_po2_with_rounding_up) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700324 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
325 for (uint32_t s = 1; s < 32; s++) {
326 RequantizationTester()
327 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700328 .qmin(std::numeric_limits<uint8_t>::min())
329 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700330 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700331 .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_gemmlowp__scalar);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700332 }
333 }
334}
335
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700336/* No rounding down test - it fails because of upward bias in multiplication */
337/* No rounding away test - it fails because of upward bias in multiplication */
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700338
Marat Dukhan9976cd82021-05-24 23:15:45 -0700339TEST(QU8_GEMMLOWP__SCALAR, special_cases) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700340 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700341 .qmin(std::numeric_limits<uint8_t>::min())
342 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan9976cd82021-05-24 23:15:45 -0700343 .TestSpecialCases(xnn_qu8_requantize_gemmlowp__scalar);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700344}
345
Marat Dukhan9976cd82021-05-24 23:15:45 -0700346TEST(QU8_GEMMLOWP__SCALAR, random_cases) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700347 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700348 .qmin(std::numeric_limits<uint8_t>::min())
349 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700350 .iterations(100)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700351 .TestRandomCasesApproximate(xnn_qu8_requantize_gemmlowp__scalar);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700352}
353
354
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700355#if XNN_ARCH_X86 || XNN_ARCH_X86_64
356 /*
Marat Dukhan06716242021-05-26 15:56:39 -0700357 * Round-to-nearest, ties away from zero, SSE2 implementation using floating-point shuffle.
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700358 */
359
Marat Dukhan06716242021-05-26 15:56:39 -0700360 TEST(QU8_RNDNA__SSE2, exact_divide_by_po2) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700361 for (uint32_t s = 1; s < 32; s++) {
362 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700363 .qmin(std::numeric_limits<uint8_t>::min())
364 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700365 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700366 .TestExactDivideByPO2(xnn_qu8_requantize_rndna__sse2);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700367 }
368 }
369
Marat Dukhan06716242021-05-26 15:56:39 -0700370 TEST(QU8_RNDNA__SSE2, exact_divide_by_po2_with_zero_point) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700371 for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
372 for (uint32_t s = 1; s < 32; s++) {
373 RequantizationTester()
374 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700375 .qmin(std::numeric_limits<uint8_t>::min())
376 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700377 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700378 .TestExactDivideByPO2(xnn_qu8_requantize_rndna__sse2);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700379 }
380 }
381 }
382
Marat Dukhan06716242021-05-26 15:56:39 -0700383 TEST(QU8_RNDNA__SSE2, divide_by_po2_with_rounding_up) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700384 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
385 for (uint32_t s = 1; s < 32; s++) {
386 RequantizationTester()
387 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700388 .qmin(std::numeric_limits<uint8_t>::min())
389 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700390 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700391 .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_rndna__sse2);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700392 }
393 }
394 }
395
Marat Dukhan06716242021-05-26 15:56:39 -0700396 TEST(QU8_RNDNA__SSE2, divide_by_po2_with_rounding_down) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700397 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
398 for (uint32_t s = 1; s < 32; s++) {
399 RequantizationTester()
400 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700401 .qmin(std::numeric_limits<uint8_t>::min())
402 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700403 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700404 .TestDivideByPO2WithRoundingDown(xnn_qu8_requantize_rndna__sse2);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700405 }
406 }
407 }
408
Marat Dukhan06716242021-05-26 15:56:39 -0700409 TEST(QU8_RNDNA__SSE2, divide_by_po2_with_rounding_away) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700410 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
411 for (uint32_t s = 1; s < 32; s++) {
412 RequantizationTester()
413 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700414 .qmin(std::numeric_limits<uint8_t>::min())
415 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700416 .s(s)
Marat Dukhan062bee32021-05-27 20:31:07 -0700417 .TestDivideByPO2WithRoundingTiesAway(xnn_qu8_requantize_rndna__sse2);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700418 }
419 }
420 }
421
Marat Dukhan06716242021-05-26 15:56:39 -0700422 TEST(QU8_RNDNA__SSE2, special_cases) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700423 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700424 .qmin(std::numeric_limits<uint8_t>::min())
425 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan06716242021-05-26 15:56:39 -0700426 .TestSpecialCases(xnn_qu8_requantize_rndna__sse2);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700427 }
428
Marat Dukhan06716242021-05-26 15:56:39 -0700429 TEST(QU8_RNDNA__SSE2, random_cases) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700430 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700431 .qmin(std::numeric_limits<uint8_t>::min())
432 .qmax(std::numeric_limits<uint8_t>::max())
433 .zero_point(128)
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700434 .iterations(100)
Marat Dukhan06716242021-05-26 15:56:39 -0700435 .TestRandomCasesRoundToNearestTiesAway(xnn_qu8_requantize_rndna__sse2);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700436 }
437
438
439 /*
Marat Dukhan06716242021-05-26 15:56:39 -0700440 * Round-to-nearest, ties away from zero, SSSE3 implementation using floating-point shuffle.
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700441 */
442
Marat Dukhan06716242021-05-26 15:56:39 -0700443 TEST(QU8_RNDNA__SSSE3, exact_divide_by_po2) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700444 TEST_REQUIRES_X86_SSSE3;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700445 for (uint32_t s = 1; s < 32; s++) {
446 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700447 .qmin(std::numeric_limits<uint8_t>::min())
448 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700449 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700450 .TestExactDivideByPO2(xnn_qu8_requantize_rndna__ssse3);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700451 }
452 }
453
Marat Dukhan06716242021-05-26 15:56:39 -0700454 TEST(QU8_RNDNA__SSSE3, exact_divide_by_po2_with_zero_point) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700455 TEST_REQUIRES_X86_SSSE3;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700456 for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
457 for (uint32_t s = 1; s < 32; s++) {
458 RequantizationTester()
459 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700460 .qmin(std::numeric_limits<uint8_t>::min())
461 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700462 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700463 .TestExactDivideByPO2(xnn_qu8_requantize_rndna__ssse3);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700464 }
465 }
466 }
467
Marat Dukhan06716242021-05-26 15:56:39 -0700468 TEST(QU8_RNDNA__SSSE3, divide_by_po2_with_rounding_up) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700469 TEST_REQUIRES_X86_SSSE3;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700470 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
471 for (uint32_t s = 1; s < 32; s++) {
472 RequantizationTester()
473 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700474 .qmin(std::numeric_limits<uint8_t>::min())
475 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700476 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700477 .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_rndna__ssse3);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700478 }
479 }
480 }
481
Marat Dukhan06716242021-05-26 15:56:39 -0700482 TEST(QU8_RNDNA__SSSE3, divide_by_po2_with_rounding_down) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700483 TEST_REQUIRES_X86_SSSE3;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700484 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
485 for (uint32_t s = 1; s < 32; s++) {
486 RequantizationTester()
487 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700488 .qmin(std::numeric_limits<uint8_t>::min())
489 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700490 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700491 .TestDivideByPO2WithRoundingDown(xnn_qu8_requantize_rndna__ssse3);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700492 }
493 }
494 }
495
Marat Dukhan06716242021-05-26 15:56:39 -0700496 TEST(QU8_RNDNA__SSSE3, divide_by_po2_with_rounding_away) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700497 TEST_REQUIRES_X86_SSSE3;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700498 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
499 for (uint32_t s = 1; s < 32; s++) {
500 RequantizationTester()
501 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700502 .qmin(std::numeric_limits<uint8_t>::min())
503 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700504 .s(s)
Marat Dukhan062bee32021-05-27 20:31:07 -0700505 .TestDivideByPO2WithRoundingTiesAway(xnn_qu8_requantize_rndna__ssse3);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700506 }
507 }
508 }
509
Marat Dukhan06716242021-05-26 15:56:39 -0700510 TEST(QU8_RNDNA__SSSE3, special_cases) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700511 TEST_REQUIRES_X86_SSSE3;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700512 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700513 .qmin(std::numeric_limits<uint8_t>::min())
514 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan06716242021-05-26 15:56:39 -0700515 .TestSpecialCases(xnn_qu8_requantize_rndna__ssse3);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700516 }
517
Marat Dukhan06716242021-05-26 15:56:39 -0700518 TEST(QU8_RNDNA__SSSE3, random_cases) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700519 TEST_REQUIRES_X86_SSSE3;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700520 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700521 .qmin(std::numeric_limits<uint8_t>::min())
522 .qmax(std::numeric_limits<uint8_t>::max())
523 .zero_point(128)
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700524 .iterations(100)
Marat Dukhan06716242021-05-26 15:56:39 -0700525 .TestRandomCasesRoundToNearestTiesAway(xnn_qu8_requantize_rndna__ssse3);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700526 }
527
528
529 /*
Marat Dukhan06716242021-05-26 15:56:39 -0700530 * Round-to-nearest, ties away from zero, SSE4.1 implementation using static blend instruction.
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700531 */
532
Marat Dukhan06716242021-05-26 15:56:39 -0700533 TEST(QU8_RNDNA__SSE4, exact_divide_by_po2) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700534 TEST_REQUIRES_X86_SSE41;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700535 for (uint32_t s = 1; s < 32; s++) {
536 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700537 .qmin(std::numeric_limits<uint8_t>::min())
538 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700539 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700540 .TestExactDivideByPO2(xnn_qu8_requantize_rndna__sse4);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700541 }
542 }
543
Marat Dukhan06716242021-05-26 15:56:39 -0700544 TEST(QU8_RNDNA__SSE4, exact_divide_by_po2_with_zero_point) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700545 TEST_REQUIRES_X86_SSE41;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700546 for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
547 for (uint32_t s = 1; s < 32; s++) {
548 RequantizationTester()
549 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700550 .qmin(std::numeric_limits<uint8_t>::min())
551 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700552 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700553 .TestExactDivideByPO2(xnn_qu8_requantize_rndna__sse4);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700554 }
555 }
556 }
557
Marat Dukhan06716242021-05-26 15:56:39 -0700558 TEST(QU8_RNDNA__SSE4, divide_by_po2_with_rounding_up) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700559 TEST_REQUIRES_X86_SSE41;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700560 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
561 for (uint32_t s = 1; s < 32; s++) {
562 RequantizationTester()
563 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700564 .qmin(std::numeric_limits<uint8_t>::min())
565 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700566 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700567 .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_rndna__sse4);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700568 }
569 }
570 }
571
Marat Dukhan06716242021-05-26 15:56:39 -0700572 TEST(QU8_RNDNA__SSE4, divide_by_po2_with_rounding_down) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700573 TEST_REQUIRES_X86_SSE41;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700574 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
575 for (uint32_t s = 1; s < 32; s++) {
576 RequantizationTester()
577 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700578 .qmin(std::numeric_limits<uint8_t>::min())
579 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700580 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700581 .TestDivideByPO2WithRoundingDown(xnn_qu8_requantize_rndna__sse4);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700582 }
583 }
584 }
585
Marat Dukhan06716242021-05-26 15:56:39 -0700586 TEST(QU8_RNDNA__SSE4, divide_by_po2_with_rounding_away) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700587 TEST_REQUIRES_X86_SSE41;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700588 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
589 for (uint32_t s = 1; s < 32; s++) {
590 RequantizationTester()
591 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700592 .qmin(std::numeric_limits<uint8_t>::min())
593 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700594 .s(s)
Marat Dukhan062bee32021-05-27 20:31:07 -0700595 .TestDivideByPO2WithRoundingTiesAway(xnn_qu8_requantize_rndna__sse4);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700596 }
597 }
598 }
599
Marat Dukhan06716242021-05-26 15:56:39 -0700600 TEST(QU8_RNDNA__SSE4, special_cases) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700601 TEST_REQUIRES_X86_SSE41;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700602 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700603 .qmin(std::numeric_limits<uint8_t>::min())
604 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan06716242021-05-26 15:56:39 -0700605 .TestSpecialCases(xnn_qu8_requantize_rndna__sse4);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700606 }
607
Marat Dukhan06716242021-05-26 15:56:39 -0700608 TEST(QU8_RNDNA__SSE4, random_cases) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700609 TEST_REQUIRES_X86_SSE41;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700610 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700611 .qmin(std::numeric_limits<uint8_t>::min())
612 .qmax(std::numeric_limits<uint8_t>::max())
613 .zero_point(128)
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700614 .iterations(100)
Marat Dukhan06716242021-05-26 15:56:39 -0700615 .TestRandomCasesRoundToNearestTiesAway(xnn_qu8_requantize_rndna__sse4);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700616 }
617
618
619 /*
620 * FP32-based x86 SSE2 implementation.
621 */
622
623 TEST(QU8_FP32__SSE2, random_cases) {
624 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700625 .qmin(std::numeric_limits<uint8_t>::min())
626 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700627 .iterations(1000)
628 .TestRandomCasesApproximate(xnn_qu8_requantize_fp32__sse2);
629 }
630
631
632 /*
Marat Dukhan9976cd82021-05-24 23:15:45 -0700633 * GEMMLOWP-equivalent x86 SSE2 implementation.
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700634 */
635
Marat Dukhan9976cd82021-05-24 23:15:45 -0700636 TEST(QU8_GEMMLOWP__SSE2, exact_divide_by_po2) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700637 for (uint32_t s = 1; s < 32; s++) {
638 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700639 .qmin(std::numeric_limits<uint8_t>::min())
640 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700641 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700642 .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__sse2);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700643 }
644 }
645
Marat Dukhan9976cd82021-05-24 23:15:45 -0700646 TEST(QU8_GEMMLOWP__SSE2, exact_divide_by_po2_with_zero_point) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700647 for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
648 for (uint32_t s = 1; s < 32; s++) {
649 RequantizationTester()
650 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700651 .qmin(std::numeric_limits<uint8_t>::min())
652 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700653 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700654 .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__sse2);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700655 }
656 }
657 }
658
Marat Dukhan9976cd82021-05-24 23:15:45 -0700659 TEST(QU8_GEMMLOWP__SSE2, divide_by_po2_with_rounding_up) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700660 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
661 for (uint32_t s = 1; s < 32; s++) {
662 RequantizationTester()
663 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700664 .qmin(std::numeric_limits<uint8_t>::min())
665 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700666 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700667 .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_gemmlowp__sse2);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700668 }
669 }
670 }
671
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700672 /* No rounding down test - it fails because of upward bias in multiplication */
673 /* No rounding away test - it fails because of upward bias in multiplication */
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700674
Marat Dukhan9976cd82021-05-24 23:15:45 -0700675 TEST(QU8_GEMMLOWP__SSE2, special_cases) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700676 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700677 .qmin(std::numeric_limits<uint8_t>::min())
678 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan9976cd82021-05-24 23:15:45 -0700679 .TestSpecialCases(xnn_qu8_requantize_gemmlowp__sse2);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700680 }
681
Marat Dukhan9976cd82021-05-24 23:15:45 -0700682 TEST(QU8_GEMMLOWP__SSE2, random_cases) {
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700683 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700684 .qmin(std::numeric_limits<uint8_t>::min())
685 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700686 .iterations(100)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700687 .TestRandomCasesApproximate(xnn_qu8_requantize_gemmlowp__sse2);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700688 }
689
690
691 /*
Marat Dukhan9976cd82021-05-24 23:15:45 -0700692 * GEMMLOWP-equivalent x86 SSSE3 implementation.
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700693 */
694
Marat Dukhan9976cd82021-05-24 23:15:45 -0700695 TEST(QU8_GEMMLOWP__SSSE3, exact_divide_by_po2) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700696 TEST_REQUIRES_X86_SSSE3;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700697 for (uint32_t s = 1; s < 32; s++) {
698 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700699 .qmin(std::numeric_limits<uint8_t>::min())
700 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700701 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700702 .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__ssse3);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700703 }
704 }
705
Marat Dukhan9976cd82021-05-24 23:15:45 -0700706 TEST(QU8_GEMMLOWP__SSSE3, exact_divide_by_po2_with_zero_point) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700707 TEST_REQUIRES_X86_SSSE3;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700708 for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
709 for (uint32_t s = 1; s < 32; s++) {
710 RequantizationTester()
711 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700712 .qmin(std::numeric_limits<uint8_t>::min())
713 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700714 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700715 .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__ssse3);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700716 }
717 }
718 }
719
Marat Dukhan9976cd82021-05-24 23:15:45 -0700720 TEST(QU8_GEMMLOWP__SSSE3, divide_by_po2_with_rounding_up) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700721 TEST_REQUIRES_X86_SSSE3;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700722 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
723 for (uint32_t s = 1; s < 32; s++) {
724 RequantizationTester()
725 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700726 .qmin(std::numeric_limits<uint8_t>::min())
727 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700728 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700729 .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_gemmlowp__ssse3);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700730 }
731 }
732 }
733
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700734 /* No rounding down test - it fails because of upward bias in multiplication */
735 /* No rounding away test - it fails because of upward bias in multiplication */
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700736
Marat Dukhan9976cd82021-05-24 23:15:45 -0700737 TEST(QU8_GEMMLOWP__SSSE3, special_cases) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700738 TEST_REQUIRES_X86_SSSE3;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700739 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700740 .qmin(std::numeric_limits<uint8_t>::min())
741 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan9976cd82021-05-24 23:15:45 -0700742 .TestSpecialCases(xnn_qu8_requantize_gemmlowp__ssse3);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700743 }
744
Marat Dukhan9976cd82021-05-24 23:15:45 -0700745 TEST(QU8_GEMMLOWP__SSSE3, random_cases) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700746 TEST_REQUIRES_X86_SSSE3;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700747 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700748 .qmin(std::numeric_limits<uint8_t>::min())
749 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700750 .iterations(100)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700751 .TestRandomCasesApproximate(xnn_qu8_requantize_gemmlowp__ssse3);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700752 }
753
754
755 /*
Marat Dukhan9976cd82021-05-24 23:15:45 -0700756 * GEMMLOWP-equivalent x86 SSE4 implementation.
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700757 */
758
Marat Dukhan9976cd82021-05-24 23:15:45 -0700759 TEST(QU8_GEMMLOWP__SSE4, exact_divide_by_po2) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700760 TEST_REQUIRES_X86_SSE41;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700761 for (uint32_t s = 1; s < 32; s++) {
762 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700763 .qmin(std::numeric_limits<uint8_t>::min())
764 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700765 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700766 .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__sse4);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700767 }
768 }
769
Marat Dukhan9976cd82021-05-24 23:15:45 -0700770 TEST(QU8_GEMMLOWP__SSE4, exact_divide_by_po2_with_zero_point) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700771 TEST_REQUIRES_X86_SSE41;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700772 for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
773 for (uint32_t s = 1; s < 32; s++) {
774 RequantizationTester()
775 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700776 .qmin(std::numeric_limits<uint8_t>::min())
777 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700778 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700779 .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__sse4);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700780 }
781 }
782 }
783
Marat Dukhan9976cd82021-05-24 23:15:45 -0700784 TEST(QU8_GEMMLOWP__SSE4, divide_by_po2_with_rounding_up) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700785 TEST_REQUIRES_X86_SSE41;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700786 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
787 for (uint32_t s = 1; s < 32; s++) {
788 RequantizationTester()
789 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700790 .qmin(std::numeric_limits<uint8_t>::min())
791 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700792 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700793 .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_gemmlowp__sse4);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700794 }
795 }
796 }
797
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700798 /* No rounding down test - it fails because of upward bias in multiplication */
799 /* No rounding away test - it fails because of upward bias in multiplication */
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700800
Marat Dukhan9976cd82021-05-24 23:15:45 -0700801 TEST(QU8_GEMMLOWP__SSE4, special_cases) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700802 TEST_REQUIRES_X86_SSE41;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700803 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700804 .qmin(std::numeric_limits<uint8_t>::min())
805 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan9976cd82021-05-24 23:15:45 -0700806 .TestSpecialCases(xnn_qu8_requantize_gemmlowp__sse4);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700807 }
808
Marat Dukhan9976cd82021-05-24 23:15:45 -0700809 TEST(QU8_GEMMLOWP__SSE4, random_cases) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700810 TEST_REQUIRES_X86_SSE41;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700811 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700812 .qmin(std::numeric_limits<uint8_t>::min())
813 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700814 .iterations(100)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700815 .TestRandomCasesApproximate(xnn_qu8_requantize_gemmlowp__sse4);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700816 }
817#endif // XNN_ARCH_X86 || XNN_ARCH_X86_64
818
819#if XNN_ARCH_ARM || XNN_ARCH_ARM64
820 /*
Marat Dukhan06716242021-05-26 15:56:39 -0700821 * Round-to-nearest, ties away from zero, ARM NEON implementation.
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700822 */
823
Marat Dukhan06716242021-05-26 15:56:39 -0700824 TEST(QU8_RNDNA__NEON, exact_divide_by_po2) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700825 TEST_REQUIRES_ARM_NEON;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700826 for (uint32_t s = 1; s < 32; s++) {
827 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700828 .qmin(std::numeric_limits<uint8_t>::min())
829 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700830 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700831 .TestExactDivideByPO2(xnn_qu8_requantize_rndna__neon);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700832 }
833 }
834
Marat Dukhan06716242021-05-26 15:56:39 -0700835 TEST(QU8_RNDNA__NEON, exact_divide_by_po2_with_zero_point) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700836 TEST_REQUIRES_ARM_NEON;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700837 for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
838 for (uint32_t s = 1; s < 32; s++) {
839 RequantizationTester()
840 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700841 .qmin(std::numeric_limits<uint8_t>::min())
842 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700843 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700844 .TestExactDivideByPO2(xnn_qu8_requantize_rndna__neon);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700845 }
846 }
847 }
848
Marat Dukhan06716242021-05-26 15:56:39 -0700849 TEST(QU8_RNDNA__NEON, divide_by_po2_with_rounding_up) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700850 TEST_REQUIRES_ARM_NEON;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700851 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
852 for (uint32_t s = 1; s < 32; s++) {
853 RequantizationTester()
854 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700855 .qmin(std::numeric_limits<uint8_t>::min())
856 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700857 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700858 .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_rndna__neon);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700859 }
860 }
861 }
862
Marat Dukhan06716242021-05-26 15:56:39 -0700863 TEST(QU8_RNDNA__NEON, divide_by_po2_with_rounding_down) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700864 TEST_REQUIRES_ARM_NEON;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700865 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
866 for (uint32_t s = 1; s < 32; s++) {
867 RequantizationTester()
868 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700869 .qmin(std::numeric_limits<uint8_t>::min())
870 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700871 .s(s)
Marat Dukhan06716242021-05-26 15:56:39 -0700872 .TestDivideByPO2WithRoundingDown(xnn_qu8_requantize_rndna__neon);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700873 }
874 }
875 }
876
Marat Dukhan06716242021-05-26 15:56:39 -0700877 TEST(QU8_RNDNA__NEON, divide_by_po2_with_rounding_away) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700878 TEST_REQUIRES_ARM_NEON;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700879 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
880 for (uint32_t s = 1; s < 32; s++) {
881 RequantizationTester()
882 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700883 .qmin(std::numeric_limits<uint8_t>::min())
884 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700885 .s(s)
Marat Dukhan062bee32021-05-27 20:31:07 -0700886 .TestDivideByPO2WithRoundingTiesAway(xnn_qu8_requantize_rndna__neon);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700887 }
888 }
889 }
890
Marat Dukhan06716242021-05-26 15:56:39 -0700891 TEST(QU8_RNDNA__NEON, special_cases) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700892 TEST_REQUIRES_ARM_NEON;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700893 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700894 .qmin(std::numeric_limits<uint8_t>::min())
895 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan06716242021-05-26 15:56:39 -0700896 .TestSpecialCases(xnn_qu8_requantize_rndna__neon);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700897 }
898
Marat Dukhan06716242021-05-26 15:56:39 -0700899 TEST(QU8_RNDNA__NEON, random_cases) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700900 TEST_REQUIRES_ARM_NEON;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700901 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700902 .qmin(std::numeric_limits<uint8_t>::min())
903 .qmax(std::numeric_limits<uint8_t>::max())
904 .zero_point(128)
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700905 .iterations(100)
Marat Dukhan06716242021-05-26 15:56:39 -0700906 .TestRandomCasesRoundToNearestTiesAway(xnn_qu8_requantize_rndna__neon);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700907 }
908
909
910 /*
911 * FP32-based ARM NEON implementation.
912 */
913
914 TEST(QU8_FP32__NEON, random_cases) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700915 TEST_REQUIRES_ARM_NEON;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700916 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700917 .qmin(std::numeric_limits<uint8_t>::min())
918 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700919 .iterations(1000)
920 .TestRandomCasesApproximate(xnn_qu8_requantize_fp32__neon);
921 }
922
923
924 /*
Marat Dukhan9976cd82021-05-24 23:15:45 -0700925 * GEMMLOWP-equivalent ARM NEON implementation.
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700926 */
927
Marat Dukhan9976cd82021-05-24 23:15:45 -0700928 TEST(QU8_GEMMLOWP__NEON, exact_divide_by_po2) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700929 TEST_REQUIRES_ARM_NEON;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700930 for (uint32_t s = 1; s < 32; s++) {
931 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700932 .qmin(std::numeric_limits<uint8_t>::min())
933 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700934 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700935 .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__neon);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700936 }
937 }
938
Marat Dukhan9976cd82021-05-24 23:15:45 -0700939 TEST(QU8_GEMMLOWP__NEON, exact_divide_by_po2_with_zero_point) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700940 TEST_REQUIRES_ARM_NEON;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700941 for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
942 for (uint32_t s = 1; s < 32; s++) {
943 RequantizationTester()
944 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700945 .qmin(std::numeric_limits<uint8_t>::min())
946 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700947 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700948 .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__neon);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700949 }
950 }
951 }
952
Marat Dukhan9976cd82021-05-24 23:15:45 -0700953 TEST(QU8_GEMMLOWP__NEON, divide_by_po2_with_rounding_up) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700954 TEST_REQUIRES_ARM_NEON;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700955 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
956 for (uint32_t s = 1; s < 32; s++) {
957 RequantizationTester()
958 .zero_point(zero_point)
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700959 .qmin(std::numeric_limits<uint8_t>::min())
960 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700961 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700962 .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_gemmlowp__neon);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700963 }
964 }
965 }
966
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700967 /* No rounding down test - it fails because of upward bias in multiplication */
968 /* No rounding away test - it fails because of upward bias in multiplication */
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700969
Marat Dukhan9976cd82021-05-24 23:15:45 -0700970 TEST(QU8_GEMMLOWP__NEON, special_cases) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700971 TEST_REQUIRES_ARM_NEON;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700972 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700973 .qmin(std::numeric_limits<uint8_t>::min())
974 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan9976cd82021-05-24 23:15:45 -0700975 .TestSpecialCases(xnn_qu8_requantize_gemmlowp__neon);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700976 }
977
Marat Dukhan9976cd82021-05-24 23:15:45 -0700978 TEST(QU8_GEMMLOWP__NEON, random_cases) {
Marat Dukhan348ed6d2021-08-06 01:19:04 -0700979 TEST_REQUIRES_ARM_NEON;
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700980 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700981 .qmin(std::numeric_limits<uint8_t>::min())
982 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700983 .iterations(100)
Marat Dukhan9976cd82021-05-24 23:15:45 -0700984 .TestRandomCasesApproximate(xnn_qu8_requantize_gemmlowp__neon);
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700985 }
986#endif // XNN_ARCH_ARM || XNN_ARCH_ARM64
987
988#if XNN_ARCH_WASMSIMD
989 /*
990 * FP32-based ARM NEON implementation.
991 */
992
993 TEST(QU8_FP32__WASMSIMD, random_cases) {
994 RequantizationTester()
Marat Dukhan2e23d2b2020-07-29 16:01:37 -0700995 .qmin(std::numeric_limits<uint8_t>::min())
996 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan5b69f8b2020-07-24 15:26:48 -0700997 .iterations(1000)
998 .TestRandomCasesApproximate(xnn_qu8_requantize_fp32__wasmsimd);
999 }
Marat Dukhan22de5e72020-08-03 21:53:18 -07001000
1001
1002 /*
Marat Dukhan9976cd82021-05-24 23:15:45 -07001003 * GEMMLOWP-equivalent WAsmd SIMD implementation.
Marat Dukhan22de5e72020-08-03 21:53:18 -07001004 */
1005
Marat Dukhan9976cd82021-05-24 23:15:45 -07001006 TEST(QU8_GEMMLOWP__WASMSIMD, exact_divide_by_po2) {
Marat Dukhan22de5e72020-08-03 21:53:18 -07001007 for (uint32_t s = 1; s < 32; s++) {
1008 RequantizationTester()
1009 .qmin(std::numeric_limits<uint8_t>::min())
1010 .qmax(std::numeric_limits<uint8_t>::max())
1011 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -07001012 .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__wasmsimd);
Marat Dukhan22de5e72020-08-03 21:53:18 -07001013 }
1014 }
1015
Marat Dukhan9976cd82021-05-24 23:15:45 -07001016 TEST(QU8_GEMMLOWP__WASMSIMD, exact_divide_by_po2_with_zero_point) {
Marat Dukhan22de5e72020-08-03 21:53:18 -07001017 for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
1018 for (uint32_t s = 1; s < 32; s++) {
1019 RequantizationTester()
1020 .zero_point(zero_point)
1021 .qmin(std::numeric_limits<uint8_t>::min())
1022 .qmax(std::numeric_limits<uint8_t>::max())
1023 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -07001024 .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__wasmsimd);
Marat Dukhan22de5e72020-08-03 21:53:18 -07001025 }
1026 }
1027 }
1028
Marat Dukhan9976cd82021-05-24 23:15:45 -07001029 TEST(QU8_GEMMLOWP__WASMSIMD, divide_by_po2_with_rounding_up) {
Marat Dukhan22de5e72020-08-03 21:53:18 -07001030 for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
1031 for (uint32_t s = 1; s < 32; s++) {
1032 RequantizationTester()
1033 .zero_point(zero_point)
1034 .qmin(std::numeric_limits<uint8_t>::min())
1035 .qmax(std::numeric_limits<uint8_t>::max())
1036 .s(s)
Marat Dukhan9976cd82021-05-24 23:15:45 -07001037 .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_gemmlowp__wasmsimd);
Marat Dukhan22de5e72020-08-03 21:53:18 -07001038 }
1039 }
1040 }
1041
1042 /* No rounding down test - it fails because of upward bias in multiplication */
1043 /* No rounding away test - it fails because of upward bias in multiplication */
1044
Marat Dukhan9976cd82021-05-24 23:15:45 -07001045 TEST(QU8_GEMMLOWP__WASMSIMD, special_cases) {
Marat Dukhan22de5e72020-08-03 21:53:18 -07001046 RequantizationTester()
1047 .qmin(std::numeric_limits<uint8_t>::min())
1048 .qmax(std::numeric_limits<uint8_t>::max())
Marat Dukhan9976cd82021-05-24 23:15:45 -07001049 .TestSpecialCases(xnn_qu8_requantize_gemmlowp__wasmsimd);
Marat Dukhan22de5e72020-08-03 21:53:18 -07001050 }
1051
Marat Dukhan9976cd82021-05-24 23:15:45 -07001052 TEST(QU8_GEMMLOWP__WASMSIMD, random_cases) {
Marat Dukhan22de5e72020-08-03 21:53:18 -07001053 RequantizationTester()
1054 .qmin(std::numeric_limits<uint8_t>::min())
1055 .qmax(std::numeric_limits<uint8_t>::max())
1056 .iterations(100)
Marat Dukhan9976cd82021-05-24 23:15:45 -07001057 .TestRandomCasesApproximate(xnn_qu8_requantize_gemmlowp__wasmsimd);
Marat Dukhan22de5e72020-08-03 21:53:18 -07001058 }
Marat Dukhan5b69f8b2020-07-24 15:26:48 -07001059#endif // XNN_ARCH_WASMSIMD