xref: /aosp_15_r20/external/XNNPACK/test/vmulcaddc-microkernel-tester.h (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
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(&params, 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         &params);
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(&params, 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         &params);
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