| 42 | */ |
| 43 | template <typename OutputType, typename InputType, bool AllFill, boundary::BoundaryType BorderType> |
| 44 | void SliceKernelImplChannelLast(OutputType *output, |
| 45 | const InputType *input, |
| 46 | const int64_t *out_strides, |
| 47 | const int64_t *in_strides, |
| 48 | const int64_t *out_shape, |
| 49 | const int64_t *in_shape, |
| 50 | const int64_t *anchor, |
| 51 | const int64_t *step, |
| 52 | const OutputType *fill_values, |
| 53 | int channel_dim, // negative if no channel dim or already processed |
| 54 | std::integral_constant<boundary::BoundaryType, BorderType>, |
| 55 | std::integral_constant<bool, AllFill>) { |
| 56 | static_assert(!AllFill || BorderType == boundary::BoundaryType::CONSTANT); |
| 57 | constexpr int d = 0; |
| 58 | assert(channel_dim == 1); |
| 59 | int64_t out_nchannels = out_shape[channel_dim]; |
| 60 | int64_t in_nchannels = in_shape[channel_dim]; |
| 61 | int64_t npixels = out_shape[d]; |
| 62 | |
| 63 | if constexpr (AllFill) { |
| 64 | PadFill(output, fill_values, npixels, out_nchannels); |
| 65 | return; |
| 66 | } |
| 67 | |
| 68 | if constexpr (BorderType == boundary::BoundaryType::CONSTANT) { |
| 69 | // If the whole row is out of bounds, just fill |
| 70 | // Calculate number of pixels to pad on the left and right, and the number of pixels to be |
| 71 | // copied |
| 72 | int64_t pad_pixels_before, copy_pixels, pad_pixels_after; |
| 73 | std::tie(pad_pixels_before, copy_pixels, pad_pixels_after) = |
| 74 | CalcPadCopyExtents(anchor[d], in_shape[d], out_shape[d]); |
| 75 | |
| 76 | // Padding pixels on the left, if needed |
| 77 | if (pad_pixels_before > 0) { |
| 78 | PadFill(output, fill_values, pad_pixels_before, out_nchannels); |
| 79 | output += pad_pixels_before * out_strides[d]; |
| 80 | } |
| 81 | |
| 82 | // If the anchor is positive, advance the input pointer |
| 83 | if (anchor[d] > 0) |
| 84 | input += anchor[d] * in_strides[d]; |
| 85 | |
| 86 | bool channel_dim_unchanged = in_nchannels == out_nchannels && anchor[channel_dim] == 0; |
| 87 | if (channel_dim_unchanged) { |
| 88 | auto n = copy_pixels * out_nchannels; |
| 89 | for (int64_t i = 0; i < n; i++) |
| 90 | output[i] = input[i]; |
| 91 | output += n; |
| 92 | } else { |
| 93 | // Calculate number of channels to pad on the left, right and the number of channels to be |
| 94 | // copied |
| 95 | int64_t pad_channels_before, copy_channels, pad_channels_after; |
| 96 | std::tie(pad_channels_before, copy_channels, pad_channels_after) = |
| 97 | CalcPadCopyExtents(anchor[channel_dim], in_nchannels, out_nchannels); |
| 98 | int64_t anchor_channel_in = std::max<int64_t>(0, anchor[channel_dim]); |
| 99 | // Copy pixels with potential padding on the channel dimension |
| 100 | for (int64_t i = 0; i < copy_pixels; i++) { |
| 101 | int64_t out_c = 0; |
no test coverage detected