1*4bdc9457SAndroid Build Coastguard Worker // Copyright 2021 Google LLC 2*4bdc9457SAndroid Build Coastguard Worker // 3*4bdc9457SAndroid Build Coastguard Worker // This source code is licensed under the BSD-style license found in the 4*4bdc9457SAndroid Build Coastguard Worker // LICENSE file in the root directory of this source tree. 5*4bdc9457SAndroid Build Coastguard Worker 6*4bdc9457SAndroid Build Coastguard Worker #pragma once 7*4bdc9457SAndroid Build Coastguard Worker 8*4bdc9457SAndroid Build Coastguard Worker #include <gtest/gtest.h> 9*4bdc9457SAndroid Build Coastguard Worker 10*4bdc9457SAndroid Build Coastguard Worker #include <algorithm> 11*4bdc9457SAndroid Build Coastguard Worker #include <cassert> 12*4bdc9457SAndroid Build Coastguard Worker #include <cstddef> 13*4bdc9457SAndroid Build Coastguard Worker #include <cstdlib> 14*4bdc9457SAndroid Build Coastguard Worker #include <functional> 15*4bdc9457SAndroid Build Coastguard Worker #include <limits> 16*4bdc9457SAndroid Build Coastguard Worker #include <random> 17*4bdc9457SAndroid Build Coastguard Worker #include <vector> 18*4bdc9457SAndroid Build Coastguard Worker 19*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack.h> 20*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/microfnptr.h> 21*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/microparams-init.h> 22*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/requantization.h> 23*4bdc9457SAndroid Build Coastguard Worker 24*4bdc9457SAndroid Build Coastguard Worker 25*4bdc9457SAndroid Build Coastguard Worker class VMulCMicrokernelTester { 26*4bdc9457SAndroid Build Coastguard Worker public: batch_size(size_t batch_size)27*4bdc9457SAndroid Build Coastguard Worker inline VMulCMicrokernelTester& batch_size(size_t batch_size) { 28*4bdc9457SAndroid Build Coastguard Worker assert(batch_size != 0); 29*4bdc9457SAndroid Build Coastguard Worker this->batch_size_ = batch_size; 30*4bdc9457SAndroid Build Coastguard Worker return *this; 31*4bdc9457SAndroid Build Coastguard Worker } 32*4bdc9457SAndroid Build Coastguard Worker batch_size()33*4bdc9457SAndroid Build Coastguard Worker inline size_t batch_size() const { 34*4bdc9457SAndroid Build Coastguard Worker return this->batch_size_; 35*4bdc9457SAndroid Build Coastguard Worker } 36*4bdc9457SAndroid Build Coastguard Worker inplace(bool inplace)37*4bdc9457SAndroid Build Coastguard Worker inline VMulCMicrokernelTester& inplace(bool inplace) { 38*4bdc9457SAndroid Build Coastguard Worker this->inplace_ = inplace; 39*4bdc9457SAndroid Build Coastguard Worker return *this; 40*4bdc9457SAndroid Build Coastguard Worker } 41*4bdc9457SAndroid Build Coastguard Worker inplace()42*4bdc9457SAndroid Build Coastguard Worker inline bool inplace() const { 43*4bdc9457SAndroid Build Coastguard Worker return this->inplace_; 44*4bdc9457SAndroid Build Coastguard Worker } 45*4bdc9457SAndroid Build Coastguard Worker a_scale(float a_scale)46*4bdc9457SAndroid Build Coastguard Worker inline VMulCMicrokernelTester& a_scale(float a_scale) { 47*4bdc9457SAndroid Build Coastguard Worker assert(a_scale > 0.0f); 48*4bdc9457SAndroid Build Coastguard Worker assert(std::isnormal(a_scale)); 49*4bdc9457SAndroid Build Coastguard Worker this->a_scale_ = a_scale; 50*4bdc9457SAndroid Build Coastguard Worker return *this; 51*4bdc9457SAndroid Build Coastguard Worker } 52*4bdc9457SAndroid Build Coastguard Worker a_scale()53*4bdc9457SAndroid Build Coastguard Worker inline float a_scale() const { 54*4bdc9457SAndroid Build Coastguard Worker return this->a_scale_; 55*4bdc9457SAndroid Build Coastguard Worker } 56*4bdc9457SAndroid Build Coastguard Worker a_zero_point(uint8_t a_zero_point)57*4bdc9457SAndroid Build Coastguard Worker inline VMulCMicrokernelTester& a_zero_point(uint8_t a_zero_point) { 58*4bdc9457SAndroid Build Coastguard Worker this->a_zero_point_ = a_zero_point; 59*4bdc9457SAndroid Build Coastguard Worker return *this; 60*4bdc9457SAndroid Build Coastguard Worker } 61*4bdc9457SAndroid Build Coastguard Worker a_zero_point()62*4bdc9457SAndroid Build Coastguard Worker inline uint8_t a_zero_point() const { 63*4bdc9457SAndroid Build Coastguard Worker return this->a_zero_point_; 64*4bdc9457SAndroid Build Coastguard Worker } 65*4bdc9457SAndroid Build Coastguard Worker b_scale(float b_scale)66*4bdc9457SAndroid Build Coastguard Worker inline VMulCMicrokernelTester& b_scale(float b_scale) { 67*4bdc9457SAndroid Build Coastguard Worker assert(b_scale > 0.0f); 68*4bdc9457SAndroid Build Coastguard Worker assert(std::isnormal(b_scale)); 69*4bdc9457SAndroid Build Coastguard Worker this->b_scale_ = b_scale; 70*4bdc9457SAndroid Build Coastguard Worker return *this; 71*4bdc9457SAndroid Build Coastguard Worker } 72*4bdc9457SAndroid Build Coastguard Worker b_scale()73*4bdc9457SAndroid Build Coastguard Worker inline float b_scale() const { 74*4bdc9457SAndroid Build Coastguard Worker return this->b_scale_; 75*4bdc9457SAndroid Build Coastguard Worker } 76*4bdc9457SAndroid Build Coastguard Worker b_zero_point(uint8_t b_zero_point)77*4bdc9457SAndroid Build Coastguard Worker inline VMulCMicrokernelTester& b_zero_point(uint8_t b_zero_point) { 78*4bdc9457SAndroid Build Coastguard Worker this->b_zero_point_ = b_zero_point; 79*4bdc9457SAndroid Build Coastguard Worker return *this; 80*4bdc9457SAndroid Build Coastguard Worker } 81*4bdc9457SAndroid Build Coastguard Worker b_zero_point()82*4bdc9457SAndroid Build Coastguard Worker inline uint8_t b_zero_point() const { 83*4bdc9457SAndroid Build Coastguard Worker return this->b_zero_point_; 84*4bdc9457SAndroid Build Coastguard Worker } 85*4bdc9457SAndroid Build Coastguard Worker y_scale(float y_scale)86*4bdc9457SAndroid Build Coastguard Worker inline VMulCMicrokernelTester& y_scale(float y_scale) { 87*4bdc9457SAndroid Build Coastguard Worker assert(y_scale > 0.0f); 88*4bdc9457SAndroid Build Coastguard Worker assert(std::isnormal(y_scale)); 89*4bdc9457SAndroid Build Coastguard Worker this->y_scale_ = y_scale; 90*4bdc9457SAndroid Build Coastguard Worker return *this; 91*4bdc9457SAndroid Build Coastguard Worker } 92*4bdc9457SAndroid Build Coastguard Worker y_scale()93*4bdc9457SAndroid Build Coastguard Worker inline float y_scale() const { 94*4bdc9457SAndroid Build Coastguard Worker return this->y_scale_; 95*4bdc9457SAndroid Build Coastguard Worker } 96*4bdc9457SAndroid Build Coastguard Worker y_zero_point(uint8_t y_zero_point)97*4bdc9457SAndroid Build Coastguard Worker inline VMulCMicrokernelTester& y_zero_point(uint8_t y_zero_point) { 98*4bdc9457SAndroid Build Coastguard Worker this->y_zero_point_ = y_zero_point; 99*4bdc9457SAndroid Build Coastguard Worker return *this; 100*4bdc9457SAndroid Build Coastguard Worker } 101*4bdc9457SAndroid Build Coastguard Worker y_zero_point()102*4bdc9457SAndroid Build Coastguard Worker inline uint8_t y_zero_point() const { 103*4bdc9457SAndroid Build Coastguard Worker return this->y_zero_point_; 104*4bdc9457SAndroid Build Coastguard Worker } 105*4bdc9457SAndroid Build Coastguard Worker qmin(uint8_t qmin)106*4bdc9457SAndroid Build Coastguard Worker inline VMulCMicrokernelTester& qmin(uint8_t qmin) { 107*4bdc9457SAndroid Build Coastguard Worker this->qmin_ = qmin; 108*4bdc9457SAndroid Build Coastguard Worker return *this; 109*4bdc9457SAndroid Build Coastguard Worker } 110*4bdc9457SAndroid Build Coastguard Worker qmin()111*4bdc9457SAndroid Build Coastguard Worker inline uint8_t qmin() const { 112*4bdc9457SAndroid Build Coastguard Worker return this->qmin_; 113*4bdc9457SAndroid Build Coastguard Worker } 114*4bdc9457SAndroid Build Coastguard Worker qmax(uint8_t qmax)115*4bdc9457SAndroid Build Coastguard Worker inline VMulCMicrokernelTester& qmax(uint8_t qmax) { 116*4bdc9457SAndroid Build Coastguard Worker this->qmax_ = qmax; 117*4bdc9457SAndroid Build Coastguard Worker return *this; 118*4bdc9457SAndroid Build Coastguard Worker } 119*4bdc9457SAndroid Build Coastguard Worker qmax()120*4bdc9457SAndroid Build Coastguard Worker inline uint8_t qmax() const { 121*4bdc9457SAndroid Build Coastguard Worker return this->qmax_; 122*4bdc9457SAndroid Build Coastguard Worker } 123*4bdc9457SAndroid Build Coastguard Worker iterations(size_t iterations)124*4bdc9457SAndroid Build Coastguard Worker inline VMulCMicrokernelTester& iterations(size_t iterations) { 125*4bdc9457SAndroid Build Coastguard Worker this->iterations_ = iterations; 126*4bdc9457SAndroid Build Coastguard Worker return *this; 127*4bdc9457SAndroid Build Coastguard Worker } 128*4bdc9457SAndroid Build Coastguard Worker iterations()129*4bdc9457SAndroid Build Coastguard Worker inline size_t iterations() const { 130*4bdc9457SAndroid Build Coastguard Worker return this->iterations_; 131*4bdc9457SAndroid Build Coastguard Worker } 132*4bdc9457SAndroid Build Coastguard Worker Test(xnn_qu8_vmul_minmax_ukernel_function vmul_minmax,xnn_init_qu8_mul_minmax_params_fn init_params,xnn_qu8_requantize_fn requantize)133*4bdc9457SAndroid Build Coastguard Worker void Test( 134*4bdc9457SAndroid Build Coastguard Worker xnn_qu8_vmul_minmax_ukernel_function vmul_minmax, 135*4bdc9457SAndroid Build Coastguard Worker xnn_init_qu8_mul_minmax_params_fn init_params, 136*4bdc9457SAndroid Build Coastguard Worker xnn_qu8_requantize_fn requantize) const 137*4bdc9457SAndroid Build Coastguard Worker { 138*4bdc9457SAndroid Build Coastguard Worker std::random_device random_device; 139*4bdc9457SAndroid Build Coastguard Worker auto rng = std::mt19937(random_device()); 140*4bdc9457SAndroid Build Coastguard Worker auto u8rng = std::bind(std::uniform_int_distribution<uint32_t>(0, std::numeric_limits<uint8_t>::max()), rng); 141*4bdc9457SAndroid Build Coastguard Worker 142*4bdc9457SAndroid Build Coastguard Worker std::vector<uint8_t> a(batch_size() + XNN_EXTRA_BYTES / sizeof(uint8_t)); 143*4bdc9457SAndroid Build Coastguard Worker std::vector<uint8_t> y(batch_size() + (inplace() ? XNN_EXTRA_BYTES / sizeof(uint8_t) : 0)); 144*4bdc9457SAndroid Build Coastguard Worker std::vector<float> y_fp(batch_size()); 145*4bdc9457SAndroid Build Coastguard Worker std::vector<uint8_t> y_ref(batch_size()); 146*4bdc9457SAndroid Build Coastguard Worker for (size_t iteration = 0; iteration < iterations(); iteration++) { 147*4bdc9457SAndroid Build Coastguard Worker std::generate(a.begin(), a.end(), std::ref(u8rng)); 148*4bdc9457SAndroid Build Coastguard Worker const uint8_t b = u8rng(); 149*4bdc9457SAndroid Build Coastguard Worker if (inplace()) { 150*4bdc9457SAndroid Build Coastguard Worker std::generate(y.begin(), y.end(), std::ref(u8rng)); 151*4bdc9457SAndroid Build Coastguard Worker } else { 152*4bdc9457SAndroid Build Coastguard Worker std::fill(y.begin(), y.end(), 0xA5); 153*4bdc9457SAndroid Build Coastguard Worker } 154*4bdc9457SAndroid Build Coastguard Worker const uint8_t* a_data = inplace() ? y.data() : a.data(); 155*4bdc9457SAndroid Build Coastguard Worker 156*4bdc9457SAndroid Build Coastguard Worker // Prepare parameters. 157*4bdc9457SAndroid Build Coastguard Worker const float product_scale = a_scale() * b_scale(); 158*4bdc9457SAndroid Build Coastguard Worker const float product_output_scale = product_scale / y_scale(); 159*4bdc9457SAndroid Build Coastguard Worker xnn_qu8_mul_minmax_params quantization_params; 160*4bdc9457SAndroid Build Coastguard Worker init_params( 161*4bdc9457SAndroid Build Coastguard Worker &quantization_params, 162*4bdc9457SAndroid Build Coastguard Worker a_zero_point(), b_zero_point(), y_zero_point(), 163*4bdc9457SAndroid Build Coastguard Worker product_output_scale, qmin(), qmax()); 164*4bdc9457SAndroid Build Coastguard Worker 165*4bdc9457SAndroid Build Coastguard Worker // Compute reference results. 166*4bdc9457SAndroid Build Coastguard Worker for (size_t i = 0; i < batch_size(); i++) { 167*4bdc9457SAndroid Build Coastguard Worker const int32_t acc = 168*4bdc9457SAndroid Build Coastguard Worker (int32_t(a_data[i]) - int32_t(a_zero_point())) * (int32_t(b) - int32_t(b_zero_point())); 169*4bdc9457SAndroid Build Coastguard Worker y_fp[i] = float(y_zero_point()) + product_output_scale * float(acc); 170*4bdc9457SAndroid Build Coastguard Worker y_fp[i] = std::min<float>(y_fp[i], float(int32_t(qmax()))); 171*4bdc9457SAndroid Build Coastguard Worker y_fp[i] = std::max<float>(y_fp[i], float(int32_t(qmin()))); 172*4bdc9457SAndroid Build Coastguard Worker y_ref[i] = requantize( 173*4bdc9457SAndroid Build Coastguard Worker acc, product_output_scale, y_zero_point(), qmin(), qmax()); 174*4bdc9457SAndroid Build Coastguard Worker } 175*4bdc9457SAndroid Build Coastguard Worker 176*4bdc9457SAndroid Build Coastguard Worker // Call optimized micro-kernel. 177*4bdc9457SAndroid Build Coastguard Worker vmul_minmax(batch_size(), a_data, &b, y.data(), &quantization_params); 178*4bdc9457SAndroid Build Coastguard Worker 179*4bdc9457SAndroid Build Coastguard Worker // Verify results. 180*4bdc9457SAndroid Build Coastguard Worker for (size_t i = 0; i < batch_size(); i++) { 181*4bdc9457SAndroid Build Coastguard Worker ASSERT_LE(uint32_t(y[i]), uint32_t(qmax())) 182*4bdc9457SAndroid Build Coastguard Worker << "at element " << i << " / " << batch_size(); 183*4bdc9457SAndroid Build Coastguard Worker ASSERT_GE(uint32_t(y[i]), uint32_t(qmin())) 184*4bdc9457SAndroid Build Coastguard Worker << "at element " << i << " / " << batch_size(); 185*4bdc9457SAndroid Build Coastguard Worker ASSERT_NEAR(float(int32_t(y[i])), y_fp[i], 0.6f) 186*4bdc9457SAndroid Build Coastguard Worker << "at element " << i << " / " << batch_size(); 187*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(uint32_t(y[i]), uint32_t(y_ref[i])) 188*4bdc9457SAndroid Build Coastguard Worker << "at element " << i << " / " << batch_size(); 189*4bdc9457SAndroid Build Coastguard Worker } 190*4bdc9457SAndroid Build Coastguard Worker } 191*4bdc9457SAndroid Build Coastguard Worker } 192*4bdc9457SAndroid Build Coastguard Worker Test(xnn_qs8_vmul_minmax_ukernel_function vmul_minmax,xnn_init_qs8_mul_minmax_params_fn init_params,xnn_qs8_requantize_fn requantize)193*4bdc9457SAndroid Build Coastguard Worker void Test( 194*4bdc9457SAndroid Build Coastguard Worker xnn_qs8_vmul_minmax_ukernel_function vmul_minmax, 195*4bdc9457SAndroid Build Coastguard Worker xnn_init_qs8_mul_minmax_params_fn init_params, 196*4bdc9457SAndroid Build Coastguard Worker xnn_qs8_requantize_fn requantize) const 197*4bdc9457SAndroid Build Coastguard Worker { 198*4bdc9457SAndroid Build Coastguard Worker std::random_device random_device; 199*4bdc9457SAndroid Build Coastguard Worker auto rng = std::mt19937(random_device()); 200*4bdc9457SAndroid Build Coastguard Worker auto i8rng = std::bind( 201*4bdc9457SAndroid Build Coastguard Worker std::uniform_int_distribution<int32_t>(std::numeric_limits<int8_t>::min(), std::numeric_limits<int8_t>::max()), 202*4bdc9457SAndroid Build Coastguard Worker rng); 203*4bdc9457SAndroid Build Coastguard Worker 204*4bdc9457SAndroid Build Coastguard Worker std::vector<int8_t> a(batch_size() + XNN_EXTRA_BYTES / sizeof(int8_t)); 205*4bdc9457SAndroid Build Coastguard Worker std::vector<int8_t> y(batch_size() + (inplace() ? XNN_EXTRA_BYTES / sizeof(int8_t) : 0)); 206*4bdc9457SAndroid Build Coastguard Worker std::vector<float> y_fp(batch_size()); 207*4bdc9457SAndroid Build Coastguard Worker std::vector<int8_t> y_ref(batch_size()); 208*4bdc9457SAndroid Build Coastguard Worker for (size_t iteration = 0; iteration < iterations(); iteration++) { 209*4bdc9457SAndroid Build Coastguard Worker std::generate(a.begin(), a.end(), std::ref(i8rng)); 210*4bdc9457SAndroid Build Coastguard Worker const int8_t b = i8rng(); 211*4bdc9457SAndroid Build Coastguard Worker if (inplace()) { 212*4bdc9457SAndroid Build Coastguard Worker std::generate(y.begin(), y.end(), std::ref(i8rng)); 213*4bdc9457SAndroid Build Coastguard Worker } else { 214*4bdc9457SAndroid Build Coastguard Worker std::fill(y.begin(), y.end(), 0xA5); 215*4bdc9457SAndroid Build Coastguard Worker } 216*4bdc9457SAndroid Build Coastguard Worker const int8_t* a_data = inplace() ? y.data() : a.data(); 217*4bdc9457SAndroid Build Coastguard Worker 218*4bdc9457SAndroid Build Coastguard Worker // Prepare parameters. 219*4bdc9457SAndroid Build Coastguard Worker const float product_scale = a_scale() * b_scale(); 220*4bdc9457SAndroid Build Coastguard Worker const float product_output_scale = product_scale / y_scale(); 221*4bdc9457SAndroid Build Coastguard Worker EXPECT_GE(product_output_scale, 0x1.0p-32f); 222*4bdc9457SAndroid Build Coastguard Worker xnn_qs8_mul_minmax_params quantization_params; 223*4bdc9457SAndroid Build Coastguard Worker init_params( 224*4bdc9457SAndroid Build Coastguard Worker &quantization_params, 225*4bdc9457SAndroid Build Coastguard Worker int8_t(a_zero_point() - 0x80), int8_t(b_zero_point() - 0x80), int8_t(y_zero_point() - 0x80), 226*4bdc9457SAndroid Build Coastguard Worker product_output_scale, int8_t(qmin() - 0x80), int8_t(qmax() - 0x80)); 227*4bdc9457SAndroid Build Coastguard Worker 228*4bdc9457SAndroid Build Coastguard Worker // Compute reference results. 229*4bdc9457SAndroid Build Coastguard Worker for (size_t i = 0; i < batch_size(); i++) { 230*4bdc9457SAndroid Build Coastguard Worker const int32_t acc = 231*4bdc9457SAndroid Build Coastguard Worker (int32_t(a_data[i]) - int32_t(a_zero_point() - 0x80)) * (int32_t(b) - int32_t(b_zero_point() - 0x80)); 232*4bdc9457SAndroid Build Coastguard Worker y_fp[i] = float(y_zero_point() - 0x80) + product_output_scale * float(acc); 233*4bdc9457SAndroid Build Coastguard Worker y_fp[i] = std::min<float>(y_fp[i], float(int32_t(qmax() - 0x80))); 234*4bdc9457SAndroid Build Coastguard Worker y_fp[i] = std::max<float>(y_fp[i], float(int32_t(qmin() - 0x80))); 235*4bdc9457SAndroid Build Coastguard Worker y_ref[i] = requantize( 236*4bdc9457SAndroid Build Coastguard Worker acc, product_output_scale, int8_t(y_zero_point() - 0x80), int8_t(qmin() - 0x80), int8_t(qmax() - 0x80)); 237*4bdc9457SAndroid Build Coastguard Worker } 238*4bdc9457SAndroid Build Coastguard Worker 239*4bdc9457SAndroid Build Coastguard Worker // Call optimized micro-kernel. 240*4bdc9457SAndroid Build Coastguard Worker vmul_minmax(batch_size(), a_data, &b, y.data(), &quantization_params); 241*4bdc9457SAndroid Build Coastguard Worker 242*4bdc9457SAndroid Build Coastguard Worker // Verify results. 243*4bdc9457SAndroid Build Coastguard Worker for (size_t i = 0; i < batch_size(); i++) { 244*4bdc9457SAndroid Build Coastguard Worker ASSERT_LE(int32_t(y[i]), int32_t(qmax() - 0x80)) 245*4bdc9457SAndroid Build Coastguard Worker << "at element " << i << " / " << batch_size(); 246*4bdc9457SAndroid Build Coastguard Worker ASSERT_GE(int32_t(y[i]), int32_t(qmin() - 0x80)) 247*4bdc9457SAndroid Build Coastguard Worker << "at element " << i << " / " << batch_size(); 248*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(int32_t(y_ref[i]), int32_t(y[i])) 249*4bdc9457SAndroid Build Coastguard Worker << "at element " << i << " / " << batch_size(); 250*4bdc9457SAndroid Build Coastguard Worker ASSERT_NEAR(float(int32_t(y[i])), y_fp[i], 0.6f) 251*4bdc9457SAndroid Build Coastguard Worker << "at element " << i << " / " << batch_size(); 252*4bdc9457SAndroid Build Coastguard Worker } 253*4bdc9457SAndroid Build Coastguard Worker } 254*4bdc9457SAndroid Build Coastguard Worker } 255*4bdc9457SAndroid Build Coastguard Worker 256*4bdc9457SAndroid Build Coastguard Worker private: 257*4bdc9457SAndroid Build Coastguard Worker size_t batch_size_{1}; 258*4bdc9457SAndroid Build Coastguard Worker bool inplace_{false}; 259*4bdc9457SAndroid Build Coastguard Worker float a_scale_{0.75f}; 260*4bdc9457SAndroid Build Coastguard Worker float b_scale_{1.25f}; 261*4bdc9457SAndroid Build Coastguard Worker float y_scale_{0.96875f}; 262*4bdc9457SAndroid Build Coastguard Worker uint8_t a_zero_point_{121}; 263*4bdc9457SAndroid Build Coastguard Worker uint8_t b_zero_point_{127}; 264*4bdc9457SAndroid Build Coastguard Worker uint8_t y_zero_point_{133}; 265*4bdc9457SAndroid Build Coastguard Worker uint8_t qmin_{0}; 266*4bdc9457SAndroid Build Coastguard Worker uint8_t qmax_{255}; 267*4bdc9457SAndroid Build Coastguard Worker size_t iterations_{15}; 268*4bdc9457SAndroid Build Coastguard Worker }; 269