| 89 | } |
| 90 | |
| 91 | void CpuConcatenateHeightKernel::run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info) |
| 92 | { |
| 93 | ARM_COMPUTE_TRACE_EVENT(ARM_COMPUTE_PROF_CAT_CPU, ARM_COMPUTE_PROF_LVL_CPU, "CpuConcatenateHeightKernel::run_op"); |
| 94 | ARM_COMPUTE_UNUSED(info); |
| 95 | ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this); |
| 96 | ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(ICpuKernel::window(), window); |
| 97 | |
| 98 | const auto src = tensors.get_const_tensor(TensorType::ACL_SRC); |
| 99 | auto dst = tensors.get_tensor(TensorType::ACL_DST); |
| 100 | |
| 101 | // Offset destination pointer to the correct position |
| 102 | uint8_t *dst_ptr = dst->buffer() + dst->info()->offset_first_element_in_bytes() + |
| 103 | _height_offset * dst->info()->strides_in_bytes()[Window::DimY]; |
| 104 | |
| 105 | const auto window_start_x = static_cast<int>(window.x().start()); |
| 106 | const auto window_end_x = static_cast<int>(window.x().end()) * static_cast<int>(dst->info()->element_size()); |
| 107 | const int window_step_x = 16; |
| 108 | |
| 109 | Window win{window}; |
| 110 | win.set(Window::DimX, Window::Dimension(0, 1, 1)); |
| 111 | win.set(Window::DimY, Window::Dimension(0, src->info()->tensor_shape().y(), 1)); |
| 112 | |
| 113 | // Create iterators |
| 114 | Iterator src_it(src, win); |
| 115 | Iterator dst_it(dst, win); |
| 116 | |
| 117 | const DataType dt = src->info()->data_type(); |
| 118 | const UniformQuantizationInfo &src_qinfo = src->info()->quantization_info().uniform(); |
| 119 | const UniformQuantizationInfo &dst_qinfo = dst->info()->quantization_info().uniform(); |
| 120 | if (dt == DataType::QASYMM8 && src_qinfo != dst_qinfo) |
| 121 | { |
| 122 | execute_window_loop( |
| 123 | win, |
| 124 | [&](const Coordinates &) |
| 125 | { |
| 126 | int x = window_start_x; |
| 127 | for (; x <= (window_end_x - window_step_x); x += window_step_x) |
| 128 | { |
| 129 | vst1q_u8(dst_ptr + dst_it.offset() + x, |
| 130 | vquantize(vdequantize(vld1q_u8(src_it.ptr() + x), src_qinfo), dst_qinfo)); |
| 131 | } |
| 132 | |
| 133 | // Compute left-over elements |
| 134 | for (; x < window_end_x; ++x) |
| 135 | { |
| 136 | *(dst_ptr + dst_it.offset() + x) = |
| 137 | quantize_qasymm8(dequantize_qasymm8(*(src_it.ptr() + x), src_qinfo), dst_qinfo); |
| 138 | } |
| 139 | }, |
| 140 | src_it, dst_it); |
| 141 | } |
| 142 | else if (dt == DataType::QASYMM8_SIGNED && src_qinfo != dst_qinfo) |
| 143 | { |
| 144 | execute_window_loop( |
| 145 | win, |
| 146 | [&](const Coordinates &) |
| 147 | { |
| 148 | int x = window_start_x; |
nothing calls this directly
no test coverage detected