| 342 | } |
| 343 | |
| 344 | void ClElementwiseKernel::run_op(ITensorPack &tensors, const Window &window, ::cl::CommandQueue &queue) |
| 345 | { |
| 346 | ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this); |
| 347 | ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(ICLKernel::window(), window); |
| 348 | |
| 349 | const auto src_0 = |
| 350 | utils::cast::polymorphic_downcast<const ICLTensor *>(tensors.get_const_tensor(TensorType::ACL_SRC_0)); |
| 351 | const auto src_1 = |
| 352 | utils::cast::polymorphic_downcast<const ICLTensor *>(tensors.get_const_tensor(TensorType::ACL_SRC_1)); |
| 353 | auto dst = utils::cast::polymorphic_downcast<ICLTensor *>(tensors.get_tensor(TensorType::ACL_DST)); |
| 354 | |
| 355 | ARM_COMPUTE_ERROR_ON_NULLPTR(src_0, src_1, dst); |
| 356 | |
| 357 | const TensorShape &in_shape1 = src_0->info()->tensor_shape(); |
| 358 | const TensorShape &in_shape2 = src_1->info()->tensor_shape(); |
| 359 | const TensorShape &out_shape = dst->info()->tensor_shape(); |
| 360 | |
| 361 | bool can_collapse = true; |
| 362 | const bool is_vector = in_shape1.num_dimensions() == 1 || in_shape2.num_dimensions() == 1; |
| 363 | if (std::min(in_shape1.total_size(), in_shape2.total_size()) > 1 && !is_vector) |
| 364 | { |
| 365 | can_collapse = (std::min(in_shape1.num_dimensions(), in_shape2.num_dimensions()) > Window::DimZ); |
| 366 | for (size_t d = Window::DimZ; can_collapse && (d < out_shape.num_dimensions()); d++) |
| 367 | { |
| 368 | can_collapse = (in_shape1[d] == in_shape2[d]); |
| 369 | } |
| 370 | } |
| 371 | |
| 372 | bool has_collapsed = false; |
| 373 | Window collapsed = |
| 374 | can_collapse ? window.collapse_if_possible(ICLKernel::window(), Window::DimZ, &has_collapsed) : window; |
| 375 | |
| 376 | const TensorShape &in_shape1_collapsed = has_collapsed ? in_shape1.collapsed_from(Window::DimZ) : in_shape1; |
| 377 | const TensorShape &in_shape2_collapsed = has_collapsed ? in_shape2.collapsed_from(Window::DimZ) : in_shape2; |
| 378 | |
| 379 | Window slice = collapsed.first_slice_window_3D(); |
| 380 | Window slice_src1 = slice.broadcast_if_dimension_le_one(in_shape1_collapsed); |
| 381 | Window slice_src2 = slice.broadcast_if_dimension_le_one(in_shape2_collapsed); |
| 382 | |
| 383 | // Check whether it is in_place calculation |
| 384 | const bool in_place = (src_0 == dst) || (src_1 == dst); |
| 385 | do |
| 386 | { |
| 387 | unsigned int idx = 0; |
| 388 | add_3D_tensor_argument(idx, src_0, slice_src1); |
| 389 | add_3D_tensor_argument(idx, src_1, slice_src2); |
| 390 | if (!in_place) |
| 391 | { |
| 392 | add_3D_tensor_argument(idx, dst, slice); |
| 393 | } |
| 394 | |
| 395 | enqueue(queue, *this, slice, lws_hint()); |
| 396 | ARM_COMPUTE_UNUSED(collapsed.slide_window_slice_3D(slice_src1)); |
| 397 | ARM_COMPUTE_UNUSED(collapsed.slide_window_slice_3D(slice_src2)); |
| 398 | } while (collapsed.slide_window_slice_3D(slice)); |
| 399 | } |
| 400 | |
| 401 | /** Logical binary */ |
nothing calls this directly
no test coverage detected