/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-roccv/checkouts/latest/include/core/wrappers/border_wrapper.hpp Source File

/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-roccv/checkouts/latest/include/core/wrappers/border_wrapper.hpp Source File#

6 min read time

Applies to Linux

rocCV: /home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-roccv/checkouts/latest/include/core/wrappers/border_wrapper.hpp Source File
border_wrapper.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved.
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to deal
5  * in the Software without restriction, including without limitation the rights
6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  * copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19  * THE SOFTWARE.
20  */
21 
22 #pragma once
23 
24 #include <hip/hip_runtime.h>
25 
27 #include "operator_types.h"
28 
29 namespace roccv {
30 
38 template <typename T, eBorderType BorderType>
40  public:
47  BorderWrapper(const Tensor& tensor, T border_value) : m_desc(tensor), m_border_value(border_value) {}
48 
56  BorderWrapper(ImageWrapper<T> image_wrapper, T border_value)
57  : m_desc(image_wrapper), m_border_value(border_value) {}
58 
69  __device__ __host__ const T at(int64_t n, int64_t h, int64_t w, int64_t c) const {
70  // Constant border type implementation. This is a special case which doesn't remap values, but rather returns
71  // the provided constant value.
72  if constexpr (BorderType == eBorderType::BORDER_TYPE_CONSTANT) {
73  if (w < 0 || w >= width() || h < 0 || h >= height())
74  return m_border_value;
75  else
76  return m_desc.at(n, h, w, c);
77  }
78 
79  // We can return early if our coordinates are within the bounds. This is to avoid expensive calculations
80  // required at image borders. While this may cause branch divergence, a good bulk of the pixels should fall
81  // within image bounds and will take the same branch. This is preferred over having to do expensive calculations
82  // for EVERY pixel in the image (most of which do not require said calculations).
83  if (w >= 0 && w < width() && h >= 0 && h < height()) {
84  return m_desc.at(n, h, w, c);
85  }
86 
87  // Otherwise, do some additional calculations to map the provided x and y coordinates to be within bounds.
88  int64_t x = w, y = h;
89  int64_t imgWidth = width(), imgHeight = height();
90 
91  // Reflect border type implementation. (Note: This is NOT REFLECT101, pixels at the border will be duplicated as
92  // is the intended behavior for this border mode.)
93  if constexpr (BorderType == eBorderType::BORDER_TYPE_REFLECT) {
94  // There is a special case if we have a dimension of size 1
95  if (imgWidth == 1) {
96  x = 0;
97  } else {
98  int64_t scale = imgWidth * 2;
99  int64_t val = (w % scale + scale) % scale;
100  x = (val < imgWidth) ? val : scale - 1 - val;
101  }
102 
103  if (imgHeight == 1) {
104  y = 0;
105  } else {
106  int64_t scale = imgHeight * 2;
107  int64_t val = (h % scale + scale) % scale;
108  y = (val < imgHeight) ? val : scale - 1 - val;
109  }
110  }
111 
112  // Replicate border type implementation
113  if constexpr (BorderType == eBorderType::BORDER_TYPE_REPLICATE) {
114  x = std::clamp<int64_t>(w, 0, imgWidth - 1);
115  y = std::clamp<int64_t>(h, 0, imgHeight - 1);
116  }
117 
118  // Wrap border type implementation
119  if constexpr (BorderType == eBorderType::BORDER_TYPE_WRAP) {
120  if (w < 0 || w >= imgWidth) {
121  x = (w % imgWidth + imgWidth) % imgWidth;
122  }
123 
124  if (h < 0 || h >= imgHeight) {
125  y = (h % imgHeight + imgHeight) % imgHeight;
126  }
127  }
128 
129  return m_desc.at(n, y, x, c);
130  }
131 
137  __device__ __host__ inline int64_t height() const { return m_desc.height(); }
138 
144  __device__ __host__ inline int64_t width() const { return m_desc.width(); }
145 
151  __device__ __host__ inline int64_t batches() const { return m_desc.batches(); }
152 
158  __device__ __host__ inline int64_t channels() const { return m_desc.channels(); }
159 
160  private:
161  ImageWrapper<T> m_desc;
162  T m_border_value;
163 };
164 } // namespace roccv
Wrapper class for ImageWrapper. This extends the descriptors by defining behaviors for when tensor co...
Definition: border_wrapper.hpp:39
__device__ __host__ int64_t batches() const
Retrieves the number of batches in the image tensor.
Definition: border_wrapper.hpp:151
__device__ __host__ int64_t width() const
Retrieves the width of the image.
Definition: border_wrapper.hpp:144
__device__ __host__ int64_t height() const
Retrives the height of the images.
Definition: border_wrapper.hpp:137
__device__ __host__ int64_t channels() const
Retries the number of channels in the image.
Definition: border_wrapper.hpp:158
BorderWrapper(ImageWrapper< T > image_wrapper, T border_value)
Constructs a BorderWrapper from an existing ImageWrapper. Extends its capabilities to handle out of b...
Definition: border_wrapper.hpp:56
BorderWrapper(const Tensor &tensor, T border_value)
Wraps an ImageWrapper and extends its capabilities to handle out of bounds coordinates.
Definition: border_wrapper.hpp:47
__device__ __host__ const T at(int64_t n, int64_t h, int64_t w, int64_t c) const
Returns a reference to the underlying data given image coordinates. If the coordinates fall out of bo...
Definition: border_wrapper.hpp:69
ImageWrapper is a non-owning wrapper for roccv::Tensors with a NHWC/NCHW/HWC layout....
Definition: image_wrapper.hpp:40
Definition: tensor.hpp:37
Definition: strided_data_wrap.hpp:33
@ BORDER_TYPE_REPLICATE
Replicates the last element for borders.
Definition: operator_types.h:38
@ BORDER_TYPE_WRAP
Wraps the border elements.
Definition: operator_types.h:40
@ BORDER_TYPE_CONSTANT
Uses a constant value for borders.
Definition: operator_types.h:37
@ BORDER_TYPE_REFLECT
Reflects the border elements.
Definition: operator_types.h:39