| 51 | { |
| 52 | template <typename T> |
| 53 | void depth_concat(const ITensor *src, ITensor *dst, unsigned int depth_offset, const Window &window) |
| 54 | { |
| 55 | // Offset source |
| 56 | uint8_t *src_ptr = src->buffer() + src->info()->offset_first_element_in_bytes(); |
| 57 | |
| 58 | // Offset destination |
| 59 | uint8_t *dst_ptr = dst->buffer() + dst->info()->offset_first_element_in_bytes() + |
| 60 | depth_offset * dst->info()->strides_in_bytes()[2]; |
| 61 | |
| 62 | const auto window_start_x = static_cast<int>(window.x().start()); |
| 63 | const auto window_end_x = static_cast<int>(window.x().end()); |
| 64 | const int window_step_x = 16 / dst->info()->element_size(); |
| 65 | |
| 66 | Window win{window}; |
| 67 | win.set(Window::DimX, Window::Dimension(0, 1, 1)); |
| 68 | win.set(Window::DimZ, Window::Dimension(0, src->info()->tensor_shape().z(), 1)); |
| 69 | |
| 70 | Iterator src_it(src, win); |
| 71 | Iterator dst_it(dst, win); |
| 72 | |
| 73 | const DataType dt = src->info()->data_type(); |
| 74 | const UniformQuantizationInfo src_qinfo = src->info()->quantization_info().uniform(); |
| 75 | const UniformQuantizationInfo dst_qinfo = dst->info()->quantization_info().uniform(); |
| 76 | if (dt == DataType::QASYMM8 && src_qinfo != dst_qinfo) |
| 77 | { |
| 78 | execute_window_loop( |
| 79 | win, |
| 80 | [&](const Coordinates &) |
| 81 | { |
| 82 | const auto in_ptr = reinterpret_cast<const uint8_t *>(src_ptr + src_it.offset()); |
| 83 | const auto out_ptr = reinterpret_cast<uint8_t *>(dst_ptr + dst_it.offset()); |
| 84 | int x = window_start_x; |
| 85 | for (; x <= (window_end_x - window_step_x); x += window_step_x) |
| 86 | { |
| 87 | wrapper::vstore(out_ptr + x, |
| 88 | vquantize(vdequantize(wrapper::vloadq(in_ptr + x), src_qinfo), dst_qinfo)); |
| 89 | } |
| 90 | |
| 91 | // Compute left-over elements |
| 92 | for (; x < window_end_x; ++x) |
| 93 | { |
| 94 | *(out_ptr + x) = quantize_qasymm8(dequantize_qasymm8(*(in_ptr + x), src_qinfo), dst_qinfo); |
| 95 | } |
| 96 | }, |
| 97 | src_it, dst_it); |
| 98 | } |
| 99 | else if (dt == DataType::QASYMM8_SIGNED && src_qinfo != dst_qinfo) |
| 100 | { |
| 101 | execute_window_loop( |
| 102 | win, |
| 103 | [&](const Coordinates &) |
| 104 | { |
| 105 | const auto in_ptr = reinterpret_cast<const int8_t *>(src_ptr + src_it.offset()); |
| 106 | const auto out_ptr = reinterpret_cast<int8_t *>(dst_ptr + dst_it.offset()); |
| 107 | int x = window_start_x; |
| 108 | for (; x <= (window_end_x - window_step_x); x += window_step_x) |
| 109 | { |
| 110 | wrapper::vstore(out_ptr + x, |
nothing calls this directly
no test coverage detected