Compute Library
 23.05
SliceOperations.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2020 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #include "SliceOperations.h"
25 
28 
29 namespace arm_compute
30 {
31 namespace test
32 {
33 namespace validation
34 {
35 namespace reference
36 {
37 template <typename T>
39 {
41 
42  // Validation checks
43  ARM_COMPUTE_ERROR_ON(src.shape().num_dimensions() > 4);
44  ARM_COMPUTE_ERROR_ON(starts.num_dimensions() > src.shape().num_dimensions());
45  ARM_COMPUTE_ERROR_ON(std::any_of(starts.cbegin(), starts.cbegin() + starts.num_dimensions(), [](int i)
46  {
47  return i < 0;
48  }));
49  ARM_COMPUTE_ERROR_ON(ends.num_dimensions() > src.shape().num_dimensions());
50 
51  // Get source shape
52  const TensorShape &src_shape = src.shape();
53 
54  // Get destination shape
56 
57  // Create destination tensor
59 
60  // Perform slice
61  Window win;
62  win.use_tensor_dimensions(dst_shape);
63  execute_window_loop(win, [&](const Coordinates & id)
64  {
66  for(unsigned int i = 0; i < id.num_dimensions(); ++i)
67  {
68  offset.set(i, starts[i] + id[i]);
69  }
70  *reinterpret_cast<T *>(dst(id)) = *reinterpret_cast<const T *>(src(offset));
71  });
72 
73  return dst;
74 }
75 
78 
79 template <typename T>
81  Coordinates starts, Coordinates ends, BiStrides strides,
82  int32_t begin_mask, int32_t end_mask, int32_t shrink_axis_mask)
83 {
85 
86  // Validation checks
87  ARM_COMPUTE_ERROR_ON(src.shape().num_dimensions() > 4);
88  ARM_COMPUTE_ERROR_ON(starts.num_dimensions() > src.shape().num_dimensions());
89  ARM_COMPUTE_ERROR_ON(ends.num_dimensions() > src.shape().num_dimensions());
90  ARM_COMPUTE_ERROR_ON(strides.num_dimensions() > src.shape().num_dimensions());
91  ARM_COMPUTE_ERROR_ON(std::any_of(strides.cbegin(), strides.cbegin() + strides.num_dimensions(), [](int i)
92  {
93  return i == 0;
94  }));
95 
96  // Get source shape
97  const TensorShape &src_shape = src.shape();
98 
99  // Get destination shape
100  const TensorShape dst_shape = compute_strided_slice_output_shape(src_shape, starts, ends, strides, begin_mask, end_mask, shrink_axis_mask);
101 
102  // Create destination tensor
103  SimpleTensor<T> dst{ dst_shape, src.data_type(), 1 };
104 
105  // Get coordinates
106  Coordinates starts_abs{};
107  Coordinates ends_abs{};
108  Coordinates final_strides{};
109  std::tie(starts_abs, ends_abs, final_strides) = calculate_strided_slice_coords(src_shape,
110  starts, ends, strides,
111  begin_mask, end_mask, shrink_axis_mask);
112 
113  // Perform strided slice
114  unsigned int idx = 0;
115  Window win;
117  starts, ends, strides,
118  begin_mask, end_mask, shrink_axis_mask, true));
119  execute_window_loop(win, [&](const Coordinates & id)
120  {
122  for(unsigned int i = 0; i < id.num_dimensions(); ++i)
123  {
124  offset.set(i, starts_abs[i] + id[i] * final_strides[i]);
125  }
126  dst.data()[idx++] = *reinterpret_cast<const T *>(src(offset));
127  });
128 
129  return dst;
130 }
131 
133  Coordinates starts, Coordinates ends, BiStrides strides,
134  int32_t begin_mask, int32_t end_mask, int32_t shrink_axis_mask);
136  Coordinates starts, Coordinates ends, BiStrides strides,
137  int32_t begin_mask, int32_t end_mask, int32_t shrink_axis_mask);
138 } // namespace reference
139 } // namespace validation
140 } // namespace test
141 } // namespace arm_compute
void set(size_t dimension, T value, bool increase_dim_unit=true)
Accessor to set the value of one of the dimensions.
Definition: Dimensions.h:76
__global uchar * offset(const Image *img, int x, int y)
Get the pointer position of a Image.
Definition: helpers.h:1110
std::tuple< Coordinates, Coordinates, Coordinates > calculate_strided_slice_coords(TensorShape input_shape, Coordinates starts, Coordinates ends, Coordinates strides, int32_t begin_mask=0, int32_t end_mask=0, int32_t shrink_axis_mask=0)
Calculate start, end and stride coordinates for a strided slice.
TensorShape compute_slice_shape(const TensorShape &input_shape, const Coordinates &starts, const Coordinates &ends)
Calculate the slice output shape of a tensor.
Shape of a tensor.
Definition: TensorShape.h:39
DataType data_type() const override
Data type of the tensor.
Definition: SimpleTensor.h:373
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:466
TensorShape shape() const override
Shape of the tensor.
Definition: SimpleTensor.h:329
void use_tensor_dimensions(const TensorShape &shape, size_t first_dimension=Window::DimX)
Use the tensor&#39;s dimensions to fill the window dimensions.
Definition: Window.inl:276
SimpleTensor< float > src
Definition: DFT.cpp:155
Copyright (c) 2017-2023 Arm Limited.
Coordinates of an item.
Definition: Coordinates.h:37
SimpleTensor< T > strided_slice(const SimpleTensor< T > &src, Coordinates starts, Coordinates ends, BiStrides strides, int32_t begin_mask, int32_t end_mask, int32_t shrink_axis_mask)
Simple tensor object that stores elements in a consecutive chunk of memory.
Definition: SimpleTensor.h:58
std::array< T, num_max_dimensions >::const_iterator cbegin() const
Returns a read-only (constant) iterator that points to the first element in the dimension array...
Definition: Dimensions.h:231
unsigned int num_dimensions() const
Returns the effective dimensionality of the tensor.
Definition: Dimensions.h:143
void execute_window_loop(const Window &w, L &&lambda_function, Ts &&... iterators)
Iterate through the passed window, automatically adjusting the iterators and calling the lambda_funct...
Definition: Helpers.inl:77
Describe a multidimensional execution window.
Definition: Window.h:39
SimpleTensor< T > slice(const SimpleTensor< T > &src, Coordinates starts, Coordinates ends)
TensorShape compute_strided_slice_output_shape(TensorShape input_shape, Coordinates starts, Coordinates ends, Coordinates strides, int32_t begin_mask=0, int32_t end_mask=0, int32_t shrink_axis_mask=0, bool return_unshrinked=false)
Computes output shape of strided slice.