diff options
author | Abe Mbise <abe.mbise@arm.com> | 2018-05-31 16:48:41 +0100 |
---|---|---|
committer | Anthony Barbier <anthony.barbier@arm.com> | 2018-11-02 16:54:54 +0000 |
commit | 7784c837afd5844fb6dc4d166ff253d983abfd2d (patch) | |
tree | 3bc770240de148d565aa828e8f3471c354ac3837 /src/runtime | |
parent | b03f7c5c780fe2df23eb8c5c1b4b1d65bd7f0339 (diff) | |
download | ComputeLibrary-7784c837afd5844fb6dc4d166ff253d983abfd2d.tar.gz |
COMPMID-1167: Validation for NEDepthwiseConvolutionLayer
Change-Id: I9689e1a0627dc015dd2ce98417e4c97bb55581bb
Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/131327
Reviewed-by: Anthony Barbier <anthony.barbier@arm.com>
Tested-by: Jenkins <bsgcomp@arm.com>
Diffstat (limited to 'src/runtime')
-rw-r--r-- | src/runtime/NEON/functions/NEDepthwiseConvolutionLayer.cpp | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/runtime/NEON/functions/NEDepthwiseConvolutionLayer.cpp b/src/runtime/NEON/functions/NEDepthwiseConvolutionLayer.cpp index 1d65dde2a6..3b54ed62c7 100644 --- a/src/runtime/NEON/functions/NEDepthwiseConvolutionLayer.cpp +++ b/src/runtime/NEON/functions/NEDepthwiseConvolutionLayer.cpp @@ -123,6 +123,16 @@ void NEDepthwiseConvolutionLayer3x3::configure(ITensor *input, const ITensor *we } } +Status NEDepthwiseConvolutionLayer3x3::validate(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *output, const PadStrideInfo &conv_info, + unsigned int depth_multiplier) +{ + ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, weights, output); + ARM_COMPUTE_UNUSED(biases); + ARM_COMPUTE_RETURN_ERROR_ON(input->data_layout() != DataLayout::NCHW && input->data_layout() != DataLayout::NHWC); + + return NEDepthwiseConvolutionLayer3x3Kernel::validate(input, weights, output, conv_info, depth_multiplier); +} + void NEDepthwiseConvolutionLayer3x3::run() { if(_is_first_run && _is_optimized) @@ -263,6 +273,58 @@ void NEDepthwiseConvolutionLayer::configure(ITensor *input, const ITensor *weigh _v2mm_output.allocator()->allocate(); } +Status NEDepthwiseConvolutionLayer::validate(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *output, const PadStrideInfo &conv_info, + unsigned int depth_multiplier) +{ + ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, weights, output); + ARM_COMPUTE_RETURN_ERROR_ON(input->data_layout() != DataLayout::NCHW && input->data_layout() != DataLayout::NHWC); + + const bool is_quantized = is_data_type_quantized_asymmetric(input->data_type()); + const bool append_bias = (biases != nullptr) && !is_quantized; + const TensorShape output_shape = shape_calculator::compute_depthwise_convolution_shape(*input, *weights, conv_info, depth_multiplier); + const size_t weights_w = weights->dimension(0); + const size_t weights_h = weights->dimension(1); + const size_t weights_z = weights->dimension(2); + const unsigned int conv_w = output_shape.x(); + const unsigned int conv_h = output_shape.y(); + const size_t patch_size = weights_w * weights_h + (append_bias ? 1 : 0); + const size_t conv_size = conv_w * conv_h; + + ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(output->tensor_shape(), output_shape); + + // Im2Col configuration + TensorShape shape_im2col = input->tensor_shape(); + shape_im2col.set(0, patch_size); + shape_im2col.set(1, conv_size); + shape_im2col.set(2, weights_z); + TensorInfo input_reshaped(input->clone()->set_is_resizable(true).reset_padding().set_tensor_shape(shape_im2col)); + ARM_COMPUTE_RETURN_ON_ERROR(NEDepthwiseIm2ColKernel::validate(input, &input_reshaped, Size2D(weights_w, weights_h), conv_info, append_bias, depth_multiplier)); + + // Weights reshape configuration + const TensorShape shape_weights_reshape(patch_size, weights_z); + TensorInfo weights_reshaped(weights->clone()->set_is_resizable(true).reset_padding().set_tensor_shape(shape_weights_reshape)); + ARM_COMPUTE_RETURN_ON_ERROR(NEDepthwiseWeightsReshapeKernel::validate(weights, &weights_reshaped, append_bias ? biases : nullptr)); + + // GEMV configuration + DataType v2mm_dt = (input->data_type() == DataType::QASYMM8) ? DataType::S32 : input->data_type(); + TensorShape shape_v2mm_out = input->tensor_shape(); + shape_v2mm_out.set(0, conv_size * weights_z); + shape_v2mm_out.set(1, 1); + shape_v2mm_out.set(2, 1); + TensorInfo v2mm_output(input->clone()->set_is_resizable(true).reset_padding().set_data_type(v2mm_dt).set_tensor_shape(shape_v2mm_out)); + ARM_COMPUTE_RETURN_ON_ERROR(NEGEMMMatrixVectorMultiplyKernel::validate(&input_reshaped, &weights_reshaped, &v2mm_output)); + + TensorInfo output_reshaped(v2mm_output.clone()->set_is_resizable(true).reset_padding().set_tensor_shape(output_shape)); + ARM_COMPUTE_RETURN_ON_ERROR(NEDepthwiseVectorToTensorKernel::validate(&v2mm_output, (is_quantized) ? &output_reshaped : output, conv_w, conv_h)); + + if(is_quantized) + { + ARM_COMPUTE_RETURN_ON_ERROR(NEDirectConvolutionLayerOutputStageKernel::validate(&output_reshaped, biases, output)); + } + + return Status{}; +} + void NEDepthwiseConvolutionLayer::run() { prepare(); |