COMPMID-1676: Change CLROIAlign interface to accept ROIs as tensors

Change-Id: I69e995973597ba3927d29e4f6ed5438560e53d77
diff --git a/arm_compute/core/CL/kernels/CLROIAlignLayerKernel.h b/arm_compute/core/CL/kernels/CLROIAlignLayerKernel.h
index 6908675..b5e0232 100644
--- a/arm_compute/core/CL/kernels/CLROIAlignLayerKernel.h
+++ b/arm_compute/core/CL/kernels/CLROIAlignLayerKernel.h
@@ -52,7 +52,8 @@
     /** Set the input and output tensors.
      *
      * @param[in]  input     Source tensor. Data types supported: F16/F32.
-     * @param[in]  rois      Array containing @ref ROI.
+     * @param[in]  rois      ROIs tensor, it is a 2D tensor of size [5, N] (where N is the number of ROIs) containing top left and bottom right corner
+     *                       as coordinate of an image and batch_id of ROI [ batch_id, x1, y1, x2, y2 ]. Data types supported: same as @p input
      * @param[out] output    Destination tensor. Data types supported: Same as @p input.
      * @param[in]  pool_info Contains pooling operation information described in @ref ROIPoolingLayerInfo.
      *
@@ -61,11 +62,11 @@
      * @note The z dimensions of @p output tensor and @p input tensor must be the same.
      * @note The fourth dimension of @p output tensor must be the same as the number of elements in @p rois array.
      */
-    void configure(const ICLTensor *input, const ICLROIArray *rois, ICLTensor *output, const ROIPoolingLayerInfo &pool_info);
+    void configure(const ICLTensor *input, const ICLTensor *rois, ICLTensor *output, const ROIPoolingLayerInfo &pool_info);
     /** Static function to check if given info will lead to a valid configuration of @ref CLROIAlignLayerKernel
      *
      * @param[in]  input     Source tensor info. Data types supported: F16/F32.
-     * @param[in]  num_rois  Length of the array containing @ref ROI.
+     * @param[in]  rois      ROIs tensor info. Data types supported: same as @p input
      * @param[out] output    Destination tensor info. Data types supported: Same as @p input.
      * @param[in]  pool_info Contains pooling operation information described in @ref ROIPoolingLayerInfo.
      *
@@ -76,7 +77,7 @@
      *
      * @return a Status
      */
-    static Status validate(const ITensorInfo *input, size_t num_rois, ITensorInfo *output, const ROIPoolingLayerInfo &pool_info);
+    static Status validate(const ITensorInfo *input, const ITensorInfo *rois, ITensorInfo *output, const ROIPoolingLayerInfo &pool_info);
 
     // Inherited methods overridden:
     void run(const Window &window, cl::CommandQueue &queue);
@@ -84,7 +85,7 @@
 private:
     const ICLTensor    *_input;
     ICLTensor          *_output;
-    const ICLROIArray *_rois;
+    const ICLTensor    *_rois;
     ROIPoolingLayerInfo _pool_info;
 };
 } // namespace arm_compute
diff --git a/arm_compute/runtime/CL/functions/CLROIAlignLayer.h b/arm_compute/runtime/CL/functions/CLROIAlignLayer.h
index 6cf9bd2..fec0dac 100644
--- a/arm_compute/runtime/CL/functions/CLROIAlignLayer.h
+++ b/arm_compute/runtime/CL/functions/CLROIAlignLayer.h
@@ -44,7 +44,8 @@
     /** Set the input and output tensors.
      *
      * @param[in]  input     Source tensor. Data types supported: F16/F32.
-     * @param[in]  rois      Array containing @ref ROI.
+     * @param[in]  rois      ROIs tensor, it is a 2D tensor of size [5, N] (where N is the number of ROIs) containing top left and bottom right corner
+     *                       as coordinate of an image and batch_id of ROI [ batch_id, x1, y1, x2, y2 ]. Data types supported: same as @p input
      * @param[out] output    Destination tensor. Data types supported: Same as @p input.
      * @param[in]  pool_info Contains pooling operation information described in @ref ROIPoolingLayerInfo.
      *
@@ -53,11 +54,11 @@
      * @note The z dimensions of @p output tensor and @p input tensor must be the same.
      * @note The fourth dimension of @p output tensor must be the same as the number of elements in @p rois array.
      */
-    void configure(const ICLTensor *input, const ICLROIArray *rois, ICLTensor *output, const ROIPoolingLayerInfo &pool_info);
+    void configure(const ICLTensor *input, const ICLTensor *rois, ICLTensor *output, const ROIPoolingLayerInfo &pool_info);
     /** Static function to check if given info will lead to a valid configuration of @ref CLROIAlignLayer
      *
      * @param[in]  input     Source tensor info. Data types supported: F16/F32.
-     * @param[in]  num_rois  Length of the array containing @ref ROI.
+     * @param[in]  rois      ROIs tensor info. Data types supported: same as @p input
      * @param[out] output    Destination tensor info. Data types supported: Same as @p input.
      * @param[in]  pool_info Contains pooling operation information described in @ref ROIPoolingLayerInfo.
      *
@@ -68,7 +69,7 @@
      *
      * @return a Status
      */
-    static Status validate(const ITensorInfo *input, size_t num_rois, ITensorInfo *output, const ROIPoolingLayerInfo &pool_info);
+    static Status validate(const ITensorInfo *input, const ITensorInfo *rois, ITensorInfo *output, const ROIPoolingLayerInfo &pool_info);
 };
 } // namespace arm_compute
 #endif /* __ARM_COMPUTE_CLROIALIGNLAYER_H__ */
diff --git a/src/core/CL/cl_kernels/roi_align_layer.cl b/src/core/CL/cl_kernels/roi_align_layer.cl
index 4625e53..f52eb18 100644
--- a/src/core/CL/cl_kernels/roi_align_layer.cl
+++ b/src/core/CL/cl_kernels/roi_align_layer.cl
@@ -97,38 +97,40 @@
  * @note Sampling ratio (i.e., the number of samples in each bin) may be passed using -DSAMPLING_RATIO. If not defined each roi
  *       will have a default sampling ratio of roi_dims/pooling_dims
  *
- * @param[in]  input_ptr                            Pointer to the source image. Supported data types: F16, F32
- * @param[in]  input_stride_x                       Stride of the source image in X dimension (in bytes)
+ * @param[in]  input_ptr                            Pointer to the source tensor. Supported data types: F16, F32
+ * @param[in]  input_stride_x                       Stride of the source tensor in X dimension (in bytes)
  * @param[in]  input_step_x                         input_stride_x * number of elements along X processed per workitem(in bytes)
- * @param[in]  input_stride_y                       Stride of the source image in Y dimension (in bytes)
+ * @param[in]  input_stride_y                       Stride of the source tensor in Y dimension (in bytes)
  * @param[in]  input_step_y                         input_stride_y * number of elements along Y processed per workitem(in bytes)
  * @param[in]  input_stride_z                       Stride of the source tensor in Z dimension (in bytes)
  * @param[in]  input_step_z                         input_stride_z * number of elements along Z processed per workitem(in bytes)
- * @param[in]  input_offset_first_element_in_bytes  The offset of the first element in the pooled region of the source image as specifed by ROI
- * @param[in]  rois_ptr                             Pointer to the rois array. Layout: {x, y, width, height, batch_indx}
- * @param[in]  rois_stride_x                        Stride of the rois array in X dimension (in bytes)
- * @param[in]  rois_step_x                          rois_stride_x * number of elements along X processed per workitem(in bytes)
- * @param[in]  rois_offset_first_element_in_bytes   The offset of the first element in the rois array
- * @param[out] output_ptr                           Pointer to the destination image. Supported data types: F16, F32
- * @param[in]  output_stride_x                      Stride of the destination image in X dimension (in bytes)
+ * @param[in]  input_offset_first_element_in_bytes  The offset of the first element in the pooled region of the source tensor as specifed by ROI
+ * @param[in]  rois_ptr                             Pointer to the ROIs tensor. Layout: { batch_index, x1, y1, x2, y2 }. Supported data types: same as @p input_ptr
+ * @param[in]  rois_stride_x                        Stride of the ROIs tensor in X dimension (in bytes)
+ * @param[in]  rois_step_x                          Step of the ROIs tensor in X dimension (in bytes)
+ * @param[in]  rois_stride_y                        Stride of the ROIs tensor in Y dimension (in bytes)
+ * @param[in]  rois_step_y                          Step of the ROIs tensor in Y dimension (in bytes)
+ * @param[in]  rois_offset_first_element_in_bytes   The offset of the first element in the ROIs tensor
+ * @param[out] output_ptr                           Pointer to the destination tensor. Supported data types: Supported data types: same as @p input_ptr
+ * @param[in]  output_stride_x                      Stride of the destination tensor in X dimension (in bytes)
  * @param[in]  output_step_x                        output_stride_x * number of elements along X processed per workitem(in bytes)
- * @param[in]  output_stride_y                      Stride of the destination image in Y dimension (in bytes)
+ * @param[in]  output_stride_y                      Stride of the destination tensor in Y dimension (in bytes)
  * @param[in]  output_step_y                        output_stride_y * number of elements along Y processed per workitem(in bytes)
  * @param[in]  output_stride_z                      Stride of the destination tensor in Z dimension (in bytes)
  * @param[in]  output_step_z                        output_stride_z * number of elements along Z processed per workitem(in bytes)
- * @param[in]  output_offset_first_element_in_bytes The offset of the first element in the destination image
- * @param[in]  input_stride_w                       Stride of the source image in W dimension (in bytes)
- * @param[in]  output_stride_w                      Stride of the destination image in W dimension (in bytes)
+ * @param[in]  output_offset_first_element_in_bytes The offset of the first element in the destination tensor
+ * @param[in]  input_stride_w                       Stride of the source tensor in W dimension (in bytes)
+ * @param[in]  output_stride_w                      Stride of the destination tensor in W dimension (in bytes)
  */
 __kernel void roi_align_layer(
     TENSOR3D_DECLARATION(input),
-    VECTOR_DECLARATION(rois),
+    IMAGE_DECLARATION(rois),
     TENSOR3D_DECLARATION(output),
     unsigned int input_stride_w, unsigned int output_stride_w)
 {
     // Get pixels pointer
     Tensor3D input  = CONVERT_TO_TENSOR3D_STRUCT_NO_STEP(input);
-    Vector   rois   = CONVERT_TO_VECTOR_STRUCT_NO_STEP(rois);
+    Image    rois   = CONVERT_TO_IMAGE_STRUCT_NO_STEP(rois);
     Tensor3D output = CONVERT_TO_TENSOR3D_STRUCT_NO_STEP(output);
 
     const int px = get_global_id(0);
@@ -136,19 +138,19 @@
     const int pw = get_global_id(2);
 
     // Load roi parameters
-    // roi is laid out as follows:
-    // { x, y, width, height, batch_index }
-    const ushort4 roi       = vload4(0, (__global ushort *)vector_offset(&rois, pw));
-    const ushort roi_batch  = *((__global ushort *)vector_offset(&rois, pw) + 4);
+    // roi is laid out as follows { batch_index, x1, y1, x2, y2 }
+    const ushort roi_batch = (ushort) * ((__global DATA_TYPE *)offset(&rois, 0, pw));
+    const VEC_DATA_TYPE(DATA_TYPE, 4)
+    roi                 = vload4(0, (__global DATA_TYPE *)offset(&rois, 1, pw));
     const float2 roi_anchor = convert_float2(roi.s01) * convert_float(SPATIAL_SCALE);
-    const float2 roi_dims   = fmax(convert_float2(roi.s23) * convert_float(SPATIAL_SCALE), 1.f);
+    const float2 roi_dims   = fmax(convert_float2(roi.s23 - roi.s01) * convert_float(SPATIAL_SCALE), 1.f);
 
     // Calculate pooled region start and end
     const float2 spatial_indx     = (float2)(px, py);
     const float2 pooled_dims      = (float2)(POOLED_DIM_X, POOLED_DIM_Y);
     const float2 max_spatial_dims = (float2)(MAX_DIM_X, MAX_DIM_Y);
 
-    const float2 bin_size     = roi_dims / pooled_dims;
+    const float2 bin_size     = (float2)((roi_dims.s0 / (float)POOLED_DIM_X), (roi_dims.s1 / (float)POOLED_DIM_Y));
     float2       region_start = spatial_indx * bin_size + roi_anchor;
     float2       region_end   = (spatial_indx + 1) * bin_size + roi_anchor;
 
@@ -159,7 +161,7 @@
     const float2 roi_bin_grid = SAMPLING_RATIO;
 #else  // !defined(SAMPLING_RATIO)
     // Note that we subtract EPS_GRID before ceiling. This is to avoid situations where 1.000001 gets ceiled to 2.
-    const float2 roi_bin_grid = ceil(roi_dims / pooled_dims - EPS_GRID);
+    const float2 roi_bin_grid = ceil(bin_size - EPS_GRID);
 #endif // defined(SAMPLING_RATIO)
 
     // Move input and output pointer across the fourth dimension
diff --git a/src/core/CL/kernels/CLROIAlignLayerKernel.cpp b/src/core/CL/kernels/CLROIAlignLayerKernel.cpp
index 2e1e854..2d2ac07 100644
--- a/src/core/CL/kernels/CLROIAlignLayerKernel.cpp
+++ b/src/core/CL/kernels/CLROIAlignLayerKernel.cpp
@@ -39,24 +39,47 @@
 {
 namespace
 {
-Status validate_arguments(const ITensorInfo *input, size_t num_rois, const ITensorInfo *output, const ROIPoolingLayerInfo &pool_info)
+Status validate_arguments(const ITensorInfo *input, const ITensorInfo *rois, ITensorInfo *output, const ROIPoolingLayerInfo &pool_info)
 {
-    ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, output);
+    ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, rois, output);
+    ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, rois);
+    ARM_COMPUTE_RETURN_ERROR_ON(rois->dimension(0) != 5);
+    ARM_COMPUTE_RETURN_ERROR_ON(rois->num_dimensions() > 2);
     ARM_COMPUTE_RETURN_ERROR_ON_F16_UNSUPPORTED(input);
     ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::F32, DataType::F16);
     ARM_COMPUTE_RETURN_ERROR_ON((pool_info.pooled_width() == 0) || (pool_info.pooled_height() == 0));
-    ARM_COMPUTE_RETURN_ERROR_ON(num_rois == 0);
 
     if(output->total_size() != 0)
     {
         ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, output);
         ARM_COMPUTE_RETURN_ERROR_ON((output->dimension(0) != pool_info.pooled_width()) || (output->dimension(1) != pool_info.pooled_height()));
         ARM_COMPUTE_RETURN_ERROR_ON(input->dimension(2) != output->dimension(2));
-        ARM_COMPUTE_RETURN_ERROR_ON(num_rois != output->dimension(3));
+        ARM_COMPUTE_RETURN_ERROR_ON(rois->dimension(1) != output->dimension(3));
     }
 
     return Status{};
 }
+
+std::pair<Status, Window> validate_and_configure_window(ITensorInfo *input, ITensorInfo *rois, ITensorInfo *output, const ROIPoolingLayerInfo &pool_info)
+{
+    ARM_COMPUTE_ERROR_ON_NULLPTR(input, output);
+
+    // Output auto inizialitation if not yet initialized
+    TensorShape output_shape(pool_info.pooled_width(), pool_info.pooled_height(), input->dimension(2), rois->dimension(1));
+    auto_init_if_empty((*output), output_shape, 1, input->data_type());
+
+    // Configure kernel window
+    const unsigned int num_elems_processed_per_iteration = 1;
+    Window             win                               = calculate_max_window(*output, Steps(num_elems_processed_per_iteration));
+
+    AccessWindowHorizontal output_access(output, 0, num_elems_processed_per_iteration);
+    AccessWindowHorizontal input_access(input, input->valid_region().start(0), num_elems_processed_per_iteration);
+
+    bool window_changed = update_window_and_padding(win, input_access, output_access);
+    output_access.set_valid_region(win, ValidRegion(Coordinates(), output->tensor_shape()));
+    Status err = (window_changed) ? ARM_COMPUTE_CREATE_ERROR(ErrorCode::RUNTIME_ERROR, "Insufficient Padding!") : Status{};
+    return std::make_pair(err, win);
+}
 } // namespace
 
 CLROIAlignLayerKernel::CLROIAlignLayerKernel()
@@ -64,13 +87,14 @@
 {
 }
 
-void CLROIAlignLayerKernel::configure(const ICLTensor *input, const ICLROIArray *rois, ICLTensor *output, const ROIPoolingLayerInfo &pool_info)
+void CLROIAlignLayerKernel::configure(const ICLTensor *input, const ICLTensor *rois, ICLTensor *output, const ROIPoolingLayerInfo &pool_info)
 {
     ARM_COMPUTE_ERROR_ON_NULLPTR(input, output, rois);
-    ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), rois->num_values(), output->info(), pool_info));
+    ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), rois->info(), output->info(), pool_info));
 
-    TensorShape output_shape(pool_info.pooled_width(), pool_info.pooled_height(), input->info()->dimension(2), rois->num_values());
-    auto_init_if_empty(*output->info(), output_shape, 1, input->info()->data_type());
+    // Configure kernel window
+    auto win_config = validate_and_configure_window(input->info(), rois->info(), output->info(), pool_info);
+    ARM_COMPUTE_ERROR_THROW_ON(win_config.first);
 
     _input     = input;
     _output    = output;
@@ -78,46 +102,27 @@
     _pool_info = pool_info;
 
     // Set build options
-    std::set<std::string> build_opts;
-    build_opts.emplace(("-DDATA_TYPE=" + get_cl_type_from_data_type(input->info()->data_type())));
-    build_opts.emplace(("-DDATA_SIZE=" + get_data_size_from_data_type(input->info()->data_type())));
-    build_opts.emplace(("-DMAX_DIM_X=" + support::cpp11::to_string(_input->info()->dimension(Window::DimX))));
-    build_opts.emplace(("-DMAX_DIM_Y=" + support::cpp11::to_string(_input->info()->dimension(Window::DimY))));
-    build_opts.emplace(("-DMAX_DIM_Z=" + support::cpp11::to_string(_input->info()->dimension(Window::DimZ))));
-    build_opts.emplace(("-DPOOLED_DIM_X=" + support::cpp11::to_string(pool_info.pooled_width())));
-    build_opts.emplace(("-DPOOLED_DIM_Y=" + support::cpp11::to_string(pool_info.pooled_height())));
-    build_opts.emplace(("-DSPATIAL_SCALE=" + float_to_string_with_full_precision(pool_info.spatial_scale())));
-    if(pool_info.sampling_ratio() > 0)
-    {
-        build_opts.emplace(("-DSAMPLING_RATIO=" + support::cpp11::to_string(pool_info.sampling_ratio())));
-    }
+    CLBuildOptions build_opts;
+    build_opts.add_option("-DDATA_TYPE=" + get_cl_type_from_data_type(input->info()->data_type()));
+    build_opts.add_option("-DDATA_SIZE=" + get_data_size_from_data_type(input->info()->data_type()));
+    build_opts.add_option("-DMAX_DIM_X=" + support::cpp11::to_string(_input->info()->dimension(Window::DimX)));
+    build_opts.add_option("-DMAX_DIM_Y=" + support::cpp11::to_string(_input->info()->dimension(Window::DimY)));
+    build_opts.add_option("-DMAX_DIM_Z=" + support::cpp11::to_string(_input->info()->dimension(Window::DimZ)));
+    build_opts.add_option("-DPOOLED_DIM_X=" + support::cpp11::to_string(pool_info.pooled_width()));
+    build_opts.add_option("-DPOOLED_DIM_Y=" + support::cpp11::to_string(pool_info.pooled_height()));
+    build_opts.add_option("-DSPATIAL_SCALE=" + float_to_string_with_full_precision(pool_info.spatial_scale()));
+    build_opts.add_option_if(pool_info.sampling_ratio() > 0, "-DSAMPLING_RATIO=" + support::cpp11::to_string(pool_info.sampling_ratio()));
 
     // Create kernel
     std::string kernel_name = "roi_align_layer";
-    _kernel                 = static_cast<cl::Kernel>(CLKernelLibrary::get().create_kernel(kernel_name, build_opts));
+    _kernel                 = static_cast<cl::Kernel>(CLKernelLibrary::get().create_kernel(kernel_name, build_opts.options()));
 
-    // Set static kernel arguments
-    unsigned int idx = 2 * num_arguments_per_3D_tensor() + num_arguments_per_1D_array();
-    add_argument<cl_uint>(idx, _input->info()->strides_in_bytes()[3]);
-    add_argument<cl_uint>(idx, _output->info()->strides_in_bytes()[3]);
-
-    // Configure kernel window
-    const unsigned int num_elems_processed_per_iteration = 1;
-    Window             window                            = calculate_max_window(*output->info(), Steps(num_elems_processed_per_iteration));
-    AccessWindowStatic input_access(input->info(),
-                                    input->info()->valid_region().start(0),
-                                    input->info()->valid_region().start(1),
-                                    input->info()->valid_region().end(0),
-                                    input->info()->valid_region().end(1));
-    AccessWindowStatic output_access(output->info(), 0, 0, pool_info.pooled_width(), pool_info.pooled_height());
-
-    output_access.set_valid_region(window, ValidRegion(Coordinates(), output->info()->tensor_shape()));
-    ICLKernel::configure_internal(window);
+    ICLKernel::configure_internal(win_config.second);
 }
 
-Status CLROIAlignLayerKernel::validate(const ITensorInfo *input, size_t num_rois, ITensorInfo *output, const ROIPoolingLayerInfo &pool_info)
+Status CLROIAlignLayerKernel::validate(const ITensorInfo *input, const ITensorInfo *rois, ITensorInfo *output, const ROIPoolingLayerInfo &pool_info)
 {
-    ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input, num_rois, output, pool_info));
+    ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input, rois, output, pool_info));
     return Status{};
 }
 
@@ -126,16 +131,20 @@
     ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this);
     ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(IKernel::window(), window);
 
-    Window slice = window.first_slice_window_3D();
-    // Parallelize spatially and across the fourth dimension of the output tensor (also across ROIArray)
+    Window slice      = window.first_slice_window_3D();
+    Window slice_rois = slice;
+    // Parallelize spatially and across the fourth dimension of the output tensor (also across ROITensor)
+    slice_rois.set_dimension_step(Window::DimX, _rois->info()->dimension(0));
     slice.set(Window::DimZ, window[3]);
 
     // Set arguments
     unsigned int idx = 0;
     add_3D_tensor_argument(idx, _input, slice);
-    add_1D_array_argument<ROI>(idx, _rois, Strides(sizeof(ROI)), 1U, slice);
+    add_2D_tensor_argument(idx, _rois, slice_rois);
     add_3D_tensor_argument(idx, _output, slice);
+    add_argument<cl_uint>(idx, _input->info()->strides_in_bytes()[3]);
+    add_argument<cl_uint>(idx, _output->info()->strides_in_bytes()[3]);
+
     enqueue(queue, *this, slice);
 }
-
 } // namespace arm_compute
diff --git a/src/runtime/CL/functions/CLROIAlignLayer.cpp b/src/runtime/CL/functions/CLROIAlignLayer.cpp
index 1528759..5bfd594 100644
--- a/src/runtime/CL/functions/CLROIAlignLayer.cpp
+++ b/src/runtime/CL/functions/CLROIAlignLayer.cpp
@@ -29,14 +29,14 @@
 
 namespace arm_compute
 {
-Status CLROIAlignLayer::validate(const ITensorInfo *input, size_t num_rois, ITensorInfo *output, const ROIPoolingLayerInfo &pool_info)
+Status CLROIAlignLayer::validate(const ITensorInfo *input, const ITensorInfo *rois, ITensorInfo *output, const ROIPoolingLayerInfo &pool_info)
 {
-    ARM_COMPUTE_RETURN_ON_ERROR(CLROIAlignLayerKernel::validate(input, num_rois, output, pool_info));
+    ARM_COMPUTE_RETURN_ON_ERROR(CLROIAlignLayerKernel::validate(input, rois, output, pool_info));
 
     return Status{};
 }
 
-void CLROIAlignLayer::configure(const ICLTensor *input, const ICLROIArray *rois, ICLTensor *output, const ROIPoolingLayerInfo &pool_info)
+void CLROIAlignLayer::configure(const ICLTensor *input, const ICLTensor *rois, ICLTensor *output, const ROIPoolingLayerInfo &pool_info)
 {
     // Configure ROI pooling kernel
     auto k = arm_compute::support::cpp14::make_unique<CLROIAlignLayerKernel>();
diff --git a/tests/datasets/ROIAlignLayerDataset.h b/tests/datasets/ROIAlignLayerDataset.h
new file mode 100644
index 0000000..27c6ee4
--- /dev/null
+++ b/tests/datasets/ROIAlignLayerDataset.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2018 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef ARM_COMPUTE_TEST_ROI_ALIGN_LAYER_DATASET
+#define ARM_COMPUTE_TEST_ROI_ALIGN_LAYER_DATASET
+
+#include "utils/TypePrinter.h"
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace datasets
+{
+class ROIAlignLayerDataset
+{
+public:
+    using type = std::tuple<TensorShape, ROIPoolingLayerInfo, TensorShape>;
+
+    struct iterator
+    {
+        iterator(std::vector<TensorShape>::const_iterator         tensor_shape_it,
+                 std::vector<ROIPoolingLayerInfo>::const_iterator infos_it,
+                 std::vector<TensorShape>::const_iterator         rois_shape_it)
+            : _tensor_shape_it{ std::move(tensor_shape_it) },
+              _infos_it{ std::move(infos_it) },
+              _rois_shape_it{ std::move(rois_shape_it) }
+        {
+        }
+
+        std::string description() const
+        {
+            std::stringstream description;
+            description << "In=" << *_tensor_shape_it << ":";
+            description << "Info=" << *_infos_it << ":";
+            description << "ROIS=" << *_rois_shape_it;
+            return description.str();
+        }
+
+        ROIAlignLayerDataset::type operator*() const
+        {
+            return std::make_tuple(*_tensor_shape_it, *_infos_it, *_rois_shape_it);
+        }
+
+        iterator &operator++()
+        {
+            ++_tensor_shape_it;
+            ++_infos_it;
+            ++_rois_shape_it;
+
+            return *this;
+        }
+
+    private:
+        std::vector<TensorShape>::const_iterator         _tensor_shape_it;
+        std::vector<ROIPoolingLayerInfo>::const_iterator _infos_it;
+        std::vector<TensorShape>::const_iterator         _rois_shape_it;
+    };
+
+    iterator begin() const
+    {
+        return iterator(_tensor_shapes.begin(), _infos.begin(), _rois_shape.begin());
+    }
+
+    int size() const
+    {
+        return std::min(std::min(_tensor_shapes.size(), _infos.size()), _rois_shape.size());
+    }
+
+    void add_config(TensorShape tensor_shape, ROIPoolingLayerInfo info, TensorShape rois_shape)
+    {
+        _tensor_shapes.emplace_back(std::move(tensor_shape));
+        _infos.emplace_back(std::move(info));
+        _rois_shape.emplace_back(std::move(rois_shape));
+    }
+
+protected:
+    ROIAlignLayerDataset()                        = default;
+    ROIAlignLayerDataset(ROIAlignLayerDataset &&) = default;
+
+private:
+    std::vector<TensorShape>         _tensor_shapes{};
+    std::vector<ROIPoolingLayerInfo> _infos{};
+    std::vector<TensorShape>         _rois_shape{};
+};
+
+class SmallROIAlignLayerDataset final : public ROIAlignLayerDataset
+{
+public:
+    SmallROIAlignLayerDataset()
+    {
+        add_config(TensorShape(50U, 47U, 1U, 1U), ROIPoolingLayerInfo(7U, 7U, 1.f / 4.f), TensorShape(5U, 1U));
+        add_config(TensorShape(50U, 47U, 3U, 4U), ROIPoolingLayerInfo(7U, 7U, 1.f / 4.f), TensorShape(5U, 1U));
+        add_config(TensorShape(50U, 47U, 3U, 1U), ROIPoolingLayerInfo(7U, 7U, 1.f / 4.f), TensorShape(5U, 10U));
+        add_config(TensorShape(50U, 47U, 10U, 1U), ROIPoolingLayerInfo(7U, 7U, 1.f / 4.f), TensorShape(5U, 80U));
+
+        //Spatial Scale 1/4
+        add_config(TensorShape(50U, 47U, 80U, 4U), ROIPoolingLayerInfo(7U, 7U, 1.f / 4.f), TensorShape(5U, 80U));
+        add_config(TensorShape(50U, 47U, 3U, 1U), ROIPoolingLayerInfo(9U, 9U, 1.f / 4.f), TensorShape(5U, 40U));
+        add_config(TensorShape(50U, 47U, 10U, 1U), ROIPoolingLayerInfo(9U, 9U, 1.f / 4.f), TensorShape(5U, 80U));
+        add_config(TensorShape(50U, 47U, 80U, 8U), ROIPoolingLayerInfo(9U, 9U, 1.f / 4.f), TensorShape(5U, 80U));
+
+        //Spatial Scale 1/8
+        add_config(TensorShape(50U, 47U, 80U, 4U), ROIPoolingLayerInfo(7U, 7U, 1.f / 8.f), TensorShape(5U, 80U));
+        add_config(TensorShape(50U, 47U, 3U, 1U), ROIPoolingLayerInfo(9U, 9U, 1.f / 8.f), TensorShape(5U, 40U));
+        add_config(TensorShape(50U, 47U, 10U, 1U), ROIPoolingLayerInfo(9U, 9U, 1.f / 8.f), TensorShape(5U, 80U));
+        add_config(TensorShape(50U, 47U, 80U, 8U), ROIPoolingLayerInfo(9U, 9U, 1.f / 8.f), TensorShape(5U, 80U));
+
+        //Spatial Scale 1/16
+        add_config(TensorShape(50U, 47U, 80U, 4U), ROIPoolingLayerInfo(7U, 7U, 1.f / 16.f), TensorShape(5U, 80U));
+        add_config(TensorShape(50U, 47U, 3U, 1U), ROIPoolingLayerInfo(9U, 9U, 1.f / 16.f), TensorShape(5U, 40U));
+        add_config(TensorShape(50U, 47U, 10U, 1U), ROIPoolingLayerInfo(9U, 9U, 1.f / 16.f), TensorShape(5U, 80U));
+        add_config(TensorShape(50U, 47U, 80U, 8U), ROIPoolingLayerInfo(9U, 9U, 1.f / 16.f), TensorShape(5U, 80U));
+    }
+};
+
+} // namespace datasets
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_ROI_ALIGN_LAYER_DATASET */
diff --git a/tests/validation/CL/ROIAlignLayer.cpp b/tests/validation/CL/ROIAlignLayer.cpp
index acea6d4..f3fc381 100644
--- a/tests/validation/CL/ROIAlignLayer.cpp
+++ b/tests/validation/CL/ROIAlignLayer.cpp
@@ -24,9 +24,8 @@
 #include "arm_compute/runtime/CL/CLScheduler.h"
 #include "arm_compute/runtime/CL/functions/CLROIAlignLayer.h"
 #include "tests/CL/CLAccessor.h"
-#include "tests/CL/CLArrayAccessor.h"
 #include "tests/Globals.h"
-#include "tests/datasets/ROIPoolingLayerDataset.h"
+#include "tests/datasets/ROIAlignLayerDataset.h"
 #include "tests/datasets/ShapeDatasets.h"
 #include "tests/framework/Macros.h"
 #include "tests/framework/datasets/Datasets.h"
@@ -43,7 +42,10 @@
 namespace
 {
 RelativeTolerance<float> relative_tolerance_f32(0.01f);
-RelativeTolerance<float> absolute_tolerance_f32(0.001f);
+AbsoluteTolerance<float> absolute_tolerance_f32(0.001f);
+
+RelativeTolerance<float> relative_tolerance_f16(0.01f);
+AbsoluteTolerance<float> absolute_tolerance_f16(0.001f);
 } // namespace
 
 TEST_SUITE(CL)
@@ -53,17 +55,28 @@
 // clang-format off
 DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(
                framework::dataset::make("InputInfo", { TensorInfo(TensorShape(250U, 128U, 3U), 1, DataType::F32),
+                                                       TensorInfo(TensorShape(250U, 128U, 3U), 1, DataType::F32), // Mismatching data type input/rois
                                                        TensorInfo(TensorShape(250U, 128U, 3U), 1, DataType::F32), // Mismatching data type input/output
                                                        TensorInfo(TensorShape(250U, 128U, 2U), 1, DataType::F32), // Mismatching depth size input/output
                                                        TensorInfo(TensorShape(250U, 128U, 2U), 1, DataType::F32), // Mismatching number of rois and output batch size
+                                                       TensorInfo(TensorShape(250U, 128U, 3U), 1, DataType::F32), // Invalid number of values per ROIS
                                                        TensorInfo(TensorShape(250U, 128U, 2U), 1, DataType::F32), // Mismatching height and width input/output
 
                                                      }),
-               framework::dataset::make("NumRois", { 3U, 3U, 4U, 10U, 4U})),
+               framework::dataset::make("RoisInfo", { TensorInfo(TensorShape(5, 3U), 1, DataType::F32),
+                                                      TensorInfo(TensorShape(5, 3U), 1, DataType::F16),
+                                                      TensorInfo(TensorShape(5, 3U), 1, DataType::F32),
+                                                      TensorInfo(TensorShape(5, 4U), 1, DataType::F32),
+                                                      TensorInfo(TensorShape(5, 10U), 1, DataType::F32),
+                                                      TensorInfo(TensorShape(4, 3U), 1, DataType::F32),
+                                                      TensorInfo(TensorShape(5, 4U), 1, DataType::F32),
+                                                    })),
                framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(7U, 7U, 3U, 3U), 1, DataType::F32),
+                                                       TensorInfo(TensorShape(7U, 7U, 3U, 3U), 1, DataType::F32),
                                                        TensorInfo(TensorShape(7U, 7U, 3U, 3U), 1, DataType::F16),
                                                        TensorInfo(TensorShape(7U, 7U, 4U, 3U), 1, DataType::F32),
                                                        TensorInfo(TensorShape(7U, 7U, 2U, 3U), 1, DataType::F32),
+                                                       TensorInfo(TensorShape(7U, 7U, 3U, 3U), 1, DataType::F32),
                                                        TensorInfo(TensorShape(5U, 5U, 2U, 4U), 1, DataType::F32),
                                                      })),
                framework::dataset::make("PoolInfo", { ROIPoolingLayerInfo(7U, 7U, 1./8),
@@ -71,30 +84,35 @@
                                                       ROIPoolingLayerInfo(7U, 7U, 1./8),
                                                       ROIPoolingLayerInfo(7U, 7U, 1./8),
                                                       ROIPoolingLayerInfo(7U, 7U, 1./8),
+                                                      ROIPoolingLayerInfo(7U, 7U, 1./8),
+                                                      ROIPoolingLayerInfo(7U, 7U, 1./8),
                                                       })),
-               framework::dataset::make("Expected", { true, false, false, false, false })),
-               input_info, num_rois, output_info, pool_info, expected)
+               framework::dataset::make("Expected", { true, false, false, false, false, false, false })),
+               input_info, rois_info, output_info, pool_info, expected)
 {
-    ARM_COMPUTE_EXPECT(bool(CLROIAlignLayer::validate(&input_info.clone()->set_is_resizable(true), num_rois, &output_info.clone()->set_is_resizable(true), pool_info)) == expected, framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(bool(CLROIAlignLayer::validate(&input_info.clone()->set_is_resizable(true), &rois_info.clone()->set_is_resizable(true), &output_info.clone()->set_is_resizable(true), pool_info)) == expected, framework::LogLevel::ERRORS);
 }
 // clang-format on
 // *INDENT-ON*
 
 template <typename T>
-using CLROIAlignLayerFixture = ROIAlignLayerFixture<CLTensor, CLAccessor, CLROIAlignLayer, CLArray<ROI>, CLArrayAccessor<ROI>, T>;
+using CLROIAlignLayerFixture = ROIAlignLayerFixture<CLTensor, CLAccessor, CLROIAlignLayer, T>;
 
 TEST_SUITE(Float)
-TEST_SUITE(FP32)
-FIXTURE_DATA_TEST_CASE(SmallROIAlignLayer, CLROIAlignLayerFixture<float>, framework::DatasetMode::ALL,
-                       framework::dataset::combine(framework::dataset::combine(datasets::SmallROIPoolingLayerDataset(),
-                                                                               framework::dataset::make("DataType", { DataType::F32 })),
-                                                   framework::dataset::make("Batches", { 1, 4, 8 })))
+FIXTURE_DATA_TEST_CASE(SmallROIAlignLayerFloat, CLROIAlignLayerFixture<float>, framework::DatasetMode::ALL,
+                       framework::dataset::combine(datasets::SmallROIAlignLayerDataset(),
+                                                   framework::dataset::make("DataType", { DataType::F32 })))
 {
     // Validate output
     validate(CLAccessor(_target), _reference, relative_tolerance_f32, .02f, absolute_tolerance_f32);
 }
-TEST_SUITE_END() // FP32
-
+FIXTURE_DATA_TEST_CASE(SmallROIAlignLayerHalf, CLROIAlignLayerFixture<half>, framework::DatasetMode::ALL,
+                       framework::dataset::combine(datasets::SmallROIAlignLayerDataset(),
+                                                   framework::dataset::make("DataType", { DataType::F16 })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, relative_tolerance_f16, .02f, absolute_tolerance_f16);
+}
 TEST_SUITE_END() // Float
 
 TEST_SUITE_END() // RoiAlign
diff --git a/tests/validation/fixtures/ROIAlignLayerFixture.h b/tests/validation/fixtures/ROIAlignLayerFixture.h
index d327b09..c029fba 100644
--- a/tests/validation/fixtures/ROIAlignLayerFixture.h
+++ b/tests/validation/fixtures/ROIAlignLayerFixture.h
@@ -41,18 +41,15 @@
 {
 namespace validation
 {
-template <typename TensorType, typename AccessorType, typename FunctionType, typename Array_T, typename ArrayAccessor, typename T>
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
 class ROIAlignLayerFixture : public framework::Fixture
 {
 public:
     template <typename...>
-    void setup(TensorShape input_shape, const ROIPoolingLayerInfo pool_info, unsigned int num_rois, DataType data_type, int batches)
+    void setup(TensorShape input_shape, const ROIPoolingLayerInfo pool_info, TensorShape rois_shape, DataType data_type)
     {
-        input_shape.set(2, batches);
-        std::vector<ROI> rois = generate_random_rois(input_shape, pool_info, num_rois, 0U);
-
-        _target    = compute_target(input_shape, data_type, rois, pool_info);
-        _reference = compute_reference(input_shape, data_type, rois, pool_info);
+        _target    = compute_target(input_shape, data_type, pool_info, rois_shape);
+        _reference = compute_reference(input_shape, data_type, pool_info, rois_shape);
     }
 
 protected:
@@ -62,37 +59,78 @@
         library->fill_tensor_uniform(tensor, 0);
     }
 
+    template <typename U>
+    void generate_rois(U &&rois, const TensorShape &shape, const ROIPoolingLayerInfo &pool_info, TensorShape rois_shape)
+    {
+        const size_t values_per_roi = rois_shape.x();
+        const size_t num_rois       = rois_shape.y();
+
+        std::mt19937 gen(library->seed());
+        T           *rois_ptr = static_cast<T *>(rois.data());
+
+        const float pool_width  = pool_info.pooled_width();
+        const float pool_height = pool_info.pooled_height();
+        const float roi_scale   = pool_info.spatial_scale();
+
+        // Calculate distribution bounds
+        const auto scaled_width  = static_cast<T>((shape.x() / roi_scale) / pool_width);
+        const auto scaled_height = static_cast<T>((shape.y() / roi_scale) / pool_height);
+        const auto min_width     = static_cast<T>(pool_width / roi_scale);
+        const auto min_height    = static_cast<T>(pool_height / roi_scale);
+
+        // Create distributions
+        std::uniform_int_distribution<int> dist_batch(0, shape[3] - 1);
+        std::uniform_int_distribution<>    dist_x1(0, scaled_width);
+        std::uniform_int_distribution<>    dist_y1(0, scaled_height);
+        std::uniform_int_distribution<>    dist_w(min_width, std::max(float(min_width), (pool_width - 2) * scaled_width));
+        std::uniform_int_distribution<>    dist_h(min_height, std::max(float(min_height), (pool_height - 2) * scaled_height));
+
+        for(unsigned int pw = 0; pw < num_rois; ++pw)
+        {
+            const auto batch_idx = dist_batch(gen);
+            const auto x1        = dist_x1(gen);
+            const auto y1        = dist_y1(gen);
+            const auto x2        = x1 + dist_w(gen);
+            const auto y2        = y1 + dist_h(gen);
+
+            rois_ptr[values_per_roi * pw]     = batch_idx;
+            rois_ptr[values_per_roi * pw + 1] = x1;
+            rois_ptr[values_per_roi * pw + 2] = y1;
+            rois_ptr[values_per_roi * pw + 3] = x2;
+            rois_ptr[values_per_roi * pw + 4] = y2;
+        }
+    }
+
     TensorType compute_target(const TensorShape         &input_shape,
                               DataType                   data_type,
-                              std::vector<ROI> const    &rois,
-                              const ROIPoolingLayerInfo &pool_info)
+                              const ROIPoolingLayerInfo &pool_info,
+                              const TensorShape          rois_shape)
     {
         // Create tensors
-        TensorType src = create_tensor<TensorType>(input_shape, data_type);
+        TensorType src         = create_tensor<TensorType>(input_shape, data_type);
+        TensorType rois_tensor = create_tensor<TensorType>(rois_shape, data_type);
         TensorType dst;
 
-        size_t num_rois = rois.size();
-
-        // Create roi arrays
-        std::unique_ptr<Array_T> rois_array = arm_compute::support::cpp14::make_unique<Array_T>(num_rois);
-        fill_array(ArrayAccessor(*rois_array), rois);
-
         // Create and configure function
         FunctionType roi_align_layer;
-        roi_align_layer.configure(&src, rois_array.get(), &dst, pool_info);
+        roi_align_layer.configure(&src, &rois_tensor, &dst, pool_info);
 
         ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(rois_tensor.info()->is_resizable(), framework::LogLevel::ERRORS);
         ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
         // Allocate tensors
         src.allocator()->allocate();
+        rois_tensor.allocator()->allocate();
         dst.allocator()->allocate();
 
         ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!rois_tensor.info()->is_resizable(), framework::LogLevel::ERRORS);
         ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
         // Fill tensors
         fill(AccessorType(src));
+        generate_rois(AccessorType(rois_tensor), input_shape, pool_info, rois_shape);
 
         // Compute function
         roi_align_layer.run();
@@ -102,16 +140,18 @@
 
     SimpleTensor<T> compute_reference(const TensorShape         &input_shape,
                                       DataType                   data_type,
-                                      std::vector<ROI> const    &rois,
-                                      const ROIPoolingLayerInfo &pool_info)
+                                      const ROIPoolingLayerInfo &pool_info,
+                                      const TensorShape          rois_shape)
     {
         // Create reference tensor
         SimpleTensor<T> src{ input_shape, data_type };
+        SimpleTensor<T> rois_tensor{ rois_shape, data_type };
 
         // Fill reference tensor
         fill(src);
+        generate_rois(rois_tensor, input_shape, pool_info, rois_shape);
 
-        return reference::roi_align_layer(src, rois, pool_info);
+        return reference::roi_align_layer(src, rois_tensor, pool_info);
     }
 
     TensorType      _target{};
diff --git a/tests/validation/reference/ROIAlignLayer.cpp b/tests/validation/reference/ROIAlignLayer.cpp
index 68a465d..8a76983 100644
--- a/tests/validation/reference/ROIAlignLayer.cpp
+++ b/tests/validation/reference/ROIAlignLayer.cpp
@@ -114,30 +114,35 @@
 }
 } // namespace
 template <typename T>
-SimpleTensor<T> roi_align_layer(const SimpleTensor<T> &src, const std::vector<ROI> &rois, const ROIPoolingLayerInfo &pool_info)
+SimpleTensor<T> roi_align_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &rois, const ROIPoolingLayerInfo &pool_info)
 {
-    const size_t num_rois      = rois.size();
-    DataType     dst_data_type = src.data_type();
+    const size_t values_per_roi = rois.shape()[0];
+    const size_t num_rois       = rois.shape()[1];
+    DataType     dst_data_type  = src.data_type();
+
+    const auto *rois_ptr = static_cast<const T *>(rois.data());
 
     TensorShape     input_shape = src.shape();
     TensorShape     output_shape(pool_info.pooled_width(), pool_info.pooled_height(), src.shape()[2], num_rois);
     SimpleTensor<T> dst(output_shape, dst_data_type);
 
     // Iterate over every pixel of the input image
-    for(size_t px = 0; px < pool_info.pooled_width(); px++)
+    for(size_t px = 0; px < pool_info.pooled_width(); ++px)
     {
-        for(size_t py = 0; py < pool_info.pooled_height(); py++)
+        for(size_t py = 0; py < pool_info.pooled_height(); ++py)
         {
-            for(size_t pw = 0; pw < num_rois; pw++)
+            for(size_t pw = 0; pw < num_rois; ++pw)
             {
-                ROI       roi       = rois[pw];
-                const int roi_batch = roi.batch_idx;
+                const unsigned int roi_batch = rois_ptr[values_per_roi * pw];
+                const auto         x1        = float(rois_ptr[values_per_roi * pw + 1]);
+                const auto         y1        = float(rois_ptr[values_per_roi * pw + 2]);
+                const auto         x2        = float(rois_ptr[values_per_roi * pw + 3]);
+                const auto         y2        = float(rois_ptr[values_per_roi * pw + 4]);
 
-                const float roi_anchor_x = roi.rect.x * pool_info.spatial_scale();
-                const float roi_anchor_y = roi.rect.y * pool_info.spatial_scale();
-                const float roi_dims_x   = std::max(roi.rect.width * pool_info.spatial_scale(), 1.0f);
-                const float roi_dims_y   = std::max(roi.rect.height * pool_info.spatial_scale(), 1.0f);
-                ;
+                const float roi_anchor_x = x1 * pool_info.spatial_scale();
+                const float roi_anchor_y = y1 * pool_info.spatial_scale();
+                const float roi_dims_x   = std::max((x2 - x1) * pool_info.spatial_scale(), 1.0f);
+                const float roi_dims_y   = std::max((y2 - y1) * pool_info.spatial_scale(), 1.0f);
 
                 float bin_size_x     = roi_dims_x / pool_info.pooled_width();
                 float bin_size_y     = roi_dims_y / pool_info.pooled_height();
@@ -178,8 +183,8 @@
     }
     return dst;
 }
-template SimpleTensor<float> roi_align_layer(const SimpleTensor<float> &src, const std::vector<ROI> &rois, const ROIPoolingLayerInfo &pool_info);
-template SimpleTensor<half> roi_align_layer(const SimpleTensor<half> &src, const std::vector<ROI> &rois, const ROIPoolingLayerInfo &pool_info);
+template SimpleTensor<float> roi_align_layer(const SimpleTensor<float> &src, const SimpleTensor<float> &rois, const ROIPoolingLayerInfo &pool_info);
+template SimpleTensor<half> roi_align_layer(const SimpleTensor<half> &src, const SimpleTensor<half> &rois, const ROIPoolingLayerInfo &pool_info);
 } // namespace reference
 } // namespace validation
 } // namespace test
diff --git a/tests/validation/reference/ROIAlignLayer.h b/tests/validation/reference/ROIAlignLayer.h
index 818f9b1..b67ff42 100644
--- a/tests/validation/reference/ROIAlignLayer.h
+++ b/tests/validation/reference/ROIAlignLayer.h
@@ -37,7 +37,7 @@
 namespace reference
 {
 template <typename T>
-SimpleTensor<T> roi_align_layer(const SimpleTensor<T> &src, const std::vector<ROI> &rois, const ROIPoolingLayerInfo &pool_info);
+SimpleTensor<T> roi_align_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &rois, const ROIPoolingLayerInfo &pool_info);
 } // namespace reference
 } // namespace validation
 } // namespace test