| 146 | |
| 147 | template <typename OutputType, typename InputType, boundary::BoundaryType BorderType, bool AllFill> |
| 148 | void SliceKernelImpl(OutputType *output, |
| 149 | const InputType *input, |
| 150 | const int64_t *out_strides, |
| 151 | const int64_t *in_strides, |
| 152 | const int64_t *out_shape, |
| 153 | const int64_t *in_shape, |
| 154 | const int64_t *anchor, |
| 155 | const int64_t *step, |
| 156 | const OutputType *fill_values, |
| 157 | int channel_dim, // negative if no channel dim or already processed |
| 158 | std::integral_constant<int, 1>, |
| 159 | std::integral_constant<boundary::BoundaryType, BorderType>, |
| 160 | std::integral_constant<bool, AllFill>) { |
| 161 | constexpr int d = 0; |
| 162 | if constexpr (AllFill) { |
| 163 | for (int i = 0; i < out_shape[d]; i++) { |
| 164 | output[i] = *fill_values; |
| 165 | if (d == channel_dim) |
| 166 | fill_values++; |
| 167 | } |
| 168 | } else { |
| 169 | int64_t in_idx = anchor[d]; |
| 170 | int64_t out_idx = 0; |
| 171 | |
| 172 | if constexpr (BorderType == boundary::BoundaryType::CONSTANT) { |
| 173 | // out of bounds (left side of output) |
| 174 | for (; (in_idx < 0 || in_idx >= in_shape[d]) && out_idx < out_shape[d]; |
| 175 | in_idx += step[d], out_idx++) { |
| 176 | output[out_idx] = *fill_values; |
| 177 | if (d == channel_dim) |
| 178 | fill_values++; |
| 179 | } |
| 180 | } else if constexpr (BorderType != boundary::BoundaryType::TRANSPARENT) { // NOLINT - liter bug with else if constexpr |
| 181 | // out of bounds (left side of output) |
| 182 | for (; (in_idx < 0 || in_idx >= in_shape[d]) && out_idx < out_shape[d]; |
| 183 | in_idx += step[d], out_idx++) { |
| 184 | auto in_idx_in_range = boundary::handle_bounds(in_idx, in_shape[d], BorderType); |
| 185 | output[out_idx] = clamp<OutputType>(input[in_idx_in_range]); |
| 186 | if (d == channel_dim) |
| 187 | fill_values++; |
| 188 | } |
| 189 | } |
| 190 | // within input bounds |
| 191 | for (; (0 <= in_idx && in_idx < in_shape[d]) && out_idx < out_shape[d]; |
| 192 | in_idx += step[d], out_idx++) { |
| 193 | output[out_idx] = clamp<OutputType>(input[in_idx]); |
| 194 | if (BorderType == boundary::BoundaryType::CONSTANT && d == channel_dim) |
| 195 | fill_values++; |
| 196 | } |
| 197 | |
| 198 | if constexpr (BorderType == boundary::BoundaryType::CONSTANT) { |
| 199 | // out of bounds (right side of output) |
| 200 | for (; out_idx < out_shape[d]; in_idx += step[d], out_idx += out_strides[d]) { |
| 201 | output[out_idx] = *fill_values; |
| 202 | if (d == channel_dim) |
| 203 | fill_values++; |
| 204 | } |
| 205 | } else if constexpr (BorderType != boundary::BoundaryType::TRANSPARENT) { // NOLINT - liter bug with else if constexpr |
no test coverage detected