| 102 | |
| 103 | template <typename T> |
| 104 | void run_reverse( |
| 105 | const Window &window, const ITensor *input, const ITensor *axis, ITensor *output, bool use_inverted_axis) |
| 106 | { |
| 107 | unsigned int axis_bit = 0; |
| 108 | const int rank = input->info()->num_dimensions(); |
| 109 | |
| 110 | for (unsigned int i = 0; i < axis->info()->dimension(0); ++i) |
| 111 | { |
| 112 | int axis_i = *(reinterpret_cast<const int *>(axis->buffer()) + i); |
| 113 | |
| 114 | // The values of axis tensor must be between [-rank, rank-1]. |
| 115 | if ((axis_i < -rank) || (axis_i >= rank)) |
| 116 | { |
| 117 | ARM_COMPUTE_ERROR("the values of the axis tensor must be within [-rank, rank-1]."); |
| 118 | } |
| 119 | |
| 120 | // In case of negative axis value i.e targeted axis(i) = rank + axis(i) |
| 121 | if (axis_i < 0) |
| 122 | { |
| 123 | axis_i = rank + axis_i; |
| 124 | } |
| 125 | |
| 126 | // Reverse ACL axis indices convention i.e. (inverted)axis = (tensor_rank - 1) - axis |
| 127 | if (use_inverted_axis) |
| 128 | { |
| 129 | axis_i = (rank - 1) - axis_i; |
| 130 | } |
| 131 | |
| 132 | axis_bit |= 1 << axis_i; |
| 133 | } |
| 134 | |
| 135 | // Check if we need a left-over loop for the y dimension |
| 136 | const int window_step_x = 16 / input->info()->element_size(); |
| 137 | const int window_start_x = window.x().start(); |
| 138 | const int window_end_x = window.x().end(); |
| 139 | |
| 140 | Window win(window); |
| 141 | win.set(Window::DimX, Window::Dimension(0, 1, 1)); |
| 142 | |
| 143 | Iterator input_it(input, win); |
| 144 | execute_window_loop( |
| 145 | win, |
| 146 | [&](const Coordinates &id) |
| 147 | { |
| 148 | int x = window_start_x; |
| 149 | for (; x <= (window_end_x - window_step_x); x += window_step_x) |
| 150 | { |
| 151 | auto in = wrapper::vloadq(reinterpret_cast<T *>(input_it.ptr()) + x); |
| 152 | |
| 153 | // Reverse 0 axis |
| 154 | if (axis_bit & 0x1) |
| 155 | { |
| 156 | in = wrapper::vrev64(in); |
| 157 | in = wrapper::vcombine(wrapper::vgethigh(in), wrapper::vgetlow(in)); |
| 158 | } |
| 159 | |
| 160 | const int offset_x = (axis_bit & 0x1) ? output->info()->dimension(0) - x - window_step_x : x; |
| 161 | const int offset_y = (axis_bit & 0x2) ? output->info()->dimension(1) - id.y() - 1 : id.y(); |
nothing calls this directly
no test coverage detected