Compute Library
 21.02
cl_cache.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019-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  */
25 #include "arm_compute/core/Types.h"
30 #include "utils/Utils.h"
31 
32 using namespace arm_compute;
33 using namespace utils;
34 
35 namespace
36 {
37 } // namespace
38 
39 class CLCacheExample : public Example
40 {
41 public:
42  CLCacheExample() = default;
43 
44  bool do_setup(int argc, char **argv) override
45  {
46  std::cout << "Once the program has run and created the file cache.bin, rerun with --restore_cache." << std::endl;
48 
49  if(argc > 1)
50  {
51  std::string argv1 = argv[1];
52  std::transform(argv1.begin(), argv1.end(), argv1.begin(), ::tolower);
53  if(argv1 == "--restore_cache")
54  {
55  // Load the precompiled kernels from a file into the kernel library, in this way the next time they are needed
56  // compilation won't be required.
58  }
59  else
60  {
61  std::cout << "Unkown option " << argv1 << std::endl;
62  }
63  }
64 
65  // Initialise shapes
66  init_tensor(TensorShape(8U, 4U, 2U), tensor_nchw, DataType::U8, DataLayout::NCHW);
67  init_tensor(TensorShape(2U, 8U, 4U), tensor_nhwc, DataType::U8, DataLayout::NHWC);
68  init_tensor(TensorShape(8U, 4U, 2U), tensor_nchw_result, DataType::U8, DataLayout::NCHW);
69 
70  // Create the permutation vector to turn a NCHW tensor to NHWC.
71  // The input tensor is NCHW, which means that the fastest changing coordinate is W=8U.
72  // For permutation vectors the fastest changing coordinate is the one on the left too.
73  // Each element in the permutation vector specifies a mapping from the source tensor to the destination one, thus if we
74  // use 2U in the permutation vector's first element we are telling the function to move the channels to the fastest
75  // changing coordinate in the destination tensor.
76 
77  const PermutationVector vector_nchw_to_nhwc(2U, 0U, 1U);
78  permute_nhwc.configure(&tensor_nchw, &tensor_nhwc, vector_nchw_to_nhwc);
79 
80  // Allocate and fill tensors
81  tensor_nhwc.allocator()->allocate();
82  tensor_nchw.allocator()->allocate();
83  fill_tensor(tensor_nchw);
84 
85  // Demostrate autoconfigure for the output tensor
86  const PermutationVector vector_nhwc_to_nchw(1U, 2U, 0U);
87  permute_nchw.configure(&tensor_nhwc, &tensor_nchw_result, vector_nhwc_to_nchw);
88  tensor_nchw_result.allocator()->allocate();
89 
90  // Save the opencl kernels to a file
92 
93  return true;
94  }
95  void do_run() override
96  {
97  permute_nhwc.run();
98  permute_nchw.run();
99  }
100  void do_teardown() override
101  {
102  }
103 
104 private:
105  void validate_result(CLTensor &reference, CLTensor &result)
106  {
107  reference.map();
108  result.map();
109  Window window;
110  window.use_tensor_dimensions(reference.info()->tensor_shape());
111  Iterator it_ref(&reference, window);
112  Iterator it_res(&result, window);
113  execute_window_loop(window, [&](const Coordinates &)
114  {
115  assert(*reinterpret_cast<unsigned char *>(it_ref.ptr()) == *reinterpret_cast<unsigned char *>(it_res.ptr()));
116  },
117  it_ref, it_res);
118  reference.unmap();
119  result.unmap();
120  }
121 
122  void fill_tensor(CLTensor &tensor)
123  {
124  tensor.map();
125  Window window;
126  window.use_tensor_dimensions(tensor.info()->tensor_shape());
127  Iterator it_tensor(&tensor, window);
128  unsigned char val(0);
129  execute_window_loop(window, [&](const Coordinates &)
130  {
131  *reinterpret_cast<unsigned char *>(it_tensor.ptr()) = val++;
132  },
133  it_tensor);
134  tensor.unmap();
135  }
136  void init_tensor(const TensorShape shape, CLTensor &tensor, DataType type, DataLayout layout)
137  {
138  tensor.allocator()->init(TensorInfo(shape, 1, type).set_data_layout(layout));
139  }
140 
141  CLTensor tensor_nchw{};
142  CLTensor tensor_nhwc{};
143  CLTensor tensor_nchw_result{};
144  CLPermute permute_nhwc{};
145  CLPermute permute_nchw{};
146 };
147 
148 /** Main program creating an example that demostrates how to load precompiled kernels from a file.
149  *
150  * @param[in] argc Number of arguments
151  * @param[in] argv Arguments
152  */
153 int main(int argc, char **argv)
154 {
155  return utils::run_example<CLCacheExample>(argc, argv);
156 }
Shape of a tensor.
Definition: TensorShape.h:39
void restore_program_cache_from_file(const std::string &filename="cache.bin")
This function loads prebuilt opencl kernels from a file.
Definition: Utils.cpp:35
TensorInfo * info() const override
Interface to be implemented by the child class to return the tensor&#39;s metadata.
Definition: CLTensor.cpp:41
static CLScheduler & get()
Access the scheduler singleton.
1 channel, 1 U8 per channel
CLTensorAllocator * allocator()
Return a pointer to the tensor&#39;s allocator.
Definition: CLTensor.cpp:61
decltype(strategy::transforms) typedef type
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
void init(const TensorInfo &input, size_t alignment=0)
Initialize a tensor based on the passed TensorInfo.
Copyright (c) 2017-2021 Arm Limited.
int main(int argc, char **argv)
Main program creating an example that demostrates how to load precompiled kernels from a file...
Definition: cl_cache.cpp:153
void map(bool blocking=true)
Enqueue a map operation of the allocated buffer.
Definition: CLTensor.cpp:66
Interface to enqueue OpenCL kernels and get/set the OpenCL CommandQueue and ICLTuner.
std::string tolower(std::string string)
Convert string to lower case.
Definition: Utility.h:203
fill_tensor(input_to_input_weights, std::vector< uint8_t >{ 122, 130, 124, 134, 120, 122, 134, 134 })
Coordinates of an item.
Definition: Coordinates.h:37
Abstract Example class.
Definition: Utils.h:78
Basic function to execute an opencl::kernels::ClPermuteKernel.
Definition: CLPermute.h:39
void save_program_cache_to_file(const std::string &filename="cache.bin")
This function saves opencl kernels library to a file.
Definition: Utils.cpp:73
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.
Wrapper to configure the Khronos OpenCL C++ header.
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
void default_init(ICLTuner *cl_tuner=nullptr, CLGEMMHeuristicsHandle *gemm_h=nullptr)
Initialises the context and command queue used by the scheduler to default values and sets a default ...
const TensorShape & tensor_shape() const override
Size for each dimension of the tensor.
Definition: TensorInfo.h:262
Iterator updated by execute_window_loop for each window element.
Definition: Helpers.h:46
DataType
Available data types.
Definition: Types.h:77
void unmap()
Enqueue an unmap operation of the allocated and mapped buffer.
Definition: CLTensor.cpp:71
DataLayout
[DataLayout enum definition]
Definition: Types.h:120
Describe a multidimensional execution window.
Definition: Window.h:39
Basic implementation of the OpenCL tensor interface.
Definition: CLTensor.h:41