blob: 6737109f3452830afc77f97e730ea6de8b1008a3 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Manuel Bottinibe9f9f92021-01-25 15:07:17 +00002 * Copyright (c) 2016-2021 Arm Limited.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003 *
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 */
Michalis Spyrouf4643372019-11-29 16:17:13 +000024#ifndef ARM_COMPUTE_ICLKERNEL_H
25#define ARM_COMPUTE_ICLKERNEL_H
Anthony Barbier6ff3b192017-09-04 18:44:23 +010026
steniu015f910722017-08-23 10:15:22 +010027#include "arm_compute/core/CL/CLKernelLibrary.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010028#include "arm_compute/core/CL/CLTypes.h"
29#include "arm_compute/core/CL/OpenCL.h"
Michele Di Giorgiob8fc60f2018-04-25 11:58:07 +010030#include "arm_compute/core/GPUTarget.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010031#include "arm_compute/core/IKernel.h"
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010032#include "arm_compute/core/Validate.h"
Michalis Spyrou2aad21a2020-07-02 12:43:53 +010033#include "arm_compute/core/experimental/Types.h"
Manuel Bottinibe9f9f92021-01-25 15:07:17 +000034#include "arm_compute/runtime/CL/CLTuningParams.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010035
Gian Marcode691f02017-09-08 16:13:11 +010036#include <string>
37
Anthony Barbier6ff3b192017-09-04 18:44:23 +010038namespace arm_compute
39{
SiCong Li3e363692017-07-04 15:02:10 +010040template <typename T>
41class ICLArray;
Anthony Barbier6ff3b192017-09-04 18:44:23 +010042class ICLTensor;
43class Window;
44
45/** Common interface for all the OpenCL kernels */
46class ICLKernel : public IKernel
47{
Diego Lopez Recas0021d752017-12-18 14:42:56 +000048private:
49 /** Returns the number of arguments enqueued per array object.
50 *
51 * @return The number of arguments enqueued per array object.
52 */
53 template <unsigned int dimension_size>
54 constexpr static unsigned int num_arguments_per_array()
55 {
56 return num_arguments_per_tensor<dimension_size>();
57 }
58 /** Returns the number of arguments enqueued per tensor object.
59 *
60 * @return The number of arguments enqueued per tensor object.
61 */
62 template <unsigned int dimension_size>
63 constexpr static unsigned int num_arguments_per_tensor()
64 {
65 return 2 + 2 * dimension_size;
66 }
Anthony Barbierb6eb3532018-08-08 13:20:04 +010067 using IKernel::configure; //Prevent children from calling IKernel::configure() directly
Anthony Barbier5a65cfd2018-08-10 14:10:08 +010068protected:
69 /** Configure the kernel's window and local workgroup size hint.
70 *
Manuel Bottinibe9f9f92021-01-25 15:07:17 +000071 * @param[in] window The maximum window which will be returned by window()
72 * @param[in] lws_hint Local-Workgroup-Size to use.
73 * @param[in] wbsm_hint (Optional) Workgroup-Batch-Size-Modifier to use.
Anthony Barbier5a65cfd2018-08-10 14:10:08 +010074 */
Manuel Bottinibe9f9f92021-01-25 15:07:17 +000075 void configure_internal(const Window &window, cl::NDRange lws_hint, cl_int wbsm_hint = 0)
Anthony Barbierb6eb3532018-08-08 13:20:04 +010076 {
Manuel Bottinibe9f9f92021-01-25 15:07:17 +000077 configure_internal(window, CLTuningParams(lws_hint, wbsm_hint));
78 }
79
80 /** Configure the kernel's window and tuning parameters hints.
81 *
82 * @param[in] window The maximum window which will be returned by window()
83 * @param[in] tuning_params_hint (Optional) Tuning parameters to use.
84 */
85 void configure_internal(const Window &window, CLTuningParams tuning_params_hint = CLTuningParams(CLKernelLibrary::get().default_ndrange(), 0))
86 {
87 _tuning_params_hint = tuning_params_hint;
Anthony Barbierb6eb3532018-08-08 13:20:04 +010088 IKernel::configure(window);
89 }
90
Anthony Barbier5a65cfd2018-08-10 14:10:08 +010091public:
Anthony Barbier6ff3b192017-09-04 18:44:23 +010092 /** Constructor */
Diego Lopez Recas0021d752017-12-18 14:42:56 +000093 ICLKernel()
Manuel Bottinibe9f9f92021-01-25 15:07:17 +000094 : _kernel(nullptr), _target(GPUTarget::MIDGARD), _config_id(arm_compute::default_config_id), _max_workgroup_size(0), _tuning_params_hint()
Diego Lopez Recas0021d752017-12-18 14:42:56 +000095 {
96 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +010097 /** Returns a reference to the OpenCL kernel of this object.
98 *
99 * @return A reference to the OpenCL kernel of this object.
100 */
Diego Lopez Recas0021d752017-12-18 14:42:56 +0000101 cl::Kernel &kernel()
102 {
103 return _kernel;
104 }
SiCong Li3e363692017-07-04 15:02:10 +0100105 /** Add the passed 1D array's parameters to the object's kernel's arguments starting from the index idx.
106 *
107 * @param[in,out] idx Index at which to start adding the array's arguments. Will be incremented by the number of kernel arguments set.
108 * @param[in] array Array to set as an argument of the object's kernel.
109 * @param[in] strides @ref Strides object containing stride of each dimension in bytes.
110 * @param[in] num_dimensions Number of dimensions of the @p array.
111 * @param[in] window Window the kernel will be executed on.
112 */
113 template <typename T>
Diego Lopez Recas0021d752017-12-18 14:42:56 +0000114 void add_1D_array_argument(unsigned int &idx, const ICLArray<T> *array, const Strides &strides, unsigned int num_dimensions, const Window &window)
115 {
116 add_array_argument<T, 1>(idx, array, strides, num_dimensions, window);
117 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100118 /** Add the passed 1D tensor's parameters to the object's kernel's arguments starting from the index idx.
119 *
120 * @param[in,out] idx Index at which to start adding the tensor's arguments. Will be incremented by the number of kernel arguments set.
121 * @param[in] tensor Tensor to set as an argument of the object's kernel.
122 * @param[in] window Window the kernel will be executed on.
123 */
Diego Lopez Recas0021d752017-12-18 14:42:56 +0000124 void add_1D_tensor_argument(unsigned int &idx, const ICLTensor *tensor, const Window &window)
125 {
126 add_tensor_argument<1>(idx, tensor, window);
127 }
Michalis Spyroue1651a52019-07-11 15:00:49 +0100128 /** Add the passed 1D tensor's parameters to the object's kernel's arguments starting from the index idx if the condition is true.
129 *
130 * @param[in] cond Condition to check
131 * @param[in,out] idx Index at which to start adding the tensor's arguments. Will be incremented by the number of kernel arguments set.
132 * @param[in] tensor Tensor to set as an argument of the object's kernel.
133 * @param[in] window Window the kernel will be executed on.
134 */
135 void add_1D_tensor_argument_if(bool cond, unsigned int &idx, const ICLTensor *tensor, const Window &window)
136 {
137 if(cond)
138 {
139 add_1D_tensor_argument(idx, tensor, window);
140 }
141 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100142 /** Add the passed 2D tensor's parameters to the object's kernel's arguments starting from the index idx.
143 *
144 * @param[in,out] idx Index at which to start adding the tensor's arguments. Will be incremented by the number of kernel arguments set.
145 * @param[in] tensor Tensor to set as an argument of the object's kernel.
146 * @param[in] window Window the kernel will be executed on.
147 */
Diego Lopez Recas0021d752017-12-18 14:42:56 +0000148 void add_2D_tensor_argument(unsigned int &idx, const ICLTensor *tensor, const Window &window)
149 {
150 add_tensor_argument<2>(idx, tensor, window);
151 }
Michalis Spyroue1651a52019-07-11 15:00:49 +0100152 /** Add the passed 2D tensor's parameters to the object's kernel's arguments starting from the index idx if the condition is true.
153 *
154 * @param[in] cond Condition to check
155 * @param[in,out] idx Index at which to start adding the tensor's arguments. Will be incremented by the number of kernel arguments set.
156 * @param[in] tensor Tensor to set as an argument of the object's kernel.
157 * @param[in] window Window the kernel will be executed on.
158 */
159 void add_2D_tensor_argument_if(bool cond, unsigned int &idx, const ICLTensor *tensor, const Window &window)
160 {
161 if(cond)
162 {
163 add_2D_tensor_argument(idx, tensor, window);
164 }
165 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100166 /** Add the passed 3D tensor's parameters to the object's kernel's arguments starting from the index idx.
167 *
168 * @param[in,out] idx Index at which to start adding the tensor's arguments. Will be incremented by the number of kernel arguments set.
169 * @param[in] tensor Tensor to set as an argument of the object's kernel.
170 * @param[in] window Window the kernel will be executed on.
171 */
Diego Lopez Recas0021d752017-12-18 14:42:56 +0000172 void add_3D_tensor_argument(unsigned int &idx, const ICLTensor *tensor, const Window &window)
173 {
174 add_tensor_argument<3>(idx, tensor, window);
175 }
steniu01868e5412017-07-17 23:16:00 +0100176 /** Add the passed 4D tensor's parameters to the object's kernel's arguments starting from the index idx.
177 *
178 * @param[in,out] idx Index at which to start adding the tensor's arguments. Will be incremented by the number of kernel arguments set.
179 * @param[in] tensor Tensor to set as an argument of the object's kernel.
180 * @param[in] window Window the kernel will be executed on.
181 */
Diego Lopez Recas0021d752017-12-18 14:42:56 +0000182 void add_4D_tensor_argument(unsigned int &idx, const ICLTensor *tensor, const Window &window)
183 {
184 add_tensor_argument<4>(idx, tensor, window);
185 }
SiCong Li3e363692017-07-04 15:02:10 +0100186 /** Returns the number of arguments enqueued per 1D array object.
187 *
188 * @return The number of arguments enqueues per 1D array object.
189 */
Diego Lopez Recas0021d752017-12-18 14:42:56 +0000190 constexpr static unsigned int num_arguments_per_1D_array()
191 {
192 return num_arguments_per_array<1>();
193 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100194 /** Returns the number of arguments enqueued per 1D tensor object.
195 *
196 * @return The number of arguments enqueues per 1D tensor object.
197 */
Diego Lopez Recas0021d752017-12-18 14:42:56 +0000198 constexpr static unsigned int num_arguments_per_1D_tensor()
199 {
200 return num_arguments_per_tensor<1>();
201 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100202 /** Returns the number of arguments enqueued per 2D tensor object.
203 *
204 * @return The number of arguments enqueues per 2D tensor object.
205 */
Diego Lopez Recas0021d752017-12-18 14:42:56 +0000206 constexpr static unsigned int num_arguments_per_2D_tensor()
207 {
208 return num_arguments_per_tensor<2>();
209 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100210 /** Returns the number of arguments enqueued per 3D tensor object.
211 *
212 * @return The number of arguments enqueues per 3D tensor object.
213 */
Diego Lopez Recas0021d752017-12-18 14:42:56 +0000214 constexpr static unsigned int num_arguments_per_3D_tensor()
215 {
216 return num_arguments_per_tensor<3>();
217 }
steniu01868e5412017-07-17 23:16:00 +0100218 /** Returns the number of arguments enqueued per 4D tensor object.
219 *
220 * @return The number of arguments enqueues per 4D tensor object.
221 */
Diego Lopez Recas0021d752017-12-18 14:42:56 +0000222 constexpr static unsigned int num_arguments_per_4D_tensor()
223 {
224 return num_arguments_per_tensor<4>();
225 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100226 /** Enqueue the OpenCL kernel to process the given window on the passed OpenCL command queue.
227 *
228 * @note The queue is *not* flushed by this method, and therefore the kernel will not have been executed by the time this method returns.
229 *
230 * @param[in] window Region on which to execute the kernel. (Must be a valid region of the window returned by window()).
231 * @param[in,out] queue Command queue on which to enqueue the kernel.
232 */
Michalis Spyrou2aad21a2020-07-02 12:43:53 +0100233 virtual void run(const Window &window, cl::CommandQueue &queue)
234 {
235 ARM_COMPUTE_UNUSED(window, queue);
236 }
237 /** Enqueue the OpenCL kernel to process the given window on the passed OpenCL command queue.
238 *
239 * @note The queue is *not* flushed by this method, and therefore the kernel will not have been executed by the time this method returns.
240 *
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100241 * @param[in] tensors A vector containing the tensors to operato on.
Michalis Spyrou2aad21a2020-07-02 12:43:53 +0100242 * @param[in] window Region on which to execute the kernel. (Must be a valid region of the window returned by window()).
243 * @param[in,out] queue Command queue on which to enqueue the kernel.
244 */
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100245 virtual void run_op(ITensorPack &tensors, const Window &window, cl::CommandQueue &queue)
Michalis Spyrou2aad21a2020-07-02 12:43:53 +0100246 {
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100247 ARM_COMPUTE_UNUSED(tensors, window, queue);
Michalis Spyrou2aad21a2020-07-02 12:43:53 +0100248 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100249 /** Add the passed parameters to the object's kernel's arguments starting from the index idx.
250 *
251 * @param[in,out] idx Index at which to start adding the arguments. Will be incremented by the number of kernel arguments set.
252 * @param[in] value Value to set as an argument of the object's kernel.
253 */
254 template <typename T>
255 void add_argument(unsigned int &idx, T value)
256 {
257 _kernel.setArg(idx++, value);
258 }
259
Gian Marco Iodice9331aeb2017-08-10 17:11:08 +0100260 /** Set the Local-Workgroup-Size hint
261 *
262 * @note This method should be called after the configuration of the kernel
263 *
264 * @param[in] lws_hint Local-Workgroup-Size to use
265 */
Anthony Barbierd727e852018-04-20 11:05:29 +0100266 void set_lws_hint(const cl::NDRange &lws_hint)
Gian Marco Iodice9331aeb2017-08-10 17:11:08 +0100267 {
Anthony Barbierb6eb3532018-08-08 13:20:04 +0100268 ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this); // lws_hint will be overwritten by configure()
Manuel Bottinibe9f9f92021-01-25 15:07:17 +0000269 _tuning_params_hint.set_lws(lws_hint);
Gian Marco Iodice9331aeb2017-08-10 17:11:08 +0100270 }
271
Georgios Pinitasc0d1c862018-03-23 15:13:15 +0000272 /** Return the Local-Workgroup-Size hint
273 *
274 * @return Current lws hint
275 */
276 cl::NDRange lws_hint() const
277 {
Manuel Bottinibe9f9f92021-01-25 15:07:17 +0000278 return _tuning_params_hint.get_lws();
279 }
280
281 /** Set the workgroup batch size modifier hint
282 *
283 * @note This method should be called after the configuration of the kernel
284 *
285 * @param[in] wbsm_hint workgroup batch size modifier value
286 */
287 void set_wbsm_hint(const cl_int &wbsm_hint)
288 {
289 ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this); // wbsm_hint will be overwritten by configure()
290 _tuning_params_hint.set_wbsm(wbsm_hint);
291 }
292
293 /** Return the workgroup batch size modifier hint
294 *
295 * @return Current wbsm hint
296 */
297 cl_int wbsm_hint() const
298 {
299 return _tuning_params_hint.get_wbsm();
Georgios Pinitasc0d1c862018-03-23 15:13:15 +0000300 }
301
Gian Marcode691f02017-09-08 16:13:11 +0100302 /** Get the configuration ID
303 *
304 * @note The configuration ID can be used by the caller to distinguish different calls of the same OpenCL kernel
305 * In particular, this method can be used by CLScheduler to keep track of the best LWS for each configuration of the same kernel.
306 * The configuration ID should be provided only for the kernels potentially affected by the LWS geometry
307 *
308 * @note This method should be called after the configuration of the kernel
309 *
310 * @return configuration id string
311 */
312 const std::string &config_id() const
313 {
314 return _config_id;
315 }
316
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100317 /** Set the targeted GPU architecture
318 *
319 * @param[in] target The targeted GPU architecture
320 */
Diego Lopez Recas0021d752017-12-18 14:42:56 +0000321 void set_target(GPUTarget target)
322 {
323 _target = target;
324 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100325
326 /** Set the targeted GPU architecture according to the CL device
327 *
328 * @param[in] device A CL device
329 */
330 void set_target(cl::Device &device);
331
332 /** Get the targeted GPU architecture
333 *
334 * @return The targeted GPU architecture.
335 */
Diego Lopez Recas0021d752017-12-18 14:42:56 +0000336 GPUTarget get_target() const
337 {
338 return _target;
339 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100340
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100341 /** Get the maximum workgroup size for the device the CLKernelLibrary uses.
342 *
343 * @return The maximum workgroup size value.
344 */
345 size_t get_max_workgroup_size();
Georgios Pinitas1f378ee2017-10-27 13:37:16 +0100346 /** Get the global work size given an execution window
347 *
348 * @param[in] window Execution window
349 *
350 * @return Global work size of the given execution window
351 */
352 static cl::NDRange gws_from_window(const Window &window);
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100353
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100354private:
SiCong Li3e363692017-07-04 15:02:10 +0100355 /** Add the passed array's parameters to the object's kernel's arguments starting from the index idx.
356 *
357 * @param[in,out] idx Index at which to start adding the array's arguments. Will be incremented by the number of kernel arguments set.
358 * @param[in] array Array to set as an argument of the object's kernel.
359 * @param[in] strides @ref Strides object containing stride of each dimension in bytes.
360 * @param[in] num_dimensions Number of dimensions of the @p array.
361 * @param[in] window Window the kernel will be executed on.
362 */
363 template <typename T, unsigned int dimension_size>
364 void add_array_argument(unsigned int &idx, const ICLArray<T> *array, const Strides &strides, unsigned int num_dimensions, const Window &window);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100365 /** Add the passed tensor's parameters to the object's kernel's arguments starting from the index idx.
366 *
367 * @param[in,out] idx Index at which to start adding the tensor's arguments. Will be incremented by the number of kernel arguments set.
368 * @param[in] tensor Tensor to set as an argument of the object's kernel.
369 * @param[in] window Window the kernel will be executed on.
370 */
371 template <unsigned int dimension_size>
372 void add_tensor_argument(unsigned int &idx, const ICLTensor *tensor, const Window &window);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100373
374protected:
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100375 cl::Kernel _kernel; /**< OpenCL kernel to run */
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100376 GPUTarget _target; /**< The targeted GPU */
377 std::string _config_id; /**< Configuration ID */
378 size_t _max_workgroup_size; /**< The maximum workgroup size for this kernel */
Anthony Barbierb6eb3532018-08-08 13:20:04 +0100379private:
Manuel Bottinibe9f9f92021-01-25 15:07:17 +0000380 CLTuningParams _tuning_params_hint; /**< Tuning parameters hint for the OpenCL kernel */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100381};
382
383/** Add the kernel to the command queue with the given window.
384 *
385 * @note Depending on the size of the window, this might translate into several jobs being enqueued.
386 *
387 * @note If kernel->kernel() is empty then the function will return without adding anything to the queue.
388 *
Gian Marco Iodiceb0c50372019-03-15 10:13:05 +0000389 * @param[in,out] queue OpenCL command queue.
390 * @param[in] kernel Kernel to enqueue
391 * @param[in] window Window the kernel has to process.
392 * @param[in] lws_hint (Optional) Local workgroup size requested. Default is based on the device target.
393 * @param[in] use_dummy_work_items (Optional) Use dummy work items in order to have two dimensional power of two NDRange. Default is false
394 * Note: it is kernel responsibility to check if the work-item is out-of-range
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100395 *
396 * @note If any dimension of the lws is greater than the global workgroup size then no lws will be passed.
397 */
Gian Marco Iodiceb0c50372019-03-15 10:13:05 +0000398void enqueue(cl::CommandQueue &queue, ICLKernel &kernel, const Window &window, const cl::NDRange &lws_hint = CLKernelLibrary::get().default_ndrange(), bool use_dummy_work_items = false);
SiCong Li3e363692017-07-04 15:02:10 +0100399
Alex Gildayc357c472018-03-21 13:54:09 +0000400/** Add the passed array's parameters to the object's kernel's arguments starting from the index idx.
401 *
402 * @param[in,out] idx Index at which to start adding the array's arguments. Will be incremented by the number of kernel arguments set.
403 * @param[in] array Array to set as an argument of the object's kernel.
404 * @param[in] strides @ref Strides object containing stride of each dimension in bytes.
405 * @param[in] num_dimensions Number of dimensions of the @p array.
406 * @param[in] window Window the kernel will be executed on.
407 */
SiCong Li3e363692017-07-04 15:02:10 +0100408template <typename T, unsigned int dimension_size>
409void ICLKernel::add_array_argument(unsigned &idx, const ICLArray<T> *array, const Strides &strides, unsigned int num_dimensions, const Window &window)
410{
Diego Lopez Recas0021d752017-12-18 14:42:56 +0000411 ARM_COMPUTE_ERROR_ON(array == nullptr);
412
SiCong Li3e363692017-07-04 15:02:10 +0100413 // Calculate offset to the start of the window
414 unsigned int offset_first_element = 0;
415
416 for(unsigned int n = 0; n < num_dimensions; ++n)
417 {
418 offset_first_element += window[n].start() * strides[n];
419 }
420
421 unsigned int idx_start = idx;
422 _kernel.setArg(idx++, array->cl_buffer());
423
424 for(unsigned int dimension = 0; dimension < dimension_size; dimension++)
425 {
426 _kernel.setArg<cl_uint>(idx++, strides[dimension]);
427 _kernel.setArg<cl_uint>(idx++, strides[dimension] * window[dimension].step());
428 }
429
430 _kernel.setArg<cl_uint>(idx++, offset_first_element);
431
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100432 ARM_COMPUTE_ERROR_ON_MSG_VAR(idx_start + num_arguments_per_array<dimension_size>() != idx,
433 "add_%dD_array_argument() is supposed to add exactly %d arguments to the kernel", dimension_size, num_arguments_per_array<dimension_size>());
SiCong Li3e363692017-07-04 15:02:10 +0100434 ARM_COMPUTE_UNUSED(idx_start);
435}
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100436}
Michalis Spyrouf4643372019-11-29 16:17:13 +0000437#endif /*ARM_COMPUTE_ICLKERNEL_H */