#ifndef GPU_GENERIC_SYCL_RESAMPLING_UTILS_HPP
#define GPU_GENERIC_SYCL_RESAMPLING_UTILS_HPP
#include "common/c_types_map.hpp"
#include "gpu/generic/sycl/sycl_q10n.hpp"
namespace dnnl {
namespace impl {
namespace gpu {
namespace generic {
namespace sycl {
namespace resampling_utils {
static inline float linear_map(dim_t y, dim_t y_max, dim_t x_max) {
return ((y + 0.5f) * x_max / y_max) - 0.5f;
}
static inline dim_t nearest_idx(dim_t y, dim_t y_max, dim_t x_max) {
return (dim_t)roundf(linear_map(y, y_max, x_max));
}
static inline dim_t ceil_idx(float x) {
if (x < 0) return (dim_t)0;
return (dim_t)x == x ? (dim_t)x : (dim_t)x + 1;
}
static inline float linear_weight(int i, dim_t x, dim_t y_max, dim_t x_max) {
float s = linear_map(x, y_max, x_max);
float w = nstl::abs(s - (dim_t)s);
return i == 0 ? 1.f - w : w;
}
struct linear_coeffs_t {
linear_coeffs_t(dim_t y, dim_t y_max, dim_t x_max) {
float s = linear_map(y, y_max, x_max);
idx[0] = left(s);
idx[1] = right(s, x_max);
wei[1] = nstl::abs(s - saturate<float>(idx[0]));
wei[0] = 1.f - wei[1];
}
dim_t idx[2];
float wei[2];
private:
static dim_t right(float s, dim_t x_max) {
return nstl::min(ceil_idx(s), x_max - 1);
}
static dim_t left(float s) { return nstl::max((dim_t)s, (dim_t)0); }
};
struct bwd_linear_coeffs_t {
bwd_linear_coeffs_t(dim_t x, dim_t y_max, dim_t x_max) {
start[0] = x == 0 ? 0 : left_start(x, y_max, x_max);
start[1] = right_start(x, y_max, x_max);
end[0] = left_end(x, y_max, x_max);
end[1] = x == x_max - 1 ? y_max : right_end(x, y_max, x_max);
}
dim_t start[2], end[2];
private:
static dim_t left_start(dim_t x, dim_t y_max, dim_t x_max) {
return ceil_idx(linear_map(x, x_max, y_max));
}
static dim_t left_end(dim_t x, dim_t y_max, dim_t x_max) {
return nstl::min(ceil_idx(linear_map(x + 1, x_max, y_max)), y_max);
}
static dim_t right_start(dim_t x, dim_t y_max, dim_t x_max) {
float s = linear_map(x - 1, x_max, y_max);
return s < 0 ? 0 : (dim_t)(s) + 1;
}
static dim_t right_end(dim_t x, dim_t y_max, dim_t x_max) {
float s = linear_map(x, x_max, y_max);
return nstl::min(s < 0 ? 0 : (dim_t)s + 1, y_max);
}
};
}
} } } } }
#endif