1/*******************************************************************************
2* Copyright 2019-2020 Intel Corporation
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*******************************************************************************/
16
17#ifndef CPU_RESAMPLING_UTILS_HPP
18#define CPU_RESAMPLING_UTILS_HPP
19
20#include "common/c_types_map.hpp"
21
22#include "cpu/simple_q10n.hpp"
23
24namespace dnnl {
25namespace impl {
26namespace cpu {
27
28namespace resampling_utils {
29
30static inline float linear_map(dim_t y, dim_t y_max, dim_t x_max) {
31 return ((y + 0.5f) * x_max / y_max) - 0.5f;
32}
33static inline dim_t nearest_idx(dim_t y, dim_t y_max, dim_t x_max) {
34 return (dim_t)roundf(linear_map(y, y_max, x_max));
35}
36static inline dim_t ceil_idx(float x) {
37 if (x < 0) return (dim_t)0;
38 return (dim_t)x == x ? (dim_t)x : (dim_t)x + 1;
39}
40static inline float linear_weight(int i, dim_t x, dim_t y_max, dim_t x_max) {
41 float s = linear_map(x, y_max, x_max);
42 float w = nstl::abs(s - (dim_t)s);
43 return i == 0 ? 1.f - w : w;
44};
45
46struct linear_coeffs_t {
47 linear_coeffs_t(dim_t y, dim_t y_max, dim_t x_max) {
48 float s = linear_map(y, y_max, x_max);
49 idx[0] = left(s);
50 idx[1] = right(s, x_max);
51 wei[1] = nstl::abs(s - saturate<float>(idx[0]));
52 wei[0] = 1.f - wei[1];
53 }
54 // left and right index of source image used for interpolation
55 dim_t idx[2];
56 // left and right interpolation weights
57 float wei[2];
58
59private:
60 static dim_t right(float s, dim_t x_max) {
61 return nstl::min(ceil_idx(s), x_max - 1);
62 }
63 static dim_t left(float s) { return nstl::max((dim_t)s, (dim_t)0); }
64};
65
66struct bwd_linear_coeffs_t {
67 bwd_linear_coeffs_t(dim_t x, dim_t y_max, dim_t x_max) {
68 start[0] = x == 0 ? 0 : left_start(x, y_max, x_max);
69 start[1] = right_start(x, y_max, x_max);
70 end[0] = left_end(x, y_max, x_max);
71 end[1] = x == x_max - 1 ? y_max : right_end(x, y_max, x_max);
72 }
73 // index range (from start to end) of source image used as left and right
74 // edge for interpolation
75 dim_t start[2], end[2];
76
77private:
78 static dim_t left_start(dim_t x, dim_t y_max, dim_t x_max) {
79 return ceil_idx(linear_map(x, x_max, y_max));
80 }
81 static dim_t left_end(dim_t x, dim_t y_max, dim_t x_max) {
82 return nstl::min(ceil_idx(linear_map(x + 1, x_max, y_max)), y_max);
83 }
84 static dim_t right_start(dim_t x, dim_t y_max, dim_t x_max) {
85 float s = linear_map(x - 1, x_max, y_max);
86 return s < 0 ? 0 : (dim_t)(s) + 1;
87 }
88 static dim_t right_end(dim_t x, dim_t y_max, dim_t x_max) {
89 float s = linear_map(x, x_max, y_max);
90 return nstl::min(s < 0 ? 0 : (dim_t)s + 1, y_max);
91 }
92};
93
94} // namespace resampling_utils
95
96} // namespace cpu
97} // namespace impl
98} // namespace dnnl
99
100#endif
101