ArmNN
 25.11
Loading...
Searching...
No Matches
Convolution3dLayer.cpp
Go to the documentation of this file.
1//
2// Copyright © 2021-2024 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
7#include "LayerCloneBase.hpp"
8
10
12
13using namespace armnnUtils;
14
15namespace armnn
16{
17
19 : LayerWithParameters(param.GetNumInputs(), 1, LayerType::Convolution3d, param, name)
20{
21}
22
24{
25 const std::vector<TensorShape>& inputShapes =
26 {
29 };
30
31 // Conv3d Filter Layout: [D,H,W,I,O]
32 const TensorShape filterShape = inputShapes[1];
33 unsigned int filterDepth = filterShape[0];
34 unsigned int filterHeight = filterShape[1];
35 unsigned int filterWidth = filterShape[2];
36 unsigned int inChannels = filterShape[3];
37 unsigned int outChannels = filterShape[4];
38
39 fn("FilterDepth",std::to_string(filterDepth));
40 fn("FilterHeight",std::to_string(filterHeight));
41 fn("FilterWidth",std::to_string(filterWidth));
42 fn("InputChannels",std::to_string(inChannels));
43 fn("OutputChannels",std::to_string(outChannels));
44
46}
47
48std::unique_ptr<IWorkload> Convolution3dLayer::CreateWorkload(const IWorkloadFactory& factory) const
49{
51 SetAdditionalInfo(descriptor);
52
53 return factory.CreateWorkload(LayerType::Convolution3d, descriptor, PrepInfoAndDesc(descriptor));
54}
55
57{
58 auto layer = CloneBase<Convolution3dLayer>(graph, m_Param, GetName());
59 return std::move(layer);
60}
61
62std::vector<TensorShape> Convolution3dLayer::InferOutputShapes(const std::vector<TensorShape>& inputShapes) const
63{
64 if (inputShapes.size() != 2)
65 {
66 throw armnn::Exception("inputShapes' size is \"" + std::to_string(inputShapes.size()) +
67 "\" - should be \"2\".");
68 }
69
70 const TensorShape& inputShape = inputShapes[0];
71 const TensorShape& filterShape = inputShapes[1];
72
73 if (inputShape.GetNumDimensions() != 5)
74 {
75 throw armnn::Exception("Convolutions will always have 5D input.");
76 }
77
78 if (m_Param.m_StrideX == 0)
79 {
80 throw armnn::Exception("m_StrideX cannot be 0.");
81 }
82
83 if (m_Param.m_StrideY == 0)
84 {
85 throw armnn::Exception("m_StrideY cannot be 0.");
86 }
87
88 if (m_Param.m_StrideZ == 0)
89 {
90 throw armnn::Exception("m_StrideZ cannot be 0.");
91 }
92
93 DataLayoutIndexed dataLayoutIndex(m_Param.m_DataLayout);
94
95 unsigned int inWidth = inputShape[dataLayoutIndex.GetWidthIndex()];
96 unsigned int inHeight = inputShape[dataLayoutIndex.GetHeightIndex()];
97 unsigned int inDepth = inputShape[dataLayoutIndex.GetDepthIndex()];
98 unsigned int inBatchSize = inputShape[0];
99
100 // Conv3d Filter Layout: [D,H,W,I,O]
101 unsigned int filterDepth = filterShape[0];
102 unsigned int dilatedFilterDepth = filterDepth + (m_Param.m_DilationZ - 1) * (filterDepth - 1);
103 unsigned int readDepth = (inDepth + m_Param.m_PadFront + m_Param.m_PadBack) - dilatedFilterDepth;
104 unsigned int outDepth = 1 + (readDepth / m_Param.m_StrideZ);
105
106 unsigned int filterHeight = filterShape[1];
107 unsigned int dilatedFilterHeight = filterHeight + (m_Param.m_DilationY - 1) * (filterHeight - 1);
108 unsigned int readHeight = (inHeight + m_Param.m_PadTop + m_Param.m_PadBottom) - dilatedFilterHeight;
109 unsigned int outHeight = 1 + (readHeight / m_Param.m_StrideY);
110
111 unsigned int filterWidth = filterShape[2];
112 unsigned int dilatedFilterWidth = filterWidth + (m_Param.m_DilationX - 1) * (filterWidth - 1);
113 unsigned int readWidth = (inWidth + m_Param.m_PadLeft + m_Param.m_PadRight) - dilatedFilterWidth;
114 unsigned int outWidth = 1 + (readWidth / m_Param.m_StrideX);
115
116 unsigned int outChannels = filterShape[4];
117 unsigned int outBatchSize = inBatchSize;
118
119 TensorShape tensorShape = m_Param.m_DataLayout == armnn::DataLayout::NDHWC ?
120 TensorShape( { outBatchSize, outDepth, outHeight, outWidth, outChannels } ) :
121 TensorShape( { outBatchSize, outChannels, outDepth, outHeight, outWidth });
122
123 return std::vector<TensorShape>({ tensorShape });
124}
125
127{
129
130 const TensorShape& outputShape = GetOutputSlot(0).GetTensorInfo().GetShape();
131
133
134 if (!GetInputSlot(1).GetConnection())
135 {
136 throw armnn::LayerValidationException("Convolution3dLayer: Weights should be connected to input slot 1.");
137 }
138
139 auto inferredShapes = InferOutputShapes({
142
143 if (inferredShapes.size() != 1)
144 {
145 throw armnn::LayerValidationException("inferredShapes has "
146 + std::to_string(inferredShapes.size()) +
147 " elements - should only have 1.");
148 }
149
150 ValidateAndCopyShape(outputShape, inferredShapes[0], m_ShapeInferenceMethod, "Convolution3dLayer");
151}
152
154{
155 strategy.ExecuteStrategy(this, GetParameters(), {}, GetName());
156}
157
158} // namespace armnn
#define CHECK_LOCATION()
void SerializeLayerParameters(ParameterStringifyFunction &fn) const override
Helper to serialize the layer parameters to string.
void ExecuteStrategy(IStrategy &strategy) const override
Apply a visitor to this layer.
std::vector< TensorShape > InferOutputShapes(const std::vector< TensorShape > &inputShapes) const override
By default returns inputShapes if the number of inputs are equal to number of outputs,...
void ValidateTensorShapesFromInputs() override
Check if the input tensor shape(s) will lead to a valid configuration of Convolution3dLayer.
Convolution3dLayer * Clone(Graph &graph) const override
Creates a dynamically-allocated copy of this layer.
virtual std::unique_ptr< IWorkload > CreateWorkload(const IWorkloadFactory &factory) const override
Makes a workload for the Convolution3d type.
Convolution3dLayer(const Convolution3dDescriptor &param, const char *name)
Constructor to create a Convolution3dLayer.
Base class for all ArmNN exceptions so that users can filter to just those.
virtual void ExecuteStrategy(const IConnectableLayer *layer, const armnn::BaseDescriptor &descriptor, const std::vector< armnn::ConstTensor > &constants, const char *name, const armnn::LayerBindingId id=0)=0
virtual std::unique_ptr< IWorkload > CreateWorkload(LayerType type, const QueueDescriptor &descriptor, const WorkloadInfo &info) const =0
Backends should implement their own CreateWorkload function with a switch statement.
const TensorInfo & GetTensorInfo() const override
Gets the TensorInfo for this InputSlot.
Definition Layer.cpp:614
void VerifyLayerConnections(unsigned int expectedConnections, const CheckLocation &location) const
Definition Layer.cpp:410
const InputSlot & GetInputSlot(unsigned int index) const override
Get a const input slot handle by slot index.
Definition Layer.hpp:337
void VerifyShapeInferenceType(const TensorShape &outputShape, ShapeInferenceMethod shapeInferenceMethod)
Definition Layer.cpp:526
const OutputSlot & GetOutputSlot(unsigned int index=0) const override
Get the const output slot handle by slot index.
Definition Layer.hpp:339
LayerType * CloneBase(Graph &graph, Params &&... params) const
const char * GetName() const override
Returns the name of the layer.
Definition Layer.hpp:332
void ValidateAndCopyShape(const TensorShape &outputShape, const TensorShape &inferredShape, const ShapeInferenceMethod shapeInferenceMethod, const std::string &layerName, const unsigned int outputSlotIndex=0)
Definition Layer.cpp:457
void SetAdditionalInfo(QueueDescriptor &descriptor) const
Definition Layer.cpp:303
ShapeInferenceMethod m_ShapeInferenceMethod
Definition Layer.hpp:441
LayerWithParameters(unsigned int numInputSlots, unsigned int numOutputSlots, LayerType type, const Convolution3dDescriptor &param, const char *name)
void SerializeLayerParameters(ParameterStringifyFunction &fn) const override
Helper to serialize the layer parameters to string (currently used in DotSerializer and company).
WorkloadInfo PrepInfoAndDesc(QueueDescriptor &descriptor) const
const Convolution3dDescriptor & GetParameters() const override
const TensorInfo & GetTensorInfo() const override
Definition Layer.cpp:100
const TensorShape & GetShape() const
Definition Tensor.hpp:193
unsigned int GetNumDimensions() const
Function that returns the tensor rank.
Definition Tensor.cpp:174
Provides access to the appropriate indexes for Channels, Height and Width based on DataLayout.
unsigned int GetHeightIndex() const
Copyright (c) 2021 ARM Limited and Contributors.
uint32_t GetNumInputs(bool biasEnabled)
LayerType
When adding a new layer, adapt also the LastLayer enum value in the enum class LayerType below.
Definition Types.hpp:494
std::function< void(const std::string &name, const std::string &value)> ParameterStringifyFunction
A Convolution3dDescriptor for the Convolution3dLayer.