xref: /aosp_15_r20/external/XNNPACK/bench/deconvolution.cc (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 #include <algorithm>
7*4bdc9457SAndroid Build Coastguard Worker #include <array>
8*4bdc9457SAndroid Build Coastguard Worker #include <cfloat>
9*4bdc9457SAndroid Build Coastguard Worker #include <cmath>
10*4bdc9457SAndroid Build Coastguard Worker #include <functional>
11*4bdc9457SAndroid Build Coastguard Worker #include <random>
12*4bdc9457SAndroid Build Coastguard Worker #include <string>
13*4bdc9457SAndroid Build Coastguard Worker #include <vector>
14*4bdc9457SAndroid Build Coastguard Worker 
15*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack.h>
16*4bdc9457SAndroid Build Coastguard Worker 
17*4bdc9457SAndroid Build Coastguard Worker #include <benchmark/benchmark.h>
18*4bdc9457SAndroid Build Coastguard Worker #ifdef BENCHMARK_TENSORFLOW_LITE
19*4bdc9457SAndroid Build Coastguard Worker #include "flatbuffers/include/flatbuffers/flatbuffers.h"
20*4bdc9457SAndroid Build Coastguard Worker #include "tensorflow/lite/interpreter.h"
21*4bdc9457SAndroid Build Coastguard Worker #include "tensorflow/lite/kernels/register.h"
22*4bdc9457SAndroid Build Coastguard Worker #include "tensorflow/lite/model.h"
23*4bdc9457SAndroid Build Coastguard Worker #include "tensorflow/lite/schema/schema_generated.h"
24*4bdc9457SAndroid Build Coastguard Worker #include "tensorflow/lite/version.h"
25*4bdc9457SAndroid Build Coastguard Worker #endif  // BENCHMARK_TENSORFLOW_LITE */
26*4bdc9457SAndroid Build Coastguard Worker #include "bench/utils.h"
27*4bdc9457SAndroid Build Coastguard Worker 
28*4bdc9457SAndroid Build Coastguard Worker #ifndef XNN_NO_QU8_OPERATORS
xnnpack_deconvolution_qu8(benchmark::State & state,const char * net)29*4bdc9457SAndroid Build Coastguard Worker void xnnpack_deconvolution_qu8(benchmark::State& state, const char* net) {
30*4bdc9457SAndroid Build Coastguard Worker   const size_t batch_size = state.range(0);
31*4bdc9457SAndroid Build Coastguard Worker   const size_t input_height = state.range(1);
32*4bdc9457SAndroid Build Coastguard Worker   const size_t input_width = state.range(2);
33*4bdc9457SAndroid Build Coastguard Worker   const size_t kernel_height = state.range(3);
34*4bdc9457SAndroid Build Coastguard Worker   const size_t kernel_width = state.range(4);
35*4bdc9457SAndroid Build Coastguard Worker   const size_t padding_height = state.range(5);
36*4bdc9457SAndroid Build Coastguard Worker   const size_t padding_width = state.range(6);
37*4bdc9457SAndroid Build Coastguard Worker   const size_t adjustment = state.range(7);
38*4bdc9457SAndroid Build Coastguard Worker   const size_t stride_height = state.range(8);
39*4bdc9457SAndroid Build Coastguard Worker   const size_t stride_width = state.range(9);
40*4bdc9457SAndroid Build Coastguard Worker   const size_t dilation = state.range(10);
41*4bdc9457SAndroid Build Coastguard Worker   const size_t input_channels = state.range(11);
42*4bdc9457SAndroid Build Coastguard Worker   const size_t output_channels = state.range(12);
43*4bdc9457SAndroid Build Coastguard Worker 
44*4bdc9457SAndroid Build Coastguard Worker   std::random_device random_device;
45*4bdc9457SAndroid Build Coastguard Worker   auto rng = std::mt19937(random_device());
46*4bdc9457SAndroid Build Coastguard Worker   auto i32rng = std::bind(std::uniform_int_distribution<int32_t>(-10000, 10000), std::ref(rng));
47*4bdc9457SAndroid Build Coastguard Worker   auto u8rng = std::bind(
48*4bdc9457SAndroid Build Coastguard Worker     std::uniform_int_distribution<int32_t>(std::numeric_limits<uint8_t>::min(), std::numeric_limits<uint8_t>::max()),
49*4bdc9457SAndroid Build Coastguard Worker     std::ref(rng));
50*4bdc9457SAndroid Build Coastguard Worker 
51*4bdc9457SAndroid Build Coastguard Worker   const size_t effective_kernel_height = (kernel_height - 1) * dilation + 1;
52*4bdc9457SAndroid Build Coastguard Worker   const size_t effective_kernel_width = (kernel_width - 1) * dilation + 1;
53*4bdc9457SAndroid Build Coastguard Worker   const size_t padding_left = padding_width / 2;
54*4bdc9457SAndroid Build Coastguard Worker   const size_t padding_top = padding_height / 2;
55*4bdc9457SAndroid Build Coastguard Worker   const size_t padding_right = padding_width - padding_left;
56*4bdc9457SAndroid Build Coastguard Worker   const size_t padding_bottom = padding_height - padding_top;
57*4bdc9457SAndroid Build Coastguard Worker   const size_t output_height = std::max(stride_height * (input_height - 1) + adjustment + effective_kernel_height, padding_height) - padding_height;
58*4bdc9457SAndroid Build Coastguard Worker   const size_t output_width = std::max(stride_width * (input_width - 1) + adjustment + effective_kernel_width, padding_width) - padding_width;
59*4bdc9457SAndroid Build Coastguard Worker 
60*4bdc9457SAndroid Build Coastguard Worker   std::vector<uint8_t> input(batch_size * input_height * input_width * input_channels);
61*4bdc9457SAndroid Build Coastguard Worker   std::generate(input.begin(), input.end(), std::ref(u8rng));
62*4bdc9457SAndroid Build Coastguard Worker   std::vector<uint8_t> kernel(output_channels * kernel_height * kernel_width * input_channels);
63*4bdc9457SAndroid Build Coastguard Worker   std::generate(kernel.begin(), kernel.end(), std::ref(u8rng));
64*4bdc9457SAndroid Build Coastguard Worker   std::vector<int32_t> bias(output_channels);
65*4bdc9457SAndroid Build Coastguard Worker   std::generate(bias.begin(), bias.end(), std::ref(i32rng));
66*4bdc9457SAndroid Build Coastguard Worker   const size_t output_elements = batch_size * output_height * output_width * output_channels;
67*4bdc9457SAndroid Build Coastguard Worker 
68*4bdc9457SAndroid Build Coastguard Worker   xnn_status status = xnn_initialize(nullptr /* allocator */);
69*4bdc9457SAndroid Build Coastguard Worker   if (status != xnn_status_success) {
70*4bdc9457SAndroid Build Coastguard Worker     state.SkipWithError("failed to initialize XNNPACK");
71*4bdc9457SAndroid Build Coastguard Worker     return;
72*4bdc9457SAndroid Build Coastguard Worker   }
73*4bdc9457SAndroid Build Coastguard Worker 
74*4bdc9457SAndroid Build Coastguard Worker   const size_t num_buffers = 1 +
75*4bdc9457SAndroid Build Coastguard Worker     benchmark::utils::DivideRoundUp<size_t>(benchmark::utils::GetMaxCacheSize(),
76*4bdc9457SAndroid Build Coastguard Worker       sizeof(float) * (kernel.size() + bias.size() + output_elements));
77*4bdc9457SAndroid Build Coastguard Worker   std::vector<uint8_t> output(output_elements * num_buffers);
78*4bdc9457SAndroid Build Coastguard Worker 
79*4bdc9457SAndroid Build Coastguard Worker   std::vector<xnn_operator_t> deconvolution_operators(num_buffers);
80*4bdc9457SAndroid Build Coastguard Worker   for (xnn_operator_t& deconvolution_op : deconvolution_operators) {
81*4bdc9457SAndroid Build Coastguard Worker     status = xnn_create_deconvolution2d_nhwc_qu8(
82*4bdc9457SAndroid Build Coastguard Worker         padding_top, padding_right, padding_bottom, padding_left,
83*4bdc9457SAndroid Build Coastguard Worker         kernel_height, kernel_width,
84*4bdc9457SAndroid Build Coastguard Worker         stride_height, stride_width,
85*4bdc9457SAndroid Build Coastguard Worker         dilation, dilation,
86*4bdc9457SAndroid Build Coastguard Worker         /*groups=*/1, input_channels, output_channels,
87*4bdc9457SAndroid Build Coastguard Worker         /*input_pixel_stride=*/input_channels, /*output_pixel_stride=*/output_channels,
88*4bdc9457SAndroid Build Coastguard Worker         127, 0.5f, 127, 0.5f,
89*4bdc9457SAndroid Build Coastguard Worker         kernel.data(), bias.data(),
90*4bdc9457SAndroid Build Coastguard Worker         127, 0.5f, 0, 255,
91*4bdc9457SAndroid Build Coastguard Worker         0 /* flags */,
92*4bdc9457SAndroid Build Coastguard Worker         NULL,
93*4bdc9457SAndroid Build Coastguard Worker         &deconvolution_op);
94*4bdc9457SAndroid Build Coastguard Worker     if (status != xnn_status_success) {
95*4bdc9457SAndroid Build Coastguard Worker       state.SkipWithError("failed to create QINT8 Deconvolution operator");
96*4bdc9457SAndroid Build Coastguard Worker       return;
97*4bdc9457SAndroid Build Coastguard Worker     }
98*4bdc9457SAndroid Build Coastguard Worker   }
99*4bdc9457SAndroid Build Coastguard Worker 
100*4bdc9457SAndroid Build Coastguard Worker   for (size_t i = 0; i < deconvolution_operators.size(); i++) {
101*4bdc9457SAndroid Build Coastguard Worker     status = xnn_setup_deconvolution2d_nhwc_qu8(
102*4bdc9457SAndroid Build Coastguard Worker         deconvolution_operators[i],
103*4bdc9457SAndroid Build Coastguard Worker         batch_size, input_height, input_width,
104*4bdc9457SAndroid Build Coastguard Worker         0 /* height adjustment */, 0 /* width adjustment */,
105*4bdc9457SAndroid Build Coastguard Worker         input.data(), output.data() + i * output_elements,
106*4bdc9457SAndroid Build Coastguard Worker         nullptr /* thread pool */);
107*4bdc9457SAndroid Build Coastguard Worker     if (status != xnn_status_success) {
108*4bdc9457SAndroid Build Coastguard Worker       state.SkipWithError("failed to setup QINT8 Deconvolution operator");
109*4bdc9457SAndroid Build Coastguard Worker       return;
110*4bdc9457SAndroid Build Coastguard Worker     }
111*4bdc9457SAndroid Build Coastguard Worker   }
112*4bdc9457SAndroid Build Coastguard Worker 
113*4bdc9457SAndroid Build Coastguard Worker   size_t buffer_index = 0;
114*4bdc9457SAndroid Build Coastguard Worker   for (auto _ : state) {
115*4bdc9457SAndroid Build Coastguard Worker     state.PauseTiming();
116*4bdc9457SAndroid Build Coastguard Worker     benchmark::utils::PrefetchToL1(input.data(), input.size() * sizeof(uint8_t));
117*4bdc9457SAndroid Build Coastguard Worker     buffer_index = (buffer_index + 1) % num_buffers;
118*4bdc9457SAndroid Build Coastguard Worker     state.ResumeTiming();
119*4bdc9457SAndroid Build Coastguard Worker 
120*4bdc9457SAndroid Build Coastguard Worker     status = xnn_run_operator(deconvolution_operators[buffer_index], nullptr /* thread pool */);
121*4bdc9457SAndroid Build Coastguard Worker     if (status != xnn_status_success) {
122*4bdc9457SAndroid Build Coastguard Worker       state.SkipWithError("failed to run QINT8 Deconvolution operator");
123*4bdc9457SAndroid Build Coastguard Worker       return;
124*4bdc9457SAndroid Build Coastguard Worker     }
125*4bdc9457SAndroid Build Coastguard Worker   }
126*4bdc9457SAndroid Build Coastguard Worker 
127*4bdc9457SAndroid Build Coastguard Worker   for (xnn_operator_t& deconvolution_op : deconvolution_operators) {
128*4bdc9457SAndroid Build Coastguard Worker     status = xnn_delete_operator(deconvolution_op);
129*4bdc9457SAndroid Build Coastguard Worker     if (status != xnn_status_success) {
130*4bdc9457SAndroid Build Coastguard Worker       state.SkipWithError("failed to delete QINT8 Deconvolution operator");
131*4bdc9457SAndroid Build Coastguard Worker       return;
132*4bdc9457SAndroid Build Coastguard Worker     }
133*4bdc9457SAndroid Build Coastguard Worker     deconvolution_op = nullptr;
134*4bdc9457SAndroid Build Coastguard Worker   }
135*4bdc9457SAndroid Build Coastguard Worker 
136*4bdc9457SAndroid Build Coastguard Worker   const uint64_t cpu_frequency = benchmark::utils::GetCurrentCpuFrequency();
137*4bdc9457SAndroid Build Coastguard Worker   if (cpu_frequency != 0) {
138*4bdc9457SAndroid Build Coastguard Worker     state.counters["cpufreq"] = cpu_frequency;
139*4bdc9457SAndroid Build Coastguard Worker   }
140*4bdc9457SAndroid Build Coastguard Worker 
141*4bdc9457SAndroid Build Coastguard Worker   state.counters["OPS"] = benchmark::Counter(
142*4bdc9457SAndroid Build Coastguard Worker   uint64_t(state.iterations()) * 2 *
143*4bdc9457SAndroid Build Coastguard Worker     batch_size * input_width * input_width *
144*4bdc9457SAndroid Build Coastguard Worker     input_channels * output_channels *
145*4bdc9457SAndroid Build Coastguard Worker     kernel_height * kernel_width,
146*4bdc9457SAndroid Build Coastguard Worker   benchmark::Counter::kIsRate);
147*4bdc9457SAndroid Build Coastguard Worker }
148*4bdc9457SAndroid Build Coastguard Worker #endif  // XNN_NO_QU8_OPERATORS
149*4bdc9457SAndroid Build Coastguard Worker 
xnnpack_deconvolution_f32(benchmark::State & state,const char * net)150*4bdc9457SAndroid Build Coastguard Worker void xnnpack_deconvolution_f32(benchmark::State& state, const char* net) {
151*4bdc9457SAndroid Build Coastguard Worker   const size_t batch_size = state.range(0);
152*4bdc9457SAndroid Build Coastguard Worker   const size_t input_height = state.range(1);
153*4bdc9457SAndroid Build Coastguard Worker   const size_t input_width = state.range(2);
154*4bdc9457SAndroid Build Coastguard Worker   const size_t kernel_height = state.range(3);
155*4bdc9457SAndroid Build Coastguard Worker   const size_t kernel_width = state.range(4);
156*4bdc9457SAndroid Build Coastguard Worker   const size_t padding_height = state.range(5);
157*4bdc9457SAndroid Build Coastguard Worker   const size_t padding_width = state.range(6);
158*4bdc9457SAndroid Build Coastguard Worker   const size_t adjustment = state.range(7);
159*4bdc9457SAndroid Build Coastguard Worker   const size_t stride_height = state.range(8);
160*4bdc9457SAndroid Build Coastguard Worker   const size_t stride_width = state.range(9);
161*4bdc9457SAndroid Build Coastguard Worker   const size_t dilation = state.range(10);
162*4bdc9457SAndroid Build Coastguard Worker   const size_t input_channels = state.range(11);
163*4bdc9457SAndroid Build Coastguard Worker   const size_t output_channels = state.range(12);
164*4bdc9457SAndroid Build Coastguard Worker 
165*4bdc9457SAndroid Build Coastguard Worker   std::random_device random_device;
166*4bdc9457SAndroid Build Coastguard Worker   auto rng = std::mt19937(random_device());
167*4bdc9457SAndroid Build Coastguard Worker   auto f32rng = std::bind(std::uniform_real_distribution<float>(0.0f, 1.0f), std::ref(rng));
168*4bdc9457SAndroid Build Coastguard Worker 
169*4bdc9457SAndroid Build Coastguard Worker   const size_t effective_kernel_height = (kernel_height - 1) * dilation + 1;
170*4bdc9457SAndroid Build Coastguard Worker   const size_t effective_kernel_width = (kernel_width - 1) * dilation + 1;
171*4bdc9457SAndroid Build Coastguard Worker   const size_t padding_left = padding_width / 2;
172*4bdc9457SAndroid Build Coastguard Worker   const size_t padding_top = padding_height / 2;
173*4bdc9457SAndroid Build Coastguard Worker   const size_t padding_right = padding_width - padding_left;
174*4bdc9457SAndroid Build Coastguard Worker   const size_t padding_bottom = padding_height - padding_top;
175*4bdc9457SAndroid Build Coastguard Worker   const size_t output_height = std::max(stride_height * (input_height - 1) + adjustment + effective_kernel_height, padding_height) - padding_height;
176*4bdc9457SAndroid Build Coastguard Worker   const size_t output_width = std::max(stride_width * (input_width - 1) + adjustment + effective_kernel_width, padding_width) - padding_width;
177*4bdc9457SAndroid Build Coastguard Worker 
178*4bdc9457SAndroid Build Coastguard Worker   std::vector<float> input(XNN_EXTRA_BYTES / sizeof(float) +
179*4bdc9457SAndroid Build Coastguard Worker     batch_size * input_height * input_width * input_channels);
180*4bdc9457SAndroid Build Coastguard Worker   std::generate(input.begin(), input.end(), std::ref(f32rng));
181*4bdc9457SAndroid Build Coastguard Worker   std::vector<float> kernel(output_channels * kernel_height * kernel_width * input_channels);
182*4bdc9457SAndroid Build Coastguard Worker   std::generate(kernel.begin(), kernel.end(), std::ref(f32rng));
183*4bdc9457SAndroid Build Coastguard Worker   std::vector<float> bias(output_channels);
184*4bdc9457SAndroid Build Coastguard Worker   std::generate(bias.begin(), bias.end(), std::ref(f32rng));
185*4bdc9457SAndroid Build Coastguard Worker   const size_t output_elements = batch_size * output_height * output_width * output_channels;
186*4bdc9457SAndroid Build Coastguard Worker 
187*4bdc9457SAndroid Build Coastguard Worker   xnn_status status = xnn_initialize(nullptr /* allocator */);
188*4bdc9457SAndroid Build Coastguard Worker   if (status != xnn_status_success) {
189*4bdc9457SAndroid Build Coastguard Worker     state.SkipWithError("failed to initialize XNNPACK");
190*4bdc9457SAndroid Build Coastguard Worker     return;
191*4bdc9457SAndroid Build Coastguard Worker   }
192*4bdc9457SAndroid Build Coastguard Worker 
193*4bdc9457SAndroid Build Coastguard Worker   const size_t num_buffers = 1 +
194*4bdc9457SAndroid Build Coastguard Worker     benchmark::utils::DivideRoundUp<size_t>(benchmark::utils::GetMaxCacheSize(),
195*4bdc9457SAndroid Build Coastguard Worker       sizeof(float) * (kernel.size() + bias.size() + output_elements));
196*4bdc9457SAndroid Build Coastguard Worker   std::vector<float> output(output_elements * num_buffers);
197*4bdc9457SAndroid Build Coastguard Worker 
198*4bdc9457SAndroid Build Coastguard Worker   std::vector<xnn_operator_t> deconvolution_operators(num_buffers);
199*4bdc9457SAndroid Build Coastguard Worker   for (xnn_operator_t& deconvolution_op : deconvolution_operators) {
200*4bdc9457SAndroid Build Coastguard Worker     status = xnn_create_deconvolution2d_nhwc_f32(
201*4bdc9457SAndroid Build Coastguard Worker         padding_top, padding_right, padding_bottom, padding_left,
202*4bdc9457SAndroid Build Coastguard Worker         kernel_height, kernel_width,
203*4bdc9457SAndroid Build Coastguard Worker         stride_height, stride_width,
204*4bdc9457SAndroid Build Coastguard Worker         dilation, dilation,
205*4bdc9457SAndroid Build Coastguard Worker         /*groups=*/1, input_channels, output_channels,
206*4bdc9457SAndroid Build Coastguard Worker         /*input_pixel_stride=*/input_channels, /*output_pixel_stride=*/output_channels,
207*4bdc9457SAndroid Build Coastguard Worker         kernel.data(), bias.data(),
208*4bdc9457SAndroid Build Coastguard Worker         -std::numeric_limits<float>::infinity(), +std::numeric_limits<float>::infinity(),
209*4bdc9457SAndroid Build Coastguard Worker         0 /* flags */,
210*4bdc9457SAndroid Build Coastguard Worker         NULL,
211*4bdc9457SAndroid Build Coastguard Worker         &deconvolution_op);
212*4bdc9457SAndroid Build Coastguard Worker     if (status != xnn_status_success) {
213*4bdc9457SAndroid Build Coastguard Worker       state.SkipWithError("failed to create FP32 Deconvolution operator");
214*4bdc9457SAndroid Build Coastguard Worker       return;
215*4bdc9457SAndroid Build Coastguard Worker     }
216*4bdc9457SAndroid Build Coastguard Worker   }
217*4bdc9457SAndroid Build Coastguard Worker 
218*4bdc9457SAndroid Build Coastguard Worker   for (size_t i = 0; i < deconvolution_operators.size(); i++) {
219*4bdc9457SAndroid Build Coastguard Worker     status = xnn_setup_deconvolution2d_nhwc_f32(
220*4bdc9457SAndroid Build Coastguard Worker         deconvolution_operators[i],
221*4bdc9457SAndroid Build Coastguard Worker         batch_size, input_height, input_width,
222*4bdc9457SAndroid Build Coastguard Worker         0 /* height adjustment */, 0 /* width adjustment */,
223*4bdc9457SAndroid Build Coastguard Worker         input.data(), output.data() + i * output_elements,
224*4bdc9457SAndroid Build Coastguard Worker         nullptr /* thread pool */);
225*4bdc9457SAndroid Build Coastguard Worker     if (status != xnn_status_success) {
226*4bdc9457SAndroid Build Coastguard Worker       state.SkipWithError("failed to setup QINT8 Deconvolution operator");
227*4bdc9457SAndroid Build Coastguard Worker       return;
228*4bdc9457SAndroid Build Coastguard Worker     }
229*4bdc9457SAndroid Build Coastguard Worker   }
230*4bdc9457SAndroid Build Coastguard Worker 
231*4bdc9457SAndroid Build Coastguard Worker   size_t buffer_index = 0;
232*4bdc9457SAndroid Build Coastguard Worker   for (auto _ : state) {
233*4bdc9457SAndroid Build Coastguard Worker     state.PauseTiming();
234*4bdc9457SAndroid Build Coastguard Worker     benchmark::utils::PrefetchToL1(input.data(), input.size() * sizeof(float));
235*4bdc9457SAndroid Build Coastguard Worker     buffer_index = (buffer_index + 1) % num_buffers;
236*4bdc9457SAndroid Build Coastguard Worker     state.ResumeTiming();
237*4bdc9457SAndroid Build Coastguard Worker 
238*4bdc9457SAndroid Build Coastguard Worker     status = xnn_run_operator(deconvolution_operators[buffer_index], nullptr /* thread pool */);
239*4bdc9457SAndroid Build Coastguard Worker     if (status != xnn_status_success) {
240*4bdc9457SAndroid Build Coastguard Worker       state.SkipWithError("failed to run FP32 Deconvolution operator");
241*4bdc9457SAndroid Build Coastguard Worker       return;
242*4bdc9457SAndroid Build Coastguard Worker     }
243*4bdc9457SAndroid Build Coastguard Worker   }
244*4bdc9457SAndroid Build Coastguard Worker 
245*4bdc9457SAndroid Build Coastguard Worker   for (xnn_operator_t& deconvolution_op : deconvolution_operators) {
246*4bdc9457SAndroid Build Coastguard Worker     status = xnn_delete_operator(deconvolution_op);
247*4bdc9457SAndroid Build Coastguard Worker     if (status != xnn_status_success) {
248*4bdc9457SAndroid Build Coastguard Worker       state.SkipWithError("failed to delete FP32 Deconvolution operator");
249*4bdc9457SAndroid Build Coastguard Worker       return;
250*4bdc9457SAndroid Build Coastguard Worker     }
251*4bdc9457SAndroid Build Coastguard Worker     deconvolution_op = nullptr;
252*4bdc9457SAndroid Build Coastguard Worker   }
253*4bdc9457SAndroid Build Coastguard Worker 
254*4bdc9457SAndroid Build Coastguard Worker   const uint64_t cpu_frequency = benchmark::utils::GetCurrentCpuFrequency();
255*4bdc9457SAndroid Build Coastguard Worker   if (cpu_frequency != 0) {
256*4bdc9457SAndroid Build Coastguard Worker     state.counters["cpufreq"] = cpu_frequency;
257*4bdc9457SAndroid Build Coastguard Worker   }
258*4bdc9457SAndroid Build Coastguard Worker 
259*4bdc9457SAndroid Build Coastguard Worker   state.counters["FLOPS"] = benchmark::Counter(
260*4bdc9457SAndroid Build Coastguard Worker     uint64_t(state.iterations()) * 2 *
261*4bdc9457SAndroid Build Coastguard Worker       batch_size * input_width * input_width *
262*4bdc9457SAndroid Build Coastguard Worker       input_channels * output_channels *
263*4bdc9457SAndroid Build Coastguard Worker       kernel_height * kernel_width,
264*4bdc9457SAndroid Build Coastguard Worker     benchmark::Counter::kIsRate);
265*4bdc9457SAndroid Build Coastguard Worker }
266*4bdc9457SAndroid Build Coastguard Worker 
267*4bdc9457SAndroid Build Coastguard Worker #ifdef BENCHMARK_TENSORFLOW_LITE
tflite_deconvolution_f32(benchmark::State & state,const char * net)268*4bdc9457SAndroid Build Coastguard Worker void tflite_deconvolution_f32(benchmark::State& state, const char* net) {
269*4bdc9457SAndroid Build Coastguard Worker   const size_t batch_size = state.range(0);
270*4bdc9457SAndroid Build Coastguard Worker   const size_t input_height = state.range(1);
271*4bdc9457SAndroid Build Coastguard Worker   const size_t input_width = state.range(2);
272*4bdc9457SAndroid Build Coastguard Worker   const size_t kernel_height = state.range(3);
273*4bdc9457SAndroid Build Coastguard Worker   const size_t kernel_width = state.range(4);
274*4bdc9457SAndroid Build Coastguard Worker   const size_t padding_height = state.range(5);
275*4bdc9457SAndroid Build Coastguard Worker   const size_t padding_width = state.range(6);
276*4bdc9457SAndroid Build Coastguard Worker   const size_t adjustment = state.range(7);
277*4bdc9457SAndroid Build Coastguard Worker   const size_t stride_height = state.range(8);
278*4bdc9457SAndroid Build Coastguard Worker   const size_t stride_width = state.range(9);
279*4bdc9457SAndroid Build Coastguard Worker   const size_t dilation = state.range(10);
280*4bdc9457SAndroid Build Coastguard Worker   const size_t input_channels = state.range(11);
281*4bdc9457SAndroid Build Coastguard Worker   const size_t output_channels = state.range(12);
282*4bdc9457SAndroid Build Coastguard Worker 
283*4bdc9457SAndroid Build Coastguard Worker   if (dilation != 1) {
284*4bdc9457SAndroid Build Coastguard Worker     state.SkipWithError("dilated deconvolution is not supported");
285*4bdc9457SAndroid Build Coastguard Worker     return;
286*4bdc9457SAndroid Build Coastguard Worker   }
287*4bdc9457SAndroid Build Coastguard Worker 
288*4bdc9457SAndroid Build Coastguard Worker   std::random_device random_device;
289*4bdc9457SAndroid Build Coastguard Worker   auto rng = std::mt19937(random_device());
290*4bdc9457SAndroid Build Coastguard Worker   auto f32rng = std::bind(std::uniform_real_distribution<float>(0.0f, 1.0f), std::ref(rng));
291*4bdc9457SAndroid Build Coastguard Worker 
292*4bdc9457SAndroid Build Coastguard Worker   tflite::Padding tf_padding = tflite::Padding_VALID;
293*4bdc9457SAndroid Build Coastguard Worker   if (padding_width == kernel_width - stride_width && padding_height == kernel_height - stride_height) {
294*4bdc9457SAndroid Build Coastguard Worker     tf_padding = tflite::Padding_SAME;
295*4bdc9457SAndroid Build Coastguard Worker   } else if (padding_width == 0 && padding_height == 0) {
296*4bdc9457SAndroid Build Coastguard Worker     tf_padding = tflite::Padding_VALID;
297*4bdc9457SAndroid Build Coastguard Worker   } else {
298*4bdc9457SAndroid Build Coastguard Worker     state.SkipWithError("unsupported padding");
299*4bdc9457SAndroid Build Coastguard Worker     return;
300*4bdc9457SAndroid Build Coastguard Worker   }
301*4bdc9457SAndroid Build Coastguard Worker 
302*4bdc9457SAndroid Build Coastguard Worker   const size_t output_height = std::max(stride_height * (input_height - 1) + adjustment + kernel_height, padding_height) - padding_height;
303*4bdc9457SAndroid Build Coastguard Worker   const size_t output_width = std::max(stride_width * (input_width - 1) + adjustment + kernel_width, padding_width) - padding_width;
304*4bdc9457SAndroid Build Coastguard Worker 
305*4bdc9457SAndroid Build Coastguard Worker   std::vector<float> kernel(output_channels * kernel_height * kernel_width * input_channels);
306*4bdc9457SAndroid Build Coastguard Worker   std::generate(kernel.begin(), kernel.end(), std::ref(f32rng));
307*4bdc9457SAndroid Build Coastguard Worker 
308*4bdc9457SAndroid Build Coastguard Worker   flatbuffers::FlatBufferBuilder builder;
309*4bdc9457SAndroid Build Coastguard Worker   flatbuffers::Offset<tflite::OperatorCode> operator_code =
310*4bdc9457SAndroid Build Coastguard Worker       CreateOperatorCode(builder, tflite::BuiltinOperator_TRANSPOSE_CONV, 0);
311*4bdc9457SAndroid Build Coastguard Worker 
312*4bdc9457SAndroid Build Coastguard Worker   flatbuffers::Offset<tflite::TransposeConvOptions> transpose_conv_options = CreateTransposeConvOptions(
313*4bdc9457SAndroid Build Coastguard Worker       builder,
314*4bdc9457SAndroid Build Coastguard Worker       tf_padding,
315*4bdc9457SAndroid Build Coastguard Worker       static_cast<int32_t>(stride_width), static_cast<int32_t>(stride_height));
316*4bdc9457SAndroid Build Coastguard Worker 
317*4bdc9457SAndroid Build Coastguard Worker   const std::array<int32_t, 4> input_shape{{
318*4bdc9457SAndroid Build Coastguard Worker     static_cast<int32_t>(batch_size),
319*4bdc9457SAndroid Build Coastguard Worker     static_cast<int32_t>(input_height),
320*4bdc9457SAndroid Build Coastguard Worker     static_cast<int32_t>(input_width),
321*4bdc9457SAndroid Build Coastguard Worker     static_cast<int32_t>(input_channels)
322*4bdc9457SAndroid Build Coastguard Worker   }};
323*4bdc9457SAndroid Build Coastguard Worker   const std::array<int32_t, 4> output_shape{{
324*4bdc9457SAndroid Build Coastguard Worker     static_cast<int32_t>(batch_size),
325*4bdc9457SAndroid Build Coastguard Worker     static_cast<int32_t>(output_height),
326*4bdc9457SAndroid Build Coastguard Worker     static_cast<int32_t>(output_width),
327*4bdc9457SAndroid Build Coastguard Worker     static_cast<int32_t>(output_channels)
328*4bdc9457SAndroid Build Coastguard Worker   }};
329*4bdc9457SAndroid Build Coastguard Worker   const std::array<int32_t, 4> filter_shape{{
330*4bdc9457SAndroid Build Coastguard Worker     static_cast<int32_t>(output_channels),
331*4bdc9457SAndroid Build Coastguard Worker     static_cast<int32_t>(kernel_height),
332*4bdc9457SAndroid Build Coastguard Worker     static_cast<int32_t>(kernel_width),
333*4bdc9457SAndroid Build Coastguard Worker     static_cast<int32_t>(input_channels)
334*4bdc9457SAndroid Build Coastguard Worker   }};
335*4bdc9457SAndroid Build Coastguard Worker   const std::array<int32_t, 1> output_shape_shape{{ 4 }};
336*4bdc9457SAndroid Build Coastguard Worker 
337*4bdc9457SAndroid Build Coastguard Worker   const std::array<flatbuffers::Offset<tflite::Buffer>, 3> buffers{{
338*4bdc9457SAndroid Build Coastguard Worker     tflite::CreateBuffer(builder, builder.CreateVector({})),
339*4bdc9457SAndroid Build Coastguard Worker     tflite::CreateBuffer(builder, builder.CreateVector(
340*4bdc9457SAndroid Build Coastguard Worker       reinterpret_cast<const uint8_t*>(kernel.data()),
341*4bdc9457SAndroid Build Coastguard Worker       sizeof(float) * kernel.size())),
342*4bdc9457SAndroid Build Coastguard Worker     tflite::CreateBuffer(builder, builder.CreateVector(
343*4bdc9457SAndroid Build Coastguard Worker       reinterpret_cast<const uint8_t*>(output_shape.data()),
344*4bdc9457SAndroid Build Coastguard Worker       sizeof(int32_t) * output_shape.size())),
345*4bdc9457SAndroid Build Coastguard Worker   }};
346*4bdc9457SAndroid Build Coastguard Worker 
347*4bdc9457SAndroid Build Coastguard Worker   const std::array<flatbuffers::Offset<tflite::Tensor>, 4> tensors{{
348*4bdc9457SAndroid Build Coastguard Worker     tflite::CreateTensor(builder,
349*4bdc9457SAndroid Build Coastguard Worker                          builder.CreateVector<int32_t>(output_shape_shape.data(), output_shape_shape.size()),
350*4bdc9457SAndroid Build Coastguard Worker                          tflite::TensorType_INT32,
351*4bdc9457SAndroid Build Coastguard Worker                          2 /* buffer id */),
352*4bdc9457SAndroid Build Coastguard Worker     tflite::CreateTensor(builder,
353*4bdc9457SAndroid Build Coastguard Worker                          builder.CreateVector<int32_t>(filter_shape.data(), filter_shape.size()),
354*4bdc9457SAndroid Build Coastguard Worker                          tflite::TensorType_FLOAT32,
355*4bdc9457SAndroid Build Coastguard Worker                          1 /* buffer id */),
356*4bdc9457SAndroid Build Coastguard Worker     tflite::CreateTensor(builder,
357*4bdc9457SAndroid Build Coastguard Worker                          builder.CreateVector<int32_t>(input_shape.data(), input_shape.size()),
358*4bdc9457SAndroid Build Coastguard Worker                          tflite::TensorType_FLOAT32),
359*4bdc9457SAndroid Build Coastguard Worker     tflite::CreateTensor(builder,
360*4bdc9457SAndroid Build Coastguard Worker                          builder.CreateVector<int32_t>(output_shape.data(), output_shape.size()),
361*4bdc9457SAndroid Build Coastguard Worker                          tflite::TensorType_FLOAT32),
362*4bdc9457SAndroid Build Coastguard Worker   }};
363*4bdc9457SAndroid Build Coastguard Worker 
364*4bdc9457SAndroid Build Coastguard Worker   const std::array<int32_t, 3> op_inputs{{ 0, 1, 2 }};
365*4bdc9457SAndroid Build Coastguard Worker   const std::array<int32_t, 1> op_outputs{{ 3 }};
366*4bdc9457SAndroid Build Coastguard Worker   flatbuffers::Offset<tflite::Operator> op = CreateOperator(
367*4bdc9457SAndroid Build Coastguard Worker       builder,
368*4bdc9457SAndroid Build Coastguard Worker       0 /* opcode_index */,
369*4bdc9457SAndroid Build Coastguard Worker       builder.CreateVector<int32_t>(op_inputs.data(), op_inputs.size()),
370*4bdc9457SAndroid Build Coastguard Worker       builder.CreateVector<int32_t>(op_outputs.data(), op_outputs.size()),
371*4bdc9457SAndroid Build Coastguard Worker       tflite::BuiltinOptions_TransposeConvOptions,
372*4bdc9457SAndroid Build Coastguard Worker       transpose_conv_options.Union());
373*4bdc9457SAndroid Build Coastguard Worker 
374*4bdc9457SAndroid Build Coastguard Worker   const std::array<int32_t, 1> graph_inputs{{ 2 }};
375*4bdc9457SAndroid Build Coastguard Worker   const std::array<int32_t, 1> graph_outputs{{ 3 }};
376*4bdc9457SAndroid Build Coastguard Worker   flatbuffers::Offset<tflite::SubGraph> subgraph = CreateSubGraph(
377*4bdc9457SAndroid Build Coastguard Worker       builder,
378*4bdc9457SAndroid Build Coastguard Worker       builder.CreateVector(tensors.data(), tensors.size()),
379*4bdc9457SAndroid Build Coastguard Worker       builder.CreateVector<int32_t>(graph_inputs.data(), graph_inputs.size()),
380*4bdc9457SAndroid Build Coastguard Worker       builder.CreateVector<int32_t>(graph_outputs.data(), graph_outputs.size()),
381*4bdc9457SAndroid Build Coastguard Worker       builder.CreateVector(&op, 1),
382*4bdc9457SAndroid Build Coastguard Worker       builder.CreateString("TransposeConv subgraph"));
383*4bdc9457SAndroid Build Coastguard Worker 
384*4bdc9457SAndroid Build Coastguard Worker   const flatbuffers::Offset<flatbuffers::String> description = builder.CreateString("TransposeConv model");
385*4bdc9457SAndroid Build Coastguard Worker 
386*4bdc9457SAndroid Build Coastguard Worker   const flatbuffers::Offset<tflite::Model> model_buffer = tflite::CreateModel(builder,
387*4bdc9457SAndroid Build Coastguard Worker       TFLITE_SCHEMA_VERSION,
388*4bdc9457SAndroid Build Coastguard Worker       builder.CreateVector(&operator_code, 1),
389*4bdc9457SAndroid Build Coastguard Worker       builder.CreateVector(&subgraph, 1),
390*4bdc9457SAndroid Build Coastguard Worker       description,
391*4bdc9457SAndroid Build Coastguard Worker       builder.CreateVector(buffers.data(), buffers.size()));
392*4bdc9457SAndroid Build Coastguard Worker 
393*4bdc9457SAndroid Build Coastguard Worker   builder.Finish(model_buffer);
394*4bdc9457SAndroid Build Coastguard Worker 
395*4bdc9457SAndroid Build Coastguard Worker   const tflite::Model* model = tflite::GetModel(builder.GetBufferPointer());
396*4bdc9457SAndroid Build Coastguard Worker   tflite::ops::builtin::BuiltinOpResolverWithoutDefaultDelegates resolver;
397*4bdc9457SAndroid Build Coastguard Worker   tflite::InterpreterBuilder interpreterBuilder(model, resolver);
398*4bdc9457SAndroid Build Coastguard Worker   std::unique_ptr<tflite::Interpreter> interpreter;
399*4bdc9457SAndroid Build Coastguard Worker   if (interpreterBuilder(&interpreter) != kTfLiteOk) {
400*4bdc9457SAndroid Build Coastguard Worker     state.SkipWithError("failed to create TFLite interpreter");
401*4bdc9457SAndroid Build Coastguard Worker     return;
402*4bdc9457SAndroid Build Coastguard Worker   }
403*4bdc9457SAndroid Build Coastguard Worker   if (interpreter == nullptr) {
404*4bdc9457SAndroid Build Coastguard Worker     state.SkipWithError("TFLite interpreter is null");
405*4bdc9457SAndroid Build Coastguard Worker     return;
406*4bdc9457SAndroid Build Coastguard Worker   }
407*4bdc9457SAndroid Build Coastguard Worker   interpreter->SetNumThreads(1);
408*4bdc9457SAndroid Build Coastguard Worker 
409*4bdc9457SAndroid Build Coastguard Worker   if (interpreter->AllocateTensors() != kTfLiteOk) {
410*4bdc9457SAndroid Build Coastguard Worker     state.SkipWithError("failed to allocate tensors");
411*4bdc9457SAndroid Build Coastguard Worker     return;
412*4bdc9457SAndroid Build Coastguard Worker   }
413*4bdc9457SAndroid Build Coastguard Worker 
414*4bdc9457SAndroid Build Coastguard Worker   std::generate(
415*4bdc9457SAndroid Build Coastguard Worker     interpreter->typed_tensor<float>(2),
416*4bdc9457SAndroid Build Coastguard Worker     interpreter->typed_tensor<float>(2) + batch_size * input_channels * input_height * input_width,
417*4bdc9457SAndroid Build Coastguard Worker     std::ref(f32rng));
418*4bdc9457SAndroid Build Coastguard Worker 
419*4bdc9457SAndroid Build Coastguard Worker   for (auto _ : state) {
420*4bdc9457SAndroid Build Coastguard Worker     state.PauseTiming();
421*4bdc9457SAndroid Build Coastguard Worker     benchmark::utils::WipeCache();
422*4bdc9457SAndroid Build Coastguard Worker     benchmark::utils::PrefetchToL1(
423*4bdc9457SAndroid Build Coastguard Worker       interpreter->typed_tensor<float>(2),
424*4bdc9457SAndroid Build Coastguard Worker       batch_size * input_channels * input_height * input_width * sizeof(float));
425*4bdc9457SAndroid Build Coastguard Worker     state.ResumeTiming();
426*4bdc9457SAndroid Build Coastguard Worker 
427*4bdc9457SAndroid Build Coastguard Worker     if (interpreter->Invoke() != kTfLiteOk) {
428*4bdc9457SAndroid Build Coastguard Worker       state.SkipWithError("failed to invoke TFLite interpreter");
429*4bdc9457SAndroid Build Coastguard Worker       return;
430*4bdc9457SAndroid Build Coastguard Worker     }
431*4bdc9457SAndroid Build Coastguard Worker   }
432*4bdc9457SAndroid Build Coastguard Worker 
433*4bdc9457SAndroid Build Coastguard Worker   const uint64_t cpu_frequency = benchmark::utils::GetCurrentCpuFrequency();
434*4bdc9457SAndroid Build Coastguard Worker   if (cpu_frequency != 0) {
435*4bdc9457SAndroid Build Coastguard Worker     state.counters["cpufreq"] = cpu_frequency;
436*4bdc9457SAndroid Build Coastguard Worker   }
437*4bdc9457SAndroid Build Coastguard Worker 
438*4bdc9457SAndroid Build Coastguard Worker   state.counters["FLOPS"] = benchmark::Counter(
439*4bdc9457SAndroid Build Coastguard Worker     uint64_t(state.iterations()) * 2 *
440*4bdc9457SAndroid Build Coastguard Worker       batch_size * input_width * input_width *
441*4bdc9457SAndroid Build Coastguard Worker       input_channels * output_channels *
442*4bdc9457SAndroid Build Coastguard Worker       kernel_height * kernel_width,
443*4bdc9457SAndroid Build Coastguard Worker     benchmark::Counter::kIsRate);
444*4bdc9457SAndroid Build Coastguard Worker 
445*4bdc9457SAndroid Build Coastguard Worker   interpreter.reset();
446*4bdc9457SAndroid Build Coastguard Worker }
447*4bdc9457SAndroid Build Coastguard Worker #endif  // BENCHMARK_TENSORFLOW_LITE
448*4bdc9457SAndroid Build Coastguard Worker 
449*4bdc9457SAndroid Build Coastguard Worker // FCN-32 model (PASCAL VOC version).
450*4bdc9457SAndroid Build Coastguard Worker // We assume CIF image (352x288) on model input / output.
FCN32(benchmark::internal::Benchmark * b)451*4bdc9457SAndroid Build Coastguard Worker static void FCN32(benchmark::internal::Benchmark* b) {
452*4bdc9457SAndroid Build Coastguard Worker   b->ArgNames({"N", "H", "W", "KH", "KW", "PH", "PW", "A", "SH", "SW", "D", "Cin", "Cout"});
453*4bdc9457SAndroid Build Coastguard Worker 
454*4bdc9457SAndroid Build Coastguard Worker   /*       N  H   W  KH  KW  PH  PW  A  SH  SW  D  Cin  Cout */
455*4bdc9457SAndroid Build Coastguard Worker   b->Args({1, 9, 11, 64, 64,  0,  0, 0, 32, 32, 1,  21,  21});
456*4bdc9457SAndroid Build Coastguard Worker }
457*4bdc9457SAndroid Build Coastguard Worker 
458*4bdc9457SAndroid Build Coastguard Worker // FCN-16 model (PASCAL VOC version).
459*4bdc9457SAndroid Build Coastguard Worker // We assume CIF image (352x288) on model input / output.
FCN16(benchmark::internal::Benchmark * b)460*4bdc9457SAndroid Build Coastguard Worker static void FCN16(benchmark::internal::Benchmark* b) {
461*4bdc9457SAndroid Build Coastguard Worker   b->ArgNames({"N", "H", "W", "KH", "KW", "PH", "PW", "A", "SH", "SW", "D", "Cin", "Cout"});
462*4bdc9457SAndroid Build Coastguard Worker 
463*4bdc9457SAndroid Build Coastguard Worker   /*       N   H   W  KH  KW  PH  PW  A  SH  SW  D  Cin  Cout */
464*4bdc9457SAndroid Build Coastguard Worker   b->Args({1,  9, 11,  4,  4,  0,  0, 0,  2,  2, 1,  21,  21});
465*4bdc9457SAndroid Build Coastguard Worker   b->Args({1, 18, 22, 32, 32,  0,  0, 0, 16, 16, 1,  21,  21});
466*4bdc9457SAndroid Build Coastguard Worker }
467*4bdc9457SAndroid Build Coastguard Worker 
468*4bdc9457SAndroid Build Coastguard Worker // FCN-8 model (PASCAL VOC version).
469*4bdc9457SAndroid Build Coastguard Worker // We assume CIF image (352x288) on model input / output.
FCN8(benchmark::internal::Benchmark * b)470*4bdc9457SAndroid Build Coastguard Worker static void FCN8(benchmark::internal::Benchmark* b) {
471*4bdc9457SAndroid Build Coastguard Worker   b->ArgNames({"N", "H", "W", "KH", "KW", "PH", "PW", "A", "SH", "SW", "D", "Cin", "Cout"});
472*4bdc9457SAndroid Build Coastguard Worker 
473*4bdc9457SAndroid Build Coastguard Worker   /*       N   H   W  KH  KW  PH  PW  A  SH  SW  D  Cin  Cout */
474*4bdc9457SAndroid Build Coastguard Worker   b->Args({1,  9, 11,  4,  4,  0,  0, 0,  2,  2, 1,  21,  21});
475*4bdc9457SAndroid Build Coastguard Worker   b->Args({1, 18, 22,  4,  4,  0,  0, 0,  2,  2, 1,  21,  21});
476*4bdc9457SAndroid Build Coastguard Worker   b->Args({1, 36, 44, 16, 16,  0,  0, 0,  8,  8, 1,  21,  21});
477*4bdc9457SAndroid Build Coastguard Worker }
478*4bdc9457SAndroid Build Coastguard Worker 
ENet(benchmark::internal::Benchmark * b)479*4bdc9457SAndroid Build Coastguard Worker static void ENet(benchmark::internal::Benchmark* b) {
480*4bdc9457SAndroid Build Coastguard Worker   b->ArgNames({"N", "H", "W", "KH", "KW", "PH", "PW", "A", "SH", "SW", "D", "Cin", "Cout"});
481*4bdc9457SAndroid Build Coastguard Worker 
482*4bdc9457SAndroid Build Coastguard Worker   /*********************** Bottleneck 4.0 ***********************/
483*4bdc9457SAndroid Build Coastguard Worker   /*       N   H    W   KH  KW  PH  PW  A  SH  SW  D  Cin  Cout */
484*4bdc9457SAndroid Build Coastguard Worker   b->Args({1,  64,  64,  3,  3,  2,  2, 1,  2,  2, 1,  32,  32});
485*4bdc9457SAndroid Build Coastguard Worker   /*********************** Bottleneck 5.0 ***********************/
486*4bdc9457SAndroid Build Coastguard Worker   /*       N   H    W   KH  KW  PH  PW  A  SH  SW  D  Cin  Cout */
487*4bdc9457SAndroid Build Coastguard Worker   b->Args({1, 128, 128,  3,  3,  2,  2, 1,  2,  2, 1,  16,  16});
488*4bdc9457SAndroid Build Coastguard Worker   /******************* Final Full Convolution *******************/
489*4bdc9457SAndroid Build Coastguard Worker   /*       N   H    W   KH  KW  PH  PW  A  SH  SH  D  Cin  Cout */
490*4bdc9457SAndroid Build Coastguard Worker   b->Args({1, 256, 256,  2,  2,  0,  0, 0,  2,  2, 1,  16,  12});
491*4bdc9457SAndroid Build Coastguard Worker }
492*4bdc9457SAndroid Build Coastguard Worker 
ESPNet(benchmark::internal::Benchmark * b)493*4bdc9457SAndroid Build Coastguard Worker static void ESPNet(benchmark::internal::Benchmark* b) {
494*4bdc9457SAndroid Build Coastguard Worker   b->ArgNames({"N", "H", "W", "KH", "KW", "PH", "PW", "A", "SH", "SW", "D", "Cin", "Cout"});
495*4bdc9457SAndroid Build Coastguard Worker 
496*4bdc9457SAndroid Build Coastguard Worker   /*       N   H    W   KH  KW  PH  PW  A  SH  SW  D  Cin  Cout */
497*4bdc9457SAndroid Build Coastguard Worker   b->Args({1,  64, 128,  2,  2,  0,  0, 0,  2,  2, 1,  20,  20});
498*4bdc9457SAndroid Build Coastguard Worker   b->Args({1, 128, 256,  2,  2,  0,  0, 0,  2,  2, 1,  20,  20});
499*4bdc9457SAndroid Build Coastguard Worker   b->Args({1, 256, 512,  2,  2,  0,  0, 0,  2,  2, 1,  20,  20});
500*4bdc9457SAndroid Build Coastguard Worker }
501*4bdc9457SAndroid Build Coastguard Worker 
502*4bdc9457SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(xnnpack_deconvolution_f32, fcn32, "FCN-32")
503*4bdc9457SAndroid Build Coastguard Worker   ->Apply(FCN32)
504*4bdc9457SAndroid Build Coastguard Worker   ->UseRealTime();
505*4bdc9457SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(xnnpack_deconvolution_f32, fcn16, "FCN-16")
506*4bdc9457SAndroid Build Coastguard Worker   ->Apply(FCN16)
507*4bdc9457SAndroid Build Coastguard Worker   ->UseRealTime();
508*4bdc9457SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(xnnpack_deconvolution_f32, fcn8, "FCN-8")
509*4bdc9457SAndroid Build Coastguard Worker   ->Apply(FCN8)
510*4bdc9457SAndroid Build Coastguard Worker   ->UseRealTime();
511*4bdc9457SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(xnnpack_deconvolution_f32, enet, "ENet")
512*4bdc9457SAndroid Build Coastguard Worker   ->Apply(ENet)
513*4bdc9457SAndroid Build Coastguard Worker   ->UseRealTime();
514*4bdc9457SAndroid Build Coastguard Worker BENCHMARK_CAPTURE(xnnpack_deconvolution_f32, espnet, "ESPNet")
515*4bdc9457SAndroid Build Coastguard Worker   ->Apply(ESPNet)
516*4bdc9457SAndroid Build Coastguard Worker   ->UseRealTime();
517*4bdc9457SAndroid Build Coastguard Worker 
518*4bdc9457SAndroid Build Coastguard Worker #ifndef XNN_NO_QU8_OPERATORS
519*4bdc9457SAndroid Build Coastguard Worker   BENCHMARK_CAPTURE(xnnpack_deconvolution_qu8, fcn32, "FCN-32")
520*4bdc9457SAndroid Build Coastguard Worker     ->Apply(FCN32)
521*4bdc9457SAndroid Build Coastguard Worker     ->UseRealTime();
522*4bdc9457SAndroid Build Coastguard Worker   BENCHMARK_CAPTURE(xnnpack_deconvolution_qu8, fcn16, "FCN-16")
523*4bdc9457SAndroid Build Coastguard Worker     ->Apply(FCN16)
524*4bdc9457SAndroid Build Coastguard Worker     ->UseRealTime();
525*4bdc9457SAndroid Build Coastguard Worker   BENCHMARK_CAPTURE(xnnpack_deconvolution_qu8, fcn8, "FCN-8")
526*4bdc9457SAndroid Build Coastguard Worker     ->Apply(FCN8)
527*4bdc9457SAndroid Build Coastguard Worker     ->UseRealTime();
528*4bdc9457SAndroid Build Coastguard Worker   BENCHMARK_CAPTURE(xnnpack_deconvolution_qu8, enet, "ENet")
529*4bdc9457SAndroid Build Coastguard Worker     ->Apply(ENet)
530*4bdc9457SAndroid Build Coastguard Worker     ->UseRealTime();
531*4bdc9457SAndroid Build Coastguard Worker   BENCHMARK_CAPTURE(xnnpack_deconvolution_qu8, espnet, "ESPNet")
532*4bdc9457SAndroid Build Coastguard Worker     ->Apply(ESPNet)
533*4bdc9457SAndroid Build Coastguard Worker     ->UseRealTime();
534*4bdc9457SAndroid Build Coastguard Worker #endif  // XNN_NO_QU8_OPERATORS
535*4bdc9457SAndroid Build Coastguard Worker 
536*4bdc9457SAndroid Build Coastguard Worker #ifdef BENCHMARK_TENSORFLOW_LITE
537*4bdc9457SAndroid Build Coastguard Worker   BENCHMARK_CAPTURE(tflite_deconvolution_f32, fcn32, "FCN-32")
538*4bdc9457SAndroid Build Coastguard Worker     ->Apply(FCN32)
539*4bdc9457SAndroid Build Coastguard Worker     ->UseRealTime();
540*4bdc9457SAndroid Build Coastguard Worker   BENCHMARK_CAPTURE(tflite_deconvolution_f32, fcn16, "FCN-16")
541*4bdc9457SAndroid Build Coastguard Worker     ->Apply(FCN16)
542*4bdc9457SAndroid Build Coastguard Worker     ->UseRealTime();
543*4bdc9457SAndroid Build Coastguard Worker   BENCHMARK_CAPTURE(tflite_deconvolution_f32, fcn8, "FCN-8")
544*4bdc9457SAndroid Build Coastguard Worker     ->Apply(FCN8)
545*4bdc9457SAndroid Build Coastguard Worker     ->UseRealTime();
546*4bdc9457SAndroid Build Coastguard Worker   BENCHMARK_CAPTURE(tflite_deconvolution_f32, enet, "ENet")
547*4bdc9457SAndroid Build Coastguard Worker     ->Apply(ENet)
548*4bdc9457SAndroid Build Coastguard Worker     ->UseRealTime();
549*4bdc9457SAndroid Build Coastguard Worker   BENCHMARK_CAPTURE(tflite_deconvolution_f32, espnet, "ESPNet")
550*4bdc9457SAndroid Build Coastguard Worker     ->Apply(ESPNet)
551*4bdc9457SAndroid Build Coastguard Worker     ->UseRealTime();
552*4bdc9457SAndroid Build Coastguard Worker #endif  // BENCHMARK_TENSORFLOW_LITE
553*4bdc9457SAndroid Build Coastguard Worker 
554*4bdc9457SAndroid Build Coastguard Worker #ifndef XNNPACK_BENCHMARK_NO_MAIN
555*4bdc9457SAndroid Build Coastguard Worker BENCHMARK_MAIN();
556*4bdc9457SAndroid Build Coastguard Worker #endif
557