| 305 | } |
| 306 | |
| 307 | void ClMulKernel::run_op(ITensorPack &tensors, const Window &window, cl::CommandQueue &queue) |
| 308 | { |
| 309 | ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this); |
| 310 | ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(ICLKernel::window(), window); |
| 311 | |
| 312 | const auto src_0 = |
| 313 | utils::cast::polymorphic_downcast<const ICLTensor *>(tensors.get_const_tensor(TensorType::ACL_SRC_0)); |
| 314 | const auto src_1 = |
| 315 | utils::cast::polymorphic_downcast<const ICLTensor *>(tensors.get_const_tensor(TensorType::ACL_SRC_1)); |
| 316 | auto dst = utils::cast::polymorphic_downcast<ICLTensor *>(tensors.get_tensor(TensorType::ACL_DST)); |
| 317 | |
| 318 | ARM_COMPUTE_ERROR_ON_NULLPTR(src_0, src_1, dst); |
| 319 | |
| 320 | const TensorShape &in_shape1 = src_0->info()->tensor_shape(); |
| 321 | const TensorShape &in_shape2 = src_1->info()->tensor_shape(); |
| 322 | const TensorShape &out_shape = dst->info()->tensor_shape(); |
| 323 | |
| 324 | bool can_collapse = true; |
| 325 | if (std::min(in_shape1.total_size(), in_shape2.total_size()) > 1) |
| 326 | { |
| 327 | can_collapse = (std::min(in_shape1.num_dimensions(), in_shape2.num_dimensions()) > Window::DimZ); |
| 328 | for (size_t d = Window::DimZ; can_collapse && (d < out_shape.num_dimensions()); ++d) |
| 329 | { |
| 330 | can_collapse = (in_shape1[d] == in_shape2[d]); |
| 331 | } |
| 332 | } |
| 333 | |
| 334 | bool has_collapsed = false; |
| 335 | Window collapsed = |
| 336 | can_collapse ? window.collapse_if_possible(ICLKernel::window(), Window::DimZ, &has_collapsed) : window; |
| 337 | |
| 338 | const TensorShape &in_shape1_collapsed = has_collapsed ? in_shape1.collapsed_from(Window::DimZ) : in_shape1; |
| 339 | const TensorShape &in_shape2_collapsed = has_collapsed ? in_shape2.collapsed_from(Window::DimZ) : in_shape2; |
| 340 | |
| 341 | Window slice = collapsed.first_slice_window_3D(); |
| 342 | Window slice_input1 = slice.broadcast_if_dimension_le_one(in_shape1_collapsed); |
| 343 | Window slice_input2 = slice.broadcast_if_dimension_le_one(in_shape2_collapsed); |
| 344 | |
| 345 | // Check whether it is in_place calculation |
| 346 | const bool in_place = (src_0 == dst) || (src_1 == dst); |
| 347 | do |
| 348 | { |
| 349 | unsigned int idx = 0; |
| 350 | add_3D_tensor_argument(idx, src_0, slice_input1); |
| 351 | add_3D_tensor_argument(idx, src_1, slice_input2); |
| 352 | if (!in_place) |
| 353 | { |
| 354 | add_3D_tensor_argument(idx, dst, slice); |
| 355 | } |
| 356 | enqueue(queue, *this, slice, lws_hint()); |
| 357 | |
| 358 | ARM_COMPUTE_UNUSED(collapsed.slide_window_slice_3D(slice_input1)); |
| 359 | ARM_COMPUTE_UNUSED(collapsed.slide_window_slice_3D(slice_input2)); |
| 360 | } while (collapsed.slide_window_slice_3D(slice)); |
| 361 | } |
| 362 | |
| 363 | namespace |
| 364 | { |
nothing calls this directly
no test coverage detected