39 static std::vector<IConnectableLayer*> AddConstantLayers(
INetwork *network,
53 class DepthwiseConv2dTest
71 static std::vector<IConnectableLayer*> AddConstantLayers(
INetwork *network,
78 std::vector<IConnectableLayer*> layers = {weightsLayer};
84 layers.emplace_back(biasLayer);
92 std::vector<T> GetVector(
unsigned int size,
float initial,
float increment)
94 std::vector<float> typeVector(size, initial);
95 std::vector<T> vector(size);
99 for (
unsigned int i = 0; i < size; ++i)
101 vector[i] = T(initial + (increment * static_cast<float>(i)));
109 template <
typename Conv2dTest,
111 typename ConvDescriptorType =
typename Conv2dTest::ConvDescriptorType,
113 INetworkPtr CreateNetwork(
bool depthwise,
bool preventFusing)
116 ConvDescriptorType convolution2dDescriptor;
117 convolution2dDescriptor.m_BiasEnabled =
false;
118 convolution2dDescriptor.m_DataLayout = DataLayout::NHWC;
119 convolution2dDescriptor.m_StrideX = 1;
120 convolution2dDescriptor.m_StrideY = 1;
124 const unsigned int inputDimensionSizes[] = {1, 4, 4, 3};
125 unsigned int weightsDimensionSizes[] = {4, 2, 2, 3};
126 unsigned int outputDimensionSizes[] = {1, 3, 3, 4};
131 weightsDimensionSizes[0] = 1;
132 weightsDimensionSizes[1] = 2;
133 weightsDimensionSizes[2] = 2;
134 weightsDimensionSizes[3] = 12;
135 outputDimensionSizes[3] = weightsDimensionSizes[3];
137 const unsigned int outputChannelSize[] = {outputDimensionSizes[3]};
139 TensorInfo inputInfo(4, inputDimensionSizes, ArmnnType);
140 TensorInfo outputInfo(4, outputDimensionSizes, ArmnnType);
142 std::vector<int> weightsIntVector = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
143 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
144 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
145 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42};
146 std::vector<T> weightsVector(begin(weightsIntVector), end(weightsIntVector));
147 TensorInfo weightsInfo(4, weightsDimensionSizes, ArmnnType, 0.0f, 0,
true);
150 std::vector<T> betaVector = GetVector<T>(outputDimensionSizes[3], 0.0f, 0.2f);
151 std::vector<T> gammaVector = GetVector<T>(outputDimensionSizes[3], 0.5f, 0.1f);
152 std::vector<T> meanVector = GetVector<T>(outputDimensionSizes[3], 0.1f, 0.1f);
153 std::vector<T> varianceVector = GetVector<T>(outputDimensionSizes[3], 1.0f, 0.1f);
166 convolution2dDescriptor,
171 IConnectableLayer* batchNormLayer = network->AddBatchNormalizationLayer(batchNormDescriptor,
183 output2Layer = network->AddOutputLayer(1);
186 std::vector<IConnectableLayer*> constantLayers = Conv2dTest::AddConstantLayers(network.get(),
187 convolution2dDescriptor,
192 for (
unsigned int i = 0; i < constantLayers.size(); ++i)
194 constantLayers[i]->GetOutputSlot(0).Connect(convLayer->
GetInputSlot(i + 1));
215 template <
typename Conv2dTest,
217 typename ConvDescriptorType =
typename Conv2dTest::ConvDescriptorType,
218 typename ConvLayerType =
typename Conv2dTest::ConvLayerType,
220 void FuseBatchNormIntoConvTest(
bool depthwise,
float tolerance,
armnn::Compute backendId)
224 INetworkPtr networkFused = CreateNetwork<Conv2dTest, ArmnnType>(depthwise,
false);
234 auto checkFusedConv2d = [ ](
const armnn::Layer*
const layer) ->
bool 236 return IsLayerOfType<ConvLayerType>(layer) &&
237 (layer->GetNameStr() ==
"fused-batchNorm-into-convolution");
240 CHECK(5 == graphFused.GetNumLayers());
243 &IsLayerOfType<InputLayer>,
244 &IsLayerOfType<ConstantLayer>,
245 &IsLayerOfType<ConstantLayer>,
247 &IsLayerOfType<OutputLayer>));
251 CHECK(run->LoadNetwork(networkIdentifier, std::move(optNetFused)) == Status::Success);
254 std::vector<T> inputDataFused = GetVector<T>(48, 1.0f, 0.1f);
256 std::vector<T> outputDataFused(36);
260 outputDataFused.resize(108);
263 TensorInfo inputTensorInfo = run->GetInputTensorInfo(networkIdentifier, 0);
266 {0,
ConstTensor(inputTensorInfo, inputDataFused.data())}};
268 {0,
Tensor(run->GetOutputTensorInfo(networkIdentifier, 0), outputDataFused.data())}};
271 run->EnqueueWorkload(networkIdentifier, inputTensorsFused, outputTensorsFused);
275 INetworkPtr networkNotFused = CreateNetwork<Conv2dTest, ArmnnType>(depthwise,
true);
285 CHECK(6 == graphNotFused.GetNumLayers());
287 graphNotFused.cend(),
288 &IsLayerOfType<armnn::InputLayer>,
289 &IsLayerOfType<armnn::ConstantLayer>,
290 &IsLayerOfType<ConvLayerType>,
291 &IsLayerOfType<armnn::BatchNormalizationLayer>,
292 &IsLayerOfType<armnn::OutputLayer>,
293 &IsLayerOfType<armnn::OutputLayer>));
297 CHECK(runNotFused->LoadNetwork(networkIdentifierNotFused, std::move(optNetNotFused)) == Status::Success);
300 std::vector<T> inputDataNotFused = GetVector<T>(48, 1.0f, 0.1f);
302 std::vector<T> outputDataNotFused(36);
303 std::vector<T> outputData2NotFused(36);
307 outputDataNotFused.resize(108);
308 outputData2NotFused.resize(108);
311 TensorInfo inputTensorInfo2 = runNotFused->GetInputTensorInfo(networkIdentifierNotFused, 0);
314 { 0,
ConstTensor(inputTensorInfo2, inputDataNotFused.data()) } };
316 { 0,
Tensor(runNotFused->GetOutputTensorInfo(networkIdentifierNotFused, 0), outputDataNotFused.data()) },
317 { 1,
Tensor(runNotFused->GetOutputTensorInfo(networkIdentifierNotFused, 1), outputData2NotFused.data()) } };
320 runNotFused->EnqueueWorkload(networkIdentifierNotFused, inputTensorsNotFused, outputTensorsNotFused);
323 auto epsilon = T(tolerance);
324 for (
unsigned int n = 0; n < outputDataFused.size(); ++n)
326 CHECK_EQ(outputDataFused[n], doctest::Approx(outputDataNotFused[n]).epsilon(epsilon));
331 #if defined(ARMNNREF_ENABLED) 332 TEST_CASE(
"FuseBatchNormIntoConv2DFloat32Test")
337 TEST_CASE(
"FuseBatchNormIntoConv2DFloat16Test")
342 TEST_CASE(
"FuseBatchNormIntoDepthwiseConv2DFloat32Test")
347 TEST_CASE(
"FuseBatchNormIntoDepthwiseConv2DFloat16Test")
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
bool m_BiasEnabled
Enable/disable bias.
CPU Execution: Reference C++ kernels.
bool CheckSequence(const armnn::Graph::ConstIterator first, const armnn::Graph::ConstIterator last)
IConnectableLayer * AddConstantLayer(const ConstTensor &input, const char *name=nullptr)
Adds a layer with no inputs and a single output, which always corresponds to the passed in constant t...
#define ARMNN_NO_DEPRECATE_WARN_BEGIN
IConnectableLayer * AddDepthwiseConvolution2dLayer(const DepthwiseConvolution2dDescriptor &convolution2dDescriptor, 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
void IgnoreUnused(Ts &&...)
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.
#define ARMNN_NO_DEPRECATE_WARN_END
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
const TensorInfo & GetInfo() const
Graph & GetGraphForTesting(IOptimizedNetwork *optNet)
IConnectableLayer * AddConvolution2dLayer(const Convolution2dDescriptor &convolution2dDescriptor, const char *name=nullptr)
Adds a 2D convolution layer to the network.
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.