54 if((region_end_x <= region_start_x) || (region_end_y <= region_start_y))
62 for(
int iy = 0; iy < grid_size_y; ++iy)
64 for(
int ix = 0; ix < grid_size_x; ++ix)
67 float y = region_start_y + (iy + 0.5) * bin_size_y / float(grid_size_y);
68 float x = region_start_x + (ix + 0.5) * bin_size_x / float(grid_size_x);
73 const int y_high = y_low + 1;
74 const int x_high = x_low + 1;
76 const float ly = y - y_low;
77 const float lx = x - x_low;
78 const float hy = 1. - ly;
79 const float hx = 1. - lx;
81 const float w1 = hy * hx;
82 const float w2 = hy * lx;
83 const float w3 = ly * hx;
84 const float w4 = ly * lx;
86 const size_t idx1 =
coord2index(input_shape, Coordinates(x_low, y_low, pz));
87 float data1 = input[idx1];
89 const size_t idx2 =
coord2index(input_shape, Coordinates(x_high, y_low, pz));
90 float data2 = input[idx2];
92 const size_t idx3 =
coord2index(input_shape, Coordinates(x_low, y_high, pz));
93 float data3 = input[idx3];
95 const size_t idx4 =
coord2index(input_shape, Coordinates(x_high, y_high, pz));
96 float data4 = input[idx4];
98 avg += w1 * data1 + w2 * data2 + w3 * data3 + w4 * data4;
102 avg /= grid_size_x * grid_size_y;
108 template <
typename TI,
typename TO>
109 SimpleTensor<TO> float_converter(
const SimpleTensor<TI> &tensor,
DataType dst_dt)
111 SimpleTensor<TO>
dst{ tensor.shape(), dst_dt, 1, QuantizationInfo(), tensor.data_layout() };
113 #pragma omp parallel for 115 for(
int i = 0; i < tensor.num_elements(); ++i)
122 SimpleTensor<float> convert_rois_from_asymmetric(SimpleTensor<uint16_t> rois)
124 const UniformQuantizationInfo &quantization_info = rois.quantization_info().uniform();
125 SimpleTensor<float>
dst{ rois.shape(),
DataType::F32, 1, QuantizationInfo(), rois.data_layout() };
127 for(
int i = 0; i < rois.num_elements(); i += 5)
129 dst[i] =
static_cast<float>(rois[i]);
144 const size_t values_per_roi = rois.
shape()[0];
145 const size_t num_rois = rois.
shape()[1];
148 const auto *rois_ptr =
static_cast<const float *
>(rois.
data());
159 for(
size_t pw = 0; pw < num_rois; ++pw)
161 const unsigned int roi_batch = rois_ptr[values_per_roi * pw];
162 const auto x1 = float(rois_ptr[values_per_roi * pw + 1]);
163 const auto y1 = float(rois_ptr[values_per_roi * pw + 2]);
164 const auto x2 = float(rois_ptr[values_per_roi * pw + 3]);
165 const auto y2 = float(rois_ptr[values_per_roi * pw + 4]);
169 const float roi_dims_x = std::max((x2 - x1) * pool_info.
spatial_scale(), 1.0f);
170 const float roi_dims_y = std::max((y2 - y1) * pool_info.
spatial_scale(), 1.0f);
172 float bin_size_x = roi_dims_x / pool_info.
pooled_width();
174 float region_start_x = px * bin_size_x + roi_anchor_x;
175 float region_start_y = py * bin_size_y + roi_anchor_y;
176 float region_end_x = (px + 1) * bin_size_x + roi_anchor_x;
177 float region_end_y = (py + 1) * bin_size_y + roi_anchor_y;
179 region_start_x =
utility::clamp(region_start_x, 0.0f,
float(input_shape[0]));
180 region_start_y =
utility::clamp(region_start_y, 0.0f,
float(input_shape[1]));
181 region_end_x =
utility::clamp(region_end_x, 0.0f,
float(input_shape[0]));
182 region_end_y =
utility::clamp(region_end_y, 0.0f,
float(input_shape[1]));
188 const size_t input_stride_w = input_shape[0] * input_shape[1] * input_shape[2];
190 const float *input_ptr = src.
data() + roi_batch * input_stride_w;
191 float *output_ptr = dst.data() + px + py * output_shape[0] + pw * output_stride_w;
193 for(
int pz = 0; pz < int(input_shape[2]); ++pz)
196 *(output_ptr + pz * output_shape[0] * output_shape[1]) =
roi_align_1x1(input_ptr, input_shape,
217 SimpleTensor<float> dst_tmp = roi_align_layer<float, float>(src_tmp, rois_tmp, pool_info, output_qinfo);
227 SimpleTensor<float> dst_tmp = roi_align_layer<float, float>(src_tmp, rois_tmp, pool_info, output_qinfo);
236 SimpleTensor<float> dst_tmp = roi_align_layer<float, float>(src_tmp, rois_tmp, pool_info, output_qinfo);
input_data_type roi_align_1x1(const ITensor *input, unsigned int roi_batch, float region_start_x, float bin_size_x, int grid_size_x, float region_end_x, float region_start_y, float bin_size_y, int grid_size_y, float region_end_y, int pz)
Average pooling over an aligned window.
1 channel, 1 F32 per channel
DataType data_type() const override
Data type of the tensor.
SimpleTensor< float > convert_from_asymmetric(const SimpleTensor< uint8_t > &src)
TensorShape shape() const override
Shape of the tensor.
unsigned int pooled_width() const
Get the pooled width of the layer.
SimpleTensor< float > src
Copyright (c) 2017-2021 Arm Limited.
int coord2index(const TensorShape &shape, const Coordinates &coord)
Linearise the given coordinate.
1 channel, 1 F16 per channel
DataType clamp(const DataType &n, const DataType &lower=std::numeric_limits< RangeType >::lowest(), const DataType &upper=std::numeric_limits< RangeType >::max())
Performs clamping among a lower and upper value.
float dequantize_qasymm16(uint16_t value, const UniformQuantizationInfo &qinfo)
Dequantize a value given a 16-bit asymmetric quantization scheme.
Quantization information.
TensorShape input_shape
Validate test suite is to test ARM_COMPUTE_RETURN_ON_* macros we use to check the validity of given a...
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
unsigned int sampling_ratio() const
Get sampling ratio.
Simple tensor object that stores elements in a consecutive chunk of memory.
unsigned int pooled_height() const
Get the pooled height of the layer.
ROI Pooling Layer Information class.
float spatial_scale() const
Get the spatial scale.
DataType
Available data types.
SimpleTensor< float > roi_align_layer(const SimpleTensor< float > &src, const SimpleTensor< float > &rois, const ROIPoolingLayerInfo &pool_info, const QuantizationInfo &output_qinfo)
const T * data() const
Constant pointer to the underlying buffer.