1*4bdc9457SAndroid Build Coastguard Worker // Copyright 2019 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 <random> 16*4bdc9457SAndroid Build Coastguard Worker #include <vector> 17*4bdc9457SAndroid Build Coastguard Worker 18*4bdc9457SAndroid Build Coastguard Worker #include <fp16.h> 19*4bdc9457SAndroid Build Coastguard Worker 20*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack.h> 21*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/aligned-allocator.h> 22*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/pack.h> 23*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/microfnptr.h> 24*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/microparams-init.h> 25*4bdc9457SAndroid Build Coastguard Worker 26*4bdc9457SAndroid Build Coastguard Worker 27*4bdc9457SAndroid Build Coastguard Worker class VMulCAddCMicrokernelTester { 28*4bdc9457SAndroid Build Coastguard Worker public: channel_tile(size_t channel_tile)29*4bdc9457SAndroid Build Coastguard Worker inline VMulCAddCMicrokernelTester& channel_tile(size_t channel_tile) { 30*4bdc9457SAndroid Build Coastguard Worker this->channel_tile_ = channel_tile; 31*4bdc9457SAndroid Build Coastguard Worker return *this; 32*4bdc9457SAndroid Build Coastguard Worker } 33*4bdc9457SAndroid Build Coastguard Worker channel_tile()34*4bdc9457SAndroid Build Coastguard Worker inline size_t channel_tile() const { 35*4bdc9457SAndroid Build Coastguard Worker return this->channel_tile_; 36*4bdc9457SAndroid Build Coastguard Worker } 37*4bdc9457SAndroid Build Coastguard Worker channels(size_t channels)38*4bdc9457SAndroid Build Coastguard Worker inline VMulCAddCMicrokernelTester& channels(size_t channels) { 39*4bdc9457SAndroid Build Coastguard Worker assert(channels != 0); 40*4bdc9457SAndroid Build Coastguard Worker this->channels_ = channels; 41*4bdc9457SAndroid Build Coastguard Worker return *this; 42*4bdc9457SAndroid Build Coastguard Worker } 43*4bdc9457SAndroid Build Coastguard Worker channels()44*4bdc9457SAndroid Build Coastguard Worker inline size_t channels() const { 45*4bdc9457SAndroid Build Coastguard Worker return this->channels_; 46*4bdc9457SAndroid Build Coastguard Worker } 47*4bdc9457SAndroid Build Coastguard Worker packed_channels()48*4bdc9457SAndroid Build Coastguard Worker inline size_t packed_channels() const { 49*4bdc9457SAndroid Build Coastguard Worker return channels() % channel_tile() == 0 ? channels() : (channels() / channel_tile() + 1) * channel_tile(); 50*4bdc9457SAndroid Build Coastguard Worker } 51*4bdc9457SAndroid Build Coastguard Worker rows(size_t rows)52*4bdc9457SAndroid Build Coastguard Worker inline VMulCAddCMicrokernelTester& rows(size_t rows) { 53*4bdc9457SAndroid Build Coastguard Worker assert(rows != 0); 54*4bdc9457SAndroid Build Coastguard Worker this->rows_ = rows; 55*4bdc9457SAndroid Build Coastguard Worker return *this; 56*4bdc9457SAndroid Build Coastguard Worker } 57*4bdc9457SAndroid Build Coastguard Worker rows()58*4bdc9457SAndroid Build Coastguard Worker inline size_t rows() const { 59*4bdc9457SAndroid Build Coastguard Worker return this->rows_; 60*4bdc9457SAndroid Build Coastguard Worker } 61*4bdc9457SAndroid Build Coastguard Worker input_stride(size_t input_stride)62*4bdc9457SAndroid Build Coastguard Worker inline VMulCAddCMicrokernelTester& input_stride(size_t input_stride) { 63*4bdc9457SAndroid Build Coastguard Worker this->input_stride_ = input_stride; 64*4bdc9457SAndroid Build Coastguard Worker return *this; 65*4bdc9457SAndroid Build Coastguard Worker } 66*4bdc9457SAndroid Build Coastguard Worker input_stride()67*4bdc9457SAndroid Build Coastguard Worker inline size_t input_stride() const { 68*4bdc9457SAndroid Build Coastguard Worker return this->input_stride_ == 0 ? channels() : this->input_stride_; 69*4bdc9457SAndroid Build Coastguard Worker } 70*4bdc9457SAndroid Build Coastguard Worker output_stride(size_t output_stride)71*4bdc9457SAndroid Build Coastguard Worker inline VMulCAddCMicrokernelTester& output_stride(size_t output_stride) { 72*4bdc9457SAndroid Build Coastguard Worker this->output_stride_ = output_stride; 73*4bdc9457SAndroid Build Coastguard Worker return *this; 74*4bdc9457SAndroid Build Coastguard Worker } 75*4bdc9457SAndroid Build Coastguard Worker output_stride()76*4bdc9457SAndroid Build Coastguard Worker inline size_t output_stride() const { 77*4bdc9457SAndroid Build Coastguard Worker return this->output_stride_ == 0 ? channels() : this->output_stride_; 78*4bdc9457SAndroid Build Coastguard Worker } 79*4bdc9457SAndroid Build Coastguard Worker inplace(bool inplace)80*4bdc9457SAndroid Build Coastguard Worker inline VMulCAddCMicrokernelTester& inplace(bool inplace) { 81*4bdc9457SAndroid Build Coastguard Worker this->inplace_ = inplace; 82*4bdc9457SAndroid Build Coastguard Worker return *this; 83*4bdc9457SAndroid Build Coastguard Worker } 84*4bdc9457SAndroid Build Coastguard Worker inplace()85*4bdc9457SAndroid Build Coastguard Worker inline bool inplace() const { 86*4bdc9457SAndroid Build Coastguard Worker return this->inplace_; 87*4bdc9457SAndroid Build Coastguard Worker } 88*4bdc9457SAndroid Build Coastguard Worker qmin(uint8_t qmin)89*4bdc9457SAndroid Build Coastguard Worker inline VMulCAddCMicrokernelTester& qmin(uint8_t qmin) { 90*4bdc9457SAndroid Build Coastguard Worker this->qmin_ = qmin; 91*4bdc9457SAndroid Build Coastguard Worker return *this; 92*4bdc9457SAndroid Build Coastguard Worker } 93*4bdc9457SAndroid Build Coastguard Worker qmin()94*4bdc9457SAndroid Build Coastguard Worker inline uint8_t qmin() const { 95*4bdc9457SAndroid Build Coastguard Worker return this->qmin_; 96*4bdc9457SAndroid Build Coastguard Worker } 97*4bdc9457SAndroid Build Coastguard Worker qmax(uint8_t qmax)98*4bdc9457SAndroid Build Coastguard Worker inline VMulCAddCMicrokernelTester& qmax(uint8_t qmax) { 99*4bdc9457SAndroid Build Coastguard Worker this->qmax_ = qmax; 100*4bdc9457SAndroid Build Coastguard Worker return *this; 101*4bdc9457SAndroid Build Coastguard Worker } 102*4bdc9457SAndroid Build Coastguard Worker qmax()103*4bdc9457SAndroid Build Coastguard Worker inline uint8_t qmax() const { 104*4bdc9457SAndroid Build Coastguard Worker return this->qmax_; 105*4bdc9457SAndroid Build Coastguard Worker } 106*4bdc9457SAndroid Build Coastguard Worker iterations(size_t iterations)107*4bdc9457SAndroid Build Coastguard Worker inline VMulCAddCMicrokernelTester& iterations(size_t iterations) { 108*4bdc9457SAndroid Build Coastguard Worker this->iterations_ = iterations; 109*4bdc9457SAndroid Build Coastguard Worker return *this; 110*4bdc9457SAndroid Build Coastguard Worker } 111*4bdc9457SAndroid Build Coastguard Worker iterations()112*4bdc9457SAndroid Build Coastguard Worker inline size_t iterations() const { 113*4bdc9457SAndroid Build Coastguard Worker return this->iterations_; 114*4bdc9457SAndroid Build Coastguard Worker } 115*4bdc9457SAndroid Build Coastguard Worker Test(xnn_f16_vmulcaddc_ukernel_function vmulcaddc,xnn_init_f16_minmax_params_fn init_params)116*4bdc9457SAndroid Build Coastguard Worker void Test(xnn_f16_vmulcaddc_ukernel_function vmulcaddc, xnn_init_f16_minmax_params_fn init_params) const { 117*4bdc9457SAndroid Build Coastguard Worker std::random_device random_device; 118*4bdc9457SAndroid Build Coastguard Worker auto rng = std::mt19937(random_device()); 119*4bdc9457SAndroid Build Coastguard Worker std::uniform_real_distribution<float> f32dist; 120*4bdc9457SAndroid Build Coastguard Worker 121*4bdc9457SAndroid Build Coastguard Worker if (inplace()) { 122*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(input_stride(), output_stride()); 123*4bdc9457SAndroid Build Coastguard Worker } 124*4bdc9457SAndroid Build Coastguard Worker 125*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t> x((rows() - 1) * input_stride() + channels() + XNN_EXTRA_BYTES / sizeof(uint16_t)); 126*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t> scale(channels()); 127*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t> bias(channels()); 128*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> packed_w(packed_channels() * 2); 129*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t> y((rows() - 1) * output_stride() + channels() + (inplace() ? XNN_EXTRA_BYTES / sizeof(uint16_t) : 0)); 130*4bdc9457SAndroid Build Coastguard Worker std::vector<float> y_ref(rows() * channels()); 131*4bdc9457SAndroid Build Coastguard Worker 132*4bdc9457SAndroid Build Coastguard Worker for (size_t iteration = 0; iteration < iterations(); iteration++) { 133*4bdc9457SAndroid Build Coastguard Worker std::generate(scale.begin(), scale.end(), [&]() { return fp16_ieee_from_fp32_value(f32dist(rng)); }); 134*4bdc9457SAndroid Build Coastguard Worker std::generate(bias.begin(), bias.end(), [&]() { return fp16_ieee_from_fp32_value(f32dist(rng)); }); 135*4bdc9457SAndroid Build Coastguard Worker std::generate(x.begin(), x.end(), [&]() { return fp16_ieee_from_fp32_value(f32dist(rng)); }); 136*4bdc9457SAndroid Build Coastguard Worker if (inplace()) { 137*4bdc9457SAndroid Build Coastguard Worker std::copy(x.cbegin(), x.cend(), y.begin()); 138*4bdc9457SAndroid Build Coastguard Worker } else { 139*4bdc9457SAndroid Build Coastguard Worker std::fill(y.begin(), y.end(), UINT16_C(0x7E00) /* NaN */); 140*4bdc9457SAndroid Build Coastguard Worker } 141*4bdc9457SAndroid Build Coastguard Worker const uint16_t* x_data = inplace() ? y.data() : x.data(); 142*4bdc9457SAndroid Build Coastguard Worker 143*4bdc9457SAndroid Build Coastguard Worker std::fill(packed_w.begin(), packed_w.end(), UINT16_C(0x7E00) /* NaN */); 144*4bdc9457SAndroid Build Coastguard Worker xnn_pack_f16_vmulcaddc_w(channels(), channel_tile(), 145*4bdc9457SAndroid Build Coastguard Worker scale.data(), bias.data(), packed_w.data(), nullptr); 146*4bdc9457SAndroid Build Coastguard Worker 147*4bdc9457SAndroid Build Coastguard Worker // Compute reference results. 148*4bdc9457SAndroid Build Coastguard Worker for (size_t i = 0; i < rows(); i++) { 149*4bdc9457SAndroid Build Coastguard Worker for (size_t j = 0; j < channels(); j++) { 150*4bdc9457SAndroid Build Coastguard Worker y_ref[i * channels() + j] = fp16_ieee_to_fp32_value(x_data[i * input_stride() + j]) * fp16_ieee_to_fp32_value(scale[j]) + fp16_ieee_to_fp32_value(bias[j]); 151*4bdc9457SAndroid Build Coastguard Worker } 152*4bdc9457SAndroid Build Coastguard Worker } 153*4bdc9457SAndroid Build Coastguard Worker const float accumulated_min = *std::min_element(y_ref.cbegin(), y_ref.cend()); 154*4bdc9457SAndroid Build Coastguard Worker const float accumulated_max = *std::max_element(y_ref.cbegin(), y_ref.cend()); 155*4bdc9457SAndroid Build Coastguard Worker const float accumulated_range = accumulated_max - accumulated_min; 156*4bdc9457SAndroid Build Coastguard Worker const float y_max = fp16_ieee_to_fp32_value(fp16_ieee_from_fp32_value(accumulated_max - accumulated_range / 255.0f * float(255 - qmax()))); 157*4bdc9457SAndroid Build Coastguard Worker const float y_min = fp16_ieee_to_fp32_value(fp16_ieee_from_fp32_value(accumulated_min + accumulated_range / 255.0f * float(qmin()))); 158*4bdc9457SAndroid Build Coastguard Worker 159*4bdc9457SAndroid Build Coastguard Worker for (float& y_value : y_ref) { 160*4bdc9457SAndroid Build Coastguard Worker y_value = std::max(std::min(y_value, y_max), y_min); 161*4bdc9457SAndroid Build Coastguard Worker } 162*4bdc9457SAndroid Build Coastguard Worker 163*4bdc9457SAndroid Build Coastguard Worker // Prepare parameters. 164*4bdc9457SAndroid Build Coastguard Worker xnn_f16_minmax_params params; 165*4bdc9457SAndroid Build Coastguard Worker init_params(¶ms, fp16_ieee_from_fp32_value(y_min), fp16_ieee_from_fp32_value(y_max)); 166*4bdc9457SAndroid Build Coastguard Worker 167*4bdc9457SAndroid Build Coastguard Worker // Call optimized micro-kernel. 168*4bdc9457SAndroid Build Coastguard Worker vmulcaddc(rows(), channels() * sizeof(uint16_t), 169*4bdc9457SAndroid Build Coastguard Worker x_data, input_stride() * sizeof(uint16_t), 170*4bdc9457SAndroid Build Coastguard Worker packed_w.data(), 171*4bdc9457SAndroid Build Coastguard Worker y.data(), output_stride() * sizeof(uint16_t), 172*4bdc9457SAndroid Build Coastguard Worker ¶ms); 173*4bdc9457SAndroid Build Coastguard Worker 174*4bdc9457SAndroid Build Coastguard Worker // Verify results. 175*4bdc9457SAndroid Build Coastguard Worker for (size_t i = 0; i < rows(); i++) { 176*4bdc9457SAndroid Build Coastguard Worker for (size_t j = 0; j < channels(); j++) { 177*4bdc9457SAndroid Build Coastguard Worker ASSERT_NEAR(fp16_ieee_to_fp32_value(y[i * output_stride() + j]), y_ref[i * channels() + j], std::max(1.0e-4f, std::abs(y_ref[i * channels() + j]) * 1.0e-2f)) 178*4bdc9457SAndroid Build Coastguard Worker << "at pixel " << i << " / " << rows() 179*4bdc9457SAndroid Build Coastguard Worker << ", channel = " << j << " / " << channels(); 180*4bdc9457SAndroid Build Coastguard Worker } 181*4bdc9457SAndroid Build Coastguard Worker } 182*4bdc9457SAndroid Build Coastguard Worker } 183*4bdc9457SAndroid Build Coastguard Worker } 184*4bdc9457SAndroid Build Coastguard Worker Test(xnn_f32_vmulcaddc_ukernel_function vmulcaddc,xnn_init_f32_minmax_params_fn init_params)185*4bdc9457SAndroid Build Coastguard Worker void Test(xnn_f32_vmulcaddc_ukernel_function vmulcaddc, xnn_init_f32_minmax_params_fn init_params) const { 186*4bdc9457SAndroid Build Coastguard Worker std::random_device random_device; 187*4bdc9457SAndroid Build Coastguard Worker auto rng = std::mt19937(random_device()); 188*4bdc9457SAndroid Build Coastguard Worker std::uniform_real_distribution<float> f32dist; 189*4bdc9457SAndroid Build Coastguard Worker 190*4bdc9457SAndroid Build Coastguard Worker if (inplace()) { 191*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(input_stride(), output_stride()); 192*4bdc9457SAndroid Build Coastguard Worker } 193*4bdc9457SAndroid Build Coastguard Worker 194*4bdc9457SAndroid Build Coastguard Worker std::vector<float> x((rows() - 1) * input_stride() + channels() + XNN_EXTRA_BYTES / sizeof(float)); 195*4bdc9457SAndroid Build Coastguard Worker std::vector<float> scale(channels()); 196*4bdc9457SAndroid Build Coastguard Worker std::vector<float> bias(channels()); 197*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> packed_w(packed_channels() * 2); 198*4bdc9457SAndroid Build Coastguard Worker std::vector<float> y((rows() - 1) * output_stride() + channels() + (inplace() ? XNN_EXTRA_BYTES / sizeof(float) : 0)); 199*4bdc9457SAndroid Build Coastguard Worker std::vector<float> y_ref(rows() * channels()); 200*4bdc9457SAndroid Build Coastguard Worker for (size_t iteration = 0; iteration < iterations(); iteration++) { 201*4bdc9457SAndroid Build Coastguard Worker std::generate(scale.begin(), scale.end(), [&]() { return f32dist(rng); }); 202*4bdc9457SAndroid Build Coastguard Worker std::generate(bias.begin(), bias.end(), [&]() { return f32dist(rng); }); 203*4bdc9457SAndroid Build Coastguard Worker std::generate(x.begin(), x.end(), [&]() { return f32dist(rng); }); 204*4bdc9457SAndroid Build Coastguard Worker if (inplace()) { 205*4bdc9457SAndroid Build Coastguard Worker std::copy(x.cbegin(), x.cend(), y.begin()); 206*4bdc9457SAndroid Build Coastguard Worker } else { 207*4bdc9457SAndroid Build Coastguard Worker std::fill(y.begin(), y.end(), nanf("")); 208*4bdc9457SAndroid Build Coastguard Worker } 209*4bdc9457SAndroid Build Coastguard Worker const float* x_data = inplace() ? y.data() : x.data(); 210*4bdc9457SAndroid Build Coastguard Worker 211*4bdc9457SAndroid Build Coastguard Worker std::fill(packed_w.begin(), packed_w.end(), nanf("")); 212*4bdc9457SAndroid Build Coastguard Worker xnn_pack_f32_vmulcaddc_w(channels(), channel_tile(), 213*4bdc9457SAndroid Build Coastguard Worker scale.data(), bias.data(), packed_w.data(), nullptr); 214*4bdc9457SAndroid Build Coastguard Worker 215*4bdc9457SAndroid Build Coastguard Worker // Compute reference results. 216*4bdc9457SAndroid Build Coastguard Worker for (size_t i = 0; i < rows(); i++) { 217*4bdc9457SAndroid Build Coastguard Worker for (size_t j = 0; j < channels(); j++) { 218*4bdc9457SAndroid Build Coastguard Worker y_ref[i * channels() + j] = x_data[i * input_stride() + j] * scale[j] + bias[j]; 219*4bdc9457SAndroid Build Coastguard Worker } 220*4bdc9457SAndroid Build Coastguard Worker } 221*4bdc9457SAndroid Build Coastguard Worker const float accumulated_min = *std::min_element(y_ref.cbegin(), y_ref.cend()); 222*4bdc9457SAndroid Build Coastguard Worker const float accumulated_max = *std::max_element(y_ref.cbegin(), y_ref.cend()); 223*4bdc9457SAndroid Build Coastguard Worker const float accumulated_range = accumulated_max - accumulated_min; 224*4bdc9457SAndroid Build Coastguard Worker const float y_max = accumulated_max - accumulated_range / 255.0f * float(255 - qmax()); 225*4bdc9457SAndroid Build Coastguard Worker const float y_min = accumulated_min + accumulated_range / 255.0f * float(qmin()); 226*4bdc9457SAndroid Build Coastguard Worker for (float& y_value : y_ref) { 227*4bdc9457SAndroid Build Coastguard Worker y_value = std::max<float>(std::min<float>(y_value, y_max), y_min); 228*4bdc9457SAndroid Build Coastguard Worker } 229*4bdc9457SAndroid Build Coastguard Worker 230*4bdc9457SAndroid Build Coastguard Worker // Prepare parameters. 231*4bdc9457SAndroid Build Coastguard Worker xnn_f32_minmax_params params; 232*4bdc9457SAndroid Build Coastguard Worker init_params(¶ms, y_min, y_max); 233*4bdc9457SAndroid Build Coastguard Worker 234*4bdc9457SAndroid Build Coastguard Worker // Call optimized micro-kernel. 235*4bdc9457SAndroid Build Coastguard Worker vmulcaddc(rows(), channels() * sizeof(float), 236*4bdc9457SAndroid Build Coastguard Worker x_data, input_stride() * sizeof(float), 237*4bdc9457SAndroid Build Coastguard Worker packed_w.data(), 238*4bdc9457SAndroid Build Coastguard Worker y.data(), output_stride() * sizeof(float), 239*4bdc9457SAndroid Build Coastguard Worker ¶ms); 240*4bdc9457SAndroid Build Coastguard Worker 241*4bdc9457SAndroid Build Coastguard Worker // Verify results. 242*4bdc9457SAndroid Build Coastguard Worker for (size_t i = 0; i < rows(); i++) { 243*4bdc9457SAndroid Build Coastguard Worker for (size_t j = 0; j < channels(); j++) { 244*4bdc9457SAndroid Build Coastguard Worker ASSERT_NEAR(y[i * output_stride() + j], y_ref[i * channels() + j], std::abs(y_ref[i * channels() + j]) * 1.0e-6f) 245*4bdc9457SAndroid Build Coastguard Worker << "at pixel " << i << " / " << rows() 246*4bdc9457SAndroid Build Coastguard Worker << ", channel = " << j << " / " << channels(); 247*4bdc9457SAndroid Build Coastguard Worker } 248*4bdc9457SAndroid Build Coastguard Worker } 249*4bdc9457SAndroid Build Coastguard Worker } 250*4bdc9457SAndroid Build Coastguard Worker } 251*4bdc9457SAndroid Build Coastguard Worker 252*4bdc9457SAndroid Build Coastguard Worker private: 253*4bdc9457SAndroid Build Coastguard Worker size_t channel_tile_{1}; 254*4bdc9457SAndroid Build Coastguard Worker size_t channels_{1}; 255*4bdc9457SAndroid Build Coastguard Worker size_t rows_{1}; 256*4bdc9457SAndroid Build Coastguard Worker size_t input_stride_{0}; 257*4bdc9457SAndroid Build Coastguard Worker size_t output_stride_{0}; 258*4bdc9457SAndroid Build Coastguard Worker bool inplace_{false}; 259*4bdc9457SAndroid Build Coastguard Worker uint8_t qmin_{0}; 260*4bdc9457SAndroid Build Coastguard Worker uint8_t qmax_{255}; 261*4bdc9457SAndroid Build Coastguard Worker size_t iterations_{15}; 262*4bdc9457SAndroid Build Coastguard Worker }; 263