xref: /aosp_15_r20/external/XNNPACK/test/qu8-requantization.cc (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
1*4bdc9457SAndroid Build Coastguard Worker // Copyright (c) Facebook, Inc. and its affiliates.
2*4bdc9457SAndroid Build Coastguard Worker // All rights reserved.
3*4bdc9457SAndroid Build Coastguard Worker //
4*4bdc9457SAndroid Build Coastguard Worker // Copyright 2019 Google LLC
5*4bdc9457SAndroid Build Coastguard Worker //
6*4bdc9457SAndroid Build Coastguard Worker // This source code is licensed under the BSD-style license found in the
7*4bdc9457SAndroid Build Coastguard Worker // LICENSE file in the root directory of this source tree.
8*4bdc9457SAndroid Build Coastguard Worker 
9*4bdc9457SAndroid Build Coastguard Worker #include <cmath>
10*4bdc9457SAndroid Build Coastguard Worker #include <cstddef>
11*4bdc9457SAndroid Build Coastguard Worker #include <cstdlib>
12*4bdc9457SAndroid Build Coastguard Worker 
13*4bdc9457SAndroid Build Coastguard Worker #include <gtest/gtest.h>
14*4bdc9457SAndroid Build Coastguard Worker 
15*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/common.h>
16*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/isa-checks.h>
17*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/requantization-stubs.h>
18*4bdc9457SAndroid Build Coastguard Worker #include "requantization-tester.h"
19*4bdc9457SAndroid Build Coastguard Worker 
20*4bdc9457SAndroid Build Coastguard Worker 
21*4bdc9457SAndroid Build Coastguard Worker /*
22*4bdc9457SAndroid Build Coastguard Worker  * Round-to-nearest, ties away from zero, scalar implementation using unsigned 32-bit arithmetics.
23*4bdc9457SAndroid Build Coastguard Worker  */
24*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_UNSIGNED32,exact_divide_by_po2)25*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_UNSIGNED32, exact_divide_by_po2) {
26*4bdc9457SAndroid Build Coastguard Worker   for (uint32_t s = 1; s < 32; s++) {
27*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
28*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
29*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
30*4bdc9457SAndroid Build Coastguard Worker       .s(s)
31*4bdc9457SAndroid Build Coastguard Worker       .TestExactDivideByPO2(xnn_qu8_requantize_rndna__scalar_unsigned32);
32*4bdc9457SAndroid Build Coastguard Worker   }
33*4bdc9457SAndroid Build Coastguard Worker }
34*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_UNSIGNED32,exact_divide_by_po2_with_zero_point)35*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_UNSIGNED32, exact_divide_by_po2_with_zero_point) {
36*4bdc9457SAndroid Build Coastguard Worker   for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
37*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
38*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
39*4bdc9457SAndroid Build Coastguard Worker         .zero_point(zero_point)
40*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
41*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
42*4bdc9457SAndroid Build Coastguard Worker         .s(s)
43*4bdc9457SAndroid Build Coastguard Worker         .TestExactDivideByPO2(xnn_qu8_requantize_rndna__scalar_unsigned32);
44*4bdc9457SAndroid Build Coastguard Worker     }
45*4bdc9457SAndroid Build Coastguard Worker   }
46*4bdc9457SAndroid Build Coastguard Worker }
47*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_UNSIGNED32,divide_by_po2_with_rounding_up)48*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_UNSIGNED32, divide_by_po2_with_rounding_up) {
49*4bdc9457SAndroid Build Coastguard Worker   for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
50*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
51*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
52*4bdc9457SAndroid Build Coastguard Worker         .zero_point(zero_point)
53*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
54*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
55*4bdc9457SAndroid Build Coastguard Worker         .s(s)
56*4bdc9457SAndroid Build Coastguard Worker         .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_rndna__scalar_unsigned32);
57*4bdc9457SAndroid Build Coastguard Worker     }
58*4bdc9457SAndroid Build Coastguard Worker   }
59*4bdc9457SAndroid Build Coastguard Worker }
60*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_UNSIGNED32,divide_by_po2_with_rounding_down)61*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_UNSIGNED32, divide_by_po2_with_rounding_down) {
62*4bdc9457SAndroid Build Coastguard Worker   for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
63*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
64*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
65*4bdc9457SAndroid Build Coastguard Worker         .zero_point(zero_point)
66*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
67*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
68*4bdc9457SAndroid Build Coastguard Worker         .s(s)
69*4bdc9457SAndroid Build Coastguard Worker         .TestDivideByPO2WithRoundingDown(xnn_qu8_requantize_rndna__scalar_unsigned32);
70*4bdc9457SAndroid Build Coastguard Worker     }
71*4bdc9457SAndroid Build Coastguard Worker   }
72*4bdc9457SAndroid Build Coastguard Worker }
73*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_UNSIGNED32,divide_by_po2_with_rounding_away)74*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_UNSIGNED32, divide_by_po2_with_rounding_away) {
75*4bdc9457SAndroid Build Coastguard Worker   for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
76*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
77*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
78*4bdc9457SAndroid Build Coastguard Worker         .zero_point(zero_point)
79*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
80*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
81*4bdc9457SAndroid Build Coastguard Worker         .s(s)
82*4bdc9457SAndroid Build Coastguard Worker         .TestDivideByPO2WithRoundingTiesAway(xnn_qu8_requantize_rndna__scalar_unsigned32);
83*4bdc9457SAndroid Build Coastguard Worker     }
84*4bdc9457SAndroid Build Coastguard Worker   }
85*4bdc9457SAndroid Build Coastguard Worker }
86*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_UNSIGNED32,special_cases)87*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_UNSIGNED32, special_cases) {
88*4bdc9457SAndroid Build Coastguard Worker   RequantizationTester()
89*4bdc9457SAndroid Build Coastguard Worker     .qmin(std::numeric_limits<uint8_t>::min())
90*4bdc9457SAndroid Build Coastguard Worker     .qmax(std::numeric_limits<uint8_t>::max())
91*4bdc9457SAndroid Build Coastguard Worker     .TestSpecialCases(xnn_qu8_requantize_rndna__scalar_unsigned32);
92*4bdc9457SAndroid Build Coastguard Worker }
93*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_UNSIGNED32,random_cases)94*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_UNSIGNED32, random_cases) {
95*4bdc9457SAndroid Build Coastguard Worker   RequantizationTester()
96*4bdc9457SAndroid Build Coastguard Worker     .qmin(std::numeric_limits<uint8_t>::min())
97*4bdc9457SAndroid Build Coastguard Worker     .qmax(std::numeric_limits<uint8_t>::max())
98*4bdc9457SAndroid Build Coastguard Worker     .zero_point(128)
99*4bdc9457SAndroid Build Coastguard Worker     .iterations(100)
100*4bdc9457SAndroid Build Coastguard Worker     .TestRandomCasesRoundToNearestTiesAway(xnn_qu8_requantize_rndna__scalar_unsigned32);
101*4bdc9457SAndroid Build Coastguard Worker }
102*4bdc9457SAndroid Build Coastguard Worker 
103*4bdc9457SAndroid Build Coastguard Worker 
104*4bdc9457SAndroid Build Coastguard Worker /*
105*4bdc9457SAndroid Build Coastguard Worker  * Round-to-nearest, ties away from zero, scalar implementation using unsigned 64-bit arithmetics.
106*4bdc9457SAndroid Build Coastguard Worker  */
107*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_UNSIGNED64,exact_divide_by_po2)108*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_UNSIGNED64, exact_divide_by_po2) {
109*4bdc9457SAndroid Build Coastguard Worker   for (uint32_t s = 1; s < 32; s++) {
110*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
111*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
112*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
113*4bdc9457SAndroid Build Coastguard Worker       .s(s)
114*4bdc9457SAndroid Build Coastguard Worker       .TestExactDivideByPO2(xnn_qu8_requantize_rndna__scalar_unsigned64);
115*4bdc9457SAndroid Build Coastguard Worker   }
116*4bdc9457SAndroid Build Coastguard Worker }
117*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_UNSIGNED64,exact_divide_by_po2_with_zero_point)118*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_UNSIGNED64, exact_divide_by_po2_with_zero_point) {
119*4bdc9457SAndroid Build Coastguard Worker   for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
120*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
121*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
122*4bdc9457SAndroid Build Coastguard Worker         .zero_point(zero_point)
123*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
124*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
125*4bdc9457SAndroid Build Coastguard Worker         .s(s)
126*4bdc9457SAndroid Build Coastguard Worker         .TestExactDivideByPO2(xnn_qu8_requantize_rndna__scalar_unsigned64);
127*4bdc9457SAndroid Build Coastguard Worker     }
128*4bdc9457SAndroid Build Coastguard Worker   }
129*4bdc9457SAndroid Build Coastguard Worker }
130*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_UNSIGNED64,divide_by_po2_with_rounding_up)131*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_UNSIGNED64, divide_by_po2_with_rounding_up) {
132*4bdc9457SAndroid Build Coastguard Worker   for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
133*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
134*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
135*4bdc9457SAndroid Build Coastguard Worker         .zero_point(zero_point)
136*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
137*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
138*4bdc9457SAndroid Build Coastguard Worker         .s(s)
139*4bdc9457SAndroid Build Coastguard Worker         .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_rndna__scalar_unsigned64);
140*4bdc9457SAndroid Build Coastguard Worker     }
141*4bdc9457SAndroid Build Coastguard Worker   }
142*4bdc9457SAndroid Build Coastguard Worker }
143*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_UNSIGNED64,divide_by_po2_with_rounding_down)144*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_UNSIGNED64, divide_by_po2_with_rounding_down) {
145*4bdc9457SAndroid Build Coastguard Worker   for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
146*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
147*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
148*4bdc9457SAndroid Build Coastguard Worker         .zero_point(zero_point)
149*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
150*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
151*4bdc9457SAndroid Build Coastguard Worker         .s(s)
152*4bdc9457SAndroid Build Coastguard Worker         .TestDivideByPO2WithRoundingDown(xnn_qu8_requantize_rndna__scalar_unsigned64);
153*4bdc9457SAndroid Build Coastguard Worker     }
154*4bdc9457SAndroid Build Coastguard Worker   }
155*4bdc9457SAndroid Build Coastguard Worker }
156*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_UNSIGNED64,divide_by_po2_with_rounding_away)157*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_UNSIGNED64, divide_by_po2_with_rounding_away) {
158*4bdc9457SAndroid Build Coastguard Worker   for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
159*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
160*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
161*4bdc9457SAndroid Build Coastguard Worker         .zero_point(zero_point)
162*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
163*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
164*4bdc9457SAndroid Build Coastguard Worker         .s(s)
165*4bdc9457SAndroid Build Coastguard Worker         .TestDivideByPO2WithRoundingTiesAway(xnn_qu8_requantize_rndna__scalar_unsigned64);
166*4bdc9457SAndroid Build Coastguard Worker     }
167*4bdc9457SAndroid Build Coastguard Worker   }
168*4bdc9457SAndroid Build Coastguard Worker }
169*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_UNSIGNED64,special_cases)170*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_UNSIGNED64, special_cases) {
171*4bdc9457SAndroid Build Coastguard Worker   RequantizationTester()
172*4bdc9457SAndroid Build Coastguard Worker     .qmin(std::numeric_limits<uint8_t>::min())
173*4bdc9457SAndroid Build Coastguard Worker     .qmax(std::numeric_limits<uint8_t>::max())
174*4bdc9457SAndroid Build Coastguard Worker     .TestSpecialCases(xnn_qu8_requantize_rndna__scalar_unsigned64);
175*4bdc9457SAndroid Build Coastguard Worker }
176*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_UNSIGNED64,random_cases)177*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_UNSIGNED64, random_cases) {
178*4bdc9457SAndroid Build Coastguard Worker   RequantizationTester()
179*4bdc9457SAndroid Build Coastguard Worker     .qmin(std::numeric_limits<uint8_t>::min())
180*4bdc9457SAndroid Build Coastguard Worker     .qmax(std::numeric_limits<uint8_t>::max())
181*4bdc9457SAndroid Build Coastguard Worker     .zero_point(128)
182*4bdc9457SAndroid Build Coastguard Worker     .iterations(100)
183*4bdc9457SAndroid Build Coastguard Worker     .TestRandomCasesRoundToNearestTiesAway(xnn_qu8_requantize_rndna__scalar_unsigned64);
184*4bdc9457SAndroid Build Coastguard Worker }
185*4bdc9457SAndroid Build Coastguard Worker 
186*4bdc9457SAndroid Build Coastguard Worker 
187*4bdc9457SAndroid Build Coastguard Worker /*
188*4bdc9457SAndroid Build Coastguard Worker  * Round-to-nearest, ties away from zero, scalar implementation using signed 64-bit arithmetics.
189*4bdc9457SAndroid Build Coastguard Worker  */
190*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_SIGNED64,exact_divide_by_po2)191*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_SIGNED64, exact_divide_by_po2) {
192*4bdc9457SAndroid Build Coastguard Worker   for (uint32_t s = 1; s < 32; s++) {
193*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
194*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
195*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
196*4bdc9457SAndroid Build Coastguard Worker       .s(s)
197*4bdc9457SAndroid Build Coastguard Worker       .TestExactDivideByPO2(xnn_qu8_requantize_rndna__scalar_signed64);
198*4bdc9457SAndroid Build Coastguard Worker   }
199*4bdc9457SAndroid Build Coastguard Worker }
200*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_SIGNED64,exact_divide_by_po2_with_zero_point)201*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_SIGNED64, exact_divide_by_po2_with_zero_point) {
202*4bdc9457SAndroid Build Coastguard Worker   for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
203*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
204*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
205*4bdc9457SAndroid Build Coastguard Worker         .zero_point(zero_point)
206*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
207*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
208*4bdc9457SAndroid Build Coastguard Worker         .s(s)
209*4bdc9457SAndroid Build Coastguard Worker         .TestExactDivideByPO2(xnn_qu8_requantize_rndna__scalar_signed64);
210*4bdc9457SAndroid Build Coastguard Worker     }
211*4bdc9457SAndroid Build Coastguard Worker   }
212*4bdc9457SAndroid Build Coastguard Worker }
213*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_SIGNED64,divide_by_po2_with_rounding_up)214*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_SIGNED64, divide_by_po2_with_rounding_up) {
215*4bdc9457SAndroid Build Coastguard Worker   for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
216*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
217*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
218*4bdc9457SAndroid Build Coastguard Worker         .zero_point(zero_point)
219*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
220*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
221*4bdc9457SAndroid Build Coastguard Worker         .s(s)
222*4bdc9457SAndroid Build Coastguard Worker         .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_rndna__scalar_signed64);
223*4bdc9457SAndroid Build Coastguard Worker     }
224*4bdc9457SAndroid Build Coastguard Worker   }
225*4bdc9457SAndroid Build Coastguard Worker }
226*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_SIGNED64,divide_by_po2_with_rounding_down)227*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_SIGNED64, divide_by_po2_with_rounding_down) {
228*4bdc9457SAndroid Build Coastguard Worker   for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
229*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
230*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
231*4bdc9457SAndroid Build Coastguard Worker         .zero_point(zero_point)
232*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
233*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
234*4bdc9457SAndroid Build Coastguard Worker         .s(s)
235*4bdc9457SAndroid Build Coastguard Worker         .TestDivideByPO2WithRoundingDown(xnn_qu8_requantize_rndna__scalar_signed64);
236*4bdc9457SAndroid Build Coastguard Worker     }
237*4bdc9457SAndroid Build Coastguard Worker   }
238*4bdc9457SAndroid Build Coastguard Worker }
239*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_SIGNED64,divide_by_po2_with_rounding_away)240*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_SIGNED64, divide_by_po2_with_rounding_away) {
241*4bdc9457SAndroid Build Coastguard Worker   for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
242*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
243*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
244*4bdc9457SAndroid Build Coastguard Worker         .zero_point(zero_point)
245*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
246*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
247*4bdc9457SAndroid Build Coastguard Worker         .s(s)
248*4bdc9457SAndroid Build Coastguard Worker         .TestDivideByPO2WithRoundingTiesAway(xnn_qu8_requantize_rndna__scalar_signed64);
249*4bdc9457SAndroid Build Coastguard Worker     }
250*4bdc9457SAndroid Build Coastguard Worker   }
251*4bdc9457SAndroid Build Coastguard Worker }
252*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_SIGNED64,special_cases)253*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_SIGNED64, special_cases) {
254*4bdc9457SAndroid Build Coastguard Worker   RequantizationTester()
255*4bdc9457SAndroid Build Coastguard Worker     .qmin(std::numeric_limits<uint8_t>::min())
256*4bdc9457SAndroid Build Coastguard Worker     .qmax(std::numeric_limits<uint8_t>::max())
257*4bdc9457SAndroid Build Coastguard Worker     .TestSpecialCases(xnn_qu8_requantize_rndna__scalar_signed64);
258*4bdc9457SAndroid Build Coastguard Worker }
259*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SCALAR_SIGNED64,random_cases)260*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_RNDNA__SCALAR_SIGNED64, random_cases) {
261*4bdc9457SAndroid Build Coastguard Worker   RequantizationTester()
262*4bdc9457SAndroid Build Coastguard Worker     .qmin(std::numeric_limits<uint8_t>::min())
263*4bdc9457SAndroid Build Coastguard Worker     .qmax(std::numeric_limits<uint8_t>::max())
264*4bdc9457SAndroid Build Coastguard Worker     .zero_point(128)
265*4bdc9457SAndroid Build Coastguard Worker     .iterations(100)
266*4bdc9457SAndroid Build Coastguard Worker     .TestRandomCasesRoundToNearestTiesAway(xnn_qu8_requantize_rndna__scalar_signed64);
267*4bdc9457SAndroid Build Coastguard Worker }
268*4bdc9457SAndroid Build Coastguard Worker 
269*4bdc9457SAndroid Build Coastguard Worker 
270*4bdc9457SAndroid Build Coastguard Worker /*
271*4bdc9457SAndroid Build Coastguard Worker  * FP32-based scalar implementation using lrintf function.
272*4bdc9457SAndroid Build Coastguard Worker  */
273*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_FP32__SCALAR_LRINTF,random_cases)274*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_FP32__SCALAR_LRINTF, random_cases) {
275*4bdc9457SAndroid Build Coastguard Worker   RequantizationTester()
276*4bdc9457SAndroid Build Coastguard Worker     .qmin(std::numeric_limits<uint8_t>::min())
277*4bdc9457SAndroid Build Coastguard Worker     .qmax(std::numeric_limits<uint8_t>::max())
278*4bdc9457SAndroid Build Coastguard Worker     .iterations(1000)
279*4bdc9457SAndroid Build Coastguard Worker     .TestRandomCasesApproximate(xnn_qu8_requantize_fp32__scalar_lrintf);
280*4bdc9457SAndroid Build Coastguard Worker }
281*4bdc9457SAndroid Build Coastguard Worker 
282*4bdc9457SAndroid Build Coastguard Worker 
283*4bdc9457SAndroid Build Coastguard Worker /*
284*4bdc9457SAndroid Build Coastguard Worker  * FP32-based scalar implementation using magic trick for FP32->INT32 conversion.
285*4bdc9457SAndroid Build Coastguard Worker  */
286*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_FP32__SCALAR_FMAGIC,random_cases)287*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_FP32__SCALAR_FMAGIC, random_cases) {
288*4bdc9457SAndroid Build Coastguard Worker   RequantizationTester()
289*4bdc9457SAndroid Build Coastguard Worker     .qmin(std::numeric_limits<uint8_t>::min())
290*4bdc9457SAndroid Build Coastguard Worker     .qmax(std::numeric_limits<uint8_t>::max())
291*4bdc9457SAndroid Build Coastguard Worker     .iterations(1000)
292*4bdc9457SAndroid Build Coastguard Worker     .TestRandomCasesApproximate(xnn_qu8_requantize_fp32__scalar_fmagic);
293*4bdc9457SAndroid Build Coastguard Worker }
294*4bdc9457SAndroid Build Coastguard Worker 
295*4bdc9457SAndroid Build Coastguard Worker 
296*4bdc9457SAndroid Build Coastguard Worker /*
297*4bdc9457SAndroid Build Coastguard Worker  * GEMMLOWP-equivalent scalar implementation.
298*4bdc9457SAndroid Build Coastguard Worker  */
299*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SCALAR,exact_divide_by_po2)300*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_GEMMLOWP__SCALAR, exact_divide_by_po2) {
301*4bdc9457SAndroid Build Coastguard Worker   for (uint32_t s = 1; s < 32; s++) {
302*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
303*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
304*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
305*4bdc9457SAndroid Build Coastguard Worker       .s(s)
306*4bdc9457SAndroid Build Coastguard Worker       .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__scalar);
307*4bdc9457SAndroid Build Coastguard Worker   }
308*4bdc9457SAndroid Build Coastguard Worker }
309*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SCALAR,exact_divide_by_po2_with_zero_point)310*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_GEMMLOWP__SCALAR, exact_divide_by_po2_with_zero_point) {
311*4bdc9457SAndroid Build Coastguard Worker   for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
312*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
313*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
314*4bdc9457SAndroid Build Coastguard Worker         .zero_point(zero_point)
315*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
316*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
317*4bdc9457SAndroid Build Coastguard Worker         .s(s)
318*4bdc9457SAndroid Build Coastguard Worker         .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__scalar);
319*4bdc9457SAndroid Build Coastguard Worker     }
320*4bdc9457SAndroid Build Coastguard Worker   }
321*4bdc9457SAndroid Build Coastguard Worker }
322*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SCALAR,divide_by_po2_with_rounding_up)323*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_GEMMLOWP__SCALAR, divide_by_po2_with_rounding_up) {
324*4bdc9457SAndroid Build Coastguard Worker   for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
325*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
326*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
327*4bdc9457SAndroid Build Coastguard Worker         .zero_point(zero_point)
328*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
329*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
330*4bdc9457SAndroid Build Coastguard Worker         .s(s)
331*4bdc9457SAndroid Build Coastguard Worker         .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_gemmlowp__scalar);
332*4bdc9457SAndroid Build Coastguard Worker     }
333*4bdc9457SAndroid Build Coastguard Worker   }
334*4bdc9457SAndroid Build Coastguard Worker }
335*4bdc9457SAndroid Build Coastguard Worker 
336*4bdc9457SAndroid Build Coastguard Worker /* No rounding down test - it fails because of upward bias in multiplication */
337*4bdc9457SAndroid Build Coastguard Worker /* No rounding away test - it fails because of upward bias in multiplication */
338*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SCALAR,special_cases)339*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_GEMMLOWP__SCALAR, special_cases) {
340*4bdc9457SAndroid Build Coastguard Worker   RequantizationTester()
341*4bdc9457SAndroid Build Coastguard Worker     .qmin(std::numeric_limits<uint8_t>::min())
342*4bdc9457SAndroid Build Coastguard Worker     .qmax(std::numeric_limits<uint8_t>::max())
343*4bdc9457SAndroid Build Coastguard Worker     .TestSpecialCases(xnn_qu8_requantize_gemmlowp__scalar);
344*4bdc9457SAndroid Build Coastguard Worker }
345*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SCALAR,random_cases)346*4bdc9457SAndroid Build Coastguard Worker TEST(QU8_GEMMLOWP__SCALAR, random_cases) {
347*4bdc9457SAndroid Build Coastguard Worker   RequantizationTester()
348*4bdc9457SAndroid Build Coastguard Worker     .qmin(std::numeric_limits<uint8_t>::min())
349*4bdc9457SAndroid Build Coastguard Worker     .qmax(std::numeric_limits<uint8_t>::max())
350*4bdc9457SAndroid Build Coastguard Worker     .iterations(100)
351*4bdc9457SAndroid Build Coastguard Worker     .TestRandomCasesApproximate(xnn_qu8_requantize_gemmlowp__scalar);
352*4bdc9457SAndroid Build Coastguard Worker }
353*4bdc9457SAndroid Build Coastguard Worker 
354*4bdc9457SAndroid Build Coastguard Worker 
355*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_X86 || XNN_ARCH_X86_64
356*4bdc9457SAndroid Build Coastguard Worker   /*
357*4bdc9457SAndroid Build Coastguard Worker    * Round-to-nearest, ties away from zero, SSE2 implementation using floating-point shuffle.
358*4bdc9457SAndroid Build Coastguard Worker    */
359*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSE2,exact_divide_by_po2)360*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSE2, exact_divide_by_po2) {
361*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
362*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
363*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
364*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
365*4bdc9457SAndroid Build Coastguard Worker         .s(s)
366*4bdc9457SAndroid Build Coastguard Worker         .TestExactDivideByPO2(xnn_qu8_requantize_rndna__sse2);
367*4bdc9457SAndroid Build Coastguard Worker     }
368*4bdc9457SAndroid Build Coastguard Worker   }
369*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSE2,exact_divide_by_po2_with_zero_point)370*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSE2, exact_divide_by_po2_with_zero_point) {
371*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
372*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
373*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
374*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
375*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
376*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
377*4bdc9457SAndroid Build Coastguard Worker           .s(s)
378*4bdc9457SAndroid Build Coastguard Worker           .TestExactDivideByPO2(xnn_qu8_requantize_rndna__sse2);
379*4bdc9457SAndroid Build Coastguard Worker       }
380*4bdc9457SAndroid Build Coastguard Worker     }
381*4bdc9457SAndroid Build Coastguard Worker   }
382*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSE2,divide_by_po2_with_rounding_up)383*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSE2, divide_by_po2_with_rounding_up) {
384*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
385*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
386*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
387*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
388*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
389*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
390*4bdc9457SAndroid Build Coastguard Worker           .s(s)
391*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_rndna__sse2);
392*4bdc9457SAndroid Build Coastguard Worker       }
393*4bdc9457SAndroid Build Coastguard Worker     }
394*4bdc9457SAndroid Build Coastguard Worker   }
395*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSE2,divide_by_po2_with_rounding_down)396*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSE2, divide_by_po2_with_rounding_down) {
397*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
398*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
399*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
400*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
401*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
402*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
403*4bdc9457SAndroid Build Coastguard Worker           .s(s)
404*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingDown(xnn_qu8_requantize_rndna__sse2);
405*4bdc9457SAndroid Build Coastguard Worker       }
406*4bdc9457SAndroid Build Coastguard Worker     }
407*4bdc9457SAndroid Build Coastguard Worker   }
408*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSE2,divide_by_po2_with_rounding_away)409*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSE2, divide_by_po2_with_rounding_away) {
410*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
411*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
412*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
413*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
414*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
415*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
416*4bdc9457SAndroid Build Coastguard Worker           .s(s)
417*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingTiesAway(xnn_qu8_requantize_rndna__sse2);
418*4bdc9457SAndroid Build Coastguard Worker       }
419*4bdc9457SAndroid Build Coastguard Worker     }
420*4bdc9457SAndroid Build Coastguard Worker   }
421*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSE2,special_cases)422*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSE2, special_cases) {
423*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
424*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
425*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
426*4bdc9457SAndroid Build Coastguard Worker       .TestSpecialCases(xnn_qu8_requantize_rndna__sse2);
427*4bdc9457SAndroid Build Coastguard Worker   }
428*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSE2,random_cases)429*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSE2, random_cases) {
430*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
431*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
432*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
433*4bdc9457SAndroid Build Coastguard Worker       .zero_point(128)
434*4bdc9457SAndroid Build Coastguard Worker       .iterations(100)
435*4bdc9457SAndroid Build Coastguard Worker       .TestRandomCasesRoundToNearestTiesAway(xnn_qu8_requantize_rndna__sse2);
436*4bdc9457SAndroid Build Coastguard Worker   }
437*4bdc9457SAndroid Build Coastguard Worker 
438*4bdc9457SAndroid Build Coastguard Worker 
439*4bdc9457SAndroid Build Coastguard Worker   /*
440*4bdc9457SAndroid Build Coastguard Worker    * Round-to-nearest, ties away from zero, SSSE3 implementation using floating-point shuffle.
441*4bdc9457SAndroid Build Coastguard Worker    */
442*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSSE3,exact_divide_by_po2)443*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSSE3, exact_divide_by_po2) {
444*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSSE3;
445*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
446*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
447*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
448*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
449*4bdc9457SAndroid Build Coastguard Worker         .s(s)
450*4bdc9457SAndroid Build Coastguard Worker         .TestExactDivideByPO2(xnn_qu8_requantize_rndna__ssse3);
451*4bdc9457SAndroid Build Coastguard Worker     }
452*4bdc9457SAndroid Build Coastguard Worker   }
453*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSSE3,exact_divide_by_po2_with_zero_point)454*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSSE3, exact_divide_by_po2_with_zero_point) {
455*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSSE3;
456*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
457*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
458*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
459*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
460*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
461*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
462*4bdc9457SAndroid Build Coastguard Worker           .s(s)
463*4bdc9457SAndroid Build Coastguard Worker           .TestExactDivideByPO2(xnn_qu8_requantize_rndna__ssse3);
464*4bdc9457SAndroid Build Coastguard Worker       }
465*4bdc9457SAndroid Build Coastguard Worker     }
466*4bdc9457SAndroid Build Coastguard Worker   }
467*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSSE3,divide_by_po2_with_rounding_up)468*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSSE3, divide_by_po2_with_rounding_up) {
469*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSSE3;
470*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
471*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
472*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
473*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
474*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
475*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
476*4bdc9457SAndroid Build Coastguard Worker           .s(s)
477*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_rndna__ssse3);
478*4bdc9457SAndroid Build Coastguard Worker       }
479*4bdc9457SAndroid Build Coastguard Worker     }
480*4bdc9457SAndroid Build Coastguard Worker   }
481*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSSE3,divide_by_po2_with_rounding_down)482*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSSE3, divide_by_po2_with_rounding_down) {
483*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSSE3;
484*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
485*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
486*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
487*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
488*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
489*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
490*4bdc9457SAndroid Build Coastguard Worker           .s(s)
491*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingDown(xnn_qu8_requantize_rndna__ssse3);
492*4bdc9457SAndroid Build Coastguard Worker       }
493*4bdc9457SAndroid Build Coastguard Worker     }
494*4bdc9457SAndroid Build Coastguard Worker   }
495*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSSE3,divide_by_po2_with_rounding_away)496*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSSE3, divide_by_po2_with_rounding_away) {
497*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSSE3;
498*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
499*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
500*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
501*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
502*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
503*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
504*4bdc9457SAndroid Build Coastguard Worker           .s(s)
505*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingTiesAway(xnn_qu8_requantize_rndna__ssse3);
506*4bdc9457SAndroid Build Coastguard Worker       }
507*4bdc9457SAndroid Build Coastguard Worker     }
508*4bdc9457SAndroid Build Coastguard Worker   }
509*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSSE3,special_cases)510*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSSE3, special_cases) {
511*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSSE3;
512*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
513*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
514*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
515*4bdc9457SAndroid Build Coastguard Worker       .TestSpecialCases(xnn_qu8_requantize_rndna__ssse3);
516*4bdc9457SAndroid Build Coastguard Worker   }
517*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSSE3,random_cases)518*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSSE3, random_cases) {
519*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSSE3;
520*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
521*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
522*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
523*4bdc9457SAndroid Build Coastguard Worker       .zero_point(128)
524*4bdc9457SAndroid Build Coastguard Worker       .iterations(100)
525*4bdc9457SAndroid Build Coastguard Worker       .TestRandomCasesRoundToNearestTiesAway(xnn_qu8_requantize_rndna__ssse3);
526*4bdc9457SAndroid Build Coastguard Worker   }
527*4bdc9457SAndroid Build Coastguard Worker 
528*4bdc9457SAndroid Build Coastguard Worker 
529*4bdc9457SAndroid Build Coastguard Worker   /*
530*4bdc9457SAndroid Build Coastguard Worker    * Round-to-nearest, ties away from zero, SSE4.1 implementation using static blend instruction.
531*4bdc9457SAndroid Build Coastguard Worker    */
532*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSE4,exact_divide_by_po2)533*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSE4, exact_divide_by_po2) {
534*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSE41;
535*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
536*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
537*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
538*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
539*4bdc9457SAndroid Build Coastguard Worker         .s(s)
540*4bdc9457SAndroid Build Coastguard Worker         .TestExactDivideByPO2(xnn_qu8_requantize_rndna__sse4);
541*4bdc9457SAndroid Build Coastguard Worker     }
542*4bdc9457SAndroid Build Coastguard Worker   }
543*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSE4,exact_divide_by_po2_with_zero_point)544*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSE4, exact_divide_by_po2_with_zero_point) {
545*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSE41;
546*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
547*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
548*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
549*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
550*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
551*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
552*4bdc9457SAndroid Build Coastguard Worker           .s(s)
553*4bdc9457SAndroid Build Coastguard Worker           .TestExactDivideByPO2(xnn_qu8_requantize_rndna__sse4);
554*4bdc9457SAndroid Build Coastguard Worker       }
555*4bdc9457SAndroid Build Coastguard Worker     }
556*4bdc9457SAndroid Build Coastguard Worker   }
557*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSE4,divide_by_po2_with_rounding_up)558*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSE4, divide_by_po2_with_rounding_up) {
559*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSE41;
560*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
561*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
562*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
563*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
564*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
565*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
566*4bdc9457SAndroid Build Coastguard Worker           .s(s)
567*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_rndna__sse4);
568*4bdc9457SAndroid Build Coastguard Worker       }
569*4bdc9457SAndroid Build Coastguard Worker     }
570*4bdc9457SAndroid Build Coastguard Worker   }
571*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSE4,divide_by_po2_with_rounding_down)572*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSE4, divide_by_po2_with_rounding_down) {
573*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSE41;
574*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
575*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
576*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
577*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
578*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
579*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
580*4bdc9457SAndroid Build Coastguard Worker           .s(s)
581*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingDown(xnn_qu8_requantize_rndna__sse4);
582*4bdc9457SAndroid Build Coastguard Worker       }
583*4bdc9457SAndroid Build Coastguard Worker     }
584*4bdc9457SAndroid Build Coastguard Worker   }
585*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSE4,divide_by_po2_with_rounding_away)586*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSE4, divide_by_po2_with_rounding_away) {
587*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSE41;
588*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
589*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
590*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
591*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
592*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
593*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
594*4bdc9457SAndroid Build Coastguard Worker           .s(s)
595*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingTiesAway(xnn_qu8_requantize_rndna__sse4);
596*4bdc9457SAndroid Build Coastguard Worker       }
597*4bdc9457SAndroid Build Coastguard Worker     }
598*4bdc9457SAndroid Build Coastguard Worker   }
599*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSE4,special_cases)600*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSE4, special_cases) {
601*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSE41;
602*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
603*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
604*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
605*4bdc9457SAndroid Build Coastguard Worker       .TestSpecialCases(xnn_qu8_requantize_rndna__sse4);
606*4bdc9457SAndroid Build Coastguard Worker   }
607*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__SSE4,random_cases)608*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__SSE4, random_cases) {
609*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSE41;
610*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
611*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
612*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
613*4bdc9457SAndroid Build Coastguard Worker       .zero_point(128)
614*4bdc9457SAndroid Build Coastguard Worker       .iterations(100)
615*4bdc9457SAndroid Build Coastguard Worker       .TestRandomCasesRoundToNearestTiesAway(xnn_qu8_requantize_rndna__sse4);
616*4bdc9457SAndroid Build Coastguard Worker   }
617*4bdc9457SAndroid Build Coastguard Worker 
618*4bdc9457SAndroid Build Coastguard Worker 
619*4bdc9457SAndroid Build Coastguard Worker   /*
620*4bdc9457SAndroid Build Coastguard Worker    * FP32-based x86 SSE2 implementation.
621*4bdc9457SAndroid Build Coastguard Worker    */
622*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_FP32__SSE2,random_cases)623*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_FP32__SSE2, random_cases) {
624*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
625*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
626*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
627*4bdc9457SAndroid Build Coastguard Worker       .iterations(1000)
628*4bdc9457SAndroid Build Coastguard Worker       .TestRandomCasesApproximate(xnn_qu8_requantize_fp32__sse2);
629*4bdc9457SAndroid Build Coastguard Worker   }
630*4bdc9457SAndroid Build Coastguard Worker 
631*4bdc9457SAndroid Build Coastguard Worker 
632*4bdc9457SAndroid Build Coastguard Worker   /*
633*4bdc9457SAndroid Build Coastguard Worker    * GEMMLOWP-equivalent x86 SSE2 implementation.
634*4bdc9457SAndroid Build Coastguard Worker    */
635*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SSE2,exact_divide_by_po2)636*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__SSE2, exact_divide_by_po2) {
637*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
638*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
639*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
640*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
641*4bdc9457SAndroid Build Coastguard Worker         .s(s)
642*4bdc9457SAndroid Build Coastguard Worker         .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__sse2);
643*4bdc9457SAndroid Build Coastguard Worker     }
644*4bdc9457SAndroid Build Coastguard Worker   }
645*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SSE2,exact_divide_by_po2_with_zero_point)646*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__SSE2, exact_divide_by_po2_with_zero_point) {
647*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
648*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
649*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
650*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
651*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
652*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
653*4bdc9457SAndroid Build Coastguard Worker           .s(s)
654*4bdc9457SAndroid Build Coastguard Worker           .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__sse2);
655*4bdc9457SAndroid Build Coastguard Worker       }
656*4bdc9457SAndroid Build Coastguard Worker     }
657*4bdc9457SAndroid Build Coastguard Worker   }
658*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SSE2,divide_by_po2_with_rounding_up)659*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__SSE2, divide_by_po2_with_rounding_up) {
660*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
661*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
662*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
663*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
664*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
665*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
666*4bdc9457SAndroid Build Coastguard Worker           .s(s)
667*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_gemmlowp__sse2);
668*4bdc9457SAndroid Build Coastguard Worker       }
669*4bdc9457SAndroid Build Coastguard Worker     }
670*4bdc9457SAndroid Build Coastguard Worker   }
671*4bdc9457SAndroid Build Coastguard Worker 
672*4bdc9457SAndroid Build Coastguard Worker   /* No rounding down test - it fails because of upward bias in multiplication */
673*4bdc9457SAndroid Build Coastguard Worker   /* No rounding away test - it fails because of upward bias in multiplication */
674*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SSE2,special_cases)675*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__SSE2, special_cases) {
676*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
677*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
678*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
679*4bdc9457SAndroid Build Coastguard Worker       .TestSpecialCases(xnn_qu8_requantize_gemmlowp__sse2);
680*4bdc9457SAndroid Build Coastguard Worker   }
681*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SSE2,random_cases)682*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__SSE2, random_cases) {
683*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
684*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
685*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
686*4bdc9457SAndroid Build Coastguard Worker       .iterations(100)
687*4bdc9457SAndroid Build Coastguard Worker       .TestRandomCasesApproximate(xnn_qu8_requantize_gemmlowp__sse2);
688*4bdc9457SAndroid Build Coastguard Worker   }
689*4bdc9457SAndroid Build Coastguard Worker 
690*4bdc9457SAndroid Build Coastguard Worker 
691*4bdc9457SAndroid Build Coastguard Worker   /*
692*4bdc9457SAndroid Build Coastguard Worker    * GEMMLOWP-equivalent x86 SSSE3 implementation.
693*4bdc9457SAndroid Build Coastguard Worker    */
694*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SSSE3,exact_divide_by_po2)695*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__SSSE3, exact_divide_by_po2) {
696*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSSE3;
697*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
698*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
699*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
700*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
701*4bdc9457SAndroid Build Coastguard Worker         .s(s)
702*4bdc9457SAndroid Build Coastguard Worker         .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__ssse3);
703*4bdc9457SAndroid Build Coastguard Worker     }
704*4bdc9457SAndroid Build Coastguard Worker   }
705*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SSSE3,exact_divide_by_po2_with_zero_point)706*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__SSSE3, exact_divide_by_po2_with_zero_point) {
707*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSSE3;
708*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
709*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
710*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
711*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
712*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
713*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
714*4bdc9457SAndroid Build Coastguard Worker           .s(s)
715*4bdc9457SAndroid Build Coastguard Worker           .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__ssse3);
716*4bdc9457SAndroid Build Coastguard Worker       }
717*4bdc9457SAndroid Build Coastguard Worker     }
718*4bdc9457SAndroid Build Coastguard Worker   }
719*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SSSE3,divide_by_po2_with_rounding_up)720*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__SSSE3, divide_by_po2_with_rounding_up) {
721*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSSE3;
722*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
723*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
724*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
725*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
726*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
727*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
728*4bdc9457SAndroid Build Coastguard Worker           .s(s)
729*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_gemmlowp__ssse3);
730*4bdc9457SAndroid Build Coastguard Worker       }
731*4bdc9457SAndroid Build Coastguard Worker     }
732*4bdc9457SAndroid Build Coastguard Worker   }
733*4bdc9457SAndroid Build Coastguard Worker 
734*4bdc9457SAndroid Build Coastguard Worker   /* No rounding down test - it fails because of upward bias in multiplication */
735*4bdc9457SAndroid Build Coastguard Worker   /* No rounding away test - it fails because of upward bias in multiplication */
736*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SSSE3,special_cases)737*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__SSSE3, special_cases) {
738*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSSE3;
739*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
740*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
741*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
742*4bdc9457SAndroid Build Coastguard Worker       .TestSpecialCases(xnn_qu8_requantize_gemmlowp__ssse3);
743*4bdc9457SAndroid Build Coastguard Worker   }
744*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SSSE3,random_cases)745*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__SSSE3, random_cases) {
746*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSSE3;
747*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
748*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
749*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
750*4bdc9457SAndroid Build Coastguard Worker       .iterations(100)
751*4bdc9457SAndroid Build Coastguard Worker       .TestRandomCasesApproximate(xnn_qu8_requantize_gemmlowp__ssse3);
752*4bdc9457SAndroid Build Coastguard Worker   }
753*4bdc9457SAndroid Build Coastguard Worker 
754*4bdc9457SAndroid Build Coastguard Worker 
755*4bdc9457SAndroid Build Coastguard Worker   /*
756*4bdc9457SAndroid Build Coastguard Worker    * GEMMLOWP-equivalent x86 SSE4 implementation.
757*4bdc9457SAndroid Build Coastguard Worker    */
758*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SSE4,exact_divide_by_po2)759*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__SSE4, exact_divide_by_po2) {
760*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSE41;
761*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
762*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
763*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
764*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
765*4bdc9457SAndroid Build Coastguard Worker         .s(s)
766*4bdc9457SAndroid Build Coastguard Worker         .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__sse4);
767*4bdc9457SAndroid Build Coastguard Worker     }
768*4bdc9457SAndroid Build Coastguard Worker   }
769*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SSE4,exact_divide_by_po2_with_zero_point)770*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__SSE4, exact_divide_by_po2_with_zero_point) {
771*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSE41;
772*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
773*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
774*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
775*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
776*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
777*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
778*4bdc9457SAndroid Build Coastguard Worker           .s(s)
779*4bdc9457SAndroid Build Coastguard Worker           .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__sse4);
780*4bdc9457SAndroid Build Coastguard Worker       }
781*4bdc9457SAndroid Build Coastguard Worker     }
782*4bdc9457SAndroid Build Coastguard Worker   }
783*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SSE4,divide_by_po2_with_rounding_up)784*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__SSE4, divide_by_po2_with_rounding_up) {
785*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSE41;
786*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
787*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
788*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
789*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
790*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
791*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
792*4bdc9457SAndroid Build Coastguard Worker           .s(s)
793*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_gemmlowp__sse4);
794*4bdc9457SAndroid Build Coastguard Worker       }
795*4bdc9457SAndroid Build Coastguard Worker     }
796*4bdc9457SAndroid Build Coastguard Worker   }
797*4bdc9457SAndroid Build Coastguard Worker 
798*4bdc9457SAndroid Build Coastguard Worker   /* No rounding down test - it fails because of upward bias in multiplication */
799*4bdc9457SAndroid Build Coastguard Worker   /* No rounding away test - it fails because of upward bias in multiplication */
800*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SSE4,special_cases)801*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__SSE4, special_cases) {
802*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSE41;
803*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
804*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
805*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
806*4bdc9457SAndroid Build Coastguard Worker       .TestSpecialCases(xnn_qu8_requantize_gemmlowp__sse4);
807*4bdc9457SAndroid Build Coastguard Worker   }
808*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__SSE4,random_cases)809*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__SSE4, random_cases) {
810*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_X86_SSE41;
811*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
812*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
813*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
814*4bdc9457SAndroid Build Coastguard Worker       .iterations(100)
815*4bdc9457SAndroid Build Coastguard Worker       .TestRandomCasesApproximate(xnn_qu8_requantize_gemmlowp__sse4);
816*4bdc9457SAndroid Build Coastguard Worker   }
817*4bdc9457SAndroid Build Coastguard Worker #endif  // XNN_ARCH_X86 || XNN_ARCH_X86_64
818*4bdc9457SAndroid Build Coastguard Worker 
819*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_ARM || XNN_ARCH_ARM64
820*4bdc9457SAndroid Build Coastguard Worker   /*
821*4bdc9457SAndroid Build Coastguard Worker    * Round-to-nearest, ties away from zero, ARM NEON implementation.
822*4bdc9457SAndroid Build Coastguard Worker    */
823*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__NEON,exact_divide_by_po2)824*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__NEON, exact_divide_by_po2) {
825*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_ARM_NEON;
826*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
827*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
828*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
829*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
830*4bdc9457SAndroid Build Coastguard Worker         .s(s)
831*4bdc9457SAndroid Build Coastguard Worker         .TestExactDivideByPO2(xnn_qu8_requantize_rndna__neon);
832*4bdc9457SAndroid Build Coastguard Worker     }
833*4bdc9457SAndroid Build Coastguard Worker   }
834*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__NEON,exact_divide_by_po2_with_zero_point)835*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__NEON, exact_divide_by_po2_with_zero_point) {
836*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_ARM_NEON;
837*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
838*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
839*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
840*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
841*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
842*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
843*4bdc9457SAndroid Build Coastguard Worker           .s(s)
844*4bdc9457SAndroid Build Coastguard Worker           .TestExactDivideByPO2(xnn_qu8_requantize_rndna__neon);
845*4bdc9457SAndroid Build Coastguard Worker       }
846*4bdc9457SAndroid Build Coastguard Worker     }
847*4bdc9457SAndroid Build Coastguard Worker   }
848*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__NEON,divide_by_po2_with_rounding_up)849*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__NEON, divide_by_po2_with_rounding_up) {
850*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_ARM_NEON;
851*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
852*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
853*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
854*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
855*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
856*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
857*4bdc9457SAndroid Build Coastguard Worker           .s(s)
858*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_rndna__neon);
859*4bdc9457SAndroid Build Coastguard Worker       }
860*4bdc9457SAndroid Build Coastguard Worker     }
861*4bdc9457SAndroid Build Coastguard Worker   }
862*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__NEON,divide_by_po2_with_rounding_down)863*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__NEON, divide_by_po2_with_rounding_down) {
864*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_ARM_NEON;
865*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
866*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
867*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
868*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
869*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
870*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
871*4bdc9457SAndroid Build Coastguard Worker           .s(s)
872*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingDown(xnn_qu8_requantize_rndna__neon);
873*4bdc9457SAndroid Build Coastguard Worker       }
874*4bdc9457SAndroid Build Coastguard Worker     }
875*4bdc9457SAndroid Build Coastguard Worker   }
876*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__NEON,divide_by_po2_with_rounding_away)877*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__NEON, divide_by_po2_with_rounding_away) {
878*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_ARM_NEON;
879*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
880*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
881*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
882*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
883*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
884*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
885*4bdc9457SAndroid Build Coastguard Worker           .s(s)
886*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingTiesAway(xnn_qu8_requantize_rndna__neon);
887*4bdc9457SAndroid Build Coastguard Worker       }
888*4bdc9457SAndroid Build Coastguard Worker     }
889*4bdc9457SAndroid Build Coastguard Worker   }
890*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__NEON,special_cases)891*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__NEON, special_cases) {
892*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_ARM_NEON;
893*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
894*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
895*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
896*4bdc9457SAndroid Build Coastguard Worker       .TestSpecialCases(xnn_qu8_requantize_rndna__neon);
897*4bdc9457SAndroid Build Coastguard Worker   }
898*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_RNDNA__NEON,random_cases)899*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_RNDNA__NEON, random_cases) {
900*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_ARM_NEON;
901*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
902*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
903*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
904*4bdc9457SAndroid Build Coastguard Worker       .zero_point(128)
905*4bdc9457SAndroid Build Coastguard Worker       .iterations(100)
906*4bdc9457SAndroid Build Coastguard Worker       .TestRandomCasesRoundToNearestTiesAway(xnn_qu8_requantize_rndna__neon);
907*4bdc9457SAndroid Build Coastguard Worker   }
908*4bdc9457SAndroid Build Coastguard Worker 
909*4bdc9457SAndroid Build Coastguard Worker 
910*4bdc9457SAndroid Build Coastguard Worker   /*
911*4bdc9457SAndroid Build Coastguard Worker    * FP32-based ARM NEON implementation.
912*4bdc9457SAndroid Build Coastguard Worker    */
913*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_FP32__NEON,random_cases)914*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_FP32__NEON, random_cases) {
915*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_ARM_NEON;
916*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
917*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
918*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
919*4bdc9457SAndroid Build Coastguard Worker       .iterations(1000)
920*4bdc9457SAndroid Build Coastguard Worker       .TestRandomCasesApproximate(xnn_qu8_requantize_fp32__neon);
921*4bdc9457SAndroid Build Coastguard Worker   }
922*4bdc9457SAndroid Build Coastguard Worker 
923*4bdc9457SAndroid Build Coastguard Worker 
924*4bdc9457SAndroid Build Coastguard Worker   /*
925*4bdc9457SAndroid Build Coastguard Worker    * GEMMLOWP-equivalent ARM NEON implementation.
926*4bdc9457SAndroid Build Coastguard Worker    */
927*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__NEON,exact_divide_by_po2)928*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__NEON, exact_divide_by_po2) {
929*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_ARM_NEON;
930*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
931*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
932*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
933*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
934*4bdc9457SAndroid Build Coastguard Worker         .s(s)
935*4bdc9457SAndroid Build Coastguard Worker         .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__neon);
936*4bdc9457SAndroid Build Coastguard Worker     }
937*4bdc9457SAndroid Build Coastguard Worker   }
938*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__NEON,exact_divide_by_po2_with_zero_point)939*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__NEON, exact_divide_by_po2_with_zero_point) {
940*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_ARM_NEON;
941*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
942*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
943*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
944*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
945*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
946*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
947*4bdc9457SAndroid Build Coastguard Worker           .s(s)
948*4bdc9457SAndroid Build Coastguard Worker           .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__neon);
949*4bdc9457SAndroid Build Coastguard Worker       }
950*4bdc9457SAndroid Build Coastguard Worker     }
951*4bdc9457SAndroid Build Coastguard Worker   }
952*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__NEON,divide_by_po2_with_rounding_up)953*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__NEON, divide_by_po2_with_rounding_up) {
954*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_ARM_NEON;
955*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
956*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
957*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
958*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
959*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
960*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
961*4bdc9457SAndroid Build Coastguard Worker           .s(s)
962*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_gemmlowp__neon);
963*4bdc9457SAndroid Build Coastguard Worker       }
964*4bdc9457SAndroid Build Coastguard Worker     }
965*4bdc9457SAndroid Build Coastguard Worker   }
966*4bdc9457SAndroid Build Coastguard Worker 
967*4bdc9457SAndroid Build Coastguard Worker   /* No rounding down test - it fails because of upward bias in multiplication */
968*4bdc9457SAndroid Build Coastguard Worker   /* No rounding away test - it fails because of upward bias in multiplication */
969*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__NEON,special_cases)970*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__NEON, special_cases) {
971*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_ARM_NEON;
972*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
973*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
974*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
975*4bdc9457SAndroid Build Coastguard Worker       .TestSpecialCases(xnn_qu8_requantize_gemmlowp__neon);
976*4bdc9457SAndroid Build Coastguard Worker   }
977*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__NEON,random_cases)978*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__NEON, random_cases) {
979*4bdc9457SAndroid Build Coastguard Worker     TEST_REQUIRES_ARM_NEON;
980*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
981*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
982*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
983*4bdc9457SAndroid Build Coastguard Worker       .iterations(100)
984*4bdc9457SAndroid Build Coastguard Worker       .TestRandomCasesApproximate(xnn_qu8_requantize_gemmlowp__neon);
985*4bdc9457SAndroid Build Coastguard Worker   }
986*4bdc9457SAndroid Build Coastguard Worker #endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
987*4bdc9457SAndroid Build Coastguard Worker 
988*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_WASMSIMD
989*4bdc9457SAndroid Build Coastguard Worker   /*
990*4bdc9457SAndroid Build Coastguard Worker    * FP32-based ARM NEON implementation.
991*4bdc9457SAndroid Build Coastguard Worker    */
992*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_FP32__WASMSIMD,random_cases)993*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_FP32__WASMSIMD, random_cases) {
994*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
995*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
996*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
997*4bdc9457SAndroid Build Coastguard Worker       .iterations(1000)
998*4bdc9457SAndroid Build Coastguard Worker       .TestRandomCasesApproximate(xnn_qu8_requantize_fp32__wasmsimd);
999*4bdc9457SAndroid Build Coastguard Worker   }
1000*4bdc9457SAndroid Build Coastguard Worker 
1001*4bdc9457SAndroid Build Coastguard Worker 
1002*4bdc9457SAndroid Build Coastguard Worker   /*
1003*4bdc9457SAndroid Build Coastguard Worker    * GEMMLOWP-equivalent WAsmd SIMD implementation.
1004*4bdc9457SAndroid Build Coastguard Worker    */
1005*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__WASMSIMD,exact_divide_by_po2)1006*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__WASMSIMD, exact_divide_by_po2) {
1007*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t s = 1; s < 32; s++) {
1008*4bdc9457SAndroid Build Coastguard Worker       RequantizationTester()
1009*4bdc9457SAndroid Build Coastguard Worker         .qmin(std::numeric_limits<uint8_t>::min())
1010*4bdc9457SAndroid Build Coastguard Worker         .qmax(std::numeric_limits<uint8_t>::max())
1011*4bdc9457SAndroid Build Coastguard Worker         .s(s)
1012*4bdc9457SAndroid Build Coastguard Worker         .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__wasmsimd);
1013*4bdc9457SAndroid Build Coastguard Worker     }
1014*4bdc9457SAndroid Build Coastguard Worker   }
1015*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__WASMSIMD,exact_divide_by_po2_with_zero_point)1016*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__WASMSIMD, exact_divide_by_po2_with_zero_point) {
1017*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 1; zero_point < 256; zero_point++) {
1018*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
1019*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
1020*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
1021*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
1022*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
1023*4bdc9457SAndroid Build Coastguard Worker           .s(s)
1024*4bdc9457SAndroid Build Coastguard Worker           .TestExactDivideByPO2(xnn_qu8_requantize_gemmlowp__wasmsimd);
1025*4bdc9457SAndroid Build Coastguard Worker       }
1026*4bdc9457SAndroid Build Coastguard Worker     }
1027*4bdc9457SAndroid Build Coastguard Worker   }
1028*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__WASMSIMD,divide_by_po2_with_rounding_up)1029*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__WASMSIMD, divide_by_po2_with_rounding_up) {
1030*4bdc9457SAndroid Build Coastguard Worker     for (int32_t zero_point = 0; zero_point < 256; zero_point++) {
1031*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t s = 1; s < 32; s++) {
1032*4bdc9457SAndroid Build Coastguard Worker         RequantizationTester()
1033*4bdc9457SAndroid Build Coastguard Worker           .zero_point(zero_point)
1034*4bdc9457SAndroid Build Coastguard Worker           .qmin(std::numeric_limits<uint8_t>::min())
1035*4bdc9457SAndroid Build Coastguard Worker           .qmax(std::numeric_limits<uint8_t>::max())
1036*4bdc9457SAndroid Build Coastguard Worker           .s(s)
1037*4bdc9457SAndroid Build Coastguard Worker           .TestDivideByPO2WithRoundingUp(xnn_qu8_requantize_gemmlowp__wasmsimd);
1038*4bdc9457SAndroid Build Coastguard Worker       }
1039*4bdc9457SAndroid Build Coastguard Worker     }
1040*4bdc9457SAndroid Build Coastguard Worker   }
1041*4bdc9457SAndroid Build Coastguard Worker 
1042*4bdc9457SAndroid Build Coastguard Worker   /* No rounding down test - it fails because of upward bias in multiplication */
1043*4bdc9457SAndroid Build Coastguard Worker   /* No rounding away test - it fails because of upward bias in multiplication */
1044*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__WASMSIMD,special_cases)1045*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__WASMSIMD, special_cases) {
1046*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
1047*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
1048*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
1049*4bdc9457SAndroid Build Coastguard Worker       .TestSpecialCases(xnn_qu8_requantize_gemmlowp__wasmsimd);
1050*4bdc9457SAndroid Build Coastguard Worker   }
1051*4bdc9457SAndroid Build Coastguard Worker 
TEST(QU8_GEMMLOWP__WASMSIMD,random_cases)1052*4bdc9457SAndroid Build Coastguard Worker   TEST(QU8_GEMMLOWP__WASMSIMD, random_cases) {
1053*4bdc9457SAndroid Build Coastguard Worker     RequantizationTester()
1054*4bdc9457SAndroid Build Coastguard Worker       .qmin(std::numeric_limits<uint8_t>::min())
1055*4bdc9457SAndroid Build Coastguard Worker       .qmax(std::numeric_limits<uint8_t>::max())
1056*4bdc9457SAndroid Build Coastguard Worker       .iterations(100)
1057*4bdc9457SAndroid Build Coastguard Worker       .TestRandomCasesApproximate(xnn_qu8_requantize_gemmlowp__wasmsimd);
1058*4bdc9457SAndroid Build Coastguard Worker   }
1059*4bdc9457SAndroid Build Coastguard Worker #endif  // XNN_ARCH_WASMSIMD
1060