Compute Library
 21.02
GCNodeValidator.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2020 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
25 
28 
30 #include "support/Cast.h"
31 
32 using namespace arm_compute::utils::cast;
33 
34 namespace arm_compute
35 {
36 namespace graph
37 {
38 namespace backends
39 {
40 namespace
41 {
42 /** Validates a Depthwise Convolution layer node
43  *
44  * @param[in] node Node to validate
45  *
46  * @return Status
47  */
48 Status validate_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node)
49 {
50  ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating GCDepthwiseConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl);
51  ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 3);
52  ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1);
53 
54  // Extract IO and info
56  ARM_COMPUTE_ERROR_ON(weights == nullptr);
57 
58  // TODO (geopin01) : Switch when validation is implemented
59  // Validate function
60  ARM_COMPUTE_RETURN_ERROR_ON_MSG(weights->tensor_shape().x() != 3 && weights->tensor_shape().y() != 3, "Unsupported depthwise convolution");
61 
62  return Status{};
63 }
64 /** Validates a Convolution layer node
65  *
66  * @param[in] node Node to validate
67  *
68  * @return Status
69  */
70 Status validate_convolution_layer(ConvolutionLayerNode &node)
71 {
72  ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating ConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl);
73  ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 3);
74  ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1);
75 
76  // Extract IO and info
78  const PadStrideInfo conv_info = node.convolution_info();
79  const ConvolutionMethod conv_algorithm = node.convolution_method();
80 
81  // Validate function
82  ARM_COMPUTE_RETURN_ERROR_ON_MSG(node.num_groups() != 1, "Grouping is not supported by ConvolutionLayer!");
83  if(conv_algorithm == ConvolutionMethod::Direct)
84  {
85  bool is_square = weights->tensor_shape().x() == weights->tensor_shape().y();
86  bool is_direct = (weights->tensor_shape().x() == 1) || (weights->tensor_shape().x() == 3) || (weights->tensor_shape().x() == 5);
87  bool is_correct_stride = (conv_info.stride().first) <= 2 && (conv_info.stride().second <= 2);
88  ARM_COMPUTE_RETURN_ERROR_ON_MSG(!(is_square && is_direct && is_correct_stride), "Direct convolution is not supported for given configuration");
89  }
90 
91  return Status{};
92 }
93 } // namespace
94 
96 {
97  if(node == nullptr)
98  {
99  return Status{};
100  }
101 
102  NodeType type = node->type();
103  switch(type)
104  {
105  case NodeType::BoundingBoxTransformLayer:
106  return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : BoundingBoxTransformLayer");
107  case NodeType::ChannelShuffleLayer:
108  return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : ChannelShuffleLayer");
109  case NodeType::ConvolutionLayer:
110  return validate_convolution_layer(*polymorphic_downcast<ConvolutionLayerNode *>(node));
111  case NodeType::DepthwiseConvolutionLayer:
112  return validate_depthwise_convolution_layer(*polymorphic_downcast<DepthwiseConvolutionLayerNode *>(node));
113  case NodeType::DequantizationLayer:
114  return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : DequantizationLayer");
115  case NodeType::DetectionOutputLayer:
116  return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : DetectionOutputLayer");
117  case NodeType::DetectionPostProcessLayer:
118  return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : DetectionPostProcessLayer");
119  case NodeType::FlattenLayer:
120  return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : FlattenLayer");
121  case NodeType::GenerateProposalsLayer:
122  return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : GenerateProposalsLayer");
123  case NodeType::NormalizePlanarYUVLayer:
124  return detail::validate_normalize_planar_yuv_layer<GCNormalizePlanarYUVLayer>(*polymorphic_downcast<NormalizePlanarYUVLayerNode *>(node));
125  case NodeType::PadLayer:
126  return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : PadLayer");
127  case NodeType::PermuteLayer:
128  return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : PermuteLayer");
129  case NodeType::PriorBoxLayer:
130  return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : PriorBoxLayer");
131  case NodeType::QuantizationLayer:
132  return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : QuantizationLayer");
133  case NodeType::ReorgLayer:
134  return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : ReorgLayer");
135  case NodeType::ReshapeLayer:
136  return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : ReshapeLayer");
137  case NodeType::ROIAlignLayer:
138  return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : ROIAlignLayer");
139  case NodeType::SliceLayer:
140  return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : SliceLayer");
141  default:
142  return Status{};
143  }
144 }
145 } // namespace backends
146 } // namespace graph
147 } // namespace arm_compute
arm_compute::ITensorInfo * get_backing_tensor_info(arm_compute::graph::Tensor *tensor)
Returns backing tensor info of a given tensor.
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:466
Store the tensor&#39;s metadata.
Definition: ITensorInfo.h:40
Status class.
Definition: Error.h:52
ConvolutionMethod
Available ConvolutionMethod.
Definition: Types.h:138
#define ARM_COMPUTE_RETURN_ERROR_ON(cond)
If the condition is true, an error is returned.
Definition: Error.h:296
decltype(strategy::transforms) typedef type
Copyright (c) 2017-2021 Arm Limited.
Node interface.
Definition: INode.h:45
NodeType
Supported nodes.
Definition: Types.h:142
Includes all the OpenGLES functions at once.
#define ARM_COMPUTE_CREATE_ERROR(error_code, msg)
Creates an error with a given message.
Definition: Error.h:159
#define ARM_COMPUTE_LOG_GRAPH_VERBOSE(x)
Definition: Logger.h:50
#define ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, msg)
If the condition is true, an error is returned.
Definition: Error.h:244
Status validate_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node)
Validates a Depthwise Convolution layer node.
Status validate_convolution_layer(ConvolutionLayerNode &node)
Validates a Convolution layer node.
virtual NodeType type() const =0
Returns node&#39;s type.
Status validate(const ITensorInfo *scores_in, const ITensorInfo *boxes_in, const ITensorInfo *batch_splits_in, const ITensorInfo *scores_out, const ITensorInfo *boxes_out, const ITensorInfo *classes, const ITensorInfo *batch_splits_out, const ITensorInfo *keeps, const ITensorInfo *keeps_size, const BoxNMSLimitInfo info)