diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/validation/reference/PadLayer.cpp | 104 | ||||
-rw-r--r-- | tests/validation/reference/PadLayer.h | 10 |
2 files changed, 91 insertions, 23 deletions
diff --git a/tests/validation/reference/PadLayer.cpp b/tests/validation/reference/PadLayer.cpp index b9a93ddaff..d072bc529b 100644 --- a/tests/validation/reference/PadLayer.cpp +++ b/tests/validation/reference/PadLayer.cpp @@ -36,27 +36,27 @@ namespace validation namespace reference { template <typename T> -SimpleTensor<T> pad_layer(const SimpleTensor<T> &src, const PaddingList &paddings) +SimpleTensor<T> pad_layer(const SimpleTensor<T> &src, const PaddingList &paddings, const PixelValue const_value, const PaddingMode mode) { - DataType dst_data_type = src.data_type(); + const DataType dst_data_type = src.data_type(); - TensorShape orig_shape = src.shape(); + const TensorShape orig_shape = src.shape(); std::vector<PaddingInfo> paddings_extended = paddings; - for(size_t i = paddings.size(); i < TensorShape::num_max_dimensions; i++) + for(size_t i = paddings.size(); i < TensorShape::num_max_dimensions; ++i) { paddings_extended.emplace_back(PaddingInfo{ 0, 0 }); } - TensorShape padded_shape = misc::shape_calculator::compute_padded_shape(orig_shape, paddings); + const TensorShape padded_shape = misc::shape_calculator::compute_padded_shape(orig_shape, paddings); SimpleTensor<T> dst(padded_shape, dst_data_type); // Reference algorithm: loop over the different dimension of the input. - for(int idx = 0; idx < dst.num_elements(); idx++) + for(int idx = 0; idx < dst.num_elements(); ++idx) { - Coordinates coord = index2coord(padded_shape, idx); + const Coordinates coord = index2coord(padded_shape, idx); const size_t i = coord.x(); const size_t j = coord.y(); @@ -65,23 +65,89 @@ SimpleTensor<T> pad_layer(const SimpleTensor<T> &src, const PaddingList &padding const size_t m = coord[4]; const size_t n = coord[5]; - std::array<size_t, TensorShape::num_max_dimensions> dims = { { 0, 1, 2, 3, 4, 5 } }; - std::array<size_t, TensorShape::num_max_dimensions> coords = { { i, j, k, l, m, n } }; + const std::array<size_t, TensorShape::num_max_dimensions> dims = { { 0, 1, 2, 3, 4, 5 } }; + const std::array<size_t, TensorShape::num_max_dimensions> coords = { { i, j, k, l, m, n } }; auto is_padding_area = [&](size_t i) { return (coords[i] < paddings_extended[i].first || coords[i] > orig_shape[i] + paddings_extended[i].first - 1); }; - // If the tuple [i,j,k,l,m] is in the padding area, then seimply set the value + auto orig_coord_reflect = [&](size_t i) + { + if(is_padding_area(i)) + { + if(coords[i] < paddings_extended[i].first) + { + return paddings_extended[i].first - coords[i]; + } + else + { + return 2 * orig_shape[i] + paddings_extended[i].first - 2 - coords[i]; + } + } + return coords[i] - paddings_extended[i].first; + }; + + auto orig_coord_symm = [&](size_t i) + { + if(is_padding_area(i)) + { + if(coords[i] < paddings_extended[i].first) + { + return paddings_extended[i].first - coords[i] - 1; + } + else + { + return 2 * orig_shape[i] + paddings_extended[i].first - 1 - coords[i]; + } + } + return coords[i] - paddings_extended[i].first; + }; + + // If the tuple [i,j,k,l,m] is in the padding area, then simply set the value if(std::any_of(dims.begin(), dims.end(), is_padding_area)) { - dst[idx] = T(0); + switch(mode) + { + case PaddingMode::CONSTANT: + const_value.get(dst[idx]); + break; + case PaddingMode::REFLECT: + { + const Coordinates orig_coords{ orig_coord_reflect(0), + orig_coord_reflect(1), + orig_coord_reflect(2), + orig_coord_reflect(3), + orig_coord_reflect(4), + orig_coord_reflect(5) }; + + const size_t idx_src = coord2index(orig_shape, orig_coords); + dst[idx] = src[idx_src]; + break; + } + case PaddingMode::SYMMETRIC: + { + const Coordinates orig_coords{ orig_coord_symm(0), + orig_coord_symm(1), + orig_coord_symm(2), + orig_coord_symm(3), + orig_coord_symm(4), + orig_coord_symm(5) }; + + const size_t idx_src = coord2index(orig_shape, orig_coords); + dst[idx] = src[idx_src]; + break; + } + default: + ARM_COMPUTE_ERROR("Padding mode not supported."); + break; + } } else { // If the tuple[i,j,k,l,m] is not in the padding area, then copy the input into the output - Coordinates orig_coords{ i - paddings_extended[0].first, + const Coordinates orig_coords{ i - paddings_extended[0].first, j - paddings_extended[1].first, k - paddings_extended[2].first, l - paddings_extended[3].first, @@ -96,13 +162,13 @@ SimpleTensor<T> pad_layer(const SimpleTensor<T> &src, const PaddingList &padding return dst; } -template SimpleTensor<float> pad_layer(const SimpleTensor<float> &src, const PaddingList &paddings); -template SimpleTensor<half> pad_layer(const SimpleTensor<half> &src, const PaddingList &paddings); -template SimpleTensor<uint32_t> pad_layer(const SimpleTensor<uint32_t> &src, const PaddingList &paddings); -template SimpleTensor<uint8_t> pad_layer(const SimpleTensor<uint8_t> &src, const PaddingList &paddings); -template SimpleTensor<int8_t> pad_layer(const SimpleTensor<int8_t> &src, const PaddingList &paddings); -template SimpleTensor<uint16_t> pad_layer(const SimpleTensor<uint16_t> &src, const PaddingList &paddings); -template SimpleTensor<int16_t> pad_layer(const SimpleTensor<int16_t> &src, const PaddingList &paddings); +template SimpleTensor<float> pad_layer(const SimpleTensor<float> &src, const PaddingList &paddings, const PixelValue const_value = PixelValue(), const PaddingMode mode); +template SimpleTensor<half> pad_layer(const SimpleTensor<half> &src, const PaddingList &paddings, const PixelValue const_value = PixelValue(), const PaddingMode mode); +template SimpleTensor<uint32_t> pad_layer(const SimpleTensor<uint32_t> &src, const PaddingList &paddings, const PixelValue const_value = PixelValue(), const PaddingMode mode); +template SimpleTensor<uint8_t> pad_layer(const SimpleTensor<uint8_t> &src, const PaddingList &paddings, const PixelValue const_value = PixelValue(), const PaddingMode mode); +template SimpleTensor<int8_t> pad_layer(const SimpleTensor<int8_t> &src, const PaddingList &paddings, const PixelValue const_value = PixelValue(), const PaddingMode mode); +template SimpleTensor<uint16_t> pad_layer(const SimpleTensor<uint16_t> &src, const PaddingList &paddings, const PixelValue const_value = PixelValue(), const PaddingMode mode); +template SimpleTensor<int16_t> pad_layer(const SimpleTensor<int16_t> &src, const PaddingList &paddings, const PixelValue const_value = PixelValue(), const PaddingMode mode); } // namespace reference } // namespace validation } // namespace test diff --git a/tests/validation/reference/PadLayer.h b/tests/validation/reference/PadLayer.h index 9406b05c4d..5ebb5edf5e 100644 --- a/tests/validation/reference/PadLayer.h +++ b/tests/validation/reference/PadLayer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 ARM Limited. + * Copyright (c) 2018-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -39,13 +39,15 @@ namespace reference /** Reference function to pad an ND tensor. This function is not supposed to be optimized, but to * clearly and naively execute the padding of a tensor * - * @param[in] src Tensor to pad - * @param[in] paddings Padding size in each dimension + * @param[in] src Tensor to pad + * @param[in] paddings Padding size in each dimension + * @param[in] const_value Constant value to fill padding with + * @param[in] mode [optional] Padding mode to use * * @return The padded Tensor */ template <typename T> -SimpleTensor<T> pad_layer(const SimpleTensor<T> &src, const PaddingList &paddings); +SimpleTensor<T> pad_layer(const SimpleTensor<T> &src, const PaddingList &paddings, const PixelValue const_value = PixelValue(), const PaddingMode mode = PaddingMode::CONSTANT); } // namespace reference } // namespace validation } // namespace test |