Compute Library
 19.11
CLGenerateProposalsLayer Class Reference

Basic function to generate proposals for a RPN (Region Proposal Network) More...

#include <CLGenerateProposalsLayer.h>

Collaboration diagram for CLGenerateProposalsLayer:
[legend]

Public Member Functions

 CLGenerateProposalsLayer (std::shared_ptr< IMemoryManager > memory_manager=nullptr)
 Default constructor. More...
 
 CLGenerateProposalsLayer (const CLGenerateProposalsLayer &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
 CLGenerateProposalsLayer (CLGenerateProposalsLayer &&)=default
 Default move constructor. More...
 
CLGenerateProposalsLayeroperator= (const CLGenerateProposalsLayer &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
CLGenerateProposalsLayeroperator= (CLGenerateProposalsLayer &&)=default
 Default move assignment operator. More...
 
void configure (const ICLTensor *scores, const ICLTensor *deltas, const ICLTensor *anchors, ICLTensor *proposals, ICLTensor *scores_out, ICLTensor *num_valid_proposals, const GenerateProposalsInfo &info)
 Set the input and output tensors. More...
 
void run () override
 Run the kernels contained in the function. More...
 
- Public Member Functions inherited from IFunction
virtual ~IFunction ()=default
 Destructor. More...
 
virtual void prepare ()
 Prepare the function for executing. More...
 

Static Public Member Functions

static Status validate (const ITensorInfo *scores, const ITensorInfo *deltas, const ITensorInfo *anchors, const ITensorInfo *proposals, const ITensorInfo *scores_out, const ITensorInfo *num_valid_proposals, const GenerateProposalsInfo &info)
 Static function to check if given info will lead to a valid configuration of CLGenerateProposalsLayer. More...
 

Detailed Description

Basic function to generate proposals for a RPN (Region Proposal Network)

This function calls the following OpenCL kernels:

  1. CLComputeAllAnchors
  2. CLPermute x 2
  3. CLReshapeLayer x 2
  4. CLBoundingBoxTransform
  5. CLPadLayerKernel
  6. CLDequantizationLayerKernel x 2
  7. CLQuantizationLayerKernel And the following CPP functions:
  8. CPPBoxWithNonMaximaSuppressionLimit

Definition at line 58 of file CLGenerateProposalsLayer.h.

Constructor & Destructor Documentation

◆ CLGenerateProposalsLayer() [1/3]

CLGenerateProposalsLayer ( std::shared_ptr< IMemoryManager memory_manager = nullptr)

Default constructor.

Parameters
[in]memory_manager(Optional) Memory manager.

Definition at line 32 of file CLGenerateProposalsLayer.cpp.

33  : _memory_group(memory_manager),
34  _permute_deltas_kernel(),
35  _flatten_deltas_kernel(),
36  _permute_scores_kernel(),
37  _flatten_scores_kernel(),
38  _compute_anchors_kernel(),
39  _bounding_box_kernel(),
40  _pad_kernel(),
41  _dequantize_anchors(),
42  _dequantize_deltas(),
43  _quantize_all_proposals(),
44  _cpp_nms(memory_manager),
45  _is_nhwc(false),
46  _is_qasymm8(false),
47  _deltas_permuted(),
48  _deltas_flattened(),
49  _deltas_flattened_f32(),
50  _scores_permuted(),
51  _scores_flattened(),
52  _all_anchors(),
53  _all_anchors_f32(),
54  _all_proposals(),
55  _all_proposals_quantized(),
56  _keeps_nms_unused(),
57  _classes_nms_unused(),
58  _proposals_4_roi_values(),
59  _all_proposals_to_use(nullptr),
60  _num_valid_proposals(nullptr),
61  _scores_out(nullptr)
62 {
63 }

◆ CLGenerateProposalsLayer() [2/3]

Prevent instances of this class from being copied (As this class contains pointers)

◆ CLGenerateProposalsLayer() [3/3]

Default move constructor.

Member Function Documentation

◆ configure()

void configure ( const ICLTensor scores,
const ICLTensor deltas,
const ICLTensor anchors,
ICLTensor proposals,
ICLTensor scores_out,
ICLTensor num_valid_proposals,
const GenerateProposalsInfo info 
)

Set the input and output tensors.

Parameters
[in]scoresScores from convolution layer of size (W, H, A), where H and W are the height and width of the feature map, and A is the number of anchors. Data types supported: QASYMM8/F16/F32
[in]deltasBounding box deltas from convolution layer of size (W, H, 4*A). Data types supported: Same as scores
[in]anchorsAnchors tensor of size (4, A). Data types supported: QSYMM16 with scale of 0.125 if scores is QASYMM8, otherwise same as scores
[out]proposalsBox proposals output tensor of size (5, W*H*A). Data types supported: QASYMM16 with scale of 0.125 and 0 offset if scores is QASYMM8, otherwise same as scores
[out]scores_outBox scores output tensor of size (W*H*A). Data types supported: Same as scores
[out]num_valid_proposalsScalar output tensor which says which of the first proposals are valid. Data types supported: U32
[in]infoContains GenerateProposals operation information described in GenerateProposalsInfo
Note
Only single image prediction is supported. Height and Width (and scale) of the image will be contained in the GenerateProposalsInfo struct.
Proposals contains all the proposals. Of those, only the first num_valid_proposals are valid.

Definition at line 65 of file CLGenerateProposalsLayer.cpp.

67 {
68  ARM_COMPUTE_ERROR_ON_NULLPTR(scores, deltas, anchors, proposals, scores_out, num_valid_proposals);
69  ARM_COMPUTE_ERROR_THROW_ON(CLGenerateProposalsLayer::validate(scores->info(), deltas->info(), anchors->info(), proposals->info(), scores_out->info(), num_valid_proposals->info(), info));
70 
71  _is_nhwc = scores->info()->data_layout() == DataLayout::NHWC;
72  const DataType scores_data_type = scores->info()->data_type();
73  _is_qasymm8 = scores_data_type == DataType::QASYMM8;
74  const int num_anchors = scores->info()->dimension(get_data_layout_dimension_index(scores->info()->data_layout(), DataLayoutDimension::CHANNEL));
75  const int feat_width = scores->info()->dimension(get_data_layout_dimension_index(scores->info()->data_layout(), DataLayoutDimension::WIDTH));
76  const int feat_height = scores->info()->dimension(get_data_layout_dimension_index(scores->info()->data_layout(), DataLayoutDimension::HEIGHT));
77  const int total_num_anchors = num_anchors * feat_width * feat_height;
78  const int pre_nms_topN = info.pre_nms_topN();
79  const int post_nms_topN = info.post_nms_topN();
80  const size_t values_per_roi = info.values_per_roi();
81 
82  const QuantizationInfo scores_qinfo = scores->info()->quantization_info();
83  const DataType rois_data_type = (_is_qasymm8) ? DataType::QASYMM16 : scores_data_type;
84  const QuantizationInfo rois_qinfo = (_is_qasymm8) ? QuantizationInfo(0.125f, 0) : scores->info()->quantization_info();
85 
86  // Compute all the anchors
87  _memory_group.manage(&_all_anchors);
88  _compute_anchors_kernel.configure(anchors, &_all_anchors, ComputeAnchorsInfo(feat_width, feat_height, info.spatial_scale()));
89 
90  const TensorShape flatten_shape_deltas(values_per_roi, total_num_anchors);
91  _deltas_flattened.allocator()->init(TensorInfo(flatten_shape_deltas, 1, scores_data_type, deltas->info()->quantization_info()));
92 
93  // Permute and reshape deltas
94  _memory_group.manage(&_deltas_flattened);
95  if(!_is_nhwc)
96  {
97  _memory_group.manage(&_deltas_permuted);
98  _permute_deltas_kernel.configure(deltas, &_deltas_permuted, PermutationVector{ 2, 0, 1 });
99  _flatten_deltas_kernel.configure(&_deltas_permuted, &_deltas_flattened);
100  _deltas_permuted.allocator()->allocate();
101  }
102  else
103  {
104  _flatten_deltas_kernel.configure(deltas, &_deltas_flattened);
105  }
106 
107  const TensorShape flatten_shape_scores(1, total_num_anchors);
108  _scores_flattened.allocator()->init(TensorInfo(flatten_shape_scores, 1, scores_data_type, scores_qinfo));
109 
110  // Permute and reshape scores
111  _memory_group.manage(&_scores_flattened);
112  if(!_is_nhwc)
113  {
114  _memory_group.manage(&_scores_permuted);
115  _permute_scores_kernel.configure(scores, &_scores_permuted, PermutationVector{ 2, 0, 1 });
116  _flatten_scores_kernel.configure(&_scores_permuted, &_scores_flattened);
117  _scores_permuted.allocator()->allocate();
118  }
119  else
120  {
121  _flatten_scores_kernel.configure(scores, &_scores_flattened);
122  }
123 
124  CLTensor *anchors_to_use = &_all_anchors;
125  CLTensor *deltas_to_use = &_deltas_flattened;
126  if(_is_qasymm8)
127  {
128  _all_anchors_f32.allocator()->init(TensorInfo(_all_anchors.info()->tensor_shape(), 1, DataType::F32));
129  _deltas_flattened_f32.allocator()->init(TensorInfo(_deltas_flattened.info()->tensor_shape(), 1, DataType::F32));
130  _memory_group.manage(&_all_anchors_f32);
131  _memory_group.manage(&_deltas_flattened_f32);
132  // Dequantize anchors to float
133  _dequantize_anchors.configure(&_all_anchors, &_all_anchors_f32);
134  _all_anchors.allocator()->allocate();
135  anchors_to_use = &_all_anchors_f32;
136  // Dequantize deltas to float
137  _dequantize_deltas.configure(&_deltas_flattened, &_deltas_flattened_f32);
138  _deltas_flattened.allocator()->allocate();
139  deltas_to_use = &_deltas_flattened_f32;
140  }
141  // Bounding box transform
142  _memory_group.manage(&_all_proposals);
143  BoundingBoxTransformInfo bbox_info(info.im_width(), info.im_height(), 1.f);
144  _bounding_box_kernel.configure(anchors_to_use, &_all_proposals, deltas_to_use, bbox_info);
145  deltas_to_use->allocator()->allocate();
146  anchors_to_use->allocator()->allocate();
147 
148  _all_proposals_to_use = &_all_proposals;
149  if(_is_qasymm8)
150  {
151  _memory_group.manage(&_all_proposals_quantized);
152  // Requantize all_proposals to QASYMM16 with 0.125 scale and 0 offset
153  _all_proposals_quantized.allocator()->init(TensorInfo(_all_proposals.info()->tensor_shape(), 1, DataType::QASYMM16, QuantizationInfo(0.125f, 0)));
154  _quantize_all_proposals.configure(&_all_proposals, &_all_proposals_quantized);
155  _all_proposals.allocator()->allocate();
156  _all_proposals_to_use = &_all_proposals_quantized;
157  }
158  // The original layer implementation first selects the best pre_nms_topN anchors (thus having a lightweight sort)
159  // that are then transformed by bbox_transform. The boxes generated are then fed into a non-sorting NMS operation.
160  // Since we are reusing the NMS layer and we don't implement any CL/sort, we let NMS do the sorting (of all the input)
161  // and the filtering
162  const int scores_nms_size = std::min<int>(std::min<int>(post_nms_topN, pre_nms_topN), total_num_anchors);
163  const float min_size_scaled = info.min_size() * info.im_scale();
164  _memory_group.manage(&_classes_nms_unused);
165  _memory_group.manage(&_keeps_nms_unused);
166 
167  // Note that NMS needs outputs preinitialized.
168  auto_init_if_empty(*scores_out->info(), TensorShape(scores_nms_size), 1, scores_data_type, scores_qinfo);
169  auto_init_if_empty(*_proposals_4_roi_values.info(), TensorShape(values_per_roi, scores_nms_size), 1, rois_data_type, rois_qinfo);
170  auto_init_if_empty(*num_valid_proposals->info(), TensorShape(1), 1, DataType::U32);
171 
172  // Initialize temporaries (unused) outputs
173  _classes_nms_unused.allocator()->init(TensorInfo(TensorShape(scores_nms_size), 1, scores_data_type, scores_qinfo));
174  _keeps_nms_unused.allocator()->init(*scores_out->info());
175 
176  // Save the output (to map and unmap them at run)
177  _scores_out = scores_out;
178  _num_valid_proposals = num_valid_proposals;
179 
180  _memory_group.manage(&_proposals_4_roi_values);
181  _cpp_nms.configure(&_scores_flattened, _all_proposals_to_use, nullptr, scores_out, &_proposals_4_roi_values, &_classes_nms_unused, nullptr, &_keeps_nms_unused, num_valid_proposals,
182  BoxNMSLimitInfo(0.0f, info.nms_thres(), scores_nms_size, false, NMSType::LINEAR, 0.5f, 0.001f, true, min_size_scaled, info.im_width(), info.im_height()));
183  _keeps_nms_unused.allocator()->allocate();
184  _classes_nms_unused.allocator()->allocate();
185  _all_proposals_to_use->allocator()->allocate();
186  _scores_flattened.allocator()->allocate();
187 
188  // Add the first column that represents the batch id. This will be all zeros, as we don't support multiple images
189  _pad_kernel.configure(&_proposals_4_roi_values, proposals, PaddingList{ { 1, 0 } });
190  _proposals_4_roi_values.allocator()->allocate();
191 }
void configure(const ICLTensor *anchors, ICLTensor *all_anchors, const ComputeAnchorsInfo &info)
Set the input and output tensors.
TensorInfo * info() const override
Interface to be implemented by the child class to return the tensor's metadata.
Definition: CLTensor.cpp:41
std::vector< PaddingInfo > PaddingList
List of padding information.
Definition: Types.h:454
1 channel, 1 F32 per channel
Strides PermutationVector
Permutation vector.
Definition: Types.h:47
CLTensorAllocator * allocator()
Return a pointer to the tensor's allocator.
Definition: CLTensor.cpp:61
#define ARM_COMPUTE_ERROR_THROW_ON(status)
Definition: Error.h:455
quantized, asymmetric fixed-point 16-bit number
void init(const TensorInfo &input, size_t alignment=0)
Initialize a tensor based on the passed TensorInfo.
bool auto_init_if_empty(ITensorInfo &info, const TensorShape &shape, int num_channels, DataType data_type, QuantizationInfo quantization_info=QuantizationInfo())
Auto initialize the tensor info (shape, number of channels and data type) if the current assignment i...
Definition: Helpers.inl:202
void configure(const ICLTensor *input, ICLTensor *output)
Set the input, output.
void manage(IMemoryManageable *obj) override
Sets a object to be managed by the given memory group.
Definition: MemoryGroup.h:79
void configure(const ICLTensor *boxes, ICLTensor *pred_boxes, const ICLTensor *deltas, const BoundingBoxTransformInfo &info)
Set the input and output tensors.
1 channel, 1 U32 per channel
quantized, asymmetric fixed-point 8-bit number unsigned
void configure(const ICLTensor *input, ICLTensor *output, const PaddingList &padding, PixelValue constant_value=PixelValue(), PaddingMode mode=PaddingMode::CONSTANT)
Set the input and output tensor.
void configure(const ICLTensor *input, ICLTensor *output)
Set the input and output of the kernel.
static Status validate(const ITensorInfo *scores, const ITensorInfo *deltas, const ITensorInfo *anchors, const ITensorInfo *proposals, const ITensorInfo *scores_out, const ITensorInfo *num_valid_proposals, const GenerateProposalsInfo &info)
Static function to check if given info will lead to a valid configuration of CLGenerateProposalsLayer...
void allocate() override
Allocate size specified by TensorInfo of OpenCL memory.
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
Definition: Validate.h:161
void configure(const ICLTensor *input, ICLTensor *output)
Set the input, output, min and max.
Num samples, height, width, channels.
void configure(const ICLTensor *input, ICLTensor *output, const PermutationVector &perm)
Set the input and output of the kernel.
size_t get_data_layout_dimension_index(const DataLayout data_layout, const DataLayoutDimension data_layout_dimension)
Get the index of the given dimension.
Definition: Helpers.inl:327
const TensorShape & tensor_shape() const override
Size for each dimension of the tensor.
Definition: TensorInfo.h:261
DataType
Available data types.
Definition: Types.h:74
void configure(const ITensor *scores_in, const ITensor *boxes_in, const ITensor *batch_splits_in, ITensor *scores_out, ITensor *boxes_out, ITensor *classes, ITensor *batch_splits_out=nullptr, ITensor *keeps=nullptr, ITensor *keeps_size=nullptr, const BoxNMSLimitInfo info=BoxNMSLimitInfo())
Configure the BoxWithNonMaximaSuppressionLimit CPP kernel.

References CLTensorAllocator::allocate(), CLTensor::allocator(), ARM_COMPUTE_ERROR_ON_NULLPTR, ARM_COMPUTE_ERROR_THROW_ON, arm_compute::auto_init_if_empty(), arm_compute::CHANNEL, CLDequantizationLayerKernel::configure(), CLReshapeLayerKernel::configure(), CLComputeAllAnchorsKernel::configure(), CLPermuteKernel::configure(), CLQuantizationLayerKernel::configure(), CLPadLayerKernel::configure(), CLBoundingBoxTransformKernel::configure(), CPPBoxWithNonMaximaSuppressionLimit::configure(), ITensorInfo::data_layout(), ITensorInfo::data_type(), ITensorInfo::dimension(), arm_compute::F32, arm_compute::get_data_layout_dimension_index(), arm_compute::HEIGHT, ITensor::info(), CLTensor::info(), arm_compute::test::validation::info, ITensorAllocator::init(), arm_compute::LINEAR, MemoryGroup::manage(), arm_compute::NHWC, arm_compute::QASYMM16, arm_compute::QASYMM8, ITensorInfo::quantization_info(), TensorInfo::tensor_shape(), arm_compute::U32, CLGenerateProposalsLayer::validate(), and arm_compute::WIDTH.

◆ operator=() [1/2]

CLGenerateProposalsLayer& operator= ( const CLGenerateProposalsLayer )
delete

Prevent instances of this class from being copied (As this class contains pointers)

◆ operator=() [2/2]

Default move assignment operator.

◆ run()

void run ( )
overridevirtual

Run the kernels contained in the function.

For NEON kernels:

  • Multi-threading is used for the kernels which are parallelisable.
  • By default std::thread::hardware_concurrency() threads are used.
Note
CPPScheduler::set_num_threads() can be used to manually set the number of threads

For OpenCL kernels:

  • All the kernels are enqueued on the queue associated with CLScheduler.
  • The queue is then flushed.
Note
The function will not block until the kernels are executed. It is the user's responsibility to wait.
Will call prepare() on first run if hasn't been done

Implements IFunction.

Definition at line 333 of file CLGenerateProposalsLayer.cpp.

334 {
335  // Acquire all the temporaries
336  MemoryGroupResourceScope scope_mg(_memory_group);
337 
338  // Compute all the anchors
339  CLScheduler::get().enqueue(_compute_anchors_kernel, false);
340 
341  // Transpose and reshape the inputs
342  if(!_is_nhwc)
343  {
344  CLScheduler::get().enqueue(_permute_deltas_kernel, false);
345  CLScheduler::get().enqueue(_permute_scores_kernel, false);
346  }
347  CLScheduler::get().enqueue(_flatten_deltas_kernel, false);
348  CLScheduler::get().enqueue(_flatten_scores_kernel, false);
349 
350  if(_is_qasymm8)
351  {
352  CLScheduler::get().enqueue(_dequantize_anchors, false);
353  CLScheduler::get().enqueue(_dequantize_deltas, false);
354  }
355 
356  // Build the boxes
357  CLScheduler::get().enqueue(_bounding_box_kernel, false);
358 
359  if(_is_qasymm8)
360  {
361  CLScheduler::get().enqueue(_quantize_all_proposals, false);
362  }
363 
364  // Non maxima suppression
365  run_cpp_nms_kernel();
366  // Add dummy batch indexes
367  CLScheduler::get().enqueue(_pad_kernel, true);
368 }
static CLScheduler & get()
Access the scheduler singleton.
Definition: CLScheduler.cpp:99
void enqueue(ICLKernel &kernel, bool flush=true)
Schedule the execution of the passed kernel if possible.

References CLScheduler::enqueue(), and CLScheduler::get().

◆ validate()

Status validate ( const ITensorInfo scores,
const ITensorInfo deltas,
const ITensorInfo anchors,
const ITensorInfo proposals,
const ITensorInfo scores_out,
const ITensorInfo num_valid_proposals,
const GenerateProposalsInfo info 
)
static

Static function to check if given info will lead to a valid configuration of CLGenerateProposalsLayer.

Parameters
[in]scoresScores info from convolution layer of size (W, H, A), where H and W are the height and width of the feature map, and A is the number of anchors. Data types supported: QASYMM8/F16/F32
[in]deltasBounding box deltas info from convolution layer of size (W, H, 4*A). Data types supported: Same as scores
[in]anchorsAnchors tensor of size (4, A). Data types supported: QSYMM16 with scale of 0.125 if scores is QASYMM8, otherwise same as scores
[in]proposalsBox proposals info output tensor of size (5, W*H*A). Data types supported: QASYMM16 with scale of 0.125 and 0 offset if scores is QASYMM8, otherwise same as scores
[in]scores_outBox scores output tensor info of size (W*H*A). Data types supported: Same as scores
[in]num_valid_proposalsScalar output tensor info which says which of the first proposals are valid. Data types supported: U32
[in]infoContains GenerateProposals operation information described in GenerateProposalsInfo
Returns
a Status

Definition at line 193 of file CLGenerateProposalsLayer.cpp.

195 {
196  ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(scores, deltas, anchors, proposals, scores_out, num_valid_proposals);
201 
202  const int num_anchors = scores->dimension(get_data_layout_dimension_index(scores->data_layout(), DataLayoutDimension::CHANNEL));
203  const int feat_width = scores->dimension(get_data_layout_dimension_index(scores->data_layout(), DataLayoutDimension::WIDTH));
204  const int feat_height = scores->dimension(get_data_layout_dimension_index(scores->data_layout(), DataLayoutDimension::HEIGHT));
205  const int num_images = scores->dimension(3);
206  const int total_num_anchors = num_anchors * feat_width * feat_height;
207  const int values_per_roi = info.values_per_roi();
208 
209  const bool is_qasymm8 = scores->data_type() == DataType::QASYMM8;
210 
211  ARM_COMPUTE_RETURN_ERROR_ON(num_images > 1);
212 
213  if(is_qasymm8)
214  {
216  const UniformQuantizationInfo anchors_qinfo = anchors->quantization_info().uniform();
217  ARM_COMPUTE_RETURN_ERROR_ON(anchors_qinfo.scale != 0.125f);
218  }
219 
220  TensorInfo all_anchors_info(anchors->clone()->set_tensor_shape(TensorShape(values_per_roi, total_num_anchors)).set_is_resizable(true));
221  ARM_COMPUTE_RETURN_ON_ERROR(CLComputeAllAnchorsKernel::validate(anchors, &all_anchors_info, ComputeAnchorsInfo(feat_width, feat_height, info.spatial_scale())));
222 
223  TensorInfo deltas_permuted_info = deltas->clone()->set_tensor_shape(TensorShape(values_per_roi * num_anchors, feat_width, feat_height)).set_is_resizable(true);
224  TensorInfo scores_permuted_info = scores->clone()->set_tensor_shape(TensorShape(num_anchors, feat_width, feat_height)).set_is_resizable(true);
225  if(scores->data_layout() == DataLayout::NHWC)
226  {
227  ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(deltas, &deltas_permuted_info);
228  ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(scores, &scores_permuted_info);
229  }
230  else
231  {
232  ARM_COMPUTE_RETURN_ON_ERROR(CLPermuteKernel::validate(deltas, &deltas_permuted_info, PermutationVector{ 2, 0, 1 }));
233  ARM_COMPUTE_RETURN_ON_ERROR(CLPermuteKernel::validate(scores, &scores_permuted_info, PermutationVector{ 2, 0, 1 }));
234  }
235 
236  TensorInfo deltas_flattened_info(deltas->clone()->set_tensor_shape(TensorShape(values_per_roi, total_num_anchors)).set_is_resizable(true));
237  ARM_COMPUTE_RETURN_ON_ERROR(CLReshapeLayerKernel::validate(&deltas_permuted_info, &deltas_flattened_info));
238 
239  TensorInfo scores_flattened_info(scores->clone()->set_tensor_shape(TensorShape(1, total_num_anchors)).set_is_resizable(true));
240  TensorInfo proposals_4_roi_values(deltas->clone()->set_tensor_shape(TensorShape(values_per_roi, total_num_anchors)).set_is_resizable(true));
241 
242  ARM_COMPUTE_RETURN_ON_ERROR(CLReshapeLayerKernel::validate(&scores_permuted_info, &scores_flattened_info));
243 
244  TensorInfo *proposals_4_roi_values_to_use = &proposals_4_roi_values;
245  TensorInfo proposals_4_roi_values_quantized(deltas->clone()->set_tensor_shape(TensorShape(values_per_roi, total_num_anchors)).set_is_resizable(true));
246  proposals_4_roi_values_quantized.set_data_type(DataType::QASYMM16).set_quantization_info(QuantizationInfo(0.125f, 0));
247  if(is_qasymm8)
248  {
249  TensorInfo all_anchors_f32_info(anchors->clone()->set_tensor_shape(TensorShape(values_per_roi, total_num_anchors)).set_is_resizable(true).set_data_type(DataType::F32));
250  ARM_COMPUTE_RETURN_ON_ERROR(CLDequantizationLayerKernel::validate(&all_anchors_info, &all_anchors_f32_info));
251 
252  TensorInfo deltas_flattened_f32_info(deltas->clone()->set_tensor_shape(TensorShape(values_per_roi, total_num_anchors)).set_is_resizable(true).set_data_type(DataType::F32));
253  ARM_COMPUTE_RETURN_ON_ERROR(CLDequantizationLayerKernel::validate(&deltas_flattened_info, &deltas_flattened_f32_info));
254 
255  TensorInfo proposals_4_roi_values_f32(deltas->clone()->set_tensor_shape(TensorShape(values_per_roi, total_num_anchors)).set_is_resizable(true).set_data_type(DataType::F32));
256  ARM_COMPUTE_RETURN_ON_ERROR(CLBoundingBoxTransformKernel::validate(&all_anchors_f32_info, &proposals_4_roi_values_f32, &deltas_flattened_f32_info,
257  BoundingBoxTransformInfo(info.im_width(), info.im_height(), 1.f)));
258 
259  ARM_COMPUTE_RETURN_ON_ERROR(CLQuantizationLayerKernel::validate(&proposals_4_roi_values_f32, &proposals_4_roi_values_quantized));
260  proposals_4_roi_values_to_use = &proposals_4_roi_values_quantized;
261  }
262  else
263  {
264  ARM_COMPUTE_RETURN_ON_ERROR(CLBoundingBoxTransformKernel::validate(&all_anchors_info, &proposals_4_roi_values, &deltas_flattened_info,
265  BoundingBoxTransformInfo(info.im_width(), info.im_height(), 1.f)));
266  }
267 
268  ARM_COMPUTE_RETURN_ON_ERROR(CLPadLayerKernel::validate(proposals_4_roi_values_to_use, proposals, PaddingList{ { 1, 0 } }));
269 
270  if(num_valid_proposals->total_size() > 0)
271  {
272  ARM_COMPUTE_RETURN_ERROR_ON(num_valid_proposals->num_dimensions() > 1);
273  ARM_COMPUTE_RETURN_ERROR_ON(num_valid_proposals->dimension(0) > 1);
275  }
276 
277  if(proposals->total_size() > 0)
278  {
279  ARM_COMPUTE_RETURN_ERROR_ON(proposals->num_dimensions() > 2);
280  ARM_COMPUTE_RETURN_ERROR_ON(proposals->dimension(0) != size_t(values_per_roi) + 1);
281  ARM_COMPUTE_RETURN_ERROR_ON(proposals->dimension(1) != size_t(total_num_anchors));
282  if(is_qasymm8)
283  {
285  const UniformQuantizationInfo proposals_qinfo = proposals->quantization_info().uniform();
286  ARM_COMPUTE_RETURN_ERROR_ON(proposals_qinfo.scale != 0.125f);
287  ARM_COMPUTE_RETURN_ERROR_ON(proposals_qinfo.offset != 0);
288  }
289  else
290  {
292  }
293  }
294 
295  if(scores_out->total_size() > 0)
296  {
297  ARM_COMPUTE_RETURN_ERROR_ON(scores_out->num_dimensions() > 1);
298  ARM_COMPUTE_RETURN_ERROR_ON(scores_out->dimension(0) != size_t(total_num_anchors));
300  }
301 
302  return Status{};
303 }
static Status validate(const ITensorInfo *input, const ITensorInfo *output, const PaddingList &padding, PixelValue constant_value=PixelValue(), PaddingMode mode=PaddingMode::CONSTANT)
Static function to check if given info will lead to a valid configuration of CLPadLayerKernel.
quantized, symmetric fixed-point 16-bit number
std::vector< PaddingInfo > PaddingList
List of padding information.
Definition: Types.h:454
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(...)
Definition: Validate.h:494
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(...)
Definition: Validate.h:545
#define ARM_COMPUTE_RETURN_ON_ERROR(status)
Checks if a status contains an error and returns it.
Definition: Error.h:204
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c,...)
Definition: Validate.h:792
1 channel, 1 F32 per channel
Strides PermutationVector
Permutation vector.
Definition: Types.h:47
quantized, asymmetric fixed-point 16-bit number
#define ARM_COMPUTE_RETURN_ERROR_ON(cond)
If the condition is true, an error is returned.
Definition: Error.h:296
static Status validate(const ITensorInfo *input, const ITensorInfo *output)
Static function to check if given info will lead to a valid configuration of CLQuantizationLayerKerne...
1 channel, 1 F16 per channel
static Status validate(const ITensorInfo *input, const ITensorInfo *output)
Static function to check if given info will lead to a valid configuration of CLDequantizationLayerKer...
static Status validate(const ITensorInfo *anchors, const ITensorInfo *all_anchors, const ComputeAnchorsInfo &info)
Static function to check if given info will lead to a valid configuration of CLComputeAllAnchorsKerne...
1 channel, 1 U32 per channel
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(...)
Definition: Validate.h:443
quantized, asymmetric fixed-point 8-bit number unsigned
static Status validate(const ITensorInfo *input, const ITensorInfo *output)
Static function to check if given info will lead to a valid configuration of CLReshapeLayerKernel.
Num samples, channels, height, width.
static Status validate(const ITensorInfo *boxes, const ITensorInfo *pred_boxes, const ITensorInfo *deltas, const BoundingBoxTransformInfo &info)
Static function to check if given info will lead to a valid configuration of CLBoundingBoxTransform.
#define ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(...)
Definition: Validate.h:163
Num samples, height, width, channels.
size_t get_data_layout_dimension_index(const DataLayout data_layout, const DataLayoutDimension data_layout_dimension)
Get the index of the given dimension.
Definition: Helpers.inl:327
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_LAYOUT_NOT_IN(t,...)
Definition: Validate.h:746
static Status validate(const ITensorInfo *input, const ITensorInfo *output, const PermutationVector &perm)
Static function to check if given info will lead to a valid configuration of CLPermuteKernel.

References ARM_COMPUTE_RETURN_ERROR_ON, ARM_COMPUTE_RETURN_ERROR_ON_DATA_LAYOUT_NOT_IN, ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN, ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT, ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES, ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES, ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR, ARM_COMPUTE_RETURN_ON_ERROR, arm_compute::CHANNEL, ICloneable< T >::clone(), ITensorInfo::data_layout(), ITensorInfo::data_type(), ITensorInfo::dimension(), arm_compute::F16, arm_compute::F32, arm_compute::get_data_layout_dimension_index(), arm_compute::HEIGHT, arm_compute::test::validation::info, arm_compute::NCHW, arm_compute::NHWC, ITensorInfo::num_dimensions(), UniformQuantizationInfo::offset, arm_compute::QASYMM16, arm_compute::QASYMM8, arm_compute::QSYMM16, ITensorInfo::quantization_info(), UniformQuantizationInfo::scale, TensorInfo::set_data_type(), ITensorInfo::set_quantization_info(), ITensorInfo::total_size(), arm_compute::U32, QuantizationInfo::uniform(), CLDequantizationLayerKernel::validate(), CLReshapeLayerKernel::validate(), CLPermuteKernel::validate(), CLComputeAllAnchorsKernel::validate(), CLQuantizationLayerKernel::validate(), CLPadLayerKernel::validate(), CLBoundingBoxTransformKernel::validate(), and arm_compute::WIDTH.

Referenced by CLGenerateProposalsLayer::configure().


The documentation for this class was generated from the following files: