aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFerran Balaguer <ferran.balaguer@arm.com>2018-10-26 16:41:17 +0100
committerMatthew Bentham <matthew.bentham@arm.com>2018-11-06 17:02:26 +0000
commitd2966a96822772683f4b4a8a368edd3ee8adfdad (patch)
treefec9a51b65545173c30911a379ab9d5b00de5d8f
parentae622b7553d3d3f49447160655f2feb7aa3b0e17 (diff)
downloadandroid-nn-driver-branches/nhwc-preview.tar.gz
MLCE-65 Early access release with NHWC for Androidbranches/nhwc-preview
Change-Id: I612efc41b5ea460f4893bb05b8d358d21ee393bb
-rw-r--r--1.0/HalPolicy.cpp111
-rw-r--r--ConversionUtils.hpp35
2 files changed, 72 insertions, 74 deletions
diff --git a/1.0/HalPolicy.cpp b/1.0/HalPolicy.cpp
index 4c5fba3f..e4193e31 100644
--- a/1.0/HalPolicy.cpp
+++ b/1.0/HalPolicy.cpp
@@ -354,11 +354,8 @@ bool HalPolicy::ConvertConv2d(const Operation& operation, const Model& model, Co
const armnn::TensorInfo& inputInfo = input.GetTensorInfo();
const armnn::TensorInfo& outputInfo = GetTensorInfoForOperand(*output);
- const armnn::TensorInfo swizzledInputInfo = armnnUtils::Permuted(inputInfo, NHWCToArmNN);
- const armnn::TensorInfo swizzledOutputInfo = armnnUtils::Permuted(outputInfo, NHWCToArmNN);
-
// ArmNN does not currently support non-fixed weights or bias
- const ConstTensorPin weightsPin = ConvertOperationInputToConstTensorPin(operation, 1, model, data, NHWCToArmNN);
+ const ConstTensorPin weightsPin = ConvertOperationInputToConstTensorPin(operation, 1, model, data);
const ConstTensorPin biasPin = ConvertOperationInputToConstTensorPin(operation, 2, model, data);
if (!weightsPin.IsValid() || !biasPin.IsValid())
@@ -368,9 +365,10 @@ bool HalPolicy::ConvertConv2d(const Operation& operation, const Model& model, Co
armnn::ConstTensor weights = weightsPin.GetConstTensor();
armnn::ConstTensor bias = biasPin.GetConstTensor();
- SanitizeBiasQuantizationScale(bias.GetInfo(), weights.GetInfo(), swizzledInputInfo);
+ SanitizeBiasQuantizationScale(bias.GetInfo(), weights.GetInfo(), inputInfo);
armnn::Convolution2dDescriptor desc;
+ desc.m_DataLayout = armnn::DataLayout::NHWC;
ActivationFn activation;
if (operation.inputs.size() == 10)
@@ -397,10 +395,10 @@ bool HalPolicy::ConvertConv2d(const Operation& operation, const Model& model, Co
return Fail("%s: Operation has invalid inputs", __func__);
}
- const uint32_t kernelX = weights.GetShape()[3];
- const uint32_t kernelY = weights.GetShape()[2];
- const uint32_t inputX = swizzledInputInfo.GetShape()[3];
- const uint32_t inputY = swizzledInputInfo.GetShape()[2];
+ const uint32_t kernelX = weights.GetShape()[2];
+ const uint32_t kernelY = weights.GetShape()[1];
+ const uint32_t inputX = inputInfo.GetShape()[2];
+ const uint32_t inputY = inputInfo.GetShape()[1];
CalcPadding(inputX, kernelX, desc.m_StrideX, desc.m_PadLeft, desc.m_PadRight, paddingScheme);
CalcPadding(inputY, kernelY, desc.m_StrideY, desc.m_PadTop, desc.m_PadBottom, paddingScheme);
@@ -416,8 +414,8 @@ bool HalPolicy::ConvertConv2d(const Operation& operation, const Model& model, Co
if (!IsLayerSupported(__func__,
armnn::IsConvolution2dSupported,
data.m_Compute,
- swizzledInputInfo,
- swizzledOutputInfo,
+ inputInfo,
+ outputInfo,
desc,
weights.GetInfo(),
biases))
@@ -426,18 +424,20 @@ bool HalPolicy::ConvertConv2d(const Operation& operation, const Model& model, Co
}
armnn::IConnectableLayer* startLayer = data.m_Network->AddConvolution2dLayer(desc, weights, bias);
- armnn::IConnectableLayer* endLayer = ProcessActivation(swizzledOutputInfo, activation, startLayer, data);
-
- if (endLayer != nullptr)
+ if (!startLayer)
{
- armnn::IConnectableLayer& outSwizzleLayer =
- SwizzleInDeswizzleOut(*data.m_Network, input, *startLayer, *endLayer);
- return SetupAndTrackLayerOutputSlot(operation, 0, outSwizzleLayer, model, data);
+ return Fail("%s: AddConvolution2dLayer failed", __func__);
}
- else
+
+ armnn::IConnectableLayer* endLayer = ProcessActivation(outputInfo, activation, startLayer, data);
+ if (!endLayer)
{
return Fail("%s: ProcessActivation failed", __func__);
}
+
+ input.Connect(startLayer->GetInputSlot(0));
+
+ return SetupAndTrackLayerOutputSlot(operation, 0, *endLayer, model, data);
}
bool HalPolicy::ConvertDepthwiseConv2d(const Operation& operation, const Model& model, ConversionData& data)
@@ -457,13 +457,10 @@ bool HalPolicy::ConvertDepthwiseConv2d(const Operation& operation, const Model&
const armnn::TensorInfo& inputInfo = input.GetTensorInfo();
const armnn::TensorInfo& outputInfo = GetTensorInfoForOperand(*output);
- const armnn::TensorInfo swizzledInputInfo = armnnUtils::Permuted(inputInfo, NHWCToArmNN);
- const armnn::TensorInfo swizzledOutputInfo = armnnUtils::Permuted(outputInfo, NHWCToArmNN);
-
// ArmNN does not currently support non-fixed weights or bias
// Find the shape of the weights tensor. In AndroidNN this will be [ 1, H, W, I * M ]
- // but in ArmNN it needs to be [ M, I, H, W ]
+ // which is equal to [ M, H, W, I ]
const Operand* weightsOperand = GetInputOperand(operation, 1, model);
if (weightsOperand == nullptr)
@@ -476,10 +473,10 @@ bool HalPolicy::ConvertDepthwiseConv2d(const Operation& operation, const Model&
inputInfo.GetShape()[3],
weightsOperand->dimensions[3] / inputInfo.GetShape()[3] });
- // Swizzle weight data [ H, W, I, M ] -> [ M, I, H, W ]
- const armnn::PermutationVector HWIMToMIHW = { 2U, 3U, 1U, 0U };
+ // Swizzle weight data [ H, W, I, M ] -> [ M, H, W, I ]
+ const armnn::PermutationVector HWIMToMHWI = { 1U, 2U, 3U, 0U };
ConstTensorPin weightsPin =
- ConvertOperationInputToConstTensorPin(operation, 1, model, data, HWIMToMIHW, &weightsShape);
+ ConvertOperationInputToConstTensorPin(operation, 1, model, data, HWIMToMHWI, &weightsShape);
// Bias is a 1D tensor
ConstTensorPin biasPin = ConvertOperationInputToConstTensorPin(operation, 2, model, data);
@@ -491,19 +488,20 @@ bool HalPolicy::ConvertDepthwiseConv2d(const Operation& operation, const Model&
armnn::ConstTensor weights = weightsPin.GetConstTensor();
armnn::ConstTensor bias = biasPin.GetConstTensor();
- SanitizeBiasQuantizationScale(bias.GetInfo(), weights.GetInfo(), swizzledInputInfo);
+ SanitizeBiasQuantizationScale(bias.GetInfo(), weights.GetInfo(), inputInfo);
armnn::DepthwiseConvolution2dDescriptor desc;
+ desc.m_DataLayout = armnn::DataLayout::NHWC;
ActivationFn activation;
if (operation.inputs.size() == 11)
{
- if (!GetInputScalar(operation, 3, OperandType::INT32, desc.m_PadLeft, model, data) ||
- !GetInputScalar(operation, 4, OperandType::INT32, desc.m_PadRight, model, data) ||
- !GetInputScalar(operation, 5, OperandType::INT32, desc.m_PadTop, model, data) ||
- !GetInputScalar(operation, 6, OperandType::INT32, desc.m_PadBottom, model, data) ||
- !GetInputScalar(operation, 7, OperandType::INT32, desc.m_StrideX, model, data) ||
- !GetInputScalar(operation, 8, OperandType::INT32, desc.m_StrideY, model, data) ||
+ if (!GetInputScalar(operation, 3, OperandType::INT32, desc.m_PadLeft, model, data) ||
+ !GetInputScalar(operation, 4, OperandType::INT32, desc.m_PadRight, model, data) ||
+ !GetInputScalar(operation, 5, OperandType::INT32, desc.m_PadTop, model, data) ||
+ !GetInputScalar(operation, 6, OperandType::INT32, desc.m_PadBottom, model, data) ||
+ !GetInputScalar(operation, 7, OperandType::INT32, desc.m_StrideX, model, data) ||
+ !GetInputScalar(operation, 8, OperandType::INT32, desc.m_StrideY, model, data) ||
!GetInputActivationFunction(operation, 10, activation, model, data))
{
return Fail("%s: Operation has invalid inputs", __func__);
@@ -512,18 +510,18 @@ bool HalPolicy::ConvertDepthwiseConv2d(const Operation& operation, const Model&
else if (operation.inputs.size() == 8)
{
android::nn::PaddingScheme paddingScheme;
- if (!GetInputPaddingScheme(operation, 3, paddingScheme, model, data) ||
- !GetInputScalar(operation, 4, OperandType::INT32, desc.m_StrideX, model, data) ||
- !GetInputScalar(operation, 5, OperandType::INT32, desc.m_StrideY, model, data) ||
+ if (!GetInputPaddingScheme(operation, 3, paddingScheme, model, data) ||
+ !GetInputScalar(operation, 4, OperandType::INT32, desc.m_StrideX, model, data) ||
+ !GetInputScalar(operation, 5, OperandType::INT32, desc.m_StrideY, model, data) ||
!GetInputActivationFunction(operation, 7, activation, model, data))
{
return Fail("%s: Operation has invalid inputs", __func__);
}
- const uint32_t kernelX = weights.GetShape()[3];
- const uint32_t kernelY = weights.GetShape()[2];
- const uint32_t inputX = swizzledInputInfo.GetShape()[3];
- const uint32_t inputY = swizzledInputInfo.GetShape()[2];
+ const uint32_t kernelX = weights.GetShape()[2];
+ const uint32_t kernelY = weights.GetShape()[1];
+ const uint32_t inputX = inputInfo.GetShape()[2];
+ const uint32_t inputY = inputInfo.GetShape()[1];
CalcPadding(inputX, kernelX, desc.m_StrideX, desc.m_PadLeft, desc.m_PadRight, paddingScheme);
CalcPadding(inputY, kernelY, desc.m_StrideY, desc.m_PadTop, desc.m_PadBottom, paddingScheme);
@@ -539,8 +537,8 @@ bool HalPolicy::ConvertDepthwiseConv2d(const Operation& operation, const Model&
if (!IsLayerSupported(__func__,
armnn::IsDepthwiseConvolutionSupported,
data.m_Compute,
- swizzledInputInfo,
- swizzledOutputInfo,
+ inputInfo,
+ outputInfo,
desc,
weights.GetInfo(),
biases))
@@ -549,18 +547,20 @@ bool HalPolicy::ConvertDepthwiseConv2d(const Operation& operation, const Model&
}
armnn::IConnectableLayer* startLayer = data.m_Network->AddDepthwiseConvolution2dLayer(desc, weights, bias);
- armnn::IConnectableLayer* endLayer = ProcessActivation(swizzledOutputInfo, activation, startLayer, data);
-
- if (endLayer != nullptr)
+ if (!startLayer)
{
- armnn::IConnectableLayer& outSwizzleLayer =
- SwizzleInDeswizzleOut(*data.m_Network, input, *startLayer, *endLayer);
- return SetupAndTrackLayerOutputSlot(operation, 0, outSwizzleLayer, model, data);
+ return Fail("%s: AddDepthwiseConvolution2dLayer failed", __func__);
}
- else
+
+ armnn::IConnectableLayer* endLayer = ProcessActivation(outputInfo, activation, startLayer, data);
+ if (!endLayer)
{
return Fail("%s: ProcessActivation failed", __func__);
}
+
+ input.Connect(startLayer->GetInputSlot(0));
+
+ return SetupAndTrackLayerOutputSlot(operation, 0, *endLayer, model, data);
}
bool HalPolicy::ConvertFloor(const Operation& operation, const Model& model, ConversionData& data)
@@ -1324,18 +1324,17 @@ bool HalPolicy::ConvertResizeBilinear(const Operation& operation, const Model& m
const armnn::TensorInfo& inputInfo = input.GetTensorInfo();
const armnn::TensorInfo& outputInfo = GetTensorInfoForOperand(*output);
- const armnn::TensorInfo swizzledInputInfo = armnnUtils::Permuted(inputInfo, NHWCToArmNN);
- const armnn::TensorInfo swizzledOutputInfo = armnnUtils::Permuted(outputInfo, NHWCToArmNN);
if (!IsLayerSupported(__func__,
armnn::IsResizeBilinearSupported,
data.m_Compute,
- swizzledInputInfo))
+ inputInfo))
{
return false;
}
armnn::ResizeBilinearDescriptor desc;
+ desc.m_DataLayout = armnn::DataLayout::NHWC;
if ( !GetInputScalar(operation, 1, OperandType::INT32, desc.m_TargetHeight, model, data)
|| !GetInputScalar(operation, 2, OperandType::INT32, desc.m_TargetWidth, model, data))
@@ -1344,12 +1343,14 @@ bool HalPolicy::ConvertResizeBilinear(const Operation& operation, const Model& m
}
armnn::IConnectableLayer* layer = data.m_Network->AddResizeBilinearLayer(desc);
- assert(layer != nullptr);
- layer->GetOutputSlot(0).SetTensorInfo(swizzledOutputInfo);
+ if (!layer)
+ {
+ return Fail("%s: AddResizeBilinearLayer failed to execute", __func__);
+ }
- armnn::IConnectableLayer& outSwizzleLayer = SwizzleInDeswizzleOut(*data.m_Network, input, *layer);
+ input.Connect(layer->GetInputSlot(0));
- return SetupAndTrackLayerOutputSlot(operation, 0, outSwizzleLayer, model, data);
+ return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data);
}
diff --git a/ConversionUtils.hpp b/ConversionUtils.hpp
index 783f7cec..9b56a9aa 100644
--- a/ConversionUtils.hpp
+++ b/ConversionUtils.hpp
@@ -939,10 +939,8 @@ bool ConvertPooling2d(const HalOperation& operation,
const armnn::TensorInfo& inputInfo = input.GetTensorInfo();
const armnn::TensorInfo& outputInfo = GetTensorInfoForOperand(*output);
- const armnn::TensorInfo swizzledInputInfo = armnnUtils::Permuted(inputInfo, NHWCToArmNN);
- const armnn::TensorInfo swizzledOutputInfo = armnnUtils::Permuted(outputInfo, NHWCToArmNN);
-
armnn::Pooling2dDescriptor desc;
+ desc.m_DataLayout = armnn::DataLayout::NHWC;
desc.m_PoolType = poolType;
desc.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
@@ -962,8 +960,8 @@ bool ConvertPooling2d(const HalOperation& operation,
return Fail("%s: Operation has invalid inputs", operationName);
}
- const unsigned int inputWidth = swizzledInputInfo.GetShape()[3];
- const unsigned int inputHeight = swizzledInputInfo.GetShape()[2];
+ const unsigned int inputWidth = inputInfo.GetShape()[2];
+ const unsigned int inputHeight = inputInfo.GetShape()[1];
CalcPadding(inputWidth, desc.m_PoolWidth, desc.m_StrideX, desc.m_PadLeft, desc.m_PadRight, scheme);
CalcPadding(inputHeight, desc.m_PoolHeight, desc.m_StrideY, desc.m_PadTop, desc.m_PadBottom, scheme);
@@ -985,32 +983,31 @@ bool ConvertPooling2d(const HalOperation& operation,
}
}
- armnn::IConnectableLayer* startLayer = nullptr;
-
if (!IsLayerSupported(__func__,
armnn::IsPooling2dSupported,
data.m_Compute,
- swizzledInputInfo,
- swizzledOutputInfo,
+ inputInfo,
+ outputInfo,
desc))
{
return false;
}
- startLayer = data.m_Network->AddPooling2dLayer(desc);
-
- armnn::IConnectableLayer* endLayer = ProcessActivation(swizzledOutputInfo, activation, startLayer, data);
-
- if (endLayer != nullptr)
+ armnn::IConnectableLayer* startLayer = data.m_Network->AddPooling2dLayer(desc);
+ if (!startLayer)
{
- armnn::IConnectableLayer& outSwizzleLayer =
- SwizzleInDeswizzleOut(*data.m_Network, input, *startLayer, *endLayer);
- return SetupAndTrackLayerOutputSlot(operation, 0, outSwizzleLayer, model, data);
+ return Fail("%s: AddPooling2dLayer failed", __func__);
}
- else
+
+ armnn::IConnectableLayer* endLayer = ProcessActivation(outputInfo, activation, startLayer, data);
+ if (!endLayer)
{
- return Fail("%s: ProcessActivation failed", operationName);
+ return Fail("%s: ProcessActivation failed", __func__);
}
+
+ input.Connect(startLayer->GetInputSlot(0));
+
+ return SetupAndTrackLayerOutputSlot(operation, 0, *endLayer, model, data);
}
} // namespace armnn_driver