38 class DepthwiseConv2dTest
55 std::vector<T> GetVector(
unsigned int size,
float initial,
float increment)
57 std::vector<float> typeVector(size, initial);
58 std::vector<T> vector(size);
62 for (
unsigned int i = 0; i < size; ++i)
64 vector[i] = T(initial + (increment * static_cast<float>(i)));
72 template <
typename Conv2dTest,
74 typename ConvDescriptorType =
typename Conv2dTest::ConvDescriptorType,
76 INetworkPtr CreatNetwork(
bool depthwise,
bool preventFusing)
79 ConvDescriptorType convolution2dDescriptor;
80 convolution2dDescriptor.m_BiasEnabled =
false;
81 convolution2dDescriptor.m_DataLayout = DataLayout::NHWC;
82 convolution2dDescriptor.m_StrideX = 1;
83 convolution2dDescriptor.m_StrideY = 1;
87 const unsigned int inputDimensionSizes[] = {1, 4, 4, 3};
88 unsigned int weightsDimensionSizes[] = {4, 2, 2, 3};
89 unsigned int outputDimensionSizes[] = {1, 3, 3, 4};
94 weightsDimensionSizes[0] = 1;
95 weightsDimensionSizes[1] = 2;
96 weightsDimensionSizes[2] = 2;
97 weightsDimensionSizes[3] = 12;
98 outputDimensionSizes[3] = weightsDimensionSizes[3];
100 const unsigned int outputChannelSize[] = {outputDimensionSizes[3]};
102 TensorInfo inputInfo(4, inputDimensionSizes, ArmnnType);
103 TensorInfo outputInfo(4, outputDimensionSizes, ArmnnType);
105 std::vector<int> weightsIntVector = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
106 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
107 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
108 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42};
109 std::vector<T> weightsVector(begin(weightsIntVector), end(weightsIntVector));
110 TensorInfo weightsInfo(4, weightsDimensionSizes, ArmnnType, 0.0f, 0,
true);
113 std::vector<T> biasVector = GetVector<T>(outputDimensionSizes[3], 3.3f, 0.1f);
114 TensorInfo biasInfo(1, outputChannelSize, ArmnnType, 0.0f, 0,
true);
118 std::vector<T> betaVector = GetVector<T>(outputDimensionSizes[3], 0.0f, 0.2f);
119 std::vector<T> gammaVector = GetVector<T>(outputDimensionSizes[3], 0.5f, 0.1f);
120 std::vector<T> meanVector = GetVector<T>(outputDimensionSizes[3], 0.1f, 0.1f);
121 std::vector<T> varianceVector = GetVector<T>(outputDimensionSizes[3], 1.0f, 0.1f);
134 convolution2dDescriptor,
139 IConnectableLayer* batchNormLayer = network->AddBatchNormalizationLayer(batchNormDescriptor,
151 output2Layer = network->AddOutputLayer(1);
157 batchNormLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
162 batchNormLayer->GetOutputSlot(0).Connect(outputLayer->
GetInputSlot(0));
172 template <
typename Conv2dTest,
174 typename ConvDescriptorType =
typename Conv2dTest::ConvDescriptorType,
175 typename ConvLayerType =
typename Conv2dTest::ConvLayerType,
177 void FuseBatchNormIntoConvTest(
bool depthwise,
float tolerance,
armnn::Compute backendId)
181 INetworkPtr networkFused = CreatNetwork<Conv2dTest, ArmnnType>(depthwise,
false);
191 auto checkFusedConv2d = [ ](
const armnn::Layer*
const layer) ->
bool 193 return IsLayerOfType<ConvLayerType>(layer) &&
194 (layer->GetNameStr() ==
"fused-batchNorm-into-convolution");
197 CHECK(3 == graphFused.GetNumLayers());
200 &IsLayerOfType<InputLayer>,
202 &IsLayerOfType<OutputLayer>));
206 CHECK(run->LoadNetwork(networkIdentifier, std::move(optNetFused)) == Status::Success);
209 std::vector<T> inputDataFused = GetVector<T>(48, 1.0f, 0.1f);
211 std::vector<T> outputDataFused(36);
215 outputDataFused.resize(108);
218 TensorInfo inputTensorInfo = run->GetInputTensorInfo(networkIdentifier, 0);
221 {0,
ConstTensor(inputTensorInfo, inputDataFused.data())}};
223 {0,
Tensor(run->GetOutputTensorInfo(networkIdentifier, 0), outputDataFused.data())}};
226 run->EnqueueWorkload(networkIdentifier, inputTensorsFused, outputTensorsFused);
230 INetworkPtr networkNotFused = CreatNetwork<Conv2dTest, ArmnnType>(depthwise,
true);
240 CHECK(5 == graphNotFused.GetNumLayers());
242 graphNotFused.cend(),
243 &IsLayerOfType<armnn::InputLayer>,
244 &IsLayerOfType<ConvLayerType>,
245 &IsLayerOfType<armnn::BatchNormalizationLayer>,
246 &IsLayerOfType<armnn::OutputLayer>,
247 &IsLayerOfType<armnn::OutputLayer>));
251 CHECK(runNotFused->LoadNetwork(networkIdentifierNotFused, std::move(optNetNotFused)) == Status::Success);
254 std::vector<T> inputDataNotFused = GetVector<T>(48, 1.0f, 0.1f);
256 std::vector<T> outputDataNotFused(36);
257 std::vector<T> outputData2NotFused(36);
261 outputDataNotFused.resize(108);
262 outputData2NotFused.resize(108);
265 TensorInfo inputTensorInfo2 = runNotFused->GetInputTensorInfo(networkIdentifierNotFused, 0);
268 {0,
ConstTensor(inputTensorInfo2, inputDataNotFused.data())}};
270 {0,
Tensor(runNotFused->GetOutputTensorInfo(networkIdentifierNotFused, 0), outputDataNotFused.data())},
271 {1,
Tensor(runNotFused->GetOutputTensorInfo(networkIdentifierNotFused, 1), outputData2NotFused.data())}};
274 runNotFused->EnqueueWorkload(networkIdentifierNotFused, inputTensorsNotFused, outputTensorsNotFused);
277 auto epsilon = T(tolerance);
278 for (
unsigned int n = 0; n < outputDataFused.size(); ++n)
280 CHECK_EQ(outputDataFused[n], doctest::Approx(outputDataNotFused[n]).epsilon(epsilon));
285 #if defined(ARMNNREF_ENABLED) 286 TEST_CASE(
"FuseBatchNormIntoConv2DFloat32Test")
291 TEST_CASE(
"FuseBatchNormIntoConv2DFloat16Test")
296 TEST_CASE(
"FuseBatchNormIntoDepthwiseConv2DFloat32Test")
301 TEST_CASE(
"FuseBatchNormIntoDepthwiseConv2DFloat16Test")
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
CPU Execution: Reference C++ kernels.
IConnectableLayer * AddDepthwiseConvolution2dLayer(const DepthwiseConvolution2dDescriptor &convolution2dDescriptor, const ConstTensor &weights, const Optional< ConstTensor > &biases, const char *name=nullptr)
Adds a 2D depthwise convolution layer to the network.
This layer represents a depthwise convolution 2d operation.
A Convolution2dDescriptor for the Convolution2dLayer.
std::unique_ptr< IRuntime, void(*)(IRuntime *runtime)> IRuntimePtr
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
typename ResolveTypeImpl< DT >::Type ResolveType
Main network class which provides the interface for building up a neural network. ...
std::vector< std::pair< LayerBindingId, class ConstTensor > > InputTensors
IConnectableLayer * AddConvolution2dLayer(const Convolution2dDescriptor &convolution2dDescriptor, const ConstTensor &weights, const Optional< ConstTensor > &biases, const char *name=nullptr)
Adds a 2D convolution layer to the network.
virtual void SetTensorInfo(const TensorInfo &tensorInfo)=0
A tensor defined by a TensorInfo (shape and data type) and a mutable backing store.
Compute
The Compute enum is now deprecated and it is now being replaced by BackendId.
IOptimizedNetworkPtr Optimize(const INetwork &network, const std::vector< BackendId > &backendPreferences, const IDeviceSpec &deviceSpec, const OptimizerOptions &options=OptimizerOptions(), Optional< std::vector< std::string > &> messages=EmptyOptional())
Create an optimized version of the network.
A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
std::vector< std::pair< LayerBindingId, class Tensor > > OutputTensors
std::unique_ptr< IOptimizedNetwork, void(*)(IOptimizedNetwork *network)> IOptimizedNetworkPtr
Graph & GetGraphForTesting(IOptimizedNetwork *optNet)
bool CheckSequence(const armnn::Graph::ConstIterator first, const armnn::Graph::ConstIterator last)
virtual const IInputSlot & GetInputSlot(unsigned int index) const =0
Get a const input slot handle by slot index.
void SetConstant(const bool IsConstant=true)
Marks the data corresponding to this tensor info as constant.
virtual const IOutputSlot & GetOutputSlot(unsigned int index) const =0
Get the const output slot handle by slot index.
This layer represents a convolution 2d operation.
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
virtual int Connect(IInputSlot &destination)=0
A DepthwiseConvolution2dDescriptor for the DepthwiseConvolution2dLayer.
A BatchNormalizationDescriptor for the BatchNormalizationLayer.