Compute Library
 21.02
neon_permute.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 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  */
25 
26 #include "arm_compute/core/Types.h"
27 #include "utils/Utils.h"
28 
29 using namespace arm_compute;
30 using namespace utils;
31 
32 class NeonPermuteExample : public Example
33 {
34 public:
35  NeonPermuteExample() = default;
36 
37  bool do_setup(int, char **) override
38  {
39  // Initialise shapes
40  init_tensor(TensorShape(8U, 4U, 2U), tensor_nchw, DataType::U8, DataLayout::NCHW);
41  init_tensor(TensorShape(2U, 8U, 4U), tensor_nhwc, DataType::U8, DataLayout::NHWC);
42  init_tensor(TensorShape(8U, 4U, 2U), tensor_nchw_result, DataType::U8, DataLayout::NCHW);
43 
44  // Create the permutation vector to turn a NCHW tensor to NHWC.
45  // The input tensor is NCHW, which means that the fastest changing coordinate is W=8U.
46  // For permutation vectors the fastest changing coordinate is the one on the left too.
47  // Each element in the permutation vector specifies a mapping from the source tensor to the destination one, thus if we
48  // use 2U in the permutation vector's first element we are telling the function to move the channels to the fastest
49  // changing coordinate in the destination tensor.
50 
51  const PermutationVector vector_nchw_to_nhwc(2U, 0U, 1U);
52  permute_nhwc.configure(&tensor_nchw, &tensor_nhwc, vector_nchw_to_nhwc);
53 
54  // Allocate and fill tensors
55  tensor_nhwc.allocator()->allocate();
56  tensor_nchw.allocator()->allocate();
57  fill_tensor(tensor_nchw);
58 
59  // Demostrate autoconfigure for the output tensor
60  const PermutationVector vector_nhwc_to_nchw(1U, 2U, 0U);
61  permute_nchw.configure(&tensor_nhwc, &tensor_nchw_result, vector_nhwc_to_nchw);
62  tensor_nchw_result.allocator()->allocate();
63 
64  return true;
65  }
66  void do_run() override
67  {
68  permute_nhwc.run();
69  permute_nchw.run();
70  }
71  void do_teardown() override
72  {
73 #if ARM_COMPUTE_DEBUG_ENABLED
74  std::cout << "Tensor NCHW" << std::endl;
75  tensor_nchw.print(std::cout);
76  std::cout << "Tensor NHWC" << std::endl;
77  tensor_nhwc.print(std::cout);
78 #endif // ARM_COMPUTE_DEBUG_ENABLED
79  }
80 
81 private:
82  void validate_result(const Tensor &reference, const Tensor &result)
83  {
84  Window window;
85  window.use_tensor_dimensions(reference.info()->tensor_shape());
86  Iterator ref_it(&reference, window);
87  Iterator res_it(&result, window);
88  execute_window_loop(window, [&](const Coordinates &)
89  {
90  assert(*reinterpret_cast<unsigned char *>(ref_it.ptr()) == *reinterpret_cast<unsigned char *>(res_it.ptr()));
91  },
92  ref_it, res_it);
93  }
94 
95  void fill_tensor(Tensor &tensor)
96  {
97  Window window;
98  window.use_tensor_dimensions(tensor.info()->tensor_shape());
99  Iterator tensor_it(&tensor, window);
100  unsigned char val(0);
101  execute_window_loop(window, [&](const Coordinates &)
102  {
103  *reinterpret_cast<unsigned char *>(tensor_it.ptr()) = val++;
104  },
105  tensor_it);
106  }
107  void init_tensor(const TensorShape shape, Tensor &tensor, DataType type, DataLayout layout)
108  {
109  tensor.allocator()->init(TensorInfo(shape, 1, type).set_data_layout(layout));
110  }
111 
112  Tensor tensor_nchw{};
113  Tensor tensor_nhwc{};
114  Tensor tensor_nchw_result{};
115  NEPermute permute_nhwc{};
116  NEPermute permute_nchw{};
117 };
118 
119 /** Main program that instantiates a permute function example.
120  *
121  * @param[in] argc Number of arguments
122  * @param[in] argv Arguments
123  */
124 int main(int argc, char **argv)
125 {
126  return utils::run_example<NeonPermuteExample>(argc, argv);
127 }
Shape of a tensor.
Definition: TensorShape.h:39
void init(const TensorAllocator &allocator, const Coordinates &coords, TensorInfo &sub_info)
Shares the same backing memory with another tensor allocator, while the tensor info might be differen...
1 channel, 1 U8 per channel
Basic function to run cpu::kernels::CpuPermuteKernel.
Definition: NEPermute.h:40
decltype(strategy::transforms) typedef type
Includes all the Neon functions at once.
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
Copyright (c) 2017-2021 Arm Limited.
TensorAllocator * allocator()
Return a pointer to the tensor&#39;s allocator.
Definition: Tensor.cpp:48
ITensorInfo * info() const override
Interface to be implemented by the child class to return the tensor&#39;s metadata.
Definition: Tensor.cpp:33
fill_tensor(input_to_input_weights, std::vector< uint8_t >{ 122, 130, 124, 134, 120, 122, 134, 134 })
virtual const TensorShape & tensor_shape() const =0
Size for each dimension of the tensor.
Coordinates of an item.
Definition: Coordinates.h:37
Abstract Example class.
Definition: Utils.h:78
int main(int argc, char **argv)
Main program that instantiates a permute function example.
Basic implementation of the tensor interface.
Definition: Tensor.h:37
Num samples, channels, height, width.
src_info set_data_layout(data_layout)
Strides of an item in bytes.
Definition: Strides.h:37
Num samples, height, width, channels.
Store the tensor&#39;s metadata.
Definition: TensorInfo.h:45
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
Iterator updated by execute_window_loop for each window element.
Definition: Helpers.h:46
DataType
Available data types.
Definition: Types.h:77
DataLayout
[DataLayout enum definition]
Definition: Types.h:120
Describe a multidimensional execution window.
Definition: Window.h:39