From 7b7858df42fccefbe6eb086ad516d5c011becd07 Mon Sep 17 00:00:00 2001 From: Georgios Pinitas Date: Wed, 21 Jun 2017 16:44:24 +0100 Subject: COMPMID-359: Implement NEON ROIPoolingLayer Change-Id: Ibffa738d4016d7221968bd43a4e6e1dab85baee8 Reviewed-on: http://mpd-gerrit.cambridge.arm.com/78623 Reviewed-by: Moritz Pflanzer Reviewed-by: Gian Marco Iodice Tested-by: Kaizen --- tests/validation/TensorOperations.h | 72 +++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'tests/validation/TensorOperations.h') diff --git a/tests/validation/TensorOperations.h b/tests/validation/TensorOperations.h index 4f7765613c..5499e58f35 100644 --- a/tests/validation/TensorOperations.h +++ b/tests/validation/TensorOperations.h @@ -1438,6 +1438,78 @@ void pooling_layer(const Tensor &in, Tensor &out, PoolingLayerInfo pool_in } } +// Pooling layer +template +void roi_pooling_layer(const Tensor &in, Tensor &out, const std::vector &rois, const ROIPoolingLayerInfo &pool_info) +{ + const int num_rois = rois.size(); + const int width_in = in.shape().x(); + const int height_in = in.shape().y(); + const int fms = in.shape().z(); + const int volume_in = width_in * height_in * fms; + const int pool_w = pool_info.pooled_width(); + const int pool_h = pool_info.pooled_height(); + const int volume_out = pool_w * pool_h * fms; + const float roi_scale = pool_info.spatial_scale(); + + // Iterate through all rois + for(int roi_idx = 0; roi_idx < num_rois; ++roi_idx) + { + // Get dimensions of current ROI + const ROI &roi = rois[roi_idx]; + + int batch_id = roi.batch_idx; + int roi_start_x = support::cpp11::round(roi.rect.x * roi_scale); + int roi_start_y = support::cpp11::round(roi.rect.y * roi_scale); + int roi_width = std::max(support::cpp11::round(roi.rect.width * roi_scale), 1.f); + int roi_height = std::max(support::cpp11::round(roi.rect.height * roi_scale), 1.f); + + // Determine pooling regions + float pool_region_size_x = static_cast(roi_width) / pool_w; + float pool_region_size_y = static_cast(roi_height) / pool_h; + + // Iterate through all channel + for(int fm = 0; fm < fms; ++fm) + { + // Calculate each output pixel + for(int py = 0; py < pool_h; ++py) + { + for(int px = 0; px < pool_w; ++px) + { + int region_start_x = static_cast(std::floor(px * pool_region_size_x)); + int region_end_x = static_cast(std::ceil((px + 1) * pool_region_size_x)); + int region_start_y = static_cast(std::floor(py * pool_region_size_y)); + int region_end_y = static_cast(std::ceil((py + 1) * pool_region_size_y)); + + region_start_x = std::min(std::max(region_start_x + roi_start_x, 0), width_in); + region_end_x = std::min(std::max(region_end_x + roi_start_x, 0), width_in); + region_start_y = std::min(std::max(region_start_y + roi_start_y, 0), height_in); + region_end_y = std::min(std::max(region_end_y + roi_start_y, 0), height_in); + + // Iterate through each pixel in the pooling region + if((region_end_x <= region_start_x) || (region_end_y <= region_start_y)) + { + out[roi_idx * volume_out + fm * pool_w * pool_h + py * pool_w + px] = 0; + } + else + { + T curr_max = std::numeric_limits::lowest(); + for(int j = region_start_y; j < region_end_y; ++j) + { + for(int i = region_start_x; i < region_end_x; ++i) + { + const auto val = in[batch_id * volume_in + fm * width_in * height_in + j * width_in + i]; + curr_max = std::max(val, curr_max); + } + } + out[roi_idx * volume_out + fm * pool_w * pool_h + py * pool_w + px] = curr_max; + } + } + } + } + } +} + // Softmax Layer template ::value, int>::type * = nullptr> void softmax_layer(const Tensor &in, Tensor &out) -- cgit v1.2.1