| 40 | namespace |
| 41 | { |
| 42 | void precompute_dx_dy_offsets( |
| 43 | ITensor *dx, ITensor *dy, ITensor *offsets, float wr, float hr, SamplingPolicy sampling_policy, bool align_corners) |
| 44 | { |
| 45 | ARM_COMPUTE_ERROR_ON(offsets == nullptr); |
| 46 | float sampling_offset = 0.0f; |
| 47 | if (sampling_policy == SamplingPolicy::CENTER) |
| 48 | { |
| 49 | sampling_offset = 0.5f; |
| 50 | } |
| 51 | |
| 52 | Window win; |
| 53 | win.set(Window::DimX, Window::Dimension(0, offsets->info()->dimension(0), 1)); |
| 54 | win.set(Window::DimY, Window::Dimension(0, offsets->info()->dimension(1), 1)); |
| 55 | |
| 56 | if (dx != nullptr && dy != nullptr) |
| 57 | { |
| 58 | // Pre-compute the offset and pixel's distance for BILINEAR interpolation |
| 59 | Iterator offsets_it(offsets, win); |
| 60 | Iterator dx_it(dx, win); |
| 61 | Iterator dy_it(dy, win); |
| 62 | |
| 63 | execute_window_loop( |
| 64 | win, |
| 65 | [&](const Coordinates &id) |
| 66 | { |
| 67 | const float in_x = (id.x() + sampling_offset) * wr - sampling_offset; |
| 68 | const float in_y = (id.y() + sampling_offset) * hr - sampling_offset; |
| 69 | const int in_xi = std::floor(in_x); |
| 70 | const int in_yi = std::floor(in_y); |
| 71 | |
| 72 | *reinterpret_cast<int32_t *>(offsets_it.ptr()) = in_xi; |
| 73 | *reinterpret_cast<float *>(dx_it.ptr()) = in_x - in_xi; |
| 74 | *reinterpret_cast<float *>(dy_it.ptr()) = in_y - in_yi; |
| 75 | }, |
| 76 | offsets_it, dx_it, dy_it); |
| 77 | } |
| 78 | else |
| 79 | { |
| 80 | // Pre-compute the offset for NEAREST interpolation |
| 81 | Iterator offsets_it(offsets, win); |
| 82 | |
| 83 | execute_window_loop( |
| 84 | win, |
| 85 | [&](const Coordinates &id) |
| 86 | { |
| 87 | const float float_in_xi = (id.x() + sampling_offset) * wr; |
| 88 | const auto in_xi = static_cast<size_t>( |
| 89 | align_corners ? arm_compute::utils::rounding::round_half_away_from_zero(float_in_xi) |
| 90 | : std::floor(float_in_xi)); |
| 91 | *reinterpret_cast<int32_t *>(offsets_it.ptr()) = in_xi; |
| 92 | }, |
| 93 | offsets_it); |
| 94 | } |
| 95 | } |
| 96 | } // namespace |
| 97 | |
| 98 | void CpuScale::configure(ITensorInfo *src, ITensorInfo *dst, const ScaleKernelInfo &info) |