aboutsummaryrefslogtreecommitdiff
path: root/src/armnnTfParser/TfParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/armnnTfParser/TfParser.cpp')
-rwxr-xr-xsrc/armnnTfParser/TfParser.cpp118
1 files changed, 57 insertions, 61 deletions
diff --git a/src/armnnTfParser/TfParser.cpp b/src/armnnTfParser/TfParser.cpp
index f926013faa..d13a277924 100755
--- a/src/armnnTfParser/TfParser.cpp
+++ b/src/armnnTfParser/TfParser.cpp
@@ -423,28 +423,29 @@ const std::list<std::string> ITfParser::TfParserImpl::m_ControlInputs = {
"Assert"
};
-inline void CalculateSamePadding(uint32_t inputSize, uint32_t stride,
- uint32_t filterSize, bool samePadding,
- uint32_t* paddingFront, uint32_t* paddingBack) {
- *paddingFront = 0;
- *paddingBack = 0;
-
- if (samePadding) {
+void CalcPadding(uint32_t inputSize,
+ uint32_t filterSize,
+ uint32_t stride,
+ uint32_t dilation,
+ uint32_t& paddingFront,
+ uint32_t& paddingBack,
+ bool samePadding)
+{
+ paddingFront = 0;
+ paddingBack = 0;
+ if (samePadding)
+ {
uint32_t outputSize = (inputSize + stride - 1) / stride;
- uint32_t temp = (outputSize - 1) * stride + filterSize;
- if (temp > inputSize) {
- *paddingFront = (temp - inputSize) / 2;
- *paddingBack = (temp - inputSize) - *paddingFront;
+ uint32_t dilatedSize = filterSize + (dilation - 1) * (filterSize - 1);
+ uint32_t temp = (outputSize - 1) * stride + dilatedSize;
+ if (temp > inputSize)
+ {
+ paddingFront = (temp - inputSize) / 2;
+ paddingBack = (temp - inputSize) - paddingFront;
}
}
}
-void CalcPadding(uint32_t input, uint32_t kernel, uint32_t stride, uint32_t& outPadHead, uint32_t& outPadTail,
- bool samePadding)
-{
- CalculateSamePadding(input, stride, kernel, samePadding, &outPadHead, &outPadTail);
-}
-
/// An Abstract base class which represents a single tensorflow operation (node)
/// that has been (potentially partially) converted to Armnn.
/// It may not yet have been fully converted into actual Armnn layers.
@@ -1229,22 +1230,6 @@ ParsedTfOperationPtr ITfParser::TfParserImpl::ParseConv2D(const tensorflow::Node
std::string dataFormat = ReadMandatoryNodeStringAttribute(nodeDef, "data_format");
std::vector<uint32_t> strides = ReadMandatoryNodeUint32ListAttribute(nodeDef, "strides");
- // Read the dilations, if present - only [1,1,1,1] (the default) is supported.
- std::vector<uint32_t> dilations = ReadOptionalNodeUint32ListAttribute(nodeDef, "dilations");
- if (!dilations.empty())
- {
- for (auto dilation : dilations)
- {
- if (dilation != 1u)
- {
- throw ParseException(
- fmt::format("ArmNN only supports Convolution layers with dilations [1,1,1,1] for {} {}",
- nodeDef.name(),
- CHECK_LOCATION().AsString()));
- }
- }
- }
-
Convolution2dDescriptor desc;
desc.m_BiasEnabled = false;
@@ -1259,6 +1244,13 @@ ParsedTfOperationPtr ITfParser::TfParserImpl::ParseConv2D(const tensorflow::Node
desc.m_StrideX = strides[dataLayoutIndexed.GetWidthIndex()];
desc.m_StrideY = strides[dataLayoutIndexed.GetHeightIndex()];
+ std::vector<uint32_t> dilations = ReadOptionalNodeUint32ListAttribute(nodeDef, "dilations");
+ if (!dilations.empty())
+ {
+ desc.m_DilationX = dilations[dataLayoutIndexed.GetWidthIndex()];
+ desc.m_DilationY = dilations[dataLayoutIndexed.GetHeightIndex()];
+ }
+
uint32_t inputHeight = inputTensorInfo.GetShape()[dataLayoutIndexed.GetHeightIndex()];
uint32_t inputWidth = inputTensorInfo.GetShape()[dataLayoutIndexed.GetWidthIndex()];
@@ -1296,22 +1288,24 @@ ParsedTfOperationPtr ITfParser::TfParserImpl::ParseConv2D(const tensorflow::Node
if (paddingString == "SAME")
{
padding = true;
-
- outputHeight = static_cast<uint32_t>(ceil(static_cast<float>(inputHeight) /
- static_cast<float>(desc.m_StrideY)));
- outputWidth = static_cast<uint32_t>(ceil(static_cast<float>(inputWidth) /
- static_cast<float>(desc.m_StrideX)));
}
else if (paddingString == "VALID")
{
padding = false;
-
- outputHeight = static_cast<uint32_t>(ceil(static_cast<float>(inputHeight - weightHeight + 1) /
- static_cast<float>(desc.m_StrideY)));
- outputWidth = static_cast<uint32_t>(ceil(static_cast<float>(inputWidth - weightWidth + 1) /
- static_cast<float>(desc.m_StrideX)));
}
+ CalcPadding(inputHeight, weightHeight, desc.m_StrideY, desc.m_DilationY, desc.m_PadTop, desc.m_PadBottom, padding);
+ CalcPadding(inputWidth, weightWidth, desc.m_StrideX, desc.m_DilationX, desc.m_PadLeft, desc.m_PadRight, padding);
+
+ // Calculate output height and width
+ unsigned int dilatedFilterWidth = weightWidth + (desc.m_DilationX - 1) * (weightWidth - 1);
+ unsigned int readWidth = (inputWidth + desc.m_PadLeft + desc.m_PadRight) - dilatedFilterWidth;
+ outputWidth = 1 + (readWidth / desc.m_StrideX);
+
+ unsigned int dilatedFilterHeight = weightHeight + (desc.m_DilationY - 1) * (weightHeight - 1);
+ unsigned int readHeight = (inputHeight + desc.m_PadTop + desc.m_PadBottom) - dilatedFilterHeight;
+ outputHeight = 1 + (readHeight / desc.m_StrideY);
+
switch (dataLayout)
{
case DataLayout::NHWC:
@@ -1331,9 +1325,6 @@ ParsedTfOperationPtr ITfParser::TfParserImpl::ParseConv2D(const tensorflow::Node
break;
}
- CalcPadding(inputHeight, weightHeight, desc.m_StrideY, desc.m_PadTop, desc.m_PadBottom, padding);
- CalcPadding(inputWidth, weightWidth, desc.m_StrideX, desc.m_PadLeft, desc.m_PadRight, padding);
-
IConnectableLayer* layer = m_Network->AddConvolution2dLayer(desc,
weightTensor,
EmptyOptional(),
@@ -1382,6 +1373,12 @@ ParsedTfOperationPtr ITfParser::TfParserImpl::ParseDepthwiseConv2D(const tensorf
desc.m_StrideX = strides[dataLayoutIndexed.GetWidthIndex()];
desc.m_StrideY = strides[dataLayoutIndexed.GetHeightIndex()];
+ std::vector<uint32_t> dilations = ReadOptionalNodeUint32ListAttribute(nodeDef, "dilations");
+ if (!dilations.empty())
+ {
+ desc.m_DilationX = dilations[dataLayoutIndexed.GetWidthIndex()];
+ desc.m_DilationY = dilations[dataLayoutIndexed.GetHeightIndex()];
+ }
uint32_t inputHeight = inputTensorInfo.GetShape()[dataLayoutIndexed.GetHeightIndex()];
uint32_t inputWidth = inputTensorInfo.GetShape()[dataLayoutIndexed.GetWidthIndex()];
@@ -1416,22 +1413,24 @@ ParsedTfOperationPtr ITfParser::TfParserImpl::ParseDepthwiseConv2D(const tensorf
if (paddingString == "SAME")
{
padding = true;
-
- outputHeight = static_cast<uint32_t>(ceil(static_cast<float>(inputHeight) /
- static_cast<float>(desc.m_StrideY)));
- outputWidth = static_cast<uint32_t>(ceil(static_cast<float>(inputWidth) /
- static_cast<float>(desc.m_StrideX)));
}
else if (paddingString == "VALID")
{
padding = false;
-
- outputHeight = static_cast<uint32_t>(ceil(static_cast<float>(inputHeight - weightHeight + 1) /
- static_cast<float>(desc.m_StrideY)));
- outputWidth = static_cast<uint32_t>(ceil(static_cast<float>(inputWidth - weightWidth + 1) /
- static_cast<float>(desc.m_StrideX)));
}
+ CalcPadding(inputHeight, weightHeight, desc.m_StrideY, desc.m_DilationY, desc.m_PadTop, desc.m_PadBottom, padding);
+ CalcPadding(inputWidth, weightWidth, desc.m_StrideX, desc.m_DilationX, desc.m_PadLeft, desc.m_PadRight, padding);
+
+ // Calculate output height and width
+ unsigned int dilatedFilterWidth = weightWidth + (desc.m_DilationX - 1) * (weightWidth - 1);
+ unsigned int readWidth = (inputWidth + desc.m_PadLeft + desc.m_PadRight) - dilatedFilterWidth;
+ outputWidth = 1 + (readWidth / desc.m_StrideX);
+
+ unsigned int dilatedFilterHeight = weightHeight + (desc.m_DilationY - 1) * (weightHeight - 1);
+ unsigned int readHeight = (inputHeight + desc.m_PadTop + desc.m_PadBottom) - dilatedFilterHeight;
+ outputHeight = 1 + (readHeight / desc.m_StrideY);
+
switch (dataLayout)
{
case DataLayout::NHWC:
@@ -1451,9 +1450,6 @@ ParsedTfOperationPtr ITfParser::TfParserImpl::ParseDepthwiseConv2D(const tensorf
break;
}
- CalcPadding(inputHeight, weightHeight, desc.m_StrideY, desc.m_PadTop, desc.m_PadBottom, padding);
- CalcPadding(inputWidth, weightWidth, desc.m_StrideX, desc.m_PadLeft, desc.m_PadRight, padding);
-
IConnectableLayer* layer = m_Network->AddDepthwiseConvolution2dLayer(desc,
weightTensor,
EmptyOptional(),
@@ -3094,9 +3090,9 @@ ParsedTfOperationPtr ITfParser::TfParserImpl::ParsePooling2d(const tensorflow::N
break;
}
- CalcPadding(inputWidth, pooling2dDescriptor.m_PoolWidth, pooling2dDescriptor.m_StrideX,
+ CalcPadding(inputWidth, pooling2dDescriptor.m_PoolWidth, pooling2dDescriptor.m_StrideX, 1u,
pooling2dDescriptor.m_PadLeft, pooling2dDescriptor.m_PadRight, padding);
- CalcPadding(inputHeight, pooling2dDescriptor.m_PoolHeight, pooling2dDescriptor.m_StrideY,
+ CalcPadding(inputHeight, pooling2dDescriptor.m_PoolHeight, pooling2dDescriptor.m_StrideY, 1u,
pooling2dDescriptor.m_PadTop, pooling2dDescriptor.m_PadBottom, padding);