1*c217d954SCole Faust /*
2*c217d954SCole Faust * Copyright (c) 2017-2022 Arm Limited.
3*c217d954SCole Faust *
4*c217d954SCole Faust * SPDX-License-Identifier: MIT
5*c217d954SCole Faust *
6*c217d954SCole Faust * Permission is hereby granted, free of charge, to any person obtaining a copy
7*c217d954SCole Faust * of this software and associated documentation files (the "Software"), to
8*c217d954SCole Faust * deal in the Software without restriction, including without limitation the
9*c217d954SCole Faust * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*c217d954SCole Faust * sell copies of the Software, and to permit persons to whom the Software is
11*c217d954SCole Faust * furnished to do so, subject to the following conditions:
12*c217d954SCole Faust *
13*c217d954SCole Faust * The above copyright notice and this permission notice shall be included in all
14*c217d954SCole Faust * copies or substantial portions of the Software.
15*c217d954SCole Faust *
16*c217d954SCole Faust * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*c217d954SCole Faust * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*c217d954SCole Faust * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*c217d954SCole Faust * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*c217d954SCole Faust * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21*c217d954SCole Faust * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22*c217d954SCole Faust * SOFTWARE.
23*c217d954SCole Faust */
24*c217d954SCole Faust #include "tests/validation/Helpers.h"
25*c217d954SCole Faust
26*c217d954SCole Faust #include <algorithm>
27*c217d954SCole Faust #include <cmath>
28*c217d954SCole Faust
29*c217d954SCole Faust namespace arm_compute
30*c217d954SCole Faust {
31*c217d954SCole Faust namespace test
32*c217d954SCole Faust {
33*c217d954SCole Faust namespace validation
34*c217d954SCole Faust {
35*c217d954SCole Faust template <>
convert_from_asymmetric(const SimpleTensor<uint8_t> & src)36*c217d954SCole Faust SimpleTensor<float> convert_from_asymmetric(const SimpleTensor<uint8_t> &src)
37*c217d954SCole Faust {
38*c217d954SCole Faust const UniformQuantizationInfo &quantization_info = src.quantization_info().uniform();
39*c217d954SCole Faust SimpleTensor<float> dst{ src.shape(), DataType::F32, 1, QuantizationInfo(), src.data_layout() };
40*c217d954SCole Faust #if defined(_OPENMP)
41*c217d954SCole Faust #pragma omp parallel for
42*c217d954SCole Faust #endif /* _OPENMP */
43*c217d954SCole Faust for(int i = 0; i < src.num_elements(); ++i)
44*c217d954SCole Faust {
45*c217d954SCole Faust dst[i] = dequantize_qasymm8(src[i], quantization_info);
46*c217d954SCole Faust }
47*c217d954SCole Faust return dst;
48*c217d954SCole Faust }
49*c217d954SCole Faust
50*c217d954SCole Faust template <>
convert_from_asymmetric(const SimpleTensor<int8_t> & src)51*c217d954SCole Faust SimpleTensor<float> convert_from_asymmetric(const SimpleTensor<int8_t> &src)
52*c217d954SCole Faust {
53*c217d954SCole Faust const UniformQuantizationInfo &quantization_info = src.quantization_info().uniform();
54*c217d954SCole Faust SimpleTensor<float> dst{ src.shape(), DataType::F32, 1, QuantizationInfo(), src.data_layout() };
55*c217d954SCole Faust
56*c217d954SCole Faust #if defined(_OPENMP)
57*c217d954SCole Faust #pragma omp parallel for
58*c217d954SCole Faust #endif /* _OPENMP */
59*c217d954SCole Faust for(int i = 0; i < src.num_elements(); ++i)
60*c217d954SCole Faust {
61*c217d954SCole Faust dst[i] = dequantize_qasymm8_signed(src[i], quantization_info);
62*c217d954SCole Faust }
63*c217d954SCole Faust return dst;
64*c217d954SCole Faust }
65*c217d954SCole Faust
66*c217d954SCole Faust template <>
convert_from_asymmetric(const SimpleTensor<uint16_t> & src)67*c217d954SCole Faust SimpleTensor<float> convert_from_asymmetric(const SimpleTensor<uint16_t> &src)
68*c217d954SCole Faust {
69*c217d954SCole Faust const UniformQuantizationInfo &quantization_info = src.quantization_info().uniform();
70*c217d954SCole Faust SimpleTensor<float> dst{ src.shape(), DataType::F32, 1, QuantizationInfo(), src.data_layout() };
71*c217d954SCole Faust
72*c217d954SCole Faust #if defined(_OPENMP)
73*c217d954SCole Faust #pragma omp parallel for
74*c217d954SCole Faust #endif /* _OPENMP */
75*c217d954SCole Faust for(int i = 0; i < src.num_elements(); ++i)
76*c217d954SCole Faust {
77*c217d954SCole Faust dst[i] = dequantize_qasymm16(src[i], quantization_info);
78*c217d954SCole Faust }
79*c217d954SCole Faust return dst;
80*c217d954SCole Faust }
81*c217d954SCole Faust
82*c217d954SCole Faust template <>
convert_to_asymmetric(const SimpleTensor<float> & src,const QuantizationInfo & quantization_info)83*c217d954SCole Faust SimpleTensor<uint8_t> convert_to_asymmetric(const SimpleTensor<float> &src, const QuantizationInfo &quantization_info)
84*c217d954SCole Faust {
85*c217d954SCole Faust SimpleTensor<uint8_t> dst{ src.shape(), DataType::QASYMM8, 1, quantization_info };
86*c217d954SCole Faust const UniformQuantizationInfo &qinfo = quantization_info.uniform();
87*c217d954SCole Faust
88*c217d954SCole Faust #if defined(_OPENMP)
89*c217d954SCole Faust #pragma omp parallel for
90*c217d954SCole Faust #endif /* _OPENMP */
91*c217d954SCole Faust for(int i = 0; i < src.num_elements(); ++i)
92*c217d954SCole Faust {
93*c217d954SCole Faust dst[i] = quantize_qasymm8(src[i], qinfo);
94*c217d954SCole Faust }
95*c217d954SCole Faust return dst;
96*c217d954SCole Faust }
97*c217d954SCole Faust
98*c217d954SCole Faust template <>
convert_to_asymmetric(const SimpleTensor<float> & src,const QuantizationInfo & quantization_info)99*c217d954SCole Faust SimpleTensor<int8_t> convert_to_asymmetric(const SimpleTensor<float> &src, const QuantizationInfo &quantization_info)
100*c217d954SCole Faust {
101*c217d954SCole Faust SimpleTensor<int8_t> dst{ src.shape(), DataType::QASYMM8_SIGNED, 1, quantization_info };
102*c217d954SCole Faust const UniformQuantizationInfo &qinfo = quantization_info.uniform();
103*c217d954SCole Faust
104*c217d954SCole Faust #if defined(_OPENMP)
105*c217d954SCole Faust #pragma omp parallel for
106*c217d954SCole Faust #endif /* _OPENMP */
107*c217d954SCole Faust for(int i = 0; i < src.num_elements(); ++i)
108*c217d954SCole Faust {
109*c217d954SCole Faust dst[i] = quantize_qasymm8_signed(src[i], qinfo);
110*c217d954SCole Faust }
111*c217d954SCole Faust return dst;
112*c217d954SCole Faust }
113*c217d954SCole Faust
114*c217d954SCole Faust template <>
convert_to_asymmetric(const SimpleTensor<float> & src,const QuantizationInfo & quantization_info)115*c217d954SCole Faust SimpleTensor<uint16_t> convert_to_asymmetric(const SimpleTensor<float> &src, const QuantizationInfo &quantization_info)
116*c217d954SCole Faust {
117*c217d954SCole Faust SimpleTensor<uint16_t> dst{ src.shape(), DataType::QASYMM16, 1, quantization_info };
118*c217d954SCole Faust const UniformQuantizationInfo &qinfo = quantization_info.uniform();
119*c217d954SCole Faust
120*c217d954SCole Faust #if defined(_OPENMP)
121*c217d954SCole Faust #pragma omp parallel for
122*c217d954SCole Faust #endif /* _OPENMP */
123*c217d954SCole Faust for(int i = 0; i < src.num_elements(); ++i)
124*c217d954SCole Faust {
125*c217d954SCole Faust dst[i] = quantize_qasymm16(src[i], qinfo);
126*c217d954SCole Faust }
127*c217d954SCole Faust return dst;
128*c217d954SCole Faust }
129*c217d954SCole Faust
130*c217d954SCole Faust template <>
convert_to_symmetric(const SimpleTensor<float> & src,const QuantizationInfo & quantization_info)131*c217d954SCole Faust SimpleTensor<int16_t> convert_to_symmetric(const SimpleTensor<float> &src, const QuantizationInfo &quantization_info)
132*c217d954SCole Faust {
133*c217d954SCole Faust SimpleTensor<int16_t> dst{ src.shape(), DataType::QSYMM16, 1, quantization_info };
134*c217d954SCole Faust const UniformQuantizationInfo &qinfo = quantization_info.uniform();
135*c217d954SCole Faust
136*c217d954SCole Faust #if defined(_OPENMP)
137*c217d954SCole Faust #pragma omp parallel for
138*c217d954SCole Faust #endif /* _OPENMP */
139*c217d954SCole Faust for(int i = 0; i < src.num_elements(); ++i)
140*c217d954SCole Faust {
141*c217d954SCole Faust dst[i] = quantize_qsymm16(src[i], qinfo);
142*c217d954SCole Faust }
143*c217d954SCole Faust return dst;
144*c217d954SCole Faust }
145*c217d954SCole Faust
146*c217d954SCole Faust template <>
convert_from_symmetric(const SimpleTensor<int16_t> & src)147*c217d954SCole Faust SimpleTensor<float> convert_from_symmetric(const SimpleTensor<int16_t> &src)
148*c217d954SCole Faust {
149*c217d954SCole Faust const UniformQuantizationInfo &quantization_info = src.quantization_info().uniform();
150*c217d954SCole Faust SimpleTensor<float> dst{ src.shape(), DataType::F32, 1, QuantizationInfo(), src.data_layout() };
151*c217d954SCole Faust
152*c217d954SCole Faust #if defined(_OPENMP)
153*c217d954SCole Faust #pragma omp parallel for
154*c217d954SCole Faust #endif /* _OPENMP */
155*c217d954SCole Faust for(int i = 0; i < src.num_elements(); ++i)
156*c217d954SCole Faust {
157*c217d954SCole Faust dst[i] = dequantize_qsymm16(src[i], quantization_info);
158*c217d954SCole Faust }
159*c217d954SCole Faust return dst;
160*c217d954SCole Faust }
161*c217d954SCole Faust
162*c217d954SCole Faust template <typename T>
matrix_multiply(const SimpleTensor<T> & a,const SimpleTensor<T> & b,SimpleTensor<T> & out)163*c217d954SCole Faust void matrix_multiply(const SimpleTensor<T> &a, const SimpleTensor<T> &b, SimpleTensor<T> &out)
164*c217d954SCole Faust {
165*c217d954SCole Faust ARM_COMPUTE_ERROR_ON(a.shape()[0] != b.shape()[1]);
166*c217d954SCole Faust ARM_COMPUTE_ERROR_ON(a.shape()[1] != out.shape()[1]);
167*c217d954SCole Faust ARM_COMPUTE_ERROR_ON(b.shape()[0] != out.shape()[0]);
168*c217d954SCole Faust
169*c217d954SCole Faust const int M = a.shape()[1]; // Rows
170*c217d954SCole Faust const int N = b.shape()[0]; // Cols
171*c217d954SCole Faust const int K = b.shape()[1];
172*c217d954SCole Faust
173*c217d954SCole Faust #if defined(_OPENMP)
174*c217d954SCole Faust #pragma omp parallel for collapse(2)
175*c217d954SCole Faust #endif /* _OPENMP */
176*c217d954SCole Faust for(int y = 0; y < M; ++y)
177*c217d954SCole Faust {
178*c217d954SCole Faust for(int x = 0; x < N; ++x)
179*c217d954SCole Faust {
180*c217d954SCole Faust float acc = 0.0f;
181*c217d954SCole Faust for(int k = 0; k < K; ++k)
182*c217d954SCole Faust {
183*c217d954SCole Faust acc += a[y * K + k] * b[x + k * N];
184*c217d954SCole Faust }
185*c217d954SCole Faust
186*c217d954SCole Faust out[x + y * N] = acc;
187*c217d954SCole Faust }
188*c217d954SCole Faust }
189*c217d954SCole Faust }
190*c217d954SCole Faust
191*c217d954SCole Faust template <typename T>
transpose_matrix(const SimpleTensor<T> & in,SimpleTensor<T> & out)192*c217d954SCole Faust void transpose_matrix(const SimpleTensor<T> &in, SimpleTensor<T> &out)
193*c217d954SCole Faust {
194*c217d954SCole Faust ARM_COMPUTE_ERROR_ON((in.shape()[0] != out.shape()[1]) || (in.shape()[1] != out.shape()[0]));
195*c217d954SCole Faust
196*c217d954SCole Faust const int width = in.shape()[0];
197*c217d954SCole Faust const int height = in.shape()[1];
198*c217d954SCole Faust
199*c217d954SCole Faust #if defined(_OPENMP)
200*c217d954SCole Faust #pragma omp parallel for collapse(2)
201*c217d954SCole Faust #endif /* _OPENMP */
202*c217d954SCole Faust for(int y = 0; y < height; ++y)
203*c217d954SCole Faust {
204*c217d954SCole Faust for(int x = 0; x < width; ++x)
205*c217d954SCole Faust {
206*c217d954SCole Faust const T val = in[x + y * width];
207*c217d954SCole Faust
208*c217d954SCole Faust out[x * height + y] = val;
209*c217d954SCole Faust }
210*c217d954SCole Faust }
211*c217d954SCole Faust }
212*c217d954SCole Faust
213*c217d954SCole Faust template <typename T>
get_tile(const SimpleTensor<T> & in,SimpleTensor<T> & tile,const Coordinates & coord)214*c217d954SCole Faust void get_tile(const SimpleTensor<T> &in, SimpleTensor<T> &tile, const Coordinates &coord)
215*c217d954SCole Faust {
216*c217d954SCole Faust ARM_COMPUTE_ERROR_ON(tile.shape().num_dimensions() > 2);
217*c217d954SCole Faust
218*c217d954SCole Faust const int w_tile = tile.shape()[0];
219*c217d954SCole Faust const int h_tile = tile.shape()[1];
220*c217d954SCole Faust
221*c217d954SCole Faust // Fill the tile with zeros
222*c217d954SCole Faust std::fill(tile.data() + 0, (tile.data() + (w_tile * h_tile)), static_cast<T>(0));
223*c217d954SCole Faust
224*c217d954SCole Faust // Check if with the dimensions greater than 2 we could have out-of-bound reads
225*c217d954SCole Faust for(size_t d = 2; d < Coordinates::num_max_dimensions; ++d)
226*c217d954SCole Faust {
227*c217d954SCole Faust if(coord[d] < 0 || coord[d] >= static_cast<int>(in.shape()[d]))
228*c217d954SCole Faust {
229*c217d954SCole Faust ARM_COMPUTE_ERROR("coord[d] < 0 || coord[d] >= in.shape()[d] with d >= 2");
230*c217d954SCole Faust }
231*c217d954SCole Faust }
232*c217d954SCole Faust
233*c217d954SCole Faust // Since we could have out-of-bound reads along the X and Y dimensions,
234*c217d954SCole Faust // we start calculating the input address with x = 0 and y = 0
235*c217d954SCole Faust Coordinates start_coord = coord;
236*c217d954SCole Faust start_coord[0] = 0;
237*c217d954SCole Faust start_coord[1] = 0;
238*c217d954SCole Faust
239*c217d954SCole Faust // Get input and roi pointers
240*c217d954SCole Faust auto in_ptr = static_cast<const T *>(in(start_coord));
241*c217d954SCole Faust auto roi_ptr = static_cast<T *>(tile.data());
242*c217d954SCole Faust
243*c217d954SCole Faust const int x_in_start = std::max(0, coord[0]);
244*c217d954SCole Faust const int y_in_start = std::max(0, coord[1]);
245*c217d954SCole Faust const int x_in_end = std::min(static_cast<int>(in.shape()[0]), coord[0] + w_tile);
246*c217d954SCole Faust const int y_in_end = std::min(static_cast<int>(in.shape()[1]), coord[1] + h_tile);
247*c217d954SCole Faust
248*c217d954SCole Faust // Number of elements to copy per row
249*c217d954SCole Faust const int n = x_in_end - x_in_start;
250*c217d954SCole Faust
251*c217d954SCole Faust // Starting coordinates for the ROI
252*c217d954SCole Faust const int x_tile_start = coord[0] > 0 ? 0 : std::abs(coord[0]);
253*c217d954SCole Faust const int y_tile_start = coord[1] > 0 ? 0 : std::abs(coord[1]);
254*c217d954SCole Faust
255*c217d954SCole Faust // Update input pointer
256*c217d954SCole Faust in_ptr += x_in_start;
257*c217d954SCole Faust in_ptr += (y_in_start * in.shape()[0]);
258*c217d954SCole Faust
259*c217d954SCole Faust // Update ROI pointer
260*c217d954SCole Faust roi_ptr += x_tile_start;
261*c217d954SCole Faust roi_ptr += (y_tile_start * tile.shape()[0]);
262*c217d954SCole Faust
263*c217d954SCole Faust for(int y = y_in_start; y < y_in_end; ++y)
264*c217d954SCole Faust {
265*c217d954SCole Faust // Copy per row
266*c217d954SCole Faust std::copy(in_ptr, in_ptr + n, roi_ptr);
267*c217d954SCole Faust
268*c217d954SCole Faust in_ptr += in.shape()[0];
269*c217d954SCole Faust roi_ptr += tile.shape()[0];
270*c217d954SCole Faust }
271*c217d954SCole Faust }
272*c217d954SCole Faust
273*c217d954SCole Faust template <typename T>
zeros(SimpleTensor<T> & in,const Coordinates & anchor,const TensorShape & shape)274*c217d954SCole Faust void zeros(SimpleTensor<T> &in, const Coordinates &anchor, const TensorShape &shape)
275*c217d954SCole Faust {
276*c217d954SCole Faust ARM_COMPUTE_ERROR_ON(anchor.num_dimensions() != shape.num_dimensions());
277*c217d954SCole Faust ARM_COMPUTE_ERROR_ON(in.shape().num_dimensions() > 2);
278*c217d954SCole Faust ARM_COMPUTE_ERROR_ON(shape.num_dimensions() > 2);
279*c217d954SCole Faust
280*c217d954SCole Faust // Check if with the dimensions greater than 2 we could have out-of-bound reads
281*c217d954SCole Faust for(size_t d = 0; d < Coordinates::num_max_dimensions; ++d)
282*c217d954SCole Faust {
283*c217d954SCole Faust if(anchor[d] < 0 || ((anchor[d] + shape[d]) > in.shape()[d]))
284*c217d954SCole Faust {
285*c217d954SCole Faust ARM_COMPUTE_ERROR("anchor[d] < 0 || (anchor[d] + shape[d]) > in.shape()[d]");
286*c217d954SCole Faust }
287*c217d954SCole Faust }
288*c217d954SCole Faust
289*c217d954SCole Faust // Get input pointer
290*c217d954SCole Faust auto in_ptr = static_cast<T *>(in(anchor[0] + anchor[1] * in.shape()[0]));
291*c217d954SCole Faust
292*c217d954SCole Faust const unsigned int n = in.shape()[0];
293*c217d954SCole Faust
294*c217d954SCole Faust for(unsigned int y = 0; y < shape[1]; ++y)
295*c217d954SCole Faust {
296*c217d954SCole Faust std::fill(in_ptr, in_ptr + shape[0], 0);
297*c217d954SCole Faust in_ptr += n;
298*c217d954SCole Faust }
299*c217d954SCole Faust }
300*c217d954SCole Faust
get_quantized_bounds(const QuantizationInfo & quant_info,float min,float max)301*c217d954SCole Faust std::pair<int, int> get_quantized_bounds(const QuantizationInfo &quant_info, float min, float max)
302*c217d954SCole Faust {
303*c217d954SCole Faust ARM_COMPUTE_ERROR_ON_MSG(min > max, "min must be lower equal than max");
304*c217d954SCole Faust
305*c217d954SCole Faust const int min_bound = quantize_qasymm8(min, quant_info.uniform());
306*c217d954SCole Faust const int max_bound = quantize_qasymm8(max, quant_info.uniform());
307*c217d954SCole Faust return std::pair<int, int> { min_bound, max_bound };
308*c217d954SCole Faust }
309*c217d954SCole Faust
get_quantized_qasymm8_signed_bounds(const QuantizationInfo & quant_info,float min,float max)310*c217d954SCole Faust std::pair<int, int> get_quantized_qasymm8_signed_bounds(const QuantizationInfo &quant_info, float min, float max)
311*c217d954SCole Faust {
312*c217d954SCole Faust ARM_COMPUTE_ERROR_ON_MSG(min > max, "min must be lower equal than max");
313*c217d954SCole Faust
314*c217d954SCole Faust const int min_bound = quantize_qasymm8_signed(min, quant_info.uniform());
315*c217d954SCole Faust const int max_bound = quantize_qasymm8_signed(max, quant_info.uniform());
316*c217d954SCole Faust return std::pair<int, int> { min_bound, max_bound };
317*c217d954SCole Faust }
318*c217d954SCole Faust
get_symm_quantized_per_channel_bounds(const QuantizationInfo & quant_info,float min,float max,size_t channel_id)319*c217d954SCole Faust std::pair<int, int> get_symm_quantized_per_channel_bounds(const QuantizationInfo &quant_info, float min, float max, size_t channel_id)
320*c217d954SCole Faust {
321*c217d954SCole Faust ARM_COMPUTE_ERROR_ON_MSG(min > max, "min must be lower equal than max");
322*c217d954SCole Faust
323*c217d954SCole Faust const int min_bound = quantize_qsymm8_per_channel(min, quant_info, channel_id);
324*c217d954SCole Faust const int max_bound = quantize_qsymm8_per_channel(max, quant_info, channel_id);
325*c217d954SCole Faust return std::pair<int, int> { min_bound, max_bound };
326*c217d954SCole Faust }
327*c217d954SCole Faust
add_padding_x(std::initializer_list<ITensor * > tensors,const DataLayout & data_layout,bool only_right_pad)328*c217d954SCole Faust void add_padding_x(std::initializer_list<ITensor *> tensors, const DataLayout &data_layout, bool only_right_pad)
329*c217d954SCole Faust {
330*c217d954SCole Faust if(data_layout == DataLayout::NHWC)
331*c217d954SCole Faust {
332*c217d954SCole Faust constexpr unsigned int lower = 1U;
333*c217d954SCole Faust constexpr unsigned int upper = 16U;
334*c217d954SCole Faust
335*c217d954SCole Faust std::uniform_int_distribution<unsigned int> distribution(lower, upper);
336*c217d954SCole Faust size_t seed_offset = 0;
337*c217d954SCole Faust
338*c217d954SCole Faust for(ITensor *tensor : tensors)
339*c217d954SCole Faust {
340*c217d954SCole Faust ARM_COMPUTE_ERROR_ON(!tensor->info()->is_resizable());
341*c217d954SCole Faust
342*c217d954SCole Faust std::mt19937 gen(library->seed() + seed_offset++);
343*c217d954SCole Faust
344*c217d954SCole Faust const unsigned int right = distribution(gen);
345*c217d954SCole Faust const unsigned int left = only_right_pad ? 0 : distribution(gen);
346*c217d954SCole Faust
347*c217d954SCole Faust tensor->info()->extend_padding(PaddingSize(0U, right, 0U, left));
348*c217d954SCole Faust }
349*c217d954SCole Faust }
350*c217d954SCole Faust }
351*c217d954SCole Faust
add_padding_y(std::initializer_list<ITensor * > tensors,const DataLayout & data_layout)352*c217d954SCole Faust void add_padding_y(std::initializer_list<ITensor *> tensors, const DataLayout &data_layout)
353*c217d954SCole Faust {
354*c217d954SCole Faust if(data_layout == DataLayout::NHWC)
355*c217d954SCole Faust {
356*c217d954SCole Faust constexpr unsigned int lower = 1U;
357*c217d954SCole Faust constexpr unsigned int upper = 4U;
358*c217d954SCole Faust
359*c217d954SCole Faust std::uniform_int_distribution<unsigned int> distribution(lower, upper);
360*c217d954SCole Faust size_t seed_offset = 0;
361*c217d954SCole Faust
362*c217d954SCole Faust for(ITensor *tensor : tensors)
363*c217d954SCole Faust {
364*c217d954SCole Faust ARM_COMPUTE_ERROR_ON(!tensor->info()->is_resizable());
365*c217d954SCole Faust
366*c217d954SCole Faust std::mt19937 gen(library->seed() + seed_offset++);
367*c217d954SCole Faust
368*c217d954SCole Faust const unsigned int top = distribution(gen);
369*c217d954SCole Faust const unsigned int bottom = distribution(gen);
370*c217d954SCole Faust
371*c217d954SCole Faust tensor->info()->extend_padding(PaddingSize(top, 0U, bottom, 0U));
372*c217d954SCole Faust }
373*c217d954SCole Faust }
374*c217d954SCole Faust }
375*c217d954SCole Faust
376*c217d954SCole Faust template void get_tile(const SimpleTensor<float> &in, SimpleTensor<float> &roi, const Coordinates &coord);
377*c217d954SCole Faust template void get_tile(const SimpleTensor<half> &in, SimpleTensor<half> &roi, const Coordinates &coord);
378*c217d954SCole Faust template void get_tile(const SimpleTensor<int> &in, SimpleTensor<int> &roi, const Coordinates &coord);
379*c217d954SCole Faust template void get_tile(const SimpleTensor<short> &in, SimpleTensor<short> &roi, const Coordinates &coord);
380*c217d954SCole Faust template void get_tile(const SimpleTensor<char> &in, SimpleTensor<char> &roi, const Coordinates &coord);
381*c217d954SCole Faust template void zeros(SimpleTensor<float> &in, const Coordinates &anchor, const TensorShape &shape);
382*c217d954SCole Faust template void zeros(SimpleTensor<half> &in, const Coordinates &anchor, const TensorShape &shape);
383*c217d954SCole Faust template void transpose_matrix(const SimpleTensor<float> &in, SimpleTensor<float> &out);
384*c217d954SCole Faust template void transpose_matrix(const SimpleTensor<half> &in, SimpleTensor<half> &out);
385*c217d954SCole Faust template void transpose_matrix(const SimpleTensor<int> &in, SimpleTensor<int> &out);
386*c217d954SCole Faust template void transpose_matrix(const SimpleTensor<short> &in, SimpleTensor<short> &out);
387*c217d954SCole Faust template void transpose_matrix(const SimpleTensor<char> &in, SimpleTensor<char> &out);
388*c217d954SCole Faust template void transpose_matrix(const SimpleTensor<int8_t> &in, SimpleTensor<int8_t> &out);
389*c217d954SCole Faust template void transpose_matrix(const SimpleTensor<uint8_t> &in, SimpleTensor<uint8_t> &out);
390*c217d954SCole Faust template void matrix_multiply(const SimpleTensor<float> &a, const SimpleTensor<float> &b, SimpleTensor<float> &out);
391*c217d954SCole Faust template void matrix_multiply(const SimpleTensor<half> &a, const SimpleTensor<half> &b, SimpleTensor<half> &out);
392*c217d954SCole Faust
393*c217d954SCole Faust } // namespace validation
394*c217d954SCole Faust } // namespace test
395*c217d954SCole Faust } // namespace arm_compute
396