xref: /aosp_15_r20/external/ComputeLibrary/tests/validation/Helpers.cpp (revision c217d954acce2dbc11938adb493fc0abd69584f3)
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